Java面试经验(常见的面试题)持续更新~~

前言:

作为一名应届生,没有参加过培训机构,且现在行业要求水平也很高,找到一份让自己满意的工作还是挺不容易的。在没有高学历的加持下就只能靠自身过硬的技术了,以下是我面试中常见的一些问题,希望对大家有所帮助。

一、Java基础

1.1、重载和重写的区别(了解)

重载:

  发生在同一个类中,方法名必须相同,参数类型不同,个数不同, 顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。

重写:

  发生在父子类中,方法名,参数列表必须相同,返回值范围小于等 于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父 类方法访问修饰符为 private则子类就不能重写该方法

1.2、String和StringBuffer、StringBuilder的区别是什么?

String:

  String对象是不可变的。

StringBuffer:

  继承自 AbstractStringBuilder类,没有用 final关键字修饰,所以对象是可变的。
  StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程 安全的。

StringBuilder:

  继承自 AbstractStringBuilder类,没有用 final关键字修饰,所以对象是可变的。
  StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

1.3、==与 equals

== :

  它的作用是判断两个对象的地址是不是相等。即:判断两个对象是不是 同一个对象。(基本数据类型== 比较的是值,引用数据类型== 比较的是内存地址)。

equals():

  它的作用也是判断两个对象是否相等。但它一般有两种使用情况, 如下: 情况 1:类没有覆盖 equals()方法。则通过 equals()比较该类的两个 对象时,等价于通过“==”比较这两个对象。 情况 2:类覆盖了 equals()方法。一般,我们都覆盖 equals()方法来 两个对象的内容相等;若它们的内容相等,则返回 true(即,认为这两个对象相 等)。

1.4、接口和抽象类的区别是什么?

  1. 接口的方法默认是 public,所有方法在接口中不能有实现(Java8开始 接口方法可以有默认实现),抽象类可以有非抽象的方法。
  2. 接口中的实例变量默认是 final类型的,而抽象类中则不一定。
  3. 一个类可以实现多个接口,但最多只能实现一个抽象类。
  4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定。
  5. 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口 的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的 抽象,是一种行为的规范。
备注:

  在JDK8中,接口也可以定义静态方法,可以直接用接口名调用。实 现类和实现是不可以调用的。如果同时实现两个接口,接口中定义了一样的默认方法,必须重写,不然会报错。

1.5、什么是单例模式?有几种?

单例模式:

  某个类的实例在 多线程环境下只会被创建一次出来。
PS:单例模式有饿汉式单例模式、懒汉式单例模式和双检锁单例模式

饿汉式: 线程安全,一开始就初始化
懒汉式: 非线程安全,延迟初始化。
双检锁: 线程安全,延迟初始化。

1.6、集合

List(排列有序,可重复):
  1. ArrayList:
      结构:数组结构。
      特点:查询快,增删慢。
      线程:线程不安全。

  2. LinkedList:
      结构:链表结构。
      特点:增删快,查询慢。
      线程:线程不安全。

  3. Vector:
      结构:数组结构。
      特点:查询快,增删慢。
      线程:线程安全,但是效率很低。

Set(排列无序,不可重复):
  1. HashSet:
      底层:哈希表实现。

  2. TreeSet:
      底层:二叉树实现

  3. LinkedHashSet:
      底层:采用哈希表储存,并用双向链表记录插入顺序。

Map(无序、键不可重复,值可重复):
  1. HashMap(高效):
      底层:哈希表。
      特点:允许key值为null,value也可以为null。
      线程:非线程安全。

PS:如果需要满足线程安全,可以用 Collections的synchronizedMap方法使 HashMap具有线程安全的能力,或者使用 ConcurrentHashMap,HashTable

  1. HashTable(低效):
      结构:哈希表。
      特点:key、value都不允许为null。
      线程:线程安全。
  2. TreeMap:
      结构:二叉树。

性能:ConcurrentHashMap(线程安全)>HashMap>HashTable(线程安全)

1.7、什么是线程?线程和进程的区别?

线程: 是进程的一个实体,是 cpu调度和分派的基本单位,是比进程更小的 可以独立运行的基本单位。

进程: 具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作 系统进行资源分配和调度的一个独立单位。

特点: 线程的划分尺度小于进程,这使多线程程序拥有高并发性,进程在运行 时各自内存单元相互独立,线程之间 内存共享,这使多线程编程可以拥有更好 的性能和用户体验

1.8、创建线程有几种方式?

  1. 继承 Thread类
      通过 Thread类的 start()实例方法
  2. 实现 Runnable接口
  3. 实现 Callable接口

1.9、线程的基本方法有什么?

  1. 线程等待(wait):
      调用该方法的线程进入 WAITING 状态,只有等待另外线程的通知或被中断 才会返回,需要注意的是调用 wait()方法后,会释放对象的锁。因此,wait方 法一般用在同步方法或同步代码块中。
  2. 线程睡眠(sleep):
      sleep导致当前线程休眠,与 wait方法不同的是 sleep不会释放当前占 有的锁,sleep(long)会导致线程进入 TIMED-WATING 状态,而 wait()方法会导 致当前线程进入 WATING 状态.
  3. 线程让步(yield):
      yield会使当前线程让出 CPU执行时间片,与其他线程一起重新竞争 CPU 时间片。一般情况下, 优先级高的线程有更大的可能性成功竞争得到 CPU时 间片,但这又不是绝对的,有的操作系统对 线程优先级并不敏感。
  4. 线程中断(interrupt):
      中断一个线程,其本意是给这个线程一个通知信号,会影响这个线程内部的 一个中断标识位。这个线程本身并不会因此而改变状态(如阻塞,终止等)
  5. 等待其他线程终止(Join):
      join()方法,等待其他线程终止,在当前线程中调用一个线程的 join()方法, 则当前线程转为阻塞状态,回到另一个线程结束,当前线程再由阻塞状态变为就 绪状态,等待 cpu的宠幸.
  6. 线程唤醒(notify):
      Object类中的 notify()方法,唤醒在此对象监视器上等待的单个线程,如 果所有线程都在此对象上等待,则会选择唤醒其中一个线程,选择是任意的,并 在对实现做出决定时发生,线程通过调用其中一个 wait()方法,在对象的监视 器上等待,直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程, 被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。类 似的方法还有 notifyAll(),唤醒再次监视器上等待的所有线程。

1.10、死锁产生的条件以及如何避免?

死锁产生的四个必要条件:
  1. 互斥:一个资源每次只能被一个进程使用(资源独立)。
  2. 请求与保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放(不释放锁)。
  3. 不剥夺:进程已获得的资源,在未使用之前,不能强行剥夺(抢夺资源)。
  4. 循环等待:若干进程之间形成一种头尾相接的循环等待的资源关闭(死循环)。
避免死锁:
  1. 破坏”互斥”条件
  2. 破坏“请求和保持”条件
  3. 破坏“不剥夺”条件
  4. 破坏“循环等待”条件

二、数据库

2.1、事务是什么?

  是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整 体一起向系统提交,要么都执行.要么都不执行。事务是一个不可分割的工作逻辑单元。

2.2、事务的特性

  1. 原子性:
      事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。
  2. 一致性:
      当事务完成时,数据必须处于一致状态。
  3. 隔离性:
      对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。
  4. 持久性:
      事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的持久性。

2.3、 事务的隔离级别

  1. Readuncommitted 读未提交:
      一个事务可以读取另一个未提交事务的数据。
  2. Readcommitted 读已提交:
       一个事务要等另一个事务提交后才能读取数
  3. Repeatableread 可重复读(默认):
      就是在开始读取数据(事务开启)时,不再允许修改操作
  4. Serializable序列化:
      Serializable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以 避免脏读.不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库 性能,一般不使用。

2.4、 什么是索引?

   索引是帮助 MySQL高效获取数据的数据结构。
   索引就是加快检索表中数据的方法。

索引类型
  • 普通索引
       最基本的索引,它没有任何限制。
  • 唯一索引
       索引列的值必须唯一,但允许有空值。
  • 主键索引
       一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。
  • 全文索引
       主要用来查找文本中的关键字,而不是直接与索引中的值相比较。全文索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的 where语句 的参数匹配。
  • 组合索引
       多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段, 索引才会被使用。

2.5、SQL聚合函数

  1. avg(): 返回的是指定组中的平均值,空值被忽略。
  2. count(): 返回的是指定组中的项目个数。
  3. max(): 返回指定数据中的最大值。
  4. min(): 返回指定数据中的最小值。
  5. sum(): 返回指定数据的和,只能用于数字列,空值忽略。
  6. groupby(): 对数据进行分组,对执行完 groupby之后的组进行聚合函 数的运算,计算每一组的值。最后用 having去掉不符合条件的组, having子句中的每一个元素必须出现在 select列表中(只针对于 mysql)

2.6、SQL调优(例举6条)

  1. 应尽量避免在 where子句中使用!=或<>操作符,否则引擎将放弃使用 索引而进行全表扫描。
  2. 应尽量避免在 where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。(可以设置默认值 为0,然后用0替换null)
  3. 尽量避免在 where子句中使用 or来连接条件,否则将导致引擎放 弃使用索引而进行全表扫描。(可以用And或者union all 连接)
  4. 尽量避免模糊查询时使用前置百分号(可以使用后置)
  5. in 和 notin也要慎用,能用 between就不要用 in了(between 1and3)
  6. 任何地方都不要使用 select * from ,用具体的字段列表代替“ * ”,不要 返回用不到的任何字段

三、Web层

3.1、TCP与 UDP区别?

UDP:

  1. 是面向无连接,将数据及源的封装成数据包中,不需要建立连接
  2. 每个数据报的大小在限制 64k内
  3. 因无连接,是不可靠协议
  4. 不需要建立连接,速度快

TCP:

  1. 建立连接,形成传输数据的通道.
  2. 在连接中进行大数据量传输,以字节流方式
  3. 通过三次握手完成连接,是可靠协议
  4. 必须建立连接效率会稍低.聊天.网络视频会议就是 UDP

3.2、get与 post请求区别?

  1. get重点在从服务器上获取资源,post重点在向服务器发送数据;
  2. Get传输的数据量小,因为受 URL长度限制,但效率较高;
    Post可以传输大量数据,所以上传文件时只能用 Post方式;
  3. Get是不安全的,因为 URL是可见的,可能会泄露私密信息,如密码等;
    Post较 get安全性较高
  4. get方式只能支持 ASCII字符,向服务器传的中文字符可能会乱码。
    post支持标准字符集,可以正确传递中文字符。

3.3、http中重定向和请求转发的区别?

本质区别:
   转发是服务器行为,重定向是客户端行为。
重定向特点:
   两次请求,浏览器地址发生变化,可以访问自己 web之外的 资源,传输的数据会丢失。
请求转发特点:
   一次请求,浏览器地址不变,访问的是自己本身的 web资 源,传输的数据不会丢失。

四、Mybatis框架

4.1、什么是 Mybatis?

   Mybatis是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC, 开发时只需要关注 SQL语句本身,不需要花费精力去处理加载驱动.创建连接. 创建 statement等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。

4.2、#{}和${}的区别是什么?

  • #{}是预编译处理,$ {}是字符串替换。
  • Mybatis在处理#{}时,会将 sql中的#{}替换为?号,调用 PreparedStatement 的 set方法来赋值;
  • Mybatis在处理$ {}时,就是把${}替换成变量的值。
  • 使用#{}可以有效的防止 SQL注入,提高系统安全性。

4.3、Mybatis的一级.二级缓存

  1. 一级缓存:
       基于 PerpetualCache的 HashMap本地缓存,其存储作用 域为 Session,当 Sessionflush或 close之后,该 Session中的所有 Cache 就将清空,默认打开一级缓存且不能关闭。
  2. 二级缓存:
       二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache, HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定 义存储源,如 Ehcache。默认不打开二级缓存,要手动开启二级缓存,使用二 级缓存属性类需要实现 Serializable序列化接口(可用来保存对象的状态),可在它 的映射文件中配置< cache/>。

五、Spring框架

5.1、Spring是什么?

   Spring是一个轻量级的 IoC和 AOP容器框架。

  1. IOC:
       IOC,控制反转,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系。
  2. AOP:
      面向切面编程,不修改源代码的情况下进行功能增加。(JDK代理模式)

5.2、spring常用的注解

@Service: 用于标注业务层组件.
@Controller: 用于标注控制层组件
@Repository: 用于标注数据访问组件,即 DAO组件。
@Component: 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Resource: 默认按名称装配,当找不到与名称匹配的 bean才会按类型装配。
@Autowired: 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier 注解一起使用。如下:@Autowired@Qualifier(“personDaoBean”)存在多个实例 配合使用@Scope用于指定 scope作用域的(用在类上)
@PostConstruct: 用于指定初始化方法(用在方法上)
@PreDestory: 用于指定销毁方法(用在方法上)
@DependsOn: 定义 Bean初始化及销毁时的顺序
@Primary: 自动装配时当出现多个 Bean候选者时,被注解为 @Primary的 Bean 将作为首选者,否则将抛出异常

5.3、Spring基于 xml注入 bean的几种方式

(1)Set方法注入;
(2)构造器注入:

  1. 通过 index设置参数的位置;
  2. 通过 type设置参数类型;
  3. 通过 name注入;

(3)静态工厂注入;
(4)实例工厂;

六、数据结构

七、Linux

八、项目管理

8.1、开发模型

  1. 瀑布模型:
       有明确需求,在开发过程中严格按照需求一步一步进行开发。
  2. 敏捷开发:
       先将用户最关心的软件模型做出来,先上线使用,然后在实际场景中发现不足再加以修改,再不断进行版本迭代。(适合前期需求不太明确,创新项目)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值