❶ 長頭發的程序員,會影響工作和求職嗎
只要形象正直,看起來干凈利落,談吐有風度,對自己有自信,長發短發影響倒不是很大。我面試前端的時候經常被叫先生,因為我是超短發。面試官發現叫錯後一般會道歉,哈哈一笑帶過就好。暫時沒有因為外貌或穿衣打扮被拒的經歷,看重的還是你會不會幹活,畢竟我們程序員大部分時間還是呆在辦公室面對電腦,接待客戶拿需求那些就讓我們可愛的產品經理去吧。
不會,我們公司有個程序猿辮子還要長點,入職的時候都是穿拖鞋去的,老闆頭發比我還長。無所謂……這個真無所謂,可能國企會在乎這個,正常的互聯網企業不存在的,特別是游戲公司,說真的,你要弄得特陽光,或者西裝革履的,反而有點格格不入,至少我誠實的說,我可能會有點偏見,可能算「反向」歧視吧,當然我這個心態也不太好,最好怎麼穿怎麼打扮都行。「穿得越隨意越牛」,這話明說出來就很傻逼,但我們很多人心裡隱隱就是這么想的。當然,你要是特別隨性,最好有相應的實力,不然就真有點傻逼了。按你舒服的來吧,要是公司接受不了,你自己待著也難受,早晚因為「價值觀不符」開除。
❷ 如何防止程序員反編譯
java從誕生以來,其基因就是開放精神,也正因此,其可以得到廣泛愛好者的支持和奉獻,最終很快發展壯大,以至於有今天之風光!但隨著java的應用領域越來越廣,特別是一些功能要發布到終端用戶手中(如Android開發的app),有時候,公司為了商業技術的保密考慮,不希望這裡面的一些核心代碼能夠被人破解(破解之後,甚至可以被簡單改改就發布出去,說嚴重點,就可能會擾亂公司的正常軟體的市場行為),這時候就要求這些java代碼不能夠被反編譯。
這里要先說一下反編譯的現象。因為java一直秉持著開放共享的理念,所以大家也都知道,我們一般共享一個自己寫的jar包時,同時會共享一個對應的source包。但這些依然與反編譯沒有什麼關系,但java的共享理念,不只是建議我們這樣做,而且它自己也在底層上「強迫」我們這么做!在java寫的.java文件後,使用javac編譯成class文件,在編譯的過程,不像C/C++或C#那樣編譯時進行加密或混淆,它是直接對其進行符號化、標記化的編譯處理,於是,也產生了一個逆向工程的問題:可以根據class文件反向解析成原來的java文件!這就是反編譯的由來。
但很多時候,有些公司出於如上述的原因考慮時,真的不希望自己寫的代碼被別人反編譯,尤其是那些收費的app或桌面軟體(甚至還有一些j2ee的wen項目)!這時候,防止反編譯就成了必然!但前面也說過了,因為開放理念的原因,class是可以被反編譯的,那現在有這樣的需求之後,有哪些方式可以做到防止反編譯呢?經過研究java源代碼並進行了一些技術實現(結果發現,以前都有人想到過,所以在對應章節的時候,我會貼出一些寫得比較細的文章,而我就簡單闡述一下,也算偷個懶吧),我總共整理出以下這幾種方式:
代碼混淆
這種方式的做法正如其名,是把代碼打亂,並摻入一些隨機或特殊的字元,讓代碼的可讀性大大降低,「曲線救國」似的達到所謂的加密。其實,其本質就是打亂代碼的順序、將各類符號(如類名、方法名、屬性名)進行隨機或亂命名,使其無意義,讓人讀代碼時很累,進而讓人乍一看,以為這些代碼是加過密的!
由其實現方式上可知,其實現原理只是擾亂正常的代碼可讀性,並不是真正的加密,如果一個人的耐心很好,依然可以理出整個程序在做什麼,更何況,一個應用中,其核心代碼才是人們想去了解的,所以大大縮小了代碼閱讀的范圍!
當然,這種方式的存在,而且還比較流行,其原因在於,基本能防範一些技術人員進行反編譯(比如說我,讓我破解一個混淆的代碼,我寧願自己重寫一個了)!而且其實現較為簡單,對項目的代碼又無開發上的侵入性。目前業界也有較多這類工具,有商用的,也有免費的,目前比較流行的免費的是:proguard(我現象臨時用的就是這個)。
上面說了,這種方式其實並不是真正加密代碼,其實代碼還是能夠被人反編譯(有人可能說,使用proguard中的optimize選項,可以從位元組流層面更改代碼,甚至可以讓JD這些反編譯軟體可以無法得到內容。說得有點道理,但有兩個問題:1、使用optimize對JDK及環境要求較高,容易造成混淆後的代碼無法正常運行;2、這種方式其實還是混淆,JD反編譯有點問題,可以有更強悍的工具,矛盾哲學在哪兒都是存在的^_^)。那如何能做到我的class代碼無法被人反編譯呢?那就需要我們下面的「加密class」!
加密class
在說加密class之前,我們要先了解一些java的基本概念,如:ClassLoader。做java的人已經或者以後會知道,java程序的運行,是類中的邏輯在JVM中運行,而類又是怎麼載入到JVM中的呢(JVM內幕之類的,不在本文中闡述,所以點到為止)?答案是:ClassLoader。JVM在啟動時是如何初始化整個環境的,有哪些ClassLoader及作用是什麼,大家可以自己問度娘,也不在本文中討論。
讓我們從最常見的代碼開始,揭開一下ClassLoader的一點點面紗!看下面的代碼:
Java代碼
publicclassDemo{
publicstaticvoidmain(String[]args){
System.out.println(「helloworld!」);
}
}
上面這段代碼,大家都認識。但我要問的是:如果我們使用javac對其進行編譯,然後使用java使其運行(為什麼不在Eclipse中使用Runas功能呢?因為Eclipse幫我們封閉,從而簡化了太多東西,使我們忽略了太多的底層細節,只有從原始的操作上,我們才能看到本質),那麼,它是怎麼載入到JVM中的?答案是:通過AppClassLoader載入的(相關知識點可以參考:http://hxraid.iteye.com/blog/747625)!如果不相信的話,可以輸出一下System.out.println(Thread.currentThrea().getContextLoader());看看。
那又有一個新的問題產生了:ClassLoader又是怎樣載入class的呢?其實,AppClassLoader繼承自java.lang.ClassLoader類,所以,基本操作都在這個類裡面,讓我們直接看下面這段核心代碼吧:
看到這里,已經沒有必要再往下面看了(再往下就是native方法了,這是一個重大伏筆哦),我們要做的手腳就在這里!
手腳怎麼做呢?很簡單,上面的代碼邏輯告訴我們,ClassLoader只是拿到class文件中的內容byte[],然後交給JVM初始化!於是我們的邏輯就簡單了:只要在交給JVM時是正確的class文件就行了,在這之前是什麼樣子無所謂!所以,我們的加密的整個邏輯就是:
在編譯代碼時(如使用ant或maven),使用插件將代碼進行加密(加密方式自己選),將class文件裡面的內容讀取成byte[],然後進行加密後再寫回到class文件(這時候class文件裡面的內容不是標準的class,無法被反編譯了)
在啟動項目代碼時,指定使用我們自定義的ClassLoader就行了,而自定義的部分,主要就是在這里做解密工作!
如此,搞定!以上的做法比較完整的闡述,可以仔細閱讀一下這篇文章:https://www.ddtsoft.com/#developerworks/cn/java/l-secureclass/文章中的介紹。
通過這個方法貌似可以解決代碼反編譯的問題了!錯!這里有一個巨大的坑!因為我們自定義的ClassLoader是不能加密的,要不然JVM不認識,就全歇菜了!如果我來反編譯,呵呵,我只要反編譯一下這個自定義的ClassLoader,然後把裡面解密後的內容寫到指定的文件中保存下來,再把這個加了邏輯的自定義ClassLoader放回去運行,你猜結果會怎樣?沒錯,你會想死!因為你好不容易想出來的加密演算法,結果人家根本不需要破解,直接就繞過去了!
現在,讓我們總結一下這個方法的優缺點:實現方式簡單有效,同時對代碼幾乎沒有侵入性,不影響正常開發與發布。缺點也很明顯,就是很容易被人破解!
當然啦,關於缺點問題,你也可以這么干:先對所有代碼進行混淆、再進行加密,保證:1、不容易找到我們自定義的那個ClassLoader;2、就算找到了,破解了,代碼可讀性還是很差,讓你看得吐血!(有一篇文章,我覺得寫得不錯,大家可以看一看:http://www.scjgcj.com/#blog/851544)
嗯,我覺得這個方法很好,我自己也差點被這個想法感動了,但是,作為一個嚴謹的程序員,我真的不願意留下一個隱患在這里!所以,我繼續思索!
高級加密class
前面我們說過有個伏筆來著,還記得吧?沒錯,就是那個native!native定義的方法是什麼方法?就是我們傳說中的JNI調用!前面介紹過的有一篇文章中提到過,其實jvm的真實身份並不是java,而是c++寫的jvm.dll(windows版本下),java與dll文件的調用就是通過JNI實現的!於是,我們就可以這樣想:JNI可以調用第三方語言的類庫,那麼,我們可不可以把解密與裝載使用第三方語言寫(如C++,因為它們生成的庫是不好反編譯的),這樣它可以把解密出來的class內容直接調jvm.dll的載入介面進行初始化成class,再返回給我們的ClassLoader?這樣,我們自定義的ClassLoader只要使用JNI調用這個第三方語言寫的組件,整個解密過程,都在黑盒中進行,別人就無從破解了!
嗯,這個方法真的很不錯的!但也有兩個小問題:1.使用第三方語言寫,得會第三方語言,我說的會,是指很溜!2.對於不同的操作系統,甚至同一操作系統不同的版本,都可能要有差異化的代碼生成對應環境下的組件(如window下是exe,linux是so等)!如果你不在乎這兩個問題,我覺得,這個方式真的挺不錯的。但對於我來說,我的信條是,越復雜的方式越容易出錯!我個人比較崇尚簡潔的美,所以,這個方法我不會輕易使用!
對了,如果大家覺得這個方法還算可行的話,可以推薦一個我無意中看到的東西給大家看看(我都沒有用過的):jinstall,
更改JVM
看到這個標題,我想你可能會震驚。是的,你沒看錯,做為一個程序員,是應該要具有懷疑一切、敢想敢做的信念。如果你有意留心的話,你會發現JVM版本在業界其實也有好幾個版本的,如:Sun公司的、IBM的、Apache的、Google的……
所以,不要阻礙自己的想像力,現在沒有這個能力,並不代表不可能。所以,我想到,如果我把jvm改了,在裡面對載入的類進行解密,那不就可以了嗎?我在設計構思過程中,突然發現:人老了就是容易糊塗!前面使用第三方語言實現解密的兩個問題,正好也是更改JVM要面對的兩個問題,而且還有一個更大的問題:這個JVM就得跟著這個項目到處走啊!
❸ 要成為一名專業的程序員,從零開始需要怎麼一步步來比較好,要把最底層的先學精通嗎(個人認為)求學長
前言
你是否覺得自己從學校畢業的時候只做過小玩具一樣的程序?走入職場後哪怕沒有什麼經驗也可以把以下這些課外練習走一遍(朋友的抱怨:學校課程總是從理論出發,作業項目都看不出有什麼實際作用,不如從工作中的需求出發)
建議:
不要亂買書,不要亂追新技術新名詞,基礎的東西經過很長時間積累而且還會在未來至少10年通用。
回顧一下歷史,看看歷史上時間線上技術的發展,你才能明白明天會是什麼樣。
一定要動手,例子不管多麼簡單,建議至少自己手敲一遍看看是否理解了里頭的細枝末節。
一定要學會思考,思考為什麼要這樣,而不是那樣。還要舉一反三地思考。
註:你也許會很奇怪為什麼下面的東西很偏Unix/Linux,這是因為我覺得Windows下的編程可能會在未來很沒有前途,原因如下:
現在的用戶界面幾乎被兩個東西主宰了,1)Web,2)移動設備iOS或Android。Windows的圖形界面不吃香了。
越來越多的企業在用成本低性能高的Linux和各種開源技術來構架其系統,Windows的成本太高了。
微軟的東西變得太快了,很不持久,他們完全是在玩弄程序員。詳情參見《Windows編程革命史》
所以,我個人認為以後的趨勢是前端是Web+移動,後端是Linux+開源。開發這邊基本上沒Windows什麼事。
啟蒙入門
1、 學習一門腳本語言,例如python/Ruby
可以讓你擺脫對底層語言的恐懼感,腳本語言可以讓你很快開發出能用得上的小程序。實踐項目:
處理文本文件,或者csv (關鍵詞 python csv, python open, python sys) 讀一個本地文件,逐行處理(例如 word count,或者處理log)
遍歷本地文件系統 (sys, os, path),例如寫一個程序統計一個目錄下所有文件大小並按各種條件排序並保存結果
跟資料庫打交道 (python sqlite),寫一個小腳本統計資料庫里條目數量
學會用各種print之類簡單粗暴的方式進行調試
學會用Google (phrase, domain, use reader to follow tech blogs)
為什麼要學腳本語言,因為他們實在是太方便了,很多時候我們需要寫點小工具或是腳本來幫我們解決問題,你就會發現正規的編程語言太難用了。
2、 用熟一種程序員的編輯器(不是IDE) 和一些基本工具
Vim / Emacs / Notepad++,學會如何配置代碼補全,外觀,外部命令等。
Source Insight (或 ctag)
使用這些東西不是為了Cool,而是這些編輯器在查看、修改代碼/配置文章/日誌會更快更有效率。
3、 熟悉Unix/Linux Shell和常見的命令行
如果你用windows,至少學會用虛擬機里的linux, vmware player是免費的,裝個Ubuntu吧
一定要少用少用圖形界面。
學會使用man來查看幫助
文件系統結構和基本操作 ls/chmod/chown/rm/find/ln/cat/mount/mkdir/tar/gzip …
學會使用一些文本操作命令 sed/awk/grep/tail/less/more …
學會使用一些管理命令 ps/top/lsof/netstat/kill/tcpmp/iptables/dd…
了解/etc目錄下的各種配置文章,學會查看/var/log下的系統日誌,以及/proc下的系統運行信息
了解正則表達式,使用正則表達式來查找文件。
對於程序員來說Unix/Linux比Windows簡單多了。(參看我四年前CSDN的博文《其實Unix很簡單》)學會使用Unix/Linux你會發現圖形界面在某些時候實在是太難用了,相當地相當地降低工作效率。
4、 學習Web基礎(HTML/CSS/JS) + 伺服器端技術 (LAMP)
未來必然是Web的世界,學習WEB基礎的最佳網站是W3School。
學習HTML基本語法
學習CSS如何選中HTML元素並應用一些基本樣式(關鍵詞:box model)
學會用 Firefox + Firebug 或 chrome 查看你覺得很炫的網頁結構,並動態修改。
學習使用Javascript操縱HTML元件。理解DOM和動態網頁(Dynamic HTML: The Definitive Reference, 3rd Edition - O'Reilly Media) 網上有免費的章節,足夠用了。或參看 DOM 。
學會用 Firefox + Firebug 或 chrome 調試Javascript代碼(設置斷點,查看變數,性能,控制台等)
在一台機器上配置Apache 或 Nginx
學習php,讓後台PHP和前台HTML進行數據交互,對伺服器相應瀏覽器請求形成初步認識。實現一個表單提交和反顯的功能。
把PHP連接本地或者遠程資料庫 MySQL(MySQL 和 SQL現學現用夠了)
跟完一個名校的網路編程課程(例如:http://www.stanford.e/~ouster/cgi-bin/cs142-fall10/index.php ) 不要覺得需要多於一學期時間,大學生是全職一學期選3-5門課,你業余時間一定可以跟上
學習一個javascript庫(例如jQuery 或 ExtJS)+ Ajax (非同步讀入一個伺服器端圖片或者資料庫內容)+JSON數據格式。
HTTP: The Definitive Guide 讀完前4章你就明白你每天上網用瀏覽器的時候發生的事情了(proxy, gateway, browsers)
做個小網站(例如:一個小的留言板,支持用戶登錄,Cookie/Session,增、刪、改、查,上傳圖片附件,分頁顯示)
買個域名,租個空間,做個自己的網站。
進階加深
1、 C語言和操作系統調用
重新學C語言,理解指針和內存模型,用C語言實現一下各種經典的演算法和數據結構。推薦《計算機程序設計藝術》、《演算法導論》和《編程珠璣》。
學習(麻省理工免費課程)計算機科學和編程導論
學習(麻省理工免費課程)C語言內存管理
學習Unix/Linux系統調用(Unix高級環境編程),,了解系統層面的東西。
用這些系統知識操作一下文件系統,用戶(實現一個可以拷貝目錄樹的小程序)
用fork/wait/waitpid寫一個多進程的程序,用pthread寫一個多線程帶同步或互斥的程序。多進程多進程購票的程序。
用signal/kill/raise/alarm/pause/sigprocmask實現一個多進程間的信號量通信的程序。
學會使用gcc和gdb來編程和調試程序(參看我的《用gdb調試程序》)
學會使用makefile來編譯程序。(參看我的《跟我一起寫makefile》)
IPC和Socket的東西可以放到高級中來實踐。
學習Windows SDK編程(Windows 程序設計 ,MFC程序設計)
寫一個窗口,了解WinMain/WinProcere,以及Windows的消息機制。
寫一些程序來操作Windows SDK中的資源文件或是各種圖形控制項,以及作圖的編程。
學習如何使用MSDN查看相關的SDK函數,各種WM_消息以及一些常式。
這本書中有很多常式,在實踐中請不要照抄,試著自己寫一個自己的常式。
不用太多於精通這些東西,因為GUI正在被Web取代,主要是了解一下Windows 圖形界面的編程。@virushuo 說:「 我覺得GUI確實不那麼熱門了,但充分理解GUI工作原理是很重要的。包括移動設備開發,如果沒有基礎知識仍然很吃力。或者說移動設備開發必須理解GUI工作,或者在win那邊學,或者在mac/iOS上學」。
2、學習Java
Java 的學習主要是看經典的Core Java 《Java 核心技術編程》和《Java編程思想》(有兩卷,我僅鏈了第一卷,足夠了,因為Java的圖形界面了解就可以了)
學習JDK,學會查閱Java API Doc Java Platform SE 6
了解一下Java這種虛擬機語言和C和Python語言在編譯和執行上的差別。從C、Java、Python思考一下「跨平台」這種技術。
學會使用IDE Eclipse,使用Eclipse 編譯,調試和開發Java程序。
建一個Tomcat的網站,嘗試一下JSP/Servlet/JDBC/MySQL的Web開發。把前面所說的那個PHP的小項目試著用JSP和Servlet實現一下。
3、Web的安全與架構
學習HTML5,網上有很多很多教程,以前酷殼也介紹過很多,我在這里就不羅列了。
學習Web開發的安全問題(參考新浪微博被攻擊的這個事,以及Ruby的這篇文章)
學習HTTP Server的rewrite機制,Nginx的反向代理機制,fast-cgi(如:PHP-FPM)
學習Web的靜態頁面緩存技術。
學習Web的非同步工作流處理,數據Cache,數據分區,負載均衡,水平擴展的構架。
實踐任務:
使用HTML5的canvas 製作一些Web動畫。
嘗試在前面開發過的那個Web應用中進行SQL注入,JS注入,以及XSS攻擊。
把前面開發過的那個Web應用改成構造在Nginx + PHP-FPM + 靜態頁面緩存的網站
4、學習關系型資料庫
你可以安裝MSSQLServer或MySQL來學習資料庫。
學習教科書里資料庫設計的那幾個範式,1NF,2NF,3NF,……
學習資料庫的存過,觸發器,視圖,建索引,游標等。
學習SQL語句,明白表連接的各種概念(參看《SQL Join的圖示》)
學習如何優化資料庫查詢(參看《MySQL的優化》)
實踐任務:設計一個論壇的資料庫,至少滿足3NF,使用SQL語句查詢本周,本月的最新文章,評論最多的文章,最活躍用戶。
5、一些開發工具
學會使用SVN或Git來管理程序版本。
學會使用JUnit來對Java進行單元測試。
學習C語言和Java語言的coding standard 或 coding guideline。(我N年前寫過一篇關C語言非常簡單的文章——《編程修養》,這樣的東西你可以上網查一下,一大堆)。
推薦閱讀《代碼大全》《重構》《代碼整潔之道》
高級深入
1、C++ / Java 和面向對象
我個人以為學好C++,Java也就是舉手之勞。但是C++的學習曲線相當的陡。不過,我覺得C++是最需要學好的語言了。參看兩篇趣文「C++學習信心圖」 和「21天學好C++」
學習(麻省理工免費課程)C++面向對象編程
讀我的 「如何學好C++」中所推薦的那些書至少兩遍以上(如果你對C++的理解能夠深入到像我所寫的《C++虛函數表解析》或是《C++對象內存存局(上)(下)》,或是《C/C++返回內部靜態成員的陷阱》那就非常不錯了)
然後反思為什麼C++要干成這樣,Java則不是?你一定要學會對比C++和Java的不同。比如,Java中的初始化,垃圾回收,介面,異常,虛函數,等等。
實踐任務:
用C++實現一個BigInt,支持128位的整形的加減乘除的操作。
用C++封裝一個數據結構的容量,比如hash table。
用C++封裝並實現一個智能指針(一定要使用模板)。
《設計模式》必需一讀,兩遍以上,思考一下,這23個模式的應用場景。主要是兩點:1)鍾愛組合而不是繼承,2)鍾愛介面而不是實現。(也推薦《深入淺出設計模式》)
實踐任務:
使用工廠模式實現一個內存池。
使用策略模式製做一個類其可以把文本文件進行左對齊,右對齊和中對齊。
使用命令模式實現一個命令行計算器,並支持undo和redo。
使用修飾模式實現一個酒店的房間價格訂價策略——旺季,服務,VIP、旅行團、等影響價格的因素。
學習STL的用法和其設計概念 - 容器,演算法,迭代器,函數子。如果可能,請讀一下其源碼。
實踐任務:嘗試使用面向對象、STL,設計模式、和WindowsSDK圖形編程的各種技能
做一個貪吃蛇或是俄羅斯方塊的游戲。支持不同的級別和難度。
做一個文件瀏覽器,可以瀏覽目錄下的文件,並可以對不同的文件有不同的操作,文本文件可以打開編輯,執行文件則執行之,mp3或avi文件可以播放,圖片文件可以展示圖片。
學習C++的一些類庫的設計,如: MFC(看看候捷老師的《深入淺出MFC》) ,Boost, ACE, CPPUnit,STL (STL可能會太難了,但是如果你能了解其中的設計模式和設計那就太好了,如果你能深入到我寫的《STL string類的寫時拷貝技術》那就非常不錯了,ACE需要很強在的系統知識,參見後面的「加強對系統的了解」)
Java是真正的面向對象的語言,Java的設計模式多得不能再多,也是用來學習面向對象的設計模式的最佳語言了(參看Java中的設計模式)。
推薦閱讀《Effective Java》 and 《Java解惑》
學習Java的框架,Java的框架也是多,如Spring, Hibernate,Struts 等等,主要是學習Java的設計,如IoC等。
Java的技術也是爛多,重點學習J2EE架構以及JMS, RMI, 等消息傳遞和遠程調用的技術。
學習使用Java做Web Service (官方教程在這里)
實踐任務: 嘗試在Spring或Hibernate框架下構建一個有網路的Web Service的遠程調用程序,並可以在兩個Service中通過JMS傳遞消息。
C++和Java都不是能在短時間內能學好的,C++玩是的深,Java玩的是廣,我建議兩者選一個。我個人的學習經歷是:
深究C++(我深究C/C++了十來年了)
學習Java的各種設計模式。
2、加強系統了解
重要閱讀下面的幾本書:
《Unix編程藝術》了解Unix系統領域中的設計和開發哲學、思想文化體系、原則與經驗。你一定會有一種醍醐灌頂的感覺。
《Unix網路編程卷1,套接字》這是一本看完你就明白網路編程的書。重要注意TCP、UDP,以及多路復用的系統調用select/poll/epoll的差別。
《TCP/IP詳解 卷1:協議》- 這是一本看完後你就可以當網路黑客的書。了解乙太網的的運作原理,了解TCP/IP的協議,運作原理以及如何TCP的調優。
實踐任務:
理解什麼是阻塞(同步IO),非阻塞(非同步IO),多路復用(select, poll, epoll)的IO技術。
寫一個網路聊天程序,有聊天伺服器和多個聊天客戶端(服務端用UDP對部分或所有的的聊天客戶端進Multicast或Broadcast)。
寫一個簡易的HTTP伺服器。
《Unix網路編程卷2,進程間通信》信號量,管道,共享內存,消息等各種IPC…… 這些技術好像有點老掉牙了,不過還是值得了解。
實踐任務:
主要實踐各種IPC進程序通信的方法。
嘗試寫一個管道程序,父子進程通過管道交換數據。
嘗試寫一個共享內存的程序,兩個進程通過共享內存交換一個C的結構體數組。
學習《Windows核心編程》一書。把CreateProcess,Windows線程、線程調度、線程同步(Event, 信號量,互斥量)、非同步I/O,內存管理,DLL,這幾大塊搞精通。
實踐任務:使用CreateProcess啟動一個記事本或IE,並監控該程序的運行。把前面寫過的那個簡易的HTTP服務用線程池實現一下。寫一個DLL的鉤子程序監控指定窗口的關閉事件,或是記錄某個窗口的按鍵。
有了多線程、多進程通信,TCP/IP,套接字,C++和設計模式的基本,你可以研究一下ACE了。使用ACE重寫上述的聊天程序和HTTP伺服器(帶線程池)
實踐任務:通過以上的所有知識,嘗試
寫一個服務端給客戶端傳大文件,要求把100M的帶寬用到80%以上。(注意,磁碟I/O和網路I/O可能會很有問題,想一想怎麼解決,另外,請注意網路傳輸最大單元MTU)
了解BT下載的工作原理,用多進程的方式模擬BT下載的原理。
3、系統架構
負載均衡。HASH式的,純動態式的。(可以到Google學術里搜一些關於負載均衡的文章讀讀)
多層分布式系統 – 客戶端服務結點層、計算結點層、數據cache層,數據層。J2EE是經典的多層結構。
CDN系統 – 就近訪問,內容邊緣化。
P2P式系統,研究一下BT和電驢的演算法。比如:DHT演算法。
伺服器備份,雙機備份系統(Live-Standby和Live-Live系統),兩台機器如何通過心跳監測對方?集群主結點備份。
虛擬化技術,使用這個技術,可以把操作系統當應用程序一下切換或重新配置和部署。
學習Thrift,二進制的高性能的通訊中間件,支持數據(對象)序列化和多種類型的RPC服務。
學習Hadoop。Hadoop框架中最核心的設計就是:MapRece和HDFS。MapRece的思想是由Google的一篇論文所提及而被廣為流傳的,簡單的一句話解釋MapRece就是「任務的分解與結果的匯總」。HDFS是Hadoop分布式文件系統(Hadoop Distributed File System)的縮寫,為分布式計算存儲提供了底層支持。
了解NoSQL資料庫(有人說可能是一個過渡炒作的技術),不過因為超大規模以及高並發的純動態型網站日漸成為主流,而SNS類網站在數據存取過程中有著實時性等剛性需求,這使得目前NoSQL資料庫慢慢成了人們所關注的焦點,並大有成為取代關系型資料庫而成為未來主流數據存儲模式的趨勢。當前NoSQL資料庫很多,大部分都是開源的,其中比較知名的有:MemcacheDB、Redis、Tokyo Cabinet(升級版為Kyoto Cabinet)、Flare、MongoDB、CouchDB、Cassandra、Voldemort等。
❹ 不能再繼續下去了,技術人員的最終出路在哪
俗話說,365行,行行出狀元,此話也適用於IT行業,尤其是程序員。
當你迷茫找不到出路,又想快速成長和提高的時候,有兩種方案可以供你參考:
1、努力成為你工作環境中最優秀的人(技術最好的人);
2、跳槽,去另外一家公司做比你能力要高的工作。
針對工作環境的不同,分為大環境和小環境(人多和人少):
1、小環境,尋找技術最好的人,努力不斷向他接近,當你通過努力覺得超過他的時候,我相信你就不會再來問「出路在哪裡」的問題了。
2、大環境,人多優秀的人也多,想短時間超越所有人是有相當難度的,能與每個優秀人都交流的概率低,所以你可以選擇跳槽。
跳槽,在我看來是程序員成功的必經之路。跳槽是有技巧的,同時也需要一定的運氣,如果想跳槽就要果斷。當你覺得不如意時,當你覺得沒有出路時,當你覺得待遇不滿意時,當你覺得成長不夠快時。。。都可以考慮跳槽。
跳槽有利有弊,對企業來說,跳槽是不好的;對於打工者來說,跳槽是很完美的。企業培養一個程序員不容易,辛苦的帶起來一個人,熟悉了業務,掌握了技術,這時候走人,損失最大的當然是企業,花時間培養人和熟悉業務也是需要成本的。對程序員來說,跳槽幾乎是利大於弊,首先待遇上肯定立竿見影的體現,如果沒體現出來那就是跳的失敗,除非有其他想法和目標。
不要誤會我的意圖,跳槽對於技術人員來說並不是壞事:
1、一般的IT公司都有自己的常用的模式,該模式經過一個項目之後,就可以基本掌握,相關覆蓋的知識、架構等大概也可以了解,此時可以換個環境尋找更高的發展;
2、跳槽相當於變向的升職,這個可以從你的簡歷中體現出來。
假如你是一個初級程序員。當你做完一個項目的時候,你會了解這個項目的整個流程,此時可以在簡歷中填寫中級程序員的角色,把很多中級程序員做的事情寫到你的履歷里(前提是你要了解這些),跳槽的時候,你的目標自然就是中級程序員,而招聘公司看到你的情況也會覺得合適。
假如你是一個中級程序員。你需要在項目中了解高級程序員的工作范圍,並不要求你全部掌握,但需要你能表達出來,這個很重要。比如後台的設計模式、軟體架構、介面設計等,把這些寫到你的履歷中,給自己定位成高級程序員,自然的,高級程序員的職位會找到你。
假如你是一個高級程序員。你所需要了解的就不僅僅是程序設計,而是整個項目的運作和管理流程。包括項目管理、系統架構(軟硬體)、系統集成等,整個環節不一定都要會,但需要知道是什麼,比如,什麼是交換機,什麼是硬體負載均衡設備,什麼是反向代理,什麼是緩存伺服器,什麼是WEB伺服器,什麼是集群、負載均衡、分布式、資料庫優化、大數據存儲、高並發訪問等等,都是你需要了解的,面試的時候能表達出來,那麼你就成功了。同樣的把這些寫到你的履歷中,給自己定位架構師或項目經理,更新簡歷後,獵頭會來找你。
假如你是系統架構師。既然選擇了架構師的角色,那麼肯定是向技術方向發展了。技術總監、研發總監甚至CTO就是你的目標。想知道技術總監、CTO都在做什麼嗎,看看丁磊在做什麼,你就要去模仿去做。想成為一個角色人物,首先要從身體力行上模仿的像這個角色,時間長了那麼你就是這樣的人。技術總監需要負責整個公司的技術部運作,包括對人員的管理、績效考核、各語言組之間的協調、各項目間的協調,各部門間的協調,除此之外,你還需要考慮所運營的項目如何發展的更好,網站如何才能更加優化,產品如何能更上一個層次,公司的技術發展如何規劃,各種方案如何快速的編寫和實施,如何與老闆打交道等,都是你需要掌握的。
假如你是項目經理。在中國,項目經理分兩種,一種是TEAM LEADER的角色,需要很強的技術;一種是負責招標、流程式控制制的偏商務角色,要懂技術。發展到這個層次的,我想應該不用我來告訴他們出路在哪裡了,這樣的人一般都有自己的規劃,但凡事都有例外,如果沒有規劃或發展迷茫的,TEAM LEADER角色可以重點把項目管理、人力資源、系統架構等環節再強化一下,緊跟當前發展形勢學習新知識;偏商務角色的,可以考慮往總經理、CIO、CEO等方向努力,到這個層次的,需要的不僅僅是知識,更多的是一種理念和個人魅力。
大概聊了聊上述這些,我想每個層次的人可以大概了解自己該做什麼了。一定要有計劃、有目標高效的做事情,有效的管理分配好自己的時間,只有這樣你才可以成為一個優秀的人才。不要總讓別人告訴你該做什麼,而是自己不斷推動手裡的任務去更好的完成,處處體現出「我做的東西就比別人做的好」的信念,那我想,成功離你就不遠了。
❺ as3程序員到底是什麼
ActionScript,通常簡稱為AS,是Flash平台的100語言。作為程序,可以編譯成SWF、SWC。SWF就是我們所說的Flash動畫。但是現在SWF不僅僅是一個動畫,而是RIA的一個載體。ActionScript有三個版本:1.0(AS1)、2.0(AS2)和3.0(AS3)。
只有FlashPlayer9及以上支持as3編譯的SWF。這三個版本非常不同,現在最新的版本是AS3。所以as3程序員做的是flash開發,而不是flash設計。
(5)反向程序員擴展閱讀:
命名技巧
最好使用與所有者和相關項對應的包名。按照慣例,包名應該以反向url名開頭。
例如:如果ExampleCorp(examplecorp.com)編寫了一些ActionScript3.0類,所有這些類都將放在com中。examplecorp包(或com.examplecorp的子包)。
這樣,如果英國有另一個ExampleCorp(ExampleCorp.co.UK),它也編寫了一些ActionScript3.0類,您可以通過簡單地使用包UK.co.ExampleCorp來確保唯一性。
當類是特定應用程序的一部分時,應該將它們放在特定於應用程序的子包中例如:ExampleCorp可能有一個名為WidgetStore的應用程序。
如果WidgetStore應用程序使用一個名為ApplicationManager的類,那麼這個類應該在com.examplecorp中。或者在該包的子包中。
通常,包名以小寫字母開頭。
[隱式獲取方法(getter)和設置方法(setter)]
public函數getcount():uint{
Return_count;
}
Publicfunctionsetcount(值:uint):uint{
If(值< 100){
_count=價值;
其他}{
ThrowError();
}
}
❻ 程序員為什麼要學深度學習
費良宏:程序員為什麼要學深度學習?
深度學習本身是一個非常龐大的知識體系。本文更多想從程序員的視角出發,讓大家觀察一下深度學習對程序員意味著什麼,以及我們如何利用這樣一個高速發展的學科,來幫助程序員提升軟體開發的能力。
本文根據費良宏在2016QCon全球軟體開發大會(上海)上的演講整理而成。
前言
1973年,美國上映了一部熱門的科幻電影《WestWorld》,三年之後又有一個續集叫做《FutureWorld》。這部電影在80年代初被引進到中國叫《未來世界》。那部電影對我來講簡直可以說得上是震撼。影片中出現了很多機器人,表情豐富的面部下面都是集成電路板。這讓那時候的我覺得未來世界都是那麼遙遠、那麼神秘。
時間到了2016年,很多朋友可能都在追看HBO斥巨資拍攝的同一題材的系列劇《WestWorld》。如果前兩部電影還是局限在機器人、人工智慧這樣的話題,2016年的新劇則在劇情和人工智慧的思考方面有了很大的突破。不再渲染機器人是否會威脅到人類,而是在探討「Dreamsaremainlymemories」這一類更具哲理的問題。
「記憶究竟如何影響了智能」這個話題非常值得我們去思考,也給我們一個很好的啟示——今天,人工智慧領域究竟有了怎樣的發展和進步。
今天我們探討的話題不僅僅是簡單的人工智慧。如果大家對深度學習感興趣,我相信各位一定會在搜索引擎上搜索過類似相關的關鍵字。我在Google上以deeplearning作為關鍵字得到了2,630萬個搜索的結果。這個數字比一周之前足足多出了300多萬的結果。這個數字足以看得出來深度學習相關的內容發展的速度,人們對深度學習的關注也越來越高。
從另外的一個角度,我想讓大家看看深度學習在市場上究竟有多麼熱門。從2011年到現在一共有140多家專注人工智慧、深度學習相關的創業公司被收購。僅僅在2016年這種並購就發生了40多起。
其中最瘋狂的是就是Google,已經收購了 11 家人工智慧創業公司,其中最有名的就是擊敗了李世石九段的 DeepMind。排名之後的就要數 Apple、Intel以及Twitter。以Intel 公司為例,僅在今年就已經收購了 3 家創業公司,Itseez、Nervana 和 Movidius。這一系列大手筆的並購為了布局人工智慧以及深度學習的領域。
當我們去搜索深度學習話題的時候,經常會看到這樣的一些晦澀難懂的術語:Gradient descent(梯度下降演算法)、Backpropagation(反向傳播演算法)、Convolutional Neural Network(卷積神經網路)、受限玻耳茲曼機(Restricted Boltzmann Machine)等。
如打開任何一篇技術文章,你看到的通篇都是各種數學公式。大家看到如下左邊的圖,其實並不是一篇高水準的學術論文,而僅僅是維基網路關於玻耳茲曼機的介紹。維基網路是科普層面的內容,內容復雜程度就超過了大多數數學知識的能力。
在這樣的背景之下,我今天的的話題可以歸納成三點:第一,我們為什麼要學習深度學習;第二,深度學習最核心的關鍵概念就是神經網路,那麼究竟什麼是神經網路;第三,作為程序員,當我們想要成為深度學習開發者的時候,我們需要具備怎樣的工具箱,以及從哪裡著手進行開發。
為什麼要學習深度學習
首先,我們談談為什麼要學習深度學習。在這個市場當中,最不缺乏的就是各種概念以及各種時髦新技術的詞彙。深度學習有什麼不一樣的地方?我非常喜歡AndrewNg(吳恩達)曾經用過的一個比喻。
他把深度學習比喻成一個火箭。這個火箭有一個最重要的部分,就是它的引擎,目前來看在這個領域裡面,引擎的核心就是神經網路。大家都知道,火箭除了引擎之外還需要有燃料,那麼大數據其實就構成了整個火箭另外的重要組成部分——燃料。以往我們談到大數據的時候,更多是強調存儲和管理數據的能力,但是這些方法和工具更多是對於以往歷史數據的統計、匯總。
而對於今後未知的東西,這些傳統的方法並不能夠幫助我們可以從大數據中得出預測的結論。如果考慮到神經網路和大數據結合,我們才可能看清楚大數據真正的價值和意義。AndrewNg就曾經說過「我們相信(神經網路代表的深度學習)是讓我們獲得最接近於人工智慧的捷徑」。這就是我們要學習深度學習的一個最重要的原因。
其次,隨著我們進行數據處理以及運算能力的不斷提升,深度學習所代表的人工智慧技術和傳統意義上人工智慧技術比較起來,在性能上有了突飛猛進的發展。這主要得益於在過去幾十間計算機和相關產業不斷發展帶來的成果。在人工智慧的領域,性能是我們選擇深度學習另一個重要的原因。
這是一段Nvidia在今年公布的關於深度學習在無人駕駛領域應用的視頻。我們可以看到,將深度學習應用在自動駕駛方面,僅僅經歷了3千英里的訓練,就可以達到什麼樣的程度。在今年年初進行的實驗上,這個系統還不具備真正智能能力,經常會出現各種各樣的讓人提心吊膽的狀況,甚至在某些情況下還需要人工干預。
但經過了3千英里的訓練之後,我們看到在山路、公路、泥地等各種復雜的路況下面,無人駕駛已經有了一個非常驚人的表現。請大家注意,這個深度學習的模型只經過了短短幾個月、3千英里的訓練。
如果我們不斷完善這種模型的話,這種處理能力將會變得何等的強大。這個場景裡面最重要的技術無疑就是深度學習。我們可以得出一個結論:深度學習可以為我們提供強大的能力,如果程序員擁有了這個技術的話,無異於會讓每個程序員如虎添翼。
神經網路快速入門
如果我們對於學習深度學習沒有任何疑慮的話,接下來就一定會關心我需要掌握什麼樣的知識才能讓我進入到這個領域。這裡面最重要的關鍵技術就是「神經網路」。說起「神經網路」,容易混淆是這樣兩個完全不同的概念。
一個是生物學神經網路,第二個才是我們今天要談起的人工智慧神經網路。可能在座的各位有朋友在從事人工智慧方面的工作。當你向他請教神經網路的時候,他會拋出許多陌生的概念和術語讓你聽起來雲里霧里,而你只能望而卻步了。
對於人工智慧神經網路這個概念,大多數的程序員都會覺得距離自己有很大的距離。因為很難有人願意花時間跟你分享神經網路的本質究竟是什麼。而你從書本上讀的到的理論和概念,也很讓你找到一個清晰、簡單的結論。
今天就我們來看一看,從程序員角度出發神經網路究竟是什麼。我第一次知道神經網路這個概念是通過一部電影——1991年上映的《終結者2》。男主角施瓦辛格有一句台詞:
「MyCPUisaneural-netprocessor;alearningcomputer.」(我的處理器是一個神經處理單元,它是一台可以學習的計算機)。從歷史來看人類對自身智力的探索,遠遠早於對於神經網路的研究。
1852年,義大利學者因為一個偶然的失誤,將人類的頭顱掉到硝酸鹽溶液中,從而獲得第一次通過肉眼關注神經網路的機會。這個意外加速了對人類智力奧秘的探索,開啟了人工智慧、神經元這樣概念的發展。
生物神經網路這個概念的發展,和今天我們談的神經網路有什麼關系嗎?我們今天談到的神經網路,除了在部分名詞上借鑒了生物學神經網路之外,跟生物學神經網路已經沒有任何關系,它已經完全是數學和計算機領域的概念,這也是人工智慧發展成熟的標志。這點大家要區分開,不要把生物神經網路跟我們今天談到的人工智慧有任何的混淆。
90年代中期,由Vapnik等人提出了支持向量機演算法(Support Vector Machines,支持向量機)。很快這個演算法就在很多方面體現出了對比神經網路的巨大優勢,例如:無需調參、高效率、全局最優解等。基於這些理由,SVM演算法迅速打敗了神經網路演算法成為那個時期的主流。而神經網路的研究則再次陷入了冰河期。
在被人摒棄的十年裡面,有幾個學者仍然在堅持研究。其中很重要的一個人就是加拿大多倫多大學的Geoffery Hinton教授。2006年,他的在著名的《Science》雜志上發表了論文,首次提出了「深度信念網路」的概念。
與傳統的訓練方式不同,「深度信念網路」有一個「預訓練」(pre-training)的過程,這可以方便的讓神經網路中的權值找到一個接近最優解的值,之後再使用「微調」(fine-tuning)技術來對整個網路進行優化訓練。這兩個技術的運用大幅度減少了訓練多層神經網路的時間。在他的論文裡面,他給多層神經網路相關的學習方法賦予了一個新名詞— 「深度學習」。
很快,深度學習在語音識別領域嶄露頭角。接著在2012年,深度學習技術又在圖像識別領域大展拳腳。Hinton與他的學生在ImageNet競賽中,用多層的卷積神經網路成功地對包含一千個類別的一百萬張圖片進行了訓練,取得了分類錯誤率15%的好成績,這個成績比第二名高了將近11個百分點。
這個結果充分證明了多層神經網路識別效果的優越性。從那時起,深度學習就開啟了新的一段黃金時期。我們看到今天深度學習和神經網路的火熱發展,就是從那個時候開始引爆的。
利用神經網路構建分類器,這個神經網路的結構是怎樣的?
其實這個結構非常簡單,我們看到這個圖就是簡單神經網路的示意圖。神經網路本質上就是一種「有向圖」。圖上的每個節點借用了生物學的術語就有了一個新的名詞 – 「神經元」。連接神經元的具有指向性的連線(有向弧)則被看作是「神經」。這這個圖上神經元並不是最重要的,最重要的是連接神經元的神經。每個神經部分有指向性,每一個神經元會指向下一層的節點。
節點是分層的,每個節點指向上一層節點。同層節點沒有連接,並且不能越過上一層節點。每個弧上有一個值,我們通常稱之為」權重「。通過權重就可以有一個公式計算出它們所指的節點的值。這個權重值是多少?我們是通過訓練得出結果。它們的初始賦值往往通過隨機數開始,然後訓練得到的最逼近真實值的結果作為模型,並可以被反復使用。這個結果就是我們說的訓練過的分類器。
節點分成輸入節點和輸出節點,中間稱為隱層。簡單來說,我們有數據輸入項,中間不同的多個層次的神經網路層次,就是我們說的隱層。之所以在這樣稱呼,因為對我們來講這些層次是不可見的。輸出結果也被稱作輸出節點,輸出節點是有限的數量,輸入節點也是有限數量,隱層是我們可以設計的模型部分,這就是最簡單的神經網路概念。
如果簡單做一個簡單的類比,我想用四層神經網路做一個解釋。左邊是輸入節點,我們看到有若干輸入項,這可能代表不同蘋果的RGB值、味道或者其它輸入進來的數據項。中間隱層就是我們設計出來的神經網路,這個網路現在有不同的層次,層次之間權重是我們不斷訓練獲得一個結果。
最後輸出的結果,保存在輸出節點裡面,每一次像一個流向一樣,神經是有一個指向的,通過不同層進行不同的計算。在隱層當中,每一個節點輸入的結果計算之後作為下一層的輸入項,最終結果會保存在輸出節點上,輸出值最接近我們的分類,得到某一個值,就被分成某一類。這就是使用神經網路的簡單概述。
除了從左到右的形式表達的結構圖,還有一種常見的表達形式是從下到上來表示一個神經網路。這時候,輸入層在圖的最下方,輸出層則在圖的最上方。從左到右的表達形式以AndrewNg和LeCun的文獻使用較多。而在Caffe框架里則使用的則是從下到上的表達。
簡單來說,神經網路並不神秘,它就是有像圖,利用圖的處理能力幫助我們對特徵的提取和學習的過程。2006年Hinton的那篇著名的論文中,將深度學習總結成三個最重要的要素:計算、數據、模型。有了這三點,就可以實現一個深度學習的系統。
程序員需要的工具箱
對於程序員來說,掌握理論知識是為了更好的編程實踐。那就讓我們看看,對於程序員來說,著手深度學習的實踐需要准備什麼樣的工具。
硬體
從硬體來講,我們可能需要的計算能力,首先想到的就是CPU。除了通常的CPU架構以外,還出現了附加有乘法器的CPU,用以提升計算能力。此外在不同領域會有DSP的應用場景,比如手寫體識別、語音識別、等使用的專用的信號處理器。還有一類就是GPU,這是一個目前深度學習應用比較熱門的領域。最後一類就是FPGA(可編程邏輯門陣列)。
這四種方法各有其優缺點,每種產品會有很大的差異。相比較而言CPU雖然運算能力弱一些,但是擅長管理和調度,比如讀取數據,管理文件,人機交互等,工具也豐富。DSP相比而言管理能力較弱,但是強化了特定的運算能力。
這兩者都是靠高主頻來解決運算量的問題,適合有大量遞歸操作以及不便拆分的演算法。GPU的管理能力更弱一些,但是運算能力更強。但由於計算單元數量多,更適合整塊數據進行流處理的演算法。
FPGA在管理與運算處理方面都很強,但是開發周期長,復雜演算法開發難度較大。就實時性來說,FPGA是最高的。單從目前的發展來看,對於普通程序員來說,現實中普遍採用的計算資源就還是是CPU以及GPU的模式,其中GPU是最熱門的領域。
這是我前天為這次分享而准備的一個AWS 上p2的實例。僅僅通過幾條命令就完成了實例的更新、驅動的安裝和環境的設置,總共的資源創建、設置時間大概在10分鍾以內。而之前,我安裝調試前面提到的那台計算機,足足花了我兩天時間。
另外,從成本上還可以做一個對比。p2.8xLarge 實例每小時的費用是7.2美元。而我自己那台計算機總共的花費了是¥16,904元。這個成本足夠讓我使用350多個小時的p2.8xLarge。在一年裡使用AWS深度學習站就可以抵消掉我所有的付出。隨著技術的不斷的升級換代,我可以不斷的升級我的實例,從而可以用有限的成本獲得更大、更多的處理資源。這其實也是雲計算的價值所在。
雲計算和深度學習究竟有什麼關系?今年的8月8號,在IDG網站上發表了一篇文章談到了這個話題。文章中做了這樣一個預言:如果深度學習的並行能力不斷提高,雲計算所提供的處理能力也不斷發展,兩者結合可能會產生新一代的深度學習,將帶來更大影響和沖擊。這是需要大家考慮和重視的一個方向!
軟體
深度學習除了硬體的基礎環境之外。程序員會更關心與開發相關的軟體資源。這里我羅列了一些曾經使用過的軟體框架和工具。
Scikit-learn是最為流行的一個Python機器學習庫。它具有如下吸引人的特點:簡單、高效且異常豐富的數據挖掘/數據分析演算法實現; 基於NumPy、SciPy以及matplotlib,從數據探索性分析,數據可視化到演算法實現,整個過程一體化實現;開源,有非常豐富的學習文檔。
Caffe專注在卷及神經網路以及圖像處理。不過Caffe已經很久沒有更新過了。這個框架的一個主要的開發者賈揚清也在今年跳槽去了Google。也許曾經的霸主地位要讓位給他人了。
Theano 是一個非常靈活的Python 機器學習的庫。在研究領域非常流行,使用上非常方便易於定義復雜的模型。Tensorflow 的API 非常類似於Theano。我在今年北京的QCon 大會上也分享過關於Theano 的話題。
Jupyter notebook 是一個很強大的基於ipython的python代碼編輯器,部署在網頁上,可以非常方便的進行互動式的處理,很適合進行演算法研究合數據處理。
Torch 是一個非常出色的機器學習的庫。它是由一個比較小眾的lua語言實現的。但是因為LuaJIT 的使用,程序的效率非常出色。Facebook在人工智慧領域主打Torch,甚至現在推出了自己的升級版框架Torchnet。
深度學習的框架非常之多,是不是有一種亂花漸欲迷人眼的感覺?我今天向各位程序員重點介紹的是將是TensorFlow。這是2015年穀歌推出的開源的面向機器學習的開發框架,這也是Google第二代的深度學習的框架。很多公司都使用了TensorFlow開發了很多有意思的應用,效果很好。
用TensorFlow可以做什麼?答案是它可以應用於回歸模型、神經網路以深度學習這幾個領域。在深度學習方面它集成了分布式表示、卷積神經網路(CNN)、遞歸神經網路(RNN) 以及長短期記憶人工神經網路(Long-Short Term Memory, LSTM)。
關於Tensorflow 首先要理解的概念就是Tensor。在辭典中對於這個詞的定義是張量,是一個可用來表示在一些向量、標量和其他張量之間的線性關系的多線性函數。實際上這個表述很難理解,用我自己的語言解釋Tensor 就是「N維數組」而已。
使用 TensorFlow, 作為程序員必須明白 TensorFlow這樣幾個基礎概念:它使用圖 (Graph) 來表示計算任務;在被稱之為 會話 (Session) 的上下文 (context) 中執行圖;使用 Tensor 表示數據;通過 變數 (Variable) 維護狀態;使用 feed 和 fetch 可以為任意的操作(arbitrary operation) 賦值或者從其中獲取數據。
一句話總結就是,TensorFlow 就是有狀態圖的數據流圖計算環境,每個節點就是在做數據操作,然後提供依賴性和指向性,提供完整數據流。
TensorFlow安裝非常簡單,但官網提供下載的安裝包所支持的CUDA 的版本是7.5。考慮到CUDA 8 的讓人心動的新特以及不久就要正式發布的現狀。或許你想會考慮立即體驗CUDA 8,那麼就只能通過編譯Tensorflow源代碼而獲得。目前TensorFlow已經支持了Python2.7、3.3+。
此外,對於使用Python 語言的程序員還需要安裝所需要的一些庫,例如:numpy、protobuf等等。對於卷積處理而言,cuDNN是公認的性能最好的開發庫,請一定要安裝上。常規的Tensorsorflow的安裝很簡單,一條命令足矣:
$ pip3 install —upgrade https://storage.233.wiki/tensorflow/linux/cpu/tensorflow-0.11.0rc0-cp35-cp35m-linux_x86_64.whl
如果想評估一下或者簡單學習一下,還可以通過Docker進行安裝,安裝的命令如下:
$ docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow
TensorFlow有很多優點。首先,目前為止,深度學習的開發框架裡面TensorFlow的文檔做的最好,對程序員學習而言是非常好的一點。第二,TensorFlow有豐富的參考實例,作為參考學習起來非常容易。
第三,開發者社區活躍,在任何一個深度學習的社區里,都有大量關於TensorFlow的討論。第四,谷歌的支持力度非常大,從2015年到現在升級速度非常快,這是其他開源框架遠遠達不到的結果。
參考TensorFlow的白皮書,我們會看到未來TensorFlow還將會有巨大的發展潛力。讓我特別感興趣是這兩個方向。第一,支持跨多台機器的 parallelisation。盡管在0.8版本中推出了並行化的能力,但是目前還不完善。隨著未來不斷發展,依託雲計算的處理能力的提升這個特性將是非常讓人振奮的。
第二,支持更多的開發語言,對於開發者來說這是一個絕大的利好,通過使用自己擅長的語言使用TensorFlow應用。這些開發語言將會擴展到Java、Lua以及R 等。
在這里我想給大家展示一個應用Tensorflow 的例子。這個例子的代碼託管在這個網址上 https://github.com/anishathalye/neural-style。白俄羅斯的現代印象派藝術家Leonid Afremov善於用濃墨重彩來表現都市和風景題材,尤其是其雨景系列作品。他習慣用大色塊的鋪陳來營造光影效果,對反光物體和環境色的把握非常精準。
於是我就找到了一張上海東方明珠電視塔的一張攝影作品,我希望通過Tensorflow 去學習一下Leonid Afremov 的繪畫風格,並將這張東方明珠的照片處理成那種光影色彩豐富的作品風格。利用Tensorflow 以及上面提到的那個項目的代碼,在一個AWS 的p2類型的實例上進行了一個一千次的迭代,於是就得到了下圖這樣的處理結果。
這個處理的代碼只有350行里,模型使用了一個成名於2014年ImageNet比賽中的明星 VGG。這個模型非常好,特點就是「go depper」。
TensorFlow 做出這樣的作品,並不僅僅作為娛樂供大家一笑,還可以做更多有意思的事情。將剛才的處理能力推廣到視頻當中,就可以看到下圖這樣的效果,用梵高著名的作品」星月夜「的風格就加工成了這樣新的視頻風格。
可以想像一下,如果這種處理能力在更多領域得以應用,它會產生什麼樣的神奇結果?前景是美好的,讓我們有無限遐想。事實上我們目前所從事的很多領域的應用開發都可以通過使用神經網路和深度學習來加以改變。對於深度學習而言,掌握它並不是難事。每一個程序員都可以很容易的掌握這種技術,利用所具備的資源,讓我們很快成為深度學習的程序開發人員。
結束語
未來究竟是什麼樣,我們沒有辦法預言。有位作家Ray Kurzweil在2005年寫了《奇點臨近》一書。在這本書裡面他明確告訴我們,那個時代很快到來。作為那個時代曙光前的人群,我們是不是有能力加速這個過程,利用我們學習的能力實現這個夢想呢?
中國人工智慧的發展
人工智慧的時代無疑已經到來,這個時代需要的當然就是掌握了人工智慧並將其解決具體問題的工程師。坦率的說,市場上這一類的工程師還屬於鳳毛麟角。職場上的薪酬待遇可以看得出來這樣的工程師的搶手的程度。人工智慧這門學科發展到今天,就學術自身而言已經具備了大規模產業化的能力。
所以說,對於工程師而言當務之急就是盡快的掌握應用人工智慧的應用技術。當下在互聯網上關於人工智慧的學習資料可以說已經是「汗牛充棟」,那些具備了快速學習能力的工程師一定會在人工智慧的大潮當中脫穎而出。
中國發展人工智慧產業的環境已經具備。無論從創業環境、人員的素質乃至市場的機遇而言完全具備了產生產業變革的一切條件。與美國相比較,在人工智慧的許多領域中國團隊的表現也可以說是不逞多讓。就人工智慧的技術層面而言,中國的工程師與全球最好的技術團隊正處於同一個起跑線上。
時不我待,中國的工程師是有機會在這個領域大展身手的。不過值得注意的是,要切忌兩點:一是好高騖遠,盲目與國外攀比。畢竟積累有長短,術業有專攻,我們要立足於已有的積累,尋求逐步的突破。二是一擁而上,盲目追求市場的風口。人工智慧的工程化需要大量的基礎性的積累,並非一蹴而就簡單復制就可以成功。
中國的科研技術人員在人工智慧領域的成就有目共睹。在王詠剛的一篇文章裡面,他統計了從2013年到2015年SCI收錄的「深度學習」論文,中國在2014年和2015年超已經超過了美國居於領跑者的位置。
另外一讓我感到驚訝的事情,Google的JeffDean在2016年發表過一篇名為《TensorFlow:Asystemforlarge-scalemachinelearning》的論文。文章的22個作者裡面,明顯是中國名字的作者占已經到了1/5。如果要列舉中國人/華人在人工智慧領域里的大牛,吳恩達、孫劍、楊強、黃廣斌、馬毅、張大鵬……很容易就可以說出一大串。
對於中國來說目前的當務之急是人工智慧技術的產業化,唯有如此我們才可以講科研/智力領域的優勢轉化為整體的、全面的優勢。在這一點上,中國是全球最大的消費市場以及製造業強國,我們完全有機會藉助市場的優勢成為這個領域的領先者。
矽谷創新企業
矽谷雖然去過許多回,但一直無緣在那裡長期工作。在人工智慧領域的市場我們聽到的更多是圍繞Google、Apple、Intel、Amazon這樣的一些大型科技公司的一舉一動。但是在美國市場上還有一大批小型的創業企業在人工智慧這個領域有驚艷的表現。僅以矽谷區域的公司為例:
Captricity,提供了手寫數據的信息提取;
VIVLab,針對語音識別開發了虛擬助手服務;
TERADEEP,利用FPGA提供了高效的卷積神經網路的方案;
還有提供無人駕駛解決方案的NetraDyne。
這個名單還可以很長,還有許許多多正在利用人工智慧技術試圖去創造歷史的團隊正在打造他們的夢想。這些團隊以及他們正在專注的領域是值得我們去學習和體會的。
❼ 北大青鳥java培訓:java中的編譯與反編譯
一、什麼是編譯1、利用編譯程序從源語言編寫的源程序產生目標程序的過程。
2、用編譯程序產生目標程序的動作。
編譯就是把高級語言變成計算機可以識別的2進制語言,計算機只認識1和0,編譯程序把人們熟悉的語言換成2進制的。
編譯程序把一個源程序翻譯成目標程序的工作過程分為五個階段:詞法分析;語法分析;語義檢查和中間代碼生成;代碼優化;目標代碼生成。
主要是進行詞法分析和語法分析,又稱為源程序分析,分析過程中發現有語法錯誤,給出提示信息。
二、什麼是反編譯計算機軟體反向工程(Reverseengineering)也稱為計算機軟體還原工程,是指通過對他人軟體的目標程序(可執行程序)進行「逆向分析、研究」工作,以推導出他人的軟體產品所使用的思路、原理、結構、演算法、處理過程、運行方法等設計要素,某些特定情況下可能推導出源代碼。
反編譯作為自己開發軟體時的參考,或者直接用於自己的軟體產品中。
三、Java類的編譯與反編譯我們在最初學習Java的時候,會接觸到兩個命令:javac和java,那個時候我們就知道,javac是用來編譯Java類的,就是將我們寫好的helloworld.java文件編譯成helloworld.class文件。
class文件打破了C或者C++等語言所遵循的傳統,使用這些傳統語言寫的程序通常首先被編譯,然後被連接成單獨的、專門支持特定硬體平台和操作系統的二進制文件。
通常情況下,一個平台上的二進制可執行文件不能在其他平台上工作。
而Javaclass文件是可以運行在任何支持Java虛擬機的硬體平台和操作系統上的二進制文件。
那麼反編譯呢,就是通過helloworld.class文件得到java文件(或者說是程序員能看懂的Java文件)四、什麼時候會用到反編譯1、我們只有一個類的class文件,但是我們又看不懂Java的class文件,那麼山東java培訓http://www.kmbdqn.cn/認為可以把它反編譯成我們可以看得懂的文件。
2、學習Java過程中,JDK的每個版本都會加入越來越多的語法糖,有些時候我們想知道Java一些實現細節,我們可以藉助反編譯。
❽ 程序員的到底能幹多久
程序員到底能幹多久和自己的興趣愛好緊密聯系的,有些朋友本身就喜愛編程研究,這也許就是他的終生歸屬了,一直當成事業幹下去。還有一部分開發到一定階段後,因為某些原因可能會轉行出現。下面部分學習知識點:
1.例如字元串查找、子串、模式匹配等。當在 Lua 中對字元串做索引時,第一個字元從 1 開始計算(而不是 C 里的 0 )。 索引可以是負數,它指從字元串末尾反向解析。 即,最後一個字元在 -1 位置處,等等。
2.字元串庫中的所有函數都在表 string 中。它還將其設置為字元串元表的 __index 域。 因此,你可以以面向對象的形式使用字元串函數。 例如,string.byte(s,i) 可以寫成 s:byte(i)。
字元串庫假定採用單位元組字元編碼。
接收零或更多的整數。 返回和參數數量相同長度的字元串。 其中每個字元的內部編碼值等於對應的參數值。
數字編碼沒有必要跨平台。
string.mp (function [, strip])
3.返回包含有以二進制方式表示的(一個 二進制代碼塊 )指定函數的字元串。之後可以用 load 調用這個字元串獲得 該函數的副本(但是綁定新的上值)。 如果strip 為真值, 二進制代碼塊不攜帶該函數的調試信息 (局部變數名,行號,等等。)。
帶上值的函數只保存上值的數目。 當(再次)載入時,這些上值被更新為 nil 的實例。 (你可以使用調試庫按你需要的方式來序列化上值,並重載到函數中)
string.find (s, pattern [, init [, plain]])
4.查找第一個字元串 s 中匹配到的 pattern )。如果找到一個匹配,find 會返回 s 中關於它起始及終點位置的索引; 否則,返回 nil。 第三個可選數字參數 init 指明從哪裡開始搜索; 默認值為 1 ,同時可以是負值。 第四個可選參數 plain 為 true 時, 關閉模式匹配機制。 此時函數僅做直接的 「查找子串」的操作, 而 pattern 中沒有字元被看作魔法字元。 注意,如果給定了 plain,就必須寫上 init 。
如果在模式中定義了捕獲,捕獲到的若干值也會在兩個索引之後返回。
string.format (formatstring, ···)
5.返回不定數量參數的格式化版本, 格式化串為第一個參數(必須是一個字元串)。格式化字元串遵循 ISO C 函數 sprintf 的規則。 不同點在於選項 *, h, L, l, n, p 不支持, 另外還增加了一個選項 q。 q 選項將一個字元串格式化為兩個雙引號括起,對內部字元做恰當的轉義處理的字元串。 該字元串可以安全的被 Lua 解釋器讀回來。
希望能幫到你,謝謝!
❾ 如何從程序員走向架構師
如何從程序員走向架構師。首先,作為程序員,必須熟練使用各種框架,了解其實際安裝的原理、jvm虛擬機原理,雲南昆明電腦培訓認為了解jvm能夠讓您編寫性能更好的代碼。
技術歸納
熟悉tcp協議,為了創建三握手連接和斷開四次握手的整個過程,不能優化高並發的網路應用;熟悉http協議,特別是http頭,電腦培訓認為沒有五年多的大量工作無法理解session和cookie的生命周期以及它們之間的關系。
系統集群;負載均衡;反向代理;靜態與動態分離;靜態網站。
分布式緩存技術memcached,redis,是提高系統性能所必需的。總之,昆明北大青鳥發現把硬碟的內容放入內存提高速度,順便演算法的整合性hash。
資料庫設計能力,必不可少的是mysql,最基本的資料庫工具易於使用,它的基本參數優化,緩慢的查詢日誌分析,主從副本配置,至少成為半mysqdba。其他nosql資料庫,如mongodb。
成為架構師不是了解很多技術就行了,這些都是解決問題的基礎和工具,不懂這些知識是無法提出解決方案的,雲南計算機學習認為這是成為一名架構師所必備的。
❿ 一個「熟練」程序員和一個「有能力」程序員誰更牛
一、宏觀方面
一、 JAVA。
要想成為JAVA(高級)工程師肯定要學習JAVA。一般的程序員或許只需知道一些JAVA的語法結構就可以應付了。但要成為JAVA(高級)
工程師,您要對JAVA做比較深入的研究。您應該多研究一下JDBC、IO包、Util包、Text包、JMS、EJB、RMI、線程。如果可能,希望您
對JAVA的所有包都瀏覽一下,知道大概的API,這樣您就發現其實您想實現的很多功能,通過JAVA的API都可以實現了,就不必自己費太多的腦經 了。
二、 設計模式。
其實寫代碼是很容易的事情,我相信您也有同感。但如何寫得好就比較難了。這個「好」字包括代碼可重用性,可維護性,可擴展性等。如何寫出好的代
碼往往要藉助一些設計模式。當然長期的代碼經驗積累,只要您用心,會使您形成自己代碼風格。相信您的代碼也比較符合代碼的可重用性,可維護性,可擴展性。
但既然前人已經給我們總結出了經驗,我們何不踩著前人的肩膀前進?
三、 XML。
現在的系統中不使用XML幾乎是不可能的。XML的功能非常強大,它可以做數據轉換、做系統的配置、甚至可保存您的系統業務數據。因此您必須了解
XML,包括它的語法,結構。您還需要比較熟練的使用解析XML的一些API,比如JDOM,SAX等,因為在我們一般的項目中,XML往往擔當系統配置
信息的作用,您需要用這些API解析這些配置信息,開發完美的項目。
四、 精通使用一種或兩種框架。
「框架都會有許多可重用的代碼,良好的層次關系和業務控制邏輯,基於框架的開
發使你可以省出很多的開發成本」。這里希望您能精通,更多的是希望您能通過框架的使用了解框架的思想。這樣您在開發一個項目時思路會開闊一些,比如您
會想到把SQL語句與您的JAVA代碼分開,再比如您會考慮把您的業務邏輯配置到XML或者資料庫中,這樣整個項目就很容易擴張了。
五、 熟悉主流資料庫。其實真正比較大的項目都是有人專門做資料庫的,但往往很多項目要求作為(高級)工程師的您也參與資料庫的設計以及SQL的編寫。所以為了
更好的為國家做貢獻,建議您還是多了解一些主流資料庫,比如SQLSERVER,ORACLE,多連接SQL和存儲過程以及觸發器。如果您不是「科班」出
身,您還需要補充一些資料庫原理方面的知識。
六、 精通一種或兩種WEBServer。
因為作為JAVA工程師,特別時
想成為高級JAVA工程師的您,您不可避免地要部署您的項目到WebServer上,而且只有當您精通一種WebServer,您才可能最大限度地使用它
的資源,這往往可以節省很多時間和精力。
七、 UML。
您肯定想成為高級工程師,因此您有必要了解或熟練或精通UML,這取決於您有多大決心想成為高級工程師和項目經理。在比較正規的開發團隊
中,UML是討論項目的交流工具,您要想做一個軟體工程師,您至少要能看懂,您要想做高級工程師,您要能通過它來描述您對項目的理解,盡管這不是必須,但
卻很重要。
八、 站在高度分析問題:
這不是一個知識點,也不是通過書本就能學得到的。只所以提到這一點,是因為我比您還著急,我希望您更快的成為一個高級的軟體工程師,而
不是一個一般的軟體工程師。希望您在工作中多向您的系統分析員、需求分析員、系統設計員學習,多站在他們角度上去看您在開發的項目。在最好在項目之初先在
您的腦海里對項目有個大致的分析、設計,然後和他們進行比較,找找差別,想想缺點。
九、 工具。
您在這個階段可能接觸到不同的工具了,盡管您還需要使用JB或者IDEA,但能可能對
ROSE,Together要多了解一些,因為您要畫UML了。不要再對Dreamweaver等HTML編輯器情有獨鍾了,那些JSP頁面讓初級程序員去寫吧
二、微觀方面
1.Core Java部分
這是最基礎的,對於一個java高級開發/設計人員,你需要對這一部分達到精通的水平,重點內容如下:
a.面向對象編程思想(封裝繼承多態介面)
b.字元串處理
c.java.lang包,java.util包等常用包
d.java異常處理
2.Java高級部分
a.Java I/O流
b.Java多線程技術
c.Java網路編程
d.Java Swing
後兩項可以了解即可,如果項目需要可以深入研究
3.前端基本技能
* HTML + CSS網頁開發
* JavaScript
* Jquery
* 瀏覽器兼容性 CSS hack(了解)
4.熟練使用JSP + Servlet進行開發
5.MVC設計模式,原理,以及相關框架,如Struts
6.SSH框架
7.緩存技術 session & cookie
8.熟練使用一種以上Java開發工具(Eclipse/MyEclipse/Jbuilder/Jcreator/IntelliJIEDA/NetBeans)
9.熟練使用XML
JDOM w3c.dom SAX
10.Java設計模式
工廠模式,單例模式 ==
11.Java反射機制
反射的各種用法
12.了解或熟悉 C, C++, .NET
13.熟悉JDK的配置,環境變數
14.資料庫oracle必學,其他最好了解一種以上(mysql,sql server,access==)
oracle:視圖,索引,存儲過程,觸發器,游標,包,常用函數 ==
15.資料庫原理
事務的原理,鎖機制,表連接,復雜查詢語句(工作經驗),性能調優,鎖表以及解決方案==
16.JDBC,連接池
17.Ajax,反向Ajax
18.HTTP協議,request 和 response的原理,HTTP status(了解常用的),Https原理
19.熟悉Linux基本命令,使用過Linux/Unix系統,可以編寫shell腳本,可以在Linux上部署項目
20.了解windows系統批處理腳本bat
21.了解HTML5,最好學習過
22.熟悉一種JS框架,如Prototype
23.J2EE原理 熟悉一種以上web容器如Tomcat,JBoss,websphere,weblogic==
24.熟悉ant或maven
25.熟悉一門腳本語言,如python ,ruby
26.了解php/ asp
27.了解ftp協議及原理
28.熟練使用Junit測試,熟悉Mockito等測試工具
29,熟悉javac,javadoc,native,native2ascii等常用命令
30.熟悉常用的排序演算法,如冒泡排序,快速排序等,最好自己研究過一些的演算法。
31.了解Flex(不學也沒關系)
32.了解敏捷開發模式
33.工作流workflow至少用過一種,如OSworkflow,了解原理
34.使用過VPN了解其原理
35.熟悉jstl表達式和el表達式
36.熟悉webservice,WSDL,SOAP
37.圖片處理,如圖片上傳,預覽,限制大小等
38.版本控制工具,CVS VSS SVN
39,JSON技術,JSON+AJAX
40.分頁技術,最好自己實現過不僅僅是用過要知道原理
41.Java Mail
42.Java讀寫txt,excel,JXL技術
43.JVM原理,JVM內存管理,GC,Java堆棧池
44.熟練使用下面的工具:
office辦公軟體,word,excel,ppt等
plsql,sqldevelop 資料庫開發工具
outlook大公司都用
ue編輯器
瀏覽器控制台,調試
SHH/PUTTY 遠程
45.UML建模工具Rational Rose等
46. 使用log4j
47.使用過開放Api如網路,騰訊街景,新浪微博等
48.頁面靜態化技術(偽靜態頁面)
49.報表技術,使用過報表製作工具,如水晶易表。
50.定時任務,如Spring batch ,學會自定義batch任務(不適用第三方工具)
51.了解uuid
52.b/s 和 c/s架構
53.正則表達式
54.了解jndi jms
55.ERP
56.UNICODE編碼,亂碼解決
57.開源網路編輯器,如ckEditor
58.二進制原理
59.使用過,了解過開源論壇框架,如discuzz
60.GWT,Closure框架
61.了解大數據,雲計算
62.搜索引擎搜索技術
63.軟體工程,項目管理