Many people may have encountered such a question in the interview:
There are 1000 identical bottles, 999 of which are ordinary water, one of which is highly toxic (diluted and still toxic), and you only have 10 mice, which will die immediately after drinking the poison, how do you use them to determine which bottle is the poison in the shortest time?
As we all know, in computer language, all numbers are eventually converted to binary for calculation, and each “bit” in binary can represent two states, the digits 0 and 1.
Back to the topic, each state of the birth and death of mice can be said a “a” in binary, 10 mice can said total 1024 kinds of composite state, therefore, a solution of this problem is for the 1000 bottles of water, according to the binary format label mark (10 bit binary number can mark all), The 10 mice were assigned to one of the 10 binary digits, and then the mice were given the water with the current digit of 1 in the 10 binary digits to drink. Based on the death condition of the mice, they could determine which bottle of water was toxic.
Understand bit operations from MeasureSpec
In Android development, we are also familiar with in-place computing. Int makeMeasureSpec(int size, int mode) : int makeMeasureSpec(int size, int mode) Simply is to use a 32 bit binary number in the high two MeasureMode to store measurement mode, with low MeasureSize 30 to store size, MeasureSpec is android. The view. The view class in an inner class, key code is as follows:
public static class MeasureSpec { private static final int MODE_SHIFT = 30; //SpecMode mask for masking high bits //11 000000 00000000 00000000 00000000 00000000 private static final Int MODE_MASK = 0x3 << MODE_SHIFT; //00 000000 00000000 00000000 00000000 public static final int UNSPECIFIED = 0 << MODE_SHIFT; //01 000000 00000000 00000000 00000000 public static final int EXACTLY = 1 << MODE_SHIFT; //10 000000 00000000 00000000 00000000 public static final int AT_MOST = 2 << MODE_SHIFT; MeasureSpec public static int makeMeasureSpec(int size, int mode) {MeasureSpec public static int makeMeasureSpec(int size, int mode)if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return(size & ~MODE_MASK) | (mode & MODE_MASK); SpecMode public static int measureSpec (measureSpec) {return(measureSpec & MODE_MASK); SpecSize public static int measureSpec (measureSpec) {return(measureSpec & ~MODE_MASK); }}Copy the code
Bitwise operators are commonly used as follows:
-
Or operator | : 0 | 0 = 0, 0 = 1, 1 | | 1 1 = 1
-
The and operator & : 0&0=0, 0&1=0, 1&1=1
-
Non-operators ~ : ~0=1, ~1=0
-
The xOR operator ^ : same is 0, different is 1:0 ^0=0, 1^0=1, 0^1=1, 1^1=0
-
The right shift operator >> and the left shift operator << : 001<<2= 100,110 >>1=11
MeasureSpec class, the getMode method is with MODE_MASK parameter MeasureSpec with operations, MODE_MASK can be understood as SpecMode mask, the result of operation is retained MeasureSpec high two, The remaining last 30, at position 0, yields MeasureMode.
MeasureSpec = measureSpec = measureSpec = measureSpec = measureSpec = measureSpec = measureSpec = measureSpec
In makeMeasureSpec, the result of size & ~MODE_MASK is size SpecSize, and the result of mode & MODE_MASK is SpecMode.
The use of bit operations in practical development
Similarly, in daily development, we can also use bit operations to simplify some operations. If the server returns a number, there may be several state superposition situations (figure below), if the traditional method to deal with it will be troublesome, this time we need to use bit operations.
We can create a new StatusManager class to handle this complex state:
Public class StatusManager {// Normal public static final int STATUS_NORMAL = 0; Public static final int STATUS_TIME_ASY = 1; public static final int STATUS_TIME_ASY = 1; Public static final int STATUS_OPEN_DOOR = 1 << 1; Public static final int STATUS_ADD_FIXED_PSW = 1 << 2; Public static final int STATUS_DEL_FIXED_PSW = 1 << 3; // 1000 // Store current permission status private int flag; /** * resets state */ public voidsetStatus(int status) { flag = status; } / add one or more state * * * * / public void addStatus (int status) {flag | = status; } public void deleteStatus(int status) {flag &= ~status; } public Boolean hasStatus(int status) {public Boolean hasStatus(int status) {return(flag & status) == status; } /** * public Boolean isHasnotStatus(int status) {return(flag & status) == 0; } public Boolean isOnlyHas(int status) {returnflag == status; }}Copy the code
To add a state, write:
manager.addStatus(StatusManager.STATUS_TIME_ASY | STATUS_ADD_FIXED_PSW )
Copy the code
If you need to check whether time synchronization and open door instruction fail at the same time, you can write:
manager.hasStatus(StatusManager.STATUS_TIME_ASY | STATUS_OPEN_DOOR)
Copy the code