第一階段:基礎(chǔ)階段(基礎(chǔ)PHP程序員)

為玉田等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及玉田網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、玉田網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
重點(diǎn):把LNMP搞熟練(核心是安裝配置基本操作) ?目標(biāo):能夠完成基本的LNMP系統(tǒng)安裝,簡單配置維護(hù);能夠做基本的簡單系統(tǒng)的PHP開發(fā);能夠在PHP中型系統(tǒng)中支持某個(gè)PHP功能模塊的開發(fā)。
時(shí)間:完成本階段的時(shí)間因人而異,有的成長快半年一年就過了,成長慢的兩三年也有。
Linux
基本命令、操作、啟動(dòng)、基本服務(wù)配置(包括rpm安裝文件,各種服務(wù)配置等);會(huì)寫簡單的shell腳本和awk/sed 腳本命令等。
Nginx
做到能夠安裝配置nginx+php,知道基本的nginx核心配置選項(xiàng),知道 server/fastcgi_pass/access_log 等基礎(chǔ)配置,目標(biāo)是能夠讓nginx+php_fpm順利工作。
MySQL
會(huì)自己搭建mysql,知道基本的mysql配置選項(xiàng);知道innodb和myisam的區(qū)別,知道針對(duì)InnoDB和MyISAM兩個(gè)引擎的不同配置選項(xiàng);知道基本的兩個(gè)引擎的差異和選擇上面的區(qū)別;能夠純手工編譯搭建一個(gè)MySQL數(shù)據(jù)庫并且配置好編碼等正常穩(wěn)定運(yùn)行;核心主旨是能夠搭建一個(gè)可運(yùn)行的MySQL數(shù)據(jù)庫。
PHP
基本語法數(shù)組、字符串、數(shù)據(jù)庫、XML、Socket、GD/ImageMgk圖片處理等等;熟悉各種跟MySQL操作鏈接的api(mysql/mysqli/PDO),知道各種編碼問題的解決;知道常規(guī)熟練使用的PHP框架(ThinkPHP、Zendframework、Yii、Yaf等);了解基本MVC的運(yùn)行機(jī)制和為什么這么做,稍微知道不同的PHP框架之間的區(qū)別;能夠快速學(xué)習(xí)一個(gè)MVC框架。能夠知道開發(fā)工程中的文件目錄組織,有基本的良好的代碼結(jié)構(gòu)和風(fēng)格,能夠完成小系統(tǒng)的開發(fā)和中型系統(tǒng)中某個(gè)模塊的開發(fā)工作。
前端
如果條件時(shí)間允許,可以適當(dāng)學(xué)習(xí)下 HTML/CSS/JS 等相關(guān)知識(shí),知道什么web標(biāo)準(zhǔn),div+css的web/wap頁面模式,知道HTML5和HTML4的區(qū)別;了解一些基本的前端只是和JS框架(jQuery之類的);了解一些基本的JavaScript編程知識(shí);(本項(xiàng)不是必須項(xiàng),如果有時(shí)間,稍微了解一下是可以的,不過不建議作為重點(diǎn),除非個(gè)人有強(qiáng)烈興趣)。
系統(tǒng)設(shè)計(jì)
能夠完成小型系統(tǒng)的基本設(shè)計(jì),包括簡單的數(shù)據(jù)庫設(shè)計(jì),能夠完成基本的:瀏覽器 - Nginx+PHP - 數(shù)據(jù)庫 架構(gòu)的設(shè)計(jì)開發(fā)工作;能夠支撐每天幾十萬到數(shù)百萬流量網(wǎng)站的開發(fā)維護(hù)工作;
第二階段:提高階段 (中級(jí)PHP程序員)
重點(diǎn):提高針對(duì)LNMP的技能,能夠更全面的對(duì)LNMP有熟練的應(yīng)用。 ?目標(biāo):能夠隨時(shí)隨地搭建好LNMP環(huán)境,快速完成常規(guī)配置;能夠追查解決大部分遇到的開發(fā)和線上環(huán)境的問題;能夠獨(dú)立承擔(dān)中型系統(tǒng)的構(gòu)架和開發(fā)工作;能夠在大型系統(tǒng)中承擔(dān)某個(gè)中型模塊的開發(fā)工作。
1. Linux
在第一階段的基礎(chǔ)上面,能夠流暢的使用Shell腳本來完成很多自動(dòng)化的工作;awk/sed/perl 也操作的不錯(cuò),能夠完成很多文本處理和數(shù)據(jù)統(tǒng)計(jì)等工作;基本能夠安裝大部分非特殊的Linux程序(包括各種庫、包、第三方依賴等等,比如MongoDB/Redis/Sphinx/Luncene/SVN之類的);了解基本的Linux服務(wù),知道如何查看Linux的性能指標(biāo)數(shù)據(jù),知道基本的Linux下面的問題跟蹤等。
2. Nginx
在第一階段的基礎(chǔ)上面,了解復(fù)雜一些的Nginx配置;包括 多核配置、events、proxy_pass,sendfile/tcp_*配置,知道超時(shí)等相關(guān)配置和性能影響;知道nginx除了web server,還能夠承擔(dān)代理服務(wù)器、反向靜態(tài)服務(wù)器等配置;知道基本的nginx配置調(diào)優(yōu);知道如何配置權(quán)限、編譯一個(gè)nginx擴(kuò)展到nginx;知道基本的nginx運(yùn)行原理(master/worker機(jī)制,epoll),知道為什么nginx性能比apache性能好等知識(shí)。
3. MySQL/MongoDB
在第一階段的基礎(chǔ)上面,在MySQL開發(fā)方面,掌握很多小技巧,包括常規(guī)SQL優(yōu)化(group by/order by/rand優(yōu)化等);除了能夠搭建MySQL,還能夠冷熱備份MySQL數(shù)據(jù),還知道影響innodb/myisam性能的配置選項(xiàng)(比如key_buffer/query_cache/sort_buffer/innodb_buffer_pool_size/innodb_flush_log_at_trx_commit等),也知道這些選項(xiàng)配置成為多少值合適;另外也了解一些特殊的配置選項(xiàng),比如 ?知道如何搭建mysql主從同步的環(huán)境,知道各個(gè)binlog_format的區(qū)別;知道MySQL的性能追查,包括slow_log/explain等,還能夠知道基本的索引建立處理等知識(shí);原理方面了解基本的MySQL的架構(gòu)(Server+存儲(chǔ)引擎),知道基本的InnoDB/MyISAM索引存儲(chǔ)結(jié)構(gòu)和不同(聚簇索引,B樹);知道基本的InnoDB事務(wù)處理機(jī)制;了解大部分MySQL異常情況的處理方案(或者知道哪兒找到處理方案)。條件允許的情況,建議了解一下NoSQL的代表MongoDB數(shù)據(jù)庫,順便對(duì)比跟MySQL的差別,同事能夠在合適的應(yīng)用場景安全謹(jǐn)慎的使用MongoDB,知道基本的PHP與MongoDB的結(jié)合開發(fā)。
4. Redis/Memcached
在大部分中型系統(tǒng)里面一定會(huì)涉及到緩存處理,所以一定要了解基本的緩存;知道Memcached和Redis的異同和應(yīng)用場景,能夠獨(dú)立安裝 Redis/Memcached,了解Memcahed的一些基本特性和限制,比如最大的value值,知道PHP跟他們的使用結(jié)合;Redis了解基本工作原理和使用,了解常規(guī)的數(shù)據(jù)類型,知道什么場景應(yīng)用什么類型,了解Redis的事務(wù)等等。原理部分,能夠大概了解Memcached的內(nèi)存結(jié)構(gòu)(slab機(jī)制),redis就了解常用數(shù)據(jù)類型底層實(shí)現(xiàn)存儲(chǔ)結(jié)構(gòu)(SDS/鏈表/SkipList/HashTable)等等,順便了解一下Redis的事務(wù)、RDB、AOF等機(jī)制更好。
5. PHP
除了第一階段的能力,安裝配置方面能夠隨意安裝PHP和各種第三方擴(kuò)展的編譯安裝配置;了解php-fpm的大部分配置選項(xiàng)和含義(如max_requests/max_children/request_terminate_timeout之類的影響性能的配置),知道m(xù)od_php/fastcgi的區(qū)別;在PHP方面已經(jīng)能夠熟練各種基礎(chǔ)技術(shù),還包括各種深入些的PHP,包括對(duì)PHP面向?qū)ο蟮纳钊肜斫?SPL/語法層面的特殊特性比如反射之類的;在框架方面已經(jīng)閱讀過最少一個(gè)以上常規(guī)PHP MVC框架的代碼了,知道基本PHP框架內(nèi)部實(shí)現(xiàn)機(jī)制和設(shè)計(jì)思想;在PHP開發(fā)中已經(jīng)能夠熟練使用常規(guī)的設(shè)計(jì)模式來應(yīng)用開發(fā)(抽象工廠/單例/觀察者/命令鏈/策略/適配器 等模式);建議開發(fā)自己的PHP MVC框架來充分讓開發(fā)自由化,讓自己深入理解MVC模式,也讓自己能夠在業(yè)務(wù)項(xiàng)目開發(fā)里快速升級(jí);熟悉PHP的各種代碼優(yōu)化方法,熟悉大部分PHP安全方面問題的解決處理;熟悉基本的PHP執(zhí)行的機(jī)制原理(Zend引擎/擴(kuò)展基本工作機(jī)制)。
6. C/C++
開始涉獵一定的C/C++語言,能夠?qū)懟镜腃/C++代碼,對(duì)基本的C/C++語法熟悉(指針、數(shù)組操作、字符串、常規(guī)標(biāo)準(zhǔn)API)和數(shù)據(jù)結(jié)構(gòu)(鏈表、樹、哈希、隊(duì)列)有一定的熟悉下;對(duì)Linux下面的C語言開發(fā)有基本的了解概念,會(huì)簡單的makefile文件編寫,能夠使用簡單的GCC/GDB的程序編譯簡單調(diào)試工作;對(duì)基本的網(wǎng)絡(luò)編程有大概了解。(本項(xiàng)是為了向更高層次打下基礎(chǔ))。
7. 前端
在第一階段的基礎(chǔ)上面,熟悉基本的HTTP協(xié)議(協(xié)議代碼200/300/400/500,基本的HTTP交互頭);條件允許,可以在深入寫出稍微優(yōu)雅的HTML+CSS+JavaScript,或者能夠大致簡單使用某些前端框架(jQuery/YUI/ExtJS/RequireJS/BootStrap之類);如果條件允許,可以深入學(xué)習(xí)JavaScript編程,比如閉包機(jī)制、DOM處理;再深入些可以讀讀jQuery源碼做深入學(xué)習(xí)。(本項(xiàng)不做重點(diǎn)學(xué)習(xí),除非對(duì)前端有興趣)。
8. 系統(tǒng)設(shè)計(jì)
能夠設(shè)計(jì)大部分中型系統(tǒng)的網(wǎng)站架構(gòu)、數(shù)據(jù)庫、基本PHP框架選型;性能測試排查處理等;能夠完成類似:瀏覽器 - CDN(Squid) - Nginx+PHP - 緩存 - 數(shù)據(jù)庫 結(jié)構(gòu)網(wǎng)站的基本設(shè)計(jì)開發(fā)維護(hù);能夠支撐每天數(shù)百萬到千萬流量基本網(wǎng)站的開發(fā)維護(hù)工作;
第三階段:高級(jí)階段 (高級(jí)PHP程序員)
重點(diǎn):除了基本的LNMP程序,還能夠在某個(gè)方向或領(lǐng)域有深入學(xué)習(xí)。(縱深維度發(fā)展) ?目標(biāo):除了能夠完成基本的PHP業(yè)務(wù)開發(fā),還能夠解決大部分深入復(fù)雜的技術(shù)問題,并且可以獨(dú)立設(shè)計(jì)完成中大型的系統(tǒng)設(shè)計(jì)和開發(fā)工作;自己能夠獨(dú)立hold深入某個(gè)技術(shù)方向,在這塊比較專業(yè)。(比如在MySQL、Nginx、PHP、Redis等等任一方向深入研究)
1. Linux
除了第二階段的能力,在Linux下面除了常規(guī)的操作和性能監(jiān)控跟蹤,還能夠使用很多高級(jí)復(fù)雜的命令完成工作(watch/tcpdump/starce/ldd/ar等);在shell腳本方面,已經(jīng)能夠編寫比較復(fù)雜的shell腳本(超過500行)來協(xié)助完成很多包括備份、自動(dòng)化處理、監(jiān)控等工作的shell;對(duì)awk/sed/perl 等應(yīng)用已經(jīng)如火純青,能夠隨意操作控制處理文本統(tǒng)計(jì)分析各種復(fù)雜格式的數(shù)據(jù);對(duì)Linux內(nèi)部機(jī)制有一些了解,對(duì)內(nèi)核模塊加載,啟動(dòng)錯(cuò)誤處理等等有個(gè)基本的處理;同時(shí)對(duì)一些其他相關(guān)的東西也了解,比如NFS、磁盤管理等等;
2. Nginx
在第二階段的基礎(chǔ)上面,已經(jīng)能夠把Nginx操作的很熟練,能夠?qū)ginx進(jìn)行更深入的運(yùn)維工作,比如監(jiān)控、性能優(yōu)化,復(fù)雜問題處理等等;看個(gè)人興趣,更多方面可以考慮側(cè)重在關(guān)于Nginx工作原理部分的深入學(xué)習(xí),主要表現(xiàn)在閱讀源碼開始,比如具體的master/worker工作機(jī)制,Nginx內(nèi)部的事件處理,內(nèi)存管理等等;同時(shí)可以學(xué)習(xí)Nginx擴(kuò)展的開發(fā),可以定制一些自己私有的擴(kuò)展;同時(shí)可以對(duì)Nginx+Lua有一定程度的了解,看看是否可以結(jié)合應(yīng)用出更好模式;這個(gè)階段的要求是對(duì)Nginx原理的深入理解,可以考慮成為Nginx方向的深入專業(yè)者。
3. MySQL/MongoDB
在第二階段的基礎(chǔ)上面,在MySQL應(yīng)用方面,除了之前的基本SQL優(yōu)化,還能夠在完成一些復(fù)雜操作,比如大批量數(shù)據(jù)的導(dǎo)入導(dǎo)出,線上大批量數(shù)據(jù)的更改表結(jié)構(gòu)或者增刪索引字段等等高危操作;除了安裝配置,已經(jīng)能夠處理更多復(fù)雜的MySQL的問題,比如各種問題的追查,主從同步延遲問題的解決、跨機(jī)房同步數(shù)據(jù)方案、MySQL高可用架構(gòu)等都有涉及了解;對(duì)MySQL應(yīng)用層面,對(duì)MySQL的核心關(guān)鍵技術(shù)比較熟悉,比如事務(wù)機(jī)制(隔離級(jí)別、鎖等)、對(duì)觸發(fā)器、分區(qū)等技術(shù)有一定了解和應(yīng)用;對(duì)MySQL性能方面,有包括磁盤優(yōu)化(SAS遷移到SSD)、服務(wù)器優(yōu)化(內(nèi)存、服務(wù)器本身配置)、除了二階段的其他核心性能優(yōu)化選項(xiàng)(innodb_log_buffer_size/back_log/table_open_cache/thread_cache_size/innodb_lock_wait_timeout等)、連接池軟件選擇應(yīng)用,對(duì)show *(show status/show profile)類的操作語句有深入了解,能夠完成大部分的性能問題追查;MySQL備份技術(shù)的深入熟悉,包括災(zāi)備還原、對(duì)Binlog的深入理解,冷熱備份,多IDC備份等;在MySQL原理方面,有更多了解,比如對(duì)MySQL的工作機(jī)制開始閱讀部分源碼,比如對(duì)主從同步(復(fù)制)技術(shù)的源碼學(xué)習(xí),或者對(duì)某個(gè)存儲(chǔ)引擎(MyISAM/Innodb/TokuDB)等等的源碼學(xué)習(xí)理解,如果條件允許,可以參考CSV引擎開發(fā)自己簡單的存儲(chǔ)引擎來保存一些數(shù)據(jù),增強(qiáng)對(duì)MySQL的理解;在這個(gè)過程,如果自己有興趣,也可以考慮往DBA方向發(fā)展。MongoDB層面,可以考慮比如說在寫少讀多的情況開始在線上應(yīng)用MongoDB,或者是做一些線上的數(shù)據(jù)分析處理的操作,具體場景可以按照工作來,不過核心是要更好的深入理解RMDBS和NoSQL的不同場景下面的應(yīng)用,如果條件或者興趣允許,可以開始深入學(xué)習(xí)一下MongoDB的工作機(jī)制。
4. Redis/Memcached
在第二階段的基礎(chǔ)上面,能夠更深入的應(yīng)用和學(xué)習(xí)。因?yàn)镸emcached不是特別復(fù)雜,建議可以把源碼進(jìn)行閱讀,特別是內(nèi)存管理部分,方便深入理解;Redis部分,可以多做一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)的應(yīng)用(zset來做排行榜排序操作/事務(wù)處理用來保證原子性在秒殺類場景應(yīng)用之類的使用操作);多涉及aof等同步機(jī)制的學(xué)習(xí)應(yīng)用,設(shè)計(jì)一個(gè)高可用的Redis應(yīng)用架構(gòu)和集群;建議可以深入的學(xué)習(xí)一下Redis的源碼,把在第二階段積累的知識(shí)都可以應(yīng)用上,特別可以閱讀一下包括核心事件管理、內(nèi)存管理、內(nèi)部核心數(shù)據(jù)結(jié)構(gòu)等充分學(xué)習(xí)了解一下。如果興趣允許,可以成為一個(gè)Redis方面非常專業(yè)的使用者。
5. PHP
作為基礎(chǔ)核心技能,我們在第二階段的基礎(chǔ)上面,需要有更深入的學(xué)習(xí)和應(yīng)用。從基本代碼應(yīng)用上面來說,能夠解決在PHP開發(fā)中遇到95%的問題,了解大部分PHP的技巧;對(duì)大部分的PHP框架能夠迅速在一天內(nèi)上手使用,并且了解各個(gè)主流PHP框架的優(yōu)缺點(diǎn),能夠迅速方便項(xiàng)目開發(fā)中做技術(shù)選型;在配置方面,除了常規(guī)第二階段會(huì)的知識(shí),會(huì)了解一些比較偏門的配置選項(xiàng)(php auto_prepend_file/auto_append_file),包括擴(kuò)展中的一些復(fù)雜高級(jí)配置和原理(比如memcached擴(kuò)展配置中的memcache.hash_strategy、apc擴(kuò)展配置中的apc.mmap_file_mask/apc.slam_defense/apc.file_update_protection之類的);對(duì)php的工作機(jī)制比較了解,包括php-fpm工作機(jī)制(比如php-fpm在不同配置機(jī)器下面開啟進(jìn)程數(shù)量計(jì)算以及原理),對(duì)zend引擎有基本熟悉(vm/gc/stream處理),閱讀過基本的PHP內(nèi)核源碼(或者閱讀過相關(guān)文章),對(duì)PHP內(nèi)部機(jī)制的大部分核心數(shù)據(jù)結(jié)構(gòu)(基礎(chǔ)類型/Array/Object)實(shí)現(xiàn)有了解,對(duì)于核心基礎(chǔ)結(jié)構(gòu)(zval/hashtable/gc)有深入學(xué)習(xí)了解;能夠進(jìn)行基本的PHP擴(kuò)展開發(fā),了解一些擴(kuò)展開發(fā)的中高級(jí)知識(shí)(minit/rinit等),熟悉php跟apache/nginx不同的通信交互方式細(xì)節(jié)(mod_php/fastcgi);除了開發(fā)PHP擴(kuò)展,可以考慮學(xué)習(xí)開發(fā)Zend擴(kuò)展,從更底層去了解PHP。
6. C/C++
在第二階段基礎(chǔ)上面,能夠在C/C++語言方面有更深入的學(xué)習(xí)了解,能夠完成中小型C/C++系統(tǒng)的開發(fā)工作;除了基本第二階段的基礎(chǔ)C/C++語法和數(shù)據(jù)結(jié)構(gòu),也能夠?qū)W習(xí)一些特殊數(shù)據(jù)結(jié)構(gòu)(b-tree/rb-tree/skiplist/lsm-tree/trie-tree等)方便在特殊工作中需求;在系統(tǒng)編程方面,熟悉多進(jìn)程、多線程編程;多進(jìn)程情況下面了解大部分多進(jìn)程之間的通信方式,能夠靈活選擇通信方式(共享內(nèi)存/信號(hào)量/管道等);多線程編程能夠良好的解決鎖沖突問題,并且能夠進(jìn)行多線程程序的開發(fā)調(diào)試工作;同時(shí)對(duì)網(wǎng)絡(luò)編程比較熟悉,了解多進(jìn)程模型/多線程模型/異步網(wǎng)絡(luò)IO模型的差別和選型,熟悉不同異步網(wǎng)絡(luò)IO模型的原理和差異(select/poll/epoll/iocp等),并且熟悉常見的異步框架(ACE/ICE/libev/libevent/libuv/Boost.ASIO等)和使用,如果閑暇也可以看看一些國產(chǎn)自己開發(fā)的庫(比如muduo);同時(shí)能夠設(shè)計(jì)好的高并發(fā)程序架構(gòu)(leader-follow/master-worker等);了解大部分C/C++后端Server開發(fā)中的問題(內(nèi)存管理、日志打印、高并發(fā)、前后端通信協(xié)議、服務(wù)監(jiān)控),知道各個(gè)后端服務(wù)RPC通信問題(struct/http/thirft/protobuf等);能夠更熟絡(luò)的使用GCC和GDB來開發(fā)編譯調(diào)試程序,在線上程序core掉后能夠迅速追查跟蹤解決問題;通用模塊開發(fā)方面,可以積累或者開發(fā)一些通用的工具或庫(比如異步網(wǎng)絡(luò)框架、日志庫、內(nèi)存池、線程池等),不過開發(fā)后是否應(yīng)用要謹(jǐn)慎,省的埋坑去追bug。
7. 前端
深入了解HTTP協(xié)議(包括各個(gè)細(xì)致協(xié)議特殊協(xié)議代碼和背后原因,比如302靜態(tài)文件緩存了,502是nginx后面php掛了之類的);除了之前的前端方面的各種框架應(yīng)用整合能力,前端方面的學(xué)習(xí)如果有興趣可以更深入,表現(xiàn)形式是,可以自己開發(fā)一些類似jQuery的前端框架,或者開發(fā)一個(gè)富文本編輯器之類的比較瑣碎考驗(yàn)JavaScript功力。
8. 其他領(lǐng)域語言學(xué)習(xí)
在基礎(chǔ)的PHP/C/C++語言方面有基本積累,建議在當(dāng)前階段可以嘗試學(xué)習(xí)不同的編程語言,看個(gè)人興趣愛好,腳本類語言可以學(xué)學(xué) Python/Ruby 之類的,函數(shù)式編程語言可以試試 Lisp/Haskell/Scala/Erlang 之類的,靜態(tài)語言可以試試 Java/Golang,數(shù)據(jù)統(tǒng)計(jì)分析可以了解了解R語言,如果想換個(gè)視角做后端業(yè)務(wù),可以試試 Node.js還有前面提到的跟Nginx結(jié)合的Nginx_Lua等。學(xué)習(xí)不同的語言主要是提升自己的視野和解決問題手段的差異,比如會(huì)了解除了進(jìn)程/線程,還有輕量級(jí)協(xié)程;比如在跨機(jī)器通信場景下面,Erlang的解決方案簡單的驚人;比如在不想選擇C/C++的情況下,還有類似高效的Erlang/Golang可用等等;主要是提升視野。
9. 其他專業(yè)方向?qū)W習(xí)
在本階段里面,會(huì)除了基本的LNMP技能之外,會(huì)考慮一些其他領(lǐng)域知識(shí)的學(xué)習(xí),這些都是可以的,看個(gè)人興趣和長期的目標(biāo)方向。目前情況能夠選擇的領(lǐng)域比較多,比如、云計(jì)算(分布式存儲(chǔ)、分布式計(jì)算、虛擬機(jī)等),機(jī)器學(xué)習(xí)(數(shù)據(jù)挖掘、模式識(shí)別等,應(yīng)用到統(tǒng)計(jì)、個(gè)性化推薦),自然語言處理(中文分詞等),搜索引擎技術(shù)、圖形圖像、語音識(shí)別等等。除了這些高大上的,也有很多偏工程方面可以學(xué)習(xí)的地方,比如高性能系統(tǒng)、移動(dòng)開發(fā)(Android/IOS)、計(jì)算機(jī)安全、嵌入式系統(tǒng)、硬件等方向。
10. 系統(tǒng)設(shè)計(jì)
系統(tǒng)設(shè)計(jì)在第二階段的基礎(chǔ)之上,能夠應(yīng)用掌握的經(jīng)驗(yàn)技能,設(shè)計(jì)出比較復(fù)雜的中大型系統(tǒng),能夠解決大部分線上的各種復(fù)雜系統(tǒng)的問題,完成類似 瀏覽器 - CDN - 負(fù)載均衡 -接入層 - Nginx+PHP - 業(yè)務(wù)緩存 - 數(shù)據(jù)庫 - 各路復(fù)雜后端RPC交互(存儲(chǔ)后端、邏輯后端、反作弊后端、外部服務(wù)) - 更多后端 醬紫的復(fù)雜業(yè)務(wù);能夠支撐每天數(shù)千萬到數(shù)億流量網(wǎng)站的正常開發(fā)維護(hù)工作。
就是把鏈表的結(jié)構(gòu)稍加改造,這種數(shù)據(jù)結(jié)構(gòu)叫
為了提升鏈表的查詢效率,怎么讓鏈表支持類似‘?dāng)?shù)組’那樣的‘二分’算法呢
跳表是一個(gè)各方面性能都比較優(yōu)秀的 動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu) ,可以支持快速地插入、刪除、查找操作,寫起來也不復(fù)雜,甚至可以替代紅黑樹。
Redis 中的有序集合(Sorted Set)就是用跳表來實(shí)現(xiàn)的。
那 Redis 為什么會(huì)選擇用跳表(和散列表)來實(shí)現(xiàn)有序集合呢? 為什么不用紅黑樹呢?這個(gè)問題一會(huì)在回答,先看看跳表的數(shù)據(jù)結(jié)構(gòu)
其實(shí)概念很簡單,就是在鏈表上加上了
當(dāng)我們在不停插入數(shù)據(jù),如果我們不更新索引,可能出現(xiàn)某 2 個(gè)索引結(jié)點(diǎn)之間數(shù)據(jù)非常多的情況。極端情況下,跳表還會(huì)退化成單鏈表。
紅黑樹、AVL 樹這樣平衡二叉樹,是通過左右旋的方式保持左右子樹的大小平衡,而跳表是通過 隨機(jī)函數(shù) 來維護(hù)平衡性。
插入、刪除、查找以及迭代輸出有序序列這幾個(gè)操作,紅黑樹也可以完成,時(shí)間復(fù)雜度跟跳表是一樣的。但是, 按照區(qū)間來查找數(shù)據(jù)這個(gè)操作,紅黑樹的效率沒有跳表高。
對(duì)于按照區(qū)間查找數(shù)據(jù)這個(gè)操作,跳表可以做到 O(logn) 的時(shí)間復(fù)雜度定位區(qū)間的起點(diǎn),然后在原始鏈表中順序往后遍歷就可以了。
Redis 鍵值構(gòu)建一個(gè)散列表,這樣按照 key 來刪除、查找一個(gè)成員對(duì)象的時(shí)間復(fù)雜度就變成了 O(1)。同時(shí),借助跳表結(jié)構(gòu),其他操作也非常高效。
散列表的英文叫“Hash Table”,我們平時(shí)也叫它“哈希表”或者“Hash 表”
散列技術(shù)是在記錄的存儲(chǔ)位置和它的關(guān)鍵字之間建立一個(gè)確定的對(duì)應(yīng)關(guān)系 f,使得每個(gè)關(guān)鍵字 key 對(duì)應(yīng)一個(gè)存儲(chǔ)位置 f(key)。查找時(shí)根據(jù)這個(gè)對(duì)應(yīng)關(guān)系匠互給定的 key 的映射 f(key)
這種關(guān)系 f 稱為散列函數(shù)(又稱哈希函數(shù))。散列技術(shù)將記錄存儲(chǔ)在一塊連續(xù)的存儲(chǔ)空間中,這塊連續(xù)存儲(chǔ)空間稱為散列表或哈希表。那么關(guān)鍵字對(duì)應(yīng)的記錄存儲(chǔ)位置稱為散列地址。
散列函數(shù)的構(gòu)造方法特點(diǎn)就是:計(jì)算簡單、散列地址分布均勻
大家一定聽說過 hash 碰撞。就是2個(gè)不同的 key 對(duì)應(yīng)著不同的 f 關(guān)系。但這是幾乎不可能的,即便像業(yè)界著名的MD5、SHA、CRC等哈希算法,也無法完全避免這種散列沖突。而且,因?yàn)閿?shù)組的存儲(chǔ)空間有限,也會(huì)加大散列沖突的概率。
我們只能通過其它途徑來尋找方法。我們常用的散列沖突解決方法有兩類,開放尋址法(open addressing)和鏈表法(chaining)。
所謂的開放尋址法就是一但發(fā)生了沖突,就去尋找下一個(gè)空的散地址,只要散列表足夠大,空的散列表地址總能找到,并將記錄存入。
鏈地址法又稱鏈表法,其實(shí)當(dāng)發(fā)生沖突時(shí)存入鏈表,如下圖很容易就可以看明白。此時(shí),已經(jīng)不存在什么沖突地址的問題,無論有多少?zèng)_突,都只是在當(dāng)前位置給單鏈表增加結(jié)點(diǎn)的問題。
這種不常見,就是把沖突的單獨(dú)找個(gè)地方。
顧名思義,紅黑樹中的節(jié)點(diǎn),一類被標(biāo)記為黑色,一類被標(biāo)記為紅色。除此之外,一棵紅黑
平衡二叉樹 是一種二叉排序樹,其中每一個(gè)節(jié)點(diǎn)的左子樹和右子樹的高度不能大于 1
紅黑樹是一種平衡二叉查找樹。它是為了解決普通二叉查找樹在數(shù)據(jù)更新的過程中,復(fù)雜度退化的問題而產(chǎn)生的。紅黑樹的高度近似 log2n,所以它是近似平衡,插入、刪除、查找操作的時(shí)間復(fù)雜度都是 O(logn)。
平衡二叉查找樹其實(shí)有很多,比如,Splay Tree(伸展樹)、Treap(樹堆)等,但是我們提到平衡二叉查找樹,聽到的基本都是紅黑樹。
紅黑樹在眾多里面,表現(xiàn)的最為平衡。
“近似平衡”就等價(jià)為性能不會(huì)退化得太嚴(yán)重。
一棵紅黑樹還需要滿足這樣幾個(gè)要求:
看到這里你會(huì)很頭大,什么黑的紅的,完全不懂。賦上連接,有時(shí)間在看
散列表 :插入刪除查找都是O(1), 是最常用的,但其缺點(diǎn)是不能順序遍歷(存入的數(shù)據(jù)是無順序的)以及擴(kuò)容縮容的性能損耗。適用于那些不需要順序遍歷,數(shù)據(jù)更新不那么頻繁的。
散列表總和鏈表、跳表一起出現(xiàn)組合使用。
跳表 :插入刪除查找都是O(logn), 并且能順序遍歷。缺點(diǎn)是空間復(fù)雜度O(n)。適用于不那么在意內(nèi)存空間的,其順序遍歷和區(qū)間查找非常方便。
跳表還可以和散列表組合讓刪除、查找一個(gè)成員對(duì)象操作變?yōu)镺(1),也就是說利用了散列表查找速度,跳表的順序結(jié)構(gòu)
紅黑樹 :插入刪除查找都是O(logn), 中序遍歷即是順序遍歷,穩(wěn)定。缺點(diǎn)是難以實(shí)現(xiàn),去查找不方便。其實(shí)跳表更佳,但紅黑樹已經(jīng)用于很多地方了。
C要難得多!
原因:
1 PHP數(shù)據(jù)結(jié)構(gòu)有數(shù)組,C有數(shù)組,鏈表,隊(duì)列等
2 假如PHP寫一個(gè)功能要一行代碼,C一般要20行
3 一般來說PHP代碼可讀性更高,但性能比C差很多
4 C可以直接操作內(nèi)存,PHP只能通過擴(kuò)展操作
5 PHP的底層是C寫的,擴(kuò)展也是
深入PHP中的HashTable結(jié)構(gòu)詳解
深入PHP中的HashTable結(jié)構(gòu)詳解
對(duì)php內(nèi)核有一定了解的人應(yīng)該都知道php的精髓就是HashTable,HashTable在php的實(shí)現(xiàn)中無處不在。包括php的數(shù)組、什么全局變量、局部變量的作用域等等,php的hashtable拆開來說就是四部分:
hash函數(shù):用的是time33的散列函數(shù),將一個(gè)字符串的key轉(zhuǎn)換成一個(gè)數(shù)字
一個(gè)C數(shù)組:用來儲(chǔ)存桶(buckets)的
兩個(gè)雙向的鏈表:第一個(gè)雙向鏈表是數(shù)組的每個(gè)元素(桶bucket)是一個(gè)雙向鏈表,這樣做是為了解決hash沖突;第二個(gè)雙向鏈表是數(shù)組將每一個(gè)桶(bucket)連接起來,這里要連接的也就是第一個(gè)雙向鏈表的鏈表頭,這樣做是為了遍歷整個(gè)hash表用的,鳥哥有篇blog是講php的foreach的,這里這樣設(shè)計(jì)就是給foreach用的==《深入理解PHP之?dāng)?shù)組(遍歷順序)》
我這里不再說hashtable的struct和bucket的`struct了,因?yàn)橄旅娴耐扑]鏈接幾乎都講了,我不覺得我能描述和說的比他們好,每個(gè)人的水平不一樣,我就以我現(xiàn)在的技術(shù)水平來描述,所以我就只把我整理的一些東西記錄一下
下面是php中hash實(shí)現(xiàn)的兩個(gè)文件:zend_hash.c zend_hash.h。這兩個(gè)文件里面實(shí)現(xiàn)了一堆的api,也引申出了一堆的api,下面是實(shí)現(xiàn)出來的api的原型
復(fù)制代碼 代碼如下:
ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength)
ZEND_API ulong zend_get_hash_value(const char *arKey, uint nKeyLength)
ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
ZEND_API void zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProtection)
ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API int _zend_hash_index_update_or_next_(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API int zend_hash_rehash(HashTable *ht)
static int zend_hash_do_resize(HashTable *ht)
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag)
ZEND_API void zend_hash_destroy(HashTable *ht)
ZEND_API void zend_hash_clean(HashTable *ht)
static Bucket *zend_hash_apply_r(HashTable *ht, Bucket *p)
ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *argument TSRMLS_DC)
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht TSRMLS_DC, apply_func_args_t apply_func, int num_args, …)
ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size)
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite ZEND_FILE_LINE_DC)
static zend_bool zend_hash_replace_checker_wrapper(HashTable *target, void *source_data, Bucket *p, void *pParam, merge_checker_func_t merge_checker_func)
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam)
ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData)
ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength)
ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h)
ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData)
ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h)
ZEND_API int zend_hash_num_elements(const HashTable *ht)
ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr)
ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr)
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos)
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos)
ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos)
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compar, int renumber TSRMLS_DC)
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC)
ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC)
ZEND_API ulong zend_hash_next_free_element(const HashTable *ht)
void zend_hash_display_pListTail(const HashTable *ht)
void zend_hash_display(const HashTable *ht)
;
本文題目:php數(shù)據(jù)結(jié)構(gòu)鏈表 php數(shù)組數(shù)據(jù)結(jié)構(gòu)
文章地址:http://chinadenli.net/article38/hppepp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、外貿(mào)建站、ChatGPT、網(wǎng)站設(shè)計(jì)、企業(yè)網(wǎng)站制作、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)