原文鏈接 開發者社區> 面試一點通> 正文
【不懂】 16. 用什么工具,可以在Java程序運行的情況下跟蹤某個方法的執行時間,請求參數信息等,並請解釋下工具實現的原理。
btrace,Arthas,主要借助JVM attach agent,ASM以及Instrumentation來動態的替換字節碼,從而實現動態的對程序運行情況的跟蹤。 -- http://www.sohu.com/a/298857998_494946
17. 當一個Java程序接收請求,很長時間都沒響應的話,通常你會怎么去排查這種問題?
- JPS找到對應java進程pid,jstack一把找出運行的線程信息,找出對應的卡點信息
- 或者查看日志,看運行到哪里不動了,嘗試本地復現,bugfix
- 大批量任務而沒有使用異步機制,重點關注相關的同步操作。
18. Java進程突然消失了,你會怎么去排查這種問題?
- 內存里是沒東西的,查看日志信息
- 嘗試本地復現
- 查看操作系統/var/log/dmesg日志,通常是OOM(內存溢出)導致被OS殺掉進程 --https://blog.csdn.net/weixin_33859231/article/details/93757163
- 查看運維系統的一些操作日志
19. 以下這段代碼思路,你覺得在運行時可能會產生的風險是,應該如何改進?
List getUsers(String[] userIds){
// 從數據庫查找符合userIds的user記錄
// 將返回的記錄組裝為User對象,放入List並返回
}
- 很正常啊,沒問題啊!
- 仔細想想,數據量大的話,常見的表會有幾十萬-幾百萬行數據,直接OOM!
- 沒有分頁!這么簡單!
20. 以下兩種代碼,在運行時有什么不同?為什么?
第一種
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());
}
- 貌似還是差不多
- 再看看, isLoggerDebugEnabled 是static,在編譯期會取到結果,上面的代碼可能永遠不會執行一次,當isLoggerDebugEnabled = false的時候,在編譯期會會kill掉
- 下面的代碼不會.
21.Java程序為什么通常在剛啟動的時候會執行的比較慢,而處理了一些請求后會變快,AOT能帶來什么幫助?
- Java程序先慢后快: 剛啟動的時候Java還處於解釋執行階段,處理了一些請求后隨着C1、C2編譯的介入,會優化為機器碼,並且借助各種運行時數據的高級優化,使得Java程序逐漸進入一個高速運行的狀態 [沒想過,這還是Java嗎?]
- AOT (Ahead-Of-Time - 預先編譯,事先生成機器碼,) 詳見https://www.zhihu.com/question/23874627
-JIT:吞吐量高,有運行時性能加成,可以跑得更快,並可以做到動態生成代碼等,但是相對啟動速度較慢,並需要一定時間和調用頻率才能觸發 JIT 的分層機制
- AOT:內存占用低,啟動速度快,可以無需 runtime 運行,直接將 runtime 靜態鏈接至最終的程序中,但是無運行時性能加成,不能根據程序運行情況做進一步的優化