21-0003 2020年3月25日的面試,開發崗位遇到的題目

1.簡歷投遞情況

前言:考研呢,自然是失敗了,開始了一邊找工作,一邊寫畢設的日子,於我而言項目經歷並不是特別的充足,而且考研時候學習的知識還剩下一丟丟,簡歷相對而言是比較空蕩蕩的,寫代碼的速度也比較慢,可能我就不適合做程序員?不,我就是程序員。
先說簡歷投遞:

青果靈動【接了個電話就沒消息了】
樂道互動【實習過兩個月,但是再投簡歷的時候完全沒有消息】
攜程【能力測試題寫完就沒啦】
快看世界【牛客網上投遞之後沒了消息】
華爲【目前寫了筆試題】
北京庚圖【筆試+面試,效果不太好,估計是涼了】
美團【目前只是投遞了簡歷】
三七互娛【寫了筆試題】
博樂科技【寫了筆試題】
京東方【莫得消息】
埃森哲【同上】
尚遊遊戲【沒有消息】
帆軟【沒有消息】
科大訊飛【麼有消息】
搜狗【麼有消息】

跟人覺得投遞還算比較積極,但是效果並不是很好,學習的動力並不是很足,但是我有學習的慾望,不想學的時候就開始寫博客,寫累了就去學習,話說我已經兩個星期沒有碰畢設了,似乎別人的都快完成啦,真的!我比較菜?不,我不承認。

2.知識掌握情況

2.1 C++

掌握不牢固的:

  • 遇到tree、map就開始發慌,二叉樹的那一大堆東西掌握的不是很好,圖的掌握情況更不好,相關的知識點總是記混。
  • 字符串處理的相關函數掌握不牢固,有個分割函數,總覺得用過,但就是想不起來。
  • 數據類型的轉化也不是特比好,比如string轉化爲int就比較噁心,當時沒想出來可以使用什麼函數,只能自己寫函數處理。
  • 數據的存儲、編譯過程、內存的管理掌握的並不是很好,比如虛函數列表,父類指針直線子類對象等,感覺很亂。
  • 關於循環中的++i,i++等究竟應該怎麼加,退出條件要不要等號,這樣的問題通常需要想很久。
  • 最後一個,與代碼相關的:遞歸的使用,非常之不熟練,即使能夠看懂別人的代碼,但是自己依舊不能復現。
  • 與線程有關的,與Linix有關的,與Qt有關,與MySQL有關的,看到就比較慌,不知所措。

比較熟練的:

  • 數組、動態數組、堆棧、向量、隊列這樣的數據結構,使用起來都比較好,但是初始化的時候需要編譯器的提示,自己總是忘記初始化的規則。
  • 排序算法也還好,快排現在應該是可以實現的,其他比較高級的LSD、MSD、shell sort等知道原理,自己實現可能要花費一些時間。
  • 面向對象的思想以及類的使用,比較熟練,現在寫稍稍長一點的代碼都傾向於使用面向對象,而不是面向過程。
  • 文件處理這一塊雖然談不上精通,但也用的得心應手。

2.2 Unity 3d

不太熟練的地方:有很多

  • Unity用了兩年,基本的操作都會,但是需要回憶,考研的時候沒有Unity好久都不實用了,Unity的基礎知識現在不是特別牢固。
  • Unity中函數的執行過程,以及執行順序?
  • Unity中的渲染流水線都有哪些過程?會進行什麼操作?
  • Unity中的協程與線程的異同有哪些?
  • 還有好多Unity的相關問題,似乎都不是特別的瞭解?

3.筆試面試情況

現在做過的筆試題目,只有北京庚圖,華爲,三七互娛,效果不是特別好,三七互娛考的是Unity知識點,還有一顆樹,好難受,不知道寫的代碼可不可以運行。

3.1 北京庚圖

兩道題目,一道代碼找錯題目,一道編程題(C語言)。
編程題:從輸入的字符串中析取出文件路徑,文件名,文件後綴。

比如:"C:\book library\This Is Dat.001.txt"
路徑名:C:\book library\
文件名:This Is Dat
後綴名:txt

當時太緊張了,以爲這路徑有蹊蹺,不知道Is是屬於路徑的,還是屬於文件的,竟然傻到用空格作爲劃分字符。
實際上,這裏應該從後往前讀取,第一個點分割的是文件名與後綴,第一個反斜槓分割的是路徑名與文件名。

3.2 華爲

三道編程題,奈何自己寫代碼速度實在是慢,在沒有百度的情況下!
第一道:輸入 IP地址 IP地址 子網掩碼 判斷兩個IP是不是來自同一個網絡
是的話就輸出 1 並且輸出網絡地址,如下:

輸入:IP地址1 IP地址2 子網掩碼
輸出:是否一致 IP1的網絡地址

輸入:192.168.127.1 192.168.127.2 255.255.255.0
輸出:1 192.168.127.0

輸入:192.168.127.1 192.168.125.2 255.255.255.0
輸出:0 192.168.127.0

我的代碼:

#include <iostream>
#include <string>
using namespace std;
//字符串轉化爲數字
int strint_to_int(string str) {
	int num = 0;
	for (int i = 0; i < str.size(); i++) {
		int temp = pow(10, str.size() - i - 1) * ((int)str[i] - 48);
		num += temp;
	}
	return num;
}
//字符串的分割,根據'.'
string* get_split(string str) {
	string* str_sp = new string[4];
	int index[3], count = 0;
	for (int i = 0; i < str.size(); i++) {
		if (str[i] == '.') {
			index[count++] = i;
		}
	}
	for (int i = 0; i < index[0]; i++)
		str_sp[0] += str[i];
	for (int i = index[0] + 1; i < index[1]; i++)
		str_sp[1] += str[i];
	for (int i = index[1] + 1; i < index[2]; i++)
		str_sp[2] += str[i];
	for (int i = index[2] + 1; i < str.size(); i++)
		str_sp[3] += str[i];
	return str_sp;

}
//獲取IP地址中的字符串
int* get_num(string str) {
	int* arr = new int[4];
	string* str_split = get_split(str);
	for (int i = 0; i < 4; i++) {
		arr[i] = strint_to_int(str_split[i]);

	}
	return arr;
}
//打印數組arr
void print_arr(int* arr, int num) {
	for (int i = 0; i < num; i++) {
		cout << arr[i] << ' ';
	}
}
int main() {
	string str1, str2, str3;
	cin >> str1;//讀入IP地址1
	cin >> str2;//讀入IP地址2
	cin >> str3;//讀入子網掩碼
	int* arr1 = get_num(str1);
	int* arr2 = get_num(str2);
	int* arr3 = get_num(str3);
	int* result = new int[4];
	int same = 0;
	//判斷是否一致
	if ((arr1[0] & arr3[0]) == (arr2[0] & arr3[0]))
		if ((arr1[1] & arr3[1]) == (arr2[1] & arr3[1]))
			if ((arr1[2] & arr3[2]) == (arr2[2] & arr3[2]))
				if ((arr1[3] & arr3[3]) == (arr2[3] & arr3[3]))
					same = 1;
	for (int i = 0; i < 4; i++) {
		result[i] = (arr1[i] & arr3[i]);
	}
	//輸出結果
	cout << same << ' ' << result[0] << '.' << result[1] << '.' << result[2] << '.' << result[3];
}

備註:我的代碼實在是太原生了,字符串分割的沒想起來,string轉化爲int也沒有想起來,只能自己寫函數進行轉化。最後竟然通過了測試,我也真的是覺得神奇。

題目中原來想要使用的函數s:

字符串分割函數:

//C++中沒有提供類似於python,java中那樣的對於字符串進行分割的函數,幸好當時沒寫出來
//只能自己寫一個函數,用來進行字符串的分割
vector<string> str_split(string str, char ch) {
	//不知道會匹配到幾個
	//返回string* 會不會不太合理
	//這裏返回的是vectir類型的變量,比較方便
	vector<string> v_str;
	string temp;
	for (int i = 0; i < str.size(); i++) {
		if (str[i] != ch) {
			temp.push_back(str[i]);
		}else {
			v_str.push_back(temp);
			temp = "";
		}
	}
	if (temp.size() > 0)//如果最後temp中是有元素的,也要壓如棧中
		v_str.push_back(temp);
	return v_str;
}

字符轉轉化爲整形:

#include <stdio.h>
int i = atoi("2234");//頭文件以及這個函數是可以完成轉換的
//可以理解爲auto to int

第二道:輸入一個只含有0或1的二維矩陣,計算該矩陣的最大子矩陣的面積,其中對於最大子矩陣的定義是方形的,原二維矩陣也是方形的,如下:

矩陣A:
1 1 1 0 0 
1 1 1 0 1
1 1 1 0 0
1 1 0 0 0
1 1 0 0 0

最大子矩陣:
1 1 1
1 1 1
1 1 1

面積:2

我的代碼,只通過了80%的測試用例,不知道是爲什麼????

#include <iostream>
#include <string>
using namespace std;

//檢測矩陣中是不是全爲1
//給定一個數組,從元素(x,y)處,向右向下開始判斷是否爲方形
bool mat_one_test(int** m, int x, int y, int d) {
	for (int i = x; i < x + d; i++) {
		for (int j = y; j < y + d; j++) {//直線寫的是j<x+d是一處錯誤
			if (m[i][j] != 1)
				return false;
		}
	}
	return true;
}

int main() {
	int d;
	cin >> d;
	//d = 3;
	char* str = new char[d];
	int** m = new int* [d];
	//int mat[3][3] = { {1,0,0},{1,1,1},{1,0,1} };

	//處理輸入,一一賦值到數組裏面
	for (int i = 0; i < d; i++) {
		cin >> str;
		m[i] = new int[d];
		for (int j = 0; j < d; j++) {
			m[i][j] = (int)str[j] - 48;
		}
	}
	int sub_m = 0;//子邊的長度
	int left, right;//左右下標
	//先找連續邊
	//獲取邊長然後對方形進行檢測,判斷是否是方形的
	//是否應該用矩陣直接進行對比
	//判斷這個矩陣中的元素是否全爲1
	for (int i = d; i > 0; i--) {
		for (int j = 0; j <= d - i; j++) {
			for (int k = 0; k <= d - i; k++) {
				if (mat_one_test(m, j, k, i)) {
					if (i > sub_m) {
						sub_m = i;
					}
				}
			}
		}
	}
	cout << sub_m * sub_m << endl;
}

輸入和輸出,如下:

4
1110
1110
1111
1111
9
//備註:輸入的時候先輸入邊長,然後不帶空格輸入數組信息,最後一行是得到的結果
//so?爲什麼不能全部通過測試?

備註:So?爲什麼會有20%的測試用例,是無法通過測試的

第三道:SJF作業調度問題?最後一道題目剩餘的時間很短,還沒來得及理解題意,大概是多cpu情況下的SJF調度?
恨自己當時爲什麼沒有複製下來,只想着提交試卷了!!!!!

3.3 三七互娛

問題1

Q:產生死鎖的四個條件?
A:

  1. 互斥 【臨界資源只能被一個進程使用】
  2. 請求與保持 【進程需要新資源的時候發出請求,並保持已有資源】
  3. 不可剝奪 【不能夠剝奪其他進程的資源】
  4. 循環等待 【若干進程首尾相連,循環等待】

問題2:Unity中協程與線程的區別?
Q:進程、線程、協程之間的關係?
A:

  1. 進程擁有自己獨立的堆和棧,既不共享堆,亦不共享棧,進程由操作系統調度.
  2. 線程擁有自己獨立的棧和共享的堆,共享堆,不共享棧,線程亦由操作系統調度(標準線程是的)。
  3. 協程和線程一樣共享堆,不共享棧,協程由程序員在協程的代碼裏顯示調度。
  4. 一個進程有一個主線程與多個輔線程,線程之間是平行運行的,在線程中可以開啓協程。

Q:線程與協程的區別?
A:

  1. 協程避免了無意義的調度,可以提高性能,因此需要程序員承擔起調度責任。
  2. 協程失去了標準線程使用多CPU的能力,只能使用一個CPU,不能並行。
  3. 在一個CPU上多線程交互進行,在多CPU上多線程可以並行。

Q:Unity中的協程?
A:

  1. U3d中協程的執行通過,yield return xxx,將程序掛起。
  2. 協程不是線程,在Update和LateUpdate中執行。

Link:unity 協程原理與線程的區別

問題3:TCP與UDP的異同
Q:TCP?
A:

  1. TCP(Transmission Control Protocol傳輸控制協議)。
  2. 傳輸層協議,是一種面向連接的,可靠的,基於字節流的傳輸通信協議。
  3. 面向連接,即在客戶端和服務器之間發送數據之間,必須先建立連接。
  4. 屬於傳輸層,位於應用層和IP層之間,因爲應用層需要可靠的連接,但是IP層沒有這樣的流機制。
  5. 連接需要建立三次握手、四次揮手斷開連接。
  6. 傳輸數據時可靠的。

Q:TCP連接建立:使用三次握手建立連接
A:

  1. 客戶端發送請求【尋址請求】
  2. 服務器端收到報文請求,迴應客戶端【確認請求】
  3. 客戶端收到服務端的報文進行迴應【連接請求】

Q:TCP終止一個連接——四次握手
A:

  1. 數據驗證請求碼
  2. 傳輸結束標記
  3. 確認結束標記
  4. 連接斷開標記

Q:UDP?
A:

  1. UDP(User Datagram Protocol用戶數據報協議)。
  2. 傳輸層協議。
  3. 無連接的數據報協議。
  4. 不能提供數據報分組,組裝和不能對數據報進行排序。
  5. 主要用於不要求分組順序到達的傳輸中,分組傳輸順序的檢查和排序有應用層完成。
  6. 提供面向事務的簡單不可靠傳遞服務。
  7. UDP協議使用端口分別運行在同一臺設備上的多個應用程序。
  8. 功能:爲了在給定的主機上能識別多個目的的地址,同時允許多個應用程序在同一臺主句上工作並能夠獨立地進行數據包的發送和接受,設計用戶數據報協議UDP。

Q:TCP與UDP的異同?
A:

  1. TCP是面向連接的(在客戶端和服務器之間傳輸數據之前要先建立連接),UDP是無連接的(發送數據之前不需要先建立連接)。
  2. TCP提供可靠的服務(通過TCP傳輸的數據。無差錯,不丟失,不重複,且按序到達);UDP提供面向事務的簡單的不可靠的傳輸。
  3. UDP具有較好的實時性,工作效率比TCP高,適用於對高速傳輸和實時性比較高的通訊或廣播通信。隨着網速的提高,UDP使用越來越多。
  4. 每一條TCP連接只能是點到點的,UDP支持一對一,一對多和多對多的交互通信。
  5. TCP對系統資源要去比較多,UDP對系統資源要求比較少。
  6. UDP程序結構更加簡單。
  7. TCP是流模式,UDP是數據報模式。

【原文地址】:什麼是TCP、UDP以及兩者的區別
備註:原文中錯別字有點多,不影響閱讀。

問題4
Q:Unity中函數的執行順序
A:11-0002 Unity中函數的執行過程

Unity函數的執行過程,都寫在了上面的博文中,主要是對Unity官網中的一篇文章進行了翻譯,看中文的話,勉強還是能看得懂的。

問題5
Q:Unity渲染管線的順序?
A:應用程序階段(CPU控制)、幾何階段(GPU控制)、光柵化階段(GPU控制)

鏈接:Unity3D Shader 渲染流程

問題6
Q:OSI七層模型?TCP/IP四層模型
A:OSI 七層模型和TCP/IP模型及對應協議(詳解)

上面文章中給出的解釋十分的清晰,推薦!

4.個人現狀

現在時間:2020年3月30日20:24:45
這篇文章大概是上週寫的,已經通過了背景庚圖的面試,拿到了offer,但是這家如同無心插柳,明天是華爲的面試,技術面試有兩輪,順便還約定了綜面,雖然不是特別能搞清楚面試流程,盡力就好!
.
特別緊張,聽說有基本軟件基礎、個人項目、手撕代碼,emm,手撕代碼這一項,我認爲是程序員必要的,但目前自己的能力不是很足,尚且還做不到,開篇就需要百度,比較噁心。

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