基本面试题

面向对象三大基本特性

封装:把描述一个对象的属性和行为封装成一个类,把具体的业务逻辑功能实现封装成一个方法,其次封装的意义还有效的保护属性通过访问修饰符私有化属性(成员变量),公有化方法。
继承:实现代码的复用,所有的子类所共有的行为和属性抽取为一个父类,所有的子类继承该类可具备父类的属性和行为,继承具有单一性和传递性。
多态:不同的对象可以执行相同的动作,但是要通过他们自己的实现代码来执行。

堆和栈的区别

功能方面:堆是用来存放对象的,栈是用来执行程序的
共享性:堆是共享的,栈是私有的
空间大小:堆的大小远远大于栈

队列和栈的区别

  • 队列和栈都是被用来预存储数据的。
  • 队列允许先进先出检索元素,但也有例外的情况,Deque接口允许从两端检索元素
  • 栈和队列很相似,但它运行对元素进行后进先出进行检索

进程和线程的区别

进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高。线程是进程中的一个实际运作单位,是操作系统中能够进行运算调度的最小单位。同一个进程中的多个线程之间可以并发执行。

线程的几种状态

新建状态:当用new操作符创建一个线程时。此时程序还没有运行线程中的代码
就绪状态:一个新创建的线程并不自动开始运行,要执行线程,必须调用程序的 start() 方法。当线程对象调用 start() 方法即启动了线程,start() 方法创建线程运行的系统故障,并调度线程运行 run() 方法。当 start() 方法返回后,线程就处于就绪状态。
处于就绪状态的线程并不一定立即运行 run() 方法,线程还必须同其他线程竞争 CPU 时间,只有获得了 CPU 时间才可以运行线程。因为在但 CPU 的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序来调度的。
运行状态:当线程获得 CPU 时间后,它才进入运行状态,真正开始执行 run()方法
阻塞状态:线程运行过程中,可能由于各种原因进入阻塞状态:
1)线程通过调用 sleep() 方法进入睡眠状态
2)线程调用一个在I/O上阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者
3)线程试图得到一个锁,而该锁正被其它线程持有
4)线程在等待某个触发条件
所谓阻塞状态是正在运行的线程没有运行结束,暂时让出 CPU ,这时其它处于就绪状态的线程就可以获得 CPU 时间,进入运行系统

什么是线程池

线程池是一种多线程处理形式,处理过程中将任务提交到线程池中,任务的执行交由线程池来管理。如果每个请求都创建一个线程去处理,那么服务器的资源很快就会被耗尽,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

举个例子:我们可以把线程池当做一个客服团队,如果同时有1000个人打电话进行咨询按照正常的逻辑那就需要1000个客服接听电话,服务客户。但现实往往不是这样的,我们需要考虑更多层面的东西,如:资源够不够,招这么多人需要的费用。正常的做法技术就是招100个人出来一个客服中心,当有电话进来后分配没有接听的客服进行服务,如果超出了100个人同时咨询的话,提示客户等待,稍后处理,等有客服空出来就可继续服务下一个客户,这样才能达到一个资源的合理利用,实现利益的最大化。

多线程的优缺点

优点
1)多线程技术是程序的响应速度更快
2)当前没有进行处理的任务可以将处理器时间让给其它任务
3)占用大量处理时间的任务可以定期将处理器时间让给其它任务
4)可以随时停止任务
5)可以分别设置各个任务的优先级以及优化性能

缺点:
1)等待使用共享资源时造成程序的运行速度变慢
2)对线程进行管理要求额外的CPU开销
3)可能出现线程死锁情况。即较长时间的等待或资源竞争以及死锁等状况

什么是线程安全

简单来说就是,如果你的代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是线程安全的。

  • 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的。
  • 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会引起此共享资源的不一致性。因此,为避免线程安全问题,应该避免多线程环境下对此共享资源的并发访问。
  • 线程安全问题多是由全局变量和静态变量引起的,当多个线程对共享数据只执行读操作,不执行写操作时,一般是线程安全的;当多个线程都执行写操作时,需要考虑线程同步来解决线程安全问题。

什么是死锁

当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。

什么防止死锁

  • 尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。
  • 尽量使用 Java. util. concurrent 并发类代替自己手写锁。
  • 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
  • 尽量减少同步的代码块。

Spring是什么

Spring是一个轻量级的容器,用于管理业务相关对象的。核心功能主要是:控制反转(IOC),面向切面编程(AOP)

Spring的优点

  • Spring属于低侵入式设计,代码的污染度极低
  • Spring的DI机制降低了业务对象替换的复杂性
  • 容器提供了AOP集成,利用它很容易实现如权限拦截,运行期监控等功能
  • 降低了组件之间的耦合性,实现了软件各层之间的解耦
  • 容器提供单例模式支持
  • 可以还有容器提供的众多服务,如事务管理,信息服务
  • 容器提供了众多辅助类,能监控应用的开发
  • Spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
  • 独立于各种应用服务器
  • Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可用自由选择 Spring的步伐或全部

IOC是什么

控制反转,把对象创建的控制权交给容器去完成,而我们直接去调用就可以了,这样就减少了代码之间的依赖关系,实现了解耦合

  1. 最直接的表达就是,IOC让对象的创建不用去new了,可以由Spring自动生产,这里用的就是java的反射机制,通过反射在运行时动态的去创建、调用对象。Spring就是感觉配置文件在运行时动态的去创建对象,并调用对象的方法的。
  2. IOC:控制反转。就是对象的创建权反转交给Spring,由容器控制程序之间的依赖关系,作用实现了程序的解耦合,而非传统实现中,有程序代码直接操控。控制权由应用代码本身转到了外部容器,由容器根据配置文件去创造实例并管理各个实例之间的依赖关系,控制权的转移,是所谓的反转,并且由容器动态的将某种依赖关系注入到组件之中。BeanFactory 是Spring IOC容器的具体实现与核心接口,提供了一个先进的配置机制,使得任何类型的对象的配置成为可能,用来包装盒管理各种bean。
  3. IOC,控制反转:将对象交给容器管理,你只需要在Spring配置文件中配置相应的bean,已经设置相关的属性,让Spring容器生成类的实例对象一级管理对象。在Spring容器启动的时候,Spring会把你在配置文件中配置的bean都初始化一级装配好,然后在你需要调用的时候,就把它已经初始化好的哪些bean分派给你需要调用这些bean的类。就是将对象的控制权反转给Spring容器管理。
  4. IOC,控制反转。将对象的创建过程交给容器,让容器管理对象的生命周期,如创建,初始化,销毁等。

Spring IOC的注入方式:

  1. 根据属性注入,也叫set方法注入
  2. 根据构造方法注入
  3. 根据注解注入

AOP是什么

面向切面编程,通过预编译方式和运行期动态代理实现实现程序功能的统一维护的一种技术,是OOP的延续。它的核心原理是使用动态代理的设计模式在执行方法前后或是出现异常的地方加入相关逻辑。我们可以用AOP进行事务的处理,权限的判断,日志的处理

AOP,面向切面编程。作为面向对象的一种补充,用户解剖封装好的对象内部,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”,切面将那些鱼业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中重复的代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。

AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理以Spring AOP为代表。

AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译截断
生成AOP代理类,因此也被称为编译时增强,他会在编译阶段将AspectJ织入到Java字节码中,运行的时候就是增强之后的AOP对象。

Spring AOP所用的是动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调对象的方法。

Spring AOP中的动态代理分为,JDK动态代理CGLIB动态代理
1)JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是 InvocationHandler 接口和 Proxy 类。生成的代理对象的方法调用都会委托到 InvocationHandler.invoke() 方法,当我们调用代理类对象的方法时,这个“调用”会转送到 invoke 方法中,代理类对象作为 proxy 参数传入,参数 mehtod 标识了我们具体调用的是代理类的哪个方法,args 为这个方法的参数。
2)如果目标类没有实现接口,那么Spring AOp会选择使用CGLIB来动态代理目标类。CGLIB,是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法,覆盖方法时可以添加增强代码,从而实现AOP。CGLIB是通过检查的方式做到动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的
3)静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编辑器进行处理,而 Spring AOP 则无需特定的编辑器处理。

什么是Spring MVC

Spring MVC是一个基于MVC架构,用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无序中间整合层来整合,它和Struts2应用都属于表现层的框架。在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合

Spring MVC的优点

  1. 它是基于组件技术的。全部的应用对象,无论控制器,视图还是业务对象之类的都是java组件,并且和Spring提供的其他基础结构紧密集成
  2. 不依赖于Servlet API(目标虽如此,但是在实现的时候确实是依赖于Servlet的)
  3. 可以任意使用各种视图技术,而不仅仅局限于JSP
  4. 支持各种请求资源的映射策略
  5. 易于扩展

Spring MVC有哪些组件

  • 前置控制器 DispatcherServlet
  • 映射控制器 HandlerMapping
  • 处理器 Controller
  • 模型和视图 ModelAndView
  • 视图解析器 ViewResoler

Spring MVC的运行流程

  • Spring MVC先将请求发送给DispatcherServlet
  • DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller
  • DispatcherServlet再把请求提交到对应的Controller
  • Controller进行业务逻辑处理后,会返回一个ModelAndView
  • Dispather查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
  • 视图对象赋值渲染返回给客户端

什么是反射

反射就是动态加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能称为java反射机制

反射优缺点

优点:提高了程序的灵活性和扩展性,在底层框架中用的比较多,业务层面的开发过程中尽量少用
缺点:性能不好,反射是一种解释操作,用于字段和方法接入时要远慢于直接代码

session和cookie的区别

  • 存储位置不同:session存储在服务器端;cookie存储在浏览器端
  • 安全性不同:cookie安全性一般,在浏览器存储,跨越被伪造和修改
  • 容量和个数限制:cookie有容量限制,每个站点下的cookie也有个数限制
  • 存储的多样性:sessioin跨越存储在Redis中、数据库中、应用程序中;而cookie只能存储在浏览器中

抽象类和接口的区别

  1. 抽象类和接口都不能直接实例化,如果要实例化,抽象类必须指向实现所有抽象方法的子类,接口变量必须指向实现所有接口方法的类对象。
  2. 抽象类要被子类继承,接口要被类实现
  3. 接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
  4. 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量
  5. 抽象类里的抽象方法必须全部被子类实现,如果子类不能全部实现父类的方法,那么该子类只能是抽象类。同样,一个类在实现接口的时候,如果不能全部实现接口方法,那么该类也只能是抽象类
  6. 抽象方法只能申明,不能实现,接口是设计的结果,抽象类是成功的结果
  7. 抽象类里可以没有抽象方法,抽象方法一定要在抽象类中
  8. 抽象方法要被实现,所有不能是静态的,也不能是私有的
  9. 接口可以继承接口,并可以多继承接口,但类只能单个继承抽象类

java中final的用法

  1. 修饰数据:只能进行一个赋值操作,并在生存期内不可以改变它的值
  2. 修饰方法参数:使我们传入的参数只能赋值一次并不能修改
  3. 修饰方法:使方法不可以被覆盖重写
  4. 修饰类:使该类无法被继承

String,StringBuilder,StringBuffer三者的区别

运行速度:StringBuilder > StringBuffer > String
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
详细可以看这里https://www.cnblogs.com/su-feng/p/6659064.html

访问修饰符public,private,protected,以及不写(default)时的区别

修饰符		当前类		同包		子类		其他包
public		√			√		 	√		 	√
protected	√			√		 	√		 	×
default		√			√		 	×		 	×
private		√			×		 	×		 	×

Java中8中基本数据类型

byte,short,int,long,float,double,char,boolean

thorw和thorws的区别

throw:是真实的抛出一个异常
throws:是声明可能会抛出一个异常

JSP的4种作用域

page:代表与一个页面相关的对象和属性
request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web组件;需要在页面显示的临时数据跨越置于次作用域
session:代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的seesion中
application:代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域

数据库建立索引的目的(优点)?简单列举常用索引的类型

优点:创建索引可以大大提高系统的性能,加快查询速度
缺点:更新数据时效率低,因为要同时更新索引
如果对数据库进行频繁查询数据就建议使用索引,如果对数据库更改数据就不建议使用索引

普通索引:仅加快查询
唯一索引:加快查询+列值唯一(可以有null)
主键索引:加快查询+列值唯一(不可以有null)+表中只有一个
组合索引:多列值组成的一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索

数据库三大范式介绍

1NF 字段是最小单元,不可再分
2NF 满足1NF 表中字段必须完全依赖全部主键而并非部分主键
3NF 满足2NF,非主键外的所有字段必须互不依赖

MySql中myisam与innodb的区别,至少5点

  1. Innodb支持事务,而MyIsAM不支持事务
  2. Innodb支持行级锁,而MyIsAM支持表级锁
  3. InnoDB在效率上不如MyISAM,MyISAM相对简单,小型应用可以考虑使用MyISAM。
  4. Innodb支持外键,而MyIsAM不支持
  5. Innodb不支持全文类型索引,而MyIsAM支持
  6. InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

MyIsAM更快,因为MyIsAM内部维护了一个计数器,可以直接调取

数据库事务4大特性(ACID)

原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务就从来没有执行过一样

一致性:在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏,从一个一致性状态变换到另一个一致性状态。比如:转账,假设用户A和用户B两者的钱加在一起是5000元,那么不管A和B之间如何转账,转几次帐。事务结束后两个用户的钱加在一起还得是5000

隔离性:当多个用户并发访问数据库时,比如:操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。要达到这么一种效果:对于任意并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务就感觉不到其他事务在并发的执行。

持久性:一个事务一旦被提交了。那么对数据库中的数据的改变是永久性的,即便是在数据库系统遇到故障情况下也不会丢失提交事务的操作。

drop, delete truncate的区别delete和truncate只删除表的数据不删除表的结构

速度:drop > truncate > delete
想删除部分数据时, delete 删除时要带上where语句
保留表而想删除所有的数据时用truncate

触发器的作用

触发器是一种特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算,如,某表上的触发器上包含对另一个表的数据库操作,而该操作又会导致该表触发器被触发。

数据库隔离级别

脏读:指一个事务处理过程中读取了另一个为提交事务中的数据。当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致

不可重复读
在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
解决不可重复读的问题只需锁住满足条件的行.

幻读(虚读):事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
解决幻读需要锁表.

事务隔离级别	读数据一致性		脏读	不可重复读	幻读
读未提交	    最低级别 		是		是			是
不可重复读	语句级			否		是			是
可重复读		事务级			否		否			是
串行化		事务级			否		否			否

		级别越高,执行效率就越低,并发性越差

聚集索引和非聚集索引区别

聚集索引,数据按索引顺序存储,中子结点存储真实的物理数据
非聚集索引,存储指向真正数据行的指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值