2016年11月24日 星期四

What are some things you wish you knew when you started programming?

I wish I knew a ton stuff, but 27 things come to mind.

Full disclosure: I put the most important things at #14 and #26 (depicted above) because I’d love for you to read the full answer. I think you’ll enjoy it.
1. You learn by doing. The only way to get better at programming is to actually program. Don’t let an analysis paralysis prevent you from ever starting.
2. Programming isn’t like studying for a test. Memorizing stuff doesn’t matter all that much.
3. Cheating is completely acceptable. I use Google to solve most of my problems, and so do most programmers.
4. Letting problems pile up without checking is a poor strategy. I used to make endless changes to my code and expect it to work right away. The problem with this approach is that it stacks one problem on top of another, and it becomes difficult to figure what went wrong.
5. Learning by yourself is really tough. Talking about code and collaborating with other aspiring developers is a better way to learn for most people.
6. Let go of your emotions. You’re going to see error messages on your journey to becoming a programmer. When screwing up is such an integral part of the process, you need to be ok with making mistakes in order to grow.
7. You don’t need 5 monitors. Contrary to what Hollywood might tell you, you don’t need an insane external monitor setup to be a programmer. The computer that you own right now is probably good enough to use to start programming. Don’t waste your money.
8. There’s a BIG difference between a capital letter and a lowercase letter. It took me a while to get used to noticing subtle differences between similar symbols, and it can be pretty frustrating until you get used to it.
9. Trying to understand everything is a lost cause. In the beginning, I tried to chase down the “why” to every problem I encountered. This isn’t necessary. Computers are so complex and there is so much to learn, and you’re never going to understand everything. That’s ok.
10. Pair program as much as possible. There is no faster way to learn how to code.
11. Changing bad code is part of the process. I used to think that every piece of code I wrote needed to be perfect. But making improvements to your code is normal. You’re not writing a book that can’t be changed once it’s published.
12. There’s a right way to ask for help. Everybody needs to ask for help at some point. And when you do, make sure that you do these 4 things:
  • Overcommunicate details that you see.
  • Explain exactly what you think should be happening.
  • Explain exactly what is actually happening.
  • Explain why you think it should be working differently.
When you go through this process, you’ll often come across a solution without ever asking for help. It makes you think about problems in a holistic way.
13. You don’t need to be a math genius. If you’re not a “math person,” that doesn’t mean that you can’t be a programmer.
14. Always celebrate the small wins. Building stuff with code is really cool. I never would have arrived where I’m at if I hadn’t stepped back and admired the awesome things I was building along the way.
15. Meet-ups are incredibly valuable. In the beginning, it was pretty intimidating to get myself to the point where I felt comfortable attending these. But once I did, I realized that there were a ton of developers just like me.
16. Avoiding merge conflicts makes you happier. Merge conflicts are annoying. So when I realized that I could sneak a feature in before a teammate so that he/she had to deal with these instead of me, I was super excited.
17. It’s ok to admit what you don’t know. When you land your first programming job, you might be inclined to “fake it till you make it.” Don’t. Nobody expects you to know everything right away.
18. It doesn’t take 10,000 hours to be good enough to land a job. In reality, you need to be good enough to know how to self correct and get back on track when problems arise. This takes far less time than 10,000 hours.
19. You’re going to wake up in the morning thinking about code. And when it happens, it’s really freakin’ cool.
20. It’s ok to make big mistakes. I once made a mistake that cost my company $10,000 dollars. In the process, I learned the most important lesson of my programming career.
21. An algorithm is like finding a name in a phonebook. Algorithms are a step-by-step approach where there is exactly one correct next step. An easier way to think about this is the strategy that you would take to find one specific name in a phonebook.
22. You’re never going to feel like you’re ready to program full time. Imposter syndrome is real. Try to remember that it’s normal to not know everything. The most important thing is understanding that you can figure out the stuff that you don’t know.
23. Programmers never stop learning. New technologies come out all the time, so the programmers that succeed are the ones who continue to learn and develop their craft on an ongoing basis.
24. Make the computer think like a human. Too many people have the impression that you need to think like a computer. It’s actually the opposite.
25. Programming is about using the right tool for the job. There are so many different open source libraries, tools, and frameworks at your disposal. So you need to grow your developer toolkit and understand which tool makes sense for each problem that they encounter.
26. It’s common to give up right before change is about to happen. Learning to code (especially to the point where you can switch careers) is a lot of work. It takes time and a lot of discipline, but it is possible. Too many people make the mistake of doing almost enough work to to get where they want.
27. Learning to code isn’t easy. But that’s why it’s worth doing.
In hindsight, I’m actually really happy that I was so naive in the beginning. Knowing so little back then gave me the motivation to think critically about everything I learned later on.
Now I get to spend time helping other people achieve their goals through code. What could be better than that?
Too many beginner programmers worry about when they’ll be ready to start programming full time. So I wrote about the one milestone that means you’re ready to make the leap
If you liked my answer, I’d really appreciate it if you upvoted it by pressing the light blue button below.

IT如何入行(2) - 入行條件

Monday, June 16, 2014

想入行做IT o既朋友,第一個問題一定係:「要識D咩先可以入行呢?」講真,唔係嚇你,做IT其實同做超人差唔多,去jobsDB望一望IT工嘅job description就知,間間公司都想請超人。要識嘅野多到嚇死你。

舉個例,IT Support需要非常廣泛o既知識,又要經常update市場上新出o既軟件硬件o既知識,又要托得起server機,仲要經常同vendor吹水,所以做IT Support一D都唔容易。但係,唔知咩係IT o既人,經常以為IT Support請返黎就係service佢地,會呼呼喝喝,所以做IT Support亦都要好高EQ。

先講IT行業最多人有嘅野學歷。其實無論係唔係做IT都好,大學生己經通街都係。而IT行業,最近幾年己經係碩士滿天飛。好多都係喺大學讀埋個MPhil先出黎做野,而更多嘅係出黎做左幾年野,自知競爭激烈而進修碩士學位。所以,一般IT公司嘅學歷比例多數係一半碩士,一半學士。如果連學士都冇,咁要入行就難上加難。

不過,無論學歷幾高,都總有人係拎住張沙紙就以為可以呃飯食。事實上,就算你有學歷,要順利通過interview係一D都唔容易。CV要寫得靚,最好有埋Cover Letter,仲要識面試技巧。好多時仲有筆試,有時要即場比電腦你寫code,更多時淨係比幾張紙你就要寫code。test paper由十幾頁到幾十頁都有,interview由一小時到五六小時都有,小弟試過最短嘅interview係半個鐘,最長係五個鐘。想知更多關於interview嘅野,可以參考IT interview系列:


IT interview (9) - Cover Letter

IT interview (8) - CV

IT interview (7) - 你in我時我in你

IT interview (6) - Q&A

IT interview (5)

IT interview (4)

IT interview (3)

IT interview (2)

IT interview

不過講到尾,想入行做IT人,當然要腦筋好,轉數快,最重要係EQ高,如果唔係點樣解決排山倒海嘅adhoc request嘅同時仲保持到唔發老脾。另外仲要學野快,因為IT真係日新月異,基本上每一日都要update自己,隔左一排唔update就好難追返架喇。英文千萬唔好太差,一日send幾十封email係好普通嘅事,而且全部英文,唔好以為英文差做IT就ok,我擔保你一定好痛苦。近年普通話同殘體字都一樣咁重要,呢樣真係唔知你點學返黎,自己諗掂佢。

咁幾時先係入行好時機呢?喺2001年科網股爆破,再加上2003年沙士後,IT一直都係一工難求,導致大量畢業生對前景唔樂觀而轉行。但係到左十幾年之後嘅今日,就係因為當年冇人肯入行,結果令到IT界人才極度短缺,十年以上經驗嘅IT人就更加係買少見少。所以如果想入行嘅話,而家就係時候喇。

IT如何入行(1) - IT係乜東東?

Tuesday, May 27, 2014

近呢一兩年,IT熱潮又黎料,唔單止科網股被炒起,連報讀IT相關課程o既人都增加唔少。好多人對IT非常好奇,覺得D野好新奇刺激,亦對IT行業有無限o既幻想,以為做IT同打機一樣咁好玩。我相信,好多人連IT係乜都唔知就話對IT有興趣,仲口聲聲話想入行添。所以今次就寫返個IT如何入行系列講講呢個話題。

IT界o既範圍其實非常大,而且有好多灰色地帶。簡單分類的話,IT主要可以分為以下幾類人:
1. Programmer / Software Engineer / Software Developer
2. System Administrator / System Support / IT Support / System Engineer / Infrastructure Engineer
3. Business Analyst / Project Officer / Project Manager
4. Technical Account Manager / Technical Sales
5. Quality Assurance Engineer / Software Tester
6. Database Administrator

第一類人統稱為Programmer,主要工作係寫program,即係「揼code」。Programmer通常只會專於一兩種programming language,例如C++,Java,C#呢D都係比較大路。冷門/專門少少o既language有Python,Cobol,Tcl,Delphi。而Programmer通常都會再細分幾類,例如Web Programmer會專門寫Web Application,仲有UI/UX Designer,雖然叫Designer,但好多時都係Programmer黎,會專門寫User Interface,執靚個介面比人睇。仲有一類係專寫server side application,通常最覆雜o既business logic都會集中o係呢度。

第二類人統稱為IT Support,九成公司都會有一兩個IT Support,主要係setup成個network,common drive,printer,甚至電話系統,仲要負責買電腦,network equipment,software license。如果間公司係做D mission critical o既business,例如股票交易系統,咁好多時IT Support都要通頂去deploy system。如果要搬office,通常最多野做o既都係IT Support。

第三類人係Business Analyst,主要係負責將business requirement寫成一D IT人先睇得明o既文件,方便IT人同非IT人溝通。事實上,IT人有自己o既document format,仲有不同o既diagram去記低network structure,system architecture等。通常非IT人睇完都唔知D咁專業o既圖/doc講乜。

第四類人係Technical Sales,通常只會出現o係vendor公司。由於佢地要幫間公司賣IT product,所以佢地除左要把口了得之外,都要具備technical knowledge。

第五類係QA,主要係做測試,用盡所有方法去令D system出事,從而令quality提升,通常大公司先會有。細公司通常都會由programmer自己做埋testing,所以呢類人係比較少。

第六類係DBA,主要係睇住D database,manage user access rights,fine tune database performance等。通常只有用Oracle o既大公司先會有DBA因為只有Oracle先會難用到需要有專人照顧。

除左以上六類IT人之外,其實仲有好多唔知算唔算IT人o既工種,例如上門幫你裝寬頻o既師傅,佢地可能會claim自己係IT人,但佢所做o既野,可能只係IT Support 工作內容o既一小部份。OK,就當佢地係IT人,咁腦場賣電腦/幫人砌機o既人呢?佢地可能又會claim自己係IT人,但我覺得如果佢地都係,咁半個深水埗o既人都係IT人。。。

其實IT係一個非常專業o既area,因為IT知識並非睇下書,唔洗郁手就識。冇返三五七年,想學IT野,只能掂到皮毛。相反,一D聽落好專業o既area,例如會計,有時真係求其阿豬阿狗都可以叫自己係做會計囉。

http://samsamyung.blogspot.hk/2014/05/it1-it.html

2016年11月17日 星期四

30 天精通 Git 版本控管 (01):認識 Git 版本控管

第 01 天:認識 Git 版本控管

筆者使用 Subversion (SVN) 已經將近 10 年,從來都不覺得有任何必要轉換至其他版本控管平台,直到前幾年因應雲端化的改變,慢慢導入 TFS 版本控管 (TFS Service),轉換的過程還算順利,只因為 SVN 與 TFS 的版本控管概念相近,都屬於集中式版本控管系統。這類集中式版本控管系統,使用上簡單、直覺且容易進行權限控管,說真的,在大部分的開發情境下,Subversion 或 TFS 已經相當足夠,那又是甚麼契機或是需求,迫使我們一定要轉換到 Git 版本控管呢?我相信,不同人採用 Git 一定有他的理由,有些人覺得好玩、有些人覺得新鮮、有些人覺得功能強大,無論如何,只要這個理由能夠支持你去主動認識一個陌生技術,都是好的,本篇文章除了帶大家認識 Git 版本控管機制外,也會說說我想轉換到 Git 的理由。

文章目的

在軟體開發領域,對原始碼進行版本控管是非常重要的一件事,有別於 Subversion 或 TFVC (Team Foundation Version Control) 這類集中式版本控管系統,Git 是一套分散式版本控管系統(DVCS; Distributed Version Control System),並帶來許多版本控管上的各種優勢與解決傳統集中式版本控管的缺失,例如支援本地操作、備份容易、功能強大且彈性的分支與合併等等。不過,由於 Git 版本控管無論在版控觀念與工具使用上,都與傳統集中式版控工具差異甚大,因此造成了不小的學習門檻。
雖然說本次文章的主題是「30 天精通 Git 版本控管」,不過,說實在的,還真有點言過其實了,因為 Git 博大精深,有非常多細節可以探究,如果真的要應用在工作上,學幾天可以真正上手呢?每天學一點,連續學習 30 天,似乎是個合理的數字 (或太多?),如果有一個工具大家都要用,而且要立刻上手的工具,如果學 30 天都還不知道怎麼活用,那這學習門檻也太高了些。因此我想,這個系列的文章,主要還是專注於「如何在 30 天內學會 Git 版本控管,而且必須要能熟練的應用在實務開發工作上」,這才是本系列的真正目的,那些繁瑣的細節,我不會特別強調,但總是有些重要的概念與細節還是不能錯過,我會嘗試在每一個主題中提到一部份,一有機會就會深入探討,希望大家可以透過做中學,深刻體會 Git 版本控管的強大魅力。

轉換的契機

這幾個月,公司因為有個大型專案,參與開發人數超過 12 人,最後大家決議採用 Git 作為本次專案的版本控管機制,與其說我們採用了 Git 版本控管,其實真正採用的原因是「我們選擇使用 GitHub 當成我們的版控平台」,原因就是 GitHub 平台實在整合得太好,完整的 Git 版控支援、議題追蹤與管理、線上 Wiki 文件管理、友善的原始碼審核(Code Review)介面。這些特性,都能有效協助我們在多人協同開發的過程中,減少團隊溝通的問題。
剛開始接觸 Git 說實在挺辛苦的,因為 Git 版本控管的觀念,實在與 Subversion 差太多,沒有辦法很直覺的去體會其差異,就算給了你 GUI 圖形化工具介面,你也不見得就會使用。你知道的,一個強大又好用的工具在你手上,「錯誤的使用方式」比「不會用」還可怕!說穿了,就是你必須先建立一套思維模式(Mindset),了解 Git 的運作原理,然後再上手使用 Git 相關工具 (無論是指令列工具或圖形化介面工具),才是正途!

學習的方法

我在剛學習 Git 的時候,看了好幾本書 (其實是挑重點看),也看了許多線上的文章與簡報,甚至還看了好幾部教學影片,看著看著,確實可以學會如何使用 Git 工具,我覺得並不會太過艱深。不過,Git 的指令與參數非常多,完全超出大腦能記憶的範圍,除非每天使用,否則哪有可能一天到晚打指令進行版控,如果每次要使用 Git 指令都要查書的話,那這也太沒效率了點,當下的我就直覺地認為,學習 Git 最終還是要回歸到好用的 GUI 工具,否則這東西在團隊中可能不容易推廣。
再者,因為 Git 是屬於「分散式版本控管」機制,當開發人數開始變多,版本庫又開始變成一人一份時,在第一次進行多人分支與合併的過程時,大家都飽受煎熬,而且持續一段不短的時間。雖然公司內部有先進行技術分享,不過由於大家都是第一次學,那些 Git 的抽象概念,還沒辦法深植人心,只能基於 Git 的使用方法進行分享,例如工具怎麼用、有哪些常用的指令、甚麼特殊的情況下應該下甚麼指令,諸如此類的。過程中就算說出了複雜的原理,由於大家對於 Git 的認知還很模糊,不同人對 Git 版控方式的理解也不盡相同,所吸收到的知識與概念,也不一定一致。所以,雖然上完課了,大家還是需要好幾天的時間不斷磨合,相互討論,互相解決問題,如果你只有一人使用 Git 的話,確實不容易感受 Git 帶來的好處,也恐怕不容易堅持下去。
所以,我認為,要學好 Git 版本控管,若先知道以下幾點,也許比較容易學會:
  • 先擁有 Git 基礎觀念,透過下指令的方式學習是最快的方式,不要跳過這一段
  • 找多一點人跟你一起學 Git 版本控管,最好能直接用在實務的開發工作上
  • 團隊中最好要有幾個先遣部隊,可以多學一點 Git 觀念,好分享給其他人,或有人卡關時,能適時提供協助
  • 了解 Git 屬於「分散式版本控管」,每個人都有一份完整的儲存庫(Repository),所以必須經常合併檔案
  • 使用 Git 的時候,分支與合併是常態,但只要有合併,就會有衝突,要學會如何解決衝突

認識 Git 版本控管

Git 的出現,來自於 Linux 之父 "Linus Torvalds" 開發 Linux kernel 的時候,因為早期的版本控制方法非常沒有效率,屬集中式控管,當 Linux kernel 這類複雜又龐大的專案在進行版本控管時,出現了許多問題。最早期 Linux kernel 採用 BitKeeper 進行版本控管,但後來 Linus Torvalds 基於 BitKeeper 與 Monotone 的使用經驗,設計出更棒的 Git 版控系統。原先 Git 只被設計成一個低階的版控工具,用來當做其他版控系統(SCM)的操作工具,後來才漸漸演變成一套完整的版本控制系統。
有趣的是,Linus Torvalds 改採 Git 進行版本控管初期,由於 Git 太過複雜,許多版控觀念跟以往差異太大,也受到世界各地開放原始碼社群的反對,但經過幾年的努力與發展,操作 Git 的相關工具也越來越成熟,才漸漸平撫反對的壓力,從 2013 年的市場調查看來,全世界已有 30% 的開放原始碼專案改採 Git 進行版本控管,這是個非常驚人的市占率,意謂著 Git 絕對有其驚豔之處,不好好研究一番還不行呢!
講到 Git 的架構,完全是基於 Linus Torvalds 在維護 Linux kernel 這個大型專案時得到的經驗,以及他本身在檔案系統優化方面的豐富經驗進行設計,也因為這樣,Git 包含了以下幾個重要的設計:
  • 強力支援非線性開發模式 (分散式開發模式)
    • Git 擁有快速的分支與合併機制,還包括圖形化的工具顯示版本變更的歷史路徑。
    • Git 非常強調分支與合併,所以版本控管的過程中,你會不斷的在執行分支與合併動作。
    • Git 的分支機制非常輕量,沒有負擔,每一次的分支只是某個 commit 的參考指標而已。
  • 分散式開發模型
    • 參與 Git 開發的每個人,都將擁有完整的開發歷史紀錄。
    • 當開發人員第一次將 Git 版本庫複製(clone)下來後,完全等同於這份 Git 版本庫的「完整備份」。
    • 整個版本庫中所有變更過的檔案與歷史紀錄,通通都會儲存在本機儲存庫(local repository)。
  • 相容於現有作業系統
    • Git 版本庫其實就只是一個資料夾而已,資料夾中有許多相關的設定檔與各種 blob 物件檔案而已。
    • Git 版本庫可以用任何方式發布,所以你用 HTTP, FTP, rsync, SSH 甚至於用 Git protocol 都可以當成存取 Git 版本庫的媒介,相容性極高。
  • 有效率的處理大型專案
    • 由於完整的版本庫會複製(clone)一份在本機,該版本庫包含完整的檔案與版本變更紀錄,所以針對版本控管中的各種檔案操作速度,將會比直接從遠端存取來的快上百倍之多。
    • 這也代表著,Git 版本控管不會因為專案越來越大、檔案越來越多,而導致速度變慢。
  • 歷史紀錄保護
    • Git 版控的過程,每次 commit 都會產生一組 hash id 編號,而且每個版本在變化的過程都會參考到這個 hash id,只要 hash id 無法比對的上,Git 就會無法運作,所以當專案越來越大,版本庫複製(clone)的越來越多份,你幾乎無法竄改檔案的內容或版本紀錄。
    • 請記得: 每個人都有一份完整的版本庫,你改了原始的那份,所有人的版本庫就無法再合併回原本的版本庫了,所以你幾乎不可能任意竄改版本紀錄。
  • 以工具集為主的設計 (Toolkit-based design)
    • Git 被設計成一個一個的工具軟體(指令列工具),你可以很輕易的組合不同工具的使用,使用上非常彈性。
  • 彈性的合併策略 (Pluggable merge strategies)
    • Git 有一個擁有良好設計的「不完整合併(incomplete merge)」 機制,以及多種可以完成合併的演算法,並在最後告知使用者為何無法自動完成合併,或通知你需要手動進行合併動作。
  • 被動的垃圾回收機制
    • 在使用 Git 的時候,若想要中斷目前的操作或回復上一個操作,都是可以的,你完全可以不必擔心可能有其中一個指令下錯,或指令執行到一半當機等問題。
    • Git 的垃圾回收機制,其實就是那些殘留在檔案系統中的無用檔案,這個垃圾回收機制只會在這些無用的物件累積一段時間後自動執行,或你也可以自行下達指令清空它。例如: git gc --prune
  • 定期的封裝物件
    • 我們在 Git 中提到的 "物件" 其實就是代表版本庫中的一個檔案。而在版本異動的過程中,專案中的程式碼或其他檔案會被更新,每次更新時,只要檔案內容不一樣,就會建立一個新的 "物件",這些不同內容的檔案全部都會保留下來。
    • 你應該可以想像,當一個專案越來越大、版本越來越多時,這個物件會越來越多,雖然每個檔案都可以各自壓縮讓檔案變小,不過過多的檔案還是會檔案存取變得越來越沒效率。因此 Git 的設計有個機制可以將一群老舊的 "物件" 自動封裝進一個封裝檔(packfile)中,以改善檔案存取效率。
    • 那些新增的檔案還是會以單一檔案的方式存在著,也代表一個 Git 版本庫中的 "檔案" 就是一個 Git "物件",但每隔一段時間就會需要重新封裝(repacking)。
    • 照理說 Git 會自動執行重新封裝等動作,但你依然可以自行下達指令執行。例如: git gc
    • 如果你要檢查 Git 維護的檔案系統是否完整,可以執行以下指令: git fsck
關於 Git 的分散式版控系統,我再重申幾件事:
  • Git 完全不需要伺服器端的支援就可以運作版本控制,因為每個人都有一份完整的儲存庫副本。
  • 因為每個人都有一份完整的儲存庫副本,所以每次提交版本變更時,都僅提交到本地的儲存庫而已,因此提交速度非常快,也不用網路連線,可大幅節省開發時間。
  • 由於每個人都有一份完整的儲存庫副本,代表著在使用 Git 版本控管時,沒有所謂的「權限控管」這件事,每個成員都能把儲存庫複製(clone)回來,也都可以在本地提交變更,沒有任何權限可以限制。使用 Git 時,唯一能設定的權限是,你有沒有權利存取上層儲存庫(upstream repository)或遠端儲存庫(remote repository)的權限。
  • 如果需要跟別人交換變更後的版本,隨時可以透過「合併」的方式進行,Git 擁有非常強悍的合併追蹤(merge tracing)能力。
  • 要合併多人的版本,你只要有存取共用儲存庫(shared repository)的權限或管道即可。 例如:在同一台伺服器上可以透過資料夾權限進行共用,或透過 SSH 遠端存取另一台伺服器的 Git 儲存庫,也可以透過 Web 伺服器等方式來共用 Git 儲存庫。

今日小結

今天這篇只是個大致介紹,若看不太懂 Git 的設計理念沒關係,你可以用一段時間之後再回來看這篇文章,或許會有更深一層的體會。
我覺得要寫「認識 Git 版本控管」比教大家怎麼用還難許多,以下我在列出一些 Git 相關連結,供大家進一步學習。

參考連結


2016年11月15日 星期二

Upload large files to S3 using Laravel 5

This is the code he used (slightly redacted):

$disk= Storage::disk('s3');
$disk->put($targetFile, file_get_contents($sourceFile));
This is a good way to go about it for small files. You should note that file_get_contentswill load the entire file into memory before sending it to S3. This can be problematic for large files.
If you want to upload big files you should use streams. Here’s the code to do it:

$disk = Storage::disk('s3');
$disk->put($targetFile, fopen($sourceFile, 'r+'));
PHP will only require a few MB of RAM even if you upload a file of several GB.
You can also use streams to download a file from S3 to the local file system:

$disk = Storage::disk('s3');
$stream = $disk->getDriver()
               ->readStream($sourceFileOnS3);
file_put_contents($targetFile, stream_get_contents($stream), FILE_APPEND);
You can even use streams to copy file from one disk to another without touching the local filesystem:

$stream = Storage::disk('s3')->getDriver()
                             ->readStream($sourceFile);
Storage::disk('sftp')->put($targetFile, $stream);

2016年11月11日 星期五

十年來,程式設計領域有什麼重要進展?

编程语言层出不穷,然而内核是万变不离其宗。我个人看法觉得是以下几个方面的变化比较明显。
语言本身:
1. 工业标准
网页标准有 W3C 控制,尤其是浏览器的开发,所有主流的浏览器都会自觉符合这个组织的标准,当然这些开发商本身就是这个组织的成员。所以新的 HTML5,CSS3,ES6 JavaScript 的新特性的得到顺利推动,让大部分主流浏览器都支持它,W3C 功不可没。
PHP 有 PHPFIG 组织,虽然不是强制性的,但是很多新的框架和库都自觉遵守这个组织的编程标准。
Java, C 语言都有各自的工业标准准则,来维护各自工业标准。
这个标准其实不是强制性的,虽然很多程序员在自己工作上,不遵守这些工业标准,但是要推出新的模块的话,不遵守这些工业标准的模块,是没有人会去使用的。如今是不是面向标准编程,是体现一个程序员是否专业,一个模块是不是专业模块的一个重要指标。
2.第三方模块走红
各种语言的框架和库,可能比自己的语言还出名,比如 CSS 的 BootstrapJavaScript 的 jQuery;一个好的框架和库甚至可以推动这个这个语言的发展,比如说 PHP 的 Laravel 框架,JavaScript 的 jQuery.
模块化的发展,大大加快了开发的速度。很多人也愿意开发各种框架和模块,不但可以锻炼自己的开发技能,也是一种展示自己的能力。
过去,程序员要成名,要开发出有用的软件,比如说求伯君开发出了 WPS,牛;张晓龙开发出了 Foxmail,牛。
现在,程序员要成名,开发出一个大家都会用的框架和模块也行。比如 Evan You 开发的 Vue.js,玉伯开发的 SeaJs。
3.模块化编程和依赖管理
在 2010 前,依赖管理工具只是个很时髦的概念,大家习惯手动到库的官方网站上下载后手动导入到项目中。升级也是个麻烦事。所以一般大家也就下载一两个必要的库,其他都自己手写完成。
如今,依赖管理工具已经是必备的了,大家不再手动导入库了;而且是能找到第三方模块的功能,就不再自己编写了,统统用工具导入项目;自己编写的程序代码,能模块化的代码统统模块化,甚至是独立出来,网上开源,然后使用依赖管理工具进行管理导入到自己的项目中。
这样好处也明显:
  • 代码量减少
  • 加快开发速度
  • 高度解耦
  • 定位 bug 容易,改动影响小
  • 写单元测试容易
如今大家更加愿意写小模块,而不是重复造轮子了。
4. 框架使用
更愿意先选一个合适的框架,再开始编程,而不是所有功能自己从头开始写了.
  • JavaScript 的框架多了,Vue,React, Backbone,AngularJs 等;
  • CSS 有 Bootstrap,Fundation 等;
  • PHP 有 Laravel,CakePHP 等
  • C#有 MVC
  • Java 有 Spring+Hibernate+struts
框架要先选好,模块的话,等需要慢慢加就行了。
5. 测试代码
2006 年,单元测试在开发过程中,重要性不是很大,可有可无,程序完成,功能能用就行。
如今的代码,没有单元测试部分,这个工程就不能算完结。甚至是,测试驱动开发已经成为主流,先写测试代码,然后开发。
测试代码的发展有不单单是单元测试部分。单元测试,集成测试,功能测试,性能测试,压力测试等等,都在开发过程中占了极大的位置。以前测试都是由专门的测试员进行人工测试,或者他们负责测试;如今单元测试和集成测试都是要开发者自己写。
6.跨设备,跨平台
Java 提出的跨平台,一次编译到处运行的梦想,其实至今未很好的实现。但是如今这个跨设备,跨平台编程趋势却越来越明显了。
跨设备,主要是指桌面和手机,尤其是针对显示器的最佳实践是层出不穷,如今是响应式成为了主流
跨平台,出自于 Java 的一个概念,如今已经算普及了,尤其是 JavaScript,桌面,手机,服务器,浏览器,嵌入式都能看到 JavaScript 的身影,这大大归功于 JavaScript 标准化的推广。跨平台过去是说一次编译到处运行;如今是只要这个平台支持这个语言或标准,就能用。如今的跨平台编程,更讲究特性检查这个功能,如果你这个 平台没有这个特性,那么就关闭这个有这个特性的功能,但其他功能还可以继续使用。
今后,各种设备层出不穷,VR 头盔,AR 眼镜,巨型屏幕,物联网等等,跨平台会有进一步的发展。
工程方面的:
1.工具化
我觉得工具化非常突出了,凡是能工具完成的事情,绝对不手工完成。以下几个方面都是可以找到相应工具,帮助开发者管理代码质量
  • 代码风格检查
  • 工业标准检查
  • 代码整理
  • 代码复杂度检查
  • 单元测试覆盖率检查
  • 依赖管理
  • 压缩代码
  • 重复代码检查
  • 无用代码检查
等等,
2. 工程化
工程化也是近年来最最突出的一个发展趋势,过去只是选择性的,现在是必须的。
工程化是以工具化为基础的,没有工具,那么工程化也无从谈起。
工程的核心就是流程自动化,又称之为构建,这些包括了:代码质量检测,代码压缩,代码合并,代码优化,代码编译,单元测试等等部分。构建就是把这些以工作流程的方式组合起来,然后用一个命令行运行这整个流程。它有点像批处理,但是是程序开发中使用的特殊批处理
在网页编程的过程中,现在又流行“实时编程”,就是当你在保存代码的时候,以上的构建流程就开始工作完成后自动刷新浏览器,保证新代码效果立刻反应在浏览器上。
现在,你去 GitHub 的项目库中找软件,首先翻看,是否有工程文件,看看它的构建流程是什么,就知道这个项目的专业程度和项目的质量了
而自己,没有一个配置一个工程化的流程系统,都不好意思说自己在做软件工程。
3. 自动化
自动化是以工程化为基础的,工程化本身就是一种流程自动化。而自动化有在工程化的过程中更进一步的自动化。
持续集成就是全自动化的一个终极体现。他的主要流程是:版本控制库 ->构建 ->测试 ->报告.
持续集成有点像 Windows 的定时任务,但是它是程序开发专用的定时任务。
持续集成的特点就是全自动,一个项目一次配置好了后,要求不变的话,就不用管了;然后开发者不断把代码加入到版本控制库里就行了,每当库有新代码时 候,持续集成就会下载代码进行构建;当它完成构建和测试后,如果测试没有通过,就会报告给你,然后你根据报告结果进行修改代码。所以你每次往版本库加的新 代码时候,持续集成就会全自动的帮你构建和测试代码,尽快的通知你代码的问题。这样程序员就可以更加集中精力编写功能代码和测试代码,而不用担心新代码是 否会影响到过去的代码了。
持续集成在多人一起开发的时候,更是有用,谁上传的代码没通过测试,能马上知道。这样保证多人项目在代码顺利合并,体现“持续集成”的功效。
另外还有个持续部署,其实就是持续集成在测试成功后部署上产品服务器上的流程。如今有些网站一天就要部署几十次,有了持续部署后,部署多少次都毫无压力。
工具化,工程化,自动化的关系挺有意思,前者是后者的基础,而后者却极大推动了前者的发展。它们是相互积极作用,相互推动了对方的发展,形成了一个很好的良性循环
其他方面:
1. 版本控制,Git,GitHub
版本控制在编程界中的地位是越来越重要了。在编程界中有个说法:没有版本控制的项目,就等于没有这个项目。
版本控制的工具很多过去有 SVN,如今 Git 的强大,用的人也是越来越多,而它和 GitHub 的相同作用下,对编程界的积极影响和积极推动,是令人无法忽视的。比如几乎所有的依赖管理工具的库下载源,都是和 GitHub 绑定的, 就这一点来说,GitHub 的重要性在 IT 就不可估量。
而 GitHub 上和 Git 的方便管理,上传,查看,统计,bug 报告等功能更是极大地推动了程序员之间的合作;GitHub 上的开源更是改变了开源软件对世界的影响力。
GitHub 不是 Git 的全部,Git 也不是版本控制的全部,本质上来说,GitHub 只是一个网站而已;然后 GitHub 确实又是这个编程世界不可缺少的一个重要的模块,已经成为了一个不可或缺的组成部分了。甚至 GitHub 已经跳出了编程界,成为了一个世界级的不可或缺的服务平台了。然而 GitHub 是 2008 年建立的,真正开始流行是在 2012 年的。在 2015 年 Google 宣布关闭自己的 Google Code。可见 GitHub 的影响力,以及在业界的重要程度了。
2.生态圈意识
生态圈意识在业界是越来越强了,它应该和编程工具化和工程化有极大的关系。一个语言,框架或者库的出现,人们用它们,不但是因为它们本身的强大,更是因为它们背后的生态圈。
比如说人们选一个 JavaScript 的框架,选 React 还是选 Ember.js,更多是看支持他们的生态圈如何,React 是有 Facebook 支持的,更有很多程序员为它开发相关工具和库以及有很多文档教程。这样 React 的生态圈就很大,会让更多人愿意选择 React 作为第一开发框架。而 Ember.js 相对来说生态圈小,选择它的人可能就不会很多。
选语言也一样,选 JavaScript 编写爬虫还是选 PHP 编写爬虫还是用 Python?更多的是看他们的生态系统了,Python 的爬虫库强大且丰富,所以更多人选用 Python 编写爬虫。
一个新的语言出现,成熟与否,看的就是它的生态圈了,比如是否有测试框架,是否有 MVC 框架,成熟的时间库,数据库 SDK 等等,这些都是其必要的生态圈组成部分。
总结:
以上的这些现象和趋势,其实都是相辅相成的,最终成了一种良性循环。这些现象和趋势都会继续发展下去,并成为以后新趋势的基础。所以这些特点都是非常重要的,而且应该成为每个程序员都应该知道的知识。
一些建议:
我在读编程专业的时候,这些东西大学都没有教过,甚至在工作中,公司都没有这些要求。大学主要教的是代码编写,能编译通过,能出正确结果就可以了。在工作中,代码能用,没有明显 bug 就行。
然而,在我个人工作实践中,逐渐的体会到这些趋势的重要性了,可维护性的高质量代码可以大大减少自己在维护中的难度和压力。作为准备成为一个合格的开发人员,应该熟练掌握这些知识和技能。如果大学没有教过,一定想办法自己学习和提高。
又想到几个发展,这里更新一下
1. WEB 技术的桌面化和 JavaScript 的全栈化
JavaScript 近些年发展火热,逐渐印证了一个 Atwood 法则:凡是可以用 JavaScript 实现的,最终都会用 JavaScript 实现
  • Nodejs 的出现,奠定了 JavaScript 走出浏览器,走向了服务器端
  • NW 的出现和 electron 正式版发布,JavaScript 走向了桌面
  • MongoDB 的出现,JavaScript 走向了数据库
  • Tessel 的出现,走向了硬件和物联网
如今一个全栈系统,从前端到数据库,可以完全使用 JavaScript 一种语言。还有很多人正在致力于把 JavaScript 推向更多的领域中。
而 Web 技术(html+css+JavaScript)由于 NW 和 Electron 的出现,已经可以编写桌面程序了。正是由于 JS 的优秀模块很多,以及 HTML+CSS 的界面容易编写和掌控,纠错工具丰富,很多人愿意用 WEB 技术进行开发。现在比较火的桌面工具有 VS-Code 编辑器和 Atom 编辑器。
总结一下:由于 WEB 技术的便利性,WEB 技术涉及的领域也就越来越多,再也不是浏览器的专利了。
2. Web API 的全面发展
Web API 虽然历史悠久,但是真正使其推广流行的应该是 Twitter,而后移动设备的普及使其得到更大发展和普及。移动设备如果没有 Web API 基本就不能工作了。Web API 的普及,也使得网络服务之间相互连通,形成一个更大的服务网络。总之,如今的 Web API 已经是不可或缺的存在了。
Web API 更多的是一种服务,或是一种数据交换模式。只要语言带有 HTTP 的网络访问功能,就都能使用。提供 Web API 的公司,发布 Web API 后,一般也会同时发布一些常用语言的 SDK,方便相应语言开发人员快速上手;但是如果语言比较小众,没有提供相应的 SDK 也没有关系,编写一段 HTTP 的请求,也是可以交换数据。
从编程的角度来归纳一下 Web API 特点就是:
  • 容易编写,就是个函数,无需界面
  • 语言无关性,无论 Web API 是个语言编写,几乎任何语言都能调用
  • 访问性好,无论在哪,只要网络能访问,Web API 就可以用。
3. 语言之间的相互借鉴
语言之间的相互借鉴也越来越明显了,比如:
  • PHP5.0 后支持了类,5.4 后支持了 Trait,5.5 后支持了生成器(Generator)
  • JavaScript ES6 支持了箭头匿名函数,生成器(Generator),类(不是 Prototype 的类)
  • C# 和 Java 相互借鉴
  • Coffee Script 借鉴 Python 和 Ruby
与其说是相互借鉴,不如说随着语言的发展,一些语言概念逐渐成为了标配,如果没有,就算是一个不完整的语言了。比如说类,匿名函数,常用数据结构等都成为了标配。
4. 语言解析器的工具化
语言解析器(Parser)在过去自是作为编译器的一部分存在的。如今,它已经独立出来作为一个模块或者工具来使用了,这个对于一个语言的生态有着很大的意义,促进了语言生态圈的良好发展。
独立出来的解析器,可以用来编写以下和语言有关的工具,这些工具都是用来优化代码质量的,提高编码体验的。
  • 语法检查,JavaScript 的 JSHint 用的就是 JavaScript 的一个解释器,被 JavaScript 重新解释一遍,把可能有问题的地方标记出来通知程序员,程序员可修改避免潜在错误。
  • 代码最小化,代码重写的一种形式,JavaScript 的最小化项目(比如 Urglify),是把语法正确读取后,进行最小化压缩。把单词变量转换成单字母变量。甚至是 if else 转换成?: 形式。
  • 语法扰乱器,就是代码重写的一种形式,让代码无法阅读,保护代码。
  • 语法整理器,代码重新的一个形式,把无法阅读的代码,转换成可阅读的代码,比如 beautifier。
  • 语法高亮,一般用于代码编辑器和代码显示组件的。
  • 代码分析器, 把可用的代码部分进行扫描,列出代码相关数据,比如用了多少类,多少对象,多少变量,多少全局变量等等
  • 代码清理器,分析器的加强,清理不用的变量,不用的对象和,不用的函数等。
  • 自动完成,一些 IDE 可以分析已经存在的变化和函数,以后在不断的打字中可以智能的自动完成。
  • 代码追踪,比如说某段代码被执行了几次,程序报错时候,函数被执行的顺序,测试程序时候的代码覆盖率等等
  • 虚拟执行,JavaScript 代码在一个保护区域内或环境执行,代码可以返回值,但不能影响非虚拟环境内的代码执行。比如说,代码里面有全局变量,但是虚拟执行后这个全局变量只在虚拟环境内,非虚拟环境的没有这个全局变量。
关于这点,我回答过下面的问题。
5. 数据交换语言的发展
数据交换语言发展总体来说就是从 XML 主流逐渐发展到 JSON 主流的过程. 虽然 XML 现在应用还是非常广泛,但是由于其复杂和标签占用空间大,逐渐被轻量级的 JSON 给代替了。尤其 JSON 与 JavaScript 天然兼容,无需解析,直接使用。所以在很多网络技术中 JSON 是优先使用的。
而如今很多配置文件也是用 JSON 实现的,比如 Composer 和 node 的配置文件。
JSON 的阅读方式更符合程序员的阅读习惯,格式化后的结构一目了然,容易理解。
JSON 好处:
  • 结构符合程序员阅读习惯
  • 文件大小相对更小
  • JavaScript 可以直接使用
  • 在非 JavaScript 的脚步语言中,转化成数据结构更容易
  • 学习曲线很短
正是以上这些原因,使用 JSON 作为数据交换语言可以说在编程界里,是大势所趋了。