2020Java面試題答案

JAVA基礎

JAVA中的幾種基本類型,各佔用多少字節?

下圖單位是bit,非字節 1B=8bit

String能被繼承嗎?爲什麼?

不可以,因爲String類有final修飾符,而final修飾的類是不能被繼承的,實現細節不允許改變。平常我們定義的String str=”a”;其實和String str=new String(“a”)還是有差異的。

前者默認調用的是String.valueOf來返回String實例對象,至於調用哪個則取決於你的賦值,比如String num=1,調用的是
public static String valueOf(int i) {
return Integer.toString(i);
}

後者則是調用如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最後我們的變量都存儲在一個char數組中
private final char value[];

String, Stringbuffer, StringBuilder 的區別。

String 字符串常量(final修飾,不可被繼承),String是常量,當創建之後即不能更改。(可以通過StringBuffer和StringBuilder創建String對象(常用的兩個字符串操作類)。)
StringBuffer 字符串變量(線程安全),其也是final類別的,不允許被繼承,其中的絕大多數方法都進行了同步處理,包括常用的Append方法也做了同步處理(synchronized修飾)。其自jdk1.0起就已經出現。其toString方法會進行對象緩存,以減少元素複製開銷。
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}

StringBuilder 字符串變量(非線程安全)其自jdk1.5起開始出現。與StringBuffer一樣都繼承和實現了同樣的接口和類,方法除了沒使用synch修飾以外基本一致,不同之處在於最後toString的時候,會直接返回一個新對象。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}

JAVA容器列舉,同步容器和併發容器

Collection下 和 Map下的實現, 例如ArrayList, HashMap. HashTable, HashSet, LinkedArrayList等

同步容器: HashTable,Vector

併發容器: ConcurrentHashMap

ArrayList 和 LinkedList 有什麼區別,以及查詢和插入的時間複雜度。

ArrayList和LinkedList都實現了List接口,有以下的不同點:
1、ArrayList是基於索引的數據接口,它的底層是數組。它可以以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每一個元素都和它的前一個和後一個元素鏈接在一起,在這種情況下,查找某個元素的時間複雜度是O(n)。
2、相對於ArrayList,LinkedList的插入,添加,刪除操作速度更快,因爲當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。
3、LinkedList比ArrayList更佔內存,因爲LinkedList爲每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。

講講類的實例化順序,比如父類靜態數據,構造函數,字段,子類靜態數據,構造函數,字段,當 new 的時候, 他們的執行順序。

此題考察的是類加載器實例化時進行的操作步驟(加載–>連接->初始化)。
父類靜態代變量、
父類靜態代碼塊、
子類靜態變量、
子類靜態代碼塊、
父類非靜態變量(父類實例成員變量)、
父類構造函數、
子類非靜態變量(子類實例成員變量)、
子類構造函數。
測試demo:http://blog.csdn.net/u014042066/article/details/77574956
參閱我的博客《深入理解類加載》:http://blog.csdn.net/u014042066/article/details/77394480

用過哪些 Map 類,都有什麼區別,HashMap 是線程安全的嗎,併發下使用的 Map 是什麼,他們內部原理分別是什麼,比如存儲方式, hashcode,擴容, 默認容量等。

hashMap是線程不安全的,HashMap是數組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實現的,採用哈希表來存儲的,
參照該鏈接:https://zhuanlan.zhihu.com/p/21673805
JAVA8 的 ConcurrentHashMap 爲什麼放棄了分段鎖,有什麼問題嗎,如果你來設計,你如何設計。
參照:https://yq.aliyun.com/articles/36781

有沒有有順序的 Map 實現類, 如果有, 他們是怎麼保證有序的。

TreeMap和LinkedHashMap是有序的(TreeMap默認升序,LinkedHashMap則記錄了插入順序)。
參照:http://uule.iteye.com/blog/1522291

請你簡單說下HashMap的Put()方法.

抽象類和接口的區別,類可以繼承多個類麼,接口可以繼承多個接口麼,類可以實現多個接口麼。

1、抽象類和接口都不能直接實例化,如果要實例化,抽象類變量必須指向實現所有抽象方法的子類對象,接口變量必須指向實現所有接口方法的類對象。
2、抽象類要被子類繼承,接口要被類實現。
3、接口只能做方法申明,抽象類中可以做方法申明,也可以做方法實現
4、接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量。
5、抽象類裏的抽象方法必須全部被子類所實現,如果子類不能全部實現父類抽象方法,那麼該子類只能是抽象類。同樣,一個實現接口的時候,如不能全部實現接口方法,那麼該類也只能爲抽象類。
6、抽象方法只能申明,不能實現。abstract void abc();不能寫成abstract void abc(){}。
7、抽象類裏可以沒有抽象方法
8、如果一個類裏有抽象方法,那麼這個類只能是抽象類
9、抽象方法要被實現,所以不能是靜態的,也不能是私有的。
10、接口可繼承接口,並可多繼承接口,但類只能單根繼承。

繼承和聚合的區別在哪。

繼承指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關係;在Java中此類關係通過關鍵字extends明確標識,在設計時一般沒有爭議性;

聚合是關聯關係的一種特例,他體現的是整體與部分、擁有的關係,即has-a的關係,此時整體與部分之間是可分離的,他們可以具有各自的生命週期,部分可以屬於多個整體對象,也可以爲多個整體對象共享;比如計算機與CPU、公司與員工的關係等;表現在代碼層面,和關聯關係是一致的,只能從語義級別來區分;

參考:http://www.cnblogs.com/jiqing9006/p/5915023.html

講講你理解的 nio和 bio 的區別是啥,談談 reactor 模型。

IO是面向流的,NIO是面向緩衝區的
參考:https://zhuanlan.zhihu.com/p/23488863
http://developer.51cto.com/art/201103/252367.htm
http://www.jianshu.com/p/3f703d3d804c

反射的原理,反射創建類實例的三種方式是什麼

  1. getClass()

2.xxx.class

  1. Class.forName

參照:http://www.jianshu.com/p/3ea4a6b57f87?amp

http://blog.csdn.net/yongjian1092/article/details/7364451

反射中,Class.forName 和 ClassLoader 區別。

Class.forName(className)方法,其實調用的方法是Class.forName(className,true,classloader);注意看第2個boolean參數,它表示的意思,在loadClass後必須初始化。比較下我們前面準備jvm加載類的知識,我們可以清晰的看到在執行過此方法後,目標對象的 static塊代碼已經被執行,static參數也已經被初始化。

再看ClassLoader.loadClass(className)方法,其實他調用的方法是ClassLoader.loadClass(className,false);還是注意看第2個 boolean參數,該參數表示目標對象被裝載後不進行鏈接,這就意味這不會去執行該類靜態塊中間的內容。因此2者的區別就顯而易見了

https://my.oschina.net/gpzhang/blog/486743

描述動態代理的幾種實現方式,分別說出相應的優缺點。

Jdk cglib jdk底層是利用反射機制,需要基於接口方式,這是由於
Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
Cglib則是基於asm框架,實現了無反射機制進行代理,利用空間來換取了時間,代理效率高於jdk
http://lrd.ele.me/2017/01/09/dynamic_proxy/

動態代理與 cglib 實現的區別

同上(基於invocationHandler和methodInterceptor)

爲什麼 CGlib 方式可以對接口實現代理。

同上

註解原理

https://www.jianshu.com/p/a692150d625c

final 的用途

類、變量、方法
http://www.importnew.com/7553.html

寫出三種單例模式實現。

懶漢式單例,餓漢式單例,雙重檢查等
參考:https://my.oschina.net/dyyweb/blog/609021

如何在父類中爲子類自動完成所有的 hashcode 和 equals 實現?這麼做有何優劣。

同時複寫hashcode和equals方法,優勢可以添加自定義邏輯,且不必調用超類的實現。
參照:http://java-min.iteye.com/blog/1416727

請結合 OO 設計理念,談談訪問修飾符 public、private、protected、default 在應用設計中的作用。

訪問修飾符,主要標示修飾塊的作用域,方便隔離防護

同一個類 同一個包 不同包的子類 不同包的非子類
1
2
Private √
Default √ √
Protected √ √ √
Public √ √ √ √
public: Java語言中訪問限制最寬的修飾符,一般稱之爲“公共的”。被其修飾的類、屬性以及方法不
     僅可以跨類訪問,而且允許跨包(package)訪問。
private: Java語言中對訪問權限限制的最窄的修飾符,一般稱之爲“私有的”。被其修飾的類、屬性以
     及方法只能被該類的對象訪問,其子類不能訪問,更不能允許跨包訪問。
protect: 介於public 和 private 之間的一種訪問修飾符,一般稱之爲“保護形”。被其修飾的類、
     屬性以及方法只能被類本身的方法及子類訪問,即使子類在不同的包中也可以訪問。
default:即不加任何訪問修飾符,通常稱爲“默認訪問模式“。該模式下,只允許在同一個包中進行訪
     問。

深拷貝和淺拷貝區別。

http://www.oschina.net/translate/java-copy-shallow-vs-deep-in-which-you-will-swim

數組和鏈表數據結構描述,各自的時間複雜度

http://blog.csdn.net/snow_wu/article/details/53172721

error 和 exception 的區別,CheckedException,RuntimeException 的區別

http://blog.csdn.net/woshixuye/article/details/8230407

請列出 5 個運行時異常。

同上

在自己的代碼中,如果創建一個 java.lang.String 對象,這個對象是否可以被類加載器加載?爲什麼

類加載無須等到“首次使用該類”時加載,jvm允許預加載某些類。。。。
http://www.cnblogs.com/jasonstorm/p/5663864.html

說一說你對 java.lang.Object 對象中 hashCode 和 equals 方法的理解。在什麼場景下需要重新實現這兩個方法。

參考上邊試題

在 jdk1.5 中,引入了泛型,泛型的存在是用來解決什麼問題。

泛型的本質是參數化類型,也就是說所操作的數據類型被指定爲一個參數,泛型的好處是在編譯的時候檢查類型安全,並且所有的強制轉換都是自動和隱式的,以提高代碼的重用率
http://baike.baidu.com/item/java%E6%B3%9B%E5%9E%8B

這樣的 a.hashcode() 有什麼用,與 a.equals(b)有什麼關係。

hashcode
hashcode()方法提供了對象的hashCode值,是一個native方法,返回的默認值與System.identityHashCode(obj)一致。

通常這個值是對象頭部的一部分二進制位組成的數字,具有一定的標識對象的意義存在,但絕不定於地址。

作用是:用一個數字來標識對象。比如在HashMap、HashSet等類似的集合類中,如果用某個對象本身作爲Key,即要基於這個對象實現Hash的寫入和查找,那麼對象本身如何實現這個呢?就是基於hashcode這樣一個數字來完成的,只有數字才能完成計算和對比操作。

hashcode是否唯一
hashcode只能說是標識對象,在hash算法中可以將對象相對離散開,這樣就可以在查找數據的時候根據這個key快速縮小數據的範圍,但hashcode不一定是唯一的,所以hash算法中定位到具體的鏈表後,需要循環鏈表,然後通過equals方法來對比Key是否是一樣的。

equals與hashcode的關係
equals相等兩個對象,則hashcode一定要相等。但是hashcode相等的兩個對象不一定equals相等。
https://segmentfault.com/a/1190000004520827

有沒有可能 2 個不相等的對象有相同的 hashcode。

Java 中的 HashSet 內部是如何工作的。

底層是基於hashmap實現的
http://wiki.jikexueyuan.com/project/java-collection/hashset.html

什麼是序列化,怎麼序列化,爲什麼序列化,反序列化會遇到什麼問題,如何解決。

序列化:把對象轉換爲字節序列的過程稱爲對象的序列化。
反序列化:把字節序列恢復爲對象的過程稱爲對象的反序列化。

例如對象在網絡中傳輸, Redis, 消息中間件, 分佈式通訊中都是需要用到, 對象必須實現Serializable接口.

https://blog.csdn.net/u013870094/article/details/82765907

JVM 知識

什麼情況下會發生棧內存溢出。

如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。 如果虛擬機在動態擴展棧時無法申請到足夠的內存空間,則拋出OutOfMemoryError異常。
參照:http://wiki.jikexueyuan.com/project/java-vm/storage.html

JVM 的內存結構,Eden 和 Survivor 比例。

eden 和 survior 是按8比1分配的
http://blog.csdn.net/lojze_ly/article/details/49456255

jvm 中一次完整的 GC 流程是怎樣的,對象如何晉升到老年代,說說你知道的幾種主要的jvm 參數。

對象誕生即新生代->eden,在進行minor gc過程中,如果依舊存活,移動到from,變成Survivor,進行標記代數,如此檢查一定次數後,晉升爲老年代,
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037056.html
http://ifeve.com/useful-jvm-flags/
https://wangkang007.gitbooks.io/jvm/content/jvmcan_shu_xiang_jie.html

你知道哪幾種垃圾收集器,各自的優缺點,重點講下 cms,包括原理,流程,優缺點

Serial、parNew、ParallelScavenge、SerialOld、ParallelOld、CMS、G1
https://wangkang007.gitbooks.io/jvm/content/chapter1.html

垃圾回收算法的實現原理。
http://www.importnew.com/13493.html

內存泄漏與內存溢出的區別, 你怎麼排錯。

內存泄漏:對象無法得到及時的回收,持續佔用內存空間,從而造成內存空間的浪費。
內存溢出:內存泄漏到一定的程度就會導致內存溢出,但是內存溢出也有可能是大對象導致的。

手動dump

jmap -dump:format=b,file=heap.hprof PID

一般在開發中,JVM參數可以加上下面兩句,這樣內存溢出時,會自動dump出該文件

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

https://wangkang007.gitbooks.io/jvm/content/4jvmdiao_you.html

一般使用哪些JVM監控工具

jvisualvm,jconsole,Arthas

MAT 用於解析dump文件

JVM性能優化步驟

JVM 內存模型的相關知識瞭解多少,比如重排序,內存屏障,happen-before,主內存,工作內存等。

內存屏障:爲了保障執行順序和可見性的一條cpu指令
重排序:爲了提高性能,編譯器和處理器會對執行進行重拍
happen-before:操作間執行的順序關係。有些操作先發生。
主內存:共享變量存儲的區域即是主內存
工作內存:每個線程copy的本地內存,存儲了該線程以讀/寫共享變量的副本
http://ifeve.com/java-memory-model-1/
http://www.jianshu.com/p/d3fda02d4cae
http://blog.csdn.net/kenzyq/article/details/50918457

簡單說說你瞭解的類加載器。

類加載器的分類(bootstrap,ext,app,curstom),類加載的流程(load-link-init)
http://blog.csdn.net/gjanyanlig/article/details/6818655/

講講 JAVA 的反射機制。

Java程序在運行狀態可以動態的獲取類的所有屬性和方法,並實例化該類,調用方法的功能
http://baike.baidu.com/link?url=C7p1PeLa3ploAgkfAOK-4XHE8HzQuOAB7K5GPcK_zpbAa_Aw-nO3997K1oir8N–1_wxXZfOThFrEcA0LjVP6wNOwidVTkLBzKlQVK6JvXYvVNhDWV9yF-NIOebtg1hwsnagsjUhOE2wxmiup20RRa#7

你們線上應用的 JVM 參數有哪些。

-server
Xms6000M
-Xmx6000M
-Xmn500M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log

g1 和 cms 區別,吞吐量優先和響應優先的垃圾收集器選擇。

Cms是以獲取最短回收停頓時間爲目標的收集器。基於標記-清除算法實現。比較佔用cpu資源,切易造成碎片。
G1是面向服務端的垃圾收集器,是jdk9默認的收集器,基於標記-整理算法實現。可利用多核、多cpu,保留分代,實現可預測停頓,可控。
http://blog.csdn.net/linhu007/article/details/48897597

請解釋如下 jvm 參數的含義:

-server -Xms512m -Xmx512m -Xss1024K
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=20
XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly。

Server模式啓動

最小堆內存512m
最大512m
每個線程棧空間1m
永久代256
最大永久代256
最大轉爲老年代檢查次數20
Cms回收開啓時機:內存佔用80%
命令JVM不基於運行時收集的數據來啓動CMS垃圾收集週期

開源框架知識

簡單講講 tomcat 結構,以及其類加載器流程。

Server- –多個service
Container級別的:–>engine–》host–>context
Listenter
Connector
Logging、Naming、Session、JMX等等

通過WebappClassLoader 加載class

http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/
http://blog.csdn.net/dc_726/article/details/11873343
http://www.cnblogs.com/xing901022/p/4574961.html
http://www.jianshu.com/p/62ec977996df

tomcat 如何調優,涉及哪些參數。

硬件上選擇,操作系統選擇,版本選擇,jdk選擇,配置jvm參數,配置connector的線程數量,開啓gzip壓縮,trimSpaces,集羣等
http://blog.csdn.net/lifetragedy/article/details/7708724

https://blog.csdn.net/ThinkWon/article/details/102744033

講講 Spring 加載流程。

通過listener入口,核心是在AbstractApplicationContext的refresh方法,在此處進行裝載bean工廠,bean,創建bean實例,攔截器,後置處理器等。
https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/

講講 Spring 事務的傳播屬性。

七種傳播屬性。
事務傳播行爲
所謂事務的傳播行爲是指,如果在開始當前事務之前,一個事務上下文已經存在,此時有若干選項可以指定一個事務性方法的執行行爲。在TransactionDefinition定義中包括瞭如下幾個表示傳播行爲的常量:
TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,如果當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,如果當前存在事務,則拋出異常。
TransactionDefinition.PROPAGATION_MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
TransactionDefinition.PROPAGATION_NESTED:如果當前存在事務,則創建一個事務作爲當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。
https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/

Spring 如何管理事務的。

編程式和聲明式
同上

Spring 怎麼配置事務(具體說出一些關鍵的 xml 元素)。

說說你對 Spring 的理解,非單例注入的原理?它的生命週期?循環注入的原理, aop 的實現原理,說說 aop 中的幾個術語,它們是怎麼相互工作的。

單例注入是通過單例beanFactory進行創建,生命週期是在創建的時候通過接口實現開啓,循環注入是通過後置處理器,aop其實就是通過反射進行動態代理,pointcut,advice等。
Aop相關:https://blog.csdn.net/weixin_38399962/article/details/79882226

Spring 如何解決循環依賴的

三級緩存

https://blog.csdn.net/qq_36381855/article/details/79752689

BeanFactory和ApplicationContext有什麼區別?

BeanFactory 可以理解爲含有bean集合的工廠類。BeanFactory 包含了種bean的定義,以便在接收到客戶端請求時將對應的bean實例化。

BeanFactory還能在實例化對象的時生成協作類之間的關係。此舉將bean自身與bean客戶端的配置中解放出來。BeanFactory還包含了bean生命週期的控制,調用客戶端的初始化方法(initialization methods)和銷燬方法(destruction methods)。

從表面上看,application context如同bean factory一樣具有bean定義、bean關聯關係的設置,根據請求分發bean的功能。但application context在此基礎上還提供了其他的功能。

提供了支持國際化的文本消息
統一的資源文件讀取方式
已在監聽器中註冊的bean的事件

你對Spring核心組件的理解

核心組件:bean,context,core.

我的理解 :

我們知道 Bean 包裝的是 Object,而 Object 必然有數據,如何給這些數據提供生存環境就是 Context 要解決的問題,對 Context 來說他就是要發現每個 Bean 之間的關係,爲它們建立這種關係並且要維護好這種關係。所以 Context 就是一個 Bean 關係的集合,這個關係集合又叫 Ioc 容器,一旦建立起這個 Ioc 容器後 Spring 就可以爲你工作了。那 Core 組件又有什麼用武之地呢?其實 Core 就是發現、建立和維護每個 Bean 之間的關係所需要的一些列的工具,從這個角度看來,Core 這個組件叫 Util 更能讓你理解。

簡述Bean的生命週期

Spring容器初始化-> bean構造器-> bean字段注入-> 【init-method】調用的init-method屬性指定的初始化方法

->容器初始化成功 ->單例bean的使用->關閉容器->【destroy-method】調用的destroy-method屬性指定的初始化方法

->bean死亡

詳見 https://www.cnblogs.com/zrtqsk/p/3735273.html

@AspectJ 的用法

https://blog.csdn.net/weixin_38399962/article/details/83894823

Springmvc 中 DispatcherServlet 初始化過程。

入口是web.xml中配置的ds,ds繼承了HttpServletBean,FrameworkServlet,通過其中的init方法進行初始化裝載bean和實例,initServletBean是實際完成上下文工作和bean初始化的方法。
http://www.mamicode.com/info-detail-512105.html

SpringBoot比Spring做了哪些改進?

• 獨立運行
• 簡化配置
• 自動配置
• 無代碼生成和 XML 配置
• 應用監控
• 上手容易

簡稱四簡一快

簡化編碼, 簡化監控, 簡化配置, 簡化部署, 快速搭建

詳情移步: 爲什麼說JAVA程序員必須掌握SpringBoot?

你如何理解 Spring Boot 中的 Starters, 其中加載原理?

Starters 可以理解爲啓動器,它包含了一系列可以集成到應用裏面的依賴包,你可以一站式集成 Spring 及其他技術,而不需要到處找示例代碼和依賴包。如你想使用 Spring JPA 訪問數據庫,只要加入 spring-boot-starter-data-jpa 啓動器依賴就能使用了。
Starters 包含了許多項目中需要用到的依賴,它們能快速持續的運行,都是一系列得到支持的管理傳遞性依賴。

https://mp.weixin.qq.com/s/9YDLIcF7J6pQ91o-lipL6w

SpringIOC是什麼?DI是什麼 優點是什麼?

控制反轉是應用於軟件工程領域中的,在運行時被裝配器對象來綁定耦合對象的一種編程技巧,對象之間耦合關係在編譯時通常是未知的。在傳統的編程方式中,業務邏輯的流程是由應用程序中的早已被設定好關聯關係的對象來決定的。在使用控制反轉的情況下,業務邏輯的流程是由對象關係圖來決定的,該對象關係圖由裝配器負責實例化,這種實現方式還可以將對象之間的關聯關係的定義抽象化。而綁定的過程是通過“依賴注入”實現的。

     控制反轉是一種以給予應用程序中目標組件更多控制爲目的設計範式,並在我們的實際工作中起到了有效的作用。

依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他對象所依賴的功能對象實例化的模式。這就需要一種機制用來激活相應的組件以提供特定的功能,所以依賴注入是控制反轉的基礎。否則如果在組件不受框架控制的情況下,框架又怎麼知道要創建哪個組件?

在Java中依然注入有以下三種實現方式:

構造器注入
Setter方法注入
接口注入

操作系統
Linux 系統下你關注過哪些內核參數,說說你知道的。
http://www.haiyun.me/category/system/

Linux 下 IO 模型有幾種,各自的含義是什麼。

阻塞式io,非阻塞io,io複用模型,信號驅動io模型,異步io模型。
https://yq.aliyun.com/articles/46404
https://yq.aliyun.com/articles/46402

epoll 和 poll 有什麼區別。

select的本質是採用32個整數的32位,即3232= 1024來標識,fd值爲1-1024。當fd的值超過1024限制時,就必須修改FD_SETSIZE的大小。這個時候就可以標識32max值範圍的fd。
對於單進程多線程,每個線程處理多個fd的情況,select是不適合的。
1.所有的線程均是從1-32*max進行掃描,每個線程處理的均是一段fd值,這樣做有點浪費
2.1024上限問題,一個處理多個用戶的進程,fd值遠遠大於1024
所以這個時候應該採用poll,
poll傳遞的是數組頭指針和該數組的長度,只要數組的長度不是很長,性能還是很不錯的,因爲poll一次在內核中申請4K(一個頁的大小來存放fd),儘量控制在4K以內
epoll還是poll的一種優化,返回後不需要對所有的fd進行遍歷,在內核中維持了fd的列表。select和poll是將這個內核列表維持在用戶態,然後傳遞到內核中。但是隻有在2.6的內核才支持。
epoll更適合於處理大量的fd ,且活躍fd不是很多的情況,畢竟fd較多還是一個串行的操作
https://yq.aliyun.com/articles/10525

平時用到哪些 Linux 命令。

Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等
https://yq.aliyun.com/articles/69417?spm=5176.100240.searchblog.18.Zrbh9R

用一行命令查看文件的最後五行。

Tail -n 5 filename

用一行命令輸出正在運行的 java 進程。

ps -ef|grep Java

介紹下你理解的操作系統中線程切換過程。

控制權的轉換,根據優先級切換上下文(用戶,寄存器,系統)
http://www.cnblogs.com/kkshaq/p/4544426.html

進程和線程的區別。

Linux 實現並沒有區分這兩個概念(進程和線程)

  1. 進程:程序的一次執行
  2. 線程:CPU的基本調度單位
    一個進程可以包含多個線程。

http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

多線程

多線程的幾種實現方式,什麼是線程安全。
實現runable接口,繼承thread類。
http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/

volatile 的原理,作用,能代替鎖麼。

Volatile利用內存柵欄機制來保持變量的一致性。不能代替鎖,其只具備數據可見性一致性,不具備原子性。
http://blog.csdn.net/gongzi2311/article/details/20715185

畫一個線程的生命週期狀態圖。

新建,可運行,運行中, 睡眠,阻塞,等待,死亡。

http://ifeve.com/thread-status

sleep 和 wait 的區別。

Sleep是休眠線程,wait是等待,sleep是thread的靜態方法,wait則是object的方法。

Sleep依舊持有鎖,並在指定時間自動喚醒。wait則釋放鎖。

http://www.jianshu.com/p/4ec3f4b3903d

Lock 與 Synchronized 的區別。

首先兩者都保持了併發場景下的原子性和可見性,區別則是synchronized的釋放鎖機制是交由其自身控制,且互斥性在某些場景下不符合邏輯,無法進行干預,不可人爲中斷等。
而lock常用的則有ReentrantLock和readwritelock兩者,添加了類似鎖投票、定時鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用情況下更佳的性能。
http://blog.csdn.net/vking_wang/article/details/9952063

synchronized 的原理是什麼,解釋以下名詞:重排序,自旋鎖,偏向鎖,輕量級鎖,可重入鎖,公平鎖,非公平鎖,樂觀鎖,悲觀鎖。

Synchronized底層是通過監視器的enter和exit實現
https://my.oschina.net/cnarthurs/blog/847801
http://blog.csdn.net/a314773862/article/details/54095819

用過哪些原子類,他們的原理是什麼。

AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基於CAS原語實現 ,比較並交換、加載鏈接/條件存儲,最壞的情況下是旋轉鎖
https://www.ibm.com/developerworks/cn/java/j-jtp11234/index.html
http://www.jmatrix.org/java/848.html

用過線程池嗎,newCache 和 newFixed 有什麼區別,他們的原理簡單概括下,構造函數的各個參數的含義是什麼,比如 coreSize,maxsize 等。

newSingleThreadExecutor返回以個包含單線程的Executor,將多個任務交給此Exector時,這個線程處理完一個任務後接着處理下一個任務,若該線程出現異常,將會有一個新的線程來替代。

newFixedThreadPool返回一個包含指定數目線程的線程池,如果任務數量多於線程數目,那麼沒有沒有執行的任務必須等待,直到有任務完成爲止。

newCachedThreadPool根據用戶的任務數創建相應的線程來處理,該線程池不會對線程數目加以限制,完全依賴於JVM能創建線程的數量,可能引起內存不足。
底層是基於ThreadPoolExecutor實現,藉助reentrantlock保證併發。
coreSize核心線程數,maxsize最大線程數。
http://ifeve.com/java-threadpoolexecutor/

線程池的關閉方式有幾種,各自的區別是什麼。

Shutdown shutdownNow tryTerminate 清空工作隊列,終止線程池中各個線程,銷燬線程池
http://blog.csdn.net/xxcupid/article/details/51993235

假如有一個第三方接口,有很多個線程去調用獲取數據,現在規定每秒鐘最多有 10 個線程同時調用它,如何做到。

ScheduledThreadPoolExecutor 設置定時,進行調度。
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}

http://ifeve.com/java-scheduledthreadpoolexecutor/

spring 的 controller 是單例還是多例,怎麼保證併發的安全。

單例
通過單例工廠 DefaultSingletonBeanRegistry實現單例
通過保AsyncTaskExecutor持安全

面試問我,創建多少個線程合適?

其實多線程使用,所需線程數和實際場景息息相關,如果是 CPU 密集型(例如:1-1000 萬累加計算)則是 CUP核心數+1,如果是IO 密集型(數據庫訪問,遠程調用)則是:最佳線程數 = (1/CPU利用率) = 1 + (I/O耗時/CPU耗時)

https://www.jianshu.com/p/f30ee2346f9f

ThreadLocal 用過麼,用途是什麼,原理是什麼,用的時候要注意什麼。

Threadlocal底層是通過threadlocalMap進行存儲鍵值 每個ThreadLocal類創建一個Map,然後用線程的ID作爲Map的key,實例對象作爲Map的value,這樣就能達到各個線程的值隔離的效果。
ThreadLocal的作用是提供線程內的局部變量,這種變量在線程的生命週期內起作用,減少同一個線程內多個函數或者組件之間一些公共變量的傳遞的複雜度。

誰設置誰負責移除

http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/

如果讓你實現一個併發安全的鏈表,你會怎麼做。

Collections.synchronizedList() ConcurrentLinkedQueue
http://blog.csdn.net/xingjiarong/article/details/48046751

有哪些無鎖數據結構,他們實現的原理是什麼。

LockFree,CAS
基於jdk提供的原子類原語實現,例如AtomicReference
http://blog.csdn.net/b_h_l/article/details/8704480

講講 java 同步機制的 wait 和 notify。

首先這兩個方法只能在同步代碼塊中調用,wait會釋放掉對象鎖,等待notify喚醒。
http://blog.csdn.net/ithomer/article/details/7685594

多線程如果線程掛住了怎麼辦。

根據具體情況(sleep,wait,join等),酌情選擇notifyAll,notify進行線程喚醒。
http://blog.chinaunix.net/uid-122937-id-215913.html

countdowlatch 和 cyclicbarrier 的內部原理和用法,以及相互之間的差別。

CountDownLatch是一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它運行一個或者多個線程一直處於等待狀態。
CyclicBarrier要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障纔會開門,所有被屏障攔截的線程纔會繼續運行。
CyclicBarrier初始化的時候,設置一個屏障數。線程調用await()方法的時候,這個線程就會被阻塞,當調用await()的線程數量到達屏障數的時候,主線程就會取消所有被阻塞線程的狀態。
前者是遞減,不可循環,後者是遞加,可循環用
countdowlatch 基於abq cb基於ReentrantLock Condition
http://www.jianshu.com/p/a101ae9797e3
http://blog.csdn.net/tolcf/article/details/50925145

使用 synchronized 修飾靜態方法和非靜態方法有什麼區別。

對象鎖和類鎖
https://yq.aliyun.com/articles/24226

簡述 ConcurrentLinkedQueue LinkedBlockingQueue 的用處和不同之處。

LinkedBlockingQueue 是一個基於單向鏈表的、範圍任意的(其實是有界的)、FIFO 阻塞隊列。
ConcurrentLinkedQueue是一個基於鏈接節點的無界線程安全隊列,它採用先進先出的規則對節點進行排序,當我們添加一個元素的時候,它會添加到隊列的尾部,當我們獲取一個元素時,它會返回隊列頭部的元素。它採用了“wait-free”算法來實現,該算法在Michael & Scott算法上進行了一些修改, Michael & Scott算法的詳細信息可以參見參考資料一。
http://ifeve.com/concurrentlinkedqueue/
http://ifeve.com/juc-linkedblockingqueue/
http://blog.csdn.net/xiaohulunb/article/details/38932923

導致線程死鎖的原因?怎麼解除線程死鎖。

死鎖問題是多線程特有的問題,它可以被認爲是線程間切換消耗系統性能的一種極端情況。在死鎖時,線程間相互等待資源,而又不釋放自身的資源,導致無窮無盡的等待,其結果是系統任務永遠無法執行完成。死鎖問題是在多線程開發中應該堅決避免和杜絕的問題。
一般來說,要出現死鎖問題需要滿足以下條件:

  1. 互斥條件:一個資源每次只能被一個線程使用。
  2. 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
  3. 不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪。
  4. 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。
    只要破壞死鎖 4 個必要條件之一中的任何一個,死鎖問題就能被解決。
    https://www.ibm.com/developerworks/cn/java/j-lo-deadlock/

非常多個線程(可能是不同機器),相互之間需要等待協調,才能完成某種工作,問怎麼設計這種協調方案。
此問題的本質是保持順序執行。可以使用executors

TCP 與 HTTP

TCP與UDP的區別
TCP 是面向連接的,UDP 是面向無連接的
UDP程序結構較簡單
TCP 是面向字節流的,UDP 是基於數據報的
TCP 保證數據正確性,UDP 可能丟包
TCP 保證數據順序,UDP 不保證
TCP與HTTP協議的關係
關於TCP/IP和HTTP協議的關係,網絡有一段比較容易理解的介紹:“我們在傳輸數據時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別數據內容,如果想要使傳輸的數據有意義,則必須使用到應用層協議,應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。WEB使用HTTP協議作應用層協議,以封裝HTTP 文本信息,然後使用TCP/IP做傳輸層協議將它發到網絡上。”

http1.0 和 http1.1 有什麼區別。
HTTP 1.0主要有以下幾點變化:
請求和相應可以由於多行首部字段構成
響應對象前面添加了一個響應狀態行
響應對象不侷限於超文本
服務器與客戶端之間的連接在每次請求之後都會關閉
實現了Expires等傳輸內容的緩存控制
內容編碼Accept-Encoding、字符集Accept-Charset等協商內容的支持
這時候開始有了請求及返回首部的概念,開始傳輸不限於文本(其他二進制內容)

HTTP 1.1加入了很多重要的性能優化:持久連接、分塊編碼傳輸、字節範圍請求、增強的緩存機制、傳輸編碼及請求管道。
http://imweb.io/topic/554c5879718ba1240cc1dd8a

請畫出三次握手和四次揮手的示意圖
爲什麼連接的時候是三次握手?
什麼是半連接隊列?
ISN(Initial Sequence Number)是固定的嗎?
三次握手過程中可以攜帶數據嗎?
如果第三次握手丟失了,客戶端服務端會如何處理?
SYN攻擊是什麼?
揮手爲什麼需要四次?
四次揮手釋放連接時,等待2MSL的意義?

https://blog.csdn.net/hyg0811/article/details/102366854

TIME_WAIT 和 CLOSE_WAIT 的區別。
TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。

說說你知道的幾種 HTTP 響應碼,比如 200, 302, 404。
1xx:信息,請求收到,繼續處理
2xx:成功,行爲被成功地接受、理解和採納
3xx:重定向,爲了完成請求,必須進一步執行的動作
4xx:客戶端錯誤,請求包含語法錯誤或者請求無法實現
5xx:服務器錯誤,服務器不能實現一種明顯無效的請求
200 ok 一切正常
302 Moved Temporatily 文件臨時移出
404 not found
https://my.oschina.net/gavinjin/blog/42856

當你用瀏覽器打開一個鏈接的時候,計算機做了哪些工作步驟。
Dns解析–>端口分析–>tcp請求–>服務器處理請求–>服務器響應–>瀏覽器解析—>鏈接關閉

TCP/IP 如何保證可靠性,說說 TCP 頭的結構。
使用序號,對收到的TCP報文段進行排序以及檢測重複的數據;使用校驗和來檢測報文段的錯誤;使用確認和計時器來檢測和糾正丟包或延時。//TCP頭部,總長度20字節
typedef struct _tcp_hdr
{
unsigned short src_port; //源端口號
unsigned short dst_port; //目的端口號
unsigned int seq_no; //序列號
unsigned int ack_no; //確認號
#if LITTLE_ENDIAN
unsigned char reserved_1:4; //保留6位中的4位首部長度
unsigned char thl:4; //tcp頭部長度
unsigned char flag:6; //6位標誌
unsigned char reseverd_2:2; //保留6位中的2位
#else
unsigned char thl:4; //tcp頭部長度
unsigned char reserved_1:4; //保留6位中的4位首部長度
unsigned char reseverd_2:2; //保留6位中的2位
unsigned char flag:6; //6位標誌
#endif
unsigned short wnd_size; //16位窗口大小
unsigned short chk_sum; //16位TCP檢驗和
unsigned short urgt_p; //16爲緊急指針
}tcp_hdr;

https://zh.bywiki.com/zh-hans/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

如何避免瀏覽器緩存。
無法被瀏覽器緩存的請求:
HTTP信息頭中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告訴瀏覽器不用緩存的請求
需要根據Cookie,認證信息等決定輸入內容的動態請求是不能被緩存的
經過HTTPS安全加密的請求(有人也經過測試發現,ie其實在頭部加入Cache-Control:max-age信息,firefox在頭部加入Cache-Control:Public之後,能夠對HTTPS的資源進行緩存,參考《HTTPS的七個誤解》)
POST請求無法被緩存
HTTP響應頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被緩存
http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/

簡述 Http 請求 get 和 post 的區別以及數據包格式。

http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://www.360doc.com/content/12/0612/14/8093902_217673378.shtml

簡述 HTTP 請求的報文格式。
參考上面

HTTPS 的加密方式是什麼,講講整個加密解密流程。
加密方式是tls/ssl,底層是通過對稱算法,非對稱,hash算法實現
客戶端發起HTTPS請求 –》2. 服務端的配置 –》
3. 傳送證書 —》4. 客戶端解析證書 5. 傳送加密信息 6. 服務段解密信息 7. 傳輸加密後的信息 8. 客戶端解密信息
http://www.cnblogs.com/zhuqil/archive/2012/07/23/2604572.html
————————————————
版權聲明:本文爲CSDN博主「晴天小哥哥」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_38399962/article/details/80358168

轉載於CSDN博主[晴天小各個]
原文鏈接:https://blog.csdn.net/weixin_38399962/article/details/80358168

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章