要想处理位元,你必须先得知道在二进制补码([**two’s complement**](http://en.wikipedia.org/wiki/Two%27s_complement))标记内部,数字是如何表示的——二进制补码和无格式二进制标记是一样的,只是负数要“进行位元翻转之后再加1”。比如要想得到数字-1,你要从用8位二进制整数表示是00000001的1开始。对每一个位元进行翻转之后的结果是11111110,再加上1就是11111111,也就成了二进制补码中的-1。
**左移位**运算符“<<”会把位元移向左边,用0来补上移走之后的空位。
**右移位**运算符“>>”会把一个位模式向右移,但当向右移动负数时,它的作用在不同编程语言中也不一样,在Java中,右移位会用符号扩充的办法,用1来填充负数中的空位。
**逻辑右移位**运算符“>>>”是Java和Javascript中独有的,无论数值是多少,它都用0来填充空位。
**设置某一位**:可以用**按位或**运算符(|)。
~~~
num |= 1 << x; //这行代码将会设置位元x
~~~
**清除某一位**:可以用**按位与**运算符(&),并且用**取反**运算符(~)来屏蔽所有你不想清除的位元。
~~~
num &= ~(1 << x); //这会清除位元x
~~~
**清除一直到****i****的所有有效位元**:
~~~
num &= (1 << (i + 1)) -1;
~~~
切换某一位元:可以用**按位异或**运算符(^)
~~~
num ^= 1 << x; //这会切换位元x
~~~
获得一个位元:对你想检查的位元用**按位与**
~~~
bit = num & (1 << x);
~~~
### 设计模式/面向对象编程
和面向对象编程相关的问题,一般会涉及到设计相关类里的集,以便检验你对面向对象编程的熟悉程度,并了解你是如何架构代码的。你可以使用界面和/或抽象的类来说明,并记住用单例模式([**Singleton**](http://en.wikipedia.org/wiki/Singleton_pattern))、工厂方法模式([**Factory**](http://en.wikipedia.org/wiki/Factory_method_pattern))和策略模式([**Strategy**](http://en.wikipedia.org/wiki/Strategy_pattern))来解决这类问题,在编写优雅而可维护的代码方面,它们能对你有长久的助益。