美文网首页
面试-计数器相关

面试-计数器相关

作者: 史小猿 | 来源:发表于2018-05-15 19:26 被阅读45次

面试官问:

文件里有m个身份证号,统计每个身份证号出现的次数

回答:

使用hashMap实现,key作为身份证号
ContainsKey

Map<String, Integer> freq = new HashMap<String, Integer>();
public void incr (String word){
    int count = freq.containsKey(word) ? freq.get(word) : 0;
    freq.put(word, count + 1);
}

面试官问:

还能优化吗

回答:

TestForNull

Map<String, Integer> freq = new HashMap<String, Integer>();
public void incr (String word){
  Integer count = freq.get(word);
  if (count == null) {
      freq.put(word, 1);
  }
  else {
    freq.put(word, count + 1);
  }
}

减少调用containsKey方法的开销

面试官问:

如果是高并发情况呢

回答:

采用ConcurrentHashMap去做,线程安全的

面试官问:

高并发下HashMap有什么问题吗

回答:

并发情况下使用HashMap造成Race Condition,从而导致死循环,CPU占用率会达到100%
博文链接hashMap死循环

面试官问:

ok 用ConcurrentHashMap 实现下

回答:

ConcurrentMap <String, Integer> freq = new ConcurrentHashMap <String, Integer>();
public void incr (String word){
  Integer count = freq.get(word);
  if (count == null) {
      freq.put(word, 1);
  }
  else {
      freq.put(word, count + 1);
  }
}

面试官问:

确定能实现?

回答:

实现不了 put操作会覆盖,比如两个线程同时进来读到了都是4,那么都会put 5进去,
可以给方法加上synchronized锁

ConcurrentMap <String, Integer> freq = new ConcurrentHashMap <String, Integer>();
public synchronized void incr (String word){
  Integer count = freq.get(word);
  if (count == null) {
      freq.put(word, 1);
  }
  else {
      freq.put(word, count + 1);
  }
}

面试官问:

嗯嗯 加锁确实能实现,但是性能差点,能优化下吗

回答(当时回答的不好):

能,采用cas方式

ConcurrentMap<String, AtomicLong> map = new ConcurrentHashMap<String, AtomicLong>();
public void incr (String word){
  map.putIfAbsent(word, new AtomicLong(0));
  map.get(word).incrementAndGet();
}

也可以采用 AtomicLongMap,AtomicLongMap是Google Guava项目的一个类,它是线程安全、支持并发访问的,通过CAS方式实现

AtomicLongMap<String> map = AtomicLongMap.create();
public void incr (String word){
   map.getAndIncrement(word);
}

延伸:

AtomicLong – 这组类使用CAS(比较并交换)处理器指令来更新计数器的值。听起来不错,真的是这样吗?是也不是。好的一面是它通过一个直接机器码指令设置值时,能够最小程度地影响其他线程的执行。坏的一面是如果它在与其他线程竞争设置值时失败了,它不得不再次尝试。在高竞争下,这将转化为一个自旋锁,线程不得不持续尝试设置值,无限循环直到成功。这可不是我们想要的方法。让我们进入Java 8的LongAdders

相关文章

  • 面试-计数器相关

    面试官问: 文件里有m个身份证号,统计每个身份证号出现的次数 回答: 使用hashMap实现,key作为身份证号C...

  • 如何多个请求返回成功后再执行相关操作?

    去面试的时候,遇到面试官问这个问题。 多个请求返回成功后再执行相关操作的方式有三种: 第一种:计数器变量 每个页面...

  • 【2019-05-09】MapReduce的特性

    计数器内置计数器 任务计数器采集任务的相关信息,每个作业的所有任务的结果会被聚集起来。任务计数器由其关联任务维护,...

  • JVM以及调优

    为了 面试!!!!jvm内存模型: 栈、堆、程序计数器、方法区 调优

  • Need Note Link

    Android 2.2 中文 Api 农民伯伯的博客 面试相关 面试相关1(内有干货链接)吧主 面试相关2(面试题...

  • iOS面试准备之思维导图(附资料)

    目录 1.UI视图相关面试问题 2.Runtime相关面试问题 3.内存管理相关面试问题 4.Block相关面试问...

  • ios 面试指南思维导图

    1.UI视图相关面试问题 2.Runtime相关面试问题 3.内存管理相关面试问题 4.Block相关面试问题 5...

  • iOS 的内存管理

    面试的时候几乎都会被问, 是个比较大的问题. 整理了一些可以聊的点. 引用计数器, ARC 和 MRC 引用计数器...

  • php7内存分配与垃圾回收

    垃圾回收 文件:zend_gc.c 引用计数方式:数据存储的物理空间增加一个计数器,其它数据相关时,计数器+1,反...

  • 面试相关

    问:谈一下你是用了哪些数据交换格式. (0)介绍+用法 (1)Json:是以键值对来存放数据的,大括号表示一个对象...

网友评论

      本文标题:面试-计数器相关

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