关于c++:你手里都有哪些offer

58次阅读

共计 11691 个字符,预计需要花费 30 分钟才能阅读完成。

在这里给大家整顿了腾讯、阿里、百度、华为、头条等一共九家大厂 2020 年的面试题以及答案,篇幅所限,我就每家的只放两道题了,有须要完整版的敌人能够评论区留言获取。不足我的项目实战经验的小老弟能够点这里☞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;
} 

企业级实战我的项目纲要,学完轻松待业☟

我都这么有诚意了你还不关注我???

正文完
 0