面試:第十五章:螞蟻金服面試以及答案

一面

1、自我介紹、自己做的項(xiàng)目和技術(shù)領(lǐng)域

開放題

2、項(xiàng)目中的監(jiān)控:那個(gè)監(jiān)控指標(biāo)常見的有哪些?

答:CPU、內(nèi)存、IO 等等。建議下載個(gè)nmon工具,里面有各個(gè)指標(biāo)。

數(shù)據(jù)庫(kù):Mysql(緩存命中、索引、單條SQL性能、數(shù)據(jù)庫(kù)線程數(shù)、數(shù)據(jù)池連接數(shù))

中間件:1.消息2、負(fù)載均衡3、緩存(包括線程數(shù)、連接數(shù)、日志)。

網(wǎng)絡(luò): 吞吐量、吞吐率

應(yīng)用: jvm內(nèi)存、日志、Full GC頻率

3、微服務(wù)涉及到的技術(shù)以及需要注意的問題有哪些?

4、注冊(cè)中心你了解了哪些?

答:Consul 、Eureka、ZooKeeper

5、consul 的可靠性你了解嗎?

6、consul 的機(jī)制你有沒有具體深入過?有沒有和其他的注冊(cè)中心對(duì)比過?

7、項(xiàng)目用 Spring 比較多,有沒有了解 Spring 的原理?AOP 和 IOC 的原理

答:(1). IoC(Inversion of Control)是指容器控制程序?qū)ο笾g的關(guān)系,而不是傳統(tǒng)實(shí)現(xiàn)中,由程序代碼直接操控。控制權(quán)由應(yīng)用代碼中轉(zhuǎn)到了外部容器,控制權(quán)的轉(zhuǎn)移是所謂反轉(zhuǎn)。 對(duì)于Spring而言,就是由Spring來(lái)控制對(duì)象的生命周期和對(duì)象之間的關(guān)系;IoC還有另外一個(gè)名字——“依賴注入(Dependency Injection)”。從名字上理解,所謂依賴注入,即組件之間的依賴關(guān)系由容器在運(yùn)行期決定,即由容器動(dòng)態(tài)地將某種依賴關(guān)系注入到組件之中。  

(2). 在Spring的工作方式中,所有的類都會(huì)在spring容器中登記,告訴spring這是個(gè)什么東西,你需要什么東西,然后spring會(huì)在系統(tǒng)運(yùn)行到適當(dāng)?shù)臅r(shí)候,把你要的東西主動(dòng)給你,同時(shí)也把你交給其他需要你的東西。所有的類的創(chuàng)建、銷毀都由 spring來(lái)控制,也就是說控制對(duì)象生存周期的不再是引用它的對(duì)象,而是spring。對(duì)于某個(gè)具體的對(duì)象而言,以前是它控制其他對(duì)象,現(xiàn)在是所有對(duì)象都被spring控制,所以這叫控制反轉(zhuǎn)。

(3). 在系統(tǒng)運(yùn)行中,動(dòng)態(tài)的向某個(gè)對(duì)象提供它所需要的其他對(duì)象。  

(4). 依賴注入的思想是通過反射機(jī)制實(shí)現(xiàn)的,在實(shí)例化一個(gè)類時(shí),它通過反射調(diào)用類中set方法將事先保存在HashMap中的類屬性注入到類中。 總而言之,在傳統(tǒng)的對(duì)象創(chuàng)建方式中,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例,而在Spring中創(chuàng)建被調(diào)用者的工作由Spring來(lái)完成,然后注入調(diào)用者,即所謂的依賴注入or控制反轉(zhuǎn)。 注入方式有兩種:依賴注入和設(shè)置注入; IoC的優(yōu)點(diǎn):降低了組件之間的耦合,降低了業(yè)務(wù)對(duì)象之間替換的復(fù)雜性,使之能夠靈活的管理對(duì)象。

AOP(Aspect Oriented Programming)

(1). AOP面向方面編程基于IoC,是對(duì)OOP的有益補(bǔ)充;

(2). AOP利用一種稱為“橫切”的技術(shù),剖解開封裝的對(duì)象內(nèi)部,并將那些影響了 多個(gè)類的公共行為封裝到一個(gè)可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡(jiǎn)單地說,就是將那些與業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的 邏輯或責(zé)任封裝起來(lái),比如日志記錄,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可操作性和可維護(hù)性。

(3). AOP代表的是一個(gè)橫向的關(guān) 系,將“對(duì)象”比作一個(gè)空心的圓柱體,其中封裝的是對(duì)象的屬性和行為;則面向方面編程的方法,就是將這個(gè)圓柱體以切面形式剖開,選擇性的提供業(yè)務(wù)邏輯。而 剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復(fù)原,不留痕跡,但完成了效果。

(4). 實(shí)現(xiàn)AOP的技術(shù),主要分為兩大類:一是采用動(dòng)態(tài)代理技術(shù),利用截取消息的方式,對(duì)該消息進(jìn)行裝飾,以取代原有對(duì)象行為的執(zhí)行;二是采用靜態(tài)織入的方式,引入特定的語(yǔ)法創(chuàng)建“方面”,從而使得編譯器可以在編譯期間織入有關(guān)“方面”的代碼。

(5). Spring實(shí)現(xiàn)AOP:JDK動(dòng)態(tài)代理和CGLIB代理 JDK動(dòng)態(tài)代理:其代理對(duì)象必須是某個(gè)接口的實(shí)現(xiàn),它是通過在運(yùn)行期間創(chuàng)建一個(gè)接口的實(shí)現(xiàn)類來(lái)完成對(duì)目標(biāo)對(duì)象的代理;其核心的兩個(gè)類是InvocationHandler和Proxy。 CGLIB代理:實(shí)現(xiàn)原理類似于JDK動(dòng)態(tài)代理,只是它在運(yùn)行期間生成的代理對(duì)象是針對(duì)目標(biāo)類擴(kuò)展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節(jié)碼編輯類庫(kù))操作字節(jié)碼實(shí)現(xiàn)的,性能比JDK強(qiáng);需要引入包asm.jar和cglib.jar。   使用AspectJ注入式切面和@AspectJ注解驅(qū)動(dòng)的切面實(shí)際上底層也是通過動(dòng)態(tài)代理實(shí)現(xiàn)的。

(6). AOP使用場(chǎng)景:           

Authentication 權(quán)限檢查     

Caching 緩存     

Context passing 內(nèi)容傳遞     

Error handling 錯(cuò)誤處理     

Lazy loading 延遲加載     

Debugging 調(diào)試    

logging, tracing, profiling and monitoring 日志記錄,跟蹤,優(yōu)化,校準(zhǔn)     

Performance optimization 性能優(yōu)化,效率檢查     

Persistence 持久化     

Resource pooling 資源池     

Synchronization 同步     

Transactions 事務(wù)管理   

另外Filter的實(shí)現(xiàn)和struts2的攔截器的實(shí)現(xiàn)都是AOP思想的體現(xiàn)。

8、Spring Boot除了自動(dòng)配置,相比傳統(tǒng)的 Spring 有什么其他的區(qū)別?

為Spring 生態(tài)系統(tǒng)的開發(fā)提供一種更簡(jiǎn)潔的方式,提供了很多非功能性特性,例如:嵌入式 Server,Security,統(tǒng)計(jì),健康檢查,外部配置等等,主要體現(xiàn)在以下幾點(diǎn):

1.Spring Boot可以建立獨(dú)立的Spring應(yīng)用程序;

2.內(nèi)嵌了如Tomcat,Jetty和Undertow這樣的容器,也就是說可以直接跑起來(lái),用不著再做部署工作了;

3.無(wú)需再像Spring那樣搞一堆繁瑣的xml文件的配置;

4.可以自動(dòng)配置Spring。SpringBoot將原有的XML配置改為Java配置,將bean注入改為使用注解注入的方式(@Autowire),并將多個(gè)xml、properties配置濃縮在一個(gè)appliaction.yml配置文件中。

5.提供了一些現(xiàn)有的功能,如量度工具,表單數(shù)據(jù)驗(yàn)證以及一些外部配置這樣的一些第三方功能;

6.整合常用依賴(開發(fā)庫(kù),例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM可以簡(jiǎn)化Maven的配置。當(dāng)我們引入核心依賴時(shí),SpringBoot會(huì)自引入其他依賴。

9、Spring Cloud 有了解多少?

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發(fā)便利性巧妙地簡(jiǎn)化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊(cè)、配置中心、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動(dòng)和部署。Spring Cloud并沒有重復(fù)制造輪子,它只是將目前各家公司開發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的服務(wù)框架組合起來(lái),通過Spring Boot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開發(fā)者留出了一套簡(jiǎn)單易懂、易部署和易維護(hù)的分布式系統(tǒng)開發(fā)工具包。

10、Spring Bean 的生命周期

一個(gè)Bean從創(chuàng)建到銷毀,如果是用BeanFactory來(lái)生成,管理Bean的話

Spring上下文中的Bean也類似,如下

  1、實(shí)例化一個(gè)Bean--也就是我們常說的new;

  2、按照Spring上下文對(duì)實(shí)例化的Bean進(jìn)行配置--也就是IOC注入;

  3、如果這個(gè)Bean已經(jīng)實(shí)現(xiàn)了BeanNameAware接口,會(huì)調(diào)用它實(shí)現(xiàn)的setBeanName(String)方法,此處傳遞的就是Spring配置文件中Bean的id值

  4、如果這個(gè)Bean已經(jīng)實(shí)現(xiàn)了BeanFactoryAware接口,會(huì)調(diào)用它實(shí)現(xiàn)的setBeanFactory(setBeanFactory(BeanFactory)傳遞的是Spring工廠自身(可以用這個(gè)方式來(lái)獲取其它Bean,只需在Spring配置文件中配置一個(gè)普通的Bean就可以);

  5、如果這個(gè)Bean已經(jīng)實(shí)現(xiàn)了ApplicationContextAware接口,會(huì)調(diào)用setApplicationContext(ApplicationContext)方法,傳入Spring上下文(同樣這個(gè)方式也可以實(shí)現(xiàn)步驟4的內(nèi)容,但比4更好,因?yàn)锳pplicationContext是BeanFactory的子接口,有更多的實(shí)現(xiàn)方法);

  6、如果這個(gè)Bean關(guān)聯(lián)了BeanPostProcessor接口,將會(huì)調(diào)用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor經(jīng)常被用作是Bean內(nèi)容的更改,并且由于這個(gè)是在Bean初始化結(jié)束時(shí)調(diào)用那個(gè)的方法,也可以被應(yīng)用于內(nèi)存或緩存技術(shù);

  7、如果Bean在Spring配置文件中配置了init-method屬性會(huì)自動(dòng)調(diào)用其配置的初始化方法。

  8、如果這個(gè)Bean關(guān)聯(lián)了BeanPostProcessor接口,將會(huì)調(diào)用postProcessAfterInitialization(Object obj, String s)方法、;

  注:以上工作完成以后就可以應(yīng)用這個(gè)Bean了,那這個(gè)Bean是一個(gè)Singleton的,所以一般情況下我們調(diào)用同一個(gè)id的Bean會(huì)是在內(nèi)容地址相同的實(shí)例,當(dāng)然在Spring配置文件中也可以配置非Singleton,這里我們不做贅述。

  9、當(dāng)Bean不再需要時(shí),會(huì)經(jīng)過清理階段,如果Bean實(shí)現(xiàn)了DisposableBean這個(gè)接口,會(huì)調(diào)用那個(gè)其實(shí)現(xiàn)的destroy()方法;

  10、最后,如果這個(gè)Bean的Spring配置中配置了destroy-method屬性,會(huì)自動(dòng)調(diào)用其配置的銷毀方法。

另外我們這里描述的是應(yīng)用Spring上下文Bean的生命周期,如果應(yīng)用Spring的工廠也就是BeanFactory的話去掉第5步就Ok了

11、HashMap 和 hashTable 區(qū)別?

區(qū)別:Hashtable是線程安全的,效率比較低

Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的注釋中有說明

Hashtable默認(rèn)的初始大小為11,之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的2n+1。

HashMap默認(rèn)的初始化大小為16。之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的2倍

Hashtable在計(jì)算元素的位置時(shí)需要進(jìn)行一次除法運(yùn)算,而除法運(yùn)算是比較耗時(shí)的

HashMap為了提高計(jì)算效率,將哈希表的大小固定為了2的冪,這樣在取模預(yù)算時(shí),不需要做除法,只需要做位運(yùn)算。位運(yùn)算比除法的效率要高很多。

HashMap是繼承自AbstractMap類,而HashTable是繼承自Dictionary類。不過它們都實(shí)現(xiàn)了同時(shí)實(shí)現(xiàn)了map、Cloneable(可復(fù)制)、Serializable(可序列化)這三個(gè)接口

12、Object 的 hashcode 方法重寫了,equals 方法要不要改?

不需要,Ojbect類中有兩個(gè)方法equals、hashCode,這兩個(gè)方法都是用來(lái)比較兩個(gè)對(duì)象是否相等的,如果兩個(gè)對(duì)象相等(equal),那么必須擁有相同 的哈希碼(hash code)

即使兩個(gè)對(duì)象有相同的哈希值(hash code),他們不一定相等

重寫equals()方法就必須重寫hashCode(),但重寫hashcode方法不一定要重寫equals方法

13、Hashmap 線程不安全的出現(xiàn)場(chǎng)景

用ConcurrentHashMap 線程安全

多線程處理時(shí)hashmap線程不安全

首先hashmap里這個(gè)size沒有用volatile關(guān)鍵字修飾,代表這不是一個(gè)內(nèi)存可見的變量,線程操作數(shù)據(jù)的時(shí)候一般是從主存拷貝一個(gè)變量副本進(jìn)行操作,操作完成過后在把size的值寫回到主存size的

線程不安全問題應(yīng)該屬于并發(fā)問題之一的,屬于相對(duì)高級(jí)的問題了。這個(gè)時(shí)候的問題已經(jīng)不僅僅局限于代碼層面了,很多時(shí)候需要結(jié)合JVM一起分析了

14、線上服務(wù) CPU 很高該怎么做?有哪些措施可以找到問題

定位出現(xiàn)問題的堆棧信息排查具體問題

1、top命令:Linux命令??梢圆榭磳?shí)時(shí)的CPU使用情況。也可以查看最近一段時(shí)間的CPU使用情況。

2、ps命令: Linux命令。強(qiáng)大的進(jìn)程狀態(tài)監(jiān)控命令??梢圆榭催M(jìn)程以及進(jìn)程中線程的當(dāng)前CPU使用情況。屬于當(dāng)前狀態(tài)的采樣數(shù)據(jù)。

3、jstack: Java提供的命令。可以查看某個(gè)進(jìn)程的當(dāng)前線程棧運(yùn)行情況。根據(jù)這個(gè)命令的輸出可以定位某個(gè)進(jìn)程的所有線程的當(dāng)前運(yùn)行狀態(tài)、運(yùn)行代碼,以及是否死鎖等等。

4、pstack:Linux命令??梢圆榭茨硞€(gè)進(jìn)程的當(dāng)前線程棧運(yùn)行情況

 15、JDK 中有哪幾個(gè)線程池?順帶把線程池講了個(gè)遍

JUC提供了調(diào)度器對(duì)象Executors來(lái)創(chuàng)建線程池,可創(chuàng)建的線程池有四種

1、newFixedThreadPool創(chuàng)建一個(gè)指定工作線程數(shù)量的線程池。每當(dāng)提交一個(gè)任務(wù)就創(chuàng)建一個(gè)工作線程,如果工作線程數(shù)量達(dá)到線程池初始的最大數(shù),則將提交的任務(wù)存入到池隊(duì)列中。

2、newCachedThreadPool創(chuàng)建一個(gè)可緩存的線程池。這種類型的線程池特點(diǎn)是:

1).工作線程的創(chuàng)建數(shù)量幾乎沒有限制(其實(shí)也有限制的,數(shù)目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程。

2).如果長(zhǎng)時(shí)間沒有往線程池中提交任務(wù),即如果工作線程空閑了指定的時(shí)間(默認(rèn)為1分鐘),則該工作線程將自動(dòng)終止。終止后,如果你又提交了新的任務(wù),則線程池重新創(chuàng)建一個(gè)工作線程。

3、newSingleThreadExecutor創(chuàng)建一個(gè)單線程化的Executor,即只創(chuàng)建唯一的工作者線程來(lái)執(zhí)行任務(wù),如果這個(gè)線程異常結(jié)束,會(huì)有另一個(gè)取代它,保證順序執(zhí)行(我覺得這點(diǎn)是它的特色)。單工作線程最大的特點(diǎn)是可保證順序地執(zhí)行各個(gè)任務(wù),并且在任意給定的時(shí)間不會(huì)有多個(gè)線程是活動(dòng)的 。

4、newScheduleThreadPool創(chuàng)建一個(gè)定長(zhǎng)的線程池,而且支持定時(shí)的以及周期性的任務(wù)執(zhí)行,類似于Timer。(這種線程池原理暫還沒完全了解透徹)

16、SQL 優(yōu)化的常見方法有哪些

查詢條件減少使用函數(shù),避免全表掃描

減少不必要的表連接

有些數(shù)據(jù)操作的業(yè)務(wù)邏輯可以放到應(yīng)用層進(jìn)行實(shí)現(xiàn)

可以使用with as

盡量避免使用游標(biāo),因?yàn)橛螛?biāo)的效率較差

不要把SQL語(yǔ)句寫得太復(fù)雜

不能循環(huán)執(zhí)行查詢

用 exists 代替 in

表關(guān)聯(lián)關(guān)系不要太糾結(jié)

查詢多用索引列取查,用charindex或者like[0-9]來(lái)代替%%

inner關(guān)聯(lián)的表可以先查出來(lái),再去關(guān)聯(lián)leftjoin的表

可以進(jìn)行表關(guān)聯(lián)數(shù)據(jù)拆分,即先查出核心數(shù)據(jù),再通過核心數(shù)據(jù)查其他數(shù)據(jù),這樣會(huì)快得多

參考SQL執(zhí)行順序進(jìn)行優(yōu)化

表關(guān)聯(lián)時(shí)取別名,也能提高效率

使用視圖,給視圖建立索引進(jìn)行優(yōu)化

使用數(shù)據(jù)倉(cāng)庫(kù)的形式,建立單獨(dú)的表存儲(chǔ)數(shù)據(jù),根據(jù)時(shí)間戳定期更新數(shù)據(jù)。將多表關(guān)聯(lián)的數(shù)據(jù)集中抽取存入一張表中,查詢時(shí)單表查詢,提高了查詢效率

對(duì)查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引

應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:   

select id from t where num is null   

可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:  

select id from t where num=0    

  19.應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描

17、SQL 索引的順序,字段的順序

18、查看 SQL 是不是使用了索引?(有什么工具)

在select語(yǔ)句前加上EXPLAIN即可

19、TCP 和 UDP 的區(qū)別?TCP 數(shù)據(jù)傳輸過程中怎么做到可靠的?

UDP(User Data Protocol,用戶數(shù)據(jù)報(bào)協(xié)議)是與TCP相對(duì)應(yīng)的協(xié)議。它是屬于TCP/IP協(xié)議族中的一種

1)為了保證數(shù)據(jù)包的可靠傳遞,發(fā)送方必須把已發(fā)送的數(shù)據(jù)包保留在緩沖區(qū);

(2)并為每個(gè)已發(fā)送的數(shù)據(jù)包啟動(dòng)一個(gè)超時(shí)定時(shí)器;

(3)如在定時(shí)器超時(shí)之前收到了對(duì)方發(fā)來(lái)的應(yīng)答信息(可能是對(duì)本包的應(yīng)答,也可以是對(duì)本包后續(xù)包的應(yīng)答),則釋放該數(shù)據(jù)包占用的緩沖區(qū);

(4)否則,重傳該數(shù)據(jù)包,直到收到應(yīng)答或重傳次數(shù)超過規(guī)定的最大次數(shù)為止。

(5)接收方收到數(shù)據(jù)包后,先進(jìn)行CRC校驗(yàn),如果正確則把數(shù)據(jù)交給上層協(xié)議,然后給發(fā)送方發(fā)送一個(gè)累計(jì)應(yīng)答包,表明該數(shù)據(jù)已收到,如果接收方正好也有數(shù)據(jù)要發(fā)給發(fā)送方,應(yīng)答包也可方在數(shù)據(jù)包中捎帶過去。

20、說下你知道的排序算法吧

常見的內(nèi)部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸并排序、快速排序、堆排序、基數(shù)排序等

21、查找一個(gè)數(shù)組的中位數(shù)?

通過二分查找法來(lái)找中位數(shù)

基本思想是:假設(shè)ar1[i]是合并后的中位數(shù),那么ar1[i]大于ar1[]中前i-1個(gè)數(shù),且大于ar2[]中前j=n-i-1個(gè)數(shù)。通過ar1[i]和ar2[j]、ar2[j+1]兩個(gè)數(shù)的比較,在ar1[i]的左邊或者ar1[i]右邊繼續(xù)進(jìn)行二分查找。對(duì)于兩個(gè)數(shù)組 ar1[] 和ar2[], 先在 ar1[] 中做二分查找。如果在ar1[]中沒找到中位數(shù), 繼續(xù)在ar2[]中查找。

算法流程:

1) 得到數(shù)組ar1[]最中間的數(shù),假設(shè)下標(biāo)為i.

2) 計(jì)算對(duì)應(yīng)在數(shù)組ar2[]的下標(biāo)j,j = n-i-1

3) 如果 ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1],那么 ar1[i] 和 ar2[j] 就是兩個(gè)中間元素,返回ar2[j] 和 ar1[i] 的平均值

4) 如果 ar1[i] 大于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的左部分做二分查找(i.e., arr[left ... i-1])

5) 如果 ar1[i] 小于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的右部分做二分查找(i.e., arr[i+1....right])

6) 如果到達(dá)數(shù)組ar1[]的邊界(left or right),則在數(shù)組ar2[]中做二分查找

時(shí)間復(fù)雜度:O(logn)。

二面

22、你有什么問題想問我的嗎?

1、自我介紹、工作經(jīng)歷、技術(shù)棧

2、項(xiàng)目中你學(xué)到了什么技術(shù)?

3、微服務(wù)劃分的粒度?

4、微服務(wù)的高可用怎么保證的?

負(fù)載均衡與反向代理,隔離,限流,降級(jí),超時(shí)與重試,回滾,壓力測(cè)試與應(yīng)急預(yù)案

5、常用的負(fù)載均衡,該怎么用,你能說下嗎?

1、http重定向

當(dāng)http代理(比如瀏覽器)向web服務(wù)器請(qǐng)求某個(gè)URL后,web服務(wù)器可以通過http響應(yīng)頭信息中的Location標(biāo)記來(lái)返回一個(gè)新的URL。這意味著HTTP代理需要繼續(xù)請(qǐng)求這個(gè)新的URL,完成自動(dòng)跳轉(zhuǎn)。

2、DNS負(fù)載均衡

DNS 負(fù)責(zé)提供域名解析服務(wù),當(dāng)訪問某個(gè)站點(diǎn)時(shí),實(shí)際上首先需要通過該站點(diǎn)域名的DNS服務(wù)器來(lái)獲取域名指向的IP地址,在這一過程中,DNS服務(wù)器完成了域名到IP地址的映射,同樣,這樣映射也可以是一對(duì)多的,這時(shí)候,DNS服務(wù)器便充當(dāng)了負(fù)載均衡調(diào)度器,它就像http重定向轉(zhuǎn)換策略一樣,將用戶的請(qǐng)求分散到多臺(tái)服務(wù)器上,但是它的實(shí)現(xiàn)機(jī)制完全不同。

3、反向代理負(fù)載均衡

這個(gè)肯定大家都有所接觸,因?yàn)閹缀跛兄髁鞯腤eb服務(wù)器都熱衷于支持基于反向代理的負(fù)載均衡。它的核心工作就是轉(zhuǎn)發(fā)HTTP請(qǐng)求。

相比前面的HTTP重定向和DNS解析,反向代理的調(diào)度器扮演的是用戶和實(shí)際服務(wù)器中間人的角色:

   1、任何對(duì)于實(shí)際服務(wù)器的HTTP請(qǐng)求都必須經(jīng)過調(diào)度器

   2、調(diào)度器必須等待實(shí)際服務(wù)器的HTTP響應(yīng),并將它反饋給用戶(前兩種方式不需要經(jīng)過調(diào)度反饋,是實(shí)際服務(wù)器直接發(fā)送給用戶)

4、IP負(fù)載均衡(LVS-NAT)

因?yàn)榉聪虼矸?wù)器工作在HTTP層,其本身的開銷就已經(jīng)嚴(yán)重制約了可擴(kuò)展性,從而也限制了它的性能極限。那能否在HTTP層面以下實(shí)現(xiàn)負(fù)載均衡呢?

NAT服務(wù)器:它工作在傳輸層,它可以修改發(fā)送來(lái)的IP數(shù)據(jù)包,將數(shù)據(jù)包的目標(biāo)地址修改為實(shí)際服務(wù)器地址

5、直接路由(LVS-DR)

NAT是工作在網(wǎng)絡(luò)分層模型的傳輸層(第四層),而直接路由是工作在數(shù)據(jù)鏈路層(第二層),貌似更屌些。它通過修改數(shù)據(jù)包的目標(biāo)MAC地址(沒有修改目標(biāo)IP),將數(shù)據(jù)包轉(zhuǎn)發(fā)到實(shí)際服務(wù)器上,不同的是,實(shí)際服務(wù)器的響應(yīng)數(shù)據(jù)包將直接發(fā)送給客戶羰,而不經(jīng)過調(diào)度器

6、IP隧道(LVS-TUN)

基于IP隧道的請(qǐng)求轉(zhuǎn)發(fā)機(jī)制:將調(diào)度器收到的IP數(shù)據(jù)包封裝在一個(gè)新的IP數(shù)據(jù)包中,轉(zhuǎn)交給實(shí)際服務(wù)器,然后實(shí)際服務(wù)器的響應(yīng)數(shù)據(jù)包可以直接到達(dá)用戶端。目前Linux大多支持,可以用LVS來(lái)實(shí)現(xiàn),稱為L(zhǎng)VS-TUN,與LVS-DR不同的是,實(shí)際服務(wù)器可以和調(diào)度器不在同一個(gè)WANt網(wǎng)段,調(diào)度器通過 IP隧道技術(shù)來(lái)轉(zhuǎn)發(fā)請(qǐng)求到實(shí)際服務(wù)器,所以實(shí)際服務(wù)器也必須擁有合法的IP地址。

總體來(lái)說,LVS-DR和LVS-TUN都適合響應(yīng)和請(qǐng)求不對(duì)稱的Web服務(wù)器,如何從它們中做出選擇,取決于你的網(wǎng)絡(luò)部署需要,因?yàn)長(zhǎng)VS-TUN可以將實(shí)際服務(wù)器根據(jù)需要部署在不同的地域,并且根據(jù)就近訪問的原則來(lái)轉(zhuǎn)移請(qǐng)求,所以有類似這種需求的,就應(yīng)該選擇LVS-TUN。

6、網(wǎng)關(guān)能夠?yàn)楹蠖朔?wù)帶來(lái)哪些好處?

后端服務(wù)器可以專心處理業(yè)務(wù)請(qǐng)求,節(jié)省了大量連接管理的開銷

7、Spring Bean 的生命周期

8、xml 中配置的 init、destroy 方法怎么可以做到調(diào)用具體的方法?

9、反射的機(jī)制

大家都知道,要讓Java程序能夠運(yùn)行,那么就得讓Java類要被Java虛擬機(jī)加載。Java類如果不被Java虛擬機(jī)加載,是不能正常運(yùn)行的?,F(xiàn)在我們運(yùn)行的所有的程序都是在編譯期的時(shí)候就已經(jīng)知道了你所需要的那個(gè)類的已經(jīng)被加載了。

Java的反射機(jī)制是在編譯并不確定是哪個(gè)類被加載了,而是在程序運(yùn)行的時(shí)候才加載、探知、自審。使用在編譯期并不知道的類。這樣的特點(diǎn)就是反射

反射機(jī)制通過void setAccessible(boolean flag)方法可以得到一個(gè)類的private的方法和屬性,使用這些private的方法和屬性

10、Object 類中的方法

1,構(gòu)造函數(shù)

2,hashCode和equale函數(shù)用來(lái)判斷對(duì)象是否相同,

3,wait(),wait(long),wait(long,int),notify(),notifyAll()

4,toString()和getClass,

5,clone()

6,finalize()用于在垃圾回收

11、hashcode 和 equals 方法常用地方

12、對(duì)象比較是否相同

equals通常用來(lái)比較兩個(gè)對(duì)象的內(nèi)容是否相等,==用來(lái)比較兩個(gè)對(duì)象的地址是否相等

13、hashmap put 方法存放的時(shí)候怎么判斷是否是重復(fù)的

先比較key的hashCode,再比較相等或equals的,所以重寫hashCode()和equals()方法即可實(shí)現(xiàn)添加重復(fù)元素。

14、Object toString 方法常用的地方,為什么要重寫該方法

常用在對(duì)象模型類

因?yàn)榧偃鏤ser是一個(gè)用戶的對(duì)象,如果User.toString();結(jié)果是不正常的,因?yàn)閁ser對(duì)象中可能有多個(gè)屬性,如年齡,姓名等,這個(gè)toString后無(wú)法知道具體的是那個(gè)屬性轉(zhuǎn)換為字符串

15、Set 和 List 區(qū)別?

Set(集):集合中的對(duì)象不按特定方式排序,并且沒有重復(fù)對(duì)象。它的有些實(shí)現(xiàn)類能對(duì)集合中的對(duì)象按特定方式排序。

List(列表):集合中的對(duì)象按索引位置排序,可以有重復(fù)對(duì)象,允許按照對(duì)象在集合中的索引位置檢索對(duì)象。

16、ArrayList 和 LinkedList 區(qū)別

 ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)

ArrayList 繼承AbstractList

LinkedList 繼承AbstractSequentialList

ArrayList 采用的是數(shù)組形式來(lái)保存對(duì)象的,這種方式將對(duì)象放在連續(xù)的位置中,所以最大的缺點(diǎn)就是插入刪除時(shí)非常麻煩

LinkedList 采用的將對(duì)象存放在獨(dú)立的空間中,而且在每個(gè)空間中還保存下一個(gè)鏈接的索引 但是缺點(diǎn)就是查找非常麻煩 要叢第一個(gè)索引開始

17、如果存取相同的數(shù)據(jù),ArrayList 和 LinkedList 誰(shuí)占用空間更大?

對(duì)于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList,因?yàn)長(zhǎng)inkedList要移動(dòng)指針

對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì),因?yàn)锳rrayList要移動(dòng)數(shù)據(jù),若要從數(shù)組中刪除或插入某一個(gè)對(duì)象,需要移動(dòng)后段的數(shù)組元素,從而會(huì)重新調(diào)整索引順序,調(diào)整索引順序會(huì)消耗一定的時(shí)間,相反,LinkedList是使用鏈表實(shí)現(xiàn)的,若要從鏈表中刪除或插入某一個(gè)對(duì)象,只需要改變前后對(duì)象的引用即可

18、Set 存的順序是有序的嗎?

無(wú)序

Set是Map的一個(gè)馬甲,主要邏輯都交給Map實(shí)現(xiàn)

19、常見 Set 的實(shí)現(xiàn)有哪些?

HashSet

LinkedHashSet

TreeSet

20、TreeSet 對(duì)存入對(duì)數(shù)據(jù)有什么要求呢?

TreeSet集合是用來(lái)對(duì)象元素進(jìn)行排序的,同樣他也可以保證元素的唯一

21、HashSet 的底層實(shí)現(xiàn)呢?

22、TreeSet 底層源碼有看過嗎?

TreeSet的底層實(shí)現(xiàn)是TreeMap

public TreeSet(Comparator<? super E> comparator) {

    this(new TreeMap<>(comparator));

  }

23、HashSet 是不是線程安全的?為什么不是線程安全的?

說白了,HashSet就是限制了功能的HashMap,所以了解HashMap的實(shí)現(xiàn)原理

24、Java 中有哪些線程安全的 Map?

Concurrenthashmap

25、Concurrenthashmap 是怎么做到線程安全的?

ConcurrentHashMap的大部分操作和HashMap是相同的,例如初始化,擴(kuò)容和鏈表向紅黑樹的轉(zhuǎn)變等。但是,在ConcurrentHashMap中,大量使用了U.compareAndSwapXXX

的方法,這個(gè)方法是利用一個(gè)CAS算法實(shí)現(xiàn)無(wú)鎖化的修改值的操作,他可以大大降低鎖代理的性能消耗。這個(gè)算法的基本思想就是不斷地去比較當(dāng)前內(nèi)存中的變量值與你指定的

一個(gè)變量值是否相等,如果相等,則接受你指定的修改的值,否則拒絕你的操作。因?yàn)楫?dāng)前線程中的值已經(jīng)不是最新的值,你的修改很可能會(huì)覆蓋掉其他線程修改的結(jié)果。這一

點(diǎn)與樂觀鎖,SVN的思想是比較類似的。

同時(shí),在ConcurrentHashMap中還定義了三個(gè)原子操作,用于對(duì)指定位置的節(jié)點(diǎn)進(jìn)行操作。這三種原子操作被廣泛的使用在ConcurrentHashMap的get和put等方法中,

正是這些原子操作保證了ConcurrentHashMap的線程安全。

在ConcurrentHashMap沒有出現(xiàn)以前,jdk使用hashtable來(lái)實(shí)現(xiàn)線程安全,但是hashtable是將整個(gè)hash表鎖住,所以效率很低下。

ConcurrentHashMap將數(shù)據(jù)分別放到多個(gè)Segment中,默認(rèn)16個(gè),每一個(gè)Segment中又包含了多個(gè)HashEntry列表數(shù)組,

對(duì)于一個(gè)key,需要經(jīng)過三次hash操作,才能最終定位這個(gè)元素的位置,這三次hash分別為:

對(duì)于一個(gè)key,先進(jìn)行一次hash操作,得到hash值h1,也即h1 = hash1(key);

將得到的h1的高幾位進(jìn)行第二次hash,得到hash值h2,也即h2 = hash2(h1高幾位),通過h2能夠確定該元素的放在哪個(gè)Segment;

將得到的h1進(jìn)行第三次hash,得到hash值h3,也即h3 = hash3(h1),通過h3能夠確定該元素放置在哪個(gè)HashEntry。

每一個(gè)Segment都擁有一個(gè)鎖,當(dāng)進(jìn)行寫操作時(shí),只需要鎖定一個(gè)Segment,而其它Segment中的數(shù)據(jù)是可以訪問的。

26、HashTable 你了解過嗎?

Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的注釋中有說明

Hashtable是線程安全的,

Hashtable是線程安全的,它的每個(gè)方法中都加入了Synchronize方法,效率比較低

Hashtable默認(rèn)的初始大小為11,之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的2n+1。

Hashtable在計(jì)算元素的位置時(shí)需要進(jìn)行一次除法運(yùn)算,而除法運(yùn)算是比較耗時(shí)的。

27、如何保證線程安全問題?

28、synchronized、lock

synchronized是java中的一個(gè)關(guān)鍵字,也就是說是Java語(yǔ)言內(nèi)置的特性

如果一個(gè)代碼塊被synchronized修飾了,當(dāng)一個(gè)線程獲取了對(duì)應(yīng)的鎖,并執(zhí)行該代碼塊時(shí),其他線程便只能一直等待,等待獲取鎖的線程釋放鎖,而這里獲取鎖的線程釋放鎖只會(huì)有兩種情況:

1)獲取鎖的線程執(zhí)行完了該代碼塊,然后線程釋放對(duì)鎖的占有;

2)線程執(zhí)行發(fā)生異常,此時(shí)JVM會(huì)讓線程自動(dòng)釋放鎖

那么如果這個(gè)獲取鎖的線程由于要等待IO或者其他原因(比如調(diào)用sleep方法)被阻塞了,但是又沒有釋放鎖,其他線程便只能干巴巴地等待,試想一下,這多么影響程序執(zhí)行效率。

因此就需要有一種機(jī)制可以不讓等待的線程一直無(wú)期限地等待下去(比如只等待一定的時(shí)間或者能夠響應(yīng)中斷),通過Lock就可以辦到

再舉個(gè)例子:當(dāng)有多個(gè)線程讀寫文件時(shí),讀操作和寫操作會(huì)發(fā)生沖突現(xiàn)象,寫操作和寫操作會(huì)發(fā)生沖突現(xiàn)象,但是讀操作和讀操作不會(huì)發(fā)生沖突現(xiàn)象。

但是采用synchronized關(guān)鍵字來(lái)實(shí)現(xiàn)同步的話,就會(huì)導(dǎo)致一個(gè)問題:

如果多個(gè)線程都只是進(jìn)行讀操作,所以當(dāng)一個(gè)線程在進(jìn)行讀操作時(shí),其他線程只能等待無(wú)法進(jìn)行讀操作。

因此就需要一種機(jī)制來(lái)使得多個(gè)線程都只是進(jìn)行讀操作時(shí),線程之間不會(huì)發(fā)生沖突,通過Lock就可以辦到。

另外,通過Lock可以知道線程有沒有成功獲取到鎖。這個(gè)是synchronized無(wú)法辦到的

29、volatile 的原子性問題?為什么 i++ 這種不支持原子性?從計(jì)算機(jī)原理的設(shè)計(jì)來(lái)講下不能保證原子性的原因

30、happens before 原理

31、cas 操作

java.util.concurrent包中借助CAS實(shí)現(xiàn)了區(qū)別于synchronized同步鎖的一種樂觀鎖

cas是比較并交換算法

 CAS有3個(gè)操作數(shù),內(nèi)存值V,舊的預(yù)期值A(chǔ),要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B,否則什么都不做

JDK提供了AtomicReference類來(lái)保證引用對(duì)象之間的原子性,就可以把多個(gè)變量放在一個(gè)對(duì)象里來(lái)進(jìn)行CAS操作。

32、lock 和 synchronized 的區(qū)別?

  1)Lock是一個(gè)接口,而synchronized是Java中的關(guān)鍵字,synchronized是內(nèi)置的語(yǔ)言實(shí)現(xiàn);

2)synchronized在發(fā)生異常時(shí),會(huì)自動(dòng)釋放線程占有的鎖,因此不會(huì)導(dǎo)致死鎖現(xiàn)象發(fā)生;而Lock在發(fā)生異常時(shí),如果沒有主動(dòng)通過unLock()去釋放鎖,則很可能造成死鎖現(xiàn)象,因此使用Lock時(shí)需要在finally塊中釋放鎖;

3)Lock可以讓等待鎖的線程響應(yīng)中斷,而synchronized卻不行,使用synchronized時(shí),等待的線程會(huì)一直等待下去,不能夠響應(yīng)中斷;

4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無(wú)法辦到。

5)Lock可以提高多個(gè)線程進(jìn)行讀操作的效率。

在性能上來(lái)說,如果競(jìng)爭(zhēng)資源不激烈,兩者的性能是差不多的,而當(dāng)競(jìng)爭(zhēng)資源非常激烈時(shí)(即有大量線程同時(shí)競(jìng)爭(zhēng)),此時(shí)Lock的性能要遠(yuǎn)遠(yuǎn)優(yōu)于synchronized。所以說,在具體使用時(shí)要根據(jù)適當(dāng)情況選擇。

 

類別

synchronized

Lock

存在層次

Java的關(guān)鍵字,在jvm層面上

是一個(gè)類

鎖的釋放

1、以獲取鎖的線程執(zhí)行完同步代碼,釋放鎖 2、線程執(zhí)行發(fā)生異常,jvm會(huì)讓線程釋放鎖

在finally中必須釋放鎖,不然容易造成線程死鎖

鎖的獲取

假設(shè)A線程獲得鎖,B線程等待。如果A線程阻塞,B線程會(huì)一直等待

分情況而定,Lock有多個(gè)鎖獲取的方式,具體下面會(huì)說道,大致就是可以嘗試獲得鎖,線程可以不用一直等待

鎖狀態(tài)

無(wú)法判斷

可以判斷

鎖類型

可重入 不可中斷 非公平

可重入 可判斷 可公平(兩者皆可)

性能

少量同步

大量同步

33、公平鎖和非公平鎖

公平和非公平鎖的隊(duì)列都基于鎖內(nèi)部維護(hù)的一個(gè)雙向鏈表,表結(jié)點(diǎn)Node的值就是每一個(gè)請(qǐng)求當(dāng)前鎖的線程。公平鎖則在于每次都是依次從隊(duì)首取值

非公平鎖在等待鎖的過程中, 如果有任意新的線程妄圖獲取鎖,都是有很大的幾率直接獲取到鎖的

(在ReentrantLock中很明顯可以看到其中同步包括兩種,分別是公平的FairSync和非公平的NonfairSync。公平鎖的作用就是嚴(yán)格按照線程啟動(dòng)的順序來(lái)執(zhí)行的,不允許其他線程插隊(duì)執(zhí)行的;而非公平鎖是允許插隊(duì)的。

默認(rèn)情況下ReentrantLock是通過非公平鎖來(lái)進(jìn)行同步的,包括synchronized關(guān)鍵字都是如此,因?yàn)檫@樣性能會(huì)更好。因?yàn)閺木€程進(jìn)入了RUNNABLE狀態(tài),可以執(zhí)行開始,到實(shí)際線程執(zhí)行是要比較久的時(shí)間的。而且,在一個(gè)鎖釋放之后,其他的線程會(huì)需要重新來(lái)獲取鎖。其中經(jīng)歷了持有鎖的線程釋放鎖,其他線程從掛起恢復(fù)到RUNNABLE狀態(tài),其他線程請(qǐng)求鎖,獲得鎖,線程執(zhí)行,這一系列步驟。如果這個(gè)時(shí)候,存在一個(gè)線程直接請(qǐng)求鎖,可能就避開掛起到恢復(fù)RUNNABLE狀態(tài)的這段消耗,所以性能更優(yōu)化)

34、Java 讀寫鎖

35、讀寫鎖設(shè)計(jì)主要解決什么問題?

多線程,

讀操作可以共享,寫操作是排他的,讀可以有多個(gè)在讀,寫只有唯一個(gè)在寫,同時(shí)寫的時(shí)候不允許讀

解決了讀和讀可以同時(shí)進(jìn)行,讀和寫不能同時(shí)進(jìn)行,寫和寫不能同時(shí)進(jìn)行

36、你項(xiàng)目除了寫 Java 代碼,還有前端代碼,那你知道前端有哪些框架嗎?

Vue layer react element

37、MySQL 分頁(yè)查詢語(yǔ)句

LIMIT [offset,] rows

offset指定要返回的第一行的偏移量,rows第二個(gè)指定返回行的最大數(shù)目

38、MySQL 事務(wù)特性和隔離級(jí)別

事務(wù)的基本要素(ACID)

1、原子性(Atomicity):事務(wù)開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環(huán)節(jié)。事務(wù)執(zhí)行過程中出錯(cuò),會(huì)回滾到事務(wù)開始前的狀態(tài),所有的操作就像沒有發(fā)生一樣。也就是說事務(wù)是一個(gè)不可分割的整體,就像化學(xué)中學(xué)過的原子,是物質(zhì)構(gòu)成的基本單位。

2、一致性(Consistency):事務(wù)開始前和結(jié)束后,數(shù)據(jù)庫(kù)的完整性約束沒有被破壞 。比如A向B轉(zhuǎn)賬,不可能A扣了錢,B卻沒收到。

3、隔離性(Isolation):同一時(shí)間,只允許一個(gè)事務(wù)請(qǐng)求同一數(shù)據(jù),不同的事務(wù)之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結(jié)束前,B不能向這張卡轉(zhuǎn)賬。

4、持久性(Durability):事務(wù)完成后,事務(wù)對(duì)數(shù)據(jù)庫(kù)的所有更新將被保存到數(shù)據(jù)庫(kù),不能回滾。

二、事務(wù)的并發(fā)問題

1、臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)

2、不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過程中,對(duì)數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致。

3、幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫(kù)中所有學(xué)生的成績(jī)從具體分?jǐn)?shù)改為ABCDE等級(jí),但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒有改過來(lái),就好像發(fā)生了幻覺一樣,這就叫幻讀

MySQL事務(wù)隔離級(jí)別

事務(wù)隔離級(jí)別

臟讀

不可重復(fù)讀

幻讀

讀未提交(read-uncommitted)

不可重復(fù)讀(read-committed)

可重復(fù)讀(repeatable-read)

串行化(serializable)

39、不可重復(fù)讀會(huì)出現(xiàn)在什么場(chǎng)景?

40、sql having 的使用場(chǎng)景

如果需要對(duì)組函數(shù)的結(jié)果作為條件,那么不能使用where子句,必須使用having子句

41、前端瀏覽器地址的一個(gè) http 請(qǐng)求到后端整個(gè)流程是怎么樣?

能夠說下嗎?

域名解析 --> 發(fā)起TCP的3次握手 --> 建立TCP連接后發(fā)起http請(qǐng)求 -->服務(wù)器響應(yīng)http請(qǐng)求,瀏覽器得到html代碼 -->瀏覽器解析html代碼,并請(qǐng)求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對(duì)頁(yè)面進(jìn)行渲染呈現(xiàn)給用戶

42、http 默認(rèn)端口,https 默認(rèn)端口

HTTP協(xié)議代理服務(wù)器常用端口號(hào):80/8080/3128/8081/9080

HTTPS服務(wù)器,默認(rèn)的端口號(hào)為443/tcp 443/udp

43、DNS 你知道是干嘛的嗎?

DNS是指:域名服務(wù)器(Domain Name Server)。在Internet上域名與IP地址之間是一一對(duì)應(yīng)的,域名雖然便于人們記憶,但機(jī)器之間只能互相認(rèn)識(shí)IP地址,它們之間的轉(zhuǎn)換工作稱為域名解析,域名解析需要由專門的域名解析服務(wù)器來(lái)完成,DNS就是進(jìn)行域名解析的服務(wù)器

44、你們開發(fā)用的 ide 是啥?你能說下 idea 的常用幾個(gè)快捷鍵吧?

45、代碼版本管理你們用的是啥?

46、git rebase 和 merge 有什么區(qū)別?

47、你們公司加班多嗎?

 

注:有些問題待補(bǔ)充。