牛客刷题知识点总结

一、垃圾回收

1.java提供了一个系统级的线程,即垃圾回收器线程。用来对每一个分配出去的内存空间进行跟踪。当JVM空闲时,自动回收每块可能被回收的内存,GC是完全自动的,不能被强制执行。程序员最多只能用System.gc()来建议执行垃圾回收器回收内存,但是具体的回收时间以及顺序,是不可知的。当对象的引用变量被赋值为null,可能被当成垃圾。

程序可以任意指定释放内存的时间,这句话显然不对。

程序可明确地标识某个局部变量的引用不再被使用。这句话也不对,局部变量是放在栈内存上的,栈上的垃圾回收,由finalize()来实现。
 
 
2
(1)、JVM类加载机制中有讲,类加载的最后一个阶段是初始化阶段,即为真正执行java 代码的时候终于到了。
(2)、这一阶段,会依次执行2个方法:<clinit>()方法和<init>()方法。
(3)<clinit>()方法:是编译器自动收集类中的所有类变量和静态语句块(static{})中的语句合并而成的。知道这一点很重要,而<clinit>()方法里面语句的顺序由源程序代码决定。<clinit>()方法和类实例构造器<init>()方法是不同的。同一个类加载器,一个类型只会初始化一次,对应此方法只被调用一次。
4()<init>()方法:涉及到实例代码块、构造方法的调用的执行。同时,实例化几次类,则进行“实例代码块”和“构造器方法”的几次调用,并且,“实例代码块”优先于“构造器方法”的调用。

二、线程

1.将一个线程标记成daemon(守护神、守护进程)线程,意味着当主线程结束,并且没有其它正在运行的非daemon线程时,该daemon线程也会自动结束。这句话正确。   daemon线程是守护线程,当主线程结束时,守护线程会自动结束。
 2.  
CyclicBarrier(栅栏):可以让一组线程等待其他线程。 CountDownLatch(闭锁): 可以让一组线程等待某个事件发生。所以  
CyclicBarrier和CountDownLatch都可以让一组线程等待其他线程这句话对的。

3.同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作。最常用的同步器是CountDownLatch和Semaphore,不常用的是Barrier 和Exchanger。CyclicBarrier 主要的方法就是一个:await()。await() 方法每被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。

4. ThreadLocal的类声明:

(1)public class ThreadLocal<T>
可以看出ThreadLocal并没有继承自Thread,也没有实现Runnable接口。所以AB都不对。
(2)ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量。
所以ThreadLocal重要作用并不在于多线程间的数据共享,而是数据的独立,C选项错。
由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问,
变量被彻底封闭在每个访问的线程中。所以E对。
(3)ThreadLocal中定义了一个哈希表用于为每个线程都提供一个变量的副本:

5.后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。 前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起,就像傀儡和幕后操纵者一样的关系。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。

main()函数即主函数,是一个前台线程,前台进程是程序中必须执行完成的,而后台线程则是java中所有前台结束后结束,不管有没有完成,后台线程主要用与内存分配等方面。

6. volatile关键字

(1)每次从内存中取值,不从缓存中什么的拿值。这就保证了用  volatile修饰的共享变量,每次的更新对于其他线程都是可见的。
(2)  volatile保证了其他线程的立即可见性,就没有保证原子性。

(3)由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况,多线程下计数器必须使用锁保护。

7.  

 进入”Dead”状态的线程 不一定 被垃圾回收器回收。当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
垃圾回收线程的priority(优先级)相当相当低

8.

第一,记住wait必须要进行异常捕获
第二,记住调用wait或者notify方法必须采用当前锁调用,即必须采用synchronized中的对象
obj.wait();
这句话需要进行try catch 异常捕捉
类似thread.sleep()这句话。同样需要异常捕捉。
线程这抛出的错误一般都与InterruptedException有关

9.

三、面向对象

1.在继承中,子类不会继承父类的构造方法。。但是可以通过super调用

2.普通方法能够调用静态方法,不能调用静态属性。反过来,静态方法只能调用静态属性,不能调用非静态的方法和属性。

3.父类没有无参的构造函数,所以子类需要在自己的构造函数中显式调用父类的构造函数添加super("nm");否则报错:

4.: private  修饰的变量或方法  不能在外部类中调用,main 方法属于Test类的方法, 所以main方法中的 对象 t 可以调用它的private方法或变量

5. 

   java中true ,false , null在java中不是关键字,也不是保留字,它们只是显式常量值,但是你在程序中不能使用它们作为标识符。
其中const和goto是java的保留字。java中所有的关键字都是小写的,还有要注意true,false,null, friendly,sizeof不是java的关键字,但是你不能把它们作为java标识符用

四、基本数据类型比较

1.两个数值进行二元操作时,会有如下的转换操作:
如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。
否则,如果其中一个操作数是float类型,另一个将会转换为float类型。 原因参考http://blog.csdn.net/shanshan1yi/article/details/48477119
否则,如果其中一个操作数是long类型,另一个会转换为long类型。
否则,两个操作数都转换为int类型。

2. ,成员变量可以不显式初始化,它们可以由系统设定默认值;局部变量没有默认值,所以必须设定初始赋值。 还有,在内存中的位置也不一样。成员变量在所在类被实例化后,存在堆内存中;局部变量在所在方法调用时,存在栈内存空间中。
3.Java中,赋值是有返回值的 ,赋什么值,就返回什么值。比如这题,x=y,返回y的值,所以括号里的值是1。
    Java跟C的区别,C中赋值后会与0进行比较,如果大于0,就认为是true;而Java不会与0比较,而是直接把赋值后的结果放入括号
详细见 http://blog.csdn.net/dawn_after_dark/article/details/74094399
4.     常见字符的 ASCII码 值如下:空格的 ASCII码 值为32;数字0到9的 ASCII码 值分别为48到57;大写字母“A”到“Z”的ASCII码值分别为65到90; 小写字母 “a”到“z”的ASCII码值分别为97到到122。


五、java容器

1.  关于HashMap的一些说法:

a)  HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。

b)  HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。

c)  HashMap实现不同步,线程不安全。  HashTable线程安全

d)  HashMap中的key-value都是存储在Entry中的。

e)  HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性

f)  解决冲突主要有三种方法:定址法,拉链法,再散列法。HashMap是采用拉链法解决哈希冲突的。

注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;

   用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。

  拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。

//以下是Hashtable的方法
public synchronized boolean contains(Object value)
public synchronized boolean containsKey(Object key)
public boolean containsValue(Object value)
 
//以下是HashMap中的方法,注意,没有contains方法,所以,D错误
public boolean containsKey(Object key)
public boolean containsValue(Object value)

   

2.  Hashtable和HashMap的区别:

a)   继承不同。

 public class Hashtable extends Dictionary implements Map

public class HashMap extends  AbstractMap implements Map

b)  Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

c)  Hashtable 中, key  value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。

d)  两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

e)  哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

f)  Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

 

注:  HashSet子类依靠hashCode()和equal()方法来区分重复元素。

     HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。


六、java web基础知识

1.会话跟踪是一种灵活、轻便的机制,它使Web上的状态编程变为可能。
HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的。当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题。当一个客户在多个页面间切换时,服务器会保存该用户的信息。
有四种方法可以实现会话跟踪技术:URL重写、隐藏表单域、Cookie、Session。
1).隐藏表单域:<input type="hidden">,非常适合不需要大量数据存储的会话应用。
2).URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对
3).Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP
响应的一部分传送到客户端,客户端被请求保存 Cookie 值,在对同一服务器的后续请求使用一个
Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在浏览器会话结束后,甚至
在客户端计算机重启后它仍可以保留其值
4).Session:使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话

2. 页面请求的工作流程

(1)用户输入网址

(2)把用户请求发送给服务器

(3)服务器查询所请求的页面

(4)找到用户请求的页面

(5)服务器发送相应消息

(6)浏览器返回显示的结果

3. filter(过滤器)作用

filetr 使得用户可以更改一个request或者更改一个response。  filter不是一个Servlet,不能产生response。但是他能在request到达Servlet之前预处理request,也可以在离开Servlet时处理response。 filter其实是一个 Servlet Chaining(Servlet链)。

4.JSP内置对象

request、response、session、application、out、page、pageContext、exception、config

5.cookie和session有什么区别

(1)cookie(文件)存在客户端,session(存储结构)存在服务器

(2)cookie由于存在客户端其他人能够方便得到,安全性不如session

(3)使用cookie,服务器性能高,session会根据访问量增加,进而降低服务器性能。

(4)cookie容量小,一般不超过4kb

6.XML(可扩展标记语言)

优点:实用性强、访问速度快、可扩展性好、跨平台性号

XML解析方式:(1)DOM(2)SAX(Simple API for XML)

DOM会根据XML在内存创建一个树形结构,占用内存较大。适合对XML内容随机访问与频繁修改 的情况。

SAX是时间驱动型XML解析方式,不会在内存中存储XML文件,把每次对数据的请求当做一个事件,通过遍历获得用户所需数据。适合对XML顺序访问、XML文件庞大的情况。

七、java框架

1.优化Hibernate所鼓励的7大措施:

(1)尽量使用many-to-one,避免使用单项one-to-many
(2)灵活使用单向one-to-many
(3)不用一对一,使用多对一代替一对一
(4)配置对象缓存,不使用集合缓存
(5)一对多使用Bag 多对一使用Set
(6)继承使用显示多态 HQL:from object polymorphism="exlicit" 避免查处所有对象
(7)消除大表,使用二级缓存


2. structs1 和 structs2 不同点

(1)Action的实现类, Structs1要求Action类继承一个抽象基类,Structs2中Action类既可以实现一个Action接口,也可以实现其他接口。

(2)Structs1 Action是单例模式且是线程安全的(只有Action的一个实例来处理所有请求),structs2 Action对象为每个请求产生一个实例,不存在线程安全。

(3)Structs1 Action以来Servlet API,Structs2 Action 不依赖

(4)Structs1使用ActionForm对象封装用户的请求参数,所有ActionForm必须继承一个基类(ActionForm)。 Structs2直接使用Action属性来封装用户请求属性,避免了大量开发ActionForm类的繁琐。

3.IOC

IoC控制反转(依赖注入),是一种降低对象之间的耦合关系的设计思想。  对象不会被显示调用,而是根据需求通过IoC容器(如Spring)来提供,

(通过配置文件 创建调用者对象,同时把被调用者的对象的实例化对象通过构造函数或set()方法  注入到调用者 对象中)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值