1. 程式人生 > >面試中被問到:你在工作中碰到的最困難的問題是什麼?

面試中被問到:你在工作中碰到的最困難的問題是什麼?

  首先,面試官問道這個問題的目的肯定是想從側面瞭解你對技術的理解,或者說我解決問題的思路。那麼說,我們回答這個問題也要從這點著手。我是這樣總結的。

  在我的程式設計生涯中,我總結出了幾點:
1. 良好的程式設計習慣是對有效率程式設計最大的幫助。
2. 除錯能力的高低是最能反映一個程式設計師水平的素質。

  那我就分享一些我對除錯的理解。我記得有一次專案中需要將一個Ubuntu下的Qt程式碼移植到VS裡面,整體的過程都進行的比較順利,但是在最後進行效能測試的時候,發現效率相差有近百倍。怎麼辦呢?除錯第一點,就是定位問題。在下手之前,我有下列疑問:
  
1. 效率低,常見的是多執行緒阻塞導致。我這裡有多執行緒讀寫圖片,所以是有這個可能。
2. 但是,這個架構在Ubuntu下沒有出現問題,不存在兩者效能懸殊這麼大!

  基於這些疑問,我將除錯重點放在多執行緒讀取圖片部分,最後也的確定位到問題是在多執行緒裡面用OpenCV的imread讀取圖片消耗的時間巨大。難道問題是Windows下的OpenCV庫出現了問題?那麼是什麼問題呢,程式碼在Ubuntu下經過了測試,換個平臺,差距如此大。這個中間,我動過各種歪腦筋,什麼看OpenCV的原始碼,對多執行緒流程除錯等等,花費了幾天時間,最後是一個偶然的機會再論壇裡面看到有人討論到VS下Debug模式和Release模式效能差異的問題,我才驚醒,這就是關鍵,最後用Release模式呼叫相對於的Release庫,果然解決了問題。

  這是一個很簡單的VS使用的問題,但是當時我的日常使用多是Qt,初次接觸VS,並沒有考慮到這個問題,導致浪費了相當長的時間。但是,事後我進行了反思總結,我認為出現本次事件的關鍵並非是我對VS不熟,而是我分析問題的流程不夠科學。Debug就像是警察判案,先要分析作案現場,然後通過各種現象得到一個嫌疑人名單,之後一個一個去排除,最終定位作案人員。這當然是最理想的判案路徑,但是,如果所有的嫌疑人都被排除了,怎麼辦?如果,都被排除了,那麼說,有兩點:
  
1. 你的作案現場分析的不夠細緻,遺漏了一些資訊。
2. 你根據現場資訊得出的嫌疑人名單遺漏了某些人。

  接下來應該做的是重新分析問題,確定問題分析很完善了後,下一步很關鍵,放大你的作案現場。從刑偵的角度看,凶手可能存在多個案發現場,也有可能我們目前看到的不是第一現場。回到程式設計這裡來,首先懷疑多執行緒然後找到讀寫圖片慢的現象,接下來懷疑是否是OpenCV原始碼有問題,這個可能性實在是小概率事件,且大致的看了原始碼後也未有發現異常,接下來應該擴大案發現場:

  • 是否是其他程式碼區域有問題?
    • 不會,這個讀寫差異的大小就基本上等於整個工程反映的差異大小了
  • 如果程式碼沒問題,程式設計環境的差異呢?那麼可以重點關注VS和Qt的差異,從這裡出發,不難就可以找到在VS下Debug模式和Release模式效能差異的狀況。

      以上,雖然是一個很簡單的問題,但是基本能夠反映我對除錯的理解,也可以算是我從事程式設計到現在總結的一些內功心法了。除錯的過程,本質上也就是一個猜想->定位->放大猜想->定位 這樣一個迴圈迭代的過程。簡易的示意圖如下:
      這裡寫圖片描述

      說句題外話,有人會覺得懷疑OpenCV的程式碼有誤是否有必要,我想說,當然有必要,OpenCV也是人寫的,當然有出錯的可能,而且我也的確碰到過。我在使用某一個版本的OpenCV時發現其設定攝像頭解析度的函式不生效,但是僅限於那個版本,冥思苦想後,最終發現是因為這個版本的設定解析度的函式沒有實現。