1.为什么字符串使用final关键字
主要目的就是保证String是不可变(immutable)。不可变就是第二次给一个String 变量赋值的时候,不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。
String类的主力成员字段value是个char[]数组,而且是用final修饰的。编译器不允许把value指向另一个地址。但可以直接对数组元素修改。为了保证这个数组元素不能修改,做了如下措施:
(1)所有String的方法里很小心的没有去动数组里的元素,没有暴露内部成员字段。
(2)避免被其他人继承后破坏,整个String设成final禁止继承。如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象。
安全性:
String被广泛用作许多java类的参数,例如网络连接、打开文件等。如果对string的某一处改变一不小心就影响了该变量所有引用的表现,则连接或文件将被更改,这可能导致严重的安全威胁。 不可变对象不能被写,所以不可变对象自然是线程安全的,因为不可变对象不能更改,它们可以在多个线程之间自由共享。
2.=这三种的区别和联系:
final
finally
finalize() 在jdk9之后过时了
1.final是一个关键字,如果我们用final来修饰属性的话,属性不可以改变,所以被final修饰的属性必须在声明的时候设置一个初始值,在之后需要用到的地方只能读取该值,不能对该属性做出改变,final修饰方法的话,方法可以被使用,但是不能被重写,final修饰类的话,类不能被继承,也就是说该类不能有子类,所以我们不能final来修饰一个抽象类。
2.finally是java的异常处理机制,我们经常会将finally语句放在try...catch...语句后面作为一种补充,因为finally语句不管代码有没有异常都会执行,这样我们可以用finally语句维护对象内部状态,清理非内存操作,例如我们可以使用finally语句来关闭流或者数据库等操作。
3.finallize方法是java.lang.Object里面定义的,因为Object是所有类的基类,所以我们可以理解为每个对象都有finalize方法,finalize的主要目的是在不可撤销的丢弃对象之前执行清除操作,对于给定的任何对象,java虚拟机最多只调用一次finalize()方法,finalize()方法是垃圾回收器删除对象之前对这个对象调用的。
3.java中字符串常量池在什么地方?
1:字符串常量池在Java内存区域的哪个位置?
在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
在JDK7.0版本,字符串常量池被移到了堆中
4.面试题:
String s = " In all the parting, I like it best see you tomorrow.Of all the blessings I prefer, as you wish. Sometimes you look at the wrong person, not because you are jealous, but because you are kind.
You never know how strong you really are until being strong is the only choice you have. Never bend your head. Always hold it high. Look the world straight in the face.The twentieth meeting you used to spend al my luck.Reading is a happy thing. For those who love reading, once they read it,
they can't stop, they can't give up reading, they want to read to the
ends of the world. Some people say: "the deepest and most peaceful
happiness Calm down, open the book, the deposition
of ink a little bit over the space, those dusty happiness a little bit
open. Reading is really fun.I became a searcher,wanting to find out who I was and what made me unique. My view of myself was changing. I wanted a solid base to start from. I started to resist3 pressure to act in ways that I didn’t like any more,and I was delighted by who I really was. I came to feel much more sure that no one can ever take my place.
Each of us holds a unique place in the world. You are special,no matter what others say or what you may think. So forget about being replaced. You can’t be. "
给定如上字符串,统计每个单词出现的次数
5.synchronized和Lock锁的区别(总结作业):
用法区别:
synchronized:在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。
lock:一般使用ReentrantLock类做为锁。在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。
性能区别:
synchronized是托管给JVM执行的, 而lock是java写的控制锁的代码
在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。
但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。
用途区别
synchronized原语和ReentrantLock在一般情况下没有什么区别,但是在非常复杂的同步应用中,请考虑使用ReentrantLock,特别是遇到下面几种种需求的时候。
1.某个线程在等待一个锁的控制权的这段时间需要中断
2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
3.具有公平锁功能,每个到来的线程都将排队等候
总结:
--synchronized和ReentrantLock的异同
--ReentrantLock支持非阻塞的方式获取锁,能够响应中断,而synchronized不行
--ReentrantLock必须手动获取和释放锁,而synchronized不需要
--ReentrantLock可以是公平锁或者非公平锁,而synchronized只能是非公平锁
--synchronized在发生异常的时候,会自动释放线程占有的锁,而ReentrantLock在发生异常时,如果没有通过unlock去释放锁,很有可能造成死锁,因此需要在finally块中释放锁
--synchronized和ReentrantLock都是可重入锁