引言:

作为资深老鸟,有事没事,出去面试;找准差距、定位价值。

面试必谈哈希,

Q1:什么是哈希?

Q2:哈希为什么快?

Q3:你是怎么理解哈希算法利用空间换取时间的?

Q4:你是怎么解决哈希冲突的?

Q5:你有实际用写过哈希算法吗?

1. 知识储备

  哈希(也叫散列)是一种查找算法(可用于插入),哈希算法希望能做到不经过任何比较(发生冲突,还是需要少许比较),通过一次存取就能得到查找的数据。

因此哈希的关键在key和数据元素的存储位置之间建立一个确定的对应关系,每个key在哈希表中都有唯一的地址相对应(形成有限、连续的地址空间),查找时根据对应关系经过一步计算得到key在散列表的位置。

在数学上, 原Key叫做原像,由映射函数h(key)映射的存储位置叫做像;在IT领域,以上存储位置叫哈希地址(散列地址),这个映射过程叫做哈希/散列。

故我们可以预见:

  ① 不同的key值,由哈希函数h(x) 作用后可能映射到同一个哈希地址, 这就是哈希冲突,冲突发生的概率取决于 定义的哈希函数

  ② 由哈希表作用后的哈希地址需要空间存储,这一系列连续相邻的地址空间叫哈希表、 散列表。

  处理哈希冲突可分为两大类:

  (1)开散列法发生冲突的元素存储于数组空间之外。可以把“开”字理解为需要另外“开辟”空间存储发生冲突的元素, 又称【链地址法】

  (2)闭散列法发生冲突的元素存储于数组空间之内。可以把“闭”字理解为所有元素,不管是否有冲突,都“关闭”于数组之中,闭散列法又称【开放定址法】,意指数组空间对所有元素,不管是否冲突都是开放的

  哈希表是用数组实现的一片连续的地址空间,两种冲突解决方案的区别在于发生冲突的元素是存储在这片数组的空间之外还是空间之内

2. 看图说话

---以下是开散列法(链地址法)解决冲突的示意图------

  从图上看实现【哈希】过程分两部分:

① 哈希函数

  收敛函数,不可避免会冲突,需要思考设定一个均衡的哈希函数,使哈希地址尽可能均匀地分布在哈希地址空间

②  构造哈希表 + 冲突链表

  装填因子loadfactor :所谓装填因子是指哈希表中已存入的记录数n与哈希地址空间大小m的比值,即 α=n / m ,α越小,冲突发生的可能性就越小;α越大(最大可取1),冲突发生的可能性就越大。

  另一方面,α越小,存储窨的利用率就越低;反之,存储窨的利用率就越高。为了既兼顾减少冲突的发生,又兼顾提高存储空间的利用率,通常把α控制在0.6~0.9的范围之内

哈希在.Net中的应用

  Object基类中有GetHashCode方法,HashCode是一个数字值,用于在【基于哈希特性的集合】中插入和查找某对象;GetHashCode方法为需要快速检查对象相等性的算法提供此哈希代码;

  Do not test for equality of hash codes to determine whether two objects are equal. (Unequal objects can have identical hash codes.) To test for equality, call the ReferenceEquals or Equals method.  (重要的话要读3遍)

单纯判断【逻辑相等】时,本无所谓重写 GetHashCode方法;但若在基于hash的集合中快速查找/插入某元素,则一定要重写GetHashCode方法。

? 我们看一个实锤:

  统计参加Footabll,Basketball 两个球队的所有成员,自然会想到对 footabllTeam, basketballTeam 成员使用Union方法求并集 (A∪B)

  观察Union源码计算A,B并集的实现,内部会构造哈希表Set<TElement> 快速查找和插入并集元素,故我们需要给元素编写合适的哈希函数。

public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)

{

if (first == null) throw Error.ArgumentNull("first");

if (second == null) throw Error.ArgumentNull("second");

return UnionIterator<TSource>(first, second, comparer);

}

static IEnumerable<TSource> UnionIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)

{

Set<TSource> set = new Set<TSource>(comparer);

foreach (TSource element in first)

if (set.Add(element)) yield return element;      //  Set 便是Union方法内部构造的哈希表

foreach (TSource element in second)

if (set.Add(element)) yield return element;

}

Union方法入口

高潮来了,不是总说没处理过哈希冲突吗?结

【知识储备】

围观链地址法处理哈希冲突

因此有最佳实践: 当两对象重写Equal方法返回true时, 请务必重写GetHashCode方法为对象返回相同的hashcode。

话虽如此,写一个合适、均衡的哈希函数还是比较考验算法的。

在一般场景中,经验会帮助你编写哈希函数, 比如以上Person类中,字符串类型Name的HashCode总是相等的。

That‘all   看完了通篇文章的同栈猿,应该就可以回答文章引言 5大提问。

面试必谈的哈希,.Net 程序员温故而知新相关推荐

  1. 谈恋爱就是创业?程序员必看的恋爱秘籍,赶紧get起来吧

    谈恋爱就是创业?程序员必看的恋爱秘籍,赶紧get起来吧 我注意到你的时候,你没注意到我 我爱上你的时候,你注意到我 我准备离开的时候,你爱上了我 好险,你喜欢我的时候我还喜欢着你 高中.大学.毕业.工 ...

  2. 大厂面试:一个四年多经验程序员的BAT面经(字节、阿里、腾讯)

    大厂面试:一个四年多经验程序员的BAT面经(字节.阿里.腾讯) 目录 背景 说明 字节面经 面试题 腾讯面经 面试题 阿里Lazada 面试题 经验之谈 1.首要条件:准备好基础的八股文 2.常用的中 ...

  3. Interview:Java岗位面试—面试求职攻略之一个JAVA程序员面试心得(非常值得收藏)

    Interview:Java岗位面试-面试求职攻略之一个JAVA程序员面试心得(非常值得收藏) 导读 据网上资料显示:2018年互联网行业是寒冬,其他行业日子也不好过.各个互联网大厂纷纷缩招减员,严格 ...

  4. Android面试总结,终于有人把安卓程序员必学知识点全整理出来了,移动架构师成长路线

    前言 这篇文章主要是分享今年面试心得,现已就职于某大厂有三个月了,近期有很多公司均已启动秋招,也祝大家面试顺利,获得理想的offer! 之前找工作的那段时间感想颇多,总结一点面试经验和人生思考分享给大 ...

  5. 面试感悟:3年工作经验程序员应有的技能

    前言 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Ja ...

  6. java面试时候算法题多吗_java程序员面试中最容易被问到的18个算法题(附答案!)...

    作者:cpp软件架构狮 链接:https://www.toutiao.com/i6618515311836529156/ (点击阅读原文前去围观) 算法是比较复杂又基础的学科,每个学编程的人都会学习大 ...

  7. 面试了一位 46 岁的程序员,思绪万千,最后结局竟让我大惊失色!

    故事开头 最近一直忙于面试,人事推给了我一份简历,职位是算法工程师,年龄是 46 岁,我揉了揉眼睛后再看看,确实是 46 岁.抱着忐忑的心,我电话面试一番后,还是不觉得他和我们的团队很适合. 人都会有 ...

  8. 从面试官的角度聊聊培训班对程序员的帮助,同时给培训班出身的程序员一些建议...

    谈到程序员(尤其是零项目经验的程序员)找工作,培训班是个不可回避的讨论热点.虽然本人也做过兼职Java培训老师,多少了解些培训班的事,但在这问题上无意为任何培训学校站台.而且本人一直在做技术面试官,所 ...

  9. 想要,不一定得到,一定要,则必成功——一封初为程序员充满困惑的大学毕业生的来信以及本人

    尊敬的程杰老师:您好! 首先请允许我这么称呼你,虽然你是高级软件工程师,但我觉得叫你高级软件工程师老师更能表达我对你所写的<大话设计模式>一书无比的喜爱和对你本人无比的敬佩! 我是个刚大学 ...

最新文章

  1. 不到顶会现场也能听论文讲解?这个视频集合网站值得收藏
  2. 网站常规基本优化工作有哪些?
  3. python各个解释器的用途-常见的Python五大解释器!
  4. HTML 各种鼠标手势
  5. json数据封装以及使用Gson将json数据封装到bean
  6. SQL server 复习一
  7. 光缆弹性模量计算_光缆的制造、种类、施工、选用方法(超全)
  8. 【Flink】FLink 如果watermark水印时间超出今天会是什么问题呢
  9. python while for 只循环一次,如何在python 3中为每个inside和while循环只执行一次代码块...
  10. access口 环路_利用STP解决二层环路、实现链路冗余-stp文件怎么打开
  11. Windows 7,无法访问internet,DNS无响应
  12. vue 第七天(循环遍历)
  13. 离线使用yum·无法使用yum的情况下安装软件·最简单的方法
  14. sublime text2配置文件详解(转)
  15. 系统编程之实战小项目-利用LVGL 与 mplayer制作音频播放器
  16. w10用计算机卸载,win10系统用电脑自带的程序卸载软件的方法 (两种方法)
  17. 软件管理的一位牛人.
  18. 宇宙飞机(space plane)
  19. 新手小白搭建服务器环境如何选择呢?lnmp还是lamp?
  20. IOS学习路线(2014-05-08)

热门文章

  1. 面向全球用户的Teams app之Culture计量单位和禁忌篇
  2. 小程序禁用ios 左右滑动_如何在使用应用程序时禁用iOS控制中心
  3. 受 SQLite 多年青睐,C 语言到底好在哪儿?
  4. 使用Java实现K-Means聚类算法
  5. Codevs2157 配对
  6. Resin的安全性ip限制
  7. S5PC100基于I2C子系统的lm75驱动流程图
  8. POJ 3981(字符串替换)
  9. google code for xbmc addons2
  10. 操作系统和数据库的知识梳理(思维导图)