美團後端工程師面試

前言

美團由於其技術棧的方向爲Java所以他問的問題都是Java,但是由於我的方向是C++所以他並沒有怎麼問Java的問題。並且美團的招聘小哥態度很好,我遇到不會回答的問題的時候,他都會給我說沒事的,雖然這句話沒多大的作用。但是對我而言也有很好的緩解緊張的作用,經過這次面試我愈發嚮往這種新型互聯網公司的工作氛圍,也希望這次面試能有一個好結果。下面我就來複現一下面試過程中的一些問題。

算法題目

題目一

給出一個數組,實現最終分組功能。例[1,1,1,2,2,3,3]分組爲[1,1,1],[2,2],[3,3],每一個分組的長度如果相同那麼就可以確認爲true,每一組長度必須大於1。

幾個例子:

  1. [1,1,2,2,3,3,3,3]分組爲[1,1],[2,2],[3,3],[3,3],每一組的長度相同則返回true
  2. [1,1,2,2,2,3,3,3]分組爲[1,1],[2,2,2],[3,3,3],每一組的長度不一致則返回false
  3. [1]分組爲[1],組長度不滿足大於1則返回false
  4. [1,1]分組爲[1,1],每一組的長度一致則返回true
  5. [1,2,3,3,2,1]分組爲[1,1],[2,2],[3,3],每一組的長度相同則返回true

思路
使用map容器收集每一個權值出現頻度,
在這裏插入圖片描述
將所有數據分類收集之後,將每個收集容器裏面的權值的大小導入一個vector容器之中。
在這裏插入圖片描述
編寫一個函數實現計算兩個數最大公約數的功能,可以使用一般的順序相除法,也可以使用輾轉相除法

這裏以輾轉相除法作爲例子:

bool fun(int m,int n){
	int rem = m > n ? m : n;
	n = m > n ? n : m;
	m = rem;
	while(n > 0){
		rem = m % n;
		m = n;
		n = rem;
	}
	return m != 1;				
}

具體輾轉相除的原理可以看這一篇blog,通過這個算法就是得到兩個數的最大公約數是否爲1,如果爲1則返回false,反之返回true

最後對vector容器進行遍歷兩層,因爲兩兩數據如果出現了最大公約數爲1,則這兩個數是不滿足可分解的條件則認爲這兩個數不能分解,則該例不滿足要求返回false。另外當存在一個值爲1的時候這個時候也是不滿足可以分解爲非1長度組的要求的。

所以最終的算法就是下面這樣:

#include <iostream>
#include <vector>
#include <map>

using namespace std;

bool fun_1(int m,int n){
	int rem = m > n ? m : n;
	n = m > n ? n : m;
	m = rem;
	while(n > 0){
		rem = m % n;
		m = n;
		n = rem;
	}
	return m != 1;				
}

void fun_2(vector<int> vec_int) {
    map<int, int> map_int;
    for (auto temp : vec_int)
        map_int[temp]++;
    vector<int> vec;
    for (auto temp : map_int)
        vec.push_back(temp.second);
    for (int i = 0; i < vec.size(); i++)
    {
        if (vec[i] == 1)
        {
            cout << "false" << endl;
            return;
        }
        for (int j = i + 1; j < vec.size(); j++)
        {
            if (fun_1(vec[i], vec[j]) != true)
            {
                cout << "false" << endl;
                return;
            }
            
        }
    }
    cout << "true" << endl;
    return;
}

int main() {
    vector<int> vec_1{1,1,2,2,3,3,3,3};
    vector<int> vec_2{1,1,2,2,2,3,3,3};
    vector<int> vec_3{1};
    vector<int> vec_4{1,2,3,3,2,1};
    vector<int> vec_5{1,1,1,1,1,1};
    vector<int> vec_6{1,1,1,1,2,2,2,2,2,2};
    fun_2(vec_1);
    fun_2(vec_2);
    fun_2(vec_3);
    fun_2(vec_4);
    fun_2(vec_5);
    fun_2(vec_6);
}

執行結果如下圖:
在這裏插入圖片描述

題目二

已知n個人圍成一圈(編號:0,1,2,3,…,n-1),從編號爲0的人開始報數,報數爲m的那個人出列;從他的下一個人又從1開始數,同樣報數爲m的人出列;依此循環下去,直到剩餘一個人。求最後這一個人在最開始的序列中編號是幾號?輸入NM

例:
0,1,2,3,4按3報數,第一個出隊的人是2,第二個出隊的人是0,第三個出隊的人是4,第四個出隊的人是1,最終結果是3。

這種題目如果在短時間內想不到簡化方法,那麼最有效的方法就是暴力破解法。

使用電腦進行模擬這一操作的執行,最終當vec_int.size()大小爲1時結束循環。

#include <vector>
#include <iostream>

using namespace std;

void fun(int n, int m){
    vector<int> vec_int;
    for (int i = 0; i < n; i++)
        vec_int.push_back(i);
    vector<int>::iterator i = vec_int.end();
    while (vec_int.size() != 1)
    {
        int temp;
        temp = (m +vec_int.size() - 1) % vec_int.size();
        int t = 0;
        for (; i != vec_int.end() && t < temp; i++, t++);
        if (i == vec_int.end())
        {
            i = vec_int.begin();
            for (; i != vec_int.end() && t < temp; i++, t++);
        }
        cout << "----" << *i << endl;
        vec_int.erase(i);
        
    }
    cout << "****" << vec_int[0] << endl;
}

int main() {
    fun(5,3);
    fun(20,3);
}

執行結果:
在這裏插入圖片描述

專業問題

  • Q: OSI七層模型
    A: 物理層:定義物理接口標準;數據線鏈路層:在通信實體之間建立數據鏈路連接;網絡層:控制子網運行;傳輸層:定義數據傳輸的協議和端口;會話層;表示層;應用層。
  • Q: TCP和UDP的區別
    A:
TCP UDP
面向連接的傳輸 提供無連接的傳輸
提供可靠的傳輸 提供不可靠的傳輸
面向字節流的傳輸 面向數據報的傳輸
提供擁塞控制和流量控制機制 不提供擁塞控制和流量控制機制
  • Q: TCP三次握手過程,如果沒有最後一次握手會出現什麼情況?
    A: 在這裏插入圖片描述
    爲了實現可靠傳輸,發送方和接收方始終需要同步( SYNchronize )序號。 需要注意的是, 序號並不是從 0 開始的, 而是由發送方隨機選擇的初始序列號 ( Initial Sequence Number, ISN )開始 。 由於 TCP 是一個雙向通信協議, 通信雙方都有能力發送信息, 並接收響應。

剩下的一堆關於MySQL我是一個都不會,當場自閉了。

總結

雖然這次面試表現不是很好,但是也給我提出一個警報,學校學習的內容和公司需要的可能完全不同。而且工程技術人員比較喜歡問數據庫有關的知識,這一個需要回去惡補了。希望這次面試能有一個好結果吧,雖然希望渺茫,但是還是要期待一下的!!哈哈

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