求職不怕考
pcw-chendx@vip.sina.com
與編程相關的招聘,都會準備很多考題,一不小心考生就在考題上栽了跟頭,特別是沒有多少工作經驗的應屆畢業生,往往回答得過於理論化,很難令考官滿意。為此,我們特意推出本系列,通過對真實考題的分析讓大家在回答考題時有更多的實用性,讓考官滿意,順利找到工作。
位元運算 最佳化運算速度
爪哇米工作室 陳躍峰
位元運算在語言基礎學習中比較枯燥,所以很多學生朋友未深入學習,也沒有實際應用該基礎知識,但是在實際的項目開發中,位元運算由於其運算的速度優勢,在很多的領域被廣泛應用,所以在實際的招聘考試中,位元運算的考題比較常見。
招聘題目:請寫出求2的3次方最快的方法。
答案A:2x2x2
答案B:1 << 3
題目答案:B
為什麼答案是B
答案A是計算2的3次方的數學方法,通過十進位運算方式實現題目要求的結果,但是在執行效率上無法滿足題目的要求。為什麼這種方法無法滿足題目的要求呢?這就要從電腦的運算模式說起了。
電腦的運算模式是以二進位為基礎,所以十進位運算在計算時會被轉換成二進位再進行運算,而轉換過程就會導致運行速度降低。計算2的3次方最快的方法應該是使用位元運算中的移位元運算符,通過二進位移位實現,這種方法可以提高運算速度。
通過這個題目,考官既考查了應聘者是否對程式的執行效率有深刻的認識,也考查應聘者是否具備位元運算的相關知識。位元運算在程式開發中非常常見,合理使用位元運算可以提高程式的執行效率,所以我們平時使用的軟體大多數都用到了位元運算操作。下面我們來看看位元運算操作在實際開發中是如何被應用的。
位元運算儲存資料
利用位元運算儲存資料,主要是為了減少程式佔用的記憶體。以int資料為例子,如果按照十進位的方式儲存資料,一個32位的int變數只能儲存一個數值,而如果使用二進位方式儲存資料(缺點是只能儲存0或1兩個資料)則可以儲存32個資料,將極大的節約記憶體。
例如,在一個int變數的從右側開始倒數第2位儲存資料,則儲存和讀取資料的代碼如下所示:
int bData = 0;
//儲存數值1
bData = bData | (1 << (2 - 1));
//儲存數值0
bData = bData & (~(1 << (2 - 1));
//讀取資料
int
n = bData & (1 << (2 - 1));
點評:在該代碼中,將需要儲存的資料(0或1)儲存在變數bData的倒數第二位中,所以在儲存時,則只需要將倒數第二位的數值改變,其他位的數值不改變即可。所以在儲存1時,不論bData的數值是多少,只需要和位元據10進行位或運算就可以將倒數第二位置1,而需要儲存0時,則需要bData和0xfffffffd進行位與運算,即可達到清零倒數第二位的目的。
需要注意的是,有些可能會認為在儲存數值0時,會使用如下的代碼實現:
bData = bData | (0 << (2 - 1));
其實這樣是錯誤的,因為0無論左移多少位都還是0,這樣在進行位或運算時,0和1位或得到的結果會是1,無法實現設定對應的位為0的目的,所以需要使用以上的代碼進行實現。
異或位元運算簡單加密
利用位元運算的計算速度快,以及異或的特性(和同一個數字異或兩次還是自身),可以用來簡單加密資料,且加解密的速度會非常快。這種加密方式強度比較低,但是可以用於一般的加解密任務。
例如,假設密匙是數字123,則加解密一個byte數組的代碼如下:
byte[]
b = {1,2,3,5,6};
byte
key = 123;
//依次加密的代碼
for(int
i = 0;i < b.length;i++){
b[i]
= (byte)(b[i] ^ key); //利用異或加密
}
//解密的代碼
for(int
i = 0;i < b.length;i++){
b[i]
= (byte)(b[i] ^ key); //利用異或解密
}
點評:在該代碼中,對數組b使用密匙key進行加密,加密的過程是將數組b中每個元素和key進行異或,加密以後的資料可以在實際應用中進行儲存或網路傳輸,而解密時的操作和加密時一樣,使用這種簡單的加密方式雖然保密性不高,但是加解密的速度確實是很值得稱讚的。