Java初中级面试题

Java初中级面试题

1.1. 初级招聘面试题

1.1.1. 计算机基础

  • 说说进程,线程之间的区别? 什么是多线程上下文切换

    进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程.进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高.线程是进程的一个实体,是cpu调度和分派的基本单位,是比程序更小的能独立运行的基本单位.同一进程中的多个线程之间可以并发执行.在Linux中,进程也称为Task。
    多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU执行权的线程的过程.

  • 谈一谈 TCP 与 UDP 的区别。

    TCP与UDP都是传输层的协议,且都用端口号标识数据所达的进程。
    TCP提供的是面向连接服务,提供可靠交付。且具有流量控制和拥塞控制。可用于可靠要求高的场合如:SMTP,FTP,HTTP等
    UDP提供的是无连接服务,提供不可靠交付,且无确认机制。主要用于即时强的场合如:视频聊天,语音电话等
    TCP/IP 三次握手四次挥手解决什么问题
    三次握手:网络不稳定性,可能导致重复连接存在,三次握手客户端可以判断请求是否旧的请求,如果是旧请求可以发送abort中断指令终止该连接
    四次挥手:避免关闭连接过程中,还有数据未发送处理完。

  • 谈一谈 DNS 域名系统的工作原理

    DNS(Domain Name System,域名系统)
    因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)
    每个IP地址都可以有一个主机名,主机名由一个或多个字符串组成,字符串之间用小数点隔开。有了主机名,就不要死记硬背每台IP设备的IP地址,只要记住相对直观有意义的主机名就行了。这就是DNS协议所要完成的功能。
    主机名到IP地址的映射有两种方式:DNS
    1)静态映射,每台设备上都配置主机到IP地址的映射,各设备独立维护自己的映射表,而且只供本设备使用;
    2)动态映射,建立一套域名解析系统(DNS),只在专门的DNS服务器上配置主机到IP地址的映射,网络上需要使用主机名通信的设备,首先需要到DNS服务器查询主机所对应的IP地址。
    请叙述一下并发与并行概念区别?
    并行是指两个或多个事件在同一时刻发生,并发是指两个或多个事件在同一事件间隔内发生。

1.1.2. Java语言基础

  • 面向对象特征,多态的优点

    封装,继承,多态.
    多态的优点
    可替换性:多态对已存在代码具有可替换性.
    可扩充性:增加新的子类不影响已经存在的类结构.
    接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现的.
    接口和抽象类的区别
    抽象类:
    抽象类可以有默认的方法实现。
    子类使用extends关键字来继承抽象类.如果子类不是抽象类,子类需要提供抽象类中所声明方法的实现。
    抽象类中可以有构造器,接口中不能
    抽象类不能被实例化
    抽象方法可以有public,protected和default等修饰
    一个子类只能存在一个父类
    抽象类中添加新方法,可以提供默认的实现,因此可以不修改子类现有的代码
    接口:
    java 8之前,接口中不存在方法的实现
    子类使用implements来实现接口,需要提供接口中所有声明的实现.
    接口默认是public,不能使用其他修饰符
    一个子类可以存在多个接口
    如果往接口中添加新方法,则子类中需要实现该方法
    什么是不可变对象?好处是什么?
    不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象,如 String、Integer及其它包装类.不可变对象最大的好处是线程安全.

  • Java创建对象的几种方式

    new创建新对象
    通过反射机制
    采用clone机制
    通过序列化机制

  • java中 “= =” 和eqauls()的区别?

    "= = " 是运算符,用于比较两个变量是否相等,对于基本类型而言比较的是变量的值,对于对象类型而言比较的是对象的地址.

  • 深拷贝和浅拷贝的区别是什么?

    浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象
    深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍

  • final有哪些用法?

    被final修饰的类不可以被继承
    被final修饰的方法不可以被重写
    被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
    被final修饰的方法,JVM会尝试将其内联,以提高运行效率
    被final修饰的常量,在编译阶段会存入常量池中.

int和Integer的区别?

Integer是int的包装类型,在拆箱和装箱中,二者自动转换.int是基本类型,直接存数值;而integer是对象;用一个引用指向这个对象.由于Integer是一个对象,在JVM中对象需要一定的数据结构进行描述,相比int而言,其占用的内存更大一些.

String,StringBuffer和StringBuilder区别?

String是字符串常量,final修饰;
StringBuffer字符串变量(线程安全);StringBuilder 字符串变量(线程不安全).此外StringBuilder和StringBuffer实现原理一样,都是基于数组扩容来实现的

3*0.1==0.3返回值是什么

false,因为有些浮点数不能完全精确的表示出来.

了解反射吗? 谈谈反射机制的优缺点

反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。
通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性
优点 : 可以让咱们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利
缺点 :让我们在运行时有了分析操作类的能力,这同样也增加了安全问题。比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍差点,不过,对于框架来说实际是影响不大的。

说说 List, Set, Queue, Map 四者的区别?

List(对付顺序的好帮手): 存储的元素是有序的、可重复的。
Set(注重独一无二的性质): 存储的元素是无序的、不可重复的。
Queue(实现排队功能的叫号机): 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。
Map(用 key 来搜索的专家): 使用键值对(key-value)存储,类似于数学上的函数 y=f(x),“x” 代表 key,“y” 代表 value,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。

了解ConcurrentHashMap吗?

Java8 中的 ConcurrentHashMap 使用的 Synchronized 锁加 CAS 的机制。结构也由 Java7 中的 Segment 数组 + HashEntry 数组 + 链表 进化成了 Node 数组 + 链表 / 红黑树,Node 是类似于一个 HashEntry 的结构。它的冲突再达到一定大小时会转化成红黑树,在冲突小于一定数量时又退回链表。

1.1.3. 数据库基础

CHAR 和 VARCHAR 的区别?

CHAR和VARCHAR类型在存储和检索方面有所不同
CHAR列长度固定为创建表时声明的长度,长度值范围是1到255当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。

事务特性

原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。
一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态
隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,
持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
什么是事务的隔离级别?MySQL的默认隔离级别是什么?
由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

为什么使用B+Tree?

索引查找过程中就要产生磁盘I/O消耗,主要看IO次数,和磁盘存取原理有关。
根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,
将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入
局部性原理与磁盘预读

drop,delete与truncate的区别

drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。
(1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。
(2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。
(3) 一般而言,drop > truncate > delete
(4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view
(5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。
(6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。
(7) delete语句为DML(Data Manipulation Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。
(8) truncate、drop是DDL(Data Define Language),操作立即生效,原数据不放到 rollback segment中,不能回滚
(9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老是想触发trigger,还是用delete。
(10) Truncate table 表名 速度快,而且效率高,因为: truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
(11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。
(12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。

1.1.4. 数据结构与算法

如何实现一个高效的单向链表逆序输出?

class Solution<T> {

    public void reverse(ListNode<T> head) {
       if (head == null || head.next == null) {
           return ;
       }
       ListNode<T> currentNode = head;
       Stack<ListNode<T>> stack = new Stack<>();
       while (currentNode != null) {
           stack.push(currentNode);
           ListNode<T> tempNode = currentNode.next;
           currentNode.next = null; // 断开连接
           currentNode = tempNode;
       }

       head = stack.pop();
       currentNode = head;

       while (!stack.isEmpty()) {
           currentNode.next = stack.pop();
           currentNode = currentNode.next;
       }
    }
}

class ListNode<T>{
    T val;
    public ListNode(T val) {
        this.val = val;
    }
    ListNode<T> next;
}

快排算法实现

快排排序:是对冒泡排序的一种改进,基本思想是选取一个记录作为枢轴,经过一趟排序,
将整段序列分为两个部分,其中一部分的值都小于枢轴,另一部分都大于枢轴。然后继续对这两部分继续进行排序,从而使整个序列达到有序

  • 快排排序:是对冒泡排序的一种改进,基本思想是选取一个记录作为枢轴,经过一趟排序,
  • 将整段序列分为两个部分,其中一部分的值都小于枢轴,另一部分都大于枢轴。
  • 然后继续对这两部分继续进行排序,从而使整个序列达到有序
public static void sort(int[] data) {
        if (data.length <= 1) {
            return;
        }

        quickSort(data, 0, data.length - 1);
    }

    private static void quickSort(int[] data, int p, int n) {
        if (p >= n) {
            return;
        }

        //获取分区点
        int point = partition(data, p, n);
        quickSort(data, p, point - 1);
        quickSort(data, point + 1, n);
    }

    private static int partition(int[] data, int p, int r) {
        //分区点
        int point = data[r];
        int i = p;
        for (int j = p; j < r; j++) {
            if (data[j] < point) {
                if (i == j) {
                    i++;
                } else {
                    int tmp = data[i];
                    data[i++] = data[j];
                    data[j] = tmp;
                }
            }
        }

        int tmp = data[i];
        data[i] = data[r];
        data[r] = tmp;
        return i;
    }

    public static void printAll(int[] data) {
        for (int datum : data) {
            System.out.print(datum + ",");
        }
        System.out.println(" ");
    }

    public static void main(String[] args) {
        int[] data = {5, 2, 1, 5, 7, 4, 8, 9, 0, 3};
        sort(data);
        printAll(data);
    }

1.2. 中级招聘面试题

1.2.1. 计算机

浏览器url请求中间经历哪些环节最终到达服务器。

浏览器查找域名的 IP 地址,本地域名解析、内部域名、运用商域名解析
本地网络、路由器、公网出口到服务器网络,经过网络7层协议,经过http --> SSL/STL(会话层) --> TCP/IP(传输层/网络层) --> 数据链路层 --> 物理层
https协议加解密及证书认证
http请求交互并返回数据
HTTP1.1与HTTP2.0有什么区别。
http1.1把所有请求和响应作为纯文本不同,http2 使用二进制框架层把所有消息封装成二进制,且仍然保持http语法,消息的转换让http2能够尝试http1.1所不能的传输方式
Http1.1 流水线和队头阻塞,单向请求只能由客户端发起。
Http2.0 优点:首部压缩,多路复用,请求优先级,服务器推送。
Http2.0 原理:原理:在二进制分帧层上,HTTP2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中HTTP1.x的首部信息会被封装到Headers帧,而Request Body则封装到Data帧。

谈谈HTTPS通信

客户端通过发送 Client Hello 报文开始 SSL通信。报文中包含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
服务器可进行 SSL通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
之后服务器发送 Certificate 报文。报文中包含公开密钥证书。
最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL握手协商部分结束。
SSL第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
服务器同样发送 Change Cipher Spec 报文。
服务器同样发送 Finished 报文。
服务器和客户端的 Finished 报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
应用层协议通信,即发送 HTTP 响应。
最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP的通信。

1.2.2. 数据库

InnoDB索引和MyISAM索引的区别

一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主

B树与B+树区别

B 树的所有节点既存放 键(key) 也存放 数据(data);而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key
B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点
B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。

查询哪些情况会导致索引失败

左前缀原则, 用了左模糊导致索引失败 select * from table where field like ‘%name’;
查询字段用SQL函数,导致索引失败。 select * from table where field - 10 = 9;
查询的数量是大表的大部分,应该是30%以上。
联合索引第一个参数没有作为条件,则索引失效。 UNIQUE KEY(‘owner_no’,‘bill_no’) , 查询时候只bill_no作为条件。
索引无法存储null值,所以where的判断条件如果对字段进行了null值判断,将导致数据库放弃索引而进行全表查询
索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引

1.2.3. Java试题

死锁是怎么产生的

1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

synchronized和ReentrantLock的区别

synchronized是和if、else、for、while一样的关键字,ReentrantLock是类,这是二者的本质区别。既然ReentrantLock是类,那么它就提供了比synchronized更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock比synchronized的扩展性体现在几点上:
(1)ReentrantLock可以对获取锁的等待时间进行设置,这样就避免了死锁
(2)ReentrantLock可以获取各种锁的信息
(3)ReentrantLock可以灵活地实现多路通知
另外,二者的锁机制其实也是不一样的: ReentrantLock底层调用的是Unsafe的park方法加锁,synchronized操作的应该是对象头中 mark word.

什么是线程局部变量ThreadLocal

线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java提供ThreadLocal类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。

说一下Java线程池有哪些参数,分别做什么用

核心线程数:启动保持最小线程数
最大线程数:任务队列满后,启用剩余线程【最大线程数-核心线程数】
活跃时间KeepAliveTime及时间单位:最大线程数空闲时间,超过自动销毁,保持核心线程数
任务队列: 等待执行的任务
线程工厂名称:定义线程池名称
拒绝策略:任务池已满且无线程可处理,执行拒绝策略,包括:丢弃策略、拒接策略、阻塞策略。

Java的JVM内存布局

一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈 和 本地方法栈

1.2.4. 数据结构与算法

什么是布隆过滤器,布隆过滤器使用场景?
布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于 1970 年提出的。我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值