Java 工程師成神之路疙挺!

1. 面向對象

什么是面向對象

  • 面向對象與面向過程

始終圍繞如何解決具體問題進行扛邑。面向過程就是分析出解決問題所需要的步驟,然后用函數(shù)把這些步驟一步一步實現(xiàn)铐然,使用的時候一個一個依次調用就可以了蔬崩;
以更形象的方式在計算機中構建現(xiàn)實的事物,更符合人認識世界的習慣搀暑。面向對象是把構成問題事務分解成各個對象沥阳,建立對象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為自点。

  • 面向對象的三大基本特征和五大基本原則

特征:封裝桐罕,繼承,多態(tài)
原則:單一職責原則(SRP) 一個類應該有且只有一個去改變它的理由桂敛,這意味著一個類應該只有一項工作功炮。
開放封閉原則(OCP) 對象或實體應該對擴展開放,對修改封閉术唬。例如私有方法允許重載薪伏,但不允許重寫。
里氏替換原則(LSP) 在對象 x 為類型 T 時 q(x) 成立粗仓,那么當 S 是 T 的子類時毅该,對象 y 為類型 S 時 q(y) 也應成立博秫。(即對父類的調用同樣適用于子類)
依賴倒置原則(DIP) 高層次的模塊不應該依賴于低層次的模塊,他們都應該依賴于抽象眶掌。具體實現(xiàn)應該依賴于抽象挡育,而不是依賴于實現(xiàn)。依賴于實現(xiàn)會使得日后擴展不斷朴爬。例如A依賴于B即寒、C、D的實現(xiàn)不如依賴于BCD共同實現(xiàn)的接口或抽象類召噩。
接口隔離原則(ISP) 不應強迫客戶端實現(xiàn)一個它用不上的接口母赵,或是說客戶端不應該被迫依賴它們不使用的方法,使用多個專門的接口比使用單個接口要好的多具滴!

平臺無關性

  • Java 如何實現(xiàn)的平臺無關

java的運行依賴于java運行環(huán)境(JRE)凹嘲,Java雖然平臺無關但JRE是平臺相關的,雖然它支持大部分主流平臺构韵。

  • JVM 還支持哪些語言

(Kotlin周蹭、Groovy、JRuby疲恢、Jython凶朗、Scala)

值傳遞

  • 值傳遞、引用傳遞

1.基本類型作為參數(shù)傳遞時显拳,是傳遞值的拷貝棚愤,無論你怎么改變這個拷貝,原值是不會改變的
2.對象作為參數(shù)傳遞時杂数,是把對象在內存中的地址拷貝了一份傳給了參數(shù)宛畦。
3.C++中還有指針傳遞。

  • 為什么說Java中只有值傳遞揍移?

前述的引用傳遞刃永,形參拿到的是實參地址的復制,相當于是地址值的傳遞羊精。
Java中的引用傳遞相當于c++中的指針傳遞。至于C++中的引用傳遞解釋如下:

引用參數(shù)傳遞過程中囚玫,被調函數(shù)的形式參數(shù)也作為局部變量在棧中開辟了內存空間喧锦,但是這時存放的是由主調函數(shù)放進來的實參變量的地址。被調函數(shù)對形參(本體)的任何操作都被處理成間接尋址抓督,即通過棧中存放的地址訪問主調函數(shù)中的實參變量(根據(jù)別名找到主調函數(shù)中的本體)燃少。因此,被調函數(shù)對形參的任何操作都會影響主調函數(shù)中的實參變量铃在。

2. java基礎知識

浮點數(shù)精度

浮點數(shù)在機器中的表示由三部分組成:符號阵具,指數(shù)碍遍,尾數(shù)。所以其最大精度由尾數(shù)位數(shù)來決定阳液。

包裝類型

包裝類型用于經基本類型轉換為一個對象怕敬,包裝類于基本類型之間的自動轉換稱為自動拆裝箱。

Integer的緩存機制

在 Java 5 中帘皿,為 Integer 的操作引入了一個新的特性东跪,用來節(jié)省內存和提高性能。整型對象在內部實現(xiàn)中通過使用相同的對象引用實現(xiàn)了緩存和重用鹰溜。上面的規(guī)則適用于整數(shù)區(qū)間 -128 到 +127虽填。這種 Integer 緩存策略僅在自動裝箱(autoboxing)的時候有用,使用構造器創(chuàng)建的 Integer 對象不能被緩存曹动。Java 編譯器把原始類型自動轉換為封裝類的過程稱為自動裝箱(autoboxing)斋日,這相當于調用 valueOf 方法。這種緩存行為不僅適用于Integer對象墓陈。我們針對所有整數(shù)類型的類都有類似的緩存機制恶守。
有 ByteCache 用于緩存 Byte 對象
有 ShortCache 用于緩存 Short 對象
有 LongCache 用于緩存 Long 對象
有 CharacterCache 用于緩存 Character 對象
Byte,Short跛蛋,Long 有固定范圍: -128 到 127熬的。對于 Character, 范圍是 0 到 127。除了 Integer 可以通過參數(shù)改變范圍外赊级,其它的都不行押框。

String

  • JDK 6 和 JDK 7 中 substring 的原理及區(qū)別

String是通過字符數(shù)組實現(xiàn)的。在jdk 6 中理逊,String類包含三個成員變量:char value[]橡伞, int offset,int count晋被。他們分別用來存儲真正的字符數(shù)組兑徘,數(shù)組的第一個位置索引以及字符串中包含的字符個數(shù)。
當調用substring方法的時候羡洛,會創(chuàng)建一個新的string對象挂脑,但是這個string的值仍然指向堆中的同一個字符數(shù)組。這兩個對象中只有count和offset 的值是不同的欲侮。
這樣做乍看起來可以減少內存占用崭闲,可是substring的存在會使得整個字符串在無用后得不到回收。所以在JDK7中substring實現(xiàn)方式變?yōu)殚_辟新的內存存儲子字符串威蕉。

  • 字符串拼接的方式

加號“+”
String contact() 方法
StringUtils.join() 方法
StringBuffer append() 方法
StringBuilder append() 方法

  • stringbuild和stringbuffer的區(qū)別

在執(zhí)行速度方面的比較:StringBuilder > StringBuffer
StringBuffer與StringBuilder刁俭,他們是字符串變量,是可改變的對象韧涨,每當我們用它們對字符串做操作時牍戚,實際上是在一個對象上操作的侮繁,不像String一樣創(chuàng)建一些對象進行操作,所以速度就快了如孝。
StringBuilder:線程非安全的 StringBuffer:線程安全的

  • String.valueOf 和 Integer.toString 的區(qū)別

String.valueOf()對不同數(shù)據(jù)類型實現(xiàn)了重載宪哩,對于int類型的參數(shù)直接調用Integer.toString()

  • 字符串池、常量池(運行時常量池暑竟、Class 常量池)斋射、intern

String有兩種賦值方式,第一種是通過“字面量”賦值但荤。
String str = "Hello";
第二種是通過new關鍵字創(chuàng)建新對象罗岖。
String str = new String("Hello");

class常量池:我們寫的每一個Java類被編譯后,就會形成一份class文件腹躁;class文件中除了包含類的版本桑包、字段、方法纺非、接口等描述信息外哑了,還有一項信息就是常量池(constant pool tle),用于存放編譯器生成的各種字面量(Literal)和符號引用(Symbolic References)烧颖;
運行時常量池:運行時常量池存在于內存中弱左,也就是class常量池被加載到內存之后的版本,不同之處是:它的字面量可以動態(tài)的添加(String.intern()),符號引用可以被解析為直接引用.
字符串池為他們的一部分炕淮。

字面量創(chuàng)建字符串會先在字符串池中找拆火,看是否有相等的對象,沒有的話就在堆中創(chuàng)建涂圆,把地址駐留在字符串池们镜;有的話則直接用池中的引用,避免重復創(chuàng)建對象润歉。
new關鍵字創(chuàng)建時模狭,前面的操作和字面量創(chuàng)建一樣,只不過最后在運行時會創(chuàng)建一個新對象踩衩,變量所引用的都是這個新對象的地址嚼鹉。

由于不同版本的JDK內存會有些變化,JDK1.6字符串常量池在永久代(即方法區(qū))驱富,1.7移到了堆中(與運行時常量池分開)锚赤,1.8用元空間代替了永久代。但是基本對上面的結論沒有影響萌朱,思想是一樣的。

各種關鍵字

  • transient策菜、instanceof晶疼、final酒贬、static、volatile翠霍、synchronized锭吨、const 原理及用法

transient 表示無需序列化的變量
final可以用來修飾類(繼承),方法(重寫)和變量(const)(成員變量或局部變量)
finally作為異常處理的一部分寒匙,它只能用在try/catch語句中
finalize()是在java.lang.Object里定義的零如,也就是說每一個對象都有這么個方法。這個方法在gc啟動锄弱,該對象被回收的時候被調用

集合類

  • ArrayList 和 LinkedList 和 Vector 的區(qū)別

ArrayList和Vector都是基于數(shù)組實現(xiàn)的考蕾,但Vector實現(xiàn)了線程安全所以他效率會低,linkedList是基于雙向列表實現(xiàn)的会宪。還有synchronizedList肖卧,是實現(xiàn)了線程安全的ArrayList,所以與Vector的區(qū)別僅僅是增長速度掸鹅。

  • HashMap塞帐、HashTable、ConcurrentHashMap 區(qū)別

Hashtable和HashMap有幾個主要的不同:線程安全以及速度巍沙。僅在你需要完全的線程安全的時候使用Hashtable葵姥,而如果你使用Java 5或以上的話,請使用ConcurrentHashMap吧句携。

  • HashSet是如何保證元素唯一性的呢榔幸?

是通過元素的兩個方法,hashCode和equals來完成务甥。
如果元素的HashCode值相同牡辽,才會判斷equals是否為true。
如果元素的hashcode值不同敞临,不會調用equals态辛。

  • Java 8 中 stream 相關用法

Stream 就如同一個迭代器(Iterator),單向挺尿,不可往復奏黑,數(shù)據(jù)只能遍歷一次,遍歷過一次后即用盡了编矾,就好比流水從面前流過熟史,一去不復返≌危可以并行化處理蹂匹。
常用操作有 filter map distinct 排序 reduction collect

  • apache 集合處理工具類的使用

并交補、過濾凹蜈、collect(獲取某些屬性的集合)

  • 不同版本的 JDK 中 HashMap 的實現(xiàn)的區(qū)別以及原因

JDK1.8之前處理hash沖突使用鏈表限寞,但是鏈表查詢滿忍啸,鏈表長了之后效率會下降,故JDK1.8之后鏈表長度達到一定閾值后轉換為紅黑樹履植,紅黑樹增刪慢计雌,查詢快。

  • Collection與Collections

java.util.Collection 是一個集合接口(集合類的一個頂級接口)
Collections則是集合類的一個工具類/幫助類玫霎,其中提供了一系列靜態(tài)方法凿滤,用于對集合中元素進行排序、搜索以及線程安全等各種操作庶近。

  • Arrays.asList

是不支持add和remove操作的翁脆,也就是說Arrays.asList返回的List是個固定大小的List。如果希望轉過后的list可以支持add和remove操作拦盹,可使用如下方法:

ArrayList<Integer> copyArrays=new ArrayList<>(Arrays.asList(integerArray));
  • Enumeration 和 Iterator 區(qū)別

Iterator除了能讀取集合的數(shù)據(jù)之外鹃祖,也能數(shù)據(jù)進行刪除操作。
Iterator支持fail-fast機制普舆,而Enumeration不支持恬口。

  • fail-fast 和 fail-safe

在使用迭代器遍歷集合時,若集合內容發(fā)生改變沼侣,而我們接著對該集合遍歷祖能,此事是否應該拋出異常?快速失敗就是即刻拋出Concurrent Modification Exception蛾洛。而安全失敗的遍歷是在遍歷之前將集合內容復制出來养铸,在其上進行遍歷。

  • CopyOnWrite容器

CopyOnWrite容器即寫時復制的容器轧膘。通俗的理解是當我們往一個容器添加元素的時候钞螟,不直接往當前容器添加,而是先將當前容器進行Copy谎碍,復制出一個新的容器鳞滨,然后新的容器里添加元素,添加完元素之后蟆淀,再將原容器的引用指向新的容器拯啦。這樣做的好處是我們可以對CopyOnWrite容器進行并發(fā)的讀,而不需要加鎖熔任,因為當前容器不會添加任何元素褒链。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器

  • ConcurrentSkipListMap

TreeMap使用紅黑樹按照key的順序(自然順序疑苔、自定義順序)來使得鍵值對有序存儲甫匹,但是只能在單線程下安全使用;多線程下想要使鍵值對按照key的順序來存儲,則需要使用ConcurrentSkipListMap兵迅。 ConcurrentSkipListMap的底層是通過跳表來實現(xiàn)的哀墓。

  • 同步、異步喷兼、阻塞、非阻塞

同步異步是指進程通信方式后雷,阻塞非阻塞是指同步之下進程能否繼續(xù)執(zhí)行其他任務季惯。
linux下的五種I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O(nonblocking I/O)
3)I/O復用(select 和poll) (I/O multiplexing)
I/O復用模型會用到select、poll臀突、epoll函數(shù)勉抓,這幾個函數(shù)也會使進程阻塞,但是和阻塞I/O所不同的的候学,這兩個函數(shù)可以同時阻塞多個I/O操作
4)信號驅動I/O (signal driven I/O (SIGIO))
在信號處理函數(shù)中調用I/O操作函數(shù)處理數(shù)據(jù),進程繼續(xù)運行并不阻塞
5)異步I/O (asynchronous I/O (the POSIX aio_functions))
實際處理這個調用的部件在完成后,通過狀態(tài)捕儒、通知和回調來通知調用者的輸入輸出操作
前者與后者的區(qū)別在于啟用異步I/O意味著通知內核啟動某個I/O操作望几,并讓內核在整個操作(包括數(shù)據(jù)從內核復制到用戶緩沖區(qū))完成時通知我們。也就是說掰茶,異步I/O是由內核通知我們I/O操作何時完成暇藏,即實際的I/O操作也是異步的;而 信號驅動I/O是由內核通知我們何時可以啟動一個I/O

  • select濒蒋、epoll

select的幾大缺點及epoll解決方式:
1.每次循環(huán)調用select盐碱,都需要把fd集合從用戶態(tài)拷貝到內核態(tài),返回時從內核態(tài)拷貝到用戶態(tài)沪伙,這個開銷在fd很多時會很大(epoll的解決方案-在epoll_ctl函數(shù)中瓮顽。每次注冊新的事件到epoll句柄中時(在epoll_ctl中指定EPOLL_CTL_ADD),會把所有的fd拷貝進內核围橡,而不是在循環(huán)調用epoll_wait的時候重復拷貝暖混。epoll保證了每個fd在整個過程中只會拷貝一次。)
2.同時每次調用select都需要在內核遍歷傳遞進來的所有fd某饰,這個開銷在fd很多時也很大(epoll的解決方案不像select或poll一樣每次都把current輪流加入fd對應的設備等待隊列中儒恋,而只在epoll_ctl時把current掛一遍(這一遍必不可少)并為每個fd指定一個回調函數(shù),當設備就緒黔漂,喚醒等待隊列上的等待者時诫尽,就會調用這個回調函數(shù),而這個回調函數(shù)會把就緒的fd加入一個就緒鏈表)炬守。epoll_wait的工作實際上就是在這個就緒鏈表中查看有沒有就緒的fd(利用schedule_timeout()實現(xiàn)睡一會牧嫉,判斷一會的效果,和select實現(xiàn)中的第7步是類似的))
3.select支持的文件描述符數(shù)量太小了,默認是1024(fd_set只包含一個int數(shù)組酣藻,數(shù)組大小為1024)

  • BIO曹洽、NIO、AIO

BIO
NIO的最重要的地方是當一個連接創(chuàng)建后辽剧,不需要對應一個線程送淆,這個連接會被注冊到多路復用器上面,所以所有的連接只需要一個線程就可以搞定怕轿,當這個線程中的多路復用器進行輪詢的時候偷崩,發(fā)現(xiàn)連接上有請求的話,才開啟一個線程進行處理撞羽,也就是一個請求一個線程模式阐斜。也就是說,這個時候诀紊,已經不是一個連接就要對應一個處理線程了谒出,而是有效的請求,對應一個線程邻奠,當連接沒有數(shù)據(jù)時笤喳,是沒有工作線程來處理的。netty基于此
AIO與NIO不同碌宴,當進行讀寫操作時莉测,只須直接調用API的read或write方法即可。這兩種方法均為異步的唧喉,對于讀操作而言捣卤,當有流可讀取時,操作系統(tǒng)會將可讀的流傳入read方法的緩沖區(qū)八孝,并通知應用程序董朝;對于寫操作而言,當操作系統(tǒng)將write方法傳遞的流寫入完畢時干跛,操作系統(tǒng)主動通知應用程序子姜。 即可以理解為,read/write方法都是異步的楼入,完成后會主動調用回調函數(shù)哥捕。

反射

  • 反射與工廠模式,IOC

將反射與工廠模式結合嘉熊,可以通過類名字(查找類文件)便能生成對象遥赚。可以動態(tài)加入類文件阐肤。

class Factory{  
  public static fruit getInstance(String ClassName){  
       fruit f=null;  
       try{  
           f=(fruit)Class.forName(ClassName).newInstance();  
       }catch (Exception e) {  
          e.printStackTrace();  
       }  
       return f;  
   }  
} 

我們可以把IOC(控制反轉)容器的工作模式看做是工廠模式的升華凫佛,可以把IOC容器看作是一個工廠讲坎,這個工廠里要生產的對象都在配置文件中給出定義,然后利用編程語言提供的反射機制愧薛,根據(jù)配置文件中給出的類名生成相應的對象晨炕。從實現(xiàn)來看,IOC是把以前在工廠方法里寫死的對象生成代碼毫炉,改變?yōu)橛膳渲梦募矶x瓮栗,也就是把工廠和對象生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性

代理

靜態(tài)代理

public void execute() {
     System.out.println("前攔截...");
     bussinessImpl.execute();
     System.out.println("后攔截...");
 }

動態(tài)代理瞄勾,無需手動實現(xiàn)每個接口遵馆,只需添加對方法的判斷

public Object getProxyInstance(){
       return Proxy.newProxyInstance(
               targetObject.getClass().getClassLoader(), //和目標對象的類加載器保持一致
               targetObject.getClass().getInterfaces(), //目標對象實現(xiàn)的接口,因為需要根據(jù)接口動態(tài)生成對象
               new InvocationHandler() { //InvocationHandler:事件處理器丰榴,即對目標對象方法的執(zhí)行
                    
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                       System.out.println("前攔截...");
                        
                       Object result = method.invoke(proxy, args);
                        
                       System.out.println("后攔截...");
                       return result;
                   }
               });

動態(tài)代理類并不是程序員寫的,而是根據(jù)傳入的參數(shù)秆撮,由Proxy類在運行時生成的四濒。
有一點必須注意:jdk動態(tài)代理的應用前提,必須是目標類基于統(tǒng)一的接口职辨?盗蟆。如果沒有上述前提,jdk動態(tài)代理不能應用舒裤。由此可以看出喳资,jdk動態(tài)代理有一定的局限性,cglib這種第三方類庫實現(xiàn)的動態(tài)代理應用更加廣泛腾供,且在效率上更有優(yōu)勢

序列化

  • Java序列化底層原理

https://cloud.tencent.com/developer/article/1125165

  • protobuf

相對于XML仆邓,protocol buffers在序列化結構數(shù)據(jù)時擁有許多先進的特性:
1、更簡單
2伴鳖、序列化后字節(jié)占用空間比XML少3-10倍
3节值、序列化的時間效率比XML快20-100倍
4、具有更少的歧義性
5榜聂、自動生成數(shù)據(jù)訪問類方便應用程序的使用

JMS

  • 什么是JMS

JMS 原本就是一個異步的消息服務搞疗,客戶端獲取消息的時候,不需要主動發(fā)送請求须肆,消息會自動發(fā)送給可用的客戶端

  • Kafka

kafka是什么

泛型

泛型的目的簡單地說就是可以讓一些運行時才能發(fā)現(xiàn)的錯誤可以在編譯期間就可以被編譯器所檢測出匿乃,運行時出問題的代價與編譯期出現(xiàn)問題的代價的差別可想而知。換句話說豌汇,泛型是編譯器的一種及時發(fā)現(xiàn)錯誤的機制幢炸,同時也給用戶帶來了代碼的清晰與簡潔的附加好處

  • 泛型與繼承

public class Solution<T> extends HashMap<Integer, T> {
   void push(Entry<Integer, T> x){
       super.put(x.getKey(),x.getValue());
   }

   public static void main(String[] args){
       Solution<Integer> b2 = new Solution<>();
       Entry<Integer, Integer> x = new SimpleEntry<>(1,2);
       b2.push(x);
   }
}
  • 類型擦除

Java 的泛型在編譯器有效,在運行期被刪除拒贱,也就是說所有泛型參數(shù)類型在編譯后都會被清除掉
List<String>阳懂、List<T>擦除后的類型為 List。
List<String>[]、List<T>[] 擦除后的類型為 List[]岩调。
List<? extends E>巷燥、List<? super E> 擦除后的類型為 List<E>。
List<T extends Serialzable & Cloneable> 擦除后類型為List<Serializable>号枕。

  • 限定通配符和非限定通配符缰揪、上下界限定符 extends 和 super

https://www.cnblogs.com/dtx0/p/8466127.html

  • List<Object>、原始類型 List葱淳、list<?>

list<Object>表示列表中可以存放任意類型的元素钝腺,List<?>表示該列表中的元素類型可以是任一相同類型,即他是List<E>的父類赞厕,為了保證類型安全艳狐,不允許對List<?>或List<? extends E>這樣的通配符類型進行類似add的操作。
相對于List皿桑,List<Object>可以幫助編譯器在編譯階段發(fā)現(xiàn)錯誤毫目。

測試

  • mock、mockito

https://www.cnblogs.com/wangtj-19/p/5822369.html

API诲侮、SPI

API (Application Programming Interface)
大多數(shù)情況下镀虐,都是實現(xiàn)方來制定接口并完成對接口的不同實現(xiàn),調用方僅僅依賴卻無權選擇不同實現(xiàn)沟绪。
SPI (Service Provider Interface)
而如果是調用方來制定接口刮便,實現(xiàn)方來針對接口來實現(xiàn)不同的實現(xiàn)。調用方來選擇自己需要的實現(xiàn)方绽慈。

語法糖

語法糖:switch 支持 String 與枚舉恨旱、泛型、自動裝箱與拆箱坝疼、方法變長參數(shù)窖杀、枚舉、內部類裙士、條件編譯入客、 斷言、數(shù)值字面量腿椎、for-each桌硫、try-with-resource、Lambda 表達式

并發(fā)編程

  • 創(chuàng)建線程的幾種方式

一般有四種方法啃炸,Thread,Runnable,Callable,使用Executor框架來創(chuàng)建線程池.
Runnable和Callable的區(qū)別是铆隘,
(1)Callable規(guī)定的方法是call(),Runnable規(guī)定的方法是run().
(2)Callable的任務執(zhí)行后可返回值,而Runnable的任務是不能返回值得
(3)call方法可以拋出異常南用,run方法不可以
(4)運行Callable任務可以拿到一個Future對象膀钠,表示異步計算的結果掏湾。它提供了檢查計算是否完成的方法,以等待計算的完成肿嘲,并檢索計算的結果融击。通過Future對象可以了解任務執(zhí)行情況,可取消任務的執(zhí)行雳窟,還可獲取執(zhí)行結果尊浪。
一般來說,CachedTheadPool在程序執(zhí)行過程中通常會創(chuàng)建與所需數(shù)量相同的線程封救,然后在它回收舊線程時停止創(chuàng)建新線程拇涤,因此它是合理的Executor的首選,只有當這種方式會引發(fā)問題時(比如需要大量長時間面向連接的線程時)誉结,才需要考慮用FixedThreadPool

  • 守護線程

Java的線程分為兩種:User Thread(用戶線程)鹅士、DaemonThread(守護線程)。
只要當前JVM實例中尚存任何一個非守護線程沒有結束惩坑,守護線程就全部工作掉盅;只有當最后一個非守護線程結束是,守護線程隨著JVM一同結束工作旭贬,Daemon作用是為其他線程提供便利服務,守護線程最典型的應用就是GC(垃圾回收器)搪泳,他就是一個很稱職的守護者稀轨。
User和Daemon兩者幾乎沒有區(qū)別,唯一的不同之處就在于虛擬機的離開:如果 User Thread已經全部退出運行了岸军,只剩下Daemon Thread存在了奋刽,虛擬機也就退出了。 因為沒有了被守護者艰赞,Daemon也就沒有工作可做了佣谐,也就沒有繼續(xù)運行程序的必要了。

public class DaemonThreadTest  
{  
    public static void main(String[] args)  
    {  
        Thread mainThread = new Thread(new Runnable(){  
            @Override 
            public void run()  
            {  
                Thread childThread = new Thread(new ClildThread());  
                childThread.setDaemon(true);  
                childThread.start();  
                System.out.println("I'm main thread...");  
            }  
        });  
        mainThread.start();  
           
        Thread otherThread = new Thread(new Runnable(){  
            @Override 
            public void run()  
            {  
                while(true)  
                {  
                    System.out.println("I'm other user thread...");  
                    try 
                    {  
                        TimeUnit.MILLISECONDS.sleep(1000);  
                    }  
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        });  
        otherThread.start();  
    }  
}  
   
class ClildThread implements Runnable  
{  
    @Override 
    public void run()  
    {  
        while(true)  
        {  
            System.out.println("I'm child thread..");  
            try 
            {  
                TimeUnit.MILLISECONDS.sleep(1000);  
            }  
            catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            }  
        }  
    }  
}

還有補充一點方妖,不是說當子線程是守護線程狭魂,主線程結束,子線程就跟著結束党觅,這里的前提條件是:當前jvm應用實例中沒有用戶線程繼續(xù)執(zhí)行雌澄,如果有其他用戶線程繼續(xù)執(zhí)行,那么后臺線程不會中斷杯瞻,如下:

public class DaemonThreadTest  
{  
    public static void main(String[] args)  
    {  
        Thread mainThread = new Thread(new Runnable(){  
            @Override 
            public void run()  
            {  
                Thread childThread = new Thread(new ClildThread());  
                childThread.setDaemon(true);  
                childThread.start();  
                System.out.println("I'm main thread...");  
            }  
        });  
        mainThread.start();  
           
        Thread otherThread = new Thread(new Runnable(){  
            @Override 
            public void run()  
            {  
                while(true)  
                {  
                    System.out.println("I'm other user thread...");  
                    try 
                    {  
                        TimeUnit.MILLISECONDS.sleep(1000);  
                    }  
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        });  
        otherThread.start();  
    }  
}  
   
class ClildThread implements Runnable  
{  
    @Override 
    public void run()  
    {  
        while(true)  
        {  
            System.out.println("I'm child thread..");  
            try 
            {  
                TimeUnit.MILLISECONDS.sleep(1000);  
            }  
            catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            }  
        }  
    }  
}
  • 線程池不允許使用 Executors 去創(chuàng)建,而是通過ThreadPoolExecutor 的方式

http://www.reibang.com/p/51c4ad2da4df

  • 線程安全與內存模型

可見性镐牺,重排序,happens-before魁莉,內存屏障指令

  • 死鎖出現(xiàn)的條件

  1. 互斥條件:一個資源每次只能被一個線程使用睬涧。
  2. 請求與保持條件:一個進程因請求資源而阻塞時募胃,對已獲得的資源保持不放。
  3. 不可剝奪條件:進程已獲得的資源畦浓,在未使用完之前痹束,不能強行剝奪。
  4. 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系宅粥。
  • 銀行家算法

框架

hibernate

  • 懶加載

實現(xiàn)懶加載的前提:
1.實體類不能是final的
2.能實現(xiàn)懶加載的對象都是被CGLIB(反射調用)改寫的代理對象,所以不能是final修飾的
3.須要asm,cglib兩個jar包
4.相應的lazy屬性為true
5.相應的fetch屬性為select

下面幾種可以實現(xiàn)懶加載功能:
1.通過Session.load()實現(xiàn)懶加載
2.one-to-one,many-to-one,one-to-many参袱。

因為懶加載的存在,在session關閉之后秽梅,hibernate又向數(shù)據(jù)庫發(fā)出一次請求抹蚀,結果就拋出異常.解決這個問題的四種方式:
1.Hibernate.initialize(Department.class);
2.修改對象關系文件,將lazy改寫lazy=false企垦,即關閉懶加載
3.使用過濾器(web項目)
4.在SSH框架中环壤,使用spring提供的openSessionView

mysql

  • 四種事務隔離級別

臟讀:事務中讀到其他事務修改中間的數(shù)據(jù),若其他事務回滾了钞诡,那就讀到了臟數(shù)據(jù)
不可重復讀:事務多次重復讀取數(shù)據(jù)郑现,數(shù)據(jù)中途卻被其他事務修改
幻讀:事務A首先根據(jù)條件索引得到N條數(shù)據(jù),然后事務B改變了這N條數(shù)據(jù)之外的M條或者增添了M條符合事務A搜索條件的數(shù)據(jù)荧降,導致事務A再次搜索發(fā)現(xiàn)有N+M條數(shù)據(jù)了接箫,就產生了幻讀

  • 引擎

innodb
支持“ACID”事務
鎖的粒度小,支持行鎖定(只在可以確定主鍵時)朵诫,所以適合經常更新的表辛友,適合處理多重并發(fā)的更新請求
支持外鍵約束
不支持fulltext索引
必須導出SQL來備份

myisam
大批量的插入語句時(這里是INSERT語句)執(zhí)行的比較的快
極度強調快速讀取操作。
如果表的讀操作遠遠多于寫操作且不需要數(shù)據(jù)庫事務的支持剪返,那么MyIASM也是很好的選擇废累。
允許沒有主鍵和索引的表
MyISAM的數(shù)據(jù)是以文件的形式存儲,所以在跨平臺的數(shù)據(jù)轉移中會很方便

一個強調的是性能脱盲,一個強調的是大容量數(shù)據(jù)庫的事務安全

  • 索引數(shù)據(jù)結構

B-與B+的區(qū)別
B-每個非葉子結點由n-1個key和n個指針組成邑滨,其中d<=n<=2d;B+每個結點的指針上限為2d
B+內結點不存儲data钱反,只存儲key掖看;葉子結點不存儲指針。

  • 為何使用B-/+來實現(xiàn)索引

可以將一個節(jié)點的大小設為一個頁面面哥,每個節(jié)點一次I/O便可讀入內存乙各,便于磁盤I/O
每次查找,最大的節(jié)點訪問數(shù)為h(樹高)幢竹,而h的大小與非葉節(jié)點的出度d有關耳峦,d增大,便可以減少磁盤I/O
另外焕毫,在B+Tree的每個葉子結點增加一個指向相鄰葉子結點的指針蹲坷,就形成了帶有順序訪問指針的B+Tree驶乾。做這個優(yōu)化的目的是為了提高區(qū)間訪問的性能,例如圖4中如果要查詢key為從18到49的所有數(shù)據(jù)記錄循签,當找到18后级乐,只需順著結點和指針順序遍歷就可以一次性訪問到所有數(shù)據(jù)結點,極大提到了區(qū)間查詢效率县匠。

  • innodb與myisam索引區(qū)別

myisam節(jié)點data域存放的是數(shù)據(jù)的地址风科,innodb主鍵索引中節(jié)點data域存放的直接是數(shù)據(jù),輔助索引data域存放主鍵乞旦,然后根據(jù)主鍵再進行一次主鍵索引找到非主鍵列贼穆。

  • 覆蓋索引

前面說到innodb使用非主鍵索引時需要進行兩次索引,第二次索引叫回表兰粉,當所查詢數(shù)據(jù)為主鍵時是不需要回表的故痊,如下1

1.select id from user_table where username = 'lzs'
2.select password from user_table where username = 'lzs'

面對2這樣的查詢?yōu)榱思涌觳樵兯俣取玖姑?梢越⒙?lián)合索引愕秫,也叫覆蓋索引

  • 最左前綴索引

繼續(xù)以上面的例子來說明,為了提高語句B的執(zhí)行速度焰络,我們添加了一個聯(lián)合索引(username,password),特別注意這個聯(lián)合索引的順序戴甩,如果我們顛倒下順序改成(password,username),這樣查詢能使用這個索引嗎?答案是不能的闪彼!這是最左前綴的第一層含義:聯(lián)合索引的多個字段中甜孤,只有當查詢條件為聯(lián)合索引的一個字段時,查詢才能使用該索引备蚓。
最左前綴的第二層含義:索引可以用于查詢條件字段為索引字段课蔬,根據(jù)字段值最左若干個字符進行的模糊查詢囱稽。

1.where username like '張%'
2.where username like '%張%'
  • 列中存在重復數(shù)據(jù)時郊尝,索引是什么結構的?

聚合索引要求非空唯一战惊,如果沒有滿足字段則會自建一列用作聚合索引流昏,非聚合索引(普通索引)葉節(jié)點指向聚合索引的鍵,不存在索引重復數(shù)據(jù)問題
值重復率高的字段不適合建索引吞获,從性別字段不適合建索引說起

  • count(*)與索引

當利用主鍵索引(聚集索引)來進行統(tǒng)計效率一般會小于利用二級索引况凉,這是因為count(*)主要的操作是在B+索引樹的葉節(jié)點上進行掃描,頁節(jié)點越小所需的磁盤IO便越少各拷,而聚集索引需要掃描整個數(shù)據(jù)文件刁绒。

mysql中的鎖

  • 行級鎖

mysql中的行級鎖不是在表上加鎖,而是在索引上面加鎖烤黍,所以只有使用了索引的操作才有可能加行鎖知市,另外行級鎖有幾率出現(xiàn)死鎖傻盟。
[mysql行級鎖與表所鎖]
(https://www.cnblogs.com/guanghe/p/9217421.html)

  • 間隙鎖

可以用來防止幻讀
innodb在RR級別快照讀模式下使用MVCC解決幻讀,在當前讀(insert嫂丙、update都屬于當前讀)模式下使用next-key lock娘赴。在唯一索引上(如主鍵索引),只需加record lock(記錄鎖)即可跟啤,在非唯一索引上需要加next-key鎖(record lock+gap lock)诽表,如班級=12,光加行鎖還是會使前后兩次select * from student where 班級=12結果出現(xiàn)幻讀

密碼學相關

RSA加密算法描述
DH密鑰交換算法描述
https連接建立過程

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末隅肥,一起剝皮案震驚了整個濱河市竿奏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌武福,老刑警劉巖议双,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捉片,居然都是意外死亡平痰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門伍纫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宗雇,“玉大人,你說我怎么就攤上這事莹规∨馄眩” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵良漱,是天一觀的道長舞虱。 經常有香客問我,道長母市,這世上最難降的妖魔是什么矾兜? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮患久,結果婚禮上椅寺,老公的妹妹穿的比我還像新娘。我一直安慰自己蒋失,他們只是感情好返帕,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著篙挽,像睡著了一般荆萤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铣卡,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天链韭,我揣著相機與錄音邑闲,去河邊找鬼。 笑死梧油,一個胖子當著我的面吹牛苫耸,可吹牛的內容都是我干的。 我是一名探鬼主播儡陨,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼褪子,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骗村?” 一聲冷哼從身側響起嫌褪,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胚股,沒想到半個月后笼痛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡琅拌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年缨伊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片进宝。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡刻坊,死狀恐怖,靈堂內的尸體忽然破棺而出党晋,到底是詐尸還是另有隱情谭胚,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布未玻,位于F島的核電站灾而,受9級特大地震影響,放射性物質發(fā)生泄漏扳剿。R本人自食惡果不足惜旁趟,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舞终。 院中可真熱鬧轻庆,春花似錦癣猾、人聲如沸敛劝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夸盟。三九已至,卻和暖如春像捶,著一層夾襖步出監(jiān)牢的瞬間上陕,已是汗流浹背桩砰。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留释簿,地道東北人亚隅。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像庶溶,于是被迫代替她去往敵國和親煮纵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容