这次电话面试有个提前预约,20160324_1509时,约到第二天下午五点。
我的另一篇博客:进程和线程的区别
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)地址空间:线程是进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源(内存资源);
(3)线程是处理器调度的基本单位,但进程不是;
(4)二者均可并发执行;
因为CPU的地址线范围大于了内存的大小。
虚函数用于成员函数的多态性,用于声明那些大体结构内容相似但细节实现上又有不同的成员函数,比如飞禽类的一个成员函数叫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
(1)malloc是函数,new是运算符;
(2)用new和delete申请内存空间需要调用构造函数,而malloc不经过构造函数;
(3)new 建立的是一个对象,malloc分配的是一块内存;
一、预备知识——程序的内存分配
一个由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)栈读取的速度快,但是不灵活。堆的读取速度慢,但是灵活。
当申请的局部变量的内存空间大于了栈的可用内存空间时,则会出现栈溢出。
压栈的形式,在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
参数出栈也不能由函数自己完成,而应该由调用者完成。因为函数自身不知道调用者传入了多少参数,但是调用者知道,所以调用者应该负责将所有参数出栈。
参考资料:C函数调用与入栈顺序
给定一个单链表,只给出头指针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
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表中的表号,根据这个数来直接输出地区;
UDP是数据报的形式传输的,发出去就不管了,多用于传输视频,实时地图等不怕丢包,追求速度的应用场景。
TCP是发出去的数据还会判断发没发出,发没发到,用于像遥控机器人求稳定的这种场景。
应答的方法,ACK