美團點評2020校招系統開發方向筆試題

Brewin發表於2020-09-25

題目描述

如果線上某臺虛機CPU Load過高,該如何快速排查原因?只介紹思路和涉及的Linux命令即可 。

回答

造成cpu load過高的原因: Full gc次數的增大、程式碼中存在Bug(例如死迴圈、正則的不恰當使用等)都有可能造成cpu load 增高。
1. jps -v:檢視java程式號
2. top -Hp [java程式號]:檢視當前程式下最耗費CPU的執行緒
3. printf "%x\n" [步驟2中的執行緒號]:得到執行緒的16進製表示
4. jstack [java程式號] | grep -A100 [步驟3的結果]:檢視執行緒堆疊,定位程式碼行。

題目描述

請簡要描述MySQL資料庫聯合索引的命中規則,可舉例說明。

回答

1) MySQL聯合索引遵循最左字首匹配規則,即從聯合索引的最左列開始向右匹配,直到遇到匹配終止條件。例如聯合索引(col1, col2, col3), where條件為col1=`a` AND col2=`b`可命中該聯合索引的(col1,col2)字首部分, where條件為col2=`b` AND col3=`c`不符合最左字首匹配,不能命中該聯合索引。
2) 匹配終止條件為範圍運算子(>, <, between, like等)或函式等不能應用索引的情況。例如聯合索引(col1, col2, col3), where條件為col1=`a` AND col2>1 AND col3=`c`, 在col2列上為範圍查詢,匹配即終止,只會匹配到col1,不能匹配到(col1, col2, col3).
3) where條件中的順序不影響索引命中。例如聯合索引(col1, col2, col3), where條件為col3=`c` AND col2=b AND col1=`a`, MySQL最佳化器會自行進行最佳化,可命中聯合索引(col1, col2, col3).

題目描述

什麼是分散式事務,分散式事務產生的原因是什麼?分散式事務的解決方案有哪些?分別有哪些優缺點?

回答

分散式事物:將一次大的操作分為很多小的操作,這些小的操作位於各自的伺服器上,分散式事物需要保證這些小的操作要麼全部成功,要麼全部失敗。
分散式事物產生的原因:1.為了解決不同資料庫操作時資料不一致的問題。2.應用SOA話。
分散式事物的解決方案:
1.2PC:兩階段提交
優點:保證資料的強一致性,適合對資料要求高的強一致性領域。
缺點:實現複雜,犧牲了可用性,效能不高,不適合高併發,高效能的場景。
2.3PC:三階段提交
優點:相對於二階段,它減低了阻塞的範圍,解決了協調者這參與者同時掛掉的問題,即等待超時後,協調者或參與者會中斷事務,避免單點問題。
缺點:資料不一致性依然存在。
3.補償事務(TCC)
優點:1)效能提升,2)資料最終一致, 3)可靠性更高
缺點:花費高

題目描述

請描述https的請求過程。

回答

1) 客戶端向伺服器發起HTTPS請求,連線到伺服器的443埠;
2) 伺服器端有一個金鑰對,即公鑰(即數字證照)和私鑰,是用來進行非對稱加密使用的,伺服器端儲存著私鑰,不能將其洩露,公鑰可以傳送給任何人;
3) 伺服器將自己的公鑰傳送給客戶端;
4) 客戶端收到伺服器端的公鑰之後,檢查其合法性,如果發現發現公鑰有問題,那麼HTTPS傳輸就無法繼續,如果公鑰合格,則客戶端會生成一個客戶端金鑰,然後用伺服器的公鑰對客戶端金鑰進行非對稱加密成密文,至此,HTTPS中的第一次HTTP請求結束;
5) 客戶端發起HTTPS中的第二個HTTP請求,將加密之後的客戶端金鑰傳送給伺服器;
6) 伺服器接收到客戶端發來的密文之後,會用自己的私鑰對其進行非對稱解密,解密之後的明文就是客戶端金鑰,然後用客戶端金鑰對資料進行對稱加密,這樣資料就變成了密文;
7) 然後伺服器將加密後的密文傳送給客戶端;
8) 客戶端收到伺服器傳送來的密文,用客戶端金鑰對其進行對稱解密,得到伺服器傳送的資料。這樣HTTPS中的第二個HTTP請求結束,整個HTTPS傳輸完成。

題目描述

什麼是事務傳播行為?你知道Spring事務中都有哪些傳播型別嗎?如何使用/指定傳播型別?

1) 事務傳播用於描述當一個由事務傳播行為修飾的方法被巢狀入另外一個方法時,事務如何傳播。常用於定義發生事務巢狀時,如何繼續執行。
2) Spring 中共定義了7中事務傳播型別,明細如下表, 需答出3~4種常見型別即可:
    a) PROPAGATION_REQUIRED: 當前沒有事務時開啟新事務,如果有則加入;
    b) PROPAGATION_REQUIRES_NEW: 強制開啟新事務,掛起已有事務(如有);
    c) PROPAGATION_SUPPORTS: 當前有事務時加入, 沒有則以非事務方式執行;
    d) PROPAGATION_NOT_SUPPORTED: 以非事務方式執行, 掛起當前事務(如有);
3) 可以在註解或者XML中指定傳播型別, 如 “@Transactional(Propagation=xxx)

題目描述

IO設計中Reactor 和 Proactor 區別。

1、 Reactor被動的等待指示事件的到來並作出反應,有一個等待的過程,做什麼都要先放入到監聽事件集合中等待handler可用時再進行操作,實現相對簡單,對於耗時短的處理場景比較高效,但Reactor處理耗時長的操作會造成事件分發的阻塞,影響到後續事件的處理。
2、Proactor直接呼叫非同步讀寫操作,呼叫完後立刻返回,實現了一個主動的事件分離和分發模型;這種設計允許多個任務併發的執行,從而提高吞吐量;並可執行耗時長的任務(各個任務間互不影響),Proactor效能更高,能夠處理耗時長的併發場景,但Proactor實現邏輯複雜;依賴作業系統對非同步的支援,目前實現了純非同步操作的作業系統少,實現優秀的如windows IOCP,但由於其windows系統用於伺服器的侷限性,目前應用範圍較小;而Unix/Linux系統對純非同步的支援有限,應用事件驅動的主流還是透過select/epoll來實現。

連結:www.nowcoder.com/questionTerminal/...

以字串的形式讀入兩個數字,再以字串的形式輸出兩個數字的和。

輸入描述:

輸入兩行,表示兩個數字a和b,-109 <= a , b <= 109  ,用雙引號括起。

輸出描述:

輸出a+b的值,用雙引號括起。

示例1

輸入

"-26"
"100"

輸出

"74"

回答

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String num1 = in.nextLine().split("\"")[1];
        String num2 = in.nextLine().split("\"")[1];
        int sum = Integer.parseInt(num1)+Integer.parseInt(num2);
        System.out.println("\""+""+sum+"\"");
    }
}

連結:www.nowcoder.com/questionTerminal/...

給定一個字串,你的任務是計算這個字串中有多少個迴文子串(迴文串是一個正讀和反讀都一樣的字串)。

具有不同開始位置或結束位置的迴文串,即使是由相同的字元組成,也會被計為是不同的子串。

輸入描述:

輸入僅包含一個字串,長度不會超過 1000

輸出描述:

輸出僅包含一個非負整數, 代表輸入字串有多少個迴文子串。

示例1

輸入

abc

輸出

3

示例2

輸入

aaa

輸出

6

回答

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count = 0;
        StringBuilder sb=null;
        for (int i = 0; i < s.length(); i++) {
            for (int j = i; j < s.length(); j++) {
                sb = new StringBuilder(s.substring(i,j+1));
                if(sb.toString().equals(sb.reverse().toString())){
                    count++;
            }
            }
        }
        System.out.println(count);
    }
}

連結:www.nowcoder.com/questionTerminal/...

有 N 堆金幣排成一排,第 i 堆中有 C[i] 塊金幣。每次合併都會將相鄰的兩堆金幣合併為一堆,成本為這兩堆金幣塊數之和。經過N-1次合併,最終將所有金幣合併為一堆。請找出將金幣合併為一堆的最低成本。

其中,1 <= N <= 30,1 <= C[i] <= 100

輸入描述:

第一行輸入一個數字 N 表示有 N 堆金幣第二行輸入 N 個數字表示每堆金幣的數量 C[i]

輸出描述:

輸出一個數字 S 表示最小的合併成一堆的成本

示例1

輸入

4
3 2 4 1

輸出

20

示例2

輸入

30
10 20 30 40 50 60 70 80 90 100 99 89 79 69 59 49 39 29 19 9 2 12 22 32 42 52 62 72 82 92

輸出

7307

回答

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] money = new int[n+1];
        int[] preSum = new int[n+1];
        for(int i = 1; i <= n; i++){
            money[i] = sc.nextInt();
            if(i == 1) {
                preSum[i] = money[i];
            }
            else {
                preSum[i] = preSum[i-1] + money[i];
            }
        }
        sc.close();

        int[][] dp = new int[n + 1][n + 1];
        for(int len = 2; len <= n; len++){
            for(int i = 1; i <= n - len + 1; i++){
                int j = i + len - 1;
                dp[i][j] = Integer.MAX_VALUE;
                int sum = preSum[j] - preSum[i - 1];
                for(int k = i; k < j; k++){
                    dp[i][j] = Math.min(dp[i][j],dp[i][k] + dp[k + 1][j] + sum);
                }
            }
        }
        System.out.println(dp[1][n]);
    }
}

連結:www.nowcoder.com/questionTerminal/...

給定一組個字串,為每個字串找出能夠唯一識別該字串的最小字首。

輸入描述:

第一行輸入一個整數 n 表示字串個數後面n行,每行一個字串,一共n串互不相同的字串。(2 <= n <= 100,字串長度不超過100

輸出描述:

輸出n行,每行一個字串,依次是每個字串的最小可唯一識別字首

示例1

輸入

5
meituanapp
meituanwaimai
dianpingliren
dianpingjiehun
mt

輸出

meituana
meituanw
dianpingl
dianpingj
mt

備註:

如果一個字串S是另一個字串T的字首,則S的最小可識別字首為S

回答

import java.util.Scanner;  
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        String[] strings = new String[N];
        for (int i = 0; i < N; i++)
            strings[i] = scanner.next();
        scanner.close();
        for (String s : strings)
            System.out.println(unique(s, strings));
    }
    //返回字串s在字串陣列strings中最短唯一字首
    private static String unique(String s, String[] strings) {
        //字首初始為首字元
        String prefix = s.substring(0, 1);
        for (String single : strings) {
            //跳過字串s本身
            if (single.equals(s)){
                continue;
            }
            //字首被其他字串包含,繼續增加長度
            while (single.indexOf(prefix) == 0 && prefix.length() < s.length()) {
                prefix = s.substring(0, prefix.length()+1);   
            }
        }
        return prefix;
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章