2015-09-15

AutoCAD 2016系列 中文字無法正確排列問題

在AutoCAD 2016系列中
內建的DWG to PDF設定有問題,導致中文字的排列間隔不正確

解決方法如下
1. 變更出圖設定,將文字以圖形方式出圖
2. 使用外部PDF轉換程式
3. 到下面網址下載update後,自行置換掉內建的DWGtoPDF Driver
連結請按此


參考網址:
http://www.synnex.com.tw/asp/fae_qaDetail.asp?topic=FAE&group=&parent=&classifyid=01997&seqno=22284&vendor=AUTOD

2015-05-21

台灣專利 & 日本特許

兩國的專利搜尋用網頁連結

台湾
經濟部智慧財產局 專利資訊檢索系統
http://twpat.tipo.gov.tw/

日本
特許電子図書館(IPDL) (平成11年~平成27年3月20日)
特許情報プラットフォーム(J-PlatPat) (平成27年3月23日より)
https://www7.j-platpat.inpit.go.jp/tkk/doc/sitemap.html

2015-05-19

VirtualBox Guest OS Serial Port Setting

又是公司的電腦

急著要用舊型Win95/98se要連結Serial Port
設定了半天沒弄好,找了一下,參考一下下面的網站,設定Win98及序列埠的設定

Windows 98SE step by step
How to Add a Serial Port in XP and Win7 Guest.


簡單的說,Host端必須要先有一個可以連結的COM Port
例如說,COM1

然後照下面設定
連接埠號: COM1
連接埠模式: 主機裝置
連接埠/檔案路徑: COM1:
最後的冒號很重要,一定要打,不然就會像我一樣設半天連不上

Guest端可能不會自動偵測到,要自己手動加裝置

至於主端是Unix系的,請另外找吧XD

2015-05-14

JDownloader 2 關閉廣告

從下面網址獲得消息及作法
http://d.hatena.ne.jp/koutas0121/20150127/1422383531

JDownloader 2是個不錯的YouTube處理器
但是有時候還蠻煩的(笑)

如果覺得看到那些廣告或是捐獻欄很煩,可以關掉或是調整下列的選項。

第一個,關掉GET PREMIUM!的標示/按鈕

開啟「選項」裡面的「進階選項」,從過濾器裡面鍵入關鍵字「ulbanner
[GraphicalUserInterfaceSettings: ULBanner] 選項會跳出來。關掉右側的勾選。


第二個,關掉[Contribute]頁籤

關鍵字「donate
[GraphicalUserInterfaceSettings: Donate Button State] 選項會跳出來。將他的值改成「Hidden(Automode)」。


額外選項,關掉Captchas(只是讓他不顯示,如果有問題的話記得改回來)
[GraphicalUserInterfaceSettings: Hate Captchas Text In Captcha Dialog Visible] 選項。將值的打勾

關掉各種Premium警告 [GraphicalUserInterfaceSettings: Premium Alert ??? Column]
??? = ETA, Speed, Task等等


請從下面網址取得原廠的JDownloader 2 (beta)
http://jdownloader.org/download/offline

2015-04-22

真圓度計算方法

這東西搞了兩個多禮拜,終於讓我找到合理的計算方式。

真圓度的計算方法,若使用半徑法,目前有4種方式(參考Wikipedia(en)資料)去取假想圓中心。
1. 最小區域圓法 Minimum Zone circle (MZC)
這是ISO及JIS B0621有規定的正式計算方法。此方法所取中心點畫同心圓,兩同心圓之間包含所有點,且同心圓所夾之面積區域為最小。
此方法之好處為,所取資料點只要落在原先所取的同心圓區域內,中心位置並不會變動。

2. 最小二乘圓法 Least Squares Circles (LSC)
以高斯方程式,計算各點到假想中心之距離總合為最小之假想圓中心。
當取得資料點到假想圓中心距離呈正常分布時,取得之假想圓最接近理想值。但若距離有偏頗時,容易取得不良中心值。

3. 最大內接圓中心 Maximum Inscribed Circle (MIC)
先取得最大內接圓,再取與內接圓同中心之外接圓。

4. 最小外接圓中心 Minimum Circumscribed Circle (MCC)
先取得最小外接圓,再取與外接圓同中心之內接圓。

--

最小二乘圓的計算方法在網路上有介紹。可以藉由Excel進行陣列計算而自動算出。
但是其他的計算法都沒有人寫出來。讓我找了半天快吐血= =。
在此筆記一下各個計算方法之計算手續。

1. 最小區域圓法
先取假想中心O。這比較簡單,可以由其他各種算法計算出的中心做一開始的假想圓,或是可以藉由多邊形幾何中心計算式(參考Wikipedia(zh)資料)先求出假想中心。
i) 取得假想中心O後,計算各點Pi到中心O之距離Ri。
ii) 將各點依距離Ri排序,取得距離最大兩點A,B,以及距離最小兩點C,D
iii) 以AB及CD取中線交點M。
iv) 將M設為新假想中心O,重新計算新中點O到各點之距離Ri。
v) 重複步驟ii到iv,直到A,B及C,D停止變動(亦即,距離最大點與距離最小點不變)。此假想中心O即為所求之最小區域圓中心。OA(OB)為最大圓半徑,OC(OD)為最小圓半徑。真圓度t=(OA-OC)

在最佳的狀況下,重複計算2次ABCD就會安定。

2. 最小二乘圓法
可以參照下面連結,使用Excel之行列計算功能(MINVERSE與MMULT),快速自動計算行列式得出中心
一般式による最小2乗法近似
此法算出之圓周到各點距離之幾何平均為最小。

3. 最大內接圓中心
i) 依照最小2乘法計算式算出假想中心Og
ii) 計算各點Pi到假想中心Og之距離Ri
iii) 根據上記Ri排序,取得距離最小之三點Pa, Pb, Pc
iv) 依據距離最小三點重新做三點取圓,取得最小內接圓中心O。
v) 重新計算中心O到各點距離。真圓度 t =最大距離Rmax-最小距離Rmin

4. 最小外接圓中心
計算順序與最大內接圓中心類似,唯所取基準三點為距離最大之三點。

以上

2015-03-05

Use SQLite in Java(Netbeans)

It's my study note.
I made it by reference to Jens-André Koch's webpage, and updated it into a netbeans 8.0 with SQLite 3.8 version.

Step 1. Download the SQLite JDBC Library

To use SQLite in Netbeans, we must download the library at first.
We can get the library here:
https://bitbucket.org/xerial/sqlite-jdbc

Step 2. Add the JDBC Driver into your project

Add the downloaded JAR into our project.
It can be copied into the project's lib dir, too.

At this moment, it was sqlite-jdbc-3.8.7.jar

Step 3. use it in your code


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.sqlite.JDBC;

public class JavaSQLiteTest {

    public static void main(String[] args) throws ClassNotFoundException {
        // load the sqlite-JDBC driver using the current class loader
        //Class.forName("org.sqlite.JDBC"); // you can use this if you don't use the import.
        
        Connection connection = null;
        try{
            connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
            Statement stm = connection.createStatement();
            
            stm.setQueryTimeout(30); // set timeout to 30 sec.
            stm.executeUpdate("drop table if exists person");
            stm.executeUpdate("create table person (id integer, name string)");
            stm.executeUpdate("insert into person values(1,'leo')");
            stm.executeUpdate("insert into person values(2,'yui')");
            
            ResultSet rs = stm.executeQuery("select * from person");
            while(rs.next()){
                // read the result set
                System.out.println("name = " + rs.getString("name"));
                System.out.println("id = " +rs.getInt("id"));
            }
        }catch(SQLException e){
            // if the error message is "out of memory",
            // it probably means no database file is found
            System.err.println(e.getMessage());
        }finally{
            try{
                if(connection != null)
                    connection.close();
                
            }catch(SQLException e){
                // connection close failed.
                System.err.println(e);
            }
        }
    }
}


Step 4. to manage your database in netbeans

1. Add the JDBC driver in Service->Databases->Drivers
there should be "org.sqlite.JDBC" showed in "Driver Class", and the Name field is "SQLite".
2. Add a JDBC link by SQLite JDBC Driver
right-click on the SQLite Driver, and select "Connecting Using...". Then give the JDBC URL as you like.
To connect with the file named "sample.db", the JDBC URL should be jdbc:sqlite:sample.db 3. Done.

十個PostgreSQL比SQL Server好的理由

Ten Reasons PostgreSQL is better than SQL Server


原文出處: Ten Reasons PostgreSQL is Better Than SQL Server
原文作者: Jeremiah Peschka
原文發布時間: Dec. 06, 2011

為什麼會有人想要用PostgreSQL取代SQL Server?當你在選擇如何儲存你的資料之時會有很多因素需要考慮。有時候你需要看一些比標準選擇更深層一些的部分,並考慮一些新的事情。如果你是要開始一個新的專案,你應該將你的資料儲存在哪裡?以下列出十個理由,告訴你為什麼也許應該要考慮用PostgreSQL而不是SQL Server。


每年版本發布 Release Every Year

讓我們面對問題吧,等某個產品的三到五年的更新週期去加入新的功能是件痛苦的事。我不想不斷地學習新功能,但是另一方面,我又不想為了解決業務上的重大問題而自己寫黑客解決方案,因為我知道某些東西終究會沿著管線下來,但是在我自己實踐他之前我又不能等上個好幾年。迅捷發布週期保證PostgreSQL的開發團隊可以快速地將用戶需求的功能交出來,並且持續的改進。

從9.0版開始,PostgreSQL的發布週期已經切換為年度週期。在那之前,PostgreSQL總是在新功能完成時發布釋出。縱觀維基百科上的主要版本的發布時間,我們可以看到每18個月會推出新的主要版本。對軟體產品來說,18個月的發布週期並不差,比起一個資料庫之類的重大任務來說已經是短得多了。

真.序列化 True Serialization

快照隔離(snapshot isolation)保證同一次的交易處理中的所有的讀取動作都會對應到一致的資料快照內容。另外,一次的交易處理應當只在當次的快照之後的資料變更沒有起衝突的時候進行提交。但不幸的是,快照允許異常狀況存在。那可能會發生一種狀況,兩筆有效的交易發生,讓資料庫留在一個不一致的狀態上 — 資料庫不會符合它自己的資料完整性規則。

序列化快照隔離(serializable snapshot isolation)在9.1版中被加進了PostgreSQL中。SSI模擬了嚴格的序列化執行動作 - 交易行為會以一個接著一個的方式被執行。如果中間有衝突發生,甚至是一個潛在的衝突,資料庫引擎會將一個錯誤丟回給呼叫者(呼叫者將留下如何處理下一步的指示)。

序列化快照隔離聽起來很痛。但厲害的是它提供讓資料庫去擁有更高等級的一致性控制方案。應用程式可以在假設資料修改會失敗的前提下進行開發,隨後重試失敗的交易。真正的好處是寫得好的城市可以預防資料不一致,並且維持所有的操作都應該是符合期望的形象。

理智的預設值,荒謬的調校 Sane Defaults, Ridiculous Tuning

好吧,讓我們保持公平,PostgreSQL附帶了一些荒謬的保守性共享記憶體設定。其他大部分的PostgreSQL設定都是保守的,但是一般來說足以滿足大多數普通的工作負載。大多數人在佈署PostgreSQL的時候將不需對PostgreSQL做太多變更(也許只是在開始時將shared_buffers增加到整體記憶體的25%)。

一旦PostgreSQL安裝完成開始運行,有一些設定還是可以變更。最好的部分是,雖然,是在伺服器,資料庫,用戶,或甚至是單獨查詢級別中可以對其大部分的設定進行變更。擁有混合工作負載的伺服器是十分常見的 - 大部分在該伺服器上的活動都是在基本的CRUD上執行,但是活動中的百分之幾的小部份,用來做報告的那些,需要調整為高一些的優先度。與其將獨立報告移到分離的區域(不管是分離的伺服器,資料庫,還是相同資料庫中的分離資源池)去執行,我們可以藉由使用適當的參數簡單地調校小部分的查詢,包括分配要用來做排序(sort)與聯結(join)的記憶體分配。

無紀錄資料表 Unlogged Tables

你是否對試著取得批量插入作業的少量記錄感到不快?我也是。與其嘗試各種不同的方法去讓某些資料表的紀錄少量化,PostgreSQL讓我們選擇可以創建一個無紀錄資料表 - 只要在創建資料表create table語句中簡單地直接加上UNLOGGED字句,一切就都準備好了。

無紀錄資料表會繞過寫入起始紀錄;他們沒有崩潰防護,但是他們就是可以執行的飛快。無紀錄資料表中的資料將會在伺服器崩潰或是不明關機後被截斷,不然他們就是一直在那裏。他們也會被排除在備用伺服器的備份以外。這讓無紀錄資料表成為ETL或是其他資料操作程序的理想選項,那會讓他們易於重複使用原資料。

地理位置的KNN...以及更多 KNN for Geospatial… and More

對,我有聽過這消息,關於SQL Server將會很快地擁有這個功能,但是PostgreSQL已經擁有了。如果K最近鄰居(K Nearest Neighbor)搜尋對你的業務來說非常重要,你已經走過一些痛苦的過去,為了要讓他在你的RDBMS裡面起作用。或者你已經放棄並且在其他地方實作解決方案。我不會怪你 - 地理位置查詢是好,但是沒有KNN功能會讓人想死。

PostgreSQL的KNN查詢在特定索引(index)類型上動作(在PostgreSQL中有許多種索引類型)。你不只可以使用KNN查詢去找到前五個離你最近的Dairy Queen(*連鎖冰品店),你還可以使用KNN搜尋去找其他的資料類型。你完全有可能藉由執行KNN搜尋去找到10個最接近"冰淇淋"的語句。

KNN搜尋能力使得PostgreSQL在任何尋找地理位置查詢功能的人眼中是個有力的競爭者。而追加的柔軟性讓PostgreSQL在其他同種搜尋導向的應用程式中處於領導地位。

交易管理同步複製 Transcation-Controlled Synchronous Replication

要保持你的資料庫的另一個備份的最簡單的方法之一,就是用某種資料庫複製(database replication)。SQL Server DBA將主要使用交易紀錄性的複製(transactional replication) - 一個專門的代理程序會讀取SQL Server的紀錄,蒐集重要的指令,然後將其傳送給應用他們的訂戶。

PostgreSQL的內建複製,比起SQL Server的複製來說,更接近SQL Server的鏡像(PostgreSQL的複製是個可讀性的待機)。紀錄活動將會固定在主要機上,然後被傳輸給二號機。那個動作可以是同步也可以是非同步的。直到PostgreSQL 9.1為止,複製是一個全友或是全無的動作 - 每一筆交易不是同步就是非同步的。開發者可以藉由單次交易的synchronous_replication設定值去設定一個特定的交易。這很重要,因為它讓我們在除錯時可以寫入大量的複製資料進紀錄資料表而不會受到同步提交在寫入紀錄資料表的效能影響。

每當我們在開發應用程式時有更多的選項時,我都很快樂。

可寫的CTE Writeable CTEs

CTE對讀取來說很好,但是如果我需要用他們來做一些更複雜的動作,那會發生一些其他的問題。一個例子會讓他更簡單一些。比方說我想刪除過時的資料,但是我想要將它儲存在一個封存資料表中。要在SQL Server上這麼做,最簡單的方法(從開發的觀點上)就是提升我的隔離級別(isolation level)到至少快照的等級,如果不是序列化(serializable)的,並且使用隔離等級去保證資料不會被變更。我也可以讀取將要被刪除的註解的PK值,將它放在一個暫存資料表中,並多次參照它。

兩種方法都可行,但是兩種方法都有問題。第一種方法需要程式碼在特定隔離等級上執行。這讓目前的特定設定會失效。程式碼也可以從特定程序中被複製出來,並在SSMS中運行,會導致潛在的異常,會有少數的幾行被刪除且不存在於封存之中。對垃圾留言來說不是個大問題,但是在其他的狀況中這可能會是大問題。第二種方法並不是十分差勁,而且他也沒有錯,只是它涉及額外的程式碼噪音。暫存資料表對解決我們的問題來說不是必要的,而且它是在處理不同隔離級別時產生的副產品。

PostgreSQL有不同的方法來解決這個問題:可寫式的CTE。CTE是用T-SQL中被打造的同樣方式來打造。不同的是,當我們使用PostgreSQL,資料可以在CTE之中被更改。然後輸出資料可以就像其他CTE輸出一樣被再度利用:
CREATE TABLE old_text_data (text_data text); 

WITH deleted_comments AS ( 
  DELETE FROM comments 
  WHERE comment_text LIKE '%spam%' 
  RETURNING comment_id, email_address, created_at, comment_text 
) 
INSERT INTO spam_comments 
SELECT * 
FROM deleted_comments 

這可以結合預設值(default value),觸發器(trigger),或是任何其他資料修改方式去打造非常豐富的ETL鏈。在表面之下它可能就像我們在SQL Server上做的事一樣,但是好處是它簡潔。

擴充 Extensions

有曾想過要在SQL Server上增加一些功能嗎?要如何保持這些功能是最新版的?這也許對DBA來說是個大問題。當你在橫跨生產環境中執行管理用腳本時要跳過一台伺服器是十分簡單的事。更進一步,你怎麼知道你已經安裝的是哪個版本?

PostgreSQL擴充功能網路(PostgreSQL Extension Network, PGXN)是一個外部功能的集中發放點。它是開源PostgreSQL書庫的一個可信賴的來源 - 不會包含任何可疑的二進位程式。再加上,在PGXN上的任何東西都有版本編號。當更新時,PGXN會有效地提供,擴充功能將會為你關注更新途徑 - 它知道如何確認自己是最新的。

有一些關於排名的擴充功能像是 K均值叢類(K-Means clustering)甲骨文兼容功能(Oracle compatibility functions)Amazon S3遠端查詢(remote queries to Amazon S3)

將這些功能推出並放進擴充功能中,讓開發者與DBA易於打造客製化封包,讓它看起來且動作就像是PostgreSQL的核心功能,但卻不需試著在PostgreSQL發布程序中取得這些包裝。這些包裝可以之後再獨立開發,進而提升他們自己的效率,並提供那些無法符合PostgreSQL核心團隊的發布計畫的複雜功能。簡單地說,這有一個環繞PostgreSQL的健全生態系統。

豐富的時間資料類別Rich Temporal Data Types

我最喜歡的PostgreSQL的功能之一就是它的時間資料類別的豐富支援。當然,SQL Server 2008最終為SQL Server帶來了一些成熟的時間資料支援,但是那還是塊十分貧脊的土地。對時間資料的強力支援在很多工業中是關鍵議題,而且不幸地是,在SQL Server中還有許多工作在繼續進行,為了解決要SQL Server對時間資料支援上的限制。

PostgreSQL引進了時區智能處理。加上了對ISO 8601標準(1999-01-08 04:05:06 -8:00)的支援,PostgreSQL支持用縮寫(PST)或是指定位置識別子(America/Tijuana)來識別時區。縮寫會對應到從UTC的固定偏移量,而位置識別子會加上夏令時間的規則支援。

在時區柔軟性之上,PostgreSQL有個interval資料類別。interval資料類別能夠在14位精度上儲存最大178,000,000年的間隔。interval可以量測時間,以一年的間隔內測出比微秒還要小的精細度。

排除約束 Exclustion Constraints

你是否有嘗試過用SQL Server寫任何一種排程功能?如果你有,你將會知道當你有業務上的需求像是"兩個人不能在同一時間占用同一間會議室",你就會知道這很難執行程式碼,而且通常會需要資料庫中的額外動作。有很多方法可以完全透過在應用程式層別程式碼來實現這個功能,但沒有一個會讓用戶與開發者開心。

PostgreSQL 9.0引進了排除約束在欄位之中。換句話說,我們定義資料表並加上追加的約束,那包括一些檢查(check),且至少要有一項檢查是假(false)。排除約束藉由索引的罩門下受支援,所以這些動作可以像是在我們的磁碟以及我們所設計的索引一樣快。你可以在時空間結合資料上使用排除約束,確定在同一個時間點不同的人不能預約同一間會議室或是區塊不會重疊。

在2010 PGCon大會中有一份發表資料是關於排除約束的細節部分。雖然沒有視頻,但是幻燈片已經足以讓他們展示足夠的案例與解釋幫助你開始。

加分功能 - 原價 Bonus Feature - Cost

它是免費的。所有的功能都是。PostgreSQL沒有版本分類(edition) - 功能總是存在資料庫中。一些公司會提供商業支援,他們之中有些甚至會提供追加的閉源功能,但是核心的PostgreSQL資料庫一直都是可用的,一直都是免費的,一直都擁有相同的功能。

讓我們開始吧 Getting Started

想要開始用PostgreSQL嗎?跳到下載頁面並下載你選擇的平台的副本。如果你想要更多細節,文件都已經準備好了而且良好撰寫,或是你可以查看維基上的教程

2015-02-20

用十年自學編程

用十年自學編程
Teach Yourself Programming in Ten Years

Peter Norvig

為什麼大家要這麼急?
Why is everyone in such a rush?

走進任何書店,你可以找到像是24小時自學Java以及無數的類似書籍,在數天或是數小時內教你有關C, SQL, Ruby, 演算法, 等等類似的內容。你可以在亞馬遜書店的進階搜尋中搜尋關鍵字title: teach, yourself, hours, since: 2000並且找到512本相關的書籍。其中最前面的10到九本都是編程的書(其他是有關簿記的)。將關鍵字"自學Teach yourself"換成"學習learn"或是將"小時hour"換成"天day",你將會得到類似的結果。

結論是,要不是人們非常急於學習編程,不然就是編程本身比起其他任何東西來說都是超級無敵簡單。 Felleisen 等在他們的著書How to Design Programs中對這種趨勢下了個簡單的注解,他們說「要寫爛程式很簡單,白痴們可以在21天內學會,即是他們是傻瓜」。Abtruse Goose漫畫也對這個下了他們的注解

讓我們對來分析一下像是24小時自學C++(Teach Yourself C++ in 24 Hours之類的書籍標題可能具有的涵義:
  • 自學Teach Yourself: 在24小時之內你將不會有時間寫任何顯而易懂的程式,並且從中學到你的成功與失敗。 你將沒有機會與經驗老道的程式員一起工作並了解用C++開發環境來討生活是什麼樣的狀況。 總之,你沒有太多學習的時間。所以這本書紙會談到一些超級膚淺的內容,而不會有深度的理解。 就像Alexander Pope所說的,只學表面是件非常危險的事。
  • C++: 在24小時內,你也許可以學到C++的一些文法(如果你已經知道其他語言),但是關於如何使用這個語言,你無法學到更多。 總之,或說,如果你是個Basic的程式員,你可以學到如何用C++的文法編寫Basic風格的程式,但是你不會學到有關C++實際上是哪裡好(以及不好)。 所以重點是什麼呢?Alan Perlis說過:「一個不會影響你對編程的想法的語言,不值得去瞭解。」 一個可能的重點是,你必須學C++(或者其他常見的,像是JavaScript或是處理程序Processing)的一點皮毛,因為你需要藉由一個既存工具的介面來完成特定的工作。但是你不是在學習如何編程,你是在學習如何完成任務。
  • 24小時in 24 Hours: 不幸的是,那並不夠,就如同下一小節中所描述的一樣。

十年自學編程
Teach Yourself Programming in Ten Years

研究人員(Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) 指出,在任何不同的領域,包括西洋棋,編曲,電報操作,繪畫,鋼琴,游泳,網球,以及神經心理學與拓撲學等等,發展專長大約需要10年的時間。 關鍵在於審議式的(deliberative)練習:不是只有反覆的實作,而是要藉由超過你現有能力的任務來作自我挑戰,嘗試去實作,並在實作後分析你自己的能力,並且修正所有的錯誤。然後不斷的重複。似乎沒有真正的捷徑:即使是4歲時被稱作音樂神童的莫札特,在他開始作出世界頂尖的音樂之前也花了超過13年的歲月。在其他世代中,披頭四似乎在1964年Ed Sullivan的表演中突然嶄露頭角。但是他們早從1957年開始就在Livepool與Hamburg的小型俱樂部中表演,而他們真正大量出現並發行第一張超級成功的專輯Sgt. Peppers是在1967年。 Malcolm Gladwell的說法是,比起10年,他用10,000小時來堆砌他的成功。

也許10,000個小時才是魔法數字,而不是10年。或者它只是另一個不同的基準; Henri Cartier-Bresson (1908-2004) 說:「你的前10,000張相片會是你最爛的相片。」 真正的專長也許需要花上一生: Samuel Johnson (1709-1784)說:「任何部門的精英只能藉由終身勞動來達成;那無法用低廉的價錢購買。」 且Chaucer (1340-1400)抱怨說「人生太短,學習之路卻太長」。 Hippocrates (c. 400BC)有名的筆記裡寫到:「ars longa, vita brevis」, 而那是長篇短文「Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile」的一部分,譯為「人生太短,工藝之路太長,機會稍縱即逝,體驗苦澀,判斷困難。」 當然,最終的答案不會是只是個單純的數字:似乎沒有合理的假設,編程,下西洋棋,完跳棋,演奏音樂,他們都需要相當長的時間去成為大師,而且不是每個人所需要的時間都會一樣。

那你想要成為一個程式員
So You Want to be a Programmer

要在編程中成功,以下是我的菜單:
  • 對編程感興趣,且真正因為有趣而去做。確保它有足夠的樂趣,那麼你會願意在那上面花上你的10年/10,000小時。
  • 程式Program. 最佳的學習方法是從作中學(learning by doing)。更技術性的說法,「個體在某個給定的特定領域中的最高效能不會像經驗成長的一部分自動獲得,但是在經驗豐富的個體上效能水平可藉由刻意努力的結果而獲得均衡的提升。」(p. 366)還有「最有效率的學習,需要為個體提供良好定義的任務,伴隨著適合的難度等級,訊息回饋,以及複習與錯誤改正的機會。」(p20-21) Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life這本書提供了有關這個觀點的有趣的資料。
  • 與其他程式員交流; 閱讀別人的程式碼。這比起任何書或是訓練課程來的重要。
  • 如果你願意的話,進大學(或是更上一層的研究所)去學習。這將給你參與某些需要學歷的工作的機會,並對這個領域有更深層的理解。但是如果你不喜歡學校,(透過某些方法)你可以靠自己或是在工作中獲得類似的經驗。無論如何,光靠書本的知識是不夠的。 「計算機科學教育不會讓任何人成為頂尖程式員,就像學習筆刷跟顏料不會讓任何人成為頂尖的畫家一樣。」The New Hacker's Dictionary的作者Eric Raymond說到。 我曾經雇用的最好的程式員之一,他只有高中學歷;他創造了很多偉大軟體,擁有他自己的新聞群組,並且賺取了夠多的股票去買他自己的夜店
  • 與其他程式員一同作專案。在一些專案裡當最佳程式員;並在其他某些專案中當最爛的。當你是最佳程式員的時候,你必須測試你領導專案的能力,並且用你的眼光激勵其他人。 當你是最爛的程式員的時候,你學習主人的做法,並學習他們不喜歡作的部分(因為他們會讓你幫他們做那部份)。
  • 跟隨其他程式員作專案。 理解其他人所寫的程式。看看當原始作者不在的時候如何理解並修復它。想想要如何設計你的程式讓其他人在你之後易於維護。
  • 學習至少六種程式語言。 那其中包括一種強調類抽象class abstractions的語言(像是Java或C++), 一種強調函數抽象functional abstraction的語言(像是Lisp, ML, Haskell), 一種支援語法抽象syntactic abstraction的語言(像是Lisp), 一種支援聲明規格declarative specifiaction的語言(像是Prolog或C++模板), 以及一種強調並行處理parallelism的語言(像是Clojure或是Go)。
  • 請記得在「計算機科學」之中有「計算機」這個字眼。 理解你的電腦處理指令的時間,從記憶體獲取資料的時間(伴隨以及不伴隨快取失誤),從磁碟連續讀取資料的時間,以及在磁碟上搜尋新位址所需的時間。(答案在此)
  • 涉足一項語言標準化作業。它可以是ANSI C++委員會,也可以是決定在你的團隊中的編碼風格將有2個或是4個空白來進行縮排。不管是哪一種,你學到其他人在語言中喜歡的做法,還有他們的感受有多深,甚至有可能稍微瞭解為什麼他們覺得那樣之類的。
  • 要明確果斷,盡快脫離語言標準化作業

瞭解了上述的觀點,只藉由書本學習你能夠走多遠是十分可疑的。在我第一個孩子出生前,我讀過很多要如何做 How To的書,但是還是感覺自己是個手足無措的新手。30個月後當我第二個孩子出生時,我有重新把那些書拿來讀嗎?不。相反的,我遵照我個人的經驗,那更加有用,且比起專家寫的上千頁的書更讓我放心。
Fred Brooks在他的著作No Silver Bullet中提到了一個尋找優秀軟體設計師的三部曲計畫:
  1. 有系統的尋找頂尖設計師,越早越好。
  2. 指定一個職業導師負責前景發展,並仔細地規劃職業生涯。
  3. 為設計師提供成長的機會,讓他們彼此互動與刺激。
前提是有些人已經有成為優秀設計師的素質;而工作只是引導他們正確的前進。 Alan Perlis用說得更簡潔:「任何人都可以被教導如何去雕刻:米開朗基羅也被教導過什麼是不該做的。優秀的程式員也沒有不同。」 Perlis說,優秀的人們擁有內在的素質,那超越了他們的訓練。但是那素質是從哪來的?那是與生俱來的嗎?或是他們藉由努力而開發的呢?Auguste Gusteau(Ratatouille中虛構的大廚)下了這樣的注解:「任何人都可以下廚,但只有無畏者才會偉大。」 我覺得那有一大部分是源自一個人是否願意奉獻其生命中極大部分去做審議實踐。但是無畏也許是個總結的方法。 又或者,就像Gusteau的評論家Anton Ego說的:「不是任何人都可以成為優秀的藝術家,但是優秀的藝術家可以從任何地方而來。」

所以,儘管去買那些Java/Ruby/JavaScript/PHP的書;你將也許從中知道一些用法。但是你將不會改變你的生活,或是你的作為程式員的整體專業知識在24小時或是21天內。但是如果你持續努力改善超過24個月後呢?好吧,該是你從某處開始努力的時候了...

資源 References

Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.
Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.
Bryan, W.L. & Harter, N. "Studies on the telegraphic language: The acquisition of a hierarchy of habits. Psychology Review, 1899, 8, 345-375
Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989.
Chase, William G. & Simon, Herbert A. "Perception in Chess" Cognitive Psychology, 1973, 4, 55-81.
Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.

答案Answers



典型個人電腦上各種操作的大約時間:
典型指令之執行
execute typical instruction
1/1,000,000,000 sec = 1 nanosec
從L1快取獲取資料
fetch from L1 cache memory
0.5 nanosec
分歧預測失誤
branch misprediction
5 nanosec
從L2快取獲取資料
fetch from L2 cache memory
7 nanosec
互斥鎖定/解鎖
Mutex lock/unlock
25 nanosec
從主記憶體獲取資料
fetch from main memory
100 nanosec
從1Gbps頻寬的網路傳送2K bytes資料
send 2K bytes over 1Gbps network
20,000 nanosec
從記憶體循序讀取1MB資料
read 1MB sequentially from memory
250,000 nanosec
取得新磁碟位址(搜尋)
fetch from new disk location (seek)
8,000,000 nanosec
從磁碟循序讀取1MB資料
read 1MB sequentially from disk
20,000,000 nanosec
將封包從美國送到歐洲再傳回
send packet US to Europe and back
150 milliseconds = 150,000,000 nanosec


附錄:言語選擇
Appendix: Language Choice

有些人會問,他們應該從哪個程式語言開始學習。這並沒有固定答案,但是可以考慮以下幾個標準:

  • 利用你的朋友Use your friends。 當被問到「我該用哪個作業系統呢? Windows, Unix, 還是Mac?」,我的回答通常是「用你朋友用的那個」。 向你朋友學習的好處將會在不同OS或是不同程式語言間的固有問題上被抵銷掉。 同時,考慮那些你未來會結交的朋友:程式員社群,如果你持續下去的話,你將會是他們的一部分。 你所選擇的語言是否擁有一個大型成長中的社群,還是他擁有的是一個小型且逐漸萎縮的社群?是否有書籍,網站,以及線上討論區可以得到答案? 你是否喜歡那些討論區中的人們?
  • 維持簡單Keep it simple。 像C++與Java之類的程式語言,設計給那些經驗老道的程式員所組成的大型團隊作專業開發,那些人關心他們的程式碼的執行時期效率。 結論上來說,這些語言會擁有一些為了達成這些目標而設計的複雜部分。你應該關心在學習程式上。你不需要那些複雜的部分。你需要一個語言設計便於單一新手程式員學習與記憶。
  • 玩 Play. 一樣是學彈鋼琴,你會比較喜歡哪種方法?一般,互動的方法,那這種方法之中你可以聽到每個音符,就當你壓下琴鍵之後馬上;或是"批量"模式,在那種方法中你只能在完成整首歌之後才能聽到音符。很明顯的,互動模式會讓鋼琴易於學習,而寫程式也是一樣。堅持使用一個擁有互動模式的語言。

鑑於這些標準,我建議第一個程式語言可以用Python或是Scheme。 其他的選擇是JavaScript,不是因為它是完全為初心者精心設計,而是因為它有大量的線上教學,像是可汗學院的教學 Khan Academy's tutorial。 但是你的情況可能會有所不同,而且還有其他不錯的選擇。 如果你的年紀還只有一位數,你可能會比較喜歡愛麗絲Alice 或是Squeak 或是Blockly(有點年紀的學習者也可能會喜歡他們)。重點是你已經選好了一個,並著手開始。


附錄:書籍與其他資源
Appendix: Books and Other Resources

有些人要求我建議一些學習用的書與網頁。我會重複我的論調「只看書是不夠的」,但是我可以建議以下的資源:




筆記 Notes

  1. T. Capey指出亞馬遜書店上的完全問題解決者 Complete Problem Solver一頁現在有"21天自學孟加拉Teach Yourself Bengali in 21 days"與"自學文法與風格Teach Yourself Grammar and Style"在「購買此商品的人同時也買了這些商品」的欄位中。我猜有一大部分的人是從這個網頁找到那本書的。
  2. 感謝Ross Cohen幫忙有關Hippocrates的部分。



原始內容是由Peter Norvig前輩的網站上轉譯而來
原始網址於此:(blog)http://www.yamdas.org/column/technique/21-daysj.html

原本的網站上有各國翻譯的連結。但很不巧的,中文的連結失效了。
於是我參照了日文翻譯與原文重製了我自己的翻譯版本。
希望對有需要或是想參考的各位有所幫助。
Updated: 2015/02/20

GoogleCode-Prettify

SyntaxHighlighter

人気の投稿