阿里、网易和腾讯面试题 C/C++
一、线程、锁
1、Posix Thread互斥锁
- 线程锁创建
a.静态创建
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
b.动态创建
pthread_mutex_t mutex = pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
- 互斥锁的属性
互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。
a.PTHREAD_MUTEX_TIMED_NP
这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
b.PTHREAD_MUTEX_RECURSIVE_NP
嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。 c.PTHREAD_MUTEX_ERRORCHECK_NP
检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
d.PTHREAD_MUTEX_ADAPTIVE_NP
适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。 - 锁操作
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)
pthread_mutex_trylock()
与pthread_mutex_lock()
类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待
- Linux线程
Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h
- 线程创建
int pthread_create((pthread_t *thread, const pthread_attr_t *__attr,void *(*__start_routine)(void *), void *__arg))
第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。返回0表示创建成功,否则不成功。
pthread_t id;
pthread_create(&id,NULL,(void *) thread,NULL);
- 线程等待
int pthread_join __P ((pthread_t __th, void **__thread_return))
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。 线程终止
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。
void pthread_exit ((void *__retval)) __attribute__ ((__noreturn__))
唯一的参数是函数的返回代码。2、死锁及其预防和处理方法
死锁的规范定义如下:如果一个进程在等待只能由该进程停止才能引发的事件,那么该进程就是死锁的。
(1)产生死锁的原因
- 因为系统资源不足。
- 进程运行推进的顺序不合适。
资源分配不当等。
(2)产生死锁的四个必要条件
- 互斥条件:每个资源要么已经分配给了一个进程,要么就是可用的。
- 占有和等待条件:已经得到了某个资源的进程可以再请求新的资源。
- 不可抢占条件:已经分配给一个进程的资源不能强制性地被抢占,只能被占有它的进程显式地释放;
- 环路等待条件:死锁发生时,系统中一定有两个或者两个以上的进程组成的一条环路,该环路中的每个进程都在等待着下一个进程所占有的资源。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
(3)处理死锁的四种策略:
- 鸵鸟策略(忽略死锁);
- 检测死锁并恢复;
- 仔细对资源进行分配,动态地避免死锁;
- 通过破坏引起死锁的四个必要条件之一,防止死锁的产生。
(4)死锁避免
死锁避免的主要算法是基于一个安全状态 的概念。在任何时刻,如果没有死锁发生,并且即使所有进程忽然请求对资源的最大请求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。从安全状态出发,系统能够保证所有进程都能完成,而从不安全状态出发,就没有这样的保证。
银行家算法 :判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求,如果满足请求后系统仍然是安全的,就予以分配。不安全状态不一定引起死锁,因为客户不一定需要其最大贷款额度。
二、C++
1. 虚函数的实现原理
虚函数表的创建和继承
a. 基类的虚函数表的创建:首先在基类声明中找到所有的虚函数,按照其声明顺序,编码0,1,2,3,4……,然后按照此声明顺序为基类创建一个虚函数表,其内容就是指向这些虚函数的函数指针,按照虚函数声明的顺序将这些虚函数的地址填入虚函数表中。例如若show放在虚函数声明的第二位,则在虚函数表中也放在第二位。 b. 对于子类的虚函数表:首先将基类的虚函数表复制到该子类的虚函数表中。若子类重写了基类的虚函数show,则将子类的虚函数表中存放show的函数地址(未重写前存放的是子类的show虚函数的函数地址)更新为重写后函数的函数指针。若子类增加了一些虚函数的声明,则将这些虚函数的地址加到该类虚函数表的后面。
通过虚函数表访问对象的方法
当执行Base->show()
时,要观察show
在Base
基类中声明的是虚函数还是非虚函数。若为虚函数将使用动态联编(使用虚函数表决定如何调用函数),若为非虚函数则使用静态联编(根据调用指针Base
的类型来确定调用哪个类的成员函数)。此处假设show
为虚函数,首先:由于检查到Base
指针类型所指的类Base
中show
定义为虚函数,因此找到Base
所指的对象,访问对象得到该对象所属类的虚函数表地址。其次:查找show
在Base
类中声明的位置在Base
类中所有虚函数声明中的位序。然后到Base所指对象的所属类的虚函数表中访问该位序的函数指针,从而得到要执行的函数。
为什么要把析构函数定义为虚函数?
new出来的是子类son的对象,采用一个父类father的指针来接收,故在析构的时候,编译器因为只知道这个指针是父类的,所以只将父类部分的内存析构了,而不会去析构子类的内存,就造成了内存泄露。基类析构函数定义为虚拟函数的时候,在子类的对象的首地址开始会有一块基类的虚函数表拷贝,在析构子类对象的时候会删除此虚函数表,此时会调用基类的析构函数,所以此时内存是安全的。
为什么虚函数比普通函数慢?
因为虚函数要通过查找虚函数表的方法访问。
为什么构造函数不能是虚函数?
构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个死循环。
- 内联函数、构造函数和静态成员函数可以定义为虚函数么?为什么?
基类指针指向派生类时如何知道指向的是哪一个派生类?
2. 正确区分重载、重写和隐藏。
注意三个概念的适用范围:处在同一个类中的函数才会出现重载。处在父类和子类中的函数才会出现重写和隐藏。
重载:同一类中,函数名相同,但参数列表不同。
重写:父子类中,函数名相同,参数列表相同,且有virtual修饰。
隐藏:父子类中,函数名相同,参数列表相同,但没有virtual修饰;函数名相同,参数列表不同,无论有无virtual修饰都是隐藏
基类中:(1) virtual void show(); //是虚函数(2) void show(int); //不是虚函数
子类中:(3) void show(); //是虚函数(4) void show(int); //不是虚函数
1,2构成重载,3,4构成重载,1,3构成重写,2,4构成隐藏。另外2,3也会构成隐藏,子类对象无法访问基类的void show(int)成员方法,但是由于子类中4的存在导致了子类对象也可以直接调用void show(int)函数,不过此时调用的函数不在是基类中定义的void show(int)函数2,而是子类中的与3重载的4号函数。
3、C对象和C++对象的区别(struct和class)
C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。struct能包含成员函数吗? 能!struct能继承吗? 能!!struct能实现多态吗? 能!!!
a. 默认的继承访问权限。struct是public的,class是private的。
b. struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。
三、网络
1、TCP和UDP
tcp是一种面向连接的、可靠的、基于字节流的传输层通信协议。udp(用户数据报协议)传输层协议,提供面向操作的简单不可靠的非连接传输层服务,面向报文。
- 区别 a. tcp是基于连接的,可靠性高;udp是基于无连接的,可靠性较低; b. 由于tcp是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差;同时过程复杂,也使其易于被攻击;而udp无连接,无建立连接的过程,因而实时性较强,也稍安全; c. 在传输相同大小的数据时,tcp首部开销20字节;udp首部开销只有8个字节,tcp报头比udp复杂,故实际包含的用户数据较少。tcp无丢包,而udp有丢包,故tcp开销大,udp开销较小;
d .每条tcp连接只能是点到点的;udp支持一对一、一对多、多对一、多对多的交互通信。 - TCP的三次握手
第一次握手:客户端发送一个tcp的syn标志位置为1的包(连接请求),指明客户打算连接服务器的端口;SYN=1,seq=client_isn
第二次握手:当服务器收到连接请求之后,返回确认包(ack)应答,即将syn和ack标志位同时致为1(授予连接),并为这次连接分配资源;SYN=1,ACK=1,seq = server_isn
第三次握手:客户端收到服务器的授予连接请求之后,再次发送确认包(ack)(syn标志位为0,ack标志位为1),并分配资源,这样tcp就建立连接了SYN=0,ACK=1,seq=client_isn+1 - TCP和UDP的数据结构
a.TCP
struct TCP_HEADER
{short m_sSourPort; // 源端口号16bitshort m_sDestPort; // 目的端口号16bitunsigned int m_uiSequNum; // 序列号32bitunsigned int m_uiAcknowledgeNum; // 确认号32bitshort m_sHeaderLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志位short m_sWindowSize; // 窗口大小16bitshort m_sCheckSum; // 检验和16bitshort m_surgentPointer; // 紧急数据偏移量16bit
}
b.UDP
struct UDP_HEADER
{short m_sSourPort; // 源端口号16bitshort m_sDestPort; // 目的端口号16bitshort m_size; //长度16bitshort m_sCheckSum; // 检验和16bit
}
四、组合数学
五、数据库
1、范式
常见的范式:第一范式(1NF),第二范式(2NF),第三范式(3NF)。下面就简单介绍下这三个范式。
| name | tel | age |
| :--: | :-----: | :--: |
| 大宝 | 136 | 22 |
| 小明 | 132,158 | 21 |
- 第一范式(1NF):强调的是列的原子性,即列(属性)不能够再分成其他几列。
考虑这样一个表:【联系人】(姓名,性别,电话)
如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分,即:【联系人】(姓名,性别,家庭电话,公司电话)。1NF 很好辨别,但是 2NF 和 3NF 就容易搞混淆。 - 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是不能只依赖于主键的一部分。
学生课程 老师 老师职称 教材 教室 上课时间
小明一年级语文(上) 大宝 副教授 《小学语文1》 101 14:30
一个学生上一门课,一定在特定某个教室。所以有(学生,课程)->教室
一个学生上一门课,一定是特定某个老师教。所以有(学生,课程)->老师
一个学生上一门课,他老师的职称可以确定。所以有(学生,课程)->老师职称
一个学生上一门课,一定是特定某个教材。所以有(学生,课程)->教材
一个学生上一门课,一定在特定时间。所以有(学生,课程)->上课时间
因此(学生,课程)是一个码。
◆ 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
六、数据结构
1、链表
(1)链表建立、插入、删除
- 建立
Node *L;
L = new Node;
L = NULL;//不带头节点的初始化
L->=NUll;//带头结点的初始化
- 头尾插入元素
p->next = L; L = p;//头插法
Node *tail = new Node;//尾插法
Node *cur = L;
while(cur->next!=NULL){cur = cur->next;
}
tail = cur;
tail->next = p;
p->next = NULL;
- 精确插入
bool ListInsert(List *L,int pos,Node *node){int i=1;Node *cur=new Node;cur = L;while(cur->next != Null && i != pose){cur = cur->next;i++;}if(cur->next = NULL) return false;else{node->next = cur->next;cur ->next = node;return true;}
}
- 精确删除
bool ListDelete(List *L,int pos){int i=1;Node *cur=new Node;cur = L;while(cur->next != Null && i != pose){cur = cur->next;i++;}if(cur->next = NULL||i>pos) return false;else{cur->next = cur->next->nextdelete cur->nextreturn true;}
}
(2)链表反转,环、
- 反转
bool ListReverse(List *L){Node cur = L->next;Node *temp = new Node;while(cur->next!=NULL){temp = cur;L->next->next = L;L->next = temp->next;cur = L->next;}return true;
}
环
算法的思想是设定两个指针p, q,其中p每次向前移动一步,q每次向前移动两步。那么如果单链表存在环,则p和q相遇;否则q将首先遇到NULL。- 如何定义一个只能在栈上或者堆上生成对象的类?
- sizeof(类),如何计算类的大小?
sizeof(结构体),如何计算结构体的大小?
- 结构体和类有什么区别?
- extern“C”有什么作用?原理是什么?
- const修饰的变量和#define有什么区别?
- static有什么作用?如何改变变量的生命周期和作用域?
- volitale什么作用?
new 和malloc有什么不一样?
- 指针和引用的区别?
- STL容器有哪些?
- vector内部数据结构是什?List/Map/Queue
- STL,vector和List有什么不一样?map是用什么数据结构实现的?
switch和if分支有什么区别?
全局变量好用么?
面向对象有哪些特点?如何体现?
面向对象的设计原则有哪些?
如何检查内存泄漏?
从源代码到可执行二进制文件,要经过哪些过程?
- 二维数组为题
http://c.biancheng.net/cpp/html/79.html
//这是一个关于二维数组指针的问题。
//假设定义一个int型的二维数组指针。
int Sec[2][3]={4,6,3,7,2,7};
int **P = Sec;
**p 等价 Sec[0][0] *p 等价 Sec[0] *(p+n) 等价 Sec[n] *(*(p+n)+m) 等价 Sec[n][m]
//所以++m,为行数增加为afternoon一行,而*m输出整行。
- C++中不能重载的运算符:“?:”、“.”、“::”、“sizeof”和”.*”
- 各个容器的内部实现数据结构
- 数组越界
死循环
栈溢出
内存泄露
- 数组越界
- 首先所谓的接口是指只包含纯虚函数的抽象类,和普通的抽象类含不一样
图像
视觉
转载于:https://www.cnblogs.com/shinny/p/9228549.html
阿里、网易和腾讯面试题 C/C++相关推荐
- 2011-2012年腾讯,创新工场,淘宝,百度,阿里,迅雷。网易游戏校园招聘面试题集锦(1-25题含答案)
2011-2012年腾讯,创新工场,淘宝,百度,阿里,迅雷.网易游戏校园招聘面试题集锦(1-25题含答案) 又是一年招聘季,小鸟我也在本季参加招聘,所以特在网上和群里面这里去年和今年的面试题,以备战招 ...
- 网易、腾讯、阿里竞相押宝的NFT,还有多大的想象空间?
软萌的叫声.粉嫩的肉垫.可爱的脸蛋,人们对于猫咪的喜爱正在不断的升温. "猫咪经济学"这一概念应运而生,它最初起源于日本,意指不管经济多么困难,大众对猫及相关产品的热情永远高涨,只 ...
- 阿里扔给腾讯一个烫手山芋
据 36 氪报道,阿里巴巴副总裁.C2M 事业部总经理七公(本名汪海)3月25日表示,阿里的确提交了淘宝特价版小程序的申请,期待和腾讯的合作,但申请仍在审批中. 淘宝特价版是淘宝旗下一款 App 应用 ...
- 程序员求助:腾讯面试题,64匹马8个跑道,多少轮选出最快的四匹
昨天,有网友私信我,说去阿里面试,彻底的被打击到了.问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题.无独有偶,今天笔 ...
- 阿里P10、腾讯T4、华为18都是怎样的神级收入?
点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 来源:InfoQ 关注我,回复口令获取可获取独家整理的学习资料: - 001 :领取<Sprin ...
- 阿里P10、腾讯T4、华为18,互联网公司职级、薪资、股权大揭秘
本文转载公众号: InfoQ 作者 | 小智 BAT.头条.华为们的最新技术职级序列是如何划分的?各个职级的大致薪资范围.股票都是多少?不同职级之间的晋升难度有多大,如何评审?校招.社招程序员想去大厂 ...
- 阿里 P10、腾讯 T4、华为 18,互联网公司职级、薪资、股权大揭秘-巴分巴秒
BAT.头条.华为们的最新技术职级序列是如何划分的?各个职级的大致薪资范围.股票都是多少?不同职级之间的晋升难度有多大,如何评审?校招.社招程序员想去大厂应该如何准备?本篇文章搜集整理了最新版数据,为 ...
- 阿里云、腾讯云、华为云:从内卷到外卷
近年来,在各行各业的飞速发展以及数字经济的高歌猛进下,国内电商.社交.游戏.视频等多个行业的企业纷纷开始扬帆出海,企图通过拓展海外业务来寻求更广阔的增量市场.无独有偶,随着越来越多的中国企业加快了出海 ...
- 大客户市场:阿里云、腾讯云、华为云“贴身肉搏”
配图来自Canva可画 近年来,随着中国逐渐进入数字化经济快车道,国内企业数字化.智能化升级已是刻不容缓.而为了帮助自身或其他企业实现数字化转型升级,阿里.腾讯.百度.京东.字节.网易.华为等众多国内 ...
最新文章
- python实现自动发送微博,当自己写博客时同步上去。
- Python-流程控制
- Android-Activity启动流程
- 钉钉老版本下载3.31_钉钉旧版pc下载-钉钉旧版pc客户端下载-西西软件下载
- createsemaphore 异常_浅析SPC之异常分析
- AMD推土机性能逼近六核心Core i7
- E - Alignment
- 梦断A股:证监会发现了小米的违规之处
- java excel 打勾,两种方法教你如何在excel文件中打勾
- MAC将latex等大软件安装到移动硬盘
- java font 字体大小_Java字体大小从宽度
- 关于电子账户开户四五要素
- 训练过程出现trian_dice一直大于1(mask范围0-255转为0-1)
- hdu 5234 - Happy birthday DP
- vue project vlog
- 阿里云编码规范答案_令人沮丧的答案是“我如何开始学习编码?”
- 再获2亿元A+轮融资,乐生智能能否“扫出”舒适区?
- ffmpeg+dxva2 +D3D9显示 学习笔记
- 他被称为中国第一程序员,一人之力单挑微软,如今拜入武当修道
- 数据结构实验+理解1 基于c++的二叉树函数实现