1. Java的数据类型:
    包括基本数据类型和引用数据类型:
    a.基本数据类型:
    整数类型{long, int, short, byte}; 浮点类型: float, double;
    字符类型: char; 布尔类型: Boolean
    boolean :false
    byte :0
    char:
    double :0.0
    float :0.0
    int :0
    long :0
    short :0
    String :null
    成员变量默认值不同, 基本数据类型的默认值跟它的类型有关;
    引用类型的默认值是null;
    b.引用数据类型: 类, 接口, 数组, 枚举, 注解, 字符串型;所有非基本数据类型都是引用数据类型;
    1.存储位置不同:
    基本: 栈中存的变量的值;
    引用: 栈中存引用类型的地址, 堆中存的是引用类型的值.
    2.传递方式不同:
    基本: 按数值传递, 对形参值的更改不会影响到实参的值;
    引用: 按引用传递, 若改变形参指向的数据内容则会对实参变量的值产生影响, 对形参值的更改实际上是对实参值的更改.
    枚举:
    “枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。本质就是,一个类里定义几个静态变量,每个变量都是这个类的实例。”
    枚举的注意事项:
    1.不能含有public修饰的构造器,即构造器只能是private修饰,如果没有构造器编译器同样也会自动生成一个带private修饰无参默认构造器。;
    2.所有的枚举值默认都是public static final 修饰的;
    3.枚举值与值之间用逗号分割,最后一个用分号,如果枚举值后面没有任何东西该分号可以省略;
    4.每一个枚举值就是一个枚举类型的实例;
    5.枚举类型中可以定义带任意修饰符的非枚举值变量;
    6.枚举值必须位于枚举类型的第一位置,即非枚举值必须位于枚举值之后;
    7.枚举类型自带两个方法,values() 和 value(String name) 两个方法。
    2.Integer的缓存机制:

    1. ==的左右操作数如果是对象的话,那么比较的是引用的地址;
      2.Integer是int的包装类,在和int做比较的时候,会自动拆箱成int数值类型再进行比较;
      3.IntegerCache类中有一个数组缓存了值从-128到127的Integer对象.如果值在这个范围之内则直接返回否则就new一个Integer对象, Integer.valueOf()方法对int类型装箱根据数值范围决定是否new一个Integer对象.
      3.String和StringBuffer的区别 String:是对象不是原始类型。为不可变对象,一旦被创建,就不能修改它的值。 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去。String是final类,即不能被继承。 StringBuffer:是一个可变对象,当对它进行修改的时候不会像String那样重新建立对象。它只能通过构造函数来建立,StringBuffer subffer=new StringBuffer(); 对象被建立以后,在内存中就会分配内存空间,并初始保存一个null,通过它的append方法向其赋值 subffer.append(“hello word”); sb.append(“def”).insert(0, “123”);
      1.字符串连接操作中StringBuffer的效率要明显比String高; 2.String对象是不可变对象,每次操作String都会建立新的对象来保存新的值。 3.StringBuffer对象实例化后,只对这一个对象操作。
      4.Java中集合的图解:

List, Set继承自Collection接口, Map独立.

List和ArrayList的区别:
1.List是一个接口, 而ArrayList是一个类;
2.ArrayList继承实现了List接口;
3.List是接口不能被构造, 但可以为List创建一个引用;
4.ArrayList可以被构造,
5.有很多公共方法.

ArrayList和LinkedList的区别:
1.ArrayList是实现了基于动e79fa5e98193e78988e69d8331333339666131态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。
LinkedList中get(int index) 先传入的index通过二分查找来判断从first遍历还是从last遍历: first就进行++ last就进行-- 最后得到对应的Node输出
ArrayList中的get(int index)直接通过下标获取到元素。
*若业务中对集合的增删改的操作较多的用LinkedList效率会比较高
*若业务中对集合的查询的操作较多的用ArrayList效率会比较高
List和Set的区别:
1.List是允许重复的对象, Set不允许重复对象;
2.List可以插入多个null元素, 而Set只允许插入一个null元素;
3.List是一个有序的容器,而Set是无序的;
4.List的实现类有ArrayList, LinkedList和Vector; Set的实现类是HashSet, LinkedHashSet以及TreeSet;

HashMap和ConcurrentHashMap的区别:
HashMap是非线程安全的, 而ConcurrentHashMap采用分段锁的概念来实现线程同步, 线程安全.
HashMap和HashTable的区别:
1.HashMap允许key为null或者值为null; HashTable的key和value都不能为null;
2. HashMap线程不安全; HashTable线程安全;
3. HashMap的方法是containsKey()和containsValue(); HashTable的方法是contains();
4.两者采用的算法差不多, 性能不会有太大差异;
HashMap和TreeMap的区别:
1.HashMap适用于在Map中插入, 删除和定位元素;
TreeMap适用于按自然顺序或自定义顺序遍历键(key);
2. HashMap通常比TreeMap要快一点(树和哈希表的结构使然)
3.建议多使用HashMap, 在需要排序的时候才用TreeMap;
4. HashMap是非线程安全的, TreeMap非线程安全.
HashMap集合的三种遍历方式:
HashMap: HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元, Entry是HashMap中的一个静态内部类, 每一个Entry包含一个key-value键值对.

TreeMap:

TreeMap是需要我们实现Comparator接口的:
1.当未实现 Comparator 接口时,key 不可以为null,否则抛 NullPointerException 异常; 2.当实现 Comparator 接口时,若未对 null 情况进行判断,则可能抛 NullPointerException 异常。如果针对null情况实现了,可以存入,但是却不能正常使用get()访问,只能通过遍历去访问。

各类集合的底层实现原理:
ArrayList的扩容机制:
总的来说就是分两步:
1、扩容:把原来的数组复制到另一个内存空间更大的数组中
2、添加元素:把新元素添加到扩容以后的数组中
在无参构造中,我们看到了在用无参构造来创建对象的时候其实就是创建了一个空数组,长度为0; 在有参构造中,传入的参数是正整数就按照传入的参数来确定创建数组的大小;
接下来我们来看扩容,扩容的方法就是 add(E e)
其实add方法就两步,第一步:增加长度,第二步:添加元素到数组
这个地方我们看到了,如果在添加的时候远数组是空的,就直接给一个10的长度,否则的话就加一; 通过这个地方是真正的增加长度,当需要的长度大于原来数组长度的时候就需要扩容了,相反的则不需要扩容
这个地方注意这一句int newCapacity = oldCapacity + (oldCapacity >> 1);
oldCapacity >> 1 右移运算符
原来长度的一半 再加上原长度也就是每次扩容是原来的1.5倍
之前的所有都是确定新数组的长度,确定之后就是把老数组copy到新数组中,这样数组的扩容就结束了.
1.ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。
2.底层使用数组实现
3.该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。
4.采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险
5.remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC.
LinkedList实现原理要点概括:
1.LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。
2.底层的数据结构是基于双向链表的,该数据结构我们称为节点
3.双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。
4.它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
HashMap的put()和get()的实现:
HashMap的最底层是数组来实现的,数组里的元素可能为null,也有可能是单个对象,还有可能是单向链表或是红黑树。
1、map.put(k,v)实现原理
第一步首先将k,v封装到Node对象当中(节点)。第二步它的底层会调用K的hashCode()方法得出hash值。第三步通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。
2、map.get(k)实现原理
第一步:先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。第二步:通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着参数K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。
ConcurrentHashMap实现原理:
1.ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。
2.它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。
3.ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
4.与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment)
5.ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。
5.Java中Overload和Override区别:
重载是在一个类中,同名方法拥有不同的参数列表则视为重载。
不同的参数列表包括:参数数量不同,参数类型不同,参数顺序不同。
重写是在子类中重写父类的方法, 参数列表必须完全相同;
1.是Java多态性的不同表现;
2.重载是一个类中多态性的一种表现; 重写存在于父类与子类之中;
3.重载必须有不同的参数列表; 重写方法必须与被重写方法的参数列表一致;
4.重载对于修饰符访问权限没要求; 重写方法的修饰符访问权限必须>=被重写方法的修饰符访问权限;
5.重写方法抛出的异常必须<=被重写方法抛出的异常.
6.抽象类和接口的区别:
相同点:
1.不能实例化; 2.都包含未实现的方法; 3.派生类必须实现未实现方法.
不同点:
1.接口支持多继承, 抽象类不可以;
2.接口中只能定义未实现方法, 抽象类中可以实现部分方法;
3.接口中基本数据类型的数据都默认为static和final的, 抽象类不是;

只有在必须使用方法定义或者成员变量的时候, 才应考虑采用抽象类.
7 .JDK特性:
1.JDK5新特性;
a.自动拆箱和装箱;
b.Foreach: 增强for循环,新增一种循环语法,格式:for( : );
c.静态导入; import static 和导包一样的方式直接导入;
d.可变参数Var args: 当传入到方法的参数不固定可变参数 格式:数据类型… 参数名;
e.引入了枚举类型, 关键字enum表示枚举类型相当于类声明中的class关键字;
f.引入泛型将运行期异常转移到编译异常.
g.元数据: 也可以叫注解. 格式: @注解名
2.JDK6新特性;
a.JAXB是Java Architecture for XML Binding的缩写,我们把对象与关系数据库之间的映射成为ORM, 把对象与XML之间的映射成为OXM(Object XML Mapping);
b.轻量级Http Server API;
c.用Console开发控制台程序;
d.对脚本语言的支持;
e.Common Annotations.
3.JDK7新特性;
a.二进制字面值: 整数类型可以使用二进制数,指定二进制前面加0b或者0B编号;
b.switch表达式中使用String对象;
{在JDK 1.7之前,switch只能支持byte,short,char,int或者其对应的包装类以及Enum类型.从JDK 1.7之后switch开始支持String类型.但到目前为止,switch都不支持long类型.}
c.try-with-resources可以自动关闭相关资源(只要实现了AutoCloseable接口)
d.catch块可处理多个异常类型, 每个异常类型用竖线(|)分隔;
e.字面值中使用下划线, 任意数量的下划线字符(_)可以出现在字面值的任意位置;
f.类型推断: 可以用一组空的类型参数(<>)来代替泛型类的构造函数所需的类型参数;
g.改进泛型类型可变参数;
4.JDK8新特性;
a.Lambda表达式: 一段可以传递的代码(将代码像数据一样传递); ->

 b.函数式接口: 只包含一个抽象方法的接口.@FunctionalInterface;c.接口支持默认方法和静态方法;d.Stream API(java.util.stream.*): 提供了一种非常高效且易于使用的处理数据的格式; 其中最为重要的是——Stream流。Stream的是通过函数式编程方式实现的在集合类上进行复杂操作的工具。e.增强类型判断: 使用方法调用的目标类型来推断其参数的数据类型;f.新的日期时间API: (java.time.*)不可变的LocalDate, LocalTime, LocalDateTime类;g.;Optional类: (java.util.Optional)是一个容器类,代表一个值存在或者不存在.h. 重复注解和类型注解

5.JDK9新特性;
a.目录结构;
b.模块化系统;
c. 新增了REPL(Read-Eval-print Loop)工具jshell, 提供了一个交互式命令界面;
d.多版本兼容JAR;
e.接口运行使用静态方法和默认方法后可以在接口中使用私有方法;
f.改进try-with-resources可以在try外初始化资源然后再try后的括号中添加需要自动关闭的资源;
g.钻石操作符可以使用匿名实现类,可以在匿名实现类中重写方法;
h.限制使用单独下划线标识符;
i.String存储结构变更:将底层存储数据由char数组改为byte数组;
j.快速创建只读集合;
k.统一的JVM日志系统.
8.Servlet和Filter的区别:
1.作用不同:
Servlet是一个运行在web服务端的java程序, 用于接收和响应请求
Filter是一个运行在web服务端的java程序, 用于拦截请求和拦截响应
2.方法不同:
Servlet只能接收请求和处理响应
Filter可以接收请求和处理响应, 还可以拦截请求
3.生命周期不同:
Servlet: 第一次请求访问的时候, 创建对象
Filter: web应用加载的时候, 创建对象
4.访问的优先级: Filter访问优先于Servlet
过滤器与拦截器的区别:
过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用
1.拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的)
2.拦截器不依赖servlet容器,过滤器依赖于servlet容器。
3.拦截器只对Action起作用,过滤器可以对所有请求起作用。
4.拦截器可以访问Action上下文和值栈中的对象,过滤器不能。
5.在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次。

  1. Java的类和JS的对象的区别:
    1.Java是完全面向对象的编程语言, 也就是有继承, 封装, 多态;
    JS是基于对象的一种脚本语言, 没有上述三点, JS的继承是通过原型链或其他方式实现的.
    2.Java的类不可以直接运行, 而JS的对象时可以直接运行的, 这也就是基于对象的特点.
    3.数据类型不同:
    Java的数据类型分为8种: byte, short, int, long, float, double, Boolean
    而JS的数据类型有三种: number, string和Boolean.
    4.本质不同就是用途:
    Java的舞台在编程领域, 目前被广泛应用于PC端, 手机端, 互联网, 数据中心等等,
    而JS的得心之处在Web页面中, 被主要用于嵌入文本到HTML页面, 读写HTML元素, 控制cookies等.
  2. 值传递和引用传递:
    1.值传递: 形参类型是基本数据类型: 方法中执行形参数值的改变不影响实参的值;
    2.引用传递: 形参类型是引用数据类型: 也称为传地址, 方法执行中, 对形参的改变将会影响实参的值.
    ***在java里没有引用传递,只有值传递;
    这个值指的是实参的地址的拷贝,得到这个拷贝地址后,你可以通过它修改这个地址的内容(引用不变);
    但是你不能改变这个地址本身使其重新引用其它的对象;
    不管是对象、基本类型还是对象数组、基本类型数组,在函数中都不能改变其实际地址但能改变其中的内容。
  3. Java解析XML的4种方法:
    一.DOM: 通常需要加载整个XML文档来构造层次结构,消耗资源大;

1.创建一个DocumentBuilderFactory对象。
2.创建一个DocumentBuilder对象。
3.通过DocumentBuilder的parse方法加载XML到当前工程目录下。
4.通过getElementsByTagName方法获取所有XML所有节点的集合。遍历所有节点。
5.通过item方法获取某个节点的属性。
6.通过getNodeName和getNodeValue方法获取属性名和属性值。
7.通过getChildNodes方法获取子节点,并遍历所有子节点。
8.通过getNodeName和getTextContent方法获取子节点名称和子节点值。
二.SAX: 可以在某个条件得到满足时停止解析,不必解析整个文档;

1.获取一个SAXParserFactory的实例。
2.通过factory获取SAXParser实例。
3.创建一个handler对象。
4.通过parser的parse()方法来解析XML。
三.DOM4J: 简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP;

全例子如下:

1.创建SAXReader的对象reader
2.通过reader对象的read()方法加载books.xml文件,获取document对象
3.通过document对象获取根节点bookstore
4.通过element对象的elementIterator获取迭代器
5.遍历迭代器,获取根节点中的信息
6.获取book的属性名和属性值
7.通过book对象的elementIterator获取节点元素迭代器
8.遍历迭代器,获取子节点中的信息
9.获取节点名和节点值
四.JDOM: 使用具体类而不是接口,简化了DOM的API.

1.创建一个SAXBuilder的对象
2.创建一个输入流,将xml文件加载到输入流中
3.通过saxBuilder的build方法,将输入流加载到saxBuilder中
4.通过document对象获取xml文件的根节点
5.获取根节点下的子节点的List集合
12. redirect和forward的区别:
1.请求方不同: 前者是客户端发起的后者是服务端发起的请求;
2.浏览器地址表现不同: 前者浏览器地址显示被请求的, 后者浏览器地址不显示被请求的url;
3.参数传递不同: 前者重新开始一个 request, 原页面的request生命周期结束; 后者另一个连接的时候, request变量是在其生命周期之内的.
4.定义不同: 直接和间接对应到代码是: 分别是RequestDispatcher类的forward()方法和HttpServletRequest类的sendRedirect()方法。redirect是间接转发, 服务器在响应第一次请求的时候, 让浏览器再向另外一个URL发出请求, 从而达到转发的目的。它本质上是两次HTTP请求,对应两个request对象。而forward则是指客户端浏览器只发出一次请求,Servlet把请求转发给Servlet、HTML、JSP或其它信息资源,由第2个信息资源响应该请求,两个信息资源共享同一个request对象。

  1. cookie 和session 的区别:
    1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
    2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗, 考虑到安全应当使用session。
    3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能, 考虑到减轻服务器性能方面,应当使用COOKIE。
    4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  2. java 创建对象的几种方式:
    1.用new语句创建对象;
    2.用反射调用class的newInstance方法;
    3.用反射调用Constractor的newInstance方法;
    4.调用对象的clone()方法;
    { 浅克隆,仅仅复制对象的引用;深度克隆,得到预期效果[会破坏单例]}
    浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.
    深拷贝把要复制的对象所引用的对象都复制了一遍.
    5.直接使用=赋值例如String test = “”;
  3. java中==和eqauls()的区别:
    1.是运算符,用于比较两个变量是否相等,对于基本类型而言比较的是变量的值,对于对象类型而言比较的是对象的地址; 如果a 和b 都是对象,则 ab 是比较两个对象内存地址,只有当 a 和 b 指向的是堆中的同一个对象才会返回 true;
    而 a.equals(b) 是进行内容比较,其比较结果取决于equals()具体实现.
    2.equals()是Object类的方法,用于比较两个对象内容是否相等.默认Object类的equals().
  4. &和&&的区别:
    逻辑运算符具有短路特性,而&不具备短路特性;
  5. 内部类的作用:
    1.可以无条件访问外围类的所有元素,包括被private修饰的私有数据;
    2.实现隐藏和封装, 是一个相对独立的实体,与外部类不是is-a关系;
    3.实现多重继承;
    4.通过匿名内部类优化简单的接口实现.
    分类: Java内部类可分为成员内部类、局部内部类、匿名内部类、静态内部类。
    内部类是一个编译时的概念,编译后会生成两个独立的class文件:

1.成员内部类对外部类对象的引用,是通过在this前面加上外部类的名字构成的;
2. 局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。
3. 匿名内部类想象成是没有类名的局部内部类:
a.、匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器。
b、匿名内部类必须继承或实现一个接口,指定给new的类型为匿名类的超类型,匿名类不能有显示的extends或implements子句,也不能有任何修饰符。
c、匿名内部类和成员内部类、局部内部类一样,也不能声明静态成员。
4.静态内部类,有的书上也称为嵌套类,声明它时需要用static修饰符,静态内部类不同于前三种内部类,静态内部类不会持有外部类当前对象的引用,所以在静态内部类中无法访问外部类的非静态成员,可以这么说,静态内部类不依赖于外部类。
18. final有哪些用法:
1.被final修饰的类不可以被继承;
2.被final修饰的方法不可以被重写;
3.被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变;
4.被final修饰的方法,JVM会尝试将其内联,以提高运行效率;
5.被final修饰的常量,在编译阶段会存入常量池中.
19. String对象的intern():
Stirng中的intern()是个Native方法,它会首先从常量池中查找是否存在该常量值的字符串,若不存在则先在常量池中创建,否则直接返回常量池已经存在的字符串的引用.
20. String,StringBuffer和StringBuilder区别:
1.String是字符串常量,final修饰; String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,所以尽量不要对String进行大量的拼接操作,否则会产生很多临时对象; JVM会对String拼接做一定的优化,常量池.
2.StringBuffer字符串变量(线程安全); StringBuffer是对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用StringBuffer(线程安全).
3.StringBuilder 字符串变量(线程不安全).
此外StringBuilder和StringBuffer实现原理一样,都是基于数组扩容来实现的.
21.+=和运算符的的区别:

  1. short s1= 1; s1 = s1 + 1; 有错误.short类型在进行运算时会自动提升为int类型,也就是说s1+1的运算结果是int类型,而s1是short类型,此时编译器会报错.
  2. short s1= 1; s1 += 1; +=操作符会对右边的表达式结果强转匹配左边的数据类型,所以没错.
    22.泛型:
    所谓泛型:就是允许定义类、接口时指定类型形参,这个类型形参将在声明变量,创建对象时确定(即传入实际的类型参数,也可称为类型实参)。
    没有泛型之前,一旦吧一个对象“丢进”Java集合中,集合就会忘记对象的类型,把所有的对象都当成是Object类型处理。当程序从集合中取出对象之后,就要进行强制类型转换,这种强制类型转换不仅代码臃肿还容易引起ClassCastException异常。

<?>: 无限制通配符; <? extends E>: extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类; <? super E>: super关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类. 1.通配符问号(?)表示任意类型.如"List<?>"表示可以存放任意对象类型的List,和List一样。

2.通配符可以连接限制符:extends 和 super
如:上边界List<? extends Parent> 申明的List只能存放Parent及其子类,而下边界 List<? super Child> 申明的List只能存放Child及其父类。
3.通用类型,通常使用一个大写字母表示如:T(这里可以使用任意符合命名规则的字符都可以,不过我通常喜欢使用一个大写字母表示),它能代表任何类型。
如果使用通用类型申明一个变量,那么必须在类申明后面加上,尖括号里面的符号必须是前面申明的通用类型变量,如果有多个可以使用逗号分割如:<T,D>;
如果使用通用类型申明一个方法返回值或者方法参数,要么如上在类申明后加使用<>申明通用类型,要么在方法前申明通用类型。
23.数据结构:
1.线性表: 由N个元素组成的有序序列, 重点有数组和链表:
a.数组: 是一种存储单元连续,存储固定大小元素的线性表.ArrayList
b.链表: 分单链表和双链表, 是在物理存储单元上非连续, 非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链次序实现的.LinkedList
2.栈和队列:
a.栈: 是一种运算受限的线性表, 后进先出: 基本操作有push和pop, statck; Heap(堆),stack(栈)
一、栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
二、堆是栈的一个组成元素
第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。
第二,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。这种共享一方面提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。
第三,栈因为运行时的需要(比如保存系统运行的上下文),需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。
b.队列: 同上, 先进先出. Queue的实现;
3.树(重点):
a.二叉搜索树: 又叫二叉排序树;
b.平衡二叉树: 又叫AVL树;
c.红黑树: 特殊的平衡二叉树.
4.图: 更复杂的数据结构.
24. 两个系统之间的通讯方式:
a) 1、Webservice:效率不高基于soap协议。项目中不推荐使用。
b) 2、使用restful形式的服务:http+json。很多项目中应用。如果服务太多,服务之间调用关系混乱,需要治疗服务。
c) 3、使用dubbo。使用rpc协议进行远程调用,直接使用socket通信。传输效率高,并且可以统计出系统之间的调用关系、调用次数。
2. 传输协议 - HTTP,TCP,UDP,
3. 通信是基于Http的通信,
4. a.数据传输格式是XML;
5. 需要传输的对象 -> XML -> 远程传输(Http) -> 解析XML -> 需要传输的对象
6. b. 数据传输格式是二进制格式
7. 需要传输的对象 -> 二进制格式 -> 远程传输(Http) -> 解析二进制 -> 需要传输的对象
8. c. 可以使用java提供的Httpclient来通信,数据传输格式可以是Json
9. 需要传输的对象 -> Json -> 远程传输(Http) -> 解析Json -> 需要传输的对象
10. web service、RPC远程调用、
11. restful api,
12. 消息中间件小夕通信比如JMS, RocketMQ
13. 分布式系统间通信的常见方式有两种,
14. 一种是消息通信,比如JMS,RocketMQ等,
15. 一种是RPC远程调用:
16. RPC调用需要考虑的两个关键问题
17. a.远程通信协议的选择,例如Http,基于TCP或者UDP的socket等。
18. b.数据传输的格式,例如Java Object,xml,json,binary等.
25. 面向对象,面向服务,面向组件三种编程模式有什么区别:
三个数据后面都缺了一个词,分别是:“编程”、“架构”和“开发”(或“软件工程”).同时,不是“面向”组件而是“基于”组件。

1.面向对象编程(Object-Oreinted Programming) 是一种编程范式。指在设计程序时大量运用类实例对象的方式。OOP一旦在项目中被运用,就成了时刻要考虑的东西。
2.面向服务架构(Service-Oreinted Architecture) 是将软件设计成一组可互操作的服务的一套原则或方法论。通常在考虑系统架构时才会触及SOA。
3.基于组件开发(Component-Based Development) 是一种软件工程实践,设计时通常要求组件之间高内聚,松耦合。其接口可能是OO的,调用方式可能是以Service的方式。基于组件开发关注系统层次、子 系统边界和子系统间通讯的的设计,处于代码层面但不像OOP的一样是时刻需要运用的东西。

三者身处软件开发的不同层面,因此说他们用于“哪些领域”并不恰当。不论是哪个领域的软件开发,都可能要同时面对OOP、SOA和CBD。
26.JAVA类加载机制:
JVM将类加载过程划分为三个步骤:装载、链接和初始化。
装载(Load):装载过程负责找到二进制字节码并加载至JVM中,JVM通过类的全限定名(com.bluedavy. HelloWorld)及类加载器(ClassLoaderA实例)完成类的加载;
链接(Link):链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量及解析类中调用的接口、类;
初始化(Initialize):执行类中的静态初始化代码、构造器代码及静态属性的初始化。
27. 什么是反射API?它是如何实现的?:
需要动态绑定的场景下自然需要运用反射, 无法在编译期确定的,因此只能使用动态加载进行加载,然后通过反射探查其方法,并反射调用方法。反射是指在运行时能查看一个类的状态及特征,并能进行动态管理的功能。这些功能是通过一些内建类的反射API提供的,比如Class,Method,Field, Constructors等。使用的例子:使用Java反射API的getName方法可以获取到类名。
1,已知字节码对象(class),如何找到指定的Method,有哪些需要注意的地方?
答:
Method method = class.getMethod(methodName,methodName,methodType)//获取类中指定公有方法 包含继承
Method method = class.getDeclaredMethods(methodName,methodName,methodType)//获取类中指定定义的方法 包含私有
注意:当方法修饰符为private(私有)时,需要通过指定方法强制访问,如果方法有参数,需要指明参数类型
例:method.setAccessible(true); //指定方法的强制访问
2,已知实例对象,通过反射机制进行对象的创建?
答:
Boy.class.newInstance(); //直接构建没有初始化值的对象
class.getConstructors().newInstance(); //使用无参构造器构创建对象
class.getDeclaredConstructor(String.class).newInstance($ConstructorName); //使用有参构造器构创建对象

  1. 什么是java序列化,如何实现java序列化?:
    什么是序列化: 一、序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。为了解决在对对象流进行读写操作时所引发的问题。
    二、可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。
    序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的;
    然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
    29.多线程有几种实现方法?同步有几种实现方法:
    线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
    Java中的线程有四种状态分别是:运行、就绪、挂起、结束。
    多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
    同步的实现方面有两种,分别是synchronized,wait与notify
    30.线程池的概念?为何使用线程池?:
    创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,JavaAPI提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。
    31.数据连接池的工作机制是什么?:
    服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
    32.Exception和Error的区别:
    ① Exception 和Error 都是继承了Throwable类,在Java中只有Throwable类型的实例才可以被抛出或者捕获,它是异常处理机制的基本类型。
    ② Exception和Error体现了Java平台设计者对不同异常情况的分类。
    ⑴Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。
    ⑵Exception又分为可检查(checked)异常和不可检查(unchecked)异常。
    可检查异常在源代码里必须显式的进行捕获处理,这是编译期检查的一部分。
    不可检查时异常是指运行时异常,
    像NullPointerException、ArrayIndexOutOfBoundsException之类,
    通常是可以编码避免的逻辑错误,
    具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
    ⑶Error是指正常情况下,不大可能出现的情况,
    绝大部分的Error都会导致程序处于非正常的、不可恢复的状态。
    既然是非正常情况,不便于也不需要捕获。
    常见的比如OutOfMemoryError之类都是Error的子类。

从性能方面审视异常:
1.try-catch代码段会产生额外的性能开销,会影响JVM对代码进行优化,
所以建议仅捕获有必要的代码,不要一个大try包住整段代码,
不要用异常控制流程代码,很低效。
2.JAVA每实例化一个Exception,都会对当时的栈进行快照,
这是一个相对比较重的操作,如果发生的非常频繁,这个开销可就不能被忽视了。
3.不要推诿或者延迟处理异常,就地解决最好,
并需要实实在在的进行处理,而不是只捕捉,不动作
4.一个函数尽管抛出了多个异常,但是只有一个异常可被传播到调用端,
最后被抛出的异常时唯一被调用端接收的异常,其他异常都会被吞没掩盖。
如果调用端要知道造成失败的最初原因,程序中就不能掩盖异常
33.项目中遇到的异常以及解决方法:

  1. java.lang.NullPointerException: 当null调用属性或者方法的时候就会报空指针异常;
  2. ArrayIndexOutOfBoundsException: 数组下标越界;
  3. ClassCastException: 类型强制转换异常;
  4. SQLException:SQL语句有问题需要修改;
  5. OutOfMemoryError:内存溢出,: 代码中存在死循环,(处理循环)启动参数设定过小(设定服务器的启动参数增大),内存中一次加载的数据量过于庞大(减少一次加载的数据),集合类应用的对象未回收(手动回收未回收对象);
  6. java.lang.NoSuchMethodException: 找不到方法,可能与配置有关;
    7.java.text.ParseException: 格式转换异常;
    8.java.lang.ClassNotFoundException: 找不到调用的class文件;
    9.java.lang.NumberFormatException:数字格式化异常;
  7. FileNotFoundException:找不到文件异常;
  8. IOException:输入输出异常;
  9. java.lang.StackOverflowError:当一个应用递归调用的层次太深而导致堆栈溢出;
  10. java.lang.StringIndexOutOfBoundsException: 字符串索引越界异常.
  11. java.lang.IllegalAccessException非法参数异常
  12. 面向对象,面向服务,面向组件三种编程模式有什么区别?
    三个数据后面都缺了一个词,分别是:“编程”、“架构”和“开发”(或“软件工程”).同时,不是“面向”组件而是“基于”组件。
    面向对象编程(Object-Oreinted Programming) 是一种编程范式。指在设计程序时大量运用类实例对象的方式。OOP一旦在项目中被运用,就成了时刻要考虑的东西。
    面向服务架构(Service-Oreinted Architecture) 是将软件设计成一组可互操作的服务的一套原则或方法论。通常在考虑系统架构时才会触及SOA。
    基于组件开发(Component-Based Development) 是一种软件工程实践,设计时通常要求组件之间高内聚,松耦合。其接口可能是OO的,调用方式可能是以Service的方式。基于组件开发关注系统层次、子 系统边界和子系统间通讯的的设计,处于代码层面但不像OOP的一样是时刻需要运用的东西。
    35.堆和栈的区别?
    Heap(堆),stack(栈)
    一、栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
    二、堆是栈的一个组成元素
    第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。
    第二,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。这种共享一方面提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。
    第三,栈因为运行时的需要(比如保存系统运行的上下文),需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。
  13. Java内存泄露和内存溢出?
     内存泄漏:分配出去的内存回收不了
     内存溢出:指系统内存不够用了
  14. 两个系统之间的通讯方式:
    a) 1、Webservice:效率不高基于soap协议。项目中不推荐使用。
    b) 2、使用restful形式的服务:http+json。很多项目中应用。如果服务太多,服务之间调用关系混乱,需要治疗服务。
    c) 3、使用dubbo。使用rpc协议进行远程调用,直接使用socket通信。传输效率高,并且可以统计出系统之间的调用关系、调用次数。
    TCP HTTP UDP三者的关系:
    TCP/IP是个协议组,可分知为四个层次:网络接口层、网络层、传输道层和应用层。
    在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
    在传输层中回有TCP协议与UDP协议。
    在应用层有FTP、HTTP、TELNET、SMTP、DNS等协议。
    因此,HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏答览器的传送协议。大多都基于TCP协议传输.
    TCP(Transmission Control Protocol,传输控制协议)—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
    UDP(User Datagram Protocol)—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
    TCP是面向连接的,有比较高的可靠性,
    一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等,而UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。
    TCP与UDP区别总结:
    1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
    2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
    3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
    UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
    4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
    5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
    6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

传输协议 - HTTP,TCP,UDP,
通信是基于Http的通信,
a.数据传输格式是XML;
需要传输的对象 -> XML -> 远程传输(Http) -> 解析XML -> 需要传输的对象
b. 数据传输格式是二进制格式
需要传输的对象 -> 二进制格式 -> 远程传输(Http) -> 解析二进制 -> 需要传输的对象
c. 可以使用java提供的Httpclient来通信,数据传输格式可以是Json
需要传输的对象 -> Json -> 远程传输(Http) -> 解析Json -> 需要传输的对象
web service、RPC远程调用、
restful api,
消息中间件小夕通信比如JMS, RocketMQ
分布式系统间通信的常见方式有两种,
一种是消息通信,比如JMS,RocketMQ等,
一种是RPC远程调用:
RPC调用需要考虑的两个关键问题
a.远程通信协议的选择,例如Http,基于TCP或者UDP的socket等。
b.数据传输的格式,例如Java Object,xml,json,binary等。
38. 项目中遇到的问题以及解决思路:
Single Sign on相比于单系统登录,SSO需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,SSO认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理.
sso-client

  1. 拦截子系统未登录用户请求,跳转至sso认证中心
  2. 接收并存储sso认证中心发送的令牌
  3. 与sso-server通信,校验令牌的有效性
  4. 建立局部会话
  5. 拦截用户注销请求,向sso认证中心发送注销请求
  6. 接收sso认证中心发出的注销请求,销毁局部会话
      sso-server
  7. 验证用户的登录信息
  8. 创建全局会话
  9. 创建授权令牌
  10. 与sso-client通信发送令牌
  11. 校验sso-client令牌有效性
  12. 系统注册
  13. 接收sso-client注销请求,注销所有会话
  14. 查询的速度在开发环境快, 但是在生产环境变慢了,你会怎么办?:
    查看电脑配置的CPU和虚拟机大小是否差别很大;
    开发环境和生产环境数据量不一样
    代码层面分析: for循环分析, 业务逻辑复杂度分析
    左连接就是必须先查左表全表扫描,然后一条一条的到另外表去查询,右连接同理。
    左连接LEFT JOIN ON:左边有的,右边没有的为null
    右连接RIGHT JOIN ON:左边没有的,右边有的为null
    内连接INNER JOIN:显示左边右边共有的
  15. SOA架构: Service Oriented Architecture面向服务的架构:
    把工程拆分成服务层工程和表现层工程: 服务层中包含业务逻辑, 只需要对外提供服务即可, 表现层只需要处理和页面的交互, 业务逻辑都是调用服务层的服务来实现, 工程都可以独立部署.
    分布式架构:
    把系统按照模块拆分成多个子系统;多个子系统相互协作才能完成业务流程系统之间需要进行通信。
    优点:
    1、把模块拆分,使用接口通信,降低模块之间的耦合度。
    2、把项目拆分成若干个子项目,不同的团队负责不同的子项目。
    3、增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。
    4、可以灵活的进行分布式部署。

缺点:
1、系统之间交互需要使用远程通信,需要开发接口,增加工作量。
2、各个模块有一些通用的业务逻辑无法公用。
41. cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗, 考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能, 考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
42.System.out::println含义:
查看println方法的源码得知println是PrintStream类中的一个非静态方法
System.out::println这段代码其实就是Consumer接口的一个实现方式
因此按照方法引用的逻辑,它肯定可以使用
“函数式接口 变量名 = 类实例::方法名” 的方式对该方法进行引用

42.JVM, JRE, JDK之间的关系:
JVM: (java virtual machine)JVM是java虚拟机,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。
JRE: (java runtime environment)JRE是Java的运行环境,包括JVM标准实现及Java核心类库。
JDK:(java development kit)JDK是Java开发工具包,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。
三者之间关系:
  JDK包含JRE,JRE包含JVM。
金字塔结构 JDK=JRE+JVM+其它 运行Java程序一般都要求用户的电脑安装JRE环境(Java Runtime Environment);没有jre,java程序无法运行;而没有java程序,jre就没有用武之地。   
43.类加载机制的含义和过程:
类加载机制就是将class中的类信息加载到内存后经过检验、转化、解析、初始化后,变成可使用的java类型的过程。
加载过程:
1装载:将.class文件通过字节流读入内存,然后将字节流转化为方法区的运行时数据结构,接着在堆中生成该类的实例对象
2验证:验证加载类文件格式、元数据、字节码、符号引用等的正确性
3准备:为类的静态变量分配内存,并将其初始化为默认值
4解析:把类中的符号引用转换为直接引用(内存地址)
5初始化:对类的静态变量、静态代码块执行初始化操作
44. 简述你对吞吐量和停顿时间的理解:
吞吐量为非垃圾收集时间占程序运行时间的百分比。
停顿为为准备回收垃圾(可忽略不计)和垃圾收集时程序未响应的时间。
个人认为这两个指标本质上衡量的就是GC出现的频率和时间,只是从不同的角度体现而已。
44.JVM常用的类型参数:
(1)标准参数:一般参数是不随着jdk版本的变化而变化的,比如-version,-help
(2)-X参数:非标准参数,比如可以设置JVM是编译执行还是解释执行还是混合模式:
a)-X:int 使JVM解释(interpret)执行
b)-X:comp 使JVM编译(compile)执行
c)-X:mixed 解释执行和编译执行的混合模式
(3)-XX参数:
a)-XX:=,比如-XX:MataspaceSize -XX:MaxMetaspaceSize -XX:DumpHeapPath
b)-XX:[+/-],比如-XX:-UserG1GC -XX:+DumpHeapOnOutOfMemoryError
(4)其他参数:比如-Xms、-Xmx、-Xss
45.doGet和doPost的区别:
1,form运行方式
当form框里面的method为get时,执行doGet方法
当form框里面的method为post时,执行doPost方法
2,生成方式
get方式有四种:1)直接在URL地址栏中输入URL。2)网页中的超链接。3)form中method为get。4)form中method为空时,默认是get提交。
post只知道有一种:form中method属性为post。
3,数据传送方式
get方式:表单数据存放在URL地址后面。所有get方式提交时HTTP中没有消息体。
post方式:表单数据存放在HTTP协议的消息体中以实体的方式传送到服务器。
get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。
post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
4、服务器获取数据方式
GET方式:服务器采用request.QueryString来获取变量的值。
POST方式:服务器采用request.Form来获取数据。
5、传送的数据量
GET方式:数据量长度有限制,一般不超过2kb。因为是参数传递,且在地址栏中,故数据量有限制。
POST方式:适合大规模的数据传送。因为是以实体的方式传送的。
6、安全性
GET方式:安全性差。因为是直接将数据显示在地址栏中,浏览器有缓冲,可记录用户信息。所以安全性低。
POST方式:安全性高。因为post方式提交数据时是采用的HTTP post机制,是将表单中的字段与值放置在HTTP HEADER内一起传送到ACTION所指的URL中,用户是看不见的。
7、在用户刷新时
GET方式:不会有任何提示、
POST方式:会弹出提示框,问用户是否重新提交。
在做数据查询时,建议用Get方式;
而在做数据添加、修改或删除时,建议用Post方式。
46.sleep()和wait()的区别:
1.sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
2.wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
47.同步和异步有什么不同, 什么情况下使用他们?
1.如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
2.当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
48.GC是什么?
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
49.多线程机制:
线程的生命周期和触发的机制:
线程的生命周期包含5个阶段:新建、就绪、运行、阻塞、销毁。
新建:就是刚使用new方法,new出来的线程;
就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;
运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;
阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;
销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;
NEW->RUNNABLE->BLOCKED->WAITING->TIME_WAITING->TERMINATED
Java中线程的使用及多线程的触发:
1)继承Thread类或直接使用Thread类;
2)实现Runnable接口.
3)实现Callable接口使用Executor框架来创建线程池。

多线程相关名词解释:
并发数:每一秒能处理的请求数
服务器能承载的并发数:
1.硬件[CPU,内存,磁盘,网络];
2.软件[线程数量,JVM内存分配大小,网络通信机制BIO/NIO/AIO,磁盘IO]
线程数量如何提升服务端的并发数量?
线程:操作系统和CPU调度的最小单元
一个进程中可以创建N个线程->取决CPU的核心数

并发指的是多个任务交替进行,并行则是指真正意义上的“同时进行”。
串行: 是一次只能取得一个任务,并执行这个任务。串行表示所有任务都一一按先后顺序进行。
并行: 是同一时刻可以多个进程在运行,并行意味着可以同时取得多个任务,并同时去执行所取得的这些任务。并行与否程序员无法控制,只能让操作系统决定。
并发: 并发的"同时"是经过上下文快速切换,使得看上去多个进程同时都在运行的现象.
什么是死锁如何解决?
死锁就是一组互相竞争资源的线程因互相等待,导致永久阻塞的现象。
首先造成死锁必须得同时满足互斥、占有且等待、不可抢占和循环等待四大条件。
所以解决死锁只需要破坏死锁条件的一条即可,
1)互斥是必备的一个因素,不可改变,
2)对于占有且等待,可以一次性获取所有资源即可解决,
3)对于不可抢占,可以在申请不到资源的时候,主动释放它所占有的资源即可,
4)对于循环等待,可以顺序申请资源。
sleep() 方法和 wait() 方法区别和共同点?
相同点:两者都可以暂停线程的执行,都会让线程进入等待状态。
不同点:
sleep()方法没有释放锁,而 wait()方法释放了锁。
sleep()方法属于Thread类的静态方法,作用于当前线程;而wait()方法是Object类的实例方法,作用于对象本身。
执行sleep()方法后,可以通过超时或者调用interrupt()方法唤醒休眠中的线程;执行wait()方法后,通过调用notify()或notifyAll()方法唤醒等待线程。
为什么我们调用 start() 方法时会执行 run() 方法?
调用 start 方法可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。
线程安全问题:
线程安全问题指的是在某一线程从开始访问到结束访问某一数据期间,该数据被其他的线程所修改,那么对于当前线程而言,该线程就发生了线程安全问题,表现形式为数据的缺失,数据不一致等。
线程安全问题的解决思路:
1)尽量不使用共享变量,将不必要的共享变量变成局部变量来使用。
2)使用synchronized关键字同步代码块,或者使用jdk包中提供的Lock为操作进行加锁。
3)使用ThreadLocal为每一个线程建立一个变量的副本,各个线程间独立操作,互不影响。
Java中线程的使用及多线程的触发:
性能问题:一个线程的创建到销毁都会占用大量的内存
利用线程池,模拟一个池,预先创建有限合理个数的线程放入池中,当需要执行任务时从池中取出空闲的先去执行任务,执行完成后将线程归还到池中,这样就减少了线程的频繁创建和销毁,节省内存开销和减小了垃圾回收的压力。同时因为任务到来时本身线程已经存在,减少了创建线程时间,提高了执行效率,而且合理的创建线程池数量还会使各个线程都处于忙碌状态,提高任务执行效率,线程池还提供了拒绝策略,当任务数量到达某一临界区时,线程池将拒绝任务的进入,保持现有任务的顺利执行,减少池的压力。
使用线程池的好处?:
1.降低资源消耗。通过重复利用已创建的线程,降低线程创建和销毁造成的消耗。
2.提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3.提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会4.降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。
几种常见的线程池及适用场景?
FixedThreadPool:可重用固定线程数的线程池。
SingleThreadExecutor:只会创建一个线程执行任务。
CachedThreadPool:是一个会根据需要调整线程数量的线程池。
ScheduledThreadPool:继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务
volatile关键字?
保证共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
把变量声明为volatile,这就指示 JVM每次使用它都到主存中进行读取。
什么叫互斥锁,什么叫共享锁,他们有什么区别?
1、互斥锁:字面理解相互排斥的,即两个线程获得锁是互斥的,一个线程获得了锁,其他线程在此线程释放锁之前是不能获得锁的,java提供了一个互斥锁为reentrantlock,该锁是可以重入的。重入就是指,线程获得了锁之后,此线程可以进入任一其他方法中关于这个对象的锁。
共享锁:就是多个线程可以共享锁,这里指的就是lock的实现ReentrantReadWriteLock,ReentrantReadWriteLock分为读锁与写锁,这里锁的特殊之处就是,提供了读写锁分离
,分离的好处就是可以让读锁共享,就是多个线程可以共享读锁,读读共享以及写写互斥以及读写互斥,是这个锁的主要特点。
区别:互斥锁也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行。而共享锁则是一种乐观锁,它放宽了加锁策略,允许多个执行读操作的线程同时访问共享资源。
有界队列和无界队列的区别
2、有界队列:就是有固定大小的队列。比如设定了固定大小的 LinkedBlockingQueue,又或者大小为 0,只是在生产者和消费者中做中转用的 SynchronousQueue。
无界队列:指的是没有设置固定大小的队列。这些队列的特点是可以直接入列,直到溢出。当然现实几乎不会有到这么大的容量(超过 Integer.MAX_VALUE),所以从使用者的体验上,就相当于“无界”。比如没有设定固定大小的 LinkedBlockingQueue。
什么叫阻塞队列,它有什么特点
3、阻塞队列是一个在队列基础上又实现了特定情况下的阻塞操作的队列。
特点:
(1)支持阻塞的插入方法:队列满时,队列会阻塞插入元素的线程,直到队列不满。
(2)支持阻塞的移除方法:队列空时,获取元素的线程会等待队列变为非空。
线程池的核心参数有哪些,分别表示什么意思?
corePoolSize:核心线程数,代表线程池在不超负荷(即没有由于任务过多而使得阻塞队列满了创建临时线程)工作的情况下,能够被允许创建的线程数上限;
maximunPoolSize:最大线程数,代表由于并发量太大,而导致任务过多,阻塞队列中存放的任务满了,这时会在corePoolSize线程数的基础上最多再创建(maximumPoolSize-corePoolSize)个数量的线程来帮助处理任务;
blockingQueue:阻塞队列,用于存放待处理任务的数据结构;
keepAliveTime:线程空闲时存活时间,表示在没有任务处理的时候还能存活这么长时间;
allowCoreThreadTimeOut:是否允许核心线程超时,如果为true,代表允许,即当没有任务处理时,在keepAliveTime时间后线程会消亡;
rejectExecutorHandler:拒绝执行策略,表示当线程的阻塞队列已经满了,且临时线程已经达到maximumPoolSize个数量时,再来新任务,线程池会拒绝执行,这个参数表示了拒绝的方式。
50.为什么使用jQuery?
• 因为jQuery是轻量级的框架,大小不到30kb
• 它有强大的选择器,出色的DOM操作的封装
• 有可靠的事件处理机制(jQuery在处理事件绑定的时候相当的可靠)
• 完善的ajax(它的ajax封装的非常的好,不需要考虑复杂浏览器的兼容性和XMLHttpRequest对象的创建和使用的问题。)
• 出色的浏览器的兼容性
• 支持链式操作,隐式迭代
• 行为层和结构层的分离,还支持丰富的插件,jquery的文档也非常的丰富
jQuery中有哪几种类型的选择器?
1.基本选择器:
id选择器; class选择器, element(元素)选择器; * 选择器(遍历所有元素);
并列选择器; 层次选择器, prev + next(下一个兄弟元素,等同于next()方法);
prev ~ siblings(prev元素的所有兄弟元素,等同于nextAll()方法);
2. 过滤选择器——基本过滤选择器:
first和:last(取第一个元素或最后一个元素); not(取非元素);
even和:odd(取偶数索引或奇数索引元素,索引从0开始,
even表示偶数,odd表示奇数);
eq(x)(取指定索引的元素);
gt(x)和:lt(x) (取大于x索引或小于x索引的元素);
header(取H1~H6标题元素);
3. 过滤选择器——内容过滤选择器:
contains(text)(取包含text文本的元素);
empty(取不包含子元素或文本为空的元素);
has(selector)(取选择器匹配的元素); parent(取包含子元素或文本的元素);
4. -过滤选择器—— 可见性过滤选择器:
hidden(取不可见的元素): jQuery至1.3.2之后的:hidden选择器仅匹配display:none或的元素,而不匹配visibility: hidden或opacity:0的元素。这也意味着hidden只匹配那些“隐藏的”并且不占空间的元素,像visibility:hidden或opactity:0的元素占据了空间,会被排除在外;
visible(取可见的元素);
5. 过滤选择器——属性过滤选择器:
[attribute](取拥有attribute属性的元素);
[attribute = value]和[attribute != value](取attribute属性值等于value或不等于value的元素);
6. 表单选择器:
:input表单选择器; :text表单文本选择器; :password表单密码选择器;
:radio单选按钮选择器; :checkbox复选框选择器; :submit提交按钮选择器;
:image图像域选择器; :button表单按钮选择器; :checked选中状态选择器;
:selected选中状态选择器;
( d o c u m e n t ) . r e a d y ( ) 是 个 什 么 函 数 ? 为 什 么 要 用 它 ? 这 个 问 题 很 重 要 , 并 且 常 常 被 问 到 。 r e a d y ( ) 函 数 用 于 在 文 档 进 入 r e a d y 状 态 时 执 行 代 码 。 当 D O M 完 全 加 载 ( 例 如 H T M L 被 完 全 解 析 D O M 树 构 建 完 成 时 ) , j Q u e r y 允 许 你 执 行 代 码 。 使 用 (document).ready() 是个什么函数?为什么要用它? 这个问题很重要,并且常常被问到。 ready() 函数用于在文档进入ready状态时执行代码。当DOM 完全加载(例如HTML被完全解析DOM树构建完成时),jQuery允许你执行代码。使用 (document).ready()是个什么函数?为什么要用它?这个问题很重要,并且常常被问到。ready()函数用于在文档进入ready状态时执行代码。当DOM完全加载(例如HTML被完全解析DOM树构建完成时),jQuery允许你执行代码。使用(document).ready()的最大好处在于它适用于所有浏览器,jQuery帮你解决了跨浏览器的难题。
jQuery 库中的 $() 是什么?
$() 函数是 jQuery() 函数的别称, $() 函数用于将任何对象包裹成 jQuery 对象,接着你就被允许调用定义在 jQuery 对象上的多个不同方法。你甚至可以将一个选择器字符串传入 $() 函数,它会返回一个包含所有匹配的 DOM 元素数组的 jQuery 对象。
$(this) 和 this 关键字在 jQuery 中有何不同
$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用val() 获取值等等。而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹.
jQuery 里的 each() 是什么函数?
each() 函数就像是 Java 里的一个 Iterator,它允许你遍历一个元素集合。你可以传一个函数给 each() 方法,被调用的 jQuery 对象会在其每个元素上执行传入的函数。
你如何使用jQuery设置一个属性值?
对象.attr(“name”,“value”);name是属性的名称,value是这个属性的新值;
对象.prop(“name”,“value”);
设置多个属性值:对象.attr(“name”:“value”,“name”:“value”)属性:属性值,属性:属性值;
对于html元素本身就带有的固定属性(本身就带有的属性),在处理时,使用prop方法 可以操作布尔类型的属性;
对于html元素我们自己定义的dom属性,在处理时,使用attr方法 不可以操作布尔类型的属性.
ready()方法和onload()方法的区别?
onload()方法要等页面中全部元素加载到浏览器中才执行,如果页面中存在大量图片,要等这些内容加载完毕。ready()方法只要页面的dom模型加载完毕即可,就会触发ready()。

.什么是Ajax呢?
Ajax是Asynchronous JavaScript and XML的缩写,核心是通过XMLHttpRequest对象进行异步获取的方法,向服务器发送数据请求,通过这个对象进行接收请求返回的数据。

java面试之Java基础相关推荐

  1. [Java面试三]JavaWeb基础知识总结.

    [Java面试三]JavaWeb基础知识总结. 1.web服务器与HTTP协议 Web服务器 l WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. l Int ...

  2. very very good,Java面试宝典+Java核心知识集

    这几天刚整理出炉的两份最全"Java面试宝典+Java核心知识集"(very very good!!!),因此有了今天咱这篇文章,没错,我又来分享干货了!!! Java面试宝典 说 ...

  3. Java面试之语言基础

    文章目录 Java八种基本数据类型 Java三大基础特性 面向对象和面向过程的区别 面向过程 面向对象 Java与C++对比 Java8 新特性 Java反射机制 Java异常机制 Throwable ...

  4. java面试必知--基础

    1 / 66 Java 基础知识总结 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的 j ...

  5. 46道面试题带你了解中高级Java面试,Java开发必看书籍

    前言 分布式事务主要解决分布式一致性的问题.说到底就是数据的分布式操作导致仅依靠本地事务无法保证原子性.与单机版的事务不同的是,单机是把多个命令打包成一个统一处理,分布式事务是将多个机器上执行的命令打 ...

  6. (Java面试)Java面试越来越难,不加油卷起来,怎么拿到大厂offer!!

    前言 最近看到一则很现实的故事:陆路最近心态很崩.和他同期一道进公司的陈琪又升了一级,可是明明大家在进公司时,陈琪不论是学历还是工作经验,样样都不如自己,眼下不过短短的两年时间便一跃在自己的职级之上, ...

  7. Java面试:java小项目实例

    前言 本人是底层 211 本科,刚毕业,⽆科研经历,但是有些项⽬经历. 在国内监控行业某头部企业做过一段时间的实习. 想着投下字节,可以积累⼀下⾯试经验和为金九银十面招做准备.投了简历之后,过了一段时 ...

  8. 2021最后一次Java面试,java工程师职业生涯规划

    前言 Spring 5 于 2017 年 9 月发布了通用版本 (GA),它标志着自 2013 年 12 月以来第一个主要 Spring Framework 版本.它提供了一些人们期待已久的改进,还采 ...

  9. 阿里Java面试之-Java高级工程师

    哈喽,大家好呀,前段时间我去阿里面试高级Java工程师,我这次把这些问道的题目都列举出来了! 文章末尾我还为大家准备了一份福利哦! JVM · 请介绍一下JVM内存模型??用过什么垃圾回收器?都说说呗 ...

最新文章

  1. android open source
  2. 爆款互联网人, 28岁的财富自由?
  3. Leetcode--3Sum
  4. 查询工资最低的3名员工的职工工号、姓名和收入_关于工资条,这6个常识必须掌握,事关你的权益!...
  5. OPCServer Modbus使用和配置
  6. C++——如何重载*(指针)操作符
  7. How to install OpenERP 6 on Ubuntu 10.04 LTS Server--1
  8. Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)
  9. 早上起床后喝的第一杯水最好选择白开水
  10. jest自动化测试遇到的一些报错信息及解决方案
  11. 3-51单片机ESP8266学习-AT指令(学会刷固件)
  12. android 组件重用,Android提高显示布局文件的性能,使用include标签重用layouts
  13. python 根据地址求经纬度 谷歌_利用google地图根据地址批量获取经纬度
  14. 2022-2028全球针织捆包网行业调研及趋势分析报告
  15. 工作经验的Java学习心得
  16. python控制蓝牙pybluez_Python之蓝牙通讯模块pybluez学习笔记
  17. asp.net MVC三层结构代码生成器
  18. CF1503D Flip the Cards(思维题)
  19. 【无浪】自己用C++实现的零游戏的战斗(半成品)
  20. void *指针是什么含义

热门文章

  1. 路由器地址大全 各品牌路由设置地址
  2. TinyXml入门简易教程.
  3. Jenkins任务优先级插件
  4. 论文解读:PeSTo:用于精确预测蛋白质结合界面的无参数几何深度学习
  5. SugarCRM开发入门
  6. noj 2068 爱魔法的露露 [线性扫一遍]
  7. 马云的创业故事及他人生中的摆渡人-创建阿里巴巴(六)
  8. 数据分析入门(一)数据加载及初步分析
  9. 天堂还是地狱!美国大学不是你想象的那样!道翰天琼认知智能API接口平台为您揭秘。
  10. haproxy 503 Service Unavailable