零星面试问题补充_part2

这篇博客汇总了多个面试问题,涵盖了算法、Java、数据库、操作系统、网络等多个方面。主要内容包括:树的镜像判断、Java访问修饰符、synchronized与ReentrantLock的区别、数据库索引使用、异常处理、临界区概念、子网掩码作用、红黑树特性、HashMap多线程问题、并发HashMap的并发策略等。这些问题深入探讨了相关技术的核心概念和实现细节。
摘要由CSDN通过智能技术生成

1.算法:判断一棵树是否是镜像

https://blog.csdn.net/cuit/article/details/78639682

递归解法:首先判断根是否有左右节点,如果左右节点都有,则判断左节点的右子节点和右节点的左子节点是否有相同的值,并进行递归。

非递归解法:用队列来代替递归过程,把要比较的节点成对放入队列中。

 public boolean isSymmetric(TreeNode root) 
    {
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        if(root == null) return true;
        q.add(root.left);
        q.add(root.right);
        while(q.size() > 1)
        {
            TreeNode left = q.poll();
            TreeNode right = q.poll();
            if(left== null && right == null) { continue; }
            if(left == null ^ right == null) { return false; }
            if(left.val != right.val) { return false; }
            q.add(left.left);
            q.add(right.right);
            q.add(left.right);
            q.add(right.left);            
        }
        return true;
    }

2.Java:几个访问修饰符的区别

https://blog.csdn.net/zhangbinu/article/details/53736388

主要记忆defalut是只能在同包中访问。protected可以在同包和子类中进行访问

3.Java:synchronized 和 ReentranLock的区别

https://blog.csdn.net/zheng548/article/details/54426947

明显的区别点:

a.synchronized是一个关键字可以直接修饰方法或者修饰代码块,reentranlock需要定义所并设置加锁和解锁。

b.reentranlock的等待可中断。

c.synchronized是非公平锁,而rlock都可以。

d.rlock可以绑定多个条件。

共同点:

a.都是可重入的。

b.现在来讲性能和优化倾向于synchronized。

sychronized实现原理:sychronized关键字经过编译后会在同步块的前后形成monitirenter和monitorexit两个字节码指令。

ReenTrantLock的实现是一种自旋锁,通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。

4.数据库:一个表 A B C字段 index(A,B,C) select * from table where A= xx and B>0 order by C 走索引嘛?

放弃索引导致全表扫描的情况

https://blog.csdn.net/illusion_you/article/details/79097287

https://www.cnblogs.com/wangxusummer/p/5329813.html

a.like语句,is null语句,非等于语句,in语句,表达式操作,count(*)

b.组合索引查询条件中没有前导列

c.or语句并且有列非索引

d.组合索引排序时应该按照组合索引中各列的顺序进行排序,这个题目就应该写成order by a,b,c

e.where 语句与ORDER BY语句组合满足最左前缀,但where语句中使用了条件查询,所以B>0这个地方会导致filesort

5.Java:常见的IO异常

https://blog.csdn.net/zhufuing/article/details/38312441

文件不存在异常;传入的参数是文件夹异常;权限错误异常;

6.操作系统:临界区

https://blog.csdn.net/nopoppy/article/details/52644397

临界区:并发程序访问共享资源的程序片段。同一时刻只能一个线程进入,其余线程在临界区外等待。

7.数据库:where语句中有两个索引,怎么执行,第二个还执行不

https://blog.csdn.net/gb4215287/article/details/78037835

与其说是“数据库查询只能用到一个索引”,倒不是说是 和全表扫描/只使用一个索引的速度比起来,去分析两个索引二叉树更加耗费时间,所以绝大多数情况下数据库都是是用一个索引。

8.Java:公平锁与非公平锁

https://blog.csdn.net/z69183787/article/details/50971317

reentrantlock有公平锁和非公平锁两种。公平锁上线程按照他们发出请求的顺序来获取锁。非公平锁则允许后来的线程先得到锁,是一种抢占式的机制。非公平锁性能高于公平锁,原因在于在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。

9.Java:TreeMap的底层原理

底层是红黑树数据结构。插入,删除,检索的复杂度都是logn。

10.网络:osi模型,每一层做了什么事情,有什么协议

https://blog.csdn.net/lisa890608/article/details/8231666

https://www.cnblogs.com/wxd0108/p/7597216.html

物理层 比特
数据链路层 不可靠的物理介质上提供可靠的传输,ARP,PPP,帧中继
网络层 网间的数据包进行路由选择,IP,ICMP
传输层 端口到端口的层次,TCP、UDP
会话层 主机之间的会话进程,即负责建立、管理、终止进程之间的会话。
表示层 对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。
应用层 操作系统或网络应用程序提供访问网络服务的接口。FTP、HTTP

11.网络:cookie

https://www.cnblogs.com/andy-zhou/p/5360107.html

用于做会话跟踪,cookie是客户端的解决方案。存储的是服务器端发送给客户端的特殊信息,以文本的方式存储在客户端,之后客户端向服务器端发起请求的时候都会附上这些信息。一个用户的所有连接和请求都应该是在一个会话中。生存周期与max_age相关,如果max_age大于0会被持久化存储。

session机制是服务器端的解决方案。创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;

12.Java:异常处理是具体怎样执行的

https://blog.csdn.net/jakezhang1990/article/details/72880700

try里面捕获异常,然后跳转到catch模块,如果有finally模块就执行finally模块

1. 一旦产生异常,则首先会产生一个异常类的实例化对象。 
2. 在try语句中对此异常对象进行捕捉。 
3. 产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功则执行catch语句中的代码。

13.JVM:原子性和可见性

https://blog.csdn.net/qq_33689414/article/details/73527438

原子性:由java内存模型来保障原子性变量操作包括read,load,use,store。基本数据类型的访问读写是有原子性的。指一个操作或多个操作要么全部执行,且执行的过程不会被任何因素打断,要么就都不执行。sychronized可以做到

可见性:当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。变量修改后会将新值同步回主内存,在变量读取前从主内存刷新变量值来保证可见性的。sychronized,final,valitile可以做到。

有序性:线程内保持串行,线程外观察是无序的。volatile,sychronized可以做到。

14.程序:手写消费者生产者伪代码

https://blog.csdn.net/qq_25232555/article/details/77856035

消费者一个类,生产者一个类,然后仓库一个类,同步控制是在仓库的put和get中间做的

实现线程的代码

new Thread(new Runnable() {
	public void run() {
	    produ pro = new produ(bigbox);
	    pro.put();
    }
}).start();
public void put(apple app) {
		synchronized (this) {
			try {
				while (boxlist.size() >= capacity)
					wait();
				boxlist.add(app);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
 
			notifyAll();
			System.out.println("put finished! Now the box has "
					+ boxlist.size() + " apples!");
		}
}

15.Python:Python的GIL functionTools

https://www.cnblogs.com/SuKiWX/p/8804974.html

GIL无疑就是一把全局排他锁。毫无疑问全局锁的存在会对多线程的效率有不小影响。甚至就几乎等于Python是个单线程的程序。但当CPU有多个核心的时候,问题就来了。从伪代码可以看到,从release GIL到acquire GIL之间几乎是没有间隙的。所以当其他在其他核心上的线程被唤醒时,大部分情况下主线程已经又再一次获取到GIL了。这个时候被唤醒执行的线程只能白白的浪费CPU时间,看着另一个线程拿着GIL欢快的执行着。然后达到切换时间后进入待调度状态,再被唤醒,再等待,以此往复恶性循环。

使用了多进程而不是多线程。每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢。

16.计网:子网掩码的作用

https://blog.csdn.net/qq1449301756/article/details/48652117

将某个IP地址划分成网络地址和主机地址两部分。

通过ip和子网掩码可以计算出:网络地址(与运算),广播地址,地址范围(网络地址+1,广播地址-1),本网主机数。

17.计网:mac寻址

http://blog.51cto.com/07net01/586888

交换机利用mac地址表进行下一步的转发,若mac地址未在表中,则向出了来的端口外所有端口发送,收到回应后在mac地址表会记录下mac地址

18.算法:01矩阵求最大正方形

https://blog.csdn.net/u011484326/article/details/76474387

a.暴力搜索,以每个位置为左上角能形成的最大矩形

b.动态规划,dij为以(i,j)为右下角的正方形的最大边,dij = min { d[i-1][j-1],min {d[i-1][j],d[i,j-1]}}+1

如果是求最大的子矩形

https://blog.csdn.net/libin56842/article/details/41849769

首先统计每一行连续1的个数,然后按列累加(相邻的才进行累加),记录最大值即可得到面积

19.网络:http的状态码

http://www.runoob.com/http/http-status-codes.html

https://blog.csdn.net/GarfieldEr007/article/details/77984065

1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求,权限错误也在这一步
5** 服务器错误,服务器在处理请求的过程中发生了错误

401:未授权

403:禁止访问

404:未找到文件

500:服务器内部错误

502:网关错误

503:网关不可用

504:网关超时

20.数据库事务回滚方法

https://blog.csdn.net/nangeali/article/details/75578557

rollback语句,利用的是回滚日志(undo log)

21.算法:判断一个数是不是2的幂次方

https://www.cnblogs.com/haitao-fan/p/3923412.html

由于2的k次方肯定是一个正数,故这个地方不需要考虑负数的情况。2的k次方的二进制表示应该只有1位为1.故可以用m & (m-1)  == 0来进行判断。

22.Linux:gdb调试的原理

https://blog.csdn.net/earbao/article/details/53933594

主要功能的实现依赖于一个系统函数ptrace,通过man手册可以了解到,ptrace可以让父进程观察和控制其子进程的检查、执行,改变其寄存器和内存的内容,主要应用于打断点(也是gdb的主要功能)和打印系统调用轨迹。以x86为例,内核向某个地址打入断点,实际上就是往该地址写入断点指令INT 3,即0xCC。

23.算法:二叉树的中序遍历递归及非递归

递归的方法:首先访问左子树,再访问当前节点,然后访问右子树

非递归的方法:一个栈进行辅助,若当前节点有左子树,则当前节点入栈,指针指向左子树,当前节点为空则出栈并访问,之后当前指针指向出栈节点的右子树。

24.算法:输出给定节点到目标节点的路径

a.可以转化为首先求出根节点到给定节点的路径及根节点到目标节点的路径,然后比较这两个路径,如果完全没有重合,则相加,如果部分重合,则找到最近的重合点。如果给定节点就在到目标节点的路径上则选取那段即可。

https://blog.csdn.net/shixiaoguo90/article/details/23759887

计算根节点到任意节点的方法:递归,用ArrayList记录路径走过的路径,注意如果未查找到要进行remove操作。这个地方为了避免多余的查找,可以设置一个查找标志。

b.可以首先查找目标节点是否在给定节点的子树中,第二,是否在根的另一子树中。第三种情况就是在根的同一边子树中,转化为求公共父节点的算法。https://blog.csdn.net/zjkC050818/article/details/72621487。本质上还是变成了根据根到节点的路径来进行求解的算法。

25.算法: 寻找两个字符串中只有首尾字符相同的所有子串,例如 ABCDE 和 ADCAE中包含(ABC--ADC)以及(CDE--CAE)

a.可以用map结构把开头结尾,子串信息记录下来,然后进行比对。例如 AC:ABC,...,然后匹配过后输出。复杂度是o(n2);

26.数据结构:建堆的时间复杂度

https://blog.csdn.net/liliuteng/article/details/8496050

建新堆的时间复杂度应该是o(n),是一个反复筛选的过程。从第一个非根节点一直调整到根。

排序算法的复杂度应该是T(n) <=  O(n)  + (n - 1)*O(log2(n)) 就是nlogn

27.数据结构:快排的时间复杂度在最好情况和最坏情况

h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值