後端開發面試題(持續更新,歡迎評論增長答案)
在面試的時候,我並不特別喜歡問一些技術性的問題。我更喜歡的方式是這樣的: 和麪試者坐在一塊兒,看一些實際的代碼,解決一些實際的問題。而且用一成天的時間,讓團隊全部成員輪流和麪試者進行結對編程。雖然如此,可是一些技術問題仍然能夠用來很好地啓動一段有深度的談話,可以讓面試者和麪試官相互都有更加深刻的瞭解。git
1、通用問題
- 語言設計中空引用(null reference)的存在有什麼問題?假設你想要將空引用的概念從你的首選語言中移除,可能致使什麼結果?
- 爲何函數式編程重要?何時適用函數式語言?
- 設計(design)、架構(architecture)、功能(functionality)和美學(aesthetic)之間有什麼區別?討論一下。
- 微軟、谷歌、歐朋(opera)和火狐這類公司是如何從他們的瀏覽器中獲利的?
- 爲何打開TCP套接字有很大的開銷?
- 封裝的重要性體如今哪兒?
- 什麼是實時系統?它與普通系統有什麼區別?
- 實時語言(real-time language)和堆內存分配(heap memory allocation)之間的關係是什麼?
- 不變性(Immutability)是指: (變量的)值只能在建立的時候被設置一次,以後就不能被改變。爲何不變性對寫更加安全的代碼有幫助?
- 可變值(mutable values)和不可變值(immutable values)有哪些優缺點?
- 什麼是O/R阻抗失衡(Object-Relational impedence mismatch)?
- 若是你須要使用緩存,你使用哪些原則來肯定緩存的大小?
- TCP和HTTP有什麼區別?
- 在客戶端渲染(client-side rendering)和服務端渲染(server-side rendering)之間,你是如何權衡的?
- 如何在一個不可靠的協議之上構建一個可靠的通訊協議?
2、開放式問題
- 爲何人們會抵制變化?
- 如何向你的祖母解釋什麼是線程?
- 做爲一個軟件工程師,你想要既要有創新力,又要產出具備可預測性。採用什麼策略才能使這兩個目標能夠共存呢?
- 什麼是好的代碼?
- 解釋什麼是流(Streaming)和如何實現一個流?
- 假設你的公司給你一週的時間,用來改善你和同事的生活: 你將如何使用這一週?
- 本週你學了什麼?
- 全部的設計中都會有美學元素(aesthetic element)的存在。問題是,你認爲美學元素是你的朋友仍是敵人?
- 列出最近你讀過的5本書。
- 假設目前有個大型公司(很是有錢),他們的開發流程是瀑布式流程(Waterfall),若是須要你在他們公司引入持續交付(Continue Devivery),你會怎麼作?
- 咱們來談談"重複造輪子","非我發明症", "吃本身作出來的狗糧"的這些作法吧。(注: 重複造輪子: Reinventing the wheel; 非我發明症:Not Invented Here Syndrome; 吃本身作出來的狗糧: Eating Your Own Dog Food)
- 在你當前的工做流中,什麼事情是你計劃下一步須要自動化的?
- 爲何寫軟件是困難的?是什麼使軟件的維護變得困難?
- 你更喜歡在全新項目(Green Field Project)上工做仍是在已有項目(Brown Field Project)基礎上工做?爲何?
- 當你在瀏覽器地址欄輸入google.com回車以後都發生了什麼?
- 當操做系統CPU處於空閒的時候,它可能在處理哪些事情?
- 如何向一個5歲的孩子解釋什麼是Unicode/數據庫事務?
- 如何維護單體架構(monolithic architecture)?
- 一個"專業的開發者"意味着什麼?
- 軟件開發是藝術、是技藝仍是工程?你的觀點是什麼?
"喜歡這個的人也喜歡...",如何在一個電子商務商店裏實現這種功能?
- 爲何在創新上,企業會比創業公司慢些?
- 爲何說,你不該該嘗試應用本身發明或者設計的密碼學?
3、設計模式相關問題
- 請用一個例子代表,全局對象是邪惡的存在。
- 假設你工做的系統不支持事務性,你會如何從頭開始實現它?
- 什麼是好萊塢原則(Hollywood Principles)?
- 關於迪米特法則(最少知識原則): 寫一段代碼違反它, 而後修復它。(注: 迪米特法則:the Law of Demeter, 最少知識原則: the Principle of Least Knowledge)
- Active-Record模式有什麼限制和缺陷?
- Data-Mapper模式和Active-Record模式有什麼區別?
- 空對象模式(Null Object Pattern)的目的是什麼?
- 爲何組合(Composition)比繼承(Inheritance)更好?
- 什麼是反腐敗層(Anti-corruption Layer)?
- 你能夠寫一個線程安全的單例(Singleton)類嗎?
- 數據抽象(Data Abstraction)能力是指能改變實現而不影響客戶端的這種能力。請構造一個一個例子,違反這個特性,而且嘗試修復它。
- 你是如何處理依賴關係地獄(Dependency Hell)的?
- 爲何說goto語句是惡魔般的存在?
- 健壯性是進行軟件設計時的一個通用原則,它建議 「發送時要保守,接收時要開放」。這也常常被寫成,「作一個有耐心的讀者,作一個謹慎的做者」。你能解釋一些這背後的邏輯嗎?
4、代碼設計相關問題
- 你在進行軟件設計時會考慮軟件測試嗎?軟件測試是如何影響軟件設計的?
- 內聚和耦合的區別是什麼?
- 重構在哪些場景下有用?
- 代碼中的註釋有用嗎?
- 設計和架構有什麼區別?
- 爲何在測試驅動開發(TDD)中是先寫測試,再寫代碼?
- C++支持多繼承,Java容許類實現多個接口。這些特性對正交性有什麼影響?使用多繼承和使用多接口有區別嗎?[這個問題來自Andrew .Hunt 和 David Thomas寫的《程序員修煉之道》]
- 在存儲過程(Stored Procedures)中寫業務邏輯有什麼優缺點?
5、語言相關問題
爲何"第一方cookie(first-party cookie)"和"第三方cookie(third-party cookie)"被如此不一樣的對待?web
6、數據庫相關問題
- 若是要你將一個項目從MySQL遷移至PostgreSQL中,你會如何遷移?
- 爲何SELECT * FROM table WHERE field = null不能匹配空的字段?
- 什麼是ACID(原子性,一致性,隔離性,持久性)原則?
- 你是如何進行數據庫模式(Database schema)遷移的?
- 延遲加載(lazy loading)是如何實現的?什麼場景下有用?他有什麼缺陷?
- 什麼是N+1問題?
- 如何找出應用中開銷最大的查詢?
7、非關係型數據庫相關問題
- 什麼是最終一致性(Eventual Consistency)?
- 關於CAP理論,舉一些CP、AP、CA系統的例子。
- NoSQL是如何解決可伸縮性的挑戰的?
- 什麼狀況下你會使用相似於MongoDB的文檔數據庫而不是關係型數據庫(如Mysql或者PostgreSQL)?
8、代碼版本管理相關問題
- 爲何在Mercurial或者git中(管理)分支比SVN容易?
- 分散式版本控制系統(好比git),相比集中式版本控制系統(如svn)有哪些優點和劣勢?(注:集中式版本控制系統: Centralized Version Control Systems;分散式版本控制系統: Distributed Version Control Systems)
- 能描述一下什麼是GitHubFlow和GitFlow工做流嗎?
- 什麼是rebase?
- 爲何合併操做(merge)在Mercurial和git中比在SVN和CVS中容易?
9、併發問題
- 爲何咱們須要併發呢?解釋一下。
- 爲何測試多線程/併發代碼這麼困難?
- 什麼是競爭條件(Race Condition)?用任何一個語言寫一個例子。
- 什麼是死鎖?用代碼解釋一下。
- 什麼是餓死?
- 什麼是Wait-Free算法?
10、分佈式系統相關問題
- 怎麼測試一個分佈式系統?
- 什麼場景下你會在兩個系統中採用異步通訊機制?
- 遠程過程調用的通用缺點是什麼?
- 若是你爲了可擴展性和魯棒性而構建一個分佈式的系統,分別在封閉安全的網絡環境狀況下,和地理上的位置不一樣可是網絡環境不是封閉和安全的狀況下,你會考慮什麼不一樣的事情?
- 在Web應用中如何管理容錯性?在桌面端呢?
- 在分佈式系統中,如何處理故障?
- 讓咱們來談談網絡分裂(network partitions)後有的幾種恢復的手段吧。
- 你認爲分佈式計算中有哪些謬論?
- 你在何時會使用Request/Response模式,何時使用Publish/Subscribe模式?
11、軟件生命週期和團隊管理相關問題
- 什麼是敏捷(Agility)?
- 你是如何處理遺留代碼(Legacy Code)的?
- 假設我是大家公司的CEO,請向我解釋什麼是看板,而且說服我在它上面投資。
- 敏捷(Agility)和瀑布(Waterfall)之間的最大區別是什麼?
- 做爲團隊管理者,你對會議太多這個問題是如何處理的?
- 你會如何處理延期很長時間了的項目?
- "個體與交互重於過程和工具"和"客戶協做重於合同談判"佔了敏捷宣言(Agile Manifesto)的一半,談論一下這兩個觀念。
- 若是你是大家公司的CTO,你會採起什麼樣的決策?
- 你以爲項目經理有用嗎?
- 若是要你組織一個彈性工做制的開發團隊(即沒有強制工做時間的要求),而且假期制度是"按需休假",你會如何作?
- 你會如何管理一我的員流動很是高的團隊?如何在不加薪的條件下說服團隊成員不要離開?
- 除了代碼以外,你最關注你的同事的哪3項素質?
- 關於代碼,你最但願非技術人員能知道的的三件事是什麼?
12、 邏輯和算法相關問題
- 只用LIFO棧如何構造一個FIFO隊列?只用FIFO隊列如何構造一個LIFO棧?
- 寫一段有棧溢出的代碼。
- 寫一個尾遞歸版本的階乘函數。
- 使用任何一個語言,寫一個REPL,功能是echo你輸入的字符串。而後將它演化成一個逆波蘭表達式的計算器。
- 若是須要你設計一個文件系統磁盤碎片整理程序,你會如何設計?
- 寫一個生成隨機迷宮的程序。
- 寫一段有內存泄漏的示例代碼。
- 隨機生成一個的數字序列,裏面每一個數字都不一樣。
- 寫一個簡單的垃圾回收系統。
- 使用任何一門語言,寫一個基本的消息代理。
- 寫一個基礎的web服務器,而後畫一張線路圖,展現你未來還想要實現的功能。
- 如何對一個10GB的文件進行排序?若是是10TB的數據,你會採用什麼方法?
- 請實現rnd()函數
十3、 軟件架構相關問題
- 什麼狀況下緩存是沒用的,甚至是危險的?
- 爲何事件驅動的架構能提升可擴展性(scalability)?
- 什麼樣的代碼是可讀性強的代碼?
- 緊急設計(Emergent Design)和演化架構(Evolutionary Architecture)之間的區別是什麼?
- 橫向擴展(scale out) vs 縱向擴展(scale up): 有什麼區別?分別在什麼場景下使用?
- 分佈式系統中如何處理"故障切換(failover)"和"用戶會話(user session)"?
- 什麼是CQRS(Command Query Responsibility Segregation)?他和最先的Command-Query Separation原則有什麼區別?
- 什麼是三層架構?
- 如何設計一個可擴展性高的系統?
- 處理C10k問題的策略有哪些?
- 若是讓你來設計一個去中心化的P2P系統,你會如何設計?
- 爲何CGI的擴展性很差?
- 在設計系統時,你如何防止供應商依賴(Vendor Lock-in)?
- 在可擴展性上,發佈/訂閱(Publish-Subscribe)模式有什麼缺點?
- 80年代之後,CPU有哪些變化?這些變化,對編程產生了什麼影響?
- 性能生命週期(performace lifecycle)中,你認爲哪一個部分是須要考慮進去的? 如何管理?
- 除了惡意攻擊形成的拒絕服務現象之外,哪些設計或者架構上的問題會致使拒絕服務?
- 性能和可擴展性之間有什麼關係?
- 何時緊耦合是OK的?
- 一個系統要有什麼特徵才能適配雲計算環境(Cloud Ready)?
- Does unity of design imply an aristocracy of architects?
十4、面向服務架構(SOA)和微服務(Microservice)相關問題
- 在SOA中,爲何長期存活的事務(Long-lived transation)不被看好,而Saga卻被看好?
- SOA和MicroService之間有什麼區別?
- 咱們來談談Web服務的版本管理、版本兼容性、重大變動管理這些事情吧.
- 在saga中事務和補償操做(compensation operation)之間的區別是什麼?在SOA中呢?
- 微服務不能作得太"微",你認爲何時候微服務太"微"了?
- MicroService架構的優劣是什麼?
十5、安全相關問題
- 什麼是雙因素認證(Two Factor Authentication)?在一個已有的Web應用中,你如何實現這種機制?
十6、比爾蓋茨式問題
- 若是你把一面鏡子放在掃描儀上,會發生什麼?
- 假設有一個和你徹底同樣的克隆人,而他是你的上司,你願意和他工做嗎?
- 如今請你面試一下我。
- 爲何Quora上的回答會比Yahoo Answer上的回答好?
- 對手是現代語言,你的任務是要爲Cobol辯護,你會如何進行?
- 10年後的你是什麼樣子?
- 假設你是我老闆,我被解僱了。你會如何通知我?
- 我想要重構一個系統,而你想要從頭重寫。咱們來爭論一下該怎麼弄吧。而後咱們反轉角色,再爭論一下。
- 老闆要你對公司撒謊,你的反應是什麼?
- 若是你能夠穿越到之前,你會給年輕時候的你什麼建議?
十6、代碼示例問題
function hookupevents() {
for (var i = 0; i < 3; i++) {
document.getElementById("button" + i)
.addEventListener("click", function() {
alert(i);
});
}
}
- 關於類型擦除(Type Erasure),這段Java代碼的輸出是什麼?爲何?
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
System.out.println("Equal");
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
- if語句,或者更加通用點,條件表達式一般是過程式編程/命令式編程的形式。你能去掉這段代碼中的switch語句,用面向對象的方式來修改這段代碼嗎?
public class Formatter {
private Service service;
public Formatter(Service service) {
this.service = service;
}
public String doTheJob(String theInput) {
String response = service.askForPermission();
switch (response) {
case "FAIL":
return "error";
case "OK":
return String.format("%s%s", theInput, theInput);
default:
return null;
}
}
}
public class TheService {
private final FileHandler fileHandler;
private final FooRepository fooRepository;
public TheService(FileHandler fileHandler, FooRepository fooRepository) {
this.fileHandler = fileHandler;
this.fooRepository = fooRepository;
}
public String Execute(final String file) {
final String rewrittenUrl = fileHandler.getXmlFileFromFileName(file);
final String executionId = fileHandler.getExecutionIdFromFileName(file);
if ((executionId == "") || (rewrittenUrl == "")) {
return "";
}
Foo knownFoo = fooRepository.getFooByXmlFileName(rewrittenUrl);
if (knownFoo == null) {
return "";
}
return knownFoo.DoThat(file);
}
}
function()
{
HRESULT error = S_OK;
if(SUCCEEDED(Operation1()))
{
if(SUCCEEDED(Operation2()))
{
if(SUCCEEDED(Operation3()))
{
if(SUCCEEDED(Operation4()))
{
}
else
{
error = OPERATION4FAILED;
}
}
else
{
error = OPERATION3FAILED;
}
}
else
{
error = OPERATION2FAILED;
}
}
else
{
error = OPERATION1FAILED;
}
return error;
}