基本功
1、面向对象的特征
抽象:
忽略一个主题中与当前目标无关的东西,专注与当前目标有关的方面。把现实中的某一类东西提取出来,用程序代码表示,抽象出来的一般叫做类或者接口。
数据抽象--->表示一类事物的特征,就是对象的属性。
过程抽象--->表示一类事物的行为,就是对象的行为。
封装:
就是将事物的过程和数据包围起来,对于数据的访问只能通过特定的方法,如私有变量,用set,get方法获取。
继承:
对象的新类可以从现有类中派生,这个过程叫做继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),原始类称为新类的基类(父类)。派生类可以从它的父类中继承方法和变量,并且可以修改或增加新的方法使之适合更特殊的需要,因此可以说,继承是为了重用父类的代码,同时为实现多态性做准备。
多态:
多态是指允许不同类的对象对同一消息做出响应,多态性包括参数化多态性和包含多态性,总的来说方法的重写和重载与动态链接构成多态性。
动态链接--->对于父类中定义的方法,如果子类重写该方法,那么父类类型中的引用将调用子类中的这个方法,这就是动态链接。
2、final、finally、finalize的区别
final修饰符:
被final修饰的类,就意味着不能派生出子类,不能作为父类被子类所继承。因此一个类不能既被abstract声明,又被final声明。被final修饰的变量或者方法可以保证他们在使用的过程中不被修改,被final声明的变量必须在声明时就给出变量的初始值,在以后的使用中只能被读取。被final声明的方法不能被重载。
finally:
finally是在异常处理时提供finally块来执行必要的操作,不管有没有异常被抛出,捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束,catch块中的内容是在发生catch所声明的异常时,跳转到catch块中执行,finally块则是无论异常是否发生,都会执行。所以在代码逻辑中有无论发生什么都需要执行的代码,都可以放在finally中
finalize:
finalize是方法名,java允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,所有类都会继承它。子类中覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
3、int和Integer有什么区别(==做比较)
Integer和new Integer不会相等,因为new出的对象放在堆内存中,而非new出来的Integer常量则存放在常量池中,它们的内存地址不一样。两个都是非new出来的Integer,如果数在-128到127之间,则为true,否则为false。因为java在编译Integer i = 128的时候会被翻译成,Integet i = Integer.valueOf(128),而valueOf()方法会对-128到127之间的数进行缓存。
两个都为new出来的,都为false,因为内存地址不一样。
int和Integer(无论new与否),都为true,因为Integer会自动拆箱为int再去比较
4、重载和重写的区别
重载(overloading):方法重载是让类以统一的方式处理不同类型数据的一种手段,多个同名函数同时存在,具有不同的参数个数/类型,重载是类的多态性的一种表现。需要注意一点的是,不以返回值类型是否相同做为重载函数的区分标准。
重写(overriding):
重写体现的是父类与子类之间的多态性,子类对父类中的方法进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们称之为方法被重写,在子类中需要调用父类中原有的方法,可以使用super关键字,该关键字啊引用类当前类的父类。重写时需要注意子类函数的访问修饰权限不能少于父类的,子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常),方法被定义为final不能被重写。
5、接口和抽象类有什么区别/异同
接口和抽象类的概念不一样,接口是对动作的抽象,抽象类是对事物根源的抽象。接口表示的是这个对象能做什么,抽象类表示的是这个对象是什么。总结来说就是:抽象类和接口都不能直接实例化,如果要实例化,抽象类必须由实现所有抽象方法的子类进行实例化,接口必须由实现所有接口方法的类对象实例化。
抽象类要被子类所继承,接口要被类实现。
接口只能做方法声明,抽象类中可以做方法声明,也可以做方法实现(java8中已可以在接口中做方法的实现)。
接口中定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
抽象类中的抽象方法必须全部被子类所实现,如果子类不能实现父类全部的抽象方法,那么该子类只能是抽象类。同样如果不能实现接口的全部方法,那么该类也只能是抽象类。
抽象方法只能声明,不能实现,接口是设计的接口,抽象类是重构的接口。
抽象类里可以没有抽象方法,但是一个类中存在抽象方法,这个类只能是抽象类。
抽象方法要被实现,所以不能是静态的,也不能是私有的。
接口可以继承接口,并且可以多继承接口,但是类只能单继承。
6、说说反射的用途及实现
反射用途:反射是指在运行中加载、探知、使用编译期间完全未知的class。java程序可以加载一个在运行期间才知道名称的class,获取其完整的构造并生成对象实例或者对其字段进行赋值或调用实例的方法。
反射的使用:
第一步:获取想操作类的Class对象,在运行中的java程序中,用java.lang.Class类描述类和接口等。Class c = Class.forName(className);
第二步:调用诸如getDeclaredMethods 的方法,获取该类中定义的方法列表等。
第三步:使用reflection API 来操作这些信息。
7、说说自定义注解的场景及实现
登陆、权限拦截:在web项目中,登陆拦截和权限拦截是一个老生常谈的功能。通过自定义登陆注解或权限注解,在自定义拦截器中解析注解,实现登陆和权限的拦截功能。
定时任务管理:
在系统构建过程中,会有各种定时任务的需求,而定时任务的集中管理,可以更高效维护系统的运行。
多数据源路由的数据源指定:
Spring提供的AbstractRoutingDataSource实现多数据源的动态路由,可应用在主从分离的架构下。通过对不同的方法指定不同的数据源,实现数据源的动态路由(例如:读方法走从库数据源,写方法走主库数据源)。而如何标识不同的方法对应的数据源类型,则可使用自定义注解实现。通过解析方法上声明的自定义注解对应的数据源类型,实现数据源的路由功能。
8、HTTP 请求的 GET 与 POST 方式的区别
GET请求能够被缓存,POST请求不能被缓存下来GET请求会保存在浏览器的浏览记录中,POST请求不会保存在浏览器浏览记录中
GET请求有长度限制,POST请求没有长度限制
POST对比GET相对安全
在RESTful风格中,GET用于从服务器获获取数据,而POST用于创建数据
9、session 与 cookie 区别以及session的实现原理
session保存在服务器,客户端不知道其中的信息,cookie保存在客户端,服务端可以知道其中的信息。session中保存的是对象,cookie保存的是字符串。
session不能区分路径,同一个用户在访问同一个网站期间,所有的session在任意一个地方都能访问到,而cookie中如果设置了路径参数,那么在同一个网站中不同路径下的cookie不能互相访问。
session实现原理:
服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。若浏览器禁用cookie,可以使用URL重写的方式来实现session(response. encodeRedirectURL(java.lang.String url)和response. encodeURL(java.lang.String url)是两个非常智能的方法,当检测到浏览器没有禁用cookie时,那么就不进行URL重写了)。
10、session 分布式处理
粘性session:负载均衡器设置粘性session,以后用户的每次请求都会转发到固定的服务器上。优点:不需要对session做任何处理,缺点:缺乏容错性,如果当前服务器发生故障,用户被转移到第二台服务器上,它的session信息将失效。适用场景:发生故障对客户产生影响较小,服务器发生故障概率较小。
服务器session复制:
任何一个服务器上的session发生改变,该节点会把这个session的所有内容序列化,然后广播给所有的其他节点,不管其他服务器需不需要session,以此保证session同步。优点:可容错,各个服务器间session能够实时响应,缺点:对网络负荷造成压力,如果session量大的话可能造成网络堵塞,拖慢服务器性能。
session共享机制:
使用分布式缓存方案比如memcached、redis,但是要求Memcached或Redis必须是集群。使用Session共享也分两种机制,两种情况如下:
①粘性session处理方式,原理:不同的web容器指定访问不同的主redis,多个redis服务之间信息是同步的,能主从备份和高可用。用户访问时首先在web服务中创建session,然后将session复制一份到它对应的redis上,redis仅起到备份作用,读写都在web服务中。当一个web服务挂掉之后,集群将用户访问定位到备份web服务上,然后根据cookie中存储的sessionId找session,找不到时再去相应的redis获取session,找到之后将session复制到备份web服务中。
②非粘性session处理方式,redis做主从复制,写入session都往redis服务上写,读取都从redis服务上读取,web服务本身不存储session。优点:可容错,session实时响应。
session持久化到数据库:
将session信息存储到数据库中,保证session的持久化。优点:服务器出现问题,session不会丢失。缺点:如果访问量很大,会对数据库造成压力,还需要增加额外的开销维护数据库。
terracotta实现session复制:
terracotta的基本原理是对于集群间共享的数据,当一个节点发生变化时,terracotta只把变化的部分发送给terracotta服务器,然后由服务器把它转发给真正需要这个数据的节点,这个可以看作是对第二种方案(session复制方案)的优化。优点:对于网络的压力非常小,各个节点也不需要浪费CPU和内存进行大量的序列化操作,把这种集群间数据共享的机制应用在session同步上,既避免了对数据库的依赖,又能达到负载均衡和灾难恢复的效果。
11、JDBC 流程
注册驱动,Class.forName("oracle.jdbc.OracleDriver");建立链接,Connection conn = DriverManager.getConnection(url,name,password);
创建语句,Statement statement = conn.createStatement();
执行语句,ResultSet resultSet = statement.executeQuery(sql);
处理结果,resultSet.next()方法移动行,可以使用各种get方法获取当前行的值。
12、MVC 设计思想
模型:业务层,业务逻辑层。包含业务数据处理加工及相应的事务,安全,权限,日志等功能模块。
视图层:
展现模型处理的结果,另外还需要提供相应的操作界面。
控制层:
视图发送请求给控制器,由控制器选择相应的模型来处理,模型返回的结果给控制器,由控制器选择合适的视图。
MVC设计模式的优点:实现分层开发,每个层均有各自的作用。降低层与层之间的依赖,有利于代码的标准化开发。高重用性和可适用性。测试友好性。缺点:实现复杂,增加代码量,增加软件开发成本,设计难度也会增加。
13、equals 与 == 的区别
==:==比较的是内存中存放对象的内存地址,用来判断两个对象的地址是否相同,即是否指向的是同一个对象。
equals:
equals比较的是两个对象内容是否相等,由于所有的类都是继承Object类,所以适用所有的对象,如果没有对该方法进行覆盖,调用的仍是Obejct类中的方法,Object类中equals方法返回的是==判断。