腾讯面试收集

1、一个班要有多少个人才能保证跟你生日重复率高于50% 23人
概率树,
n个人两个不重复的概率有:
(n-1)/n*(n-2)/n…1/n=

2、IO多路复用
3、mysql的不同引擎,区别,优劣势
一、**MyISAM:**在创建MyISAM的时候会出来三个默认的文件:
1.tb_demo.frm,存储表定义;
2.tb_demo.MYD,存储数据;
3.tb_demo.MYI,存储索引。
MyISAM表无法处理事务,所以它只适合在以下几种情况使用
1、选择密集型的表。MyISAM存储引擎在筛选大量数据时非常迅速,这是它最突出的优点。
2、插入密集型的表。MyISAM的并发插入特性允许同时选择和插入数据。例如:MyISAM存储引擎很适合管理邮件或Web服务器日志数据。

二、InnoDB:在mysql5.6版本以上被作为默认引擎,并且加入了行级锁定外键约束
1. 更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。
2.事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。
3.自动灾难恢复。与其它存储引擎不同,InnoDB表能够自动从灾难中恢复。
4.外键约束。MySQL支持外键的存储引擎只有InnoDB。
5.支持 自动增加列 AUTO_INCREMENT属性。

三、MEMORY:使用MEMORY引擎主要是因为速度,好处就在MEMORY采用的逻辑存储是系统内存,极大的提高了储存数据表的性能;
坏处就是当mysqld守护进程崩溃时,所有的Memory数据都会丢失
要求存储在Memory数据表里的数据使用的是长度不变的格式,这意味着不能使用BLOB和TEXT这样的长度可变的数据类型
所以一般在以下几种情况下使用Memory存储引擎:
1.目标数据较小,而且被非常频繁地访问。在内存中存放数据,所以会造成内存的使用,可以通过参数max_heap_table_size控制Memory表的大小,设置此参数,就可以限制Memory表的最大大小。
2.如果数据是临时的,而且必须立即使用,那么就可以存放在内存表中。
3.存储在Memory表中的数据如果突然丢失,不会对应用服务产生实质的负面影响。
Memory同时支持散列索引B树索引。B树索引的优于散列索引的是,可以使用部分查询和通配查询,也可以使用<、>和>=等操作符方便数据挖掘。散列索引进行“相等比较”非常快,但是对“范围比较”的速度就慢多了,因此散列索引值适合使用在=和<>的操作符中,不适合在<或>操作符中,也同样不适合用在order by子句中

四、MERGE: MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须完全相同,所以就相当于一个集合器。比起其他储存引擎MERGE不是很优秀,但是在某些情况下MERGE还是非常的有用。对于服务器日志这种信息,一般常用的存储策略是将数据分成很多表,每个名称与特定的时间端相关。

五、ARCHIVE:Archive是归档的意思,在归档之后很多的高级功能就不再支持了,仅仅支持最基本的插入和查询两种功能。在MySQL 5.5版以前,Archive是不支持索引,但是在MySQL 5.5以后的版本就开始支持索引了。Archive拥有很好的压缩机制,它使用zlib压缩库,在记录被请求时会实时压缩,所以它经常被用来当做仓库使用。

4、C++线程池
多线程基础入门
C++线程库:#include 创建 阻塞(join)
thrad :线程
mutex:互斥量:lock和unlock;lock_gard线程保姆(通过作用域,作用域结束自动析构) unique_lock比lock_guard多了几种模式
condition_variable:条件变量,wait(locker)调用unlock自动释放锁并阻塞当前进程,本线程释放锁其他线程就可以获得锁。当本线程被其他线程notify后,wait()就会调用locker_lock()上锁
cond.notify_one():随机唤醒一的等待的进程,cond.notify_all()唤醒所有的线程
异步线程:#include
future占位:std::async是一个函数模板,用来启动一个异步任务,它返回一个std::future类模板对象,future对象起到了占位的作用(记住这点就可以了)。刚实例化的future是没有储存值的,但在调用std::future对象的get()成员函数时,主线程会被阻塞直到异步线程执行结束,并把返回结果传递给std::future,即通过FutureObject.get()获取函数返回值。
shader_future:与future类似,但是他是复制了数据,可以多次调用
原子类型automic<>:用来定义一个自动加锁解锁的共享变量
** 线程池 **
产生的原因:创建和销毁线程需要占用时间和CPU资源
程序启动后,预先创建一定数量的线程放入空闲队列中,这些线程都是处于
阻塞状态
,基本不消耗CPU,只占用较小的内存空间。
接收到任务后,任务被挂在任务队列,线程池选择一个空闲线程来执行此任务。
任务执行完毕后,不销毁线程,线程继续保持在池中等待下一次的任务。
5.1 线程与进程/并发与并行
并发的两种方式: 双核及其的真正并行、单核机器的任务切换
并发的两种基本途径: 多进程并发、多线程并发
多进程并发: 优点是更容易编写安全的并发代码(操作系统为进程通信提供了一定的保护措施)、可分布式(可以通过远程连接的方式在不同的计算机上独立运行进程);缺点是进程开销大启动慢 ,进程之前的 通信复杂耗时
多线程并发: 优点是共享内存的灵活性(进程中的所有线程共享内存地址空间。虽然进程之前也共享内存,但这种共享通常是难以管理的,因为同一数据的内存地址在不同的进程中是不同的),缺点是编写代码时工作量大(需要保证多个线程访问到的共享数据是一致的)
5.2 创建线程时的传参问题分析
std::thread的构造函数会拷贝传入的参数:
1. 当传入参数为基本数据类型(int,char,string等)时,会拷贝一份给创建的线程;
2. 当传入参数为指针时,会浅拷贝一份给创建的线程,也就是说,只会拷贝对象的指针,不会拷贝指针指向的对象本身。
3. 当传入的参数为引用时,实参必须用ref()函数处理后传递给形参,否则编译不通过,此时不存在“拷贝”行为。引用只是变量的别名,在线程中传递对象的引用,那么该对象始终只有一份,只是存在多个别名罢了(注意把引用与指针区别开:指针是一块内存指向另一块内存,指针侧重“指向”二字;引用是只有一块内存,存在多个别名。理解引用时不要想着别名“指向”内存,这是错误的理解,这样的理解会导致分不清指针和引用,别名与其本体侧重于“一体”二字,引用就是本体,本体就是引用,根本没有“指向”关系。);
4. 当传入的参数为类对象时,会拷贝一份给创建的线程。此时会调用类对象的拷贝构造函数
5.3 detach()
使用detach()时,可能存在主线程比子线程先结束的情况,主线程结束后会释放掉自身的内存空间;在创建线程时,如果std::thread类传入的参数含有引用或指针,则子线程中的数据依赖于主线程中的内存,主线程结束后会释放掉自身的内存空间,则子线程会出现错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值