上篇整理了下後面準備更系統化寫的Java編程進階的思路,若是僅看裏面的詞,不少同窗會以爲都懂,但我真心以爲沒有多少人是真懂的,因此簡單的想了一些題目,感興趣的同窗們能夠來作作看,看看本身的Java編程水平怎麼樣。java
懶得去作小程序了,因此你們就直接回復你的答案吧,我會來一一點評下,友情提醒下,有些題目有點坑。數據庫
基於BIO實現的Server端,當創建了100個鏈接時,會有多少個線程?若是基於NIO,又會是多少個線程? 爲何?編程
一般來講基於NIO實現的Server端,會用多少個線程去處理IO事件,爲何?小程序
一個典型的客戶端集羣->LB->服務端集羣這樣的結構中,如客戶端採用鏈接池,長鏈接的方式,這種設計你以爲可能會出現什麼問題?若是客戶端採用的是單個長鏈接的方式呢?若是有問題,你以爲應該怎麼解決?數組
cglib和Java的動態代理相比,具體有什麼不一樣?緩存
在基於Netty實現FrameDecoder時,下面兩種代碼的表現會有什麼不一樣?服務器
第一種併發
private void callDecode(...) {less
List<Object> results = new ArrayList<Object>();高併發
while (cumulation.readable()) {
int oldReaderIndex = cumulation.readerIndex();
Object frame = decode(context, channel, cumulation);
if (frame == null) {
if (oldReaderIndex == cumulation.readerIndex())
break;
else
continue;
}
else if (oldReaderIndex == cumulation.readerIndex()) {
throw new IllegalStateException( ".....");
}
results.add(frame);
}
if(results.size() > 0)
fireMessageReceived(context, remoteAddress, results);
}
第二種
private void callDecode(...) {
int oldReaderIndex = cumulation.readerIndex();
Object frame = decode(context, channel, cumulation);
if (frame != null)
fireMessageReceived(context, remoteAddress, frame);
}
用Executors.newCachedThreadPool建立的線程池,在運行的過程當中有可能產生的風險是?
new ThreadPoolExecutor(10,100,10,TimeUnit.MILLISECONDS,new LinkedBlockingQueue(10));一個這樣建立的線程池,當已經有10個任務在運行時,第11個任務提交到此線程池執行的時候會發生什麼,爲何?
實現一個自定義的ThreadFactory的做用一般是?
除了用Object.wait和Object.notifyAll來實現線程間的交互外,你還會經常使用哪些來實現?
爲何ConcurrentHashMap能夠在高併發的狀況下比HashMap更爲高效?
AtomicInteger、AtomicBoolean這些類之因此在高併發時高效,共同的緣由是?
請合理的使用Queue來實現一個高併發的生產/消費的場景,給些核心的代碼片斷。
請實現讓10個任務同時併發啓動,給些代碼片斷。
在Java程序運行階段,能夠用什麼命令行工具來查看當前Java程序的一些啓動參數值,例如Heap Size等。
用什麼命令行工具能夠查看運行的Java程序的GC情況,請具體寫出命令行格式。
用什麼工具,能夠在Java程序運行的狀況下跟蹤某個方法的執行時間,請求參數信息等,並請解釋下工具實現的原理。
當一個Java程序接收請求,很長時間都沒響應的話,一般你會怎麼去排查這種問題?
Java進程忽然消失了,你會怎麼去排查這種問題?
如下這段代碼思路,你以爲在運行時可能會產生的風險是,應該如何改進?
public List<User> getUsers(String[] userIds){
// 從數據庫查找符合userIds的user記錄
// 將返回的記錄組裝爲User對象,放入List並返回
}
如下兩種代碼,在運行時有什麼不一樣?爲何?
第一種
private static final boolean isLoggerDebugEnabled = log.isDebugEnabled();
public void xx(User user){
if(isLoggerDebugEnabled){
log.debug("enter xx method, user id is: " + user.getId());
}
}
第二種
public void xx(User user){
log.debug("enter xx method, user id is: " + user.getId());
}
Java程序爲何一般在剛啓動的時候會執行的比較慢,而處理了一些請求後會變快,AOT能帶來什麼幫助?
Parallel GC、CMS GC、ZGC、Azul Pauseless GC最主要的不一樣是?背後的原理也請簡單描述下?
請寫一段程序,讓其運行時的表現爲觸發5次ygc,而後3次fgc,而後3次ygc,而後1次fgc,請給出代碼以及啓動參數。
Go的Coroutine和Java的線程機制最主要的不一樣是?若是Java語言要透明的實現Coroutine,你以爲主要的難點是?
一、BIO 有100個線程。BIO面向鏈接,一個鏈接一個線程,直接從流stream裏讀寫。
NIO 能夠只有1個處理線程。NIO面向緩衝區,讀寫操做的是緩衝區(buffer)。一個鏈接對應一個channel,不會直接從channel讀寫,數據都是經過緩衝區處理。
NIO有Selector,經過while循環檢查或系統調用通知,檢查多個channel的狀態是否可讀寫,因此能夠用單線程管理多個channel。
Java IO與NIO:https://juejin.im/post/5af79bcc51882542ad771546
Java NIO 之 Channel(通道):https://juejin.im/post/5af7f01b6fb9a07a9f01a339
二、2*cpu核數 左右
三、長鏈接創建後通常不會斷開,也就是某個client會固定請求到某臺server,隨着擴容縮容、服務器上下線,會負載不均衡。
解決方法:
A、重啓負載高的服務器
B、用短鏈接
C、不用LB
四、CGLIB經過字節碼操做生成代理,能對類作代理。
JDK經過反射接口生成代理,因此被代理類必須有實現接口。
五、X
六、使用SynchronousQueue隊列,不會緩存請求,可能致使線程數暴漲。
七、放到阻塞隊列裏
八、命名線程
九、阻塞隊列、
十、ConcurrentHashMap 用分段鎖,鎖粒度更小
十一、使用CAS指令實現原子操做,不須要加鎖
十二、阻塞隊列
1三、略
1四、ps -ef | grep java
1五、jstat -gc pid 5000
1六、btrace、Arthas(只用過一次)
1七、先看線程
1八、查看操做系統/var/log/dmesg日誌,一般是OOM致使被OS殺掉進程
1九、userIds數組過程,致使處理時間變成,消耗完全部IO線程,服務能力降爲0。
措施:限制長度
20、第二種運行時會拼接字符串,對性能有影響
2一、剛啓動是解釋執行還要佔用資源並採樣鏡像JTT編譯,AOP在啓動後提供最搞笑運行代碼
2二、略
2三、略
2四、X