太讚了!這或許是騰訊一線最真實的Android面試資料了吧

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

都說金三銀四青銅五,這幾個月份是程序員最好的跳槽時間。作為求職這來說,面試是一道坎,很多人會恐懼面試,即使是工作很多年的老鳥,可能仍存在面試的焦慮。

所以今天小編就在這面分享一波大廠面試題及技術知識點福利,不多說直接上乾貨。

以下是本文的知識清單:

  • SparseArray
  • atomic包
  • Android埋點
  • Java基礎之註解
  • 一點小感悟

在這裡由於文字較多,小編總結了一份高階Android技術大綱和學習資料免費分享給大家,文末有領取!

1. SparseArray

當新建一個key為整型的HashMap時,會出現如下的提示信息,推薦使用SparseArray來替代HashMap:

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

接下來就來介紹下SparseArray:

a.數據結構:又稱稀疏數組,內部通過兩個數組分別存儲key和value,並用壓縮的方式來存儲數據

b.優點:可替代key為int、value為Object的HashMap,相比於HashMap

  • 能更節省存儲空間
  • 由於key指定為int,能節省int和Integer的裝箱拆箱操作帶來的性能消耗
  • 擴容時只需要數組拷貝工作,而不需重建哈希表

c.適用場景:數據量不大(千以內)、空間比時間重要、需要使用Map且key為整型;不適合存儲大容量數據,此時性能將退化至少50%

d.使用

添加:public void put(int key, E value)

刪除:

  • public void delete(int key)
  • public void remove(int key)實際上內部會調用delete方法

查找:

  • public E get(int key)
  • public E get(int key, E valueIfKeyNotFound)可設置假設key不存在時默認返回的value
  • public int keyAt(int index)獲取相應的key
  • public E valueAt(int index)獲取相應的value

e.get/put過程:元素會按照key從小到大進行存儲,先使用二分法查詢key對應在數組中的下標index,然後通過該index進行增刪查。源碼分析見SparseArray解析

2. atomic包

a.原子操作類:

與採取悲觀鎖策略的synchronized不同,atomic包採用樂觀鎖策略去原子更新數據,並使用CAS技術具體實現

<code> 

public

class

Sample

{

private

static

Integer count =

0

;

synchronized

public

static

void

increment

()

{ count++; } }

public

class

Sample

{

private

static

AtomicInteger count =

new

AtomicInteger(

0

);

public

static

void

increment

()

{ count.getAndIncrement(); } }/<code>

基礎知識:Java併發問題--樂觀鎖與悲觀鎖以及樂觀鎖的一種實現方式-CAS

b.類型

原子更新基本類型:

  • AtomicInteger:原子更新Integer
  • AtomicLong:原子更新Long
  • AtomicBoolean:原子更新boolean

以AtomicInteger為例,常用方法:

  • getAndAdd(int delta):取當前值,再和delta值相加
  • addAndGet(int delta) :先和delta值相加,再取相加後的最終值
  • getAndIncrement():取當前 值,再自增
  • incrementAndGet() :先自增,再取自增後的最終值
  • getAndSet(int newValue):取當前值,再設置為newValue值

原子更新數組:

  • AtomicIntegerArray:原子更新整型數組中的元素
  • AtomicLongArray:原子更新長整型數組中的元素
  • AtomicReferenceArray:原子更新引用類型數組中的元素

以AtomicIntegerArray為例,常用方法:

  • addAndGet(int i, int delta):先將數組中索引為i的元素與delta值相加,再取相加後的最終值
  • getAndIncrement(int i):取數組中索引為i的元素的值,再自增
  • compareAndSet(int i, int expect, int update):如果數組中索引為i的元素的值和expect值相等,則更新為update值

原子更新引用類型:

  • AtomicReference:原子更新引用類型
  • AtomicReferenceFieldUpdater:原子更新引用類型裡的字段
  • AtomicMarkableReference:原子更新帶有標記位的引用類型
<code> 

public

class

AtomicDemo

{

private

static

AtomicReference reference =

new

AtomicReference<>();

public

static

void

main

(

String[] args

)

{ User user1 =

new

User(

"a"

,

1

); reference.

set

(user1); User user2 =

new

User(

"b"

,

2

); User user = reference.getAndSet(user2); System.

out

.println(user); User{userName=

'a'

, age=

1

} System.

out

.println(reference.

get

()); User{userName=

'b'

, age=

2

}}

static

class

User

{

private

String userName;

private

int

age;

public

User

(

String userName,

int

age

)

{

this

.userName = userName;

this

.age = age; } @

Override

public

String

toString

(

)

{

return

"User{"

+

"userName='"

+ userName +

'\''

+

", age="

+ age +

'}'

; } } }/<code>

原子更新字段:

  • AtomicIntegeFieldUpdater:原子更新整型字段
  • AtomicLongFieldUpdater:原子更新長整型字段
  • AtomicStampedReference:原子更新帶有版本號的引用類型

使用方法:由於原子更新字段類是抽象類,因此需要先通過其靜態方法newUpdater創建一個更新器,並設置想更新的類和屬性注意:被更新的屬性必須用public volatile修飾

<code> 

public

class

AtomicDemo

{

private

static

AtomicIntegerFieldUpdater updater = AtomicIntegerFieldUpdater.newUpdater(User.class,

"age"

);

public

static

void

main

(String[] args)

{ User user =

new

User(

"a"

,

1

);

int

oldValue = updater.getAndAdd(user,

5

); System.out.println(oldValue); System.out.println(updater.get(user)); }

static

class

User

{

private

String userName;

public

volatile

int

age;

public

User

(String userName,

int

age)

{

this

.userName = userName;

this

.age = age; } @

Override

public

String

toString

()

{

return

"User{"

+

"userName='"

+ userName +

'\''

+

", age="

+ age +

'}'

; } } }/<code>

c.優點:

可以避免多線程的優先級倒置和死鎖情況的發生,提升在高併發處理下的性能,相比於synchronized ,在非激烈競爭的情況下,開銷更小,速度更快

3. Android埋點

a.含義:預先在目標應用採集數據,對特定用戶行為或事件進行捕獲、處理,並以一定方式上報至服務器,便於後續進行數據分析

b.方式

代碼埋點:在某個事件發生時通過預先寫好的代碼來發送數據

  • 優點:控制精準,採集靈活性強,可自由選擇何時發送自定義數據
  • 缺點:開發、測試成本高,需要等發版才能修改線上埋點、更新代價大

無埋點/全埋點:在端上自動採集並上報儘可能多的數據,在計算時篩選出可用的數據

  • 優點:很大程度上減少開發、測試的重複勞動,數據可回溯且覆蓋全面
  • 缺點:採集信息不夠靈活,數據量大,後端篩選分析工作量大

可視化埋點:通過可視化工具選擇需要收集的埋點數據,下發配置給客戶端,終端點擊時獲取當前點擊的控件根據配置文件進行選擇上報

  • 優點:很大程度上減少開發、測試的重複勞動,數據量可控且相對精確,可在線上動態埋點、而無需等待App發版
  • 缺點:採集信息不夠靈活,無法解決數據回溯的問題

幾個實踐:51信用卡(https://mp.weixin.qq.com/s/svzwQkAy0favp0Ty3NtoLA)、網易(https://mp.weixin.qq.com/s/0dHKu5QIBL_4S7Tum-qW2Q)、58同城(https://mp.weixin.qq.com/s/rP7PiN7lsnUxcY1BAhB_5Q)

4.Java基礎之註解(Annotation)

a.含義:是附加在代碼中的一些元數據,在JDK1.5 版本開始引入,與類、接口、枚舉在同一個層次

b.作用:

聲明在包、類、字段、方法、局部變量、方法參數等前面,用來對這些元素進行說明和註釋

註解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用,比如編譯時進行格式檢查、簡化操作進而降低代碼量

c.使用

以下代碼展示了註解的定義、屬性和使用的方法:

<code>

//

1.

註解的定義: 通過@interface關鍵字

//

以下表示創建了一個名為TestAnnotation的註解public @interface TestAnnotation {

//

2.

註解的屬性:

//

聲明:採用“無形參的方法”形式,方法名錶示屬性名,返回值表示屬性類型

//

類型:必須是

8

種基本數據類型,或者類、接口、註解及對應數組

//

默認值:用

default

關鍵值,在賦值時可以省略

//

以下表示註解TestAnnotation中有id和msg兩個屬性,且msg默認值為hiint id();String msg()

default

"hi"

;}

//

3.

註解的使用:

//

對屬性賦值:在註解使用打個括號,以value=

""

形式,多個屬性之前用逗號隔開;若註解只有一個屬性,則賦值時value=可以省略;如果沒有屬性,括號都可以省略

//

以下表示對Test類進行標識,並對註解的適兩個屬性進行賦值@TestAnnotation(id=

1

,msg=

"hello"

)public

class

Test

{}

/<code>

d.類型:

元註解:是一種基本註解,用於解釋註解,注意其描述對象是註解而非代碼,包含類型如下表:

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

來段代碼感受下這些註釋的使用效果:

<code> 

@Target

({ElementType.TYPE})

@Retention

(RetentionPolicy.RUNTIME)

@Documented

@Inheritedpublic

@interface

TestAnnotation {} /<code>

接下來用單獨一個例子來解釋可重複註解

<code>//

1

.定義一個註解容器(此處指@Persons): //作用:存放其他註解(此處指@Person),其本身也是個註解 //注意:需要有個value屬性,類型就是被@Repeatable解釋的註解數組(此處指Person[])@interface Persons { Person[] value();

//

註解屬性} //

2

.使用@Repeatable解釋(此處指@Person),括號中是註解容器類(此處指Persons)@Repeatable(Persons.class)@interface Person { String role default

""

;

//

註解屬性} //

3

.使用@Repeatable解釋的註釋時,可以取多個註解值來解釋代碼@Person(role=

"coder"

)@Person(role=

"PM"

)public class SuperMan {

//

SuperMan既是程序員又是產品經理}/<code>

Java內置註解:下表展示了幾個常用的內部已實現註解

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

自定義註解:在之前已經介紹了註解的定義、屬性和使用的具體方法,還差一步,註解的提取,需要通過Java的反射技術獲取類方法和字段的註解信息,常用方法:

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

在之前的Test類裡就可以添加以下代碼,來獲取在類上給@TestAnnotation設置的屬性值了:

<code>boolean hasAnnotation = Test

.

class

.

isAnnotationPresent

(TestAnnotation

.

class

);

if

(hasAnnotation) { TestA/<code>

結尾

如何才能讓我們在面試中對答如流呢?

答案當然是平時在工作或者學習中多提升自身實力的啦,那如何才能正確的學習,有方向的學習呢?有沒有免費資料可以借鑑。為此我整理了一份Android學習資料路線:

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

【Android核心高級技術PDF文檔,BAT大廠面試真題解析】

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

【算法合集】

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

【延伸Android必備知識點】

太讚了!這或許是騰訊一線最真實的Android面試資料了吧

好了,今天的分享就到這裡,如果你對在面試中遇到的問題,或者剛畢業及工作幾年迷茫不知道該如何準備面試並突破現狀提升自己,對於自己的未來還不夠了解不知道給如何規劃,可以看一下下面的Android學習筆記參考獲得免費領取方式。來看看同行們都是如何突破現狀,怎麼學習的,來吸收他們的面試以及工作經驗完善自己的之後的面試計劃及職業規劃。

這裡是一部分我工作以來以及參與過的大大小小的面試收集總結出來的一套進階學習的視頻及面試專題資料包,在這裡免費分享給大家,主要還是希望大家在如今大環境不好的情況下面試能夠順利一點,希望可以幫助到大家~

【Android進階學習視頻】、【全套Android面試秘籍PDF】、【Android開發核心知識點筆記】可以 私信我【安卓】免費獲取!

這裡只是整理出來的部分面試題,後續會持續更新,希望通過這些高級面試題能夠降低面試Android崗位的門檻,讓更多的Android工程師理解Android系統,掌握Android系統。喜歡的話麻煩點擊一個喜歡在關注一下~


分享到:


相關文章: