Java程序员从笨鸟到菜鸟(六)面试题

1. TCP传输的三次握手和四次挥手策略

传输控制协议(英语:Transmission Control Protocol, TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议

1.1 三次握手(TCP连接建立)

  • 第一次握手:客户端发送syn(同步序列编号)包(syn=j)到服务器,并进入SYN_SENT(表示客户端已发送syn包)状态,等待服务器确认。
  • 第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),确认序号设置为收到的序号+1,同时自己发送一个syn包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
  • 第三次握手:客户接受服务器的SYN+ACK包,同时发送确认包ACK(k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP建立连接)状态,完成三次握手。

1.2 四次挥手(断开TCP连接)

        当一方完成它的数据发送任务后就能发送一个FIN(英文的finish)来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

  • 第一次挥手:TCP客户端向服务端发送一个FIN,用来关闭客户端到服务端的数据传送,此时客户端仍能接收数据。
  • 第二次挥手:服务端接收到FIN,发送一个确认ACK,确认序号为收到的序号加1,类似syn包,一个FIN将占一个序号。
  • 第三次挥手:服务端关闭客户端连接,并发送一个FIN给客户端。
  • 第四次挥手:客户端发送ack回包,并确认序号设置为收到的序号加1,完成四次挥手。

 

2. TCP和UDP的区别

  • TCP(传输控制协议)是面向连接的、可靠的、基于字节流的传输层通信协议,每次传输数据时,要建立可靠的连接,需要进行“三次握手才能建立连接”。
  • UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!
  • TCP要求系统资源较多,UDP要求较少。
  • TCP保证数据的正确性和顺序,UDP可能会丢包,不保证顺序。
  • UDP应用场景:面向数据报、拥有大量的Client、对数据的安全性无特殊要求、网络负担非常重,但对响应速度要求非常高。

 

3. 创建ajax的过程

  • 创建XmlHttpRequest对象,也就是异步调用对象。
  • 创建一个新的http请求,并指定该请求的url、方法及校验信息。
  • 设置响应Http请求的状态变化函数。
  • 发送Http请求。
  • 获取异步调用返回的数据。
  • 使用javascript和DOM实现页面局部刷新。
// 从服务器请求数据
// XMLHttpRequest有五种状态:0:刚创建,还没调用open()方法;1:调用open()方法;2:调用send()方法;3:服务器开始相应;4:服务器响应完毕
function requestData() {
	var xhr;
	if (window.ActiveXObject) {//IE浏览器创建XMLHttpRequest对象
	    xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0");
	}else if(window.XMLHttpRequest){
	    xhr = new XMLHttpRequest();
	}
	xhr.open('get','url',true);
	xhr.send(null);
	xhr.onload = hanlder;
};
function hanlder(e) {
	var xhr = e.target;
	if(xhr.readyState == 4 && xhr.status == 200) {
	// readyState == 4表示服务器响应完毕,status == 200表示服务器已经接收到数据
	    var data = JSON.parse(xhr.responseText);
            console.log(data);
        }
}

备注:open()方法:

参数为true:表示异步加载,$.ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发$.ajax里的success方法,这时候执行的是两个线程;

参数为false:表示同步加载,在没有返回值之前,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行

 

4. final、finally、finalize的区别

  • final修饰类:不能被继承、修饰方法:不能被继承、变量:只能赋值一次。
  • finally和try catch一起使用(finally代码块无论有没有捕获到异常,都会执行),不能单独使用,用来释放资源。
  • finalize是一个方法,当垃圾回收器确定对该对象不存在引用,垃圾回收器调用finalize方法进行垃圾回收。

 

5. 深度优先搜索(DFS)和广度优先搜索(BFS)的区别

DFS:

  • 沿着一个顶点,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底(尽量往深处走)
  • 优点:内存消耗小,克服了广度优先搜索的缺点;缺点:难以寻找最优解,只是寻找有解

BFS:

  • 从一个顶点V0开始,辐射状地优先遍历其周围较广的区域。
  • 优点:可以寻找最优解,找最短路径;缺点:内存消耗大,适合子节点较少,层次不深

 

6. SpringMVC的工作原理

用户发送请求给前端控制器DispatcherServlet。
DispatcherServlet接收用户请求,调用HandlerMapping处理器映射器。
HanlderMapping很据(xml、url)查找合适的处理器,生成处理器对象和拦截器,一并返回给DispatcherServlet。
DispatcherServlet调用HanlderAdapter处理器适配器。
HanlderAdapter调用具体的处理器即Controler(后端控制器)
Controler解析生成ModelAndView。
HanlderAdapter将ModelAndView返回给DispatcherServlet。
DispatcherServlet将ModelAndView传给ViewResolver。
ViewResolver解析得到view,并返回给DispatcherServlet。
DispatcherServlet将接收到的view进行渲染,将模型数据填充到视图中
DispatcherServlet响应用户。

 

7. 封装、继承、多态

封装:隐藏对象的属性和实现细节,对外提供公共访问方法,(如插排,隐藏零线和火线,对外一共接口)

        优点:提高了代码的复用性、安全性。

继承:让类与类之间产生关系,子父类的关系,子类继承父类的非私有属性和方法。

        优点:提高了代码的复用性。

        缺点:耦合性强。

多态:同一操作作用于不同的对象,有不同的解释,产生不同的执行结果。

        产生条件:有继承关系,有方法的重写,父类引用指向子类对象。

        重载(overload)和重写(override)是实现多态的主要方式。

        override:重写(方法名和参数列表一模一样,与返回值类型有关)不能改变返回值类型。

        overload:重载(方法名相同,参数列表不同,与返回值类型无关)可以改变返回值类型。

抽象和封装的区别:

抽象和封装是互补的概念,抽象关注对象的行为,封装关注对象行为的细节,封装可以看成是用来提供抽象的一种策略

 

8. display:none和visibility:hidden的区别

  • display:none 隐藏对应元素,在文档布局中不再为其分配内存空间,就当不存在
  • visibility:hidden 隐藏对应元素,在文档中仍会为其保留原来的空间

 

9. link和@import的区别

  • link是html标签,@import是css提供的
  • 在页面加载时,link会同时加载,但是@import只有在引用的时候才会完成加载
  • @import只有在IE5以上才能识别,link无兼容问题
  • link的权重高于@import的权重

 

10. forward和redirect的区别

是servlet里面的两种跳转方式,forward也叫转发,redirect叫重定向

区别:

 

  • 地址栏:转发显示的是请求的URL,重定向显示的是新的URL,不是请求的URL
  • 请求次数:转发时1次request请求,重定向是2次请求
  • 共享request的数据:转发 两个资源共用一个request,可以共享request中的数据;重定向 两个资源不是同一个request,不可以数据共享

范例:办营业执照

转发:小明去A局办执照,A局知道这事情是B局的,但是并没有叫小明去B局,而是叫他等待,然后打电话去B局,叫B局办好送过来

重定向:小明去A局,A局知道是B局的事情,直接说这是B局负责的,叫小明自己去B局办理

 

11. error和exception的区别

 

Error类和Exception类都是Throwable类的子类

Error一般是与虚拟机相关的问题,如调用方法栈溢、内存不足、系统崩溃等,对于这类错误造成的程序中断,程序本身无法预防和恢复,建议中止程序。

Exception一般表示程序可以处理的异常,可以捕获且能恢复,出现了这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意中止,Exception又分为:运行时异常和受检查异常;运行时异常,变异能通过,但是运行之后就终止了,程序不会处理运行时异常,受检查异常,要么用try、catch,要么throws声明抛出,交给他的父类处理,否则编译不通过。

Error和Runtimeexception及其子类称为未检查异常(unchecked exception),其它为checked exception(受检查异常)

Exception:

 

  1. 可以是可被控制(checked)或不可控制的(unchecked)
  2. 表示一个由程序员导致的错误
  3. 应该在应用程序级被处理

Error:

 

  1. 总是不可控制的(unchecked)
  2. 经常用来表示系统错误或底层资源的错误
  3. 应该在系统级被捕捉

java定义了两类异常:

 

  1. Checked exception:这类异常时Exception的子类,异常的向上抛出机制进行处理,加入子类A抛出异常,那么父类必须抛出异常,问题:代码效率低、耦合度高
  2. Unchecked exception:这类是RuntimeException的子类

12. Collection和Collections的区别

Collection:是一个集合接口,提供了对集合对象的基本操作方法的接口,为各种具体的集合提供了最大化的操作方式,直接继承类有List和set;

Collections:则是集合类的辅助类/工具类,提供了一系列静态方法,包括对集合的排序、搜索、反转等操作。

 

13. HashMap和HashTable的区别

HashMap和HashTable都是实现了Serializable接口(可以序列化)、Cloneable接口(可以克隆)、Map接口。

基于哈希表实现的,同样内部都是通过单链表解决问题冲突,容量不足时,会自动增长。

扩容:新建了一个HashMap的底层数组,然后调用transfer方法,将原来HashMap的元素全部添加到新的HashMap中(重新计算元素所在数组中的位置),扩容比较耗时,所以使用时最好需要先知道元素的个数,有利于提高HashMap的性能。

构造方法:有四个构造方法,构造方法中有两个参数影响性能:初始容量(16)和加载因子(0.75),当哈希表中的条目超出了加载因子和初始容量的乘积时会进行扩容操作

加载因子:加载因子越大,对空间利用越充分,但查找效率会降低,加载因子过小,则造成空间浪费,0.75是一个比较理想的值。

区别:

1. HashMap是线程不安全的,可以存null值;HashTable是线程安全,效率低,不能存null值。

2. HashMap的父类是AbstractMap类;HashTable的父类是Dictionary类。

3. HashMap把HashTable的contains方法去掉了,改成containsValue和containsKey;HashTable则依然保存了这三个方法。

4. HashMap、HashTable都使用了Iterator,而HashTable还使用了Enumeration的方式。

5. HashMap的默认初始容量是16,扩容之后,容量是原来的2倍;HashTable的默认初始容量是11.扩容之后是原来容量的2倍+1.

 

14. String、StirngBuffer、StringBuilder的区别

1. String是不可变的字符串常量、StringBuffer可变的字符串变量,线程安全、StringBuilder可变的字符串变量,线程不安全。

2. String是不可变的对象,每次对String进行改变时都是新建一个String对象,经常改变内容的字符串最好不要使用String,每次生成对象都会对系统性能产生影响;StringBuffer类会对对象本身进行操作,而不是产生新对象,再改变对象的引用,String实现对对象的拼接实则是StringBuffer的append方法。

 

15. throw和throws的区别

异常处理:

 

  1. throws 自己不处理,抛给调用者处理
  2. throw 自己捕获处理
  3. 系统自动抛出异常

throw:用在方法体内,跟的是异常对象名,抛出一个具体的异常类型,自己捕获异常进行异常处理。

throws:用在方法后面,跟的是异常类名,声明一个方法可能抛出的异常信息,将异常往上传,自己不做处理,谁调用谁处理,表示出现异常的可能性,并不一定会抛出异常。

 

16. Spring IoC和AOP的理解

1. Spring的优点:

  • 降低了组件之间的耦合性,实现软件各层之间的解耦
  • 可以提供更多服务,如事务管理,消息服务等
  • 提供单例模式支持
  • 提供了AOP技术,容易实现权限拦截
  • 提供了众多的辅助类,加快应用的开发
  • 对主流框架提供了集成支持
  • 独立于各种应用服务器

2. IoC(控制反转)

依赖注入(Dependency Injection)和控制反转(Inversion ofControl)是同一个概念,当某个对象需要另外一个对象协助时,在传统的设计过程中,这些工作是由调用者来创建被调用者,但在spring中创建被调用者实例的工作不再由调用者来做,因此称为控制反转,而是通过spring来完成,然后注入调用者,因此也被称为依赖注入。

3. AOP(面向切面编程)

面向切面编程(AOP)完善spring的DI(依赖注入),在spring事务中主要表现为两方面:面向切面编程提供声明式事务管理、spring支持用户自定义的切面。面向切面编程(AOP)是对面向对象编程(OOP)的补充,面向对象编程将程序分解成各个层次的对象,面向切面编程是将程序分解成各个切面。特征:各个步骤之间有良好的隔离性、源代码无关性。

把系统的一个方面的功能封装成对象的形式来处理就是面向切面编程

 

17. 基本数据类型和引用数据类型

数据类型大小(bit)范围默认值包装类
byte(字节)8-128 - 1270Byte
shot(短整型)16-32768 - 327670Short
int(整型)32-2147483648-21474836470Integer
long(长整型)64-9233372036854477808-92333720368544778070Long
float(浮点型)32-3.40292347E+38-3.40292347E+380.0fFloat
double(双精度)64-1.79769313486231570E+308-1.79769313486231570E+3080.0dDouble
char(字符型)16‘ \u0000 - u\ffff ’‘\u0000 ’Character
boolean(布尔型)1true/falsefalseBoolean
基本数据类型引用数据类型
  
变量名指向具体的数值变量名指向存数据对象的内存地址,即变量名指向hash值
变量在声明之后java就会立刻分配给他内存空间它以特殊的方式(类似C指针)指向对象实体(具体的值),这类变量声明时不会分配内存,只是存储了一个内存地址
基本类型之间的赋值是创建新的拷贝对象之间的赋值只是传递引用
“==”和“!=”是在比较值“==”和“!=”是在比较两个引用是否相同,需要自己实现equals()方法
基本类型变量创建和销毁很快类对象需要JVM去销毁

 

18. public、protected、friendly、private作用域

作用域    当前类当前包子孙类外包
public   √
protected ×
friendly(默认)××
private×××

 

19. 一个“.java”源文件中是否可以包括多个类(不是内部类)

可以有多个类,但是只能有一个public类,并且public类型必须与文件名一致

 

20. Java中有没有goto

goto是java中的保留字,现在不再使用

 

21. & 和 && 的区别

共同点:都可以用作逻辑与运算,当运算符两边的表达式结果为true时,整个运算结果才为true

不同点:

1. &&还具有短路的功能,如果第一个表达式为false,则不用计算第二个表达式 

String str = null;
if (str != null && !("").equals(str)) {
    System.out.println("true");
} else {
    system.out.println("false");
}

运行结果:

如果是 && 则直接返回false,但如果是 & 的话就会抛出 java.lang.NullPointerException异常

2. &可以做位运算法,当&操作符两边的变大时不是boolean时,&表示按位与操作

 

22. switch语句能否作用在byte、long、String上

在switch语句中,参数只能是一个整数表达式或枚举常量,整形表达式可以是int或Integer包装类型,由于byte、short、char都可以隐式转换为int,所以这些类型和对应的包装类型是可以作用在switch中,但是long和String不能隐式转换成int,所以不符合语法规则。

 

23. short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 

对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误

对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译

 

24. char型变量中能不能存贮一个中文汉字?为什么?

char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字

 

25. 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的

final StringBuffer sb = new StringBuffer("Hello");

a = new StringBuffer("Hello world"); // 编译错误

sb.append("world"); // 正常编译

 

25. 静态变量和实例变量的区别?

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

 

26. 是否可以从一个static方法内部发出对非static方法的调用?

非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用

 

27. Integer与int的区别

1. int是基本数据类型,Integer是int的包装类

2. int的默认值为0,Integer默认值是null

3.Integer可以区分未赋值和值为0的情况,int不能表达出为0的情况 例如想表达一个学生未参加考试和成绩为0的区别

4.在JSP开发中,Integer默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认值为0,所以用el表达式在文本框显示是,结果为0,所以int不适合作为web层的表单数据类型

5. Int使用不需要实例化,Integer要实例化才能使用

6. Integer实际是对象的引用,指向新建的对象,int直接存储数据值

7. Integer变量和int变量比较时,只要值是相等的,返回true,java会自动拆包为int

自动装箱:将基本数据类型重新转成对象 如 Integer num = 9

自动拆箱:将包装类型转换成基本数据类型 如 Integer num = 9; num--

 

28. has a与is a的区别

has a是包含关系

is a是属于关系

 

29. 分层设计的好处:

1. 实现软件之间的解耦

2. 便于进行分工

3. 便于维护

4. 提高组件的重用

5. 便于功能扩展

 

30. hashCode方法的作用?

作用:是用来鉴定两个对象是否相等

equals和hashcode方法的不同:

equals方法是给用户调用的,但如果想要判断2个对象是否相等,可以重写equals方法,然后调用,主要是用来判断从表面上看或是从内容上看

hashcode方法一般用户不会去调用,比如hashmap中,key值是不可以重复的,在判断key是不是重复的时候使用了hashcode方法,而且也使用了equals方法,hashcode相当于是一个对象的编码,和equals不同就在于他返回的是int类型的

 

31. 对MVC的理解

MVC是Model-View-Controller,即模型-视图-控制器,MVC是一种设计模式,强制把,输入、处理和输出分开

 

  • 视图:用户看到并与之交互的界面,视图接受用户输入并向用户显示相关数据,不做任何业务处理
  • 模型:表示业务数据和业务处理,相当于JavaBean,一个模型能为多个视图提供数据,提高了应用程序的重用性
  • 控制器:控制器接受请求并调用相关的模型去处理请求,然后根据处理的结果使用响应的视图来显示结果

处理过程:控制器接收用户请求,调用相应的模型来进行业务处理,并返回给控制器,控制器调用相应的视图来显示处理结果,并通过视图呈现给用户

 

32. 代码块

 

  • 局部代码块:限定了生命周期
  • 构造代码块:在方法外出现,每创建一次对象就会执行一次,优先于构造方法执行
  • 静态代码块:随着类的加载而加载,且执行一次

 

33. servlet生命周期

  1. 初始化阶段,调用init()方法
  2. 响应客户端请求,调用service()方法,doGet()和doPost()方法
  3. 终止阶段:调用destroy()方法

 

34. “”和null的区别

“”是字符串常量,同时是一个String类对象,可以调用String类的方法

null是空常量,不能调用任何方法,会出现空指针异常,可以给任意的引用数据赋值

 

35.try{}里有一个return语句,紧跟在try后的finally里的code会不会执行?是在return前还是return后执行

private static int testTry() {
     int x = 1;
     try {
         System.out.println("try里面的x:" + x);
         return x;
     } finally {
         System.out.println("进入finally块...");
         ++x;
         System.out.println("finally块的x为:" + x);
     }
}

运行结果:

try里面的x:1
进入finally块...
finally块的x为:2
结果为:1

Process finished with exit code 0

分析:

在return后执行,函数返回值是finally之前确定的,无论finally中的代码怎么样,返回的值都不会改变,仍然是之前return语句中保存的值

 

36.常见的运行时异常(RuntimeException)

 

  • NullPointerExceptiion 空指针异常 如String s = null, boolean eq = ("").equals(s);
  • ClassCastException 类型强制转换异常 如Object obj = new Object(), String s = (String)obj;
  • IllegalArgumentException 传递非法参数异常
  • IndexOutOfBoundsException 下标越界异常 如int[] arr = new int[3], int b = arr[3];
  • NumberFormatException 数字格式异常 如int a = Integer.parseInt("ab3");
  • StringIndexOutOfBoundsException 字符串越界 如String s = "hello",  char c = s.charAt(6);

37.Exception和RuntimeException的区别

1.Exception:在程序中必须使用try...catch进行处理;RuntimeException:可以不使用try...catch进行处理,如果异常产生,则交由JVM处理,会中断程序运行

2.非RuntimeException必须自己写catch块处理掉

3.RuntimeException是非检查异常,其它都是检查异常

Throwable有两个子类:Error、Exception;RuntimeException是Exception的子类

UnCheckedException(未检查异常):Error、RuntimeException

一个方法必须声明所有的可能抛出的已检查异常;未检查异常要么不可控制(Error),要么应该避免(RuntimeException)。如果方法没有声明所有的可能发生的已检查异常,编译器就会给出错误信息

 

38. 区分set重复元素的方法

使用equals()方法

为什么使用equals()而不是==来区分

==是判断两者是否是同一对象(同一事物),equals()是用来比较两个引用是否指向同一对象,set里面存储的是对象的引用,所以使用equals()方法来比较是否有重复的值,

这样理解会好一些:一间仓库(set)有很多房间,房间有门牌号(对象的引用),房间里存储了很多货物,判断两个房间是否有重复的货物,则只需根据门牌号排查是否有重复的货物,也就是比较对应的引用是否指向同一对象。

 

39.abstract class和interface的区别

 

Abstract class

Interface

实例化

不能

不能

一种继承关系,一个类只能使用一次继承关系。可以通过继承多个接口实现多重继承

一个类可以实现多个interface

数据成员

可有自己的

静态的不能被修改即必须是static final,一般不在此定义

方法

可以私有的,非abstract方法,必须实现

不可有私有的,默认是public,abstract 类型

变量

可有私有的,默认是friendly 型,其值可以在子类中重新定义,也可以重新赋值

不可有私有的,默认是public static final 型,且必须给其初值,实现类中不能重新定义,不能改变其值。

设计理念

表示的是“is-a”关系

表示的是“like-a”关系

实现

需要继承,要用extends

要用implements

abstract class和interface都是用来进行抽象类定义的

抽象类:声明方法的存在而不实现。它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况,不能创建abstract 类的实例,不能有抽象构造函数或抽象静态方法,Abstract 类的子类为它们父类中的所有抽象方法提供实现

接口:抽象类的实体,在接口中,所有方法都是抽象的,接口中的所有方法都是抽象的,没有一个程序体

接口可以继承接口,抽象类可以实现接口,抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数,接口更关注能实现什么功能,而不管怎样实现

相同点:

1.两者都是抽象的,都不能实例化

2.interface的实现类及abstract class的子类都必须实现已经声明的抽象方法

不同点:

1.interface需要实现,使用关键字implements,abstract class需要继承,使用关键字extends

2.一个类可以实现多个interface,但类只能继承一个abstract class

3.interface强调特定功能的实现,而abstract class强调所属关系

4.尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同,interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现

选择含义:

一是Abastract class中并非所有的方法都是抽象的,只有那些由abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在Abstrct class中必须定义方法体

二是abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以通过再次声明其方法为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类

40.两个对象相同,hashcode不同?

1.对象相等,hashcode一定相等

2.hashcode相等,对象未必相等

hash code、equals和“==”三者的关系
1.如果是基本类型变量,没有hashcode和equals方法,基本变量的比较方式就只有==
2.如果是变量,==比较的是引用的地址,equals比较引用对应的值
   如果是类,用==和equals是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的
   那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容

3.hashcode:hashmap的工作方法是:通过一个你传入的object值对应的hashcode在内存中寻找地址,找到之后再通过equals比较地址中的内容是否原来放进去的一样,相等的话取出value值

 

41.2*8最有效率的做法

2  << 3 左移3位,就相当于2*2^3

 

42.外部类可以访问内部类的私有成员

外部类可以访问内部类的private/protected变量,就像访问自己的private/protected变量一样

就相当老师可以检查学生书包里有没有课外书

43.css盒子模型

css盒子模型就是在网页设计中经常用到的CSS技术的一种思维模型

外边距(margin)、边框(border)、内边距(padding)、内容(content)四个属性

内边距可以理解为盒子里装的东西和边框的距离,而边框有厚薄和颜色之分,内容就是盒子中间装的东西,外边距就是边框外面自动留出的一段空白

 

44. notify/notifyAll/wait 这3个方法必须处于 synchronized 代码块或者是方法块中,否则就会抛出 IlleegalMonitorStateException

调用这三个方法之前必须拿到当前锁对象的监视器 monitor 对象,也就是说这三个依赖于 monitor 对象,而 synchronized 关键字可以获取 monitor

45. http 和 https 的区别

HTTP (超文本传输协议)协议以明文方式发送内容,不提供任何方式的数据加密,不适合传递一些敏感信息,如:信用卡号,支付密码等信息

HTTPS(安全套接字的超文本传输协议)为了传输数据的安全,Https 在 Http 的基础上加入了 SSL(Secure Sockets Layer) 协议,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密

 1. https 相对于 http 加入了 ssl 层
 2. https 需要从CA(数字证书签发机构)申请免费的证书
 3. https 安全但是耗时多,缓存不是很好

 4. 注意兼容 http 和 https

Https 要使能客户端和服务端的通信过程得到安全保证,必须使用对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密算法也不安全,会有中间人篡改公钥的可能性,所以客户端和服务端不能直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全,这样通过这些机制得到对称加密算法,就此服务端和客户端对数据进行加密解密,从而实现安全

证书就是 HTTPS 中的数字证书,证书编号就是数字签名,而第三方机构是指数字证书签发机构(CA)

非对称加密算法:私钥加密后的密文只要是公钥都可以解密,但是公钥加密后的密文,只有私钥可以解密,私钥只有一个人有,而公钥可以发给所有人

证书真伪:背景:证书被同一家第三方机构证书的中间人进行调包,客户端验证证书的真伪:证书上写着如何根据证书的内容生成证书编号,客户端拿到证书后根据证书上的方法自己生成一个编号,如果编号和证书编号相同,证书就是真的,为避免证书编号被调包,使用第三方的私钥进行加密

 

46. redis

定义:是一个 key-value 存储系统

存储:内存储、磁盘存储、log 文件部分

存储的 value 类型:String(字符串)、list(链表)、set(集合)、zset(有序集合)、hash(哈希类型)

数据缓存在内存中,redis 会周期性把更新的数据写入磁盘,或者是把修改操作写入追加的记录文件

实现了 master-slave (主从)同步,数据可以从主服务器向任意从服务器同步

redis 使用两种文件格式:全量数据、增量请求

47.均衡负载

公司会建立很多的服务器,这些服务器组成了服务器集群,当用户访问网站的时候,先访问一个中间服务器再让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入选择的服务器,这样用户每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免服务器崩溃的情况

 

48. Hibernate 和 Mybatis 比较

1. 开发速度,真正掌握 Hibernate 比较难一些,Mybatis 容易上手

2. 开发工作量,Hibernate 有良好的映射机制,无需关心 SQL 的生成与结果映射,可更专注于业务流程,针对高级查询,Mybatis 需要手动编写 SQL 语句和 ResultMap

3. SQL 优化方面,Hibernate 会将所有字段查询出来,Mybatis 是手动编写 SQL 语句,可以指定查询字段,Hibernate 具有自己的日记统计,Mybatis 要借助 Log4j 来记录操作日志

4. 缓存:Hibernate 一级缓存是 Session 缓存,二级缓存是 SessionFactory 级别的,称为进程级缓存;Mybatis 一级缓存是 Session 级别的缓存,二级缓存是 Mapper 级别的缓存,需要在配置文件中手动开启 <cache/>

相同点:都是通过 SessionFactoryBuilder 由 XML 文件生成 SessionFactory ,然后 SessionFactory 生成 Session,Session 执行 SQL 语句;都支持事务处理

 

不同点:

Mybatis 优势:可以进行 SQL 优化,减少查询字段,容易掌握

Hibernate 优势:DAO 层开发比 Mybatis 简单, Mybatis 需要维护 SQL 和 ResultMap;对象的维护和缓存要比 Mybatis 好;数据库移植性好,Mybatis 数据库移植性不好,不同数据库要写不同的 SQL 语句;Hibernate 有更好的缓存机制,可以使用第三方缓存

 

49. SQL 优化

主要思路:避免全表扫描

1. 对查询进行优化,尽量便面全表扫描,首先考虑在 where 及 order by 上建立索引

2. 尽量避免 where 语句对字段进行null 判断

3. 尽量避免使用操作符,如 != 或 <>

4. 多条件查询时,使用 union 代替 or

5. 对于连续的值,能用 between 就不用 in

6. 尽量不要使用 like 'c%' 字段

7. 尽量避免在 where 子句中对字段进行表达式操作

8. 尽量避免在 where 子句中进行函数操作

9. 不要做没有意义的查询,如生成一个空表结构

10. 很多时候用 exists 代替 in

11. 尽量使用数字型字段

12. 尽可能使用 varchar 代替 char 变长字段占用空间小

13. 不要使用 select *

 

50. restful 风格接口

一种设计风格、架构风格,不是标准,只是提供了一种设计规范和约束,使代码更简洁、更有层次,每一个资源都有一个地址,资源本身是方法调用的目标

如 springmvc 中 @RequestMapping(value = "/", method = ReqestMethod.GET) 有请求路径

 

51. Statement 和 PreparedStatement 的关系和区别

关系:PreparedStatement 继承自 Statement, 都是接口

区别:PreparedStatement 可以使用占位符,是预编译的,批处理效率比 Statement 效率高

  1. 语法上:Statement stat = conn.createStatement(); stat.executeUpdate(sql)   PreparedStatement pstmt = conn.PreparedStatement(sql); pstmt.executeUpdate();
  2. PreparedStatement 安全高效
  3. PreparedStatement 代码可维护性和可扩展性强

 

52. HTTP、Socket、TCP 的区别

HTTP 是应用层的协议,靠近用户端;TCP 是传输层的协议;Socket 是从传输层抽象出来的一个抽象层,本质是接口;HTTP 是超文本传输协议,Socket 只是读写 IO,客户端请求服务端遵循 HTTP 协议,请求的实现方式还是基于 Socket

TCP 连接与 HTTP 连接的区别:

 HTTP 是基于 TCP,客户端往服务端发送 HTTP 请求就是要先建立 TCP 连接,也就是三次握手

TCP 连接与 Socket 连接的区别:

Socket 是传输层抽象出来的接口,可能基于 TCP,也可能基于 UDP

HTTP 连接与 Socket 连接的区别: 

1. HTTP 是短连接,Socket(基于 TCP 协议)是长连接,Socket 一旦建立三次握手,除非一方主动断开,否则连接状态一直保存

2. HTTP 连接服务端无法主动发送消息,HTTP 采用“请求-响应”机制,在客户端还没发送消息给服务端时,服务端无法向客户端主动发送数据;Socket 连接后,双方可以随时向对方发送数据。

 

53、上亿数据中找出前10000个数字

思路:

1、将所有的数字进行排序,然后取前10000个数字,最快的算法时间复杂度一般为O(nlogn),但是题目只需找到钱10000个数,而排序将所有的元素都排序了,做了很多无用功

2、局部淘汰法:与排序法类似,用一个容器保存前10000个数,然后将剩余所有的数字---与容器最小数字相比,如果所有后续元素都比容器内的10000个数还小,name容器内的10000个数就是最大的,当后续元素比最小数字大,则删掉最小元素,并将元素插入容器,遍历完剩下所有的数据,时间复杂度为O(n + m^2)

3、分治法:将一亿个数据分成100份,每份100万个数据,找到每份中最大的10000个,最后在剩下的100*10000个数据里面找最大的10000个,如果100万数据选择足够理想,那么可以过滤掉99%的数据。100万个数据里面查找最大的10000个数据的方法如下:用快速排序方法:将数据分2堆,如果大的那个堆个数大于10000个,继续对大的堆分成2堆

4、Hash 法:如果很多重复的数据,先通过hash去重,如果重复率高德华,会减少很大的内存量,从而缩小运算空间,然后通过分治法找出最大的10000个数

54、subsequence 和 substring 的区别

substring必须是原字符串中连续的字符串,而subsequence可以不是

例子:awkwqtez, akw是其subsequence,而kwqt是其substring。

55、volatile是不能保证线程安全的

它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而不是从缓存中读取的数据

56、创建对象的五种方式

new使用 new 创建调用了构造函数
反射使用 Class 类的 newInstance 方法调用了构造函数
反射使用 Constructor 类的 newInstance 方法调用了构造函数
反序列化使用反序列化没有调用构造函数
克隆使用 clone 方法没有调用构造函数

 

版权声明:欢迎转载, 转载请保留原文链接。https://mp.csdn.net/postedit/79377109

 

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EL表达式的简单介绍 一、JSP EL语言定义 E L(Expression Language) 目的:为了使JSP写起来更加简单。 表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法。它是一种简单的语言,基于可用的命名空间(PageContext 属性)、嵌套属性和对集合、操作符(算术型、关系型和逻辑型)的访问符、映射到 Java 类中静态方法的可扩展函数以及一组隐式对象。 EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能。脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素。它们通常用于对象操作以及执行那些影响所生成内容的计算。JSP 2.0 将 EL 表达式添加为一种脚本编制元素。 二、JSP EL简介 1、语法结构 ${expression} 2、[ ]与.运算符 EL 提供“.“和“[ ]“两种运算符来存取数据。 当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用“[ ]“。例如: ${user.My-Name}应当改为${user["My-Name"] } 如果要动态取值时,就可以用“[ ]“来做,而“.“无法做到动态取值。例如: ${sessionScope.user[data]}中data 是一个变量 3、变量 EL存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。 因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找。 假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。 属性范围在EL中的名称 Page PageScope Request RequestScope Session SessionScope Application ApplicationScope 二、JSP EL 中的有效表达式 有效表达式可以包含文字、操作符、变量(对象引用)和函数调用。我们将分别了解这些有效表达式中的每一种: 1、文字 JSP 表达式语言定义可在表达式中使用的以下文字: 文字 文字的值 Boolean true 和 false Integer 与 Java 类似。可以包含任何正数或负数,例如 24、-45、567 Floating Point 与 Java 类似。可以包含任何正的或负的浮点数,例如 -1.8E-45、4.567 String 任何由单引号或双引号限定的字符串。对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则单引号不需要转义。 Null null 2、操作符 JSP 表达式语言提供以下操作符,其中大部分是 Java 中常用的操作符: 术语 定义 算术型 +、-(二元)、*、/、div、%、mod、-(一元) 逻辑型 and、&&、or、||、!、not 关系型 ==、eq、!=、ne、、gt、<=、le、>=、ge。可以与其他值进行比较,或与布尔型、字符串型、整型或浮点型文字进行比较。 空 空操作符是前缀操作,可用于确定值是否为空。 条件型 A ?B :C。根据 A 赋值的结果来赋值 B 或 C。 3、隐式对象 JSP 表达式语言定义了一组隐式对象,其中许多对象在 JSP scriplet 和表达式中可用: 术语 JSP 页的上下文。它可以用于访问 JSP 隐式对象,如请求、响应、会话、输出、servletContext 等。例如,${pageContext.response} 为页面的响应对象赋值。 此外,还提供几个隐式对象,允许对以下对象进行简易访问: 术语 定义 param 将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 $(param.name) 相当于 request.getParameter (name)。 paramValues 将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues.name) 相当于 request.getParamterValues(name)。 header 将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header.name} 相当于 request.getHeader(name)。 headerValues 将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues.name} 相当于 request.getHeaderValues(name)。 cookie 将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie.name.value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues.name} 表达式。 initParam 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 除了上述两种类型的隐式对象之外,还有些对象允许访问多种范围的变量,如 Web 上下文、会话、请求、页面: 术语 定义 pageScope 将页面范围的变量名称映射到其值。例如,EL 表达式可以使用 ${pageScope.objectName} 访问一个 JSP 中页面范围的对象,还可以使用 ${pageScope.objectName.attributeName} 访问对象的属性。 requestScope 将请求范围的变量名称映射到其值。该对象允许访问请求对象的属性。例如,EL 表达式可以使用 ${requestScope.objectName} 访问一个 JSP 请求范围的对象,还可以使用 ${requestScope.objectName.attributeName} 访问对象的属性。 sessionScope 将会话范围的变量名称映射到其值。该对象允许访问会话对象的属性。例如: $sessionScope.name} applicationScope 将应用程序范围的变量名称映射到其值。该隐式对象允许访问应用程序范围的对象。 三、特别强调: 1、注意当表达式根据名称引用这些对象之一时,返回的是相应的对象而不是相应的属性。例如:即使现有的 pageContext 属性包含某些其他值,${pageContext} 也返回 PageContext 对象。 2、 注意 <%@ page isELIgnored="true" %> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言。 四、举例说明 1、例如, < %=request.getParameter(“username”)% > 等价于 ${ param.username } 2、例如,但是下面的那句EL语言可以完成如果得到一个username为空,则不显示null,而是不显示值。 userName:<input name="uname" type="text" value="${param.uname}/> pwd:<input name="pwd" type="password" value="${param.pwd}/> addr:<input name="addr" type="text" value="${param.addr}/> 3、例如: <% =request.getAttribute(“userlist”) %> 等价于$ { requestScope.userlist } 4、例如,原理如上例3。 ${ sessionScope.userlist } 1 ${ sessionScope.userlist } 2 ${ applicationScope.userlist } 3 ${ pageScope.userlist } 4 ${uselist} 含义:执行顺序为4 1 2 3。 “.”后面的只是一个字符串,并不是真正的内置对象,不能调用对象。 4、例如, <%=user.getAddr( ) %> 等价于 ${user.addr} 第一句前面的user,为一个变量。 第二句后面user,必须为在某一个范围里的属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值