总结---1

转载自:http://www.cnblogs.com/heyonggang/p/3308377.html

1.const与 #define有什么不同?

答:C++中可以使用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点

  • ①const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只是进行字符替换,没有做类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应)
  • ②有些集成化的调试工具可以对const常量进行调试,但是不能对宏进行调试即在C++中 const可以完全替换宏常量
扩展:typedef和#define的区别: http://www.cnblogs.com/heyonggang/p/3199216.html

2.头文件中的ifndef/define/endif是干什么的?

  • 是为了防止该头文件被重复引用。

3.指针和应用的区别?

 

(1)引用在创建时必须初始化,指针可以不初始化,引用不可以为NULL指针可以。

(2)不存在指向空值的引用,但是存在指向空值的指针。

(3)引用初始化后不能被改变,指针可以改变所指的对象.

 

 

  • 答案:

    ①非空区别。任何情况下都不能使用指向空值的引用,一个引用必须总是指向某些对象

    ②合法性区别。在使用引用之前不需要测试它的合法性,相反,指针则应该总是被测试,防止其为NULL

    ③可修改性区别:指针与引用的另一个重要的区别就是指针可以被重新赋值以指向另一个不同的对象,但是引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象的值是可以改变的

    ④应用区别:总的来说,在以下情况下应该使用指针:

    一:考虑到存在不指向任何对象的可能

    二:需要在不同的时刻指向不同的对象,如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么就应该使用引用

指针和引用主要有以下区别:

  1. 引用必须被初始化,但是不分配存储空间。指针不声明时初始化,在初始化的时候需要分配存储空间。
  2. 引用初始化后不能被改变,指针可以改变所指的对象。
  3. 不存在指向空值的引用,但是存在指向空值的指针

注意:引用作为函数参数时,会引发一定的问题,因为让引用作参数,目的就是想改变这个引用所指向地址的内容,而函数调用时传入的是实参,看不出函数的参数是正常变量,还是引用,因此可能引发错误。所以使用时一定要小心谨慎。

 

详见:http://www.cnblogs.com/heyonggang/archive/2012/12/13/2815730.html


4.heap和stack的差别是什么?

  • heap是堆,stack是栈。
  • stack的空间由操作系统自动分配和释放,heap上的空间手动分配和释放。
  • stack空间有限,heap是很大的自由存储区。
  • C中的malloc函数分配的内存空间即在堆上,c++中对应的是new操作符。
  • 程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行。

5.什么是平衡二叉树?

平衡二叉树是一棵空树或具有下列特点的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1.


6.给出float与“零值”比较的 if 语句(假设变量名为var)

const float EPSINON = 0.00001;
  if ((x >= - EPSINON) && (x <= EPSINON)
由于计算机表示小数(包括float和double型小数)都有误差,我们不能直接用等号(==)判断两个小数是否相等。如果两个小数的差的绝对值很小,比如小于0.0000001,就可以认为它们相等。
if(flag > -0.0000001 && flag < 0.0000001)
{
    A;   
}

 

7.什么是进程(Process)和线程(Thread)?有何区别?

  • 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
  • 线程是进程的一个实体,是CPU调度和 分派的基本单位,它是比进程更小的能独立运行的基本单位。
  • 线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和 栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
  • 一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

  进程与应用程序的区别在于应用程序作为一个静态文件存储在计算机系统的硬盘等存储空间中,而进程则是处于动态条件下由操作系统维护的系统资源管理实体。

 

8.关键字static的作用是什么?

这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:

1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。

参考:http://www.cnblogs.com/heyonggang/p/3198431.html

          http://www.cnblogs.com/heyonggang/archive/2012/12/13/2817070.html

 

9.什么是死锁?其条件是什么?怎样避免死锁?

  死锁的概念:在两个或多个并发进程中,如果每个进程持有某种资源而又都等待别的进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗地讲,就是两个或多个进程被无限期地阻塞、相互等待的一种状态。

  死锁产生的原因主要是:系统资源不足; 进程推进顺序非法。

  产生死锁的必要条件:

  (1)互斥(mutualexclusion),一个资源每次只能被一个进程使用;

  (2)不可抢占(nopreemption),进程已获得的资源,在未使用完之前,不能强行剥夺;

  (3)占有并等待(hold andwait),一个进程因请求资源而阻塞时,对已获得的资源保持不放;

  (4)环形等待(circularwait),若干进程之间形成一种首尾相接的循环等待资源关系。

  这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

   死锁的解除与预防:理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如 何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的 分配要给予合理的规划。

  死锁的处理策略:鸵鸟策略、预防策略、避免策略、检测与恢复策略。

 

10.下列关于虚函数的说法正确的是()
A、在构造函数中调用类自己的虚函数,虚函数的动态绑定机制还会生效。
B、在析构函数中调用类自己的虚函数,虚函数的动态绑定机制还会生效。
C、静态函数不可以是虚函数

因为静态成员函数没有this,也就没有存放vptr的地方,同时其函数的指针存放也不同于一般的成员函数,其无法成为一个对象的虚函数的指针以实现由此带来的动态机制。静态是编译时期就必须确定的,虚函数是运行时期确定的。
D、虚函数可以声明为inline

inline函数和virtual函数有着本质的区别,inline函数是在程序被编译时就展开,在函数调用处用整个函数体去替换,而virtual函数是在运行期才能够确定如何去调用的,因而inline函数体现的是一种编译期机制,virtual函数体现的是一种运行期机制。
因此,内联函数是个静态行为,而虚函数是个动态行为,他们之间是有矛盾的。
函数的inline属性是在编译时确定的, 然而,virtual的性质则是在运行时确定的,这两个不能同时存在,只能有一个选择,文件中声明inline关键字只是对编译器的建议,编译器是否采纳是编译器的事情。
我并不否认虚函数也同样可以用inline来修饰,但你必须使用对象来调用,因为对象是没有所谓多态的,多态只面向行为或者方法,但是C++编译器,无法保证一个内联的虚函数只会被对象调用,所以一般来说,编译器将会忽略掉所有的虚函数的内联属性。


相关知识点:什么函数不能声明为虚函数?
一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的。 
设置虚函数须注意: 
1:只有类的成员函数才能说明为虚函数; 
2:静态成员函数不能是虚函数; 
3:内联函数不能为虚函数; 
4:构造函数不能是虚函数; 

5:析构函数可以是虚函数,而且通常声明为虚函数。


11.TCP(Transmission Control Protocol) 传输控制协议

TCP的连接建立过程又称为TCP三次握手。

  • 首先发送方主机向接收方主机发起一个建立连接的同步(SYN)请求;
  • 接收方主机在收到这个请求后向发送方主机回复一个同步/确认(SYN/ACK)应答;
  • 发送方主机收到此包后再向接收方主机发送一个确认(ACK)。

参考:http://blog.csdn.net/hyg0811/article/details/12002325

 


12.用变量a给出下面的定义

a) 一个整型数(An integer

b) 一个指向整型数的指针(A pointer to an integer

c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer

d) 一个有10个整型数的数组(An array of 10 integers

e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers

f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer


答案是:

a) int a; // An integer

b) int *a; // A pointer to an integer

c) int **a; // A pointer to a pointer to an integer

d) int a[10]; // An array of 10 integers

e) int *a[10]; // An array of 10 pointers to integers

f) int (*a)[10]; // A pointer to an array of 10 integers

g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer

h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer


13.描述在浏览器中敲入一个网址并按下回车后所发生的事情(尽量详细)

答:浏览器输入网址之后,首先
步骤1:需要查找域名的IP地址,DNS查找过程如下:
(1)浏览器缓存 – 浏览器的缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存各自固定的一个时间(2分钟到30分钟不等)。
(2)系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
(3)路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
(4)ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
(5)递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。
步骤2:浏览器给web服务器发送一个HTTP请求。请求中也包含浏览器存储的该域名的cookies。可能你已经知道,在不同页面请求当中,cookies是与跟踪一个网站状态相匹配的键值。这样cookies会存储登录用户名,服务器分配的密码和一些用户设置等。Cookies会以文本文档形式存储在客户机里,每次请求时发送给服务器。
步骤3:服务的永久重定向响应
步骤4:浏览器跟踪重定向地址
步骤5:服务器“处理”请求
步骤6:服务器发回一个HTML响应
步骤7:浏览器开始显示HTML
步骤8:浏览器发送获取嵌入在HTML中的对象


14.下列排序算法中,不受数据初始状态影响,时间复杂度为O(n*logn)的是

 

A.堆排序       B.冒泡排序     C.直接选择排序        D.快速排序

A。(在堆排序和快速排序中,若原始记录接近正序或反序,则选用_堆排序____,若原始记录无序,则最好选用__快速排序___。)
C错了。C的原题是下列排序法中,时间复杂度不收数据初始状态影响,总是为O(n2)的是__直接选择排序 ____。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值