1.TCP和UDP的区别
TCP要点:(1)TCP是传输控制协议(Transmission Control Protocol);(2)TCP提供的是面向连接、可靠的字节流服务,客户和服务器交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据;(3)提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP要点:(1)UDP是用户数据报协议(User Data Protocol),是一个简单的面向数据报的运输层协议;(2)不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地,没有确认机制, 没有重传机制;(3)无连接,知道对端的IP和端口号就直接进行传输, 不需要在客户和服务器之间建立连接,且没有超时重发等机制,所以传输速度很快。
引用:https://blog.csdn.net/sifanchao/article/details/82285018
2.网络编程中,select 和epoll的区别
要点:select一般用在socket网络编程中可以实现非阻塞编程
select缺点:
最大并发数限制:使用32个整数的32位,即32*32=1024来标识fd,虽然可修改,但是有以下第二点的瓶颈;效率低:每次都会线性扫描整个fd_set,集合越大速度越慢;内核/用户空间内存拷贝问题。
epoll的提升:
本身没有最大并发连接的限制,仅受系统中进程能打开的最大文件数目限制;
效率提升:只有活跃的socket才会主动的去调用callback函数;
省去不必要的内存拷贝:epoll通过内核与用户空间mmap同一块内存实现
引用:https://blog.csdn.net/jiange_zh/article/details/50811553
3.两个容器共用同一个挂载卷,如何解决写冲突
一种思想是,两个容器中分别在不同的目录进行写操作,如挂载卷都挂载容器中的/Data目录下,但是容器A在/DATA/A下写数据,容器B在/DATA/B下写数据;或者在挂载的时候就挂载在子目录
4.快排的思想以及时间复杂度
思想:给定一个基准元素(可以选择最左边的元素,也可以随机选择一个元素),定义两个指针left和right,并且分别指向数组的最左边的元素和最右边的元素。用左右指针的元素和基准元素比较,较大的全部放到基准元素的一边,较小的放到另一边,第一趟比较结束;然后递归的遍历基准元素的左右两边的子数组,结束的标志是左指针大于等于右指针。
时间复杂度:因为每次比较要把所有元素都遍历一遍,时间复杂度为O(n),总共要进行logn轮遍历,所以总的时间复杂度为O(nlogn)
参考我的博客:https://blog.csdn.net/shao_yc/article/details/103547551
5.如何判断是否是有向无环图(DAG:Directed Acyclic Graph)
采用DFS(深度优先遍历)思想:用涂色递归的方法进行深度优先遍历。灰色的元素处于同一条递归调用上,是同一条线,如果访问到了灰色元素(正常是黑色或者白色),说明存在环。
import java.util.LinkedList;
import java.util.List;
class Solution {
private List<Integer>[] adjs;
private Color[] colors;
public boolean containsLoop(int n, int[][] edges) {
adjs = new List[n];
colors = new Color[n];
for(int i = 0; i < n; i++) {
adjs[i] = new LinkedList<>();
colors[i] = Color.WHITE;
}
// 邻接矩阵和颜色初始化
for(int i = 0 ; i<edges.length;i++) {
int[] edge = edges[i];
int from = edge[0];
int to = edge[1];
adjs[from].add(to);
}
// 通过深度优先遍历判断环是否存在
for (int i = 0; i < n;i++) {
if (colors[i] == Color.WHITE) {
if(dfsVisit(i)) return true;
}
}
return false;
}
// contains loop return true;
// else return false;
private boolean dfsVisit(int i) {
colors[i] = Color.GRAY;
for (Integer adj: adjs[i]) {
if (colors[adj] == Color.GRAY) return true; // 在同一条递归调用中,访问到自己的先祖。
if (colors[adj] == Color.WHITE) {//没有访问的元素是白色的
if (dfsVisit(adj)) return true;
else continue;
}
}
colors[i] = Color.BLACK;
return false;
}
private enum Color {
WHITE, GRAY, BLACK
}
}
引用:https://blog.csdn.net/zhaoyangyingmu/article/details/100033864
6.代码题:如何判定一棵二叉树是否镜像对称。
递归方法:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null)
return true;
return issymmetric(root.left,root.right);
}
public boolean issymmetric(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null)
return true;
if(root1==null||root2==null)
return false;
if(root1.val!=root2.val)
return false;
return issymmetric(root1.left,root2.right)&&issymmetric(root1.right,root2.left);
}
}
非递归方法,利用队列
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.*;
public class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null)
return true;
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.add(root);
queue.add(root);
return issymmetric(queue);
}
public boolean issymmetric(Queue<TreeNode> queue){
while(!queue.isEmpty()){
TreeNode temp1=queue.poll();
TreeNode temp2=queue.poll();
if(temp1==null&&temp2==null){
continue;
}
else if(temp1==null||temp2==null){
return false;
}
else if(temp1.val!=temp2.val){
return false;
}
queue.add(temp1.left);
queue.add(temp2.right);
queue.add(temp1.right);
queue.add(temp2.left);
}
return true;
}
}
引用:https://blog.csdn.net/zy854816286/article/details/104792799/