1.SparseArrayhtml
當新建一個key爲整型的HashMap時,會出現以下的提示信息,推薦使用SparseArray來替代HashMap: java
![]()
接下來就來介紹下SparseArray:程序員
a.數據結構:又稱稀疏數組,內部經過兩個數組分別存儲key和value,並用壓縮的方式來存儲數據後端
b.優勢:可替代key爲int、value爲Object的HashMap,相比於HashMap數組
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不存在時默認返回的valuepublic int keyAt(int index)
獲取相應的keypublic E valueAt(int index)
獲取相應的valuee.get/put過程:元素會按照key從小到大進行存儲,先使用二分法查詢key對應在數組中的下標index,而後經過該index進行增刪查。源碼分析見SparseArray解析數據結構
2.atomic包多線程
a.原子操做類:與採起悲觀鎖策略的synchronized不一樣,atomic包採用樂觀鎖策略去原子更新數據,並使用CAS技術具體實現併發
//保證自增線程安全的兩種方式
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();
}
}
複製代碼
b.類型
原子更新基本類型:
以AtomicInteger爲例,經常使用方法:
getAndAdd(int delta)
:取當前值,再和delta值相加addAndGet(int delta)
:先和delta值相加,再取相加後的最終值getAndIncrement()
:取當前 值,再自增incrementAndGet()
:先自增,再取自增後的最終值getAndSet(int newValue)
:取當前值,再設置爲newValue值
原子更新數組:
以AtomicIntegerArray爲例,經常使用方法:
addAndGet(int i, int delta)
:先將數組中索引爲i的元素與delta值相加,再取相加後的最終值getAndIncrement(int i)
:取數組中索引爲i的元素的值,再自增compareAndSet(int i, int expect, int update)
:若是數組中索引爲i的元素的值和expect值相等,則更新爲update值
原子更新引用類型:
//這幾個類提供的方法基本一致,以AtomicReference爲例
public class AtomicDemo {
private static AtomicReference<User> 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 + '}';
}
}
}
複製代碼
原子更新字段:
使用方法:因爲原子更新字段類是抽象類,所以須要先經過其靜態方法
newUpdater
建立一個更新器,並設置想更新的類和屬性 注意:被更新的屬性必須用public volatile
修飾
//這幾個類提供的方法基本一致,以AtomicIntegeFieldUpdater爲例
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);//輸出1
System.out.println(updater.get(user));//輸出6
}
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 +'}';
}
}
}
複製代碼
c.優勢:能夠避免多線程的優先級倒置和死鎖狀況的發生,提高在高併發處理下的性能,相比於synchronized ,在非激烈競爭的狀況下,開銷更小,速度更快
3.Android埋點
a.含義:預先在目標應用採集數據,對特定用戶行爲或事件進行捕獲、處理,並以必定方式上報至服務器,便於後續進行數據分析
b.方式
4.Java基礎之註解(Annotation)
a.含義:是附加在代碼中的一些元數據,在JDK1.5 版本開始引入,與類、接口、枚舉在同一個層次
b.做用:
c.使用
如下代碼展現了註解的定義、屬性和使用的方法:
//1.註解的定義:經過@interface關鍵字
//如下表示建立了一個名爲TestAnnotation的註解
public @interface TestAnnotation {
//2.註解的屬性:
//聲明:採用「無形參的方法」形式,方法名錶示屬性名,返回值表示屬性類型
//類型:必須是8種基本數據類型,或者類、接口、註解及對應數組
//默認值:用default關鍵值,在賦值時能夠省略
//如下表示註解TestAnnotation中有id和msg兩個屬性,且msg默認值爲hi
int id();
String msg() default "hi";
}
//3.註解的使用:
//對屬性賦值:在註解使用打個括號,以value=""形式,多個屬性以前用逗號隔開;若註解只有一個屬性,則賦值時value=能夠省略;若是沒有屬性,括號均可以省略
//如下表示對Test類進行標識,並對註解的適兩個屬性進行賦值
@TestAnnotation(id=1,msg="hello")
public class Test {
}
複製代碼
d.類型:
名稱 | 做用 | 取值 |
---|---|---|
@Target (目標註解) |
描述註解的限定使用範圍 | ElementType.CONSTRUCTOR : 對構造方法進行註解;ElementType.ANNOTATION_TYPE : 對註解進行註解;ElementType.FIELD : 對屬性進行註解;ElementType.LOCAL_VARIABLE : 對局部變量進行註解;ElementType.METHOD : 對方法進行註解;ElementType.PACKAGE : 對包進行註解;ElementType.PARAMETER : 對描述參數進行註解;ElementType.TYPE : 對類型(類、接口、枚舉)進行註解 |
@Inherited (繼承註解) |
擁有該註解的註解所做用的類,且其子類未帶任何註解,則該子類也會繼承父類的註解 | |
@Retention (保留註解) |
描述註解的生命週期 | RetentionPolicy.SOURCE : 註解只保留在源碼階段,在編譯器完整編譯以後會被丟棄忽視;RetentionPolicy.CLASS : 註解會保留到編譯進行時,但不會被加載到 JVM ;RetentionPolicy.RUNTIME : 註解會保留到程序運行時,且會被加載進入到 JVM |
@Documented (文檔註解) |
將註解添加到Java文檔 | |
@Repeatable (可重複註解) |
表示註解的值能夠同時取多個 |
來段代碼感覺下這些註釋的使用效果:
//表示TestAnnotation註釋是對類描述的、保留到運行時、被添加到Javadoc、有繼承性值的
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface TestAnnotation {
}
//因爲B類是A類的子類,且B類沒被任何註解應用,則B類繼承了A類的TestAnnotation註解
@TestAnnotation
public class A {}
public class B extends A {}
複製代碼
接下來用單獨一個例子來解釋可重複註解
//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既是程序員又是產品經理
}
複製代碼
名稱 | 做用 |
---|---|
@Override (複寫註解) |
被標記的方法須要被子類複寫,不然編譯器會報錯 |
@Deprecated (過期註解) |
標記已過期的元素,當元素使用時會在代碼劃橫線 |
@SuppressWarnings (阻止警告註解) |
被標記的元素會阻止編譯器發出警告提醒 |
@SafeVarargs (參數安全類型註解) |
提醒開發者不要用參數作不安全的操做、阻止編譯器產生unchecked警告 |
方法名 | 返回值 | 描述 |
---|---|---|
isAnnotationPresent(Class<? extends Annotation> annotationClass) |
boolean |
若是指定類型的註解存在於此元素上,則返回 true,不然返回 false |
getAnnotation(Class<A> annotationClass) |
<A extends Annotation> |
該元素若是存在指定類型的註解,則返回這些註解,不然返回 null |
getAnnotations() |
Annotation[] |
返回此元素上存在的全部註解,包括從父類繼承的 |
getDeclaredAnnotations() |
Annotation[] |
返回直接存在於此元素上的全部註解,但不包括父類的註解 |
在以前的Test類裏就能夠添加如下代碼,來獲取在類上給@TestAnnotation設置的屬性值了:
boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);
if (hasAnnotation) {
TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);
System.out.println("id:"+testAnnotation.id());//輸出1
System.out.println("msg:"+testAnnotation.msg());//輸出hello
}
複製代碼
推薦閱讀:秒懂,Java 註解 (Annotation)你能夠這樣學
5.一點小感悟
最近的生活變得很是規律和健康,果真工做令人勤快,從早上出門開始,穿梭巴士、免費早餐、養生茶水、一餐一果、關燈午休、夜宵券、打車報銷...天天都能感覺到鵝廠對員工的關懷,幸福感滿滿。
這陣子的工做也有了新的進展,走過了熟悉項目、定位bug、討論方案的階段,寫下了第一行代碼~捋代碼邏輯的這段日子我開始深深懷疑人生,感受智商down到谷底,這裏就不得不感激導師的耐心指導,還老是關心我有沒有疑問,努力挽救一個辣雞少女。
前幾天開了個總結會,關於某個版本的bug review,不只是回顧bug產生緣由和解決辦法,更可能是反思和總結經驗,好比反覆打補丁不如從根源解決、重構務必看懂每行代碼切勿放過哪怕一個字段、注意空指針問題、要考慮到邊界條件、自測要到位、多機型多系統測試、使用接口要注意內部實現...聽罷感受受益不淺,提醒本身時刻注意,少走些彎路。
看着同事愈來愈少才發覺立刻就放假了,不過你們都絲毫沒有懈怠,天天十點多還沒什麼人離開,有時候大半夜還在羣裏討論方案,週五也是如此,週末有天來公司還看到幾個好學的小哥哥在,和優秀的人共事也但願本身早日也能如此優秀呀~
PS:上週末由於身體不舒服沒有及時更新,和這周就合併了~還有立刻過年了提早祝你們新年快樂,假期愉快,明年再見(`・ω・´)