java面试题1

文章目录

面试题

面向对象有哪些特征以及你对这些特征的理解

  1. 封装
    • 隐藏类内部实现细节 提供清晰的对外接口 让使用者只能通过程序规定的接口来访问
  2. 继承
    • 继承是从已有类得到继承信息创建新类的过程,提供继承信息的类称之为父类、超类、基类,而获得继承信息的类称之为子类、派生类
  3. 多态
    • 多态性是指不同子类型对象对同一消息做出不同响应的过程,简单来就是用同样的对象引用调用同样的方法实现不同的效果。
  4. 抽象
    • 将一类对象的相同特征构建成为一个类的过程,抽象只关注对象拥有哪些属性和行为并不关注行为的具体细节是什么。

访问权限修饰符的区别

修饰符同类同包子类不同包
private可以访问
默认可以访问可以访问
protected可以访问可以访问可以访问
public可以访问可以访问可以访问可以访问

如何理解clone对象

在实际编程中我们常常要遇到这种情况,有一个对象名为A拥有一些有效数据,此时我们需要创建一个和A相同的对象B并且改变B对象的值不能影响到A,简单来说A和B两个对象是完全独立的,但B的初始值和A相同,此时clone()可以完美的帮我们解决此需求。

深度拷贝

class Body implements Cloneable{
    public Head head;

    public Body(Head head) {
        this.head = head;
    }

    public Body() {
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Body newBody = (Body) super.clone();
        newBody.head = (Head) head.clone();
        return newBody;
    }
}
class Head implements Cloneable{

    public Head() {
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Body body = new Body(new Head());
        Body body1 = (Body)body.clone();
        System.out.println(body+"+"+body1);
        System.out.println(body.head==body1.head);
    }
}

为什么说Mybatis是半自动ORM映射工具 他与全自动ORM映射工具有什么区别

Hibernate属于全自动ORM映射工具,使用hibernate查询关联对象或关联对象集合时,可以根据对象关系模型直接获取,所以他是全自动的。而mybatis在查询关联对象或关联对象集合时,需要手动编写sql来完成,所以称之为半自动ORM映射工具。

MyBatis的好处

  • 将sql语句从java中独立出来
  • 将底层JDBC的操作封装成为了API调用,并且能够将结果集自动转换成为javaBean对象,简化了java数据库编程的重复工作
  • 自己编写sql语句更加的灵活
  • 入参无需使用对象或map封装,使用@param
image-20200714185951130

#{}和${}的区别是什么

是 p r o p e r t i e s 文件中的变量占位符,它可以用于标签属性值和 s q l 内部,属于静态文本替换,例如 {}是properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,例如 properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,例如{driver}可以被静态替换为com.mysql.jdbc.driver

#{}是sql中的参数占位符,mybatis会将sql中的#{}替换成为?号,在sql执行前会使用preparedStatement的参数设置方法,按序将sql中的?设置参数值。

xml映射文件中,除了常见的insert delete update select标签之外 还有哪些标签

还有很多标签 比如resultMap、parameterMap、sql、include、selectKey 加上动态sql中的标签 where trim set foreach if choose when otherwise bind等其中sql为sql片段标签通过include标签引入sql片段 selectKey为不支持自增的主键生成策略标签

Java中堆和栈有什么不同

每个线程都有自己的栈内存,用于存储本地变量、方法参数和栈调用,一个线程中存储的变量相对于其他线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题。这时volatile变量就可以发挥作用了,他要求线程直接从主存中读取变量的值。

堆主要用于存放运行时创建的对象,存取速度慢,可以运行时动态分配内存,生存期不需要提前确定。对象属于引用类型变量,其内存分配在堆上或常量池中,需要通过new等方式来创建。

栈主要用于存放基本数据类型变量(int、byte、short、long、double、float、boolean、char)以及对象的引用变量,其内存分配在栈上,出了作用域就会自动释放。

说说你用过的spring的注解

@Repository 一般用于数据访问层
@Service 一般用于业务层
@Controller 一般用于控制层
@Autowired 自动装配
@Component 跟@repository、@Service、@Controller的作用差不多 不过他通用
@Resource 属性注入
@Pointcut 定义切入点
@Before前置增强
@afterReturning后置增强
@after 最终增强
@afterThrowing异常抛出增强
@Around环绕增强

请说说spring依赖注入的方式

设值注入 :通过属性的set方法进行注入

构造注入:通过构造方法进行注入

说说你理解的简单工厂模式

在工厂中封装了实现细节,开发人员只需知道调用接口,无需关心实现细节,简化了开发

在mybatis中怎么配置一对多关系和一对一关系

一对一关系通过association标签来配置
一对多关系通过collection标签来配置

spring配置文件中的内容

开启注解功能并配置扫描包

配置数据库

配置sql会话工厂、别名、映射文件

事务管理器

开启事务注解驱动

无需编写dao的实现类

spring下的注解

  • 注册
    • @Controller @Service @Component
  • 注入
    • @Resource @Autowired
  • 请求地址
    • @RequestMapping
  • 返回具体类型而非跳转
    • @ResponseBody

Spring主要使用了什么模式

工厂模式:每个bean的创建通过方法

单例模式:默认bean的作用域是单例的

代理模式:关于Aop的实现通过代理模式

解释Spring支持的几种bean的作用域

singleton:默认。每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

prototype:为每个bean请求提供一个实例。

request:为每个网络请求创建一个实例,请求完成之后,bean会失效并被垃圾回收器回收

session:与request范围类似,确保每一个session中都有一个bean实例,在session过期后,bean会失效。

global-session:全局作用域。global-session与portlet应用相关,当你的应用部署在portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的Portlet共用全局的存储变量的话,那么该存储变量需要存储在global-session中。全局作用域与servelet中的session作用域效果相同。

Spring MVC的请求流程

  1. 用户发送请求至前端控制器DispatcherServlet;
  2. DispatcherServlet收到请求后调用 处理器映射器,请求获取Handle;
  3. 处理器映射器根据具体的url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
  4. DispatcherServlet调用HandlerAdapter处理器适配器;
  5. HandlerAdapter经过适配调用具体处理器(Handler,也就是后端控制器);
  6. Handler执行完成后返回ModelAndView;
  7. HandlerAdapter将Handler的执行结果ModelAndView返回给DispatcherServlet;
  8. DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
  9. ViewResolver解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  11. DispatcherServlet响应用户

Spring MVC的主要组件

  1. 前端控制器DispatcherServlet(不需要程序员开发)

    • 作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet就减少了其它组件之间的耦合度。
  2. 处理器映射器HandlerMapping(不需要程序员开发)

    • 作用:根据请求的URL来查找Handler
  3. 处理器适配器HandlerAdapter

    注意:在编写Handler的时候一定要按照HandlerAdapter的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。

  4. 处理器Handler(需要程序员去开发)

  5. 视图解析器ViewResolver(不需要程序员去开发)

    • 作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
  6. 视图View(需要程序员开发)

    • View是一个接口,它的实现类支持不同的视图类型(jsp、freemarker、pdf等等);

阐述静态变量和实例变量的区别

静态变量: 是被 static 修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;静态变量可以实现让多个对象共享内存。

实例变量: 必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。

重载overload和重写的区别 重载的方法能否根据返回类型进行区分

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在父类与子类之间,重写要求子类重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏替换原则)。重载对返回类型没有特殊的要求

  • 方法重载的规则
    1. 方法名一致,参数类型、顺序、个数不同
    2. 与方法的返回值无关,发生在父类、子类及同类之间
    3. 可以抛出不同的异常,可以有不同的修饰符
  • 方法重写的规则
    1. 参数列表必须与被重写方法的一致,返回类型必须完全与被重写方法的返回类型一致
    2. 构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写,但是能再次声明
    3. 访问权限不能比父类中被重写方法的访问权限更低
    4. 重写的方法能够抛出任何非强制异常(也叫非运行时异常),无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明更广泛的强制性异常,反之则可以。

什么是重载

方法重载就是在一个类中可以创建多个方法,他们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定使用哪个方法,这就是方法的多态性

重写

重写可以做到子类继承父类中的方法,而不需要重写编写相同的方法,重写的时候,方法名、返回类型和参数都要一样

构造器Constructor是否可以被override

构造器Constructor不能被继承,因此不能被重写,但是可以被重载

abstract class和interface有什么区别

  1. 抽象类可以有构造方法,接口不能有构造方法
  2. 抽象类中可以有普通成员变量,接口中没有普通成员变量
  3. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须是抽象的,不能包含非抽象的普通方法
  4. 抽象类中的抽象方法访问类型可以是public、protected和默认类型,但接口中的抽象方法只能是public类型的并且默认为public abstract类型。
  5. 抽象类中可以包含静态方法,接口中不能包含静态方法
  6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型
  7. 一个类可以实现多个接口,但只能继承一个抽象类。

是否可以继承String类

String类是final类不能被继承

Java中实现多态的机制是什么

靠的是是父类的引用变量指向子类的实例对象。程序在运行时,该引用变量调用的方法是内存中正在运行的那个方法(也就是子类实例里的方法),而不是引用变量的类型中定义的方法。

Object对象占用多大内存

8字节

error和exception有什么区别

error表示应用程序自身无法克服和恢复的一种严重问题,比如说内存溢出。exception表示一种设计或实现问题。也就是说,如果程序运行正常,就不会发生的情况。

Java中异常处理机制的简单原理和应用

在catch中预先定义要发生的异常,若在try块中发现此异常或及其子类异常则会被catch捕获并可以在catch块中处理该异常

Java语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块可以抛出异常吗

throws捕获并向外抛出异常

throw抛出异常

try catch是内部捕获异常并做自定义处理

finally是无论是否有异常都会执行,除非在finally前存在被执行的System.exit(1)时除外

在try块可以抛出异常

try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,在return前还是后?

return在finally之后执行

主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。

1.finally里面的代码会在return之前,但是如果return里面是一个计算公式或者是调用某一个方法的话,那先执行reurn 的计算公式或者方法,再执行finally里面的代码,finally执行对return的结果无法改变的,但是如果return 返回的是一个对象的话,那么在finally里面对返回对象作出改变的话,return结果是会被改变的

2.如果finally里面有return代码,那先执行finally 里面的return,try里面的return是不会执行的。

String是基本数据类型吗

基本数据类型包括byte、short、int、long、float、double、char、boolean。

java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该使用StringBuffer类型

Integer与int的区别

  1. Integer是int的包装类,int则是java的一种基本数据类型
  2. Integer变量必须实例化后才能使用,而int变量不需要
  3. Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
  4. Integer的默认值是null,int的默认值是0

运行时异常与一般异常有何异同

一般异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机通常操作中可能遇到的异常,是一种常见的运行错误,JAVA编译器要求方法必须声明抛出可能发生的未运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

同步和异步有何异同,在什么情况下使用他们

如果数据将在线程间共享,例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,这就是线程共享数据,必须进行同步存取。

当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法返回时,就应该使用异步编程。

多线程有几种实现方法?同步有几种实现方法?

多线程有两种实现方法,分别是继承Thread类和实现Runnale接口

同步有两种实现方法,分别是synchronized,wait与notify

启用一个线程使用run(),还是start()

启动一个线程是调用start()方法,使线程进入就绪状态,并且可以被调度为运行状态。一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码

字节流与字符流的区别

字节流默认不使用缓冲区,而字符流使用缓冲区。字节流采用ASCII编码,字符流采用unicode编码。

字节流在操作文件时不会用到缓冲区,是直接操作的文件本身。而字符流在操作时则用到了缓冲区,通过缓冲区再操作文件

数据库三大范式

第一范式:确保每列的原子性
第二范式:确保每张表描述一个内容
第三范式:在第二范式上更进一步,确保表中的每列都和主键直接相关而不是间接相关
三大范式会影响数据操作性能。所以在设计数据库时,既要考虑三大范式,避免数据的冗余和各种数据操作异常;又要考虑数据访问性能。有时为了减少表间连接,提高数据访问性能,允许适当的冗余列,这是最合适的数据库设计方案。

什么是spring的IOC和AOP

IOC:Inversion of control控制反转,也叫作DI 依赖注入, dao接口的实现不再是业务逻辑层调用工厂类去获取,而是通过Spring来自动的为我们的业务层设置Dao的实现类,也可以使用@Resource注解来直接使用dao层实现类,这也就是控制反转的由来。 通过IOC我们就可以在不修改任何代码的情况下,无缝的实现数据库的换库迁移。

AOP:叫做面向切面编程,通过AOP我们可以将程序中的交叉业务逻辑(比如安全、日志、事务),封装成为一个切面,然后注入到目标业务逻辑中去

hashMap和hashtable的区别

Map是一个键值对的储存接口,Map有两个具体的实现类是HashMap和HashTable.

Hashmap是非线程安全的,hashtable是线程安全的,所以hashmap的效率高于hashtable;

Hashmap允许空值空键,table不允许空值空键;

底层原理:map通过数组和链表形式存放,在存放数据时通过key的hashcode()的值和数组的长度取余,通过余数放到相应位置(下标)上,在通过key查询的时候,也通过余数查询,但这样可能会出现重复的情况,加上个链表,通过key取到链表后,将取得的链表进行循环,然后相比较查询的出相应的值.

序列化和反序列化

序列化:就是将内存中的对象持久化到本地文件的过程.

为什么序列化: 通常在http网路传输中,是不支持对象传递的,所以通过序列化,将对象转换为可以被传输的流,方便对象信息传递.

如果将一个对象序列化:1.类实现serializable接口,2.通过ObjectOutputStream的writeObject()将对象写到文件中.

反序列化:将文件中储存的对象信息读取后写到内存中.通过ObjectInputStream的readObject()写到内存.

什么是单例多例.

单例:就是所有的请求都用一个对象来处理,service和dao层的对象通常都是单例的,单例利于节省资源.

单例就是该类只能返回一个实例。

单例特点:私有化的构造,私有的静态全局变量,公有的静态方法

多例:指每个请求用一个新的对象来做,比如action; 之所以用多例,是为了防止并发问题,即对象同时处理多个请求,一个请求改变了对象的状态,使对象对另一个请求作出了错误的处理.

用单例和多例的标准只有一个,当对象含有可改变的状态时则多例,否则单例

面试题

找到并加载Bean对象 获取Beanfactory 设置Beanname 获取Bean实例 获取Bean在上下文的引用 初始化前处理 初始化 初始化后处理 就绪 销毁

jvm

这个要理解一下jvm内存区就好理解命令。
1.栈是线程和方法执行的地方。主要耗的是cpu。jstack就是看栈的快照。所以cpu过高,或者死锁等就用jstack检查问题
2.堆存的是对象,垃圾回收的主要区域。主要耗内存,所以内存溢出等优先排查堆。jmap是看堆里对象的情况。但是线上注意jmap使用。

spring用到的设计模式

工厂方法模式:AbstractBeanFactory 。
抽象工厂模式:在 Spring 中,BeanFactory
单例模式:Spring中创建单例。
建造者模式:解析xml文件
原型模式:在创建ioc容器后,通过getBean()获取bean对象时,往里追可以发现在核心方法处spring对bean的scope属性进行了判断,配置了prototype时。
适配器模式:spring AOP中的MethodBeforeAdviceAdapter类。
装饰模式:TransactionAwareCacheDecorator 类
代理模式:spring中代理有两种,Jdk代理方式和CGLIB。
外观模式:Tomcat 中,catalina.jar 中的 RequestFacade 和 ResponseFacade 。
桥接模式:JDBC
组合模式:CompositeCacheManager,Mybatis 在处理 xml 动态 sql 中用到了。
享元模式:String常量池, Integer 的静态内部类 IntegerCache。
策略模式:多个类实现同一接口,通过context动态切换具体策略
模板方法模式:JdbcTemplate实现了一系列常用的数据访问的算法骨架。
观察者模式: ApplicationListener, ContextLoaderListener等。
迭代器模式:集合。
责任链模式:handler,filter,Intercept。
命令模式:Tomcat 中命令模式在 Connector 和 Container 组件之间有体现。
备忘录模式:spring-webflow 中的stateManageableMessageContext.createMessageMemento()
状态模式:spring-statemachine spring状态机
访问者模式:Spring 中的 BeanDefinitionVisitor 类主要用于访问 BeanDefinition。
中介者模式:Java web 开发中 MVC 模式(Model-View-Controller)就用到了中介者模式,Controller 就是 Model 和 View 的中介
解释器模式:在 Spring 中,ExpressionParser 接口内部采用的是解释器模式。

spring中支持bean的作用域

单例 原型 请求 会话 全局会话

索引失效

  1. in 、not in 过长,or,不等于 2. like 以%开头 3. where使用函数 4. 对索引列使用聚合函数 5. 索引类型不匹配 6. 复杂SQL

redis五种数据类型

string set list hash zset(sorted set)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MySQL之事务的实现原理

事务是基于重做日志文件(redo log)和回滚日志(undo log)实现的。
每提交一个事务必须先将该事务的所有日志写入到重做日志文件进行持久化,数据库就可以通过重做日志来保证事务的原子性和持久性。
每当有修改事务时,还会产生 undo log,如果需要回滚,则根据 undo log 的反向语句进行逻辑操作,比如 insert 一条记录就 delete 一条记录。undo log 主要实现数据库的一致性。

b+树储存与优势

B+树的非叶子节点不保存具体的数据,而只保存关键字的索引

B+树和B树的对比

1、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定。
2、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
3、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

redis事务如何实现

multi 开启事务,exec执行事务,discard清空事务,watch 提供cas乐观锁一直持续到exec命令

redis分布式锁如何实现

单机redis使用redis的set命令实现 或者 setnx不支持超时时间设置
具体是 使用set lock 设置过期时间如果成功则获取锁,如果节点掉线则等过期自动失效,释放锁使用del删除lock值

redis rdb aof

rdb以快照方式储存在磁盘上,save bgsave,配置文件
bgsave异步操作,主进程不需要io操作。
rdb是全量备份,快照持久化期间可能丢失数据
aof以日志的形式储存,Alawys,everysec,no
aof数据完好性比价好,不影响客户端读写,写入性能高,apf日志比较大
两者结合使用

redis缓存缺点

会造成缓存穿透,击穿以及雪崩。
缓存穿透最好的解决方案就是使用布隆过滤器。
缓存击穿最好的解决方案就是使用分布式锁。
开启事务,exec执行事务,discard清空事务,watch 提供cas乐观锁一直持续到exec命令

redis分布式锁如何实现

单机redis使用redis的set命令实现 或者 setnx不支持超时时间设置
具体是 使用set lock 设置过期时间如果成功则获取锁,如果节点掉线则等过期自动失效,释放锁使用del删除lock值

redis rdb aof

rdb以快照方式储存在磁盘上,save bgsave,配置文件
bgsave异步操作,主进程不需要io操作。
rdb是全量备份,快照持久化期间可能丢失数据
aof以日志的形式储存,Alawys,everysec,no
aof数据完好性比价好,不影响客户端读写,写入性能高,apf日志比较大
两者结合使用

redis缓存缺点

会造成缓存穿透,击穿以及雪崩。
缓存穿透最好的解决方案就是使用布隆过滤器。
缓存击穿最好的解决方案就是使用分布式锁。
缓存雪崩最好的解决方案就是实现redis高可用

  • 33
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值