Saturday 23 June 2018

你的編程生涯 : 如何避免在編程的黑暗森林中迷失


警告:你的編程生涯

如何避免在編程的黑暗森林中迷失

Author : Vardan Grigoryan 



在剛開始我的編程生涯時,困擾我的主要原因是語言/技術的選擇。我應該學什麼,我應該從哪裡開始?我應該知道什麼才能成為程序員的第一份工作?當時(近10年),沒有Coursera,Udemy或SoloLearn。我無法弄清楚自己的成功工作的確切方向,完整路徑。二十一世紀的宇航員的高薪,充分補貼,善待處理的工作:程序員。

同樣的問題依然存在:初學者被困在選擇之中,沒有一條直線成為一名優秀的程序員,社區也不熱情歡迎像“iz pythn a gut lang ???”這樣的新手問題。 。通往成功編程生涯的道路甚至比以前更加模糊。你(假設你是初學者)應該在C ++ / C ++ 11 / C ++ 14 / C ++ 17,Java,C#,Kotlin,PHP(什麼?),Python,Node.js,JavaScript, ,與Angular,React或Vue?)等等。

語言,技術或技能? The language, the technology, or the skills?
要回答你的主要問題,我必須先問你一個問題。你想要什麼?您是否興奮地構建移動應用程序,網站,像Facebook這樣的網站或像中等網站,或者您是否想要構建像Photoshop這樣的桌面應用程序?也許你完全進入遊戲開發?移動?桌面?

回答“我應該知道什麼才能在科技公司擔任軟件工程師?”的最明智的方法是找出您應該掌握的成功通過技術面試的主要技能。但首先,我們應該把事情整理好,讓我們深入到編程世界,它的國家和城市,文化和戰爭,它的勝利和失敗。對於那些不夠耐心的人,請向下滾動到“編碼採訪準備”部分。


探索編程世界將我們帶到3個主要平台:

網絡(Google搜索,Facebook,亞馬遜,Twitter和其他)
桌面(Dropbox,Photoshop,Visual Studio,Skype等)
移動 (SoloLearn, Instagram, Uber and others)

上述大多數服務幾乎都存在於所有平台中,例如,Skype是桌面應用程序,移動應用程序(儘管做得很差)的Web應用程序,Twitter是一種網絡和移動應用程序等等。

捲筒紙
Web本身在這個背景下是一個巨大的概念,為了闡明它,我們應該把它分解成所謂的前端和後端,後者是我​​個人的最愛。前端就是你所看到的,後端是你需要的,以便看到你所看到的。前端是外觀和感覺,後端是運行應用程序的服務器,處理用戶請求,處理數據庫查詢等等。

前端。如果你想掌握外觀和感覺,也就是建立那些非常漂亮的網站,那麼你應該知道HTML(外觀),CSS(外觀和感覺),JavaScript(感覺)。這還不夠,現在只使用純JavaScript是不夠的,所以你必須選擇正確的框架,目前流行的Angular,React或Vue。哪一個選擇主要基於你最喜歡的公司,谷歌或Facebook?如果你喜歡Google,可以選擇Angular;如果你喜歡Facebook,也可以選擇React。如果你不喜歡他們中的任何一個(奇怪),那麼跟Vue一起去吧。簡單!除此之外,您應該掌握一些基本概念,比如HTTP協議的內部工作原理,熟悉Web服務器(至少您不應該對Apache或Nginx等名稱感到害怕)。作為前端開發人員意味著您可以從後端獲取數據(為用戶進行美化),因此對API的內容,JSON是什麼(以及它為什麼比XML更好)的理解是必須的。 (如果聽起來有些不太熟悉,請查看本文最後的參考文獻部分)。

後端。不可思議的事實,不可思議的故事。在過去,了解PHP足以稱自己為後端開發人員,然後微軟推出了ASP.NET。他們互相爭鬥,直到Node.js來到並將事情按最佳順序排列。 Node.js最適用於事件驅動開發的一些概念,所以如果您選擇它,那麼您會對項目很好。

後端的混亂部分是它的語言多樣性,你可以在後端使用任何你想要的語言,問題是,“後端”是“查詢數據庫,過程數據,響應盡可能高效地為客戶服務“,並且選擇”正確“的語言/技術/數據庫不是一種選擇。雖然有些開發人員使用像MySQL或PostgreSQL這樣的關係數據庫,但新手選擇了黑暗面,NoSQL(如Cassandra或MongoDB)。選擇真的是你的,但我有一個簡單的公式。你的數據是否有嚴格的模式,在不久的將來它不會有太大的變化?選擇關係數據庫。你有每分鐘超過100萬的訪問量嗎?更改為NoSQL(痛苦)。你的產品變化很快嗎?選擇NoSQL。比方說,你現在選擇了哪一方,你應該選擇什麼樣的具體技術?你喜歡微軟,你有Windows服務器?選擇MsSQL。你喜歡甲骨文嗎?選擇Oracle。你對甲骨文沒問題,但你同時討厭微軟?選擇MySQL。你真的不想傷害任何人嗎?選擇PostgreSQL。

NoSQL進入棘手。這真的取決於您的服務和數據架構。你們之間只有文件和一些薄弱的聯繫?選擇MongoDB。你需要存儲一大堆鍵值對嗎?選擇Redis。您正在使用類似圖形的結構(Facebook好友圖表,Google知識圖表等)?選擇Neo4j。不確定你需要什麼,但是你覺得你需要所有這些?選擇ArangoDB。

雖然數據庫包含所有必要的數據,但您應該定義一個API,客戶端可以通過它來請求和讀取/寫入數據庫。這裡最有用的選擇是Node.js,儘管您可以使用PHP或ASP.NET,Ruby或Python,但我個人的建議是Node.js.  那麼,Facebook在其後端使用PHP,就是這樣。他們重寫了C ++中的大部分PHP。有些使用Python,而另一些則偏愛Ruby。的確,您可以在後端使用幾乎任何語言,例如,Google使用C ++,Java和Python(以及Go)。對於低級別的數據處理,C ++最適合用於更新用戶朋友建議等後台作業,Java是一個不錯的選擇。對於數據分析或自然語言處理,或者對於目前非常流行的AI相關任務,您很可能會使用Python。

同樣,除了後端的各種語言,框架和數據庫之外,還有一些核心概念需要掌握。

Caching。從CPU緩存(具有不同的級別)開始並以瀏覽器緩存結束。緩存無處不在,對於像Google搜索或Facebook這樣的高負載服務,緩存是非常必要的。

Servers。雖然您可能認為這與硬件有關(如果您知道如何設置多台計算機以作為存儲和處理數據的一部分工作,這將非常棒),而後端開發人員服務器則意味著Web服務器。時下流行的Web服務器是Nginx,知道如何設置和配置它將在未來的努力中付出高昂的代價。

Sockets。網絡編程的基石。您通過網絡發送/接收的所有內容均由套接字完成。了解套接字編程的低級細節是您技能庫存的一大優點(了解TCP套接字,UDP套接字以及WebSocket的巨大優勢)。

Database Design 無論您選擇或必須使用哪種DBMS,使用數據操作都是您的主要任務之一。能夠查看完整圖片,可視化數據單元之間的數據和連接,這是您在整個編程生涯中將掌握的一項技能。

Security。正如上面提到的其他概念一樣,這個概念也非常廣泛。你不能完全掌握它們中的任何一個,所以你至少應該熟悉一些最佳實踐,比如存儲密碼散列而不是純文本。通過API令牌檢查請求,驗證每個請求的用戶權限等等。

Desktop
我們將討論實際使其成為桌面應用程序的那部分桌面應用程序。在桌面平台上有大量需要特定技能的應用程序,例如,Photoshop正在處理圖像,並且如果您想要編寫類似Photoshop的圖像處理算法和技術,則必須知道。如果你想寫一些類似Dropbox的東西,那麼了解套接字編程是必須的。了解如何設計編譯器是您想要構建編譯器或IDE(如Visual Studio)的必備工具。我們不會涉及具體內容,只是想探索一下如果您想在桌面平台上工作,最有可能使用的語言。

當涉及桌面應用程序的語言時,程序員很難在C ++,Java或C#中進行選擇。有一個簡單的公式可以做出正確的選擇:如果您喜歡微軟,請使用C#。如果您喜歡Oracle,請使用Java。如果您認為編程語言不應該由某個公司所有,請使用C ++。如果這沒有多大幫助,我們來討論一下實際的子平台。如果您只為Windows用戶編寫軟件,那麼C#是最佳選擇。這是顯而易見的,因為兩者都是微軟的產品,它們最好地融合在一起。儘管C#開發人員堅持認為在.NET核心發布之後,C#也可以在Linux環境中使用,但我個人建議如果您想要涵蓋Linux,可以使用C ++。關鍵是,C ++被創建為一種跨平台的編程語言,它在所有操作系統中都很好(甚至是MacOS)。那麼,在這種情況下,跨平台假設你必須在所有操作系統中分別編譯你的C ++項目,以便為每個具體操作系統提供你的應用程序的“不同”可執行文件。而且,老實說,C ++缺乏任何GUI。最大的藉口是“C ++是為硬核開發者,硬核開發者只使用終端(命令行界面)”。然而,善良的開發人員聚集在一起創建了Qt,這是與C ++完美契合的最好的跨平台GUI庫。

最後,如果您對C ++的複雜性感到憤怒,並且您應該連接一個像Qt這樣的單獨庫來為您的用戶提供完整的GUI體驗,並且您討厭為不同的操作系統編譯和發布產品的不同可執行文件,請使用Java 。 Java有它的虛擬機,可以很容易地運行可執行文件。您的應用程序在任何安裝了JVM(Java虛擬機)的操作系統上運行得都很好。

Mobile
談到Java時,首先想到的就是Android。在Kotlin被介紹給世界之前很久,為了實現Android應用程序,Java是事實上的語言。如今,Kotlin吸收了開發者的心,並為開發麵向Android平台的應用程序提供了更好的體驗。所以,如果你想製作Android應用程序,你應該選擇Java和Kotlin。為了做出正確的選擇,我們應該看看幕後。關鍵是,谷歌對甲骨文來說並不那麼酷。甲骨文擁有Java和Java在谷歌的Android中占主導地位,為了在這裡有一定的靈活性,Google必須為輕微的一面(或者黑暗的一面,由您決定)引入一個選項,並將Kotlin引入為“哇,為什麼要使用Java這樣一個偉大的語言,我們支持“。我個人建議你從Kotlin開始,如果你剛剛開始Android開發人員的職業生涯,儘管要成為市場上有能力的開發人員,那麼你必須支持以前用Java實現的應用程序,因此,了解Java對你的簡歷來說是一個很好的獎勵。

最後,iOS。 iLand。一個完全不同的故事。很長一段時間,Objective-C是iOS的主流語言,並且要完全誠實,掌握Objective-C需要認真的態度,堅韌的外表和堅定的毅力。這是Objective-C開發人員數量相對較少的主要問題,Apple最終通過引入Swift做出了正確的舉動。 Swift比Objective-C更容易掌握,這導致iOS開發人員數量的增加。因此,要成為iOS開發人員,您需要使用Swift,但要成為一名非常有信心的開發人員,建議您掌握Objective-C以支持已經用Objective-C編寫的應用程序(大量應用程序)。

我應該在這裡提到React Native,因為它允許使用JavaScript編寫適用於Android和iOS平台的應用程序,但是,作為市場中新的和迅速變化的播放器,我們只要考慮它存在,並且您已經可以編寫簡單的應用程序你只知道JavaScript。

Preparing for Coding Interviews
在編程世界中有一些基本的概念。大部分的技術面試都是為了發現解決問題的能力和了解這些概念,所以除了掌握編程語言之外,您還應該熟悉程序員庫中需要的一些概念。以下是我最近在SoloLearn上課的摘錄(下面是Android和iOS應用程序的鏈接)。

要成功編寫面試代碼,您應該對以下方面充滿信心:
1.算法和數據結構
2.計算機組織和操作系統
3.編碼
4.系統設計

算法和數據結構 (Algorithms & Data Structures )
這是程序員最想要的技能。以下是每個程序員必須熟悉的主題:

算法複雜性 (Algorithm Complexity):Big-O符號以及如何計算算法複雜度;基於其複雜性知道哪種算法更好,例如, O(N)對O(logN)。

基本數據結構和適配器 (Basic Data Structures & adapters):數組,鏈接列表,堆棧,隊列。

排序和搜索 (Sorting & Searching):了解各種排序算法可幫助您確定項目的最佳實施方案。實踐中,嘗試實施插入排序,選擇排序或合併排序,並找出線性搜索和二分搜索之間的區別。

樹與圖 (Trees & Graphs):樹與圖無處不在,從Facebook中的“朋友圖”開始到Google搜索中的“知識圖”。

哈希表 (Hashtables):作為世界上最高效的數據結構之一,哈希表總是一個不錯的選擇。你應該能夠實現一個Hashtable並且熟悉解決衝突的技巧。


計算機組織和操作系統
強烈建議您熟悉如下主題:

 - 按位操作
 - CPU如何執行機器碼
 - 靜態RAM和動態RAM有什麼區別
 - 什麼樣的操作系統內核類型存在
 - “互斥體”和“信號量”有什麼區別
 - 什麼是僵局,什麼是活鎖

Coding
你應該對至少一種編程語言有很好的了解。了解所有優點和缺點,您最喜歡的語言的最佳實踐將始終幫助您編寫高效,優雅和易讀的代碼。
強烈建議通過解決具有挑戰性的問題進行練習,例如(以下所有問題都可以在SoloLearn上找到):

 - 約瑟夫問題 (The Josephus Problem)
 - 河內塔 (Tower of Hanoi)
 - 字符串壓縮 (String Compression)
 - 平衡括號 (Balanced Parenthesis)
 - 雙素數 ( Twin Prime Numbers)

System Design
了解面向對象編程對現代程序員來說是必須的。
系統設計意味著思考整個系統,能夠設計其體系結構,將其分解為類,定義對象交互。
準備嘗試回答以下問題:
 - 您將如何設計Google搜索?如果每秒有數百萬的同時請求會怎麼樣?
 - 你將如何實施Facebook的朋友搜索?
 - 為什麼要使用關係數據庫管理系統?
 - 為什麼你會使用NoSQL DB?

強烈建議您了解並使用正確的設計模式。例如,你應該知道Composite和Decorator之間的區別。

雖然初級開發人員大多需要具備良好的解決問題的能力,而且您的第一份工作不需要知道上面列出的所有要點,但這份清單對於規劃您的職業生涯會有很大的幫助。

how-to-recursively-create-subfolder-in-each-folder-of-a-directory-in-cmd

test.cmd: @echo off setlocal for /f "usebackq tokens=*" %%a in (`dir /b /a:d`) do ( rem enter the directory pushd %%a echo...