小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

華為今年薪資開的挺多!

 臨煙閣 2024-12-20

華為今年的校招薪資已經(jīng)開獎(jiǎng)了,有喜有悲!

今年華為的校招薪資波動(dòng)幅度還是蠻大的,算法類崗位總體來說很不錯(cuò),一些重要的前沿技術(shù)崗位甚至開出了 100w+ 的恐怖年薪,軟件開發(fā)類崗位相對(duì)少一些(薪資數(shù)據(jù)來源于 offershow+社區(qū)討論貼+讀者分享)

  • 算法:碩士 985,(base 27k + 績(jī)效 7k)*12+年終 10w,上海
  • 通用軟件開發(fā):碩士 985,25k*16,上海
  • 應(yīng)用軟件:碩士 211,22k*16,上海
  • 鴻蒙開發(fā):碩士 985,22k*15,北京
  • AIGC 算法:博士 985,總包 108W
  • AI 工程師:本科 211,25k*14,上海
  • 數(shù)據(jù)存儲(chǔ):碩士 211,總包 45W,上海

華為技術(shù)面試對(duì)于求職者的技術(shù)要求相比較于互聯(lián)網(wǎng)大廠來說,還是低一些的,會(huì)看重學(xué)歷一些。另外,華為面試的手撕算法可能會(huì)比較多,但難度相比較于大廠也要偏低一些。

面試華為的話,需要做好泡池子的準(zhǔn)備,這個(gè)池子還是“挺大”的。反正就是吊著你,可能要等很久才有下一步的進(jìn)度。

圖片

接下來,分享一位讀者的華為軟件開發(fā)的一二面的面經(jīng)。

簡(jiǎn)單介紹一下自己

基本每一面都會(huì)先讓你自我介紹,這個(gè)一定要提前好好準(zhǔn)備。

一個(gè)好的自我介紹應(yīng)該包含這幾點(diǎn)要素:

  1. 用簡(jiǎn)單的話說清楚自己主要的技術(shù)棧于擅長(zhǎng)的領(lǐng)域,例如 Java 后端開發(fā)、分布式系統(tǒng)開發(fā);
  2. 把重點(diǎn)放在自己的優(yōu)勢(shì)上,重點(diǎn)突出自己的能力比如自己的定位的 bug 的能力特別厲害;
  3. 避免避實(shí)就虛,適當(dāng)舉例體現(xiàn)自己的能力,例如過往的比賽經(jīng)歷、實(shí)習(xí)經(jīng)歷;
  4. 自我介紹的時(shí)間不宜過長(zhǎng),一般是 1~2 分鐘之間。

項(xiàng)目拷打

面試考察八股不多,幾乎都是在拷打項(xiàng)目。面試官對(duì)著項(xiàng)目經(jīng)歷上的工作內(nèi)容部分,一條接一條的拷打。

作為求職者,我們可以從這些方案去準(zhǔn)備項(xiàng)目經(jīng)歷的回答:

  1. 你對(duì)項(xiàng)目基本情況(比如項(xiàng)目背景、核心功能)以及整體設(shè)計(jì)(比如技術(shù)棧、系統(tǒng)架構(gòu))的了解(面試官可能會(huì)讓你畫系統(tǒng)的架構(gòu)圖、讓你講解某個(gè)模塊或功能的數(shù)據(jù)庫(kù)表設(shè)計(jì))
  2. 你在這個(gè)項(xiàng)目中你擔(dān)任了什么角色?負(fù)責(zé)了什么?有什么貢獻(xiàn)?(具體說明你在項(xiàng)目中的職責(zé)和貢獻(xiàn))
  3. 你在這個(gè)項(xiàng)目中是否解決過什么問題?怎么解決的?收獲了什么?(展現(xiàn)解決問題的能力)
  4. 你在這個(gè)項(xiàng)目用到了哪些技術(shù)?這些技術(shù)你吃透了沒有?(舉個(gè)例子,你的項(xiàng)目經(jīng)歷使用了 Seata 來做分布式事務(wù),那 Seata 相關(guān)的問題你要提前準(zhǔn)備一下吧,比如說 Seata 支持哪些配置中心、Seata 的事務(wù)分組是怎么做的、Seata 支持哪些事務(wù)模式,怎么選擇?)
  5. 你在這個(gè)項(xiàng)目中犯過的錯(cuò)誤,最后是怎么彌補(bǔ)的?(承認(rèn)不足并改進(jìn)才能走的更遠(yuǎn))
  6. 從這個(gè)項(xiàng)目中你學(xué)會(huì)了那些東西?學(xué)會(huì)了那些新技術(shù)的使用?(總結(jié)你在這個(gè)項(xiàng)目中的收獲)

什么是進(jìn)程和線程?有什么區(qū)別?

  • 進(jìn)程(Process) 是指計(jì)算機(jī)中正在運(yùn)行的一個(gè)程序?qū)嵗?。舉例:你打開的微信就是一個(gè)進(jìn)程。
  • 線程(Thread) 也被稱為輕量級(jí)進(jìn)程,更加輕量。多個(gè)線程可以在同一個(gè)進(jìn)程中同時(shí)執(zhí)行,并且共享進(jìn)程的資源比如內(nèi)存空間、文件句柄、網(wǎng)絡(luò)連接等。舉例:你打開的微信里就有一個(gè)線程專門用來拉取別人發(fā)你的最新的消息。

一個(gè)進(jìn)程中可以有多個(gè)線程,多個(gè)線程共享進(jìn)程的堆和方法區(qū) (JDK1.8 之后的元空間)資源,但是每個(gè)線程有自己的程序計(jì)數(shù)器、虛擬機(jī)棧和本地方法棧。

圖片
Java 運(yùn)行時(shí)數(shù)據(jù)區(qū)域(JDK1.8 之后)

總結(jié):

  • 線程是進(jìn)程劃分成的更小的運(yùn)行單位,一個(gè)進(jìn)程在其執(zhí)行的過程中可以產(chǎn)生多個(gè)線程。
  • 線程和進(jìn)程最大的不同在于基本上各進(jìn)程是獨(dú)立的,而各線程則不一定,因?yàn)橥贿M(jìn)程中的線程極有可能會(huì)相互影響。
  • 線程執(zhí)行開銷小,但不利于資源的管理和保護(hù);而進(jìn)程正相反。

怎么創(chuàng)建線程?

一般來說,創(chuàng)建線程有很多種方式,例如繼承Thread類、實(shí)現(xiàn)Runnable接口、實(shí)現(xiàn)Callable接口、使用線程池、使用CompletableFuture類等等。

不過,這些方式其實(shí)并沒有真正創(chuàng)建出線程。準(zhǔn)確點(diǎn)來說,這些都屬于是在 Java 代碼中使用多線程的方法。

嚴(yán)格來說,Java 就只有一種方式可以創(chuàng)建線程,那就是通過new Thread().start()創(chuàng)建。不管是哪種方式,最終還是依賴于new Thread().start()。

關(guān)于這個(gè)問題的詳細(xì)分析可以查看這篇文章:大家都說 Java 有三種創(chuàng)建線程的方式!并發(fā)編程中的驚天騙局!

Java 線程的狀態(tài)有哪幾種?

Java 線程在運(yùn)行的生命周期中的指定時(shí)刻只可能處于下面 6 種不同狀態(tài)的其中一個(gè)狀態(tài):

  • NEW: 初始狀態(tài),線程被創(chuàng)建出來但沒有被調(diào)用 start()
  • RUNNABLE: 運(yùn)行狀態(tài),線程被調(diào)用了 start()等待運(yùn)行的狀態(tài)。
  • BLOCKED:阻塞狀態(tài),需要等待鎖釋放。
  • WAITING:等待狀態(tài),表示該線程需要等待其他線程做出一些特定動(dòng)作(通知或中斷)。
  • TIME_WAITING:超時(shí)等待狀態(tài),可以在指定的時(shí)間后自行返回而不是像 WAITING 那樣一直等待。
  • TERMINATED:終止?fàn)顟B(tài),表示該線程已經(jīng)運(yùn)行完畢。

線程在生命周期中并不是固定處于某一個(gè)狀態(tài)而是隨著代碼的執(zhí)行在不同狀態(tài)之間切換。

Java 線程狀態(tài)變遷圖(圖源:挑錯(cuò) |《Java 并發(fā)編程的藝術(shù)》中關(guān)于線程狀態(tài)的三處錯(cuò)誤):

圖片
Java 線程狀態(tài)變遷圖

由上圖可以看出:線程創(chuàng)建之后它將處于 NEW(新建) 狀態(tài),調(diào)用 start() 方法后開始運(yùn)行,線程這時(shí)候處于 READY(可運(yùn)行) 狀態(tài)。可運(yùn)行狀態(tài)的線程獲得了 CPU 時(shí)間片(timeslice)后就處于 RUNNING(運(yùn)行) 狀態(tài)。

在操作系統(tǒng)層面,線程有 READY 和 RUNNING 狀態(tài);而在 JVM 層面,只能看到 RUNNABLE 狀態(tài)(圖源:HowToDoInJava[1]Java Thread Life Cycle and Thread States[2]),所以 Java 系統(tǒng)一般將這兩個(gè)狀態(tài)統(tǒng)稱為 RUNNABLE(運(yùn)行中) 狀態(tài) 。

為什么 JVM 沒有區(qū)分這兩種狀態(tài)呢? (摘自:Java 線程運(yùn)行怎么有第六種狀態(tài)?- Dawell 的回答[3] ) 現(xiàn)在的時(shí)分(time-sharing)多任務(wù)(multi-task)操作系統(tǒng)架構(gòu)通常都是用所謂的“時(shí)間分片(time quantum or time slice)”方式進(jìn)行搶占式(preemptive)輪轉(zhuǎn)調(diào)度(round-robin 式)。這個(gè)時(shí)間分片通常是很小的,一個(gè)線程一次最多只能在 CPU 上運(yùn)行比如 10-20ms 的時(shí)間(此時(shí)處于 running 狀態(tài)),也即大概只有 0.01 秒這一量級(jí),時(shí)間片用后就要被切換下來放入調(diào)度隊(duì)列的末尾等待再次調(diào)度。(也即回到 ready 狀態(tài))。線程切換的如此之快,區(qū)分這兩種狀態(tài)就沒什么意義了。

圖片
RUNNABLE-VS-RUNNING
  • 當(dāng)線程執(zhí)行 wait()方法之后,線程進(jìn)入 WAITING(等待) 狀態(tài)。進(jìn)入等待狀態(tài)的線程需要依靠其他線程的通知才能夠返回到運(yùn)行狀態(tài)。
  • TIMED_WAITING(超時(shí)等待) 狀態(tài)相當(dāng)于在等待狀態(tài)的基礎(chǔ)上增加了超時(shí)限制,比如通過 sleep(long millis)方法或 wait(long millis)方法可以將線程置于 TIMED_WAITING 狀態(tài)。當(dāng)超時(shí)時(shí)間結(jié)束后,線程將會(huì)返回到 RUNNABLE 狀態(tài)。
  • 當(dāng)線程進(jìn)入 synchronized 方法/塊或者調(diào)用 wait 后(被 notify)重新進(jìn)入 synchronized 方法/塊,但是鎖被其它線程占有,這個(gè)時(shí)候線程就會(huì)進(jìn)入 BLOCKED(阻塞) 狀態(tài)。
  • 線程在執(zhí)行完了 run()方法之后將會(huì)進(jìn)入到 TERMINATED(終止) 狀態(tài)。

相關(guān)閱讀:線程的幾種狀態(tài)你真的了解么?

Java 集合的種類?

Java 集合, 也叫作容器,主要是由兩大接口派生而來:一個(gè)是 Collection接口,主要用于存放單一元素;另一個(gè)是 Map 接口,主要用于存放鍵值對(duì)。對(duì)于Collection 接口,下面又有三個(gè)主要的子接口:List、SetQueue。

Java 集合框架如下圖所示:

圖片
Java 集合框架概覽

注:圖中只列舉了主要的繼承派生關(guān)系,并沒有列舉所有關(guān)系。比方省略了AbstractList, NavigableSet等抽象類以及其他的一些輔助類,如想深入了解,可自行查看源碼。

  • List(對(duì)付順序的好幫手): 存儲(chǔ)的元素是有序的、可重復(fù)的。
  • Set(注重獨(dú)一無二的性質(zhì)): 存儲(chǔ)的元素不可重復(fù)的。
  • Queue(實(shí)現(xiàn)排隊(duì)功能的叫號(hào)機(jī)): 按特定的排隊(duì)規(guī)則來確定先后順序,存儲(chǔ)的元素是有序的、可重復(fù)的。
  • Map(用 key 來搜索的專家): 使用鍵值對(duì)(key-value)存儲(chǔ),類似于數(shù)學(xué)上的函數(shù) y=f(x),'x' 代表 key,'y' 代表 value,key 是無序的、不可重復(fù)的,value 是無序的、可重復(fù)的,每個(gè)鍵最多映射到一個(gè)值。

HashMap 的底層實(shí)現(xiàn)是?

JDK1.8 之前

HashMap 底層是 數(shù)組和鏈表 結(jié)合在一起使用也就是 鏈表散列。HashMap 通過 key 的 hashcode 經(jīng)過擾動(dòng)函數(shù)處理過后得到 hash 值,然后通過 (n - 1) & hash 判斷當(dāng)前元素存放的位置(這里的 n 指的是數(shù)組的長(zhǎng)度),如果當(dāng)前位置存在元素的話,就判斷該元素與要存入的元素的 hash 值以及 key 是否相同,如果相同的話,直接覆蓋,不相同就通過拉鏈法解決沖突。

HashMap 中的擾動(dòng)函數(shù)(hash 方法)是用來優(yōu)化哈希值的分布。通過對(duì)原始的 hashCode() 進(jìn)行額外處理,擾動(dòng)函數(shù)可以減小由于糟糕的 hashCode() 實(shí)現(xiàn)導(dǎo)致的碰撞,從而提高數(shù)據(jù)的分布均勻性。

JDK 1.8 HashMap 的 hash 方法源碼:

JDK 1.8 的 hash 方法 相比于 JDK 1.7 hash 方法更加簡(jiǎn)化,但是原理不變。

    static final int hash(Object key) {
      int h;
      // key.hashCode():返回散列值也就是hashcode
      // ^:按位異或
      // >>>:無符號(hào)右移,忽略符號(hào)位,空位都以0補(bǔ)齊
      return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  }

對(duì)比一下 JDK1.7 的 HashMap 的 hash 方法源碼.

static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).

    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

相比于 JDK1.8 的 hash 方法 ,JDK 1.7 的 hash 方法的性能會(huì)稍差一點(diǎn)點(diǎn),因?yàn)楫吘箶_動(dòng)了 4 次。

所謂 “拉鏈法” 就是:將鏈表和數(shù)組相結(jié)合。也就是說創(chuàng)建一個(gè)鏈表數(shù)組,數(shù)組中每一格就是一個(gè)鏈表。若遇到哈希沖突,則將沖突的值加到鏈表中即可。

圖片
jdk1.8 之前的內(nèi)部結(jié)構(gòu)-HashMap

JDK1.8 之后

相比于之前的版本, JDK1.8 之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長(zhǎng)度大于閾值(默認(rèn)為 8)(將鏈表轉(zhuǎn)換成紅黑樹前會(huì)判斷,如果當(dāng)前數(shù)組的長(zhǎng)度小于 64,那么會(huì)選擇先進(jìn)行數(shù)組擴(kuò)容,而不是轉(zhuǎn)換為紅黑樹)時(shí),將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時(shí)間。

圖片
jdk1.8之后的內(nèi)部結(jié)構(gòu)-HashMap

TreeMap、TreeSet 以及 JDK1.8 之后的 HashMap 底層都用到了紅黑樹。紅黑樹就是為了解決二叉查找樹的缺陷,因?yàn)槎娌檎覙湓谀承┣闆r下會(huì)退化成一個(gè)線性結(jié)構(gòu)。

多線程交替打印 A、B、B 如何實(shí)現(xiàn)?

這個(gè)問題華為 OD 也考察過,我懷疑華為 OD 的面試也是正式員工負(fù)責(zé)的。對(duì)應(yīng)的文章地址:華為 OD 面試:三個(gè)線程交替打印 ABC 如何實(shí)現(xiàn)?

這里我們采用 ReentrantLock + Condition 實(shí)現(xiàn)。

public class ABCPrinter {
    private final int max;
    // 用來指示當(dāng)前應(yīng)該打印的線程序號(hào),0-A, 1-B, 2-C
    private int turn = 0;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition conditionA = lock.newCondition();
    private final Condition conditionB = lock.newCondition();
    private final Condition conditionC = lock.newCondition();

    public ABCPrinter(int max) {
        this.max = max;
    }

    public void printA() {
        print('A', conditionA, conditionB);
    }

    public void printB() {
        print('B', conditionB, conditionC);
    }

    public void printC() {
        print('C', conditionC, conditionA);
    }

    private void print(String name, Condition currentCondition, Condition nextCondition) {
        for (int i = 0; i < max; i++) {
            lock.lock();
            try {
                // 等待直到輪到當(dāng)前線程打印
                // turn 變量的值需要與線程要打印的字符相對(duì)應(yīng),例如,如果turn是0,且當(dāng)前線程應(yīng)該打印'A',則條件滿足。如果不滿足,當(dāng)前線程調(diào)用currentCondition.await()進(jìn)入等待狀態(tài)。
                while (!((turn == 0 && name.charAt(0) == 'A') || (turn == 1 && name.charAt(0) == 'B') || (turn == 2 && name.charAt(0) == 'C'))) {
                    currentCondition.await();
                }
                System.out.println(Thread.currentThread().getName() + ' : ' + name);
                // 更新打印輪次,并喚醒下一個(gè)線程
                turn = (turn + 1) % 3;
                nextCondition.signal();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
            }
        }
    }
}

在上面的代碼中,三個(gè)線程的協(xié)調(diào)主要依賴:

  • ReentrantLock lock: 用于線程同步的可重入鎖,確保同一時(shí)刻只有一個(gè)線程能修改共享資源。
  • Condition conditionA/B/C: 分別與'A'、'B'、'C'線程關(guān)聯(lián)的條件變量,用于線程間的協(xié)調(diào)通信。一個(gè)線程執(zhí)行完之后,通過調(diào)用nextCondition.signal()喚醒下一個(gè)應(yīng)該打印的線程。

手撕算法

  1. 給定數(shù)組,將連續(xù)的首尾用-連接輸出(例如,1-5),單個(gè)輸出單個(gè)數(shù)字
  2. 二叉樹最大深度
  3. 有效括號(hào)
  4. 單詞拆分 II
參考資料
[1]

HowToDoInJava: https://howtodoinJava.com/

[2]

Java Thread Life Cycle and Thread States: https://howtodoinJava.com/Java/multi-threading/Java-thread-life-cycle-and-thread-states/

[3]

Java 線程運(yùn)行怎么有第六種狀態(tài)?- Dawell 的回答: https://www.zhihu.com/question/56494969/answer/154053599

圖片

??Java 后端技術(shù)面試準(zhǔn)備強(qiáng)烈推薦《Java 面試指北》 和 JavaGuide ,400 多人參與維護(hù)完善,質(zhì)量非常高。另外,目前的面試趨勢(shì)是場(chǎng)景題變多,可以參考《后端面試高頻系統(tǒng)設(shè)計(jì)&場(chǎng)景題》(20+高頻系統(tǒng)設(shè)計(jì)&場(chǎng)景面試題)進(jìn)行準(zhǔn)備!

?面經(jīng)詳解合集Java后端面經(jīng)詳解

圖片

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多