精华内容
下载资源
问答
  • ConcurrentHashMap 在Java7和Java8中的区别?为什么Java8并发效率更好?什么情况下用HashMap,什么情况用ConcurrentHashMap? redis数据结构? redis数据淘汰机制? Redis 集群方案应该怎么做?都有哪些方案? 三面...

    一、前言

    Redis 提供了5种数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要。

    备注: 按照分析顺序,本节应该说道有序集合对象了,但是考虑到有序集合对象的底层实现中使用到了跳跃表结构,避免在分析有序集合时造成突兀,所以本节先来看看 redis 中跳跃表结构的具体实现。

    一面:

    1. hashmap,怎么扩容,怎么处理数据冲突?怎么高效率的实现数据迁移?
    2. Linux的共享内存如何实现,大概说了一下。
    3. Linux 中的用户模式和内核模式是什么含意?
    4. 在 Java 中 Lock 接口比 synchronized 块的优势是什么?你需要实现一个高效的缓存,它允 许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它?
    5. socket网络编程,说一下TCP的三次握手和四次挥手
    6. 同步IO和异步IO的区别?
    7. Java GC机制?GC Roots有哪些?
    8. 如和判断一个对象是否存活?(或者 GC 对象的判定方法)
    9. 红黑树讲一下,五个特性,插入删除操作,时间复杂度?
    10. 快排的时间复杂度,最坏情况呢,最好情况呢,堆排序的时间复杂度呢,建堆的复杂度是多少

    第一轮非常重要,第一面能通过,后续被录用的可能性就比较高

    二面

    1. 自我介绍,主要讲讲做了什么和擅长什么
    2. 设计模式了解哪些?
    3. Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
    4. 什么是元数据?元数据分为哪些类型?包括哪些内容?与 cluster 相关的元数据
    5. AtomicInteger怎么实现原子修改的?
    6. RabbitMQ 上的一个 queue 中存放的 message 是否有数量限制?
    7. ConcurrentHashMap 在Java7和Java8中的区别?为什么Java8并发效率更好?什么情况下用HashMap,什么情况用ConcurrentHashMap?
    8. redis数据结构?
    9. redis数据淘汰机制?
    10. Redis 集群方案应该怎么做?都有哪些方案?

    三面(约五十分钟)

    1. mysql实现事务的原理(MVCC)
    2. MySQL 中控制内存分配的全局参数,有哪些?
    3. Redis 有哪些适合的场景?
    4. 有哪些数据库优化方面的经验?MySQL数据主从同步是如何实现的?
    5. MySQL索引的实现,innodb的索引,b+树索引是怎么实现的,为什么用b+树做索引节点,一个节点存了多少数据,怎么规定大小,与磁盘页对应。
    6. 如果Redis有1亿个key,使用keys命令是否会影响线上服务?
    7. Redis的持久化方式,aod和rdb,具体怎么实现,追加日志和备份文件,底层实现原理的话知道么?
    8. 遇到最大困难是什么?怎么克服?
    9. 未来的规划是什么?
    10. 你想问我什么?

    总结

    如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了,如果你有需要的话,请一定点赞分享本文,然后点击这里获取免费下载方式!

    《Java中高级核心知识全面解析》

    小米商场项目实战,别再担心面试没有实战项目:

    …(img-ULaC9FwO-1622036353041)]

    小米商场项目实战,别再担心面试没有实战项目:

    展开全文
  • Java泛型擦除补偿

    2020-09-12 23:24:27
    Java泛型擦除补偿 文章目录对Java泛型擦除补偿一、泛型的擦除1.1 为泛型类设置边界(可以设置多个边界),就可以通过泛型对象调用边界的方法二、擦除的补充2.1 对`instanceof`的补充:引入类型标签,使用动态...

    对Java泛型擦除的补偿

    一、泛型的擦除

    在泛型代码内部,无法获得任何有关泛型参数类型的信息。

    Java泛型是使用擦除实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,唯一知道的就是在使用一个对象。

    1.1 为泛型类设置边界(可以设置多个边界),就可以通过泛型对象调用边界的方法

    public class HasF {
        public void f(){
            System.out.println("HasF.f()");
        }
    }
    
    class Manipulator<T extends HasF>{
        private T t;
        public Manipulator(T t){
            this.t = t;
        }
        public void manipulate(){
            t.f();
        }
    }
    
    // 可以自行擦除,创建出没有泛型的类
    class Manipulator2{
        private HasF obj;
        public void manipulate(){
            obj.f();
        }
    }
    

    当希望代码能够跨多个类工作时,使用泛型才有所帮助。例如,返回T的方法,那么泛型就有所帮助,因为它们之后将返回确切的类型:

    class Manipulator3<T extends HasF>{
        private T t;
        public Manipulator3(T t){
            this.t = t;
        }
        public T getT(){
            return t;
        }
    }
    

    二、擦除的补充

    任何在运行时需要知道确切类型信息的操作都无法工作

    public class Erased<T>{
      private final int SIZE = 100;
      public static void f(Object arg){
        if(arg instanceof T){} // error
        T var = new T();   // Error
        T[] array = new T[SIZE]; // Error
        T[] array = (T)new Object[SIZE]; // Unchecked warning 
      }
    }
    

    2.1 对instanceof的补充:引入类型标签,使用动态的isInstance()

    class Building{}
    class House extends Building{}
    
    public class ClassTypeCapture<T> {
        Class<T> kind;
    
        public ClassTypeCapture(Class<T> kind){
            this.kind = kind;
        }
    
        public boolean f(Object arg){
            return kind.isInstance(arg);
        }
    
        public static void main(String[] args) {
            ClassTypeCapture<Building> ctt1 = new ClassTypeCapture<>(Building.class);
    
            System.out.println(ctt1.f(new House()));
            System.out.println(ctt1.f(new Building()));
        }
    }
    

    2.2 对泛型new T()对补偿:newInstance()、显式工厂

    使用下面的方式,如果实际类型没有默认构造器,将会运行时出错。

    class Employee{}
    
    public class ClassAsFactory<T> {
        T x;
        public ClassAsFactory(Class<T> kind){
            try {
                x = kind.newInstance();
            } catch (InstantiationException|IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    
        public static void main(String[] args) {
            ClassAsFactory<Employee> fe = new ClassAsFactory<>(Employee.class);
            System.out.println("ClassAsFactory<Employee> succeed");
            try {
                // Integer 没有默认对构造器, 因此会失败
                ClassAsFactory<Integer> fi = new ClassAsFactory<>(Integer.class);
            }catch (Exception e){
                System.out.println("ClassAsFactory<Integer> failed");
            }
        }
    }
    

    通过显式工厂,可以获得编译期检查:

    interface FactoryI<T>{
        T create();
    }
    
    class Foo2<T>{
        private T t;
        public <F extends FactoryI<T>> Foo2(F f){
            t = f.create();
        }
    }
    
    class IntegerFactory implements FactoryI<Integer>{
        @Override
        public Integer create() {
            return new Integer(0);
        }
    }
    
    class Widget{
        public static class Factory implements FactoryI<Widget>{
            @Override
            public Widget create() {
                return new Widget();
            }
        }
    }
    
    public class FactoryConstraint {
        public static void main(String[] args) {
            new Foo2<Integer>(new IntegerFactory());
            new Foo2<Widget>(new Widget.Factory());
        }
    }
    
    

    2.3 创建泛型数组:Array.newInstance()

    没有任何方式可以推翻底层的数组类型,它只能是Object[]

    class Generic<T>{}
    public class ArrayOfGeneric {
    
        static final int SIZE = 100;
        static Generic<Integer>[] gia;
    
        public static void main(String[] args) {
            // java.lang.ClassCastException
    //        gia = (Generic<Integer>[]) new Object[SIZE];
            gia = (Generic<Integer>[])new Generic[SIZE];
            System.out.println(gia.getClass().getSimpleName());
        }
    }
    

    泛型T[] ,因为有了擦除,数组的运行时类型就只能是Object[]。在下面代码中调用rep() 将报错:

    public class GenericArray<T> {
        private T[] array;
    
        public GenericArray(int sz){
            array = (T[]) new Object[sz];
        }
    
        public T get(int index){
            return array[index];
        }
        public T[] rep(){
            return array;
        }
    
        public static void main(String[] args) {
            GenericArray<Integer> gai = new GenericArray<>(10);
            // java.lang.ClassCastException,因为实际运行的类型是Object[]
            Integer[] ia = gai.rep();
        }
    }
    

    尝试将Object[]转换成T[],将在运行时产生异常。没有任何方式可以推翻底层的数组类型,它只能是Object[]

    public class GenericArray2<T> {
        private Object[] array;
    
        public GenericArray2(int sz){
            array = new Object[sz];
        }
    
        public void put(int index, T item){
            array[index] = item;
        }
        public T get(int index){
            return (T) array[index];
        }
        public T[] rep(){
            return (T[]) array;
        }
    
        public static void main(String[] args) {
            GenericArray2<Integer> gai = new GenericArray2<>(10);
            for (int i = 0; i < 10; i++) {
                gai.put(i, i);
            }
            for (int i = 0; i < 10; i++) {
                System.out.print(gai.get(i) + " ");
            }
            System.out.println();
            // java.lang.ClassCastException
            Integer[] ia = gai.rep();
        }
    }
    

    使用Array.newInstance() 创建泛型的数组:

    public class GenericArrayWithTypeToken<T> {
    
        private T[] array;
        public GenericArrayWithTypeToken(Class<T> type, int sz){
            array = (T[]) Array.newInstance(type, sz);
        }
    
        public void put(int index, T item){
            array[index] = item;
        }
    
        public T[] rep(){
            return array;
        }
    
        public static void main(String[] args) {
            GenericArrayWithTypeToken<Integer> gai = new GenericArrayWithTypeToken<>(Integer.class, 10);
            Integer[] ia = gai.rep();
            System.out.println(ia);
        }
    }
    
    展开全文
  • Java泛型擦除补偿

    千次阅读 2018-11-09 11:24:51
    Java泛型擦除补偿 public class Main&lt;T&gt; { public T makeArray() { // error: Type parameter 'T' cannot be instantiated directly return new T; } } 我们无法在泛型内部创建一个T类型的对象...

    Java泛型擦除的补偿

    public class Main<T> {
        public T makeArray() {
            // error: Type parameter 'T' cannot be instantiated directly
            return new T;
        }
    }
    

    我们无法在泛型内部创建一个T类型的对象,因为在运行时T仅仅是个占位符,并没有真实的类型信息,实际上,除了new表达式之外,instanceof操作和转型(会收到警告)在泛型内部都是无法使用的,而造成这个的原因就是之前讲过的编译器对类型信息进行了擦除。如果编译时不报错,那么将会在运行时出现异常。故在编译时即报错。

    为什么还要使用泛型:

    public class Main<T> {
        private T t;
        public void set(T t) {
            this.t = t;
        }
    
        public T get() {
            return t;
        }
    
        public static void main(String[] args) {
            Main<String> m = new Main<String>();
            m.set("findingsea");
            String s = m.get();
            System.out.println(s);
        }
    }
    /* Output
    findingsea
    */
    

    虽然有类型擦除的存在,使得编译器在泛型内部其实完全无法知道有关T的任何信息,但是编译器可以保证重要的一点:内部一致性,也是我们放进去的是什么类型的对象,取出来还是相同类型的对象,这一点让Java的泛型起码还是有用武之地的。

    代码片段四展现就是编译器确保了我们放在t上的类型的确是T(即便它并不知道有关T的任何类型信息)。这种确保其实做了两步工作:

    set()处的类型检验
    get()处的类型转换
    这两步工作也成为边界动作。
    

    解决 —— 擦除的补偿

    如上看到的,但凡是涉及到确切类型信息的操作,在泛型内部都是无法共工作的。那是否有办法绕过这个问题来编程,答案就是显示地传递类型标签

    public class Main<T> {
    
        public T create(Class<T> type) {
            try {
                return type.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public static void main(String[] args) {
            Main<String> m = new Main<String>();
            String s = m.create(String.class);
        }
    }
    

    上述代码展示了一种用类型标签生成新对象的方法,但是这个办法很脆弱,因为这种办法要求对应的类型必须有默认构造函数,遇到Integer类型的时候就失败了,而且这个错误还不能在编译器捕获。

    进阶的方法可以用限制类型的显示工厂和模板方法设计模式来改进这个问题,具体可以参见《Java编程思想 (第4版)》P382。

    public class Main<T> {
        public T[] create(Class<T> type) {
            return (T[]) Array.newInstance(type, 10);
        }
    
        public static void main(String[] args) {
            Main<String> m = new Main<String>();
            String[] strings = m.create(String.class);
        }
    }
    

    上述代码展示了对泛型数组的擦除补偿,本质方法还是通过显示地传递类型标签,通过Array.newInstance(type, size)来生成数组,同时也是最为推荐的在泛型内部生成数组的方法。

    展开全文
  • JAVA泛型擦除机制

    千次阅读 2015-09-27 17:03:22
    Java 泛型擦除机制
    public class TestF {
    
        public static void main(String[] args) {
            Class a1 = new ArrayList<Integer>().getClass();
            Class a2 = new ArrayList<String>().getClass();
            System.out.println(a1 == a2);
        }
    
    }

    如果仅凭直觉来看,该程序可能会输出 false 这个结果,但在具体的环境下运行时会输出 true 。这很令人费解,这是为什么呢?

    Java泛型是使用类型擦除来实现的。这表示在运行过程中任何和类型有关的信息都会被擦除,所有在运行中 ArrayList和ArrayList的具体信息都被擦除成它们的原生类型即ArrayList类型。

    由于擦除机制,泛型不能用于显示地引用运行时类型的操作之中,例如转型、new表达式和instanceof操作。

    若在泛型内部必须使用类型操作时,可以在运行时采用反射的方法将正在运行的类信息添加到泛型内部,这种方法称为补偿。

    public class Dog {
    
        public Dog() {
            System.out.println("Dog...");
        }
    }
    
    public class TestF2<T> {
        Class<T> type;
        public TestF2(Class<T> type) {
            this.type = type;
        }
    
        public boolean check(Object obj) {
            return type.isInstance(obj); //isInstance 和instanceof动态等价 
        }
    
        public void show(Class<T> type) {   //使用反射动态实现new表达式
            try {
                type.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            TestF2<Dog> t = new TestF2<Dog>(Dog.class);
            System.out.println(t.check(new Dog()));
            t.show(Dog.class);
        }
    
    }

    输出为:
    Dog…
    true
    Dog…

    展开全文
  • Java 泛型 擦除补偿

    2013-01-11 17:56:54
    有感 thingking in java question 1  arg instanceof E // error  先获得Class class; 然后class.isInstance(arg); question 2 importance  E e = new E();// error  //传递静态工厂, javaBean可以...
  • Java -- 泛型 泛型擦除 泛型补偿

    千次阅读 热门讨论 2017-03-11 20:52:01
    运行时:会将泛型去掉,生成的class文件时不带泛型的-- 成为泛型擦除 (1)为什么会擦除? 为了兼容运行的类加载器,(jdk1.5之后引入了泛型,但与之对应的运行的类加载器没有升级) 当然,并不是每一个泛型...
  • JAVA泛型擦除

    2016-04-03 13:32:38
    泛型泛型,字面意思将一个类泛化,让它适应...}看代码,JAVA中的泛型定义和C++的很是类似,不过相比于C++泛型的强大,JAVA泛型却很是纠结。 因为目前,除了写数据结构之外,JAVA泛型几乎可有可无。这是因为JAVA的一
  • java泛型擦除的神秘之处,边界处的动作,擦除的补偿
  • 本文主要介绍Java泛型的一些语法,重点解释Java泛型擦除机制,以及擦除所带来的一些问题
  • import java.util.ArrayList; public class Itr { public static void main(String[] args) { A<Integer> a = new A(); Object o = a.show();...为什么会出现上述现象,泛型擦除补偿机制触发条件到底是什么?
  • java泛型擦除补偿

    2018-11-19 21:24:23
    由于擦除,我们无法直接得到泛型参数的类型信息。所以任何运行时需要类型信息的操作都不能工作。 例如: (1)无法使用instanceof关键字 (2)无法通过new操作创建一个泛型参数类型的对象 (3)无法创建泛型数组...
  • 泛型擦除补偿

    2016-02-22 22:51:36
    下面由于java泛型信息被擦除了 所以下面的操作无法编译通过 public void f(Object o) { if (o instanceof T) { } } 采用显示传入类型的方法 作为泛型擦出的补偿 Class kind; public Erased(Class kind) { ...
  • NULL 博文链接:https://hyzhaolt.iteye.com/blog/443661
  • Java编程思想之【泛型擦除

    热门讨论 2021-04-27 09:00:43
    泛型二、泛型擦除1.擦除的神秘之处迁移兼容性擦除的问题擦除补偿 前言 还记得几年去一间公司面试的时候,面试官问的技术方面的问题,其中一个就是关于擦除的问题,当时的我第一次接触面试有点紧张而且对擦除这个...
  • 工厂模式:主要是为了创建对象提供过度接口,以便将创建对象的具体过程(new关键字和具体的构造器)隐藏起来 ...// generics/FactoryConstraint.java import onjava.Suppliers; import java.util...
  • 定义:在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类 ...// generics/CreatorGeneric.java abstract class GenericWithCreate<T> { final T element; GenericWithCreate() { ...
  • Java泛型:类型擦除

    2018-12-29 20:53:39
    Java泛型:泛型类、泛型接口和泛型方法 类型擦除 代码片段一 1 2 3 4 5 6 7 Class c1 = new ArrayList&lt;Integer&gt;().getClass(); Class c2 = new ArrayList&lt;String&...
  • 如果我们想要创建泛型数组,来看一下下面这个泛型类 class Generic<T>{} 如果我们要实例化一个Generic 的数组,比如 static Generic<Integer>[] gia; 编译器将接受这个程序,而不会产生任何警告.但是,...
  • 关于泛型擦除

    2017-01-17 20:21:50
    关于泛型擦除泛型是JDK1.5的一项新特性,他的本质就是参数化类型的应用。 Java语言中的泛型只是在程序源码中存在,在变异后的字节码文件中,已经被替换成原来的原生类型,并且在相应的地方插入强转型代码。 因此,...
  • 1、泛型擦除 ArrayList<String> ArrayList<Integer> 我们可能认为类型不同,但其实它们是相同的 ArrayList<Integer> arrays= new ArrayList<>(); ArrayList<String> arrays1= new...
  • java泛型详解

    万次阅读 多人点赞 2016-04-29 01:02:17
    1、什么是java泛型? 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 2、...
  • Java泛型

    2019-05-22 11:17:16
    目录 相关文章: 一、概述 二、举例 三、特性 四、泛型的使用 ...Java泛型常见面试题 ...深入偏难的一篇文章:泛型的理解及应用(一):泛型擦除 java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一 ...
  • Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限。 2、简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类。 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的对象的类型 ...
  • Java泛型中的擦除

    2016-10-25 16:52:12
    1、擦除 当深入了解泛型后,就会发现很多东西初看起来是没有意义的。例如,尽管可以申明ArrayList.class,但是不能申明为Array.class。例如: class Manipulator { private T obj; public Manipulator(T x) { obj...
  • JDK1.5开始实现了对泛型的支持,但是java泛型支持的底层实现采用的是类型擦除的方式,这是一种伪泛型。这种实现方式虽然可用但有其缺陷. 《Thinking in Java》的作者 Bruce Eckel也曾撰文《这不是泛型》批评过JDK...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 898
精华内容 359
热门标签
关键字:

java泛型擦除补偿

java 订阅