自己整理的一些面试题

前言

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

正文

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

  • http属于应用层协议,他的下层是传输层(包括TCP,UDP都是传输层协议)
    网际层协议:IP协议、ICMP协议、ARP协议、RARP协议。
    传输层协议:TCP协议、UDP协议。
    应用层协议:FTP、Telnet、SMTP、HTTP、RIP、NFS、DNS。
  • TCP面向连接(传输前需要在发送端和接受端建立连接);支持IP环境下的可靠传输(可靠的原因:能保证字节流无差错的传递给接受端,而且在发送端传递数据包给接受端时,接受端也会回传数据包;这样能保证数据正确性和数据顺序);用于大规模数据传输(采用流模式);速度慢花销大(建立连接需要花费时间和资源)。多用于文件,图片,远程登录等传输。
  • UDP面向非连接;传输不可靠(传输时不需要和接受端建立连接,发送数据时不管接收端是否能接受);用于小规模数据的传输;速度快;多用于即时通讯,直播等。
  • socket套接字,用于描述一个IP地址和一个端口,在双向通讯中(发起方和接受方),应用程序通过“套接字”向网络发送请求和应答。

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

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

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

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

  • 事务就是把多件事情当做一件事情来处理。是数据库操作的最小单元,是作为单个逻辑工作单元执行的一系列操作;要么都执行、要么都不执行;事务是一组不可再分割的操作集合。具有原子性、一致性、隔离性、持久性。(粗略回答)
  • Serializable(串行化):可避免脏读、不可重复读、幻读的发生
    Repeatable read(可重复读):可避免脏读、不可重复读的发生。
    Read committed(读已提交):可避免脏读的发生
    Read uncommitted(读未提交):最低级别,任何情况下都无法保证。(粗略回答)

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的意思?

  • GET: 请求指定的页面信息,并返回实体主体。
  • HEAD: 只请求页面的首部。
  • POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
  • PUT: 从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE: 请求服务器删除指定的页面。
  • PATCH: 实体中包含一个表,表中说明与该URI所表示的原内容的区别。

12.ddl和dml的区别?

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

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

  • select avg(score), number from table group by number having avg(score) > 90

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

DEAIOPM`O(K`QZ}K$_H({53.png
  • INNER JOIN(内联):两个表a,b 相连接,取出符合连接条件的数据,数据集C
  • LEFT JOIN(左联):先返回左表的所有行,再加上符合连接条件的匹配行,数据集A1+数据集C
  • RIGHT JOIN(右联):先返回右表的所有行,再加上符合连接条件的匹配行,数据集B1+数据集C

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

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

  • 用volatile关键字修饰一个共享变量,让所有的线程监听这个共享变量,当这个共享变量发生变化的时候,线程感知到其变化并执行相应的业务。
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();
    }
}
  • 使用wait()、notify()
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();
    }
}
  • 使用JUC(java util concurrent)工具类的CountDownLatch,CountDownLatch多用于主线程需要等待子线程执行完毕后再执行的场景。
    CountDownLatch构造器的计数值(new CountDownLatch(1)的“1”)实际为闭锁时需要等待执行的线程数,这个值在初始化设置后不能进行更改;
    主线程先调用CountDownLatch.await(),使主线程阻塞,直至子线程全部执行完毕。
    子线程执行完毕后调用CountDownLatch.countDown()方法来表示自己执行完毕;每调用一次countDown()方法,开锁前需要执行操作的线程数count减1,当count=0时,主线程就会通过阻塞方法await(),恢复执行任务。所以count值也可以被看作是主线程需要等待执行的子线程数。
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
  • 新建状态
  • 就绪状态
    线程调用start()方法,线程就位于可运行池中,等待获取cpu执行权。
  • 运行状态
    就绪状态的线程获取到执行机会,调用线程对象的run()方法。
  • 阻塞状态
    线程因为某些原因暂时放弃了对cpu的执行权,暂时停止运行。阻塞状态分三种:
    等待阻塞:调用wait()方法后,线程释放其所持有的锁,被jvm放入等待池,只有调用notify()和notifyAll()方法时线程才能再次进入就绪状态,等待被调用。
    同步阻塞:当其他线程持有锁时,jvm会把当前线程设置为阻塞状态,只有线程获取到“同步锁”时,线程才能转入就绪状态。
    其他阻塞:调用sleep()或join()或者发出I/O请求,jvm会将线程设置为阻塞状态,只有当sleep()超时,join()等待其他线程终止或超时,I/O处理完毕,线程才能转入就绪状态。
  • 死亡状态
    线程执行完毕或因为异常退出了run()方法,线程生命周期就结束了。

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

  • 跨域问题是指浏览器对js的同源限制,比如在a.com不能调用b.com的资源。解决方案:jsonp,利用iframe,script,img不受同源限制来实现(粗略回答)。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容