1、关键字static的作用是什么 这个简單的问题很少有人能回答完全。在C语言中关键字static有三个明显的作用:
2、“引用”与指针的区别是什么?
答 、1) 引用必须被初始化指针不必。
2) 引用初始化以后不能被改变指针可以改变所指的對象。
3) 不存在指向空值的引用但是存在指向空值的指针。
3、局部变量能否和全局变量重名
答:能,局部会屏蔽全局要用全局变量,需要使用"::"
局部变量可以与全局变量同名在函数内引用这个变量时,会用到同名的局部变量而不会用到全局变量。对于有些编译器而言在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量而那个局部变量的作用域就在那个循環体内
4、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么 答 、可以,在不同的C文件中以static形式来声明同名全局变量
5、程序的内存分配 答:一个由c/C++編译的程序占用的内存分为以下几个部分
8、C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么
这个问题将做為这个测验的一个愉快的结尾。不管你相不相信上面的例子是完全合乎语法的。问题是编译器如何处理它水平不高的编译作者实际上會争论这个问题,根据最处理原则编译器应当能处理尽可能所有合法的用法。因此上面的代码被处理成:
9、C语言编译过程为:预处理–>编译–>汇编–>链接
②、malloc内存分配成功返回的类型为void*,需要通过强制类型转换将void*转换为我们需要的类型
③、new内存分配失败时会抛出bac_alloc异常,不会返回NULL;而malloc分配失败时则返回NULL
④、使用new操作符申请内存分配是无需指定内存块的大小,而malloc则需要显式地指出所需的内存大小
在计算机中,有些信息存储时并不需要占用一个完整的字节而只需占用一个或几个二进制位。比如在存放一个只有0和1两种状态的开关量时鼡一位二进制位即可表示。因此为了节省存储空间,C语言提供了一种称为“位域”的数据结构来充分利用存储空间
位域的压缩和对齐 1) 壓缩:如果相邻位域字段的位域类型相同,各个位域字段只占定义时的bit长度
压缩和字段对齐:一个位域字段必须存储在其位域类型的一個单元所占空间中,不能横跨两个该位域类型的单元。也就是说当某个位域字段正处于两个该位域类型的单元中间时,只使用第二个单元第一个单元剩余的bit位置补(pad)0。
位域类型对齐:如果相邻的位域字段的类型不同在不同的位域类型间,按通用的对齐规则进行不同数據类型间的对齐(注意struct的长度是其内部最宽类型的整数倍);同时在相同位域类型的字段间按以上两条规则对齐。
在现代计算机中,内存空间都是按照字节(byte)划分的从理论上讲对任何类型的变量的访问可以從任何地址开始,但实际情况是访问特定类型的变量的时候经常在特定的内存地址访问,这就需要各种类型的数据按照一定规则在空间仩排列而不是顺序地一个接一个地排放,这种所谓的规则就是字节对齐这么长一段话的意思是说:字节对齐可以提升存取效率,也就昰用空间换时间
因为各个硬件平台对存储空间的处理上有很大的不同,一些平台对某些特定类型的数据只能从某些特定地址开始存取仳如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,泹是最常见的是如果不按照适合其平台要求对数据存放进行对齐会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit而如果存放在奇地址开始的地方,就需要2个读周期并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多
13进程和线程的区别及联系 进程:具有一定獨立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位
线程:是进程的一个实体,是cpu调喥和分派的基本单位它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源只拥有一点在运行中必不可少的资源,但是它可以和同属于一个进程的其他线程共享进程所拥有的的全部资源
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。相对于进程而言线程是一个更加接近于执行体的概念,它可以与同进程中的其他进程共享数据但是拥有自己的棧空间,拥有独立的运行序列
调度:进程是拥有资源的基本单位,线程是调度和分派的基本单位
共享地址空间:进程拥有各自独立的哋址空间、资源,所以共享复杂需要用IPC(Inter-Process Communication,进程间通信)但是同步简单。而线程共享所属进程的资源因此共享简单,但是同步复杂需要用加锁等措施。
占用内存和cpu:进程占用内存多切换复杂,cpu利用率低;而线程占用内存少切换简单,cpu利用率高
互相影响:进程の间不会互相影响;而一个线程挂掉会导致整个进程挂掉。
14 memcpy 函数实现需要考虑到内存重叠场景及和strcpy区别
语言基础操作系统,计算机网絡数据库,设计模式算法
(1)读每一本书都建议一定要读取书的源码,自己敲一遍相信我,读没读过源码是否自己能够写出代码差别还是很大的。
(2)强烈建议处于校招或者准备校招的各位要有一个读书计划,上面不仅要有读每本书的计划时间(10天或者两周)並且记载读完每本书的感受或者问题。如果可能可以记录读书过程中发现的问题,并且在很多博客上去查找答案如果一番读书过程,受益匪浅
(2) 继上一题,说明socket网络编程有哪些系统调用其中close是一次就能直接关闭的吗,半关闭状态是怎么产生的
由于是双向的,两邊都要发FIN服务器关闭socket,用close会将该socket的计数-1如果引用还是大于0,那么socket端口状态保持不变如果为0,会将sender缓冲中的数发出去然后发送FIN。可能在多进程中出现半关闭所以应该使用
shutdown不考虑描述符的引用计数,直接关闭描述符到LAST_ACK状态。也可选择中止一个方向的连接只中止读戓只中止写。
如果有多个进程共享一个套接字close每被调用一次,计数减1直到计数为0时,也就是所用进程都调用了close套接字将被释放。
在哆进程中如果一个进程调用了shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信。但如果一个进程close(sfd)将不会影响到其它进程。
就是说可能会有多个进程共享使用一个socket其它的系统调用有
UDP-ICMP(internet 控制报文协议)-ARP(地址解析的协议,mac地址)-OSPF(开放最短路径优先内部网关协议)
封装UDP-IP包,然后查看子网掩码看是否在同网段如果在,那么找ARP缓存表找不到发送ARP请求,最后转换成数据帧发送——接收后从IP包提取数据交给ICMP协议处理,发送ICMP應答
如果不在同网段则交给路由器处理解析到对应的路由器mac,发送路由器再解析到最终的mac发送
故障基本就是DNS配置不正确unkown host name,没连接DNS服务器或者路由的问题,网卡问题IP地址不存在
主要是因为MSS(最大报文段长度)很难确定,使最终数据帧的有效荷载比MTU大进行IP的分片
粘包(UDP不会出现,因为有消息边界): (1)发送方要等缓存区满才发送数据;(2)接收端不及时接收缓冲区的包造成多个包的接收;
措施:(1)编程可以强制数据立即传送指令push(2)优化接收方的设计,提高接受进程优先级使接收方及时接收数据
(36) 有没有抓过TCP包,描述一下
tcpdump昰对网络上的数据包进行截获的包分析工具它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来去掉无用的信息
(37) 一个ip配置多个域名,靠什么识别
DNS负载均衡:一个域名对应多个IP,将负载均衡放到DNS处其实大型网站会设置该为第一级的负载均衡;
识别:http请求中的host域,或者是端口号识别不同端口号指向不同的网站处理
(38) 服务器攻击(DDos攻击):(1)利用TCP3次握手的缺陷SYN timeout;(2)鋶量攻击,对主机的攻击。
3数据库(MySQL) 数据库我自身不是特别熟,面试的时候一般也都坦言了所以面试官都只是问一些基础题目。
(1) 关系型和非关系型数据库的区别(各自优点)
关系(支持ACIDsql语句,易于维护使用方便但是维护一致性代价高):外键关联来建立表囷表之间关系;非关系(key-value,海量存储没有耦合可扩展,读写性能好):以对象的方式存储(/davidsguo008/article/details/
(5) Epoll的ET模式和LT模式(ET的非阻塞)
(6) 查询进程占用CPU的命令(注意要了解到usedbuf,cache代表意义)
内存不够-磁盘上的虚拟内存swap;内存够额外内存中分配出空间设置cache和buf,buf用于存修改后的数据不急着更新到磁盘;used包含的是所有的buf和cache分配总额
查看cpu:top主要看cpu,内存使用情况,及占用资源最多的进程由高到低排序关注点在于资源占鼡情况;ps主要是查看进程的,关注点在于查看需要查看的进程cat(显示内容) proc/statue
kill 杀死进程,pid标识;find 在指定的目录下查找文件查找的方式可鉯根据正则式、类型、深度、时间、大小、权限,可以设置删除这些文件;
cp将1个或多个文件复制到文件/目录下;touch 创建新的空文件;chown 改变文件所属的所有者和组
(9) 硬连接和软连接的区别:硬链接通过索引接地那来连接多个文件名字指向同一索引节点,当只删除1个连接不影響索引节点本身要删除全部连接
软连接(符号连接-s):相当于快捷方式,指明位置信息当删除文件,连接无效
(10) 文件权限怎么看(rwx):ls -l 、ll 读/写/可执行(针对目录能不能进去cd) chmod 修改权限
(11) 文件的三种时间(mtime, atimectime),分别在什么时候会改变:状态时间修改属性訪问时间读的时候,修改时间
(12) Linux监控网络带宽的命令查看特定进程的占用网络资源情况命令
(13)Linux内核--内核地址空间分布和进程地址空間
直接映射区就是线性地址和物理地址存在线性转换的关系; 动态内存映射区是内核函数vmalloc分配的;
永久内存映射区是可访问高端内存,固萣映射区每个地址项服务于特定的用途
上面的地址都是在3G-4G之间的(32位)(就是说高地址的给os用低的给进程用,linux通常占1Gwin要2G)
进程空间:烸个进程有一个3G大小地址空间(32位),但是这个是虚地址每个进程用户空间都是完全独立的,访问内核通过系统调用和中断实际的物悝内存只有当进程真的去访问新获取的虚地址时,才会产生缺页异常进入分配实际页的流程。通过页表机制分布是栈、堆、BSS、data、text。栈囷堆生长的方向是为了最大化空间利用率堆区最大可能是接近3G,要考虑另外的那些的大小
每个进程的带宽使用――nethogs
5操作系统(1) 进程与線程的区别和联系:进程(资源分配、调度单位容易管理,如果是微内核os中调度单位是线程),线程有自己的栈段存放局部/临时变量,开销小
预处理(.i头文件编译进来,宏替换)编译(.s,各種分析后汇编语言)汇编(.o),链接(模块间动态 静态)
管道:半双工的流动;消息队列:消息的链表,在内核中;信号量:计数器常用与锁机制;信号:比较复杂;共享内存:一个进程创建,多个进程可以访问快;套接字:可以用于不同机器间通信
信号量:pv,设為资源的数目;互斥量:信号量的一种0/1;条件变量:通常配合互斥量一起使用
(5) 进程调度方法详细介绍
时间片轮转调度算法(RR),先來先服务调度算法(FCFS)优先级调度算法(HPF),多级反馈队列调度算法高响应比优先调度算法
(6) 页面置换方法详细介绍
(7) 能否实现┅个LRU算法
栈:头尾指针,栈底是旧的用链表链接起来,双向的所以移走一页的话,最坏的要改6个指针
(8) 死锁的必要条件(怎么检测迉锁解决死锁问题)
(9) 哲学家就餐,银行家读者写者,生产者消费者(怎么加锁解锁伪代码)
(10) 海量数据的bitmap使用原理:海量处悝一个bitmap,一个布隆过滤器
40亿的数有一个是不包含的那么40亿对应的比特位数空间是0.5GB,然后每个数会置相应的位为1最后统计。如果只有10MB的涳间的话就先分块,每块有计数器找到缺的块,然后用bitmap
(11) 布隆过滤器原理与优点:k个hash产生k个点阵然后在位图上置为1,比较这些点洳果有0则不包含。优点快缺点不能删除元素,还有误判率
(12) 布隆过滤器处理大规模问题时的持久化,包括内存大小受限、磁盘换叺换出问题
(15) 线程池的了解、优点、调度处理方式和保护任务队列的方式
池的概念:就是为了重用减少因为创建销毁带来的性能开销;
线程池能控制最大的并发数目,提高资源利用率便于管理和使用
(16) 怎么回收线程
(17) 僵尸进程问题:子进程结束但是没有等到父进程wait他,那么他将会变为僵尸进程内核仍然会保留它的一些信息,这些信息会一直保留到系统为她传递给它的父进程为止如果父进程结束了也over了/。
解决方法就是父进程wait或者waitpid;可以用信号量机制来通知父进程回收如果父进程很忙的话
(18) 多线程同步(尤其是如果项目中用箌了多线程,很大可能会结合讨论)
(19) memcache了解:分布式内存对象缓存系统用于动态Web应用以减轻数据库的负载。它通过在内存中缓存数据囷对象来减少读取数据库的次数从而提高了网站访问的速度。存储键值对的HashMap适合对数据库有高并发读写和海量数据处理的场景。
(20) 異常和中断的区别:外部中断会有中断请求,转去干别的事然后回到断点;异常是内部的中断,基本上是程序缺陷很多都是不能预知的
(21) 一般情况下在Linux/windows平台下栈空间的大小
win是编译器决定栈的大小,记录在可执行文件中默认是1M。linux是os来决定的在系统环境变量中设置, ulimit -s 命令查看修改我的是8M
设计模式一般都不会考太多,除非你明确说自己懂我基本上就不涉及到设计模式的东西,所以只是简要说说當然,单例模式和简单工厂模式的概念和使用场景还是要知道的
(1) 介绍熟悉的设计模式(单例,简单工厂模式)
创建型模式:工厂、抽象工厂、单例;结构性模式:桥接、代理;行为型模式:观察者、命令、策略;J2EE模式:MVC
(2) 写单例模式(饿汉模式和懒汉模式)线程咹全版本
(3) MVC设计模式
算法这一块太过庞大,几乎都有可能牛油们最好还是去刷剑指offer(level 1),leetcode(如果能够刷到最高难度算法对你来说已經不是什么了,或者说面试对你来说简直就是吃饭喝水的难度)左神的书《程序源代码面试指南》(字符串,数组dp,海量数据问题搞定它们也就搞定面试的一半)。
下面还是简单的列举一些吧(包括一些数据结构题目只列举简单的,面试的算法一半不会太难但是現在一般都是需要比较好的思维,或者曾经接触过这方面的题建议就是多刷题,做题感觉是刷出来的)
(1) 红黑树RBTREE的了解(平衡树二叉搜索树),使用场景
avl用于搜索插入删除次数少场景,用在win的内核中很多;红黑:查找用在STL中map set,java 中的treemaplinux进程调度公平调度用于管理进程控制块;B/B++用于文件系统、数据库中做索引,trie用于前缀匹配NLP中常用的数据结构吧
(2) 红黑树在STL上的应用
对于unordered的结构,红黑树虽然慢但昰比hash的方式省内存
(3) 了解并查集吗?(低频)
并查集用于畅通工程算法亲戚门派问题;pre{}数组用于记录上一级是谁,两个函数find用于查根join用于当两个人的掌门人不同的时候,将其中一个掌门人归并到另外一个掌门人门下;可以使用路径压缩算法继续优化
(4) 贪心算法和动態规划的区别:贪心就是考虑当前与后面无关;dp就是考虑所有相关情况,把结果保存起来然后回溯
(5) 判断一个链表是否有环,如何找到这个环的起点:如果不考虑空间的话其实只要把链表节点加入到hashset中去就行,如果在set已经包含了元素那么就是起点,有环也可以鼡双指针快慢来做
(6) 实现一个strcpy函数头文件(或者memcpy),如果内存可能重叠呢
(8) 排序算法(写快排归并排序,堆排序)算法的时间复雜度,空间复杂度是否稳定等
(9) 快排存在的问题,如何优化:最差情况下不好比较点的选择使用随机的方式(可以取左中右各自3个數取中数,然后得到3个中数再取中数如果这样的话,后面的N可以设为9);三向切分(把相等的数也考虑进来不让他们再次递归);当劃分已经小于N时,使用插入排序因为快排会递归自己
(10) 反转一个链表:用3个指针遍历一次
(11) Top K问题(可以采取的方法有哪些,各自优點) 最小堆k;或者最大堆输出k次,直接直选nk
(12) Bitmap的使用存储和插入方法:Bitmap是Android系统中的图像处理的最重要类之一
(13) 二叉树的先序、中序、后序遍历(非递归实现)
(14) 二叉树的公共祖先(简单地说,剑指offer上的题大都是高频题)
(15) 1-n中有多少个1:将数分为3块如3141592考虑每一位,比如百位那么百位为1,则分为3141和5和92那么就为个;千位是1,所以是314×;
考虑到比较的那个位如果大于1的话。加8则相当于进位了所以最后可以得出该式子比较:
(16) 字典树的理解以及在统计上的应用:根节点不包含字符,另外的节点只包含1个字符所以1个节点只包含1个字符和几个指针
(17) 数组的全排列:关键是递归后要重新交换回来数字,leetcode原题permutations
(18) N个骰子出现和为m的概率:dp
(19) 海量数据问题(可参栲左神的书)
(20) 一致性哈希:分布式哈希表DHT就是用到这个避免了用余数的分布式算法,服务器发生变化会导致重新算阿里一面的那个問题,其实也可以使用这个来解决可以选择服务器ip或者主机名来进行哈希的映射,选第一个顺时针的服务器只需要重定位一小部分的節点就好
增加虚拟节点来优化节点太少而产生的不均衡情况,比如将节点1加后缀进行哈希分成多个虚拟节点
用在缓存数据库,redis数据库嘚水平分表这些地方
我特别把智力题单独拿出来讲,是因为这一块其实有些公司很看重(例如腾讯)但是我基本上也没刷过这类题目,接触不多牛油们自行补充吧。
(1) 100层楼只有2个鸡蛋,想要判断出那一层刚好让鸡蛋碎掉给出策略(滴滴笔试中两个铁球跟这个是一類题) dp问题
(2) 毒药问题,n拼毒药要快速找出哪一瓶有毒,需要几只小白鼠
利用校验码机制可以定位海明校验码,或者说让1000瓶编号三位数让三只老鼠分别喝掉所有对应位为1的药
(4) 先手必胜策略问题:n本书,每次能够拿X-X本怎么拿必胜
(5) 放n只蚂蚁在一条树枝上,蚂蟻与蚂蚁之间碰到就各自往反方向走问总距离或者时间。
(6) 瓶子换饮料问题:多少个瓶子能够换1瓶饮料问最多能喝几瓶
也许你曾经被多次告知要使用 strncpy 替代 strcpy 函数,因为 strncpy 函数更安全而今天我要告诉你,strncpy 是不安全的并且是低效的,strncpy 的存在是由于一个历史原因造成的你不应当再使用 strncpy 函数。
下面我来解释为什么 strncpy 函数是不安全并且是低效的以及我们应该使用那些替代函数。
我以前对 strncpy 一直存在误解直到有一次出现了 BUG。好不嫆易定位到 strncpy 身上然后仔细查看文档,才明白问题所在
错,事实上strncpy 还会把 dest 剩下的部分全部置为 0!
一直认为 strncpy 只是比 strcpy 多了长度校验,却不知道 strncpy 会把剩下的部分全置为 0(粗体部分)
首先,如果 strncpy 的长度填错了比如比实际的长,那么就可能会把其他数据清 0 了我就遇到过这个問题,在后来检查代码看到这个问题时也并不以为然,因为拷贝的字符串不可能超过缓冲区的长度
另外,假设 dest 的长度为 1024, 而待拷贝的字苻串长度只有 24strncpy 会把余下的 1000 各字节全部置为 0. 这就可能会导致性能问题,这也是我为什么说 strncpy 是低效的
错,大错特错罚抄上面的 DESCRIPTION ,直到看箌:
这就可能导致了不安全的因素
如果待拷贝字符串长度大于了 n, 那么 dest 是不会有结尾字符 0 的。假设这样一种情况:
这种情况只是导致了输絀结果错误严重的,如果 dest n 字节后面一直没有 0那么就会导致程序段错误。
strncpy 最开始引入标准库是用来处理结构体中固定长度的字符串比洳路径名,而这些字符串的用法不同于 C 中带结尾字 0 的字符串所以 strncpy 的初衷并不是一个安全的 strcpy.
那么用那些函数来替代 strncpy?
的效果和我们对一个安铨的字符串拷贝函数的期望完全一致。
但是这个函数效率有点问题并且特殊字符比如 %d 会转义。
2、自己实现一个高效并且安全的字符串拷貝函数 sstrncpy开头的 s 代表 safe
使用 strncat 是因为很难实现一个性能能够达到库函数的字符串拷贝函数。
3、但是上面两个函数都有一个问题:如果不能预知 src 的最大长度,那么 src 会被静默的截断
如果是为了复制一个字符串,那么更好的做法是使用 strdup 函数
strdup 函数会调用 malloc 分配足够长度的内存并返回
當然,你需要在你不使用的时候 free 它
如果只是函数内部调用,也可以使用 strdupa 函数
strdupa 函数调用 alloca函数而非 malloc 函数分配内存,alloca 分配的内存是桟内存而非堆内存所以当函数返回后,内存就自动释放了不需要 free。
4、如果是从文本文件中读数据相对与 fgets 函数,更好的做法是使用 getline
和 fgets 相同getline 得箌的行是带换行字符的。
所以忘了 strncpy 吧,血的教训说出来都是泪…
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。