赞
踩
给大家整理了腾讯、阿里、百度、华为、头条等一共九家大厂2020年的面试题以及答案,篇幅所限,我就每家的只放两道题了,有需要完整版的朋友可以评论区留言或进群973961276获取。缺乏项目实战经验的小老弟可以点这里☞c/c++企业级项目实战。
文末还给大家放了一份学习大纲,如果看完文章能顺手给我点个赞那就再好不过了。
1.删除字符串s1中在字符串s2中出现的字符。
基本思路:把s1的字符存到一个set里面,然后遍历s2,看是否出现过,出现过就erase掉。但是直接输出set的元素这样会改变顺序,要想顺序不变,就顺序遍历一下s1 看是否出现,出现就输出。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <set>
- #include <queue>
- #include <map>
- using namespace std;
- typedef long long LL;
- const int maxn=1005;
- set<char>s;
- int main()
- {
- string s1,s2;
- cin>>s1>>s2;
- int len=s1.length();
- for (int i=0;i<len;i++)
- s.insert(s1[i]);
- len=s2.length();
- for (int i=0;i<len;i++)
- {
- if (s.count(s2[i]))
- s.erase(s.find(s2[i]));
- }
- len=s1.length();
- for (int i=0;i<len;i++)
- {
- if (s.count(s1[i]))
- cout<<s1[i];
- }
- cout<<endl;
- return 0;
2. 求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
答案:
一天总共有3600*24=86400秒。
定义一个长度为86400的整数数组intdelta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。
然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。
这样处理一遍后数组中存储了每秒中的人数变化情况。
定义另外一个长度为86400的整数数组intonline_num[86400],每个整数对应这一秒的论坛在线人数。
假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0]=delta[0]。第n+1秒的人数online_num[n]=online_num[n-1]+delta[n]。
这样我们就获得了一天中任意时间的在线人数。
1、使用mysql索引都有哪些原则?索引什么数据结构? B+tree和B tree什么区别?
答案:
1、 对于查询频率高的字段创建索引;
2、 对排序、分组、联合查询频率高的字段创建索引;
3、 索引的数目不宜太多 原因:a、每创建一个索引都会占用相应的物理控件; b、过多的索引会导致insert, update、delete语句的执行效率降低;
4、 若在实际中,需要将多个列设置索引时,可以采用多列索引 如:某个表(假设表名为Student),存在多个字段(StudentNo, StudentName, Sex, Address, Phone, BirthDate),其中需要71 StudentNo, StudentName 字段进行查询,对 Sex字段进行分组,对BirthDate字段逹行排序,此时可以创建多列索引index index_najne (StudentNo, StudentName, Sex, BirthDate) ;#index_najne 为索引名 在上面的语句中只创建了一个索引,但是对4个字段都赋予了豪引的功能。 创建多列索引,需要遵循BTree类型,即第一列使用时,才启用索引。 在上面的创建语句中,只有mysql语句在使用到StudentNo字段时,索引才会被启 用。 如: select * from Student wheie StudentNo = 1000; #使用到了 StudentNo 字段,索引被启用。 以使用explain检测索引是否被启用如:explain select * from Student where StudentNo = 1000;
5、 选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生 表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的 信息。如果使用姓名的话,可能存 在同名现象,从而降低查询速度。
6、 尽量使用数据量少的索引 如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR (100)类型的 字段进行全文检索 需要的时间肯定要比对CHAR (10)类型的字段 需要的时间要多。
7、 尽量使用前缀来索引 如果索引字段的值很长,最好使用催的前缀来索引。例如,TEXT和BLOG类型的字 段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提 高检索速度。
8、 删除不再使用或者很少使用的索引. 表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再 需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作 的影响B+ tree树索引,B tree,散列
2、Mysql有哪些存储引擎?请详细列举其区别?
答案:
InnoDB:事务型存储引擎,并且有较高的并发读取频率
MEMORY:存储引擎,存放在内存中,数据量小,速度快
Merge: ARCHIVE:归档,有很好的压缩机制
3、设计高并发系统数据库层面该如何设计?数据库锁有哪 些类型?如何实现?
答案:
分库分表:同样量的数据平均存储在不同数据库相同表(或不同表)中,减轻单表 压力,如果还是很大,就可以每个库在分多张表,根据hash取值或者其他逻辑判断将 数据存储在哪张表中
读写分离:数据库原本就有主从数据库之分,查询在从服务器,増删改在主服务器,
归档和操作表区分:建一张归档表,将历史数据放入,需要操作的表数据单独存储
索引之类的创建,对于数据量很大,百万级别以上的单表,如果増删改操作不频 繁的话,可以创建bitMap索引,速度要快得多
共享锁:要等第一个人操作完,释放锁,才能操作
更新锁:解决死锁,别人可以读,但不能操作
排他锁:读写都被禁用
意向锁(xlock):对表中部分数据加锁,查询时,可以跳过
计划锁:操作时,别的表连接不了这张表
1、输入www.baidu.com在浏览器的完整过程,越详细越好。
答案:
浏览器获取输入的域名ww. baidu. com
浏览器向域名系统
DNS请求解析ww. baidu. com的IP地址 DNS解析出百度服务器的IP地址
浏览器与服务器建立TCP连接(默认端口 80)
浏览器发出HTTP请求,请求百度首页
服务器通过HTTP请求把首页文件发给浏览器
TCP连接释放
浏览器解析首页文件,展示web界面
2、请描述C/C++程序的内存分区?
答案:
其实c和c卄的内存分区还是有一定区别的,但此处不作区分:
1) 、栈区(stack)-由编译器自动分配軽放,存放函数的参数值,局部变量的值等。 其 操作方式类似于数据结构中的栈。
2) 、堆区(heap) ——般由程序员分配释放,若程序员不軽放,程序结束时可能由 OS回 收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3) 、全局区(静态区)(static) —,全局变量和静态变量的存储是放在一块的,初 始化的 全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻 的另 —块区域。-程序结束后由系统释放。
4) 、文字常量区一常量字符串就是放在这里的。程序结束后由系统释放。
5) 、程序代码区一存放函数体的二进制代码。 栈区与堆区的区别:
1) 堆和栈中的存储内容:栈存局部变量•,函数参数等。堆存储使用new、malloc申请 的变量等;
2) 申请方式:栈内存由系统分配,堆内有由自己申请;
3) 申请后系统的响应:栈一一只要栈的剩余空间大于所申请空间,系统将为程序提供 内存,否则将报异常提示栈溢出。 堆一一首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请 时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结 点链表中删除,并将该结点的空间分配蜘程序; 申请大小的限制:WindowsT栈的大小一般是2M,堆的容量较大; 申请效率的比较:栈由系统自动分配,速度较快。堆使用new、malloc等分配,较 慢;
总结:
栈区优势在处理效率,堆区优势在于灵活;
内存模型:自由区、静态区、动态区;
根据c/c++对象生命周期不同,c/c++的内存模型有三种不同的内存区域,即:自由存 储区,动态区、静态区。 自由存储区:
局部非静态变量的存储区域,即平常所说的栈; 动态区:用new , malloc分配的内存,即平常所说的堆;
靜态区:全局变量,静态变量,字符串常量存在的位置; 注:代码虽然占内存,但不属于c/c卄内存模型的一部分;
1、static有什么用途?(请至少说明两种)
答案:
1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中維持其值 不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所 用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。 那就是,这个函数被限制在声明它的模块的本地范围内使用
2、引用与指针有什么区别?
答案:
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。
3、某32位系统下,C++程序,请计算sizeof的值.
- char str[] = rthttp: //www. ibegroi5>. com/w
- char *p = str ;
- int n = 10;
- sizeof (str ) = ? (1)
- sizeof ( p ) = ? (2)
- sizeof ( n ) = ? (3) void Foo ( char str [100]) (
- mm
- sizeof( str ) = ?(4)
- }
- void *p = malloc( 100 );
- mm
- sizeof ( p ) = ? (5)
- 17 (2) 4 (3) 4 (4) 4 (5) 4
1、求此N的最小公倍数。把每个数字分解质因数,算他们 每个质因数的贡献,然后乘起来。
- #include<bits/stdc++. h>
- using namespace std;
- typedef long long 11;
- #define maxn 100009
- int fact [maxn];
- bool prime [maxn];
- 11 mod = 987654321;
- int cal (int t, int p) {
- int ent = 0;
- while(t % p == 0) { cnt++;
- t /= P;
- return ent;
- void first () {
- memset (prime, true, sizeof (prime)); prime[1] = false;
- for(int i = 2; i <= 100000; i++: { int top = sqrt(i);
- for(int j = 2; j <= top; j—) { if(i % j == 0){ prime[i] = false; break;
- void solve(int Limit) { first ();
- for (int i = 2; i <= Limit; i++' { int top = sqrt(i);
- for (int j = 2; j <= top; ji) { if(prime[j] && i % j == 0) {
- fact[j] = max (fact [j], cal (i, j));
- I
- if(prime[i])
- fact [i] = max (fact [i], 1);
- }
- }
- int main() {
- 11 n;
- cin^^n;
- solve (n);
- 11 ans = 1;
- for(11 i = 1; i <= n; i++) {
- for (11 j = 1; j <= fact[i]; j++) {
- ans = ans * i % mod;
- }
- }
- cout<<ai^s<<endl;
- return 0;
2、去掉字符串构成回文。其实是经典的求回文子序列个数。
- # inc lude <b i t s /s t dc++. h>
- using namespace std;
- typedef long long 11;
- 11 f[59] [59];
- string str;
- 11 dfs(int i, int j) {
- i£(i > j) {
- return 0;
- }
- if(i == j) {
- f[i] [j] = 1;
- return f [i] [j];
- }
- [j] != 0){
- return f [i] [j];f [i] [j] = dfs (i, j - 1) + dfs(i + 1, j) - dfs(i + 1, j - 1); if (str [i] == str[j])
- f [i] [j] += dfs(i + 1, j - 1: + 1;
- return f [i] [j];
- int main。{
- cin>>sh;
- int len = str.length();
- cout«dfs(0, len - l)«endl;
- return 0;
1、已知一个函数rand7()能够生成1-7的随机数,请给岀一个 函数,该函数能够生成1-10的随机数。
- 该解法基于一种叫做拒绝采样的方法。主要思想是只要产生一个目标范围内的随机数, 则直接返回。如果产生的随机数不在目标范围内,则丢弃该值,重新取样。由于目标范 围内的数字被选中的概率相等,这样一个均匀的分布生成了。
- 显然rand7至少需要执行2次,否则产生不了 1T0的数字。通过运行:rand7两次,可 以生成1-49的整数,
- 2 3 4 5 6 7
- 1 2 3 4 5 6 7
- 8 9 10 1 2 3 4
- 5 6 7 8 9 10 1
- 2 3 4 5 6 7 8
- 9 10 1 2 3 4 5
- 6 7 8 9 10 * *
- *******
- 由于49不是10的倍数,所以我们需要丢弃一些值,我们想要的数字范围为1-40,不 在此范围则丢弃并重新取样。
- 代码:
- int randlOO {
- int row, col, idx;
- do {
- row = randT ();
- col = randT ();
- idx = col + (row-1) *7;
- } while (idx > 40);
- return 1 + (idx-l)%10;
- }
- 由于row范围为1-7, col.范围为1-7,这样idx值范围为1-49。大于40的值被丢弃, 这样剩下1-40范围内的数字,通过取模返回。下面计算一下得到一个满足1-40范围的 数需要进行取样的次数的期望值:E(# calls to rand7) = 2 * (40/49) +
- 4 * (9/49) » (40/49) +
- 6 * (9/49)2 * (40/49) +
- 8
- =$ 2k * (9/49)k_1 » (40/49) k=l
- =(80/49) / (1 - 9/49)2
- =2.45
2、C++11创建线程的三种方式
- 通过暨!
- thread:标准库的类
- join:阻塞主线程并等待
- // MultiThread, cpp : Defines the en~ry point for the console application.
- #include 〃stdafx・h〃
- #include^iostream>
- #include<vec t or >
- #include<map>
- #include<string>
- it inc lude < thr e ad>
- using namespace std;
- void myPrint()
- [
- cout « "线程幵始运行”« endl;
- cout « 〃线程运行结束了” « end*std:: thread my20bj (myPrint); // 可调用对象 my20bj. joint);//主线程阻塞在这.,并等待myPrint()执行完 cout « ^wangtao^ « endl;
- return 0;
- detachO:将主线程和子线程完全分离,子线程会驻留在后台运行,被CH运行时库接 管,失去控制
- joinable ():判断是否可以成功使用join。或者detach()
- 程序说明:detach后不能在实施join std: : thread my20bj (myPrint); //主线程阻塞在这,并等待myPrint ()执行完 if (my20bj. joinable ()) {
- cout « ^1: joinable () == hue" « endl;
- }
- else {
- cout « ^1:joinable() == false” « endl;
- }
- my20bj. detachO ;
- if (my20bj. j oinable()) {
- cout « "2: joinable () == hue" « endl;
- }
- else {
- cout « °2:joinable() == false” « endl;
-
- I
- cout
- «
- 〃祁angtaol”
- «
- endl;
-
-
- cout
- «
- 〃祁angtao2"
- «
- endl;
- cout
- «
- 〃祁angtao3”
- «
- endl;
- cout
- «
- 〃祁angtao4〃
- «
- endl;
- cout
- «
- 〃祁angtao5”
- «
- endl;
- cout
- «
- 〃祁angtao6〃
- «
- endl;
- cout
- «
- ^wangtao?^
- «
- endl;
- cout
- «
- 〃祁angtao8〃
- «
- endl;
- I
- return 0;
- int
- main
- 0
- std:: thread my20bj (myPrint); //主线程阻塞在这,并等待myPrint ()执行完 if (my20bj. joinable ()) {
- my20bj. join();
- cout
- «
- 〃祁angtaol”
- «
- endl;
- cout
- «
- 〃祁angtao2"
- «
- endl;
-
- cout
- «
- 〃祁angtao3”
- «
- endl;
-
- cout
- <<
- 〃wangtao4〃
- <<
- endl;
-
- cout
- «
- 〃祁angtao5”
- «
- endl;
-
- cout
- «
- 〃祁angtao6〃
- «
- endl;
-
- cout
- «
- ^wangtao?^
- «
- endl;
-
- cout
- «
- 〃祁angtao8〃
- «
- endl;
-
- return 0;通过类对象创建线程
- class CObject
- [
- public:
- void operator () () {
- cout « "线程幵始运行"« endl; cout « '线程结束运行〃 « endl;
- int main()
- [
- CObject obj;
- std:: thread my20bj (obj); //主线程阻塞在这,并等待myPrint ()执行完 if (my20bj. joinable ()) {
- my20bj. join();
- }
- cout « see you << endl;
- return 0;
- class CObject
- [
- int& m_obj;
- public:
- CObject(int& i) :m_obj(i) {} void operator () () { // 不带参数 cout « "线程幵始运行1” « endl; cout « "线程幵始运行2” « endl; cout « "线程幵始运行3" « endl; cout « "线程幵始运行4” « endl; cout « "线程幵始运行5” « endl;
- int main。
- [
- int i = 6;
- CObject obj (i);
- std:: thread my20bj (obj); //主线程阻塞在这,并等待myPrint ()执行完 if (my20bj. joinable ()) {
- my20bj. detachO ;cout « "sue you " « endl;
- return 0;
- 用detach ()主线程结束对象即被销毁,那么子线程的成员函数还能调用吗?
- 这里的的对象会被复制到子线程中,当主线程结束,复制的子线程对象并不会被销毁 只要是没有引用、指针就不会出现问题
- 通过复制构造函数和析构函数来燈证对象是否复制到了子线程中
- // MultiThread. cpp : Defines the eniry point for the console application.
- //
- #include "stdafx.h”
- #include<iostreajn>
- #include<vector>
- Ji include〈map >
- #include<string>
- #include<thread>
- using namespace std;
- class CObject
- [
- int& m_obj;
- public:
- CObject(int& i) :m_obj(i) {
- cout « "ctor” « endl;
- }
- CObject(const CObject& m) :m_obj(m.m_obj) {
- cout « "copy ctor" « endl.
- }
- "CObject() {
- cout « "dtor” « endl;
- I
- void operator () () { // 不带参数
- cout « "线程幵始运行1” « endl;
- cout « "线程幵始运行2” « endl;
- cout « "线程幵始运行3" « endl;
- cout « "线程幵始运行4” « endl;
- cout « "线程幵始运行5” « endl;
- int main。
- [
- int i = 6;
- CObject obj (i);
- std:: thread my20bj (obj); //主线程阻塞在这,并等待myPrint ()执行完 if (my20bj. joinable ()) {
- my20bj. detachO ;
- }
- cout << see you << endl;
- return 0;
- 子线程的析构函数在后台执行,所以输出的dt皿是主线程的。用join()结果为:
- 通过lambda表达式创建线程
- int main。
- [
- auto myLamThread = [] {
- cout « "线程幵始运行"« endl;
- cout « '线程结束运行”« endl;
- };
- thread cthread(myLamThread);
- cthread. joint);
- std::cout « 〃see you " « endl.
- return 0;
1、C++智能指针如何解决内存泄露问题
- shazedjtr共享的智能指针
- std::shmed_ph使用引用计数,每一个sharedjtr的拷贝都指向相同的内存。在最 后一个shared_ptr析构的时候,内存才会被释放。
- 可以通过构造函数、std_make_shared辅助函数和reset方法来初始化shared_ptr:
- //构造函数初始化
- std::shared_ptrp ( new int(1));
- std::shared_ptrp2 = p ;
- //对于一个未初始化的智能指针,可以通过reset方法来初始化。
- std::shared_ptrptr; ptr.reset ( new int (1));
- if (ptr) {cout « "ph is not null.\n^ ; }
- 不能将一个原始指针直接赋值给一个智能指针:
- std: : shared_ptrp = new int(l) ;//编译报错,不允许直接赋值
- 获取原始指针:
- 通过get方法来返回原始指针
- std::shared_ptrptr ( new int(1));
- int * p =ptr. get ();
- 指针删除器:
- 智能指针初始化可以指定删除器
- void DeletelntPtr ( int * p ) {
- delete p ;
- }
- std::shared_ptrp ( new int , DeletelntPtr );
- 当P的引用技术为o时,自动调用删除器来释放对象的内存。删除器也可以是一个 lambda表达式,例如
- std::shared_ptrp ( new int , [](int * p){delete p});
- 注意事项:
- .不要用一个原始指针初始化多个shared_ptro
- .不要再函数实参中创建Shared_ptr,在调用函数之前先定义以及初始化它。
- (。).不荽将lhi»指针作为 ^Cd_plx返回出来。
- 0).要避免循环引用。
- unique_ptr独占的智能指针
- unique_ptr是一个独占的智能指针,他不允许其他的智能指针共享其内部的指针,不 允许通过赋值将一个unique_ptr赋值给另外一个unique_ptro
- unique_ptr不允许复制,但可以通过函数返回给其他的unique_ptr,还可以通过 std::move来转移到其他的unique_ptr,这样它本身就不再拥有原来指针的所有权了。 如果希望只有一个智能指针管理资源或管理数组就用unique_ptr,如果希望多个智能 指针管理同一个资源就用shared_ptro
- weak_ptr弱引用的智能指针
- 弱引用的智能指针weak_ptr是用来监视sharedjtr的,不会使引用计数加一,它 不管理shared_ptr内部的指针,主要是对了监视shared_ptr的生命周期,更像是 shared_ptr的一个助手。
- weak_ptr没有重载运算符桥口因为它不共享指针,不能操作资源,主要是为了 通过Shared_ptr获得资源的监测权,它的构造不会増加引用计数,它的析构不会减少 引用计数,纯粹只是作为一个旁观者来监视shmed_ph中关离得资源是否存在。
- weak_ptr还可以用来返回this指针和解决循环引用的问题。
2、linux中软连接和硬链接的区别.
原理上,硬链接和源文件的inode节点号相同,两者互为硬链接。软连接和源文件的 inode节点号不同,进而指向的block也不同,软连接block中存放了源文件的路径名。 实际上,硬链接和源文件是同一份文件,而软连接是独立的文件,类似于快捷方式,存 備看源文件的位置信息便于指冋。 使用限制上,不能对目录创建硬链接,不能对不同文件系统创建硬链接,不能对不存在 的文件创建硬链接;可以对目录创建软连接,可以跨文件系统创建软连接,可以 对不存在的文件创建软连接。
1、线上CPU爆高,请问你如何找到问题所在。
答案:
1、top命令:Linux命令。可以查看实时的CPU使用情况。也可以查看最近一段时间 的CPU使用情况。
2、PS命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的 当前CPU使用情况。属于当前状态的采栏数据。
3、jstack: Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个 命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等
4、pstack: Linux命令。可以查看某个进程的当前线程栈运行情况。
2、红黑树如何插入和删除的
答案:
插入:
(1) 如果父节点为黑色,直接插入不处理
(2) 如果父节点为红色,叔叔节点为红色,则父节点和叔叔节点变为黑色,祖先节 点变为红色,将节点操作转换为祖先节点
(3) 如果当前节点为父亲节点的右节点,则以父亲结点为中心左旋操作
(4) 如果当前节点为父亲节点的左节点,则父亲节点变为黑色,祖先节点变为红色, 以祖先节点为中心右旋操作
删除:
(1) 先按照排序二叉树的方法,删除当前节点,如果需要转移即转移到下一个节点
(2) 当前节点,必定为这样的情况:没有左子树。
(3) 删除为红色节点,不需要处理,直接按照删除二叉树节点一样
(4) 如果兄弟节点为黑色,兄弟节点的两个子节点为黑色,则将兄弟节点变为红色, 将着色转移到父亲节点
(5) 如果兄弟节点为红色,将兄弟节点设为黑色,父亲结点设为红色节点,对父亲 结点进行左旋操作
(6) 如果兄弟节点为黑色,左孩子为红色,右孩子为黑色,对兄弟节点进行右旋操 作
(7) 如果兄弟节点为黑色,右孩子为红色,则将父亲节点的颜色赋值给兄弟节点, 将父亲节点设置为黑色,将兄弟节点的右孩子设为黑色,对父亲节点进行左旋
1、寻找两个有序数组的中位数
- double findliledianSortedArrays (vectoi<intnumsl, vector<int>& nums2) { double ret - ~1;
- vector<double> buff;
- //合并两个数组
- for (auto e : numsl)
- buff. push_back(e);
- for (auto a : nums2)
- buff. push_back(a);
- 合并后的结果进行排序
- sort (buff. beginO, buff, end:));
- int size3 = buff. size();
- /依取中位数
- if (size3 % 2 == 0)
- [
- ret = ((buff[size3 / 2] + buff[size3 / 2 - 1]) / 2);
- }
- else
- {
- ret = buff[size3 / 2];
- }
- return ret;
- }
2、c++实现线程安全的单例模式
- 懒汉模式:
- class singleton
- [
- protected:
- singletonO
- [
- p thr e ad_mut ex_ini t(&mutex);
- private:
- static singleton* p;
- public:
- static pthread__mutex_t mutex;
- static singleton* initance();
- pthread_mutex_t singleton::mutex;
- singleton* singleton::p = NULL;
- singleton* singleton::initance()
- [
- if (p == NULL)
- [
- p thr e ad_mut ex_lo ck(&mutex);
- if (p == NULL)
- p = new singletonO ;
- p thr e ad_mut ex_unlo ck(&mutex;;
- }
- return p;
- }
企业级实战项目大纲,学完轻松就业☟
我都这么有诚意了你还不关注我???
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。