1.Java中设置最大堆内存和最小堆内存的参数为 -xmx -xms
2.volatile作用:内存可见性,和防止指令重排序。
3.BeanFactory和applicationContext的区别:
BeanFactory是一个最简单的容易,提供最基本的di支持。常用的beanFactory实现就是
XmlbeanFactory类,它根据xml文件中的定义来加载beans,该容器中xml中读取元数据,
然后创建一个完整的应用,applicationContext应用上下文,

4.ActiveMQ 的集群配置方式有哪些?(基于共享文件,基于数据库,基于 Zookeeper 等)ActiveMQ 的集群配置
5.Java 集合中有哪些常用的类?ArrayList 的上级(父类或者接口)是什么,HashMap 的上级又是什么?
常用的类:Map 系(HashMap,LinkedHashMap,TreeMap, WeakHashMap, EnumMap 等);List 系(ArrayList, LinkedList, Vector, Stack 等);Set 系(HashSet, LinkedHashSet, TreeSet); 工具类(Collections,Arrays)Collections.sort() 里面的实现是什么排序算法?(TimSort, 加强型归并排序)
ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable. 然后 AbstractList 又继承了 AbstractCollection. 然后 List 和 AbstractCollection 又都 implements 了 Collection.
HashMap extends AbstractMap implements Map, Cloneable, Serializable.
6.
常用的 linux 命令?(这个被用了好多次了)
cat tac head tail more less nl vim vi gvim
date cal man shutdown poweroff reboot echo
uname -r; mount; unmount; exit
cd ls pwd mkdir cp scp rm mv
touch file which whereis locate find tar unzip
grep df top free kill killall
ifconfig ping netstat telnet ftp
passwd umask chrown chmod chgrp sudo ps who
7.数据库事务隔离级别?
Uncommit Read; Commit Read; Repeated Read; Serializable.
8.说了一些常用的:单例,适配器,工厂,装饰等。然后被问了一个问题:Java中的IO包含了那些设计模式?博主记不清是不是这家公司的面试题,姑且就算作是吧。拒博主所知,Java中的IO用了两种设计模式,装饰模式和适配器模式,装饰模式比如BufferedInputStream, DataInputStream; 适配器的有InputStreamReader, OutputStreamWriter。
9.JDK中除了IO使用了装饰模式,其他什么地方还使用了装饰模式?(Collections.synchonizedMap, unchecked系列以及unmodifiable系列)

10.简述下JVM。
这个是个开放性的问题,考验你对JVM整体的理解。从Javac讲述到GC:
首先通过IDE编写完java程序之后,就要javac来编译成class文件,分为:词法分析,语法分析,语义分析,代码生成是个阶段,在语义分析阶段又可以分为:填充符号表、标注检查、数据流分析和控制流分析。标注检查比如定义int a=1+2,在这个阶段就会被解析成int a=3; 又比如在控制流分析阶段又去除语法糖的动作,类似foreach的解语法糖等。
其次,编译生成class文件之后,就需要JVM加载。加载涉及到一个双亲委派模型,需要对双亲委派模型进行一下论述,以及为什么需要双亲委派模型(为了安全加载)。
类在加载之后就需要涉及验证-准备-解析-初始化的操作。
验证:目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。比如是否以魔数0xCAFEBABE开头。
准备:正式为类变量分配内存并设置类变量初始值的阶段。譬如public static int value=123;这时候赋值value为0.
解析:虚拟机将常量池内的符号引用转换为直接引用的过程。
初始化:这个阶段在上一篇讲过了,一定要突出这个知识点:虚拟机规范严格规定了有且只有5种情况(JDK7)必须对类进行初始化(执行类构造器()方法):
遇到new,getstatic,putstatic,invokestatic这失调字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。
初始化之后就可以使用了,加载的类信息存入了运行时数据区的方法区,也就是俗称的永久代。运行时数据区分为:java堆,java栈,本地方法栈,方法区,pc寄存器。然后简单叙述下这些概念。
new一个对象需要在java堆中开辟内存,使用完之后就需要垃圾回收操作了,接下去要将GC了。
以Hot spot为例,java堆分为年轻代和老年代。通过GC Roots标记不可达内存对象进行回收处理。GC算法有:Mark-Sweep, Copying, Mark-Compact, 分代。接下去就论述垃圾收集器了。年轻代有Serial, ParNew, Parallel Scavenge等都是采用复制算法。
老年代有Serial-Old, Parallel-Old, CMS。还有一个G1收集器。一般互联网公司喜欢采用CMS,然后就论述了一下CMS,CMS分为5个部分:初始标记,并发标记,重新标记,并发清除和并发重置,其中初始标记和重新标记是需要Stop the World的。CMS还有一个概念就是Concurrent Mode Failure,发生之后需要来一记Serial-Old的干活

11 了解 Spring 框架多少?
看过一点 Spring 的源码,主要是关于 Xml 解析和 Bean 加载的,记得大致的步骤。:xml 解析之后存入一个 BeanDefinition 之中,然后主要是对其进行操作;先在 singletionObjects(是一个 ConcurrentHashMap 的对象)判断有没有 Bean 的实例,有就处理下返回,没有就继续;检测一下循坏依赖之类的;下面要进入主题了,如果是单例(Spring Bean 默认是单例)的话,就创建实例并存入 singletonObjects 中,如果不是则创建不保存(当然这里也有一个非常复杂的过程,这里就不论述了);实例创建完之后就开始属性注入(autowiredByType, autowiredByName); 初始化 Bean(激活 Aware 方法:BeanNameAware, BeanFactoryAware, ApplicationContextAware 等;BeanPostProcessor 接口;激活自定义 init 方法:init-method, InitializingBean 接口;);这里就可以使用 Bean 了;使用完之后就是销毁了(destory-method, DisposableBean 接口)

ArrayList 的问题。
有关 ArrayList 无非就是一下一些基本认知:非线程安全,初始容量为 10,按照 1.5 倍扩容,底层采用数组 elementData 实现,对于随机访问 get 和 set 效率比较高,对于 add 和 remove 效率比 LinkedList 要低。当要扩容时采用 System.arrayCopy() 这个 native 方法实现。
但是 ArrayList 有两个点需要注意的。
第一个是 ArrayList 有个 trimToSize() 方法用来缩小 elementData 数组的大小,这样可以节约内存。考虑这样一种情形,当某个应用需要,一个 ArrayList 扩容到比如 size=10000,之后经过一系列 remove 操作 size=15,在后面的很长一段时间内这个 ArrayList 的 size 一直保持在 < 100 以内,那么就造成了很大的空间浪费,这时候建议显式调用一下 trimToSize() 这个方法,以优化一下内存空间。或者在一个 ArrayList 中的容量已经固定,但是由于之前每次扩容都扩充 50%,所以有一定的空间浪费,可以调用 trimToSize() 消除这些空间上的浪费。
12
OOM 的时候是怎么处理的。
刚刚讲述了 OOM 也就是内存吃不住的时候怎么处理,如果某个线程 CPU 占用率 100% 怎么查看。
linux 的 top 命令查看一个进程的 CPU 占用率,
先 jstack 查出线程堆的信息,在用 top H -p [pid] 的方式查看某个线程占用率(pid 通过 jps 命令获取),还有一种方法也可以,在 linux 下:ps -H -eo pid,ppid,tid,%cpu –sort=%cpu | grep [pid] 也有同样的效果
13
redis 和 memcached区别是什么?
由于 redis 只使用单核,而 memcached 可以使用多核,所以平均每一个核上 redis 在存储小数据时比 memcached 性能更高。而在 100k 以上的数据中,memcached 性能要高于 redis,虽然 redis 最近也在存储大数据的性能上进行优化,但是比起 memcached,还是稍有逊色。
二 为啥 redis 单线程模型也能效率这么高?

纯内存操作
核心是基于非阻塞的 IO 多路复用机制
单线程反而避免了多线程的频繁上下文切换问题
三 其他不同

数据类型不同,redis有五种(list set string hash zset),memcached只有一种string
Redis支持数据的备份,即master-slave模式的数据备份。
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
内存的使用率上memcached数据结构简单 只有一种string ,不用记录数据的类型。而reids需要记录。

分布式锁 线程池 死锁

悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
以上是Java代码中的悲观锁的实现。
下面是数据库层面的悲观锁
一个典型的倚赖数据库的悲观锁调用:
select * from account where name=”Erica” for update

乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

死锁的产生:如果有两个进程分别是a和b 然后分别需要争夺对方手中的资源。
死锁解决方法:1.加锁的顺序,线程按照一定的顺序来加锁执行。
2.设置超时,超过时间放弃对锁的请求。
3.死锁检测

线程池:
线程池的返回值为ExecutorService是一个java管理线程池的类,这个类的作用是控制线程数量和重用线程。
1.Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中
2. Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程
//创建一个可重用固定个数的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
3. Executors.newScheduledThreadPool(int n)创建一个定长线程池,支持定时及周期性任务执行
4.Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务

Mysql优化:1.选择最适合的字段属性,例如不要使用bigin等 2.使用join查询来代替子查询 3.使用联合查询来代替手动创建临时表 4. 使用事务 格式如 begin; 全部执行的语句 commit; 5.锁定表 如下 lock table tb_user write select name from... 然后 update tb_user set ... unlocktables 6.使用外键 7.使用索引 以上这7中方式都是可以优化数据库的。
Mysql视图的作用:
作用一:提高重复使用性质,就像函数一样。作用二:对数据库的重构 作用三:提高安全 作用四:清晰

分布式锁:https://blog.csdn.net/xlgen157387/article/details/79036337

1.说一下,ArrayList的实现方式?
ArrayList是通过数组实现的,一旦我们实例化ArrayList一个无参数构造方法,就会为底层的数组初始化一个长度为10的数组
add方法来添加元素的实现,是判断如果集合中元素个数超过10个以后,就会扩容,arrarylist就会重新创建一个数组,这个
数组的长度是原来数组的长度的1.5倍加1,然后调用Arrays.copy方法把原来的数据的数据复制到新的数组中,如此循环操作。

2.说一下,LinkedLIst的实现方式?
这个集合是基于双向循环链表实现的。既然是链表,那么必定存在一中数据结构为节点数据,我们可以称之为节点,在节点中保存业务数据
每一个节点,可以分为前节点信息,业务信息,后节点信息 。前节点信息保存的是上一个节点的后节点信息。 后节点信息保存的是下一个
节点的前节点信息,中间的业务信息保存的是真实的数据信息。

3.hashmap的理解
首页hashmap的结构是数组加上链表组成的,put的方法的底层实现是通过key的hash值得到,返回的hashcode用来找到bucket位置来存储Entry对象
关键是说明了hashmap是在bucket中存储键对象和值对象的。
当两个对象的hashcode相同的时候,会发生什么?因为hashcode相同,所以他们的存储的位置是相同的,碰撞会发生,因为hashmap是使用了链表
存储对象,这个Entry会储存在链表中。如果两个键的hasncode相同,如何获取到值对象?找到bucket位置以后,会调用keys.equals()方法去
找到链表中正确的节点,最终找到需要找的值对象。

4.hashmap和hashtable的区别?
hashmap是线程不安全的,容许有null的键值对,效率高,hashmap是是hashtable的轻量级的实现。
hashtable是线程安全的。不容许有null的键值对。效率底,hashtable是继承Dictionary类的。

5.如果hashmap的大小超过了负载因子load factor定义的容量 怎么处理。
默认的负载因子的大小是0.75.也就是说,当一个map中填满了百分之七十五的bucket的时候,就会和其他的集合一样,需要调整大小,把原来创建
的hasmap的大小的两倍大小的bucket,来重新调整map的大小,并且将原来的对象放到新的bucket中,这个过程叫做rehashing.

6.传统的io和nio的区别?
传统的io,一个连接就需要一个线程去服务,这样方式,虽然服务好,但是占内存比较高,cpu也消耗大。但是现在的nio可以用一个含有有限数量的线程
池,甚至一个线程来完成任意数量的连接服务,由于线程数据小于连接数量,所以每一个线程进行io操作的时候不能出现堵塞,如果出现阻塞,有些连接
就得不到处理,nio提供了这样非阻塞的能力。
1.增加了一个角色,要有一个专门收集客人需求的人,nio里面对应的是selector
2.传统的io,当没有数据可以读的时候,比如read()方法, 一直被阻塞,知道数据来。但是nio不是,没有数据读的时候,read()方法会立即返回0.

7.cookie是一个非常具体的东西 指的是在浏览器端永久的存储数据,和服务端么有关系。仅仅是浏览器实现的一种数据存储功能。、
服务端鉴别session需要从客户端传递过来的一个sessionid ,但是这个sessionid通常是保存在cookie中,所以工程上session离开了cookie基本就无法使用。、
但是cookie可以单独使用。但是cookie是存储了明文,安全性不高。、
cookie和session的配置在项目中实际使用?
当会员登录的时候,首先进入登陆页面,然后输入用户名和密码,如果用户名和密码不正确。就会返回错误登陆信息到给用户。如果验证通过将用户信息
保存到redis中,并且将用户信息生成一个token(用户标识) 当然是对用户信息进行加密等一系列的处理以后,返回到客户端存储在cookie中。如果下次
登陆就会把数据带回来。根据taken去redis中去查询对应的用户信息。登陆成功以后,重定向到登陆页面。

8.常见的http状态码
200请求被正常处理 204请求被受理,但是没有资源可以返回 301永久的重定向 302临时性重定向。400请求参数有误。401请求需要认证
403请求的对应资源禁止被访问 404找不到资源 500服务器内部错误 503服务器忙
9.重定向和转发的区别?
重定向是客户端的行为。转发是服务器端的行为
重定向是服务端产生了两次请求,转发是一次请求,重定向的时候可以转发到项目以外的任何地址。转发只能在当前项目中。
重定向会导致request对象信息丢失转发不会
转发的url不会改变,request.geetRequestDispatch().foward().
重定向url会发生改变 response.getRedirect().