Java学习-----------查漏补缺小笔记

IU1.volatile所能保证的是可见性,不能保证Java程序的原子性。所以多线程中使用它并不能使线程安全。
2.字符编码转换格式
byte[] src,dst;
dst=new String(src,“GBK”).getBytes(“UTF-8”);
3.CopyOnWriteArrayList
/一般来说,我们会认为:CopyOnWriteArrayList是同步List的替代品,CopyOnWriteArraySet是同步Set的替代品。
无论是Hashtable–>ConcurrentHashMap,还是说Vector–>CopyOnWriteArrayList。JUC下支持并发的容器与老一代的线程安全类相比,总结起来就是加锁粒度的问题
Hashtable、Vector加锁的力度大(直接在方法声明处使用synchronized)
ConcurrentHashMap、CopyOnWriteArrayList加锁力度小(用各种的方式来实现线程安全,比如我们知道的ConcurrentHashMap用了cas锁、volatile等方式来实现线程安全…)
JUC下的线程安全容器在遍历的时候不会抛出ConcurrentModificationException异常
所以一般来说,我们都会使用JUC包下给我们提供的线程安全容器,而不是使用老一代的线程安全容器。
/

        原理:如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,
    系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。优点是如果调用者没有修改该资源,就不会有副本(private copy)
    被建立,因此多个调用者只是读取操作时可以共享同一份资源。
        缺点:   a.内存占用:如果CopyOnWriteArrayList经常要增删改里面的数据,经常要执行add()、set()、remove()的话,那是比较耗费内存的。
    因为每次add()、set()、remove()这些增删改操作都要复制一个数组出来。
                b.数据一致性:CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。

4.ReadWriteLock读写锁的使用:(用于实现读与读之间不互斥,写与写之间互斥,而不是synchronized的暴力锁法)
特性: 4.1.获取锁顺序: a.非公平性:当以非公平初始化时,读锁和写锁的获取的顺序是不确定的。非公平锁主张竞争获取,可能会延缓一个或多个读或写线程,但是会比公平锁有更高的吞吐量。(可设置)
b.当以公平模式初始化时,线程将会以队列的顺序获取锁。当当前线程释放锁后,等待时间最长的写锁线程就会被分配写锁;或者有一组读线程组等待时间比写线程长,
那么这组读线程组将会被分配读锁。
4.2.可重入
//锁升级:从读锁变成写锁
//锁降级:从写锁变成读锁
4.3.锁降级
ReadWriteLock 不支持锁升级,
ReentrantReadWriteLock支持锁降级,从写锁降级成读锁式 并不会自动释放当前线程获取的写锁,仍然需要显式的释放,否则别的线程永远也获取不到写锁。
5.hashmap用链地址法解决了hash冲突
hash冲突的几种解决方案:
a.开放定址法:提供一个增量当发生冲突时(线性探测再散列、平方探测再散列、随机探测再散列)
b.链地址法:提供一个链表
c.再哈希:反复计算哈希值,直到冲突不再产生,这样不易产生聚集区,但会增加计算时间
d.建立公共溢出区:将hash表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表
6.以下是java concurrent包下的4个类,选出差别最大的一个
Semaphore 就像是一个许可证发放者,也想一个数据库连接池。证就这么多,如果池中的证没换回来,其他人就不能用。
ReentrantLock ReentrantLock 和 synchronized一样,用于锁定线程。
Future ✔ Future表示获取一个正在指定的线程的结果。对该线程有取消和判断是否执行完毕等操作。
CountDownLatch 是个锁存器,他表示我要占用给定的多少个线程且我优先执行,我执行完之前其他要使用该资源的都要等待。
原因:a、它是个接口,其他都是类
b、别的类都处理线程间的关系,处理并发机制,但该类只用于获取线程结果。
7.请解释sleep()与wait()的区别:
1. sleep()是Thread类中定义的方法,到了一定的时间后该线程自动唤醒,不会释放对象锁。
2. wait()是Object类中定义的方法,要想唤醒必须使用notify()、notifyAll()方法才能唤醒,会释放对象锁
8.ConcurrentLinkedQueue
一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部是队列中时间最长的元素。队列的尾部是队列中时间最短的元素。
新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使用 null 元素。
add();跟offer();完全相同
9.抽象类和接口中成员或方法访问权限
关于抽象类中成员访问权限,其基本上继承了类的特性,但由于抽象类之所以为抽象类,是因为它是作为父类来使用的,是等待子类去实现的,
而类中 private的权限只能是自个访问自个,所以在抽象类中方法为abstract时只有public,protected,default三种访问权限。
而接口中所有成员的属性都为public static final,即接口中的属性自动默认为 pubic static final,也就是说接口中声明的变量都是常量,不能被继承
接口中所有方法的访问属性为public, 即接口中的方法自动默认为 public,所以实现接口中的方法必须标识为public 或者 abstract,否则编译出错。在JAVA 8 或者更高的版本中的可以使用default
10.Java语言使用的是Unicode字符集。而ASCII是国际上使用最广泛的字符编码;BCD是一种数字压缩存储编码方法。
11.java的GC回收是完全自动的,没有提供相关api手动回收,所有的内存分配和回收权限都在jvm,在开发人员手里没有绝对的强制垃圾回收的方法,不过可以这样去做:
a. 对于不再引用的对象,及时把它的引用赋为null。 obj = null;
b. 如果内存确实很紧张,调用System.gc() 方法来建议垃圾回收器开始回收垃圾,通知GC运行,但是Java语言规范并不保证GC一定会执行。
12.JUnit是一个Java语言的单元测试框架,有程序员自测,就是所谓的白盒测试,主要四个方向 a、用于测试期望结果的断言(Assertion) b、用于共享共同测试数据的测试工具
c、用于方便的组织和运行测试的测试套件 4、图形和文本的测试运行器
13.Integer、new Integer() 和 int 的比较(==)
a、两个 new Integer() 变量比较 ,永远是 false
因为new生成的是两个对象,其内存地址不同
b、Integer变量 和 new Integer() 变量比较 ,永远为 false。
因为 Integer变量 指向的是 java 常量池 中的对象,
而 new Integer() 的变量指向 堆中 新建的对象,两者在内存中的地址不同。
c、两个Integer 变量比较,如果两个变量的值在区间-128到127 之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为 false 。
d、 int 变量 与 Integer、 new Integer() 比较时,只要两个的值是相等,则为true
因为包装类Integer 和 基本数据类型int 比较时,java会自动拆包装为int ,然后进行比较,实际上就变为两个int变量的比较。
e、 Integer.equal(int);因为Integer重写了equal方法,只要值相等,依然返回ture
14.结构型模式中最体现扩展性的模式是(装饰模式)
15.堆区:只存放类对象,线程共享;
方法区:又叫静态存储区,存放class文件和静态数据,线程共享;
栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;
16.
public class Test {
public static void main(String[] args) {
Object o = new Object() {
public boolean equals(Object obj) {
return true;
}
};
System.out.println(o.equals(“Fred”));
}
} ***重写了Object的equals方法,故返回true;
17.下列关于容器集合类的说法正确的是?
LinkedList继承自List-----------linkedlist类是实现了List接口,而不是继承
AbstractSet继承自Set-----------AbstractSet类实现Set接口
HashSet继承自AbstractSet-------HashSet继承 AbstractSet类,同时也实现set
WeakMap继承自HashMap-----------WeakMap(JS)

18.接口中变量默认类型是:public static final;
19.关于形参:
a.形式参数可被视为local variable。形参和局部变量一样都不能离开方法。都只有在方法内才会发生作用,也只有在方法中使用,不会在方法外可见
b.对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。
不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。 一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,
这个参数或局部变量应该是final。
20.DateFormat这个接口的实现类都是不安全的。
21.返回结果类型不一样,parseInt方法返回的是int基本类型,valueOf方法返回的是Integer的包装类型
valueOf方法实际上是调用了parseInt方法,也就是说,如果我们仅仅只需要得到字符串类型字符数值对应的整数数值,
那我们大可不必调用valueOf,因为这样得到整形数值之后还要做一个装箱的操作,将int封装为Integer。
22.以o开头表示8进制,以0x开头表示16进制
23. a. 初始化父类中的静态成员变量和静态代码块 ;
b. 初始化子类中的静态成员变量和静态代码块 ;
c.初始化父类的普通成员变量和代码块,再执行父类的构造方法;
d.初始化子类的普通成员变量和代码块,再执行子类的构造方法;
24.递归程序的优化方式一般为-------------尾递归优化
25.找前K个大或者小的数-------用堆排
26.DNS:域名解析
FTP:文件传输
www:信息查询(WWW 是一种建立在 Internet 上的全球性的、交互的、动态的、多平台的、分布式的,超文本超媒体信息查询系统,也是建立在 Internet 上的一种网络服务)
ADSL:非对称数字用户线路,数据传输
27.传输层的数据叫段 网络层叫包 数据链路层叫帧 物理层叫比特流
28.采用递归方式对顺序表进行快速排序,下列关于递归次数的叙述:
递归次数,取决于递归树,而递归树取决于轴枢的选择。树越平衡,递归次数越少。
而对分区的长短处理顺序,影响的是递归时对栈的使用内存,而不是递归次数(先处理短的可以减少递归占用的内存空间)
29.已知某个哈希表的n个关键字具有相同的哈希值,如果使用二次探测再散列法将这n个关键字存入哈希表,至少要进行n(n+1)/2次探测。

你可能感兴趣的:(Java学习)