騰訊筆經面經(微信事業羣)

微信事業羣
時間:20190831 時長:1小時30分
地點:牛客遠程視頻

一分鐘自我介紹

一、上手code

1、手寫字符串的反轉
我的code:

public String stringReserve(String inputString) {
        int length = inputString.length();
        if(inputString == null || length == 0) {
            return null;
        }
        
        return reverse(inputString.toCharArray(), 0, length-1);
    }
    
    private String reverse(char[] str, int start, int end) {
        while (start < end) {
            char temp = str[start];
            str[start++] = str[end];
            str[end--] = temp;
        }
        return str.toString();
    }

2、 手寫雙向鏈表
我的code:

public class LinkedList{
        private Node root;
        
        public class Node{
            private Object data;
            private Node preNode;
            private Node next;
        }
        
        public Node getRoot(){
            return this.root;
        }
        
        public void setRoot(Node root) {
            this.root = root;
        }
    }

3、按照順序合併兩個鏈表,手寫代碼
我的code:

public Node merge(LinkedList first, LinkedList second) {
        if(first == null && second == null) return null;
        if (first != null && second == null) {
            return first.getRoot();
        }
        if (first == null && second != null) {
            return second.getRoot();
        }

        Node newNode;
        Node temp;
        Node  temp1 = new Node();
        Node temp2 = new Node();
        if (first.getRoot().data < second.getRoot().data) {
            newNode = first.root;
            temp = newNode.next;
            temp1 = temp;
        }
        else {
            newNode = second.root;
            temp = newNode.next;
            temp2 = temp;
        }
        
        while (temp1 != null && temp2 != null) {
            if(temp1.data < temp2.data) {
                temp.next = temp1;
                temp1 = temp1.next;
            }
            else {
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        
        if (temp1 != null) {
            temp.next = temp1;
        }

        if (temp2 != null) {
            temp.next = temp2;
        }     
        return newNode;   
    }

4、手寫快排算法,問了快排的時間複雜度,什麼情況是最差的
我的回答:快排時間最好情況是O(nlogn),最差O(n*n);最差情況是目標排序數組是有序的,基數每次移動都是移動一步,類似於冒泡排序
我的code:

public void quickSort (int[] array, int start, int end) {
        if (array == null || array.length == 0) {
            return;
        }
        
        int i = start, j = end;
        int temp = array[start];
        
        while (i < j) {
            while(array[j] > temp && i < j) {
                --j;
            }
            while(array[i] <= temp && i < j) {
                ++i;
            }
            
            int x = array[i];
            array[i] = array[j];
            array[j] = x;
        }

        array[start] = array[i];
        array[start] = temp;
        
        quickSort(array, start, i-1);
        quickSort(array, i+1, end);
    }

二、技術面試

  1. “ == ”和equals的區別
== 是比較兩個引用之間是否指向同一個對象,也就是比較兩個引用存儲的地址是否相等
equals在Object中比較的是兩個對象的hashcode,日常我們實現基類時覆蓋Object的equals方法,
例如User時,在equals中對屬性name,age進行比較
  1. Hash算法你知道哪些?
我只知道一致性hash算法,然後拓展的說了下自己在項目中如何用到一致性哈希
算法的(Dubbo的一致性哈希算法實現負載均衡算法)
  1. 哈希碰撞的解決方案有哪些?說說開放定址法原理
- HashMap應用的鏈表法
- 開放定製法:感興趣自行百度下,太多了,博主就不囉嗦了
  1. TreeMap和HashMap 的區別
看過源碼,瞭解TreeMap是基於紅黑樹的,所以元素是有序的
HashMap是基於哈希算法的,元素是亂序存放
  1. 說說紅黑樹和Avl樹
讀者自行百度?
  1. 緩存淘汰算法
我的第一想法是Redis的LRU算法,之前看過Redis的源碼,所以直接說了Redis幾種常用的淘汰算法,
包括隨機淘汰算法,FIFO淘汰算法,以及默認算法:刪除不常用的key,使用雙向鏈表維護所有被
使用的key,頻繁使用的key存放在鏈表的表頭附近,淘汰機制只需要淘汰表尾的元素
  1. TCP三次握手、四次揮手
  2. HTTP、HTTPS的區別
有必要和讀者說說這兒:
- HTTPS相對於HTTP的文本傳輸變換爲二進制傳輸,安全快捷
- HTTPS添加SSL協議,保障傳輸安全
- HTTPS默認支持長連接,採用多路複用機制
- HTTPS服務端支持反饋更多信息給應用端
  1. SSL過程
讀者自行百度,博主建議挖透式學習
  1. 進程和線程的共同點和區別
共同點:擁有CPU的執行權、切換
區別:
- 進程可包含多個線程
- 進程管理資源,線程不能
- 進程之間的切換消耗比線程之間的切換大
- 線程之間共享進程的公共資源
  1. 進程之間的通信,線程之間的通信
進程之間可以通過RPC、消息中間件、Socket,全局變量等通信
線程之間可以通過共享變量、管道、wait/notify機制
  1. 你知道協程吧?
不知道?
  1. 你知道系統中的大小端吧?
不知道?
  1. 你用過BIO、NIO、AIO,說說他們之間的區別吧
BIO:同步阻塞式,一個socket請求對應一個線程處理,耗時耗資源
NIO:同步非阻塞,socket請求由線程池來處理(boss、worker線程池原理)
AIO:異步化
我另外解釋了下系統底層的實現select、poll、epoll的區別:
- select每次執行select方法,都會從用戶態拷貝所有的fd文件到內核態中,存儲在內核態的數組中,數組大小默認1024個,存放的fd文件數量受限制
- select採用輪訓的方式尋找有事件的fd文件
- 對有事件的fd文件再次拷貝到用戶態做相應的處理
- epoll有三個函數:epoll_create、epoll_ctl、epoll_wait,epoll_create在內核態啓動時創建紅黑樹和就緒隊列,紅黑樹相對於select的數組所容納的fd文件數量更多,效率更高
- epoll_ctl負責將用戶態的fd文件符拷貝到內核的紅黑樹中,並且制定相應的回調接口,當fd文件符有事件時,回調接口,將fd文件移動到就緒隊列中
- epoll_wait負責監聽就緒隊列是否有就緒的fd文件,有的話拷貝到用戶態,否則,繼續睡眠,等待被喚醒
  1. 內核態與用戶態的交互過程
我按照自己理解說了下線程之間的上下文切換,進程之間的切換,主要是一些信息的拷貝,比較耗時,
如果切換次數過多的話,會對CPU的性能帶來影響。
  1. 怎麼看系統的CPU信息
我說到常用的TOP命令會看到系統的CPU使用率,內存等信息;還有vmstat查看上下文切換信息
  1. 給了我一段代碼
String a = "aaaaaa";
int b;
int test (int i) {
	b = i;
}
int main () {
	int temp = 0;
	int c = test(temp);
	return c;
}	

問在進程中這些信息的佈局
我的回答:

變量a:首先字符串在JVM中是常量,所以a變量肯定存放在常量池中,而常量池存放在JVM中的永久代中。
變量i、b、temp、c:基本變量類型和臨時變量都是存放在JVM棧的棧楨中,每個棧楨包含臨時變量,變量值等信息
方法test:方法是被線程調用的,所以方法存在於棧中,調用方法的過程進棧,返回方法的過程是出棧
  1. 給了一段代碼,問我char和int各佔幾個字節,這幾個變量一共佔了多少字節,JVM內存對齊知道嗎?
    代碼
struct {
	char a;
	int b;
	char c;
}

回答:

- char和int分別各佔2、4個字節
- 這幾個變量共佔了8個字節(這是我的回答,是錯誤的)
面試官問我知道JVM內存對齊知道嗎?我第一反應想到的是JVM內存中的對象佈局,
裏面有一塊內存叫對齊填充,意思是JVM對象頭佔用最少8個字節,
實例數據和對象頭+內存填充的內存必須是8字節的整數倍

面試官糾正:三個變量共佔用24個字節,因爲這一塊需要內存對齊,意思是按照內存分配最大的變量分配其
他變量的內存
  1. 用過什麼數據庫?在MySQL中使用什麼引擎?
- 之前使用的MySQL,在阿里實習轉正期間使用了Oracle
- 在MySQL中使用InnoDB引擎,還有一個叫MyISAM引擎
  1. 說說InnoDB和MyISAM的區別
- InnoDB支持事務,MyISAM不支持
- InnoDB支持行級鎖,MyISAM不支持,只支持表級鎖,當然InnoDB在where條件不是索引時也會使用表級鎖
- InnoDB傾向於數據的更改,MyISAM傾向於查詢,引用使用索引的不同
  1. 數據庫事務有幾個特性?分別是?
- 原子性
- 隔離型
- 一致性
- 持久性
  1. 說說隔離型中隔離級別有哪幾種?分別解決什麼問題
- 未提交讀:會出現髒讀、不可重複讀、幻讀
- 提交讀:避免出現髒讀,但是會出現不可重複讀、幻讀
- 可重複讀:避免不可重複讀,但是會出現幻讀
- serializable:避免出現幻讀
  1. MySQL如何解決在默認使用可重複讀隔離級別時出現的幻讀
數據庫學習時間很久了,我記得當對某一行數據進行操作時,MySQL默認會對周圍的行數據進行加鎖,
避免出現幻讀

面試官說相對地方了,它的專業名稱叫間隙型鎖
  1. 看你簡歷有分佈式經歷,使用Dubbo+Zookeeper,你說說分佈式事務
我給大家推薦我自己總結的一篇文章吧,
幾乎回答一樣:https://blog.csdn.net/qq_40910541/article/details/97974388
  1. 我說到我在項目中排查過分佈式事務空回滾的問題,和面試官一起交流了下事務空回滾的原因,解決方案
- 分佈式事務空回滾概念:分佈式事務一階段提交之後丟失了二階段的提交/回滾操作
- 分佈式事務空回滾導致原因(項目):系統一階段操作由於網絡阻塞導致超時回滾,
一階段恢復之後丟失二階段提交/回滾操作,導致一階段事務懸掛
- 排查問題過程:通過排查線上log日誌發現二階段回滾操作的時間比一階段提交的時間要早1秒,確定是分佈式事務空回滾導致
- 解決方案:1、我在系統中添加了事務懸掛預警,及時發現,及時解決。 2、TCC模塊實現30秒拒絕空回滾

面試官交流也很愉快,說他們部門是60秒拒絕空回滾
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章