朋友圈看到的,轉發一下。
1 java基礎:
1.1 算法
- 1.1 排序算法:直接插入排序、希爾排序、冒泡排序、快速排序、直接選擇排序、堆排序、歸並排序、基數排序
- 1.2 二叉查找樹、紅黑樹、B樹、B+樹、LSM樹(分別有對應的應用,數據庫、HBase)
- 1.3 BitSet解決數據重復和是否存在等問題
1.2 基本
- 2.1 字符串常量池的遷移
- 2.2 字符串KMP算法
- 2.3 equals和hashcode
- 2.4 泛型、異常、反射
- 2.5 string的hash算法
- 2.6 hash沖突的解決辦法:拉鏈法
- 2.7 foreach循環的原理
- 2.8 static、final、transient等關鍵字的作用
- 2.9 volatile關鍵字的底層實現原理
- 2.10 Collections.sort方法使用的是哪種排序方法
- 2.11 Future接口,常見的線程池中的FutureTask實現等
- 2.12 string的intern方法的內部細節,jdk1.6和jdk1.7的變化以及內部cpp代碼StringTable的實現
1.3 設計模式
- 單例模式
- 工廠模式
- 裝飾者模式
- 觀察者設計模式
- ThreadLocal設計模式
- 。。。
1.4 正則表達式
- 4.1 捕獲組和非捕獲組
- 4.2 貪婪,勉強,獨占模式
1.5 java內存模型以及垃圾回收算法
-
5.1 類加載機制,也就是雙親委派模型
-
5.2 Java內存分配模型(默認HotSpot)
線程共享的:堆區、永久區 線程獨享的:虛擬機棧、本地方法棧、程序計數器
-
5.3 內存分配機制:年輕代(Eden區、兩個Survivor區)、年老代、永久代以及他們的分配過程
-
5.4 強引用、軟引用、弱引用、虛引用與GC
-
5.5 happens-before規則
-
5.6 指令重排序、內存柵欄
-
5.7 Java 8的內存分代改進
-
5.8 垃圾回收算法:
標記-清除(不足之處:效率不高、內存碎片)
復制算法(解決了上述問題,但是內存只能使用一半,針對大部分對象存活時間短的場景,引出了一個默認的8:1:1的改進,缺點是仍然需要借助外界來解決可能承載不下的問題)
標記整理
-
5.8 常用垃圾收集器:
新生代:Serial收集器、ParNew收集器、Parallel Scavenge 收集器
老年代:Serial Old收集器、Parallel Old收集器、CMS(Concurrent Mark Sweep)收集器、 G1 收集器(跨新生代和老年代)
-
5.9 常用gc的參數:-Xmn、-Xms、-Xmx、-XX:MaxPermSize、-XX:SurvivorRatio、-XX:-PrintGCDetails
-
5.10 常用工具: jps、jstat、jmap、jstack、圖形工具jConsole、Visual VM、MAT
1.6 鎖以及並發容器的源碼
- 6.1 synchronized和volatile理解
- 6.2 Unsafe類的原理,使用它來實現CAS。因此誕生了AtomicInteger系列等
- 6.3 CAS可能產生的ABA問題的解決,如加入修改次數、版本號
- 6.4 同步器AQS的實現原理
- 6.5 獨占鎖、共享鎖;可重入的獨占鎖ReentrantLock、共享鎖 實現原理
- 6.6 公平鎖和非公平鎖
- 6.7 讀寫鎖 ReentrantReadWriteLock的實現原理
- 6.8 LockSupport工具
- 6.9 Condition接口及其實現原理
- 6.10 HashMap、HashSet、ArrayList、LinkedList、HashTable、ConcurrentHashMap、TreeMap的實現原理
- 6.11 HashMap的並發問題
- 6.12 ConcurrentLinkedQueue的實現原理
- 6.13 Fork/Join框架
- 6.14 CountDownLatch和CyclicBarrier
1.7 線程池源碼
- 7.1 內部執行原理
- 7.2 各種線程池的區別
2 web方面:
2.1 SpringMVC的架構設計
- 1.1 servlet開發存在的問題:映射問題、參數獲取問題、格式化轉換問題、返回值處理問題、視圖渲染問題
- 1.2 SpringMVC為解決上述問題開發的幾大組件及接口:HandlerMapping、HandlerAdapter、HandlerMethodArgumentResolver、HttpMessageConverter、Converter、GenericConverter、HandlerMethodReturnValueHandler、ViewResolver、MultipartResolver
- 1.3 DispatcherServlet、容器、組件三者之間的關系
- 1.4 敘述SpringMVC對請求的整體處理流程
- 1.5 SpringBoot
2.2 SpringAOP源碼
-
2.1 AOP的實現分類:編譯期、字節碼加載前、字節碼加載后三種時機來實現AOP
-
2.2 深刻理解其中的角色:AOP聯盟、aspectj、jboss AOP、spring自身實現的AOP、Spring嵌入aspectj。特別是能用代碼區分后兩者
-
2.3 接口設計:
AOP聯盟定義的概念或接口:Pointcut(概念,沒有定義對應的接口)、Joinpoint、Advice、MethodInterceptor、MethodInvocation
SpringAOP針對上述Advice接口定義的接口及其實現類:BeforeAdvice、AfterAdvice、MethodBeforeAdvice、AfterReturningAdvice;針對aspectj對上述接口的實現AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJAfterAdvice。
SpringAOP定義的定義的AdvisorAdapter接口:將上述Advise轉化為MethodInterceptor
SpringAOP定義的Pointcut接口:含有兩個屬性ClassFilter(過濾類)、MethodMatcher(過濾方法)
SpringAOP定義的ExpressionPointcut接口:實現中會引入aspectj的pointcut表達式
SpringAOP定義的PointcutAdvisor接口(將上述Advice接口和Pointcut接口結合起來)
-
2.4 SpringAOP的調用流程
-
2.5 SpringAOP自己的實現方式(代表人物ProxyFactoryBean)和借助aspectj實現方式區分
2.3 Spring事務體系源碼以及分布式事務Jotm Atomikos源碼實現
- 3.1 jdbc事務存在的問題
- 3.2 Hibernate對事務的改進
- 3.3 針對各種各樣的事務,Spring如何定義事務體系的接口,以及如何融合jdbc事務和Hibernate事務的
- 3.4 三種事務模型包含的角色以及各自的職責
- 3.5 事務代碼也業務代碼分離的實現(AOP+ThreadLocal來實現)
- 3.6 Spring事務攔截器TransactionInterceptor全景
- 3.7 X/Open DTP模型,兩階段提交,JTA接口定義
- 3.8 Jotm、Atomikos的實現原理
- 3.9 事務的傳播屬性
- 3.10 PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED的實現原理以及區別
- 3.11 事物的掛起和恢復的原理
2.4 數據庫隔離級別
- 4.1 Read uncommitted:讀未提交
- 4.2 Read committed : 讀已提交
- 4.3 Repeatable read:可重復讀
- 4.4 Serializable :串行化
2.5 數據庫
-
5.1 數據庫性能的優化
-
5.2 深入理解MySQL的Record Locks、Gap Locks、Next-Key Locks
例如下面的在什么情況下會出現死鎖:
start transaction; DELETE FROM t WHERE id =6; INSERT INTO t VALUES(6); commit;
-
5.3 insert into select語句的加鎖情況
-
5.4 事務的ACID特性概念
-
5.5 innodb的MVCC理解
-
5.6 undo redo binlog
- 1 undo redo 都可以實現持久化,他們的流程是什么?為什么選用redo來做持久化?
- 2 undo、redo結合起來實現原子性和持久化,為什么undo log要先於redo log持久化?
- 3 undo為什么要依賴redo?
- 4 日志內容可以是物理日志,也可以是邏輯日志?他們各自的優點和缺點是?
- 5 redo log最終采用的是物理日志加邏輯日志,物理到page,page內邏輯。還存在什么問題?怎么解決?Double Write
- 6 undo log為什么不采用物理日志而采用邏輯日志?
- 7 為什么要引入Checkpoint?
- 8 引入Checkpoint后為了保證一致性需要阻塞用戶操作一段時間,怎么解決這個問題?(這個問題還是很有普遍性的,redis、ZooKeeper都有類似的情況以及不同的應對策略)又有了同步Checkpoint和異步Checkpoint
- 9 開啟binlog的情況下,事務內部2PC的一般過程(含有2次持久化,redo log和binlog的持久化)
- 10 解釋上述過程,為什么binlog的持久化要在redo log之后,在存儲引擎commit之前?
- 11 為什么要保持事務之間寫入binlog和執行存儲引擎commit操作的順序性?(即先寫入binlog日志的事務一定先commit)
- 12 為了保證上述順序性,之前的辦法是加鎖prepare_commit_mutex,但是這極大的降低了事務的效率,怎么來實現binlog的group commit?
- 13 怎么將redo log的持久化也實現group commit?至此事務內部2PC的過程,2次持久化的操作都可以group commit了,極大提高了效率
2.6 ORM框架: mybatis、Hibernate
- 6.1 最原始的jdbc->Spring的JdbcTemplate->hibernate->JPA->SpringDataJPA的演進之路
2.7 SpringSecurity、shiro、SSO(單點登錄)
- 7.1 Session和Cookie的區別和聯系以及Session的實現原理
- 7.2 SpringSecurity的認證過程以及與Session的關系
- 7.3 CAS實現SSO(詳見Cas(01)——簡介)
2.8 日志
- 8.1 jdk自帶的logging、log4j、log4j2、logback
- 8.2 門面commons-logging、slf4j
- 8.3 上述6種混戰時的日志轉換
2.9 datasource
- 9.1 c3p0
- 9.2 druid
- 9.3 JdbcTemplate執行sql語句的過程中對Connection的使用和管理
2.10 HTTPS的實現原理
3 分布式、java中間件、web服務器等方面:
3.1 ZooKeeper源碼
- 1.1 客戶端架構
- 1.2 服務器端單機版和集群版,對應的請求處理器
- 1.3 集群版session的建立和激活過程
- 1.4 Leader選舉過程
- 1.5 事務日志和快照文件的詳細解析
- 1.6 實現分布式鎖、分布式ID分發器
- 1.7 實現Leader選舉
- 1.8 ZAB協議實現一致性原理
3.2 序列化和反序列化框架
- 2.1 Avro研究
- 2.2 Thrift研究
- 2.3 Protobuf研究
- 2.4 Protostuff研究
- 2.5 Hessian
3.3 RPC框架dubbo源碼
- 3.1 dubbo擴展機制的實現,對比SPI機制
- 3.2 服務的發布過程
- 3.3 服務的訂閱過程
- 3.4 RPC通信的設計
3.4 NIO模塊以及對應的Netty和Mina、thrift源碼
- 4.1 TCP握手和斷開及有限狀態機
- 4.2 backlog
- 4.3 BIO NIO
- 4.4 阻塞/非阻塞的區別、同步/異步的區別
- 4.5 阻塞IO、非阻塞IO、多路復用IO、異步IO
- 4.6 Reactor線程模型
- 4.7 jdk的poll、epoll與底層poll、epoll的對接實現
- 4.8 Netty自己的epoll實現
- 4.9 內核層poll、epoll的大致實現
- 4.10 epoll的邊緣觸發和水平觸發
- 4.11 Netty的EventLoopGroup設計
- 4.12 Netty的ByteBuf設計
- 4.13 Netty的ChannelHandler
- 4.13 Netty的零拷貝
- 4.14 Netty的線程模型,特別是與業務線程以及資源釋放方面的理解
3.5 消息隊列kafka、RocketMQ、Notify、Hermes
- 5.1 kafka的文件存儲設計
- 5.2 kafka的副本復制過程
- 5.3 kafka副本的leader選舉過程
- 5.4 kafka的消息丟失問題
- 5.5 kafka的消息順序性問題
- 5.6 kafka的isr設計和過半對比
- 5.7 kafka本身做的很輕量級來保持高效,很多高級特性沒有:事務、優先級的消息、消息的過濾,更重要的是服務治理不健全,一旦出問題,不能直觀反應出來,不太適合對數據要求十分嚴苛的企業級系統,而適合日志之類並發量大但是允許少量的丟失或重復等場景
- 5.8 Notify、RocketMQ的事務設計
- 5.9 基於文件的kafka、RocketMQ和基於數據庫的Notify和Hermes
- 5.10 設計一個消息系統要考慮哪些方面
- 5.11 丟失消息、消息重復、高可用等話題
3.6 數據庫的分庫分表mycat
3.7 NoSql數據庫mongodb
3.8 KV鍵值系統memcached redis
- 8.1 redis對客戶端的維護和管理,讀寫緩沖區
- 8.2 redis事務的實現
- 8.3 Jedis客戶端的實現
- 8.4 JedisPool以及ShardedJedisPool的實現
- 8.5 redis epoll實現,循環中的文件事件和時間事件
- 8.6 redis的RDB持久化,save和bgsave
- 8.7 redis AOF命令追加、文件寫入、文件同步到磁盤
- 8.8 redis AOF重寫,為了減少阻塞時間采取的措施
- 8.9 redis的LRU內存回收算法
- 8.10 redis的master slave復制
- 8.11 redis的sentinel高可用方案
- 8.12 redis的cluster分片方案
3.9 web服務器tomcat、ngnix的設計原理
- 9.1 tomcat的整體架構設計
- 9.2 tomcat對通信的並發控制
- 9.3 http請求到達tomcat的整個處理流程
3.10 ELK日志實時處理查詢系統
- 10.1 Elasticsearch、Logstash、Kibana
3.11 服務方面
- 11.1 SOA與微服務
- 11.2 服務的合並部署、多版本自動快速切換和回滾
- 11.3 服務的治理:限流、降級
具體見 張開濤大神的架構系列
服務限流:令牌桶、漏桶
服務降級、服務的熔斷、服務的隔離:netflix的hystrix組件
-
11.4 服務的線性擴展
無狀態的服務如何做線性擴展:
如一般的web應用,直接使用硬件或者軟件做負載均衡,簡單的輪訓機制
有狀態服務如何做線性擴展:
如Redis的擴展:一致性hash,遷移工具
-
11.5 服務鏈路監控和報警:CAT、Dapper、Pinpoint
3.12 Spring Cloud
- 12.1 Spring Cloud Zookeeper:用於服務注冊和發現
- 12.2 Spring Cloud Config:分布式配置
- 12.2 Spring Cloud Netflix Eureka:用於rest服務的注冊和發現
- 12.3 Spring Cloud Netflix Hystrix:服務的隔離、熔斷和降級
- 12.4 Spring Cloud Netflix Zuul:動態路由,API Gateway
3.13 分布式事務
- 13.1 JTA分布式事務接口定義,對此與Spring事務體系的整合
- 13.2 TCC分布式事務概念
- 13.3 TCC分布式事務實現框架案例1:tcc-transaction
- 13.3.1 TccCompensableAspect切面攔截創建ROOT事務
- 13.3.2 TccTransactionContextAspect切面使遠程RPC調用資源加入到上述事務中,作為一個參與者
- 13.3.3 TccCompensableAspect切面根據遠程RPC傳遞的TransactionContext的標記創建出分支事務
- 13.3.4 全部RPC調用完畢,ROOT事務開始提交或者回滾,執行所有參與者的提交或回滾
- 13.3.5 所有參與者的提交或者回滾,還是通過遠程RPC調用,provider端開始執行對應分支事務的confirm或者cancel方法
- 13.3.6 事務的存儲,集群共享問題13.3.7 事務的恢復,避免集群重復恢復
- 13.4 TCC分布式事務實現框架案例2:ByteTCC
- 13.4.1 JTA事務管理實現,類比Jotm、Atomikos等JTA實現
- 13.4.2 事務的存儲和恢復,集群是否共享問題調用方創建CompensableTransaction事務,並加入資源
- 13.4.3 CompensableMethodInterceptor攔截器向spring事務注入CompensableInvocation資源
- 13.4.4 Spring的分布式事務管理器創建作為協調者CompensableTransaction類型事務,和當前線程進行綁定,同時創建一個jta事務
- 13.4.5 在執行sql等操作的時候,所使用的jdbc等XAResource資源加入上述jta事務
- 13.4.6 dubbo RPC遠程調用前,CompensableDubboServiceFilter創建出一個代理XAResource,加入上述 CompensableTransaction類型事務,並在RPC調用過程傳遞TransactionContext參與方創建分支的CompensableTransaction事務,並加入資源,然后提交jta事務
- 13.4.7 RPC遠程調用來到provider端,CompensableDubboServiceFilter根據傳遞過來的TransactionContext創建出對應的CompensableTransaction類型事務
- 13.4.8 provider端,執行時遇見@Transactional和@Compensable,作為一個參與者開啟try階段的事務,即創建了一個jta事務
- 13.4.9 provider端try執行完畢開始准備try的提交,僅僅是提交上述jta事務,返回結果到RPC調用端調用方決定回滾還是提交
- 13.4.10 全部執行完畢后開始事務的提交或者回滾,如果是提交則先對jta事務進行提交(包含jdbc等XAResource資源的提交),提交成功后再對CompensableTransaction類型事務進行提交,如果jta事務提交失敗,則需要回滾CompensableTransaction類型事務。
- 13.4.11 CompensableTransaction類型事務的提交就是對CompensableInvocation資源和RPC資源的提交,分別調用每一個CompensableInvocation資源的confirm,以及每一個RPC資源的提交CompensableInvocation資源的提交
- 13.4.12 此時每一個CompensableInvocation資源的confirm又會准備開啟一個新的事務,當前線程的CompensableTransaction類型事務已存在,所以這里開啟事務僅僅是創建了一個新的jta事務而已
- 13.4.13 針對此,每一個CompensableInvocation資源的confirm開啟的事務,又開始重復上述過程,對於jdbc等資源都加入新創建的jta事務中,而RPC資源和CompensableInvocation資源仍然加入到當前線程綁定的CompensableTransaction類型事務
- 13.4.14 當前CompensableInvocation資源的confirm開啟的事務執行完畢后,開始執行commit,此時仍然是執行jta事務的提交,提交完畢,一個CompensableInvocation資源的confirm完成,繼續執行下一個CompensableInvocation資源的confirm,即又要重新開啟一個新的jta事務RPC資源的提交(參與方CompensableTransaction事務的提交)
- 13.4.15 當所有CompensableInvocation資源的confirm執行完畢,開始執行RPC資源的commit,會進行遠程調用,執行遠程provider分支事務的提交,遠程調用過程會傳遞事務id
- 13.4.16 provider端,根據傳遞過來的事務id找到對應的CompensableTransaction事務,開始執行提交操作,提交操作完成后返回響應結束
- 13.4.17 協調者收到響應后繼續執行下一個RPC資源的提交,當所有RPC資源也完成相應的提交,則協調者算是徹底完成該事務
3.14 一致性算法
-
14.1 raft(詳見Raft算法賞析)
- 14.1.1 leader選舉過程,leader選舉約束,要包含所有commited entries,實現上log比過半的log都最新即可
- 14.1.2 log復制過程,leader給所有的follower發送AppendEntries RPC請求,過半follower回復ok,則可提交該entry,然后向客戶端響應OK
- 14.1.3 在上述leader收到過半復制之后,掛了,則后續leader不能直接對這些之前term的過半entry進行提交(這一部分有詳細的案例來證明,並能說出根本原因),目前做法是在當前term中創建空的entry,然后如果這些新創建的entry被大部分復制了,則此時就可以對之前term的過半entry進行提交了
- 14.1.4 leader一旦認為某個term可以提交了,則更新自己的commitIndex,同時應用entry到狀態機中,然后在下一次與follower的heartbeat通信中,將leader的commitIndex帶給follower,讓他們進行更新,同時應用entry到他們的狀態機中
- 14.1.5 從上述流程可以看到,作為client來說,可能會出現這樣的情況:leader認為某次client的請求可以提交了(對應的entry已經被過半復制了),此時leader掛了,還沒來得及給client回復,也就是說對client來說,請求雖然失敗了,但是請求對應的entry卻被持久化保存了,但是有的時候卻是請求失敗了(過半都沒復制成功)沒有持久化成功,也就是說請求失敗了,服務器端可能成功了也可能失敗了。所以這時候需要在client端下功夫,即cleint端重試的時候仍然使用之前的請求數據進行重試,而不是采用新的數據進行重試,服務器端也必須要實現冪等。
- 14.1.6 Cluster membership changes
-
14.2 ZooKeeper使用的ZAB協議(詳見ZooKeeper的一致性算法賞析)
- 14.2.1 leader選舉過程。要點:對於不同狀態下的server的投票的收集,投票是需要選舉出一個包含所有日志的server來作為leader
- 14.2.2 leader和follower數據同步過程,全量同步、差異同步、日志之間的糾正和截斷,來保證和leader之間的一致性。以及follower加入已經完成選舉的系統,此時的同步的要點:阻塞leader處理寫請求,完成日志之間的差異同步,還要處理現有進行中的請求的同步,完成同步后,解除阻塞。
- 14.2.3 廣播階段,即正常處理客戶端的請求,過半響應即可回復客戶端。
- 14.2.4 日志的恢復和持久化。持久化:每隔一定數量的事務日志持久化一次,leader選舉前持久化一次。恢復:簡單的認為已寫入日志的的事務請求都算作已提交的請求(不管之前是否已過半復制),全部執行commit提交。具體的恢復是:先恢復快照日志,然后再應用相應的事務日志
-
14.3 paxos(詳見paxos算法證明過程)
-
14.3.1 paxos的運作過程:
Phase 1: (a) 一個proposer選擇一個編號為n的議案,向所有的acceptor發送prepare請求
Phase 1: (b) 如果acceptor已經響應的prepare請求中議案編號都比n小,則它承諾不再響應prepare請求或者accept請求中議案編號小於n的, 並且找出已經accept的最大議案的value返回給該proposer。如果已響應的編號比n大,則直接忽略該prepare請求。
Phase 2:(a) 如果proposer收到了過半的acceptors響應,那么將提出一個議案(n,v),v就是上述所有acceptor響應中最大accept議案的value,或者是proposer自己的value。然后將該議案發送給所有的acceptor。這個請求叫做accept請求,這一步才是所謂發送議案請求,而前面的prepare請求更多的是一個構建出最終議案(n,v)的過程。
Phase 2:(b) acceptor接收到編號為n的議案,如果acceptor還沒有對大於n的議案的prepare請求響應過,則acceptor就accept該議案,否則拒絕
-
14.3.2 paxos的證明過程:
1 足夠多的問題
2 acceptor的初始accept
3 P2-對結果要求
4 P2a-對acceptor的accept要求
5 P2b-對proposer提出議案的要求(結果上要求)
6 P2c-對proposer提出議案的要求(做法上要求)
7 引出prepare過程和P1a
8 8 優化prepare
-
14.3.3 base paxos和multi-paxos
-
4 大數據方向
4.1 Hadoop
- 1.1 UserGroupInformation源碼解讀:JAAS認證、user和group關系的維護
- 1.2 RPC通信的實現
- 1.3 代理用戶的過程
- 1.4 kerberos認證
4.2 MapReduce
- 2.1 MapReduce理論及其對應的接口定義
4.3 HDFS
- 3.1 MapFile、SequenceFile
- 3.2 ACL
4.4 YARN、Mesos 資源調度
4.5 oozie
- 5.1 oozie XCommand設計
- 5.2 DagEngine的實現原理
4.6 Hive
- 6.1 HiveServer2、metatore的thrift RPC通信設計
- 6.2 Hive的優化過程
- 6.3 HiveServer2的認證和授權
- 6.4 metastore的認證和授權
- 6.5 HiveServer2向metatore的用戶傳遞過程
4.7 Hbase
- 7.1 Hbase的整體架構圖
- 7.2 Hbase的WAL和MVCC設計
- 7.3 client端的異步批量flush尋找RegionServer的過程
- 7.4 Zookeeper上HBase節點解釋
- 7.5 Hbase中的mini、major合並
- 7.6 Region的高可用問題對比kafka分區的高可用實現
- 7.7 RegionServer RPC調用的隔離問題
- 7.8 數據從內存刷寫到HDFS的粒度問題
- 7.9 rowKey的設計
- 7.10 MemStore與LSM