第一次面试

  1. 谈谈对java的看法
  1. Java是一种面向对象的语言,语言特性有封装,继承,多态,泛型,Lamda表达式等;
  • 封装:将属性的修饰符设为private,限制访问;
    生成getter/setter方法;
    对getter/setter方法进行属性控制,如判空,逻辑操作
  • 继承:比如a继承了b,而b又继承了c,那么a同时拥有b和c 的方法和属性
    继承的好处:有利于代码重用,便于维护和扩展。
  • 多态:多态即同一个对象在不同时刻体现不同的状态
    多态存在的条件:
    a.必须有继承关系
    b.必须重写父类方法
    c.父类引用必须指向子类对象
    多态的好处:有利于面向对象,更有利于维护和扩展,简化了代码雍余,使开发效率大大提高
  1. 第二个特性:支持跨平台,一次书写导出运行(write once,run anywhere),能够实现跨平台是因为JVM,编写源文件,通过javac编译成字节码.class文件,然后JVM再翻译成对应的机器码来运行;
  2. 第三个特性:垃圾回收器(GC),程序员不用关注内存的分配和回收。
  1. 重载和重写的区别
  • 重载(overload):发生在本类,方法名相同,参数列表不同,与返回值无关,只和方法名,参数列表,参数的类型有关
    好处:减少函数的数量,避免命名的污染,可应对不同的需求
  • 重写(override):一般都是表示子类和父类之间的关系,其主要的特征是:方法名相同,参数相同,但是具体的实现不同。
    好处:子类可以根据需要,定义特定于自己的行为

抽象类和接口的区别

  • 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
  • 类可以实现很多个接口,但是只能继承一个抽象类
  • 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
  • 接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
  • 接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
  • 接口没有构造方法,抽象类可以用构造方法
    -接口是特征,是对一种行为的抽象,抽象类是内容,是对一种事物的抽象

相同:

  • 抽象类和接口都不可以被实例化
  • 都位于继承的顶端,用于被其他类实现或者继承
  • 都包含抽象方法,子类必须覆盖并实现这些方法

不同

  • 抽象类的声明是abstract;接口是interface
  • 子类继承抽象类用extends,如果该子类不是抽象类那么必须提供抽象类所有声明放的实现;子类实现接口用implements,实现类必须提供接口所有声明方法的实现
  • 抽象类可以有构造方法;接口不能
  • 抽象类可以用任意访问修饰符;接口默认使用public不能用private或者protected
  • 一个类只能继承一个抽象类;可以实现多个接口

3.为什么要去学习SpringBoot

Spring 为我们提供了非常灵活的配置方式,基于 XML、注解、Java 配置、这些配置我们可以随意选用搭配,但是随之而来的就是复杂性的提高,注册各种 Bean,注入各种 Bean,配置事务,数据源,数据库管理对象、前端控制器,视图解析器,关键是像注册和注入 Bean 是每一个模块都需要重复的动作
而springBoot的好处:
1.自动配置
2.依赖管理变得简单
3.内置 Tomcat、Jetty 容器

4.软件的开发流程

需求分析
概要设计
详细设计
编码
测试
软件交付
验收
维护

5.聊一下java中的集合

List集合:有序,可以重复的集合,三个典型实现:

  • List list1 = new ArrayList():底层数据结构是数组,查询快,增删慢;线程不安全,效率高
  • List list2 = new LinkedList():底层数据结构是链表,查询慢,增删快;线程不安全,效率高
  • List list3 = new Vector():底层数据结构是数组,查询快,增删慢;线程安全,效率低,几乎已经淘汰了这个集合

Set 集合

  • HashSet:速度最块;没有明显的保存元素的顺序;不可重复;集合元素可以为 nullL,但只能放一个null;
  • TreeSet:有序、不可重复,必须放入同样类的对象(默认会进行排序)
  • LinkedHashSet:有序、先进先出、不可以重复,因为底层采用 链表 和 哈希表的算法。链表保证元素的添加顺序,哈希表保证元素的唯一性

Map集合

  • HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
    扩展:HashMap 的长度为什么是2的幂次方
    为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法。
  • LinkedHashMap: LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
  • HashTable: 数组+链表组成的,数组是 HashTable 的主体,链表则是主要为了解决哈希冲突而存在的
  • TreeMap: 红黑树(自平衡的排序二叉树)

6.软件工程这门课程对你有什么帮助

7.什么是解耦

写的代码尽可能专一的完成一个任务,且各段代码尽量模块化互相独立。
低耦合也就是尽可能的使每个模块之间或者每个类之间再或者是每个方法之间的关联关系减少,这样可以使各自尽可能的独立,一个地方出错,不会影响全部,更能提高代码的重用性.

8.Mybatis的好处

把Sql语句从Java中独立出来。
封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复工作。
自己编写Sql语句,更加的灵活。
入参无需用对象封装(或者map封装),使用@Param注解

9.还用过Mybatis的哪些高级操作

一级缓存和二级缓存

  • 一级缓存是sqlsession级别的缓存,意思是只要sqlsession没有flush或者close的时候,证明它是存在的。
    一级缓存原理
    首先用户第一次查询sql时候,sql的查询结果就会被写入sqlsession一级缓存中的,这样用户第二次查询时,直接从一级缓存取出数据,而不是数据库。
    如果用户出现commit操作时,比如增删改查,这时sqlsession中一级缓存区域就会全部清空。清空之后再次去一级缓存查找不到,就会走数据库进行查找,然后再次存到缓存中。注意:缓存使用的数据结构也是map的。
  • 二级缓存*
    二级缓存的范围就是mapper级别,也就是mapper以命名空间为单位创建缓存数据结构,也是map结构。二级缓存的多个sqlsession去操作同一个mapper映射的sql语句,然后多个sqlsession可以共用二级缓存这样的一个思想,它是跨sqlsession的。

MyBatis的延迟加载
何为延迟加载
Mybatis可以进行多表查询,实现对象的关联查询。而在实际开发过程中很多时候我们并不需要在加载用户信息时就一定要加载他的订单信息。此时就是我们所说的延迟加载。
作用
在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
好处
先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
应用
通常情况下,一对一查询不需要做延迟加载,一对多需要做延迟加载

MyBatis使用generatorConfig.xml逆向工程生成实体、mapper接口和.xml文件
如何操作

10.谈谈对Spring的理解

  • Spring是轻量级框架,作用:管理bean的生命周期和框架集成
  • 两大核心:
    IOC/DI:控制反转/依赖注入,把dao层注入到service层,再把service层反转给action层
    AOP:面向切面编程
  • Spring的事务管理:
    编程式事务管理:极大灵活性,但是难以维护
    声明式事务管理:把业务实现和事务管理分离,用注解和配置文件用来管理事务
  • IOC在项目中的作用:解决对象之间的依赖问题,把所有bean的依赖关系通过注解和配置文件关联起来,降低了耦合度
  • Spring的配置文件的内容
    开启注解驱动
    事务管理器
    开启注解功能,并配置扫描包
    配置数据库
    配置SQL会话工厂,别名映射文件

11.什么是Mybatis的接口绑定,有什么好处?

Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。

12.对线程多线程的理解

并行与并发
并发:指两个或多个事件在同一个时间段内发生
并行:指两个或多个事件在同一时刻发生(同时发生)

进程与线程

  • 进程:是内存中运行的一个应用程序,每个进程存在一个独立的内存空间,进程是系统运行程序的基本单位,进程是程序的一个执行过程
  • 线程:是操作系统能够调度的最小单位,是进程中的一个执行单元
    线程与进程的关系:一个进程至少有一个线程,可以有多个线程,每条线程并行执行不同的任务,所有的线程共享一片相同的内存空间,每个线程都有独立的栈内存来存储本地数据

线程的生命周期

在这里插入图片描述

怎么实现线程

  • 继承Thread类,重写run方法
  • 实现Runnable接口,重写run方法
  1. 因为java不支持多重继承,避免单继承的局限性
  2. 增强程序扩展性,降低耦合性
    所以实现Runnable接口更好

run()和star()的区别

star()开启了一条新线程,在star的内部调用了run()方法,和直接调用run()方法不一样,直接调用还是使用原线程,并没有开启一条新线程。

Java内存模型JMM

缓存一致性协议,用来定义数据读写的规则
定义了线程工作内存和主内存之间的抽象关系:线程之间的共享变量存在主内存,每个线程都有一个私有的本地栈内存来存储本地数据
关于JMM的一些同步的约定
线程解锁前,必须把共享变量立刻刷回主存
线程加锁前,必须读取主存中的最新值到工作内存中
加锁和解锁必须是同一把锁

volatile 变量是什么

是一个特殊的修饰符,只能用于成员变量,在java并发程序缺少同步类的情况下,多线程对成员变量的操作对其他线程是透明的,volatile保证下一个读操作会在上一个写操作之后发生

Java中什么是竞态条件? 举个例子说明。

竞态条件会导致程序在并发情况下出现一些bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了, 那么整个程序就会出现一些不确定的bugs。这种bugs很难发现而且会重复出现,因为线程间的随机竞争。

Java多线程中调用wait() 和 sleep()方法有什么不同?

Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。

Join方法

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。

wait和sleep方法的不同

在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行

产生死锁的四个必要条件:

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

后台线程是什么?有什么应用?

后台线程,就是在后台工作的线程,它的任务是为其他线程提供服务,也叫做“守护线程”与“精灵线程”。通过在start()方法调用前,调用setDeamon(true)方法,将线程设置为后台线程。后台线程会在前台线程死亡后由JVM通知死亡。
后台线程最大的应用就是垃圾回收线程,它是一个典型的后台线程。

多线程操作会发生什么情况?

  • 安全性问题:在单线程系统上正常运行的代码,在多线程环境中可能会出现意料之外的结果。
  • 活跃性问题:不正确的加锁、解锁方式可能会导致死锁or活锁问题。
  • 性能问题:多线程并发即多个线程切换运行,线程切换会有一定的消耗并且不正确的加锁。

什么是死锁

由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行

如何避免死锁

  • 加锁顺序:确保所有的线程都是按照相同的顺序获得锁
  • 加锁时限
  • 死锁检测

什么是可重入锁

ReentrantLock与Synchronized都是可重入锁。可重入意味着,获得锁的线程可递归的再次获取锁。当所有锁释放后,其他线程才可以获取锁。可重入锁:可以多次获取相同的锁

ReentrantReadWriterLock读写锁

读写锁是一种非排它锁, 一般的锁都是排他锁,就是同一时刻只有一个线程可以访问,比如Synchronized和Lock。读写锁就多个线程可以同时获取读锁读资源,当有写操作的时候,获取写锁,写操作之后的读写操作都将被阻塞,直到写锁释放。读写锁适合写操作较多的场景,效率较高。

14.你还有什么要问我的吗

  • java开发这个岗位的具体要求是什么
  • 自己还有什么需要加强的地方
  • 前面没回答好的问题需要怎么去学习
  • 入职后是不是有一些培训
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三次握手和四次挥手是TCP协议中建立和终止连接的过程。下面是关于三次握手和四次挥手的面试题解答: 1. 请解释一下三次握手的过程。 答:三次握手是指在建立TCP连接时,客户端和服务器之间需要进行三个步骤的确认。首先,客户端发送一个SYN(同步)包给服务器,并进入SYN_SENT状态。接着,服务器收到SYN包后,回复一个SYN-ACK包给客户端,确认收到并同意连接,并进入SYN-RCVD状态。最后,客户端再发送一个ACK包给服务器,表示连接已经建立,双方都进入ESTABLISHED状态,可以开始传输数据。 2. 为什么需要进行三次握手而不是两次握手? 答:三次握手是为了确保双方都能够收到对方的确认,并建立可靠的连接。第一次握手是为了客户端告知服务器自己的发送序列号(SEQ)以及请求建立连接;第二次握手是为了服务器告知客户端自己的SEQ和确认序列号(ACK),同时也是为了确认客户端的SEQ;第三次握手是为了客户端再次确认服务器的SEQ和ACK,确保双方都能够正常通信。 3. 请解释一下四次挥手的过程。 答:四次挥手是指在终止TCP连接时,客户端和服务器之间需要进行四个步骤的关闭。首先,客户端发送一个FIN(结束)包给服务器,请求关闭连接,并进入FIN_WAIT_1状态。接着,服务器收到FIN包后,回复一个ACK包给客户端,表示收到请求,并进入CLOSE_WAIT状态。此时,服务器还可以继续向客户端发送数据。当服务器准备关闭连接时,发送一个FIN包给客户端,并进入LAST_ACK状态。最后,客户端收到FIN包后,回复一个ACK包给服务器,表示确认关闭请求,双方都进入CLOSED状态,连接终止。 4. 为什么需要进行四次挥手而不是三次挥手? 答:四次挥手是为了确保双方都能够完全关闭连接。第一次挥手是为了客户端告知服务器自己已经没有数据要发送,并请求关闭连接;第二次挥手是为了服务器告知客户端自己收到了FIN,并进入CLOSE_WAIT状态;第三次挥手是为了服务器告知客户端自己也准备关闭连接,并发送一个FIN;第四次挥手是为了客户端确认服务器的关闭请求,并发送一个ACK,表示双方都关闭连接。这样可以保证双方都能够正确地关闭连接,避免数据丢失或连接长时间处于半关闭状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值