为您推荐:
精华内容
最热下载
问答
  • 5星
    1.31MB qq_40957277 2021-07-25 07:32:59
  • 5星
    15.9MB Yao__Shun__Yu 2021-01-26 09:52:27
  • 5星
    24KB weixin_39709134 2021-08-30 14:40:44
  • 5星
    1.3MB qq_40957277 2021-06-24 14:00:04
  • 5星
    12.2MB m0_37968982 2020-12-01 22:25:02
  • 44.25MB lihailin8 2021-02-22 17:49:02
  • 5星
    34.07MB Feng_wwf 2020-12-31 11:42:31
  • 12.3MB weixin_40300139 2021-03-25 08:59:28
  • 5星
    332KB qq_16397653 2021-01-29 19:19:13
  • 6.02MB zjx2016 2021-11-15 17:28:06
  • 33KB qq_40625778 2020-09-05 18:19:14
  • 7.1MB qq_37774399 2021-04-03 12:41:56
  • 13.54MB m0_47503416 2021-01-10 13:48:07
  • 10.44MB qq_39735940 2021-03-21 19:20:40
  • 670KB weixin_38517095 2021-06-20 14:19:35
  • 9.23MB j610152753 2021-06-02 22:22:30
  • 5星
    14.42MB sunjian286 2021-03-24 15:53:39
  • 6.java的深拷贝和浅拷贝 7.线程池,使用的是什么线程池,使用的场景是怎样的?线程池有了解使用有什么注意事项? 8.StringBuffer和StringBuilder区别 9.有了解java的哪几种设计模式?实际开发有用过哪些,使用...

    1.rabbitMQ特点和使用经验?有了解其他的消息队列?

    2,Mybatis一级缓存和二级缓存,作用范围?

    3.synchronized与Lock的区别

    4.为什么要用到缓存?redis有哪几种数据类型?使用场景?

    5.数据库优化?

    6.java的深拷贝和浅拷贝

    7.线程池,使用的是什么线程池,使用的场景是怎样的?线程池有了解使用有什么注意事项?

    8.StringBuffer和StringBuilder区别

    9.有了解java的哪几种设计模式?实际开发有用过哪些,使用场景?

    10.Tomact类加载机制,说下双向委派?

    11.并发编程相关的,说下比如说:线程池,锁指类的

    12为什么说mybatis是一个半自动化的orm工具

    13.redis缓存失效策略,淘汰算法有哪些?

    14.给一个sql怎么判断是否有使用索引

    15.ArrayList底层是数组,比如每次扩容50%,代码是怎么实现的

    16.rabbitMQ客户端挂了掉怎么处理?

    17.谈下rabbitMQ通信组件和整个通信流程,消息是怎么异步传送到另一边?怎么通过异步来实现同步

    18.索引创建规则?

    19.你缓存的业务数据,为什么要用缓存,你缓存的数据量有多大,为什么用缓存而不用数据库?判断的标准是什么?引入redis新的复杂度?

    20.使用的定时器用的是什么?分布式定时任务?

    21.springCloud常用的组件有哪些?

    22.HashMap和Hashtable区别

    23.@Resource和@Autoware区别

    24.Spring bean生命周期

    25.雪崩和透崩

     

    展开全文
    xiao297328 2021-04-21 21:07:50
  • 3.24MB junjiemysqldba 2021-03-15 15:52:32
  • 今天不当DJ了,改当面试官。 人称杰克马

    前言

    一碗酸辣汤,耳闻口讲的,总不如亲自呷一口的明白。

    本篇主要是我整理的集合面试题,
    其中有面试官问我的或者网上收集整理的

    当然大佬们可以看看我整理的系列:光头佳的求职之旅

    https://blog.csdn.net/u013351145/category_11030408.html

    面试

    在这里插入图片描述
    我已经在会议室等待了30分钟,
    眉头紧锁仿佛是在思考哥德巴赫猜想,
    在这里插入图片描述
    其实无聊的我脑中正在思考这家前台小姐姐和上一家前台小姐姐那个好看,
    有道是窥一斑而知全豹,处一隅而观全局,
    通过前台颜值就可以知道这家公司的平均水准。
    “咔嚓”
    一声开门声将我从幻想拉回现实世界,
    “您好”x2
    我和面试官异口同声,同时我快速扫视了一下面试官,
    “蓝色牛仔裤,黑色体恤,小山羊胡子,
    牙齿很白不知道用的什么牙膏,黑眼圈有些重看来加班偏多呀”。
    这时面试官估计也在打量我,闪闪发光的头在无形中宣示我的实力,
    “先介绍一下自己”,面试官上下翻着我的简历,
    “我叫光头佳,在…”,
    “再介绍一下最近你开发的项目吧”,
    “好的,我最近开发项目是…”,
    经过自我介绍和项目介绍,之后面试官又询问了我一些项目中业务逻辑,
    和他不理解的地方,
    这个时候你只需要将自己了解的业务需求讲明白就行
    毕竟合不合理,关我开发何事
    接着来终于要进入技术面试

    Q:业务逻辑问的差不多了,我再问一些技术方面的问题
    A:好的,您问。

    Q:你们开发的JDK版本是多少?
    A:目前使用的是1.8版本

    Q: 哦哦,那ArrayList和LinkedList有什么区别?
    A:ArrayList数据结构是数组,继承List接口而LinkedList是链表结构除了继承List接口还有Deque接口。

    Q: ArrayList和LinkedList那个查询速度快?
    A:ArrayList查询快,插入慢,LinkedList查询慢,插入快。

    Q: 那为啥会这样?
    A:ArrayList是数组结构,数组上有索引可以直接映射到具体数据,而LinkedList是链表结构查询数据的时候需要循环遍历移动指针一一排查。

    Q:你看过源码没?
    A:那必须的

    Q:你了解ArrayList是如何扩容,啥时候扩容,每次扩容多少?
    A:ArrayList初始默认长度是10,超过10之后会触发第一次扩容,每次扩容原数组长度1.5倍。
    是调用ArrayCopy方法,通过数组复制形式来实现扩容。

    Q:ArrayList如何实现序列化安全的?
    A:有一个叫modCount参数,记录每次的修改,将修改次数+1,
    如发现修改次数和开始序列化前不一致就会抛出异常,序列化失败。
    这样就保证了序列化过程中是未经修改的数据,保证了序列化安全。

    在这里插入图片描述

    面试官心想:这小伙子不错,但是ArrayList比较简单,再问问HashMap,先拿Set试试水。

    我:太简单了,下面该问HashMap了吧

    Q: Set和List有什么差别?
    A: Set是无序且不可重复的而List正好相反

    Q:那么HashSet是怎么实现不可重复的?
    A:HashSet是通过HashMap实现不可重复的,每次写入将新元素作为key放入HashMap,Value为统一默认的PRESENT,
    出现重复Key的时候,原来的元素也不会有任何改变。

    Q:既然说到了HashMap,它支持哪些数据结构?
    A:HashMap支持数组、链表、红黑树。

    Q:它们之间如何转化你清楚吗?
    A:HashMap初始化默认数组长度16,当出现Hash冲突的时候采用拉链法将数组转化为链表,当链表长度超过8且容量达到64就会转化为红黑树。

    Q:一般我们知道数组的长度是2^31,为啥HashMap的数组只有30次方?
    A:由于二进制数字中最高的一位也就是最左边的一位是符号位,
    用来表示正负之分(0为正,1为负),所以只能向左移动30位,而不能移动到处在最高位的符号位。

    Q:HashMap啥时候扩容?咋扩容的?
    A:HashMap默认加载因子0.75F,超过这个数量就会触发扩容,扩容2倍
    如果是数组结构就会调用ArrayCopy方法,采用数组复制形式与ArrayList一致,
    如果是链表结构就会新创建一个2倍长度的链表,把旧链表放入新链表重新定位,
    如果是红黑树结构就会创建一个新树结构,把旧树节点放入,重新实现自平衡。

    Q:为啥选择加载因子0.75F,你知道吗?
    A:额,(⊙o⊙)… 我认为选择0.75F是查询速度与插入元素两者的平衡点,
    并且数据越多出现Hash冲突的概率越大,有人说是根据泊松分布来确定,
    我更觉得这样不会因为数据过多而导致查询偏慢也不会因为数据较少浪费空间。

    Q:那能简单说一下扩容步骤吗
    A:
    1.如果table == null, 则为HashMap的初始化, 生成空table返回即可;
    2. 如果table不为空, 需要重新计算table的长度, newLength = oldLength << 1
    3. 遍历旧table,如果首节点为空,跳出本次循环且无后续节点的情况下需要重新计算hash位,本次循环结束。
    4. 如果当前是红黑树结构TreeNode就走红黑树的重新定位
    5. 如果当前是链表通过(e.hash & oldCap) 为0判断是否需要移位,如果需要移位那么新的位置等于hash槽位(j)+oldCap位置。

    Q:为啥e.hash & oldCap == 0就可以判断是否需要移位
    A:
    因此 (n - 1) & hash的计算为1111&hash值,而hash值无论是什么,总归不是0就是1,所以1111&hash的最小值为0,最大值为1
    最后hash值肯定在当前table中能找到对应的位置。
    接着我们再推断oldCap的最高位是1,因为默认长度是16,每次扩容2的次幂

    例如16的二进制为10000,那么扩大2倍的容量就是32,二进制位是100000,最高位还是1。
    最后还剩下e.hash,如果e.hash最高是0,那么最后结果为0,如果是0,
    那么数组下标还是原来扩容前的数组下标。
    当(e.hash & oldCap) = 0时,直接把oldcap中存储该节点的下标,放到新数组同样的下标位置就可以了。
    如果(e.hash & oldCap)=1,那说明比原来计算的数组下标的位置大了2倍,因此新的下标是j + oldCap。

    Q:我们知道HashMap是线程不安全的,那你知道不安全在哪吗?
    A:在put方法中判断hash值处理下标位时候,
    假设在并发情况下,A,B两个元素都通过了判断,没有冲突,A先插入,
    接着B再插入,这个时候因为hash值一样,后插入的B会覆盖前面插入的A。
    这就是数据覆盖

    Q:那你有使用过线程安全的Map实现类吗?
    A:我有使用过ConcurrentHashMap

    Q:ConcurrentHashMap是如何保证线程安全的
    A:ConcurrentHashMap通过CAS算法和Synchronized关键字加锁的形式实现线程安全。

    Q: 集合掌握的不错,我再问问线程问题,创建线程有几种方式
    A
    在这里插入图片描述
    在这里插入图片描述

    稍等一下我去开时光机,下一秒再见

    在这里插入图片描述

    总结

    没啥好总结的,只能祝你找个事少、钱多、早九晚五从不加班的公司

    展开全文
    u013351145 2021-05-25 20:54:31
  • 3星
    10.12MB hahaandhaha 2021-03-15 10:13:03
  • 7KB weixin_38701156 2021-06-13 11:16:00
  • 5星
    253KB qq_16397653 2021-01-29 19:20:05
  • 一、Java基础面试题 二、Java 集合框架 三、Linux常用指令 四、MySQL基础面试 多线程与多进程面试 常见设计模式 JVM 底层 常用网络协议 常见的数据结构和算法 关注我们,更多技术干货: 2000多G的计算机...

    先罗列本篇文章包含的 Java 常见面试的主题:

    一、Java基础面试题

    二、Java 集合框架

    三、Linux常用指令

    四、MySQL基础面试


     

    • 多线程与多进程面试
    • 常见设计模式
    • JVM 底层

    关注我们,更多技术干货:

    2000多G的计算机各行业电子资源分享(持续更新)

    2020年微信小程序全栈项目之喵喵交友【附课件和源码】

    Spring Boot开发小而美的个人博客【附课件和源码】

    Java微服务实战296集大型视频-谷粒商城【附代码和课件】

    Java开发微服务畅购商城实战【全357集大项目】-附代码和课件

    最全最详细数据结构与算法视频-【附课件和源码】

    在这里插入图片描述

    2021年JAVA 精心整理的常见面试题-附详细答案

    https://mikejun.blog.csdn.net/article/details/114488339

    2021年- 精心整理的 SpringMVC 常见面试题-【附详细答案】

    https://mikejun.blog.csdn.net/article/details/114992529

    2021年JAVA 面试题之--数据结构篇【附详细答案】

    https://mikejun.blog.csdn.net/article/details/114647742

    精心整理的计算机各类别的电子书籍【超全】

    https://mikejun.blog.csdn.net/article/details/115442555

    三天刷完《剑指OFFER编程题》--Java版本实现(第一天)

    https://mikejun.blog.csdn.net/article/details/106996017

    三天刷完《剑指OFFER编程题》--Java版本实现(第二天)

    https://mikejun.blog.csdn.net/article/details/108098502

    三天刷完《剑指OFFER编程题》--Java版本实现(第三天)

    https://mikejun.blog.csdn.net/article/details/108253489

    一、Java基础面试题

    1. Java中 == 和 equals 的区别

    首先看一下 Java 的基本类型

    1.1  基本类型数据:

        

    byte,short,char,int,long,float,double,boolean 他们之间的比较应该使用(==),比较的是他们的值。

    equals 比较的是引用是否相同

            String s1 = "abc";
            String s2 = "abc";
            String s3 = new String("abc");
     
            System.out.println(s1 == s2); // true
            System.out.println(s1 == s3); // false
            System.out.println(s3.equals(s1)); // true


    1.2 引用类型数据:

    a, 当使用 == 比较的时候,比较的是 他们在内存中的存放地址。

    String a = "abc";
    String b = "abc";
    System.out.println(a == b);//true


    b, 当使用 equals 比较时,这个方法的初始行为是比较对象在堆内存中的地址。

    equals()方法是用来判断其他的对象是否和该对象相等.

    //equals()方法在object类中定义如下: 
    public boolean equals(Object obj) {  
        return (this == obj);  
    }  


    但在一些诸如String,Integer,Date类中把Object中的这个方法覆盖了,作用被覆盖为比较内容是否相同。

    Math、Integer、Double等这些类都是重写了equals()方法的,从而进行的是内容的比较,而不再是地址的比较。当然,基本类型是进行值的比较。

    String 的内存分配图

    String str1= "hello";   
    String str2= new String("hello");   
    String str3= str2;   


    从图中可以发现每个String对象的内容实际是保存到堆内存中的,而且堆中的内容是相等的,但是对于str1和str2来说所指向的地址堆内存地址是不等的,所以尽管内容是相等的,但是地址值是不相等的
    “==”是用来进行数值比较的,所以str1和str2比较不相等,因为str2和str3指向同一个内存地址所以str2和str3是相等的。所以“==”是用来进行地址值比较的。

    2. 如何Java 重写equals()  方法

    重写 equals()方法的模板:

    package MyDemo;
    
    import java.util.Objects;
    
    public class Human {
    
        private int age;
        private String name;
    
        public Human(int age, String neme){
            this.age = age;
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int hashCode(){
            return Objects.hash(age, name);
        }
    
        public boolean equals(Object obj){
    
            // 测试两个对象是否相同
            if (this == obj) return true;
    
            // 检测对象是否为空
            if (obj == null) return false;
    
            //  检测两个对象所属于的类是否相同;
            if (this.getClass() != obj.getClass()) return false;
    
            //  对 otherObject 进行类型转换和 类 Human 对象比较
            Human other = (Human)obj;
            return Objects.equals(name, other.name) && age == other.age;
        }
    
        public static void main(String[] args) {
    
            Human human = new Human(14, "zhangsan");
            Human human1 = new Human(14, "zhangsan");
    
            System.out.println(human.equals(human1));  // 初始没有重写equals 为false
            System.out.println(human.hashCode());
            System.out.println(human1.hashCode());  // 如果 name 和 age 都是相同的话,哈希值相同
    
    
        }
    
    }
    

    为什么重写equals方法之前要重写hashCode方法:

    因为 Object规范中说到: 相等的对象必须具有相等的散列码
    因为hashCode散列码的目的是为了HashSet、HashMap、HashTable比较的时候缩小范围空间,它只是返回一个散列整数然后根据散列码去散列桶中查找对象区间。它不保证对象是否是相等的

    3. 抽象类和接口的区别

    1. 抽象类:

    抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类作为很多子类的父类,它是一种模板式设计。

    抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,男人和女人都是属于人类,它们都有一些共性,比如有眼睛、鼻子、会走路等等,就可以把这些方法抽象出来。

    继承是一个 "是不是"的关系,如 男人 是不是 人类

    public abstract class Employee
    {
       private String name;
       private String address;
       private int number;
    
       public Employee(String name, String address, int number) // 构造方法
       {
          System.out.println("Constructing an Employee");
          this.name = name;
          this.address = address;
          this.number = number;
       }
    
       public double computePay()  // 自己实现的方法
       {
         System.out.println("Inside Employee computePay");
         return 0.0;
       }
       
       public abstract double computePay();  // 抽象方法
       
       //其余代码
    }

    1. 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样

    2. 抽象类相当于时定义一个类模板,是用来继承的,所以不能直接实例化

    3. 抽象类中的抽象方法只是声明,不给出方法的具体实现

    4. 如果类中有抽象方法,则必须是抽象类

    5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

    2. 接口:

    接口是一种行为规范,没有继承的关系,接口 实现则是 "有没有"的关系,比如 定义一个接口 Fly(),

    但 男人 这个类实现 飞 这个接口时,相当于拥有了这项 飞 的功能。所以,接口有扩展功能的作用。

    interface Animal {
       public static final String NAME = "god";
    
       public void eat();
       public void travel();
    }
    • 接口不能用于实例化对象。
    • 接口没有构造方法。
    • 接口中所有的方法必须是抽象方法。
    • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
    • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
    • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法,可以实现多继承。

    3. 抽象类和接口的区别

    • 1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
    • 2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
    • 3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
    • 4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

    4 说一说面向对象的特征

    包括有:封装,继承,多态和抽象

    封装

    封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。在 Java 当中,有 3 种修饰符: public, private 和 protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访问权限。

    下面列出了使用封装的一些好处:

    通过隐藏对象的属性来保护对象内部的状态。
    提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。
    禁止对象之间的不良交互,提高模块化继承


    继承

    给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用行,也可以在不修改类的情况下给现存的类添加新特性。

    多态

    多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力。一个多态类型上的操作可以应用到其他类型的值上面。

    抽象

    抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细节来创建类。

    Java 支持创建只暴漏接口而不包含方法实现的抽象的类。这种抽象技术的主要目的是把类的行为和实现细节分离开。

    5 重载和重写的区别

    override(重写)

    方法名、参数、返回值相同。

    子类方法不能缩小父类方法的访问权限。

    子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。

    存在于父类和子类之间。

    方法被定义为final不能被重写。

    overload(重载)

    参数类型、个数、顺序至少有一个不相同。

    不能重载只有返回值不同的方法名。

    存在于父类和子类、同类中。

    6 说说反射的用途及实现

    Java反射机制主要提供了以下功能:在运行时构造一个类的对象;判断一个类所具有的成员变量和方法;调用一个对象的方法;生成动态代理。反射最大的应用就是框架

    Java反射的主要功能:

    确定一个对象的类
    取出类的modifiers,数据成员,方法,构造器,和超类.
    找出某个接口里定义的常量和方法说明.
    创建一个类实例,这个实例在运行时刻才有名字(运行时间才生成的对象).
    取得和设定对象数据成员的值,如果数据成员名是运行时刻确定的也能做到.
    在运行时刻调用动态对象的方法.
    创建数组,数组大小和类型在运行时刻才确定,也能更改数组成员的值.

    反射的应用很多,很多框架都有用到

    spring 的 ioc/di 是反射….

    javaBean和jsp之间调用也是反射….

    struts的 FormBean 和页面之间…也是通过反射调用….

    JDBC 的 classForName()也是反射…..

    hibernate的 find(Class clazz) 也是反射….

    7 静态变量和实例变量的区别?


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

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

    8  访问修饰符public,private,protected,以及不写(默认)时的区别?

    修饰符当前类同 包子 类其他包
    public
    protected×
    default××
    private×××

    类的成员不写访问修饰时默认为default。默认对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。Java中,外部类的修饰符只能是public或默认,类的成员(包括内部类)的修饰符可以是以上四种。

    9  int、char、long各占多少字节数

    Java 基本类型占用的字节数

    1字节: byte , boolean

    2字节: short , char

    4字节: int , float

    8字节: long , double

    注:1字节(byte)=8位(bits)

    10  详细解释一下内部类


    内部类使得多重继承的解决方案变得更加完整
    使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响
    使用内部类才能实现多重继承

    内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
    在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
    创建内部类对象的时刻并不依赖于外围类对象的创建。
    内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
    内部类提供了更好的封装,除了该外围类,其他类都不能访问。

    当我们在创建某个外围类的内部类对象时,此时内部类对象必定会捕获一个指向那个外围类对象的引用,只要我们在访问外围类的成员时,就会用这个引用来选择外围类的成员

    成员内部类
    在成员内部类中要注意两点

    成员内部类中不能存在任何 static 的变量和方法
    成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类

    静态内部类

    静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:

    它的创建是不需要依赖于外围类的。
    它不能使用任何外围类的非static成员变量和方法。

    11  说明一下public static void main(String args[])这段声明里每个关键字的作用


    public: main方法是Java程序运行时调用的第一个方法,因此它必须对Java环境可见。所以可见性设置为pulic.

    static: Java平台调用这个方法时不会创建这个类的一个实例,因此这个方法必须声明为static。

    void: main方法没有返回值。

    String是命令行传进参数的类型,args是指命令行传进的字符串数组。
     

    12 为什么Java里没有全局变量?

    答案:全局变量是全局可见的,Java不支持全局可见的变量,因为:全局变量破坏了引用透明性原则。全局变量导致了命名空间的冲突。

    13. 如果不借助中间变量交换两个变量的值?

    先把两个值相加赋值给第一个变量,然后用得到的结果减去第二个变量,赋值给第二个变量。再用第一个变量减去第二个变量,同时赋值给第一个变量。代码如下:

    int a=5,b=10;a=a+b; b=a-b; a=a-b;

    使用异或操作也可以交换。第一个方法还可能会引起溢出。异或的方法如下:
    int a=5,b=10;a=a+b; b=a-b; a=a-b;

    int a = 5; int b = 10;
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;

    14 Java有没有goto?

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

    15 int和Integer有什么区别?

    答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
    Java 为每个原始类型提供了包装类型:
    - 原始类型: boolean,char,byte,short,int,long,float,double
    - 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

    class AutoUnboxingTest {
    
        public static void main(String[] args) {
            Integer a = new Integer(3);
            Integer b = 3;                  // 将3自动装箱成Integer类型
            int c = 3;
            System.out.println(a == b);     // false 两个引用没有引用同一对象
            System.out.println(a == c);     // true a自动拆箱成int类型再和c比较
        }
    }
    


    还有一个面试题,也是和自动装箱和拆箱有点关系的,代码如下所示:

    public class Test03 {
    
        public static void main(String[] args) {
            Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
    
            System.out.println(f1 == f2);
            System.out.println(f3 == f4);
        }
    }


    如果不明就里很容易认为两个输出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四个变量都是Integer对象引用,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,如果看看valueOf的源代码就知道发生了什么。

        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

    IntegerCache是Integer的内部类,其代码如下所示:

        private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }

    简单的说,如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。

    16 String能被继承吗?为什么?

    不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。平常我们定义的String str=”abc”(直接赋一个字面量);其实和String str=new String(“abc”)(通过构造器构造)还是有差异的。

    String str=“abc”和String str=new String(“abc”); 产生几个对象?
        1.前者1或0,后者2或1,先看字符串常量池,如果字符串常量池中没有,都在常量池中创建一个,如果有,前者直接引用,后者在堆内存中还需创建一个“abc”实例对象。
        2.对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。
        3.为了提升jvm(JAVA虚拟机)性能和减少内存开销,避免字符的重复创建 项目中还是不要使用new String去创建字符串,最好使用String直接赋值。

    17 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);
    }

    18 说一说常见的输入输出流

    计算机的存储器按用途可以分为主存储器和辅助存储器。

    a. 主存储器又称内存,是CPU能直接寻址的存储空间,它的特点是存取速率快。内存一般采用半导体存储单元,包括随机存储器(RAM)、只读存储器(ROM)和高级缓存(Cache)。

    b. 辅助存储器又称外存储器(简称外存),就是那些磁盘、硬盘、光盘,也就是你在电脑上看到的C、D、E、F盘。

     

    这里写图片描述

    根据处理数据类型的不同分为:字符流和字节流

    字节流和字符流的区别:

    • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

    • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

    • 字节流:一次读入或读出是8位二进制。

    • 字符流:一次读入或读出是16位二进制。

    设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。

    结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

    输入流只能进行读操作,输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

    19 说一说java 中的文件类 File

    在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。File类不同于输入输出流,它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

    File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。构造函数:
    1)File (String   pathname)   

         例:File  f1=new File("FileTest1.txt");    //创建文件对象f1,f1 所指的文件是在当前目录下创建的FileTest1.txt
    2)File (String  parent  ,  String child)

         例:File f2 = new  File(“D:\\dir1","FileTest2.txt") ;  //  注意:D:\\dir1目录事先必须存在,否则异常
    3)File (File    parent  , String child)
         例:File  f4=new File("\\dir3");
              File  f5=new File(f4,"FileTest5.txt");  // 在如果 \\dir3目录不存在使用 f4.mkdir()先创建

    一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。    

           1)public boolean exists( )              判断文件或目录是否存在
           2)public boolean isFile( )               判断是文件还是目录 
           3)public boolean isDirectory( )      判断是文件还是目录
           4)public String getName( )            返回文件名或目录名
           5)public String getPath( )              返回文件或目录的路径。
           6)public long length( )                   获取文件的长度 
           7)public String[ ] list ( )                  将目录中所有文件名保存在字符串数组中返回。 

    File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:


           1) public boolean renameTo( File newFile );         重命名文件
           2) public void delete( );                                         删除文件
           3)  public boolean mkdir( );                                   创建目录

    20  如何选择IO 流:

    1)确定是 输入还是输出

                  输入流: InputStream Reader
                  输出流: OutputStream Writer

    2)明确操作的数据对象是否是纯文本

                 是: 字符流Reader,Writer
                 否: 字节流InputStream,OutputStream

    3)明确具体的设备

    硬盘文件:

                 读取:FileInputStream,, FileReader, 

                  写入:FileOutputStream,FileWriter
    内存用数组:

                      byte[]:ByteArrayInputStream, ByteArrayOutputStream
                      是char[]:CharArrayReader, CharArrayWriter

    键盘:

                     用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印

    4)是否需要缓冲提高效率

           加上Buffered:BufferedInputStream, BufferedOuputStream, BuffereaReader, BufferedWriter

    21 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

    不对,两个对象的 hashCode()相同,equals()不一定 true。

    代码示例:

    String str1 = "通话";
    String str2 = "重地";
    System.out.println(String.format("str1:%d | str2:%d",  str1.hashCode(),str2.hashCode()));
    System.out.println(str1.equals(str2));

    执行的结果:

    str1:1179395 | str2:1179395

    false

    代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。

    22 String 类的常用方法都有那些?

    • indexOf():返回指定字符的索引。
    • charAt():返回指定索引处的字符。
    • replace():字符串替换。
    • trim():去除字符串两端空白。
    • split():分割字符串,返回一个分割后的字符串数组。
    • getBytes():返回字符串的 byte 类型数组。
    • length():返回字符串长度。
    • toLowerCase():将字符串转成小写字母。
    • toUpperCase():将字符串转成大写字符。
    • substring():截取字符串。
    • equals():字符串比较。

    23 BIO、NIO、AIO 有什么区别?

    • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
    • NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
    • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

    二、Java 集合框架

    1. 请先介绍一下java 结合框架

    1、List(有序、可重复)

    List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

    List是列表类型,以线性方式存储对象,自身的方法都与索引有关,个别常用方法如下。

    方法返回值功能描述
    add(int index, Object obj)void用来向集合中的指定索引位置添加对象,集合的索引位置从0开始,其他对象的索引位置相对向后移一位
    set(int index, E element)Object用指定元素替换列表中指定位置的元素,返回以前在指定位置的元素
    indexOf(Object obj)int返回列表中对象第一次出现的索引位置,如果集合中不包含该元素则返回-1
    lastIndexOf(Object obj)int返回列表中对象最后一次出现的索引位置,如果集合汇总不包含该元素则返回-1
    listIterator()ListIterator用来获得一个包含所有对象的ListIterator迭代器

    2、Set(无序、不能重复)

    Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

    Set接口常用方法如下

    方法返回值功能描述
    add(Object obj)boolean若集合中尚存在未指定的元素,则添加此元素
    addAll(Collection col)boolean将参数集合中所有元素添加到集合的尾部
    remove(Object obj)boolean将指定的参数对象移除
    clear()void移除此Set中的所有元素
    iterator()Iterator返回此Set中的元素上进行迭代的迭代器
    size()int返回此Set集合中的所有元素数
    isEmpty()boolean如果Set不包含元素,则返回true

    3、Map(键值对、键唯一、值不唯一)

    Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对 map  集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

    Map接口提供了将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射一个值。Map接口同样提供了clear()、isEmpty()、size()等方法,还有一些常用方法如下:

    方法返回值功能描述
    put(key k, value v)Object向集合中添加指定的key与value的映射关系
    get(Object key)boolean如果存在指定的键对象,则返回该对象对应的值,否则返回null
    values()Collection返回该集合中所有值对象形成的Collection集合

     

    1. Interface Iterable
    迭代器接口,这是Collection类的父接口。实现这个Iterable接口的对象允许使用foreach进行遍历,也就是说,所有的Collection集合对象都具有"foreach可遍历性"。这个Iterable接口只有一个方法: iterator()。它返回一个代表当前集合对象的泛型<T>迭代器,用于之后的遍历操作
    1.1 Collection
    Collection是最基本的集合接口,一个Collection代表一组Object的集合,这些Object被称作Collection的元素。Collection是一个接口,用以提供规范定义,不能被实例化使用
        1) Set
        Set集合类似于一个罐子,"丢进"Set集合里的多个对象之间没有明显的顺序。Set继承自Collection接口,不能包含有重复元素(记住,这是整个Set类层次的共有属性)。
        Set判断两个对象相同不是使用"=="运算符,而是根据equals方法。也就是说,我们在加入一个新元素的时候,如果这个新元素对象和Set中已有对象进行注意equals比较都返回false,     则Set就会接受这个新元素对象,否则拒绝。
        因为Set的这个制约,在使用Set集合的时候,应该注意两点:1) 为Set集合里的元素的实现类实现一个有效的equals(Object)方法、2) 对Set的构造函数,传入的Collection参数不能包  含重复的元素
            1.1) HashSet
            HashSet是Set接口的典型实现,HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和查找性能。当向HashSet集合中存入一个元素时,HashSet会调用该对象的     hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值决定该对象在HashSet中的存储位置。
            值得主要的是,HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法的返回值相等
                1.1.1) LinkedHashSet
                LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但和HashSet不同的是,它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。       当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
                LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时(遍历)将有很好的性能(链表很适合进行遍历)
            1.2) SortedSet    
            此接口主要用于排序操作,即实现此接口的子类都属于排序的子类
                1.2.1) TreeSet
                TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态
            1.3) EnumSet
            EnumSet是一个专门为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式、或隐式地指定。EnumSet的集合元素也是有序的,     它们以枚举值在Enum类内的定义顺序来决定集合元素的顺序
        2) List
        List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许加入重复元素,因为它可以通过索引来访问指定位置的集合元素。List集合默认按元素   的添加顺序设置元素的索引
            2.1) ArrayList
            ArrayList是基于数组实现的List类,它封装了一个动态的增长的、允许再分配的Object[]数组。
            2.2) Vector
            Vector和ArrayList在用法上几乎完全相同,但由于Vector是一个古老的集合,所以Vector提供了一些方法名很长的方法,但随着JDK1.2以后,java提供了系统的集合框架,就将     Vector改为实现List接口,统一归入集合框架体系中
                2.2.1) Stack
                Stack是Vector提供的一个子类,用于模拟"栈"这种数据结构(LIFO后进先出)
            2.3) LinkedList
            implements List<E>, Deque<E>。实现List接口,能对它进行队列操作,即可以根据索引来随机访问集合中的元素。同时它还实现Deque接口,即能将LinkedList当作双端队列     使用。自然也可以被当作"栈来使用"
        3) Queue
        Queue用于模拟"队列"这种数据结构(先进先出 FIFO)。队列的头部保存着队列中存放时间最长的元素,队列的尾部保存着队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,   访问元素(poll)操作会返回队列头部的元素,队列不允许随机访问队列中的元素。结合生活中常见的排队就会很好理解这个概念
            3.1) PriorityQueue
            PriorityQueue并不是一个比较标准的队列实现,PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序,这点从它的类名也可以 看出来
            3.2) Deque
            Deque接口代表一个"双端队列",双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可以当成队列使用、也可以当成栈使用
                3.2.1) ArrayDeque
                是一个基于数组的双端队列,和ArrayList类似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出该数组的容量时,系统会在底层重新分配一个Object[]数组来存储集合元素
                3.2.2) LinkedList
    1.2 Map
    Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value。key和value都可以是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较结果总是返回false。
    关于Map,我们要从代码复用的角度去理解,java是先实现了Map,然后通过包装了一个所有value都为null的Map就实现了Set集合
    Map的这些实现类和子接口中key集的存储形式和Set集合完全相同(即key不能重复)
    Map的这些实现类和子接口中value集的存储形式和List非常类似(即value可以重复、根据索引来查找)
        1) HashMap
        和HashSet集合不能保证元素的顺序一样,HashMap也不能保证key-value对的顺序。并且类似于HashSet判断两个key是否相等的标准也是: 两个key通过equals()方法比较返回true、   同时两个key的hashCode值也必须相等
            1.1) LinkedHashMap
            LinkedHashMap也使用双向链表来维护key-value对的次序,该链表负责维护Map的迭代顺序,与key-value对的插入顺序一致(注意和TreeMap对所有的key-value进行排序进行区分)
        2) Hashtable
        是一个古老的Map实现类
            2.1) Properties 
            Properties对象在处理属性文件时特别方便(windows平台上的.ini文件),Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的key-value对写入到属性文     件中,也可以把属性文件中的"属性名-属性值"加载到Map对象中
        3) SortedMap
        正如Set接口派生出SortedSet子接口,SortedSet接口有一个TreeSet实现类一样,Map接口也派生出一个SortedMap子接口,SortedMap接口也有一个TreeMap实现类
            3.1) TreeMap
            TreeMap就是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点。TreeMap存储key-value对(节点)时,需要根据key对节点进行排序。TreeMap可以保证所有的     key-value对处于有序状态。同样,TreeMap也有两种排序方式: 自然排序、定制排序
        4) WeakHashMap
        WeakHashMap与HashMap的用法基本相似。区别在于,HashMap的key保留了对实际对象的"强引用",这意味着只要该HashMap对象不被销毁,该HashMap所引用的对象就不会被垃圾回收。  但WeakHashMap的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,当垃  圾回收了该key所对应的实际对象之后,WeakHashMap也可能自动删除这些key所对应的key-value对
        5) IdentityHashMap
        IdentityHashMap的实现机制与HashMap基本相似,在IdentityHashMap中,当且仅当两个key严格相等(key1 == key2)时,IdentityHashMap才认为两个key相等
        6) EnumMap
        EnumMap是一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值。创建EnumMap时必须显式或隐式指定它对应的枚举类。EnumMap根据key的自然顺序  (即枚举值在枚举类中的定义顺序)

    2 Vector和ArrayList的区别

    1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。

    2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%。如果在集合中使用数据量比较大的数据,用vector有一定的优势。

    3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,如果频繁的访问数据,这个时候使用vector和arraylist都可以。而如果移动一个指定位置会导致后面的元素都发生移动,这个时候就应该考虑到使用linkedlist,因为它移动一个指定位置的数据时其它元素不移动。

    ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据快,插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快。

    3  arraylist和linkedlist的区别

    1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

    2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

    3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

    4 HashMap与TreeMap的区别

    1、 HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

    2、在Map 中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。

    两个map中的元素一样,但顺序不一样,导致hashCode()不一样。

    同样做测试:

    在HashMap中,同样的值的map,顺序不同,equals时,false;

    而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。

    5 HashTable与HashMap的区别

    1、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的。

    2、HashMap允许存在一个为null的key,多个为null的value 。

    3、hashtable的key和value都不允许为null。

    6. 常用的集合类有哪些?

    Map接口和Collection接口是所有集合框架的父接口:

    1. Collection接口的子接口包括:Set接口和List接口
    2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
    3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
    4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

    7. List,Set,Map三者的区别?List、Set、Map 是否继承自 Collection 接口?List、Map、Set 三个接口存取元素时,各有什么特点?

    image.png

    Java 容器分为 Collection 和 Map 两大类,Collection集合的子接口有Set、List、Queue三种子接口。我们比较常用的是Set、List,Map接口不是collection的子接口。

    Collection集合主要有List和Set两大接口

    • List:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
    • Set:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及 TreeSet。

    Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重复。Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。

    Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap

    8. 集合框架底层数据结构

    Collection

    1. List
    • Arraylist: Object数组
    • Vector: Object数组
    • LinkedList: 双向循环链表
    1. Set
    • HashSet(无序,唯一):基于 HashMap 实现的,底层采用 HashMap 来保存元素
    • LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
    • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)

    Map

    • HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
    • LinkedHashMap:LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
    • HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
    • TreeMap: 红黑树(自平衡的排序二叉树)

    9. 哪些集合类是线程安全的?

    • vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。
    • statck:堆栈类,先进后出。
    • hashtable:就比hashmap多了个线程安全。
    • enumeration:枚举,相当于迭代器。

    10. 怎么确保一个集合不能被修改?

    可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。

    示例代码如下:

    List<String> list = new ArrayList<>();
    list. add("x");
    Collection<String> clist = Collections. unmodifiableCollection(list);
    clist. add("y"); // 运行时此行报错
    System. out. println(list. size());
    
    

    11. 迭代器 Iterator 是什么?

    Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程中移除元素。

    Iterator 使用代码如下:

    List<String> list = new ArrayList<>();
    Iterator<String> it = list. iterator();
    while(it. hasNext()){
      String obj = it. next();
      System. out. println(obj);
    }
    
    

    Iterator 的特点是只能单向遍历,但是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。

    12 说一下 ArrayList 的优缺点

    ArrayList的优点如下:

    • ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。
    • ArrayList 在顺序添加一个元素的时候非常方便。

    ArrayList 的缺点如下:

    • 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
    • 插入元素的时候,也需要做一次元素复制操作,缺点同上。

    ArrayList 比较适合顺序添加、随机访问的场景。

    13. 如何实现数组和 List 之间的转换?

    • 数组转 List:使用 Arrays. asList(array) 进行转换。
    • List 转数组:使用 List 自带的 toArray() 方法。

    代码示例:

    // list to array
    List<String> list = new ArrayList<String>();
    list.add("123");
    list.add("456");
    list.toArray();
    
    // array to list
    String[] array = new String[]{"123","456"};
    Arrays.asList(array);
    
    

    14. 插入数据时,ArrayList、LinkedList、Vector谁速度较快?阐述 ArrayList、Vector、LinkedList 的存储性能和特性?

    ArrayList、LinkedList、Vector 底层的实现都是使用数组方式存储数据。数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。

    Vector 中的方法由于加了 synchronized 修饰,因此 Vector 是线程安全容器,但性能上较ArrayList差

    LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但插入数据时只需要记录当前项的前后项即可,所以 LinkedList 插入速度较快

    15. 多线程场景下如何使用 ArrayList?

    ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用。例如像下面这样:

    List<String> synchronizedList = Collections.synchronizedList(list);
    synchronizedList.add("aaa");
    synchronizedList.add("bbb");
    
    for (int i = 0; i < synchronizedList.size(); i++) {
        System.out.println(synchronizedList.get(i));
    }
    
    

    15.HashSet如何检查重复?HashSet是如何保证数据不可重复的?

    向HashSet 中add ()元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合equles 方法比较。
    HashSet 中的add ()方法会使用HashMap 的put()方法。

    HashMap 的 key 是唯一的,由源码可以看出 HashSet 添加进去的值就是作为HashMap 的key,并且在HashMap中如果K/V相同时,会用新的V覆盖掉旧的V,然后返回旧的V。所以不会重复( HashMap 比较key是否相等是先比较hashcode 再比较equals )。

    以下是HashSet 部分源码:

    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    public boolean add(E e) {
        // 调用HashMap的put方法,PRESENT是一个至始至终都相同的虚值
    	return map.put(e, PRESENT)==null;
    }
    
    

    hashCode()与equals()的相关规定

    1. 如果两个对象相等,则hashcode一定也是相同的
    2. 两个对象相等,对两个equals方法返回true
    3. 两个对象有相同的hashcode值,它们也不一定是相等的
    4. 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
    5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

    ==与equals的区别

    1. ==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同
    2. ==是指对内存地址进行比较 equals()是对字符串的内容进行比较3.==指引用是否相同 equals()指的是值是否相同

    15.BlockingQueue是什么?

    Java.util.concurrent.BlockingQueue是一个队列,在进行检索或移除一个元素的时候,它会等待队列变为非空;当在添加一个元素时,它会等待队列中的可用空间。BlockingQueue接口是Java集合框架的一部分,主要用于实现生产者-消费者模式。我们不需要担心等待生产者有可用的空间,或消费者有可用的对象,因为它都在BlockingQueue的实现类中被处理了。Java提供了集中BlockingQueue的实现,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,、SynchronousQueue等。

    15. 说一下 HashMap 的实现原理?

    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

    HashMap的数据结构: 在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

    HashMap 基于 Hash 算法实现的

    1. 当我们往Hashmap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
    2. 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中
    3. 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
    4. 理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。

    需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)

    16. HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底层实现

    在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做拉链法的方式可以解决哈希冲突。

    JDK1.8之前

    JDK1.8之前采用的是拉链法。拉链法:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。

    jdk1.7中HashMap数据结构

    JDK1.8之后

    相比于之前的版本,jdk1.8在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。

    jdk1.8中HashMap数据结构

    JDK1.7 VS JDK1.8 比较

    JDK1.8主要解决或优化了一下问题:

    1. resize 扩容优化
    2. 引入了红黑树,目的是避免单条链表过长而影响查询效率,红黑树算法请参考
    3. 解决了多线程死循环问题,但仍是非线程安全的,多线程时可能会造成数据丢失问题。
    不同JDK 1.7JDK 1.8
    存储结构数组 + 链表数组 + 链表 + 红黑树
    初始化方式单独函数:inflateTable()直接集成到了扩容函数resize()
    hash值计算方式扰动处理 = 9次扰动 = 4次位运算 + 5次异或运算扰动处理 = 2次扰动 = 1次位运算 + 1次异或运算
    存放数据的规则无冲突时,存放数组;冲突时,存放链表无冲突时,存放数组;冲突 & 链表长度 < 8:存放单链表;冲突 & 链表长度 > 8:树化并存放红黑树
    插入数据方式头插法(先讲原位置的数据移到后1位,再插入数据到该位置)尾插法(直接插入到链表尾部/红黑树)
    扩容后存储位置的计算方式全部按照原来方法进行计算(即hashCode ->> 扰动函数 ->> (h&length-1))按照扩容后的规律计算(即扩容后的位置=原位置 or 原位置 + 旧容量)

    17. HashMap是怎么解决哈希冲突的?

    答:在解决这个问题之前,我们首先需要知道什么是哈希冲突,而在了解哈希冲突之前我们还要知道什么是哈希才行;

    什么是哈希?

    Hash,一般翻译为“散列”,也有直接音译为“哈希”的,这就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值);这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数

    所有散列函数都有如下一个基本特性**:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同**。

    什么是哈希冲突?

    当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把它叫做碰撞(哈希碰撞)

    HashMap的数据结构

    在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做链地址法的方式可以解决哈希冲突:

    image.png

    这样我们就可以将拥有相同哈希值的对象组织成一个链表放在hash值所对应的bucket下,但相比于hashCode返回的int类型,我们HashMap初始的容量大小DEFAULT_INITIAL_CAPACITY = 1 << 4(即2的四次方16)要远小于int类型的范围,所以我们如果只是单纯的用hashCode取余来获取对应的bucket这将会大大增加哈希碰撞的概率,并且最坏情况下还会将HashMap变成一个单链表,所以我们还需要对hashCode作一定的优化

    hash()函数

    上面提到的问题,主要是因为如果使用hashCode取余,那么相当于参与运算的只有hashCode的低位,高位是没有起到任何作用的,所以我们的思路就是让hashCode取值出的高位也参与运算,进一步降低hash碰撞的概率,使得数据分布更平均,我们把这样的操作称为扰动,在JDK 1.8中的hash()函数如下:

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);// 与自己右移16位进行异或运算(高低位异或)
    }
    
    

    这比在JDK 1.7中,更为简洁,相比在1.7中的4次位运算,5次异或运算(9次扰动),在1.8中,只进行了1次位运算和1次异或运算(2次扰动)

    JDK1.8新增红黑树

    image.png

    通过上面的链地址法(使用散列表)扰动函数我们成功让我们的数据分布更平均,哈希碰撞减少,但是当我们的HashMap中存在大量数据时,加入我们某个bucket下对应的链表有n个元素,那么遍历时间复杂度就为O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn);

    总结

    简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的:

    1. 使用链地址法(使用散列表)来链接拥有相同hash值的数据;
    2. 使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均;
    3. 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快;

    18. 如果使用Object作为HashMap的Key,应该怎么办呢?

    答:重写hashCode()equals()方法

    1. 重写hashCode()是因为需要计算存储数据的存储位置,需要注意不要试图从散列码计算中排除掉一个对象的关键部分来提高性能,这样虽然能更快但可能会导致更多的Hash碰撞;
    2. 重写equals()方法,需要遵守自反性、对称性、传递性、一致性以及对于任何非null的引用值x,x.equals(null)必须返回false的这几个特性,目的是为了保证key在哈希表中的唯一性

    19. HashMap 与 HashTable 有什么区别?

    1. 线程安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);
    2. 效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它;
    3. 对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛NullPointerException。
    4. **初始容量大小和每次扩充容量大小的不同 **: ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。
    5. 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。
    6. 推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

    20. ConcurrentHashMap 和 Hashtable 的区别?

    ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。

    • 底层数据结构: JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
    • 实现线程安全的方式(重要): ① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16个Segment,比Hashtable效率提高16倍。) 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。

    两者的对比图

    HashTable:

    image.png

    JDK1.7的ConcurrentHashMap:

    image.png

    JDK1.8的ConcurrentHashMap(TreeBin: 红黑二叉树节点 Node: 链表节点):

    image.png

    答:

    ConcurrentHashMap 结合了 HashMap 和 HashTable 二者的优势。

    HashMap 没有考虑同步,HashTable 考虑了同步的问题。

    但是 HashTable 在每次同步执行时都要锁住整个结构。 ConcurrentHashMap 锁的方式是稍微细粒度的。

    21. TreeMap 和 TreeSet 在排序时如何比较元素?Collections 工具类中的 sort()方法如何比较元素?

    TreeSet 要求存放的对象所属的类必须实现 Comparable 接口,该接口提供了比较元素的 compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap 要求存放的键值对映射的键必须实现 Comparable 接口从而根据键对元素进 行排 序。

    Collections 工具类的 sort 方法有两种重载的形式,

    第一种要求传入的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较;

    第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java 中对函数式编程的支持)。

    三、Linux常用指令

    1. 常见命令

    ctrl c 退出当前执行
    cd ..  返回到上一级目录中
    cd ~   返回到根目录中 或者是 cd (加个空格)
    cd  -  返回进入此目录之前所在的目录
    exit 退出

    2. 常见的操作文件,文件夹的命令

    #  ls — List : 列举出当前工作目录的内容(文件或文件夹) 
    ls -l # 查看文件名称和 文件的权限
    ls -a # 显示全部的文件,包括隐藏的文件

    #  clear : 清除当前命令

    #  mkdir — Make Directory : 创建一个新文件夹

    #  rmdir— Remove Directory : 删除一个文件夹

    #  pwd — Print Working Directory : 显示当前目录

    #  cd — Change Directory : 切换文件路径,cd 将给定的文件夹(或目录)设置成当前工作目录

    #  rm— Remove : 删除指定的文件。 在linux没有回收站,删除之后无法恢复

    rm -rf 文件(r递归删除,f直接强行删除)
    #  sudo rm -r hadoop # 删除文件夹下的所有文件

    #  vi : 创建一个文件 vi test.txt
    # 一种比较方便打开文件的方式
    sudo gedit + 文件

    >是覆盖,>> 是追加
    #  echo >: 向已有的文件中增加内容, echo "added contents" >>test.txt

    #  echo >>: 覆盖文件内容,若不存在则创建一个新的文件 echo "new file" >newFile.txt

    #  cat— concatenate and print files : 显示一个文件 cat test.txt

    #  less, more : 如果文件太大,分页显示一个文件,按Q 结束浏 览

    #  tail : 显示文件的最后 10 行, tail -n 5 test.txt 显示最后5 行

    #  touch : 创建一个新的空的文件,不直接进行编辑

    #  cp— Copy : 对文件进行复制 ;例子: cp test.txt ../jun2

    #  mv— Move : 对文件或文件夹进行移动

    mv hello.csv ./python:把当前目录的hello.csv剪切到当前目的python文件夹里

    #  grep : 在文件中查找指定的字符; grep fun test.txt

    #  tar : tar命令能创建、查看和提取tar压缩文件。
    tar -cvf 是创建对应压缩文件, tar -cvf test.tar test.txt  # 将test.txt 压缩为 test.tar
    tar -tvf 来查看对应压缩文件,
    tar -xvf 来提取对应压缩文件

    #  mkdir — Make Directory : 创建一个新目录
    #  mkdir — Make Directory : 创建一个新目录
    #  mkdir — Make Directory : 创建一个新目录

    3. 软件下载安装

    sudo apt-get update    # 更新一下软件源,获取最新软件的列表
    sudo apt-get install gedit(软件名)    # 安装软件

    4. 系统重启和关机指令

    #  reboot : 立刻进行重启
    #  shutdown -r now : 立刻进行重启
    #  shutdown -r 10 : 10分钟后进行重启

    # 关机命令
    #  halt : 立刻关机
    #  poweroff : 立刻关机
    #  shutdown -h now : 立刻关机

    5. 文件模式和访问权限

    #  chmod (change mode) :命令来改变文件或目录的访问权限

    -rwxr-xr--  : 含义表示
    第一列的字符可以分为三组,每一组有三个,每个字符都代表不同的权限,分别为读取(r)、写入(w)和执行(x):
    u 第一组字符(2-4)表示文件所有者的权限,-rwxr-xr-- 表示所有者拥有读取(r)、写入(w)和执行(x)的权限。
    g 第二组字符(5-7)表示文件所属用户组的权限,-rwxr-xr-- 表示该组拥有读取(r)和执行(x)的权限,但没有写入权限。
    o 第三组字符(8-10)表示所有其他用户的权限,rwxr-xr-- 表示其他用户只能读取(r)文件。

    目录的访问模式为:
    读取:用户可以查看目录中的文件
    写入:用户可以在当前目录中删除文件或创建文件
    执行:执行权限赋予用户遍历目录的权利,例如执行 cd 和 ls 命令。(只是对于目录而言)

    #  chmod o=rwx anoterDir : 设置其他用户的权限,o, 
    - 表示删除权限, + 表示增加权限

    6. 环境变量

    # 常见的环境环境变量。 输入的形式为: echo $Home
    #--- 使用 env 显示所有的环境变量 
    HOME:指定用户的主工作目录    ,如: echo $Home
    LOGNAME:指当前用户的登录名
    HOSTNAME:指主机的名称
    LANG/LANGUGE:和语言相关的环境变量

    vim ~/.bashrc      #进行环境配置
    source ~/.bashrc   # 使配置立即生效


    export 设置一个新的环境变量 export HELLO="hello" (可以无引号)
    unset 清除环境变量 unset HELLO

    7. ubuntu登陆到mysql

    (登陆到mysql中)
    #---启动和终止mysql-----
    service mysql start

    service mysql restart
    service mysql stop

    #---打开mysql的shell命令
    mysql -u root -p

    四、MySQL基础面试

    1. 三个范式是什么

    第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
    第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。
    第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段x → 非关键字段y

    上面的文字我们肯定是看不懂的,也不愿意看下去的。接下来我就总结一下:

    • 首先要明确的是:满足着第三范式,那么就一定满足第二范式、满足着第二范式就一定满足第一范式
    • 第一范式:字段是最小的的单元不可再分

      • 学生信息组成学生信息表,有年龄、性别、学号等信息组成。这些字段都不可再分,所以它是满足第一范式的
    • 第二范式:满足第一范式,表中的字段必须完全依赖于全部主键而非部分主键。

      • 其他字段组成的这行记录和主键表示的是同一个东西,而主键是唯一的,它们只需要依赖于主键,也就成了唯一的
      • 学号为1024的同学,姓名为Java3y,年龄是22岁。姓名和年龄字段都依赖着学号主键。
    • 第三范式:满足第二范式,非主键外的所有字段必须互不依赖

      • 就是数据只在一个地方存储,不重复出现在多张表中,可以认为就是消除传递依赖
      • 比如,我们大学分了很多系(中文系、英语系、计算机系……),这个系别管理表信息有以下字段组成:系编号,系主任,系简介,系架构。那我们能不能在学生信息表添加系编号,系主任,系简介,系架构字段呢?不行的,因为这样就冗余了,非主键外的字段形成了依赖关系(依赖到学生信息表了)!正确的做法是:学生表就只能增加一个系编号字段。

    2. 什么是事务?

    事务简单来说:一个Session中所进行所有的操作,要么同时成功,要么同时失败

    ACID — 数据库事务正确执行的四个基本要素

    • 包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

    一个支持事务(Transaction)中的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易。

    举个例子:A向B转账,转账这个流程中如果出现问题,事务可以让数据恢复成原来一样【A账户的钱没变,B账户的钱也没变】。

    事例说明:

    
    
            /*
            * 我们来模拟A向B账号转账的场景
            *   A和B账户都有1000块,现在我让A账户向B账号转500块钱
            *
            * */
                //JDBC默认的情况下是关闭事务的,下面我们看看关闭事务去操作转账操作有什么问题
    
                //A账户减去500块
                String sql = "UPDATE a SET money=money-500 ";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.executeUpdate();
    
                //B账户多了500块
                String sql2 = "UPDATE b SET money=money+500";
                preparedStatement = connection.prepareStatement(sql2);
                preparedStatement.executeUpdate();
    

    从上面看,我们的确可以发现A向B转账,成功了。可是如果A向B转账的过程中出现了问题呢?下面模拟一下

    
                //A账户减去500块
                String sql = "UPDATE a SET money=money-500 ";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.executeUpdate();
                
                //这里模拟出现问题
                int a = 3 / 0;
    
    
                String sql2 = "UPDATE b SET money=money+500";
                preparedStatement = connection.prepareStatement(sql2);
                preparedStatement.executeUpdate();
    

    显然,上面代码是会抛出异常的,我们再来查询一下数据。A账户少了500块钱,B账户的钱没有增加这明显是不合理的


    我们可以通过事务来解决上面出现的问题

    
                //开启事务,对数据的操作就不会立即生效。
                connection.setAutoCommit(false);
                
                //A账户减去500块
                String sql = "UPDATE a SET money=money-500 ";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.executeUpdate();
    
                //在转账过程中出现问题
                int a = 3 / 0;
    
                //B账户多500块
                String sql2 = "UPDATE b SET money=money+500";
                preparedStatement = connection.prepareStatement(sql2);
                preparedStatement.executeUpdate();
                
                //如果程序能执行到这里,没有抛出异常,我们就提交数据
                connection.commit();
    
                //关闭事务【自动提交】
                connection.setAutoCommit(true);
                
    
            } catch (SQLException e) {
                try {
                    //如果出现了异常,就会进到这里来,我们就把事务回滚【将数据变成原来那样】
                    connection.rollback();
                    
                    //关闭事务【自动提交】
                    connection.setAutoCommit(true);
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
    

    上面的程序也一样抛出了异常,A账户钱没有减少,B账户的钱也没有增加。

    注意:当Connection遇到一个未处理的SQLException时,系统会非正常退出,事务也会自动回滚,但如果程序捕获到了异常,是需要在catch中显式回滚事务的。

    3. 事务隔离级别

    数据库定义了4个隔离级别:

    1. Serializable【可避免脏读,不可重复读,虚读】
    2. Repeatable read【可避免脏读,不可重复读】
    3. Read committed【可避免脏读】
    4. Read uncommitted【级别最低,什么都避免不了】

    分别对应Connection类中的4个常量

    1. TRANSACTION_READ_UNCOMMITTED
    2. TRANSACTION_READ_COMMITTED
    3. TRANSACTION_REPEATABLE_READ
    4. TRANSACTION_SERIALIZABLE

    脏读:一个事务读取到另外一个事务未提交的数据

    例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。


    不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改

    注:A查询数据库得到数据,B去修改数据库的数据,导致A多次查询数据库的结果都不一样【危害:A每次查询的结果都是受B的影响的,那么A查询出来的信息就没有意思了】


    虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

    注:和不可重复读类似,但虚读(幻读)会读到其他事务的插入的数据,导致前后读取不一致


    简单总结:脏读是不可容忍的,不可重复读和虚读在一定的情况下是可以的【做统计的肯定就不行】

    4. 数据库的乐观锁和悲观锁是什么?

    确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性,乐观锁和悲观锁是并发控制主要采用的技术手段。

    • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作

      • 在查询完数据的时候就把事务锁起来,直到提交事务
      • 实现方式:使用数据库中的锁机制
    • 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

      • 在修改数据的时候把事务锁起来,通过version的方式来进行锁定
      • 实现方式:使用version版本或者时间戳

    悲观锁:

    乐观锁:

    可以参考:

    5. 超键、候选键、主键、外键分别是什么?

    • 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键
    • 候选键(候选码):是最小超键,即没有冗余元素的超键
    • 主键(主码):数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
    • 外键:在一个表中存在的另一个表的主键称此表的外键

    候选码和主码:

    例子:邮寄地址(城市名,街道名,邮政编码,单位名,收件人)

    • 它有两个候选键:{城市名,街道名} 和 {街道名,邮政编码}
    • 如果我选取{城市名,街道名}作为唯一标识实体的属性,那么{城市名,街道名} 就是主码(主键)

    6. SQL 约束有哪几种?

    • NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
    • UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
    • PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
    • FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
    • CHECK: 用于控制字段的值范围。

    7. drop、delete与truncate分别在什么场景之下使用?

    我们来对比一下他们的区别:

    drop table

    • 1)属于DDL
    • 2)不可回滚
    • 3)不可带where
    • 4)表内容和结构删除
    • 5)删除速度快

    truncate table

    • 1)属于DDL
    • 2)不可回滚
    • 3)不可带where
    • 4)表内容删除
    • 5)删除速度快

    delete from

    • 1)属于DML
    • 2)可回滚
    • 3)可带where
    • 4)表结构在,表内容要看where执行的情况
    • 5)删除速度慢,需要逐行删除
    • 不再需要一张表的时候,用drop
    • 想删除部分数据行时候,用delete,并且带上where子句
    • 保留表而删除所有数据的时候用truncate

    8. 索引特点

    索引的特点

    • (1)索引一旦建立, Oracle管理系统会对其进行自动维护, 而且由Oracle管理系统决定何时使用索引
    • (2)用户不用在查询语句中指定使用哪个索引
    • (3)在定义primary key或unique约束后系统自动在相应的列上创建索引
    • (4)用户也能按自己的需求,对指定单个字段或多个字段,添加索引

    需要注意的是:Oracle是自动帮我们管理索引的,并且如果我们指定了primary key或者unique约束,系统会自动在对应的列上创建索引..

    什么时候【要】创建索引

    • (1)表经常进行 SELECT 操作
    • (2)表很大(记录超多),记录内容分布范围很广
    • (3)列名经常在 WHERE 子句或连接条件中出现

    什么时候【不要】创建索引

    • (1)表经常进行 INSERT/UPDATE/DELETE 操作
    • (2)表很小(记录超少)
    • (3)列名不经常作为连接条件或出现在 WHERE 子句中

    索引优缺点:

    • 索引加快数据库的检索速度
    • 索引降低了插入、删除、修改等维护任务的速度(虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引)
    • 唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
    • 索引需要占物理和数据空间

    索引分类:

    • 唯一索引:唯一索引不允许两行具有相同的索引值
    • 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空
    • 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个
    • 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个

    9. 非关系型数据库和关系型数据库区别,优势比较?

    非关系型数据库的优势:

    • 性能:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
    • 可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

    关系型数据库的优势:

    • 复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
    • 事务支持:使得对于安全性能很高的数据访问要求得以实现。

    其他:

    1.对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

    2.NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能,比如MongoDB。

    3.对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁之类的方法来曲线救国,比如Redis set nx。

    10. MYSQL的两种存储引擎区别(事务、锁级别等等),各自的适用场景

    引擎特性
    MYISAM不支持外键,表锁,插入数据时,锁定整个表,查表总行数时,不需要全表扫描
    INNODB支持外键,行锁,查表总行数时,全表扫描


    11.索引有B+索引和hash索引

    索引区别
    Hashhash索引,等值查询效率高,不能排序,不能进行范围查询
    B+数据有序,范围查询

    12 为什么设计红黑树

    红黑树通过它规则的设定,确保了插入和删除的最坏的时间复杂度是O(log N) 。

    红黑树解决了AVL平衡二叉树的维护起来比较麻烦的问题,红黑树,读取略逊于AVL,维护强于AVL,每次插入和删除的平均旋转次数应该是远小于平衡树。

    因此:

    相对于要求严格的AVL树来说,红黑树的旋转次数少,所以对于插入、删除操作较多的情况下,我们就用红黑树。但是,只是对查找要求较高,那么AVL还是较优于红黑树.

    13 B树的作用

    B树大多用在磁盘上用于查找磁盘的地址。因为磁盘会有大量的数据,有可能没有办法一次将需要的所有数据加入到内存中,所以只能逐一加载磁盘页,每个磁盘页就对应一个节点,而对于B树来说,B树很好的将树的高度降低了,这样就会减少IO查询次数,虽然一次加载到内存的数据变多了,但速度绝对快于AVL或是红黑树的。

    14 B树和 B+树的区别

    B/B+树用在磁盘文件组织、数据索引和数据库索引中。其中B+树比B 树更适合实际应用中操作系统的文件索引和数据库索引,因为:
    1、B+树的磁盘读写代价更低
    B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

    举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而B+ 树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B 树就比B+ 树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。

    2、B+-tree的查询效率更加稳定
    由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

    3、B树在元素遍历的时候效率较低

    由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。在数据库中基于范围的查询相对频繁,所以此时B+树优于B树。

    15 B树和红黑树的区别

    最大的区别就是树的深度较高,在磁盘I/O方面的表现不如B树。

    要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定。

    所以,在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。在这方面,B树表现相对优异,B树可以有多个子女,从几十到上千,可以降低树的高度。

    16 AVL树和红黑树的区别

    红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。

    1、红黑树和AVL树都能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。
    2、由于设计,红黑树的任何不平衡都会在三次旋转之内解决。AVL树增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

    在查找方面:

            红黑树的性质(最长路径长度不超过最短路径长度的2倍),其查找代价基本维持在O(logN)左右,但在最差情况下(最长路径是最短路径的2倍少1),比AVL要略逊色一点。
      AVL是严格平衡的二叉查找树(平衡因子不超过1)。查找过程中不会出现最差情况的单支树。因此查找效率最好,最坏情况都是O(logN)数量级的。

    所以,综上:
      AVL比RBtree更加平衡,但是AVL的插入和删除会带来大量的旋转。 所以如果插入和删除比较多的情况,应该使用RBtree, 如果查询操作比较多,应该使用AVL。

    AVL是一种高度平衡的二叉树,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果场景中对插入删除不频繁,只是对查找特别有要求,AVL还是优于红黑的。

    17 数据库为什么使用B树,而不使用AVL或者红黑树

    我们假设B+树一个节点可以有100个关键字,那么3层的B树可以容纳大概1000000多个关键字(100+101*100+101*101*100)。而红黑树要存储这么多至少要20层。所以使用B树相对于红黑树和AVL可以减少IO操作

    18 mysql的Innodb引擎为什么采用的是B+树的索引方式

    B+树只有叶子节点存放数据,而其他节点只存放索引,而B树每个节点都有Data域。所以相同大小的节点B+树包含的索引比B树的索引更多(因为B树每个节点还有Data域)

    还有就是B+树的叶子节点是通过链表连接的,所以找到下限后能很快进行区间查询,比B树中序遍历快

    19 红黑树 和 b+树的用途有什么区别?

    红黑树多用在内部排序,即全放在内存中的,STL的map和set的内部实现就是红黑树。

    B+树多用于外存上时,B+也被成为一个磁盘友好的数据结构。

    20 为什么B+树比B树更为友好

    磁盘读写代价更低
    树的非叶子结点里面没有数据,这样索引比较小,可以放在一个blcok(或者尽可能少的blcok)里面。避免了树形结构不断的向下查找,然后磁盘不停的寻道,读数据。这样的设计,可以降低io的次数。

    查询效率更加稳定
    非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

    遍历所有的数据更方便
    B+树只要遍历叶子节点就可以实现整棵树的遍历,而其他的树形结构 要中序遍历才可以访问所有的数据。

    21. 数据库优化

    在我们书写SQL语句的时候,其实书写的顺序、策略会影响到SQL的性能,虽然实现的功能是一样的,但是它们的性能会有些许差别。

    因此,下面就讲解在书写SQL的时候,怎么写比较好。

    ①选择最有效率的表名顺序

    数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最先处理

    在FROM子句中包含多个表的情况下:

    • 如果三个表是完全无关系的话,将记录和列名最少的表,写在最后,然后依次类推
    • 也就是说:选择记录条数最少的表放在最后

    如果有3个以上的表连接查询:

    • 如果三个表是有关系的话,将引用最多的表,放在最后,然后依次类推
    • 也就是说:被其他表所引用的表放在最后

    例如:查询员工的编号,姓名,工资,工资等级,部门名

    emp表被引用得最多,记录数也是最多,因此放在form字句的最后面

    
    select emp.empno,emp.ename,emp.sal,salgrade.grade,dept.dname
    from salgrade,dept,emp
    where (emp.deptno = dept.deptno) and (emp.sal between salgrade.losal and salgrade.hisal)          
    
    

    ②WHERE子句中的连接顺序

    数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之左,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的之右

    emp.sal可以过滤多条记录,写在WHERE字句的最右边

    
          select emp.empno,emp.ename,emp.sal,dept.dname
          from dept,emp
          where (emp.deptno = dept.deptno) and (emp.sal > 1500) 

    ③SELECT子句中避免使用*号

    我们当时学习的时候,“*”号是可以获取表中全部的字段数据的。

    • 但是它要通过查询数据字典完成的,这意味着将耗费更多的时间
    • 使用*号写出来的SQL语句也不够直观。

    ④用TRUNCATE替代DELETE

    这里仅仅是:删除表的全部记录,除了表结构才这样做

    DELETE是一条一条记录的删除,而Truncate是将整个表删除,保留表结构,这样比DELETE快

    ⑤多使用内部函数提高SQL效率

    例如使用mysql的concat()函数会比使用||来进行拼接快,因为concat()函数已经被mysql优化过了。

    ⑥使用表或列的别名

    如果表或列的名称太长了,使用一些简短的别名也能稍微提高一些SQL的性能。毕竟要扫描的字符长度就变少了。。。

    ⑦多使用commit

    comiit会释放回滚点...

    ⑧善用索引

    索引就是为了提高我们的查询数据的,当表的记录量非常大的时候,我们就可以使用索引了。

    ⑨SQL写大写

    我们在编写SQL 的时候,官方推荐的是使用大写来写关键字,因为Oracle服务器总是先将小写字母转成大写后,才执行

    ⑩避免在索引列上使用NOT

    因为Oracle服务器遇到NOT后,他就会停止目前的工作,转而执行全表扫描

    ①①避免在索引列上使用计算

    WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描,这样会变得变慢

    ①②用 >= 替代 >

          低效:
          SELECT * FROM EMP WHERE DEPTNO > 3   
          首先定位到DEPTNO=3的记录并且扫描到第一个DEPT大于3的记录
          高效:
          SELECT * FROM EMP WHERE DEPTNO >= 4  
          直接跳到第一个DEPT等于4的记录
    

    ①③用IN替代OR

    
          select * from emp where sal = 1500 or sal = 3000 or sal = 800;
          select * from emp where sal in (1500,3000,800);
    

    ①④总是使用索引的第一个列

    如果索引是建立在多个列上,只有在它的第一个列被WHERE子句引用时,优化器才会选择使用该索引。 当只引用索引的第二个列时,不引用索引的第一个列时,优化器使用了全表扫描而忽略了索引

    
          create index emp_sal_job_idex
          on emp(sal,job);
          ----------------------------------
          select *
          from emp  
          where job != 'SALES';    
          
          
          上边就不使用索引了。

    数据库结构优化

    • 1)范式优化: 比如消除冗余(节省空间。。)
    • 2)反范式优化:比如适当加冗余等(减少join)
    • 3)拆分表: 垂直拆分和水平拆分

     

     

    展开全文
    qq_40587575 2021-03-07 16:30:15
  • Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等技术栈共有1000+道面试题。 对于Java后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上

    进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全,其中概括的知识点有:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、

    Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等技术栈共有1000+道面试题。

    对于Java后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer, 也已经帮助了很多的Java学习者,希望也能帮助到你

    因为文件太多,全部展示会影响篇幅,暂时就展示部分截图。欢迎大家一起交流 点击一起学习 暗号:csdn 第一时间领取最新学习面试资料+简历优化资源

     

    面试题整理十分全面,文末还有答案解析!(文章比较长,耐心看完,让你面试提升一大截!)

     

    é¿éå·´å·´

    MyBatis 面试题

    1、什么是 Mybatis?

    2、Mybaits 的优点:

    3、MyBatis 框架的缺点:

    4、MyBatis 框架适用场合:

    5、MyBatis 与 Hibernate 有哪些不同?

    6、#{}和${}的区别是什么?

    7、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

    8、 模糊查询 like 语句该怎么写?

    9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,

    这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,

    方法能重载吗?

    10、...

     

    图片

    ZooKeeper 面试题

    1. ZooKeeper 面试题?

    2. ZooKeeper 提供了什么?

    3. Zookeeper 文件系统

    4. ZAB 协议?

    5. 四种类型的数据节点 Znode

    6. Zookeeper Watcher 机制 -- 数据变更通知

    7. 客户端注册 Watcher 实现

    8. 服务端处理 Watcher 实现

    9. 客户端回调 Watcher

    10. ...图片

     

    Dubbo 面试题

    1、为什么要用 Dubbo?

    2、Dubbo 的整体架构设计有哪些分层?

    3、默认使用的是什么通信框架,还有别的选择吗?

    4、服务调用是阻塞的吗?

    5、一般使用什么注册中心?还有别的选择吗?

    6、默认使用什么序列化框架,你知道的还有哪些?

    7、服务提供者能实现失效踢出是什么原理?

    8、服务上线怎么不影响旧版本?

    9、如何解决服务调用链过长的问题?

    10、...

    图片
     

    Elasticsearch 面试题

    1、elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据

    大小,分片有多少,以及一些调优手段 。

    2、elasticsearch 的倒排索引是什么

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

    4、elasticsearch 是如何实现 master 选举的

    5、详细描述一下 Elasticsearch 索引文档的过程

    6、详细描述一下 Elasticsearch 搜索的过程?

    7、Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法

    8、lucence 内部结构是什么?

    9、Elasticsearch 是如何实现 Master 选举的?

    10、...图片

     

    Memcached 面试题

    1、Memcached 是什么,有什么作用?

    2、Memcached 服务分布式集群如何实现?

    3、Memcached 服务特点及工作原理是什么?

    4、简述 Memcached 内存管理机制原理?

    5、memcached 是怎么工作的?

    6、memcached 最大的优势是什么?

    7、memcached 和 MySQL 的 query

    8、memcached 和服务器的 local cache(比如 PHP 的 APC、mmap

    文件等)相比,有什么优缺点?

    9、memcached 的 cache 机制是怎样的?

    10、...图片

     

    Redis 面试题

    1、什么是 Redis?

    2、Redis 的数据类型?

    3、使用 Redis 有哪些好处?

    4、Redis 相比 Memcached 有哪些优势?

    5、Memcache 与 Redis 的区别都有哪些?

    6、Redis 是单进程单线程的?

    7、一个字符串类型的值能存储最大容量是多少?

    8、Redis 的持久化机制是什么?各自的优缺点?

    9、Redis 常见性能问题和解决方案:

    10、...图片

    资料获取方式:需要的朋友点我获取:点击一起学习 暗号:csdn 最新学习资料+简历优化资源   

    (资料整理不易,大家耐心点哦)

    MySQL 面试题


    1、MySQL 中有哪几种锁?

    2、MySQL 中有哪些不同的表格?

    3、简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别

    4、MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间

    的区别?

    5、CHAR 和 VARCHAR 的区别?

    6、主键和候选键有什么区别?

    7、myisamchk 是用来做什么的?

    8、如果一个表有一列定义为 TIMESTAMP,将发生什么?

    9、你怎么看到为表格定义的所有索引?

    10、...

    图片
     

    Java 并发编程(一)

    1、在 java 中守护线程和本地线程区别?

    2、线程与进程的区别?

    3、什么是多线程中的上下文切换?

    4、死锁与活锁的区别,死锁与饥饿的区别?

    5、Java 中用到的线程调度算法是什么?

    6、什么是线程组,为什么在 Java 中不推荐使用?

    7、为什么使用 Executor 框架?

    8、在 Java 中 Executor 和 Executors 的区别?

    9、如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时间最长?

    10、...

    图片

     

    Java 并发编程(二)

    1、并发编三要素?

    2、实现可见性的方法有哪些?

    3、多线程的价值?

    4、创建线程的有哪些方式?

    5、创建线程的三种方式的对比?

    6、线程的状态流转图

    7、Java 线程具有五中基本状态

    8、什么是线程池?有哪几种创建方式?

    9、四种线程池的创建:

    10、...

    图片
     

    Java 面试题(一)

    1、面向对象的特征有哪些方面?

    2、访问修饰符 public,private,protected,以及不写(默认)时的区别?

    3、String 是最基本的数据类型吗?

    4、float f=3.4;是否正确?

    5、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

    6、Java 有没有 goto?

    7、int 和 Integer 有什么区别?

    8、&和&&的区别? 

    9、解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。

    10、...图片

     

    Java 面试题(二)

    多线程、并发及线程的基础问题

    1、Java 中能创建 volatile 数组吗?

    2、volatile 能使得一个非原子操作变成原子操作吗?

    3、volatile 修饰符的有过什么实践?

    4、volatile 类型变量提供什么保证?

    5、10 个线程和 2 个线程的同步代码,哪个更容易写? 

    6、你是如何调用 wait()方法的?使用 if 块还是循环?为什么?

    有经验程序员的 Java 面试题 

    8、什么是 Busy spin?我们为什么要使用它?

    9、Java 中怎么获取一份线程 dump 文件? 

    10、Swing 是线程安全的? 

    11、什么是线程局部变量?

    12、用 wait-notify 写一段代码来解决生产者-消费者问题?

    13、用 Java 写一个线程安全的单例模式(Singleton)?

    14、Java 中 sleep 方法和 wait 方法的区别?

    15、什么是不可变对象(immutable object)?Java 中怎么创建一

    个不可变对象?

    16、我们能创建一个包含可变对象的不可变对象吗?

    数据类型和 Java 基础面试问题

    17、Java 中应该使用什么数据类型来代表价格?

    18、怎么将 byte 转换为 String?

    19、Java 中怎样将 bytes 转换为 long 类型?

    20、我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于

    byte 类型的范围,将会出现什么现象?

    21、存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么?

    如 C = (C) B;

    22、哪个类包含 clone 方法?是 Cloneable 还是 Object?

    23、Java 中 ++ 操作符是线程安全的吗?

    23、不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,

    然后存储回内存,这个过程可能会出现多个线程交差。

    24、a = a + b 与 a += b 的区别

    25、我能在不进行强制转换的情况下将一个 double 值赋值给 long

    类型的变量吗?

    26、3*0.1 == 0.3 将会返回什么?true 还是 false?

    27、int 和 Integer 哪个会占用更多的内存?

    28、为什么 Java 中的 String 是不可变的(Immutable)? 

    JVM 底层 与 GC(Garbage Collection) 的面试问题

    31、64 位 JVM 中,int 的长度是多数?

    32、Serial 与 Parallel GC 之间的不同之处?

    33、32 位和 64 位的 JVM,int 类型变量的长度是多数? 

    34、Java 中 WeakReference 与 SoftReference 的区别?

    35、WeakHashMap 是怎么工作的?

    36、JVM 选项 -XX:+UseCompressedOops 有什么作用?为什么要

    使用?

    37、怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位?

    38、32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?

    39、JRE、JDK、JVM 及 JIT 之间有什么不同?

    3 年工作经验的 Java 面试题

    40、解释 Java 堆空间及 GC? 

    JVM 底层面试题及答案

    41、你能保证 GC 执行吗?

    42、怎么获取 Java 程序使用的内存?堆使用的百分比?

    43、Java 中堆和栈有什么区别?

    关于内存的的面试问题和答案

    Java 基本概念面试题

    44、“a==b”和”a.equals(b)”有什么区别?

    45、a.hashCode() 有什么用?与 a.equals(b) 有什么关系?

    46、final、finalize 和 finally 的不同之处?

    47、Java 中的编译期常量是什么?使用它又什么风险?

    Java 集合框架的面试题

    48、List、Set、Map 和 Queue 之间的区别(答案)

    49、poll() 方法和 remove() 方法的区别? 

    50、Java 中 LinkedHashMap 和 PriorityQueue 的区别是什么?

    51、ArrayList 与 LinkedList 的不区别?

    52、用哪两种方式来实现集合的排序?

    53、Java 中怎么打印数组?

    54、Java 中的 LinkedList 是单向链表还是双向链表?

    55、Java 中的 TreeMap 是采用什么树实现的?(答案)

    56、Hashtable 与 HashMap 有什么不同之处?

    57、Java 中的 HashSet,内部是如何工作的?

    58、写一段代码在遍历 ArrayList 时移除一个元素?

    59、我们能自己写一个容器类,然后使用 for-each 循环码?

    60、ArrayList 和 HashMap 的默认大小是多数?

    61、有没有可能两个不相等的对象有有相同的 hashcode?

    62、两个相同的对象会有不同的的 hash code 吗?

    63、我们可以在 hashcode() 中使用随机数字吗?

    64、Java 中,Comparator 与 Comparable 有什么不同?

    Java IO 和 NIO 的面试题

    66、在我 Java 程序中,我有三个 socket,我需要多少个线程来处理?

    67、Java 中怎么创建 ByteBuffer?

    68、Java 中,怎么读写 ByteBuffer ?

    69、Java 采用的是大端还是小端?

    70、ByteBuffer 中的字节序是什么?

    71、Java 中,直接缓冲区与非直接缓冲器有什么区别?

    72、Java 中的内存映射缓存区是什么?

    73、socket 选项 TCP NO DELAY 是指什么?

    74、TCP 协议与 UDP 协议有什么区别?

    75、Java 中,ByteBuffer 与 StringBuffer 有什么区别?(答案)

    Java 最佳实践的面试问题

    76、Java 中,编写多线程程序的时候你会遵循哪些最佳实践?

    77、说出几点 Java 中使用 Collections 的最佳实践

    78、说出至少 5 点在 Java 中使用线程的最佳实践。

    79、说出 5 条 IO 的最佳实践(答案)

    80、列出 5 个应该遵循的 JDBC 最佳实践

    81、说出几条 Java 中方法重载的最佳实践?

    Date、Time 及 Calendar 的面试题

    82、在多线程环境下,SimpleDateFormat 是线程安全的吗?

    83、Java 中如何格式化一个日期?如格式化为 ddMMyyyy 的形式?

    84、Java 中,怎么在格式化的日期中显示时区?

    85、Java 中 java.util.Date 与 java.sql.Date 有什么区别?

    86、Java 中,如何计算两个日期之间的差距?

    87、Java 中,如何将字符串 YYYYMMDD 转换为日期?

    单元测试 JUnit 面试题

    89、如何测试静态方法?(答案)

    90、怎么利用 JUnit 来测试一个方法的异常?

    91、你使用过哪个单元测试库来测试你的 Java 程序?

    92、@Before 和 @BeforeClass 有什么区别?

    编程和代码相关的面试题

    93、怎么检查一个字符串只包含数字?解决方案

    94、Java 中如何利用泛型写一个 LRU 缓存?

    95、写一段 Java 程序将 byte 转换为 long?

    95、在不使用 StringBuffer 的前提下,怎么反转一个字符串?

    97、Java 中,怎么获取一个文件中单词出现的最高频率?

    98、如何检查出两个给定的字符串是反序的?

    99、Java 中,怎么打印出一个字符串的所有排列?

    100、Java 中,怎样才能打印出数组中的重复元素?

    101、Java 中如何将字符串转换为整数?

    102、在没有使用临时变量的情况如何交换两个整数变量的值?

    关于 OOP 和设计模式的面试题

    103、接口是什么?为什么要使用接口而不是直接使用具体类?

    104、Java 中,抽象类与接口之间有什么不同?

    105、除了单例模式,你在生产环境中还用过什么设计模式?

    106、你能解释一下里氏替换原则吗?

    107) 什么情况下会违反迪米特法则?为什么会有这个问题?

    108、适配器模式是什么?什么时候使用?

    109、什么是“依赖注入”和“控制反转”?为什么有人使用?

    110、抽象类是什么?它与接口有什么区别?你为什么要使用过抽象类?

    111、构造器注入和 setter 依赖注入,那种方式更好?

    112、依赖注入和工程模式之间有什么不同?

    113、适配器模式和装饰器模式有什么区别?

    114、适配器模式和代理模式之前有什么不同?

    115、什么是模板方法模式?

    116、什么时候使用访问者模式?

    117、什么时候使用组合模式?

    118、继承和组合之间有什么不同?

    119、描述 Java 中的重载和重写?

    120、Java 中,嵌套公共静态类与顶级类有什么不同?

    121、 OOP 中的 组合、聚合和关联有什么区别?

    122、给我一个符合开闭原则的设计模式的例子?

    123、抽象工厂模式和原型模式之间的区别?

    Java 面试中其他各式各样的问题


    125、嵌套静态类与顶级类有什么区别?

    126、你能写出一个正则表达式来判断一个字符串是否是一个数字吗?

    127、Java 中,受检查异常 和 不受检查异常的区别?

    128、Java 中,throw 和 throws 有什么区别

    129、Java 中,Serializable 与 Externalizable 的区别?

    130、Java 中,DOM 和 SAX 解析器有什么不同?

    131、说出 JDK 1.7 中的三个新特性?

    132、说出 5 个 JDK 1.8 引入的新特性?

    133、Java 中,Maven 和 ANT 有什么区别?

     

    图片
     

    Spring 面试题(一)

     

    1、一般问题

    1.1、不同版本的 Spring Framework 有哪些主要功能?

    1.2、什么是 Spring Framework?

    1.3、列举 Spring Framework 的优点。

    1.4、Spring Framework 有哪些不同的功能?

    1.5、Spring Framework 中有多少个模块,它们分别是什么?

    1.6、什么是 Spring 配置文件?

    1.7、Spring 应用程序有哪些不同组件?

    1.8、使用 Spring 有哪些方式?

    2、依赖注入(Ioc)

    2.1、什么是 Spring IOC 容器?

    2.2、什么是依赖注入?

    2.3、可以通过多少种方式完成依赖注入?

    2.4、区分构造函数注入和 setter 注入。

    2.5、spring 中有多少种 IOC 容器?

    2.6、区分 BeanFactory 和 ApplicationContext。

    2.7、列举 IoC 的一些好处。

    2.8、Spring IoC 的实现机制。

    3、Beans

    3.1、什么是 spring bean?

    3.2、spring 提供了哪些配置方式?

    3.3、spring 支持集中 bean scope?

    3.4、spring bean 容器的生命周期是什么样的?

    3.5、什么是 spring 的内部 bean?

    3.6、什么是 spring 装配 

    3.7、自动装配有哪些方式?

    3.8、自动装配有什么局限?

    4、注解

    4.1、什么是基于注解的容器配置

    4.2、如何在 spring 中启动注解装配?

    4.3、@Component, @Controller, @Repository, @Service 有何区

    别?4.4、@Required 注解有什么用?

    4.5、@Autowired 注解有什么用?

    4.6、@Qualifier 注解有什么用?

    4.7、@RequestMapping 注解有什么用?

    5、数据访问

    5.1、spring DAO 有什么用?

    5.2、列举 Spring DAO 抛出的异常。

    5.3、spring JDBC API 中存在哪些类?

    5.4、使用 Spring 访问 Hibernate 的方法有哪些? 

    5.5、列举 spring 支持的事务管理类型.

    5.6、spring 支持哪些 ORM 框架

    6、AOP

    6.1、什么是 AOP?

    6.2、什么是 Aspect?

    6.3、什么是切点(JoinPoint)

    6.4、什么是通知(Advice)?

    6.5、有哪些类型的通知(Advice)?

    6.6、指出在 spring aop 中 concern 和 cross-cutting concern 的

    不同之处。

    6.7、AOP 有哪些实现方式?

    6.8、Spring AOP and AspectJ AOP 有什么区别?

    6.9、如何理解 Spring 中的代理?

    6.10、什么是编织(Weaving)?

    7、MVC

    7.1、Spring MVC 框架有什么用?

    7.2、描述一下 DispatcherServlet 的工作流程

    7.3、介绍一下 WebApplicationContext

    图片

    资料获取方式:点击一起学习 暗号:csdn 最新学习资料+简历优化资源   

    需要的朋友点我获取:点击一起学习 暗号:csdn 最新学习资料+简历优化资源   

    (资料整理不易,大家耐心点哦)

     

    Spring 面试题(二)

     

    1、什么是 spring?

    2、使用 Spring 框架的好处是什么?

    3、Spring 由哪些模块组成?

    4、核心容器(应用上下文) 模块。

    5、BeanFactory – BeanFactory 实现举例。

    6、XMLBeanFactory

    7、解释 AOP 模块

    8、解释 JDBC 抽象和 DAO 模块

    9、解释对象/关系映射集成模块。

    10、解释 WEB 模块。

    12、Spring 配置文件

    13、什么是 Spring IOC 容器?

    14、IOC 的优点是什么?

    15、ApplicationContext 通常的实现是什么?

    16、Bean 工厂和 Application contexts 有什么区别?

    17、一个 Spring 的应用看起来象什么?

    依赖注入

    18、什么是 Spring 的依赖注入?

    19、有哪些不同类型的 IOC(依赖注入)方式?

    20、哪种依赖注入方式你建议使用,构造器注入,还是 Setter 方法注

    入?

    Spring Beans

    21.什么是 Spring beans?

    22、一个 Spring Bean 定义 包含什么?

    23、如何给 Spring 容器提供配置元数据?

    24、你怎样定义类的作用域?

    25、解释 Spring 支持的几种 bean 的作用域。

    26、Spring 框架中的单例 bean 是线程安全的吗?

    27、解释 Spring 框架中 bean 的生命周期。

    28、哪些是重要的 bean 生命周期方法?你能重载它们吗?

    29、什么是 Spring 的内部 bean?

    30、在 Spring 中如何注入一个 java 集合?

    31、什么是 bean 装配?

    32、什么是 bean 的自动装配?

    33、解释不同方式的自动装配 。

    34.自动装配有哪些局限性 ?

    35、你可以在 Spring 中注入一个 null 和一个空字符串吗?

    Spring 注解

    36、什么是基于 Java 的 Spring 注解配置? 给一些注解的例子.

    37、什么是基于注解的容器配置?

    38、怎样开启注解装配?

    39、@Required 注解

    40、@Autowired 注解

    41、@Qualifier 注解

    Spring 数据访问

    42.在 Spring 框架中如何更有效地使用 JDBC?

    43、JdbcTemplate

    44、Spring 对 DAO 的支持

    45、使用 Spring 通过什么方式访问 Hibernate?

    46、Spring 支持的 ORM

    47.如何通过 HibernateDaoSupport 将 Spring 和 Hibernate 结合起

    来?

    48、Spring 支持的事务管理类型

    49、Spring 框架的事务管理有哪些优点?

    50、你更倾向用那种事务管理类型?

    Spring 面向切面编程(AOP)

    51、解释 AOP

    52、Aspect 切面

    52、在 Spring AOP 中,关注点和横切关注的区别是什么?

    54、连接点

    55、通知

    56、切点

    57、什么是引入?

    58、什么是目标对象?

    59、什么是代理?

    60、有几种不同类型的自动代理?

    61、什么是织入。什么是织入应用的不同点?

    62、解释基于 XML Schema 方式的切面实现。

    63、解释基于注解的切面实现

    Spring 的 MVC

    64、什么是 Spring 的 MVC 框架?

    65、DispatcherServlet

    66、WebApplicationContext

    67、什么是 Spring MVC 框架的控制器?

    68、@Controller 注解69、@RequestMapping 注解

    图片
     

    微服务 面试题

    1、您对微服务有何了解?

    2、微服务架构有哪些优势?

    3。微服务有哪些特点?

    4、设计微服务的最佳实践是什么?

    5、微服务架构如何运作?

    6、微服务架构的优缺点是什么?

    7、单片,SOA 和微服务架构有什么区别?

    8、在使用微服务架构时,您面临哪些挑战?

    9、SOA 和微服务架构之间的主要区别是什么?

    10、微服务有什么特点?

    11、什么是领域驱动设计?

    12、为什么需要域驱动设计(DDD)?

    13、什么是无所不在的语言?

    14、什么是凝聚力?

    15、什么是耦合?

    16、什么是 REST / RESTful 以及它的用途是什么?

    17、你对 Spring Boot 有什么了解?

    18、什么是 Spring 引导的执行器?

    19、什么是 Spring Cloud?

    20、Spring Cloud 解决了哪些问题?

    21、在 Spring MVC 应用程序中使用 WebMvcTest 注释有什么用处?

    22。你能否给出关于休息和微服务的要点?

    23、什么是不同类型的微服务测试?

    24、您对 Distributed Transaction 有何了解?

    25、什么是 Idempotence 以及它在哪里使用?

    26、什么是有界上下文?

    27、什么是双因素身份验证?

    28、双因素身份验证的凭据类型有哪些?

    29、什么是客户证书?

    30、PACT 在微服务架构中的用途是什么?

    31、什么是 OAuth?

    32、康威定律是什么?

    33、合同测试你懂什么?

    34、什么是端到端微服务测试?

    35、Container 在微服务中的用途是什么?

    36、什么是微服务架构中的 DRY?

    37、什么是消费者驱动的合同(CDC)?

    38、Web,RESTful API 在微服务中的作用是什么?

    39、您对微服务架构中的语义监控有何了解?

    40、我们如何进行跨功能测试?41、我们如何在测试中消除非决定论?

    42、Mock 或 Stub 有什么区别?

    43、您对 Mike Cohn 的测试金字塔了解多少?

    44、Docker 的目的是什么?

    45、什么是金丝雀释放?

    46、什么是持续集成(CI)?

    47、什么是持续监测?

    48、架构师在微服务架构中的角色是什么?

    49、我们可以用微服务创建状态机吗?

    50、什么是微服务中的反应性扩展?

    图片
     

    Linux 面试题

    1、绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令?

    2、怎么查看当前进程?怎么执行退出?怎么查看当前路径?

    3、怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户id?查看指定帮助用什么命令?

    4、Ls 命令执行什么功能?可以带哪些参数,有什么区别?

    5、建立软链接(快捷方式),以及硬链接的命令。

    6、目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?

    7、查看文件内容有哪些命令可以使用?

    8、随意写文件命令?怎么向屏幕输出带空格的字符串,比如”helloworld”? 

    9、终端是哪个文件夹下的哪个文件?黑洞文件是哪个文件夹下的哪个命令? 

    10、移动文件用哪个命令?改名用哪个命令?

    11、复制文件用哪个命令?如果需要连同文件夹一块复制呢?如果需要有提示功能呢?

    12、删除文件用哪个命令?如果需要连目录及目录下文件一块删除呢?删除空文件夹用什么命令?

    13、Linux 下命令有哪几种可使用的通配符?分别代表什么含义?

    14、用什么命令对一个文件的内容进行统计?(行号、单词数、字节数)

    15、Grep 命令有什么用?如何忽略大小写?如何查找不含该串的行?

    16、Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?

    17、怎么使一个命令在后台运行?

    18、利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?

    19、哪个命令专门用来查看后台任务?

    20、把后台任务调到前台执行使用什么命令?把停下的后台任务在后台执行起来用什么命令?

    21、终止进程用什么命令? 带什么参数?

    22、怎么查看系统支持的所有信号?

    23、搜索文件用什么命令? 格式是怎么样的?

    24、查看当前谁在使用该主机用什么命令? 查找自己所在的终端信息用什么命令?

    25、使用什么命令查看用过的命令列表?

    26、使用什么命令查看磁盘使用空间?空闲空间呢?

    27、使用什么命令查看网络是否连通?

    28、使用什么命令查看 ip 地址及接口信息?

    29、查看各类环境变量用什么命令?

    30、通过什么命令指定命令提示符?

    31、查找命令的可执行文件是去哪查找的? 怎么对其进行设置及添加?

    32、通过什么命令查找执行命令?

    33、怎么对命令进行取别名?

    34、du 和 df 的定义,以及区别?

    35、awk 详解。36、当你需要给命令绑定一个宏或者按键的时候,应该怎么做呢?

    37、如果一个 linux 新手想要知道当前系统支持的所有命令的列表,他需要怎么做?

    38、如果你的助手想要打印出当前的目录栈,你会建议他怎么做?451

    39、你的系统目前有许多正在运行的任务,在不重启机器的条件下,有什么方法可以把所有正在运行的进程移除呢?

    40、bash shell 中的 hash 命令有什么作用?

    41、哪一个 bash 内置命令能够进行数学运算。

    42、怎样一页一页地查看一个大文件的内容呢?

    43、数据字典属于哪一个用户的?

    44、怎样查看一个 linux 命令的概要与用法?假设你在/bin 目录中偶然看到一个你从没见过的的命令,怎样才能知道它的作用和用法呢?

    45、使用哪一个命令可以查看自己文件系统的磁盘空间配额呢?

    图片

    需要的朋友点我获取:点击一起学习 暗号:csdn 最新学习资料+简历优化资源   

    (资料整理不易,大家耐心点哦)

    Spring Boot 面试题

     

    1、什么是 Spring Boot?

    2、Spring Boot 有哪些优点?

    3、什么是 JavaConfig?

    4、如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?

    5、Spring Boot 中的监视器是什么?

    6、如何在 Spring Boot 中禁用 Actuator 端点安全性?

    7、如何在自定义端口上运行 Spring Boot 应用程序?

    8、什么是 YAML?

    9、如何实现 Spring Boot 应用程序的安全性?

    10、如何集成 Spring Boot 和 ActiveMQ?

    11、如何使用 Spring Boot 实现分页和排序?

    12、什么是 Swagger?你用 Spring Boot 实现了它吗? 

    13、什么是 Spring Profiles?

    14、什么是 Spring Batch?

    15、什么是 FreeMarker 模板?

    16、如何使用 Spring Boot 实现异常处理?

    17、您使用了哪些 starter maven 依赖项?

    18、什么是 CSRF 攻击?

    19、什么是 WebSockets?

    20、什么是 AOP?

    21、什么是 Apache Kafka?

    22、我们如何监视所有 Spring Boot 微服务?

    图片
     

    Spring Cloud 面试题

    1、什么是 Spring Cloud?

    2、使用 Spring Cloud 有什么优势?

    3、服务注册和发现是什么意思?Spring Cloud 如何实现?

    4、负载平衡的意义什么?

    5、什么是 Hystrix?它如何实现容错?

    6、什么是 Hystrix 断路器?我们需要它吗?

    7、什么是 Netflix Feign?它的优点是什么?

    8、什么是 Spring Cloud Bus?我们需要它吗?

    图片
     

    RabbitMQ 面试题

    1、什么是 rabbitmq

    2、为什么要使用 rabbitmq

    3、使用 rabbitmq 的场景

    4、如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消

    费了消息?

    5.如何避免消息重复投递或重复消费?

    6、消息基于什么传输?

    7、消息如何分发?

    8、消息怎么路由?

    9、如何确保消息不丢失?

    10、使用 RabbitMQ 有什么好处?

    11、RabbitMQ 的集群

    12、mq 的缺点

    图片

    kafka 面试题

    1、如何获取 topic 主题的列表

    2、生产者和消费者的命令行是什么?

    3、consumer 是推还是拉?

    4、讲讲 kafka 维护消费状态跟踪的方法

    5、讲一下主从同步**

    6、为什么需要消息系统,mysql 不能满足需求吗?

    7、Zookeeper 对于 Kafka 的作用是什么?

    8、数据传输的事务定义有哪三种?

    9、Kafka 判断一个节点是否还活着有那两个条件?

    10、Kafka 与传统 MQ 消息系统之间有三个关键区别

    11、讲一讲 kafka 的 ack 的三种机制

    13、消费者故障,出现活锁问题如何解决?

    14、如何控制消费的位置

    15、kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?

    16、kafka 的高可用机制是什么?

    17、kafka 如何减少数据丢失

    18、kafka 如何不消费重复数据?比如扣款,我们不能重复的扣。

    图片

    总结:

    所有的面试题目都不是一成不变的,上面的面试题只是给大家一个借鉴作用,最主要的是给自己增加知识的储备,有备无患。上面分享的2021最新1000+Java面试题的答案都整理成了PDF文档。

    最新2021整理收集的一些Java学习资料(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,

     点击 : 一线大厂核心技术分享 分享最新技术,走在知识前端

    点击一起学习 暗号:csdn 最新学习资料+简历优化资源

                             

      å¨è¿éæå¥å¾çæè¿°

    后续会分享更多纯干货文章,希望能真正帮到你们。你们的支持就是我最大的动力!欢迎关注点赞啊!

                                                           

    展开全文
    weixin_50333534 2021-02-24 21:48:14
  • weixin_43831049 2021-02-04 15:53:41
  • 21KB solememorykai 2019-10-13 11:08:26
  • 5星
    35.69MB qq_30354581 2018-01-30 10:22:27
  • u012889902 2021-08-05 08:26:47
  • 5星
    313.11MB SKCQTGZX 2021-09-14 21:10:32
  • 10.23MB qq_26975307 2021-10-25 15:58:33
  • 5星
    11.44MB qq_40957277 2021-06-16 21:29:30
  • 31KB yangwang213 2017-05-26 18:38:07

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 394,004
精华内容 157,601
关键字:

java面试题2021

java 订阅