Java面試

線程池

首先要明確爲什麼要使用線程池,使用線程池會帶來什麼好處?

• 線程是稀缺資源,不能頻繁的創建。

• 應當將其放入一個池子中,可以給其他任務進行復用。

• 解耦作用,線程的創建於執行完全分開,方便維護。

線程池是一種多線程處理形式,處理過程中將任務提交到線程池,任務的執行交由線程池來管理。
如果每個請求都創建一個線程去處理,那麼服務器的資源很快就會被耗盡,使用線程池可以減少創建和銷燬線程的次數,每個工作線程都可以被重複利用,可執行多個任務。

抽象類與接口區別

1.抽象類可以有構造方法,接口中不能有構造方法。

2.抽象類中可以有普通成員變量,接口中沒有普通成員變量!!!!!!!(注意重點在 普通 即 非靜態 和 變量!!!!)

3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。

悲觀鎖和樂觀鎖使用場景

樂觀鎖是在應用層加鎖,而悲觀鎖是在數據庫層加鎖(for update)

樂觀鎖顧名思義就是在操作時很樂觀,這數據只有我在用,我先儘管用,最後發現不行時就回滾。

悲觀鎖在操作時很悲觀,生怕數據被其他人更新掉,我就先將其先鎖住,讓別人用不了,我操作完成後再釋放掉。

悲觀鎖需要數據庫級別上的的實現,程序中是做不到的,如果在長事務環境中,數據會一直被鎖住,導致併發性能大大地降低。

一般來說如果併發量很高的話,建議使用悲觀鎖,否則的話就使用樂觀鎖。

如果併發量很高時使用樂觀鎖的話,會導致很多的併發事務回滾、操作失敗。

總之,衝突機率大用悲觀,小就用樂觀。

樂觀鎖不會發生併發搶佔資源

在多用戶環境中,在同一時間可能會有多個用戶更新相同的記錄,這會產生衝突。這就是著名的併發性問題。

1.悲觀鎖:指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個數據處理過程中,將數據處於鎖定狀態

2.樂觀鎖:假設不會發生併發衝突,只在提交操作時檢查是否違反數據完整性。樂觀鎖不能解決髒讀的問題。

線程安全就是多線程訪問時,採用了加鎖機制,當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程纔可使用。不會出現數據不一致或者數據污染。

線程不安全就是不提供數據訪問保護,有可能出現多個線程先後更改數據造成所得到的數據是髒數據。

死鎖和髒數據就是典型的線程安全問題。

簡單來說,線程安全就是: 在多線程環境中,能永遠保證程序的正確性。

只有存在共享數據時才需要考慮線程安全問題。

多線程會引出很多難以避免的問題, 如死鎖,髒數據,線程管理的額外開銷,等等。更大大增加了程序設計的複雜度。

在Java 8 中,如果一個桶中的元素個數超過 TREEIFY_THRESHOLD(默認是 8 ),就使用紅黑樹來替換鏈表

java內存區域:

hashmap

key value
初始化容量 1左移4位16容量 2的4次方

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

加載因子係數

1分成4等分0.25 0.25*3=0.75 在容量的3/4(0.75)的時候擴容

static final float DEFAULT_LOAD_FACTOR = 0.75f;

HashMap和Hashtable的區別

HashMap沒有考慮同步,是線程不安全的;Hashtable使用了synchronized關鍵字,是線程安全的

前者允許null作爲key,後者不允許null作爲key

從ConcurrentHashMap代碼中可以看出,它引入了一個“分段鎖”的概念,具體可以理解爲把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。

在ConcurrentHashMap中,就是把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中,ConcurrentHashMap中默認是把segments初始化爲長度爲16的數組。通過把整個Map分爲N個Segment(類似HashTable),可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。

HashMap的底層實現
Java8之前,其底層實現是數組+鏈表實現,Java8使用了數組+鏈表+紅黑樹實現

ConcurrentHashMap的具體實現

1、該類包含兩個靜態內部類HashEntry(節點)和Segment(桶);前者用來封裝映射表的鍵值對,後者用來充當鎖的角色

List有序 可以重複 set無序不可以重複

ArrayList的初始容量10 加載因子0.5

Vector的初始容量10 加載因子1

HashSet的初始容量爲16,加載因子0.75

HashMap的初始容量爲16,加載因子0.75 擴容增量:原容量的1倍

數據庫索引原理

索引原理必須清楚一種數據結構「平衡樹」(非二叉),也就是b tree或者 b+ tree,重要的事情說三遍:“平衡樹,平衡樹,平衡樹”。當然, 有的數據庫也使用哈希桶作用索引的數據結構 , 然而, 主流的RDBMS都是把平衡樹當做數據表默認的索引數據結構的。

線程和進程的區別
1、進程是一個“執行中的程序”,是系統進行資源分配和調度的一個獨立單位;

2、線程是進程的一個實體,一個進程中擁有多個線程,線程之間共享地址空間和其它資源

volatile關鍵字

該關鍵字可以保證可見性不保證原子性

ThreadLocal關鍵字

當使用ThreadLocal維護變量時,其爲每個使用該變量的線程提供獨立的變量副本,所以
每一個線程都可以獨立的改變自己的副本,而不影響其他線程對應的副本

線程池

java.util.concurrent.ThreadPoolExecutor類就是一個線程池。客戶端調用
ThreadPoolExecutor.submit(Runnabletask)提交任務

JVM劃分

1、方法區:常量、靜態變量、即時編譯器

2、堆內存:垃圾回收的主要場所

3、程序計數器

4、虛擬機棧(棧內存):保存局部變量、基本數據類型變量以及堆內存中某個對象的引用變量

5、本地方法棧

垃圾回收算法有哪些

1、引用計數

2、標記-清除 分兩個階段 第一階段從引用根節點開始標記所有被引用的對象,第二階段遍歷整個堆,把未標記的對象清除。

GC經常發生的區域是堆區,堆區還可以細分爲新生代、老年代、

內存溢出 內存泄露是導致內存溢出的原因之一

NIO和IO的主要區別

IO 面向流 阻塞IO

NIO 面向緩衝區 非阻塞IO 選擇器 選擇一個通道

雙親委派模型

(1).BootStrap ClassLoader:啓動類加載器,負責加載存放在%JAVA_HOME%lib目錄中的

(2).Extension ClassLoader:擴展類加載器,由sun.misc.Launcher$ExtClassLoader實現,負責加載%JAVA_HOME%libext目錄中的

(3).Application ClassLoader:應用程序類加載器,由sun.misc.Launcher$AppClassLoader實現,負責加載用戶類路徑classpath上所指定的類庫

Java8新特性

1、Lambda表達式允許我們將函數當成參數傳遞給某個方法

2、函數式接口@Functionallnterface來標明該接口是一個函數式接口

3、引入重複註解@Repeatable

4、接口中可以實現方法default方法

5、註解的使用場景拓寬

6、新的包java.time包

dubbo

Provider在容器裏面進行啓動,啓動之後往服務中心進行服務一個註冊,然後Consume訂閱之前註冊過的服務,如果服務發生改變註冊中心會通知Consume,Consume拿到訂閱關係之後就直接invoke調用Provider同時有個Monitor監控他們的調用情況

會員中心調用訂單中心

訂單需要提供一個接口給會員調用

Consumer:192.168.0-.192/com.tl.IOrderService?application=UserCp

數據庫索引作用 底層數據結構 爲什麼使用這種結構

索引 是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息

底層數據結構B+樹

使用B+樹的原因:查找速度快,效率高,

聚集索引和非聚集索引根本區別

是表記錄的排列順序和與索引的排列順序是否一致

聚集索引表記錄的排列順序和索引的排列順序一致

非聚集索引制定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致

MyISAM和InnoDB的區別

MyISAM不支持事務,InnoDB是事務類型的存儲引擎

MyISAM只支持表級鎖InnoDB支持行級鎖和表級鎖

MyISAM不支持外鍵InnoDB支持外鍵

MyISAM支持全文索引InnoDB不支持

MyISAM表不支持事務、不支持行級鎖、不支持外鍵

InnoDB表支持事務、支持行級鎖、支持外鍵

Spring 知識點

Spring 的 IOC 和 AOP

• IOC:控制反轉,(解耦合)將對象間的依賴關係交給 Spring 容器,使用配置文件來創建所依賴的對象,由主動創建對象改爲了被動方式;

• AOP:面向切面編程,將功能代碼從業務邏輯代碼中分離出來;

AOP 的實現方式有哪幾種?如何選擇?

JDK 動態代理實現和 cglib 實現

選擇:

  1. 如果目標對象實現了接口,默認情況下會採用 JDK 的動態代理實現 AOP,也可以強制使用 cglib 實現 AOP;
  2. 如果目標對象沒有實現接口,必須採用 cglib 庫,Spring 會自動在 JDK 動態代理和 cglib 之間轉換。

擴展:JDK 動態代理如何實現

JDK 動態代理,只能對實現了接口的類生成代理,而不是針對類,該目標類型實現的接口都將被代理。

原理是通過在運行期間創建一個接口的實現類來完成對目標對象的代理

Mybatis 知識點

關於 MyBatis 主要考察佔位符#和 $ 的區別,區別如下:

  1. 符號將傳入的數據都當做一個字符串,會對自動傳入的數據加一個雙引號;

  2. $ 符號將傳入的數據直接顯示生成 SQL 中;
  3. 符號存在預編譯的過程,對問號賦值,防止 SQL 注入;

  4. $符號是直譯的方式,一般用在 order by ${列名}語句中;
  5. 能用#號就不要用 $ 符號

Linux常用命令

文件和目錄:

pwd 顯示當前目錄

ls 顯示當前目錄下的文件和目錄:

  1. ls -F 可以區分文件和目錄;
  2. ls -a 可以把隱藏文件和普通文件一起顯示出來;
  3. ls -R 可以遞歸顯示子目錄中的文件和目錄;
  4. ls -l 顯示長列表
  5. ls -l test 過濾器,查看某個特定文件信息。可以只查看 test 文件的信息

處理文件方面的命令有:touch、cp、 In、mv、rm

處理目錄方面的命令:mkdir

查看文件內容:file、cat、more、less、tail、head

eg. 找出進程名中包括 java 的所有進程:ps -ef | grep java

top 命令 實時監測進程

壓縮數據

  1. tar -xvf 文件名
  2. tar -zxvf 文件名
  3. tar -cvzf 文件名

結束進程:kill PID 或者 kill all

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