<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          第一次面阿里,難繃!

          共 17837字,需瀏覽 36分鐘

           ·

          2024-05-27 15:30

          圖解學習網站:https://xiaolincoding.com

          大家好,我是小林。

          今天分享的是一位讀者的阿里巴巴Java后端的面經,阿里畢竟是 Java 大廠,這次的面試重點是以 Java 為主,MySQL+網絡為輔。

          感覺問的問題還挺多的,面試時長有 1小時+,壓力不小,面試官一直追問。

          面試考察的內容,我?guī)痛蠹伊_列一下:

          • MySQL:事務、數據庫文件、索引、MVCC
          • 網絡:HTTP報文、HTTP狀態(tài)碼
          • Java 框架:mybatis、springIoc、spirngAop、springMVC
          • Java八股:設計模式、多線程并發(fā)問題、線程池、集合、面向對象

          問題記錄

          MySQL

          可重復讀,已提交讀,這兩個隔離級別表現的現象是什么,區(qū)別是什么樣的?

          • 讀提交,指一個事務提交之后,它做的變更才能被其他事務看到,會有不可重復讀、幻讀的問題。
          • 可重復讀,指一個事務執(zhí)行過程中看到的數據,一直跟這個事務啟動時看到的數據是一致的,MySQL InnoDB 引擎的默認隔離級別,解決了不可重復讀的問題,并且以很大程度上避免幻讀現象的發(fā)生。

          數據管理里,數據文件大體分成哪幾種數據文件?

          我們每創(chuàng)建一個 database(數據庫) 都會在 /var/lib/mysql/ 目錄里面創(chuàng)建一個以 database 為名的目錄,然后保存表結構和表數據的文件都會存放在這個目錄里。比如,我這里有一個名為 my_test 的 database,該 database 里有一張名為 t_order 數據庫表。然后,我們進入 /var/lib/mysql/my_test 目錄,看看里面有什么文件?

          [root@xiaolin ~]#ls /var/lib/mysql/my_test
          db.opt  
          t_order.frm  
          t_order.ibd

          可以看到,共有三個文件,這三個文件分別代表著:

          • db.opt,用來存儲當前數據庫的默認字符集和字符校驗規(guī)則。
          • t_order.frm ,t_order 的表結構會保存在這個文件。在 MySQL 中建立一張表都會生成一個.frm 文件,該文件是用來保存每個表的元數據信息的,主要包含表結構定義。
          • t_order.ibd,t_order 的表數據會保存在這個文件。表數據既可以存在共享表空間文件(文件名:ibdata1)里,也可以存放在獨占表空間文件(文件名:表名字.ibd)。這個行為是由參數 innodb_file_per_table 控制的,若設置了參數 innodb_file_per_table 為 1,則會將存儲的數據、索引等信息單獨存儲在一個獨占表空間,從 MySQL 5.6.6 版本開始,它的默認值就是 1 了,因此從這個版本之后, MySQL 中每一張表的數據都存放在一個獨立的 .ibd 文件。

          日志文件是分成了哪幾種?

          • redo log 重做日志,是 Innodb 存儲引擎層生成的日志,實現了事務中的持久性,主要用于掉電等故障恢復;
          • undo log 回滾日志,是 Innodb 存儲引擎層生成的日志,實現了事務中的原子性,主要用于事務回滾和 MVCC。
          • bin log 二進制日志,是 Server 層生成的日志,主要用于數據備份和主從復制;
          • relay log 中繼日志,用于主從復制場景下,slave通過io線程拷貝master的bin log后本地生成的日志
          • 慢查詢日志,用于記錄執(zhí)行時間過長的sql,需要設置閾值后手動開啟

          說下MVCC機制的原理?

          MVCC就是多版本并發(fā)控制,實現了讀寫的并發(fā)控制,在mysql通過readview 隱藏字段和undolog實現了,比如在可重復讀里面,比如開啟了一個事務,就生成了一個readview,然后記錄現在active的事務,判斷查詢的數據在這個事務可不可讀。

          索引的類型有哈希索引,B+樹索引,而hash索引的時間復雜度是o1,那為什么我們一般情況下不使用哈希索引,而使用b+樹索引呢?

          • 哈希索引的key是經過hash運算得出的,即跟實際數據的值沒有關系,因此哈希索引不適用于范圍查詢和排序操作
          • 容易導致全表掃描,因為可能存在不同的key經過hash運算后值相同
          • 索引列上的值相同的話,易造成hash沖突,效率低下

          對一個慢sql怎么去排查?

          • 可通過開啟mysql的慢日志查詢,設置好時間閾值,進行捕獲慢 sql
          • 針對慢 sql,進行 explian 去查看執(zhí)行計劃

          索引字段是不是建的越多越好?

          不是,建的的越多會占用越多的空間,而且在寫入頻繁的場景下,對于B+樹的維護所付出的性能消耗也會越大

          網絡

          http協議的報文的格式有了解嗎?

          分請求報文和響應報文來說明。請求報文:在這里插入圖片描述

          • 請求行:包含請求方法、請求目標(URL或URI)和HTTP協議版本。
          • 請求頭部:包含關于請求的附加信息,如Host、User-Agent、Content-Type等。
          • 空行:請求頭部和請求體之間用空行分隔。
          • 請求體:可選,包含請求的數據,通常用于POST請求等需要傳輸數據的情況。

          響應報文:

          • 狀態(tài)行:包含HTTP協議版本、狀態(tài)碼和狀態(tài)信息。
          • 響應頭部:包含關于響應的附加信息,如Content-Type、Content-Length等。
          • 空行:響應頭部和響應體之間用空行分隔。
          • 響應體:包含響應的數據,通常是服務器返回的HTML、JSON等內容。

          http常用的狀態(tài)碼?

          HTTP 狀態(tài)碼分為 5 大類:1XX:表示消息狀態(tài)碼;2XX:表示成功狀態(tài)碼;3XX:表示重定向狀態(tài)碼;4XX:表示客戶端錯誤狀態(tài)碼;5XX:表示服務端錯誤狀態(tài)碼。五大類 HTTP 狀態(tài)碼 其中常見的具體狀態(tài)碼有:200:請求成功;301:永久重定向;302:臨時重定向;404:無法找到此頁面;405:請求的方法類型不支持;500:服務器內部出錯。

          Java框架

          java這一塊對框架都是熟悉的吧?

          還行,用過SSM。

          MyBatis運用了哪些常見的設計模式?

          • 建造者模式(Builder),如:SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder等;
          • 工廠模式,如:SqlSessionFactory、ObjectFactory、MapperProxyFactory;
          • 單例模式,例如ErrorContext和LogFactory;
          • 代理模式,Mybatis實現的核心,比如MapperProxy、ConnectionLogger,用的jdk的動態(tài)代理;還有executor.loader包使用了cglib或者javassist達到延遲加載的效果;
          • 組合模式,例如SqlNode和各個子類ChooseSqlNode等;
          • 模板方法模式,例如BaseExecutor和SimpleExecutor,還有BaseTypeHandler和所有的子類例如IntegerTypeHandler;
          • 適配器模式,例如Log的Mybatis接口和它對jdbc、log4j等各種日志框架的適配實現;
          • 裝飾者模式,例如Cache包中的cache.decorators子包中等各個裝飾者的實現;
          • 迭代器模式,例如迭代器模式PropertyTokenizer;

          MyBatis中創(chuàng)建了一個Mapper接口,在寫一個xml文件,java的接口是要實現的,為什么這沒有實現呢?

          因為執(zhí)行Sql所需要的所有的JDBC操作都在Mybatis的MapperProxy中實現了,所以不需要實現類。

          與傳統的JDBC相比,MyBatis的優(yōu)點?

          • 基于 SQL 語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任 何影響,SQL 寫在 XML 里,解除 sql 與程序代碼的耦合,便于統一管理;提供 XML 標簽,支持編寫動態(tài) SQL 語句,并可重用。
          • 與 JDBC 相比,減少了 50%以上的代碼量,消除了 JDBC 大量冗余的代碼,不 需要手動開關連接;
          • 很好的與各種數據庫兼容,因為 MyBatis 使用 JDBC 來連接數據庫,所以只要 JDBC 支持的數據庫 MyBatis 都支持。
          • 能夠與 Spring 很好的集成,開發(fā)效率高
          • 提供映射標簽,支持對象與數據庫的 ORM 字段關系映射;提供對象關系映射 標簽,支持對象關系組件維護。

          還記得JDBC連接數據庫的步驟嗎?

          使用Java JDBC連接數據庫的一般步驟如下:

          1. 加載數據庫驅動程序:在使用JDBC連接數據庫之前,需要加載相應的數據庫驅動程序。可以通過 Class.forName("com.mysql.jdbc.Driver") 來加載MySQL數據庫的驅動程序。不同數據庫的驅動類名會有所不同。
          2. 建立數據庫連接:使用 DriverManager 類的 getConnection(url, username, password) 方法來連接數據庫,其中url是數據庫的連接字符串(包括數據庫類型、主機、端口等)、username是數據庫用戶名,password是密碼。
          3. 創(chuàng)建 Statement 對象:通過 Connection 對象的 createStatement() 方法創(chuàng)建一個 Statement 對象,用于執(zhí)行 SQL 查詢或更新操作。
          4. 執(zhí)行 SQL 查詢或更新操作:使用 Statement 對象的 executeQuery(sql) 方法來執(zhí)行 SELECT 查詢操作,或者使用 executeUpdate(sql) 方法來執(zhí)行 INSERT、UPDATE 或 DELETE 操作。
          5. 處理查詢結果:如果是 SELECT 查詢操作,通過 ResultSet 對象來處理查詢結果??梢允褂?ResultSet 的 next() 方法遍歷查詢結果集,然后通過 getXXX() 方法獲取各個字段的值。
          6. 關閉連接:在完成數據庫操作后,需要逐級關閉數據庫連接相關對象,即先關閉 ResultSet,再關閉 Statement,最后關閉 Connection。

          以下是一個簡單的示例代碼:

          import java.sql.*;

          public class Main {
              public static void main(String[] args) {
                  try {
                      // 加載數據庫驅動程序
                      Class.forName("com.mysql.cj.jdbc.Driver");

                      // 建立數據庫連接
                      Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase""username""password");

                      // 創(chuàng)建 Statement 對象
                      Statement statement = connection.createStatement();

                      // 執(zhí)行 SQL 查詢
                      ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable");

                      // 處理查詢結果
                      while (resultSet.next()) {
                        // 處理每一行數據
                      }

                      // 關閉資源
                      resultSet.close();
                      statement.close();
                      connection.close();
                  } catch (ClassNotFoundException e) {
                      e.printStackTrace();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }

          請注意,在實際應用中,需要進行異常處理以確保資源的正確釋放,以及使用 try-with-resources 來簡化代碼和確保資源的及時關閉。

          怎么理解SpringIoc?

          IOC:Inversion Of Control,即控制反轉,是一種設計思想。在傳統的 Java SE 程序設計中,我們直接在對象內部通過 new 的方式來創(chuàng)建對象,是程序主動創(chuàng)建依賴對象;

          而在Spring程序設計中,IOC 是有專門的容器去控制對象。

          所謂控制就是對象的創(chuàng)建、初始化、銷毀。

          • 創(chuàng)建對象:原來是 new 一個,現在是由 Spring 容器創(chuàng)建。
          • 初始化對象:原來是對象自己通過構造器或者 setter 方法給依賴的對象賦值,現在是由 Spring 容器自動注入。
          • 銷毀對象:原來是直接給對象賦值 null 或做一些銷毀操作,現在是 Spring 容器管理生命周期負責銷毀對象。

          總結:IOC 解決了繁瑣的對象生命周期的操作,解耦了我們的代碼。所謂反轉:其實是反轉的控制權,前面提到是由 Spring 來控制對象的生命周期,那么對象的控制就完全脫離了我們的控制,控制權交給了 Spring 。這個反轉是指:我們由對象的控制者變成了 IOC 的被動控制者。

          如果讓你設計一個SpringIoc,你覺得會從哪些方面考慮這個設計?

          • Bean的生命周期管理:需要設計Bean的創(chuàng)建、初始化、銷毀等生命周期管理機制,可以考慮使用工廠模式和單例模式來實現。
          • 依賴注入:需要實現依賴注入的功能,包括屬性注入、構造函數注入、方法注入等,可以考慮使用反射機制和XML配置文件來實現。
          • Bean的作用域:需要支持多種Bean作用域,比如單例、原型、會話、請求等,可以考慮使用Map來存儲不同作用域的Bean實例。
          • AOP功能的支持:需要支持AOP功能,可以考慮使用動態(tài)代理機制和切面編程來實現。
          • 異常處理:需要考慮異常處理機制,包括Bean創(chuàng)建異常、依賴注入異常等,可以考慮使用try-catch機制來處理異常。
          • 配置文件加載:需要支持從不同的配置文件中加載Bean的相關信息,可以考慮使用XML、注解或者Java配置類來實現。

          Spring給我們提供了很多擴展點,這些有了解嗎?

          Spring框架提供了許多擴展點,使得開發(fā)者可以根據需求定制和擴展Spring的功能。以下是一些常用的擴展點:

          1. BeanFactoryPostProcessor:允許在Spring容器實例化bean之前修改bean的定義。常用于修改bean屬性或改變bean的作用域。
          2. BeanPostProcessor:可以在bean實例化、配置以及初始化之后對其進行額外處理。常用于代理bean、修改bean屬性等。
          3. PropertySource:用于定義不同的屬性源,如文件、數據庫等,以便在Spring應用中使用。
          4. ImportSelector和ImportBeanDefinitionRegistrar:用于根據條件動態(tài)注冊bean定義,實現配置類的模塊化。
          5. Spring MVC中的HandlerInterceptor:用于攔截處理請求,可以在請求處理前、處理中和處理后執(zhí)行特定邏輯。
          6. Spring MVC中的ControllerAdvice:用于全局處理控制器的異常、數據綁定和數據校驗。
          7. Spring Boot的自動配置:通過創(chuàng)建自定義的自動配置類,可以實現對框架和第三方庫的自動配置。
          8. 自定義注解:創(chuàng)建自定義注解,用于實現特定功能或約定,如權限控制、日志記錄等。

          servlet有寫過簡單的代碼嗎?

          沒用框架之前,就用的servlet,用了框架就用的框架

          大致了解SpringMVC的處理流程嗎?

          Spring MVC的工作流程如下:

          1. 用戶發(fā)送請求至前端控制器DispatcherServlet
          2. DispatcherServlet收到請求調用處理器映射器HandlerMapping。
          3. 處理器映射器根據請求url找到具體的處理器,生成處理器執(zhí)行鏈HandlerExecutionChain(包括處理器對象和處理器攔截器)一并返回給DispatcherServlet。
          4. DispatcherServlet根據處理器Handler獲取處理器適配器HandlerAdapter執(zhí)行HandlerAdapter處理一系列的操作,如:參數封裝,數據格式轉換,數據驗證等操作
          5. 執(zhí)行處理器Handler(Controller,也叫頁面控制器)。
          6. Handler執(zhí)行完成返回ModelAndView
          7. HandlerAdapter將Handler執(zhí)行結果ModelAndView返回到DispatcherServlet
          8. DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
          9. ViewReslover解析后返回具體View
          10. DispatcherServlet對View進行渲染視圖(即將模型數據model填充至視圖中)。
          11. DispatcherServlet響應用戶。

          Handlermapping 和 handleradapter有了解嗎?

          HandlerMapping:

          • 作用:HandlerMapping負責將請求映射到處理器(Controller)。
          • 功能:根據請求的URL、請求參數等信息,找到處理請求的 Controller。
          • 類型:Spring提供了多種HandlerMapping實現,如BeanNameUrlHandlerMapping、RequestMappingHandlerMapping等。
          • 工作流程:根據請求信息確定要請求的處理器(Controller)。HandlerMapping可以根據URL、請求參數等規(guī)則確定對應的處理器。

          HandlerAdapter:

          • 作用:HandlerAdapter負責調用處理器(Controller)來處理請求。
          • 功能:處理器(Controller)可能有不同的接口類型(Controller接口、HttpRequestHandler接口等),HandlerAdapter根據處理器的類型來選擇合適的方法來調用處理器。
          • 類型:Spring提供了多個HandlerAdapter實現,用于適配不同類型的處理器。
          • 工作流程:根據處理器的接口類型,選擇相應的HandlerAdapter來調用處理器。

          工作流程:

          1. 當客戶端發(fā)送請求時,HandlerMapping根據請求信息找到對應的處理器(Controller)。
          2. HandlerAdapter根據處理器的類型選擇合適的方法來調用處理器。
          3. 處理器執(zhí)行相應的業(yè)務邏輯,生成ModelAndView。
          4. HandlerAdapter將處理器的執(zhí)行結果包裝成ModelAndView。
          5. 視圖解析器根據ModelAndView找到對應的視圖進行渲染。
          6. 將渲染后的視圖返回給客戶端。

          HandlerMapping和HandlerAdapter協同工作,通過將請求映射到處理器,并調用處理器來處理請求,實現了請求處理的流程。它們的靈活性使得在Spring MVC中可以支持多種處理器和處理方式,提高了框架的擴展性和適應性。

          SpringAOP主要想解決什么問題

          它的目的是對于面向對象思維的一種補充,而不是像引入命令式、函數式編程思維讓他順應另一種開發(fā)場景。在我個人的理解下AOP更像是一種對于不支持多繼承的彌補,除開對象的主要特征(我更喜歡叫“強共性”)被抽象為了一條繼承鏈路,對于一些“弱共性”,AOP可以統一對他們進行抽象和集中處理。

          舉一個簡單的例子,打印日志。需要打印日志可能是許多對象的一個共性,這在企業(yè)級開發(fā)中十分常見,但是日志的打印并不反應這個對象的主要共性。而日志的打印又是一個具體的內容,它并不抽象,所以它的工作也不可以用接口來完成。而如果利用繼承,打印日志的工作又橫跨繼承樹下面的多個同級子節(jié)點,強行侵入到繼承樹內進行歸納會干擾這些強共性的區(qū)分。

          這時候,我們就需要AOP了。AOP首先在一個Aspect(切面)里定義了一些Advice(增強),其中包含具體實現的代碼,同時整理了切入點,切入點的粒度是方法。最后,我們將這些Advice織入到對象的方法上,形成了最后執(zhí)行方法時面對的完整方法。

          SpringAOP的原理了解嗎

          Spring AOP的實現依賴于動態(tài)代理技術。動態(tài)代理是在運行時動態(tài)生成代理對象,而不是在編譯時。它允許開發(fā)者在運行時指定要代理的接口和行為,從而實現在不修改源碼的情況下增強方法的功能。Spring AOP支持兩種動態(tài)代理:

          • 基于JDK的動態(tài)代理:使用java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口實現。這種方式需要代理的類實現一個或多個接口。
          • 基于CGLIB的動態(tài)代理:當被代理的類沒有實現接口時,Spring會使用CGLIB庫生成一個被代理類的子類作為代理。CGLIB(Code Generation Library)是一個第三方代碼生成庫,通過繼承方式實現代理。

          動態(tài)代理和靜態(tài)代理的區(qū)別

          代理是一種常用的設計模式,目的是:為其他對象提供一個代理以控制對某個對象的訪問,將兩個類的關系解耦。代理類和委托類都要實現相同的接口,因為代理真正調用的是委托類的方法。區(qū)別:

          • 靜態(tài)代理:由程序員創(chuàng)建或者是由特定工具創(chuàng)建,在代碼編譯時就確定了被代理的類是一個靜態(tài)代理。靜態(tài)代理通常只代理一個類;
          • 動態(tài)代理:在代碼運行期間,運用反射機制動態(tài)創(chuàng)建生成。動態(tài)代理代理的是一個接口下的多個實現類。

          Java八股

          代理模式和適配器模式有什么區(qū)別?

          • 目的不同:代理模式主要關注控制對對象的訪問,而適配器模式則用于接口轉換,使不兼容的類能夠一起工作。
          • 結構不同:代理模式一般包含抽象主題、真實主題和代理三個角色,適配器模式包含目標接口、適配器和被適配者三個角色。
          • 應用場景不同:代理模式常用于添加額外功能或控制對對象的訪問,適配器模式常用于讓不兼容的接口協同工作。

          java線程的生命周期有了解嗎?

          源自《Java并發(fā)編程藝術》

          線程狀態(tài)有New, RUNNABLE, BLOCK, WAITING, TIMED_WAITING, THERMINATED

          • NEW:新建狀態(tài),線程被創(chuàng)建且未啟動,此時還未調用 start 方法。
          • RUNNABLE: 運行狀態(tài)。其表示線程正在JVM中執(zhí)行,但是這個執(zhí)行,不一定真的在跑,也可能在排隊等CPU。
          • BLOCKED:阻塞狀態(tài)。線程等待獲取鎖,鎖還沒獲得。
          • WAITING: 等待狀態(tài)。線程內run方法運行完語句Object.wait()/Thread.join()進入該狀態(tài)。
          • TIMED_WAITING:限期等待。在一定時間之后跳出狀態(tài)。調用Thread.sleep(long) Object.wait(long) Thread.join(long)進入狀態(tài)。其中這些參數代表等待的時間。
          • TERMINATED:結束狀態(tài)。線程調用完run方法進入該狀態(tài)。

          使用多線程要注意哪些問題?

          要保證多線程的允許是安全,不要出現數據競爭造成的數據混亂的問題。

          Java的線程安全在三個方面體現:

          • 原子性:提供互斥訪問,同一時刻只能有一個線程對數據進行操作,在Java中使用了atomic和synchronized這兩個關鍵字來確保原子性;
          • 可見性:一個線程對主內存的修改可以及時地被其他線程看到,在Java中使用了synchronized和volatile這兩個關鍵字確??梢娦?;
          • 有序性:一個線程觀察其他線程中的指令執(zhí)行順序,由于指令重排序,該觀察結果一般雜亂無序,在Java中使用了happens-before原則來確保有序性。

          保證數據的一致性有哪些方案呢?

          • 事務管理:使用數據庫事務來確保一組數據庫操作要么全部成功提交,要么全部失敗回滾。通過ACID(原子性、一致性、隔離性、持久性)屬性,數據庫事務可以保證數據的一致性。
          • 鎖機制:使用鎖來實現對共享資源的互斥訪問。在 Java 中,可以使用 synchronized 關鍵字、ReentrantLock 或其他鎖機制來控制并發(fā)訪問,從而避免并發(fā)操作導致數據不一致。
          • 版本控制:通過樂觀鎖的方式,在更新數據時記錄數據的版本信息,從而避免同時對同一數據進行修改,進而保證數據的一致性。

          線程池有了解嗎?線程池大概的原理?

          線程池是為了減少頻繁的創(chuàng)建線程和銷毀線程帶來的性能損耗。

          線程池分為核心線程池,線程池的最大容量,還有等待任務的隊列,提交一個任務,如果核心線程沒有滿,就創(chuàng)建一個線程,如果滿了,就是會加入等待隊列,如果等待隊列滿了,就會增加線程,如果達到最大線程數量,如果都達到最大線程數量,就會按照一些丟棄的策略進行處理。線程池的構造函數有7個參數:

          • corePoolSize:線程池核心線程數量。默認情況下,線程池中線程的數量如果 <= corePoolSize,那么即使這些線程處于空閑狀態(tài),那也不會被銷毀。
          • maximumPoolSize:線程池中最多可容納的線程數量。當一個新任務交給線程池,如果此時線程池中有空閑的線程,就會直接執(zhí)行,如果沒有空閑的線程且當前線程池的線程數量小于corePoolSize,就會創(chuàng)建新的線程來執(zhí)行任務,否則就會將該任務加入到阻塞隊列中,如果阻塞隊列滿了,就會創(chuàng)建一個新線程,從阻塞隊列頭部取出一個任務來執(zhí)行,并將新任務加入到阻塞隊列末尾。如果當前線程池中線程的數量等于maximumPoolSize,就不會創(chuàng)建新線程,就會去執(zhí)行拒絕策略。
          • keepAliveTime:當線程池中線程的數量大于corePoolSize,并且某個線程的空閑時間超過了keepAliveTime,那么這個線程就會被銷毀。
          • unit:就是keepAliveTime時間的單位。
          • workQueue:工作隊列。當沒有空閑的線程執(zhí)行新任務時,該任務就會被放入工作隊列中,等待執(zhí)行。
          • threadFactory:線程工廠??梢杂脕斫o線程取名字等等
          • handler:拒絕策略。當一個新任務交給線程池,如果此時線程池中有空閑的線程,就會直接執(zhí)行,如果沒有空閑的線程,就會將該任務加入到阻塞隊列中,如果阻塞隊列滿了,就會創(chuàng)建一個新線程,從阻塞隊列頭部取出一個任務來執(zhí)行,并將新任務加入到阻塞隊列末尾。如果當前線程池中線程的數量等于maximumPoolSize,就不會創(chuàng)建新線程,就會去執(zhí)行拒絕策略。

          ArrayList和LinkedList有什么區(qū)別

          • 底層數據結構:ArrayList使用數組作為底層數據結構,而LinkedList使用雙向鏈表作為底層數據結構
          • 隨機訪問性能:ArrayList支持通過索引直接訪問元素,因為底層數組的連續(xù)存儲特性,所以時間復雜度為O(1)。而LinkedList需要從頭或尾部開始遍歷鏈表,時間復雜度為O(n)。
          • 插入和刪除操作:ArrayList在尾部插入和刪除元素的時間復雜度為O(1),因為它只需要調整數組的長度即可。但在中間或頭部插入和刪除元素時,需要將后續(xù)元素進行移動,時間復雜度為O(n)。而LinkedList在任意位置插入和刪除元素的時間復雜度為O(1),因為只需要調整節(jié)點的指針即可。
          • 內存占用:ArrayList在每個元素中都存儲了實際的數據,而LinkedList在每個節(jié)點中存儲了數據和前后節(jié)點的指針。因此,相同數量的元素情況下,LinkedList通常比ArrayList占用更多的內存空間。

          ArrayList線程安全嗎?把ArrayList變成線程安全有哪些方法?

          不是線程安全的,ArrayList變成線程安全的方式有:

          1. 使用Collections類的synchronizedList方法將ArrayList包裝成線程安全的List:
          List<String> synchronizedList = Collections.synchronizedList(arrayList);
          1. 使用CopyOnWriteArrayList類代替ArrayList,它是一個線程安全的List實現:
          CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>(arrayList);
          1. 使用Vector類代替ArrayList,Vector是線程安全的List實現:
          Vector<String> vector = new Vector<>(arrayList);

          對面向對象的理解?

          以下是我對Java面向對象編程的理解,封裝、繼承、多態(tài)和抽象性是Java面向對象編程的四大特性。這些特性使得代碼更具可重用性、可維護性、可擴展性和靈活性。

          • 封裝:封裝是將數據和行為組合在一個單元中的概念。Java使用類(Class)作為封裝的基本單元,通過類可以將數據和方法組合在一起,隱藏對象的內部狀態(tài),并只通過公共接口暴露對象的行為。
          • 繼承:繼承是一種機制,允許一個類(子類)繼承另一個類(父類)的屬性和方法。子類可以重用父類的實現并定義自己的特定行為。Java中的繼承支持單繼承,但一個類可以實現多個接口(接口多繼承)。
          • 多態(tài):多態(tài)性是允許在不同對象上使用相同的操作符或方法,可以根據具體對象的類型來執(zhí)行不同的操作。Java中實現多態(tài)性的方式包括方法重載(Overloading)和方法重寫(Overriding)。
          • 接口與抽象類:接口和抽象類是Java中實現多態(tài)的重要機制。接口定義了行為的規(guī)范,類實現接口以應用這些行為。抽象類提供了一種具有未實現方法的類,必須由其子類實現這些方法。

          其他

          1. 讀書中遇到最難的技術是什么,怎么克服的?
          2. 有沒有什么強項在面試中還沒有展現的?
          3. 反問

          面試總結

          • 感覺:面試官有引導,大多問的是八股,會的就回答的比較流暢,不熟悉的就磕磕巴巴,面試官給的反饋基礎還行,但是深度不夠,對剛剛設計模式的對比回答不滿意,和mybatis的原理回答也不太滿意
          • 不足之處:對框架還是不夠熟練,回答不夠全面,經常被面試官問還有呢,但就回答不上來了,網絡這方面看了就忘。

          推薦閱讀:

          阿里太狠了,把人問蒙了

          輸了!廣州某小廠一面,也涼了

          終究還是敗給了騰訊,秒掛了。。。

          瀏覽 719
          3點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          3點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天撸夜夜撸 | 超碰夫妻自拍 | 天天激情五月 | 青娱乐免费精品视频1 | 人人爱人人撸 |