1. 程式人生 > >軟體開發工程師進階之路

軟體開發工程師進階之路

伺服器方面:

1、web伺服器nginx和apache的對比分析

①nginx相對於apache的優點:

輕量級,同樣起web 服務,比apache 佔用更少的記憶體及資源 ,抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能,高度模組化的設計,編寫模組相對簡單。

apache相對於nginx 的優點:A.rewrite ,比nginx 的rewrite 強大;B.動態頁面,模組超多,基本想到的都可以找到;C.少bug ,nginx 的bug 相對較多;D.超穩定.

一般來說,需要效能的web 服務,用nginx 。如果不需要效能只求穩定,那就apache.

②作為 Web 伺服器:相比 Apache,Nginx 使用更少的資源,支援更多的併發連線,體現更高的效率。Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多.

③Nginx 配置簡潔,Apache 複雜。Nginx 靜態處理效能比 Apache 高 3倍以上,Apache 對 PHP 支援比較簡單,Nginx 需要配合其他後端用。Apache 的元件比 Nginx 多,現在 Nginx 才是Web 伺服器的首選。

④最核心的區別在於apache是同步多程序模型,一個連線對應一個程序;nginx是非同步的,多個連線(萬級別)可以對應一個程序。

⑤nginx處理靜態檔案好,耗費記憶體少.但無疑apache仍然是目前的主流,有很多豐富的特性.所以還需要搭配著來.當然如果能確定nginx就適合需求,那麼使用nginx會是更經濟的方式。

⑥nginx處理動態請求是雞肋,一般動態請求要apache去做,nginx只適合靜態和反向。

⑦Nginx優於apache的主要兩點:A.Nginx本身就是一個反向代理伺服器 B.Nginx支援7層負載均衡;其他的當然,Nginx可能會比 apache支援更高的併發。

資料庫方面:

1、資料庫優化:

①方法:MySQL可以建分表,讀寫分離,建索引,一般經常更新的欄位不適合建索引,建索引會降低資料非查詢操作的效率。主鍵是一種特殊的索引。

②導致索引失效的情況:

A、如果條件中有or,即使其中有條件帶索引也不會使用到。

B、對於多列索引,不是使用的第一部分,則不會使用索引。

C、like查詢是以%開頭,而不是以%結尾的。

D、如果索引列型別是字串,一定要在條件中將資料使用引號引用起來,否則不使用索引。

E、如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

2、MySQL引擎的種類和區別

①種類:MyISAM、InnoDB、MEMORY、MERGE、Archive、Blackhole、CSV、Federate、Merge、NDB叢集引擎,第三方引擎:OLTP類引擎、面向列的儲存引擎、社群儲存引擎。

②區別:

A、MyISAM是MySQL5.1及之前的預設儲存引擎。MyISAM不支援事務、也不支援外來鍵,但其訪問速度快,對事務完整性沒有要求。MyISAM表還支援3中不同的儲存格式:

1 靜態表

2 動態表

3 壓縮表

B、InnoDB儲存引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是比起MyISAM儲存引擎,InnoDB寫的處理效率差一些並且會佔用更多的磁碟空間以保留資料和索引。 InnoDB儲存方式為兩種:1 使用共享表空間儲存 2 使用多表空間

C、MEMORY儲存引擎使用存在記憶體中的內容來建立表。每個MEMORY表只實際對應一個磁碟檔案。MEMORY型別的表訪問非常得快,因為它的資料是放在記憶體中的,並且預設使用HASH索引。但是一旦服務關閉,表中的資料就會丟失掉。

D、MERGE儲存引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全相同。MERGE表本身沒有資料,對MERGE型別的表進行查詢、更新、刪除的操作,就是對內部的MyISAM表進行的。

3、資料庫事務

(1)四個特性:ACID,原子性,一致性,隔離性,永續性。

(2)四個隔離級別:

√: 可能出現    ×: 不會出現

  髒讀 不可重複讀 幻讀
Read uncommitted
Read committed ×
Repeatable read × ×
Serializable × × ×

Read Uncommitted(讀取未提交內容)
       在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的效能也不比其他級別好多少。讀取未提交的資料,也被稱之為髒讀(Dirty Read)。
Read Committed(讀取提交內容)
       這是大多數資料庫系統的預設隔離級別(但不是MySQL預設的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支援所謂的不可重複讀(Nonrepeatable Read),因為同一事務的其他例項在該例項處理其間可能會有新的commit,所以同一select可能返回不同結果。
Repeatable Read(可重讀)
       這是MySQL的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的資料行時,另一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的資料行時,會發現有新的“幻影” 行。InnoDB和Falcon儲存引擎通過多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
Serializable(可序列化)
       這是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

這四種隔離級別採取不同的鎖型別來實現,若讀取的是同一個資料的話,就容易發生問題。例如:
i.   髒讀(Drity Read):某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的資料就會是不正確的。
ii.  不可重複讀(Non-repeatable read):在一個事務的兩次查詢之中資料不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的資料。
iii. 幻讀(Phantom Read):在一個事務的兩次查詢中資料筆數不一致,例如有一個事務查詢了幾列(Row)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的。

(3)一致性處理: 

A、開啟事務。B、申請寫許可權,也就是給物件(表或記錄)加鎖。C、假如失敗,則結束事務,過一會重試。D、假如成功,也就是給物件加鎖成功,防止其他使用者再用同樣的方式開啟。E、進行編輯操作。F、寫入所進行的編輯結果。G、假如寫入成功,則提交事務,完成操作。 H、假如寫入失敗,則回滾事務,取消提交。I、(G、H)兩步操作已釋放了鎖定的物件,恢復到操作前的狀態。

(4)基於事務的資料庫引擎的選型:如果考慮到事務,推薦選用MySQL INNODB引擎;如果考慮速度,建議考慮MySQL MyISAM引擎,並且需要在程式碼層面做比較複雜的處理,如通過多執行緒、非同步、非阻塞等方式對資料庫進行清理,同時需要訊號量、欄柵、資料庫標誌位等工具保證資料一致性。

4、海量資料處理

(1)資料庫擴充套件:

①縱向擴充套件:基於業務的高度隔離性和資料的安全性,對業務和資料進行合理的切分,進行主-備機分離,主-主同步,主-從同步(對於MySQL資料庫是單向非同步同步機制),主-從熱備等操作。

②橫向擴充套件:對資料表進行橫向切分,按一定的規則(hash取模分、user_id尾數、自定義演算法等)對資料表進行橫向切分。

關於資料庫架構和擴充套件方面的文章請見:Mysql在大型網站的應用架構演變

(2)分散式資料方案:

①提供分庫規則和路由規則(RouteRule簡稱RR),將上面的說明中提到的三中切分規則直接內嵌入本系統,具體的嵌入方式在接下來的內容中進行詳細的說明和論述; 

②引入叢集(Group)的概念,保證資料的高可用性; 

③引入負載均衡策略(LoadBalancePolicy簡稱LB); 

④引入叢集節點可用性探測機制,對單點機器的可用性進行定時的偵測,以保證LB策略的正確實施,以確保系統的高度穩定性; 

⑤引入讀/寫分離,提高資料的查詢速度。

具體描述請參見博文:MySQL 海量資料的儲存和訪問解決方案

(3)資料庫切分策略介紹,請見博文:資料庫Sharding的基本思想和切分策略

(4)隨著資料量隨著業務的發展不斷增大,傳統的關係型資料庫RDB已經無法滿足需要,這時需要引入新的海量資料處理解決方案:Apache HBase。

框架方面:

Spring原理(建議讀一下框架核心原始碼)

①IoC(Inversion of control): 控制反轉,依賴注入

1)IoC:

概念:控制權由物件本身轉向容器;由容器根據配置檔案去建立例項並建立各個例項之間的依賴關係

2)依賴IoC容器負責管理bean,有兩種,一種是BeanFactory,另一種是ApplicationContext,但是ApplicationContext繼承與BeanFactory。

核心:bean工廠;在Spring中,bean工廠建立的各個例項稱作bean

②AOP(Aspect-Oriented Programming): 面向方面程式設計

1)代理的兩種方式:

靜態代理:

 針對每個具體類分別編寫代理類;

 針對一個介面編寫一個代理類;

動態代理:

針對一個方面編寫一個InvocationHandler,然後借用JDK反射包中的Proxy類為各種介面動態生成相應的代理類

2) AOP的主要原理:動態代理

實現:有兩種:JDK Proxy和Cglib,Spring規定對於有介面的類用JDK Proxy,對於無介面和抽象類用Cglib,雖然Cglib均可以代理,但是Cglib複雜,效率低。但是Cglib有例外,就是代理的類中不能是final修飾的類或者類中有final方法。

3、Spring、Struts2、Servlet對比

①Servlet原理:Tomcat 的容器等級中,Context 容器是直接管理 Servlet 在容器中的包裝類 Wrapper,所以 Context 容器如何執行將直接影響 Servlet 的工作方式。

A、Servlet生命週期詳解

Servlet的生命週期可以分為四個階段,即裝載類及建立例項階段、初始化階段、服務階段和例項銷燬階段。下面針對每個階段的程式設計任務及注意事項進行詳細的說明。

B、Servlet建立過程

在預設情況下Servlet例項是在第一個請求到來的時候建立,以後複用。一旦Servlet例項被建立,Web伺服器會自動呼叫init(ServletConfig config)方法來初始化該Servlet。其中方法引數config中包含了Servlet的配置資訊,比如初始化引數,該物件由伺服器建立。init方法在Servlet生命週期中只執行一次,而且該方法執行在單執行緒的環境下,因此開發者不用考慮執行緒安全的問題。

C、服務

一旦Servlet例項成功建立及初始化,該Servlet例項就可以被伺服器用來服務於客戶端的請求並生成響應。在服務階段Web伺服器會呼叫該例項的service(ServletRequest request,ServletResponse response)方法,request物件和response物件有伺服器建立並傳給Servlet例項。request物件封裝了客戶端發往伺服器端的資訊,response物件封裝了伺服器發往客戶端的資訊。

為了提高效率,Servlet規範要求一個Servlet例項必須能夠同時服務於多個客戶端請求,即service()方法執行在多執行緒的環境下,Servlet開發者必須保證該方法的執行緒安全性。

Serlvet介面只定義了一個服務方法就是service,而HttpServlet類實現了該方法並且要求呼叫下列的方法之一:

doGet:處理GET請求

doPost:處理POST請求

當發出客戶端請求的時候,呼叫service 方法並傳遞一個請求和響應物件。Servlet首先判斷該請求是GET 操作還是POST 操作。然後它呼叫下面的一個方法:doGet 或 doPost。如果請求是GET就呼叫doGet方法,如果請求是POST就呼叫doPost方法。

②對比:Spring主要有IoC和AOP,Spring中IoC管理的bean為單例模式的,可以配置成原型模式。如果用Spring管理struts2的bean,必須要設定成原型模式,因為struts2封裝來了servlet,隔離了servlet的特性,Action不同於Spring,已經是原型模式了。