圖像處理崗位面試題蒐羅彙總

傳統圖像處理部分

圖像處理基礎知識

彩色圖像、灰度圖像、二值圖像和索引圖像區別?

彩色圖像:RGB圖像。灰度圖像:0-255像素值。二值圖像:0和1,用於掩膜圖像。

索引圖像:在灰度圖像中,自定義調色板,自定義輸出256種顏色值。

常用的圖像空間

HSI、HSV、RGB、CMY、CMYK、HSL、HSB、Ycc、XYZ、Lab、YUV色彩空間(顏色模型)

RGB顏色空間是算法處理中應用最多的顏色空間。

HSI顏色空間,色調(Hue)、色飽和度(Saturation或Chroma)和亮度(Intensity或Brightness)

YUV,分爲三個分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定像素的顏色。YUV 4:4:4採樣,每一個Y對應一組UV分量。YUV 4:2:2採樣,每兩個Y共用一組UV分量。 YUV 4:2:0採樣,每四個Y共用一組UV分量。 緊縮格式(packed formats)平面格式(planar formats)。YYYYYYYYUVUV YYYYYYYYUUVV

圖像的像素數與分辨率有什麼區別?

像素數爲圖像實際組成的像素的個數,像素是沒有固定寬度和高度的,是一個感光單元。

分辨率的單位爲 像素/英寸(1英寸(inch)=2.54釐米(cm)),這裏指的不是面積,而是對角線的長度,即dpi、ppi。分辨率也稱之爲點密度,分辨率越高,看的越細膩。

視頻幀播放速度的單位

PAL制式是——25fps,NTSC是——30fps。

圖像預處理

敘述GABOR濾波器原理?

使用一個三角函數(如正弦函數)與一個高斯函數疊加我們就得到了一個Gabor濾波器。Gabor濾波器可以抽取空間局部頻度特徵,是一種有效的紋理檢測工具。

附:圖像的空域是指二維座標系上的操作,頻域指的是圖像經過傅里葉變換後的頻譜。在頻率域中,高頻分量表示圖像中灰度變換比較快的那些地方,比如物體的邊緣就是灰度的突然變化,所以物體邊緣就是高頻分量。而物體內部比較平坦的區域,灰度基本沒有變化,對應的就是低頻分量。比如低通濾波只讓低頻分量通過,往往就是使圖像模糊,因爲邊緣信息被去除了。高頻對應圖像細節,低頻對應圖像大致輪廓。

椒鹽噪聲用什麼濾波處理比較有效?

參考:中值濾波與椒鹽噪聲

椒鹽噪聲:也稱爲脈衝噪聲:

在圖像中,它是一種隨機出現的白點或者黑點,可能是亮的區域有黑色像素或是在暗的區域有白色像素(或是兩者皆有)。

濾除椒鹽噪聲比較有效的方法是對信號進行中值濾波處理。

插值

最近鄰插值

雙線性插值

立方卷積插值

二值圖像連通域搜索

matlab中連通區域標記函數bwlabel中的算法,一次遍歷圖像,並記下每一行(或列)中連續的團(run)和標記的等價對,然後通過等價對對原來的圖像進行重新標記。

  1. 創建RUN(團)結構體,包含(縱座標、橫座標開始、橫座標結束、標記號)
  2. 開始逐行掃描圖像,尋找所有的團,將他們放到一個二維數組vector< vector<Stuct> >中,以下爲每一行的操作。
    1. 當遇到一個255時,創建一個團的對象,標記縱座標和橫座標的開始。
    2. 從開始點向右尋找,直到遇到0或者這行結束,則標記爲這個團的橫座標結束。
    3. 將該行的RUN push到對應的位置。回到步驟2.1.
  3. 對衆多的團進行分析,對團進行標記且得到等價對,創建一個vector< pair<int, int> >用於存放所有的等價對。
    1. 遍歷所有相鄰行。
    2. 若該行爲第一行,則直接進行標記。
    3. 對於相鄰行,遍歷該行的所有RUN,對於每一個RUN,遍歷上一行的所有RUN(超出範圍即停止循環)。
      1. 若上一行中沒有與該行RUN鄰接,則創建新的標記。
      2. 若上一行只有一個與該RUN鄰接,則沿用相鄰RUN的標記。
      3. 若上一行有多個與該RUN鄰接,則使用這多個RUN中最小的標記,並創建多個等價對。
  4. 消除等價對,可使用並查集,使得所有的團都擁有自己的祖先。
    1. 假設標記從0開始,到1000結束。標記對爲類似的(0,10).(10,39)。
    2. 創建一個prev[1000]數組,初始化值爲-1,記錄該標記的上一級領導。初始prev[10]=0,prev[39]=10。初始化所有的等價對。
    3. 遍歷所有的等價對,修改每一級的上一級領導爲最上層領導。
  5. 修改每個團中的標記爲最上層領導的標記。

代碼見github

開源庫cvBlob中使用的標記算法,它通過定位連通區域的內外輪廓來標記整個圖像,這個算法的核心是輪廓的搜索算法

TODO:輪廓跟蹤算法

並行計算

Intel指令集中MMX,SSE,SSE2,SSE3和SSE4指的是什麼?

MMX(Multi Media eXtension,多媒體擴展指令集)是一些整數並行運算指令。

SSE(Streaming SIMD Extensions,單指令多數據流擴展)是一系列浮點並行運算指令。

SIMD,單指令多數據流,是指用一條指令執行多個計算,比如圖像像素一般是BYTE佔8位,而計算機中總線是64位,所以理論上可以同時進行8個像素的運算。

並行計算有哪些實現方式?

單指令多數據流SIMD、對稱多處理機SMP、大規模並行處理機MPP、工作站機羣COW、分佈共享存儲DSM多處理機。

機器學習面試題鏈接

機器學習部分

特徵算子

常用邊緣檢測有哪些算子,各有什麼特性和優缺點?

  1. Prewitt算子
    優點:一階微分算子,平均濾波,對低噪聲的圖像有較好的檢測效果。缺點:抗噪性差。
  2. Sobel算子Sobel算子
    優點:一階微分算子,加權平均濾波,對低噪聲的圖像有較好的檢測效果。缺點:抗噪性差。
  3. Roberts算子Roberts
    優點:一種利用局部差分算子尋找邊緣的算子,定位比較精確。缺點:對噪聲敏感,無法抑制噪聲的影響。
  4. Laplacian算子
    優點:各向同性,二階微分,精確定位邊緣位置所在。缺點:無法感知邊緣強度。只適用於無噪聲圖象。存在噪聲情況下,使用Laplacian算子檢測邊緣之前需要先進行低通濾波。
  5. Laplacian of Gaussian(LoG)算子:先對圖像做高斯濾波,再做Laplacian算子檢測。
  6. Canny算子:一個具有濾波,增強,檢測的多階段的優化算子。先利用高斯平滑濾波器來平滑圖像以除去噪聲,採用一階偏導的有限差分來計算梯度幅值和方向,然後再進行非極大值抑制。

請描述以下任一概念:SIFT/SURF LDA/PCA

SIFT/SURF爲了實現不同圖像中相同場景的匹配,主要包括三個步驟:
1. 尺度空間的建立;
2. 特徵點的提取;
3. 利用特徵點周圍鄰域的信息生成特徵描述子;
4. 特徵點匹配。

之所以採用尺度空間,是爲了應對尺度不變性。

SIFT

  1. 生成高斯差分金字塔(DOG金字塔),尺度空間構建
    • 通過對原始圖像進行尺度變換,獲得圖像多尺度下的尺度空間表示序列
    • 對這些序列進行尺度空間主輪廓的提取,並以該主輪廓作爲一種特徵向量,實現邊緣、角點檢測不同分辨率上的關鍵點提取等
    • 尺度空間構建的基礎是DOG金字塔,DOG金字塔構建的基礎是高斯金字塔
  2. 空間極值點檢測(關鍵點的初步查探)
    • 爲了尋找DOG函數的極值點,每一個像素點要和它所有的相鄰點比較,看其是否比它的圖像域和尺度空間域的相鄰點大或者小
    • 在二維圖像空間,中心點與它3*3鄰域內的8個點做比較,在同一組內的尺度空間上,中心點和上下相鄰的兩層圖像的2*9個點作比較,如此可以保證檢測到的關鍵點在尺度空間和二維圖像空間上都是局部極值點
  3. 穩定關鍵點的精確定位
    • DOG值對噪聲和邊緣比較敏感,所以在第2步的尺度空間中檢測到的局部極值點還要經過進一步的篩選,去除不穩定和錯誤檢測出的極值點,另一點就是在構建高斯金字塔過程中採用了下采樣的圖像,在下采樣圖像中提取的極值點對應在原始圖像中的確切位置,也是要在本步驟中解決的問題。
  4. 穩定關鍵點方向信息分配
    • 穩定的極值點是在不同尺度空間下提取的,這保證了關鍵點的尺度不變性。爲關鍵點分配方向信息所要解決的問題是使得關鍵點對圖像角度和旋轉具有不變性。方向的分配是通過求每個極值點的梯度來實現的。
    • 分配給關鍵點的方向並不直接是關鍵點的梯度方向,而是按照一種梯度方向直方圖的方式給出的。
    • 具體的方法是:計算以關鍵點爲中心的鄰域內所有點的梯度方向,當然梯度方向一定是在0~360°範圍內,對這些梯度方向歸一化到36個方向內,每個方向代表了10°的範圍。然後累計落到每個方向內的關鍵點個數,以此生成梯度方向直方圖。
  5. 關鍵點描述
    • 對關鍵點的描述是後續實現匹配的關鍵步驟,描述其實就是一種以數學方式定義關鍵的過程。描述子不但包含關鍵點,也包括關鍵點周圍對其有貢獻的鄰域點。
    • 描述的思路是:對關鍵點周圍像素區域分塊,計算快內梯度直方圖,生成具有獨特性的向量,這個向量是該區域圖像信息的一種抽象表述。
    • 如下圖,對於2*2塊,每塊的所有像素點的荼毒做高斯加權,每塊最終取8個方向,即可以生成2*2*8維度的向量,以這2*2*8維向量作爲中心關鍵點的數學描述。
    • David G.Lowed的實驗結果表明:對每個關鍵點,採用4*4*8共128維向量的描述子進項關鍵點表徵,綜合效果最佳:
  6. 特徵點匹配
    • 特徵點的匹配是通過計算兩組特徵點的128維的關鍵點的歐式距離實現的。歐式距離越小,則相似度越高,當歐式距離小於設定的閾值時,可以判定爲匹配成功。

線性判別分析(LDA), 主成分分析(PCA)

參考參考

LDA和PCA最終的表現都是解一個矩陣特徵值的問題,分類的目標是,使得類別內的點距離越近越好(集中),類別間的點越遠越好。

LDA的全稱是Linear Discriminant Analysis(線性判別分析),是一種supervised learning。

LDA的原理是,將帶上標籤的數據(點),通過投影的方法,投影到維度更低的空間中,使得投影后的點,會形成按類別區分,一簇一簇的情況,相同類別的點,將會在投影后的空間中更接近。要說明白LDA,首先得弄明白線性分類器(Linear Classifier):因爲LDA是一種線性分類器。對於K-分類的一個分類問題,會有K個線性函數 y = wx+b.

當滿足條件:對於所有的j,都有Yk > Yj,的時候,我們就說x屬於類別k。對於每一個分類,都有一個公式去算一個分值,在所有的公式得到的分值中,找一個最大的,就是所屬的分類了。

y = wx+b實際上就是一種投影,是將一個高維的點投影到一條高維的直線上,LDA最求的目標是,給出一個標註了類別的數據集,投影到了一條直線之後,能夠使得點儘量的按類別區分開

主成分分析(PCA)與LDA有着非常近似的意思,LDA的輸入數據是帶標籤的,而PCA的輸入數據是不帶標籤的,所以PCA是一種unsupervised learning。

PCA更像是一個預處理的方法,它可以將原本的數據降低維度,而使得降低了維度的數據之間的方差最大

它的目標是通過某種線性投影,將高維的數據映射到低維的空間中表示,並期望在所投影的維度上數據的方差最大,以此使用較少的數據維度,同時保留住較多的原數據點的特性。

通俗的理解,如果把所有的點都映射到一起,那麼幾乎所有的信息(如點和點之間的距離關係)都丟失了,而如果映射後方差儘可能的大,那麼數據點則會分散開來,以此來保留更多的信息。可以證明,PCA是丟失原始數據信息最少的一種線性降維方式。(實際上就是最接近原始數據,但是PCA並不試圖去探索數據內在結構)

Linear Discriminant Analysis (也有叫做Fisher Linear Discriminant)是一種有監督的(supervised)線性降維算法。與PCA保持數據信息不同,LDA是爲了使得降維後的數據點儘可能地容易被區分!

特徵點匹配

如下圖所示,請以準確快速實現配準爲目標,設計算法,讓兩圖中對應的特徵點(至少一部分特徵點)配準(即精準地地找出對應點之間對應的座標關係值)。

參考

之前是用角點檢測,後來採用SIFT算子,Sift算法的實質是在不同的尺度空間上查找關鍵點(特徵點),計算關鍵點的大小、方向、尺度信息,利用這些信息組成關鍵點對特徵點進行描述的問題。

  1. 生成高斯差分金字塔(DOG金字塔),尺度空間構建
  2. 空間極值點檢測(關鍵點的初步查探)
  3. 穩定關鍵點的精確定位
  4. 穩定關鍵點方向信息分配
  5. 關鍵點描述(128維向量算子)
  6. 特徵點匹配(歐氏距離)

極值點鄰域篩選

對於一般應用圖像中,景物可能存在任意特徵(如折線,弧形、亮度極值、色調等),請設計合適的算法,找到圖像中可以作爲明顯特徵點的灰度的極值點所在的鄰域。以準確快速實現極值點鄰域篩選爲目標,設計算法。用流程圖表達)。

也使用SIFT特徵

特徵離散化的好處

  1. 增減特徵較爲方便,易於迭代。
  2. 離散化後運算速度快,存儲方便。
  3. 對髒數據的魯棒性較強。
  4. 離散化一定程度簡化了模型,可以防止過擬合。

分類算法

常用的分類器有哪些,並簡述其原理?

線性分類器:Logistic迴歸 y=sigmoid(wx+b)

傳統方式:特徵描述和檢測

KNN,K最近鄰,判斷圖像與各個類別的距離

SVM,選定特徵, SVM算法輸出一個最優化的分隔超平面(分類面)。本科課題:SIFT、k-means、Bag of Words、SVM。映射函數可能爲多項式。

BPNN,全連接網絡,計算量巨大

CNN,卷積神經網絡

遷移學習,利用別人訓練好的參數,自定義網絡

LR與線性迴歸的對比

LR的優化函數爲似然函數,經典線性迴歸的優化函數爲最小二乘。

LR將預測範圍縮小到了[0,1],而經典線性迴歸的預測範圍爲整個實數。

LR與SVM的對比

相同:都是分類模型。都處理二分類。都可以添加正則項。

區別:LR是參數模型,SVM是非參數模型;LR採用logistical loss,SVM採用hinge loss;SVM之所以稱之爲支持向量,是因爲SVM只考慮了與分類最相關的少數點來學習分類器。

KNN的K是如何選取的

K值較小意味着模型會越複雜,容易發生過擬合。K值過大會使模型過於簡單,使得預測發生錯誤。實際使用中K一般取較小的數字。

什麼是SVM?

參考http://blog.csdn.net/v_july_v/ … 24837

是一個二分分類器,找尋數據之間間隔最大的線性分類器。其學習策略是使分隔間隔最大化。對於線性可分的數據,SVM構造一個分隔面。對於線性不可分的數據,SVM採用核函數將低維空間的問題映射到了高維空間,從而線性可分。常用核函數有多項式核函數、高斯核函數、線性核函數。爲了應對維度爆炸的情形,核函數事先在低維空間上進行計算,再將分類的實際效果展現在高維上。

SVM的損失函數叫做Hinge(hɪndʒ) Loss,形式爲max(0,1-y*a),y爲真實值+-1,a爲預測值,介於-1到1之間。

簡述BP神經網絡

BP(back propagation)神經網絡,輸入X,通過隱藏節點的非線性變換後,輸出信號Y,通過誤差分析,來調整隱藏節點的W和b。

AdaBoost的基本原理?

AdaBoost是一個廣泛使用的BOOSTING算法,其中訓練集上依次訓練弱分類器,每次下一個弱分類器是在訓練樣本的不同權重集合上訓練。權重是由每個樣本分類的難度確定的。分類的難度是通過分類器的輸出估計的。

參考資料

//TODO 詳細學習

聚類算法

簡述你熟悉的聚類算法並說明其優缺點

K均值聚類(K-meansClustering)

將輸入數據分到K個類中。K均值是通過循環更新類中心的初始估計值來實現的。優勢是實現起來很簡單,是並行化的。主要缺陷是,類的數目需要提前確定。

主要分三步:
1. 隨機選取k個聚類質心點(cluster centroids)
2. 對於每一個樣例i,計算其應該屬於的類
3. 對於每一個類j,重新計算該類的質心
1. 重複下面過程直到收斂

層次聚類

層次聚類(或者叫做凝聚聚類)是另一個簡單但是強大的聚類算法。其思想是基於成對距離建立一棵相似度樹。該算法首先分組成爲兩個最近的對象(基於特徵向量之間的距離),並且在一棵有着兩個對象作爲孩子的樹中創建一個平均結點。然後在餘下的結點中找到一個最近的pair,並且也包含任何平均節點,等等。在每一個結點,兩個孩子之間的距離也會被存儲。簇然後可以通過遍歷這棵樹並在距離比某個閾值小以至於決定聚類的大小的結點處停止來被提取出來。

層次聚類有幾個優勢。比如,樹結構可以被用來可視化關係,並且顯示簇是如何關聯起來的。一個好的特徵向量將得到樹中好的分離。另一個優勢是樹可以在不同的簇閾值中被重用,而不需要重新計算樹。缺點是需要選擇一個閾值如果實際的簇需要的話

譜聚類

對於n個元素的相似度矩陣(或者叫affinity matrix, 有時也叫距離矩陣)是一個有着成對相似度分數的n*n矩陣。譜聚類的這個名稱是從相似度矩陣構造的矩陣的譜的使用得來。這個矩陣的特徵向量被用來降維,然後再聚類。

譜聚類方法的其中一個優勢是唯一的輸入就是這個矩陣,並且可以被你可以想到的任何相似度度量構造出來。像K均值和層次聚類這樣的方法計算特徵向量的平均值,這個限制了特徵(或者是描述符)對向量(爲了能夠計算平均值)。有了譜方法,不再需要任何類型的特徵向量,只有“距離”或者“相似度”。

Mean Shift 聚類算法

  1. 在未被標記的數據點中隨機選擇一個點作爲中心center;
  2. 找出離center距離在bandwidth之內的所有點,記做集合M,認爲這些點屬於簇c。同時,把這些求內點屬於這個類的概率加1,這個參數將用於最後步驟的分類
  3. 以center爲中心點,計算從center開始到集合M中每個元素的向量,將這些向量相加,得到向量shift。
  4. center = center+shift。即center沿着shift的方向移動,移動距離是||shift||。
  5. 重複步驟2、3、4,直到shift的大小很小(就是迭代到收斂),記住此時的center。注意,這個迭代過程中遇到的點都應該歸類到簇c。
  6. 如果收斂時當前簇c的center與其它已經存在的簇c2中心的距離小於閾值,那麼把c2和c合併。否則,把c作爲新的聚類,增加1類。
  7. 重複1、2、3、4、5直到所有的點都被標記訪問。
  8. 分類:根據每個類,對每個點的訪問頻率,取訪問頻率最大的那個類,作爲當前點集的所屬類。

簡單的說,mean shift就是沿着密度上升的方向尋找同屬一個簇的數據點。

歐式距離和曼哈頓距離的區別

歐式距離爲最常見的2點之間的距離,爲2點之間的直線距離。

曼哈頓距離又稱爲L1距離或者城市區塊距離,是兩個點的1範數距離。

圖像分割

Graph-cut的基本原理和應用?

Graph cuts是一種十分有用和流行的能量優化算法,在計算機視覺領域普遍應用於前背景分割(Image segmentation)、立體視覺(stereo vision)、摳圖(Image matting)等。

利用圖,將目標和背景進行分割。

圖像融合,鑲嵌

已知兩幅拼接好的圖像,兩幅圖像在幾何關係配準之後,但兩圖之間存在明顯灰度差別跳變,請設計一個算法對圖像進行處理,讓兩幅圖之間的灰度看不出跳變,形成自然過渡。(可以不考慮兩圖之間的黑圖部分)。

影像融合是指高分辨率灰度圖像和低分辨率彩色圖像融合得到具有高分辨率的彩色圖像。該算法稱之爲圖像鑲嵌。簡單的做法可以是尋找兩幅影像的鑲嵌線,鑲嵌線是指兩幅影像公共區域區別最小的一條線,可以利用相關係數法判斷得到,然後根據鑲嵌線上兩幅影像的灰度差異對右影像進行反差調整,最後拼接。

其他模型

Random Forest的隨機性表現在哪裏。

Bagging方法是ensemble methods中獲得用於訓練base estimator的數據的重要一環。 正如其名,Bagging方法就是將所有training data放進一個黑色的bag中,黑色意味着我們看不到裏面的數據的詳細情況,只知道里面有我們的數據集。然後從這個bag中隨機抽一部分數據出來用於訓練一個base estimator。抽到的數據用完之後我們有兩種選擇,放回或不放回。

我們可以看到從根節點開始往下會有分支,最終會走向葉子節點,得到分類結果。每一個非葉子節點都是一個特徵,上圖中共有三維特徵。但是決策樹的一個劣勢就是容易過擬合,下面我們要結合上文提到的bagging技術來中和一下。

img

bagging + decision trees,我們得到了隨機森林。將決策樹作爲base estimator,然後採用bagging技術訓練一大堆小決策樹,最後將這些小決策樹組合起來,這樣就得到了一片森林(隨機森林)。

(X[1],Y[1])….(X[n],Y[n])是數據集,我們要訓練T棵決策樹g[1]….g[t]…g[T]。 每次從數據中有放回地隨機抽取size-N’的子數據集D[t]用於訓練第t棵決策樹g[t]。

隨機森林的隨機性體現在每顆樹的訓練樣本是隨機的,樹中每個節點的分裂屬性集合也是隨機選擇確定的。有了這2個隨機的保證,隨機森林就不會產生過擬合的現象了。

GMM的基本原理和應用

高斯混合模型(Gaussian Mixture Model, GMM)將一個事物分解爲若干的基於高斯概率密度函數(正態分佈曲線)形成的模型。

高斯混合模型(GMM,Gaussian mixture model)是建模最爲成功的方法之一,同時GMM可以用在監控視頻索引與檢索。

用於動目標檢測中的背景建模。

  • 混合高斯模型使用K(++基本爲3到5個++) 個高斯模型來表徵圖像中各個像素點的特徵。
  • 在新一幀圖像獲得後更新混合高斯模型,用當前圖像中的每個像素點與混合高斯模型匹配,如果成功則判定該點爲背景點, 否則爲前景點。
  • 通觀整個高斯模型,他主要是有++方差++和++均值++兩個參數決定,,對均值和方差的學習,採取不同的學習機制,將直接影響到模型的穩定性、精確性和收斂性。
  • 由於我們是對運動目標的背景提取建模,因此需要對高斯模型中方差和均值兩個參數實時更新。
  • 爲提高模型的學習能力,改進方法對均值和方差的更新採用不同的學習率
  • 爲提高在繁忙的場景下,大而慢的運動目標的檢測效果,引入權值均值的概念,建立背景圖像並實時更新,然後結合權值、權值均值和背景圖像對像素點進行前景和背景的分類。

其他理論

監督學習和非監督學習。

  • 監督學習:通過已有的一部分輸入數據與輸出數據之間的對應關係,生成一個函數,將輸入映射到合適的輸出,例如分類。
  • 非監督學習:直接對輸入數據集進行建模,例如聚類。
  • 半監督學習:綜合利用有類標的數據和沒有類標的數據,來生成合適的分類函數。

目前最廣泛被使用的分類器有人工神經網絡、支持向量機、最近鄰居法、高斯混合模型、樸素貝葉斯方法、決策樹和徑向基函數分類。

無監督學習裏典型的例子就是聚類了。聚類的目的在於把相似的東西聚在一起,而我們並不關心這一類是什麼。因此,一個聚類算法通常只需要知道如何計算相似度就可以開始工作了。

過擬合的解決方法

減小模型複雜度、加大數據、batch normalization、dropout、正則化、early stopping。

談談判別式模型和生成式模型?

常見的判別模型有:K近鄰、SVM、決策樹、感知機、線性判別分析(LDA)、線性迴歸、傳統的神經網絡、邏輯斯蒂迴歸、boosting、條件隨機場。通過決策函數來進行判別。

常見的生成模型有:樸素貝葉斯、隱馬爾可夫模型、高斯混合模型、文檔主題生成模型(LDA)、限制玻爾茲曼機。通過聯合概率密度分佈函數來進行預測。

L1和L2的區別

  • L1範數爲向量中各個元素的絕對值之和,符合拉普拉斯分佈,可以使權值稀疏。
  • L2範數爲向量中各個元素的平方和的1/2次方,符合高斯分佈,可以防止過擬合。
  • Lp範數爲向量中各個元素的p次方和的1/p次方。

歸一化的好處

歸一化加快了梯度下降求解最優解的速度;歸一化還可能會提高精度。

歸一化的種類

  • 線性歸一化。利用max和min進行歸一化,如果max和min不穩定,則常用經驗值來替代max和min。
  • 標準差歸一化。利用所有樣本的均值和方差將樣本歸一化爲正態分佈。
  • 非線性歸一化。比如指數、對數、三角函數等。

歸一化和標準化的區別

標準化是依照特徵矩陣的列處理數據,其通過求z-score的方法,將樣本的特徵值轉換到同一量綱下。歸一化是依照特徵矩陣的行處理數據,其目的在於樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的標準,也就是說都轉化爲“單位向量”。

對於深度網絡而言,歸一化的目的是方便比較,可以加快網絡的收斂速度;標準化是將數據利用z-score(均值、方差)的方法轉化爲符合特定分佈的數據,方便進行下一步處理,不爲比較。

熵是指樣本的隨機程度。樣本越無序,熵越大, 信息越多。

完成機器學習項目流程

  1. 抽象成數學問題。明確我們可以獲得什麼樣的數據,這個問題是迴歸還是分類。
  2. 獲取數據。增加數據的代表性,防止因數據引起的過擬合。
  3. 特徵預處理和特徵選擇。進行數據清洗,包括歸一化、離散化等操作。結合數據和業務的特點來確定需要選取的特徵算子。
  4. 訓練模型和調優。選擇一個模型進行訓練,並對超參數進行調節。
  5. 模型診斷。分析模型是否過擬合或者欠擬合,然後進行相應的操作。同時可以進行誤差分析,針對不同的問題來優化模型。
  6. 模型融合。將預處理和預測進行統一。
  7. 上線運行。

深度學習部分

潮流

圖像檢測和分割,增強學習,生成對抗網絡,預測學習

基礎理論

SGD 中 S(stochastic)代表什麼

Stochastic Gradient Descent 隨機梯度下降。GD即Full-Batch,SGD即爲Mini-Batch。隨機性表現在訓練數據的shuffle。

Softmax Loss推一下

Sigmoid、Tanh、ReLU比較

Rectified Linear Unit, ReLU

ReLU比Sigmoid、Tanh好的原因

  1. 指數函數運算量大。ReLU節省運算量。
  2. Sigmoid容易引發梯度消失問題,因爲Sigmoid函數在兩端的導數趨近於0.
  3. ReLU使得一部分神經元死亡,這樣可以使得網絡變得比較稀疏,緩解了過擬合的發生。

引入非線性激活函數的原因?

若使用線性激活函數,則無論神經網絡有多少層,輸出都是輸入的線性組合。

好的激活函數有以下特點:

  1. 非線性:即導數不是常數。
  2. 幾乎處處可微:可微性保證了在優化中梯度的可計算性。
  3. 計算簡單。
  4. 非飽和性(saturation):飽和指的是在某些區間梯度接近於零(即梯度消失),使得參數無法繼續更新的問題。
  5. 單調性(monotonic):即導數符號不變。
  6. 輸出範圍有限:有限的輸出範圍使得網絡對於一些比較大的輸入也會比較穩定
  7. 接近恆等變換(identity):即約等於x。這樣的好處是使得輸出的幅值不會隨着深度的增加而發生顯著的增加
  8. 參數少:大部分激活函數都是沒有參數的。
  9. 歸一化(normalization):這個是最近纔出來的概念,對應的激活函數是SELU。類似於Batch Normalization。

什麼造成了梯度消失和梯度膨脹?

深度網絡的鏈式連乘法則,使得反向傳播時到達前幾層時,權值更新值非常小或非常大。

可以通過ReLU解決一部分。

各大指標

先是混淆矩陣,這是基礎。

混淆矩陣

包含四部分的信息:
1. True negative(TN),稱爲真陰率,表明實際是負樣本預測成負樣本的樣本數
2. False positive(FP),稱爲假陽率,表明實際是負樣本預測成正樣本的樣本數
3. False negative(FN),稱爲假陰率,表明實際是正樣本預測成負樣本的樣本數
4. True positive(TP),稱爲真陽率,表明實際是正樣本預測成正樣本的樣本數

前面有的表示預測正確。

ROC曲線

二分類標籤的輸出概率需要定義一個閾值p,p值的選取反映了分類器的分類性能。ROC曲線的橫軸爲FP(將真實負樣本預測爲了正樣本,越低越好),縱軸爲TP(將真實正樣本預測爲正樣本,越高越好)

ROC

  • (0,0):假陽率和真陽率都爲0,即分類器全部預測成負樣本
  • (0,1):假陽率爲0,真陽率爲1,全部完美預測正確,happy
  • (1,0):假陽率爲1,真陽率爲0,全部完美預測錯誤,悲劇
  • (1,1):假陽率和真陽率都爲1,即分類器全部預測成正樣本
  • TPR=FPR,斜對角線,預測爲正樣本的結果一半是對的,一半是錯的,隨機分類

則,若ROC曲線處於對角線之下,則分類性能差於隨機分類器。希望該曲線向左上角凸。

AUC指標

AUC(Area under the ROC curve),適用於二元分類問題,AUC實際上就是ROC曲線下的面積。AUC直觀地反映了ROC曲線表達的分類能力。

  • AUC = 1,代表完美分類器
  • 0.5 < AUC < 1,優於隨機分類器
  • 0 < AUC < 0.5,差於隨機分類器

求解步驟:

  1. 獲得樣本的輸出概率和標籤值。
  2. 對於不同的從高到低的閾值,計算不同的TP和FP。
  3. 繪製ROC曲線,計算面積。

AUC含義:從所有真實的正樣本中取一個數據,判斷這個樣本是正樣本的概率是p1,從所有真實的負樣本中取一個數據,判斷這個樣本是正樣本的概率是p2。對於分類器來說p1越大越好,p2越小越好。則p1大於p2的概率稱之爲AUC。

mAP

計算步驟,參考

  1. 得到所有測試樣本的id、輸出概率和真實標籤值。
  2. 對輸出概率進行排序。
  3. 假設有M個recall值,分別計算不同recall下的準確率。
  4. 取M個準確率的平均值。

AP(average precision),

卷積神經網絡

圖像預處理手段

卷積和相關

相關和卷積的機理相似,但卷積濾波器首先要旋轉180度。

卷積算法的時間複雜度

因爲在圖像的每個位置都要計算一遍卷積核,所以圖像像素數爲M,卷積核大小爲N,則卷積的時間複雜度爲O(M*N)。

池化層的作用

  • 保留主要特徵的同時進行降維和減少計算量,防止過擬合,提高模型泛化能力。
  • 增加一定的不變性,在池化窗口內。包括平移、旋轉、尺度不變性。

CNN特性

CNN的四個特點:局部連接、權值共享、池化操作、多層次結構。

局部連接使網絡可以提取數據的局部特徵;權值共享降低了網絡的訓練難度,一個Filter只提取一個特徵;池化操作與多層次結構一起,實現了數據的降維,將低層次的局部特徵組合成爲較高層次的特徵,從而對整個圖片進行表示。

爲什麼很多做人臉的Paper會最後加入一個Local Connected Conv?

人臉在不同的區域存在不同的特徵(眼睛/鼻子/嘴的分佈位置相對固定),當不存在全局的局部特徵分佈時,Local-Conv更適合特徵的提取。

循環神經網絡

LSTM爲何比RNN好

LSTM可以防止梯度消失或者爆炸

其他網絡

生成對抗網絡

簡稱GAN。該網絡包含2個部分,一個稱之爲生成器generator,主要作用是生成圖片,並且儘量使得其看上去是來自於訓練樣本的。另一方是discriminator,其目標是判斷輸入圖片是否屬於真實訓練樣本。

TensorFlow

如何理解TensorFlow的計算圖?

TensorFlow分爲二部分,一部分是構造部分,用來構造網絡;一部分是執行部分,用來執行網絡中的計算。

圖像相關開放性知識

怎樣在一張街拍圖像中識別明星的衣着服飾信息?

我們需要把服裝與背景、人物、建築等等元素區別開來,確定是否有衣服以及衣服在什麼位置。接下來需要對衣服進行分析,提取出服裝的屬性、特徵等等。最後再根據這些特徵,在龐大的數據庫裏搜索同款或者類似的服裝圖片。

上衣純色,裙子花色,怎樣做區分?

方差判斷,梯度變化。

怎樣判斷一張廣告圖片中是否有文字信息?是否用到OCR技術?怎樣應用?

場景文字檢測與識別,先用CNN等對文字進行定位,然後再使用LSTM、OCR進行文字識別。

給一張二值化圖片(包含一個正方形),怎樣識別圖片中的正方形?如果圖片污損嚴重,怎樣識別並恢復?

首先檢測輪廓,然後對輪廓進行分析(角點)。

如果圖像污損嚴重,如何識別?

簡述圖像識別在移動互聯網中的應用

人臉識別、識別各類東西、檢索各類圖像。

圖像處理領域相關頂級論文

  • Image and Vision Computing (IVC)
  • Pattern Recognition (PR)
  • ICCV: IEEE International Conference on Computer Vision
  • CVPR: IEEE Conf on Comp Vision and Pattern Recognition
  • NIPS: Neural Information Processing Systems

數學部分

公式

貝葉斯全概率公式題

全概率公式

對任一事件A,若有互不相容的事件Bi(i=1,2,...,n) ,滿足P(Bi)>0,i=1nP(Bi)=1(i=1,2,...,n)i=1nBiA ,則事件A的概率可用下式計算:

P(A)=i=1nP(Bi)P(A|Bi)

img

此概率稱之爲全概率公式。

Bayes公式

利用乘法公式與全概率公式可導出Bayes公式

對任一事件A,若有互不相容的事件Bi(i=1,2,,n) ,滿足P(Bi)>0,i=1nP(Bi)=1(i=1,2,...,n)i=1nBiA ,(跟上個公式條件相同)則

P(Bi|A)=P(Bi)P(A|Bi)i=1nP(Bi)P(A|Bi)(i=1,2,,n)

最小二乘擬合的公式推導和代碼實現。

最小二乘法通常用於 曲線擬合 (least squares fitting) 。

推導過程

核心思想是最小化損失函數:距離差值的平方((diR)2 ),若想公式可導,則可以計算平方差的平方(di2R2)2

C/C++部分

基本概念

關鍵字static的作用是什麼?

  1. 在函數體,一個被聲明爲靜態的變量在這一函數被調用過程中維持其值不變。
  2. 在模塊內(但在函數體外),一個被聲明爲靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數,它是一個本地的全局變量。
  3. 在模塊內,一個被聲明爲靜態的函數只可被這一模塊的它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。

簡述C,C++程序編譯的內存分配情況?

C,C++中內存分配方式可以分爲三種:

  1. 從靜態存儲區域分配:內存在程序編譯時就已經分配好,這塊內存在程序的整個運行期間都存在。速度快,不容易出錯,因有系統自行管理。它主要存放靜態數據、全局數據和常量。會默認初始化,其他兩個不會自動初始化。
  2. 在棧上分配:在執行函數時,函數內局部變量的存儲單元都在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。
  3. 從堆上分配:即運態內存分配。程序在運行時候用malloc或new申請任意大小的內存,程序員自己負責在何進用free 和delete釋放內存。

一個C、C++程序編譯時內存分爲5大存儲區:堆區、棧區、全局區、文字常量區和程序代碼區。

new 和 malloc的區別

  1. malloc/free是C的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。
  2. 當使用一些非內置數據類型的對象時,maloc/free不能自動執行構造函數和析構函數。這是因爲malloc/free是庫函數,不在編譯器控制下。

圖的遍歷

深度搜索DFS

遞歸寫法

  1. 定義一個visited數組。
  2. 訪問當前節點,輸出該節點。
  3. 循環遍歷該節點的相鄰的,未被訪問過的節點。
    1. 遞歸第二步。

非遞歸寫法

  1. 定義一個棧和一個visited數組。
  2. 將初始節點入棧。開始循環,直道棧空。循環如下:

廣度搜索BFS

設置隊列

  1. 定義一個隊列Queue和visited數組。
  2. 將開頭節點入隊。
  3. 開始循環
    1. 出隊,訪問該節點
    2. 遍歷該節點的相鄰的未被訪問過的節點,入隊

hash 衝突及解決辦法

鍵字值不同的元素可能會映象到哈希表的同一地址上就會發生哈希衝突。解決辦法:

  1. 開放定址法。按照一定的方法進行順延。
  2. 再哈希法。同時構造多個不同的哈希函數。
  3. 鏈地址法。數組後的每個元素後添加單鏈表。

紅黑樹的特徵

具有二叉查找樹的所有特徵。二叉查找樹查找的效率最壞爲O(n),紅黑樹通過顏色着色的方法將最壞降低到平均水平。

  1. 每個結點要麼是紅的要麼是黑的。
  2. 根節點是黑的。
  3. 每個葉結點(樹尾端的NIL指針或者NULL結點)都是黑的。
  4. 如果一個節點是紅色,他的兩個孩子都是黑色。
  5. 對於任意結點而言,其到葉結點樹尾端NIL指針的每條路徑都包含相同數目的黑結點。

是紅黑樹的這5條性質,使一棵n個結點的紅黑樹始終保持了logn的高度,從而也就解釋了上面所說的“紅黑樹的查找、插入、刪除的時間複雜度最壞爲O(log n)”

其他編程

嵌入式系統總是用戶對變量或寄存器進行位操作。給定一個整型變量a,寫兩段代碼,第一個設置a的bit3,第二消除a的 bit 3。在以上兩個操作中,要保持其它位不變.

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

#define BIT3 (0x1<<3)
void set_bit3(unsigned &a)
{
    a |= BIT3;
}
void clear_bits(unsigned &a)
{
    a &= ~BIT3;
}

int main()
{
    unsigned a = UINT_MAX;
    clear_bits(a);
    cout << (bitset<32>)a << endl;
    set_bit3(a);
    cout << (bitset<32>)a << endl;
    return 0;
}

行列遞增矩陣的查找

解法一、分治法

因爲矩陣的行和列都是遞增的,所以整個矩陣的對角線上的數字也是遞增的,故我們可以在對角線上進行二分查找,如果要找的數是6介於對角線上相鄰的兩個數4、10,可以排除掉左上和右下的兩個矩形,而在左下和右上的兩個矩形繼續遞歸查找

解法二、定位法

首先直接定位到最右上角的元素,比要找的數大就往左走,比要找數的小就往下走,直到找到要找的數字爲止,走不動,說明這個數不存在。這個方法的時間複雜度O(m+n)。代碼如下:

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

bool YoungMatrix(vector< vector<int> > mat, int target){
    int y = 0, x = mat[y].size() - 1;
    int var = mat[y][x];
    while (true) {
        if (var == target){
            printf("Mat[%d][%d]=%d\n", y, x, target);
            return true;
        }
        else if (var < target && y < mat.size() - 1){
            var = mat[++y][x];
        }
        else if (var > target && x > 0){
            var = mat[y][--x];
        }
        else{
            return false;
        }
    }
}

int main(){
    vector<vector<int> > matrix(20);
    for (int i = 0; i < 20; i++){
        for (int j = 0; j < 20; j++) {
            matrix[i].push_back(i+j);
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }
    cout << YoungMatrix(matrix, 38) << endl;
    return 0;
}

從1到500的500個數,第一次刪除奇數位上的所有數,第二次刪除剩下來的奇數位,以此類推,最後剩下的唯一一位數是什麼?

就是當1~n,2^i

給出了一個n*n的矩形,編程求從左上角到右下角的路徑數(n > =2),限制只能向右或向下移動,不能回退。例如當n=2時,有6條路徑。

從左上角到右下角總共要走2n步,其中橫向要走n步,所以總共就是C2nn 次。

給出一棵二叉樹的前序和中序遍歷,輸出後續遍歷的結果。

已知一棵二叉樹前序遍歷和中序遍歷分別爲ABDEGCFH和DBGEACHF,則該二叉樹的後序遍歷爲多少?

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

string Subsequent(string pre, string mid) {
    if (pre.size() != mid.size() || pre.empty()) return "";
    char root = pre[0];
    int rootIndex = mid.find(root);
    string leftPre = pre.substr(1, rootIndex);
    string leftMid = mid.substr(0, rootIndex);
    string rightPre = pre.substr(rootIndex + 1);
    string rightMid = mid.substr(rootIndex + 1);

    string res;
    res += Subsequent(leftPre, leftMid);
    res += Subsequent(rightPre, rightMid);
    res += root;
    return res;
}

int main(){
    string pre = "ABDEGCFH";
    string mid = "DBGEACHF";
    cout << Subsequent(pre, mid) << endl;
    return 0;
}

自定義實現字符串轉爲整數的算法,例如把“123456”轉成整數123456.(輸入中可能存在符號,和數字)

代碼見github

字符串最長公共子序列

動態規劃推導式

img

代碼見github

字符串最長公共子串

與上文區別是不等時的處理方式,和最後是整個矩陣中尋找最大值。

代碼見github

請實現一個函數:最長順子。輸入很多個整數(1<=數值<=13),返回其中可能組成的最長的一個順子(順子中數的個數代表順的長度); 其中數字1也可以代表14;

直方圖

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

vector<int> LongestShunZi(vector<int> input) {
    // 統計直方圖
    vector<int> hist;
    hist.resize(15);
    for (int i = 0; i < input.size(); i++)
        if (input[i] > 0 && input[i] < 15)
            hist[input[i]] ++;
    hist[14] = hist[1];
    //最大牌數
    int maxCount = 0;
    for (int i = 1; i < 15; i++)
        if (hist[i] > maxCount)
            maxCount = hist[i];
    //求結果
    int resLen = 0;
    int resCount = 0;
    int resEnd = 0;
    for (int i = 1; i <= maxCount; i++)
    {
        int len = 0;
        int longestLen = 0;
        int longestEnd = 1;
        for (int j = 1; j < 15; j++) {
            if (hist[j] >= i) {
                len++;
                if (len > longestLen) {
                    longestLen = len;
                    longestEnd = j;
                }
            }
            else {
                len = 0;
            }
        }
        if (longestLen == 14 && 2 * i > hist[1]) longestLen--;
        if (longestLen * i > resLen * resCount) {
            resLen = longestLen;
            resCount = i;
            resEnd = longestEnd;
        }
    }

    vector<int> res;
    for (int i = resEnd - resLen + 1; i <= resEnd; i++)
        for (int j = 0; j < resCount; j++)
            res.push_back(i);
    return res;
}

int main() {
    int arr[] = { 1, 5, 2, 3, 4, 4, 5, 9, 6, 7, 2, 3, 3, 4 };
    vector<int> v(arr, arr+sizeof(arr)/sizeof(int));
    vector<int> res = LongestShunZi(v);
    for (int i = 0; i < res.size(); i++) cout << res[i] << " ";
    cout << endl;
    return 0;
}

對一批編號爲1-100,全部開關朝上(開)的亮燈進行如下操作

對一批編號爲1-100,全部開關朝上(開)的亮燈進行如下操作:凡是編號爲1的倍數的燈反方向撥一次開關;凡是編號爲2的倍數的燈反方向又撥一次開關;編號爲3的倍數的燈反方向又撥一次開關……凡是編號爲100的倍數的燈反方向撥一次開關。編寫程序,模擬此過程,最後打印出所熄滅燈的編號。

#include <iostream>
using namespace std;

int main() {
    bool arr[101];
    memset(arr, 0, 101);

    for (int i = 2; i <= 100; i++) {
        for (int j = 1; j <= 100; j++) {
            if (j % i == 0) {
                arr[j] = !arr[j];
            }
        }
    }
    for (int i = 1; i <= 100; i++) {
        if (!arr[i])
            cout << i << endl;
    }
    return 0;
}
1
4
9
16
25
36
49
64
81
100

一個數的約數個數爲奇數。所有的數都包含1和自己,平方數的約數肯定是奇數個。

實現個函數 unsigned int convect(char* pstr)

實現個函數 unsigned int convect(char* pstr)。其中pstr是十六進制數的字符串。函數convectpstr轉換成數字返回(比如:字符串’1A’,將返回數值26.注意,pstr[0]是’1’)。pstr中只有數字字符0到9、A到F。不得藉助其它的系統函數調用。

#include <iostream>
using namespace std;

unsigned int convect(char* pstr) {
    char *p = pstr;
    unsigned long long res = 1;
    unsigned long long maxInt = (res << 32) - 1;
    res = 0;
    while (*p != '\0') {
        if (*p >= '0' && *p <= '9') {
            res = res * 16 + *p - '0';
        }
        else if (*p >= 'A' && *p <= 'F') {
            res = res * 16 + *p - 'A' + 10;
        }
        else return 0;
        p++;
    }
    if (res > maxInt) return 0;
    return res;
}

int main() {
    cout << convect((char*)"1A") << endl;
    cout << convect((char*)"FFFFFFFF") << endl;
    cout << convect((char*)"FFFFFFFFF") << endl;
    return 0;
}

實現一個函數unsigned int counter(char* pstr)

實現一個函數unsigned int counter(char* pstr)。函數將打印出匹配的括號對。比如:字符串”a(bc(d)ef(12)g)”就存在3對匹配的括號對,分別是:
1. 位置4上的(與位置6上的)匹配。打印4 6即可。
1. 位置9上的(與位置12上的)匹配。打印9 12即可。
1. 位置1上的(與位置14上的)匹配。打印1 14即可。

軟件編程部分

設計

給你一個模塊要求,你要做出這個模塊,那麼你的做出該模塊的思路和步驟是什麼?

明確這個模塊的功能,明確其輸入以及輸出。

儘量去除與其他模塊的耦合關係,確保獨立性。

我會首先編寫輸入和輸出的接口函數,然後由粗到精,逐步實現細節算法。

同時還需要編寫模塊的測試代碼,保證交付的可靠性。

Matlab編程

Matlab 中讀、寫及顯示一幅圖像的命令各是什麼?

imread(), imwrite(), imshow()

Matlab 與VC++混合編程有哪幾種方式?

Matlab引擎方式(Matlab後臺程序爲服務器,VC前端爲客戶端,C/S結構)、Matlab編譯器(將Matlab源代碼編譯爲C++可以調用的庫文件)及COM組件(Matlab生成COM組件,VC調用)

Matlab運算中 .** 的區別?

.*表示矩陣元素分別相乘,要求兩個矩陣具有相同的shape。*表示矩陣相乘。

邏輯推理部分

智力題

藥丸問題

有四人裝藥丸的罐子,每個藥丸都有一定的重量,被污染的藥丸是沒被污染的重量+1.只稱量一次,如何判斷哪個罐子的藥被污染了?

答:在四個罐子裏面分別取1、2、3、4顆藥丸,然後進行稱量。如果稱量結果比實際(污染前)重了n,就是第n罐被污染了。 (因爲每加一顆被污染的藥丸就增加1所以增加n就是增加n顆就是在第n個罐子裏拿的)

帽子黑白問題

一羣人開舞會,每人頭上都戴着一頂帽子。帽子只有黑白兩種,黑的至少有一頂。每個人都能看到其他人帽子的顏色,卻看不到自己的。主持人先讓大家看看別人頭上戴的是什麼帽子,然後關燈,如果有人認爲自己戴的是黑帽子,就打自己一個耳光。第一次關燈,沒有聲音。於是再開燈,大家再看一遍,關燈時仍然鴉雀無聲。一直到第三次關燈,纔有劈劈啪啪打耳光的聲音響起。問有多少人戴着黑帽子?

解:假如只有一個人戴黑帽子,那他看到所有人都戴白帽,在第一次關燈時就應自打耳光,所以應該不止一個人戴黑帽子;如果有兩頂黑帽子,第一次兩人都只看到對方頭上的黑帽子,不敢確定自己的顏色,但到第二次關燈,這兩人應該明白,如果自己戴着白帽,那對方早在上一次就應打耳光了,因此自己戴的也是黑帽子,於是也會有耳光聲響起;可事實是第三次才響起了耳光聲,說明全場不止兩頂黑帽,依此類推,應該是關了幾次燈,有幾頂黑帽。

金條問題

讓工人爲你工作7天,給工人的回報是一根金條。金條平分成相連的7段,你必須在每天結束時給他們一段金條,如果只許你兩次把金條弄斷,你如何給你的工人付費?

答:分成1、2、4段。利用1,2,4可以組合成1,2,3,4,5,6,7

拆字遊戲

下面玩一個拆字遊戲,所有字母的順序都被打亂。你要判斷這個字是什麼。假設這個被拆開的字由5個字母組成:
1. 共有多少種可能的組合方式?
2. 如果我們知道是哪5個字母,那會怎麼樣?
3. 找出一種解決這個問題的方法。

個人解答:
1. A55=54321=120
1. 會依靠英文字母的規則等大致弄幾種可能性出來。
1. 將弄出來的可能性的單詞進行查找。

爲什麼下水道的蓋子是圓的?

解:很大程度上取決於下水道的形狀,一般爲了使得各個方向的管子都可以接入到下水道中,所以下水道設計成了圓柱形,所以蓋子相應的也是圓形。且圓形比較省材料,便於運輸。

請估算一下CNTOWER電視塔的質量

首先在紙上畫出了CNTOWER的草圖,然後快速估算支架和各柱的高度,以及球的半徑,算出各部分體積,然後和各部分密度運算,最後相加得出一個結果。

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