你最痛苦的一次找程序 bug 的經歷是哪次?


寫了個windows下的console程序,程序要運行好久,中間會時不時看看運行到哪了。有時候我點開任務欄里運行著的程序,就莫名其妙的殺掉了。。。而且殺掉程序沒有規律,有時點開沒問題,有時一點就殺掉。這個幽靈一樣的bug我抓了足足三天,愣是沒有找出問題所在。

後來發現是有道詞典的劃詞翻譯功能,雙擊一下就自動ctrl+C,然後就把console給關掉了。

此後再也沒用過有道詞典。


我是做Solaris Kernel相關的工作的,基本上每個kernel相關的bug都很痛苦...因為大多的bug不能重現,至少不能很輕鬆的重現。很多bug都是和用戶機器具體型號,platform,load等等相關。而且即便能找到原因,很多時候改起來也相當麻煩,因為牽一髮動全身,很可能帶來更大的regression。

我印象中最艱難痛苦的是去年和ZFS team一起搞一個bug,大致是一個客戶的機器上,在使用ZFS的過程中出現system panic。我們嘗試在內部lab里重現沒能成功,所以只能依賴於一個core dump,後來我們希望能去customer機器上遠程調試,但是他們拒絕了,怕我們所謂「破壞現場」...

這個bug大致是由於linux/unix kernel里的vnode的count不準確導致的。Solaris自帶的debug tool dtrace是可以trace每一個kernel的function call可惜vnode count加減並不是通過call function而是macro,所以我們並不能利用dtrace去追蹤每一次的vnode count變化。而面對幾百上千個系統里可能修改這個值的地方我們也不可能一個一個去設斷點或者列印log。

由於這個bug很嚴重,從vp這個級別下的命令是continuous effort,就是三個地區的工程師(美國,印度,歐洲)3班倒24*7的干,進行了一個月,在這中間發現了好幾個ZFS隱藏的很深的bug,但是始終沒能找到這個客戶的問題所在...最後據我所知我們是賠了這個客戶兩台伺服器....


某正部級部門購買了我們兩套數據採集以及分析系統。用了一段時間他們反映,有套系統採集一段時間的數據後,系統會停止數據分析和傳送。雖然他們購買系統只有兩套,但客戶重要性大,公司不敢怠慢,立馬派人出差解決,我很不幸就是那個倒霉鬼。對於這樣的問題,一開始我草率地認為他們土包子不會用。經過了解並非如此,這讓我不得不重視起來。首先對代碼進行檢查,沒有發現造成系統奔潰的問題所在;懷疑是中繼器工作久了罷工,經過測試中繼器一直很堅挺;以為埠被搶佔,結果也不是。由於遲遲解決不了問題,趕緊彙報領導。公司安排內部測試,公司測試結果顯示一……切……正……常。跟客戶溝通,能不能換一個。客戶表示這個系統已經登記了,屬於國有資產,不可以隨意更換。經過這麼長時間折騰,客戶對我的態度也經歷了三個階段:大神來了,小夥子加油,要不換個人吧。奇恥大辱,為了挽回面子,只能來野蠻暴力的了。用一個小窗口實時顯示內存使用情況,雙目緊盯屏幕,想看看是不是內存不足造成的。雙手環抱,看了幾個小時,bug重現,原來是………………電腦睡眠了。


之前看過一個,用JS調微信的介面獲取用戶名,用同事老張的微信號做測試,結果一直獲取的是null,怎麼調都沒發現錯誤,冥思苦想了許久,發現同事老張的用戶名就叫null!!!!!
當時看到這個,差點沒給我笑死!哈哈哈哈哈哈
不知道同事老張現在的輪椅玩的6不6


剛進公司做iPad應用。公司給了兩台測試機。一台iPad4.一台iPadAir。
應用裡面有個資源下載功能。
同一個資源。同一段代碼。
在iPadAir上下的飛快,在iPad4上面就慢慢爬。一直搞不懂是什麼問題。程序是我寫的。能保證兩邊都是一毛一樣。可是就是不知道什麼問題。
到debug的時候同事問我為什麼iPad4那麼慢。我說我也不知道。然後還開會討論了這個問題。我當時還天真的以為是兩台不同型號的設備內部某個網路相關的硬體不一樣導致下載速度不一樣。
然後不斷google,百度查資料看帖看論壇看博客。希望找到看有沒有前輩遇到這種怪問題。
然而找了3天還是找不到。。。
到了最後。。


我特么發現那台iPad4連的樓下咖啡店的WiFi。。。。。


講一個升級版野指針的事。
對於c/c++,野指針是最難查的bug之一了,但是普通的野指針,基本原因都是出在自己寫的代碼里,再不濟,把自己的代碼一行行給檢查過去,總能找到自己腦抽的地方。
然鵝,我遇到的這個「升級版」野指針,比這野得不止一點…


目標環境是自己設計製作的一塊arm板,剛開始出的問題是,系統啟動過程中會隨機死機。死機的位置從boot1到linux系統起來之後都有,不過死在boot1的概率最高。
(啟動過程是,boot0-&>boot1-&>uboot-&>kernel-&>init)
心想,這看上去是若干個bug的複合癥狀吧,boot1的bug最好復現,就拿這個軟柿子先捏吧,待我施展log大法…
咦,怎麼加log之後第一句log沒打完就掛了?
不怕,串口log掛了沒關係,我用io點燈來追bug…
(io點燈是上古技法,現代做法是接邏輯分析儀,然而當時手頭並沒有…)
接好一堆led,在boot1代碼里加一通關鍵數據的io輸出,架好手機錄led數據,用了這上古秘技,這次看我不把bug給揪出…
誒,怎麼led閃了一下就卡死了?這和說好的不一樣啊…
等等,這種加log就能導致隨機bug復現的癥狀不就是野指針的典型癥狀?
我加的log就那麼幾個io操作,不會引入野指針,那麼兇手就是: boot1源代碼?
但是引入任何調試語句都會導致隨機卡死的情況下,要如何從浩瀚的boot1源碼里找出bug?
我轉頭看了下雜物堆里的JLink,難道要請出終極武器了嗎?上次請它還是在調試自己寫的操作系統的時候…


先冷靜下,calm down。
經驗告訴我,如果往深處追了很久都沒找到原因,那麼很有可能一開始就找錯了方向。
不是有幾次成功啟動到登陸界面了嗎,想想那是怎麼復現的。
於是我動手插拔電源企圖復現成功啟動的情形。
插,拔,插拔,插拔…
n次之後我靈光一現,發現個玄學規律:手按在DDR晶元附近的pcb會提升啟動成功率!
莫非是DDR的問題?但是boot0里ddr自檢成功的啊?
趕緊翻回boot0代碼查看,一看就發現被boot0坑了,裡面的DDR自檢是只取了若干個採樣點進行讀寫檢測,並不能保證ddr的可靠性…
立馬寫了個隨機讀寫ddr的測試函數,一運行,果然,在10k次讀寫中就有100多次校驗出錯…
這尼瑪是硬體版野指針啊,和宇宙射線導致的比特翻轉是一樣道理,任意運行程序,某些bit就有一定概率讀寫出錯,怪不得前面怎麼跟都找不到源頭!


於是我通過硬體加軟體的方式重新將DDR穩定驅動起來,這下終於完美地運行過了boot1,然後是uboot,然後是ker…
我去,怎麼又卡死了?
重新確認了下ddr沒問題啊
再跟,結果又是和之前一樣的無理由隨機卡死情況…
連續遇到兩次加強版野指針問題,這運氣也沒誰了…
不過有之前的經驗,馬上就從硬體開始排查了。
這次發現的玄學規律是,只要用手指用力按下pmu啟動,就能提升成功概率。
加了些pmu的log,發現原來是pmu通信沒成功,導致輸出的是默認的較低內核電壓,而啟動後cpu被切換到了較高主頻,內核供電跟不上導致死機…
於是補焊了下pmu,終於成功啟動了linux~


這就是處於軟硬體交界處的debug日常…
不過linux啟動之後就是純軟體的事情了,調驅動,調應用什麼的就很簡單了。
實際上我也沒有在純軟體的地方遇到太難調的bug,直到後面在調安卓系統的時候遇到的一個問題…
不過那個調試過程更長,就按下不表了…


總管上面的現有的答案,可以發現你們的bug有三種:第一種是語法的bug,這個吹吹水啦。第二種是數據的bug,這種bug是比較頭疼的,但是也不是不可以解決。第三種bug是第三方bug,但是……

同志們,見過Oracle JDK給你挖的坑嗎!
去年寫一些機器學習的模型上線去跑,要做IO把處理下輸入數據。非常happy的寫完了,然後就交給了上線實施人員。

過了一會兒,上線實施小哥表示:嘿,兄弟,你這輸出結果不對啊!
我一臉懵逼:不能啊,在我這都是正確的啊!是不是你傢伙手欠改了啥??
小哥:卧槽,我就改了下配置文件卧槽!
我:等著,我去現場。
小哥:(⊙_⊙)
我:╭(╯^╰)╮大步流星飛赴前線,來來來,我瞅兩眼。哎呀,這個配置
小哥:這個配置怎麼可能有問題!
我:……的確看不出來問題……開log看看??
小哥:這不是log么……你看!
我:為啥一點問題都沒有……為啥……為啥……難道是我模型有bug?
小哥:你的鍋反正╭(╯^╰)╮
我:T^T不對啊,我公式推導都過了,這個鍋寶寶不背!要背也是你背
小哥:我們還是討論下甩鍋問題吧……
我:這活兒就咱倆人做的摔給誰……除了java se的庫,多餘的一個庫都沒用……總不能甩鍋給……Oracle吧……
小哥:就Oracle吧
我:(⊙o⊙)…對哦,線上系統是1.6唉……我的系統是1.8啊……
小哥:你用了1.8的什麼特性?
我:天地良心,我照著1.6寫的!多餘的一點都沒用!
小哥:(⊙o⊙)…咱切成1.8試試……卧槽,正常了發生了啥!
我:麻蛋,log全開!全開!我要上diff直接看區別
小哥:麻蛋,全開全開!

當半小時後,log全開了以後……(⊙_⊙)我們將log全部展開,一行一行比對……終於發現在一個角落裡面,有一個字元串數組長度多了一位。而這個字元串數組是用split生成的……

我、小哥:wtf?

最後,在oracle jdk的bug list 裡面發現了這個bug的兩次報告,結論如下:
這個bug事實上是早期split的設計與描述略有不符,在1.8裡面修正了這個bug,但是呢,以前的jdk就那樣啦,我們就不改了啦~

於是oracle背鍋成功。

==
上面說了三種bug,是一般程序員會碰到的,下面說說第四種bug……多數程序員不會碰到
==
第四種bug是這樣的,如果你的程序裡面,有隨機數發生器,那麼你如何跟蹤和調試bug呢?
不幸的是,我們搞機器學習的,特別是搞貝葉斯派機器學習的,經常處理這種bug。
在我們的程序中有大量的計數器,這些計數器對應著模型中的某些參數。而我們的程序就像是一個在爬山的人,隨時會根據山的走勢與峻峭程度選擇路徑。而判斷峻峭程度的依據就是計數器。

這裡,計數器只有兩個限制:
1、計數器的數據必須大於等於0。如果小於0,那麼本來想往山頂爬的,最後就爬溝裡面了。
2、根據計數器的結果計算一系列概率,形成一個骰子,然後決定往哪個方向爬。

第一個非常簡單,而第二個非常蛋疼。蛋疼在於:當你第二條限制被打破的時候,一定說明,在前面的某個時間點,第一條限制被打破了。但是……麻蛋勞資第二條限制是一個概率分布的限制啊!!!換句話說,我根本就不可能知道在什麼時候什麼時間什麼地點第一條限制被打破了!

導師告訴我:你想要力量嗎?
我:(⊙o⊙)嗯!
導師:自己想,對著模型重新敲一邊代碼……
我:T^T嗯!

我們的模型裡面的公式不能給大家看,但是可以從側面告知大家公式的複雜度:
多數符號帶有上標和下標,而他們的上標和下標裡面,又有上下標……如是反覆。這樣,計數器的名字在java裡面怎麼明明呢?一般而言就是用簡化的LaTex代碼表述這個符號,然後寫進去。

然後,在第二步中,那個骰子的形成過程中,多數計數器都以不同方式纏繞在算式上上下下……

由於公式太長,往往將製造骰子的過程單獨放一個方法,投出骰子獲得結果單獨一個方法,根據骰子的結果改變計數器又是一個方法——大骰子投出去往往牽連多個小骰子……(⊙_⊙)反正隨隨便便5-600行代碼就出來了。

這種bug很難找,第一次找花了三天。後來有經驗了,也要一個小時左右去逐個變數循環輸出其值,然後在數值的大海里尋找bug的蛛絲馬跡。

這種bug比較新鮮,所以寫在這裡。


一般遇到類似:

「為什麼啊???按理說應該沒錯啊???這邏輯看著也沒問題啊???」

的bug,最後都會變成:

「對不起我真是個智障…OTL……」


#include&

void mian()

//初學者,各位大神輕噴


竟然召喚成功了233333333


----------------------------

一個到現在都不明所以的BUG。說說吧,看有沒有大神。

差不多兩個月前,我用.net core做了一個小項目,然後正式上線了,放到了正式伺服器上。上線後一切平穩,挺開心。然後過了幾個小時,運維和我說你服務掛了啊,我幫你重啟了。當時就蛋疼了,什麼鬼。

結果噩夢就來了,服務持續重啟,重新部署後,就一切正常。但是過了幾個小時,就又頻繁重啟。伺服器狀態,只能看到內存有點高,但是還不至於崩潰。

後來就一直被這個問題困擾著,還申請了一台堡壘機,是找到一個問題,在一個頻繁調用的view層,有個緩存被撐爆了。但是吧,解決之後只是崩潰的時間延後了點。並沒有從根本上解決。

到了最後,我們嘗試了用centos image重新封裝了一個.netcore的運行環境。然後部署我們的服務,一切OK 再也不重啟了…


所以至今也不知道發生了什麼。對了,我們的伺服器一直是那兩台,系統一直是centos7系統。然後一開始用的image是微軟官方封的那個image,應該是基於Debian的。

嗯,我是在甩鍋微軟●﹏●

這個問題折騰了兩周。最後莫名其妙解決了…… 召喚一下試試@vczh


客戶報了一個bug,在運行Android的板子上,一個USB硬碟反覆熱插拔,最終會導致硬碟被格式化。
一開始,所有人都不以為然,你一個硬碟反覆熱插拔那麼多次有病啊。
可是不久,客戶另一個硬碟也同樣被格式化了。
事件極速升級
所有的領導都開始盯著了
然後,我們工程師開始重視這個bug

解bug第一步當然是復現,我們發現,連續熱插拔三千次以後,就100%復現這個問題。媽的每次都是三千次以後,真的手累
第二步加列印信息narrow down,但是因為無法想清楚問題在哪裡,所有隻能大海撈針,在android的代碼和linux的代碼里都加各種列印。

然後那段時間,我們的工作狀態就是:
加列印信息 -&> 瘋狂插拔 幾個小時之後,大叫一聲「我靠」,再去分析,繼續加列印信息,繼續瘋狂插拔,繼續我靠。。。。。
那段時間晚上回家連擼的慾望都沒得

最終經過幾周之後,終於將問題解掉了。
發現的過程太過曲折離奇,一時半會根本說不清楚,問題的根源,說出來就氣人,一個工程師在內核里把一個引用definition的地方給hard code了。。。。。

從那以後,manager痛定思痛,迅速部署了gerrit

------------------------12/19更新
鑒於很多人出招如何更輕鬆的復現這個問題,有說USB加開關的,有說用機械臂的,有說連數字開關的,首先謝謝大家的提議。
但是我想補充的是,在當時那樣的情況下,客戶天天喊著量產被耽擱,自己的領導和領導的領導每隔幾個小時就跑過來問進度,郵件的cc里已經出現了VP級別的人,我還能怎麼樣?我去找人開發一個機械臂?我去淘寶上買一個USB開關?就算馬上就得到了這個USB開關,然後過了半天之後,不能復現怎麼辦?是分析USB開關的問題呢還是回到我自己的問題?在那種高壓之下,我是萬萬不能再去引入額外的變數,如果引入之後問題發生了新的情況,我怎麼辦?
我隨便一折騰就是一天過去了,領導和客戶的耐心又減半了。。。我怎麼辦?我告訴他們我在折騰機械手臂?are you kidding?我沒有辦法,我只能以最穩妥的方式,一步一個腳印的去把問題理清去解決,給客戶一個交代。
其實,如果有充足的時間,沒人盯著沒人催著,我的辦法太多了,我都根本不需要那些輔助的東西,我對driver隨便改改就能模擬插拔了,我甚至都不需要連一個真實的硬碟,我分分鐘就能模擬一個硬碟出來。我起初做linux和android的時候,我啥都沒有,就一台電腦。
作為工程師永遠有很多辦法,但是對某一個特定問題,只有一個最優的辦法。


要論找bug最困難的,還有能比做系統驅動找bug更難的嗎?你們程序出了錯,無非是程序崩潰異常退出,我程序出了錯電腦直接藍屏有木有?
好在已經好幾年不幹這行了。。。
說個曾經遇到過的最牛bug。
為什麼叫最牛呢?
首先,地點很遙遠:我在北京上班,案發現場在重慶,我帶著台筆記本打飛機跑去現場查bug;
其次:氣氛很緊張:案發現場在重慶某部隊指揮中心,清一水的兩杠x星肩章圍著我;
再次:現象很嚴重:案發現象是指揮中心所有電腦反覆藍屏;
最後:時間很緊急:快過年了,部隊著急解決這個問題,公司也在催。
容我細細道來
曾經在一家給部隊做安全軟體的公司待過兩年,需要通過一些底層的驅動來實現控制終端電腦的外設訪問和網路訪問。有一年快過年了,重慶某部隊反映說系統裝了我們的安全軟體後隔一段時間就藍屏一次,整個指揮室的電腦都這樣了。然後這事很嚴重啊,公司派我緊急飛往重慶解決問題。
去了之後,看到整個指揮室里的電腦三三兩兩的藍屏,首先頭大了一圈。
按部就班的來吧,首先收集了系統自動生成的dump文件,沒有找到明顯有用的信息。然後更換了舊版本程序,依然存在問題,調整安全策略依然照舊。好吧,第一步並沒有獲得什麼有用的信息。
然後嘗試復現bug並找尋規律。說來奇怪,電腦什麼也不操作,靜靜的放著隔一段時間就會藍屏。指揮室的電腦不可能都給我用來做測試,最後通過協商給了我三台電腦,為了尋找藍屏的規律,這三台電腦我觀察大約一下午的時間,發現幾乎是每半個小時藍屏一次。這期間,我仔細分析了系統所有正常載入的驅動文件,排除了有惡意或者有風險驅動的因素。
第一天就這樣過去了,唯一獲取到的有用的信息就是藍屏大約半小時一次。
第二天,我選擇性的注釋掉了一些驅動代碼準備看看效果。因為藍屏現象重現一次時間太長(我每次替換一次代碼就要等半小時才能看現象)導致效率非常低,期間不斷有部隊領導來「關懷」我,我真的是一頭汗水啊。
就這樣,一點點排查到了問題所在的一個函數(我們這個軟體模塊比較多,記得一共有42個模塊,很多模塊我都沒仔細研究過),這個函數功能是每隔30分鐘向控制伺服器上報一次當前主機的網路連接狀態。但是這個問題在別的機器上並沒有問題,而且這個函數並不是內核層的代碼即使出問題也不會導致系統藍屏啊。。感覺問題又進入了死胡同。
後來想到會不會是我們的模塊和系統的某個驅動產生了衝突,導致系統的驅動出現問題使電腦藍屏,我們的程序只是一個「幕後黑手」並沒有直接讓系統藍屏呢?於是,我又試著把系統中的驅動排查了一遍,關了幾個「有嫌疑」的驅動。結果,正常了!
最終得出的結論是intel的快速存儲技術的驅動程序和我們的一個策略有衝突,導致他的驅動出現異常造成系統藍屏。
問題是查出來了,但是要怎麼解決呢?快過年了,這個現象要是按部就班的查找原因再重新發布版本肯定來不及了,正好部隊那邊有趟車下午要去他們部隊的技術中心(暫且這麼叫吧),於是我就沒跟公司彙報直接帶著一個技術支持跟車去了他們的技術中心(重慶山多,兩個地方隔著好幾個山頭,要穿越隧道,1個小時的車程),然後找到了他們負責裝機的人員,告訴他們裝新機器的時候intel的快速存儲功能暫時不要預裝了。他們愣愣的看著我,然後答應了。。。
在之後,我就飛回公司了,部隊那邊也一直沒出現這個問題。然後,這個bug就這樣。。。匿了。。後來為了留檔,給公司寫了一份1萬字左右的文檔紀錄。


本人窮逼,沒用過iphone。

有天我們測試反饋說我們遊戲在IPHONE上沒有聲音,好幾台都沒有。我就納悶了,根本沒改聲音部分啊,之前好好的。拿過來一看,真沒有聲音。然後就開始連接那台IPHONE開始調試,調用了播放聲音的代碼,沒有錯誤日誌,,,,網上也沒有這類問題。一遍遍調試,都沒找到問題,三個小時後我絕望了,準備趴在桌子上休息會,或許睡醒就解決了。
然後,,,,













我發現iphone側面有個按鈕,就按了下,,,,,,,


測試同學你過來下,我給你看下我新買的鞋底!!!!!!!!!!


還在找,還沒解決,半年了。


不是自己的經歷,最近在一本書上看到的:

後來


我們出了問題是真出了問題,大神出了問題還有可能是編譯器的問題。


敦煌莫高窟,冬天,下著大雪,零下15度,白天只有下午2點到4點可以幹活,因為早上太冷根本無法正常活動。設備在燈杠上,我爬在梯子上,用瑟瑟發抖的雙手打開筆記本電腦,連接調試器到設備,開始現場調試。。。


前不久剛發生的一個慘痛debug。

在Windows 10裡面,有一組API叫Windows.UI.Composition。裡面的最小顯示單元是Visual,也就是一個矩形。我發現的bug是,當一個Visual沿著y軸旋轉,如果有個頂點轉到比眼睛還近的位置,就會撕裂。這種事情在圖形學裡面太常見了,以至於我第一時間就覺得是w為負的情況沒處理。以至於那個頂點/w的時候,去了巨大的位置。

然而到處排查,都沒有發現問題所在,之間還被多次誤導到了沒有問題的地方。

3個星期以後,跟到了一個非常老的代碼,應該是Vista時候的。裡面有一個矩形和矩形求交的代碼,在真正畫一個Visual之前,會先和桌面顯示區域做一個求交測試,通過了才畫。因為使用很頻繁,沒人會覺得它有問題。偏偏就是這裡,在處理一個旋轉的矩形的時候,直接/w了,不管w的正負。這麼多年都大家都是在2D平面旋轉矩形,以至於到現在才暴露出來。

雖然第一判斷是對的,但仍然花了那麼長時間。


另一個bug,雖然不痛苦,但啼笑皆非。

有一段代碼,用到了一個矩陣。我知道使用的時候要轉置一下,就先轉置再用。過了一陣被人發現有bug,一看,怎麼想沒轉置的結果,查了一下我確實轉置了啊。再一查,發現我用了轉置,別人也用了,互相抵消。。。


給別人的項目接盤,完成度90%,無文檔無注釋,原作者跑了

原答案寫得太籠統,還是補充一下……( @諸葛不亮 的答案 你最痛苦的一次找程序bug的經歷是哪次? - 諸葛不亮的回答 - 知乎 寫了和我相似的經歷,而且更詳細一點,看來都做過不幸的接盤俠)

看起來我只需要做另外10%,可這僅僅是噩夢的開始,寫新功能時還得解決前人留下的迷之Bug。首先我得在沒有文檔和注釋的情況下搞清楚另外90%的代碼結構(通過各種姿勢的調試,各種斷點,監視,輸出,不知會累死多少腦細胞,在vs一次調試能跑一夜),順便還得體會前人千奇百怪的編程技巧。而且寫另外10%是小事,最後臨近上線時的無數問題和Bug才是大頭……更別說客戶還有多變的需求了。

放一張當時我向別人吐槽的截圖:

猿生不易啊。


說一個大一剛學c時候的,自己練習做一個29選7的機選彩票的小功能,大概就是循環取29以內隨機數輸出到控制台,輸出過的就跳過再取。然後就發現程序卡的不行,半天出一個數,但是單步調試的時候一點問題沒有,當時我就懵逼了。執行就卡,調試就不卡。

。。。。。。後來我就不用當前時間做取隨機數的種子了


JDK 1.4.2的編譯器有一個微小的bug,在wintel平台上會以微小几率編譯出位元組碼不符合簽名的class

3個通宵,20個人天,重裝10台開發機器,換了2個伺服器,新買了一個伺服器
才發現的


推薦閱讀:

怎麼將 Android 程序做成插件化的形式?
30 歲才開始學習編程靠譜嗎?
2013 年 7 月的 Struts2 漏洞實際帶來多大影響?
為什麼寫程序的時候可以堅持很久,但是學習數學就很難保持注意力?
為什麼大多數中國高校不直接使用英文原版教材教學?

TAG:互聯網 | 編程 | 程序 | 編程學習 | 軟體調試 |