欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java,

来源: javaer 分享于  点击 18288 次 点评:70

Java,



  1. 有个奇葩的点 ,HashTable里

区别只是能否remove而已, 这个设计不知道在干啥。
而HashMap 用了KeyIterator 和 ValueIterator 分开处理 ,HashTable用的是一个 ,区别了type而已

  1. HashMap 长度为什么必须是2的倍数?

    这是核心的get方法, 存的时候 ,Node是个数组,数组的角标 就是通过 length-1 & hash来的, 然而直接用存放数据的hash来算,数组长度一般都比较小,这样**&**出来的数据 碰撞就太容易发生了,所以HashMap自己实现了一个hash()

    右移16位, 就是取高16位 ,减少了碰撞的可能。

  2. ConcurrentHashMap 已经优化到不用Segment了 , 用volatile 的sizeCtl 实现互斥控制 ,put的同步用sychronize实现 , 用了大量的Unsafe包的CAS操作

  3. Java 8 以后 Interface 是可以有方法实现的 !


11. Monitor是对象同步的基本单元 , sychronize 在Java早期(6以前),Monitor的实现完全靠操作系统的互斥锁,这里涉及到了操作系统的两种操作级别,分权限的高低,因为内核原因, 比较耗费资源 ,设置 对象头中的Mark Word

  1. JVM 内存区域划分

    程序计数器
    

    存储当前线程的当前方法的JVM指令地址

    Java虚拟机栈
    

    每个线程在创建的时候都会创建一个虚拟机栈,调用一次方法,新建一个栈帧,JVM负责出栈和入栈
    栈中存放局部变量表动态链接,方法正常或者异常退出的定义

    堆(所有线程共享)
    

    存放对象实例, 会被不同的垃圾回收器划分,如 新生代 老年代

    方法区 (所有线程共享)
    

    存储元数据:类结构体 、对应的运行时常量池 字段 方法代码等 ,故在永久代Jdk8弃用后,增加了元数据区。

    运行时常量池
    

    在方法区里,包括 版本号、字段、方法、超类、常量池

    本地方法栈
    

    类似于Java虚拟机栈, 支持本地方法的调用

  1. volatile等 所谓的线程可见性,就是 内存屏障通过 强制刷出处理器缓存的方式 保证其他的线程拿到最新的值

  2. JMM 实际上平衡了 jvm和cpu对性能的要求 和java层简单的安全

  3. 一段代码说明 可见性和 原子性区别:

    试问: 如果去掉 sychronize 结果如何? 去掉volatile 结果如何? 去掉count的 static 结果如何???

  4. 所谓happen-bfore原则:

    在多线程条件下 发生了指令重排序,在如图场景中,对 f 的判断就会出现问题, 所以要按照原则来。

  5. java 的transient关键字,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

  6. MySQL 数据隔离级别大概分四个:

  • 读未提交 :一个事务能看到另一个事务未提交的状态, 容易脏读

  • 读已提交 :事务看到的是已提交的状态, 也不会有脏读,但是允许并发,会发生 不可重复读幻读

  • 可重复读: 在一个事务中读取的 数据是一致的,MySQL默认的隔离级别。不一定出现幻读,要根据不同数据库实现

  • 串行化: 并发事务是串行的,意味着要加锁了,也是 最高的隔离级别

    脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问 这个数据,然后使用了这个数据。
    不可重复读:一个事务中,你第一次读取了a的值,此时其他线程改变了a的值,第二次读a的值,值就不一样了。所以一个事务内读取同一个值但是结果不同,故称为 不可重复读。 其重点在于 修改
    幻读 :也是并发问题,比如当你执行 删除所有文档操作,同时,另一个事务增加了一个文档,所以当你执行完删除操作,发现还剩了一个,好像是幻觉一样。重点在于 增加和删除

  1. 线程数量的选择:

    如果主要任务是计算,那么CPU处理能力是稀缺的,如果太多线程,反而导致大量的上下文切换开销,这种情况下,
    线程数即为 CPU核数+1
    如果是较多等待的任务。比如I/O ,
    线程数可为: CPU核数 * 目标CPU利用率 *(1 +平均等待时间 / 平均工作时间)

相关文章

    暂无相关文章
相关栏目:

用户点评