java练习题(四):

java练习题(四):

  1. 列举java的常用容器(集合)
  2. List和Set的区别,不可重复是什么意思?
  3. HashMap是否线程安全,如果想用线程安全的HashMap怎么做?
  4. 编写一个单例模式,常见的单例有哪些,分别列举?
  5. 有哪些排序算法,写出快速排序算法的实现
  6. 给一个二叉树,使用递归和非递归完成先序,中序和后序的遍历
  7. 数据库的事务的四大特性及数据库的隔离级别
  8. TCP的三次握手和四次挥手
  9. GET/POST的区别,除了GET/POST还有哪些?

1 .列举java的常用容器(集合)

collection中

list接口:ArrayList,LinkedList,vector

set接口:hashset,treeset

map:hashmap,hashtable

  1. List和Set的区别,不可重复是什么意思?

    List:包含了ArrayList,LinkedList,vector,属于链表结构

    Set:Hashset不保证数据的顺序,可以为null

    不可重复是指set结构中的key唯一不重复,在hashset中利用key存放数据,能保证数据不重复

  2. HashMap是否线程安全,如果想用线程安全的HashMap怎么做?

    hashmap线程不安全,如果需要线程安全可以使用concurrenthashmap,内部使用了CAS策略保证了线程安全

  3. 编写一个单例模式,常见的单例有哪些,分别列举?
    public enum SingletonA {
    	INSTANCE;
    }
    

    常见的单例模式有饿汉式,懒汉式

    public class SingletonA {//懒汉式
    
    	private volatile static SingletonA instance;
    
    	private SingletonA() {
    
    	}
    
    	public static SingletonA getInstance() {
    		if (instance == null) {
    		synchronized (SingletonA.class) {
    		if (instance== null) {
                     instance= new SingletonA();
                 }
    			}
    		}
    		return instance;
    	}
    
    }
    
    public class SingletonC{//饿汉式
        private static SingletonC instance;
        private SingletonC(){}
        public static SingletonC getInstance(){
            return instance;
        }
    }
    
  4. 有哪些排序算法,写出快速排序算法的实现

    冒泡排序、插入排序、选择排序、快速排序、堆排序、桶排序、希尔排序

    快速排序:

    public static void quickSort(int[] arr,final int left,final int right) {
    		if (left > right)
    			return;
    		int temp = arr[left];
    		int i = left;
    		int j = right;
    		// 不相遇
    		while (i != j) {
    			// 从右边开始找比基准数小的就停下,反言之就是比基准数大或者相等就继续
    			while (arr[j] >= temp && i < j) {
    				j--;
    			}
    			while (arr[i] <= temp && i < j) {
    				i++;
    			}
    			int t = arr[i];
    			arr[i] = arr[j];
    			arr[j] = t;
    		}
    		// i=j 相遇位置的数赋值给基准数这个位置的元素
    		arr[left] = arr[i];
    		// 把基准数赋值给相遇位置的数
    		arr[i] = temp;
    		quickSort(arr, left, i - 1);
    		quickSort(arr, i + 1, right);
    	}
    
    }
    
  5. 给一个二叉树,使用递归和非递归完成先序,中序和后序的遍历
    //先序遍历
    public void preOrder(TreeNode root) {
    		if (root == null)
    			return;
    		System.out.print(root.val + " ");
    		preOrder(root.left);
    		preOrder(root.right);
    	}
    public void preOrder1(TreeNode root) {
    		Stack<TreeNode> stack=new Stack<>();
    		TreeNode currNode=root;
    		if(currNode!=null) {
    			stack.push(currNode);//根节点入栈
    			while(!stack.isEmpty()) {
    				currNode=stack.pop();//弹出根节点
    				System.out.print(currNode.val+" ");
    				if(currNode.right!=null) {//右节点先压入栈
    					stack.push(currNode.right);
    				}
    				if(currNode.left!=null) {
    					stack.push(currNode.left);
    				}
    			}
    		}
    	}
    //中序遍历
    public void inOrder(TreeNode root) {
    		if (root == null)
    			return;
    		preOrder(root.left);
    		System.out.print(root.val + " ");
    		preOrder(root.right);
    	}
    public void inOrder1(TreeNode root) {
    		Stack<TreeNode> stack=new Stack<>();
    		TreeNode currNode=root;
    		while(currNode!=null||!stack.isEmpty()) {
    			//先访问左节点,压入左节点
    			while(currNode!=null) {
    				stack.push(currNode);
    				currNode=currNode.left;
    			}
    			if(!stack.isEmpty()) {
    				currNode=stack.pop();//弹出左节点
    				System.out.print(currNode.val+" ");
    				currNode=currNode.right;//开始压入右节点
    			}
    		}
    	}
    
    
    //后序遍历
    public void afterOrder(TreeNode root) {
    		if (root == null)
    			return;
    		preOrder(root.left);
    		preOrder(root.right);
    		System.out.print(root.val + " ");
    	}
    
    public void afterOrder1(TreeNode root) {
    		Stack<TreeNode> stack1=new Stack<>();
    		Stack<TreeNode> stack2=new Stack<>();
    		TreeNode currNode=root;
    		while(currNode!=null||!stack1.isEmpty()) {
    			while(currNode!=null) {
    				//使用两个栈在stack2中按照左右顺序入栈
    				stack1.push(currNode);
    				stack2.push(currNode);
    				currNode=currNode.right;
    			}
    			if(!stack1.isEmpty()) {
    				currNode=stack1.pop();//弹出左节点
    				currNode=currNode.left;
    			}
    		}
    		while(!stack2.isEmpty()) {
    			currNode=stack2.pop();
    			System.out.print(currNode.val+" ");
    		}
    	}
    
    //层序遍历
    public void levelOrder(TreeNode root) {
    		if (root == null)
    			return;
    		Queue<TreeNode> q = new LinkedList<>();// 定义一个队列
    		q.offer(root);// 存入根节点
    		while (!q.isEmpty()) {
    			TreeNode temp = q.poll();// 弹出根节点
    			System.out.print(temp.val + " ");// 输出根节点
    			if (temp.left != null) {// 找到根节点下的左右节点并存入队列
    				q.offer(temp.left);
    			}
    			if (temp.right != null) {
    				q.offer(temp.right);
    			}
    		}
    	}
    
    
  6. 数据库的事务的四大特性及数据库的隔离级别

四大特性:原子性、隔离性、一致性、持久性

隔离级别:

读未提交:在一个事务中,读到了其他事务没有提交的数据。会产生数据脏读现象,不能限制不可重复读和幻读。

读已提交:在一个事务中可以读取到其他事务已经提交的数据变化。可防止脏读现象,无法限制不可重复读和幻读。

可重复读:在一个事务中直到事务结束之前,都可以反复的读到事务刚开始看到的数据,并且一直不会发生变化,有效的防止了脏读和不可重复读。

串行:只有等一个事务结束,才能进行下一个事务。

  1. TCP的三次握手和四次挥手

建立连接的三次握手:

第一次:客户端发起连接请求,SYN设置为1,seq随机一个值发送给服务端。

第二次:服务端确认请求将SYN为1,ack设置为上一次seq的值+1,ACK=1表示收到请求,seq发送一个随机值

第三次:客户端再次确认连接ACK=1,ack为上一次seq的值+1,ACK=1表示收到应答建立连接,seq为上一次的ack值

释放连接的四次挥手:

第一次:客户端发送关闭连接FIN=1,seq=随机值

第二次:服务端发送给客户端ACK=1,seq=随机值,ack=上一个seq+1

第三次:服务端发送给客户端相同的信息

第四次:客户端发送给服务端ACK=1,seq=上一个ack+1,ack=上一个seq+1

  1. GET/POST的区别,除了GET/POST还有哪些?

    GET和POST发送基于http协议,但是由于服务器的限制,导致两者发送的方式不同

    且GET是幂等POST是非幂等可能会修改服务器中的资源请求导致两次结果不同

    GET:参数通过URL传输,且会被浏览器主动缓存,传输的非ASCII需要转码

    POST:有两个TCP数据包,将参数放置在request body中,缓存需要手动设置,且非ASCII数据通过MIME传输

    还有DELETE:删除信息和PUT:添加信息

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值