java面试总结(4)

常见问题:

1.ArrayList和LinkedList

ArrayList 内部借助于数组实现元素的存储。
ArrayList 是线程不安全的,相对于线程安全的Vector来说可能效率较高。
ArrayList 内部基于数组实现数据存储,因此随机访问效率较高。( 可以使用索引直接访问数组中的元素 )
ArrayList 内部基于数组实现数据存储,因此增删元素速度较慢。( 增删元素可能需要挪动数组中大量元素 )

LinkedList 内部基于链表实现元素的存储。
LinkedList是线程不安全的。
LinkedList内部基于链表实现数据存储,因此随机访问效率较低。( 需要逐个遍历链表中的结点 )
LinkedList内部基于链表实现数据存储,因此增删元素速度较快。( 增删元素只需要修改相邻两个节点的指针 )

2.线程的五种状态:

1、	新建状态:new Thread();
2、	就绪状态:t.starts();等待获得CPU
3、	运行状态:获得CPU,实现run方法
4、	阻塞状态:执行了Thread.sleep方法、发生了IO操作、或者调用了同步锁的外套方法
5、	死亡状态:代码执行完毕。

3.十种常见的异常:

     IOException(输入输出异常)
     FileNotFoundException(找不到文件异常)
     RunTimeException(运行期异常)
     ArithmeticException(算术异常)
     illegalArgumentException(传递非法异常)
     ArrayIndexOutOfBoundsException(数组下标异常)
	 NullPointerException(空指针异常)
	 ArrayStoreException(数组中存放与声明类型不兼容对象异常)
	 ClassCastException(类型强制转换异常)
	 NumberFormatException(数字格式异常)

4.集合和数组的区别:

     数组的长度是固定的,而集合长度是可变的
	 数组值可以存储对象,还可以存储基本数据类型;而集合只能够只能存储对象
	 数组存储的数据类型是固定的,而集合存储的数据类型不固定

5.单例的特点和作用:

特点
	  单例类确保自己只有一个实例。
      单例类必须自己创建自己的实例。
      单例类必须为其他对象提供唯一的实例
作用:
      控制资源的使用,通过线程同步来控制资源的并发访问;
	  控制实例产生的数量,达到节约资源的目的。
      作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信

6.this、super、static、final、instanceOf关键字
This:

是当前类的实例,经常出现在方法和构造方法中,具体使用有以下三种情况:
       
	1、	返回调用当前方法的对象的引用;
	2、	在构造方法中调用当前类中的其他构造方法;
	3、	在方法参数名和成员变量名相同时,用于区分参数名和成员变量名

super:

this用于调用当前类的方法、属性和构造方法 ,而super调用父类的实例,super用于调用父类的方法、属性和构造方法,具体使用方法有以下两种:
	
	1、	调用父类的构造方法;
	2、	调用父类的实行和方法

static:

 static关键字可以修饰方法、属性、自由块和静态块,使用static修饰这些成员时,可以理解为成员与类相关,通过 类名.成员 的形式调用;
 没有使用static修饰可以理解为成员与对象相关,通过  对象名.成员 的形式调用

注意:

1static不能用于修饰构造方法;
2、	在static修饰的方法中,不能调用没有static修饰的方法和属性,也不能使用superthis关键字;
3、	被static 修饰的属性被多个类对象共享,一个对象修改静态属性值后,会影响其他对象;
4、	静态块无论对象创建几次,静态块只执行一次;

Final:用于修饰类、成员变量、成员方法

1final修饰的类:
该类不能被继承;
2final修饰的成员变量:
不能改变变量的值,即final修饰的类为常量;
3final修饰的成员方法:
该方法不能被子类重写

InstanceOf:属于Java的二元操作符,作用是判断某个对象是否某个类或接口类型

6.成员变量和局部变量的区别?

  1.局部变量是定义在方法体内部的变量,其作用域在方法块内部有效。
  2.局部变量在使用时,必须先初始化才能使用,否则不能顺理通过编译;
  3.成员变量是定义的变了里那个,即属性,其作用域整个类中有效;
  4.成员变量可以不指定初始值,系统有默认值:除了八种基本数据类型,
  5. 其他的引用类型都是null;
  Byte、Short、int的初始值为0long的初始值为0L;booleanfalsefloat的为0.0F;double的为0.0d;char为‘/u0000’;
  7.final修饰且没有被static修饰的成员变量必须显式赋初始值;
  8.public、protect、privatestatic可以修饰成员变量,但不能修饰局
  部变量;两者都可以用final修饰;
  9.成员变量存储在堆内存中,局部变量存储在栈内存中
  10.作用域不同,局部变量作用域在方法块内部,成员变量作用域整个类
  11.成员变量可以不设置默认值,局部变量必须设置默认值。

7.类、对象、属性和方法

类是对一类相同事物的抽象描述;
对象是类的一个具体体现;
属性是对一类相同特征的抽象;
方法是对一类相同行为的抽象。

8.多态、继承、封装
多态:

1、Java中主要指对象变量的多态;	
2、在Java语言中有两种形式的多态: 编译时多态、运行时多态;
3、编译时多态通过方法重载(overload)来实现,即同一个类中存在多个方法名称相
同但参数列表(参数个数、类型、顺序)不相同的方法;
4、运行时多态通过方法重写(override)来实现,当子类继承父类后重写父类中的可见
(visible)方法,在运行阶段由父类类型的引用指向了子类类型的对象,此时 父类引用
指向哪个子类类型的对象,就调用哪个子类重写后的方法(就是表现谁的形态)

继承:

1、	是指一个对象直接使用另一对象的属性和方法;
2、	Java语言中通过 extends 实现类与类、接口与接口之间的继承,从而实现代码
复用,也是实现多态的基础。

封装:

1、通常将字段私有化(被隐藏起来)、某些不需要在类外部调用的方法也可以隐藏
起来,尽可能隐藏类的实现细节,
2、	将外部可能调用的方法公开。

9.overload和override的区别:

Overload(重载):
1、是同一个类中含有多个方法名称相同但参数列表(参数个数、类型、顺序)不相同的方法,
2、这些方法可能是当前类直接声明的,也可能是从父类中继承过来的可见方法。

Override(重写)
1、重写必须是子类继承父类后,子类重新声明了从父类中继承的可见(visible)方法,
2、此时,如果子类中重新声明的方法与父类中的方法 名称相同、参数列表完全相同、返回类型也一致,就说子类重写了父类中的同名方法。

相同点:都要求方法名称相同;

不同点:
1、	重载要求本类中有同名不同那个参的方法;重写必须发生在子类和父类之间;
2、	重载 要求同名方法的参数列表一定不相同;重写要求子类和父类的同名方法
的参数列表完全相同;
3、	重载对返回类型么有要求;而 重写 ( override ) 要求 被重写后的方法的返回
类型 必须跟 父类中相应方法保持一致 ( 如果是返回基本类型,则要求完全相同 )
4、	重载( overload ) 对方法的  权限修饰符 没有要求,而 重写 ( override ) 要求 
被重写后的方法的 权限修饰符 的范围不能缩小

注意:  

子类不能重写父类的 静态方法,如果子类重新声明了父类中同名的静态方法,
则说 子类 隐藏 了 父类中的同名静态方法。

10.公平锁和非公平锁?
公平锁:

公平锁: FairSync,就是当前资源被加锁后,其他所有请求线程按照请求的先后顺序搁置到queue中,当锁被释放放掉,然后严格的按照先进先出的原则一个一个加锁。
就比如生活中去超市购物后买单,只有一个收银台,这个收银台也只能服务一个顾客。当买单的人特别多的时候,大家就需要按照先来后到排队买单。
非公平锁:
非公平锁:NonfairSync 非公平的意思就是管你三七二十一,我先尝试给共享资源加锁,如果加锁成功就阻塞其他线程(因为其他线程都在队列中排队,这个时候就特别的霸道而显得不公平),如果是共享资源上已经被加锁了,这个时候在进入队列的时候还要再判断下资源有没有被释放掉能不能加锁,两次尝试加锁都失败再霸道也没用了,就只能老老实实去队列尾部排队!
还是去超市购物后买单,只有一个收银台,这个收银台也只能服务一个顾客。当买单的人特别多,大家都排着队等着。这个时候来了个壮汉,仗着自己高大枉顾排队的游戏规则,直接跑到收银台看有没有人正在买单,如果没有人正在买单就直接插队买单。如果看了两眼还是有人正在买单,那就规规矩矩到队尾排队。

11.数据库性能优化有什么方式?

SQL 优化:
		尽量避免使用 SELECT	*;
		只查询一条记录时使用 limit 1;
		使用连接查询代替子查询;
		尽量使用一些能通过索引查询的关键字。
表结构优化:
		尽量使用数字类型字段,提高比对效率;
		长度不变且对查询速度要求高的数据可以考虑使用 char,否则使用 varchar;
		表中字段过多时可以适当的进行垂直分割,将部分字段移动到另外一张表;
		表中数据量过大可以适当的进行水平分割,将部分数据移动到另外一张表。
		
其它优化:
		对查询频率高的字段适当的建立索引,提高效率;根据表的用途使用合适的数据库引擎;
		读写分离。	

12.springmvc 常用注解
@RequestMapping:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@PathVariable:用于将请求 URL 中的模板变量映射到功能处理方法的参数上,即取出 uri 模板中的变量作为参数。

@requestParam : 主 要 用 于 在 SpringMVC 后 台 控 制 层 获 取 参 数 , 类 似 一 种 是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 铜过 boolean 设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。

@ResponseBody : 该 注 解 用 于 将 Controller 的 方 法 返 回 的 对 象 , 通 过 适 当 的HttpMessageConverter 转换为指定格式后,写入到 Response 对象的 body 数据区。使用时机:返回的数据不是 html 标签的页面,而是其他某种格式的数据时(如 json、xml 等)使用 @RequestBody : 该 注 解 常 用 来 处 理 Content-Type: 不 是 application/x-www-form-urlencoded 编码的内容,例如 application/json, application/xml 等;

@RequestHeader :可以把 Request 请求 header 部分的值绑定到方法的参数上。

@CookieValue :可以把 Request header 中关于 cookie 的值绑定到方法的参数上。

13.socket专篇:

Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

socket在哪里能体现?
在这里插入图片描述
在这里插入图片描述
socket如何通信?
在这里插入图片描述
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

14.网络中进程之间如何通信?
本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类:

消息传递(管道、FIFO、消息队列) 
同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量) 
共享内存(匿名的和具名的) 
远程过程调用(Solaris门和Sun RPC) 
但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?
首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!
在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。
其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”
可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序
(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,
网络中的进程通信就可以利用这个标志与其它进程进行交互。

使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。

15.JDK进化区别?
jdk1.7

1.在Switch中可以用String字符串
2.对Java集合(Collections)的增强支持
3.两个char之间的equals方法
4.安全的加减乘除
5.boolean类型的反转,空指针安全,参与位运算
6.支持二进制数字
7.数值可以加下划线用作分隔符
8.简化了可变参数方法的调用
9.可以捕获多个异常(多个异常通过使用 “|”操作符分隔)
10.调用泛型类的构造方法时,可以省去泛型参数,编译器会自动判断。

jdk1.8:

1.新增了接口的默认方法
2.Lambda表达式
3.使用 :: 双冒号进行方法引用
4.函数式接口(有且仅有一个抽象方法,但是可以有多个非抽象方法的接口)
5.Date Time API
6.Stream API
7.Optional 类
8.Nashorn JavaScript
9.Base64

16.java8新特性?
一:Lambda(匿名函数)介绍
1.简介(方法作为值传递、纯函数不改变值)
在Java8中引入了函数式编程,可以简化代码逻辑,并将函数作为参数来传递;其原理是在函数上封装了一层,提供了一个语法糖,编译器将lambda表达式解释为函数式接口(除了默认方法,只有一个方法的interface),而利用接口式编程对数据进行操作。
2.原理分析
1)default方法:List直接调用sort方法,是因为在List中添加了default方法,这样可以在不影响List众多的实现类和继承类的前提下,对原有的List进行功能扩充
2)方法引用,类名::方法,是Lambda表达式的一个缩写,当传入的函数正好可以直接被对应的方法使用时,使用方法引用来缩写
3)函数式接口,在上面的例子中,Student::getGrade是一个Lambda表达式,Comparator.comparing需要的参数为Function<? super T, ? extends U> keyExtractor,这个Function就是一个函数式接口,JVM会在编译时,将该Lambda表达式翻译成该函数式表达式,所以说Lambda是在Function的基础上封装了一层。
二:Stream简介
1.流是一系列数据项,一次只生成一项,它类似于Unix中的cat、tr等命令,是针对输入的一行一行的流来进行处理,这样可以将操作连贯起来,也方便系统的流水线执行;
Collection主要是为了存储和访问数据,而Stream则主要用于描述对数据的计算。Stream中将迭代等在内部实现,并可以根据Fork/Join根据系统的情况进行性能上的优化;
三:Optional类
帮助你避免出现 NullPointer异常。它是一个容器对象,可以包含,也可以不包含一个值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值