复试专业课知识记录(3)

2020.3.24学习记录

1.堆栈和堆的区别
 首先,讨论的堆和栈指的是内存中的“堆区”和“栈区”。C语言的内存模型分为5个区:栈区、堆区、静态区、常量区、代码区。每个区存储的内容如下:

 1、栈区:存放函数的参数值、局部变量等,由编译器自动分配和释放,通常在函数执行完后就释放了,其操作方式类似于数据结构中的栈。栈内存分配运算内置于CPU的指令集,效率很高,但是分配的内存量有限,比如iOS中栈区的大小是2M。注意:其实堆栈本身就是栈,只是换了个抽象的名字。栈由操作系统自动分配释放,存放函数的参数值,局部变量的值等。

 2、堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放工作,需要用程序区释放。分配方式类似于数据结构中的链表。在iOS开发中所说的“内存泄漏”说的就是堆区的内存。 堆一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。

 3、静态区:全局变量和静态变量(在iOS中就是用static修饰的局部变量或者是全局全局变量)的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后,由系统释放。

 4、常量区:常量存储在这里,不允许修改。

 5、代码区:存放函数体的二进制代码。
 补充:
1.

2.

2.递归变成非递归需要什么?

 需要变的原因:函数调用时,需要在栈中分配新的帧,将返回地址,调用参数和局部变量入栈。所以递归调用越深,占用的栈空间越多。如果层数过深,肯定会导致栈溢出,这也是消除递归的必要性之一。

 第一种情况:通过分析,跳过分解过程,直接用循环结构的算法实现求解过程。

 第二种情况:借助堆栈将递归转化为非递归,自己用栈模拟系统的运行时栈,通过分析只保存必须保存的信息,从而用非递归算法替代递归算法

 补充:能用递归解决的问题,必须满足以下两个条件:一个问题能够分解成规模更小,且与原问题有着相同解的问题;存在一个能让递归调用退出的简单出口。

3.什么是分治法、贪心算法和动态规划法?

 分治法(divide-and-conquer):将原问题划分成n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。

 分治模式在每一层递归上都有三个步骤:

 分解(Divide):将原问题分解成一系列子问题;
 解决(conquer):递归地解各个子问题。若子问题足够小,则直接求解;
 合并(Combine):将子问题的结果合并成原问题的解。

 合并排序(merge sort)是一个典型分治法的例子。其对应的直观的操作如下:

 分解:将n个元素分成各含n/2个元素的子序列;
 解决:用合并排序法对两个子序列递归地排序;
 合并:合并两个已排序的子序列以得到排序结果。

 另:在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想。

 贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。背包问题是最典型的可以用贪心算法解决的问题

 动态规划算法和分治法相似的地方是它也是将待求解问题分成若干子问题,然后从这些子问题的解得到原问题的解。但与分治法不同的是,适合动态规划法解的题,经分解得到的子问题往往不是相互独立的若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。

4.堆栈溢出是怎么回事儿?
 堆栈溢出(英语:stack overflow)在计算机科学中是指使用过多的存储器时导致调用堆栈产生的溢出。堆栈溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生。

5.迪杰斯特拉算法
 迪杰斯特拉算法的原始版本仅适用于找到两个顶点之间的最短路径,后来更常见的变体固定了一个顶点作为源节点然后找到该顶点到图中所有其它节点的最短路径,产生一个最短路径树。

算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。


 另:
 迪杰斯特拉算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索。
 把迪杰斯特拉算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于BFS搜索。

6.什么是树?什么是图?树和图有什么区别?
 树:

 图:

 区别:线性表中数据元素仅有线性关系,树则具有明显的层次性,而图的复杂性要远远超过树.树是图的子集,数有一个根节点,图没有,数可以递归遍历,图要看情况,数有层次划分,图没有,树的非根节点必定有一个父节点,图不一定。

7.数据库查询语句怎样写效率更高
 两个方法:创建合理的索引;书写高效的SQL语句
 创建合理的索引:请阅读: 数据库索引到底是什么,是怎样工作的?
 书写高效的SQL语句:1.查询列的优化:用到表中的那个列就select谁,不要select * ,除非你每个列都使用,因为select * 和select 所有列是一样的
           2.where查询条件的优化:原则,多数数据库都是从左到右的顺序处理条件,把能过滤更多数据的条件放在前面,过滤少的条件放后面。减少计算量和内存需求,提高响应速度。
           
8.数据库完整性措施(???)
 数据完整性是指数据库中数据在逻辑上的一致性、正确性、有效性和相容性
 详细阅读:数据完整性

9.关系数据库、非关系型数据库的定义,二者的区别
 参考博客:什么是数据库?什么是关系数据库?什么是非关系型数据库?

10.白盒测试与黑盒测试定义是什么,区别是什么?
 白盒测试:白盒测试也称为结构测试或逻辑驱动测试,是针对被测单元内部是如何进行工作的测试。它根据程序的控制结构设计测试用例,主要用于软件或程序验证。白盒测试检查程序内部逻辑结构,对所有的逻辑路径进行测试,是一种穷举路径的测试方法,但即使每条路径都测试过了,但仍然有可能存在错误。因为:穷举路径测试无法检查出程序本身是否违反了设计规范,即程序是否是一个错误的程序;穷举路径测试不可能检查出程序因为遗漏路径而出错;穷举路径测试发现不了一些与数据相关的错误。

 白盒测试方法有:静态测试&动态测试、单元测试、代码检查、同行评审、技术评审

 白盒测试需要遵循的原则有: 1. 保证一个模块中的所有独立路径至少被测试一次;2. 所有逻辑值均需要测试真(true)和假(false)两种情况;3. 检查程序的内部数据结构,保证其结构的有效性;4. 在上下边界及可操作范围内运行所有循环。

 黑盒测试:黑盒测试又称为功能测试、数据驱动测试或基于规格说明书的测试,是一种从用户观点出发的测试。测试人员一般把被测程序当作一个黑盒子,我们看不到它里面做了些什么事情,只能通过输入输出看是否能得到我们所需的来测试。

 黑盒测试主要测到的错误类型有:不正确或遗漏的功能;接口、界面错误;性能错误;数据结构或外部数据访问错误;初始化或终止条件错误等等。 
11.什么是事务处理?
 可以把一系列要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不执行(很经典的一个例子是:A要给B转钱,首先A的钱减少了,但是突然的数据库断电了,导致无法给B加钱,然后由于丢失数据,B不承认收到A的钱;在这里事务就是确保加钱和减钱两个都完全执行或完全不执行,如果加钱失败,那么不会发生减钱)。事务管理的意义在于:保证数据操作的完整性。
 参考博客:mysql之事务管理

12.冯诺依曼系统结构
 冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相同,数学家冯·诺依曼提出了计算机制造的三个基本原则,即采用二进制逻辑、程序存储执行以及计算机由五个部分组成(运算器、控制器、存储器、输入设备、输出设备),这套理论被称为冯·诺依曼体系结构。
参考博客:冯·诺依曼体系结构总结

13.冯诺依曼机的存储思想
 存储程序原理是冯·诺依曼于1946年提出的将程序像数据一样存储到计算机内部存储器中的一种设计原理。存储程序原理就是将我们为解决特定问题而编写的程序存放在计算机存储器中,然后按存储器存储程序的首地址执行程序的第一条指令。以后就按照该程序的规定顺序执行其他指令,直至程序结束执行。

14.什么是C++静态/动态联编技术,为什么C++要引入静态/动态联编
 通常来说联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。
参考博客:C++的静态联编和动态联编详解
15.什么是虚函数?为什么要引入虚函数
 虚函数主要是用来实现多态和多重继承的,多态就是一个指针指向子类对象,那么他调用的函数就是子类的对象的。
 参考博客:c++虚函数的作用是什么?

16.Andriod和ios各用什么语言写app
 安卓官方推荐的Java、Kotlin、C/C++
 iOS官方推荐Objective-C、Swift、C/C++

17.java一次编译多处运行的原理
 JAVA是一种编译型-解释型语言,当执行java文件时,编译器首先会将.java类型的源文件编译成.class类型的字节码文件。之后jvm虚拟机再运行编译好的字节码文件时,将字节码文件解释成具体平台上的机器指令。java的跨平台特性与jvm虚拟机的存在密不可分,jvm虚拟机可以使java语言在不同的环境中运行。比如Windows平台和Linux平台都有相应的JDK,安装好jdk后也就有了JAVA语言的运行环境。其实JAVA语言本身与其他编程语言没有特别大的差异,并不是说java语言可以跨平台,而是在不同的平台安装不同版本的jdk,都能有让java语言有可以运行的环境。
 参考博客:对java的理解一:一次编译,到处运行

18.什么是重载,如何实现重载?
 参考博客:什么是重载?什么时候重载?重载有什么好处?
      什么是重载?重载的作用?
19.什么是可信操作系统?
 可信操作系统是能够通过支持多种安全政策来适应环境变化,并保证在系统中的本地用户或远程实体的行为总是以预期的方式和意图发生的。客体内容是真实、保密和完整的,以及自身完整性的操作系统。

20.词法分析和语法分析是什么,以及怎么实现的?
 词法分析是编译程序进行编译时第一个要进行的任务,主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对构成源程序的字符流进行扫描然后根据构词规则识别单词,这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。以便为下面的语法分析和语义分析做准备。可以说词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);

 语法分析(Syntax analysis或Parsing)
  语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.

 语义分析(Syntax analysis)
  语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.例如一个C程序片断:
  int arr[2],b;
  b = arr * 10;
  源程序的结构是正确的.
  语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.
 词法分析器的实现:
 参考博客:编译原理——词法分析器实现
 语法分析器的实现:
 参考博客:编译器----语法分析

21.图的定义

22.自然数的定义

23.如何比较集合的大小



posted @ 2020-03-24 21:21  大大大大大圣归来  阅读(318)  评论(0编辑  收藏  举报