文章目录

  • 1、Java基础
  • 1、IO与NIO
  • 2、
  • 2、后端框架
  • 3、数据库
  • 4、前端


1、Java基础

1、IO与NIO

看了一堆资料等于白扯,回头面试遇到请教下面试官吧。

2、

2、后端框架

3、数据库

4、前端

一、基础

1.JVM内存模型

虚拟机将拿到的内存进行了分割,总共分为5个区域。

永辉java面试 上海永辉超市java面试_数据


1)程序计数器:线程私有,一个处理器在一个时刻都只会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可 以恢复到正确执行位置,每个线程都需有独立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

2)JVM栈(虚拟机栈):线程私有,栈描述的是Java方法执行的内存模型。每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

3)本地方法栈:是JVM栈相似,区别是虚拟机栈执行的是Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务。

4)堆:是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。它也是GC所管理的主要区域,因此常被称为GC堆。

5)方法区:线程共享,存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量,加载类的时候就被加载到方法区中。

运行时常量池

是方法区的一部分,class文件除了有类的字段、接口、方法等描述信息之外,还有常量池用于存放编译期间生成的各种字面量和符号引用。

重载:同类中处理不同类型数据的方式,同名,必须参数列表不同。
重写:参数列表必须一致,返回类型必须一致,权限不小于,抛出异常范围不能大于父类

构造能重载(例如:参数不一样)不能重写(重写是子类方法重写父类的方法,重写的方法名不变,而类的构造方法名必须与类名一致,假设父类的构造方法如果能够被子类重写则子类类名必须与父类类名一致才行,所以 Java 的构造方法是不能被重写的。)
3.类图:继承,实现,聚合,关联(静态),组合(强以来),依赖(运行)
4.设计原则:
单一,开闭(新增开,改不行),里氏替换(子能替父),隔离,依赖倒置
5. 设计模式
1)单例:懒汉和饿汉
volatile
Java关键词,声明变量值可能随时被其他线程改变,其修饰的变量会强制将修改的值写入主存,主存中的值,同时使得缓
存值失效。其禁止指令重排。
其具有可见性、有序性,不具原子性。这是其与synchronized 关键字及java.util.concurrent.locks.Lock最大的功能差异。
volatile不会让线程阻塞,响应速度比synchronized高,这是它的优点。
有序性:jvm允许编译器和处理器对指令重排,重排不会影响单线程程序执行顺序。但是影响多线程并发执行的正确性。

2)简单工厂:实例化过程单独放一个类里,这个类就是简单
3)工厂方法:

6.包装类:基本数据类型数据小存储堆浪费,推出了基本。包装丰富方法,容器等需要的是Object
Integer x = 2; // 装箱 调valueof
int y = x; // 拆箱

缓存池:new Integer()每次产生新对象,Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。

7.String
final,
jdk8-底层char数组。
jdk9-底层byte
1)不可变好处:hashMap key,Stringpool,参数,线程安全。
字符串常量池:保存所有字符串字面量,编译期就确定。
new String(“asd”):池子没有就2个,“abc” 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,
指向这个 “abc” 字符串字面量,然后堆中
2)buffer(安全synchronized慢),builder(不安全快)
8.参数传递 按值传递
9.不能隐式执行向下转型
10.j7后switch 判断可以String对象
11.抽象类和接口
抽象类:abstract,有抽象方法必是抽象类,反之不定。不能被实例化
接口:j8前完全抽象,接口字段默认static final
比较:1)设计层面抽象类is-a关系,里氏替换。接口是like-a,规范方法。
2)接口可以多实现,抽象不能多继承
3)接口字段的限制,抽象不需要
4)接口成员必public,抽象类可以多访问权限
使用:
1)接口:不相关类实现同意方法如comparable;多继承
2)抽象:相关类共享代码块;控制访问权限;集成非静态和非常量字段
12.super:1)访问父类构造,委托其完成初始化2)访问父类成员,访问未重写的方法
13.Object:1)equals2)hashCode3)clone4)getClass5)notify6)notifyAll7)wait8)finalize9)toString
14.final
数据:基本-不变;引用:地址不变
方法:不能重写,private被隐式指定final
类:不能被集成
15.static:
1)类变量,内存唯一
2)静态方法,类加载时候存在,不依赖实例。必须实现,不能抽象。只能访问静态变量和方法。不能有this,super
3)静态代码块,初始化执行一次
4)静态内部类:不依赖外部类,不能访问外部类非静态变量和方法
5)初始化顺序
16.反射
17.异常:Throwable-error和exception exception-runtime Exception和受检异常

18.容器

Cllection 对象集合

Map 存储键值对的映射表

永辉java面试 上海永辉超市java面试_Java_02


19.set

treeset :红黑树,有序操作。查找效率(O(logN))<hashSet(O(1))

hashSet:哈希表,不支持有序。没有元素插入顺序信息,Iterator遍历不确定

LinkedHashSet:HashSet,内部含有双向链表维护插入顺序

20.List

Arrayist:基于动态数组,支持随机访问。默认10,每次1.5,原数组复制到新数组,代价高。删除O(N)

Vector:线程安全 扩容2倍

linkedList:基于双向链表,只能顺序访问。可快速在链表插入和删除元素

21.Quene

双向队列

22.Map

TreeMap:红黑树

Hash Map:哈希表

Hash Table:类似上,线程安全

ConcurrentHashMap:线程安全,分段锁

23.LinkedHashMap:双向链表维护元素顺序

24. HashMap相关面试题,自己看

25. IO

25.线程无状态:新建,就绪,运行,阻塞,死亡。
26.线程三种使用:runnable,callable,Thread类
建议实现:多继承;资源过大

27.Java线程面试题,自己看
·1)线程和进程的区别
进程:系统中能够独立运行并且作为资源分配的基本单位。他由一组机器指令、数据、堆栈等组成。
线程:是进程的一个实体,是cpu调度和分配的基本单位,是比线程小的能独立运行的基本单位,自己不拥有系统资源与其
他线程共享。
一个进程可有多个线程。
2)4.在java中wait和sleep方法的不同?
最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。wait是object根类的方法。
3)为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?
调用start()方法会创建新的线程这个线程就进入了就绪状态,分配时间片后就可以开始运行了,自动执行run中的方法。但是
直接调用run方法,会将run方法当成一个main线程的普通方法执行,并不会在线程执行。

28.IO 文件复制代码,NIO 文件流 网络流

29.SSM
1.SpringMVC 运行原理
2.Spring理解:IOC和AOP(编程代码深入理解)

3.写得出五个常用注解
4.MyBatis的理解
1)${}和#{}区别:前者是字符串的替换,后者涉及预编译处理(提前将sql编译,其后传入的参数不会被当作参数编入sql)。
mybatis在处理后者时会将其换成?,底层使用prepared Statement的set方法赋值;mybatis在处理&{}仅仅是讲其替换成变量
的值。使用#{}可以有效的防止SQL注入等操作,提高安全性。
2)对mybatis的理解
他是一个半自动的ORM框架。为了解决面向对象和关系型数据库发展不平衡出现的。他可以将从数据库中取出的数据封装到
Java中的对象中。开发者直接拿走对象使用。底层其实是对jdbc操作数据库的封装,可以使得开发者专注于sql的层面,不需
要处理注册驱动,创建连接等等过程代码。
其与hibernate最大的区别在于,h能够根据Java对象的变化自动对数据库数据进行实时处理。mybatis支持定制化的sql更加灵
活。
6.spring 事务(这篇文章间的比较好)
事务的四个属性:acid
1)propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是Spring默认的选择。
(2)propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
(3)propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
(4)propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
(5)propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
(6)propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
(7)propagation_nested

SpringBoot的理解

简化Spring应用的初始化创建及开发过程的一个框架 。

永辉java面试 上海永辉超市java面试_Java面试题_03


约定大于配置的意思就是说:很多配置已经默认配置好了,我们可以手动修改,但是不鼓励,能用默认就用默认。

下边都是扯淡

1.快速创建独立运行的Spring项目

2.嵌入式Servlet容器,无需War,Java-jar

3.含有各种应用场景的starter

4.自动配置简化开发,无需xml

5.准生产环境的云运行监控。

31.SpringCloud的理解32.写出一个Ajax请求

$.ajax({
 type:‘POST’,
 data:{‘姓名’:‘蛋蛋’},
 url:’${pageContext.request.contextPath}/login’,
 dataType:‘text’,
 success:function(data){
 }
 error:function(data) {
 },
 })

33.JSP九大内置对象

永辉java面试 上海永辉超市java面试_永辉java面试_04


四个作用域:

34.redis
redis是一个key-value的nosql数据库(非关系型数据库)。支持存储的value类型包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)
redis就是C语言编写的一个高性能的键值存储(key-value)的非关系型数据库。
缺点:
1.没有主外键,则数据关系不能一目了然
2.没有强大的事务来支持,那么数据就相对来说不安全
3.不支持sql,不能进行复杂的查询

35.dubbo
是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
1、容器 (spring容器) 2、服务生产者 3、注册中心 (zookeeper 、redis (发布订阅 -频道)) 4、服务消费者 5、监控中心(可以查看哪个方法的使用次数)
容器启动,服务生产者会把自己的服务的接口地址报告给注册中心。服务消费者订阅它需要的服务,他去查询注册中心,大哥有地址吗?有就返回服务地址。消费者拿到地址就可以去调用服务。监控中心:监控生产者和消费者的健康状况。
为什么使用Dubbo?答:1、Dubbo提供了丰富的协议选择:Dubbo协议(服务调用),注册服务:zookeeper协议,tcp协议,http协议等。协议越底层,传输效率越高。 2、io的选择:异步的nio。
36.zookeeper
ZooKeeper是一个开放源码的分布式应用程序协调服务组件
具有高可靠性,可扩展性,分布式,可配置的协调机制.
3.3.1 数据发布与订阅(注册中心),Dubbo应用此特性

3.3.2 集群管理与Master选举 , Solr 集群应用此特性 

           3.3.3 命名服务(Naming Service) 

           3.3.4 分布式通知/协调 

           3.3.5 负载均衡 

           3.3.6 分布式锁 

           3.3.7 分布式队列


  1. dubble与socket与webservice与httpclient

40.freemarker
一个纯Java编写的模板引擎,基于模板来做文本输出。以往开发中使用的jsp中存在大量业务逻辑代码的现象,使得页面内容杂乱,同时不利于后期维护。使用free marker可以彻底实现表现层和业务逻辑。
free marker 的原理是:模板+数据模型=输出,模板只负责数据在页面的表现,不涉及任何的逻辑代码,所有的业务逻辑都是数据模型处理的。用户最后看到的输出是数据模型和模板整合后创建的。
适用于:数据量大同时与后台数据交互较少的情况。比如商品页展示。

JVM:
主要包括五大部分:
1.程序计数器:
内存小,线程私有。字节码解释器通过改变其值选取下一个执行指令的字节码指令。
执行Java,就虚拟机字节码指令地址。执行native方法,值为undefined。
2. Java虚拟机栈
线程私有,生命周期与线程一致。每个方法执行时创建栈帧用于存储局部变量、方法出口等信息。每个方法自调用到结束都对应一个栈帧的入栈到出栈的过程。

局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 
				returnAddress 类型(指向了一条字节码指令的地址)
				StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
				OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。
  1. 本地方法栈
    区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的
    Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。
    4.堆
    通常为jvm管理内存的最大区域。线程共享,主要存放对象实例和数组。物理内存可以不连续,逻辑要连续。
    OutOfMemoryError:如果堆中没有内存完成实例分配,并且堆也无法再扩展时,抛出该异常。
    5.方法区
    共享区域,存储已经被加载的类信息、常量、静态变量、即时编译器编译后的代码等
    运行时常量池:方法去一部分,用于存放预编译期产生的各种字面量和符号引用。编译器和运行期都可以将常量放入池中。

MySQL数据库

1.数据库优化

8秒是一个分界点。

1)sql优化和索引,性价比最高的一种优化,好的sql+合理的索引

sql优化:

1》where 子句避免!=或<>,全表扫描

2》where和groupby涉及的关键列使用索引

3》where避免null判断,设计时尽量避免null

4》where避免or,union all替代

5》避免前置%

6》避免in 和not in,between exists

7》where避免函数

8》合理索引

9》避免*

10》

2)数据库表结构:基于三大范式进行合理的数据库表设计。

3)系统配置

4)硬件

2.MySQL存储引擎MyISAM与InnoDB如何选择

3.查询语句不同元素(where、jion、limit、group by、having等等)执行先后顺序?

永辉java面试 上海永辉超市java面试_字段_05


4.inner join 和leftjoin区别

left join 是做左外关联,主表内容都会显示;符合关联条件的附表内容才会显示出来。

inner join 是内关联,没有主表附表的概念;两个表中,同时符合关联条件的数据才会显示出来。

1.redis的rdb和aof
2.Java线程(并发)控制机制
3.文件流,网络流,NIO的理解
4.MQ的理解
5.webservice的理解,接口调试,其与HTTP client的区别。hp ws和消息队列 的区别联系
6.四种引用
7.垃圾回收

程序运行过程创建对象,需要占用内存空间,对象无意义时需要销毁释放空间,垃圾回收gc。
Java 自动,可控差,易内存溢出
c人工,工作量大,可控
System.gc()调用垃圾回收器,尝试不保证。

  1. 判断是否可回收:1.引用计数 2。可达性分析,当前
  2. 确定可回收,cpu空闲,堆满,调用system。gc()
  3. 如何:标记-清除,复制,标记-整理,分代回收

8.堆栈
9.ajax
10.

1.代码,文件复制

常见问题:
1.说一下对事务的理解
答:首先事务是数据库的概念,我们在service层中也有对事务的处理,但那只不过是方便控制而已(不严谨,需要重新措辞)。
我们都知道事务有ACID四个特性,所以一句话总结:将需要保证ACID特性的一系列数据库操作称之为一个事物。

1)事务特性:
为方便说明,举例业务场景:饼干给蛋蛋转账十块钱
饼干向阳阳转账十块钱
A原子性:
事务(注意说的是事务,不是数据库操作,一个事务中可能包含增删改查多次操作)不可分割,要么转账成功,要么失 败。 不可以饼干账户了,但是蛋蛋还没收到!
B隔离性:
两个操作互不影响。(最重要,但是没讲明白,可以结合下边隔离级别业务场景理解)
C一致性:(类比能量守恒定律)
无论钱怎么转,银行系统账户中这两次操作涉及的金额是一定的(就是那十块钱)。原子性和隔离性其实都是为了保证一致性

D持久性:
无论操作怎样的,最终操作记录会持久保存!类似日志。

2)隔离级别,隔离性是事务特性中最重要的部分,隔离级别也经常问到。
业务场景:
饼干账户原来有100元。
事务A:饼干向蛋蛋转账10元。
事务B:饼干向阳阳转账10元。
目前事务A将饼干账户十块钱转走了,但是还没有给蛋蛋账户增加10元(也就是受事务还没有提交),在这时,事务B查询饼干账户余额,应不应该看到饼干账户还有90元?
这个场景就是事务隔离性的体现,至于他应该看到90还是看到100,要看隔离级别。

1>读未提交:
只要事务对数据操作了(其实就是更新操作),即使没提交,其他事务都可以看到(事务B看到饼干还剩90)。
几乎不用,会出现脏读。比如事务A将100修改成90,事务B看到了90。但是事务A发现改错了,又改成了80。肯定就出现问题了。
2>读已提交,只能读到其他事务提交的数据。可能出现两个问题:不可重复度、幻读(其实效果是一样的,只不过一个针对一行一个针对多行)。
不可重复读

T表中某字段num原来是100.
	事务B读取数据num字段结果是100,这时A事务将num修改成90并且提交了。事务B又读了一遍数据num阶段结果成了90.

幻读

T表中原来有20条数据。
    事务B查询数据条数20,这时事务A添加了一条数据并且提交了,事务B又查询数据条数成了21条。

3>可重复读:事务多次读取(某字段)数据都是一致的。

T表中某字段num原来是100.事务B读取数据num字段结果是100,这时A事务将num修改成90(修改n多次都行)并且提交了。
事务B又读了一遍数据num阶段结果**还是100.**
T表中原来有20条数据。
事务B查询数据条数20,这时事务A添加了一条数据并且提交了,事务B又查询数据条数还是20条。

解决了不可重复度,但是还是会出现幻读重点:这几个级别是SQL定义的标准,Mysql在实现该标准时已经帮我们把可能出现的幻读解决了。

4>串行化:
针对读-写、写-读操作。事务并行读和写操作时,需要等待另一个执行完才可以继续进行。

针对读,MVCC多版本并发控制,读已提交和可重复度的最大区别就是ReadView视图生成时机不同。(自己查,基本不用说到这就完事了)

首先,我们必须清楚,对于数据库的读操作无论多少个,其实完全不必加锁,数据又不会变。(为了严谨一点呢,我加个个人理解,毕竟没见过世面)

锁:视频与画面差七八秒完全整不了。。。。

2.InnoDB和MYIASAM数据库引擎最大的区别:
1)innoDB支持行锁
2)innoDB支持事务

多线程:

1.你了解多线程嘛?

线程的概念:

一组代码的执行,一个任务

多线程的目的:充分利用CPU,并发处理多个任务。

CPU做什么:计算,执行代码

线程让出cpu:

永辉java面试 上海永辉超市java面试_Java_06

永辉java面试 上海永辉超市java面试_字段_07

线程是不是越多越好?
1)耗时
线程创建、销毁需要时间。如果线程过多,创建销毁耗时过多。
2)空间
线程在Java中是一个对象,每个线程都需要一个操作系统线程支持(一个线程默认1m栈内存)。前者消耗堆内存,后者消耗系统内存。太多的话。。。
3)性能
操作系统频繁切换上下文(每个线程都希望被执行),影响性能。

由以上,合理数量的线程是很有必要的,这个合理的线程数构成线程池。
线程池的理解:
1、接收存储任务
2、线程执行任务

线程池再整整:::

数据结构:
1、手写二叉树:概念比较简单shenglve

/**
 * @program: BinarySearchTree
 * @description: 二叉树插入及遍历
 * @author: 三层饼干儿
 * @create: 2019-08-30 16:24
 **/
@Data
public class BinaryTree {
	//一个二叉树对象,必定含有一个数据和两个子树(叶子节点也有,算作null罢了)。
	private int data;
	private BinaryTree left;
	private BinaryTree right;

	public BinaryTree(int data) {
		this.data = data;
	}
	/**
	 *
	 * @param root 根节点
	 * @param data 插入的这个数字
	 */
	public void insert(BinaryTree root, int data){
		if (data>root.data){
			if (root.right!=null){
				insert(root.right,data);
			}else {
				root.right= new BinaryTree(data);
			}
		}else {
			if (root.left!=null){
				insert(root.left,data);
			}else {
				root.left = new BinaryTree(data);
			}
		}
	}
	//先序遍历
	public void preOrder(BinaryTree binaryTree){
		if (binaryTree!=null){
			System.out.println("---------->"+binaryTree.getData());
			preOrder(binaryTree.left);
			preOrder(binaryTree.right);
		}

	}
	//中序遍历
	public void midOrder(BinaryTree binaryTree){
		if (binaryTree!=null){
			midOrder(binaryTree.left);
			System.out.println("________>"+binaryTree.data);
			midOrder(binaryTree.right);
		}
	}
}

2、B树结合mysql部分看(mysql底层使用B+tree)

3、红黑树知道大体意思,基本不会让写。

4、hashmap底层 数组加链表后期转换成了 红黑树。(4)背过就好,能理解理解,理解不了背过。手写红黑树基本不会,如果面试让手写,让他滚!)

1)二叉树有个致命缺点:如果根节点是这组数字中最小的数会变成如下图这样,这样查找数据时间复杂度就变成了n。

永辉java面试 上海永辉超市java面试_字段_08


2)为了解决二叉树变成链条,提出了平衡二叉树(AVL树)。这个树追求极致平衡,花销太大(各种左右旋)。所以红黑树出现了,他也是平衡二叉树的一种。

3)红黑树特点:

1>每个节点不是红色就是黑色。(废话)

2>不可能有两个红色节点相连

3>红色节点的子节点必然是黑色节点(咱也不知道谁总结的,由上一条看完全是废话),叶子节点都是黑色的

4>根节点是黑色的

5>

4)从二叉树到红黑树的变换,要怎样实现呢?

1>变色

永辉java面试 上海永辉超市java面试_永辉java面试_09


永辉java面试 上海永辉超市java面试_Java_10


2>左旋

由上图看依然不符合条件,但是也不符合变色的条件,那么就要旋转。

永辉java面试 上海永辉超市java面试_永辉java面试_11


永辉java面试 上海永辉超市java面试_数据_12


3>右旋,发生条件与左旋类似,但是解决比左旋复杂一点。

永辉java面试 上海永辉超市java面试_数据_13


5、为什么红黑树这么牛比,很多软件底层都用到该算法,但是mysql数据库底层使用b+tree而不用红黑树。

红黑树读写基本在内存中,而数据库是要存入硬盘的。数据库存储的数据是海量的,b+tree的数据量不是红黑树能比的。大体上是这么个意思。