字节客户端+后端八股文第二弹☝️
Table of Contents
urgent #
- 最小输者树
- LFU的如何实现
- 读者-写者模型
- x86汇编的特定寄存器
- private和protected的区别
- 页面置换算法?
- OPT-逆向LRU
- FIFO-可能产生belady异常
- LRU
- CLOCK算法(NRU)
- ARP?OSPF?RIP?
- ARP:求MAC地址,采用广播的方式等待回应
- 中间人欺骗ARP攻击、网关伪造
- ARP:求MAC地址,采用广播的方式等待回应
- 拥塞控制
- 如何度量拥塞:超时重传率、平均延迟情况
- 负载脱落:随机丢弃数据包
- 随机早期检测RED:这样随机丢弃数据包可以让发送方更容易意识到自己发送太快了
- 流量控制
- 超时或者3个以上ACK,TCP就认为是阻塞了,前者恢复到最小帧长,后者恢复到一半。TCP最小包长度是1460Bytes。
- 第四次挥手老是送不到:在一定时间内没有TPDUs到达则单方面自动释放;同时利用定时器,超时时自动发一个哑TPDU(dummy TPDU),避免被对方释放
- 流量整形
- 漏桶和令牌桶:控制流出速率使之保持恒定,对于过多的流入分组进行丢弃处理
- 二叉树的遍历
- 调度算法
- SFCS
- 护航效应
- SJF
- 平均等待时间最优
- 但是几乎不能实现
- 优先级调度
- 可能饿死,可以用aging解决
- 高响应比
- 响应比是等待时间和执行时间的比值
- 多级队列
- 前面的队列可以抢占后面队列
- 每条队列上,时间片倍增
- 前面的都是FCFS,最后一个队列是RR
- SFCS
- 进制转换(除n取余再复习下)
- 给了一棵树的后序遍历和中序遍历,让我写出这棵树的前序遍历
- 注意,只有前序和后序没法求中序。但是此外已知两者可以求第三者。
- LRU实现
- malloc和free的内存分配和释放,如何设计
- 智能指针 要注意的地方
- 尽量使用make函数初始化智能指针
- 避免循环引用造成的内存泄露
- http2.0多路复用
- 用户复制粘贴,计算机都进行了什么操作?复制一个文件,在粘贴之前删除文件,再粘贴会成功吗,为什么?
- 注意互斥锁
- URL和URI
- L是location,用于资源定位,给出资源的准确路径
- I是identify,用于标识一个资源
- URL是URI的子集
反问 #
- 有没有新人培养机制
- 不同base,业务上有什么区别
常见问题 #
- 对于客户端开发的理解是什么
- 最近在看什么书
- OC基础
- iOS开发指南:从零基础到App Store上架,关东升
- 首先是IOS系统基础,然后是网络相关的知识,然后是IOS app的商业化思考,最后还有一些实战项目。
- 有没有阅读开源框架
- idb
- 前两轮面试体验如何?有哪些回答的不太好的知识点?
- 效率高,面试官引导
- 可能有的地方不是很清楚,面试官都解答了
- 比较前沿应用的知识
- 你自己的优势和劣势
- 分享一个最值得分享的经历,觉得最有成就感的?过程中最有收获的点?
- 你对同事间的矛盾怎么看
八股 #
- unix4种IO模型(3种同步,1种异步)
- 同步阻塞IO
- 发出IO请求,就停下来等着,直到完全完成IO操作
- 同步非阻塞IO
- 发出IO请求,立即返回结果。如果结果是错误,则说明数据没准备好;如果结果是正确,就开始拷贝数据,拷贝过程是同步的(即阻塞的)。
- 同步多路复用IO
- 所谓多路复用,就是可以同时监视多个fd
- select
- 只知道有IO发生,但是具体哪个fd不知道,所以只能对1024个以内的fd进行轮询
- 基于数组
- fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
- poll
- 相比select,其区别是不限制fd数量
- 基于链表来存储,所以不限数量
- epoll(event poll)
- 内核通过epoll_ctl方式注册fd,某fd一旦就绪,内核就会类似回调的方式激活该fd
- epoll_create是创建一个epoll句柄;
- epoll_ctl是注册要监听的事件类型;
- 可以注册一个回调函数,当设备就绪,就会调用这个回调函数,然后唤醒等待队列上的等待者
- 每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd从用户态拷贝进内核,所有fd只需要复制一遍(相比select,每次wait都会复制一遍,非常慢)
- epoll_wait则是等待事件的产生。
- epoll的两种触发方式
- LT水平触发
- 缓冲区有数据就会通知
- ET边缘触发
- 当出现IO操作才通知,与缓冲区内是否有数据无关
- LT水平触发
- epoll相比前两种方法的好处
- epoll的fd集合只需要从用户态复制到内核态复制一遍,而前两者每次wait都得复制
- epoll无需遍历
- 异步IO(完全异步IO)
- 调用 aio_read 函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式。然后直接返回,于是可以做其他事情,无需阻塞
- 内核将数据拷贝到缓冲区之后,再通知应用程序
- 同步阻塞IO
- 重载的底层原理
- 只是返回值不同,不能构成重载。
- 因为会进行函数更名。更名的依据是参数类型,而不是返回值
- 什么是多线程下载
- 获取总大小
- 决定要开几个线程
- 平均分每个线程要下载的数据量
- 根据分配的数据量对待下载文件在字节上进行平均划分(确定每个线程负责的字节范围)
- mysql 为什么不每个列都建索引
- 索引占用内存RAM中的空间;太多或太大的索引,而DB将不得不将它们交换到磁盘或从磁盘交换,从而降低了数据的维护速度。
- 函数返回值放在那里?栈吗?
- EAX(32位);EAX||EDX(64位)。
- C++11右值引用
&&
,也就是俩引用符号连着,可以表示右值引用- 因为传统的引用只能引用左值,但是例如int num=&3就是非法的,因为3是右值。右值引用的加入,实现了对右值也可以引用。
- 右值引用的好处是可以对右值进行修改。这样就可以打破传统的“右值只能读”的特性了。
- 也存在“常右值引用”,也就是加const,例如const int a=&&3;但是没有任何用处。因为和右值引用引入的目的相悖。
- 迭代器什么时候会失效
- vector扩容后,原有的迭代器失效
- for循环中删除或插入迭代器指向的元素,由于指向的元素被释放,导致失效。
- 实际上,插入或删除后,从该位置开始到结尾的所有位置的迭代器都失效了
- 这个时候就要用erase方法返回值来接住下一个位置的迭代器,才能正确使用。(因为会返回指向后继元素的迭代器)
- TCP/IP网络框架中,最大和最小的数据单位是?
- 一个以太网数据帧的用户数据段是 46-1500 字节 ;TCP协议的话,有20字节IP头+20字节TCP头,占用 40 字节 ;就是说留给用户的数据是 6字节-1460 字节
- 构造函数中可以调用虚函数吗
- 可以。因为编译器会让构造函数中先给vptr赋值,然后才执行构造函数的函数体。
- 如果调用也不会报错,会输出类似于
Base::Fuction A::Fuction
的情形,而不是A::Fuction A::Fuction
。因为在进入到基类的构造函数阶段,相当于用基类的指针去访问虚表。
- 使用https一定能保证安全性吗
- 自签名证书
- 用自己的私钥生成证书,而不需要通过CA机构签发,不让他们恰饭。
- 非浏览器用户连接HTTPS服务时,如果表示明确信任该证书,就可以当做是真的CA证书一样,用于HTTPS通信
- 但是由于不具有权威性,所以在浏览器用户上,无论如何都会提示证书无效。
- 可以被抓包
- 在用户知情的情况下,可以搭建中间人网络,从而用于抓包。
- 虽然浏览器会提示当前有安全风险
- 自签名证书
const char*,const * char,char const*
区别- 如果const修饰变量或是引用,const和类型的先后顺序没有区别
- 如果const修饰指针,形如
<const1> type <const1> * <const2> identifier
。- 其中type左右,星之前的俩const是等价的,所以我们都记作1,这代表这个类型是常的。表示常量指针,也就是指针本身可以变化,但是不能通过指针改变指向对象的值
- 对于const2,出现在星之后,代表指针是常的,表示常指针,也就是可以改变指向对象的值,但是指针不能指向其他地方
- 对象中的const,如果是成员,就必须在初始化表中初始化;
- 如果是const函数,则声明其在运行过程中不应当修改任何数据。const函数不允许调用非const函数。
- static的作用
- 文件作用域限定:把作用域局限在当前文件
- 静态存储:作为静态变量,不再存储在栈中
- 单例模式:static成员函数属于类,没有this指针,不能定义为虚函数
- mysql索引的缺点
- 修改业务量远大于查询业务量时,不应该创建索引,因为增加索引时,会提高检索性能,但是会降低修改性能。索引表是需要动态维护的呀。
- 数据值比较少的列没有必要建立索引
- mysql在什么情况下最好建立索引
- 第一、在经常需要搜索的列上,可以加快搜索的速度;
第二、在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
第三、在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
第四、在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
第五、在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
第六、在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
-
mysql 三个引擎是什么吗?
- 默认 myIASM,不支持事务,只支持表级锁;
- MEMORY,在内存,除了快没啥优点;
- Innodb,最常用的,支持 ACID,支持事务,支持行级锁。
-
你刚提到的管道是只能在父子进程之间吗
- 是的。管道只能用于父子进程之间
- 而且是半双工的,数据只能由一个进程流向另一个进程。如果要全双工,需要俩管道。
- 管道实际上是一段缓冲区,由内核管理。而且在Linux下被设计为环形。
- 无名管道是只存在于内存空间的文件。只能用于父子进程通信。
- 有名管道是可以存在于磁盘上的文件,可以用于非父子进程通信。
-
vector
- 连续的线性空间
-
deque了解吗,说一下实现原理
- 由一段一段的等长的连续空间构成。这就像一个一个等长的vector。但是每个这样的等长空间是分散分布在内存中的。
- 由一个连续空间,类似数组,存储指向各段这种空间的指针。
-
754标准 双精度型和浮点型的数据范围
-
怎么实现对应的区域的快速增删
-
mysql 索引 范围查询
-
fseek 系统调用 读磁盘
-
典型的负载均衡算法?
- DNS负载均衡:思路是 DNS 解析同一个域名时可以返回不同的IP地址。
- 轮询:将请求轮流发给后端不同的服务器
- 加权轮询:给厉害的后端服务器多分点请求
- 负载最低优先: LVS 可以根据“连接数”判断服务器状态,NGINX 可以根据“HTTP请求数”来判断。
- hash
-
代理服务器的工作原理是怎样的?代理和网关有什么区别?
- 网关就像是某个内网到因特网的大门。代理服务器是装备了米家智能门锁的这种大门。
- 网关区分了一个网络的内部和外部。
- 代理服务器可以屏蔽内网的信息(如果设置了的话),可以保证内部的信息不外泄。在外界看来,内网到外网的流量就好像都是从代理服务器的ip发出的。而原有的IP被屏蔽。
- 代理服务器也能缓存一些电脑经常访问的网站。
-
进程中的一个线程崩了,会引发进程崩吗
- 线程崩溃也会触发SIGSEGV (Segmentation Violation/Fault)(段错误)。默认的信号处理函数就是kill,因此会把进程kill掉。
- 但是如果设置了信号处理函数,就不会崩掉。
-
IDE如何判断代码哪一行报错
-
C++的数组作为函数参数有哪些形式?
(int *p, int p[10], int p[])
-
线程是否越多越好,线程太多有什么危害?
- 上下文切换在时间上的占比过多
-
动态绑定的底层原理?
- 基类的引用(指针)调用虚函数时,就会发生动态绑定。
- 就算是用基类的指针访问派生类对象,由于vptr的位置相对于对象都是一样的(都是开头处),所以就可以正常用vptr取找虚表,可惜找到了派生类的虚表,于是就调用了派生类的虚函数。
-
C++中发生继承时的内存对象模型是怎样的?
-
extern的作用
- 同文件下,在声明前使用这个变量(即使用的所在行要早于声明的所在行)
- 使用其他文件下的变量、函数
-
函数指针用法、原理
void (*p) (int a)
,也就是函数名的位置变成了*p
。一定要注意加括号!!!!!!!!!!!!!- 然后可以这样使用:
(*p)(2);
注意要先指向一个函数。 - 实际上就是函数的入口地址。在C中,函数名也可以看成一个地址。
- 函数指针可以用于实现多态。对同一个指针获得不同的功能。
-
野指针与悬空指针的区别?
- 野指针:指向的空间非法
- 悬空指针:指向的对象被删除
-
HTTP劫持
- 首先标注出需要劫持的
- 篡改响应体或抢先回包(导致后续真的包被丢弃),从而篡改网页内容,例如发出弹窗广告
-
函数签名
- 函数名、参数类型、个数和顺序(不包含返回值类型哟),用于识别不同的函数
-
CA数字证书有什么内容
- 证书内容包含了公钥、数字签名,证书
-
CA数字证书校验过程
- 网站信息、公钥通过hash摘要后,再通过私钥加密,生成签名
- 签名和私钥组合成证书。
- 客户端可以用公钥解密拿到摘要,利用相同的hash算法得到摘要,两个摘要比对即可判断是否发生了篡改
-
virtual function可以inline么
- 内联是编译阶段发生的
- 虚函数可以内联,但是只要发生多态就不会被内联
- 也就是,如果编译器明确知道调用虚函数的时候是调用哪个类的虚函数,那么可以内联
-
mysql 为什么有时候需要对多个字段进行添加索引
-
断点续传如何实现
- 使用HTTP请求的if-range字段+range字段
- 针对范围请求,通过HTTP响应返回状态码为206 Partial Content 的响应报文。
-
HTTP如何判断资源是否有更新
- 时间戳或ETAG
-
HTTP3.0用的UDP怎么做到可靠的?
-
mysql 什么时候索引会失效?
-
无锁机制
-
memcopy和strcopy的区别
- 后者会复制字符串的结束符
-
weak怎么置nil?原理了解吗?
-
菱形继承问题怎么解决?什么是菱形继承?
- 数据冗余和二义性问题
- 通过虚继承解决
-
操作系统如何处理中断
-
top k 几种算法的复杂度
-
有虚函数的类的内存存储情况
-
Stl中用到了哪些设计模式
-
malloc原理,是否真的直接分配物理内存?
-
编译的流程(词法分析,语法分析,语义分析,。。。?)
-
RSA的安全性靠什么保证?
- 大数因式分解较难
-
DNS底层是什么(UDP,IPV4…)
-
DNS会减缓访问速度吗?怎么解决?(说了本地缓存,貌似还有其他的
-
ARP协议,ARP攻击
-
OSPF
-
RIP
-
OS同步模型
-
动态链接区和静态链接库的区别
-
计网各个可靠传输算法
-
改进UDP让他实现可靠传输(QUIC)
- QUIC协议就是基于UDP重新实现了一遍HTTP2的特性。
- 即=UDP + TLS + HTTP2
-
动态链接库实际存了哪些东西
-
belady现象
- FIFO下,分配更多可用页面,却导致缺页错误增多。
-
http可靠传输
- 有一些丢包、重复发包,怎么处理的?
-
生产者消费者量级越来越大了之后怎么优化
-
HTTP长连接怎么保证长连接不断开?keep-alive了解吗?
- keep-alive 是客户端和服务端的一个约定,如果开启 keep-alive,则服务端在返回 response 后不关闭 TCP 连接;
- 连接时长由最大请求个数或最大连接时间决定。maxKeepAliveRequests、keepAliveTimeout。
-
map为什么用红黑树而不是搜索树?
- 红黑树确保没有一条路径会比其它路径长出两倍,因此,红黑树是一种弱平衡二叉树,相对于要求严格的AVL树来说,它的旋转次数少,也就是这样可以保证插入、删除等修改操作没有那么麻烦,提升修改效率。插入最多两次旋转,删除最多三次旋转。
- 因此性能比较稳定。基本都在logn,不会发生变化。
-
索引为什么用b+树而不是b树、其他搜索树?
- 因为b+树内部节点都是索引,所以一个盘块可以存储更多的结点,减少IO次数。
- 效率稳定:大家在树上的的查找路径的长度相等
- 相邻结点查找效率高:因为最后一层变成链表了
-
写一个宏定义函数,实现返回三个数中最大的
-
static和extern的访问范围,extern的情况下什么时候程序会报错
- 多次初始化会报错
-
const修饰指针(const摆在不同位置的区别)存储空间
-
inline在什么时候展开、编译还是运行?
-
如果堆上的资源没有释放,会发生什么?
- 内存泄露
-
三次握手的第三次失败了会怎么样
- Client 向 server端发送数据,Server端将以 RST包响应
- server会重传ack
-
可达性分析
-
手写单例模式
-
实现一个单例模式,其中各种锁的作用?
-
动态代理
-
cglib
-
class Base{ int x; int y; virtual function(){ }; } ,sizeof(Base)是多少
- 子类的大小是本身成员变量的大小加上父类的大小。
- 如果有虚函数那就加上vptr的大小。
-
三次握手为什么两次不行
- 不过此时服务器并不能确认客户端的接收能力是否正常。
-
- TCP的3次握手,4次挥手,为什么要3次握手?
- 其中一次发送失败会发生什么
-
三种继承方式区别,三种成员修饰符的区别
- protected 把父类的public放到子类的protected里面
- private成员是不能被继承的,只有public,protected的成员才可以被继承。
- protected成员不可以由该类的对象直接访问
-
进程通信的优缺点
-
const指针的两种形式
-
什么时候shared_ptr会发生内存泄露?
- 互相引用
-
c++四种cast
- constcast用于将const变量转为非const
- staticcast用于隐式类型转换
- dynamiccast用于动态类型转换,只用于指针,实现类层次间的向上和向下转化
-
override关键字的作用?
-
volatile关键字的作用?
- 两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。
-
http重传的时间是怎么确定的?
-
1xx 状态码做什么用的?
- 信息
-
数据库 联合索引建立的顺序?a, b, c 的联合索引,直接查 b 的话能查到吗?
-
mysql MVCC?
- 就是多版本并发控制
- 让读写之间也不冲突的方法
- binlog等
-
mysql 磁盘操作和内存操作量级差别多大?
-
mysql 连接池?
-
mysql 分库分表、读写分离?
-
先写 redolog 还是先写 binlog?
- 为什么有 redolog?redolog 如何保证持久性?
- redolog 也写磁盘,它是直接写磁盘吗?有 os buffer
- 如果写到 os buffer 之后,mysql 进程挂了,写成功了吗?
-
http 1.1是否是全双工的(答案是半双工),HTTP 1.1和2.0的区别
-
一个TCP支持多少个HTTP?了解HTTP复用吗?
- 同一个域名下只需要使用一个TCP链接
-
HTTP状态码有几类?
-
实践中用过哪些设计原则?
-
C++多继承
-
C++是如何进行内存管理的
-
Linux的系统结构
-
找一个Linux命令讲讲执行过程
-
管道的实现原理
-
数据库 举一个一致性的例子
-
递归查询和迭代查询
- 注意,向根域名服务器查询的过程是本地DNS服务器(例如山东大学校园网的DNS服务器)发出的,而不是客户机发出的,除非本地客户机自己假设DNS服务器。
-
让我设计一下微信扫码登录
- 注意绑定操作
-
如何避免DNS劫持(要求先说一下DNS解析过程,然后分析可能在哪些地方发生劫持,其实是在循序渐进地提示我了),如何保证不被DNS劫持(中间补充问了DNS在哪一层),有听过HTTPDNS吗(无)
-
二叉树的三种遍历
-
静态变量存在什么地方
-
类型擦除
-
hashmap扩容过程,为什么是2的倍数?hashmap线程安全?
-
操作系统层面加快矩阵的乘法
-
管道底层如何实现,信号量底层如何实现
-
智能指针的底层如何实现?
-
mysql几种索引的优缺点
-
快排的优化
-
智能指针move语义是怎么实现的
-
shared_ptr里引用计数器是怎么实现共享的
-
shared_ptr是线程安全的吗
-
C++11了解atomic吗
-
static是线程安全的吗
-
malloc和free的内存分配和释放,如何设计
- 链表,内存块从小到大排列,但会存在内碎片
-
操作系统的mmap
- 直接把文件的一部分映射到内存中来,只需要拷贝一次。
- 然后脏写回。
-
线程池里的同步和调度怎么做?
-
读写锁是怎么实现的?
-
假设客户端和服务器通过TCP通信,这时客户端突然断电,服务器是如何关闭这个连接的?(超时重传超过阈值后,主动断开连接)服务器TCP具体怎么断开连接的?发了什么包?
-
浏览器输入URL的细节
-
NAT
-
AOP设计方法
-
不能声明为内联函数的情况
-
字典树
-
print i++在多线程和单线程环境下的区别
-
计网 幂等性
-
介绍下你接触过的NoSQL数据库
-
clone和直接下载zip压缩包的区别是什么
-
http包结构 头结构
-
lambda表达式
-
bss段在哪里
-
dynamic_cast 与 static_cast的区别?
-
线程卡死、segmentfault
-
URI和URL
-
定义一个只能在堆上生成对象的类,只能在栈上的呢?
-
一个进程在内核存储的情况
-
程序是怎么链接的,相互依赖问题是在链接的时候解决吗?如果一个程序用了另一个程序的代码,是分开编译的吗
-
线程池Epoll的做法?和select的区别?
-
Md5加密和普通加密的区别
-
栈的自动释放底层原理
-
Socket和tcp的关系
-
udp可不可以实现安全传输,在应用层上面做一些手
-
内存四区模型
-
对于带null字段的sql语句怎么优化?
-
cookie是怎样被设置到浏览器的(HTTP响应首部字段)
-
C++数组越界会发生什么
-
图片和html文件是否是一起传输
-
map,unordered_map中,key的规范
-
this指针你是怎么理解的
-
vptr在哪里?如何手动调用虚函数?
- 对象的起始地址就是vptr这个指针;通过vptr指针就得到了虚表的第一个元素,即第一个函数的指针;再星一下就调用了第一个虚函数;如果要调用下一个就++即可。因为它的类型是void星,也就是函数指针
- 可以看出,每个类都有一张虚表,派生类虽然有的虚函数没有重写,但是仍让包含所有基类虚函数的函数指针,只不过指向基类虚函数。如果派生类把这个虚函数重写了,对应位置就会换成指向新的实现的指针。
- ![[Pasted image 20220314222955.png]]
- ![[Pasted image 20220314222704.png]]
-
构造函数和析构函数可以为虚函数嘛?为什么析构函数推荐写成虚函数?
- 虚表在编译阶段就生成了!也就是编译期间就确定了各个类的虚表中的内容。
- 编译器会为构造函数中增加为vptr赋值的代码。所以在没有进入构造函数前,vptr是未定义的野指针。
- 构造函数不可以虚:在定义子类对象时,vptr先指向父类的虚函数表,在父类构造完成之后,子类的vptr才指向自己的虚函数表。也就是说,对象被创建后,才会有其vatble,但是构造函数就是来创建对象的。因此,如果构造函数是虚的,因为当前还不存在当前类的虚表,所以在调用虚函数时会找不到这个虚函数。
- 析构函数可以是虚函数,且推荐写成虚函数:因为如果析构函数不是虚的,如果用基类的指针去访问派生类,需要析构的时候,就会导致只去调用基类的析构函数,于是派生类的析构函数不会被调用,会导致内存泄露的风险。反之,如果是虚的,就会实现“先调用派生类,再调用基类的析构函数”的效果。(如果用派生类的指针是不会有这种问题的。)
-
虚表放在哪里?
- 虚表放在只读数据段.rodata中,虚函数位于代码段.text中。这些区都在栈之外,和栈的地位是等同的。
- vptr得看是怎么创建的。如果是正常创建就是栈区否则是堆区。
-
计算机内存空间的结构
- 栈上方还有一段保留的段,这是为操作系统驻留存储器部分(也就是内核)的代码和数据保留的。
- .data存放已初始化的全局变量:这些变量在运行之前就有自己的值。因为要记录初值,所以已初始化的变量越多,可执行文件越大
- .bss(全称:Better Save Space)段存放未初始化的全局变量:因为不需要存储初值,所以不会影响可执行文件的大小。它只是用于指导程序在运行时的空间分配。
- .text中就是程序代码。
- .rodata中存放只读数据,例如虚表、switch的跳转表
- 在程序占用的内存空间中,栈、多态链接库、堆位于较高的地址空间;那些段位于较低的地址空间。
- 注:如果局部变量用static修饰,那么不会放到栈里,而是像全局变量那样根据是否初始化放到.data或.bss.
- 细节:栈段必然是在用户最大合法地址作为栈底的。为什么是最大合法地址?因为再大就是OS保留区了。
- 当程序运行时,加载器把相关内容复制到各段中。
-
C中怎么保证类不被实例化
-
函数内可以返回一个局部变量的引用嘛
-
Go和C的区别与联系
-
Socket编程的流程,怎么选择是用UDP和TCP
-
索引为什么用B+而不是B树?
-
快排平均复杂度是nlogn 是怎么算出来的?
-
TCP拥塞窗口 冗余3次和超时两种情况 会对应不同的处理方式
-
解释型语言的原理
-
两个队列实现一个栈;两个栈实现一个队列
-
编译器前端后端
-
session和cookie的区别?为什么说http是无状态的?
-
c++函数指针
-
想优化下二分查找的话有什么思路?
-
动态链接库内存中有几份?动态链接库能通信吗
-
扫描二维码登录网站的大致流程
-
TCP重传机制
-
了解表视图吗,解释一下复用原理(复用标识符);
-
响应链?(OC)
-
设计模式 MVC?MVVM?
-
有什么数据结构可以兼顾数组和链表的优点
-
C语言不能面向对象的根本原因
-
子线程崩了的话进程会不会崩?(如果捕获了异常或信号就不会崩)
-
异常控制流
-
WEB页面解析过程?React动态渲染的原理?
-
const * int *p
是什么 -
C++对象的内存布局
-
指针能不能访问0x0
- 保留区地址,所以不能
-
网络 子网遮罩了解吗
-
如何在进程中直接操作物理地址
-
socket的建立过程(bind/listen那一套,顺便说了accept和connect是在tcp握手的什么时间返回)
-
udp的应用
-
多态(编译时、运行时)
-
虚指针什么时候创建
-
虚函数能不能inline
-
详细介绍const
-
4种多态
-
struct/class/union的区别
-
如何实现断点续传
-
http 2.0/3.0面向对象设计榨汁机,makejuice(xxx),参数传进去什么
-
INT_MAX+1后变成啥
-
操作系统是如何快加IO读写的
-
data 和text段区别
-
链接器如何做的重定向
-
weak_ptr存在野指针的问题吗
-
虚函数表,存放在哪里
-
TCP首部
-
内存中为什么划出未初始化区域
-
数据库的三大范式
-
C++中锁的使用
-
TCP time_wait阶段在做什么
-
GC垃圾回收
-
洗牌算法?
- 用于处理类似于“从100个数中取70个随机数且不能重复”的算法。
- 如果强行rand100,越往后命中以前取过的数字的几率越大,效率会急剧下降。于是我们可考虑把数组原地打乱,然后直接取数字即可。
- 最后一个数和前面任意 n-1 个数中的一个交换,然后倒数第二个数和前面任意 n-2 个数中的一个交换。。。依次下去就行了。直接看代码:
var arr = [1,2,3,4,5,6,7,8,9]
var len = arr.length
while(len){
let idx = parseInt(Math.random()*len);
let temp;
[arr[len -1], arr[idx]] = [arr[idx], arr[len - 1]];
len--;
}
// arr: [6, 4, 2, 9, 7, 5, 1, 3, 8]
智力 #
-
出了6次:64匹马8个赛道,找出最快四匹的次数
-
这1024个数中,再随意放进去一个数,然后找到这个数的方法
-
两人抛硬币,正面向上为赢,我先抛赢的概率
2/3,因为输的概率是1/4+1/4*1/4+1/4*1/4*1/4+.....+1/4的n次方,极限值为1/3,所以赢的概率是2/3。
-
一个硬币,正反面出现次数不确定,如何生成公平事件
- 解决:抛两次就行
-
约瑟夫环问题
-
一个岛上有红黄蓝三种颜色的兔子,数量分别为a,b,c,任意两只不同颜色的兔子碰撞变成两只第三种颜色的兔子,a,b,c满足什么样的关系可以使得有可能经过足够长时间的碰撞,岛上最终都是一种颜色的兔子
- 存在两个数模3相等
-
1小时内有汽车经过的概率为96%,30分钟内有汽车经过的概率为?
- 相当于两个一小时内都没有等到车,概率P=1-(1-96%)(1-96%)=1-0.0016=99.84% , 那么假设半小时内等到车的概率为x 1-(1-x)(1-x) = 96%
-
三门问题
-
统计所有四位正整数中各个数位上数字之和是9的数的个数
- 因为是四位正整数
所以首位不能为0
当首位为1时:
有1008,1017,1026,1035,1044,…,1800
共有9+8+7+…+1=C(10,2)=45个
当首位为2时:
有2007,2016,2025,2034,2043,…,2700
共有8+7+6+…+1=C(9,2)=36个…
当首位为8时:
有8001,8010,8100
共有2+1=C(3,2)=3个当首位为9时:
有9000
共有1=C(2,2)=1个综上,所有四位正整数中各个数位上数字之和是9的数的个数有C(10,2)+C(9,2)+…+C(3,2)+C(2,2)=45+36+28+21+15+10+6+3+1=165(个)
- 因为是四位正整数
-
在一条长廊上,有100盏灯亮着,按1-100编好号,每只灯下都有一个开关控制这一只灯的亮,灭,在长廊的这一头,有100个人一字排开站军姿,也按1-100编了号,这100号人将依次齐步走经过这100只灯,当他们经过能把自已整除的灯时,就会按一下这只灯的开关,问当这100号人都经过这100只灯时,还有哪些灯是亮着的?
- 10 20 30 40 50 60 70 80 90
11 21 31 41 51 61 71 91
02 12 22 32 42 52 62 72 82 92
03 13 23 33 43 53 63 73 83 93
14 24 34 44 54 74 84 94
05 15 35 45 55 65 75 85 95
06 26 46 56 66 76 86 96
07 17 27 37 47 57 67 77 87 97
08 18 28 38 48 58 68 78 88 98
19 29 39 59 69 79 89 99
经别人提醒,原来还是有简单的方法的。
任何一个数,如果能被整除,都是一对的,又除数就有商。比如12被3整除后商是4,3和4作为一组,3关一次,4开一次,所以不影响12号灯的状况,12被1整除后商是12,1和12一组同样不影响12号灯的状况,2和6同样如此。但是完全平方数就不同。16=4*4
,但4号兵只有一个,他单独作为一组,影响了灯的状况。所以只要是完全平方数的灯最后会灭。
- 10 20 30 40 50 60 70 80 90
-
老虎吃羊假设你是一头老虎,你前面有一只羊,你身后有100只老虎。这时候你有两个选择:吃了这头羊,不吃这头羊。但如果你选择吃了这头羊,你就会睡着。这时候排在你后面的老虎A也有两个选择:吃了你,不吃你。但如果老虎A选择吃了你,老虎A就会睡着。这时候排在老虎A后面的老虎B也有两个选择:吃了老虎A,不吃老虎A……以此往复,那么问题来了,你会吃了前面的那只羊吗?
-
我觉得后面如果有偶数只老虎就可以吃,奇数就不吃。