備戰(zhàn)金九銀十,Java研發(fā)面試題(Spring、MySQL、JVM、Mybatis、Redis、Tomcat)[帶答案],刷起來!

八月在即,馬上就是"金九銀十",又是跳槽招聘季。咱們這行公認(rèn)漲薪不如跳槽加的快。但不建議頻繁跳槽,還是要學(xué)會(huì)融合團(tuán)隊(duì),抓住每個(gè)機(jī)會(huì)提升技能。

蘇先生在這里給大家整理了一套各大互聯(lián)網(wǎng)公司面試都喜歡問的一些問題或者一些出場(chǎng)率很高的Java研發(fā)面試題,給在校招或者社招路上的你一臂之力。

目錄

  1. Spring
  2. Netty
  3. MySQL
  4. JVM
  5. Tomcat
  6. Mybatis
  7. Redis
  8. Kafka
  9. 讀者福利

一. Spring

1、什么是 Spring 框架?Spring 框架有哪些主要模塊?

Spring 框架是一個(gè)為 Java 應(yīng)用程序的開發(fā)提供了綜合、廣泛的基礎(chǔ)性支持的 Java 平臺(tái)。

Spring 幫助開發(fā)者解決了開發(fā)中基礎(chǔ)性的問題,使得開發(fā)人員可以專注于應(yīng)用程序的開發(fā)。

Spring 框架本身亦是按照設(shè)計(jì)模式精心打造,這使得我們可以在開發(fā)環(huán)境中安心的集成 Spring 框架,不必?fù)?dān)心 Spring 是如何在后臺(tái)進(jìn)行工作的。

Spring 框架至今已集成了 20 多個(gè)模塊。這些模塊主要被分如下圖所示的核心容器、數(shù)據(jù)訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測(cè)試模塊。

2、什么是控制反轉(zhuǎn)(IOC)?什么是依賴注入?

控制反轉(zhuǎn)是應(yīng)用于軟件工程領(lǐng)域中的,在運(yùn)行時(shí)被裝配器對(duì)象來綁定耦合對(duì)象的一種編程技巧,對(duì)象之間耦合關(guān)系在編譯時(shí)通常是未知的。在傳統(tǒng)的編程方式中,業(yè) 務(wù)邏輯的流程是由應(yīng)用程序中的早已被設(shè)定好關(guān)聯(lián)關(guān)系的對(duì)象來決定的。在使用控制反轉(zhuǎn)的情況下,業(yè)務(wù)邏輯的流程是由對(duì)象關(guān)系 圖來決定的,該對(duì)象關(guān)系圖由裝配 器負(fù)責(zé)實(shí)例化,這種實(shí)現(xiàn)方式還可以將對(duì)象之間的關(guān)聯(lián)關(guān)系的定義抽象化。而綁定的過程是通過“依賴注入”實(shí)現(xiàn)的。

控制反轉(zhuǎn)是一種以給予應(yīng)用程序中目標(biāo)組件更多控制為目的設(shè)計(jì)范式,并在我們的實(shí)際工作中起到了有效的作用。

依賴注入是在編譯階段尚未知所需的功能是來自哪個(gè)的類的情況下,將其他對(duì)象所依賴的功能對(duì)象實(shí)例化的模式。這就需要一種機(jī)制用來激活相應(yīng)的組件以提供特定的功能,所以依賴注入是控制反轉(zhuǎn)的基礎(chǔ)。否則如果在組件不受框架控制的情況下,框架又怎么知道要?jiǎng)?chuàng)建哪個(gè)組件?

3、怎樣用注解的方式配置 Spring?

Spring 在 2.5 版本以后開始支持用注解的方式來配置依賴注入??梢杂米⒔獾姆绞絹硖娲?XML 方式的 bean 描述,可以將 bean 描述轉(zhuǎn)移到組件類的 內(nèi)部,只需要在相關(guān)類上、方法上或者字段聲明上使用注解即可。注解注入將會(huì)被容器在 XML 注入之前被處理,所以后者會(huì)覆蓋掉前者對(duì)于同一個(gè)屬性的處理結(jié)果。

注解裝配在 Spring 中是默認(rèn)關(guān)閉的。所以需要在 Spring 文件中配置一下才能使用基于注解的裝配模式。如果你想要在你的應(yīng)用程序中使用關(guān)于注解的方法的話,請(qǐng)參考如下的配置。

<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>

在 <context:annotation-config/>標(biāo)簽配置完成以后,就可以用注解的方式在 Spring 中向?qū)傩?、方法和?gòu)造方法中自動(dòng)裝配變量。

下面是幾種比較重要的注解類型

  1. @Required:該注解應(yīng)用于設(shè)值方法。
  2. @Autowired:該注解應(yīng)用于有值設(shè)值方法、非設(shè)值方法、構(gòu)造方法和變量。
  3. @Qualifier:該注解和@Autowired 注解搭配使用,用于消除特定 bean 自動(dòng)裝配的歧義。
  4. JSR-250 Annotations:Spring 支持基于 JSR-250 注解的以下注解,@Resource、@PostConstruct 和 @PreDestroy。

二. Netty

1、Netty 的特點(diǎn)?

一個(gè)高性能、異步事件驅(qū)動(dòng)的 NIO 框架,它提供了對(duì) TCP、UDP 和文件傳輸?shù)闹С质褂酶咝У?socket 底層,對(duì) epoll 空輪詢引起的 cpu 占用飆升在內(nèi)部進(jìn)行了處理,避免了直接使用 NIO 的陷阱,簡(jiǎn)化了 NIO 的處理方式。

采用多種 decoder/encoder 支持,對(duì) TCP 粘包/分包進(jìn)行自動(dòng)化處理可使用接受/處理線程池,提高連接效率,對(duì)重連、心跳檢測(cè)的簡(jiǎn)單支持可配置 IO 線程數(shù)、TCP 參數(shù), TCP 接收和發(fā)送緩沖區(qū)使用直接內(nèi)存代替堆內(nèi)存,通過內(nèi)存池的方式循環(huán)利用 ByteBuf通過引用計(jì)數(shù)器及時(shí)申請(qǐng)釋放不再引用的對(duì)象,降低了 GC 頻率使用單線程串行化的方式,高效的 Reactor 線程模型大量使用了 volitale、使用了 CAS 和原子類、線程安全類的使用、讀寫鎖的使用

2、Netty 的線程模型?

Netty 通過 Reactor 模型基于多路復(fù)用器接收并處理用戶請(qǐng)求,內(nèi)部實(shí)現(xiàn)了兩個(gè)線程池,boss 線程池和 work 線程池,其中 boss 線程池的線程負(fù)責(zé)處理請(qǐng)求的 accept 事件,當(dāng)接收到 accept 事件的請(qǐng)求時(shí),把對(duì)應(yīng)的 socket 封裝到一個(gè) NioSocketChannel 中,并交給 work線程池,其中 work 線程池負(fù)責(zé)請(qǐng)求的 read 和 write 事件,由對(duì)應(yīng)的 Handler 處理。

  • 單線程模型:所有 I/O 操作都由一個(gè)線程完成,即多路復(fù)用、事件分發(fā)和處理都是在一個(gè)Reactor 線程上完成的。既要接收客戶端的連接請(qǐng)求,向服務(wù)端發(fā)起連接,又要發(fā)送/讀取請(qǐng)求或應(yīng)答/響應(yīng)消息。一個(gè) NIO 線程同時(shí)處理成百上千的鏈路,性能上無法支撐,速度慢,若線程進(jìn)入死循環(huán),整個(gè)程序不可用,對(duì)于高負(fù)載、大并發(fā)的應(yīng)用場(chǎng)景不合適。

  • 多線程模型:有一個(gè) NIO 線程(Acceptor) 只負(fù)責(zé)監(jiān)聽服務(wù)端,接收客戶端的 TCP 連接請(qǐng)求;NIO 線程池負(fù)責(zé)網(wǎng)絡(luò) IO 的操作,即消息的讀取、解碼、編碼和發(fā)送;1 個(gè) NIO 線程可以同時(shí)處理 N 條鏈路,但是 1 個(gè)鏈路只對(duì)應(yīng) 1 個(gè) NIO 線程,這是為了防止發(fā)生并發(fā)操作問題。但在并發(fā)百萬客戶端連接或需要安全認(rèn)證時(shí),一個(gè) Acceptor 線程可能會(huì)存在性能不足問題。

  • 主從多線程模型:Acceptor 線程用于綁定監(jiān)聽端口,接收客戶端連接,將 SocketChannel從主線程池的 Reactor 線程的多路復(fù)用器上移除,重新注冊(cè)到 Sub 線程池的線程上,用于 處理 I/O 的讀寫等操作,從而保證 mainReactor 只負(fù)責(zé)接入認(rèn)證、握手等操作;

3、BIO、NIO 和 AIO 的區(qū)別?

  • BIO:一個(gè)連接一個(gè)線程,客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理。線程開銷大。

  • 偽異步 IO:將請(qǐng)求連接放入線程池,一對(duì)多,但線程還是很寶貴的資源。

  • NIO:一個(gè)請(qǐng)求一個(gè)線程,但客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有 I/O 請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。

  • AIO:一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的 I/O 請(qǐng)求都是由 OS 先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理,BIO 是面向流的,NIO 是面向緩沖區(qū)的;BIO 的各種流是阻塞的。而 NIO 是非阻塞的;BIO的 Stream 是單向的,而 NIO 的 channel 是雙向的。

  • NIO 的特點(diǎn):事件驅(qū)動(dòng)模型、單線程處理多任務(wù)、非阻塞 I/O,I/O 讀寫不再阻塞,而是返回 0、基于 block 的傳輸比基于流的傳輸更高效、更高級(jí)的 IO 函數(shù) zero-copy、IO 多路復(fù)用大大提高了 Java 網(wǎng)絡(luò)應(yīng)用的可伸縮性和實(shí)用性?;?Reactor 線程模型。

在 Reactor 模式中,事件分發(fā)器等待某個(gè)事件或者可應(yīng)用或個(gè)操作的狀態(tài)發(fā)生,事件分發(fā)器就把這個(gè)事件傳給事先注冊(cè)的事件處理函數(shù)或者回調(diào)函數(shù),由后者來做實(shí)際的讀寫操作。如在 Reactor 中實(shí)現(xiàn)讀:注冊(cè)讀就緒事件和相應(yīng)的事件處理器、事件分發(fā)器等待事件、事件到來,激活分發(fā)器,分發(fā)器調(diào)用事件對(duì)應(yīng)的處理器、事件處理器完成實(shí)際的讀操作,處理讀到的數(shù)據(jù),注冊(cè)新的事件,然后返還控制權(quán)。

三. MySQL

1、有哪些數(shù)據(jù)庫(kù)優(yōu)化方面的經(jīng)驗(yàn)?

  • ①. 用 PreparedStatement, 一般來說比 Statement 性能高:一個(gè) sql 發(fā)給服務(wù)器去執(zhí)行,涉及步驟:語法檢查、語義分析, 編譯,緩存。

  • ②. 有外鍵約束會(huì)影響插入和刪除性能,如果程序能夠保證數(shù)據(jù)的完整性, 那在設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)就去掉外鍵。

  • ③. 表中允許適當(dāng)冗余,譬如,主題帖的回復(fù)數(shù)量和最后回復(fù)時(shí)間等

  • ④. UNION ALL 要比 UNION 快很多,所以,如果可以確認(rèn)合并的兩個(gè)結(jié) 果集中不包含重復(fù)數(shù)據(jù)且不需要排序時(shí)的話,那么就使用 UNION ALL。 >>UNION 和 UNION ALL 關(guān)鍵字都是將兩個(gè)結(jié)果集合并為一 個(gè),但這兩者從使用和效率上來說都有所不同。 >1. 對(duì)重復(fù)結(jié)果的處 理:UNION 在進(jìn)行表鏈接后會(huì)篩選掉重復(fù)的記錄,Union All 不會(huì)去除 重復(fù)記錄。 >2. 對(duì)排序的處理:Union 將會(huì)按照字段的順序進(jìn)行排 序;UNION ALL 只是簡(jiǎn)單的將兩個(gè)結(jié)果合并后就返回。

2、mysql 中 myisam 與 innodb 的區(qū)別?

  • ①. 事務(wù)支持 > MyISAM:強(qiáng)調(diào)的是性能,每次查詢具有原子性,其執(zhí)行數(shù) 度比 InnoDB 類型更快,但是不提供事務(wù)支持。 > InnoDB:提供事 務(wù)支持事務(wù),外部鍵等高級(jí)數(shù)據(jù)庫(kù)功能。 具有事務(wù)(commit)、回滾 (rollback)和崩潰修復(fù)能力(crash recovery capabilities)的事務(wù)安全 (transaction-safe (ACID compliant))型表。

  • ②. InnoDB 支持行級(jí)鎖,而 MyISAM 支持表級(jí)鎖. >> 用戶在操作 myisam 表時(shí),select,update,delete,insert 語句都會(huì)給表自動(dòng) 加鎖,如果加鎖以后的表滿足 insert 并發(fā)的情況下,可以在表的尾部插入新的數(shù)據(jù)。

  • ③. InnoDB 支持 MVCC, 而 MyISAM 不支持

  • ④. InnoDB 支持外鍵,而 MyISAM 不支持

  • ⑤. 表主鍵 > MyISAM:允許沒有任何索引和主鍵的表存在,索引都是保 存行的地址。 > InnoDB:如果沒有設(shè)定主鍵或者非空唯一索引,就會(huì) 自動(dòng)生成一個(gè) 6 字節(jié)的主鍵(用戶不可見),數(shù)據(jù)是主索引的一部分,附 加索引保存的是主索引的值。

  • ⑥. InnoDB 不支持全文索引,而 MyISAM 支持。

  • ⑦. 可移植性、備份及恢復(fù) > MyISAM:數(shù)據(jù)是以文件的形式存儲(chǔ),所以 在跨平臺(tái)的數(shù)據(jù)轉(zhuǎn)移中會(huì)很方便。在備份和恢復(fù)時(shí)可單獨(dú)針對(duì)某個(gè)表進(jìn) 行操作。 > InnoDB:免費(fèi)的方案可以是拷貝數(shù)據(jù)文件、備份 binlog,或者用 mysqldump,在數(shù)據(jù)量達(dá)到幾十 G 的時(shí)候就相對(duì)痛 苦了

  • ⑧. 存儲(chǔ)結(jié)構(gòu) > MyISAM:每個(gè) MyISAM 在磁盤上存儲(chǔ)成三個(gè)文件。第一 個(gè)文件的名字以表的名字開始,擴(kuò)展名指出文件類型。.frm 文件存儲(chǔ)表 定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。索引文件的擴(kuò)展名 是.MYI (MYIndex)。 > InnoDB:所有的表都保存在同一個(gè)數(shù)據(jù)文件 中(也可能是多個(gè)文件,或者是獨(dú)立的表空間文件),InnoDB 表的大 小只受限于操作系統(tǒng)文件的大小,一般為 2GB。

3、MySQL 中 InnoDB 引擎的行鎖是通過加在什么上完成(或稱實(shí)現(xiàn)) 的?

InnoDB 行鎖是通過給索引上的索引項(xiàng)加鎖來實(shí)現(xiàn)的,這一點(diǎn) MySQL 與 Oracle 不同,后者是通過在數(shù)據(jù)塊中對(duì)相應(yīng)數(shù)據(jù)行加鎖來實(shí)現(xiàn)的。InnoDB 這 種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過索引條件檢索數(shù)據(jù),InnoDB 才使用行級(jí) 鎖,否則,InnoDB 將使用表鎖!

四. JVM

1、內(nèi)存模型以及分區(qū),需要詳細(xì)到每個(gè)區(qū)放什么。

JVM 分為堆區(qū)和棧區(qū),還有方法區(qū),初始化的對(duì)象放在堆里面,引用放在棧里面,class 類信息常量池(static 常量和 static 變量)等放在方法區(qū)new:

  • 方法區(qū):主要是存儲(chǔ)類信息,常量池(static 常量和 static 變量),編譯后的代碼(字節(jié)碼)等數(shù)據(jù)
  • 堆:初始化的對(duì)象,成員變量 (那種非 static 的變量),所有的對(duì)象實(shí)例和數(shù)組都要在堆上分配
  • 棧:棧的結(jié)構(gòu)是棧幀組成的,調(diào)用一個(gè)方法就壓入一幀,幀上面存儲(chǔ)局部變量表,操作數(shù)棧,方法出口等信息,局部變量表存放的是 8 大基礎(chǔ)類型加上一個(gè)應(yīng)用類型,所以還是一個(gè)指向地址的指針
  • 本地方法棧:主要為 Native 方法服務(wù)
  • 程序計(jì)數(shù)器:記錄當(dāng)前線程執(zhí)行的行號(hào)

2、堆里面的分區(qū):Eden,survival (from+ to),老年代,各自的特點(diǎn)。

堆里面分為新生代和老生代(java8 取消了永久代,采用了 Metaspace),新生代包 含 Eden+Survivor 區(qū),survivor 區(qū)里面分為 from 和 to 區(qū),內(nèi)存回收時(shí),如果用的是復(fù) 制算法,從 from 復(fù)制到 to,當(dāng)經(jīng)過一次或者多次 GC 之后,存活下來的對(duì)象會(huì)被移動(dòng) 到老年區(qū),當(dāng) JVM 內(nèi)存不夠用的時(shí)候,會(huì)觸發(fā) Full GC,清理 JVM 老年區(qū) 當(dāng)新生區(qū)滿了之后會(huì)觸發(fā) YGC,先把存活的對(duì)象放到其中一個(gè) Survice 區(qū),然后進(jìn)行垃圾清理。因?yàn)槿绻麅H僅清理需要?jiǎng)h除的對(duì)象,這樣會(huì)導(dǎo)致內(nèi)存碎 片,因此一般會(huì)把 Eden 進(jìn)行完全的清理,然后整理內(nèi)存。那么下次 GC 的時(shí)候, 就會(huì)使用下一個(gè) Survive,這樣循環(huán)使用。如果有特別大的對(duì)象,新生代放不下, 就會(huì)使用老年代的擔(dān)保,直接放到老年代里面。因?yàn)?JVM 認(rèn)為,一般大對(duì)象的存 活時(shí)間一般比較久遠(yuǎn)。

3、簡(jiǎn)述 java 垃圾回收機(jī)制?

在 java 中,程序員是不需要顯示的去釋放一個(gè)對(duì)象的內(nèi)存的,而是由虛擬機(jī)自行執(zhí)行。在JVM 中,有一個(gè)垃圾回收線程,它是低優(yōu)先級(jí)的,在正常情況下是不會(huì)執(zhí)行的,只有在虛擬機(jī)空閑或者當(dāng)前堆內(nèi)存不足時(shí),才會(huì)觸發(fā)執(zhí)行,掃面那些沒有被任何引用的對(duì)象,并將它們添加到要回收的集合中,進(jìn)行回收。

五. Tomcat

1、Tomcat 的缺省端口是多少,怎么修改?

  • 找到 Tomcat 目錄下的 conf 文件夾
  • 進(jìn)入 conf 文件夾里面找到 server.xml 文件
  • 打開 server.xml 文件
  • 在 server.xml 文件里面找到下列信息<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" uriEncoding="utf-8"/> port="8080"改成你想要的端口

2、Tomcat 有幾種部署方式?

  • 直接把 Web 項(xiàng)目放在 webapps 下,Tomcat 會(huì)自動(dòng)將其部署
  • 在 server.xml 文件上配置<Context>節(jié)點(diǎn),設(shè)置相關(guān)的屬性即可
  • 通過 Catalina 來進(jìn)行配置:進(jìn)入到 conf\Catalina\localhost 文件下,創(chuàng)建一個(gè) xml 文件,該文件的名字就是站點(diǎn)的名字。

3、tomcat 容器是如何創(chuàng)建 servlet 類實(shí)例?用到了什么原理?

當(dāng)容器啟動(dòng)時(shí),會(huì)讀取在 webapps 目錄下所有的 web 應(yīng)用中的 web.xml 文 件,然后對(duì) xml 文件進(jìn)行解析,并讀取 servlet 注冊(cè)信息。然后,將每個(gè)應(yīng)用中注冊(cè)的 servlet 類都進(jìn)行加載, 并通過反射的方式實(shí)例化。(有時(shí)候也是在第一次請(qǐng)求時(shí)實(shí)例化)在 servlet 注冊(cè)時(shí)加上如果為正數(shù),則在 一開始就實(shí)例化,如果不寫或?yàn)樨?fù)數(shù),則第一次請(qǐng)求實(shí)例化。

六. MyBatis

1、講下 MyBatis 的緩存

MyBatis 的緩存分為一級(jí)緩存和二級(jí)緩存,一級(jí)緩存放在 session 里面,默認(rèn)就有,二級(jí)緩存放在它的命名空間里,默認(rèn)是不打開的,使用二級(jí)緩存屬性類需要實(shí)現(xiàn) Serializable 序列化接口(可用來保存對(duì)象的狀態(tài)),可在它的映射文件中配置<cache/>

2、Mybatis 是如何進(jìn)行分頁(yè)的?分頁(yè)插件的原理是什么?

  • Mybatis 使用 RowBounds 對(duì)象進(jìn)行分頁(yè),也可以直接編寫 sql 實(shí)現(xiàn)分頁(yè),也可以使用Mybatis 的分頁(yè)插件。
  • 分頁(yè)插件的原理:實(shí)現(xiàn) Mybatis 提供的接口,實(shí)現(xiàn)自定義插件,在插件的攔截方法內(nèi)攔截待執(zhí)行的 sql,然后重寫 sql。舉例:select * from student,攔截 sql 后重寫為:select t.* from (select * from student)tlimit 0,10

3、簡(jiǎn)述 Mybatis 的插件運(yùn)行原理,以及如何編寫一個(gè)插件?

  • Mybatis 僅可以編寫針對(duì) ParameterHandler、ResultSetHandler、StatementHandler、Executor 這 4 種接口的插件,Mybatis 通過動(dòng)態(tài)代理,為需要攔截的接口生成代理對(duì)象以實(shí)現(xiàn)接口方法攔截功能,每當(dāng)執(zhí)行這 4 種接口對(duì)象的方法時(shí),就會(huì)進(jìn)入攔截方法,具體就是InvocationHandler 的 invoke()方法,當(dāng)然,只會(huì)攔截那些你指定需要攔截的方法。
  • 實(shí)現(xiàn) Mybatis 的 Interceptor 接口并復(fù)寫 intercept()方法,然后在給插件編寫注解,指定要攔截哪一個(gè)接口的哪些方法即可,記住,別忘了在配置文件中配置你編寫的插件。

七. Redis

1、Redis 有哪幾種數(shù)據(jù)淘汰策略?

  • noeviction:返回錯(cuò)誤當(dāng)內(nèi)存限制達(dá)到,并且客戶端嘗試執(zhí)行會(huì)讓更多內(nèi)存被使用的命令。
  • allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數(shù)據(jù)有空間存放。
  • volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限于在過期集合的鍵,使得新添加的數(shù)據(jù)有空間存放。
  • allkeys-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放。
  • volatile-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放,但僅限于在過期集合的鍵。
  • volatile-ttl: 回收在過期集合的鍵,并且優(yōu)先回收存活時(shí)間(TTL)較短的鍵,使得新添加的數(shù)據(jù)有空間存放。

2、為什么 Redis 需要把所有數(shù)據(jù)放到內(nèi)存中?

Redis 為了達(dá)到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中,并通過異步的方式將數(shù)據(jù)寫入磁盤。

所以 redis 具有快速和數(shù)據(jù)持久化的特征,如果不將數(shù)據(jù)放在內(nèi)存中,磁盤 I/O 速度為嚴(yán)重影響 redis 的性能。

在內(nèi)存越來越便宜的今天,redis 將會(huì)越來越受歡迎, 如果設(shè)置了最大使用的內(nèi)存,則數(shù)據(jù)已有記錄數(shù)達(dá)到內(nèi)存限值后不能繼續(xù)插入新值。

3、Redis 如何做內(nèi)存優(yōu)化?

盡可能使用散列表(hashes),散列表(是說散列表里面存儲(chǔ)的數(shù)少)使用的內(nèi)存非常小,所以你應(yīng)該盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表里面。

比如你的 web 系統(tǒng)中有一個(gè)用戶對(duì)象,不要為這個(gè)用戶的名稱,姓氏,郵箱,密碼設(shè)置單獨(dú)的 key,而是應(yīng)該把這個(gè)用戶的所有信息存儲(chǔ)到一張散列表里面。

八. Kafka

1、Kafka 的設(shè)計(jì)是什么樣的呢?

Kafka 將消息以 topic 為單位進(jìn)行歸納
將向 Kafka topic 發(fā)布消息的程序成為 producers.
將預(yù)訂 topics 并消費(fèi)消息的程序成為 consumer.
Kafka 以集群的方式運(yùn)行,可以由一個(gè)或多個(gè)服務(wù)組成,每個(gè)服務(wù)叫做一個(gè) broker.
producers 通過網(wǎng)絡(luò)將消息發(fā)送到 Kafka 集群,集群向消費(fèi)者提供消息

2、數(shù)據(jù)傳輸?shù)氖挛锒x有哪三種?

數(shù)據(jù)傳輸?shù)氖聞?wù)定義通常有以下三種級(jí)別:

  • 最多一次: 消息不會(huì)被重復(fù)發(fā)送,最多被傳輸一次,但也有可能一次不傳輸
  • 最少一次: 消息不會(huì)被漏發(fā)送,最少被傳輸一次,但也有可能被重復(fù)傳輸.
  • 精確的一次(Exactly once): 不會(huì)漏傳輸也不會(huì)重復(fù)傳輸,每個(gè)消息都傳輸被一次而且僅僅被傳輸一次,這是大家所期望的

3、Kafka 高效文件存儲(chǔ)設(shè)計(jì)特點(diǎn):

  • Kafka 把 topic 中一個(gè) parition 大文件分成多個(gè)小文件段,通過多個(gè)小文件段,就容易定期清除或刪除已經(jīng)消費(fèi)完文件,減少磁盤占用。
  • 通過索引信息可以快速定位 message 和確定 response 的最大大小。
  • 通過 index 元數(shù)據(jù)全部映射到 memory,可以避免 segment file 的 IO 磁盤操作。
  • 通過索引文件稀疏存儲(chǔ),可以大幅降低 index 文件元數(shù)據(jù)占用空間大小。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、面向?qū)ο蟮奶卣饔心男┓矫? 答:面向?qū)ο蟮奶卣髦饕幸韵聨讉€(gè)方面: -- 抽象:抽象是將一類對(duì)象的共同特征總結(jié)...
    ccc_74bd閱讀 1,049評(píng)論 0 1
  • 一 基礎(chǔ)篇 1.1 Java基礎(chǔ) 面向?qū)ο蟮奶卣鞒橄?將一類對(duì)象的共同特征總結(jié)出來構(gòu)建類的過程。繼承:對(duì)已有類的一...
    essential_note閱讀 763評(píng)論 0 0
  • 不足的地方請(qǐng)大家多多指正,如有其它沒有想到的常問面試題請(qǐng)大家多多評(píng)論,一起成長(zhǎng),感謝!~ String可以被繼承嗎...
    啟示錄是真的閱讀 3,067評(píng)論 3 3
  • 包含的重點(diǎn)內(nèi)容:JAVA基礎(chǔ)JVM 知識(shí)開源框架知識(shí)操作系統(tǒng)多線程TCP 與 HTTP架構(gòu)設(shè)計(jì)與分布式算法數(shù)據(jù)庫(kù)知...
    消失er閱讀 4,549評(píng)論 1 10
  • 每個(gè)人難免會(huì)有情感泛濫的時(shí)候,當(dāng)夜幕籠罩一切的時(shí)候,心中的孤獨(dú)野獸便蘇醒了。作為一個(gè)寫文的人好就好在,他能夠用手中...
    杏筆閱讀 510評(píng)論 1 8

友情鏈接更多精彩內(nèi)容