1. 程式人生 > >面試題整理 有經驗自己的語言

面試題整理 有經驗自己的語言

改進 IV spec block tail 連續 的人 prim 排序

4、談談你對JVM的理解?

答: Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一特點的關鍵。Java編譯器只要面向JVM,生成JVM能理解的代碼或字節碼文件。Java源文件經編譯成字節碼程序,通過JVM將每一條指令翻譯成不同平臺機器碼,通過特定平臺運行。

JVM執行程序的過程 :I.加載。class文件 ,II.管理並分配內存 ,III.執行垃圾收集

JRE(java運行時環境)由JVM構造的java程序的運行環境

1、SpringMVC的原理以及返回數據如何渲染到jsp/html上?

答:Spring MVC的核心就是 DispatcherServlet , 一個請求經過 DispatcherServlet ,轉發給HandlerMapping ,然後經反射,對應 Controller及其裏面方法的@RequestMapping地址,最後經ModelAndView和ViewResoler返回給對應視圖

2、一個類對象屬性發生改變時,如何讓調用者知道?

答:Java event時間監聽 ,即在set方法改變屬性時,觸發 ,這種模式也可以理解為觀察者模式,具體查看:觀察者模式簡單案例和說明


IO NIO
面向流 面向緩沖
阻塞IO 非阻塞IO
無 選擇器

Java NIO和IO的區別

面向流與面向緩沖

Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩沖區的。 Java IO面向流意味著每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩沖區。 Java NIO的緩沖導向方法略有不同。數據讀取到一個它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩沖區時,不要覆蓋緩沖區裏尚未處理的數據。

紅黑樹, 二叉樹

https://blog.csdn.net/yang_yulei/article/details/26066409

索引的工作原理

為什麽需要索引(Why is it needed)?

當數據保存在磁盤類存儲介質上時,它是作為數據塊存放。這些數據塊是被當作一個整體來訪問的,這樣可以保證操作的原子性。硬盤數據塊存儲結構類似於鏈表,都包含數據部分,以及一個指向下一個節點(或數據塊)的指針,不需要連續存儲。

記錄集只能在某個關鍵字段上進行排序,所以如果需要在一個無序字段上進行搜索,就要執行一個線性搜索(Linear Search)的過程,平均需要訪問N/2的數據塊,N是表所占據的數據塊數目。如果這個字段是一個非主鍵字段(也就是說,不包含唯一的訪問入口),那麽需要在N個數據塊上搜索整個表格空間。

但是對於一個有序字段,可以運用二分查找(Binary Search),這樣只要訪問log2 (N)的數據塊。這就是為什麽性能能得到本質上的提高。

什麽是索引(What is indexing)?

索引是對記錄集的多個字段進行排序的方法。在一張表中為一個字段創建一個索引,將創建另外一個數據結構,包含字段數值以及指向相關記錄的指針,然後對這個索引結構進行排序,允許在該數據上進行二分法排序。

副作用是索引需要額外的磁盤空間,對於MyISAM引擎而言,這些索引是被統一保存在一張表中的,這個文件將很快到達底層文件系統所能夠支持的大小限制,如果很多字段都建立了索引的話。

索引如何工作(How does it work?)

首先,我們建立一個示範數據庫表:

字段名 數據類型 大小
id (Primary key) Unsigned INT 4 bytes
firstName Char(50) 50 bytes
lastName Char(50) 50 bytes
emailAddress Char(100) 100 bytes
註意:使用char是為了指定準確的磁盤占用大小。這個示範數據庫包含500萬行,而且沒有索引。我們將分析一些查詢語句的性能,一個是使用主鍵id(有序)查詢,一個是使用firstName(非關鍵無序字段)。

例1

我們的示範數據庫有r=5,000,000條記錄,每條記錄長度R=204字節而且使用MyISAM引擎存儲(默認數據塊大小為B=1024字節),這張表的塊因子(blocking factor)會是bfr = (B/R) = 1024/204 = 5 條記錄每磁盤數據塊。保存這張表所需要的磁盤塊為N = (r/bfr) = 5000000/5 = 1,000,000 blocks。

在id字段上的線性搜索平均需要N/2 = 500,000塊訪問來找到一條記錄假設id字段是查詢關鍵值,不過既然id字段是有序的,可以執行一個二分查詢,這樣平均只需要訪問log2 (1000000) = 19.93 = 20 個數據塊。我們馬上就看到了極大的提高。

現在firstName字段既不是有序的,無法執行二分搜索,數值也不具有唯一性,所以對這張表的查找必須到最後一個記錄即全表掃描N = 1,000,000個數據塊訪問。這就是索引用來改進的地方。

假如索引記錄只包含一個索引列以及一個指向原記錄數據的指針,那麽它顯而易見會比原記錄(多列)要小。所以索引本身所需要的磁盤塊要更少,掃描數目也少。firstName索引表結構如下:

Field name Data type Size on disk
firstName Char(50) 50 bytes
(record pointer) Special 4 bytes
註意: MySQL裏的指針按表大小的不同分別可能是 2, 3, 4 或 5 個字節。

例2

假設我們的數據庫有r = 5,000,000 條記錄,建立了一個長R = 54字節的索引,並且使用默認磁盤塊大小為1,024字節。那麽該索引的塊因子為bfr = (B/R) = 1024/54 = 18 條記錄每磁盤塊。容納這個索引表總共需要的磁盤塊為N = (r/bfr) = 5000000/18 = 277,778 塊。

現在使用FirstName字段來進行搜索就可以利用索引來提高性能。這允許使用一個二分查找,平均log2 (277778) = 18.08 -> 19次數據塊訪問。找到實際記錄的地址,這需要進一步的塊讀取,這樣總數達到19 + 1 = 20次數據塊訪問,這和非索引表的數據塊訪問次數有天壤之別。

什麽時候使用索引(When should it be used?)

鑒於創建索引需要額外的磁盤空間(上面的例子需要額外的277778個磁盤塊),以及太多的索引會導致文件系統大小限制所產生的問題,所以對哪些字段建立索引,什麽情況下使用索引,需要審慎考慮。

由於索引只是用來加速數據查詢,那麽顯然對只是用來輸出的字段建立索引會浪費磁盤空間以及發生插入、刪除操作時的處理時間,所以這種情況下應該盡量避免。此外鑒於二分搜索的特性,數據的基數或獨立性是很重要的。在基數為2的字段上建立索引,將把數據分割一半,而基數為1000則將返回大約1000條記錄。低基數的二分查找效率將降低為一個線性排序,而且查詢優化器可能會在基數小於記錄數某個比例時(如30%)的情況下將避免使用索引而直接查詢原表,所以這種情況下的索引浪費了空間。

面向流與面向緩沖

Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩沖區的。 Java IO面向流意味著每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩沖區。 Java NIO的緩沖導向方法略有不同。數據讀取到一個它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩沖區時,不要覆蓋緩沖區裏尚未處理的數據。

紅黑樹, 二叉樹

https://blog.csdn.net/yang_yulei/article/details/26066409

索引的工作原理

為什麽需要索引(Why is it needed)?

當數據保存在磁盤類存儲介質上時,它是作為數據塊存放。這些數據塊是被當作一個整體來訪問的,這樣可以保證操作的原子性。硬盤數據塊存儲結構類似於鏈表,都包含數據部分,以及一個指向下一個節點(或數據塊)的指針,不需要連續存儲。

記錄集只能在某個關鍵字段上進行排序,所以如果需要在一個無序字段上進行搜索,就要執行一個線性搜索(Linear Search)的過程,平均需要訪問N/2的數據塊,N是表所占據的數據塊數目。如果這個字段是一個非主鍵字段(也就是說,不包含唯一的訪問入口),那麽需要在N個數據塊上搜索整個表格空間。

但是對於一個有序字段,可以運用二分查找(Binary Search),這樣只要訪問log2 (N)的數據塊。這就是為什麽性能能得到本質上的提高。

什麽是索引(What is indexing)?

索引是對記錄集的多個字段進行排序的方法。在一張表中為一個字段創建一個索引,將創建另外一個數據結構,包含字段數值以及指向相關記錄的指針,然後對這個索引結構進行排序,允許在該數據上進行二分法排序。

副作用是索引需要額外的磁盤空間,對於MyISAM引擎而言,這些索引是被統一保存在一張表中的,這個文件將很快到達底層文件系統所能夠支持的大小限制,如果很多字段都建立了索引的話。

索引如何工作(How does it work?)

首先,我們建立一個示範數據庫表:

字段名 數據類型 大小
id (Primary key) Unsigned INT 4 bytes
firstName Char(50) 50 bytes
lastName Char(50) 50 bytes
emailAddress Char(100) 100 bytes
註意:使用char是為了指定準確的磁盤占用大小。這個示範數據庫包含500萬行,而且沒有索引。我們將分析一些查詢語句的性能,一個是使用主鍵id(有序)查詢,一個是使用firstName(非關鍵無序字段)。

例1

我們的示範數據庫有r=5,000,000條記錄,每條記錄長度R=204字節而且使用MyISAM引擎存儲(默認數據塊大小為B=1024字節),這張表的塊因子(blocking factor)會是bfr = (B/R) = 1024/204 = 5 條記錄每磁盤數據塊。保存這張表所需要的磁盤塊為N = (r/bfr) = 5000000/5 = 1,000,000 blocks。

在id字段上的線性搜索平均需要N/2 = 500,000塊訪問來找到一條記錄假設id字段是查詢關鍵值,不過既然id字段是有序的,可以執行一個二分查詢,這樣平均只需要訪問log2 (1000000) = 19.93 = 20 個數據塊。我們馬上就看到了極大的提高。

現在firstName字段既不是有序的,無法執行二分搜索,數值也不具有唯一性,所以對這張表的查找必須到最後一個記錄即全表掃描N = 1,000,000個數據塊訪問。這就是索引用來改進的地方。

假如索引記錄只包含一個索引列以及一個指向原記錄數據的指針,那麽它顯而易見會比原記錄(多列)要小。所以索引本身所需要的磁盤塊要更少,掃描數目也少。firstName索引表結構如下:

Field name Data type Size on disk
firstName Char(50) 50 bytes
(record pointer) Special 4 bytes
註意: MySQL裏的指針按表大小的不同分別可能是 2, 3, 4 或 5 個字節。

例2

假設我們的數據庫有r = 5,000,000 條記錄,建立了一個長R = 54字節的索引,並且使用默認磁盤塊大小為1,024字節。那麽該索引的塊因子為bfr = (B/R) = 1024/54 = 18 條記錄每磁盤塊。容納這個索引表總共需要的磁盤塊為N = (r/bfr) = 5000000/18 = 277,778 塊。

現在使用FirstName字段來進行搜索就可以利用索引來提高性能。這允許使用一個二分查找,平均log2 (277778) = 18.08 -> 19次數據塊訪問。找到實際記錄的地址,這需要進一步的塊讀取,這樣總數達到19 + 1 = 20次數據塊訪問,這和非索引表的數據塊訪問次數有天壤之別。

什麽時候使用索引(When should it be used?)

鑒於創建索引需要額外的磁盤空間(上面的例子需要額外的277778個磁盤塊),以及太多的索引會導致文件系統大小限制所產生的問題,所以對哪些字段建立索引,什麽情況下使用索引,需要審慎考慮。

由於索引只是用來加速數據查詢,那麽顯然對只是用來輸出的字段建立索引會浪費磁盤空間以及發生插入、刪除操作時的處理時間,所以這種情況下應該盡量避免。此外鑒於二分搜索的特性,數據的基數或獨立性是很重要的。在基數為2的字段上建立索引,將把數據分割一半,而基數為1000則將返回大約1000條記錄。低基數的二分查找效率將降低為一個線性排序,而且查詢優化器可能會在基數小於記錄數某個比例時(如30%)的情況下將避免使用索引而直接查詢原表,所以這種情況下的索引浪費了空間。

Java序列化機制和原理

serialVersionUID值的重要作用 根據上面的分析,可以發現如果一個類可序列化,serialVersionUID建議給一個確定的值,不要由系統自動生成,否則在增減字段(不能修改字段類型及長度)時,如果兩邊的類的版本不同會導致反序列化失敗. 3、項目中為何要用緩存?如何理解nginx + tomcat + redis 集群緩存?
答1:最直接的表現就是減輕數據庫的壓力。避免因為數據讀取頻繁或過大而影響數據庫性能,降低程序宕機的可能性
答2:nginx常用做靜態內容服務和代理服務器,直面外來請求轉發給後面的應用服務。nginx本身也能做緩存,比如靜態頁面的緩存什麽的。而tomcat是應用服務器,處理JAVA WEB程序功能等等 。你也可以這麽理解,假設把用戶的請求當做是一條河流,那麽nginx就相當於一個水利工程,tomcat相當於一條條分流的支流,而redis 相當於支流旁邊的一個個水庫。 當你洪水來了,nginx根據你每條支流的承受力度分發不同的水流量,在確保程序正常運行的情況下,分發給每條支流(tomcat)不同的水流量。而redis相當於一個個支流的水庫,存儲水源,降低壓力,讓後面的水量平穩。

談談你對分布式的理解

答:個人理解:分布式就是把一個系統/業務 拆分成多個子系統/子業務 去協同處理,這個過程就叫分布式,

redis實現消息隊列 比ActiveMQ要輕量

https://blog.csdn.net/jacman/article/details/51246449

java實戰開發經驗 播客分享 問答形式

https://ask.csdn.net/subjects/16?page=11

JVM和JC

說到GC,記住兩點:1、GC是負責回收所有無任何引用對象的內存空間。 註意:垃圾回收回收的是無任何引用的對象占據的內存空間而不是對象本身,2、GC回收機制的兩種算法,a、引用計數法 b、可達性分析算法( 這裏的可達性,大家可以看基礎2 Java對象的什麽周期),至於更詳細的GC算法介紹,大家可

4、當數據表中A、B字段做了組合索引,那麽單獨使用A或單獨使用B會有索引效果嗎?(使用like查詢如何有索引效果)

答:看A、B兩字段做組合索引的時候,誰在前面,誰在後面,如果A在前,那麽單獨使用A會有索引效果,單獨使用B則沒有,反之亦然。同理,使用like模糊查詢時,如果只是使用前面%,那麽有索引效果,如果使用雙%號匹配,那麽則無索引效果

Object類的一些方法

protected Object   clone()創建並返回此對象的一個副本。   
boolean equals(Object obj)指示其他某個對象是否與此對象“相等”。
protected void finalize()當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。
Class<?> getClass()返回此 Object 的運行時類。
int hashCode()返回該對象的哈希碼值。
void notify()喚醒在此對象監視器上等待的單個線程。
void notifyAll()喚醒在此對象監視器上等待的所有線程。
String toString()返回該對象的字符串表示。
void wait()在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待。
void wait(long timeout)在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量前,導致當前線程等待。
void wait(long timeout, int nanos)在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量前,導致當前線程等待。


5、一條sql執行過長的時間,你如何優化,從哪些方面?

答:1、查看sql是否涉及多表的聯表或者子查詢,如果有,看是否能進行業務拆分,相關字段冗余或者合並成臨時表(業務和算法的優化)
2、涉及鏈表的查詢,是否能進行分表查詢,單表查詢之後的結果進行字段整合
3、如果以上兩種都不能操作,非要鏈表查詢,那麽考慮對相對應的查詢條件做索引。加快查詢速度
4、針對數量大的表進行歷史表分離(如交易流水表)
5、數據庫主從分離,讀寫分離,降低讀寫針對同一表同時的壓力,至於主從同步,mysql有自帶的binlog實現 主從同步

6、explain分析sql語句,查看執行計劃,分析索引是否用上,分析掃描行數等等

7、查看mysql執行日誌,看看是否有其他方面的問題

個人理解:從根本上來說,查詢慢是占用mysql內存比較多,那麽可以從這方面去酌手考慮

設計模式有什麽用?

個人觀點

作為設計模式的忠實粉絲和推廣人員,在正式學習設計模式之前,我結合多年的模式應用和教育培訓經驗與大家分享幾點個人的看法,以作參考:

(1) 掌握設計模式並不是件很難的事情,關鍵在於多思考,多實踐,不要聽到人家說懂幾個設計模式就很“牛”,只要用心學習,設計模式也就那麽回事,你也可以很“牛”的,一定要有信心。

(2) 在學習每一個設計模式時至少應該掌握如下幾點:這個設計模式的意圖是什麽,它要解決一個什麽問題,什麽時候可以使用它;它是如何解決的,掌握它的結構圖,記住它的關鍵代碼;能夠想到至少兩個它的應用實例,一個生活中的,一個軟件中的;這個模式的優缺點是什麽,在使用時要註意什麽。當你能夠回答上述所有問題時,恭喜你,你了解一個設計模式了,至於掌握它,那就在開發中去使用吧,用多了你自然就掌握了。

(3) “如果想體驗一下運用模式的感覺,那麽最好的方法就是運用它們”。正如在本章最開始所說的,設計模式是“內功心法”,它還是要與“實戰招式”相結合才能夠相得益彰。學習設計模式的目的在於應用,如果不懂如何使用一個設計模式,而只是學過,能夠說出它的用途,繪制它的結構,充其量也只能說你了解這個模式,嚴格一點說:不會在開發中靈活運用一個模式基本上等於沒學。所以一定要做到:少說多做。

(4) 千萬不要濫用模式,不要試圖在一個系統中用上所有的模式,也許有這樣的系統,但至少目前我沒有碰到過。每個模式都有自己的適用場景,不能為了使用模式而使用模式?【怎麽理解,大家自己思考,技術分享圖片】,濫用模式不如不用模式,因為濫用的結果得不到“藝術品”一樣的軟件,很有可能是一堆垃圾代碼。

(5) 如果將設計模式比喻成“三十六計”,那麽每一個模式都是一種計策,它為解決某一類問題而誕生,不管這個設計模式的難度如何,使用頻率高不高,我建議大家都應該好好學學,多學一個模式也就意味著你多了“一計”,說不定什麽時候一不小心就用上了,技術分享圖片。因此,模式學習之路上要不怕困難,勇於挑戰,有的模式雖然難一點,但反復琢磨,反復研讀,應該還是能夠征服的。

(6) 設計模式的“上乘”境界:“手中無模式,心中有模式”。模式使用的最高境界是你已經不知道具體某個設計模式的定義和結構了,但你會靈活自如地選擇一種設計方案【其實就是某個設計模式】來解決某個問題,設計模式已經成為你開發技能的一部分,能夠手到擒來,“內功”與“招式”已渾然一體,要達到這個境界並不是看完某本書或者開發一兩個項目就能夠實現的,它需要不斷沈澱與積累,所以,對模式的學習不要急於求成。

(7) 最後一點來自GoF已故成員、我個人最尊敬和崇拜的軟件工程大師之一John Vlissides的著作《設計模式沈思錄》(Pattern Hatching Design Patterns Applied):模式從不保證任何東西,它不能保證你一定能夠做出可復用的軟件,提高你的生產率,更不能保證世界和平,技術分享圖片。模式並不能替代人來完成軟件系統的創造,它們只不過會給那些缺乏經驗但卻具備才能和創造力的人帶來希望。

面試題整理 有經驗自己的語言