美文网首页编程语言爱好者
hashcode相等两个类一定相等吗?equals呢?相反呢?

hashcode相等两个类一定相等吗?equals呢?相反呢?

作者: 编程鸭 | 来源:发表于2019-04-08 10:26 被阅读0次

    1、hashcode相等两个类一定相等吗?equals呢?相反呢?

    结论:equals 相等的 hashcode一定相等,反之不一定。

    原因:在java中,equals和hashcode是有设计要求的,equals相等,则hashcode一定相等,反之则不然。 

    为何会有这样的要求? 

    在集合中,比如HashSet中,要求放入的对象不能重复,怎么判定呢? 

    首先会调用hashcode,如果hashcode相等,则继续调用equals,也相等,则认为重复。如果重写equals后,如果不重写hashcode,则hashcode就是继承自Object的,返回内存编码,这时候可能出现equals相等,而hashcode不等,你的对象使用集合时,就会等不到正确的结果。

    2、介绍一下集合框架?

    3、hashmap hastable 底层实现什么区别?hashtable和concurrenthashtable呢?

    hashmap 和hashtable基本上一样,只不过hashtable是线程安全的,而hashmap 是线程不安全的。而concurrenthashtable跟hashtable的区别在于,concurrenthashtable是基于用了分段锁的设计,只有在同一个分段内才存在竞态关系,不同的分段锁之间没有锁竞争。相比于对整个Map加锁的设计,分段锁大大的提高了高并发环境下的处理能力。但同时,由于不是对整个Map加锁,导致一些需要扫描整个Map的方法(如size(), containsValue())需要使用特殊的实现,另外一些方法(如clear())甚至放弃了对一致性的要求(ConcurrentHashMap是弱一致性的,具体请查看ConcurrentHashMap能完全替代HashTable吗?)。

    4、hashmap和treemap什么区别?低层数据结构是什么?

    hashmap底层是数组加链表结构,数组用来根据key的hashcode值来定位一个对象应该属于哪一个index,而链表结构可以解决当key的hashcode值相等而equals方法值不相等的问题。,而treemap底层是红黑树结构,红黑树的结构是为了兼顾增删改查的多维度性能而设计的。

    5、线程池用过吗都有什么参数?底层如何实现的?

    publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,                              TimeUnit unit,                              BlockingQueue workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,            Executors.defaultThreadFactory(), defaultHandler);    }

    1.corePoolSize:线程池中默认保留线程数量,即便是线程是空闲线程。

    2.maximumPoolSize:线程池中保留的最大数量的线程。

    3.keepAliveTime:当线程数量大于corePoolSize 之后,线程在空闲情况下最长保留时间。

    4.unit:keepAliveTime的时间单位,包括天、小时,分钟,秒,微妙,毫秒,纳秒。

    5.workQueue:一个阻塞队列,用来存储等待执行的任务,包括:ArrayBlockingQueue(有界阻塞队列,在队列达到一定),LinkedBlockingQueue,SynchronousQueue,其中LinkedBlockingQueue(链表阻塞队列,包括了读锁和写锁,而ArrayBlockingQueue只有一个锁,所以效率相对LinkedBlockingQueue会慢一些)和SynchronousQueue(同步阻塞队列,它没有容器,生产之后就需要有消费者来消费)比较常用。

    6.threadFactory:线程工厂,主要用来创建线程的工厂。

    7.handler:表示当拒绝任务处理时的策略。有四种取值: 

    1.ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

    2.ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

    3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

    4.ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

    6、sychnized和Lock什么区别?sychnize 什么情况情况是对象锁? 什么时候是全局锁为什么?

    1.synchnized 是关键字,在方法出错之后由java虚拟机自动解除锁定,而 Lock属于Api级别的锁,它需要自己在 finally方法后面保证锁的释放。

    2.synchnized 不能实现公平锁,而 Lock可以,Lock还可以添加多个监听条件来对锁进行控制,可以中断。

    3.synchronized 作用在普通方法上属于对象锁,作用在静态方法,类.class 上面,属于全局锁。对象锁只对同一个对象加锁,作用对象是同一个对象。而类锁是对类加锁,对整个类都有效。 

    如果锁住的是一般方法就是对象锁,对象锁只会对同一个对象起作用,如果是锁住了static 方法则是全局锁,会对全局对象都管用,如果想在普通方法中使用全局锁需要锁住class对象。

    7、ThreadLocal 是什么底层如何实现?写一个例子呗?

    ThreadLocal 底层是存储在 线程本地Map里面的一个对象,它跟当前线程绑定,以 ThreadLocal 对象本身为 key,以ThreadLocal里面存的值为值,目的是为了实现线程之间的数据的隔离。

    publicstaticfinal ThreadLocal session =newThreadLocal();publicstaticSessiongetCurrentSession() {          Session s = (Session)session.get();if(s ==null){              s = sessionFactory.openSession();              session.set(s);          }returns;      }

    8、volatile的工作原理?

    线程安全需要3步骤: 

    1.操作的原子性(要么全部成功,要不全部失败) 

    2.操作的可见性(所有线程都可见) 

    3.操作的有序性。而对于volatile的只能保证可见性,所以对于 i=i++这种操作是不具有原子性的,所以这类的操作无法使用 volatile关键字进行修饰。

    使用场景:

    1.状态标记

    volatilebooleanshutdownRequested;  ...publicvoidshutdown() {      shutdownRequested =true;  }publicvoiddoWork() {while(!shutdownRequested) {// do stuff  }  }

    2.一次性安全发布(one-time safe publication):单例模式的双重检查

    packagecom.masterslave.singleton;/**

    * 双重检查

    */publicclassDoubleCheck{/**

        * 因为instance被声明成了 volatile 所以,

        * 每次得到的对象都是主内存中最新的对象状态,所以保证了实例的可见性

        */privatevolatilestaticDoubleCheck instance;privateDoubleCheck() {    }/**    * 双重检查保证线程安全    * @return*/publicstaticDoubleCheckgetInstance() {if(instance ==null) {synchronized(instance) {if(instance ==null) {                  instance =newDoubleCheck();              }          }      }returninstance;    }}

    3.独立观察(independent observation) 

    如下代码展示了身份验证机制如何记忆最近一次登录的用户的名字。将反复使用lastUser 引用来发布值,以供程序的其他部分使用。

    publicclassUserManager{publicvolatileString lastUser;//发布的信息  publicbooleanauthenticate(String user, String password) {booleanvalid = passwordIsValid(user, password);if(valid) {              User u =newUser();              activeUsers.add(u);              lastUser = user;          }returnvalid;      }  }

    4.开销较低的“读-写锁”策略 

    如果读操作远远超过写操作,您可以结合使用内部锁和 volatile 变量来减少公共代码路径的开销。

    @ThreadSafepublicclassCheesyCounter {// Employs the cheap read-write lock trick  // All mutative operations MUST be done with the 'this' lock held  @GuardedBy("this")privatevolatileintvalue;//读操作,没有synchronized,提高性能  publicintgetValue() {returnvalue;      }//写操作,必须synchronized。因为x++不是原子操作  publicsynchronizedintincrement() {returnvalue++;      }

    15

    9、cas知道吗如何实现的?

    Compare and Swap 比较并刷新到缓存。通过比较线程旧值跟内存中的值是否相等来判断当前的值能否刷新到缓存中。

    10、请用至少四种写法写一个单例模式?

    饿汉模式:

    packagecom.masterslave.singleton;/**

    * 饿汉模式

    */publicclassHungry{privatestaticHungry instance =newHungry();privateHungry() {    }publicstaticHungrygetInstance() {returninstance;    }}

    懒汉模式

    packagecom.masterslave.singleton;/**

    * 懒汉模式

    */publicclassLazy{privatestaticLazy instance;privateLazy() {    }/**    * 使用 synchronized 解决线程安全问题    * @return*/synchronizedpublicstaticLazygetInstance() {if(instance ==null) {            instance =newLazy();        }returninstance;    }}

    双重检查

    packagecom.masterslave.singleton;/**

    * 双重检查

    */publicclassDoubleCheck{/**

        * 因为instance被声明成了 volatile 所以,

        * 每次得到的对象都是主内存中最新的对象状态,所以保证了实例的可见性

        */privatevolatilestaticDoubleCheck instance;privateDoubleCheck() {    }/**    * 双重检查保证线程安全    * @return*/publicstaticDoubleCheckgetInstance() {if(instance ==null) {synchronized(instance) {if(instance ==null) {                  instance =newDoubleCheck();              }          }      }returninstance;    }}

    静态内部类

    packagecom.masterslave.singleton;/**

    * 静态内部类

    */publicclassInnerStaticClass{staticclass InnerClass{/**

            * 由于静态单例对象没有作为 InnerStaticClass 的成员变量直接实例化,

            * 因此类加载时不会实例化 instance 对象,

            * 第一次调用 getInstance 时将加载内部类 InnerClass,

            * 在该类内部定义了一个 instance 变量,此时首先会初始化这个变量,

            * 由java虚拟机来保证线程安全性,确保改成员变量只能实例化一次,

            * 由于没有任何锁定,所以其性能不会受到任何影响。

            */privatefinalstaticInnerStaticClass instance =newInnerStaticClass();    }privateInnerStaticClass() {    }publicstaticInnerStaticClassgetInstance() {returnInnerClass.instance;    }}

    几种模式性能比较: 

    - 1.饿汉模式不论使用不使用都会初始化。 

    - 2.懒汉模式存在锁,对性能有影响。 

    - 3.双重检查也存在锁,对性能有影响。 

    - 4.静态内部类性能最好。

    JVM

    1、请介绍一下JVM内存模型??用过什么垃圾回收器都说说呗

    jvm包括2方面: 

    1.1.线程私有区: 

    1.程序计数器,记录正在执行的虚拟机字节码的地址。 

    2.虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧。 

    3.本地方法栈:虚拟机的Native方法执行的内存区。 

    1.2.线程共享区: 

    1.Java堆:对象分配内存的区域; 

    2.方法区:也称为持久代 

    3.常量池:存放编译器生成的各种字面量和符号引用,是方法区的一部分。

    2、线上发送频繁full gc如何处理? CPU 使用率过高怎么办?

    Partial GC:并不收集整个GC堆的模式Young GC:只收集young gen的GC

    Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式

    Mixed GC:收集整个young gen以及部分old gen的GC。只有G1有这个模式

    Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

    full gc 需要先定位然后找出问题之后再具体解决,比如使用visualvm 工具先定位出现问题的原因,在jvm参数上配置如下参数,在发生full GC之前先把堆内容给备份一下。

    -Xmx2g-XX:+HeapDumpBeforeFullGC-XX:HeapDumpPath=. -Xloggc:gc.log-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCDateStamps-XX:+UseGCLogFileRotation-XX:NumberOfGCLogFiles=10-XX:GCLogFileSize=100m-XX:HeapDumpOnOutOfMemoryError

    3、知道字节码吗?字节码都有哪些?Integer x =5,int y =5,比较x =y 都经过哪些步骤?

    4、讲讲类加载机制呗都有哪些类加载器,这些类加载器都加载哪些文件?

    1.启动类加载器

    2.扩展类加载器

    3.应用类加载器

    4.自定义加载器 

    手写一下类加载Demo

    importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.nio.ByteBuffer;importjava.nio.channels.Channels;importjava.nio.channels.FileChannel;importjava.nio.channels.WritableByteChannel;publicclassMyClassLoaderextendsClassLoader{publicMyClassLoader()      {      }publicMyClassLoader(ClassLoader parent)      {super(parent);      }protectedClassfindClass(String name)throwsClassNotFoundException      {          File file =newFile("D:/People.class");try{byte[] bytes = getClassBytes(file);//defineClass方法可以把二进制流字节组成的文件转换为一个java.lang.Class  Class c =this.defineClass(name, bytes,0, bytes.length);returnc;          }catch(Exception e)          {              e.printStackTrace();          }returnsuper.findClass(name);      }privatebyte[]getClassBytes(File file)throwsException      {// 这里要读入.class的字节,因此要使用字节流  FileInputStream fis =newFileInputStream(file);          FileChannel fc = fis.getChannel();          ByteArrayOutputStream baos =newByteArrayOutputStream();          WritableByteChannel wbc = Channels.newChannel(baos);          ByteBuffer by = ByteBuffer.allocate(1024);while(true){inti = fc.read(by);if(i ==0|| i == -1)break;              by.flip();              wbc.write(by);              by.clear();          }          fis.close();returnbaos.toByteArray();      }  }

    5、知道osgi吗? 他是如何实现的?

    你可以动态地安装、卸载、启动、停止不同的应用模块,而不需要重启容器。

    6、请问你做过哪些JVM优化?使用什么方法达到什么效果?

    7、classforName(“java.lang.String”)和String classgetClassLoader() LoadClass(“java.lang.String”) 什么区别啊?

    Class.forName() 会初始化对象,而String.class.getClassLoader 不会。 

    Class.forName(className)方法,内部实际调用的方法是Class.forName(className,true,classloader); 

    第2个boolean参数表示类是否需要初始化, Class.forName(className)默认是需要初始化。 

    一旦初始化,就会触发目标对象的 static块代码执行,static参数也也会被再次初始化。 

    ClassLoader.loadClass(className)方法,内部实际调用的方法是 ClassLoader.loadClass(className,false); 

    第2个 boolean参数,表示目标对象是否进行链接,false表示不进行链接,由上面介绍可以,不进行链接意味着不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行。

    Spring

    1、spring都有哪些机制啊AOP底层如何实现的啊IOC呢?

    1.IOC、AOP

    2.IOC的实现方式就是就是反射和CGLIB。

    2、cgLib知道吗?他和jdk动态代理什么区别?手写一个jdk动态代理呗?

    cglib 代理的是普通的类,而jdk代理的是接口。jdk 只能代理接口,而cglib只能代理普通类,可以在spring配置中强制使用cglib代理。

    <aop:aspectj-autoproxyproxy-target-class="true"/>)。

    1、使用mysq索引都有哪些原则? 索引什么数据结构?

    1.选择维度高

    2.选择 where、on、group by、order by中出现的列。

    3.选择较小的数据列。

    4.为较长的字符串使用前缀索引

    5.组合索引能够减小索引文件大小,使用速度也优于单列索引

    6.勿滥用索引,因为索引除了站磁盘空间意外,在进行增、删、改操作的时候,每次都要重新建立索引。

    7.索引不会包含有 NULL值得列,若组合索引包含有NULL值得列,整个索引无效

    8.使用索引尽量避免使用 OR,否定查询,模糊查询,NOT IN,“<>”操作。

    9.组合索引的最左前缀原则

    2、mysq有哪些存储引擎啊?都有啥区别? 要详细!

    1.MyISAM存储引擎:不支持事务、也不支持外键,优势是访问速度快,对事务完整性没有 要求或者以select,insert为主的应用基本上可以用这个引擎来创建表 

    2.该存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM引擎,写的处理效率会差一些,并且会占用更多的磁盘空间以保留数据和索引。 

    InnoDB存储引擎的特点:支持自动增长列,支持外键约束

    3、设计高并发系统数据库层面该怎么设计?数据库锁有哪些类型?如何实现呀?

    1.垂直拆分,根据业务拆分表。

    2.水平拆分,根据id进行取模放入到不同数据库中。

    3.垂直拆分+水平拆分。

    4、数据库事务有哪些?

    原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。 

    一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。 

    隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 

    持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。

    分库分表

    1、如何设计可以动态扩容缩容的分库分表方案?

    2、用过哪些分库分表中间件,有啥优点和缺点?讲一下你了解的分库分表中间件的底层实现原理?

    3、我现在有一个未分库分表的系统,以后系统需分库分表,如何设计,让未分库分表的系统动态切换到分库分表的系统上? 那若出现网络原因,网络连不通怎么办啊?

    4、分布式事务知道吗? 你们怎么解决的?

    5、为什么要分库分表啊???

    6、分布式寻址方式都有哪些算法知道一致性hash吗?手写一下java实现代码??你若userId取摸分片,那我要查一段连续时间里的数据怎么办???

    7、如何解决分库分表主键问题有什么实现方案??

    主键不采用自增策略,而采用统一主键生成规则。

    分布式缓存

    1、redis和memcheched 什么区别为什么单线程的redis比多线程的memched效率要高啊?

    相同点:都是使用的多路io复用的方式,减少了阻塞,充分的利用cpu和内存性能。 

    不同点:redis单进程单线程,Memcache 多进程单线程,redis自己写了一套epoll的实现,而Memcache 使用的是Libevent,这个组件本身比较大,有很多无用代码,对Memcache性能有影响,还有就是Memcache采用的CAS这种方式也会对性能造成影响。

    2、redis有什么数据类型都在哪些场景下使用啊?

    3、reids的主从复制是怎么实现的redis的集群模式是如何实现的呢redis的key是如何寻址的啊?

    1.全量同步

    Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下: 

    1)从服务器连接主服务器,发送SYNC命令; 

    2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 

    3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 

    4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 

    5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 

    6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

    2.增量同步

    RedisSlave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 

    增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

    3.同步策略

    主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全is 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

    4.注意点

    如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

    4、使用redis如何设计分布式锁?使用zk可以吗?如何实现啊这两种哪个效率更高啊??

    5、知道redis的持久化吗都有什么缺点优点啊? ?具体底层实现呢?

    6、redis过期策略都有哪些LRU 写一下java版本的代码吧??

    分布式服务框架

    1、说一下dubbo的实现过程注册中心挂了可以继续通信吗??

    2、zk原理知道吗zk都可以干什么Paxos算法知道吗?说一下原理和实现??

    3、dubbo支持哪些序列化协议?hessian 说一下hessian的数据结构PB知道吗为啥PB效率是最高的啊??

    4、知道netty吗’netty可以干嘛呀NIO,BIO,AIO 都是什么啊有什么区别啊?

    5、dubbo复制均衡策略和高可用策略都有哪些啊动态代理策略呢?

    6、为什么要进行系统拆分啊拆分不用dubbo可以吗’dubbo和thrift什么区别啊?

    分布式消息队列

    1、为什么使用消息队列啊消息队列有什么优点和缺点啊?

    2、如何保证消息队列的高可用啊如何保证消息不被重复消费啊

    3、kafka ,activemq,rabbitmq ,rocketmq都有什么优点,缺点啊???

    4、如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路

    分布式搜索引擎

    1、es的工作过程实现是如何的?如何实现分布式的啊

    2、es在数据量很大的情况下( 数十亿级别)如何提高查询效率啊?

    3、es的查询是一个怎么的工作过程?底层的lucence介绍一下呗倒排索引知道吗?es和mongdb什么区别啊都在什么场景下使用啊?

    高并发高可用架构设计

    1、如何设计一个高并发高可用系统

    2、如何限流?工程中怎么做的,说一下具体实现

    3、缓存如何使用的缓存使用不当会造成什么后果?

    4、如何熔断啊?熔断框架都有哪些?具体实现原理知道吗?

    5、如何降级如何进行系统拆分,如何数据库拆分????

    分布式专题架构

    通信协议

    1、说一下TCP ‘IP四层?

    2、http的工作流程?? ?http1.0 http1.1http2.0 具体哪些区别啊?

    3、TCP三次握手,四层分手的工作流程画一下流程图为什么不是四次五次或者二次啊?

    4、画一下https的工作流程?具体如何实现啊?如何防止被抓包啊??

    算法

    1、比较简单,我一个文件,有45亿个阿拉伯数字,如何进行去重啊如何找出最大的那个数啊?

    数据结构

    1、二叉树和红黑树等。

    源码中所用到的经典设计思想用设计模式

    及常用设计模式

    如果您Java学习的过程中遇到难题,欢迎关注微信公众号【潭州筑梦Java】,大家一起交流讨论解决!

    相关文章

      网友评论

        本文标题:hashcode相等两个类一定相等吗?equals呢?相反呢?

        本文链接:https://www.haomeiwen.com/subject/hxtuiqtx.html