操作系统
-
操作系统的特点?
– 共享:资源可被多个并发执行的进程使用
– 并发:可以在同一时间间隔处理多个进程,需要硬件支持
– 虚拟:将物理实体映射成为多个虚拟设备
– 异步:进程执行走走停停,每次进程执行速度可能不同,但OS需保证进程每次执行结果相同 -
进程的三个组成部分?
程序段、数据段、PCB(Process Control Block) -
并发与并行区别?
并发:同一间隔 并行:同一时刻 -
进程切换的过程?
保持处理机上下文 -> 更新PCB -> 把PCB移入相应队列(就绪、阻塞) -> 选择另一个进程并更新其PCB -> 更新内存管理的数据结构 -> 恢复处理机上下文 -
进程通信
1、低级通信方式
PV操作(信号量机制)。
– P:wait(S)原语,申请S资源
– V:signal(S)原语,释放S资源
2、高级通信方式:以较高效率传输大量数据的通信方式
– 共享存储(使用同步互斥工具操作共享空间)
– 消息传递(进程间以格式化的消息进行数据交换,有中间实体,分为直接和间接两种,底层通过发送消息和接收消息两个原语实现)
– 管道通信(两个进程中间存在一个特殊的管道文件,进程的输入输出都通过管道,半双工通信) -
管程是什么?
由一组数据及对这组数据操作的定义组成的模块。同一时间只能有一个进程使用管程,即管程是互斥使用的,进程释放管程后需唤醒申请管程资源的等待队列上的进程。进程只有通过进入管程并使用管程内部的操作才能访问其中数据。 -
死锁的必要条件?
– 互斥条件:资源在某一时刻只能被一个进程占有
– 不剥夺条件:进程所持有的资源在主动释放前不能被其他进程强行夺走
– 请求和占用条件:死锁进程必然是既持有资源又在申请资源的
– 循环等待条件:存在等待链,互相申请,互不释放 -
死锁与饥饿的区别?
– 都是资源分配问题
– 死锁是等待永远不会释放的资源,而饥饿申请的资源会被释放,只是永远不会分配给自己
– 一旦产生死锁,则死锁进程必然是多个,而饥饿进程可以只有一个
– 饥饿的进程可能处于就绪状态,而死锁进程一定是阻塞进程 -
进程和线程的区别?
线程被称作轻量级进程,在进程中包含线程。进程有独立的内存空间,不同进程间不能直接共享其他进程资源,而同一个进程内的线程共享进程内存空间;相比进程,线程切换对系统开销更小一些;进程是资源分配的最小单位,线程是程序执行的最小单位。 -
FCB包含什么?
文件指针:上次读写位置。
文件打开数:多少个进程打开了此文件。
文件磁盘位置。
文件的访问权限:创建、只读、读写等。 -
页面置换算法?
最佳置换算法OPT
先进先出置换算法FIFO
最近最久未使用算法LRU
时钟算法LOCK
改进型时钟算法 -
批处理作业调度算法?
先来先服务FCFS
最短作业优先SJF
最高响应比优先HRN
多级队列调度算法 -
进程调度算法?
先进先出FIFO
时间片轮转算法RR
最高优先级算法HPF
多级队列反馈算法 -
磁盘调度算法?
先来先服务FCFS
最短寻道时间优先SSTF
扫描算法SCAN
循环扫描算法C-SCAN -
FAT(File Allocation Table)?
分配给文件的所有盘块号都放在FAT中,记录了文件的物理位置。 -
中断和系统调用区别?
中断:解决处理器速度和硬件速度不匹配,是多道程序设计的必要条件。每个中断都有自己的数字标识,当中断发生时,指令计数器PC和处理机状态字PSW中的内容自动压入处理器堆栈,同时新的PC和PSW的中断向量也装入各自的寄存器中。这时,PC中包含的是该中断的中断处理程序的入口地址,它控制程序转向相应的处理,当中断处理程序执行完毕,该程序的最后一条iret(中断返回),它控制着恢复调用程序的环境。 中断和系统调用的区别: 中断是由外设产生, 无意的, 被动的 系统调用是由应用程序请求操作系统提供服务产生, 有意的, 主动的。要从用户态通过中断进入内核态。(联系) 中断过程:中断请求 中断响应 断点保护 执行中断服务程序 断点恢复 中断返回 系统调用过程:应用程序在用户态执行时请求系统调用,中断,从用户态进入内核态,在内核态执行相应的内核代码。
Java
-
名词解释
-
JVM
-
如何判断当前系统内是否存在死锁?
可以打印当前的内存快照,可以看到快照中有deadLock对象,所在的方法,请求被锁的资源,从而进一步分析死锁原因。 -
ThreadLocal
C++
- 指针和引用的区别?
- 指针是一个存储地址的变量,该地址为内存的一个存储单元;引用是原变量的一个别名;
- 指针可以为空,而引用不能为空;
- 指针可以有多级,而引用只能有一级;
- 指针可以重新赋值,而引用只能初始化一次
- sizeof引用得到的是变量大小,而sizeof指针得到的是指针本身大小
-
将引用作为函数返回值的好处是?
在内存中不会产生被返回值的副本,同时不能返回局部变量的引用,因为随着调用结束局部变量会被销毁。 -
三种传参方式?
- 值传递
传递的是实参的一个拷贝,修改形参不会改变实参值。 - 地址传递
传递的是实参地址的一个拷贝,修改形参会导致改变实参值。 - 引用传递
传递的是实参的一个别名,修改形参会导致改变实参。
被调用函数的形参只有在被调用时才会临时分配存储单元,一旦调用结束则释放内存。
-
const作用?
被const修饰符修饰的变量不能被修改。const *x表明x数据是常量,不能修改;*const x表明指针本身是常量,x的指针不能指向其他内存地址,x本身可被修改;*const *x表明x本身数据和地址都不能被修改。 -
static作用?
被static修饰符修饰的变量在整个文件中都是可见的,而在文件外是不可见的。该变量在全局数据区分配内存。C++中由程序运行new出的动态数据存放在堆区,而函数内部局部变量存放在栈区。
静态局部变量:在函数内部定义static变量,第一次运行到这里初始化,存储到全局数据区,下一次执行到这里不会再重新初始化。
static变量如果没有显式初始化,默认初始值为0。
静态函数不能被其他函数所调用。 -
面向对象的三个要素(基本特征)?
1、封装:将客观事物封装成类,隐藏实现细节,模块化代码。
2、多态:实现多态的两种方式——覆盖(重写)和重载。
覆盖是子类重新定义父类的虚函数,与多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。
重载是存在多个同名函数,但是函数的参数个数不同。这些函数实际上成为了不同的函数,对它们的调用在编译期间就已经确定,属于早绑定,与多态无关。
3、继承:子类继承父类功能,对父类功能进行扩展。 -
结构体和联合有什么区别?
(1). 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。
(2). 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。 -
C++是不是类型安全的语言?
不是。不同类型间指针可以强制互转。 -
const与#define区别?
const修饰常量受到强制保护,程序更健壮,而且const修饰的常量有数据类型,有类型安全检查。 -
基类的析构函数为什么是虚函数?
为了防止派生类析构函数未执行,造成资源泄露。 -
#include尖括号和双引号区别?
<>是标准头文件,“”是非系统头文件 -
为什么有了指针,还要使用引用?
为了支持运算符的重载。更加方便。 -
如何避免野指针?
声明指针记得初始化,暂时不用就指向NULL;使用malloc分配内存,必须经过显式释放(free),避免内存泄漏。
NoSQL
Redis
-
redis分布式锁?
setnx(set if not exist)和expire、delete联合实现(假设各个客户端时钟大致相同,误差处于可接受范围)释放锁的操作用lua脚本实现来保证原子性。在集群环境下分布式锁的key值应当是随机的不可重复的,否则如果一个客户端获得了锁,但发生了阻塞,当锁过期redis自动释放了资源,这时第二个客户端获得了锁,客户端1此时从阻塞中恢复释放了锁,就会造成混乱。 -
为什么Redis是单线程的
单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程(epoll模型)。
因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。 -
Redis为什么这么快
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4、使用多路I/O复用模型,非阻塞IO;
5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
(1)多路 I/O 复用模型
多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。
- 缓存雪崩、缓存穿透、缓存热点?
计算机网络
-
OSI模型全称?
Opening System Interconnection - Reference Model -
OSI模型与TCP模型的区别?
Key Differences between TCP/IP and OSI Model
TCP/IP is a client-server model, i.e. when the client requests for service it is provided by the server. Whereas, OSI is a conceptual model.
TCP/IP is a standard protocol used for every network including the Internet, whereas, OSI is not a protocol but a reference model used for understanding and designing the system architecture.
TCP/IP is a four layered model, whereas, OSI has seven layers.
TCP/IP follows Vertical approach. On the other hand, OSI Model supports Horizontal approach.
TCP/IP is Tangible, whereas, OSI is not.
TCP/IP follows top to bottom approach, whereas, OSI Model follows a bottom-up approach. -
TCP和UDP的区别?
TCP可靠,UDP不可靠。TCP只支持点对点服务,UDP可以一对一、一对多、多对一和多对多。
TCP面向连接,UDP无连接。UDP有较好的实时性,工作效率比TCP高。
TCP对系统资源要求多,UDP则无。 -
DNS工作过程?
应用层协议,使用UDP。分为迭代查询和递归查询。采用分布式集群的工作方式,防止单点故障,增加通信容量。
迭代:主机访问本地域名服务器,若缓存没有IP则本地域名服务器进一步向其他根域名服务器查询。
递归:主机分别向多个服务器发出查询请求。 -
UDP的优点?
发送前无需连接,减少了开销和时延,首部开销小,无拥塞控制,方便实时应用,不保证可靠交付,无需维持连接状态表。UDP的可靠性要通过应用层来控制。 -
数据链路层成帧方式?
字符填充法、字符计数法、比特填充法、违规编码法。 -
RIP和OSPF?
RIP(Routing Information Protocol)在应用层,最大站点数为15
OSPF(Open Shortest Path First)网络层,洪泛法,迪杰斯特拉算法
软件工程
-
类之间的关系有哪些?
继承:类继承另一个类的功能
实现:类实现接口的功能
依赖:A类的某个方法使用到了B类
关联:强依赖关系,B类作为一个属性出现在了A类
聚合:一种特别的关联,公司与个人的关系
组合:强聚合关系,整体与部分的联系更紧密,如汽车与轮胎 -
软件工程标准步骤?
- 问题定义
- 可行性研究
- 需求分析
- 总体设计
- 详细设计
- 编码和单元测试
- 综合测试
- 软件维护
-
有哪些软件测试分类?
黑盒测试:不考虑软件内部原理,以用户角度测试软件输入输出
白盒测试:知道软件内部工作过程,确定每个分支都能按照预定正常工作
灰盒测试:集合白盒黑盒
冒烟测试:测试软件基本功能,快速
系统测试:验证系统是否满足需求规格的黑盒类测试
性能测试:负载测试和压力测试
安全测试:假扮黑客侵入系统
兼容性测试:不同平台不同环境下的测试 -
自顶向下和自底向上测试方法的区别?
自顶向下:从程序入口主控模块开始,按照系统程序结构,沿着控制层次从上而下测试各模块。方便把握整体结构,早期可发现顶层错误。
自底向上:从最底层模块,即叶子结点开始,按照调用从下而上的测试各模块。最后一个模块提交后才能完整系统测试,某些模块可以提前测试。 -
软件工程的三要素?
方法、工具、过程。 -
软件工程的主要模型?
1、瀑布模型:前一阶段工作结束才可以进行下一阶段工作。基于文档,易于维护,但加大了工作量。
2、快速原型:快速建立可以运行的程序,完成的功能是最终软件的一个子集。不带反馈环,满足用户真实需求,但会导致系统设计差,难以维护。
3、增量模型:每个阶段不交付完整产品,软件由一系列增量构件组成。降低开发风险,易于维护,但不容易控制整体过程
4、螺旋模型:结合快速原型和瀑布模型,有利于软件重用,减少风险,风险人员需要一定经验。
5、喷泉模型:迭代,无缝,节省开发时间。
6、敏捷
-
什么是死代码?
永远不会被执行到的代码。 -
内聚和耦合
内聚:指一个好的内聚模块内应当尽量只做一件事,描述的是模块内的功能联系。
耦合:各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度。
(1)内聚类型低→高:功能内聚、信息内聚、通信内聚、过程内聚、时间内聚、逻辑内聚、偶然内聚
(2)耦合类型高→低:内容耦合、公共耦合、外部耦合、控制耦合、标记耦合、数据耦合、非直接耦合
数据结构与算法
-
两个栈模仿一个队列?
进队:入A栈。
出队:若B栈不为空,则B栈全部出栈;否则将A栈中数据全部入B栈,再依次出B栈。 -
两个队列模仿一个栈?
入栈:入A队
出栈:将A队除队尾元素全部转移到B队,出A队,算法思想就是两个队列倒来倒去,只留一个元素时出栈。 -
如何判断链表是否有环?
设置快慢指针,快指针每次前进两步,当两指针重合则有环,快指针为null则无环。 -
如何判断有环链表环的入口?
1、将遍历过的结点都入set,如果当前结点在set里有,则此结点即为入口。
2、快慢指针重合后,重置fast指针,此时fast每次走一步,再次重合结点即为入口。 -
最长公共子序列求解(LCS)?
DP。由最长公共子序列问题的最优子结构性质可知,要找出X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的一个最长公共子序列。
最长公共子串:
-
链表能否使用二分查找?
可以。先将链表排序,将各个结点的值记入数组,再二分查找。 -
给定一颗二叉树的头结点,和这颗二叉树中2个节点n1和n2,求这两个节点的最近公共祖先
后序遍历方法
public class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null || root == p || root == q) return root;TreeNode left = lowestCommonAncestor(root.left, p, q);TreeNode right = lowestCommonAncestor(root.right, p, q);if(left != null && right != null) return root;return left != null ? left : right;}
}
-
栈应用括号匹配?
左括号入栈,右括号出栈进行匹配,栈空仍未匹配到则失败。 -
汉诺塔问题?
void Hanoi(char src, char des, char via, int n) {Hanoi(src, via, des, n - 1); Move(src, des, n); //把第n个盘子直接从src移动到des Hanoi(via,des, src, n - 1);
}
-
二叉树删除节点?
被删除的节点是叶子节点,这时候只要把这个节点删除,再把指向这个节点的父节点指针置为空就行。
被删除的节点有左子树,或者有右子树,而且只有其中一个,那么只要把当前删除节点的父节点指向被删除节点的左子树或者右子树就行。
被删除的节点既有左子树而且又有右子树,这时候需要把左子树的最右边的节点或者右子树最左边的节点提到被删除节点的位置。 -
哈希表最好最坏情况下复杂度?
O(1)和O(n),n为表长。 -
求二叉树的直径?
两次DFS,第一次找出距离root最远点,第二次以第一次结果为起点找出第二个点,这两点的距离即为直径。
设计模式
- 创建型模式:抽象的实例化过程,隐藏了对象创建的具体细节,使程序代码不依赖具体的对象。
例:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。 - 结构型模式:描述类和对象之间通过组织形成新的结构,以实现新的功能。
例:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 - 行为型模式:描述算法以及对象之间的任务(职责)分配及它们之间的通讯模式。
例:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
数据库
-
数据库的ACID?
原子性Atomicity:一个事务被视为一个最小单元,要么全部提交,要么全部回滚
一致性Consistency:事务总是由一种状态转换为另一种状态,数据库事务只会是执行前的状态或是执行后的状态,不会出现执行中的状态。即如果一个事务执行了十秒,那么第一秒读到的结果和第九秒得到的应该是相同的。
隔离性Isolation:一个事务的执行不会被另一个事务影响,互不干扰。
持久性Durability:事务只要提交了,那么数据库中的数据也永久的发生了变化。 -
数据库三范式?
1NF(Normal Form):R的所有属性都不能再分解为更基本的数据单位。
2NF:R的所有非主属性都依赖于R的关键属性,所有列都依赖于任意一组候选关键字。
3NF:每一列都与任意候选关键字直接相关而不是间接相关,没有传递依赖。
BCNF:3NF基础上,关系R只有一个单属性,或R的子集都是单属性,则R满足BCNF。 -
插入100个数据和100万个数据有何区别?
100数量级小,可以随意插入;100万数量级大,如果表里有索引,则索引更新代价很高,可以采取先删除索引再插入,插入完成后再建索引的策略。 -
数据库数据可以无限插入吗?
可以。大小受到主机内存的制约。数据量大时要先删索引。减少提交次数,即减少IO次数。 -
处理大数据量的策略?
表分区,备份,入带库。 -
group by having,having和where的区别?
WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。
GROUP BY 子句用来分组 WHERE 子句的输出。
HAVING 子句用来从分组的结果中筛选行。
在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)。 -
简述数据库以及线程死锁产生的原理及必要条件,简述如何避免死锁?
其他
-
线性代数中特征值和特征向量的意义?
从定义出发,Ax=cx:A为矩阵,c为特征值,x为特征向量。矩阵A乘以x表示,对向量x进行一次转换(旋转或拉伸)(是一种线性转换),而该转换的效果为常数c乘以向量x(即只进行拉伸)。我们通常求特征值和特征向量即为求出该矩阵能使哪些向量(当然是特征向量)只发生拉伸,使其发生拉伸的程度如何(特征值大小)。这样做的意义在于,看清一个矩阵在那些方面能产生最大的效果(power),并根据所产生的每个特征向量(一般研究特征值最大的那几个)进行分类讨论与研究。 -
云计算?
云计算是一种按使用量付费的模式,这种模式提供可用的、便捷的、按需的网络访问, 进入可配置的计算资源共享池,这些资源能够被快速提供,只需投入很少的管理工作,或与服务供应商进行很少的交互。 -
大数据的特点?
1.Volume:数据量巨大
体量大是大数据区分于传统数据最显著的特征。一般关系型数据库处理的数据量在TB级,大数据所处理的数据量通常在PB级以上。
2.Variety:数据类型多
大数据所处理的计算机数据类型早已不是单一的文本形式或者结构化数据库中的表,它包括订单、日志、BLOG、微博、音频、视频等各种复杂结构的数据。
3.Velocity:数据流动快
速度是大数据区分于传统数据的重要特征。在海量数据面前,需要实时分析获取需要的信息,处理数据的效率就是组织的生命。
4.Value:数据潜在价值大
在研究和技术开发领域,上述三个特征已经足够表征大数据的特点。但在商业应用领域,第四个特征就显得非常关键!投入如此巨大的研究和技术开发的努力,就是因为大家
都洞察到了大数据的潜在巨大价值。如何通过强大的机器学习和高级分析更迅速地完成数据的价值“提纯”,挖掘出大数据的潜在价值,这是目前大数据应用背景下苛待解决的难题。 -
大数据发展的瓶颈?
没有成熟的方法采集和处理大数据。
数据涉及到隐私,法律法规还没有完善。
大量不同类别的数据不知道怎么存储。
数据的独占性:有价值的数据别人不一定会分享。 -
KNN算法的优缺点?
-
windows中程序的启动过程?
-
数据挖掘的信息熵?
-
决策树?
-
请列举面向对象设计的三个基本要素及五种主要设计原则?
-
BIOS启动过程及linux内一个程序
欢迎在我的其他文章里查看计算机各学科思维导图。