精华内容
下载资源
问答
  • 2020JAVA面试题附答案(长期更新)

    万次阅读 多人点赞 2018-05-17 22:53:57
    2018年12月28日:更新了springboot相关面试题, spring更多的内容(类别:开源框架) 2019年11月14日:更新redis缓存雪崩,击穿,穿透相关面试题,更新了tomcat调优相关问题,更新了TCP三次握手四次握手问题 JAVA基础 ...

    最新更新日志

    2020年5 月 6 日:Spring,Redis ,数据库相关更新面试题

    2020年8月4日10: ElasticSearch相关面试题


    JAVA基础

    JAVA中的几种基本类型,各占用多少字节?

    这里写图片描述 
    下图单位是bit,非字节 1B=8bit 
    这里写图片描述

    String能被继承吗?为什么?

    不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。平常我们定义的String str=”a”;其实和String str=new String(“a”)还是有差异的。

    前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个则取决于你的赋值,比如String num=1,调用的是 
    public static String valueOf(int i) { 
    return Integer.toString(i); 
    }

    后者则是调用如下部分: 
    public String(String original) { 
    this.value = original.value; 
    this.hash = original.hash; 

    最后我们的变量都存储在一个char数组中 
    private final char value[];

    String, Stringbuffer, StringBuilder 的区别。

    String 字符串常量(final修饰,不可被继承),String是常量,当创建之后即不能更改。(可以通过StringBuffer和StringBuilder创建String对象(常用的两个字符串操作类)。) 
    StringBuffer 字符串变量(线程安全),其也是final类别的,不允许被继承,其中的绝大多数方法都进行了同步处理,包括常用的Append方法也做了同步处理(synchronized修饰)。其自jdk1.0起就已经出现。其toString方法会进行对象缓存,以减少元素复制开销。 
    public synchronized String toString() { 
    if (toStringCache == null) { 
    toStringCache = Arrays.copyOfRange(value, 0, count); 

    return new String(toStringCache, true); 
    }

    StringBuilder 字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。 
    public String toString() { 
    // Create a copy, don’t share the array 
    return new String(value, 0, count); 
    }

    JAVA容器列举,同步容器和并发容器

    Collection下 和 Map下的实现, 例如ArrayList, HashMap. HashTable, HashSet, LinkedArrayList等

    同步容器: HashTable,Vector

    并发容器: ConcurrentHashMap

    ArrayList 和 LinkedList 有什么区别,以及查询和插入的时间复杂度。

    ArrayList和LinkedList都实现了List接口,有以下的不同点: 
    1、ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。 
    2、相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。 
    3、LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

    讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候, 他们的执行顺序。

    此题考察的是类加载器实例化时进行的操作步骤(加载–>连接->初始化)。 
    父类静态代变量、 
    父类静态代码块、 
    子类静态变量、 
    子类静态代码块、 
    父类非静态变量(父类实例成员变量)、 
    父类构造函数、 
    子类非静态变量(子类实例成员变量)、 
    子类构造函数。 
    测试demo:http://blog.csdn.net/u014042066/article/details/77574956 
    参阅我的博客《深入理解类加载》:http://blog.csdn.net/u014042066/article/details/77394480

    用过哪些 Map 类,都有什么区别,HashMap 是线程安全的吗,并发下使用的 Map 是什么,他们内部原理分别是什么,比如存储方式, hashcode,扩容, 默认容量等。

    hashMap是线程不安全的,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,采用哈希表来存储的, 
    参照该链接:https://zhuanlan.zhihu.com/p/21673805 
    JAVA8 的 ConcurrentHashMap 为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。 
    参照:https://yq.aliyun.com/articles/36781

    有没有有顺序的 Map 实现类, 如果有, 他们是怎么保证有序的。

    TreeMap和LinkedHashMap是有序的(TreeMap默认升序,LinkedHashMap则记录了插入顺序)。 
    参照:http://uule.iteye.com/blog/1522291

    请你简单说下HashMap的Put()方法.

    shixinzhang

    抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。

    1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。 
    2、抽象类要被子类继承,接口要被类实现。 
    3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现 
    4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。 
    5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。 
    6、抽象方法只能申明,不能实现。abstract void abc();不能写成abstract void abc(){}。 
    7、抽象类里可以没有抽象方法 
    8、如果一个类里有抽象方法,那么这个类只能是抽象类 
    9、抽象方法要被实现,所以不能是静态的,也不能是私有的。 
    10、接口可继承接口,并可多继承接口,但类只能单根继承。

    继承和聚合的区别在哪。

    继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;在Java中此类关系通过关键字extends明确标识,在设计时一般没有争议性; 
    这里写图片描述 
    聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分; 
    这里写图片描述

    参考:http://www.cnblogs.com/jiqing9006/p/5915023.html

    讲讲你理解的 nio和 bio 的区别是啥,谈谈 reactor 模型。

    IO是面向流的,NIO是面向缓冲区的 
    参考:https://zhuanlan.zhihu.com/p/23488863 
    http://developer.51cto.com/art/201103/252367.htm 
    http://www.jianshu.com/p/3f703d3d804c

    反射的原理,反射创建类实例的三种方式是什么

    1. getClass()

    2.xxx.class

    3. Class.forName

    参照:http://www.jianshu.com/p/3ea4a6b57f87?amp

    http://blog.csdn.net/yongjian1092/article/details/7364451

    反射中,Class.forName 和 ClassLoader 区别。

    Class.forName(className)方法,其实调用的方法是Class.forName(className,true,classloader);注意看第2个boolean参数,它表示的意思,在loadClass后必须初始化。比较下我们前面准备jvm加载类的知识,我们可以清晰的看到在执行过此方法后,目标对象的 static块代码已经被执行,static参数也已经被初始化。

     再看ClassLoader.loadClass(className)方法,其实他调用的方法是ClassLoader.loadClass(className,false);还是注意看第2个 boolean参数,该参数表示目标对象被装载后不进行链接,这就意味这不会去执行该类静态块中间的内容。因此2者的区别就显而易见了

    https://my.oschina.net/gpzhang/blog/486743

    描述动态代理的几种实现方式,分别说出相应的优缺点。

    Jdk cglib jdk底层是利用反射机制,需要基于接口方式,这是由于 
    Proxy.newProxyInstance(target.getClass().getClassLoader(), 
    target.getClass().getInterfaces(), this); 
    Cglib则是基于asm框架,实现了无反射机制进行代理,利用空间来换取了时间,代理效率高于jdk 
    http://lrd.ele.me/2017/01/09/dynamic_proxy/

    动态代理与 cglib 实现的区别

    同上(基于invocationHandler和methodInterceptor)

    为什么 CGlib 方式可以对接口实现代理。

    同上

    注解原理

    https://www.jianshu.com/p/a692150d625c

    final 的用途

    类、变量、方法 
    http://www.importnew.com/7553.html

    写出三种单例模式实现。

    懒汉式单例,饿汉式单例,双重检查等 
    参考:https://my.oschina.net/dyyweb/blog/609021

    如何在父类中为子类自动完成所有的 hashcode 和 equals 实现?这么做有何优劣。

    同时复写hashcode和equals方法,优势可以添加自定义逻辑,且不必调用超类的实现。 
    参照:http://java-min.iteye.com/blog/1416727

    请结合 OO 设计理念,谈谈访问修饰符 public、private、protected、default 在应用设计中的作用。

    访问修饰符,主要标示修饰块的作用域,方便隔离防护

    同一个类    同一个包    不同包的子类  不同包的非子类
    
    • 1
    • 2

    Private √ 
    Default √ √ 
    Protected √ √ √ 
    Public √ √ √ √ 
    public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不 
         仅可以跨类访问,而且允许跨包(package)访问。 
    private: Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的类、属性以 
         及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。 
    protect: 介于public 和 private 之间的一种访问修饰符,一般称之为“保护形”。被其修饰的类、 
         属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。 
    default:即不加任何访问修饰符,通常称为“默认访问模式“。该模式下,只允许在同一个包中进行访 
         问。

    深拷贝和浅拷贝区别。

    http://www.oschina.net/translate/java-copy-shallow-vs-deep-in-which-you-will-swim

    数组和链表数据结构描述,各自的时间复杂度

    http://blog.csdn.net/snow_wu/article/details/53172721

    error 和 exception 的区别,CheckedException,RuntimeException 的区别

    http://blog.csdn.net/woshixuye/article/details/8230407

    请列出 5 个运行时异常。

    同上

    在自己的代码中,如果创建一个 java.lang.String 对象,这个对象是否可以被类加载器加载?为什么

    类加载无须等到“首次使用该类”时加载,jvm允许预加载某些类。。。。 
    http://www.cnblogs.com/jasonstorm/p/5663864.html

    说一说你对 java.lang.Object 对象中 hashCode 和 equals 方法的理解。在什么场景下需要重新实现这两个方法。

    参考上边试题

    在 jdk1.5 中,引入了泛型,泛型的存在是用来解决什么问题。

    泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率 
    http://baike.baidu.com/item/java%E6%B3%9B%E5%9E%8B

    这样的 a.hashcode() 有什么用,与 a.equals(b)有什么关系。

    hashcode 
    hashcode()方法提供了对象的hashCode值,是一个native方法,返回的默认值与System.identityHashCode(obj)一致。

    通常这个值是对象头部的一部分二进制位组成的数字,具有一定的标识对象的意义存在,但绝不定于地址。

    作用是:用一个数字来标识对象。比如在HashMap、HashSet等类似的集合类中,如果用某个对象本身作为Key,即要基于这个对象实现Hash的写入和查找,那么对象本身如何实现这个呢?就是基于hashcode这样一个数字来完成的,只有数字才能完成计算和对比操作。

    hashcode是否唯一 
    hashcode只能说是标识对象,在hash算法中可以将对象相对离散开,这样就可以在查找数据的时候根据这个key快速缩小数据的范围,但hashcode不一定是唯一的,所以hash算法中定位到具体的链表后,需要循环链表,然后通过equals方法来对比Key是否是一样的。

    equals与hashcode的关系 
    equals相等两个对象,则hashcode一定要相等。但是hashcode相等的两个对象不一定equals相等。 
    https://segmentfault.com/a/1190000004520827

    有没有可能 2 个不相等的对象有相同的 hashcode。

    Java 中的 HashSet 内部是如何工作的。

    底层是基于hashmap实现的 
    http://wiki.jikexueyuan.com/project/java-collection/hashset.html 


    什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。

    序列化:把对象转换为字节序列的过程称为对象的序列化。
    反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

    例如对象在网络中传输, Redis, 消息中间件, 分布式通讯中都是需要用到, 对象必须实现Serializable接口.

     https://blog.csdn.net/u013870094/article/details/82765907


    JVM 知识

    什么情况下会发生栈内存溢出。

    如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 
    参照:http://wiki.jikexueyuan.com/project/java-vm/storage.html

    JVM 的内存结构,Eden 和 Survivor 比例。

    这里写图片描述 
    eden 和 survior 是按8比1分配的 
    http://blog.csdn.net/lojze_ly/article/details/49456255

    jvm 中一次完整的 GC 流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的jvm 参数。

    对象诞生即新生代->eden,在进行minor gc过程中,如果依旧存活,移动到from,变成Survivor,进行标记代数,如此检查一定次数后,晋升为老年代, 
    http://www.cnblogs.com/redcreen/archive/2011/05/04/2037056.html 
    http://ifeve.com/useful-jvm-flags/ 
    https://wangkang007.gitbooks.io/jvm/content/jvmcan_shu_xiang_jie.html

    你知道哪几种垃圾收集器,各自的优缺点,重点讲下 cms,包括原理,流程,优缺点

    Serial、parNew、ParallelScavenge、SerialOld、ParallelOld、CMS、G1 
    https://wangkang007.gitbooks.io/jvm/content/chapter1.html

    垃圾回收算法的实现原理。

    http://www.importnew.com/13493.html

    内存泄漏与内存溢出的区别, 你怎么排错。

    内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。
    内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。

    手动dump

    jmap -dump:format=b,file=heap.hprof PID

    一般在开发中,JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof


    https://wangkang007.gitbooks.io/jvm/content/4jvmdiao_you.html

    一般使用哪些JVM监控工具

    jvisualvm,jconsole,Arthas

    MAT 用于解析dump文件

     

    JVM性能优化步骤

     

    JVM 内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。

    内存屏障:为了保障执行顺序和可见性的一条cpu指令 
    重排序:为了提高性能,编译器和处理器会对执行进行重拍 
    happen-before:操作间执行的顺序关系。有些操作先发生。 
    主内存:共享变量存储的区域即是主内存 
    工作内存:每个线程copy的本地内存,存储了该线程以读/写共享变量的副本 
    http://ifeve.com/java-memory-model-1/ 
    http://www.jianshu.com/p/d3fda02d4cae 
    http://blog.csdn.net/kenzyq/article/details/50918457

    简单说说你了解的类加载器。

    类加载器的分类(bootstrap,ext,app,curstom),类加载的流程(load-link-init) 
    http://blog.csdn.net/gjanyanlig/article/details/6818655/

    讲讲 JAVA 的反射机制。

    Java程序在运行状态可以动态的获取类的所有属性和方法,并实例化该类,调用方法的功能 
    http://baike.baidu.com/link?url=C7p1PeLa3ploAgkfAOK-4XHE8HzQuOAB7K5GPcK_zpbAa_Aw-nO3997K1oir8N–1_wxXZfOThFrEcA0LjVP6wNOwidVTkLBzKlQVK6JvXYvVNhDWV9yF-NIOebtg1hwsnagsjUhOE2wxmiup20RRa#7

    你们线上应用的 JVM 参数有哪些。

    -server 
    Xms6000M 
    -Xmx6000M 
    -Xmn500M 
    -XX:PermSize=500M 
    -XX:MaxPermSize=500M 
    -XX:SurvivorRatio=65536 
    -XX:MaxTenuringThreshold=0 
    -Xnoclassgc 
    -XX:+DisableExplicitGC 
    -XX:+UseParNewGC 
    -XX:+UseConcMarkSweepGC 
    -XX:+UseCMSCompactAtFullCollection 
    -XX:CMSFullGCsBeforeCompaction=0 
    -XX:+CMSClassUnloadingEnabled 
    -XX:-CMSParallelRemarkEnabled 
    -XX:CMSInitiatingOccupancyFraction=90 
    -XX:SoftRefLRUPolicyMSPerMB=0 
    -XX:+PrintClassHistogram 
    -XX:+PrintGCDetails 
    -XX:+PrintGCTimeStamps 
    -XX:+PrintHeapAtGC 
    -Xloggc:log/gc.log

    g1 和 cms 区别,吞吐量优先和响应优先的垃圾收集器选择。

    Cms是以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。比较占用cpu资源,切易造成碎片。 
    G1是面向服务端的垃圾收集器,是jdk9默认的收集器,基于标记-整理算法实现。可利用多核、多cpu,保留分代,实现可预测停顿,可控。 
    http://blog.csdn.net/linhu007/article/details/48897597 
    请解释如下 jvm 参数的含义: 
    -server -Xms512m -Xmx512m -Xss1024K 
    -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=20 
    XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly。

    Server模式启动 
    最小堆内存512m 
    最大512m 
    每个线程栈空间1m 
    永久代256 
    最大永久代256 
    最大转为老年代检查次数20 
    Cms回收开启时机:内存占用80% 
    命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期

     


     

    开源框架知识

     

    简单讲讲 tomcat 结构,以及其类加载器流程。

    http://www.jianshu.com/p/62ec977996df

    tomcat 如何调优,涉及哪些参数。

    硬件上选择,操作系统选择,版本选择,jdk选择,配置jvm参数,配置connector的线程数量,开启gzip压缩,trimSpaces,集群等 
    http://blog.csdn.net/lifetragedy/article/details/7708724

    https://blog.csdn.net/ThinkWon/article/details/102744033

    讲讲 Spring 加载流程。

    通过listener入口,核心是在AbstractApplicationContext的refresh方法,在此处进行装载bean工厂,bean,创建bean实例,拦截器,后置处理器等。 
    https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/

    讲讲 Spring 事务的传播属性。

    七种传播属性。 
    事务传播行为 
    所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量: 
    TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 这个是默认的

    https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/

    Spring 如何管理事务的。

    编程式和声明式 
    同上

    Spring 怎么配置事务(具体说出一些关键的 xml 元素)。

    SpringBoot自动配置, Spring旧版配置事务确认配置的datasource配置即可

    @Transitional事务注解失效的情况

    1. 数据库引擎不支持,mysql需要InnoDB
    2. 方法必须是public的
    3. 方法必须是被其他类调用
    4. @Transitional默认是捕获运行时异常(继承RuntimeException)才回滚,所以如果想要捕获所有异常都回滚,需要在@Transitional后面加上(rollbackFor=Exception.class)
    5. 需要抛出异常,才会回滚,如果你已经自己把异常捕获了,但是没有继续往外抛,那么也是不会回滚的

    说说你对 Spring 的理解,非单例注入的原理?它的生命周期?循环注入的原理, aop 的实现原理,说说 aop 中的几个术语,它们是怎么相互工作的。

    单例注入是通过单例beanFactory进行创建,生命周期是在创建的时候通过接口实现开启,循环注入是通过后置处理器,aop其实就是通过反射进行动态代理,pointcut,advice等。 
    Aop相关:https://blog.csdn.net/weixin_38399962/article/details/79882226

    Spring 如何解决循环依赖的

    三级缓存

    https://blog.csdn.net/qq_36381855/article/details/79752689

    属性注入和构造器注入哪种会有循环依赖的问题?

    同上

    BeanFactory和ApplicationContext有什么区别?

     BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。

     BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

    从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。application context在此基础上还提供了其他的功能。

    提供了支持国际化的文本消息
    统一的资源文件读取方式
    已在监听器中注册的bean的事件

     

    你对Spring核心组件的理解

    核心组件:bean,context,core.

    å¾ 2. ä¸ä¸ªç»ä»¶å³ç³»

    我的理解 :

    我们知道 Bean 包装的是 Object,而 Object 必然有数据,如何给这些数据提供生存环境就是 Context 要解决的问题,对 Context 来说他就是要发现每个 Bean 之间的关系,为它们建立这种关系并且要维护好这种关系。所以 Context 就是一个 Bean 关系的集合,这个关系集合又叫 Ioc 容器,一旦建立起这个 Ioc 容器后 Spring 就可以为你工作了。那 Core 组件又有什么用武之地呢?其实 Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些列的工具,从这个角度看来,Core 这个组件叫 Util 更能让你理解。

     

    简述Bean的生命周期

    Spring容器初始化-> bean构造器-> bean字段注入-> 【init-method】调用<bean>的init-method属性指定的初始化方法

    ->容器初始化成功 ->单例bean的使用->关闭容器->【destroy-method】调用<bean>的destroy-method属性指定的初始化方法

    ->bean死亡

    详见 https://www.cnblogs.com/zrtqsk/p/3735273.html

     

    @AspectJ 的用法, AOP

    https://blog.csdn.net/weixin_38399962/article/details/83894823

     

    Springmvc 中 DispatcherServlet 初始化过程。

    入口是web.xml中配置的ds,ds继承了HttpServletBean,FrameworkServlet,通过其中的init方法进行初始化装载bean和实例,initServletBean是实际完成上下文工作和bean初始化的方法。 
    http://www.mamicode.com/info-detail-512105.html

     

    SpringBoot比Spring做了哪些改进?

    •    独立运行
    •    简化配置
    •    自动配置
    •    无代码生成和 XML 配置
    •    应用监控
    •    上手容易

    简称四简一快

    简化编码, 简化监控, 简化配置, 简化部署, 快速搭建

    详情移步: 为什么说JAVA程序员必须掌握SpringBoot?

     

    你如何理解 Spring Boot 中的 Starters, 其中加载原理? 

    Starters 可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。 
    Starters 包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。 

    https://mp.weixin.qq.com/s/9YDLIcF7J6pQ91o-lipL6w

     

    SpringIOC是什么?DI是什么 优点是什么? 

        控制反转是应用于软件工程领域中的,在运行时被装配器对象来绑定耦合对象的一种编程技巧,对象之间耦合关系在编译时通常是未知的。在传统的编程方式中,业务逻辑的流程是由应用程序中的早已被设定好关联关系的对象来决定的。在使用控制反转的情况下,业务逻辑的流程是由对象关系图来决定的,该对象关系图由装配器负责实例化,这种实现方式还可以将对象之间的关联关系的定义抽象化。而绑定的过程是通过“依赖注入”实现的。

             控制反转是一种以给予应用程序中目标组件更多控制为目的设计范式,并在我们的实际工作中起到了有效的作用。

    依赖注入是在编译阶段尚未知所需的功能是来自哪个的类的情况下,将其他对象所依赖的功能对象实例化的模式。这就需要一种机制用来激活相应的组件以提供特定的功能,所以依赖注入是控制反转的基础。否则如果在组件不受框架控制的情况下,框架又怎么知道要创建哪个组件?

    在Java中依然注入有以下三种实现方式:

    构造器注入
    Setter方法注入
    接口注入


     

    操作系统

    Linux 系统下你关注过哪些内核参数,说说你知道的。

    http://www.haiyun.me/category/system/

    Linux 下 IO 模型有几种,各自的含义是什么。

    阻塞式io,非阻塞io,io复用模型,信号驱动io模型,异步io模型。 
    https://yq.aliyun.com/articles/46404 
    https://yq.aliyun.com/articles/46402

    平时用到哪些 Linux 命令。

    Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等 
    https://yq.aliyun.com/articles/69417?spm=5176.100240.searchblog.18.Zrbh9R

    用一行命令查看文件的最后五行。

    Tail -n 5 filename

    用一行命令输出正在运行的 java 进程。

    ps -ef|grep Java

    介绍下你理解的操作系统中线程切换过程。

    控制权的转换,根据优先级切换上下文(用户,寄存器,系统) 
    http://www.cnblogs.com/kkshaq/p/4544426.html

    进程和线程的区别。

    Linux 实现并没有区分这两个概念(进程和线程) 
    1. 进程:程序的一次执行 
    2. 线程:CPU的基本调度单位 
    一个进程可以包含多个线程。

    http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

     


     

    多线程

    多线程的几种实现方式,什么是线程安全。

    实现runable接口,继承thread类。 
    http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/

    volatile 的原理,作用,能代替锁么。

    Volatile利用内存栅栏机制来保持变量的一致性。不能代替锁,其只具备数据可见性一致性,不具备原子性。 
    http://blog.csdn.net/gongzi2311/article/details/20715185

    画一个线程的生命周期状态图。

    新建,可运行,运行中, 睡眠,阻塞,等待,死亡。 
    这里写图片描述 
    http://ifeve.com/thread-status

    sleep 和 wait 的区别。

    Sleep是休眠线程,wait是等待,sleep是thread的静态方法,wait则是object的方法。 
    Sleep依旧持有锁,并在指定时间自动唤醒。wait则释放锁。 
    http://www.jianshu.com/p/4ec3f4b3903d

    Lock 与 Synchronized 的区别。

    首先两者都保持了并发场景下的原子性和可见性,区别则是synchronized的释放锁机制是交由其自身控制,且互斥性在某些场景下不符合逻辑,无法进行干预,不可人为中断等。 
    而lock常用的则有ReentrantLock和readwritelock两者,添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。 
    http://blog.csdn.net/vking_wang/article/details/9952063

    synchronized 的原理是什么,解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁。

    Synchronized底层是通过监视器的enter和exit实现 
    https://my.oschina.net/cnarthurs/blog/847801 
    http://blog.csdn.net/a314773862/article/details/54095819

    用过哪些原子类,他们的原理是什么。

    AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基于CAS原语实现 ,比较并交换、加载链接/条件存储,最坏的情况下是旋转锁 
    https://www.ibm.com/developerworks/cn/java/j-jtp11234/index.html 
    http://www.jmatrix.org/java/848.html

    用过线程池吗,newCache 和 newFixed 有什么区别,他们的原理简单概括下,构造函数的各个参数的含义是什么,比如 coreSize,maxsize 等。

    newSingleThreadExecutor返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。

      newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。

    newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。 
    底层是基于ThreadPoolExecutor实现,借助reentrantlock保证并发。 
    coreSize核心线程数,maxsize最大线程数。 
    http://ifeve.com/java-threadpoolexecutor/

    线程池的关闭方式有几种,各自的区别是什么。

    Shutdown shutdownNow tryTerminate 清空工作队列,终止线程池中各个线程,销毁线程池 
    http://blog.csdn.net/xxcupid/article/details/51993235

    假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有 10 个线程同时调用它,如何做到。

    ScheduledThreadPoolExecutor 设置定时,进行调度。 
    public ScheduledThreadPoolExecutor(int corePoolSize, 
    ThreadFactory threadFactory) { 
    super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, 
    new DelayedWorkQueue(), threadFactory); 
    }

    http://ifeve.com/java-scheduledthreadpoolexecutor/

    spring 的 controller 是单例还是多例,怎么保证并发的安全。

    单例 
    通过单例工厂 DefaultSingletonBeanRegistry实现单例 
    通过保AsyncTaskExecutor持安全

    面试问我,创建多少个线程合适?

    其实多线程使用,所需线程数和实际场景息息相关,如果是 CPU 密集型(例如:1-1000 万累加计算)则是 CUP核心数+1,如果是IO 密集型(数据库访问,远程调用)则是:最佳线程数 = (1/CPU利用率) = 1 + (I/O耗时/CPU耗时)

    https://www.jianshu.com/p/f30ee2346f9f

    ThreadLocal 用过么,用途是什么,原理是什么,用的时候要注意什么。

    Threadlocal底层是通过threadlocalMap进行存储键值 每个ThreadLocal类创建一个Map,然后用线程的ID作为Map的key,实例对象作为Map的value,这样就能达到各个线程的值隔离的效果。 
    ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。 
    谁设置谁负责移除 
    http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/

    如果让你实现一个并发安全的链表,你会怎么做。

    Collections.synchronizedList() ConcurrentLinkedQueue 
    http://blog.csdn.net/xingjiarong/article/details/48046751

    有哪些无锁数据结构,他们实现的原理是什么。

    LockFree,CAS 
    基于jdk提供的原子类原语实现,例如AtomicReference 
    http://blog.csdn.net/b_h_l/article/details/8704480

    讲讲 java 同步机制的 wait 和 notify。

    首先这两个方法只能在同步代码块中调用,wait会释放掉对象锁,等待notify唤醒。 
    http://blog.csdn.net/ithomer/article/details/7685594

    多线程如果线程挂住了怎么办。

    根据具体情况(sleep,wait,join等),酌情选择notifyAll,notify进行线程唤醒。 
    http://blog.chinaunix.net/uid-122937-id-215913.html

    countdowlatch 和 cyclicbarrier 的内部原理和用法,以及相互之间的差别。

    CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它运行一个或者多个线程一直处于等待状态。 
    CyclicBarrier要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。 
    CyclicBarrier初始化的时候,设置一个屏障数。线程调用await()方法的时候,这个线程就会被阻塞,当调用await()的线程数量到达屏障数的时候,主线程就会取消所有被阻塞线程的状态。 
    前者是递减,不可循环,后者是递加,可循环用 
    countdowlatch 基于abq cb基于ReentrantLock Condition 
    http://www.jianshu.com/p/a101ae9797e3 
    http://blog.csdn.net/tolcf/article/details/50925145

    使用 synchronized 修饰静态方法和非静态方法有什么区别。

    对象锁和类锁 
    https://yq.aliyun.com/articles/24226

    简述 ConcurrentLinkedQueue LinkedBlockingQueue 的用处和不同之处。

    LinkedBlockingQueue 是一个基于单向链表的、范围任意的(其实是有界的)、FIFO 阻塞队列。 
    ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。它采用了“wait-free”算法来实现,该算法在Michael & Scott算法上进行了一些修改, Michael & Scott算法的详细信息可以参见参考资料一。 
    http://ifeve.com/concurrentlinkedqueue/ 
    http://ifeve.com/juc-linkedblockingqueue/ 
    http://blog.csdn.net/xiaohulunb/article/details/38932923

    导致线程死锁的原因?怎么解除线程死锁。

    死锁问题是多线程特有的问题,它可以被认为是线程间切换消耗系统性能的一种极端情况。在死锁时,线程间相互等待资源,而又不释放自身的资源,导致无穷无尽的等待,其结果是系统任务永远无法执行完成。死锁问题是在多线程开发中应该坚决避免和杜绝的问题。 
    一般来说,要出现死锁问题需要满足以下条件: 
    1. 互斥条件:一个资源每次只能被一个线程使用。 
    2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
    3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。 
    4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 
    只要破坏死锁 4 个必要条件之一中的任何一个,死锁问题就能被解决。 
    https://www.ibm.com/developerworks/cn/java/j-lo-deadlock/

    非常多个线程(可能是不同机器),相互之间需要等待协调,才能完成某种工作,问怎么设计这种协调方案。

    此问题的本质是保持顺序执行。可以使用executors

     


     

    TCP 与 HTTP

     

    TCP与UDP的区别

    • TCP 是面向连接的,UDP 是面向无连接的
    • UDP程序结构较简单
    • TCP 是面向字节流的,UDP 是基于数据报的
    • TCP 保证数据正确性,UDP 可能丢包
    • TCP 保证数据顺序,UDP 不保证

    TCP与HTTP协议的关系

    关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:“我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP 文本信息,然后使用TCP/IP做传输层协议将它发到网络上。”

     

    http1.0 和 http1.1 有什么区别。

    HTTP 1.0主要有以下几点变化: 
    请求和相应可以由于多行首部字段构成 
    响应对象前面添加了一个响应状态行 
    响应对象不局限于超文本 
    服务器与客户端之间的连接在每次请求之后都会关闭 
    实现了Expires等传输内容的缓存控制 
    内容编码Accept-Encoding、字符集Accept-Charset等协商内容的支持 
    这时候开始有了请求及返回首部的概念,开始传输不限于文本(其他二进制内容)

    HTTP 1.1加入了很多重要的性能优化:持久连接、分块编码传输、字节范围请求、增强的缓存机制、传输编码及请求管道。 
    http://imweb.io/topic/554c5879718ba1240cc1dd8a

    请画出三次握手和四次挥手的示意图
    为什么连接的时候是三次握手?
    什么是半连接队列?
    ISN(Initial Sequence Number)是固定的吗?
    三次握手过程中可以携带数据吗?
    如果第三次握手丢失了,客户端服务端会如何处理?
    SYN攻击是什么?
    挥手为什么需要四次?
    四次挥手释放连接时,等待2MSL的意义?


    https://blog.csdn.net/hyg0811/article/details/102366854

     

     

    TIME_WAIT 和 CLOSE_WAIT 的区别。

    TIME_WAIT状态就是用来重发可能丢失的ACK报文。 
    TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

    说说你知道的几种 HTTP 响应码,比如 200, 302, 404。

    1xx:信息,请求收到,继续处理 
    2xx:成功,行为被成功地接受、理解和采纳 
    3xx:重定向,为了完成请求,必须进一步执行的动作 
    4xx:客户端错误,请求包含语法错误或者请求无法实现 
    5xx:服务器错误,服务器不能实现一种明显无效的请求 
    200 ok 一切正常 
    302 Moved Temporatily 文件临时移出 
    404 not found 
    https://my.oschina.net/gavinjin/blog/42856

    当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。

    Dns解析–>端口分析–>tcp请求–>服务器处理请求–>服务器响应–>浏览器解析—>链接关闭

    TCP/IP 如何保证可靠性,说说 TCP 头的结构。

    使用序号,对收到的TCP报文段进行排序以及检测重复的数据;使用校验和来检测报文段的错误;使用确认和计时器来检测和纠正丢包或延时。//TCP头部,总长度20字节 
    typedef struct _tcp_hdr 

    unsigned short src_port; //源端口号 
    unsigned short dst_port; //目的端口号 
    unsigned int seq_no; //序列号 
    unsigned int ack_no; //确认号 
    #if LITTLE_ENDIAN 
    unsigned char reserved_1:4; //保留6位中的4位首部长度 
    unsigned char thl:4; //tcp头部长度 
    unsigned char flag:6; //6位标志 
    unsigned char reseverd_2:2; //保留6位中的2位 
    #else 
    unsigned char thl:4; //tcp头部长度 
    unsigned char reserved_1:4; //保留6位中的4位首部长度 
    unsigned char reseverd_2:2; //保留6位中的2位 
    unsigned char flag:6; //6位标志 
    #endif 
    unsigned short wnd_size; //16位窗口大小 
    unsigned short chk_sum; //16位TCP检验和 
    unsigned short urgt_p; //16为紧急指针 
    }tcp_hdr;

    https://zh.bywiki.com/zh-hans/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

    如何避免浏览器缓存。

    无法被浏览器缓存的请求: 
    HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求 
    需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的 
    经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》) 
    POST请求无法被缓存 
    HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存 
    http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/

    简述 Http 请求 get 和 post 的区别以及数据包格式。

    这里写图片描述

    这里写图片描述 
    http://www.w3school.com.cn/tags/html_ref_httpmethods.asp 
    http://www.360doc.com/content/12/0612/14/8093902_217673378.shtml

    简述 HTTP 请求的报文格式。

    参考上面

    HTTPS 的加密方式是什么,讲讲整个加密解密流程。

    加密方式是tls/ssl,底层是通过对称算法,非对称,hash算法实现 
    客户端发起HTTPS请求 –》2. 服务端的配置 –》 
    3. 传送证书 —》4. 客户端解析证书 5. 传送加密信息 6. 服务段解密信息 7. 传输加密后的信息 8. 客户端解密信息 
    http://www.cnblogs.com/zhuqil/archive/2012/07/23/2604572.html

     


     

     

    数据库知识

    数据库隔离级别有哪些,各自的含义是什么,不同的隔离界别会加什么锁, MYSQL 默认的隔离级别是是什么。

    ·未提交读(Read Uncommitted):允许脏读,写事务时加行级共享锁,读事务不加锁, 也就是可能读取到其他会话中未提交事务修改的数据 , 

    ·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读),写事务时加行级排他锁,事务结束才释放;读事务加行级共享锁,但是读完立即释放锁,而不是事务结束释放,因此造成的问题是不可重复读(读事务第一次读取数据结束后释放共享锁,此时其他事务可以更新数据,该事务第二次读取数据时发现与第一次数据值不同)

    ·可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读, 读事务和写事务加的锁都持续到事务结束才释放, 仍然存在的问题是幻读(读或写事务只是对其所读的行加了行级锁,此时其他事务虽然不能更改这些行,但是能添加新行,因此出现幻读现象)。

    ·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

    MYSQL默认是RepeatedRead级别

    MYSQL 有哪些存储引擎,各自优缺点。

    MyISAM: 拥有较高的插入,查询速度,但不支持事务 
    InnoDB :5.5版本后Mysql的默认数据库,事务型数据库的首选引擎,支持ACID事务,支持行级锁定 
    BDB: 源自Berkeley DB,事务型数据库的另一种选择,支持COMMIT和ROLLBACK等其他事务特性 
    Memory :所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在Mysql重新启动时丢失 
    Merge :将一定数量的MyISAM表联合而成一个整体,在超大规模数据存储时很有用 
    Archive :非常适合存储大量的独立的,作为历史记录的数据。因为它们不经常被读取。Archive拥有高效的插入速度,但其对查询的支持相对较差 
    Federated: 将不同的Mysql服务器联合起来,逻辑上组成一个完整的数据库。非常适合分布式应用 
    Cluster/NDB :高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性。适合数据量大,安全和性能要求高的应用 
    CSV: 逻辑上由逗号分割数据的存储引擎。它会在数据库子目录里为每个数据表创建一个.CSV文件。这是一种普通文本文件,每个数据行占用一个文本行。CSV存储引擎不支持索引。 
    BlackHole :黑洞引擎,写入的任何数据都会消失,一般用于记录binlog做复制的中继 
    另外,Mysql的存储引擎接口定义良好。有兴趣的开发者通过阅读文档编写自己的存储引擎。 
    http://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E

    高并发下,如何做到安全的修改同一行数据。

    使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。 
    也可以缓存队列中锁定主键。

    乐观锁和悲观锁是什么,INNODB 的行级锁有哪 2 种,解释其含义。

    乐观锁是设定每次修改都不会冲突,只在提交的时候去检查,悲观锁设定每次修改都会冲突,持有排他锁。 
    行级锁分为共享锁和排他锁两种 共享锁又称读锁 排他锁又称写锁 
    http://www.jianshu.com/p/f40ec03fd0e8

    SQL 优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义。

    查看慢日志(show [session|gobal] status ),定位慢查询,查看慢查询执行计划 根据执行计划确认优化方案 
    Explain sql 
    select_type:表示select类型。常见的取值有SIMPLE(简单表,即不使用连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(union中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等。 
    talbe:输出结果集的表。 
    type:表的连接类型。性能由高到底:system(表中仅有一行)、const(表中最多有一个匹配行)、eq_ref、ref、ref_null、index_merge、unique_subquery、index_subquery、range、idnex等 
    possible_keys:查询时,可能使用的索引 
    key:实际使用的索引 
    key_len:索引字段的长度 
    rows:扫描行的数量 
    Extra:执行情况的说明和描述 
    http://blog.csdn.net/hsd2012/article/details/51106285

    数据库会死锁吗,举一个死锁的例子,mysql 怎么解决死锁。

    产生死锁的原因主要是:

    (1)系统资源不足。 
    (2) 进程运行推进的顺序不合适。 
    (3)资源分配不当等。

    如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

    产生死锁的四个必要条件:

    (1) 互斥条件:一个资源每次只能被一个进程使用。 
    (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
    (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 
    (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。 
    这里提供两个解决数据库死锁的方法:

    1)重启数据库(谁用谁知道) 
    2)杀掉抢资源的进程: 
    先查哪些进程在抢资源:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; 
    杀掉它们:Kill trx_mysql_thread_id;

    MySQL的索引原理,索引的类型有哪些,如何创建合理的索引,索引如何优化。

    索引是通过复杂的算法,提高数据查询性能的手段。从磁盘io到内存io的转变 
    普通索引,主键,唯一,单列/多列索引建索引的几大原则 
    1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。 
    2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式 
    3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录 
    4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’); 
    5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

    http://tech.meituan.com/mysql-index.html 
    http://www.cnblogs.com/cq-home/p/3482101.html

    聚集索引和非聚集索引的区别。

    “聚簇”就是索引和记录紧密在一起。 
    非聚簇索引 索引文件和数据文件分开存放,索引文件的叶子页只保存了主键值,要定位记录还要去查找相应的数据块。

    一张表只能拥有一个聚簇索引

    MySQL 中覆盖索引和回表是什么?

    https://blog.csdn.net/weixin_38399962/article/details/105909721

    索引B+树的叶子节点都可以存哪些东西?

    索引值和主键值,顺序访问指针

    数据库中 BTREE 和 B+tree 区别。

    B+是btree的变种,本质都是btree,btree+与B-Tree相比,B+Tree有以下不同点: 

    • 每个节点的指针上限为2d而不是2d+1。 
    • 内节点不存储data,只存储key;
    • 叶子节点存储指向指针。
    • 只有叶子节点报错数据。

    所以B+树查询时间复杂度固定是logn,B-树查询复杂度最好是 O(1)。但是 B+树支持区间查询。

    http://lcbk.net/9602.html 
    Btree 怎么分裂的,什么时候分裂,为什么是平衡的。 
    Key 超过1024才分裂B树为甚会分裂? 因为随着数据的增多,一个结点的key满了,为了保持B树的特性,就会产生分裂,就向红黑树和AVL树为了保持树的性质需要进行旋转一样!

    ACID 是什么。

    A,atomic,原子性,要么都提交,要么都失败,不能一部分成功,一部分失败。 
    C,consistent,一致性,事物开始及结束后,数据的一致性约束没有被破坏 
    I,isolation,隔离性,并发事物间相互不影响,互不干扰。 
    D,durability,持久性,已经提交的事物对数据库所做的更新必须永久保存。即便发生崩溃,也不能被回滚或数据丢失。

    Mysql 怎么优化 table scan 的。

    避免在where子句中对字段进行is null判断 
    应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 
    避免在where 子句中使用or 来连接条件 
    in 和not in 也要慎用 
    Like查询(非左开头) 
    使用NUM=@num参数这种 
    where 子句中对字段进行表达式操作num/2=XX 
    在where子句中对字段进行函数操作

    如何写 sql 能够有效的使用到复合索引,谈谈mysql索引最左匹配原则的理解

    由于复合索引的组合索引,类似多个木板拼接在一起,如果中间断了就无法用了,所以要能用到复合索引,首先开头(第一列)要用上,比如index(a,b) 这种,我们可以select table tname where a=XX 用到第一列索引 如果想用第二列 可以 and b=XX 或者and b like‘TTT%’,

    最左匹配原则:最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。https://blog.csdn.net/sinat_41917109/article/details/88944290

    mysql 中 in 和 exists 区别。

    mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。

    如果查询的两个表大小相当,那么用in和exists差别不大。 
    如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in: 
    not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。 
    1.EXISTS只返回TRUE或FALSE,不会返回UNKNOWN。

    2.IN当遇到包含NULL的情况,那么就会返回UNKNOWN。

    数据库自增主键可能的问题。

    在分库分表时可能会生成重复主键 利用自增比例达到唯一 自增1 2,3 等 
    https://yq.aliyun.com/articles/38438

    为什么mysql用B+树做索引而不用B-树或红黑树

    1. B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少, 这样查询速度就很快

    2. B+树所有的Data域在叶子节点,并且所有叶子节点之间都有一个链指针。 这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的遍历操作。


     

    消息队列

    用过哪些 MQ,和其他 mq 比较有什么优缺点,MQ 的连接是线程安全的吗,你们公司的MQ 服务架构怎样的。

    根据实际情况说明 
    我们公司用activeMQ 因为业务比较简单 只有转码功能,而amq比较简单 
    如果是分布式的建议用kafka 
    http://blog.csdn.net/sunxinhere/article/details/7968886

    MQ 系统的数据如何保证不丢失。

    基本都是对数据进行持久化,多盘存储

    rabbitmq 如何实现集群高可用。

    集群是保证服务可靠性的一种方式,同时可以通过水平扩展以提升消息吞吐能力。RabbitMQ是用分布式程序设计语言erlang开发的,所以天生就支持集群。接下来,将介绍RabbitMQ分布式消息处理方式、集群模式、节点类型,并动手搭建一个高可用集群环境,最后通过java程序来验证集群的高可用性。

      1. 三种分布式消息处理方式

      RabbitMQ分布式的消息处理方式有以下三种:

      1、Clustering:不支持跨网段,各节点需运行同版本的Erlang和RabbitMQ, 应用于同网段局域网。

      2、Federation:允许单台服务器上的Exchange或Queue接收发布到另一台服务器上Exchange或Queue的消息, 应用于广域网,。

      3、Shovel:与Federation类似,但工作在更低层次。

      RabbitMQ对网络延迟很敏感,在LAN环境建议使用clustering方式;在WAN环境中,则使用Federation或Shovel。我们平时说的RabbitMQ集群,说的就是clustering方式,它是RabbitMQ内嵌的一种消息处理方式,而Federation或Shovel则是以plugin形式存在。 
    https://my.oschina.net/jiaoyanli/blog/822011 
    https://www.ibm.com/developerworks/cn/opensource/os-cn-RabbitMQ/

    Kafka中是怎么体现消息顺序性的?

    kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的。
    整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1.

    Kafka 如何支撑数十万并发的写入

    页缓存技术 + 磁盘顺序写    搭建集群

    https://blog.csdn.net/qq_32649581/article/details/101675334

     

    Kafka中的消息是否会丢失和重复消费?

    要确定Kafka的消息是否丢失或重复,从两个方面分析入手:消息发送和消息消费。

    消息发送: acks 改为 -1 , 表示Leader和Follower都接收成功时确认;

    重复消费: 在数据库中添加记录表,每次消费时判断是否处理过即可。

     

    Kafka中zookeeper起到什么作用?

    zookeeper 是一个分布式的协调组件,早期版本的kafka用zk做meta信息存储,consumer的消费状态,group的管理以及 offset的值。考虑到zk本身的一些因素以及整个架构较大概率存在单点问题,新版本中逐渐弱化了zookeeper的作用。新的consumer使用了kafka内部的group coordination协议,也减少了对zookeeper的依赖,

    但是broker依然依赖于ZK,zookeeper 在kafka中还用来选举controller 和 检测broker是否存活等等。
     

    https://blog.csdn.net/qq_28900249/article/details/90346599


    缓存

    Redis性能为什么高?

    单线程, 内存操作

    Redis 的应用场景

    1. 缓存

    2.最新列表 list

    3.排行榜 zset

    4.分布式 id 生成 RedisAtomicLong

    5.分布式锁 setNx

    6.计数器

    7.延时队列

    Redis 的数据结构都有哪些。

    字符串(strings):存储整数(比如计数器)和字符串(废话。。),有些公司也用来存储json/pb等序列化数据,并不推荐,浪费内存 
    哈希表(hashes):存储配置,对象(比如用户、商品),优点是可以存取部分key,对于经常变化的或者部分key要求atom操作的适合 
    列表(lists):可以用来存最新用户动态,时间轴,优点是有序,确定是元素可重复,不去重 
    集合(sets):无序,唯一,对于要求严格唯一性的可以使用 
    有序集合(sorted sets):集合的有序版,很好用,对于排名之类的复杂场景可以考虑https://redis.readthedocs.io/en/2.4/list.html

    Redis 的使用要注意什么,讲讲内存设置,集群的应用和优劣势,淘汰策略等。


    内存设置 maxmemory used_memory 
    虚拟内存: vm-enabled yes 
    3.0采用Cluster方式, 
    Redis集群相对单机在功能上存在一些限制, 需要开发人员提前了解, 
    在使用时做好规避。 限制如下: 
    1) key批量操作支持有限。 如mset、 mget, 目前只支持具有相同slot值的 
    ke 
    y执 
    行批量操作。 对于映射为不同slot值的key由于执行mget、 mget等操作可 
    能存在于多个节点上因此不被支持。 
    2) key事务操作支持有限。 同理只支持多key在同一节点上的事务操 
    作, 当多个key分布在不同的节点上时无法使用事务功能。 
    3) key作为数据分区的最小粒度, 因此不能将一个大的键值对象如 
    ha 
    sh、 list等映射到不同的节点。 
    4) 不支持多数据库空间。 单机下的Redis可以支持16个数据库, 集群模 
    式下只能使用一个数据库空间, 即db0。 
    5) 复制结构只支持一层, 从节点只能复制主节点, 不支持嵌套树状复 
    制结构。 
    Redis Cluster是Redis的分布式解决方案, 在3.0版本正式推出, 有效地解 
    决了Redis分布式方面的需求。 当遇到单机内存、 并发、 流量等瓶颈时, 可 
    以采用Cluster架构方案达到负载均衡的目的。 之前, Redis分布式方案一般 
    有两种: 
    ·客户端分区方案, 优点是分区逻辑可控, 缺点是需要自己处理数据路 
    由、 高可用、 故障转移等问题。 
    ·代理方案, 优点是简化客户端分布式逻辑和升级维护便利, 缺点是加 
    重架构部署复杂度和性能损耗。 
    现在官方为我们提供了专有的集群方案: Redis Cluster, 它非常优雅地 
    解决了Redis集群方面的问题, 因此理解应用好Redis Cluster将极大地解放我 
    们使用分布式Redis的工作量, 同时它也是学习分布式存储的绝佳案例。

    LRU(近期最少使用算法)TTL(超时算法) 去除ttl最大的键值 
    http://wiki.jikexueyuan.com/project/redis/data-elimination-mechanism.html 
    http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage 
    http://www.redis.cn/topics/cluster-tutorial.html

    当前 Redis集群有哪些玩法,各自优缺点,场景。

    当缓存使用 持久化使用

    Redis 中的 db 用什么用?

    redis 单例的情况下 db 是用作区分不同维度的,可以在 conf 中设置。

    redis 集群情况下 db 默认为 0;

    Redis 的并发竞争问题如何解决,了解 Redis 事务的 CAS 操作吗。

    Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

    1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

    2.服务器角度,利用setnx实现锁。

    MULTI,EXEC,DISCARD,WATCH 四个命令是 Redis 事务的四个基础命令。其中:

    MULTI,告诉 Redis 服务器开启一个事务。注意,只是开启,而不是执行 
    EXEC,告诉 Redis 开始执行事务 
    DISCARD,告诉 Redis 取消事务 
    WATCH,监视某一个键值对,它的作用是在事务执行之前如果监视的键值被修改,事务会被取消。 
    可以利用watch实现cas乐观锁 
    http://wiki.jikexueyuan.com/project/redis/transaction-mechanism.html 
    http://www.jianshu.com/p/d777eb9f27df

    redis 的持久化的机制,aof 和 rdb 的区别。

    RDB 定时快照方式(snapshot): 定时备份,可能会丢失数据 
    AOF 基于语句追加方式 只追加写操作 
    AOF 持久化和 RDB 持久化的最主要区别在于,前者记录了数据的变更,而后者是保存了数据本身

    5.0 版本后,可以使用 aof+rdb 的混合存储方式

    redis 的集群怎么同步的数据的。

    redis replication redis-migrate-tool等方式

    https://blog.csdn.net/hxpjava1/article/details/78347890/

    redis 分布式锁的实现

    采用了 setNx,但是要考虑死锁以及锁的安全性

    https://blog.csdn.net/weixin_38399962/article/details/82753763

    解释下缓存雪崩,缓存击穿,缓存穿透,并如何防止出现上述情况

    缓存雪崩: 定时刷新缓存,会导致某一时间,请求qps全部打到数据导致,数据库压力过大甚至奔溃

    处理方案: 热点数据缓存过期时间加上随机数

    缓存穿透:指的是用户恶意发起缓存中和数据库中都没有的数据,这样请求会不断攻击数据库,严重击垮数据库

    处理方案:校验参数,做请求过滤(布隆过滤器),和自定义拦截

    缓存击穿:是指一个key非常热点,不停的扛着高并发,当这个key突然过期,直接击穿了缓存层,打到数据库了。其实和缓存雪崩有点像,但是又是两个概念

    处理方案:缓存永不过期, 或者互斥锁。

    同学们:其实这三者都差不多,但是面试时候一定要注意其中的细节点。

    详细见我的博文Redis:

    https://blog.csdn.net/weixin_38399962/article/details/103062908


    搜索

    elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据大小,分片有多少,以及一些调优手段。elasticsearch 的倒排索引是什么。

    ElasticSearch(简称ES)是一个分布式、Restful的搜索及分析服务器,设计用于分布式计算;能够达到实时搜索,稳定,可靠,快速。和Apache Solr一样,它也是基于Lucence的索引服务器,而ElasticSearch对比Solr的优点在于:

    轻量级:安装启动方便,下载文件之后一条命令就可以启动。
    Schema free:可以向服务器提交任意结构的JSON对象,Solr中使用schema.xml指定了索引结构。
    多索引文件支持:使用不同的index参数就能创建另一个索引文件,Solr中需要另行配置。
    分布式:Solr Cloud的配置比较复杂。
    

    倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。

    elasticsearch 索引数据多了怎么办,如何调优,部署。

    使用bulk API 
    初次索引的时候,把 replica 设置为 0 
    增大 threadpool.index.queue_size 
    增大 indices.memory.index_buffer_size 
    增大 index.translog.flush_threshold_ops 
    增大 index.translog.sync_interval 
    增大 index.engine.robin.refresh_interval 
    http://www.jianshu.com/p/5eeeeb4375d4

    一线互联网大厂 Elasticsearch 搜索工程师面试题

    1、Elasticsearch 的索引机制

    2、为什么用倒排索引

    3、为什么倒排索引会快

    4、Elasticsearch 做过什么优化吗

    5、Elasticsearch 的分片设置,写入流程,查询过程

    6、说说 Elasticsearch 有什么优化策略吧,怎样能搜的更快?

    7、如何确保搜出来的是用户想要的?

    8、如何保证你的数据能够在es召回率高?

    9、算法:给你一段视频如何找到全文最精彩的部分。

    10、其他:如何提高ctr(用户点击率)?


     

    算法

    10 亿个数字里里面找最小的 10 个。

    有 1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优。

    2 亿个随机生成的无序整数,找出中间大小的值。

    给一个不知道长度的(可能很大)输入字符串,设计一种方案,将重复的字符排重。

    遍历二叉树。

    有 3n+1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。

    写一个字符串反转函数。

    常用的排序算法,快排,归并、冒泡。 快排的最优时间复杂度,最差复杂度。冒泡排序的优化方案。

    二分查找的时间复杂度,优势。

    一个已经构建好的 TreeSet,怎么完成倒排序。

    什么是 B+树,B-树,列出实际的使用场景。

     


    架构设计与分布式

    常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的。

    Cdn缓存,redis缓存,ehcache缓存等 
    Cdn 图片资源 js等, redis集群 echcache缓存数据

    用 java 自己实现一个 LRU。

    final int cacheSize = 100; 
    Map

    分布式集群下如何做到唯一序列号。

    Redis生成,mongodb的objectId,zk生成 ,雪花算法
    http://www.cnblogs.com/haoxinyue/p/5208136.html

    redis生成每日递增唯一的分布式Id

    https://rourou.blog.csdn.net/article/details/104555529

    设计一个秒杀系统,30 分钟没付款就自动关闭交易。

    分流 – 限流–异步–公平性(只能参加一次)–用户体验(第几位,多少分钟,一抢完) 
    容错处理 
    Redis 消息队列 mysql

    30分钟关闭 可以借助redis的ZSet,

    https://rourou.blog.csdn.net/article/details/101511408

    或者 rocketMq 的延时队列

    如何使用 redis 和 zookeeper 实现分布式锁?有什么区别优缺点,分别适用什么场景。

    首先分布式锁实现常见的有数据库锁(表记录),缓存锁,基于zk(临时有序节点可以实现的)的三种

    Redis适用于对性能要求特别高的场景。redis可以每秒执行10w次,内网延迟不超过1ms 
    缺点是数据存放于内存,宕机后锁丢失。

    锁无法释放?使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。

    非阻塞锁?使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。

    不可重入?使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。

    单点问题?使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。

    http://www.hollischuang.com/archives/1716

    如果有人恶意创建非法连接,怎么解决。

    可以使用filter过滤处理

    分布式事务的原理,优缺点,如何使用分布式事务。

    Two Phase commit协议 (二段提交)
    优点是可以管理多机事务,拥有无线扩展性 确定是易用性难,承担延时风险 
    JTA,atomiks等 
    https://yq.aliyun.com/webinar/join/185?spm=5176.8067841.0.0.RL4GDa

    CAP,BASE理论,柔性事务 tcc

    什么是一致性 hash。

    一致性hash是一种分布式hash实现算法。满足平衡性 单调性 分散性 和负载。 
    http://blog.csdn.net/cywosp/article/details/23397179/

    什么是 restful,讲讲你理解的 restful。

    REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。 
    http://baike.baidu.com/link?url=fTSAdL-EyYvTp9z7mZsCOdS3kbs4VKKAnpBLg3WS_1Z4cmLMp3S-zrjcy5wakLTO5AIoPTopWVkG-IenloPKxq

    如何设计建立和保持 100w 的长连接。

    服务器内核调优(tcp,文件数),客户端调优,框架选择(netty)

     

    解释什么是 MESI 协议(缓存一致性)。

    MESI是四种缓存段状态的首字母缩写,任何多核系统中的缓存段都处于这四种状态之一。我将以相反的顺序逐个讲解,因为这个顺序更合理:

    失效(Invalid)缓存段,要么已经不在缓存中,要么它的内容已经过时。为了达到缓存的目的,这种状态的段将会被忽略。一旦缓存段被标记为失效,那效果就等同于它从来没被加载到缓存中。 
    共享(Shared)缓存段,它是和主内存内容保持一致的一份拷贝,在这种状态下的缓存段只能被读取,不能被写入。多组缓存可以同时拥有针对同一内存地址的共享缓存段,这就是名称的由来。 
    独占(Exclusive)缓存段,和S状态一样,也是和主内存内容保持一致的一份拷贝。区别在于,如果一个处理器持有了某个E状态的缓存段,那其他处理器就不能同时持有它,所以叫“独占”。这意味着,如果其他处理器原本也持有同一缓存段,那么它会马上变成“失效”状态。 
    已修改(Modified)缓存段,属于脏段,它们已经被所属的处理器修改了。如果一个段处于已修改状态,那么它在其他处理器缓存中的拷贝马上会变成失效状态,这个规律和E状态一样。此外,已修改缓存段如果被丢弃或标记为失效,那么先要把它的内容回写到内存中——这和回写模式下常规的脏段处理方式一样。

    说说你知道的几种 HASH 算法,简单的也可以。

    哈希(Hash)算法,即散列函数。 它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。 同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出 
    MD4 MD5 SHA 
    http://blog.jobbole.com/106733/

    什么是 paxos 算法。

    Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的”La”,此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法。

    http://baike.baidu.com/item/Paxos%20%E7%AE%97%E6%B3%95

    什么是 zab 协议。

    ZAB 是 Zookeeper 原子广播协议的简称

    整个ZAB协议主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段,分别是:

    发现 Discovery 
    同步 Synchronization 
    广播 Broadcast 
    组成ZAB协议的每一个分布式进程,都会循环执行这三个阶段,将这样一个循环称为一个主进程周期。 
    https://zzzvvvxxxd.github.io/2016/08/09/ZAB/

    一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新。

    点击编辑的时候,利用redis进行加锁setNX完了之后 expire 一下 
    也可以用版本号进行控制

    线上系统突然变得异常缓慢,你如何查找问题。

    逐级排查(网络,磁盘,内存,cpu),数据库,日志,中间件等也可通过监控工具排查。

    说说你平时用到的设计模式。

    单例, 代理,模板,策略,命令 
    http://www.jianshu.com/p/bdf65e4afbb0

    Dubbo 的原理,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现。重试转发,快速失败的策略是怎样的。

    Dubbo[]是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

    Cluster 实现集群

    在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。 
    Random LoadBalance:随机,按权重比率设置随机概率。 
    RoundRobin LoadBalance:轮循,按公约后的权重比率设置轮循比率。 
    LeastActive LoadBalance:最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。 
    ConsistentHash LoadBalance:一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。 
    快速失败,只发起一次调用,失败立即报错。

    https://my.oschina.net/u/1378920/blog/693374

    一次 RPC 请求的流程是什么。

    1)服务消费方(client)调用以本地调用方式调用服务; 
    2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体; 
    3)client stub找到服务地址,并将消息发送到服务端; 
    4)server stub收到消息后进行解码; 
    5)server stub根据解码结果调用本地的服务; 
    6)本地服务执行并将结果返回给server stub; 
    7)server stub将返回结果打包成消息并发送至消费方; 
    8)client stub接收到消息,并进行解码; 
    9)服务消费方得到最终结果。

    异步模式的用途和意义。

    异步模式使用与服务器多核,并发严重的场景 
    可提高服务吞吐量大,不容易受到冲击,可以采用并发策略,提高响应时间 
    缓存数据过期后的更新如何设计。 
    失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。 
    命中:应用程序从cache中取数据,取到后返回。 
    更新:先把数据存到数据库中,成功后,再让缓存失效。

    编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用。

    开闭原则(Open Close Principle) 
    一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。 
    里氏代换原则(Liskov Substitution Principle) 
    子类型必须能够替换掉它们的父类型。 
    依赖倒转原则(Dependence Inversion Principle) 
    高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。即针对接口编程,不要针对实现编程 
    接口隔离原则(Interface Segregation Principle) 
    建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少 
    组合/聚合复用原则 
    说要尽量的使用合成和聚合,而不是继承关系达到复用的目的 
    迪米特法则(Law Of Demeter) 
    迪米特法则其根本思想,是强调了类之间的松耦合,类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成影响,也就是说,信息的隐藏促进了软件的复用。 
    单一职责原则(Single Responsibility Principle) 
    一个类只负责一项职责,应该仅有一个引起它变化的原因 
    http://www.banzg.com/archives/225.html

    设计一个社交网站中的“私信”功能,要求高并发、可扩展等等。 画一下架构图。

    MVC 模式,即常见的 MVC 框架。 
    SSM SSH SSI等

    聊了下曾经参与设计的服务器架构。

    应用服务器怎么监控性能,各种方式的区别。

    如何设计一套高并发支付方案,架构如何设计。

    如何实现负载均衡,有哪些算法可以实现。

    Zookeeper 的用途,选举的原理是什么。

    Mybatis 的底层实现原理。

    请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存。

    请思考一个方案,实现分布式环境下的 countDownLatch。

    后台系统怎么防止请求重复提交。

    可以通过token值进行防止重复提交,存放到redis中,在表单初始化的时候隐藏在表单中,添加的时候在移除。判断这个状态即可防止重复提交。 
    如何看待缓存的使用(本地缓存,集中式缓存),简述本地缓存和集中式缓存和优缺点。本地缓存在并发使用时的注意事项。

    描述一个服务从发布到被消费的详细过程。

    讲讲你理解的服务治理。

    如何做到接口的幂等性。

     

     

     

    展开全文
  • 2020java面试题

    2020-04-10 09:47:43
    它用来加载 Java 的核心类 扩展类加载器(extensions class loader):它负责加载JRE的扩展目录 系统类加载器(system class loader):被称为系统(也称为应用)类加载器,它负责在JVM启动时加载来自Java命令的 mq...

    map是如何排序的?

    • TreeMap默认是升序的,如果我们需要改变排序方式,则需要使用比较器:Comparator。

    arraylist的扩容机制?

    • 以原始集合的1.5倍进行扩容

    TreeMap和HashMap

    • TreeMap:基于红黑树实现的;TreeMap就没有调优选项,因为红黑树总是处于平衡的状态;

    不同包下的同一个类jvm是如何区分的

    • 通过class loader类加载将.java文件序列号到jvm成为.class文件然后ClassLoader.loadClass(className)方法来加载不同的类
    • 类加载器一共有三种:
    • 根类加载器bootstrap class loader):它用来加载 Java 的核心类
    • 扩展类加载器(extensions class loader):它负责加载JRE的扩展目录
    • 系统类加载器(system class loader):被称为系统(也称为应用)类加载器,它负责在JVM启动时加载来自Java命令的

    Rabbitmq有什么好处项目中是如何使用的?

    • 1.同步变异步
    • 2.低内聚,解耦合----减少强依赖.
    • 3.流量削峰---秒杀系统
    • 4.rabbitmq采用信道通信。不采用tcp直接通信

      hashCode 相同是对象是否相等

    • hashCode相等对象并不一定相等
    • 对象相等时hashCode一定相等
    展开全文
  • 2020java面试题整理.docx

    2020-07-03 22:54:52
    2020java面试题整理.docx
  • 2020 Java面试题汇总.zip

    2020-01-01 16:49:14
    2020 Java面试题汇总.zip
  • java最新面试题及答案20201. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?一个“.java”源文件里面可以包含多个类,但是只允许有一java最新面试题及答案个public类,并且类名必须和文件名一致...

    java最新面试题及答案2020

    1. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

    一个“.java”源文件里面可以包含多个类,但是只允许有一java最新面试题及答案个public类,并且类名必须和文件名一致。

    每个编译单元只能java最新面试题及答案有一个public 类。这么做的意思是,每个编译单元只能有一个公开的接口,而这个接口就由其public 类来表示。你可以根据需要,往这个文件里面添加任意多个提供辅助功能的package 权限的类。但是如果这个编译单元里面有两个或两个以上的public 类的话,程序就不知道从哪里导入了,编译器就会报错。

    2. Java有没有goto?

    goto 是Java中的保留字,在目前版本的Java中没java最新面试题及答案有使用。(根据James Gosling(Java之父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)。

    3.说说&和&&的区别。

    &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。

    &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str!= null&& !str.equals(s))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 &++y>0) y会增长,If(x==33 && ++y>0)不会增长

    &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

    4. 在JAVA中如何跳出当前的多重嵌套循环?

    在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出外层循环。

    例如:

    for(int i=0;i<10;i++){

    for(intj=0;j<10;j++){

    System.out.println(“i=” + i + “,j=” + j);

    if(j == 5) break ok;

    }

    }

    另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。

    int arr[][] ={{1,2,3},{4,5,6,7},{9}};

    boolean found = false;

    for(int i=0;i

    for(intj=0;j

    System.out.println(“i=” + i + “,j=” + j);

    if(arr[i][j] ==5) {

    found =true;

    break;

    }

    }

    }

    5. switch语句能否作用在byte上,能否作用在long上,能否作用在String上?

    在switch(e)中,e只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。

    switch语句能否作用在String上说错了,Java1.7之后已经支持这种写法了!

    6. short s1= 1; s1 = (s1+1是int类型,而等号左边的是short类型,所以需要强转)1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?(没有错)

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

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

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

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

    8. 用最有效率的方法算出2乘以8等於几?

    这道题的解法:2<<3; 表示 2向左移 3位:2 * 2^3(2的3次方) = 2 * 8;

    因为一个数左移 n位,就相当于 2的 n次方,那么一个数乘以 8只要将其左移 3位即可,而为运算符的效率最高,所以 2乘以 8等于几的最有效方法是 2<<3。

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

    使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:

    finalStringBuffer a=new StringBuffer("immutable");执行如下语句将报告编译期错误:

    a=new StringBuffer("");但是,执行如下语句则可以通过编译:

    a.append(" broken!");

    有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:

    public void method(final StringBuffer param){

    }

    实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:

    param.append("a");

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

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

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

    例如,对于下面的程序,无论创建多少个java最新面试题及答案实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。

    public class VariantTest{

    publicstatic int staticVar = 0;

    publicint instanceVar = 0;

    publicVariantTest(){

    staticVar++;

    instanceVar++;

    System.out.println(staticVar +instanceVar);

    }

    }java最新面试题及答案

    原文:https://www.cnblogs.com/javamianshiti/p/12891624.html

    展开全文
  • 2020Java面试题大全

    千次阅读 多人点赞 2020-03-07 17:22:27
    Java面试题大全Java 面向对象基础 Java 面向对象基础 面向对象都有哪些特性以及你对这些特性的理解 面向对象有3大特性,即封装、继承、多态 封装:封装将复杂的功能封装起来,对外开放一个接口,简单调用即可。 ...

    学习是一条漫长之路
    本篇总结持续中,记得收藏

    Java 基础

    1. 面向对象都有哪些特性以及你对这些特性的理解
      面向对象有3大特性,即封装、继承、多态
      封装:封装将复杂的功能封装起来,对外开放一个接口,简单调用即可。
      继承:继承是从已有类得到继承信息创建新类的过程,提供继承信息的类被称为父类——又称为超类、基类,得到继承信息的类被称为子类——又称为派生类
      多态:多态性是指允许不同子类型的对象对同一种消息做出不同的响应,简单来说就是同的对象调用同样的方法但是做了不同的事情。
      多态性分为编译时的多态和运行的多态
      编译时的多态称作重载
      运行时的多态称作重写

    2. 访问权限修饰符都有哪些?以及他们的区别
      public > protected > default > private
      public:当前类、同包、子类、其他包都可访问
      protected:当前类、同包、子类可以访问
      default:当前类、同包可以访问
      private:只有当前类可以访问

    3. Collection 和 Collections 的区别
      java.util.Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,Collection 接口在 Java 类库中有很多具体的实现,Collection 接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有 List 和 Set
      java.util.Collections 是一个包装类,它包含有各种有关集合操作的静态多态方法,此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等提供方法

    4. String s = new String(“abc”) 创建了几个对象?
      两个对象,第1个对象是字符串常量 abc,第二个对象是 new String() 产生的,在堆中分配内存给这个对象,该对象内容指向字符串常量 abc 还有一个引用 s 指向第2个对象

    5. 重写(Overriding)和重载(OverLoading)的区别
      方法的重写和重载是多态性的不同表现,二者的差别在于:
      1.重载是编译时的多态,重写是运行时的多态
      2.重载的特点是:在同一类中,方法名相同,参数类型、参数顺序、以及参数个数不同具有这些特点则称为重载方法
      3.重写的特点是:参数列表、返回类型都要和被重写的方法相同,访问修饰符权限不能大于被重写方法的修饰符

    6. & 和 && 的区别
      1.&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
      2.&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式
      3.&还可以用作 位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作

    7. String 是否可以被继承
      String 类是 final 类,不可以被继承

    8. char 型变量能不能存储一个中文汉字,为什么?
      char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个 char 类型占 2 个字节(16 比特),所以放一个中文是没问题的

    9. 说出几个常见的 runtime Exception
      NullpointerException 空指针异常
      ClassCastException 数据类型转换异常
      IllegalArgumentException 传递非法参数异常
      ArithmeticException 算数运算异常
      IndexOutOfBooundsException 下标越界异常
      NumberFormatException 数字格式异常
      SecurityException 安全异常
      SQLException sql语句异常
      IOException IO流异常

    10. RunTimeException和其他Exception区分
      其他Exception,受检查异常,必须要开发者解决以后才能编译通过,比如通过 try-catch 处理
      RuntimeException,运行时异常 ,又称为不受检查异常,编译期间可以通过,但是在运行期间可能出错,比如经典的空指针、1/0 算数异常等等

    11. Erro 和 Exception 区分
      Error 表示恢复起来很困难的一种严重问题,例如内存溢出,不可能指望程序处理这样的情况
      Exception 表示一种设计实现问题,他表示如果程序运行异常,从不会发生的情况

    12. 抽象类 abstract 和接口 interface 有什么区别?
      抽象类
      1.抽象类可以定义构造函数
      2.可以有抽象方法和普通方法
      3.接口中的成员全都是 public 的
      4.抽象类中可以包含静态方法
      5.有抽象方法的类必须是抽象类,而抽象类中可有可不有抽象方法
      7.一个类只能继承一个抽象类
      接口
      1.接口中不能定义构造函数
      2.方法全部都是抽象方法
      3.接口中定义的变量实际上都是常量,都由 public final 修改
      4.接口中不能有静态方法
      5.一个类可以实现多个接口
      二者相同点
      1.都不能被实例化
      2.可以将抽象类和接口类型作为引用类型
      3.一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要
      被声明为抽象类

    13. 抽象的(abstract)方法是否可同时是静态的(static), 是否可同时是本地方法(native),是否可同时被 synchronized?
      都不能,抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如 C 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

    14. 静态变量和实例变量的区别?
      静态变量: 是被 static 修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;
      实例变量: 必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对
      象共享内存。

    15. == 和 equals 的区别?
      equals 和 == 最大的区别一个是方法一个是运算符
      == :如果比较的对象是基本类型,则比较的是数值是否相等,如果比较的是引用数据类型,则比较的是对象的地址是否相等。
      equals():用来比较方法两个对象的内容是否相等
      注意:equals 方法不能用于基本数据类型的变量,如果没有对 equals 方法进行重写,则比较的是引用类型的变
      量所指向的对象的地址

    16. break 和 continue 的区别?
      break 和 continue 都是用来控制循环的语句。
      break 用于完全结束一个循环,跳出循环执行循环后的语句。
      continue 用于跳过本次循环,执行下次循环。

    17. throw 和 throws 的区别?
      throw
      1.throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理
      2.throw 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常
      throws
      1.throws 语句主要用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常处理
      2.throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型。
      3.throws 表示出现异常的一种可能性,并不一定会发生这种异常。

    18. final、finally、finalize 的区别?
      final:用于声明属性、方法和类,分别表示属性不可变,方法不可覆盖,类不可被继承
      finally:异常处理的一部分,表示总是执行
      finalize: Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法
      提供垃圾收集时的其他资源回收,例如关闭文件等。该方法更像是一个对象生命周期的临终方法,当该方法被系统调用则代表该对象即将“死亡”,但是需要注意的是,我们主动行为上去调用该方法并不会导致该对象“死亡”,这是一个被动的方法(其实就是回调方法),不需要我们调用。

    19. switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String上?
      Java5 以前 switch(expr)中,expr 只能是 byte、short、char、int。从 Java 5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型。从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

    20. 数组有没有 length() 方法?String 有没有 length() 方法?
      数组没有 length() 方法,而是有 length 的属性,String 有 length() 方法。

    21. String 、StringBuilder 、StringBuffer 的区别?

    • String :是只读字符串,也就意味着 String 引用的字符串是不能改变的
    • StringBuffer:StringBuffer 速度没有 StringBuilder 快,但是它安全性高
    • StringBuilder :它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比 StringBuffer 要高。
    1. Java 的基本数据类型都有哪些?各占几个字节?
      整形
      byte 1字节
      short 2字节
      int 4字节
      long 8字节

      浮点型
      float 4字节
      double 8字节
      字符型
      char 2字节
      布尔型
      boolean 1字节
    2. String 是基本数据类型吗?
      String 是引用类型,底层用 char 数组实现的
    3. short s1=1; s1 = s1 + 1; 有错吗?short s1 = 1; s1+=1有错吗?
      前者不正确,后者正确。对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 =(short)(s1 + 1);其中有隐含的强制类型转换。
    4. int 和 和 Integer 有什么区别?
      (1)Integer是int的包装类;int是基本数据类型;
      (2)Integer变量必须实例化后才能使用;int变量不需要;
      (3)Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
      (4)Integer的默认值是null;int的默认值是0。
    5. 如何实现字符串反转?
      通过 StringBuffer 或者 StringBuilder 中的reverse()方法即可完成
    		String str = "123456789qwertyuiop";
            StringBuffer sBuffer = new StringBuffer(str);
            StringBuilder sBuilder =new StringBuilder(str);
            
            System.out.println(sBuffer.reverse());
            System.out.println(sBuilder.reverse());
    
    1. 什么是 java 序列化,如何实现 java 序列化?
      序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
      实体类可以通过实现 Serializable 接口来实现 Java 实例化
    2. List 的三个子类的特点
    • ArrayList 底层结构是数组,底层查询快,增删慢
    • LinkedList 底层结构是链表型的,增删快,查询慢
    • Voctor 底层结构时数组,线程安全的,增删慢,查询慢
    1. List 和 Map、Set 的区别
    • 结构特点
      List 和 Set 是存储单列数据的集合,Map 是存储键和值这样的双列数据的集合;List 中存储的数据是有顺序,并且允许重复;Map 中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的,Set 中存储的数据是无序的,且不允许有重复,但元素在集合中的位置由元素的 hashcode 决定,位置是固定的(Set 集合根据 hashcode 来进行数据的存储,所以位置是固定的,但是位置不是用户可以控制的,所以对于用户来说 set 中的元素还是无序的
    • 实现类
    • List 接口
      List 接口有三个实现类(LinkedList:基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢;ArrayList:基于数组实现,非线程安全的,效率高,便于索引,但不便于插入删除;Vector:基于数组实现,线程安全的,效率低)。
    • Map接口
      Map 接口有三个实现类(HashMap:基于 hash 表的 Map 接口实现,非线程安全,高效,支持 null 值和 null键;HashTable:线程安全,低效,不支持 null 值和 null 键;LinkedHashMap:是 HashMap 的一个子类,保存了记录的插入顺序;SortMap 接口:TreeMap,能够把它保存的记录根据键排序,默认是键值的升序排序)。
    • Set接口
      Set 接口有两个实现类(HashSet:底层是由 HashMap 实现,不允许集合中有重复的值,使用该方式时需要重写 equals()和 hashCode()方法;LinkedHashSet:继承与 HashSet,同时又基于 LinkedHashMap 来进行实现,底层使用的是 LinkedHashMp)。
    • 区别
      List 集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象,例如通过list.get(i)方法来获取集合中的元素;Map 中的每一个元素包含一个键和一个值,成对出现,键对象不可以重复,值对象可以重复;Set 集合中的对象不按照特定的方式排序,并且没有重复对象,但它的实现类能对集合中的对象按照特定的方式排序,例如 TreeSet 类,可以按照默认顺序,也可以通过实现 Java.util.Comparator< Type>接口来自定义排序方式。
    1. HashMap 和 HashTable 有什么区别?
    • HashTable 线程安全,不允许键值对(key/value)有 null 值
    • HashMap 线程不安全,允许键值对(key/value)有 null 值
    1. JDK 和 JRE 有什么区别?
    • JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。
    • JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。
      具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。
    1. String 类的常用方法都有那些?
    • indexOf():返回指定字符的索引。
    • charAt():返回指定索引处的字符。
    • replace():字符串替换。
    • trim():去除字符串两端空白。
    • split():分割字符串,返回一个分割后的字符串数组。
    • getBytes():返回字符串的 byte 类型数组。
    • length():返回字符串长度。
    • toLowerCase():将字符串转成小写字母。
    • toUpperCase():将字符串转成大写字符。
    • substring():截取字符串。
    • equals():字符串比较。
    1. Java 中 IO 流分为几种 ?
    • 按照功能来分:输入流(input)、输出流(output)。
    • 按类型来分:字节流和字符流
    • 字节流和字符流的区别在于:字节流按照8位传输以字节为单位输入输出数据,字符流按16位传输以字符为单位输入输出数据。
    1. BIO、NIO、AIO有什么区别?
    • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
    • NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel (通道)通讯,实现了多路复用
    • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非阻塞 IO,异步 IO 的操作基于事件和回调机制
    1. Files 的常用方法都有哪些?
    • Files.exists():检测文件路径是否存在。
    • Files.createFile():创建文件。
    • Files.createDirectory():创建文件夹。
    • Files.delete():删除一个文件或目录。
    • Files.copy():复制文件。
    • Files.move():移动文件。
    • Files.size():查看文件个数。
    • Files.read():读取文件。
    • Files.write():写入文件。
    1. 如何实现数组和 List 之间的转换?
    • List 转换为数组:调用 ArrayList 的 toArray 方法。
    • 数组转换为List:调用 Arrays 的 asList 方法。
    1. 在 Queue 中 poll() 和 remove() 有什么区别?
      poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
    2. 迭代器 Iterator 是什么?
      迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为 “轻量级” 对象,因为创建它的代价小。
    3. Iterator 怎么使用,有什么特点?
      Java 中的 Iterator 功能比较简单,并且只能单向移动:
    • 使用方法 iterator() 要求容器返回一个 iterator,第一次调用 iterator 的 next() 方法时,它返回序列的第一个元素。注意:iterator() 方法是 java.lang.iterable 接口,被Collection 继承。
    • 使用 next() 获得序列中的下一个元素。
    • 使用 hashNext() 检查序列中是否还有元素。
    • 使用 remove() 将迭代器新返回的元素删除。
      iterator 是 Java 迭代器最简单的实现,为 List 设计的 ListIterator 具有更多的功能,它可以从两个方面遍历List,也可以从List中插入和删除元素。

    Java 多线程

    1. 并行和并发有什么区别?
    • 并行是指两个或多个事件在同一时刻发生;并发是指两个或者多个时间在同一时间间隔发生
    • 并行是在不同实体上的多个事件,并发实在同一实体上的多个事件
    • 在一台处理器上“同时”处理多个任务,在多态处理器上同时处理多个任务,如 hadoop 分布式集群。
      所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能。
    1. 线程和进程的区别?
      进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程,进程在执行过程中拥有独立的内存单元。而多个线程共享内存资源,减少切换次数,从而效率更高。线程是进程的一个实体,是cpu调度和分配的基本单位,是比程序更小的能独立运行的基本单位。同一进程中的多个线程之间可以并发执行
    2. 守护线程是什么?
      守护线程 daemon thread 是个服务线程,给其他的线程提供服务的。
    3. 创建线程有几种方式?
    • 继承Thread类创建线程类
      • 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
      • 创建Thread子类的实例,即创建了线程对象。
      • 调用线程对象的start()方法来启动该线程。
    • 通过Runnable接口创建线程类
      • 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
      • 创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
      • 调用线程对象的start()方法来启动该线程。
    • 通过Callable和Future创建线程
      • 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
      • 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
      • 使用FutureTask对象作为Thread对象的target创建并启动新线程。
      • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
    1. 说一下 runnable 和 callable 有什么区别?
    • Runnable 接口中的 run() 方法的返回值是 void,它做的事情只是纯粹地去执行 run() 方法中的代码而已。
    • Callable 接口中的 call() 方法是有返回值的,是一个泛型,和 Future、FutureTask 配合可以用来获取异步执行的结果。
    1. 线程都有哪些状态?
      • 创建状态:在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
      • 就绪状态:当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
      • 运行状态:线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
      • 阻塞状态:线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
      • 死亡状态:如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪
    2. sleep() 和 wait() 有什么区别?
    • sleep() 方法是线程类 Thread 的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争 cpu 的执行时间。因为 sleep() 是 static 静态的方法,它不能改变对象的机制锁,当一个synchronized块中调用了 sleep() 方法,线程虽然进入休眠,但是对象的机制锁没有被释放,其他线程仍然无法访问这个对象。
    • wait() 方法是Object类得方法,当一个线程执行到wait 方法时,它就进入一个和该对象相关的等待池中,同时释放对象的机制锁,使得其他线程能够访问,可以通过 notify,notifyAll 方法来唤醒等待的线程。
    1. notiry() 和 notiryAll() 方法有什么区别?
    • 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。
    • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。
    • 优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
    1. 线程的 run() 和 start() 方法有什么区别?
      每个线程都是通过某个特定的Thread对象所对应的方法 run() 来完成其操作的,方法 run() 称为线程体,通过调用 Thread 类的 start() 方法来启动一个线程 。
    • start()方法来启动一个线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码; 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行状态, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
    • run()方法是在本线程里的,只是线程里的一个函数,而不是多线程的。 如果直接调用run(),其实就相当于是调用了一个普通函数而已,直接待用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()方法而不是run()方法。
    1. 什么是死锁?
      死锁是指两个或多个线程在执行过程中,由于竞争资源或者由于彼此通信造成的一种堵塞线程,如果没有外力干扰,他们都无法执行下去,此时称系统处于死锁状态,这些永远在互相等待的进程称为
    2. 怎么防止死锁?
      死锁形成的四个必要条件:
      • 互斥条件:进程中对分配的资源不允许其他进程进行访问,如果其他进程访问该资源,只能等待,直到占有该资源的进程完成后释放该资源 。
      • 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此时请求堵塞,但是又对自己获取的资源保持占有。
      • 不可剥夺条件:指的是进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放。
      • 环路等待条件:是指进程发生死锁后,若干线程之间形成一种头尾相接的循环等待资源关系。
        这四个条件就是形成死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
    3. 说一下 synchronized 底层实现原理?
      synchronized 可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。
      Java 中每一个对象都可以作为锁,这是 synchronized 实现同步的基础:
      • 普通同步方法,锁是当前实例
      • 静态同步方法,琐是当前类得 class 对象
      • 同步方法块,锁是括号里面的对象
    4. synchronized 和 volatile 的区别是什么?
    • volatile 本质是在告诉jvm 当前变量在工作内存中的值是不确定的,需要从主存中读取;synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被堵塞住。
    • volatile 仅能使用在变量级别;synchronized 则可以使用在变量、方法、和类级别上。
    • volatile 仅能实现变量的修改可见性,不能保证原子性;synchronized 则可以保证变量的修改可见性和原子性。
    • volatile 不会造成线程阻塞;synchronized 可能会造成线程阻塞。
    • volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化。
    1. synchronized 和 Lock 有什么区别?
    • 首先 synchronized 是Java内置关键字,在jvm层面,Lock是个java类。
    • synchronized 无法判断是否获取锁的状态,Lock 可以判断是否获取到锁。
    • synchronized 会自动释放锁,Lock 需要在 finally 中手工释放锁(unlock() 方法释放锁),否则容易造成线程死锁。
    • 用 synchronized 关键字的两个线程1和线程2吗,如果当前线程1获得锁,线程2等待。如果线程1堵塞了,线程2会一直等待下去;而Lock 锁就不一定会等待下去,如果尝试获取不到锁,线程可以不同一直等待就结束了。
    • synchronized 的锁可重入、不可中断、非公平,而 Lock 锁可重入、可判断、可公平。
    • Lock 锁适合大量同步代码的同步问题,而 synchronized 锁适合代码少量的同步问题。
    1. synchronized 和 ReentrantLock 的区别是什么?
      synchronized 是Java中的关键字,ReentrantLock是类,这是二者本质区别。既然 ReentrantLock 是类,那么它就提供了比synchronized 更多灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock 比synchronized 的扩展性体现在几点上:
      • ReentrantLock 可以对获取锁的等待时间进行设置,这样就避免了死锁发生
      • ReentrantLock 可以获取各种锁的信息
      • ReentrantLock 可以灵活的实现多路通知
        另外,二者的锁机制其实也是不一样的,ReentrantLock 底层调用的是 Unsafe的park 方法加锁,synchronized 操作的应该是对象头中的 mark word。
    2. 手写饿汉模式和懒汉模式
      懒汉模式:当你需要此实例在给你创建
    public class Signlock {
    	//懒,所以就不实例化了,加载类较快,但是第一次访问类可能会有点慢
    	private static Signlock lock = null;
    	
    	// 创建私有构造器
    	private Signlock() {
    	}
    	
    	public static Signlock get() {
    		if(lock ==null){
                synchronized (Signlock.class){
                    if(lock ==null)   //这里的二次判断很有必要啊,在多线程中同时到达第一个if的可能有多个,若此处没有二次二次判断,会导致new Signlock()同步执行多次。
                        lock =new Signlock ();
                }
            }
    		return lock;
    	}
    }
    

    饿汉模式:不管你需不需要此实例,都给你创建

    public class Signlock {
    	private static final Signlock lock = new Signlock();
    	
    	// 创建私有构造器
    	private Signlock() {
    	}
    	
    	public static Signlock get() {
    		return lock;
    	}
    }
    

    Java Web

    1. jsp 和 servlet 有什么区别?
      • jsp经编译后就变成了 Servlet JSP的本质就是Servlet,JVM只能识别 Java 类,不能识别 JSP 的代码,Web 容器将JSP的代码编译成JVM能够识别的Java类
      • jsp 更擅长表现于页面显示,servlet 更擅长与逻辑控制。
      • Servlet 中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest 对象或者 HttpServletResponse对象以及HttpServlet对象得到。
      • Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何嵌入到一个类中,由JSP容器完成。而Servlet 则是个完整的 Java类,这个类的Service 方法用于生成对客户端的相应。
    2. Jsp中有哪些内置对象?作用分别是什么?
      • request:封装客户端的请求,其中包含来自GET和POST请求的参数。
      • response:封装服务器对客户端的相应。
      • pageContext:通过此对象可以获取其他对象。
      • session:封装用户会话的对象。
      • application:封装服务器运行环境的对象,全局对象。
      • out:输出服务器响应的输出流对象。
      • config:Web应用的配置对象。
      • page:JSP页面本身。
      • exception:封装页面抛出异常的对象。
    3. 说一下 JSP 的 4 种作用域?
      • page 代表与一个页面相关的对象和属性。
      • request 代表与客户端发出的一个请求相关的对象和属性,一个请求可能跨越多个页面,涉及多个Web组件,需要在页面显示的临时数据可以至于此作用域。
      • session 代表与某个用户与服务器建立的一次会话数据,根某个用户相关的数据应该放在用户自己的 session 中。
      • application 代表与整个Web应用程序相关的属性,它实质上是跨越了整个Web应用程序,包括多个页面,请求和会话的一个全局作用域。
    4. Session 和 Cookie有什么区别呢?
    • 由于HTTP协议是无状态协议,所以服务端需要记录用户的状态时,就需要使用某种手段来识别具体的用户,这个手段就是Session ,典型的场景列如:购物车,当你点击下单时,由于HTTP协议无状态,这个时候不知道是哪个用户操作的,所以服务端要为特定的用户创建特定的Session,用于标识这个用户,并且跟踪用户,这样才知道用户购物车里有几本书。Session是保存在服务端的,有一个唯一标识,在服务端保存Session 的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。
    • 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
    • Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。所以,总结一下:Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
    1. 说一下Session的工作原理?
      其实Session是一个存放在服务器上的类似于一个散列表格的文件,里面存有我们需要的信息,在我们需要用的时候从里面取出来,类似于一个比较大的 Map,里面的键存储的是用户的sessionid,用户向服务器端发送请求的时候会带上这个 sessionid,这时就可以根据这个sessionid取出里面对应的value值了。
    2. 如何客户端禁止 Cookie 那么 Session 还能用吗?
      Cookie 与 Session,一般认为是两个独立的东西,Session 采用的实在服务端保持状态的方案,而Cookie 采用的实在客服端保持状态的方案。但为什么禁用 Cookie就不能得到 Session呢?因为 Session 使用 Session ID 来确定当前对话所对应的服务器Session,而 Session ID 是通过 Cookie 来传递的,禁用 Cookie相当于失去了Session ID,理应的就得不到Session了。
      假如用户关闭了Cookie的情况下仍然要使用Session,其中实现的方法有下列几种:
      • 设置 php.ini 配置文件中的 “session.use_trans_sid=1”,或者编辑器打开 "–enable-trans-sid"选项,让 PHP自动跨页传递 Session ID。
      • 手动通过 URL传值,隐藏表单传递 Session ID。
      • 用文件、数据库等形式保存Session ID,在跨页面中手动调用。
    3. 什么是 XSS 攻击,如何避免呢?
    • XSS攻击又称为跨脚本攻击,原理就是攻击者向有XSS漏洞的网站中输入恶意的 HTML代码,当用户浏览该网站时,这段HTML代码就会自动执行,从而达到攻击的目的。XSS攻击类似于SQL注入攻击,SQL注入攻击中以SQL语句作为用户输入,从而达到查询、修改、删除数据的目的,而在Xss攻击中,通过插入恶意脚本,实现对用户浏览器的控制,获取用户的一些信息。XSS是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式。
      Xss防范的总体思路:对输入(URL参数)进行过滤,对输出进行编码。
    1. 什么是CSRF攻击,如何避免?
    • CSRF也被称为 one-click attack 或者 session riding,中文全称是 跨站请求伪造 ,一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去。使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假信息等。 攻击者利用网站对请求的验证漏洞而实现这样的攻击行为。网站能够确认请求来源于用户的浏览器,却不能验证是否源于用户的真实意愿下的操作行为。
      那么如何避免呢?
    • 验证 HTTP Referer 字段

    HTTP头中的Referer字段记录了该HTTP请求的来源地址,在通常情况下,访问一个安全受限页面的请求来自同一个网站,而如果黑客要对其实施 CSRF攻击,他一般只能在自己的网站构造请求,因此,可以通过验证 Referer值来防御CSRF攻击

    • 使用验证码

    关键页面加上验证码,后台收到请求通过判断验证码可以防御 CSRF,但这种方法对用户不太友好。

    • 在请求地址中添加 token 并验证

    CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有用户验证信息都存在于 Cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的cookie 来通过安全验证。要抵御 CSRF,关键在于请求中放入黑客所不能伪造的信息,并且该信息不能存在 cookie 中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有token或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于session之中,然后在每次请求时把token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
    对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。
    而对于 POST 请求来说,要在 form 的最后加上 ,这样就把token以参数的形式加入请求了。

    • 在 HTTP 头中自定义属性并验证

    这种方法也是使用 token 进行验证,和上一种方法不同的是这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。

    网络

    1. Http响应码 301 和 302 代表什么,有什么区别?
      • 301 代表永久性转移
      • 302 代表暂时性转移
    2. forwar 和 redirect 的区别?
    • 请求方式不同

    redirect:客户端发起的请求
    forward:服务端发起的请求

    • 浏览器地址表现不同

    redirect:浏览器地址显示被请求的
    forward:浏览器地址不显示被请求的url

    • 参数传递不同

    redirect:重新开始一个请求,原页面的请求生命周期结束
    forward:重定向另一个连接的时候,request变量是在其生命周期内的。另一个页面也可以使用,其实质是把目标地址 include。

    • 底层运作不同

    redirect:发送的请求信息又回送给客户机,让客户机再转发到另一个资源上,需要在服务器和客户机之间增加一次通信。
    forward:服务器端直接找到目标,并include过来。

    • 定义不同

    直接转发方式(Forward):客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
    间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。

    1. tcp为什么要三次握手,两次不行吗?为什么?
    • 为了实现可靠数据传输,TCP协议的通信双方,都必须维护一个序列号,以标识发送出去的数据包中,哪些是已经被对方收到的,三次握手的过程即是通信双方相互告知序列号起始值,并确定对方已经收到了序列号起始值的毕竟步骤。
    • 如果只是两次握手,顶多只有连接请求方的起始序列号能被确认,响应方的序列号则得到不验证。
    1. OSI的七层模型都有哪些?
      • 应用层:网络服务与最终用户的一个接口
      • 表示层:数据的表示、安全、压缩。
      • 会话层:建立、管理、终止会话。
      • 传输层:定义传输数据的协议端口号,以及流控和差错校验。
      • 数据链路层:建立逻辑链接、进行硬件地址寻址、差错校验等功能。
      • 物理层:建立、维护、断开物理连接。
    2. get 和 post 请求有什么区别?
      • get 在浏览器回退时是无害的,而 post 会再次提交请求
      • get 产生的url地址可被 bookmark,而 post 不可以
      • get 请求会被浏览器主动缓存,而 post 不会,除非手动设置
      • get 请求只能手动 url 编码。而 post 支持多种编码格式
      • get 请求在 url 中传送的参数是有长度限制的,而 post 没有限制
      • get 对比 post 请求不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息
      • get 参数通过 url 传递,post 放在请求体中。

    Java 框架

    1. 为什么要使用 Spring?
      Spring 是一个轻量级的控制反转 IOC 和面向切面编程的 AOP 的容器框架
      • 控制反转
        Spring 通过一种称控制反转IOC 的技术促进了松耦合,
      • 面向切面
        Spring 提供了面向切面编程的支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发,应用对象只实现他们应该做的——完成业务逻辑仅此而已。它们并不负责其它的系统级关注点,列如日志或者事务支持。
    2. 解释一下什么是 AOP?
      AOP 面向切面编程,在不改变原代码的基础上为代码增加新的功能,列如:日志、事务处理
    3. 解释下什么是 IOC?
      IOC即控制反转,又称为依赖注入,其原理就是让 bean 与 bean 之间以配置文件的形式组织在一起,而不是以硬编码的方法耦合在一起,相当于将需要的接口实现都注入到需要它的类中。
      IOC的好处:低耦合,易管理。
    4. Spring 事务实现方式有哪些?
      • 编程式事务管理,我们需要在代码中通过调用 beginTransaction()、commit()、rollback() 等事务管理相关的办法,这就是编程式事务管理。
      • 基于 TransactionProxyFactoryBean 的声明式事务管理
      • 基于 @Transaction 的声明式事务管理
      • 基于 Aspectj AOP 配置事务
    5. 说一下 Spring 的事务隔离机制?
      事务隔离机制指的是一个事务对数据的修改与另一个并行的事务的隔离程度,当多个事务同时访问相同数据时,如果没有采取必要的隔离机制,就可能发生以下问题:
      * 脏读:一个事务读到另一个事务未提交的更新数据
      * 幻读:列如第一个事务对一个表中的数据进行了修改(比如这种修改是修改全部数据),同时,第二个事务也修改了这个表中的数据(这种修改时向表中插入一行新数据), 那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好像发生了幻觉。
      * 不可重复读:比方说在同一个事务中先后执行两条一模一样的select语句,期间在此次事务中没有执行过任何DDL语句,但先后得到的结果不一致,这就是不可重复读。
    6. 什么是Spring Boot?
      SpringBoot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,节省了繁杂的配置,提供了各种启动器,开发者能够快速上手。
    7. 为什么要使用Spring Boot?
      Spring Boot 的优点,例如:
      * 独立运行
      * 简化配置
      * 自动配置
      * 五代码生成和XML配置
      * 应用监控
      * 上手容易
      * …
    8. Spring Boot 的核心配置文件有哪几个?他们的区别是什么?
      Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
      application 配置文件主要用于 SpringBoot 项目的自动化配置。
      bootstrap 配置文件有以下几个应用场景:
      • 使用 Spring Cloud 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
      • 一些固定的不能被覆盖的属性;
      • 一些加密、解密的场景;
    9. Spring Boot 的配置文件有哪几种格式?他们有什么区别?
      .properties 和 .yml 的区别在于写法不同。
    • .properties
    server.port=8082
    
    • .yml
    server:
    	port:8082
    

    .yml格式不支持 @PropertySource 注解导入配置

    1. Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
      @SpringBootApplication是Spring Boot的核心注解,此注解的作用是启动项目,主要由3个注解组成:
    • @SpringBootConfiguration:组合了@Configuration注解,实现了配置文件的功能。
    • @EnableAutoConfiguration:打开了自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exculde={ DataSourceAutoConfiguraion.class})。
    • @ComponentScan:Spring组件扫描。
    1. 开启 SpringBoot 特性由哪几种方式?
    • 继承spring-boot-starter-parent项目
    • 导入spring-boot-dependencied项目依赖
    1. SpringBoot需要独立的容器运行吗?
      可以不需要,内置了Tomcat、Jetty等容器。
    2. 运行 Spring Boot 有哪几种方式?
      • 打包用命令或者放到容器中运行
      • 用 Maven、Gradle 插件运行
      • 直接启动类main方法运行
    3. Spring Boot 自动配置的原理是什么?
      注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
    4. Spring Boot 的目录结构是怎样的?
    cn
     +- javastack
         +- MyApplication.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java
    
    • 这个目录结构是目前主流推荐的做法,而在主入口类上加 @SpringBootApplication 注解来开启 Spring Boot 的各项能力,如自动配置,组件扫描等。
    1. 你如何理解 Spring Boot 中的 Starters?
    • Starters 可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要导出找示例代码和依赖包,如你所想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。
    1. 如何在 Spring Boot 启动的时候运行一些特定的代码?
    • 可以实现接口 ApplicationRunner 或者 CommandLineRunner ,这两个接口实现方式一样,他们都只提供了一个 run 方法。
    1. Spring Boot 有哪几种读取配置的方式?
    • Spring Boot 可以通过 @PropertySource,@Value,@Environment,@ConfigurationProperties 来绑定变量。
    1. Spring Boot 实现热部署有哪几种方式?
      主要有两种方式
      • Spring loaded
      • Spring-boot-devtools ——添加pom.xml依赖
    2. 如何理解Spring Boot 配置加载顺序?
      在Spring Boot 里面,可以使用以下几种方式来加载配置:
      • properties 文件;
      • YAML 文件;
      • 系统环境命令;
      • 命令行参数;
    3. Spring Boot 如何定义多套不同环境配置?
    application.properties	//普通环境
    
    application-dev.properties	//开发环境
    
    application-test.properties	//测试环境
    
    application-prod.properties	//生产环境
    
    1. Spring Boot 可以兼容老 Spring 项目吗?如何做到?
      可以兼容,通过 @ImportResource 注解导入老 Spring 项目配置文件。
    2. 保护 Spring Boot 应用有哪些方法?
    • 在生产中使用HTTPS
    • 使用 Snyk 检查你的依赖关系
    • 升级到最新版本
    • 启动 CSRF 保护
    • 使用内容安全策略防止 XSS 攻击
    展开全文
  • 整理2020java面试题

    2020-04-23 17:16:16
    2020java面试题目录1.Java 基础2. 容器3. 多线程4. 反射5. 对象拷贝6. Java Web7. 异常8. 网络9. 设计模式10.Spring / Spring MVC11.Spring Boot / Spring Cloud12.Hibernate13.Mybatis14.RabbitMQ15.Kafka16....
  • 2020JAVA面试题附答案

    千次阅读 2020-02-20 19:17:31
    2020JAVA面试题附答案 原创置顶华仔呀最后发布于2019-01-18 01:31:16阅读数 236072收藏 展开 前言:勤奋才是改变你命运的唯一捷径。 整理不易,各位看官点赞再看更舒适,养成好习惯(●´∀`●) JAVA基础 ...
  • 2020Java面试题整理

    2020-05-04 16:24:57
    面试题含有redis,netty,mysql,kafka,并发编程,spring,dubbo,以及思维导图学习笔记,适合20k以上突击
  • 2020Java面试题基础篇整理1.java基础部分 1.java基础部分 1.Java和JavaScript的区别? 参考回答: JavaScript和java是两家公司开发的不同的两个产品。 Java是Sun公司推出的面向对象的程序设计语言,适合于互联网...
  • 下面要给大家带来的是一个小伙伴2020年的百度java一面面经,内容包括了具体的java面试题,下面一起来看看2020年的百度java面试题都有哪些吧!自我介绍面试题(一面)项目一、项目介绍,说一下项目的亮点二、面向对象的...
  • 2020JAVA面试题附答案(持续更新版) https://blog.csdn.net/weixin_43495390/article/details/86533482
  • 2020java面试题高级篇-Spring 1.什么是Spring? 参考答案: sping是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器 2.Spring的核心? 参考答案: 控制反转(IoC) 依赖注入(DI) 面向切面编程(AOP) 控制...
  • 2020Java面试题 答案

    千次阅读 多人点赞 2020-02-01 12:20:37
    1.Java 基础 2.多线程 3.反射 4.设计模式 5.Spring/Spring MVC 6.Spring Boot/Spring Cloud Hibernate 7.MyBatis 8.RabbitMQ 9.Kafka 10.MySQL 11.Redis 12.JVM 1.Java 基础 JDK 和 JRE 有什么区别? ...
  • 继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的《Java与模式》或《设计模式精解》中关于桥梁模式的部分)。 - 封装:通常认为封装是把数据和操作...
  • 2020java面试题整理

    2020-04-06 19:57:56
    文章目录spring面试题1.你对spring的理解?与springmvc和springboot的区别?(经常被问到)2.spring 的优缺点3.spring的核心技术(IOC、DI、AOP)4.spring中Bean的作用域5.Spring JDBC API 中存在哪些类?6.Spring ...
  • 2020面试题 1.jvm部分 JVM是Java运行基础,面试时一定会遇到JVM的有关问题,内容相对集中,但对只是深度要求较高 其中内存模型,类加载机制,GC是重点方面.性能调优部分更偏向应用,重点突出实践能力.编译器优化和执行...
  • 2020Java面试题答案

    2020-06-24 12:10:29
    JAVA基础 JAVA中的几种基本类型,各占用多少字节? 下图单位是bit,非字节 1B=8bit String能被继承吗?为什么? 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。平常我们...
  • 4. final 在 java 中有什么作用? final修饰类时不可被继承;修饰方法时不可被重写;修饰变量时变常量,不可被修改。 7. java 中操作字符串都有哪些类?它们之间有什么区别? 操作字符串的类有:Stri
  • 2020Java面试题

    2020-06-10 14:40:46
    个人遇到的部分提问 1、数据库查询速度很慢是什么原因?这么解决? 2、前端到后端具体是怎么实现的? 3、你项目中功能的具体实现? ...15、Java序列号?什么情况下要做序列号处理? 16、session和cooki
  • 1、面向对象的特征有哪些方面 1)继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的... 39、编程: 用最有效率的方法算出2乘以8等於几? 2 、两...
  • 前言:今年是个不平静的一年。博主去年因为公司毁约的原因,进了一家做人脸识别的小公司。对公司的知遇之恩其实一直铭记在心,老大人也特别好。由于开发团队人员较少的原因,...也总结了一下遇到的面试题。在这儿分享.
  • 2020java面试题-基础篇

    千次阅读 2020-02-09 12:14:32
    后续会记录一些面试题方面的总结,方便复习查看。今天是基础篇的几个典型面试题。文章内容来源于自己的思考、书本、网络,如有雷同,不是巧合。 文章目录1.HashMap的源码:2.Set的实现:3.List实现:4.讲解线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,363
精华内容 1,745
关键字:

2020java面试题

java 订阅