问:
String创建后是否可以修改?为什么?
答:
不可以,从使用角度上说,我们使用String都是从String字符串池中去获取,将String设为
不可以修改便于使用和管理。从源码角度中因为String源码中有char属性value。和int属性的hash,
他们都没有set属性,源码中的修改方法都是直接再new一个字符串。
问:
嗯,很好,既然问道源码,应该是属性中value是被final修饰的,当属性被修饰时是无法修改的。
(面试官可以指出面试人没有说到的部分,这样可以提现出面试官的水准,这样面试人就会对
这个公司的技术水平有个评估,大家都是相互挑选)请问哪有没有一种String的替代类来代替
String,弥补他不可修改的缺点。
答:
你是指StringBuffer,和stringbuilder。这个我不大熟悉。但是我知道这二个都是可以原来
字符串的基础上进行修改。区别在于StringBuffer是线程安全的,Stringbuilder是非线程安全的。
所以Stringbuilder速度较快。Stringbuffer速度较慢。其他的没了。
问:
好的,String可以被继承吗?为什么?
答:
不可以,因为它有修饰词final,final这个词修饰类时这个类是不可以被继承。当修饰方法时
是不可以被覆盖重写。当修饰属性时表明是无法被修改。
问:
你对hashMap有什么了解?HashTable有什么了解?
答:
首先,他不是基于KV键值对的集合类,继承于AbstractMap,实现了Map。可以允许null为他的
key或者value。其次它不是线程安全的,也就是说当出现多线程时他有可能出现错误。默认的Hahmap
的容量是1<<4 == 16.最大容量是1<<30.还有构造函数。初始化容量,加载因子。加载因子是
表示Hsah表中元素的填满的程度。加载因子越大,填满的元素越多,空间利用率越高,但冲突的机会加大。
反之,加载因子越小,填满的元素越少,冲突的机会减小,但空间浪费多了。冲突的机会越大,则查找的
成本越高。反之,查找的成本越小。所以我们一般使用currentHashMap来代替HashMap。因为它
是线程安全的。
HashTable是线程安全的,不可以使用null作为key和value。因为它采用synchronized来确保线程。
所以性能并不高。
问:
好的,既然这样,如果我不用currentHashMap,HashMap如何来保证线程安全。currentHashMap
是如何保证线程安全?
答:
HashMap可以使用迭代器(Iterator)。是fail-fast迭代器。他只能单向移动,这就保证了他
的线程安全。currentHashMap采用锁分段技术增加锁数量。对数据集进行分段。每个分段进行
加锁,不同分段数据不存在锁竞争。对读是不进行加锁的。共享变量都采用volatile关键字修饰,
共享变量在线程之间的可见性。
问:
既然讲到了线程,那你你谈谈多线程吧。
答:
多线程我一般使用synchronized,将某个可能出现多线程的方法或者代码块,一般使用synchronized
(this),或者synchronized(property),前者表名当线程进入此代码块加锁,后者表名进入
此代码块该属性或变量要进行加锁。或者Lock接口下面的各种各样的lock子对象。Lock的子类锁
相对来说颗粒度更西,性能更加好。
synchronized缺点:它无法中断一个正在等候获得锁的线程;也无法通过投票得到锁,如果
不想等下去,也就没法得到锁;同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行。
你可以使用Lock的锁。来代替synchronized。
比如常用的ReentrantReadWriteLock读写锁,当读时相互不排斥,当读和写时互斥。
或者ReentrantLock锁具有synchronized的相同功能,但是还有锁投票、定时锁等候和可中断
锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。。嗯(....词穷)没有了。
问:
好吧,简答问一下你是如何创建一个线程?
答:
有二种方式,一种继承Thread类,一种实现Runnable接口。一般我们实现Runnable接口,因为
继承类的话就办法继承其他父类。我们一般重写run方法,和启动它时使用start方法。
问:
是的,不过我们线程都是从线程池去获得线程,线程池使用过吗?一般使用什么线程池?有多少
配置参数?
答:
我一般使用spring的线程池,ThreadPoolTaskExecutor,只需要继承spring的基础的context的jar,
另外一种java自带的线程池,Java自带的线程池ThreadPoolExecutor。
一般使用spring的线程池。有线程数和最大线程数。队列长度。如果线程池中的线程已经是最大的,
则将后续任务放入队列中。
问:
嗯,好吧。你知道线程池是如何构造的吗?
答:
对不起,源码这块我不是很了解。线程这块主要也不怎么使用,一般我也就是用synchronized
代码块加锁。其他的没怎么使用。
问:
没事,没事,那你了解过io,比如nio?
答:
io,这点我只知道nio是一种非阻塞io。是以一种块的方式处理数据。有一个nio框架neety。
还有dubbo也是基于netty的rpc分布式框架。其他的不大了解。(无语......)
问:
好吧,我们淘宝的业务量其实对高并发和大数量很有要求。基本对java基础多线程和io方面
要求要高。
(ebay面试)你应该对设计模式有些了解。请问你对适配器模式和代理模式的区别。
答:
对于代理模式,其实spring的aop使用的就是代理模式。我的理解就是对原先的类进行加强。
比如代理模式,会在进入代理类前先执行之前的方法。执行代理类的方法后再执行代理的方法。
比如说aop的日志记录,代理类方法前先执行before方法,执行后在执行after方法。没了。
总结:
面试官可以指出面试人没有说到的部分,这样可以提现出面试官的水准,这样面试人就会对这个
公司的技术水平有个评估,大家都是相互挑选。
在我第一面试淘宝工程师,他大多问的一些java基础的知识,关于集合,多线程,IO方面。
在ebay面试时问的基础的知识大多时java的设计模式,尤其spring相关的设计模式,并与其它
设计模式比较。比如他问道spring的ioc的单例模式,和工厂模式,aop的代理模式和适配模式区别。
个人认为在多线程和io方面需要大家多加学习。
在编程的天空上有二片乌云,一个是多线程,一个是IO,分别占领了左半边天,和右半边天。
--斯坦杰克森.雷