[轉貼]給學生與軟體業新進的十招

第一招:看到問題唸十次
 a. 確認你記得問題下次還記得
 b. 確認你瞭解問題,沒有漏掉什麼要求
 c. 確認你以後踫到類似問題,還會想到它
 d. 確認你連做夢都會想到它~悲慘的程式設計師宿命~
第二招:程式不會寫,先開始寫註解
 a. 例用註解將問題描述,將問題做分析
 b. 把分析方法與解法都 document 起來~對你自己最有益處
 c. 直接註解而省略白紙,由註解行數的改變,讓你老闆知道你有在努力做~
 c. 人家是用照片寫記憶~程式設計師是用文件寫記憶~
第三招:解法不會寫,先寫工具
 a. 一個複雜的問題,尤其是面對演算法相關的所謂困難部份,如果能把工具(諸如模擬)
  寫出來,這樣是比較容易找出解法的~
 b. 工具總是可以拿來重覆利用的~這會讓你越寫越輕鬆~
 c. 寫工具也是一種重要練習~
第四招:整個問題不會解,先解會解的
 a. divide and conquer(偶稱它為個個擊破法) 不用多說,不知道網上查也會知道~
 b. 就像寫論文一樣,如果無法提出所有問題的統一解決方法,限定一些條件來解
 c. 還有有時候一下就想最困難的問題,一來浪費進度、二來心情不佳、三來老闆可能把
   預算砍了因為沒有結果~所以先解會解的是經驗上的金玉良言~因為一來你花了
   20%完成了80%超越進度,老闆來拍肩膀了,二來你解了簡單問題心情大好,更
   覺得整個問題也沒什麼大不了,說不定困難問題因心情好(沒有專牛角尖)也就想
   到而解決了,三來老闆看你有成果說不定常拍你肩膀哩~(老闆這時候真好騙~可惜
   薪水不好騙)
第五招:查網路、問別人、看書獲取各種解題的資源
 a. 想想偶們還在用193x的理論,當然問題絕不可能只有你才踫到,一定粉多人早就
   見過了~只有你踫到的通常是你自己寫出來的bug~
 b. 這是群策群力的時代,多找資源、人家的經驗和別人幫忙~
 c. 對應於b, 現在這個社會最忌諱單打獨鬥, 那代表你不能 team work~
 d. 增加知名度、人緣~ Social 粉重要~切記~切記~
 第六招:暴力法求解再找最佳化
 a. 先求有再求好~
 b. 有成果人家才看得見~不然做不出來,中間再怎麼完美都沒有用~
 c. 暴力法通常是最白痴也最有效的辦法~
 d. 有時白痴解法最好~因為只有呆子在演東西給傻子和電腦看~你還期待有什麼
   人會看你的程式?偶們高貴的使用者嗎?
 e. 一代萎人瞪小平同志說過:「黑猫、白猫 會抓老鼠的就是好喵」
第七招:多印追蹤資料少偵錯
 a. 講得粉白話~就是要你可以節省出問題找錯的時間~這樣才有更多時間解決真正
   是問題的問題
 b. 因為有追蹤資料 (trace information)不僅你可以找問題,別人也才可以幫你找
   出問題,想想吧~如果 compiler 只告訴你程式錯,而沒告訴你大約是哪裡它踫
   到錯~你要花多少時間解決一個打錯字的問題
 c. 真正的問題也常能由追蹤資料找出蜘絲馬跡
 d. 養成習慣,不要等到當了還在想怎麼寫追蹤資料的程式碼或可以重覆發生的方法~
 e. 你是壞人喲~幹嘛壞怕留下線索~還是你是蜘蛛精,「偶揮揮手不帶走一片data而
   當機」所以,人家是照相機抓得住偶,程式設計師是用 bug 抓往住偶~偶不是故
   意幫那家快倒的、沒有「即時更新技術」的公司打廣告~
第八招:多讀、多寫、多想、多說
 a. 多讀,像第一招,有時候會幫助你瞭解問題的所在或 think out of box,讀也包括
   讀參考資料~
 b. 多寫,熟能生巧~工欲善其事,必先利其器~
 c. 多想,解法大部份還是要腦袋想出來,即使是人家的也要腦袋理解、吸收
 d. 多說,只有在你能表達出問題所在,才表示你真正瞭解問題~只有你能表達出你的知
   識,那個知識才是你的~
第九招:學會改進重於學會重寫
 a. 任何時間都要學會成本控制~不然你就沒有經費~
 b. 當來練習學會維護別人寫得爛程式~以後踫到再怎麼爛也看得懂~
 c. 為什麼爛-用註解的方法記錄下來,有機會(成本效益考量)再改進-記住是改進,不
   是重寫
 d. 由這種維護的痛苦加深寫好程式的方法和印象~真是歹命呀~;)
 e. 工作機會要找改進的粉多,完全寫新的粉少~
第十招:記得備份
 a. 即使BMW也會 Crash,那「軟~」體會可能都不當機嗎?有誰說他家有裝避雷針不
   怕閃電、有水管(PVC)把電源線和所有線包起來不讓老鼠咬~還有說他寫的程式永
   遠不會當 (如果是,偶送你Taiwan No 1封號 的病毒~)
 b. 讓電腦忙一下讓腦袋休息一下,對大家都好~
 c. 還是記得備份~遠方又傳來哀嚎:「神啊~請讓偶記得備份~」
————————————————————-
看了覺得很有道理,和大家分享一下

心得:ASP.NET2.0達人養成系列講座PORT.3

在寒冷的冬天,去聽了這一場研討會
主講人依舊是那位可愛的邱小姐,
先說,我不是因為主講人可愛才去聽的,
這一次的內容,
主要還是在討論VS.NET2005及.NET FRAMEWORK2.0到底多了哪些東西,
多了哪些Control,
演講的時候,由於頭痛加上疲累,
前半場一直處於昏睡狀態,
還好中場,會場有提供咖啡,才讓我清醒了一點…..
 
至於演講的肉容,就待我整理完在放上來
 

3層式架構(3-tier)

http://www.microsoft.com/taiwan/msdn/columns/200303netappintro.htm

http://www.ares.com.tw/gb/communicate/Magazine/22/three-tier.htm

http://www.infolight.com.tw/journal/index_view.asp?no=41&filepath=/journal/file/BOOK5.htm

 

1. 傳統的 1-Tier
  以前 DBF 系統就是將資料庫放於 Local(單機上),如我們用 DBASE 或 Clipper 透過Use / Append / Replace / Delete / Seek…等指令去存取DBF檔案,您寫的程式是在 Local 上執行,並呼叫 Local 上的 DBASE 或 Clipper LIB(或 DLL)去存取這些 DBF 的資料,整個過程都在同一個 Local PC 上執行,我們可以叫它 One-Tier,它的最大缺點就是在於只能單機使用 。

2. LAN 的 1-Tier
  Novell 及 Windows 可以將DBF置於 File Server 上,所以進入了Multi-User 時代,此時,DBF 讓多個 PC 可以共用資料(可讀可寫),確實帶來便利性。但在 DBASE 或 Clipper 的PRG 還是在 PC 端執行(程式可以放在File Server上,但 Run 是在 PC 上),所以 PC 端只是去網路 Open DBF 資料,讀寫都是在 PC 端去完成的,這個架構只是 DBF 的共用,File Server 並沒有任何事情做,所以還是在 One-Tier 上作業,所以此架構的問題就在於資料一多就造成速度上的瓶頸,尤其是資料的穩定度常因 PC 當機造成嚴重的毀損。

3. DataBase Server 的 2-Tier
  2-Tier 就是 Client/Server 的架構,Client 就是 PC 或終端機,Server 就是 Database Server,約十五年前,IBM發展 DB2 與 Client/Server 開啟了大門,此後如雨後春筍,Informix/Sybase/Oracle/MS-SQL相繼崛起,從此 RDBMS(Relation DataBase Management System)已經成為資料庫的共同標準。
  所謂 DataBase Server,就是專門處理資料庫的主機,處理資料庫的方法是採用一種大家標準的語言-SQL,這種語言已經成為發展資料庫的共同標準(如 ANSI-92 標準),就是無論您使用哪種資料庫,您都可以使用相同的 SQL 語言即可以存取資料庫。所有的 PC 或Client都必須以 SQL 來下達給 Database Server,並由 DataBase Server 全權處理。所以Client/Server 是一種分工的模式,由 Client 來提出申請,由Server來完成資料存取的目的,如此即可以將資料安全集中於 DataBase Server 上,不必像 DBF 分散到 PC 上存取,容易亂掉與損毀(尤其是 Index 檔案),資料的穩定度相對提高,處理大量資料的速度也相對提升(DBF 資料一大,速度就是慢),C/S 架構確實提升不少速度與品質。

4.Application Server 的 Three-Tier
  其實 2-TIER 已經解決了不少資料庫的問題,但面臨大型系統,C/S會因為Connection數量(使用者的聯機數)的暴增而造成Database Server無法負荷,通常一個 Application Connection 只要到達 30 到 50 個 User 就會造成 DB Server 疲於奔命,速度與效能將有顯著的改變;另一個問題就是當資料庫的資料很大時,Client/Server 通常會依 SQL 命令將大量數據傳回 Client,往往造成網路與 Server 的瓶頸;再者就是維護的問題,大型的系統有很多很大的 Client 程式,分散到各個 Client 上,每當有程式版本異動時,都必須大費周章的將Client 程式換掉,再加上目前整個 A/P 的全球發展趨勢就是 Thin-Client(瘦小的 Client),並讓 Client 能自動維護或不必維護的效果,3-Tier 的架構與相關技術也就因運而生了。

五個基本的排序法

http://mis.im.tku.edu.tw/~tweety15c/sort.htm
 
    ◎選擇排序法(SELECTION SORT)
     給予N個數,將這N個樹做比較,把最小的數排在第一個位
     子,再將這N-1個數做比較,從這N-1個數中再次找出最小
     的數放在第二個位子,再從這N-2個數中做比較,將最小的
     數放在第三個位子,依此類推,直到N個數都比較完為止。
 
    ◎泡沫排序法(BOBBLE SORT)
     給予N個數,將相鄰的兩個數做比較,若前面的數大於後面
     的數,則將兩個數做調換;若前面的數不大於後面的數,
     再繼續往下比,直到全部的數比較完為止 。
 
    ◎快速排序法(QUICK SORT)
     快速排序又稱為劃分交換排序(partition exchange
     sorting),就平均時間而言,快速排序是所以排序法中最好
     的。假如有n個R1,R2,R3…Rk,鍵值為k1,k2….kn其步驟
     如下:
       1.以第一個紀錄的鍵值k1作為基準K
       2.由左至右i=2,3,…,n一直找到
         ki>=K
       3.由右至左j=n,n-1,….,2一直找
         到kj<=K
       4.當i<j時Ri與Rj互換,否則R1和
         Rj互換
 
    ◎插入排序法(INSERTION SORT)
     給予N個數,若該元素為最小的數,則將該元素(鍵值)插入
     到前面的所有數前;若該元素非最大數,亦非最小數,則
     將該數插在比前一數大,比後一數小的位子上;若前面的數
     都比該元素大,則將該元素放在最後面,以此類推。
 
    ◎謝爾排序法 (SHELL SORT)
     首先將整個陣列分數個小陣列,分別以插入排序法來排序
     每一個小陣列(因為插入排序法對於小陣列效果較好);再
     將排序的陣列逐漸擴大,但是陣列中的資料中也越來越具
     有某種程度的排序關係,所以整個排序的速度獲得了改善。

顯示0,1,1,2,3,5,8,13…..

這是我去面試時的考題,

當時笨笨的,一直想不出來

(在此感謝建安,崇德及86的幫忙)

VB語法:

        Dim x, y, z, n As Integer
        x = 0
        y = 0
        z = 0

        For n = 10 To 0 Step -1
            Console.WriteLine(y)
            z = x + y
            If z = 0 Then z += 1
            x = y
            y = z
        Next


Java:

int x = 0,y = 0,z = 0;
int size = 10;
while((size–)>= 0){
    System.out.println ;
    z = x+y;
    if(z == 0)++z;
    x = y;
    y = z;
}

從 i=i++; 談程式師容易犯的錯!

轉貼自﹝工程師的家

code:
i=0; i=i++;

這樣的程式,最後 i 的值會是多少?0 還是 1 或其它值?
我在網路上看過幾個類似的問題,回覆的答案也是莫衷一是。
對大部份的 C/C++ Compiler測試的結果是 1,
有人把它拿到 java 上測試,發現結果是 0 。
但 C/C++ 和 java 對這樣表示式的計算規則是一樣的啊!
是java不好?還是 C/C++ 錯了?事實上,都不是,
是程式寫得有問題!

ANSI C/C++ 運算式(expression)有一個但書:
如果一個左值(l-value)在運算式中被改變了兩次以上,除非運算子
能保證其計算次序,否則運算式的結果是未定義的

很明顯的 i 在運算式中被改變了兩次,所以:
運算後 i 的結果在ANSI C/C++的規格是未定義的,它依compiler 所用的運
算式演算法不同而有不同的結果,用你手上的C++ Compiler,i的結果可能
是0或是1甚至是其它的值,但不表示其它家的C++compiler 會有一樣的結
果; 甚至你手上C++的下一個版本都不保證會和現在一樣。因為它們都未違
反ANSI 的法律!

很多程式員並不熟讀程式語言的細節而容易犯下這樣的錯,原來跑得好好的
程式在compiler換上新版本後出現了問題。通常直覺的會去怪"新版本"的
compiler有bug!但十有八九問題是出在自己的程式。

”一個左值(l-value)在運算式中被改變了兩次以上,除非運算子 能保證
其計算次序,否則運算式的結果是未定義的”
這在C/C++原始的定義是這樣的:
一個運算式中若含有子運算式,子運算式的計值次序是未定義。
(未定義的意思是ANSI 未規範,編譯器可自行依演算法之差異而便宜行事)
i=i++; 這個運算式來說它分成
i=i;//<—主運算式
i=i+1;//<—子運算式

兩個運算式
因為子運算式(i=i+1)計值次序未定義,所以主運算式的右值 i 到底是新值或
舊值便無法確定,所以最後指派到i的值便未定義。
那麼什麼運算子可以保證子運算式的計值次序?就是”循序”運算子:逗號 (,)
像這樣的式子是正確的運算式:
j=i++, i=j+2;
循序運算子保證其左邊會先於右邊計值。

注意到在C/C++裡只有運算式中的逗號是循序運算子,不是所有的逗號都
是循序運算子。
例如呼叫函式:
FuncCall(i, j*i++);
這程的函式的呼叫是錯的,兩個引數中間的逗號是”分隔符號”不是”循序
運算子”。C/C++也不保證引數的計值次序,結果是第一個引數值是不確定的。