搜狗面經彙總

一、Java

說明類中public和private的基本區別

訪問權限

類內

包內

子類

不同包

public

Y

Y

Y

Y

protected

Y

Y

Y

N

default

Y

Y

N

N

private

Y

N

N

N

多線程用過嗎

hashmap:先介紹基本操作概念源碼,問爲什麼多線程環境下使用hashmap,entry鏈表會造成死循環。

volatile底層原理

volatile是變量修飾符,其修飾的變量具有可見性,Java的做法是將該變量的操作放在寄存器或者CPU緩存上進行,之後纔會同步到主存,使用volatile修飾符的變量是直接讀寫主存,volatile不保證原子性,同時volatile禁止指令重排。

sychronzied和lock區別

cas

jsp/servlet聯繫

集合都有哪些

arraylist和linkedlist區別

如何防止超賣

二、JVM

GC瞭解嗎

JVM內存分佈

程序計數器:記錄正在執行的虛擬機字節碼指令的地址(如果正在執行的是本地方法則爲空)。

Java虛擬機棧:每個 Java 方法在執行的同時會創建一個棧幀用於存儲局部變量表、操作數棧、常量池引用等信息。每一個方法從調用直至執行完成的過程,就對應着一個棧幀在 Java 虛擬機棧中入棧和出棧的過程。

本地方法棧:與 Java 虛擬機棧類似,它們之間的區別只不過是本地方法棧爲本地方法服務。

Java堆:幾乎所有對象實例都在這裏分配內存。是垃圾收集的主要區域("GC 堆"),虛擬機把 Java 堆分成以下三塊:

  • 新生代
  • 老年代
  • 永久代

新生代又可細分爲Eden空間、From Survivor空間、To Survivor空間,默認比例爲8:1:1。

方法區:方法區(Method Area)與Java堆一樣,是各個線程共享的內存區域。Object Class Data(類定義數據)是存儲在方法區的,此外,常量、靜態變量、JIT編譯後的代碼也存儲在方法區。

運行時常量池:運行時常量池是方法區的一部分。Class 文件中的常量池(編譯器生成的各種字面量和符號引用)會在類加載後被放入這個區域。除了在編譯期生成的常量,還允許動態生成,例如 String 類的 intern()。這部分常量也會被放入運行時常量池。

直接內存:直接內存(Direct Memory)並不是虛擬機運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域,但是這部分內存也被頻繁地使用,而且也可能導致OutOfMemoryError 異常出現。避免在Java堆和Native堆中來回複製數據。

jvm垃圾回收器

三、數據結構與算法

手寫算法:排序。給個文檔查找輸出想要的average

兩個棧實現一個隊列

import java.util.Stack;

/**
 * 用兩個棧實現隊列
 * 用兩個棧來實現一個隊列,完成隊列的Push和Pop操作。 隊列中的元素爲int類型。
 * 思路:
 * 棧A用來作入隊列,棧B用來出隊列
 * 當棧B爲空時,棧A全部出棧到棧B,棧B再出棧(即出隊列)
 */
public class Solution18 {
    public static void main(String[] args) {
        Solution18 solution18 = new Solution18();
        solution18.push(1);
        solution18.push(2);
        System.out.println(solution18.pop());
        solution18.pop();
    }

    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int node) {
        stack1.push(node);//stack1負責入隊
    }

    public int pop() {
        if (stack1.empty() && stack2.empty()) {
            throw new RuntimeException("隊列爲空");
        }
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();//stcak2負責出隊
    }
}

堆排序

public class HeapSort {
    /**
     * 構建大頂堆
     */
    public static void adjustHeap(int[] a, int i, int len) {
        int temp, j;
        temp = a[i];
        for (j = 2 * i; j < len; j *= 2) {// 沿關鍵字較大的孩子結點向下篩選
            if (j < len && a[j] < a[j + 1])
                ++j; // j爲關鍵字中較大記錄的下標
            if (temp >= a[j])
                break;
            a[i] = a[j];
            i = j;
        }
        a[i] = temp;
    }

    public static void heapSort(int[] a) {
        int i;
        for (i = a.length / 2 - 1; i >= 0; i--) {// 構建一個大頂堆
            adjustHeap(a, i, a.length - 1);
        }
        for (i = a.length - 1; i >= 0; i--) {// 將堆頂記錄和當前未經排序子序列的最後一個記錄交換
            int temp = a[0];
            a[0] = a[i];
            a[i] = temp;
            adjustHeap(a, 0, i - 1);// 將a中前i-1個記錄重新調整爲大頂堆
        }
    }

    public static void main(String[] args) {
        int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
        heapSort(a);
        System.out.println(Arrays.toString(a));
    }
} 

寫一個 “123” 轉爲123

public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        String s1 = "+2147483647";
        String s2 = "1a33";
        System.out.println(solution.StrToInt(s2));
    }

    /**
     * 判斷字符串爲空,長度爲0,判斷字符串轉換後上下界是否溢出
     *
     * @param str
     * @return
     */
    public int StrToInt(String str) {
        //判斷字符串是否爲空,長度是否爲0
        if (str == null || str.length() == 0) {
            return 0;
        }
        int start;
        int tag;//1表示+ 0表示-
        if (str.charAt(0) == '+') {
            start = 1;
            tag = 1;
        } else if (str.charAt(0) == '-') {
            start = 1;
            tag = 0;
        } else {
            start = 0;
            tag = 1;
        }
        long result = 0;
        for (int i = start; i < str.length(); i++) {
            char temp = str.charAt(i);
            if (temp >= '0' && temp <= '9') {
                result = result * 10 + (temp - '0');
                if (tag == 1 && result > Integer.MAX_VALUE) throw new RuntimeException("上溢出");
                if (tag == 0 && result < Integer.MIN_VALUE) throw new RuntimeException("下溢出");
            } else {
                return 0;
            }
        }

        if (tag == 0) {
            return (int) (-1 * result);
        } else {
            return (int) result;
        }
    }
}

水仙花數

public class Solution {
 
    public static void main(String[] args) {
        for (int i = 100; i <1000 ; i++) {
            int firstNum = i/100;
            int secondNum = i/10%10;
            int thirdNum = i%10;
            if(firstNum*firstNum*firstNum + secondNum*secondNum*secondNum+thirdNum*thirdNum*thirdNum == i){
                System.out.println("水仙花數爲:" + i);
            }
        }
    }
}

前序aebdc,後序bcdea,畫二叉樹

冒泡排序時間空間複雜度,複雜度什麼意思

統計三種顏色的球各自的個數(hashmap)

找出str中str1和str2之間的字符串

兩個排序的數組A和B分別含有m和n個數,找到兩個排序數組的中位數

二叉樹前序遍歷,中序遍歷,後序遍歷

約瑟夫環

構建有序二叉樹

四、網絡

http瞭解嗎 什麼長連接?怎麼設置,keep-Alive有哪些值,緩存瞭解嗎,有哪些消息頭域可以設置(cacheContral的值有哪些?)

http的長連接是怎麼實現的?

TCP四次揮手

所謂四次揮手(Four-Way Wavehand)即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。整個流程如下圖所示:

  1. 第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
  2. 第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
  3. 第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
  4. 第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。

C/S中使用TCP,C和S連不上的原因

如何防止post欺詐

https

GET和POST的區別

GET 請求:

  • GET 請求可被緩存
  • GET 請求保留在瀏覽器歷史記錄中
  • GET 請求可被收藏爲書籤
  • GET 請求不應在處理敏感數據時使用
  • GET 請求有長度限制
  • GET 請求只應當用於取回數據

POST 請求 :

  • POST 請求不會被緩存
  • POST 請求不會保留在瀏覽器歷史記錄中
  • POST 不能被收藏爲書籤
  • POST 請求對數據長度沒有要求

寫出幾個IP保留地址

0.0.0.0 不清楚主機和目的網絡集合

255.255.255.255 限制廣播地址

127.0.0.1 本機地址,用於測試

224.0.0.0到239.255.255.255 組播地址

五、數據庫

sql 三表查詢

數據庫的查詢優化除了索引還有什麼?

mysql查詢優化的方法

redis單線程還是多線程

redis持久化方式

redis的數據類型

查詢出每個員工對應的boss名字(left join)

六、設計模式

手寫一個單例模式。

public class Singleton {
    private volatile static Singleton instance = null;

    private Singleton() {

    }

    /**
     * 當第一次調用getInstance()方法時,instance爲空,同步操作,保證多線程實例唯一
     * 當第一次後調用getInstance()方法時,instance不爲空,不進入同步代碼塊,減少了不必要的同步
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

七、操作系統

linux vi命令 linux的其他命令知道哪些?查詢一個文件的某一列用shell實現

linux查看進程方法

八、框架

springboot和dubbo

springmvc流程

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