c++常见面试问题总结
c++和C语言的区别
C语言是面向结构性语言,C++是面向对象语言 c语言是c++的子集,c++包含了c语言的全部词法和语法内容,比c语言多出了类。
程序运行的保存的五个区
堆 栈 常量 全局变量 代码区
什么是面向对象:注重的是对象,当解决一个问题的时候,面向对象会把事务抽象成一个对象,就是说问题里有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,最后解决问题
什么是面向结构:注重过程,当解决一个问题的时候,面向过程会把事情拆分成:一个个函数,然后按照一定的顺序执行完这些函数,然后把问题解决。
程序编译的几个步骤:
预处理:如头文件这些 输出i文件
编译:将文本文件.i 翻译成.s文件
汇编: 将文本文件.s翻译成机器语言 输出.o文件
链接: 将所有的.o文件处理合并 生成exe 可执行程序 被系统加载到内存里面
静态库 只生成lib文件
动态库的的写法 定义宏导出 ,把需要导出的方法前面加上预定义宏__ENTRY
生成 lib 和dll
#ifndef __DLLEXPORT__
#define __ENTRY__ extern "C" _declspec (dllimport)
#else
#define __ENTRY__ extern "C" _declspec (dllexport)
#endif
静态库和动态库的区别
静态库是把运行程序所需的代码全部链接到exe文件中 成为exe的一部分 相对来说使用了静态库的程序 当多个程序调用相同的函数时,内存中存这个函数的多个拷贝,浪费宝贵的内存资源。
而动态库中exe仅仅包含了函数的描述信息,往往是一些重定位信息,仅当程序被装载到内存开始运行时,在window系统的管理下,才在应用程序与相应的dll之间建立链接关系,一般情况下 一个程序使用了dll 那么在内存中只有dll的一份复制品,由系统内存映射保证。
内存映射:dll首先被系统调入全局堆;栈,然后映射到调用这个dll的进程的地址空间,
在wind32系统中每个进程都有自己的地址空间。
动态库显示加载和隐式加载的区别
隐式加载:在编译前需要知道dll中具体有哪些函数,需要导入库文件
显示加载:在编译之前并不知道dll中的函数,而是在运行期间根据需要决定调用哪个函数,
通过调用loadLibrary获得dll的函数入口地址 在调用GetProcAdress获取函数的出口地址,然后通过函数返回的函数指针调用dll里面的函数,可以避免导入库文件
理解 线层同步 和 互斥的概念 区别:
所谓互斥就是指 多个线程通过竞争的方式进入进入临界区,在有限时间内,往往只允许单个用户访问,具体排他性,也没有顺序 。
同步是指多个线程之间彼此合作,通过一定的逻辑关系共同完成一个任务,同步操作中往往包含互斥,同步也可以说是一中复杂的互斥。相当以一个线层的开始执行,依赖于另一个线层执行的进度。 比如一个线层要开始执行,需要另一个线层业务作为统治你,否则你就在那里等。
一台电脑最多能开启多少数量的线程:
一台电脑能开启的线程的数量 取决于进程调度策略,虚拟内存,硬件上主要是 物理内存、cpu 一般理论上上来说 线程的分析空间为一兆,一G内存大概是1024个
理解进程和线层的区别
一个进程可以看做是一个独立的程序,有着自己的地址空间,一个进程下面可以有多个线层。
线层只能访问自己所属进程下的变量,而不能夸进程。
进程间的通信方式
管道 socket 共享内存 消息队列 信号量(用于控制进程间对共享内存资源的访问) 信号
事件 createEvent()分手动重置 自动重置
mutex createmutex();可以看成简易版的事件
临界区(用户去 非内核 速度最快,进程死锁问题)互相等问题 initialCriticalSection()
信号量 类似于车位
Promise----futrue 同步
网络七层 四层 模型的划分:
七层: 物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
四层:物理层 网络层 传输层 应用层
简述tcp的三次握手
为什么建立连接需要三次握手?
首先非常明确的是两次握手是最基本的。第一次握手,客户端发了个连接请求消息到服务端,服务端收到信息后知道自己与客户端是可以连接成功的,但此时客户端并不知道服务端是否已经接收到了它的请求,所以服务端接收到消息后的应答,客户端得到服务端的反馈后,才确定自己与服务端是可以连接上的,这就是第二次握手。
客户端只有确定了自己能与服务端连接上才能开始发数据。所以两次握手肯定是最基本的。
看到这里,你或许会问,那么为什么需要第三次握手呢?我们来看一下,假设一下如果没有第三次握手,而是两次握手后我们就认为连接成功了,那么会发生什么?第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。
譬如发起请求遇到类似这样的情况:客户端发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务端,这是一个早已失效的报文,但是此时服务端仍然认为这是客户端的建立连接请求第一次握手,于是服务端回应了客户端,第二次握手。
Connet 客户端请求连接 发送字段syn = 1
Accept 服务器确认接收客户端的连接 回复syn = 1 ack=1;
Write 客户端向服务器发送ack = 1
四次挥手:
假设客户端先发起断连
客户端向服务器发送fin = 1 请求释放连接
服务器端收到后发送ack = 1
服务器向客户端发送释放连接请求 fin =1
客户端收到回复ack 等待2msl时间后关闭 服务器收到ack立刻关闭
Udp和tcp客户端其实都可以绑定自身的IP端口,而服务器必须绑定端口 IP
单播:服务器:1创建sosket 2.bind服务器IP端口,3.recvFrom
客户端:1.创建socket
2. sockaddr_in addrto = { 0 };//客户端也可以bind绑定端口ip(指定某个端口发送)不绑定的话 系统默认分配一个,下面填的端口是服务器的端口 往哪里发得端口
Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //发往的服务器Ip
Addrto.sin_family = AF_INet;
Addrto.sin_port = ::htons(30001); //和服务器一致的端口 要发往的端口
sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));
广播:服务器:1创建sosket 2.bind服务器IP端口3设置广播属性.BOOL ebnable =true;
setSockopt(sockclient,SOL_SOCKET,SO_BRODCAST,reinterpret_cast<constchar*>(&enable),sizeof(eanable))
- recvFrom接收
客户端:1.创建socket()
2. sockaddr_in addrto = { 0 };//客户端也可以bind绑定端口ip(指定某个端口发送)不绑定的话 系统默认分配一个,下面填的端口是服务器的端口 往哪里发得端口
Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //发往的服务器广播的话也可以是192.168.0.255
Addrto.sin_family = AF_INet;
Addrto.sin_port = ::htons(30001); //和服务器一致的端口 如果服务器端设置了广播属性的话,客户端sendto255 所有服务器都可以收的到
sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));
组播:比广播更好控制发送给谁 有限定作用
组播和广播区别不大 区别在设置属性的函数
Ip_mreq mrq;
Mrq.imr_multiaddr.S_un.S_addr = ::inet(“224.0.0.2”)//s设置加入哪个组 定义组播号
Mrq.imr_interface.S_un._s_addr = 0;//使用默认网卡//
Setsockopt(socksever,IPPROTO_IP,IP_ADD_MEMBERSHIP,rinterpret_cast<const char*>(&mrq),sizeof(mrq));
客户端区别 sendto 往192.168.0.1发也可以 往服务器设置的组播地址发也可以。
Tcp和udp的区别:
TCP是流式、可靠的,面向连接的 相当与管道从一头流向另外一头 建立连接需要三次握手
UDP是面向非连接的,不可靠
Tcp是有序的 一对一 udp是无序的 可以一对多
Tcp效率较低,适用于准确性要求较高的场景
Udp效率较高,适用于实时通信。
static const 类成员变量 成员方法 相关用法:
static成员变量不属于类不占用类的空间大小,可以被一般类方法访问。static成员方法只能访问类的static成员变量和static方法。
const成员方法 方法后面加const 在const方法里面不能修任何改成员变量
const成员变量 初初始列表 const全局变量 定义的时候需要赋值
cosnt引用 目的是为了提高效率
智能能指针
shared_ptr
weak_ptr 用与观察shared_ptr当前装态 引用计数 是否释放 无效等
unique_ptr;//禁止拷贝
boost ::auto_ptr
scoped_prt; //禁止转移所有权
make_shared; 用于给shared_ptr 赋值 消除new和delete不平衡性质
stl 容器的迭代和删除
Map 红黑树实现 键值对
Set 集合 里面的元素对象不能重复
List 链表
Vector 动态数组
mutliSet 可重复集合
mutliLMap 一键对多值
仿函数: 就是一个类重载了()方法 看上去有点像函数
c++三大特性 :
继承 :子类继承基类 三种继承方式 -基类的私有成员 子类和外部都是不能访问的
封装:隐藏细节,private和protect变量 外部不可访问
多态:静态多态 重载
动态多态 虚函数 重写
虚函数表:指向 指针数组的指针 void(*a)[]
设计模式:
单例模式:
观察者模式:
适配器模式:
工厂模式:
及不用虚函数实现c++多态的方式 通过类模板的方式 借助静态类型转换的方式 在基类里面讲将数接口在包一层。 WTL里面很多类似这样的做法
菱形继承 +virtual
为什么类作为基类 析构函数最好是虚函数
Pbase * base = new child; 虚函数机制的话 根据实际对象调用析构函数;
Delete base; 不是虚函数机制的话,这样会调用基类的析构函数,而导致子类的无法释放
c++ 四种转换:
dynaimc_cast 动态类型转换 鉴别真伪 条件:类 继承 virtual
Base *pBase = new Base;
Child *pChild = dynamic_cast<Child*>(pBase); //鉴别实际对象和实际类型是否一致 这里转换失败 : 下行转换
Base *pBase = new Child ;
Child *pChild = dynamic_cast<Child*>(pBase); //鉴别实际对象和实际类型是否一致 这里转换成功
static_cast 静态类型转换 类 继承 可以基础类型之间转换如float转换成int 下行转换也是OK 用上面1的例子是可以转换成功的只看指针类型
reinterpret_cast 无关系的类之间也可以,基础类型与类之间的转换,类型与c语言的强制转换
const_cast<> const 指针之间的转换
int value1 = 1;
int value2 = 2;
const int* pvalue =&value1;
*pvalue = 9; //错 指针常量 指向的值不让修改
pvalue = &value2; //对
int* const pvalue =&value1;
*pvalue = 9; //对
pvalue = &value2; //错 常量指针 指针不让修改
const int* const pvalue =&value1;
*const_cast<int* const>(pvalue) = 9; //去掉const 可以修改
int* const pvalue =&value1;
cosnt_const<const int *>(pvalue) = &value2//去掉对应的const
memcpy 及带内存重叠的实现
右值引用 深拷贝 浅拷贝:
类构造函数
A() = deafault 用于类中自己定义了构造函数 仍需要默认构造函数的情况 不然A a 这样调用或报错 必须A a(3)这样传一个参数。
A() = delete //相当于这个类不能用
A() = explicit // 相当于这个类不能隐式的调用 不能 A a = 5;只能A a(5);
迭代器iterator和指针的区别
迭代器是一个函数 只是重载了* ->这些符号
widows窗口程序的几个步骤:
创建窗口类 注册窗口register: 创建窗口 显示更新窗口 获取窗口消息getmessage() 获取后dispatch消息 调用窗口处理函数
动态类型 看实际对象类型
静态类型(不加virtual)看左侧指针类型:决定调用子类还是父类的方法 static下行转换也是OK的
回去验证 不存在虚函数 继承之间的重写 静态类型static_cast Base*pBase = new Base;
Child * pChild = static_cast<Child*>(pBase);
pChild ->show() 看看是调用基类还是之类的方法 期望调用子类的方法 然后去掉子类重写的方法看看调用的是不是基类的方法
然后子类不重写 看看是不是会调用基类类型的方法
iocp完成端口
完成端口等于异步IO+线层池 1.先建立一个空的完成端口IOCP = WASCreateIoCompletePort(),2.创建一定数量的线程,3.在WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr),overlapped这里面需要创建事件overlapped.event = WASCreateEvent();之后,不同于重叠IO 不是通过getoverlapped获取结果,通过线层池唤醒线层对接受的数据进行相关的业务处理,再次调用WASCreateIoCompletePort((HANDLE)sockClient,IOCP,/*传入的参数,完成建*/,/线程的数量/)进行投递到完成端口的队列,申明线层函数,在线层函数等待一个完成端口的事件::GetQueuedCompletionStatus(iocp,totalRecvCount,/完成件/,overlapped,infinity),里面通过传入的完成建将wasbuff打印出来。
重叠端口:
WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr);/获取数据 GetOverlappedResult((HANDLE)sockclint),&overlapped,&recvCount,,true); 系统通知你的时候把输入操作已经帮你做了。
异步选择事件:
事件和套接字绑定HANDLE aSock[50];
HANDLE aEvent[50];
aEvent[0] = WSACreateEvent(); 创建事件
accept和recv需要由事件来通知 通过asock = socksever ; WASEventSelect(sockserver,aEvent,FD_ACCEPT)中相关参数设置 accepte和recv的方式 用 ireturn = WSAWaitFormutilpleEvent(iicurrentNUm,aEvent,false,INFINITY,0)等待相应的事件置位 返回值是绑定对应数组的下标 由下标判断是哪个事件置位 accept还是recv
异步选择消息模型:通过windows消息的机制触发 消息到了 肯定是有accept用户连接 或者recv到数据了
线层池:
- 创建一定数量线层 创建事件 用于控制线层的退出 初始化信号量 里面车位刚开始位满 控制活跃的线层属 初始化临界区 用于控制读取任务的互斥
- 线层函数里面一个大循环,WaitForSingleObject(ms_pThreadPool->m_hSemaphore, INFINITE); 等待信号量提升 在addtask的时候提升信号量的空位
boost库 字符算法、智能指针、
数据库:
Mysql:
Mysqld --install //数据库安装
Net start mysql //数据库服务启动
Net stop mysql //停止数据库服务
Mysqld --remove 卸载数据库
Select database() 当前使用的数据库
Mysql -uroot 以管理员前线登录
Show tables 查看当前数据库有多少表
show databases //查看当前数据库所有数据库
Use test //使用哪个数据库
Show engines 查看数据使用的哪种引擎
当前主要使用较多的两种:1、myisan 2 innodb 支持事务
Drop table dd; //删表
数据类型 decimal(p,s)//小数类型 前面是整数+小数一共的位数,后面是小数的位数
Crate datebase yy 建立数据库yy
//查看建立数据库语句
Show create databse ‘db’;
//建立一张表 id不能为负 可以null填充 不足六个整数前面用0填充 插入一条记录自增id
表尾 代表 引擎使用myisam 自增赋初值为5 编码格式使用gutf8
Crate table dd(
Id INT(6) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
Name VARCHAR(20) ,
Sgender ENUM(‘男’,’女’,保密’’),
PRIMARY_KEY(id)
)ENGINE=MYISAM AUTO_INCREMENT =5 DEFAULT CHARSET = UTF8;
//查看表结构
//desc dd;
//修改表名:、
Rename table dd to student
//修改表中字段名及类型
Alter table dd change id tid int(8);
Alter table name sname varchar(30);
//给表增加一列
Alter table dd ADD score tinyint;
//在表中哪一列后增加一列
Alter table dd address varchar(80) after id;
//在表中删除某一列
Alter tabel dd drop COLUMN address;
//插入
Insert dd valules(null,’李四’,’男’);
Insert into dd values(null,’李四’,’男);
//插如多条记录
Insert dd valules(null,’李四’,’男’),Insert into dd values(null,’李四’,’男);
//选择性插入
Insert dd(id,name) values(6,‘张三’);
//将表全部查出来在插入一遍
Insert into student(id,name,Sgender)select id name Sgender from dd;
//修改数据
Update student set Sgender = ‘男’ where name = ‘李四’
Update student set Sgender = ‘男’ ,id = 10 where name = ‘李四’
//删除数据
Delete from dd where id = 8;
Delete form dd //无条件删除所有记录
Delete from dd where name like ‘张’;删除姓张的
//查询
Select * from dd
只显示姓名 成绩 以别名的形式
Select name 姓名 ,id 学号 from student;
成绩小于八十的
Select *form student where score<80;
查询条件 between and
Select * from student where score between 80 and 90;
基本条件like 条件%
查询姓名两个字的学生信息
Select *from student where name like ‘__’; 两个下划线
Select *from student where name like ‘张_’; 姓张的 名字两个字的
Select*from student where name ‘ %丽%’;名字有丽的 %代表一个和多个
基本条件查询 in() not in 多个范围
Select *from student where id in(8,9,10);
Select *from student where id not in(8,9,10);
基本条件运算 null 用is null 或 is not null
Select *from student where score is null
Update sutdent set scor = 0 where score is null;
分组查询 聚集 集合函数 主要配合分组 group by
Max()
Avg()
Count() 统计多少条记录
Sum()
Select avg(score) from student;
查询最高分
Select max(score) from student;
查询最高分学生的信息
Select *from student where score in(select max(score) from student);
统计多少人
Select cont(*) from student
Select max(score)最高分, min(score) 最低分 from student;
查询各地区的人数
Select count(*) from student group by adress;
注意:在分组查询过程,只能出现聚集函数和分组字段 下面:
Select count(*) 人数,address 地区 from student group by adress 对
Select count(*) 人数,address 地区 , sname 姓名 from student group by adress 错 出现了名字 不是分组字段
Select count(*) 人数,address 地区 from student
Where address is not null --条件 分组前 成绩为空 不参加分组
group by adress -- 分组字段
Order by count(*) DESC; --根据人数降序
分组条件 分完组后按条件查询 需要放在 group by 后面
Select count(*) 人数,address 地区 from student
Where address is not null --条件 分组前 成绩为空 不参加分组
group by adress -- 分组字段
Having count(*)>2 -- 分组后条件 分组后人数大于2的地区
Order by count(*) DESC; --根据人数降序
连接查询
建立两个表一个学生 一个老师
学生表里面包含老师的ID
多表查询 公司不推荐
Select s.name ,s.sgender* fronm s ,t where s.tid = t.tid;
连接查询 join left join rignt join
Select s.name s.sgender from s left join t on s.tid = t.tid;
Mysql 的约束
主键约束 primary key
默认约束 defaut
非空约束 not null
外键越苏 foreign key reference仅支持引擎为INoodb
Create table t
(
Tid int unsigned not null auto increment
Tname varchar(20)
Key(tname) --建立表的时候 同事建立索引 名字不能重复
Primary_key(tid)
)
Create table t
(
sid int unsigned not null auto increment,
sname varchar(20),
Tid int unsigned ,
Primary_key(tid)
Constraint fk foreign key (tid) reference t(tid)--建立外键 关联到teacher表
)
由于存在外键 删除某一项老师记录需要对应的学生不存在,删除老师表之前需要删除学生表 不然不让删除老师表 解决方案如下 级联删除
Create table t
(
sid int unsigned not null auto increment,
sname varchar(20),
Tid int unsigned ,
Primary_key(tid)
Constraint fk foreign key (tid) reference t(tid) on delete cascade
)
加上on delete casecade 就能删除教师记录 但是还是不能删除教师表 除非先删除学生表
主键 不能为空 ,不能重复
外键 一遍一个表的外键指向 另外一个表的主键 且类型一致
增加一个表的主键()
alter table tt add constranit pk primary key(name);
增加一个表主键
Alter table tt drop primary key
建立索引 方便检索数据 类似于书籍的目录 建立主键的时候 主键就是一个索引
Create index iia on(tname desc);
Alter table tt add index (tname desc);
删除索引
Drop index iia on teacher;
Alter table tt drop index tname;
常用函数:
Select length(‘ghh’);长度
Select * from student where sname like ‘__’;
Select *from student where char_lenth(sname) = 2;
//随机查询出两条记录
Select *from student order by rand() limit
查询天前的日期
Selet date_add(now(),interval -10 day);
查询10后的日期
Selet date_add(now(),interval 10 day);
存储过程
没有明确的返回值 编译后再服务器执行 熟读快
经过编译后存储在数据库中,用户通过 存储过程名字,并给出参数来执行它
函数 函数有返回值
Map 红黑树实现 键值对
Set 集合 里面的元素对象不能重复
List 链表
Vector 动态数组
mutliSet 可重复集合
mutliLMap 一键对多值
仿函数: 就是一个类重载了()方法 看上去有点像函数
c++三大特性 :
继承 :子类继承基类 三种继承方式
封装:隐藏细节,private和protect变量 外部不可访问
多态:静态多态 重载
动态多态 虚函数 重写
虚函数表:指向 指针数组的指针 void(*a)[]
设计模式:
单例模式:
观察者模式:
适配器模式:
工厂模式:
及不用虚函数实现c++多态的方式 通过类模板的方式 借助静态类型转换的方式 在基类里面讲将数接口在包一层。 WTL里面很多类似这样的做法
菱形继承 +virtual
为什么类作为基类 析构函数最好是虚函数
Pbase * base = new child; 虚函数机制的话 根据实际对象调用析构函数;
Delete base; 不是虚函数机制的话,这样会调用基类的析构函数,而导致子类的无法释放
c++ 四种转换:
dynaimc_cast 动态类型转换 鉴别真伪 条件:类 继承 virtual
Base *pBase = new Base;
Child *pChild = dynamic_cast<Child*>(pBase); //鉴别实际对象和实际类型是否一致 这里转换失败 : 下行转换
Base *pBase = new Child ;
Child *pChild = dynamic_cast<Child*>(pBase); //鉴别实际对象和实际类型是否一致 这里转换成功
static_cast 静态类型转换 类 继承 可以基础类型之间转换如float转换成int 下行转换也是OK 用上面1的例子是可以转换成功的只看指针类型
reinterpret_cast 无关系的类之间也可以,基础类型与类之间的转换,类型与c语言的强制转换
const_cast<> const 指针之间的转换
int value1 = 1;
int value2 = 2;
const int* pvalue =&value1;
*pvalue = 9; //错 指针常量 指向的值不让修改
pvalue = &value2; //对
int* const pvalue =&value1;
*pvalue = 9; //对
pvalue = &value2; //错 常量指针 指针不让修改
const int* const pvalue =&value1;
*const_cast<int* const>(pvalue) = 9; //去掉const 可以修改
int* const pvalue =&value1;
cosnt_const<const int *>(pvalue) = &value2//去掉对应的const
memcpy 及带内存重叠的实现
右值引用 深拷贝 浅拷贝:
类构造函数
A() = deafault 用于类中自己定义了构造函数 仍需要默认构造函数的情况 不然A a 这样调用或报错 必须A a(3)这样传一个参数。
A() = delete //相当于这个类不能用
A() = explicit // 相当于这个类不能隐式的调用 不能 A a = 5;只能A a(5);
迭代器iterator和指针的区别
迭代器是一个函数 只是重载了* ->这些符号
widows窗口程序的几个步骤:
创建窗口类 注册窗口register: 创建窗口 显示更新窗口 获取窗口消息getmessage() 获取后dispatch消息 调用窗口处理函数
动态类型 看实际对象类型
静态类型(不加virtual)看左侧指针类型:决定调用子类还是父类的方法 static下行转换也是OK的
回去验证 不存在虚函数 继承之间的重写 静态类型static_cast Base*pBase = new Base;
Child * pChild = static_cast<Child*>(pBase);
pChild ->show() 看看是调用基类还是之类的方法 期望调用子类的方法 然后去掉子类重写的方法看看调用的是不是基类的方法
然后子类不重写 看看是不是会调用基类类型的方法
iocp完成端口 完成端口等于异步IO+线层池 1.先建立一个空的完成端口IOCP = WASCreateIoCompletePort(),2.创建一定数量的线程,3.在WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr),overlapped这里面需要创建事件overlapped.event = WASCreateEvent();之后,不同于重叠IO 不是通过getoverlapped获取结果,通过线层池唤醒线层对接受的数据进行相关的业务处理,再次调用WASCreateIoCompletePort((HANDLE)sockClient,IOCP,/*传入的参数,完成建*/,/线程的数量/)进行投递到完成端口的队列,申明线层函数,在线层函数等待一个完成端口的事件::GetQueuedCompletionStatus(iocp,totalRecvCount,/完成件/,overlapped,infinity),里面通过传入的完成建将wasbuff打印出来。
重叠端口:WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr);/获取数据 GetOverlappedResult((HANDLE)sockclint),&overlapped,&recvCount,,true); 系统通知你的时候把输入操作已经帮你做了。
异步选择事件:事件和套接字绑定HANDLE aSock[50];
HANDLE aEvent[50];
aEvent[0] = WSACreateEvent(); 创建事件
accept和recv需要由事件来通知 通过asock = socksever ; WASEventSelect(sockserver,aEvent,FD_ACCEPT)中相关参数设置 accepte和recv的方式 用 ireturn = WSAWaitFormutilpleEvent(iicurrentNUm,aEvent,false,INFINITY,0)等待相应的事件置位 返回值是绑定对应数组的下标 由下标判断是哪个事件置位 accept还是recv
异步选择消息模型:通过windows消息的机制触发 消息到了 肯定是有accept用户连接 或者recv到数据了
线层池:
- 创建一定数量线层 创建事件 用于控制线层的退出 初始化信号量 里面车位刚开始位满 控制活跃的线层属 初始化临界区 用于控制读取任务的互斥
- 线层函数里面一个大循环,WaitForSingleObject(ms_pThreadPool->m_hSemaphore, INFINITE); 等待信号量提升 在addtask的时候提升信号量的空位
boost库 字符算法、智能指针、
数据库:
Mysql:
Mysqld --install //数据库安装
Net start mysql //数据库服务启动
Net stop mysql //停止数据库服务
Mysqld --remove 卸载数据库
Select database() 当前使用的数据库
Mysql -uroot 以管理员前线登录
Show tables 查看当前数据库有多少表
show databases //查看当前数据库所有数据库
Use test //使用哪个数据库
Show engines 查看数据使用的哪种引擎
当前主要使用较多的两种:1、myisan 2 innodb 支持事务
Drop table dd; //删表
数据类型 decimal(p,s)//小数类型 前面是整数+小数一共的位数,后面是小数的位数
Crate datebase yy 建立数据库yy
//查看建立数据库语句
Show create databse ‘db’;
//建立一张表 id不能为负 可以null填充 不足六个整数前面用0填充 插入一条记录自增id
表尾 代表 引擎使用myisam 自增赋初值为5 编码格式使用gutf8
Crate table dd(
Id INT(6) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
Name VARCHAR(20) ,
Sgender ENUM(‘男’,’女’,保密’’),
PRIMARY_KEY(id)
)ENGINE=MYISAM AUTO_INCREMENT =5 DEFAULT CHARSET = UTF8;
//查看表结构
//desc dd;
//修改表名:、
Rename table dd to student
//修改表中字段名及类型
Alter table dd change id tid int(8);
Alter table name sname varchar(30);
//给表增加一列
Alter table dd ADD score tinyint;
//在表中哪一列后增加一列
Alter table dd address varchar(80) after id;
//在表中删除某一列
Alter tabel dd drop COLUMN address;
//插入
Insert dd valules(null,’李四’,’男’);
Insert into dd values(null,’李四’,’男);
//插如多条记录
Insert dd valules(null,’李四’,’男’),Insert into dd values(null,’李四’,’男);
//选择性插入
Insert dd(id,name) values(6,‘张三’);
//将表全部查出来在插入一遍
Insert into student(id,name,Sgender)select id name Sgender from dd;
//修改数据
Update student set Sgender = ‘男’ where name = ‘李四’
Update student set Sgender = ‘男’ ,id = 10 where name = ‘李四’
//删除数据
Delete from dd where id = 8;
Delete form dd //无条件删除所有记录
Delete from dd where name like ‘张’;删除姓张的
//查询
Select * from dd
只显示姓名 成绩 以别名的形式
Select name 姓名 ,id 学号 from student;
成绩小于八十的
Select *form student where score<80;
查询条件 between and
Select * from student where score between 80 and 90;
基本条件like 条件%
查询姓名两个字的学生信息
Select *from student where name like ‘__’; 两个下划线
Select *from student where name like ‘张_’; 姓张的 名字两个字的
Select*from student where name ‘ %丽%’;名字有丽的 %代表一个和多个
基本条件查询 in() not in 多个范围
Select *from student where id in(8,9,10);
Select *from student where id not in(8,9,10);
基本条件运算 null 用is null 或 is not null
Select *from student where score is null
Update sutdent set scor = 0 where score is null;
分组查询 聚集 集合函数 主要配合分组 group by
Max()
Avg()
Count() 统计多少条记录
Sum()
Select avg(score) from student;
查询最高分
Select max(score) from student;
查询最高分学生的信息
Select *from student where score in(select max(score) from student);
统计多少人
Select cont(*) from student
Select max(score)最高分, min(score) 最低分 from student;
查询各地区的人数
Select count(*) from student group by adress;
注意:在分组查询过程,只能出现聚集函数和分组字段 下面:
Select count(*) 人数,address 地区 from student group by adress 对
Select count(*) 人数,address 地区 , sname 姓名 from student group by adress 错 出现了名字 不是分组字段
Select count(*) 人数,address 地区 from student
Where address is not null --条件 分组前 成绩为空 不参加分组
group by adress -- 分组字段
Order by count(*) DESC; --根据人数降序
分组条件 分完组后按条件查询 需要放在 group by 后面
Select count(*) 人数,address 地区 from student
Where address is not null --条件 分组前 成绩为空 不参加分组
group by adress -- 分组字段
Having count(*)>2 -- 分组后条件 分组后人数大于2的地区
Order by count(*) DESC; --根据人数降序
连接查询
建立两个表一个学生 一个老师
学生表里面包含老师的ID
多表查询 公司不推荐
Select s.name ,s.sgender* fronm s ,t where s.tid = t.tid;
连接查询 join left join rignt join
Select s.name s.sgender from s left join t on s.tid = t.tid;
Mysql 的约束
主键约束 primary key
默认约束 defaut
非空约束 not null
外键越苏 foreign key reference仅支持引擎为INoodb
Create table t
(
Tid int unsigned not null auto increment
Tname varchar(20)
Key(tname) --建立表的时候 同事建立索引 名字不能重复
Primary_key(tid)
)
Create table t
(
sid int unsigned not null auto increment,
sname varchar(20),
Tid int unsigned ,
Primary_key(tid)
Constraint fk foreign key (tid) reference t(tid)--建立外键 关联到teacher表
)
由于存在外键 删除某一项老师记录需要对应的学生不存在,删除老师表之前需要删除学生表 不然不让删除老师表 解决方案如下 级联删除
Create table t
(
sid int unsigned not null auto increment,
sname varchar(20),
Tid int unsigned ,
Primary_key(tid)
Constraint fk foreign key (tid) reference t(tid) on delete cascade
)
加上on delete casecade 就能删除教师记录 但是还是不能删除教师表 除非先删除学生表
主键 不能为空 ,不能重复
外键 一遍一个表的外键指向 另外一个表的主键 且类型一致
增加一个表的主键()
alter table tt add constranit pk primary key(name);
增加一个表主键
Alter table tt drop primary key
建立索引 方便检索数据 类似于书籍的目录 建立主键的时候 主键就是一个索引
Create index iia on(tname desc);
Alter table tt add index (tname desc);
删除索引
Drop index iia on teacher;
Alter table tt drop index tname;
常用函数:
Select length(‘ghh’);长度
Select * from student where sname like ‘__’;
Select *from student where char_lenth(sname) = 2;
//随机查询出两条记录
Select *from student order by rand() limit
查询天前的日期
Selet date_add(now(),interval -10 day);
查询10后的日期
Selet date_add(now(),interval 10 day);
存储过程
没有明确的返回值 编译后再服务器执行 熟读快
经过编译后存储在数据库中,用户通过 存储过程名字,并给出参数来执行它
函数 函数有返回值
c++常见面试问题总结相关推荐
- js 计算任意凸多边形内最大矩形_题库 | 计算机视觉常见面试题型介绍及解答 第 7 期...
- 计算机视觉 -为什么说 Dropout 可以解决过拟合?(1)取平均的作用: 先回到标准的模型即没有 dropout,我们用相同的训练数据去训练 5 个不同的神经网络,一般会得到 5 个不同的结果 ...
- Hive常见面试问题(持续更新)
Hive常见面试问题 目录 Hive 内部表和外部表的区别,以及各自使用于哪种环境?Hive和传统数据库的区别? HiveRc 文件? Hive 分区? Hive 分区过多有何坏处以及分区时的注意事项 ...
- 面经——C/C++常见面试知识点总结附面试真题
参考:C/C++ 面试题 作者:zhaouc 发布时间: 2015-02-15 15:51:00 网址:https://blog.csdn.net/zhaouc/article/details/438 ...
- java面试常见面试问题_Java面试准备:15个Java面试问题
java面试常见面试问题 并非所有的访谈都将重点放在算法和数据结构上-通常,访谈通常只侧重于您声称是专家的语言或技术.在此类访谈中,通常没有任何"陷阱"问题,而是它们要求您利用内存 ...
- spring常见面试问题_Spring面试问题
spring常见面试问题 另外,请查看我们最新的文章69Spring面试问题与解答–最终清单 . 1)什么是春天? 回答: Spring是控件和面向方面的容器框架的轻量级反转. 2)解释春天? 回答: ...
- 【C++基础】常见面试问题(二)
1. 指针和引用的区别 指针保存的是所指对象的地址,引用是所指对象的别名,指针需要通过解引用间接访问,而引用是直接访问 指针可以改变地址,从而改变所指的对象,而引用必须从一而终: 引用在定义的时候必须 ...
- Java常见面试知识点:继承、接口、多态、代码块
问题:Java常见面试知识点:继承.接口.多态.代码块 答案: 1.继承 继承中构造方法的访问特点 子类中所有的构造方法默认都会访问父类中无参的构造方法 为什么? • 子类在初始化的时候,有可能会使用 ...
- 视频教程:Java常见面试题目深度解析!
视频教程:Java常见面试题目深度解析! Java作为目前比较火的计算机语言之一,连续几年蝉联最受程序员欢迎的计算机语言榜首,因此每年新入职Java程序员也数不胜数.很多java程序员在学成之后,会面 ...
- Linux底层IIC 总线的理解、调用函数以及常见面试问题
对 IIC 总线的理解.调用函数以及常见面试问题 一.IIC 总线概述: IIC 即Inter-Integrated Circuit(集成电路总线) I2C总线是PHLIPS公司推出的一种串行总线, ...
- 面试中 项目遇见的难点答案_你和offer之间只差这几个面试问题!常见面试问题汇总...
99%的人都会大呼"坑爹"的面试问题,你真的知道该怎么回答吗? 记得第一次面试的时候,面试官对简历也很满意,前面都聊的好好的,最后问了一句简历上没有的内容:你的职业规划是什么?我一 ...
最新文章
- 撩课-Java每天5道面试题第11天
- 个人觉得非常好的B树,B+树的总结
- 阿里云产品搭建web应用梳理
- windows2003 DHCP中批处理绑定IP与MAC
- hashmap应用场景_Redis 5种数据结构 及使用场景分析
- 服务高可用:幂等性设计
- java jsoup获取cookie_java – 如何使用jsoup维护变量cookie和会话?
- 多个数据文件 mysql_mysql多实例(多个配置文件方式)
- Java同步组件之CountDownLatch,Semaphore
- android 学习之URI
- SIP协议栈基础笔记
- 短网址算法 php,PHP短网址生成算法
- 减肥测试用什么软件,该减肥了吗?教你用手机App测量体脂率
- 写在今年(2022)清明节前
- C51最小系统板红外遥控控制小车
- Projector学习笔记
- MySQL基础(一)
- 纪念日+小游戏+工具小软件
- 在mac上通过Homebrew安装redis
- 互联网应用开发实践:需求分析与数据库设计