計(jì)算機(jī)基礎(chǔ)與手撕代碼篇!準(zhǔn)算法工程師總結(jié)出的超強(qiáng)面經(jīng)(含答案)
極市導(dǎo)讀
作者燈會為21屆中部985研究生,七月份將入職某互聯(lián)網(wǎng)大廠cv算法工程師。在去年灰飛煙滅的算法求職季中,經(jīng)過幾十場不同公司以及不同部門的面試中積累出了CV總復(fù)習(xí)系列,此為計(jì)算機(jī)基礎(chǔ)與手撕代碼篇。 >>加入極市CV技術(shù)交流群,走在計(jì)算機(jī)視覺的最前沿
深度學(xué)習(xí)三十問!一位算法工程師經(jīng)歷30+場CV面試后總結(jié)的常見問題合集(含答案)
深度學(xué)習(xí)六十問!一位算法工程師經(jīng)歷30+場CV面試后總結(jié)的常見問題合集下篇(含答案)
一位算法工程師從30+場秋招面試中總結(jié)出的超強(qiáng)面經(jīng)——目標(biāo)檢測篇(含答案)
準(zhǔn)算法工程師從30+場秋招中總結(jié)出的超強(qiáng)面經(jīng)—C、Python與算法篇篇(含答案)
操作系統(tǒng)
1.線程和進(jìn)程的區(qū)別?
進(jìn)程: 是執(zhí)行中一段程序,即一旦程序被載入到內(nèi)存中并準(zhǔn)備執(zhí)行,它就是一個(gè)進(jìn)程。進(jìn)程是表示資源分配的基本概念,又是調(diào)度運(yùn)行的基本單位,是系統(tǒng)中的并發(fā)執(zhí)行的單位。
進(jìn)程是程序的一次執(zhí)行過程,是一個(gè)動態(tài)概念,是程序在執(zhí)行過程中分配和管理資源的基本單位,每一個(gè)進(jìn)程都有一個(gè)自己的地址空間,至少有 5 種基本狀態(tài),它們是:初始態(tài),執(zhí)行態(tài),等待狀態(tài),就緒狀態(tài),終止?fàn)顟B(tài)。
線程:單個(gè)進(jìn)程中執(zhí)行中每個(gè)任務(wù)就是一個(gè)線程。線程是進(jìn)程中執(zhí)行運(yùn)算的最小單位。
線程是CPU調(diào)度和分派的基本單位,它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源。
一個(gè)線程只能屬于一個(gè)進(jìn)程,但是一個(gè)進(jìn)程可以擁有多個(gè)線程。多線程處理就是允許一個(gè)進(jìn)程中在同一時(shí)刻執(zhí)行多個(gè)任務(wù)。
相同點(diǎn):進(jìn)程和線程都有ID/寄存器組、狀態(tài)和優(yōu)先權(quán)、信息塊,創(chuàng)建后都可更改自己的屬性,都可與父進(jìn)程共享資源、都不能直接訪問其他無關(guān)進(jìn)程或線程的資源。
聯(lián)系:線程是進(jìn)程的一部分,一個(gè)線程只能屬于一個(gè)進(jìn)程,而一個(gè)進(jìn)程可以有多個(gè)線程,但至少有一個(gè)線程。
區(qū)別: 1.一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程2. 線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高3. 另外,進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率4. 線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制 5. 從邏輯角度來看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用,來實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別。
什么時(shí)候用線程什么時(shí)候進(jìn)程
進(jìn)程與線程的選擇取決以下幾點(diǎn):①需要頻繁創(chuàng)建銷毀的優(yōu)先使用線程;因?yàn)閷M(jìn)程來說創(chuàng)建和銷毀一個(gè)進(jìn)程代價(jià)是很大的。②線程的切換速度快,所以在需要大量計(jì)算,切換頻繁時(shí)用線程,還有耗時(shí)的操作使用線程可提高應(yīng)用程序的響應(yīng)。③因?yàn)閷PU系統(tǒng)的效率使用上線程更占優(yōu),所以可能要發(fā)展到多機(jī)分布的用進(jìn)程,多核分布用線程。④并行操作時(shí)使用線程,如C/S架構(gòu)的服務(wù)器端并發(fā)線程響應(yīng)用戶的請求。⑤需要更穩(wěn)定安全時(shí),適合選擇進(jìn)程;需要速度時(shí),選擇線程更好。
2.線程有哪些狀態(tài)
5種基本狀態(tài),它們是:初始態(tài),執(zhí)行態(tài),等待狀態(tài),就緒狀態(tài),終止?fàn)顟B(tài)。
3.那進(jìn)程間通信的方式?線程可以通信嗎?
進(jìn)程間通信(IPC,InterProcess Communication)是指在不同進(jìn)程之間傳播或交換信息。IPC的方式通常有管道(包括無名管道和命名管道)、消息隊(duì)列、信號量、共享存儲、Socket、Streams等。其中 Socket和Streams支持不同主機(jī)上的兩個(gè)進(jìn)程IPC。
線程通信常用的方式有:wait/notify 等待、Volatile 內(nèi)存共享、CountDownLatch 并發(fā)工具、CyclicBarrier 并發(fā)工具
4.多線程多進(jìn)程

5.阻塞與非阻塞
同步:所謂同步,就是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事。
例如普通B/S模式(同步):提交請求->等待服務(wù)器處理->處理完畢返回 這個(gè)期間客戶端瀏覽器不能干任何事
異步:異步的概念和同步相對。當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。
例如 ajax請求(異步): 請求通過事件觸發(fā)->服務(wù)器處理(這是瀏覽器仍然可以作其他事情)->處理完畢
阻塞:阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起(線程進(jìn)入非可執(zhí)行狀態(tài),在這個(gè)狀態(tài)下,cpu不會給線程分配時(shí)間片,即線程暫停運(yùn)行)。函數(shù)只有在得到結(jié)果之后才會返回。
有人也許會把阻塞調(diào)用和同步調(diào)用等同起來,實(shí)際上他是不同的。對于同步調(diào)用來說,很多時(shí)候當(dāng)前線程還是激活的,只是從邏輯上當(dāng)前函數(shù)沒有返回,它還會搶占cpu去執(zhí)行其他邏輯,也會主動檢測io是否準(zhǔn)備好。
非阻塞:非阻塞和阻塞的概念相對應(yīng),指在不能立刻得到結(jié)果之前,該函數(shù)不會阻塞當(dāng)前線程,而會立刻返回。
再簡單點(diǎn)理解就是:
-
同步,就是我調(diào)用一個(gè)功能,該功能沒有結(jié)束前,我死等結(jié)果。
-
異步,就是我調(diào)用一個(gè)功能,不需要知道該功能結(jié)果,該功能有結(jié)果后通知我(回調(diào)通知)
-
阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))沒有接收完數(shù)據(jù)或者沒有得到結(jié)果之前,我不會返回。
-
非阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))立即返回,通過select通知調(diào)用者
6. 五種IO模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
-
I/O復(fù)用(select 和poll) (I/O multiplexing)
4)信號驅(qū)動I/O (signal driven I/O (SIGIO))
5)異步I/O (asynchronous I/O (the POSIX aio_functions))
LINUX
1.Linux的一些常用命令
①重啟reboot
②關(guān)機(jī)poweroff、shutdown -h now
③查看本機(jī)ip信息的名稱ifconfig
④vi和vim編輯器
一般模式,插入模式,底行模式
一般模式(通過按iaoIAO鍵)-->插入模式 插入模式(按Esc鍵)--> 一般模式
一般模式(通過按:鍵)-->底行模式 底行模式(按Esc鍵)--> 一般模式
底行模式中,wq = write quit 寫入并退出
wq! 如果有不能保存退出的情況可以使用wq! ! 強(qiáng)制退出
q! = quit !強(qiáng)制 不寫入強(qiáng)制退出
⑤ 查看目錄下的內(nèi)容
ls = list
語法:
ls [目錄名稱]
實(shí)例:
ls 查看當(dāng)前目錄下的所有內(nèi)容
ls /etc 查看etc目錄下的所有內(nèi)容(絕對路徑)
目錄下的所有文件
ls spring/ 當(dāng)前目錄下存在spring可以使用相對路徑查看
ls spring/springmvc
-a 查看目錄下所有的文件,包括隱藏文件
-l 以長格式顯示目錄下的所有文件(顯示文件或者目錄的詳細(xì)信息)
ls -l 可以簡化為 ll
-t 按更新時(shí)間倒敘排序顯示目錄下的內(nèi)容
ls -a /etc
ls -l /etc
ls -l -t /etc 等同于 ls -lt /etc
⑥切換目錄 cd = change directory
⑦刪除文件 rm =remove
2. Linux中g(shù)rep命令詳解
Linux系統(tǒng)中g(shù)rep命令是一種強(qiáng)大的文本搜索工具,它能使用正則表達(dá)式搜索文本,并把匹 配的行打印出來。grep全稱是Global Regular Expression Print,表示全局正則表達(dá)式版本,它的使用權(quán)限是所有用戶。
grep [options]
主要參數(shù):grep --help可查看
-c:只輸出匹配行的計(jì)數(shù)。
-i:不區(qū)分大小寫。
-h:查詢多文件時(shí)不顯示文件名。
-l:查詢多文件時(shí)只輸出包含匹配字符的文件名。
-n:顯示匹配行及 行號。
-s:不顯示不存在或無匹配文本的錯(cuò)誤信息。
-v:顯示不包含匹配文本的所有行。
--color=auto :可以將找到的關(guān)鍵詞部分加上顏色的顯示。
3.按時(shí)間順序打印出文件列表,按文件大小打印文件列表
ls
按大小排序:[root@localhost ~]# ls -Sh
#按時(shí)間排序:[root@localhost ~]# ls -rt
4.Linux如何查看某進(jìn)程關(guān)聯(lián)的相關(guān)文件有哪些?
lsof命令是什么?可以列出被進(jìn)程所打開的文件的信息。
5.Linux啟動的過程
Linux系統(tǒng)的啟動過程并不是大家想象中的那么復(fù)雜,其過程可以分為5個(gè)階段:
內(nèi)核的引導(dǎo)。運(yùn)行 init。系統(tǒng)初始化。建立終端 。用戶登錄系統(tǒng)。linux如何查看進(jìn)程
6.linux查看線程用哪個(gè)命令
1.使用top命令,具體用法是 top –H 加上這個(gè)選項(xiàng),top的每一行就不是顯示一個(gè)進(jìn)程,而是一個(gè)線程。
2.使用ps命令,具體用法是 ps –xH
這樣可以查看所有存在的線程,也可以使用grep作進(jìn)一步的過濾。
3.使用ps命令,具體用法是 ps -mq PID 這樣可以看到指定的進(jìn)程產(chǎn)生的線程數(shù)目。
手撕代碼篇
1.計(jì)算卷積網(wǎng)絡(luò)輸出尺寸
卷積神經(jīng)網(wǎng)絡(luò)的計(jì)算公式為:N=(W-F+2P)/S+1 其中N:輸出大小
W:輸入大小 F:卷積核大小 P:填充值的大小 S:步長大小
2. NMS
import numpy as npdef py_cpu_nms(dets, thresh):"""Pure Python NMS baseline."""x1 = dets[:, 0]y1 = dets[:, 1]x2 = dets[:, 2]y2 = dets[:, 3]scores = dets[:, 4]areas = (x2 - x1 + 1) * (y2 - y1 + 1)order = scores.argsort()[::-1] #[::-1]表示降序排序,輸出為其對應(yīng)序號keep = [] #需要保留的bounding boxwhile order.size > 0:i = order[0] #取置信度最大的(即第一個(gè))框keep.append(i) #將其作為保留的框#以下計(jì)算置信度最大的框(order[0])與其它所有的框(order[1:],即第二到最后一個(gè))框的IOU,以下都是以向量形式表示和計(jì)算xx1 = np.maximum(x1[i], x1[order[1:]]) #計(jì)算xmin的max,即overlap的xminyy1 = np.maximum(y1[i], y1[order[1:]]) #計(jì)算ymin的max,即overlap的yminxx2 = np.minimum(x2[i], x2[order[1:]]) #計(jì)算xmax的min,即overlap的xmaxyy2 = np.minimum(y2[i], y2[order[1:]]) #計(jì)算ymax的min,即overlap的ymaxw = np.maximum(0.0, xx2 - xx1 + 1) #計(jì)算overlap的widthh = np.maximum(0.0, yy2 - yy1 + 1) #計(jì)算overlap的hightinter = w * h #計(jì)算overlap的面積ovr = inter / (areas[i] + areas[order[1:]] - inter) #計(jì)算并,-inter是因?yàn)榻患糠旨恿藘纱巍?/span>inds = np.where(ovr <= thresh)[0]#本輪,order僅保留IOU不大于閾值的下標(biāo)order = order[inds + 1] #刪除IOU大于閾值的框return keep
3.手寫計(jì)算IOU代碼
def IOU(x1,y1,X1,Y1, x2,y2,X2,Y2):xx = max(x1,x2)XX = min(X1,X2)yy = max(y1,y2)YY = min(Y1,Y2)m = max(0., XX-xx)n = max(0., YY-yy)Jiao = m*nBing = (X1-x1)*(Y1-y1)+(X2-x2)*(Y2-y2)-Jiaoreturn Jiao/Bingdef bb_intersection_over_union(boxA, boxB):boxA = [int(x) for x in boxA]boxB = [int(x) for x in boxB]xA = max(boxA[0], boxB[0])yA = max(boxA[1], boxB[1])xB = min(boxA[2], boxB[2])yB = min(boxA[3], boxB[3])interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)iou = interArea / float(boxAArea + boxBArea - interArea)return iou
4.手撕SoftNMS
import numpy as npdef soft_nms(dets, sigma=0.5, Nt=0.5, method=2, threshold=0.1):box_len = len(dets) # box的個(gè)數(shù)for i in range(box_len):tmpx1, tmpy1, tmpx2, tmpy2, ts = dets[i, 0], dets[i, 1], dets[i, 2], dets[i, 3], dets[i, 4]max_pos = imax_scores = ts# get max boxpos = i+1while pos < box_len:if max_scores < dets[pos, 4]:max_scores = dets[pos, 4]max_pos = pospos += 1# add max box as a detectiondets[i, :] = dets[max_pos, :]# swap ith box with position of max boxdets[max_pos, 0] = tmpx1dets[max_pos, 1] = tmpy1dets[max_pos, 2] = tmpx2dets[max_pos, 3] = tmpy2dets[max_pos, 4] = ts# 將置信度最高的 box 賦給臨時(shí)變量tmpx1, tmpy1, tmpx2, tmpy2, ts = dets[i, 0], dets[i, 1], dets[i, 2], dets[i, 3], dets[i, 4]pos = i+1# NMS iterations, note that box_len changes if detection boxes fall below thresholdwhile pos < box_len:x1, y1, x2, y2 = dets[pos, 0], dets[pos, 1], dets[pos, 2], dets[pos, 3]area = (x2 - x1 + 1)*(y2 - y1 + 1)iw = (min(tmpx2, x2) - max(tmpx1, x1) + 1)ih = (min(tmpy2, y2) - max(tmpy1, y1) + 1)if iw > 0 and ih > 0:overlaps = iw * ihious = overlaps / ((tmpx2 - tmpx1 + 1) * (tmpy2 - tmpy1 + 1) + area - overlaps)if method == 1: # 線性if ious > Nt:weight = 1 - iouselse:weight = 1elif method == 2: # gaussianweight = np.exp(-(ious**2) / sigma)else: # original NMSif ious > Nt:weight = 0else:weight = 1# 賦予該box新的置信度dets[pos, 4] = weight * dets[pos, 4]# 如果box得分低于閾值thresh,則通過與最后一個(gè)框交換來丟棄該框if dets[pos, 4] < threshold:dets[pos, 0] = dets[box_len-1, 0]dets[pos, 1] = dets[box_len-1, 1]dets[pos, 2] = dets[box_len-1, 2]dets[pos, 3] = dets[box_len-1, 3]dets[pos, 4] = dets[box_len-1, 4]box_len = box_len-1pos = pos-1pos += 1keep = [i for i in range(box_len)]return keepif __name__ == '__main__':dets = [[0, 0, 100, 101, 0.9], [5, 6, 90, 110, 0.7], [17, 19, 80, 120, 0.8], [10, 8, 115, 105, 0.5]]dets = np.array(dets)result = soft_nms(dets, 0.5)print(result)
5.手寫k-means
import pandas as pdimport numpy as npimport random as ranimport matplotlib.pyplot as pltfrom mpl_toolkits import mplot3d #from sklearn.cluster import KMeansdef model_test():data = open_file("C:\\Users\\happy\\Desktop\\Iris1.csv")dataset = np.delete(data,-1,axis=1) #去掉最后一列k_means = KMeans(n_clusters=3) #構(gòu)建模型k_means.fit(dataset)km4_labels = k_means.labels_ax = plt.subplot(projection='3d')ax.scatter(dataset[:,0],dataset[:,1],dataset[:,2],\c=km4_labels.astype(np.float))ax.set_zlabel('Z') # 坐標(biāo)軸ax.set_ylabel('Y')ax.set_xlabel('X')plt.show()
6.寫python set的基本操作
集合常用的兩個(gè)場景是:1.去重(如:列表去重);2.關(guān)系測試(如:取交集、取并集、取差集等)
7.寫一個(gè)交叉熵?fù)p失函數(shù)
交叉熵?fù)p失函數(shù):實(shí)際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個(gè)概率分布就越接近。
def cross_entropy(a,y):return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a)))#tensorflow版loss = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1]))#numpy版loss = np.mean(-np.sum(y_*np.log(y),axis=1))
8. Softmax函數(shù)
Softmax 函數(shù):將激活值與所有神經(jīng)元的輸出值聯(lián)系在一起,所有神經(jīng)元的激活值加起來為1。第L層(最后一層)的第j個(gè)神經(jīng)元的激活輸出為:
def softmax(x):shift_x = x - np.max(x)#防止輸入增大時(shí)輸出為nanexp_x = np.exp(shift_x)return exp_x / np.sum(exp_x)
9.手推BN公式
上面的公式中m指的是mini-batch size。
源碼實(shí)現(xiàn)
m = K.mean(X, axis=-1, keepdims=True)#計(jì)算均值std = K.std(X, axis=-1, keepdims=True)#計(jì)算標(biāo)準(zhǔn)差X_normed = (X - m)/(std + self.epsilon)#歸一化out = self.gamma * X_normed + self.beta#重構(gòu)變換
10.Python打開一個(gè)文件,找出某個(gè)字符串最快的方法
python 字符串查找有4個(gè)方法,1 find, 2 index方法,3 rfind方法,4 rindex方法。
11.寫一下混淆矩陣、精確率和召回率的公式
準(zhǔn)確度(Accuracy) = (TP+TN) / (TP+TN+FN+TN)
精度(precision, 或者PPV, positive predictive value) = TP / (TP + FP)
召回(recall, 或者敏感度,sensitivity,真陽性率,TPR,True Positive Rate) = TP / (TP + FN)
F1-值(F1-score) = 2TP / (2TP+FP+FN)
12.要求畫出LSTM的結(jié)構(gòu)圖(寫了cell state,hidden state,以及門結(jié)構(gòu)和信號傳遞過程)
參考鏈接
https://blog.csdn.net/u013348164/article/details/53730056
https://blog.csdn.net/A_snail/article/details/1491790
https://blog.csdn.net/weixin_42205987/article/details/82972767
https://blog.csdn.net/weixin_46539107/article/details/108847694
https://blog.csdn.net/jacke121/article/details/82756797
https://blog.csdn.net/zhangliaobet/article/details/99699675
https://blog.csdn.net/weixin_42077852/article/details/89061825
如果覺得有用,就請分享到朋友圈吧!
公眾號后臺回復(fù)“84”獲取第84期直播PPT~
# CV技術(shù)社群邀請函 #
備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測-深圳)
即可申請加入極市目標(biāo)檢測/圖像分割/工業(yè)檢測/人臉/醫(yī)學(xué)影像/3D/SLAM/自動駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群
每月大咖直播分享、真實(shí)項(xiàng)目需求對接、求職內(nèi)推、算法競賽、干貨資訊匯總、與 10000+來自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺開發(fā)者互動交流~
