基礎7

基礎7- 阿里大文娛

多多準備,保持面試的狀態。

項目

項目介紹
如果項目不能按時完成怎麼辦?

spring/springMVC

  1. springMVC的理解。
    Spring MVC是把跳轉等交給了核心控制器,就不用像Servlet一樣去配置對外訪問路徑了。

    Spring MVC是一個基於Java的實現了MVC設計模式的請求驅動類型的輕量級Web框架,通過把Model, View,Controller分離,將Web層進行職責解耦,將複雜的web應用分成邏輯清晰的幾部分,簡化開發,減少出錯,方便組內開發人員之間的配合。

  2. @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組件。
    
  3. 創建bean方法?
    (1)使用構造器創建Bean實例
    (2)使用靜態工廠方法創建Bean實例
    (3)調用實例工廠方法創建Bean實例
    參考代碼:https://blog.csdn.net/know9163/article/details/84067836、
    https://blog.csdn.net/ligeforrent/article/details/80744756
    (待實現。)

java

  1. 什麼是線程安全,如何實現線程安全?
    當一個類被多個線程進行訪問並且正確運行,它就是線程安全的。
    參考: http://www.cnblogs.com/molao-doing/articles/8908239.html
    https://blog.csdn.net/jinggod/article/details/78275763

  2. 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

  3. 線程池的原理?

  • 線程池的創建:
    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

算法與數據結構

  1. 兩個單鏈表重合。
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;
    }
}
  1. 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");
    }
}

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