<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>

          美團(tuán)后端日常實習(xí)面試,輕松拿捏了!

          共 12134字,需瀏覽 25分鐘

           ·

          2024-07-24 15:48

          這是一位讀者分享的美團(tuán)日常實習(xí)面經(jīng),我對其中提到的面試問題添加了參加答案供大家復(fù)習(xí)參考。總體難度不大,但對于實習(xí)面試來說已經(jīng)算是高難度了!

          合集地址:《Java 后端面經(jīng)精選(附詳細(xì)參考答案)》 。

          面試情況

          總時長 45 min 左右,日常實習(xí),已經(jīng)拿到 offer 了!

          個人情況

          • 末位 211,26 屆,學(xué)習(xí) Java 一年多一點。
          • 簡歷上有一個魔改的培訓(xùn)班項目和一個參加學(xué)校比賽的項目,編碼能力一般,技術(shù)八股能力中等。

          面試題

          1、自我介紹。

          2、拷打項目 30min ,對著項目提問架構(gòu)設(shè)計以及一些功能的開發(fā)思路。

          星球里有一篇帖子分享面試官一般如何考察項目經(jīng)歷以及我們應(yīng)該如何準(zhǔn)備項目經(jīng)歷的回答:https://t.zsxq.com/136ObGpk4

          3、看你項目用到了 CompletableFuture 進(jìn)行任務(wù)編排,怎么做的?為什么要自己創(chuàng)建一個線程池?如果有一個任務(wù)失敗了,你如何處理異常?

          參考答案:從 5s 到 0.5s!看看人家的 CompletableFuture 異步任務(wù)優(yōu)化技巧,確實優(yōu)雅!

          4、 Java 線程池參數(shù)有哪些?線程數(shù)設(shè)置多少合適?線程池參數(shù)固定配置有什么問題嗎?動態(tài)線程池是什么?

          參考答案:

              /**
               * 用給定的初始參數(shù)創(chuàng)建一個新的ThreadPoolExecutor。
               */

              public ThreadPoolExecutor(int corePoolSize,//線程池的核心線程數(shù)量
                                        int maximumPoolSize,//線程池的最大線程數(shù)
                                        long keepAliveTime,//當(dāng)線程數(shù)大于核心線程數(shù)時,多余的空閑線程存活的最長時間
                                        TimeUnit unit,//時間單位
                                        BlockingQueue<Runnable> workQueue,//任務(wù)隊列,用來儲存等待執(zhí)行任務(wù)的隊列
                                        ThreadFactory threadFactory,//線程工廠,用來創(chuàng)建線程,一般默認(rèn)即可
                                        RejectedExecutionHandler handler//拒絕策略,當(dāng)提交的任務(wù)過多而不能及時處理時,我們可以定制策略來處理任務(wù)
                                         )
           
          {
                  if (corePoolSize < 0 ||
                      maximumPoolSize <= 0 ||
                      maximumPoolSize < corePoolSize ||
                      keepAliveTime < 0)
                      throw new IllegalArgumentException();
                  if (workQueue == null || threadFactory == null || handler == null)
                      throw new NullPointerException();
                  this.corePoolSize = corePoolSize;
                  this.maximumPoolSize = maximumPoolSize;
                  this.workQueue = workQueue;
                  this.keepAliveTime = unit.toNanos(keepAliveTime);
                  this.threadFactory = threadFactory;
                  this.handler = handler;
              }

          下面提到的公示也只是參考,實際項目不太可能直接按照公式來設(shè)置線程池參數(shù),畢竟不同的業(yè)務(wù)場景對應(yīng)的需求不同,具體還是要根據(jù)項目實際線上運行情況來動態(tài)調(diào)整。

          線程數(shù)設(shè)置有一個簡單并且適用面比較廣的公式:

          • CPU 密集型任務(wù)(N+1): 這種任務(wù)消耗的主要是 CPU 資源,可以將線程數(shù)設(shè)置為 N(CPU 核心數(shù))+1。比 CPU 核心數(shù)多出來的一個線程是為了防止線程偶發(fā)的缺頁中斷,或者其它原因?qū)е碌娜蝿?wù)暫停而帶來的影響。一旦任務(wù)暫停,CPU 就會處于空閑狀態(tài),而在這種情況下多出來的一個線程就可以充分利用 CPU 的空閑時間。
          • I/O 密集型任務(wù)(2N): 這種任務(wù)應(yīng)用起來,系統(tǒng)會用大部分的時間來處理 I/O 交互,而線程在處理 I/O 的時間段內(nèi)不會占用 CPU 來處理,這時就可以將 CPU 交出給其它線程使用。因此在 I/O 密集型任務(wù)的應(yīng)用中,我們可以多配置一些線程,具體的計算方法是 2N。

          線程數(shù)更嚴(yán)謹(jǐn)?shù)挠嬎愕姆椒☉?yīng)該是:最佳線程數(shù) = N(CPU 核心數(shù))?(1+WT(線程等待時間)/ST(線程計算時間)),其中 WT(線程等待時間)=線程運行總時間 - ST(線程計算時間)

          線程等待時間所占比例越高,需要越多線程。線程計算時間所占比例越高,需要越少線程。

          我們可以通過 JDK 自帶的工具 VisualVM 來查看 WT/ST 比例。

          • CPU 密集型任務(wù)的 WT/ST 接近或者等于 0,因此, 線程數(shù)可以設(shè)置為 N(CPU 核心數(shù))?(1+0)= N,和我們上面說的 N(CPU 核心數(shù))+1 差不多。
          • IO 密集型任務(wù)下,幾乎全是線程等待時間,從理論上來說,你就可以將線程數(shù)設(shè)置為 2N(按道理來說,WT/ST 的結(jié)果應(yīng)該比較大,這里選擇 2N 的原因應(yīng)該是為了避免創(chuàng)建過多線程吧)。

          傳統(tǒng)線程池的參數(shù)(如核心線程數(shù)、最大線程數(shù)和任務(wù)隊列大小)在創(chuàng)建時被固定。隨著業(yè)務(wù)負(fù)載的變化,這種固定配置難以適應(yīng),需要調(diào)整時必須重啟服務(wù),過程繁瑣且耗時。

          動態(tài)線程池是一種能夠在應(yīng)用程序運行過程中,無需重啟服務(wù)即可實時調(diào)整其核心配置參數(shù)(如核心線程數(shù)、最大線程數(shù)等)的線程池機制。通常情況下,動態(tài)線程池不僅支持參數(shù)的動態(tài)變更,還內(nèi)置了監(jiān)控和告警功能,例如在發(fā)生線程池任務(wù)堆積時通知相應(yīng)的開發(fā)人員。

          5、談?wù)勀阒赖?Java 同步機制。

          參考答案:

          • synchronized:Java 中的一個關(guān)鍵字,翻譯成中文是同步的意思,主要解決的是多個線程之間訪問資源的同步性,可以保證被它修飾的方法或者代碼塊在任意時刻只能有一個線程執(zhí)行。
          • ReentrantLock: 實現(xiàn)了 Lock 接口,是一個可重入且獨占式的鎖,和 synchronized 關(guān)鍵字類似。不過,ReentrantLock 更靈活、更強大,增加了輪詢、超時、中斷、公平鎖和非公平鎖等高級功能。
          • ReentrantReadWriteLock :實現(xiàn)了 ReadWriteLock ,是一個可重入的讀寫鎖,既可以保證多個線程同時讀的效率,同時又可以保證有寫入操作時的線程安全。
          • StampedLock:JDK 1.8 引入的性能更好的讀寫鎖,不可重入且不支持條件變量 Condition。不同于一般的 Lock 類,StampedLock 并不是直接實現(xiàn) LockReadWriteLock接口,而是基于 CLH 鎖 獨立實現(xiàn)的(AQS 也是基于這玩意)。
          • SemaphoresynchronizedReentrantLock 都是一次只允許一個線程訪問某個資源,而Semaphore(信號量)可以用來控制同時訪問特定資源的線程數(shù)量。
          • CountDownLatch :允許 count 個線程阻塞在一個地方,直至所有線程的任務(wù)都執(zhí)行完畢。CountDownLatch 是一次性的,計數(shù)器的值只能在構(gòu)造方法中初始化一次,之后沒有任何機制再次對其設(shè)置值,當(dāng) CountDownLatch 使用完畢后,它不能再次被使用。
          • ......

          6、你的項目這里為什么用分布式鎖?怎么實現(xiàn)的?

          參考答案:為什么需要分布式鎖?如何基于 Redis 實現(xiàn)分布式鎖?

          7、項目用到了 Redis 哪些數(shù)據(jù)類型?

          參考答案:Redis 八種常用數(shù)據(jù)類型常用命令和應(yīng)用場景

          8、MySQL 怎么解決慢查詢問題?

          # 開啟慢查詢?nèi)罩竟δ?/span>
          SET GLOBAL slow_query_log = 'ON';
          # 慢查詢?nèi)罩敬娣盼恢?/span>
          SET GLOBAL slow_query_log_file = '/var/lib/mysql/ranking-list-slow.log';
          # 無論是否超時,未被索引的記錄也會記錄下來。
          SET GLOBAL log_queries_not_using_indexes = 'ON';
          # 慢查詢閾值(秒),SQL 執(zhí)行超過這個閾值將被記錄在日志中。
          SET SESSION long_query_time = 1;
          # 慢查詢僅記錄掃描行數(shù)大于此參數(shù)的 SQL
          SET SESSION min_examined_row_limit = 100;

          設(shè)置成功之后,使用 show variables like 'slow%'; 命令進(jìn)行查看。

          | Variable_name       | Value                                |
          +---------------------+--------------------------------------+
          | slow_launch_time    | 2                                    |
          | slow_query_log      | ON                                   |
          | slow_query_log_file | /var/lib/mysql/ranking-list-slow.log |
          +---------------------+--------------------------------------+
          3 rows in set (0.01 sec)

          我們故意在百萬數(shù)據(jù)量的表(未使用索引)中執(zhí)行一條排序的語句:

          SELECT `score`,`name` FROM `cus_order` ORDER BY `score` DESC;

          確保自己有對應(yīng)目錄的訪問權(quán)限:

          chmod 755 /var/lib/mysql/

          查看對應(yīng)的慢查詢?nèi)罩荆?/p>

           cat /var/lib/mysql/ranking-list-slow.log

          我們剛剛故意執(zhí)行的 SQL 語句已經(jīng)被慢查詢?nèi)罩居涗浟讼聛恚?/p>

          # Time: 2022-10-09T08:55:37.486797Z
          # User@Host: root[root] @ [172.17.0.1] Id: 14
          # Query_time: 0.978054 Lock_time: 0.000164 Rows_sent: 999999 Rows_examined: 1999998
          SET timestamp=1665305736;
          SELECT `score`,`name` FROM `cus_order` ORDER BY `score` DESC;

          這里對日志中的一些信息進(jìn)行說明:

          • Time :被日志記錄的代碼在服務(wù)器上的運行時間。
          • User@Host:誰執(zhí)行的這段代碼。
          • Query_time:這段代碼運行時長。
          • Lock_time:執(zhí)行這段代碼時,鎖定了多久。
          • Rows_sent:慢查詢返回的記錄。
          • Rows_examined:慢查詢掃描過的行數(shù)。

          實際項目中,慢查詢?nèi)罩就ǔ容^復(fù)雜,我們需要借助一些工具對其進(jìn)行分析。像 MySQL 內(nèi)置的 mysqldumpslow 工具就可以把相同的 SQL 歸為一類,并統(tǒng)計出歸類項的執(zhí)行次數(shù)和每次執(zhí)行的耗時等一系列對應(yīng)的情況。

          找到了慢 SQL 之后,我們可以通過 EXPLAIN 命令分析對應(yīng)的 SELECT 語句:

          mysql> EXPLAIN SELECT `score`,`name` FROM `cus_order` ORDER BY `score` DESC;
          +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
          | id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra          |
          +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
          |  1 | SIMPLE      | cus_order | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 997572 |   100.00 | Using filesort |
          +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
          1 row in set1 warning (0.00 sec)

          比較重要的字段說明:

          • select_type :查詢的類型,常用的取值有 SIMPLE(普通查詢,即沒有聯(lián)合查詢、子查詢)、PRIMARY(主查詢)、UNION(UNION 中后面的查詢)、SUBQUERY(子查詢)等。
          • table :表示查詢涉及的表或衍生表。
          • type :執(zhí)行方式,判斷查詢是否高效的重要參考指標(biāo),結(jié)果值從差到好依次是:ALL < index < range ~ index_merge < ref < eq_ref < const < system。
          • rows : SQL 要查找到結(jié)果集需要掃描讀取的數(shù)據(jù)行數(shù),原則上 rows 越少越好。
          • ......

          關(guān)于 Explain 的詳細(xì)介紹,請看這篇文章:MySQL 執(zhí)行計劃分析[1]。另外,再推薦一下阿里的這篇文章:慢 SQL 治理經(jīng)驗總結(jié),總結(jié)的挺不錯。

          9、MySQL 的隔離級別是基于鎖實現(xiàn)的嗎?

          MySQL 的隔離級別基于鎖和 MVCC 機制共同實現(xiàn)的。

          SERIALIZABLE 隔離級別是通過鎖來實現(xiàn)的,READ-COMMITTED 和 REPEATABLE-READ 隔離級別是基于 MVCC 實現(xiàn)的。不過, SERIALIZABLE 之外的其他隔離級別可能也需要用到鎖機制,就比如 REPEATABLE-READ 在當(dāng)前讀情況下需要使用加鎖讀來保證不會出現(xiàn)幻讀。

          10、MySQL 的默認(rèn)隔離級別是什么?可以解決幻讀問題問題嗎?

          MySQL InnoDB 存儲引擎的默認(rèn)支持的隔離級別是 REPEATABLE-READ(可重讀)。我們可以通過SELECT @@tx_isolation;命令來查看,MySQL 8.0 該命令改為SELECT @@transaction_isolation;

          mysql> SELECT @@tx_isolation;
          +-----------------+
          | @@tx_isolation  |
          +-----------------+
          | REPEATABLE-READ |
          +-----------------+

          標(biāo)準(zhǔn)的 SQL 隔離級別定義里,REPEATABLE-READ(可重復(fù)讀)是不可以防止幻讀的。

          但是!InnoDB 實現(xiàn)的 REPEATABLE-READ 隔離級別其實是可以解決幻讀問題發(fā)生的,主要有下面兩種情況:

          • 快照讀:由 MVCC 機制來保證不出現(xiàn)幻讀。
          • 當(dāng)前讀:使用 Next-Key Lock 進(jìn)行加鎖來保證不出現(xiàn)幻讀,Next-Key Lock 是行鎖(Record Lock)和間隙鎖(Gap Lock)的結(jié)合,行鎖只能鎖住已經(jīng)存在的行,為了避免插入新行,需要依賴間隙鎖。

          因為隔離級別越低,事務(wù)請求的鎖越少,所以大部分?jǐn)?shù)據(jù)庫系統(tǒng)的隔離級別都是 READ-COMMITTED ,但是你要知道的是 InnoDB 存儲引擎默認(rèn)使用 REPEATABLE-READ 并不會有任何性能損失。

          11、算法:買賣股票的最佳時機 II

          Leetcode 原題:122.買賣股票的最佳時機 II[2]

          參考資料
          [1]

          MySQL 執(zhí)行計劃分析: https://javaguide.cn/database/mysql/mysql-query-execution-plan.html

          [2]

          122.買賣股票的最佳時機 II: https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/

          歡迎準(zhǔn)備面試的同學(xué)加入我的知識星球 。

          星球部分面試資料介紹

          2024 最新版原創(chuàng) PDF 面試資料來啦!涵蓋 Java 核心、數(shù)據(jù)庫、緩存、分布式、設(shè)計模式、智力題等內(nèi)容,非常全面!

          瀏覽 867
          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>
                  91三级在线观看 | 精品久久视频 | 天天干女人在线视频免费观看 | 亚洲日韩毛片 | 成人自拍偷拍视频在线 |