匠心零度 轉載請註明原創出處,謝謝!java
看過稍微底層點的源碼的人應該都會了解、熟悉裏面多多少少會碰到二進制相關操做,由於這個以前還寫了一篇java二進制相關基礎的基礎篇,本篇準備寫一些二進制實戰技巧相關內容。網絡
若是該數是無符號整數,可使用:框架
private static boolean isPowerOfTwo(int val) {
return (val & (val-1)) == 0;
}
複製代碼
若是一個數是2的n次方,那麼這個數用二進制表示時其最高位爲1,其他位爲0,(val-1)和val都錯開了0和1,那麼&必定是0。性能
若是該數是無符號整數,也可使用:spa
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}
複製代碼
若是一個數是2的n次方,那麼這個數用二進制表示時其最高位爲1,其他位爲0,(val & -val)就是獲取最右1的位,那麼若是和val等於就是了。code
擴展下,如何判斷一個無符號數是2的n次方-1cdn
private static boolean isPowerOfTwoLoseOne(int val) {
return (val & (val+1)) == 0;
}
複製代碼
理由其實和上面相似了。blog
JDK SelectionKey有四種操做類型,分別爲:ci
OP_READ = 1 << 0;
OP_WRITE = 1 << 2;
OP_CONNECT = 1 << 3;
OP_ACCEPT = 1 << 4。
複製代碼
因爲只有四種網絡操做類型,因此用4 bit就能夠表示全部的網絡操做位,因爲JAVA語言沒有bit類型,因此使用了整形來表示,每一個操做位表明一種網絡操做類型,分別爲:0000一、00100、01000、10000,這樣作的好處是能夠很是方便的經過位操做來進行網絡操做位的狀態判斷和狀態修改,提高操做性能。get
**說明:**依稀記得RocketMQ裏面好像也是相似,有一個當磁盤空間大於90%的時候不給寫權限就是相似控制的,後續分析RocketMQ源碼的時候會進行說明。
在jdk不少集合框架裏面,不知道大家還發現了,集合的大小都會是2的冪次方,哈哈,因此就引出了下面的話題。
int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
MAXIMUM_CAPACITY :
private static final int tableSizeFor(int c) {
int n = c - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
複製代碼
實例化ConcurrentHashMap時帶參數時,會根據參數調整table的大小,確保table的大小老是2的冪次方,調用tableSizeFor的時候每次返回的都是大於等於離該數最近的2的冪次方的數。好比調用tableSizeFor傳入c爲151的時候 比151大的2的冪次方的數就是256了,核心就是上面的位運算操做。
剛剛上面是求一個數離它最近的大於等於2的冪次方的數,若是求小於等於2的冪次方的數,咱們應該怎麼辦呢?
private static final int tableSizeFor(int n) {
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return n-(n>>1);
}
複製代碼
**說明:**因爲集合的大小都會是2的冪次方,那麼求table大小的0.75倍的時候,可使用(n - (n >>> 2))便可,取模的時候,可使用hash & 0x7FFFFFFF來進行操做便可。
上面的都是零度發現的一些實戰,若是你發現什麼更好的二進制實戰,歡迎在留言區積極留言評論。!!!
若是讀完以爲有收穫的話,歡迎點贊、關注、加公衆號【匠心零度】,查閱更多精彩歷史!!!