编辑注:我们很少在 Hacks 博客上听到职业生涯初期 Web 开发人员和软件工程师的声音。这篇文章很好地提醒了我们他们的经历。
Mozilla 参加 Outreachy,并提供实习机会,将女性和其他弱势群体引入 自由和开源软件 的世界。即将到来的下一轮申请流程 将于 2015 年 9 月 22 日开放。申请截止日期为 10 月 26 日。实习时间为 2015 年 12 月 7 日至 2016 年 3 月 7 日。如果你一直在考虑申请,请阅读本文,像 Gloria 一样,行动起来!
我如何成为 Mozilla 实习生
那是希腊的一个春夜,我收到了 Mozilla 选中我成为 Outreachy 实习生的消息。Outreachy 是 软件自由保护协会 的一个项目,旨在帮助 FOSS(自由和开源软件)中代表性不足的群体参与进来,通过提供多个开源软件组织的重点实习机会。那一夜,我相信我是我们镇上最快乐的人。我还记得在被幸福冲昏头脑之前,我急切地向我的导师 Peter Bengtsson 表示感谢,以至于忘记了表达我的感激之情。这是一个双向选择。我选择了 Mozilla,Mozilla 也选择了 我。
我从 2015 年 3 月开始为 Air Mozilla 做贡献,通过解决一些易于上手的 bug。最初我并不想申请,因为有太多优秀的贡献者,在某种程度上,我被这个流程的严谨性所压倒。我告诉很多人我不会申请,因为我害怕自己会被拒绝,有时害怕是正常的,但害怕自己能够做到的事情,并因此而自我破坏,这是不可取的。
在经过几番鼓励后,我查看了公司名单,决定只申请 Mozilla。我告诉自己,要么成功,要么失败。我注意到它上面写着“Python”,我意识到自己对 Python 并不精通,因为我以前只是自学过一段时间,但我告诉自己要尝试一下。有时你需要做一些困难的事情来获得你想要 的经验。每个专家都曾经是新手。我去查看 Bugzilla,看看我能解决什么问题。一个 bug 看起来非常简单,所以我认为应该做一下。就这样开始了。反馈、坚持、拉取、合并、解决合并冲突以及更深入地了解代码库的功能,让我能够做出更多贡献。我非常喜欢开源实习的一点是,一切都公开透明。我被要求写博客记录我的工作内容,我不需要隐瞒任何相关信息。当然…这并不意味着我也分享我的密码!密码需要保护并保密是有原因的。
开始在 Air Mozilla 工作
实习的第一天正式开始于 5 月 25 日。我被告知,经过讨论,我被分配了一个新的功能。这个新功能将作为一个推荐系统,在 Air Mozilla 观众观看特定事件时,推荐类似的事件。 Air Mozilla 是 Mozilla 在线多媒体平台,提供直播和预录节目、采访、新闻片段、教程视频以及关于 Mozilla 社区的特色内容。
这听起来很有趣。我一点也不紧张,它似乎很有趣,而且我一直很好奇这些东西是如何工作的,直到我开始遇到真正的困难。然后我意识到它的复杂性。我必须要么自己构建算法和计算来完成工作,要么找到一个开源工具来使用,而不是重新造轮子。经过几天的研究,我们决定 Elastic Search 似乎很合适。Elastic Search 是一款搜索服务器。它有一个名为“More Like This”的功能,可以帮助你根据设定的参数搜索类似的事件。我去阅读了 Elastic Search 的文档,但说实话,我很难理解它。主要是因为我找不到关于如何使用它与 Python 结合的足够多的例子。在某个时候,我们决定 pyelasticsearch 可能会使事情变得更容易;它是一个 Python 版本的 Elastic Search 库,拥有我们想要的功能。
简而言之,Elastic Search 创建了一个映射,并对 Air Mozilla 上的所有事件进行索引。当你访问一个事件页面时,使用“More Like This”功能,我们要求它搜索与你当前正在查看的事件类似的已索引事件,并在后端返回标题、ID、标签及其相似度分数。为了使事件被认为是相关的,它们的标签、频道和标题必须非常相似,但这并不是我们唯一的考量因素。
我们还需要能够设置某人的访问级别:登录为 Mozilla 员工的人比匿名访客拥有更多访问权限。登录的志愿者贡献者比匿名访客拥有更多访问权限,但比 Mozilla 员工少。你懂我的意思。每个事件都有自己的访问级别设置。一些事件是私密的,仅限员工访问,而大多数 Air Mozilla 事件对公众或整个 Mozilla 社区成员开放。无论如何,相关事件功能可以让用户看到类似事件的列表,根据他们的访问级别进行过滤,最相似的“相关事件”会显示在最上面。
实现 Elastic Search
在下面的代码中,我们使用的是 more_like_this (mlt) 查询。我们将标签和标题拆分为不同的查询,因为我们希望将每个查询的关联度分数提升到不同的程度。在这种情况下,我们希望相似的标题比相似的标签具有更高的关联度分数。field 参数用于确定我们尝试对哪个字段运行 mlt,docs 参数是我们尝试为其查找类似事件的文档。你可以在 More Like This 查询 页面了解更多信息。
mlt_query1 = { 'more_like_this': { 'fields': ['title'], 'docs': [ { '_index': index, '_type': doc_type, '_id': event.id }], 'min_term_freq': 1, 'max_query_terms': 20, 'min_doc_freq': 1, 'boost': 1.0, } } mlt_query2 = { 'more_like_this': { 'fields': ['tags'], 'docs': [ { '_index': index, '_type': doc_type, '_id': event.id }], 'min_term_freq': 1, 'max_query_terms': 20, 'min_doc_freq': 1, 'boost': -0.5, } }
下面我们要求一个或多个给定的 mlt 查询应该匹配文档,即事件列表。
query_ = { 'bool': { 'should': [mlt_query1, mlt_query2], } }
下面,使用 request.user.is_active
我们检查用户是否登录以及他们的访问级别。如果用户以志愿者身份登录,则显示的事件不能包含仅限 Mozilla 员工访问的事件。
如果用户登录并且不是志愿者,这意味着他们是 Mozilla 的付费员工。他们的“相关事件”结果应该包含所有与我们当前正在查看的事件类似的事件。
对于匿名用户, “相关事件”结果必须仅包含对所有人开放的事件。
if request.user.is_active: query = { 'fields': fields, 'query': query_ } else: query = { 'fields': fields, 'query': query_, "filter": { "bool": { "must": { "term": {"privacy": Event.PRIVACY_PUBLIC} } } } }
在上面的代码中,你可以看到我们使用了 more_like_this 查询以及一个过滤器。More_like_this 会根据标题、标签和频道返回类似的事件,但它并不能确保返回的事件会根据访问级别进行过滤。所以这就是 “filter”
发挥作用的地方。它确保过滤相关的事件,并只允许用户根据他们的访问级别查看的事件。
通过使用 cron 作业,我完全删除并重新索引一周的索引,并且每 10 分钟重新索引(无需先删除)所有在过去 10 分钟内发生更改的事件。
AJAX 查询用于获取相关事件的缩略图和链接。AJAX 是异步加载的,因此运行这些查询不会减慢页面加载速度。当我查看一个事件时,我希望它完全加载页面,而无需等待 Elastic Search 完成查询运行。Elastic Search 查询运行速度很快,但仍然需要一些时间。有时,它可能会很慢。相关事件部分显示在事件详情下方。理想情况下,观看事件的人不会介意在观看事件时,相关事件加载速度稍慢,但是整体页面加载速度慢会让人感到沮丧。通过 AJAX,我们的 Elastic Search 查询可以在页面加载后在后台运行。
在下面的屏幕截图中,你可以看到它是如何工作的。我在我们正在查看的事件标题和第一个推荐事件标题上添加了红色箭头。如果你比较两张图片,你可以看到我们正在查看和/或推荐的事件是如何相互关联的。
让你意识到你有多享受实习的 4 个关键要素
- 你的导师确保你采取了正确的步骤,学习了很多。
- 你感觉实习的每个部分,即使是令人沮丧的时刻,也让你在技能和个人成长方面都取得了进步。
- 你非常高兴自己得到了这次实习机会。
- 你非常悲伤实习要结束了。
这正是我所经历的。我要感谢 Outreachy、我的导师 Peter 以及我在实习期间在 IRC 和电子邮件中认识的其他 Mozilla 人员。感谢你们的帮助、欢迎和为我的学习体验做出的贡献。
让我的实习结束变得光彩照人、快乐无比的是 Mozilla 引以为傲的格言:曾经的 Mozilla 人,永远的 Mozilla 人。
关于 Gloria Dwomoh
Gloria Dwomoh 在希腊比雷埃夫斯应用科学大学学习信息学和计算机工程。她喜欢解决问题、学习新事物和编程。她一直在寻找方法,通过开源贡献、自学和其他方法来提高她的技术技能。她是一位多才多艺的通才。您可以在她的个人博客中了解更多关于她的信息:gloriadwomoh,me/blog