2020年6月11日面试被吊打总结
1.java中的final关键字。
答:1.在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。被final修饰修饰的类不能被继承(如果一个类不想让他被继承就用final修饰),final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
2.使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。注:类的private方法会隐式地被指定为final方法。
3.final修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象(即不能修改指向的内存地址)。
2.String为什么使用final进行修饰。
答:主要为了安全和效率。final修饰的String,代表了String的不可继承性,final修饰的char[]代表了被存储的数据不可更改性(但是:虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了对象本身不会变)。
1.为了实现字符串池(字符串存储的位置和其他类型的常量不一样,字符串专门有个字符串池,也只有用final修饰才能实现字符串池。不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现(String interning是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串。)
2.为了线程安全(譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。因为不可变所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。)
3.为了实现String可以创建HashCode不可变性(String创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。)
参考:https://www.cnblogs.com/dolphin0520/p/3736238.html
3.java中的static关键字
答:static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。静态方法可以通过类名直接调用。static修饰的变量也称为静态变量,静态变量和非静态变量的区别是:静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static块可以优化程序性能,是因为它的特性:只会在类被初次加载的时候执行一次。
4.java的特性
答:面向对象程序设计四大基本概念:封装、继承、多态、抽象。
1.封装在java中的体现:隐藏对象的属性和实现的细节,仅对外提供公共访问方式,在类定义中用private关键字来实现封装。
封装的好处:
一是用private把类的细节与外界隔离起来,从而实现数据项和方法的隐藏,而要访问这些数据项和方法唯一的途径就是通过类本身,类才有资格调用它所拥有的资源(方法,数据项属性等等)。所以第一个好处就是数据的安全性提高了。
二是通过隐藏隔离,只允许外部对类做有限的访问,开发者可以自由的改变类的内部实现,而无需修改使用该类的那些程序。只要那些在类外部就能被调用的方法保持其外部特征不变,内部代码就可以自由改变,各取所需,利于分工。
三就是提高了代码的重用性,封装成工具类以后能够减少很多繁琐的步骤。(参考:https://www.cnblogs.com/EasonJim/p/6936066.html)
2.继承在java中的体现:继承关系是传递的。A若类C继承类B,类B继承类A,则类C既有从类B那里继zhi承下来的属性与方dao法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法是隐式的。继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。Java出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。
子类继承后可以重写,也可以不重写,看需要决定。
如果重写的话在实例中调用的是新写的方法
如果不重写的话在实例中调用的是父类的方法。
3.多态继承在java中的体现:多态存在的三个条件(继承、重写、父类引用指向子类对象),在一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。无论子类表现的形式有几种,都可以向上转型为父类,即多态(例如:A继承了B,A重写了B中的方法,方法的表现形式为一种,C继承了B,C重写了B中的方法,表现为另一种形式,但是AC都可以向上转型:B b=new (),B b=new C())
多态的使用场景:
(1)方法的重载和重写
(2)子类对象的多态性
5.重载和重写的区别。
(1)重写:
就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。
1.发生在父类与子类之间
2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
(2)重载:
在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
1.重载Overload是一个类中多态性的一种表现
2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准
来源:https://blog.csdn.net/wintershii/article/details/80558739
6.servlet的声明周期。
答:servlet 声明周期可以分四个阶段:
- 类装载过程
- init() 初始化过程
- service() 服务过程,选择doGet \ doPost
- destroy() 销毁过程
执行流程:
1. 根据时机,Web容器加载对应的Servlet类,加载后进行init()初始化。
- 设置了容器启动时初始化
- 请求第一次请求此Servlet时初始化
- Servlet类文件被更新后,重新装载Servlet
2. 接收到请求,容器根据配置将请求交给对应的Servlet,同时创建HttpServletRequest 和 HttpServletResponse 对象,一并交给Servlet。
3. 在service()中根据HttpServletRequest得请求类型等信息,调用doGet\doPost 进行业务处理。
4. 处理后通过HttpServletResponse获得相应信息,返回给Web容器。
5. Web容器再将响应返回给客户端。
来源:https://www.cnblogs.com/lingz/p/10031309.html
7.线程的生命周期。
线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、销毁。
-
新建:就是刚使用new方法,new出来的线程;
-
就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;
-
运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;
-
阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;
-
销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;
8.怎么理解同步和异步。
同步是阻塞模式,
异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去, 而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效 率。
9.怎么解决sql注入
1.(简单又有效的方法)PreparedStatement
2.使用正则表达式过滤传入的参数
3.字符串过滤
4.jsp中调用该函数检查是否包函非法字符
5.JSP页面判断代码:
10.session和cookie的区别。
(1)、存储位置不同
cookie的数据信息存放在客户端浏览器上。
session的数据信息存放在服务器上。
(2)、存储容量不同
单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。
对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
(3)、存储方式不同
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
(4)、隐私策略不同
cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。
session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。
(5)、有效期上不同
开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。
(6)、服务器压力不同
cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
(7)、浏览器支持不同
假如客户端浏览器不支持cookie:
cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。
运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。
假如客户端支持cookie:
cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。
session只能在本窗口以及子窗口内有效。
(8)、跨域支持上不同
cookie支持跨域名访问。
session不支持跨域名访问。
- 类与类之前需要特定的接口进行协调,而不在乎其如何实现。
- 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。
- 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。
- 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。
抽象类使用场合
- 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。
- 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。
- 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特定的功能
个人理解:java中类之间只能是单继承关系,如果需要实现多继承,则使用接口的方式实现多个接口,如果接口中定义方法不需要全部实现则使用抽象类的方式去重写抽象类里面的方法。抽象类可以提供实现方法,可以将公有的方法提出来实现,需要不同表现形式的方法则在子类中进行重写。当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。实现多态时,接口更加适合。
所有的请求都可以给服务器传递内容,也可以从服务器获取内容。
GET:从服务器获取数据(给的少拿的多)
POST:向服务器推送数据(给的多拿的少)
DELETE:删除服务器的一些内容
PUT:向服务器存放一些内容
HEAD:只请求页面的头部
TRACE(或OPTIONS):发送一个探测性请求,如果返回了信息说明建立了连接
14.post和get的区别。

来源:https://blog.csdn.net/qq_41939384/article/details/87628188
15.什么是rpc。
答:RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
面试公司:中软

浙公网安备 33010602011771号