华为java面试题
?
1、Java 常用集合及特點?
List:ArrayList、LinkedList、Vector、Stack Set:LinkedSet、HashSet、TreeSet
Queue->Deque->LinkedList。
Map:HashMap、LinkedHashMap、TreeMap Dictionary->HashTable->Properties。
Vector: 底層數據結構是數組,查詢快,增刪慢,線程安全,效率低,默認長度為 10,超過會 100%延長,變成 20,浪費空間。
ArrayList :基于數組,便于按 index 訪問,超過數組需要擴容,擴容成本較高。
LinkedList:使用鏈表實現,無需擴容。
74HashSet:底層數據結構是哈希表(無序,唯一),通過 hashcode()和 equals()保證元素唯一。
LinkedHashSet: 底層數據結構是鏈表和哈希表(FIFO 插入有序,唯一),由鏈表保證元素有序,由哈希表保證元素唯一。
TreeSet:底層數據結構是紅黑樹(唯一,有序),通過自然排序和比較器排序保證元素有序,根據比較返回值是否是 0 來保證元素唯一性。
TreeMap 是有序的。
HashMap :空間換時間,哈希沖突不大的情況下查找數據性能很高。
LinkedHashMap 基本特點:繼承自 HashMap,對 Entry 集合添加了一個雙向鏈表。
2、開啟一個線程的方法?
◆?繼承 Thread 類,新建一個當前類對象,并且運行其 start()方法
◆?實現 Runnable 接口,然后新建當前類對象,接著新建 Thread 對象時把當前類對象傳進去,最后運行 Thread 對象的 start()方法
◆?實現 Callable 接口,新建當前類對象,在新建 FutureTask 類對象時傳入當前類對象,接著新建 Thread 類對象時傳入 FutureTask 類對象,最后運行 Thread 對象的 start()
方法
3、Java 面向對象包括哪些特性,怎么理解的?
◆?封裝:通常認為封裝是把數據和操作數據的方法綁定起來,對數據的訪問只能通過已定義的接口。面向對象的本質就是將現實世界描繪成一系列完全自治、封閉的對象。我們在類中編寫的方法就是對實現細節的一種封裝;我們編寫一個類就是對數據和數據操作的封裝。
可以說,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡單的編程接口。
◆?繼承:繼承是從已有類得到繼承信息創建新類的過程。提供繼承信息的類被稱為父類(超類、基類);得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件系統有了一定的延續性,同時繼承也是封裝程序中可變因素的重要手段。
◆?多態:多態性是指允許不同子類型的對象對同一消息作出不同的響應。簡單的說就是用同樣的對象引用調用同樣的方法但是做了不同的事情。多態性分為編譯時的多態性和運行時的多態性。如果將對象的方法視為對象向外界提供的服務,那么運行時的多態性可以解釋為:當 A 系統訪問 B 系統提供的服務時,B 系統有多種提供服務的方式,但一切對 A 系統來說都是透明的。方法重載(overload)實現的是編譯時的多態性(也稱為前綁定),而方法重寫(override)實現的是運行時的多態性(也稱為后綁定)。運行時的多態是面向對象最精髓的東西,要實現多態需要做兩件事:
第一:方法重寫(子類繼承父類并重寫父類中已有的或抽象的方法);
第二:對象造型(用父類型引用指向子類型對象,這樣同樣的引用調用同樣的方法就會根據子類對象的不同而表現出不同的行為)。
◆?抽象:抽象是將一類對象的共同特征總結出來構造類的過程,包括數據抽象和行為抽象兩方面。抽象只關注對象有哪些屬性和行為,并不關注這些行為的細節是什么。
4、Java 如何保證線程安全?
◆?使用同步代碼塊
◆?使用同步方法
◆?使用 Lock 鎖機制, 通過創建 Lock 對象,采用 lock()加鎖,unlock()解鎖,來保護指定的代碼塊。
5、介紹 Spring MVC 的工作流程 ?
◆?用戶向服務端發送一次請求,這個請求會先到前端控制器 DispatcherServlet。
◆?DispatcherServlet 接收到請求后會調用 HandlerMapping 處理器映射器。由此得知,該請求該由哪個 Controller 來處理(并未調用 Controller,只是得知)
◆?DispatcherServlet 調用 HandlerAdapter 處理器適配器,告訴處理器適配器應該要去執行哪個 Controller
◆?HandlerAdapter 處理器適配器去執行 Controller 并得到 ModelAndView(數據和視圖), 并層層返回給 DispatcherServlet
◆?DispatcherServlet 將 ModelAndView 交給 ViewReslover 視圖解析器解析,然后返回真正的視圖。
◆?DispatcherServlet 將模型數據填充到視圖中
◆?DispatcherServlet 將結果響應給用戶
6、Spring 框架中用到了哪些設計模式?
◆?工廠設計模式 : Spring 使用工廠模式通過 BeanFactory、ApplicationContext 創建bean 對象。
◆?代理設計模式 : Spring AOP 功能的實現。
◆?單例設計模式 : Spring 中的 Bean 默認都是單例的。
◆?模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結尾的對數據庫操作的類,它們就使用到了模板模式。
◆?包裝器設計模式 : 我們的項目需要連接多個數據庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的數據庫。這種模式讓我們可以根據客戶的需求能夠動態切換不同的數據源。
◆?觀察者模式: Spring 事件驅動模型就是觀察者模式很經典的一個應用。
◆?適配器模式 : Spring AOP 的增強或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配 Controller。
767、Redis 的特點是什么?
Redis 本質上是一個 Key-Value 類型的內存數據庫,很像 Memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據 flush 到硬盤上進行保存。
因為是純內存操作,Redis 的性能非常出色,每秒可以處理超過 10 萬次讀寫操作,是已知性能最快的 Key-Value DB。
Redis 的出色之處不僅僅是性能,Redis 最大的魅力是支持保存多種數據結構,此外單個value 的最大限制是 1GB,不像 Memcached 只能保存 1MB 的數據,因此 Redis 可以用來實現很多有用的功能。
比方說用他的 List 來做 FIFO 雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set 可以做高性能的 tag 系統等等。另外 Redis 也可以對存入的 Key-Value 設置 expire時間,因此也可以被當作一 個功能加強版的 Memcached 來用。
Redis 的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此 Redis 適合的場景主要局限在較小數據量的高性能操作和運算上。
8、為什么使用 Redis,有什么好處?
◆?速度快,因為數據存在內存中,類似于 HashMap,HashMap 的優勢就是查找和操作的時間復雜度都是 O(1)
◆?支持豐富數據類型,支持 string,list,set,sorted set,hash
◆?支持事務,操作都是原子性,所謂的原子性就是對數據的更改要么全部執行,要么全部不執行
◆?豐富的特性:可用于緩存,消息,按 key 設置過期時間,過期后將會自動刪除
9、Redis 雪崩和擊穿了解嗎?
緩存擊穿
◆?問題:某個 KEY 失效的時候,正好有大量并發請求訪問這個 KEY。
◆?分析:跟穿透其實很像,屬于比較偶然的。
◆?解決辦法:KEY 的更新操作添加全局互斥鎖。完全以緩存為準,使用延遲異步加載的策略(異步線程負責維護緩存的數據,定期或根據條件觸發更新),這樣就不會觸發更新。
緩存雪崩
◆?問題:當某一時刻發生大規模的緩存失效的情況,導致大量的請求無法獲取數據,從而將流量壓力傳導到數據庫上,導致數據庫壓力過大甚至宕機。
◆?原因:一般而言,緩存雪崩有 2 種可能性:大量的數據同一個時間失效:比如業務關系強相關的數據要求同時失效 Redis 宕機
◆?分析:一般來說,由于更新策略、或者數據熱點、緩存服務宕機等原因,可能會導致緩存數據同一個時間點大規模不可用,或者都更新。所以,需要我們的更新策略要在時間上合適,數據要均勻分享,緩存服務器要多臺高可用。
◆?解決辦法:更新策略在時間上做到比較平均。如果數據需要同一時間失效,可以給這批數據加上一些隨機值,使得這批數據不要在同一個時間過期,降低數據庫的壓力。使用的熱數據盡量分散到不同的機器上。多臺機器做主從復制或者多副本,實現高可用。做好主從的部署,當主節點掛掉后,能快速的使用從結點頂上。實現熔斷限流機制,對系統進行負載能力控制。對于非核心功能的業務,拒絕其請求,只允許核心功能業務訪問數據庫獲取數據。服務降價:提供默認返回值,或簡單的提示信息。
10、什么是面向對象,談談你的理解?
世間萬物都可以看成一個對象。每個物體包括動態的行為和靜態的屬性,這些就構成了一個對象。
11、訪問數據庫除了 JDBC 還有什么?
◆?自己封裝 JDBC 的工具類
◆?Commons-Dbutils+dbcp【QueryRunner】
◆?SpringJDBC【JdbcTemplate】
◆?JPA【配置文件、domain 實體類+注解、EntityManager】
◆?SpringDataJpa
◆?Hibernate 框架
◆?Mybatis
12、你知道有哪些設計原則?
◆?遵循單一職責原則
◆?開放-封閉原則
◆?里氏代換原則(LSP)
◆?依賴倒置原則
◆?接口隔離原則(Interface Segregation Principle)
◆?迪米特法則(Law of Demeter)
13、在生產環境 Linux 服務器上,發現某臺運行 Java 服務的服務器的CPU100%,不借助任何可視化工具,怎么進行問題的定位?
◆?top 找出進程 CPU 比較高 PID
◆?top -Hp PID 打印 該 PID 進程下哪條線程的 CPU 占用比較高 tid
◆?printf “%x\n” tid 將該 id 進行 16 進制轉換 tidhex
◆?jstack PID |grep tidhex 打印線程的堆棧信息
14、JDK 里面帶的工具你知道哪些?
◆?jstat:虛擬機進程狀況工具
◆?jinfo:Java 配置信息工具
◆?jmap:Java 內存映像工具
◆?jhat:虛擬機堆轉儲快照分析工具
◆?jstack:Java 堆棧跟蹤工具
◆?JConsole: Java 監視與管理控制臺
◆?VisualVM: 多合一故障處理工具
15、基本數據類型 bit 長度?
◆?byte:1*8
◆?short:2*8
◆?int: 4*8
◆?long: 8*8
◆?float: 4*8
◆?double: 8*8
◆?char: 2*8
◆?boolean: 1*8
16、char 能不能存中文?
可以,不過,如果某個特殊的漢字沒有被包含在 unicode 編碼字符集中,那么,這個 char型變量中就不能存儲這個特殊漢字。
17、談談你對泛型的理解?
Java 中的泛型有 3 種形式,泛型方法,泛型類,泛型接口。Java 通過在編譯時類型擦除的方式來實現泛型。擦除時使用 Object 或者界定類型替代泛型,同時在要調用具體類型方法或者成員變量的時候插入強轉代碼,為了保證多態特性,Java 編譯器還會為泛型類的子類生成橋接方法。類型信息在編譯階段被擦除之后,程序在運行期間無法獲取類型參數所對應的具體類型。
18、Java 程序是怎樣運行的?
◆?首先通過 Javac 編譯器將 .java 轉為 JVM 可加載的 .class 字節碼文件。
◆?Javac 是由 Java 編寫的程序,編譯過程可以分為:
- 詞法解析,通過空格分割出單詞、 操作符、控制符等信息,形成 token 信息流,傳遞給語法解析器。
- ?語法解析,把token 信息流按照 Java 語法規則組裝成語法樹。
- ?語義分析,檢查關鍵字使用是否合理、類型是否匹配、作用域是否正確等。
- 字節碼生成,將前面各個步驟的信息轉換為字節碼。
◆?字節碼必須通過類加載過程加載到 JVM 后才可以執行,執行有三種模式,解釋執行、JIT編譯執行、JIT 編譯與解釋器混合執行(主流 JVM 默認執行的方式)?;旌夏J降膬瀯菰谟诮忉屍髟趩訒r先解釋執行,省去編譯時間。
◆?之后通過即時編譯器 JIT 把字節碼文件編譯成本地機器碼。
◆?Java 程序最初都是通過解釋器進行解釋執行的,當虛擬機發現某個方法或代碼塊的運行特別頻繁,就會認定其為"熱點代碼",熱點代碼的檢測主要有基于采樣和基于計數器兩種方式,為了提高熱點代碼的執行效率,虛擬機會把它們編譯成本地機器碼,盡可能對代碼優化,在運行時完成這個任務的后端編譯器被稱為即時編譯器。
◆?還可以通過靜態的提前編譯器 AOT 直接把程序編譯成與目標機器指令集相關的二進制代碼。
19、GC root 有哪些?
◆?Thread-存活的線程。
◆?Java 虛擬機棧中的引用的對象。
◆?方法區中的類靜態屬性引用的對象。 (一般指被 static 修飾的對象,加載類的時候就加載到內存中。)
◆?方法區中的常量引用的對象。
◆?本地方法棧中的 JNI(native 方法)引用的對象。
◆?Monitor Used-用于同步監控的對象。
20、棧幀的大小什么時候確定?
有時候編譯期能夠確定,有些時候函數的棧幀的大小在編譯期并不確定。比如用了 VLA。所以一般會有兩個寄存器(IA-32 上就是 ebp 和 esp)來記錄棧幀的首尾地址。當進入一個函數時,首先把上個棧幀的首尾地址分別保存起來(一般做法是將 ebp 壓棧、并將 esp 寫 ebp),接著再分配新的棧幀大小(先給 esp 減一個常數,如果需要動態分配再接著減)。
21、靜態 filed 聲明和構造器哪個先執行?
filed 聲明先執行。
22、線程創建方式是什么?
◆?通過繼承 Thread 類創建線程類
◆?實現 Runnable 接口創建線程類
◆?通過 Callable 和 Future 接口創建線程81
23、傳統 I/O 跟 NIO 的區別?
◆?所有 I/O 都被視為單個的字節的移動,通過一個稱為 Stream 的對象一次移動一個字節。
流 I/O 用于與外部世界接觸。它也在內部使用,用于將對象轉換為字節,然后再轉換回對象。傳統流 IO 的好處是使用簡單,將底層的機制都抽象成流,但缺點就是性能不足。而且 IO 的各種流是阻塞的。這意味著,當一個線程調用 read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再干任何事情了。
◆?原來的 I/O 庫(在 java.io.*中) 與 NIO 最重要的區別是數據打包和傳輸的方式。 原來的I/O 以流的方式處理數據,而 NIO 以塊的方式處理數據。
◆?NIO 性能的優勢就來源于緩沖的機制(buffer 機制),不管是讀或者寫都需要以塊的形式寫入到緩沖區中。NIO 實際上讓我們對 IO 的操作更接近于操作系統的實際過程。
◆?NIO 作為非阻塞式的 IO,它的優點就在于,1、它由一個專門的線程去處理所有的 IO
事件,并負責分發;2、事件驅動,只有事件到了才會觸發,而不是同步的監聽這個事件;
3、線程之間通過 wait,notify 等方式通訊。保證每次上下文切換都是有意義的。減少無謂的線程切換。
◆?當我們在執行持續性的操作(如上傳下載)時,IO 的方式是要優于 NIO 的。分清情況,合理選用。
◆?NIO 相對于 IO 流的優勢:
非阻塞buffer 機制 流替代塊
24、消息隊列的在各種場景下如何選型?
◆?優先級隊列;隊列設置最大的優先級,之后每條消息設置對應的優先級,隊列根據消息優先級進行消費,(在有可能隊列堆積的情況才有意義);應用場景:不同業務消息推送。
◆?延遲隊列:消息發送后,并不想讓消費者立即拿到消息,等待特定的事件后,消費者才能拿到并消費;應用場景:訂單系統中訂單支付 30 分鐘內沒有支付成功,那么將這個訂單進行異常處理;遠程操作智能設備在指定時間進行工作等。(rabbit 中沒有延遲隊列,但可以借助死信隊 列與 TTL 設置來完成)
◆?死信隊列:當消息在一個隊列中變成死信之后,它能被重新被發送到另一個交換器(DLX交換器)中,綁定 DLX 的隊列就稱為死信隊列。
◆?重試隊列:消費端,一直不回傳消費的結果,rocketmq 認為消息沒收到,consumer 下一次拉取,broker 依然會發送該消息(有次數限制)。重試隊列其實可以看成是一種回退隊列,具體指消費端消費消息失敗時,為防止消息無故丟失而重新將消息回滾到Broker 中。
◆?消費模式: 推模式:對于 kafka 而言,由 Broker 主動推送消息至消費端,實時性較好,不過需要一定的流 制機制來確保服務端推送過來的消息不會壓垮消費端。拉模式:對于kafka 而言,消費端主動向 Broker 端請求拉取(一般是定時或者定量)消息,實時性較推模式差,但是可以根據自身的處理能力而控制拉取的消息量。
◆?消息回溯:重置消息 offset(如:kafka、rokcetMq) 一般消息在消費完成之后就被處理了,之后再也不能消費到該條消息。消息回溯正好相反,是指消息在消費完成之后,還能消費到之前被消費掉的消息。對于消息而言,經常面臨的問題是“消息丟失”,至于是真正由于消息中間件的缺陷丟失還是由于使用方的誤用而丟失一般很難追查,如果消息中間件本身具備消息回溯功能的話,可以通過回溯消費復現“丟失的”消息 進而查出問題的源頭之所在。消息回溯的作用遠不止與此,比如還有索引恢復、本地緩存重建,有些業務補償方案也可以采用回溯的方式來實現。
◆?消息堆積:流量削峰是消息中間件的一個非常重要的功能,而這個功能其實得益于其消息堆積能力。從某種意義上來講,如果一個消息中間件不具備消息堆積的能力,那么就不能把它看做是一個合格的消息中間件。消息堆積分內存式堆積和磁盤式堆積。
◆?消息持久化:持久化確保 MQ 的使用不只是一個部分場景的輔助工具,而是讓 MQ 能像數據庫一樣存儲核心的數據。有些功能是默認不開啟的,需要進行配置。
◆?多租戶: 也可以稱為多重租賃技術,是一種軟件架構技術,主要用來實現多用戶的環境下公用相同的系統或程序組件,并且仍可以確保各用戶間數據的隔離性。RabbitMQ 就能夠支持多租戶技術,每一個租戶表示為一個 vhost,其本質上是一個獨立的小型 RabbitMQ服務器,又有自己獨立 的隊列、交換器及綁定關系等,并且它擁有自己獨立的權限。vhost 就像是物理機中的虛擬機 一樣,它們在各個實例間提供邏輯上的分離,為不同程序安全保密地允許數據,它既能將同一 個 RabbitMQ 中的眾多客戶區分開,又可以避免隊列和交換器等命名沖突。
◆?跨語言支持: 對很多公司而言,其技術棧體系中會有多種編程語言,如 C/C++、JAVA、Go、PHP 等,消息 中間件本身具備應用解耦的特性,如果能夠進一步的支持多客戶端語言,那么就可以將此特性 的效能擴大??缯Z言的支持力度也可以從側面反映出一個消息中間件的流行程度。
◆?消息順序消息:先進先出、 逐條進行消費顧名思義,消息順序性是指保證消息有序。這個功能有個很常見的應用場景就是 CDC(Change Data Chapture),以 MySQL 為例,如果其傳輸的 binlog 的順序出錯,比如原本是先對一條數據加 1,然后再乘以 2,發送 錯序之后就變成了先乘以 2 后加 1 了,造成了數據不一致。
◆?安全機制: 在 Kafka 0.9 版本之后就開始增加了身份認證和權限控制兩種安全機制。身份認證是指客戶端與服務端連接進行身份認證,包括客戶端與 Broker 之間、Broker 與Broker 之間、Broker 與 ZooKeeper 之間的連接認證,目前支持 SSL、SASL 等認證機制。權限控制是指對客戶端的讀寫操作進行權限控制,包括對消息或 Kafka 集群操作權限控制。權限控制是可插拔的,并支持與外部的授權服務進行集成。對于 RabbitMQ而言,其同樣提供身份認證(TLS/SSL、SASL)和 權限控制(讀寫操作)的安全機制。
◆?事務支持: 事務本身是一個并不陌生的詞匯,事務是由事務開始(Begin Transaction)和事務結束(End Transaction)之間執行的全體操作組成。支持事務的消息中間件并不在少數,Kafka 和 RabbitMQ 都支持,不過此兩者的事務是指生產者發生消息的事務,要么發送成功,要么發送失敗。消息中間件可以作為用來實現分布式事務的一種手段,但其本身并不提供全局分布式事務的功能。
25、Java 的安全性體現在哪里?
◆?Java SE 安全性概述 Java SE
◆?平臺基于一個動態、可擴展、基于標準、可互操作的安全架構。加密、身份驗證和授權、公共密鑰基礎架構等安全特性是內置的。Java
◆?安全模型基于一個可定制的“沙盒”,Java 軟件程序可在其中安全運行,對系統或用戶無潛在風險。
◆?Java 編譯器和虛擬機強制實施的內置的語言安全特性:
◆?強大的數據類型管理
◆?自動內存管理
◆?字節碼驗證
◆?安全的類加載
26、static 方法怎么訪問非 static 變量?
類的靜態成員(變量和方法)都屬于類本身,在類加載的時候就會分配內存,可以通過類名直接訪問
27、講下你理解的 Java 多繼承?
◆?若子類繼承的父類中擁有相同的成員變量,子類在引用該變量時將無法判別使用哪個父類的成員變量
◆?若一個子類繼承的多個父類擁有相同方法,同時子類并未覆蓋該方法(若覆蓋,則直接使用子類中該方法),那么調用該方法時將無法確定調用哪個父類的方法。
28、Java 基本類型有哪些?
◆?byte 1
◆?short 2
◆?int 4
◆?long 8
◆?float 4
◆?double 8
◆?char 2
◆?boolean 1
29、線程池如果滿了會怎么樣?
83◆?如果使用的是無界隊列 Linke dBlockingQueue,也就是無界隊列的話,沒關系,繼續添加任務到阻塞隊列中等待執行,因為 LinkedBlockingQueue 可以近乎認為是一個無窮大的隊列,可以無限存放任務
◆?如果使用的是有界隊列比如 ArrayBlockingQueue , 任務首先會被添加到ArrayBlockingQueue 中,ArrayBlockingQueue 滿了,會根據 maximumPoolSize 的 值增加線程數量,如果增加了線程數量還是處理不過來,ArrayBlockingQueue 繼續滿,那么則會使用拒絕策略 RejectedExecutionHandler 處理滿了的任務,默認是AbortPolicy。
30、什么是雙親委派機制,它有什么作用?
雙親委派機制的意思是除了頂層的啟動類加載器以外,其余的類加載器,在加載之前,都會委派給它的父加載器進行加載。這樣一層層向上傳遞,直到祖先們都無法勝任,它才會真正的加載。
◆?通過帶有優先級的層級關可以避免類的重復加載;
◆?保證 Java 程序安全穩定運行,Java 核心 API 定義類型不會被隨意替換。
?
總結
- 上一篇: 手机c语言编译器ide文件位置,C语言编
- 下一篇: 图论及其应用 2016年 期末考试 答案