辛辛苦苦工作一年,最後沒有調薪,可能是老闆覺得疫情不太好找工作,所以沒調薪吧。已成業務員。
本來沒打算換工作了,因爲使用目前的框架工作一年了,相對熟悉,開始多了時間學點東西。(換工作是真的累,又要重新找房子,又要重新熟悉新的工作環境,在前面幾個月基本上是別想着自己學點別的了,估計要被業務搞死)但是在boss上聯繫我了,我就也試試看看自己的水平了,最後被虐的體無完膚,好多個問題我都是不懂得。做一下記錄。
值得一提,面試官很好,整個面試的過程也比較放鬆,非常的尊重面試者,讓人感覺公司氛圍很棒。
首先,先給做了一份很基礎很基礎的筆試題(但是我還是有些不知道)。因爲我是視頻面試的,就直接打開面試題,面試官直接聽我表述。
1.簡述數組和鏈表的區別,以及適用環境?
數組,連續空間,訪問快。內存利用率不高。
鏈表,不連續空間,插入、刪除速度快,查找慢,內存利用率高。
經常查找用數組,不確定大小,經常插入刪除用鏈表。
2.簡述哈希表的大致原理,衝突解決方案,以及適用環境?
記錄的存儲位置=f(關鍵字)
原理:就是把Key通過一個固定的算法函數既所謂的哈希函數轉換成一個整型數字,然後就將該數字對數組長度進行取餘,取餘結果就當作數組的下標,將value存儲在以該數字爲下標的數組空間裏。(或者:把任意長度的輸入(又叫做預映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。)
衝突:當數據量夠大時,不同的關鍵字經過散列函數的計算得到了相同的散列地址。畢竟一個數組容量是有限的,這種可能性很大。
衝突解決:
1.開放定址法
這種方法也稱再散列法,其基本思想是:當關鍵字key的哈希地址p=H(key)出現衝突時,以p爲基礎,產生另一個哈希地址p1,如果p1仍然衝突,再以p爲基礎,產生另一個哈希地址p2,…,直到找出一個不衝突的哈希地址pi ,將相應元素存入其中。
2.再哈希法
這種方法是同時構造多個不同的哈希函數:
Hi=RH1(key) i=1,2,…,k
當哈希地址Hi=RH1(key)發生衝突時,再計算Hi=RH2(key)……,直到衝突不再產生。這種方法不易產生聚集,但增加了計算時間。
3.鏈地址法
這種方法的基本思想是將所有哈希地址爲i的元素構成一個稱爲同義詞鏈的單鏈表,並將單鏈表的頭指針存在哈希表的第i個單元中,因而查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用於經常進行插入和刪除的情況。
4.建立公共溢出區
這種方法的基本思想是:將哈希表分爲基本表和溢出表兩部分,凡是和基本表發生衝突的元素,一律填入溢出表。
3.網絡通訊協議中 TCP 協議 和 UDP 協議的 區別?
基於連接與無連接:TCP基於面向連接,UDP基於面向無連接;
系統資源的要求:TCP佔用的系統資源較多,UDP較少;
程序結構較簡單:TCP程序結構複雜,UDP程序結構簡單;
流模式與數據報模式:TCP是流模式,UDP是數據報模式;
可靠性:TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證。
4.進程間通訊的方式有哪些,各自有什麼優缺點?
1.管道:管道分爲有名管道和無名管道,其中無名管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用,一般用於兩個不同進程之間的通信。有名管道也是一種半雙工的通信方式,但它允許無親緣關係進程間的通信。
無名管道:優點:簡單方便;缺點:1)侷限於單向通信2)只能創建在它的進程以及其有親緣關係的進程之間;3)緩衝區有限;
有名管道:優點:可以實現任意關係的進程間的通信;缺點:1)長期存於系統中,使用不當容易出錯;2)緩衝區有限
2.信號:信號是一種比較複雜的通信方式,信號產生的條件:按鍵、硬件異常、進程調用kill函數將信號發送給另一個進程、用戶調用kill命令將信號發送給其他進程,傳遞的消息比較少用於通知接收進程某個時間已經發生
3.信號量:信號量是一個計數器,可以用來控制多個線程對共享資源的訪問,它不是用於交換大批數據,而用於多線程之間的同步。他常作爲一種鎖機制。因此,主要作爲進程間以及同一個進程內不同線程之間的同步手段
優點:可以同步進程;缺點:信號量有限
4.消息隊列:消息隊列是消息的鏈表,存放在內核中並由消息隊列標識符標識,消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等特點。
優點:可以實現任意進程間的通信,並通過系統調用函數來實現消息發送和接收之間的同步,無需考慮同步問題,方便;缺點:信息的複製需要額外消耗CPU的時間,不適宜於信息量大或操作頻繁的場合
5.共享內存:共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。他往往與其他通信機制,如信號量配合使用,來實現進程間的同步和通信。
優點:無須複製,快捷,信息量大;缺點:1)通信是通過將空間緩衝區直接附加到進程的虛擬地址空間中來實現的,因此進程間的讀寫操作的同步問題;2)利用內存緩衝區直接交換信息,內存的實體存在於計算機中,只能同一個計算機系統中的諸多進程共享,不方便網絡通信
6.套接字:套接字可用於不同及其間的進程通信。
流式套接字:提供可靠的,面向連接的通訊流
數據包套接字:定義一種無連接的服務,通過相互獨立的報文進行傳輸,是無序的
原始套接字:用於新的網絡協議的測試
優點:1)傳輸數據爲字節級,傳輸數據可自定義,數據量小效率高;2)傳輸數據時間短,性能高;3) 適合於客戶端和服務器端之間信息實時交互;4) 可以加密,數據安全性強
缺點:1) 需對傳輸的數據進行解析,轉化成應用級的數據
5.數據庫建立索引有什麼優缺點?有哪幾類常見的索引?
優點:
第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
第二,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
缺點:
第一,創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。
第二,索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。
第三,當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
常見類型:
index ----普通的索引,數據可以重複
fulltext----全文索引,用來對大表的文本域(char,varchar,text)進行索引。語法和普通索引一樣。
unique ----唯一索引,唯一索引,要求所有記錄都唯一
primary key ----主鍵索引,也就是在唯一索引的基礎上相應的列必須爲主鍵
6.常見的HTTP 請求方法有哪些,表示什麼意思?
序號 | 方法 | 描述 |
1 | GET |
發送請求來獲得服務器上的資源,請求體中不會包含請求數據,請求數據放在協議頭中。另外get支持快取、緩存 、可保留書籤等。冪等 |
2 | POST |
和get一樣很常見,向服務器提交資源讓服務器處理,比如提交表單、上傳文件等,可能導致建立新的資源或者對 原有資源的修改。提交的資源放在請求體中。不支持快取。非冪等 |
3 | HEAD |
本質和get一樣,但是響應中沒有呈現數據,而是http的頭信息,主要用來檢查資源或超鏈接的有效性或是否可以可達、檢 查網頁是否被串改或更新,獲取頭信息等,特別適用在有限的速度和帶寬下。 |
4 | PUT |
和post類似,html表單不支持,發送資源與服務器,並存儲在服務器指定位置,要求客戶端事先知 道該位置;比如post是在一個集合上(/province),而put是具體某一個資源上(/province/123)。所以put是安全的, 無論請求多少次,都是在123上更改,而post可能請求幾次創建了幾次資源。冪等 |
5 | DELETE | 請求服務器刪除某資源。和put都具有破壞性,可能被防火牆攔截。如果是https協議,則無需擔心。冪等 |
6 | CONNECT |
HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。就是把服務器作爲跳板,去訪問其他網頁 然後把數據返回回來,連接成功後,就可以正常的get、post了。 |
7 | OPTIONS | 獲取http服務器支持的http請求方法,允許客戶端查看服務器的性能,比如ajax跨域時的預檢等。 |
8 | TRACE |
回顯服務器收到的請求,主要用於測試或診斷。一般禁用,防止被惡意攻擊或盜取信息。 |
7.使用shell腳本統計~/src/下 .c結尾的文件的代碼行數
find . -name "*.c"|xargs cat|grep -v ^$|wc -l ^C
8.下述三個聲明有什麼區別?
char* const p; 定義一個指向字符的指針常數,即const指針,不能修改p指針指向別的變量,但是可以修改該指針指向的內容
char const* p; 此種寫法和const char *等價
const char* p; 定義一個指向字符常量的指針,不能用ptr來修改所指向的內容(*p的值爲const,不能修改)
9.char str1[] = "123";
char str2[] = "123";
const char str3[] = "123";
const char str4[] = "123";
const char* str5 = "123";
const char* str6 = "123";
char* str7 = "123";
char* str8 = "123";
cout << (str1 == str2) << endl;
cout << (str3 == str4) << endl;
cout << (str5 == str6) << endl;
cout << (str7 == str8) << endl;
cout << (str5 == str7) << endl;
打印結果是?
0,數組比較,地址比較
0,數組比較,地址比較
1,值比較
1,值比較
1,值比較
10.void* p1 = NULL;
char* p2 = "abc";
int* p3 = NULL;
double* p4 = NULL;
cout << sizeof(p1) << endl;
cout << sizeof(p2) << endl;
cout << sizeof(p3) << endl;
cout << sizeof(p4) << endl;
打印結果是?
都是4,指針大小爲4
11.void print_size(char str[])
{
cout << sizeof(str) << endl;
}
char str[] = "12345";
cout << sizeof(str) << endl;
print_size (str);
打印結果是?
6,4
12.struct A
{
char a0;
short b0;
int c0;
void* p;
int c1
short b1;
char a1;
}
cout << sizeof(A) << endl;
打印結果是?
20
13.char str[5];
strcpy(str, "12345");
上述代碼有無問題,若有,請指出?
越界。
14.char* str = "12345";
str[0] = 0;
上述代碼有無問題,若有,請指出?
對未知的地址進行賦值,有危險。
15.void alloc_memory(void* p, size_t s)
{
p = malloc(s);
}
char* str = NULL;
alloc_memory(str, 10);
strcpy(str, "12345");
上述代碼有無問題,若有,請指出?
沒問題
16.char* get_name()
{
char name[] = "hello kitty";
return &name[0];
}
上述代碼有無問題,若有,請指出?
生命週期結束,返回引用無法獲取想要的值。
然後是面試的部分。只能大概記錄出一些印象比較深刻的問題。
1.linux怎麼查看i\o的佔用。
iotop
2.linux怎麼查看單個線程的cpu佔用,和cpu內存。
top -H -p [PID] 顯示某個進程所有活躍的線程消耗情況 (-H設置線程模式)
3.如果你遠程到服務器去,要敲一些命令,然後因爲你的網絡波動,你可能會斷開網絡,你怎麼保證你敲的命令會被全部執行。
4.tcp如果保證消息傳輸的可靠。
校驗和、確認應答+序列號、超時重傳、流量控制、擁塞控制
5.http屬於哪一層。
HTTP協議是屬於應用層,與其它計算機進行通訊的一個應用,它是對應應用程序的通信服務的
6.linux你怎麼查看日誌,比如,我要查看100行至200行。
head -n 200 filename | tail -n 100
7.一個系統,多線程,調用動態庫的時候,內存會使用幾份動態庫的內存。
多線程調用動態庫時候,只會使用一份動態庫內存
8.簡述快速排序的原理。
先從數據序列中選取一個元素,並將序列中所有比該元素小的元素都放在它的左邊或者右邊,在分別對左右兩邊費別用以上的方法處理知道每一個待處理的序列的長度爲1
9.你的代碼是如何測試的,如何保證代碼質量的。
10.項目上線,出bug了怎麼辦。
我目前使用的框架是支持hotfix的,一般會hotfix,如果嚴重的bug,就停服更新。
11.你在項目中,使用了哪些數據庫,有什麼區別。
mysql,redis,
1.從類型上來說,mysql是關係型數據庫,redis是緩存數據庫
2.mysql用於持久化的存儲數據到硬盤,功能強大,但是速度較慢。redis用於存儲使用較爲頻繁的數據到緩存中,讀取速度快
3.mysql和redis因爲需求的不同,一般都是配合使用
12.進程間通信使用哪些。
信方式有管道、信號量、信號、消息隊列、共享內存、套接字。都有用過,現在使用最多的是消息隊列和套接字。
13.在使用python時,缺少相應的庫,而你又不是root權限,你怎麼辦。
14.有沒有使用過正則表達式。
以前有使用過,現在很久沒用了。
15.使用你沒用過的語言開發你覺得怎樣。
當時回答,我覺得不是什麼問題,就像我原來用c語言,現在用lua語言,我也是用了新語言開發。(應該回答,技術不能都是自己學過的,總要使用自己沒用過的,工作我覺得都是這樣)
16.你們的服務器是雲服務器麼,有沒有關注一些雲服務之類的。
阿里雲的雲服務器。暫時沒關注。
17.瞭解SSH麼。
應該是一種安全協議。具體不瞭解(SSH 爲建立在應用層基礎上的安全協議。SSH 是較可靠,專爲遠程登錄會話和其他網絡服務提供安全性的協議。利用 SSH 協議可以有效防止遠程管理過程中的信息泄露問題。)
總結:整個面試下來,沒有問過我一點項目上的東西,一點都沒有,全部是一些基礎,包括語言的基礎,服務器開發的基礎,linux命令的基礎。從這點可以看出,面試官是非常的重視基礎的。而我,應該也是不滿足他們的需求的,在我看來,我只是個業務員,不過也是開了眼界,又瞭解了服務器開發需要學習的東西。擎天柱用的框架是自己寫的,平常開發寫業務也是用的腳本,是什麼腳本我忘記了,只是知道是一種很像C語言的腳本,開發環境是linux不帶界面的(我用的是ubuntu,帶界面),也就是說一般開發都是在命令行下開發的,會這幾大量的shell腳本(我覺得這應該算是比較純正的oldschool開發,技術含量高),會遠程到服務器上查詢,甚至處理bug。
我現在使用的框架下,經理早就搭建好一切,包括打包,部署,更新,一切的一切,都已經全部寫好腳本,傻瓜式。在這裏再次覺得經理真的是牛逼。我也喪失了很多能在工作中被動學習這些的路徑。大多數碼農都是再寫業務代碼,希望自己能有一些進步吧。