自己整理的一些面试题

2019-05-25  本文已影响0人  幽游不想吃饭

前言

最近面试遇到的一些面试题,归纳了一些比较有代表性的基础题,这里只归纳了基础题,一部分题给出了答案。问到多次的问题我会在题目后面标注。这次面试频率问到最高的问题就是关于多线程和单点登录的(每次面试都问了),还有就是你做过的项目里面的技术栈也是面试官的突破口。
注:某些答案在后面表明了“粗略回答”的,都是需要你根据答案再去了解更深的原理。

正文

1.http协议下层协议是什么?TCP协议和UDP协议最本质的区别?socket套接字的作用?

2.springMVC、springboot、mybatis等框架的优缺点(mybatis和hibernate的区别问到了两次)

3.公司单点登录的实现(多次)?

e.g. 这里主要是考察你是否熟悉单点登录的原理和公司实现单点登录的方案。

4.数据库事务是什么?数据库的隔离级别有几种?

5.Servlet生命周期及工作原理是什么?

6.HTTP Request进入到Tomcat中执行,请求处理流程如何?如何找到对应的Application并进行请求处理?

7.一个表名为table的表有三个字段,id,name,sex,id为唯一主键,需要一个delete语句保证执行后,表中name+sex的值唯一(sql题)。

delete from table where id not in (select min(id) from table group by name,sex);

8.excption和error的区别?

9.session和cookie的区别?如何做到会话保持?

10.将一个变量传入一个方法的形参,这个方法会改变变量的值并返回,请问这是值传递还是引用传递?

11.分别说下GET,POST,PUT,DELETE的意思?

12.ddl和dml的区别?

ddl 数据定义语言,用于直接对数据库的对象(database,table)进行操作,例如增删表/列等(drop,alter,create);
dml 数据操纵语言,用于对表的数据进行操作,例如(select,delete,insert,update)

13.一张分数表(table),学号(number),分数(score),查出平均分大于90的人的学号和平均分数?

14.数据库内联、左联和右联的区别?

DEAIOPM`O(K`QZ}K$_H({53.png

15.一个线程执行完,怎么通知其他线程执行?一个线程执行完之后如何通知其他线程执行(如何实现线程通信)?

这里列举了三种方式,应该有更好的实现方式(比如condition和blockingqueue)。

public class test {
    static volatile boolean notice = false;

    public static void main(String[] args) {
        List<String> list = new ArrayList();
        Thread a = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    //保证b线程能抢夺到执行机会
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                list.add("a");
                System.out.println("线程A向list中添加数据,list中元素个数为:" + list.size());
                if (list.size() == 5) {
                    notice = true;
                }
            }
        });
        Thread b = new Thread(() -> {
            while (true) {
                if (notice) {
                    System.out.println("线程B收到通知,开始执行自己的业务...");
                    list.add("b");
                    System.out.println("list中元素个数为:" + list.size());
                    break;
                }
            }
        });

        //先启动b
        b.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        a.start();
    }
}
public class test {

    public static void main(String[] args) {
        //创建锁对象
        Object lock = new Object();
        List<String> list = new ArrayList<>();

        Thread a = new Thread(() -> {
            synchronized (lock) {
                for (int i = 0; i < 10; i++) {
                    list.add("a");
                    System.out.println("A线程向list中添加数据,list数据个数为:" + list.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (list.size() == 5) {
                        try {
                            //将a线程放入等待池,让出执行机会
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        Thread b = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程b获取到执行机会,开始执行任务。。。");
                list.add("b");
                System.out.println("list数据个数为:" + list.size());
                lock.notify();
            }
        });

        //先启动a
        a.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        b.start();
    }
}
public class test {

    public static void main(String[] args) {
        //1表示闭锁时需要等待执行的线程数量,等同于子线程数量
        CountDownLatch countDownLatch = new CountDownLatch(1);
        List<String> list = new ArrayList<>();

        Thread a = new Thread(() -> {
           for(int i = 0; i < 10; i++){
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               list.add("a");
               System.out.println("线程A向list添加数据,list数据个数为:" + list.size());

               if(list.size() == 5){
                   countDownLatch.countDown();
               }
           }
        });

        Thread b = new Thread(() -> {
            while (true){
                if(list.size() != 5){
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程b取得执行机会,开始执行任务....");
                list.add("b");
                System.out.println("list数据个数为:" + list.size());
                break;
            }
        });

        //先启动b
        b.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        a.start();
    }
}

16.oom如何调优?说下jvm的理解

17.两个对象多对多如何设计表结构

建立中间表,存入两个对象表关联的值(粗略回答)。

18.线程生命周期

C{LWP6~HAPN[)P@6D]4QNX2.png

19.接触过跨域问题吗?分布式系统如何解决跨域问题?

上一篇下一篇

猜你喜欢

热点阅读