接着上午的双选会,晚上我又去了宣讲会~~ 今天我真的是太勤快了啊!!
晚上一共两家宣讲会,还是有现场笔试的那种,我来也是为了笔试的。
第一家是金融软件的IT企业,坐标杭州,难怪这么迅速,笔试完第二天就约面试了。
不过要我说,笔试是真的难,怀疑自己30分都有没有,选择题懵了很多,两道大题也不会,毫无思路,也记不起来(都是学过的东西)。
今天熬夜复盘一下,以免后面再次遇到了还不会。
从二进制计算开始说起吧,小数位的二进制转换,是真的忘记了。
十进制数的整数位是二进制数的整数位,十进制数的小数位是二进制数的小数位。两部分分开转换。
整数部分 除以2取余,逆序排列。 小数部分 乘 2 取整,顺序排列。
例如转换十进制小数11.4,过程如下。
计算整数部分,11转换为二进制位1011:
计算小数部分0.4,首先将小数部分一直乘2,积的整数部分顺序取出:
0.4 * 2=0.8 取0 |
0.8 * 2=1.6 取1 | 顺
0.6 * 2=1.2 取1 | 序
0.2 * 2=0.4 取0 | 排
0.4 * 2=0.8 取0 | 列
0.8 * 2=1.6 取1 |
0.6 * 2=1.2 取1 |
0.2 * 2=0.4 取0 |
可以看出0110是循环,因此小数部分的二进制是
0.01100110……(循环0110)
最终结果是整数位和小数位合并1101111.01100110……(2)
二进制小数转换为十进制小数
使用按权展开求和法,小数点左边是2的正数次方,从0开始;小数点右边是2的负数次方,从-1开始。
例如将101.111(2)转换成十进制数
1*(2^2)+0*(2^1)+1*(2^0) # 整数部分
+ 1*(2^(-1))+1*(2^(-2))+1*(2^(-3)) # 小数部分
=5.875
接着是 二叉树的前中后序遍历 。。
原题复现:
已知二叉树的后序遍历序列是dabec,中序遍历序列是debac,它的前序遍历序列是(cedba)。
(1) 中序遍历:debac
后序遍历:dabec
后序遍历序列的最后一个结点是根结点,所以可知c为根结点。
中序遍历序列的根结点在中间,其左边是左子树,右边是右子树。所以从中序遍历序列中可看出,根结点c只有左子树,没有 右子树。
(2) 中序遍历:deba
后序遍历:dabe
后序遍历序列的最后一个结点是根结点,所以可知e为c的左子树的根结点。
中序遍历序列的根结点在中间,其左边是左子树,右边是右子树。所以从中序遍历序列中可看出,根结点e的左子结点是d,右子树是ba。
(3) 中序遍历:ba
后序遍历:ab
由后序遍历序列可知b为e的右子树的根结点。由中序遍历序列中可看出,a为根结点b的右子结点。
来,小二!上一碟开胃小菜~(被操作系统虐的…)
生产者消费者问题:(伪代码实现)
假设缓冲区大小为10,生产者、消费者线程若干。生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。
items 代表缓冲区已经使用的资源数,spaces 代表缓冲区可用资源数
mutex 代表互斥锁
buf[10] 代表缓冲区,其内容类型为item
in、out 代表第一个资源和最后一个资源
var items = 0, space = 10, mutex = 1;
var in = 0, out = 0;
item buf[10] = { NULL };
producer {
while( true ) {
wait( space ); // 等待缓冲区有空闲位置, 在使用PV操作时,条件变量需要在互斥锁之前
wait( mutex ); // 保证在product时不会有其他线程访问缓冲区
// product
buf.push( item, in ); // 将新资源放到buf[in]位置
in = ( in + 1 ) % 10;
signal( mutex ); // 唤醒的顺序可以不同
signal( items ); // 通知consumer缓冲区有资源可以取走
}
}
consumer {
while( true ) {
wait( items ); // 等待缓冲区有资源可以使用
wait( mutex ); // 保证在consume时不会有其他线程访问缓冲区
// consume
buf.pop( out ); // 将buf[out]位置的的资源取走
out = ( out + 1 ) % 10;
signal( mutex ); // 唤醒的顺序可以不同
signal( space ); // 通知缓冲区有空闲位置
}
}
还有一系列操作系统的选择题记不起来了。
直接上煮菜吧!!
负载均衡
五台电脑,CPU性能不同,内存不同,怎么实现合理分配?!