类型:10道单选,5道多选,3道简答
单选:涉及数据结构
(1)哈希表:已知一个线性表(38,25,74,63,52,48),采用的散列函数为H(Key)=Key mod 7,将元素散列到表长为7的哈希表中存储。若采用线性探测的开放定址法解决冲突,则在该散列表上进行等概率成功查找的平均查找长度为 (2)。
还有一个拉链法:将冲突位置的元素,以单链表的形式,存储在index相应位置的后面。
(2)广度优先遍历和深度优先遍历
广度优先遍历效率高,深度优先遍历内存小。
广度优先遍历需要使用队列来存储大量的节点,因为相对于深度优先遍历来讲,其内存空间高。
深度优先遍历在深度很大的情况下效率不高,因为它是先深入到最后一层,然后再向上返回的。
广度优先遍历和深度优先遍历的时间复杂度:O(V+E) V定点 E边 时间复杂度相同
广度遍历的空间复杂度:O(V) O(n) 图/树 最多的顶点数
深度优先遍历空间复杂度:O(d) 图/树的最大深度
(3)排序算法[时间和空间的比较]
下面4种排序方法中,要求内存容量最大的是( A)。
A.归并排序 B.快速排序 C.选择排序 D.插入排序
归并排序:O(n) 快速排序:O(logn) 选择排序:O(1) 插入排序:O(1) 基数排序:O(rd)
(4)快排算法考察
对下列关键字序列若采用快速排序法进行排序,哪一个序列的速度最快 ( )
A.24,27,3,17,9,19,30
B.3,9,17,24,19,27,30
C.27,19,30,17,24,3,9
D.24,9,17,30,27,19,3
因为快排要求的是,以第一个关键字作为中轴,使得两部分几乎平分是最好的。所以以19或者24为中轴最好。因此是24。排除B C选项。此外,若按照第一次划分后,待排序列数组合总数最少,则排序时间最快。
经过一次划分后,再将一次划分后的序列进行查看。
A: {19,3,17,9} 24 {27,30}
D :{3,9,17,19} 24 {30,27} 由于D选项 左半部分第一个数字为3,且为有序,因此效率不如A。故选A。
此外若待排序序列基本有序的时候,快排会退化成冒泡排序,时间复杂度为O(N^2)。
两道对应练习。
关键码序列28,16,32,12,60,2,5,72快速排序,从小到大一次划分结果为(B )。
A. (2,5,12,16)26(60,32,72) B. (5,16,2,12)28(60,32,72)
C. (2,16,12,5)28(60,32,72) D. (5,16,2,12)28(32,60,72)
43.对下列关键字序列用快速排序法进行排序时,速度最快的情形是( A )。
A. {21,25,5,17,9,23,30} B.{25,23,30,17,21,5,9}
C. {21,9,17,30,25,23,5} D.{5,9,17,21,23,25,30}
(5)将长度为n的单链表链接在长度为m的单链表之后,需要的时间复杂度 O(m)
只需要从m的单链表的最开始,遍历到最后一个,然后将 p->next = q(长度为n)就行了。O(1)
(6)二叉树的前中后序遍历【跳过】
(7)linux
你使用mkdir命令创建一个临时文件夹/tmp/aaa,并将一些文件复制其中。你使用完后要删除/mnt/tmp文件夹及其中的所有文件,应该使用命令( )
(8) 同一进程下的线程可以共享
A stack (栈) B data section () C register set (寄存器值) D thread ID(线程ID )
线程与进程的区别:进程和线程的深入理解_鱼日天的博客-CSDN博客_如何理解进程和线程
线程共享的内容包括(参考链接):一个进程的线程共享堆区,而进程中的线程各自维持自己栈。
- 进程代码段
- 进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)
- 进程打开的文件描述符 (file fd ):
- 信号的处理器 (用于线程之间的调度)
- 进程的当前目录
- 进程用户ID与进程组ID
线程独有的内容包括:
- 线程ID :同一进程中每个线程拥有唯一的线程ID
- 寄存器组的值:由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线 程切换到另一个线程上 时,必须将原有的线程的寄存器集合的状态保存,以便将来该线程在被重新切换到时能得以恢复。
- 线程的堆栈:线程可以进行函数调用,必然会使用堆栈
- 错误返回码:线程执行出错时,必须明确是哪个线程出现何种错误,因此不同的线程应该拥有自己的错误返回码变量。
- 线程的信号屏蔽码:由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理。但所有的线程都共享同样的信号处理器。
- 线程的优先级:由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参数,这个参数就是线程的优先级。
(9)Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为()
A ".*?(?=\\()"
B ".*?(?=\()"
C ".*(?=\\()"
D ".*(?=\()"
多选:
(1)进程间的通信方式:管道(匿名管道/命名管道)、消息队列、共享内存、信号量、Socket
管道:linux管道pipe详解_程序员的成长之路的博客-CSDN博客_linux pipe
消息队列(和消息中间件不同):Linux消息队列编程(简单应用)_小牛CKX的博客-CSDN博客_linux queue
共享内存:Linux下进程间通信方式——共享内存 - cs_wu - 博客园
信号量:对共享内存的存取的同步
(2)指针和引用叙述正确的是
sizeof(指针) = 指针的大小 sizeof(引用) 引用的对象的大小
引用不可以更改,指针可以,指针可以不用初始化,引用必须初始化
(3)计算机内存(内存分配方式详解):内存分配方式详解(堆、栈、自由存储区、全局/静态存储区和常量存储区)_行者三个石的博客-CSDN博客_自由存储区
堆区、栈区、静态数据区(全局区)、代码区、文字常量区、自由存储区
(4) java异常处理机制:Java的异常处理机制_BoSeal的博客-CSDN博客_java中异常处理机制
(5) try catch finally 异常处理机制:
如果没有return的情况, 没有异常就是 try-finally ,存在异常:try-catch-finally
如果含有return,分为几种情况,详见:java中的异常以及 try catch finally以及finally的执行顺序 - little飞 - 博客园
编程3道题:
(1)链表求和:2. 两数相加
我写的:没有新建节点,在L1基础上,进行更改。
class Solution(object):
def addTwoNumbers(self, l1, l2):
t1 ,t2 = l1,l2
count,s= 0,0
while(t1 != None and t2 != None): ## 都不为空的时候
count = t1.val + t2.val + s ## 进位
t1.val,s = count%10,count//10
t1 = t1.next
t2 = t2.next
if t1 == None and t2== None and s == 0: ## 看s 是否进位了
return l1 ##如果不存在进位,直接返回
if t1 == None and t2 ==None and s != 0:
temp = ListNode(s) ### 存在进位,在 l1 的基础上 添加一个节点
c1 = l1
while(c1.next != None): c1 = c1.next
c1.next = temp
return l1
while (t1 != None) : ## 长度不等
count = t1.val + s ## 进位
t1.val,s = count%10,count//10
if t1.next == None and s !=0 : ## 补节点
t1.next = ListNode(s)
return l1
t1 = t1.next
while (t2 != None) :
count = t2.val + s ## 进位
t2.val,s = count%10,count//10
if t2.next == None and s !=0 : ## 补节点
temp = ListNode(s)
t2.next = temp
t2 = t2.next
#return l1
t2 = t2.next
c1,c2 = l1,l2
while(c2.next != None ): ## 将在L2上保存的节点 复制到 l1中
if c1.next == None :
c1.next = ListNode(c2.next.val)
c1 = c1.next
c2 = c2.next
return l1
官方给出:新建一个链表,用来存储结果。
class Solution(object):
def addTwoNumbers(self, l1, l2):
t1 ,t2 = l1,l2
count,i= 0,0
x,y = 0,0
s = ListNode(0)
ans = s
while(t1 != None or t2 != None):
if t1 != None:
x = t1.val
else:
x = 0
if t2 != None:
y = t2.val
else:
y = 0
count = x + y + i ## 进位
i = count//10
ans.next = ListNode(count%10)
ans = ans.next
if t1 != None : t1 = t1.next
if t2 != None : t2 = t2.next
if (i != 0) :
ans.next = ListNode(i)
return s.next
两数相加II 一个变形题目,几乎差不多。但是这个需要利用栈来存储。因为它是逆序的,(当是逆序时,首先考虑逆序)。
(2)符号匹配的问题 '()[]{}'是否合法,'{{}()'不合法。和bilibili的题目一样 【用栈来做】
(3)剑指 Offer 22. 链表中倒数第k个节点 【先让c跑k个,维持p和c之间的k,c->next=null时,返回p.val】