基礎7- 阿里大文娛
多多準備,保持面試的狀態。
項目
項目介紹
如果項目不能按時完成怎麼辦?
spring/springMVC
-
springMVC的理解。
Spring MVC是把跳轉等交給了核心控制器,就不用像Servlet一樣去配置對外訪問路徑了。Spring MVC是一個基於Java的實現了MVC設計模式的請求驅動類型的輕量級Web框架,通過把Model, View,Controller分離,將Web層進行職責解耦,將複雜的web應用分成邏輯清晰的幾部分,簡化開發,減少出錯,方便組內開發人員之間的配合。
-
@service @Component @Controller的區別
(1) Service:用於標註業務層組件
(2) Componant :泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。
(3)Conroller:用於標識處理器類。@Service:用於標註業務層組件
@Controller:用於標註控制層組件(如struts中的action)
@Repository:用於標註數據訪問組件,即DAO組件
@Component:泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。
@Named:與@Component:存在細微的差距,基本上可以互相替換,習慣上不會使用。@Controller:用於標識是處理器類;
@ComponentScan:啓用組件掃描
詳見:https://www.cnblogs.com/anjunshuang/p/9100740.html
對於Spring引入的註解有四種:@Service,@Controller,@Repository,@Component。 對於@Service,用於標註業務層組件。 對於@Controller,用於標註控制層組件。 對於@Repository, 用於標註數據訪問層組件(即Dao層); 對於@Component,用於標註所有的組件,通常用於一個不宜歸於上述三種組件類型的Bean組件。
-
創建bean方法?
(1)使用構造器創建Bean實例
(2)使用靜態工廠方法創建Bean實例
(3)調用實例工廠方法創建Bean實例
參考代碼:https://blog.csdn.net/know9163/article/details/84067836、
https://blog.csdn.net/ligeforrent/article/details/80744756
(待實現。)
java
-
什麼是線程安全,如何實現線程安全?
當一個類被多個線程進行訪問並且正確運行,它就是線程安全的。
參考: http://www.cnblogs.com/molao-doing/articles/8908239.html
https://blog.csdn.net/jinggod/article/details/78275763 -
conCurrentHashMap的原理?
底層採用分段的數組+鏈表實現,線程安全。通過分析Hashtable就知道,synchronized是針對整張Hash表的,即每次鎖住整張表讓線程獨佔,ConcurrentHashMap允許多個修改操作併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對hash表的不同部分進行的修改。ConcurrentHashMap內部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的hash table,它們有自己的鎖。只要多個修改操作發生在不同的段上,它們就可以併發進行。
有些方法需要跨段,比如size()和containsValue(),它們可能需要鎖定整個表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢後,又按順序釋放所有段的鎖。這裏“按順序”是很重要的,否則極有可能出現死鎖,在ConcurrentHashMap內部,段數組是final的,並且其成員變量實際上也是final的,但是,僅僅是將數組聲明爲final的並不保證數組成員也是final的,這需要實現上的保證。這可以確保不會出現死鎖,因爲獲得鎖的順序是固定的。鎖分段技術:首先將數據分成一段一段的存儲,然後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。
參考:https://www.cnblogs.com/heyonggang/p/9112731.html -
線程池的原理?
- 線程池的創建:
public void ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize:線程池核心線程數量
maximumPoolSize:線程池最大線程數量
keepAliveTime:當活躍線程數大於核心線程數時,空閒的多餘線程最大存活時間
unit:存活時間的單位
workQueue:存放任務的對列
handler:超出線程範圍和隊列容量的任務處理程序
-
線程池的實現原理:
提交一個任務到線程池中,線程池的處理流程如下:
(1)判斷線程池裏的核心線程是否都在執行任務,如果不是(核心線程空閒或者還有核心線程沒有被創建)則創建一個新的工作線程來執行任務。如果核心線程都在執行任務,則進入下一個流程。
(2)線程池判斷工作隊列是否已滿,如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列裏。如果工作對列滿了,則進入下個流程。
(3)判斷線程池裏的線程是否都處於工作狀態,如果沒有,則創建一個新的工作線程來執行任務。如果已經滿了,則交給飽和策略來處理這個任務。 -
線程池的優點:
1、線程是稀缺資源,使用線程池可以減少創建和銷燬線程的次數,每個工作線程都可以重複使用。
2、可以根據系統的承受能力,調整線程池中工作線程的數量,防止因爲消耗過多內存導致服務器崩潰。
參考:https://www.cnblogs.com/dongguacai/p/6030187.html
算法與數據結構
- 兩個單鏈表重合。
public class Solution {
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int len1 = getLength(pHead1);
int len2 = getLength(pHead2);
int lenDif = len1 - len2;
ListNode headLong = pHead1;
ListNode headShort = pHead2;
if(len2 > len1){
headLong = pHead2;
headShort = pHead1;
lenDif = len2 - len1;
}
for(int i = 0; i < lenDif; i++){
headLong = headLong.next;
}
while (headLong != null && headShort != null && headLong != headShort){
headLong = headLong.next;
headShort = headShort.next;
}
return headLong;
}
public static int getLength(ListNode pHead){
int len = 0;
while (pHead != null){
len++;
pHead = pHead.next;
}
return len;
}
}
- two sum
第一種暴力破解
第二種可以使用hashmap以空間換取時間。
時間複雜度:O(n),空間複雜度:O(n)。
代碼實現:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
for (int i= 0; i < nums.length; i++){
int complement = target - nums[i];
if(map.containsKey(complement)){
return new int[]{map.get(complement), i};
}
map.put((nums[i]), i);
}
throw new IllegalArgumentException("no two sum solution");
}
}