c++面试宝典

一.基础知识
1.一个字节8位:0xFF,255,char
 两个字节16位:0xFFFF,65535,short
 4个字节32位:0xFFFFFFFF,42亿,DWORD
                                   
2.大端小端
 大端:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端(同人类读写数值的方法)
 低地址 --------------------> 高地址
 0x12  |  0x34  |  0x56  |  0x78
 小端:低位字节排放在内存的低地址端,高位字节排放在内存的高地址端(个人电脑储存形式)
 低地址 --------------------> 高地址
 0x78  |  0x56  |  0x34  |  0x12
 个人电脑,Intel或AMD的x86/x64架构是小端字节序,ARM既有大端也有小端,网络通信上为大端模式    
 转换函数:ntohl(a),hton(a)
 如何进行转换:
 对于字数据(16位):(程序中的“\”表示当前行和下一行是同一行)
 #define BigtoLittle16(A)   (( ((uint16)(A) & 0xff00) >> 8)    | \  
                                       (( (uint16)(A) & 0x00ff) << 8)) 
 #define BigtoLittle32(A)   ((( (uint32)(A) & 0xff000000) >> 24) | \  
                                       (( (uint32)(A) & 0x00ff0000) >> 8)   | \  
                                       (( (uint32)(A) & 0x0000ff00) << 8)   | \  
                                       (( (uint32)(A) & 0x000000ff) << 24))  

3.申请内存
 malloc/free与new/delete区别:前者可以用于指定大小内存,也可以用于结构体,如PrivateRsa = (RSA*)malloc(sizeof(RSA));,后者只用于固定大小,如结构体
 free释放内存后,需要NULL(不置NULL导致指针成为“野指针”,诱导误操作),
4.delete 和 delete []的区别
 delete 释放new分配的单个对象指针指向的内存
 delete[] 释放new分配的对象数组指针指向的内存
5.将“引用”作为函数参数有哪些特点?
 在内存中并没有产生实参的副本,它是直接对实参操作
6.在什么时候需要使用“常引用”?const int &ra=a;
  如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用
7、结构体与联合有和区别?
  联合体所有成员共用一块地址空间
8.重载(Overloading):重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。
  重写(Overriding):父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数
  覆盖:派生类覆盖基类的虚函数,实现接口的重用,基类中必须有virtual关键字
9.请说出const与#define 相比,有何优点?
  被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性
  const 常量有数据类型,编译器可以对其进行安全检查,还可以调试
10、关键字static的作用
 1)函数体内: static 修饰的局部变量作用范围为该函数体,不同于auto变量,其内存只被分配一次,因此其值在下次调用的时候维持了上次的值
 2)文件内:static修饰全局变量或全局函数,可以被改文件内的所有函数访问,但是不能被模块外的其他函数访问,使用范围限制在声明它的模块内
 3)类中:修饰成员变量,表示该变量属于整个类所有,对类的所有对象只有一份拷贝
 4)类中:修饰成员函数,表示该函数属于整个类所有,不接受this指针,只能访问类中的static成员变量
 注意和const的区别!!!const强调值不能被修改,而static强调唯一的拷贝,对所有类的对象

11、C++的内存管理
 在C++中,内存被分成五个区:栈、堆、自由存储区、静态存储区、常量区
 栈:存放函数的参数和局部变量,编译器自动分配和释放
 堆:new关键字动态分配的内存,由程序员手动进行释放,否则程序结束后,由操作系统自动进行回收
 自由存储区:由malloc分配的内存,和堆十分相似,由对应的free进行释放
 全局/静态存储区:存放全局变量和静态变量
 常量区:存放常量,不允许被修改
12、深拷贝和浅拷贝的区别
深拷贝和浅拷贝可以简单的理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,如果资源重新分配了就是深拷贝;反之没有重新分配资源,就是浅拷贝。
13.友元函数
有元函数是可以访问类的私有成员的非成员函数。它是定义在类外的普通函数,不属于任何类,但是需要在类的定义中加以声明。
friend 类型 函数名(形式参数);
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

6、 C++的四种强制转换 
类型转化机制可以分为隐式类型转换和显示类型转化(强制类型转换)
(new-type) expression
new-type (expression)
隐式类型转换比较常见,在混合类型表达式中经常发生;四种强制类型转换操作符:
static_cast、dynamic_cast、const_cast、reinterpret_cast
1)static_cast :编译时期的静态类型检查
static_cast < type-id > ( expression )
该运算符把expression转换成type-id类型,在编译时使用类型信息执行转换,在转换时执行必要的检测(指针越界、类型检查),其操作数相对是安全的
2)dynamic_cast:运行时的检查
用于在集成体系中进行安全的向下转换downcast,即基类指针/引用->派生类指针/引用
dynamic_cast是4个转换中唯一的RTTI操作符,提供运行时类型检查。
dynamic_cast如果不能转换返回NULL
源类中必须要有虚函数,保证多态,才能使用dynamic_cast<source>(expression)
3)const_cast
去除const常量属性,使其可以修改 ; volatile属性的转换
4)reinterpret_cast
通常为了将一种数据类型转换成另一种数据类型

10.C++11有哪些新特性
 1)关键字及新语法:auto、nullptr、for
 2)STL容器:std::array、std::forward_list、std::unordered_map、std::unordered_set
 3)多线程:std::thread、std::atomic、std::condition_variable
 4)智能指针内存管理:std::shared_ptr、std::weak_ptr
 5)其他:std::function、std::bind和lamda表达式
11.线程池的实现
12.虚函数表
11.程序奔溃类型:
 1 读取未赋值的变量: int a, b;int m = multiply(a, b);注意其错误特征:“The variable is being used without being initialized”
 2 函数栈溢出函数栈溢出:
 (1)定义了一个体积太大的局部变量 int buf[1024*1024*16]; 
 (2)函数嵌套调用,层次过深(如无穷递归)
 3.数组越界访问
 4指针的目标对象不可用
 空指针 Object* obj = NULL;p->id
 野指针: 指针未赋值 Object* p;p->id;(p的有地址,是乱的,容易造成程序意想不到的错误)

12.斜杠与反斜杠:
 斜杠/表示除法,分隔。在windows系统中通常用来分隔命令行参数,/表示选项等
 反斜杠\,在windows系统中用来表示目录。
 而在unix系统中,/表示目录。由于web遵循unix命名,所以在网址(URL)中,/表示目录。
 在C中 \ 是转义字符,如下所示 '\0'
 
二.tcp/ip
1.OSI模型有7层结构,每层都可以有几个子层。 OSI的7层从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层 ;其中高层(即7、6、5、4层)定义了应用程序的功能,下面3层(即3、2、1层)主要面向通过网络的端到端的数据流。
 应用层:TELNET,HTTP,FTP
 表示层:定义数据格式及加密,ASCII
 会话层:它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的
 传输层:TCP,UDP,数据包一旦离开网卡即进入网络传输层
 网络层:IPV4 IPV6,进行逻辑地址寻址,实现不同网络之间的路径选择
 数据链路层:立逻辑连接、进行硬件地址寻址、差错校验 [2]  等功能
 物理层:建立、维护、断开物理连接
2.TCP在传输之前会进行“三次握手”,断开“四次挥手”。
3.高并发:多线程,多进程,完成端口,网络分发,数据库优化等等
  1).网络负载均衡架构设计
  2).数据库负载均衡架构设计
  3).消息队列负载均衡架构设计
   manggodb支付千亿条记录
4.五种模型
 1.select模型:将套接字放到集合中,select后,轮询查看套接字是否仍然处于读集中。默认64个连接,最大可以设置1024个
 2.异步选择模型:int WSAAsynSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent),缺点是需要窗口,而且单窗口性能也不佳
 3.事件选择模型:WSAEventSelect:在出现感兴趣的 socket事件时,系统会将相应WSAEVENT事件设为传信。只有有事件发生,WSAWaitForMultipleEvents(...)就会返回
  缺点是该模型每次只能等待64个事件
 4.重叠I/O模型: WSAWaitForMultipleEvents(...) 就返回
 5.完成端口:创建完成端口对象CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0),工作者线程调用 GetQueuedCompletionStatus 来轮询完成端口队列。
  完成端口内部提供线程池的管理,同时可以根据CPU的个数灵活的决定线程个数,这样随着系统内安装的CPU数量的增多,应用程序的性能也可以线性提升
异步的,CreateIOCompleTionPort
 GetCompleTionStatus
 PostQueuedCompletionStatus
 具体:https://blog.csdn.net/piggyxp/article/details/6922277

三.windows消息机制
 PostMessage 不等返回、SendMessage需要等返回,GetMessage获取消息后,删除队列里消息(死等),PeekMessage不等
 Windows消息循环: Windows 操作系统为每个线程维持一个消息队列,当事件产生时,操作系统感知这一事件的发生,并包装成消息发送到消息队列,应用程序通过GetMessage()函数取得消息并存于一个消息结构体中
 Windows消息提供了应用程序与应用程序之间、应用程序与Windows 系统之间。Windows 系统中有两种消息队列,一种是系统消息队列,另一种是应用程序消息队列

四、容器
 向量 std::vector<CAttep> Attemp; 连续存储的元素
 链表 std::list<CAttep> a;由节点组成的双向链表,每个结点包含着一个元素
 队列 std::<queue>a  先进先出的执的排列
 映射 std::map<CAttep>a; 由{键,值}对组成的集合
 多重映射 multimap 允许键对有相等的次序的映射
 集合 set由节点组成的红黑树,set是用红黑树的平衡二叉索引树的数据结构来实现的,插入时,它会自动调节二叉树排列,把元素放到适合的位置,确保每个子树根节点的键值大于左子树所有的值、小于右子树所有的值,插入重复数据时会忽略
 多重集合 multiset  允许存在两个次序相等的元素的集合 <set>
 迭代器:vector<int>::itertor it = v.bein();

五、数据库 
1.数据库优化
 1)优化数据库表结构.varchar,char尽可能不要使用NULL值
 2)优化查询语句:尽量避免全表扫描,包括但不限于where子句条件横真或为空,LIKE,<>、!=,is null,
   多条件查询时,把简单查询条件或则索引列查询置于前面
   请尽量指定需要查询的列,不要偷懒使用select *,
   大些的查询关键字比小写快一点点
   在索引字段上查询尽量不要使用数据库函数,不便于缓存查询结果
   当只要一行数据时,请使用LIMIT 1,如果数据过多,请适当设定LIMIT,分页查询
 3)建立索引
 4)大表拆分:垂直分表是按照日期等外部变量进行分表,水平分表是按照表中的某些字段关系,使用hash映射等分表
 5)添加本地缓存和redis缓存
 6)读写分离或者分布式

2.触发器:CREATE TRIGGER audit_log AFTER INSERT  ON COMPANY
    BEGIN
        INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));
    END;
3.事物处理
 原子性:事务必须是一个自动工作的单元,要么全部执行,要么全部不执行。
 一致性:事务结束的时候,所有的内部数据都是正确的。
 隔离性:并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
 持久性:事务提交之后,数据是永久性的,不可再回滚。
 begin tran
 commit tran

六.设计模式

七.其他 
1.内存泄露检测工具:
1.vs编译器
2.Visual Leak Detector
#include <vld.h>
2.常用api:
 _atoi64 
 _wtoll
 LOWORD。WORD wIndex=LOWORD(dwAndroidID);
 HIWORD  m_wRoundID!=HIWORD(dwAndroidID)
3.几种经典架构
4.ace框架
5.boost
6.书本:《C++程序设计语言》、《C++primer》、《VS 实战宝典》《window网络编程》


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值