电话面试2 20160325_1733_27min

这次电话面试有个提前预约,20160324_1509时,约到第二天下午五点。

1、线程和进程的区别,线程共享进程的哪些资源?

我的另一篇博客:进程和线程的区别
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)地址空间:线程是进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源(内存资源);
(3)线程是处理器调度的基本单位,但进程不是;
(4)二者均可并发执行;

2、以前用电脑的时候,内存只有256兆,然后系统运行得比较慢,内存增加4个G,整个系统就会流畅很多,为什么?

因为CPU的地址线范围大于了内存的大小。

3、你最精通的一门C语言是什么?

4、C++中的虚函数是一个什么样的概念?

虚函数用于成员函数的多态性,用于声明那些大体结构内容相似但细节实现上又有不同的成员函数,比如飞禽类的一个成员函数叫fly(),而麻雀类的fly()里面运行扑腾着飞(),老鹰类的fly()里面运行滑翔()。

而当一个类A的成员函数H声明为虚函数(virtual)的时候,再用这个类A去声明一个b,而b又定义成了类B的实例,并且类B是继承于A的,即
类A 实例b;
实例b=new 类B;(B继承于A)
b.H;

此时实例B调用这个虚函数,分为三种情况,
(1)如果类B重写(override)了这个函数,则这个b会运行重写的这个函数;
(2)如果类B没有重写这个函数,则系统会去它的父类A里面找这个虚函数运行;
(3)如果类B定义了这个和虚函数函数名一样的函数,但没有声明重写(override),则运行这个类B内的函数。

参考资料:
http://www.360doc.com/content/07/0928/15/9889_776724.shtml

5、new和delete,malloc和free,它们有什么不同啊?

(1)malloc是函数,new是运算符;
(2)用new和delete申请内存空间需要调用构造函数,而malloc不经过构造函数;
(3)new 建立的是一个对象,malloc分配的是一块内存;

6、栈呢,栈和堆有什么区别?

一、预备知识——程序的内存分配

一个由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—— 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—— 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。
4、文字常量区—— 常量字符串就是放在这里的。 程序结束后由系统释放 。
5、程序代码区—— 存放函数体的二进制代码。

//***********************************************************//
现学现卖,看一个实际例程中,不同数据属于内存的哪一片区域。
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 局部变量,栈
char s[] = “abc”; 局部变量,栈
char *p2; 局部变量,栈
char *p3 = “123456”; p3是局部变量,在栈上。 123456\0在常量区
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10); 分配得来的10字节区域,在堆区。
p2 = (char *)malloc(20); 分配得来的20字节区域,在堆区。
strcpy(p1, “123456”); 123456\0放在常量区,
编译器可能会将它与p3所指向的”123456”优化成一个地方。
}
//***********************************************************//

二、堆和栈的理论知识

2.1申请方式

stack: 由系统自动分配。
例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间

heap: 需要程序员自己申请,并指明大小,
在c中malloc函数 如p1 = (char *)malloc(10);
但是注意p1本身是在栈中的。

2.2 申请后系统的响应

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆:首先操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制

:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示stack overflow。因此,能从栈获得的空间较小

:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较大,也比较灵活。

2.4申请效率的比较

由系统自动分配,速度较。但程序员是无法控制的。

是由new分配的内存,一般速度比较,而且容易产生内存碎片,不过用起来最方便。

2.5堆和栈中的存储内容

栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

堆:一般是在堆的头部用一个字节存放堆的大小,堆中的具体内容有程序员安排。

2.6栈和堆的使用比喻

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

摘自:
http://blog.csdn.net/bxyill/article/details/8681140

Michael总结
(1)内存中的区域分为栈(stack),堆(heap),全局(静态)变量区,字符串常量区,程序二进制代码存储区。
(2)内存层面上的栈的结构类似数据结构里面的栈,而堆则不是数据结构里的堆,这里堆的结构更像是链表。
(3)栈是由系统自动分配的,使用完后系统自动释放,用于存储程序中的局部变量。而堆用于存储由程序员自己开辟的一段内存,并指明大小(如malloc开辟的)。
(4)栈的大小由系统实现预定,当申请的空间大于可用空间时,出现栈溢出(stack overflow)。堆的大小取决于系统可用的最大虚拟内存。堆比栈的最大使用空间要大。
(5)栈读取的速度快,但是不灵活。堆的读取速度慢,但是灵活。

7、栈溢出有没有了解过?

当申请的局部变量的内存空间大于了栈的可用内存空间时,则会出现栈溢出。

8、C函数调用时,它的参数是怎么传递的,哪个函数负责出栈?

压栈的形式,在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

参数出栈也不能由函数自己完成,而应该由调用者完成。因为函数自身不知道调用者传入了多少参数,但是调用者知道,所以调用者应该负责将所有参数出栈。

参考资料:C函数调用与入栈顺序

9、单向链表,如何判断里面有没有环啊?

给定一个单链表,只给出头指针h:
1、如何判断是否存在环?
2、如何知道环的长度?
3、如何找出环的连接点在哪里?
4、带环链表的长度是多少?

解法:
1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。
2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。
3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。(证明在后面附注)
4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度。
摘自:http://blog.sina.com.cn/s/blog_725dd1010100tqwp.html

10、给你一个纯数字的电话号码,你是如何判断是哪个地区的?

Hash表。。

首先定hash函数,以下是所有区号和城市的对应

北京市 010 上海市 021 天津市 022 重庆市 023 香港 852 澳门 853
邯郸市 0310
  石家庄 0311
  保定市 0312
  张家口 0313
  承德市 0314
  唐山市 0315
  廊坊市 0316
  沧州市 0317
  衡水市 0318
  邢台市 0319
  秦皇岛 0335 浙江省
  衢州市 0570
  杭州市 0571
  湖州市 0572
  嘉兴市 0573
  宁波市 0574
  绍兴市 0575
  台州市 0576
  温州市 0577
  丽水市 0578
  金华市 0579
  舟山市 0580 辽宁省
  沈阳市 024
  铁岭市 0410
  大连市 0411
  鞍山市 0412
  抚顺市 0413
  本溪市 0414
  丹东市 0415
  锦州市 0416
  营口市 0417
  阜新市 0418
  辽阳市 0419
  朝阳市 0421
  盘锦市 0427
  葫芦岛 0429 湖北省
  武汉市 027
  襄城市 0710
  鄂州市 0711
  孝感市 0712
  黄州市 0713
  黄石市 0714
  咸宁市 0715
  荆沙市 0716
  宜昌市 0717
  恩施市 0718
  十堰市 0719
  随枣市 0722
  荆门市 0724
  江汉市 0728 江苏省
  南京市 025
  无锡市 0510
  镇江市 0511
  苏州市 0512
  南通市 0513
  扬州市 0514
  盐城市 0515
  徐州市 0516
  淮阴市 0517
  淮安市 0517
  连云港 0518
  常州市 0519
  泰州市 0523 内蒙古
  海拉尔 0470
  呼和浩特 0471
  包头市 0472
  乌海市 0473
  集宁市 0474
  通辽市 0475
  赤峰市 0476
  东胜市 0477
  临河市 0478
  锡林浩特 0479
  乌兰浩特 0482
  阿拉善左旗 0483
  江西省
  新余市 0790
  南昌市 0791
  九江市 0792
  上饶市 0793
  临川市 0794
  宜春市 0795
  吉安市 0796
  赣州市 0797
  景德镇 0798
  萍乡市 0799
  鹰潭市 0701 山西省
  忻州市 0350
  太原市 0351
  大同市 0352
  阳泉市 0353
  榆次市 0354
  长治市 0355
  晋城市 0356
  临汾市 0357
  离石市 0358
  运城市 0359
  甘肃省
  临夏市 0930
  兰州市 0931
  定西市 0932
  平凉市 0933
  西峰市 0934
  武威市 0935
  张掖市 0936
  酒泉市 0937
  天水市 0938
  甘南州 0941
  白银市 0943 山东省
  菏泽市 0530
  济南市 0531
  青岛市 0532
  淄博市 0533
  德州市 0534
  烟台市 0535
  淮坊市 0536
  济宁市 0537
  泰安市 0538
  临沂市 0539 黑龙江
  阿城市 0450
  哈尔滨 0451
  齐齐哈尔 0452
  牡丹江 0453
  佳木斯 0454
  绥化市 0455
  黑河市 0456
  加格达奇 0457
  伊春市 0458
  大庆市 0459 福建省
  福州市 0591
  厦门市 0592
  宁德市 0593
  莆田市 0594
  泉州市 0595
  晋江市 0595
  漳州市 0596
  龙岩市 0597
  三明市 0598
  南平市 0599
  广东省
  广州市 020
  韶关市 0751
  惠州市 0752
  梅州市 0753
  汕头市 0754
  深圳市 0755
  珠海市 0756
  佛山市 0757
  肇庆市 0758
  湛江市 0759
  中山市 0760
  河源市 0762
  清远市 0763
  顺德市 0765
  云浮市 0766
  潮州市 0768
  东莞市 0769
  汕尾市 0660
  潮阳市 0661
  阳江市 0662
  揭西市 0663 四川省
  成都市 028
  涪陵市 0810
  重庆市 0811
  攀枝花 0812
  自贡市 0813
  永川市 0814
  绵阳市 0816
  南充市 0817
  达县市 0818
  万县市 0819
  遂宁市 0825
  广安市 0826
  巴中市 0827
  泸州市 0830
  宜宾市 0831
  内江市 0832
  乐山市 0833
  西昌市 0834
  雅安市 0835
  康定市 0836
  马尔康 0837
  德阳市 0838
  广元市 0839
  泸州市 0840
  湖南省
  岳阳市 0730
  长沙市 0731
  湘潭市 0732
  株州市 0733
  衡阳市 0734
  郴州市 0735
  常德市 0736
  益阳市 0737
  娄底市 0738
  邵阳市 0739
  吉首市 0743
  张家界 0744
  怀化市 0745
  永州冷 0746 河南省
  商丘市 0370
  郑州市 0371
  安阳市 0372
  新乡市 0373
  许昌市 0374
  平顶山 0375
  信阳市 0376
  南阳市 0377
  开封市 0378
  洛阳市 0379
  焦作市 0391
  鹤壁市 0392
  濮阳市 0393
  周口市 0394
  漯河市 0395
  驻马店 0396
  三门峡 0398 云南省
  昭通市 0870
  昆明市 0871
  大理市 0872
  个旧市 0873
  曲靖市 0874
  保山市 0875
  文山市 0876
  玉溪市 0877
  楚雄市 0878
  思茅市 0879
  景洪市 0691
  潞西市 0692
  东川市 0881
  临沧市 0883
  六库市 0886
  中甸市 0887
  丽江市 0888 安徽省
  滁州市 0550
  合肥市 0551
  蚌埠市 0552
  芜湖市 0553
  淮南市 0554
  马鞍山 0555
  安庆市 0556
  宿州市 0557
  阜阳市 0558
  黄山市 0559
  淮北市 0561
  铜陵市 0562
  宣城市 0563
  六安市 0564
  巢湖市 0565
  贵池市 0566
  宁夏
  银川市 0951
  石嘴山 0952
  吴忠市 0953
  固原市 0954
  吉林省
  长春市 0431
  吉林市 0432
  延吉市 0433
  四平市 0434
  通化市 0435
  白城市 0436
  辽源市 0437
  松原市 0438
  浑江市 0439
  珲春市 0440 广西省
  防城港 0770
  南宁市 0771
  柳州市 0772
  桂林市 0773
  梧州市 0774
  玉林市 0775
  百色市 0776
  钦州市 0777
  河池市 0778
  北海市 0779 贵州省
  贵阳市 0851
  遵义市 0852
  安顺市 0853
  都均市 0854
  凯里市 0855
  铜仁市 0856
  毕节市 0857
  六盘水 0858
  兴义市 0859 陕西省
  西安市 029
  咸阳市 0910
  延安市 0911
  榆林市 0912
  渭南市 0913
  商洛市 0914
  安康市 0915
  汉中市 0916
  宝鸡市 0917
  铜川市 0919 青海省
  西宁市 0971
  海东市 0972
  同仁市 0973
  共和市 0974
  玛沁市 0975
  玉树市 0976
  德令哈 0977 海南省
  儋州市 0890
  海口市 0898
  三亚市 0899
  西藏
  拉萨市 0891
  日喀则 0892
  山南市 0893

从上表可找出规律:
(1)除四个直辖市和香港澳门这六个地区,以及一些特别的省会城市(如武汉,南京,广州)以外,其余地区都的号码都分布于0300~1000之间;
(2)香港、澳门是唯二区号第一位不是0的。

hash函数设计:
(1)拿到一个区号,先判断特殊的情况,即是不是直辖市、香港澳门、特殊省会,这些区号单独放在一个数组里,有限个;
(2)若不是(1)的情况,则将区号去掉第一个0,然后减去300,剩下的数就是hash表中的表号,根据这个数来直接输出地区;

11、TCP和UDP有什么不同吗?

UDP是数据报的形式传输的,发出去就不管了,多用于传输视频,实时地图等不怕丢包,追求速度的应用场景。

TCP是发出去的数据还会判断发没发出,发没发到,用于像遥控机器人求稳定的这种场景。

12、TCP是如何知道这种包有没有发出去呢?

应答的方法,ACK

你可能感兴趣的:(面试,电话面试)