前言
美團由於其技術棧的方向爲Java
所以他問的問題都是Java
,但是由於我的方向是C++
所以他並沒有怎麼問Java
的問題。並且美團的招聘小哥態度很好,我遇到不會回答的問題的時候,他都會給我說沒事的,雖然這句話沒多大的作用。但是對我而言也有很好的緩解緊張的作用,經過這次面試我愈發嚮往這種新型互聯網公司的工作氛圍,也希望這次面試能有一個好結果。下面我就來複現一下面試過程中的一些問題。
算法題目
題目一
給出一個數組,實現最終分組功能。例[1,1,1,2,2,3,3]分組爲[1,1,1],[2,2],[3,3],每一個分組的長度如果相同那麼就可以確認爲true
,每一組長度必須大於1。
幾個例子:
- [1,1,2,2,3,3,3,3]分組爲[1,1],[2,2],[3,3],[3,3],每一組的長度相同則返回
true
; - [1,1,2,2,2,3,3,3]分組爲[1,1],[2,2,2],[3,3,3],每一組的長度不一致則返回
false
; - [1]分組爲[1],組長度不滿足大於1則返回
false
; - [1,1]分組爲[1,1],每一組的長度一致則返回
true
; - [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的人出列;依此循環下去,直到剩餘一個人。求最後這一個人在最開始的序列中編號是幾號?輸入N
和M
例:
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我是一個都不會,當場自閉了。
總結
雖然這次面試表現不是很好,但是也給我提出一個警報,學校學習的內容和公司需要的可能完全不同。而且工程技術人員比較喜歡問數據庫有關的知識,這一個需要回去惡補了。希望這次面試能有一個好結果吧,雖然希望渺茫,但是還是要期待一下的!!哈哈