总结

美菜网

在这里插入图片描述

在这里插入图片描述
Java类定义如下,写出main函数执行后输出的结果

public class A {

    static {
        System.out.println("static A");
    }

    public A() {
        System.out.println("class A");
    }
}

public class B extends A{

    public B() {
        System.out.println("class B");
    }

    public static void main(String[] args) {
        B instance = new B();
    }
}

简单的类加载顺序,口诀如下
执行顺序

  1. 父类的静态(静态代码块,静态成员变量),子类的静态(静态代码块,静态成员变量)
  2. 父类的非静态(构造代码块,非静态成员变量),父类的构造函数
  3. 子类的非静态(构造代码块,非静态成员变量),子类的构造函数

所以输出输出如下;

static A
class A
class B

面试官还问了一个问题如果main函数中的代码如下呢?就是B这个类new2次

public static void main(String[] args) {
    B instance = new B();
    B instance1 = new B();
}

输出应该如下

static A
class A
class B
class A
class B

因为静态成员变量和静态代码块只会在类被载入内存时加载一次

写出main函数执行后输出的结果

public class T extends Thread {

    public T() {
        this.setName("Thread t");
        this.printName();
    }

    public void run() {
        this.printName();
    }

    private void printName() {
        String name = Thread.currentThread().getName();
        System.out.println(name);
    }

    public static void main(String[] args) {
        Thread.currentThread().setName("Thread main");
        T t = new T();
        t.start();
    }
}

输出如下:

Thread main
Thread t

解释如下:
new T()的时候,因为此时在主线程,线程名字为main,
t.start()后,此时在t线程,线程名字为t

链表反转(这个大厂超级爱问)
Leetcode原题

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
         if (head == null || head.next == null) {
             return head;
         }
         ListNode cur = head.next;
         head.next = null;
         ListNode temp;
         while (cur != null) {
             temp = cur.next;
             cur.next = head;
             head = cur;
             cur = temp;
         }
         return head;
    }
}

多线程安全的单例类
单例有5种写法,具体看Java识堂微信公众号,不再阐述,一般人写双重检测锁定,我建议写静态内部类的实现方式,看起来比较优雅

public class Singleton {

   private static class SingletonHolder {
       private static Singleton uniqueInstance = new Singleton();
   }

   private Singleton() {}

   public static Singleton getInstance() {
       return SingletonHolder.uniqueInstance;
   }
}

饿汉式的方式只要Singleton类被装载了,那么uniqueInstance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,uniqueInstance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化uniqueInstance

Linux中根目录包含哪些目录?功能是什么?
在这里插入图片描述

Linux中通过命令行完成
1.查看磁盘剩余空间
df -h (-h是以人类易读的方式显示出来,如1K 234M 2G)
在这里插入图片描述
2.在/tmp目录下查找所有内容包含abc的文件

find /tmp -type f | xargs grep -l 'abc'

在这里插入图片描述
Linux下swap分区的作用

在Linux下,SWAP的作用类似Windows系统下的“虚拟内存”。当物理内存不足时,拿出部分硬盘空间当SWAP分区(虚拟成内存)使用,从而解决内存容量不足的情况。
SWAP意思是交换,顾名思义,当某进程向OS请求内存发现不足时,OS会把内存中暂时不用的数据交换出去,放在SWAP分区中,这个过程称为SWAP OUT。当某进程又需要这些数据且OS发现还有空闲物理内存时,又会把SWAP分区中的数据交换回物理内存中,这个过程称为SWAP IN。
当然,swap大小是有上限的,一旦swap使用完,操作系统会触发OOM-Killer机制,把消耗内存最多的进程kill掉以释放内存。
  
成绩表,学生表,输出每个学生的平均成绩
这个挺简单的,就不再写了

有4个人用一个手电筒,过一座桥洞,每个人过桥洞时间分别为1,2,5,10,桥洞同时只能容纳2个人通过,求所有人通过桥洞的最短时间

去1 2
回1
去5 10
回2
去1 2
总的时间为2 + 1 + 10 + 2 + 2 = 17

有2个列ab,你是建ab索引还是ba索引?
区分度高的列放在前面,假如b列的区分度高,就建ba索引,反之建ab,区分度的相关概念看微信公众号Java识堂中关于建索引的文章

一副扑克牌,除去大小王,随机抽5张,判断这5张是否连续的策略
不除去大小王,大小王可以顶替任意牌,判断这5张是否连续的策略\

最后2道算法题,欢迎大家在下方留言,不再写了

  1. 类加载顺序
  2. 输出线程名字
  3. 反转链表
  4. 单例模式
  5. Linux各个文件夹的作用
  6. /tmp 目录下找含有字符串abc的文件
  7. linux swap分区的作用
  8. 成绩表,学生表,输出每个学生的平均成绩
  9. 有4个人用一个手电筒,过一座桥洞,每个人过桥洞时间分别为1,2,5,10,桥洞同时只能容纳2个人通过,求所有人通过桥洞的最短时间
  10. 一副扑克牌,除去大小王,随机抽5张,判断这5张是否连续的策略
  11. 不除去大小王,大小王可以顶替任意牌,判断这5张是否连续的策略
  12. 索引 ab和ba的区别,区别度不同
  13. Redis Cluster

考虫网

  1. 判断2个链表是否相交,注意有环的情况
  2. 有5000万用户,在一个输入框中输入李,下拉框显示李的可选项,如李1,李2,输入张强,下拉框显示张强的可选项,如张强1,张强2,策略,按姓名分表,或者用es
  3. 获取一个数组的最大值,最大的2个值,最大的n个值,用快排
    还有一个优化思路是比较,n和数组长度的一半的大小,例如100个数求最大的99个,只要求最小的一个就行
  4. 将n个有序数组组成一个有序数组,归并排序
  5. dubbo原理
  6. netty原理
  7. 给一个数组,元素不重复,求2个数和为6的数组的下标,例如1 2 3 4 5,一种为0 4,一种为1 3,解决方法是把小于6的值放到map中,value为下标,遍历这个map即可

懒投资

打印代码的输出

public class MyTest {


    private int a = 1;
    private static int b = 1;

    private static MyTest myTest = new MyTest();

    static {
    	// 这个是我为了方便理解加的
        System.out.println("静态代码块");
        b = 200;
    }

    public MyTest() {
         // 这个是我为了方便理解加的
        System.out.println("构造函数");
        this.a = 10;
        this.b = 10;
    }

    public int sum() {
        return this.a + b;
    }

    public static void main(String[] args) {

        // 210
        System.out.println(MyTest.myTest.sum());
        // 20
        System.out.println(new MyTest().sum());
    }

}

最终的输出为

构造函数
静态代码块
210
构造函数
20

第二个输出很容易理解,第一个我懂个大概,但没有把握讲清楚,有兴趣的小伙伴可以在下方留言解释一下

一个人上楼梯,每次可以上1阶和2阶,问上到count阶台阶的数量
简单的递推,递归也行,但是感觉没必要,

递推公式为
a[n]=a[n-1]+a[n-2],简单解释一下,数组a[n]表示的是上到n阶台阶的数量,即上到n阶的数量=上到n-1阶的数量+上到n-2阶的数量,这个很容易理解吧,初始变量种类为

a[1]=1,从0阶一步到1阶
a[1]=2,从0阶一步到2阶,从1阶一步到2阶

class Solution {

    public int getNum(int num) {

        int[] a = new int[num + 10];
        a[1] = 1;
        a[2] = 2;
        for (int i = 3; i <= num; i++) {
            a[i] = a[i-1] + a[i-2];
        }
        return a[num];
    }


    public static void main(String[] args) {
        Solution solution = new Solution();
        // 3
        System.out.println(solution.getNum(3));
        // 5
        System.out.println(solution.getNum(4));
    }
}

仔细看数量

1 2 3 5 8 13,典型的斐波那契数列啊,所以一个通项公式直接求出第n项
在这里插入图片描述

一个人每次上1-n(2<=n<=count)阶台阶,求上到count阶台阶数量

这个是上面题目的变形
递推公式为
a[count]=a[count-1]+a[count-2]+…+a[count-n],简单解释一下,数组a[count]表示的是上到count阶台阶的数量

class Solution {

    public int getNum(int n, int count) {

        int[] a = new int[count + 10];
        a[0] = 1;
        a[1] = 1;
        a[2] = 2;
        for (int i = 3; i <= count; i++) {
            for (int j = 1; j <= n; j++) {
                a[i] += a[i-j];
            }
        }
        return a[count];
    }


    public static void main(String[] args) {
        Solution solution = new Solution();
        // 5
        System.out.println(solution.getNum(2, 4));
        // 4
        System.out.println(solution.getNum(3, 3));
    }
}

写一个函数,返回第一个出现的个数为1的字符,如果没有则返回空字符,例如 abbbce返回’a’,aabbcc返回’’,aabce返回b

这个题的思路也挺巧的,我刚开始居然没想出来,后来猛的才意识到,你先别看我写的,先自己想一下

class Solution {

    public char getFirstSingleChar(String str) {
        Map<Character, Integer> map = new LinkedHashMap();
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);
            Integer num = map.get(a);
            if (num == null) {
                map.put(a, 1);
            } else {
                map.put(a, num + 1);
            }
        }
        for (Map.Entry<Character, Integer> entry: map.entrySet()) {
            if (entry.getValue() == 1) {
                return entry.getKey();
            }
        }
        return ' ';
    }


    public static void main(String[] args) {

        Solution solution = new Solution();
        // a
        System.out.println(solution.getFirstSingleChar("abbbce"));
        // 空字符
        System.out.println(solution.getFirstSingleChar("aabbcc"));
        // b
        System.out.println(solution.getFirstSingleChar("aabce"));
    }
}

这道题用LinkedHashMap解决非常简单,用其他方法解决比较难,如果有更好的方法,欢迎在下方留言

掌上先机

try{}里面有一个return语句,那么紧跟在这个try后的finally{}里的code会不会执行,什么时候执行?

class Solution {

    private static int method1() {

        try {
            int a = 10 / 1;
            System.out.println("num is " + a);
            return 0;
        } finally {
            System.out.println("finally");
        }
    }

    public static void main(String[] args) {
        // num is 10
        // finally
        Solution.method1();
    }

}

看上面输出,finally里的code会执行,在try里面的return执行之前执行。

Java中的final关键字有哪些作用?

  1. final修饰类时,表明这个类不能被继承
  2. final修饰方法,表明方法不能被重写
  3. final修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象

当一个线程进入一个对象的synchronized方法后,其他线程是否可进入此对象的次方法?
不能进入

一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制?

一个.java的源文件中是可以包含多个类的,但是public类只能有一个,并且类名要和文件名相同,如果有两个public类 就会报出以下的错误
在这里插入图片描述
可以看到提示Test2应该被定义到一个Test2.java文件中
在这里插入图片描述

将Test2的的public去掉,即正常并且在Test1中可以使用
在这里插入图片描述
最后会被编译为2个class文件
在这里插入图片描述
下列程序段,数据的结果是什么?

class Solution {

    public void trythis() {
        try {
            System.out.println("1");
            problem();
        } catch (RuntimeException x) {
            System.out.println("2");
            return;
        } catch (Exception x) {
            System.out.println("3");
            return;
        } finally {
            System.out.println("4");
        }
        System.out.println("5");
    }

    private void problem() throws Exception{
        throw new Exception();
    }

    public static void main(String[] args) {
        
        Solution solution = new Solution();
        solution.trythis();
    }

}

输入为

1
2
4

在这里插入图片描述
设有一组关键词序列{5,8.14,20,31,55,78,81,93,97,11},使用二分法查找关键字93需要多少次比较

一般是让写二分查找代码,简单写一下吧,次数自己模拟一下就行

// 从list中找到target所在的下标,如果找不到,返回-1
public int binsearch(List<Integer> list, int target) {
	int left = 0;
	int right = list.size() - 1;
	//注意是小于等于,如从123456中查找6,没等于不行
	while(left <= right) {
		int mid = (left + right) / 2;
		if(target == list.get(mid)) {
			return mid;
		}
		if(target > list.get(mid)) {
			left = mid + 1;
		} else {
			right = mid - 1;
		}
	}
	return -1;
}

getValue(2)的结果是10
getValue(4)的结果是18
很简单的2个题,不再说了

下面关于abstract关键字描述错误的是
abstract类的子类必须实现其超类的所有abstract方法(错误的)

看如下代码,不会报错,所以不用实现

abstract class Father {
    public abstract void show();
}

public abstract class Son extends Father{
}

下面是一颗树,请用某种方式将其转为二叉树,同时写出先序遍历
树转二叉树有一个法则

(1)树中所有相同双亲结点的兄弟结点之间加一条连线;

(2)对树中不是双亲结点的第一个孩子的结点,只保留新添加的该结点与左兄弟结点之间的连线,删去该结点与双亲结点之间的连线;

(3)整理所有保留的连线,根据连线摆放成二叉树的结构,转换完成。

在这里插入图片描述
在这里插入图片描述

是左子树还是右子树的一个法则是,左儿子,右兄弟(儿子是左子树,兄弟是右子树)

题目中将树转为二叉树的过程如下
在这里插入图片描述
写出先序遍历,上口诀

前序遍历:根,左,右
中序遍历:左,根,右
后序遍历:左,右,根

先序遍历为ABEFCGDH

在Java中,如何跳出当前的多重嵌套循环,两种方式实现?如数组int arr[][]={{1,2,3},{4,5,6,7},{8,9,5}}
找到数值5打印并跳出循环

标记退出这种方式我就不写了,写一个大多数人不知道的骚操作,这里先演示一下retry的使用

break retry 跳到retry处,且不再进入循环
continue retry 跳到retry处,且再次进入循环

public static void main(String[] args) {
   breakRetry();
   continueRetry();
}

private static void breakRetry() {
   int i = 0;
   retry:
   for (; ; ) {
       System.out.println("start");
       for (; ; ) {
           i++;
           if (i == 4)
               break retry;
       }
   }
   //start 进入外层循环
   //4
   System.out.println(i);
}

private static void continueRetry() {
   int i = 0;
   retry:
   for(;;) {
       System.out.println("start");
       for(;;) {
           i++;
           if (i == 3)
               continue retry;
           System.out.println("end");
           if (i == 4)
               break retry;
       }
   }
   //start 第一次进入外层循环
   //end i=1输出
   //end i=2输出
   //start 再次进入外层循环
   //end i=4输出
   //4 最后输出
   System.out.println(i);
}
class Solution {

    public static void main(String[] args) {

        List<List<Integer>> list = new ArrayList<>();
        list.add(Arrays.asList(1, 2, 3));
        list.add(Arrays.asList(4, 5, 6, 7));
        list.add(Arrays.asList(8, 9, 5));
        retry:
        for (int i = 0; i < list.size(); i++) {
            List<Integer> tempList = list.get(i);
            for (int j = 0; j < tempList.size(); j++) {
                if (tempList.get(j) == 5) {
                    System.out.println("5");
                    break retry;
                }
            }
        }
        // 5
        // end
        System.out.println("end");
    }

}

在这里插入图片描述
删除list中指定的所有元素,例如List<Integer>();如果存储的数据是[1,2,3,2,4,5,2]删除所有数值等于2的元素?

这个需要注意的一点就是尽量不要用list.remove(),因为要注意的细节比较多,很容易出错,我也不想解释了,有兴趣的可以看一下这篇文章
https://blog.csdn.net/qq_42986107/article/details/81988470

用迭代器模式删除就行

class Solution {

    private static void removeElement(List<Integer> list, int target) {
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            int value = it.next();
            if (value == target) {
                it.remove();
            }
        }
    }

    public static void main(String[] args) {
        List<Integer> tempList = Arrays.asList(1, 2, 3, 2, 4, 5, 2);
        List<Integer> list = new ArrayList<>(tempList);
        removeElement(list, 2);
        for (int i = 0; i < list.size(); i++) {
            // 1 3 4 5
            System.out.print(list.get(i) + " ");
        }
    }

}

输出如下代码的输出结果

class HelloA {

    // 构造函数
    public HelloA() { System.out.println("Hello A"); }
    // 构造代码块
    { System.out.println("I'm A class");}
    // 静态代码块
    static { System.out.println("static A"); }
}

public class HelloB extends HelloA {

    public HelloB() { System.out.println("Hello B"); }
    { System.out.println("I'm B class"); }
    static { System.out.println("static B"); }

    public static void main(String[] args) {
        new HelloB();
    }
}

从这个题目也可以看出一个.java文件可以包括多个类

简单的类加载顺序,上口诀

  1. 父类的静态(静态代码块,静态成员变量),子类的静态(静态代码块,静态成员变量)
  2. 父类的非静态(构造代码块,非静态成员变量),父类的构造函数
  3. 子类的非静态(构造代码块,非静态成员变量),子类的构造函数

所以写出如下输出就很容易了

static A
static B
I'm A class
Hello A
I'm B class
Hello B

剩下的编程题没多大难度,就不写了
在这里插入图片描述

快陪练

在这里插入图片描述
算法题没啥难度,简单写一下
二叉树有三种遍历方式
前序遍历:根,左,右
中序遍历:左,根,右
后序遍历:左,右,根

发现规律没?左右的位置始终不变,前序遍历,根在前面,中序遍历,根在中间,以此类推。
在这里插入图片描述
前序遍历:A B C D E F
中序遍历:C B D A E F
后序遍历:C D B F E A

常用Linux命令
简单说几个,ls mkdir 面试就不用写了,简单的命令大家都会,top,free之类的写写

less — print LESS

less 按页或按窗口打印文件内容。在查看包含大量文本数据的大文件时是非常有用和高效的。你可以使用Ctrl+F向前翻页,Ctrl+B向后翻页。

ping

ping 通过发送数据包ping远程主机(服务器),常用与检测网络连接和服务器状态。

如 ping www.baidu.com

su — Switch User

su 用于切换不同的用户。即使没有使用密码,超级用户也能切换到其它用户。

top — Top processes

top命令会默认按照CPU的占用情况,显示占用量较大的进程,可以使用top -u 查看某个用户的CPU使用排名情况。

OSI七层模型
在这里插入图片描述
http请求方式与区别
(1)对参数的数据类型,GET只接受ASCII字符,而POST没有限制,允许二进制。

(2)GET在浏览器回退/刷新时是无害的,而POST会再次提交请求。

(3)GET请求只能进行url编码(application/x-www-form-urlencoded),而POST支持多种编码方式(application/x-www-form-urlencoded 或 multipart/form-data),可以为二进制使用多重编码。

(4)POST 比 GET 更安全,因为GET参数直接暴露在URL上,POST参数在HTTP消息主体中,而且不会被保存在浏览器历史或 web 服务器日志中。

(5)对参数数据长度的限制,GET方法URL的长度是受限制的,最大是2048个字符,POST参数数据是没有限制的。

(6)GET请求会被浏览器主动缓存,POST不会,除非手动设置。

(7)GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

(8)GET请求可被收藏为书签,POST不能。

http常见的状态码
在这里插入图片描述
我单写一篇文章来描述http状态码

200 OK //客户端请求成功

400 Bad Request //客户端请求有语法错误,不能被服务器所理解

401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用

403 Forbidden //服务器收到请求,但是拒绝提供服务

404 Not Found //请求资源不存在,eg:输入了错误的URL

500 Internal Server Error //服务器发生不可预期的错误

503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

访问网页的过程,越详细越好

详细过程单开一篇文章

反向打印链表的值
如链表的值为1-2-3-4,打印出的值为4 3 2 1

将值放在数组中,然后反向遍历数据输出,这种方法不太优雅

正确的方式如下,一个递归搞定

public Class Node {
	int value;
	Node next;
}
public static void printNode(Node node) {
	if (node == null) return;
	printNode(node.next);
	System.out.println(node.val);
}

主键用自增id好,还是uid好?

当然是自增id了,自主键的数据结构是B+树,用自增id不会造成树的分裂,uid不规则,会造成树的分裂,效率比较低

给一个数组有n个值,求m个值和为24的所有组合
回溯,DFS,算法均可,不写代码了,知道思路即可

数据单向链表中倒数第n个节点的值

我刚开始是,遍历一遍链表,求出长度,然后再遍历一变到n-k,结果告知这种方法效率比较低

后来想到,用2个指针,中间相隔n个距离,当一个指针到了尾节点时,另一个节点正好指向倒数第n个节点

其他就是类似一些string,stirngbuffer,stringbuild的区别
nio和bio的区别
抽象类和接口的区别、
在这里插入图片描述

展心展力

Java中byte,short,char,int,float各占几个字节
Java8种基本数据类型

整数类型:byte(1字节) short(2字节) int(4字节) long(8字节)
浮点类型:float(4字节) double(8字节)
字符类型:char(2字节)可以存储一个汉字
布尔类型:boolean
(JVM规范指出boolean当做int处理,也就是4字节,boolean数组当做byte数组处理,这样我们可以得出boolean类型占了单独使用是4个字节,在数组中是确定的1个字节)
如何将内容为整数的字符串解析为整数
Long.valueof()

关键字volatile的作用
不能保证原子性,只能保证可见性,有序性,我公号上对volatile的作用写的很清楚

String能否被继承,原因
不能,String类被final修饰

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

总结一下final关键字的作用

  1. final修饰类时,表明这个类不能被继承
  2. final修饰方法,表明方法不能被重写
  3. final修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象

ArrayLIst如何扩容
数组大小变为原来的1.5倍,将原来的内容复制到新数组

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    // 从这个看出新数组是原来数组大小的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

一个servlet被请求10次,会创建几个事例
只会创建一个实例

一般Servlet只初始化一次(只有一个实例)。对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此Servlet的service()方法,将这两个对象作为参数传递给该方法。如此重复以上的循环,但无需再调用init()方法。

异常处理

最后输出9,很简单的一道题

列举Spring MVC常用注解和含义(常用)
@Controller
@RequestMapping
@Autowired
@ResponseBody

Mybatis中$和#的区别,哪个能防止SQL注入
$底层用的是Statement ,字符串拼接SQL,可能会有SQL注入
#底层用的是PreparedStatement,使用预编译语句

Java线程生命周期图?
这个很重要,一定要多看看
在这里插入图片描述

列举你了解的JDK命令工具和JVM启动参数,并说明其用法

名称主要作用
jps显示指定系统内所有HotSpot虚拟机进程
jstat收集HotSpot虚拟机个方面的运行数据
jinfo显示虚拟机配置信息
jmap生成虚拟机的内存转储快照(heapdump)文件
jhat在浏览器上分析heapdump文件
jstack显示虚拟机的线程快照

-Xmx4550m 最大可用内存为4550m
-Xmx4550m 启动时分配的内存为4550m
-Xss 每个线程分配的内存大小

varchar char的区别
char(10) ,当输入的是“abc”这三个字符时,占用的空间一样是10个字符,包括7个空字符

varchar(10),当输入的是“abc”这三个字符时,占用的空间是3个字符,额外1个或2个字符用来记录字符的长度

varchar省空间,char效率高
char还有的优点如下:
一,存储很短的信息,比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的现在得不偿失。

二,固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。

三,十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。

主键和索引的区别

主键一定是唯一性索引,唯一性索引不一定就是主键
一个表中可以有多个索引,但只能有一个主键
主键列不允许为空值,索引列可以为空值
索引可以提高查询的速度

MySQL行锁和表锁的含义,并说明他们之间的区别
表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突概率高,并发度最低
行锁:开销大,加锁慢,会出现死锁;锁定粒度小,发生冲突概率低,并发度高
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般

MySQL服务占用CPU 100%,如何排查问题
查询慢SQL日志,找到执行慢的SQL语句,排查错误

事务隔离级别有哪些?
未提交读
提交读
重复读
序列化
在这里插入图片描述
LeetCode原题,不太难,直接上代码

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char a = s.charAt(i);
            if (stack.size() == 0) {
                stack.push(a);
                continue;
            }
            char peekChar = stack.peek();
            if ((peekChar == '(' && a == ')') || (peekChar == '[' && a == ']') ||
                    (peekChar == '{' && a == '}')) {
                stack.pop();
            } else {
                stack.push(a);
            }
        }
        return stack.size() == 0 ? true : false;
    }
}

在这里插入图片描述
LeetCode原题
将每个字符串排序一下,key=排序后的字符, value=原始的字符,放在map中即可

class Solution {
 
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            String key = sort(strs[i]);
            List<String> list = map.get(key);
            if (list == null) {
                list = new ArrayList<>();
                list.add(strs[i]);
                map.put(key, list);
            } else {
                list.add(strs[i]);
            }
        }
        List<List<String>> resultList = new ArrayList<>();
        for (List<String> list : map.values()) {
            resultList.add(list);
        }
        return resultList;
    }
 
    private String sort(String str) {
        char[] charArray = str.toCharArray();
        Arrays.sort(charArray);
        return new String(charArray);
    }
}

在这里插入图片描述
挺简单的一个SQL题,就不写了
在这里插入图片描述

京东

建了索引是否会用到
说几个自己熟悉的设计模式
画一个装饰者模式
反转链表
spring boot没有web.xml怎么运行?
netty
redis有几种基本数据类型?其中有序集合是啥?
string(字符串类型)
hash(散列类型)
list(列表类型)
set(集合类型)
zset(有序集合类型)

git fetch和git pull的区别

jmap和jstack的作用

这几个工具全记住得了,经常被问,jstack的详细作用我在公号Java识堂上写了,CPU100%的那篇文章

名称主要作用
jps显示指定系统内所有HotSpot虚拟机进程
jstat收集HotSpot虚拟机个方面的运行数据
jinfo显示虚拟机配置信息
jmap生成虚拟机的内存转储快照(heapdump)文件
jhat在浏览器上分析heapdump文件
jstack显示虚拟机的线程快照

宝贝格子

aop和ioc用了什么模式?
数据库优化策略
消除过多的if else 用什么模式?
搜索引擎原理
es
redis的五种基本数据类型是啥?
redis的哨兵机制

参考博客

boolean到底占用几个字节
[1]https://blog.csdn.net/YuanMxy/article/details/74170745

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java识堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值