界面开发学校:明斯克任务分析和莫斯科新任务

今天开始新的招生 Yandex 界面开发学校 在莫斯科。 第一阶段培训将于7月25日至3月XNUMX日进行。 来自其他城市的学生将能够远程或亲自参加——公司将支付旅费和宿舍住宿费。 第二阶段,也是最后阶段,将持续到XNUMX月XNUMX日,只能亲自完成。

我的名字是 Yulia Seredich,我们和 Sergei Kazakov 一起写了这篇文章。 我们都是Yandex明斯克办公室的界面开发人员,也是SRI往年的毕业生。

界面开发学校:明斯克任务分析和莫斯科新任务

在莫斯科开始注册之际,我们将发布对前一所学校(明斯克)的介绍性任务的分析。

如果你追溯 SRI 作业的历史,我们每年都会测试程序员的三项重要技能:

  • 布局。 每个开发人员都应该能够进行布局。 不可能有谢廖扎叔叔为整个团队做设计,而你只写剧本。 因此,每个学生都必须表现出他如何懂得排版。
  • JavaScript。 如果只限于布局的话,我们就不是界面开发学院,而是布局设计师学院了。 设计精美的界面需要复兴。 因此,总有 JS 的任务,但有时这也是算法的任务 - 我们非常喜欢它们。
  • 解决问题可能是开发人员最重要的技能。 在创建界面时,事情变化得非常快。 就像刘易斯·卡罗尔(Lewis Carroll)所说:“你必须尽可能快地跑才能留在同一个地方,而要到达另一个地方,你必须跑得快两倍。” 我们每天都会遇到新技术 - 我们需要考虑并理解它们。 因此,在第三个任务中,我们建议了解新手开发人员通常不熟悉的技术。

在对每个任务的分析中,我们不仅会告诉您正确的步骤,还会告诉您常见的错误。

任务 1:作品集

第一项任务是由懂得如何进行布局的 Yandex.Collections 设计师 Alexey Cherenkevich 和他的服务同事、界面开发人员 Sergey Samsonov 完成的。

条件

创建一个作品集网站:向我们介绍一下您自己、您的工作以及您对学校的期望。 该网站应尽可能符合建议的布局(布局链接: 1000px, 600px, 320px, 规格)。 我们只对布局感兴趣,所以请不要使用 JavaScript。

检查时我们会考虑:

  • 缩进大小、颜色正确性、字体样式、字体大小;
  • 语义布局;
  • 元素不同状态的存在:悬停光标时显示按钮和链接、突出显示活动输入字段等;
  • 跨浏览器兼容性(在流行浏览器的最新版本中测试)。

优点将是:

  • 使用现代 CSS 解决方案:flexbox、grid 等;
  • 自适应布局;
  • 使用预处理器和(或)后处理器、汇编、缩小、优化输出代码;
  • HTML 表单验证、风格化文件上传按钮。

该任务相当庞大,因此您可以跳过那些不起作用的内容。 这会稍微降低您的分数,但您仍然能够展示您的知识。 完成后,请向我们发送两个链接 - 您的作品集和 GitHub 上的源代码。

作业中提出的布局不仅适用于移动设备、平板电脑和台式机的屏幕,而且还具有真实的规格。

为了使第一个任务的检查结果尽可能客观,这次检查有很多标准。

标准

设计网站。 这似乎是显而易见的,但有些人完全跳过了一些块——要么他们想节省时间,要么他们做不到。 布局大致可分为四个主屏幕:带有头像的主屏幕、带有 SRI 期望列表的块、带有投资组合的块和带有联系信息的块。 它们可以分段制作,也可以简单地使用 div,最主要的是所有四个块都可用。

布局与布局的一致性。 设计师制定了单独的规范(包括颜色、排版、按钮状态等),以方便应聘者。 底部有关于第一个屏幕的缩进和功能的提示。 我对那些考虑到设计师所有愿望的人感到非常满意:例如,第一个屏幕应该不小于视口的高度。

自适应布局 - 这是当界面不仅仅是布局以便在三种分辨率下一切都是像素到像素的布局时。 在中间状态下,布局也不应该崩溃。 有些人忘记限制容器的最大宽度并将所有内容设置为 1920 像素,有些人弄乱了背景,但总的来说,候选人很好地应对了这项任务。

语义布局。 “他们告诉世界多少次”链接应该设计为,按钮应该设计为。 幸运的是,大多数候选人也满足了这一要求。 并不是每个人都认识到 SRI 期望中的隐藏列表,使其使用 div 标签,但也没有那么糟糕。 有一位候选人插入了他所知道的所有语义标签——哪里需要,哪里不需要。 例如,代替列表 -和。 毕竟,语义 - 它是关于理解页面的组成和每个块的目的(这里大多数人管理它),以及关于预处理器和/或后处理器的使用(这里一些人管理它,尽管这也是要点 - 他们最常使用 less 和 scss)。

工作滑块。 作业中我们写到不能使用JS。 这里测试了解决问题的能力——可以使用一堆来制作滑块和。 所有的魔法都发生在选择器级别#button-N:checked ~ .slider-inner .slider-slides。 当我们点击其中一个输入复选框时,它就会进入选中状态。 我们可以利用这一点,将我们需要的翻译分配给带有幻灯片的容器:transform:translate(-33%)。 可以看到滑块的实现 这里.

下拉列表。 这一切也归结为和类似的选择器:.accordion-item input:checked ~ .accordion-item__content。 你可以看到实现 这里.

:hover、:active 和 :focu* 状态的可用性。 非常重要的一点。 与界面交互过程中的舒适度取决于它。 用户应该始终收到有关其行为的反馈。 在与问卷互动的整个过程中都检查了该项目。 如果我单击“给我打电话”按钮,但视觉上没有任何反应(即使请求已发送),这很糟糕,因为这样我会一次又一次地单击它。 结果,将发送十个请求,我将被回电十次。 我们不能忘记,移动设备没有鼠标,这意味着不应该有悬停。 还有一点并不影响那些满足语义这一点的人。 如果您的控件不是交互式元素,那么当您将鼠标悬停在其上时,光标将保持标准状态。 即使你写了悬停反应,它看起来也很乱。 不要低估光标:指针。

动画。 重要的是,与元素发生的所有反应都要顺利。 生活中没有什么是瞬时的,因此在悬停和活动状态下进行转换足以使界面更加令人愉悦。 好吧,那些为滑块和列表设置动画的人通常都很棒。

使用最新技术。 很多人使用flex,但没有人使用grid完成任务。 如果正确使用了flex,则得分会被计算在内。 如果布局在某个地方由于这些弯曲而分崩离析,唉,您没有收到任何额外的分数。

表单验证。 所需要做的就是将 required 属性添加到表单的每个输入中。 我们为那些将电子邮件字段验证为电子邮件的人添加了积分。

设置文件上传按钮的样式。 我们期望看到这样的组合: 并选择文件。 接下来我们需要隐藏输入并设置标签的样式。 还有另一种常见的方法 - 制作透明输入并将其放在按钮顶部。 但并非所有浏览器都允许样式设置,这样的解决方案不能称为完全跨浏览器。 而且做标签在语义上更正确。

跨浏览器兼容性。 我们检查了两个最新版本的现代浏览器(没有 IE - 参与者很幸运)以及 iPhone 上的 Safari 和 Android 上的 Chrome 中一切正常。

相反,如果有人使用 JS 或 Bootstrap,我们就会扣分:这两者都会破坏整个任务的目的。 此外,使用 Bootstrap 的参与者不仅得到了减分,而且在语义和实现元素上也丢了很多分。

那些将网站托管在互联网上的人并没有获得任何特别的优势 - 但审阅者非常高兴他们不必下载存储库并在计算机上本地运行它们。 所以这对业力来说是一个加号。

第一个任务主要对学生来说非常有用。 那些我们没有接受的人现在已经准备好了简历 - 您可以自豪地将其附加到所有回复中或将其发布到您的 gh 页面上。

任务2:运输路线

该任务的作者是搜索界面小组的负责人 Denis Balyko。

条件

你有星图吗? 它显示每颗恒星的名称,以及它与其他恒星的距离(以光秒为单位)。 实现解决方案函数,该函数应采用三个参数:一个对象,其中键是星星的名称,值是到星星的距离(太空中的单向交通),以及路径的起点和终点 - 分别是起点和终点。 该函数应返回从起始星到结束星的最短距离以及要遵循的路径。

函数签名:

const solution = function(graph, start, finish)  {
    // Ваше решение
} 

输入数据示例:

const graph = {
  start: { A: 50, B: 20 },
  A: { C: 40, D: 20 },
  B: { A: 90, D: 90 },
  C: { D: 160, finish: 50 },
  D: { finish: 20 },
  finish: {}
};
const start = 'start';
const finish = 'finish'; 

输出示例:

{
    distance: 90,
    path: ['start', 'A', 'D', 'finish']
} 

注意:解决方案框架位于 src/ 文件夹中,将您的解决方案放入solution.js 中。

第二个任务的验证是最自动化和客观的。 大多数人猜测有必要实现 Dijkstra 算法。 那些找到它的描述并用 JS 实现该算法的人做得很好。 然而,在检查作业时,我们发现很多论文都有同样的错误。 我们在网上搜索了代码片段,找到了一篇文章,参与者从中复制了算法。 有趣的是,很多人复制了文章中的代码以及作者的评论。 此类作品得分较低。 我们不禁止使用任何来源,但我们希望人们深入研究他所写的内容。

标准

测试主要得分。 有时很明显,这些人在搞乱存储库、重命名文件夹,并且测试会失败,仅仅是因为他们找不到必要的文件。 今年,我们试图帮助这些人,并将所有东西归还给他们。 但明年我们计划改用竞赛制,这将不再被原谅。

还有“人类”的手动标准。 例如,单一代码风格的存在。 没有人因为使用制表符而不是空格而被扣分,反之亦然。 如果您根据您已知的规则将单引号与双引号交替,并随机放置分号,那就是另一回事了。

解决方案的清晰度和可读性是单独考虑的。 在世界上所有的会议上,他们都说程序员 80% 的工作就是阅读别人的代码。 甚至小学生也接受来自他们的管理者和彼此之间的代码审查。 因此,这一标准具有重要意义。 有些作品中变量的长度不超过一个字符 - 请不要这样做。 除了与 Stella Chang 的评论相同的评论之外,参与者的评论都非常令人鼓舞。

最后一个标准是自动测试的存在。 只有少数人添加了它们,但对每个人来说,这都成为他们业力的巨大加分。

正确的决定:

const solution = function(graph, START, FINISH)  {
    // Всё не бесплатно в этом мире
    const costs = Object.assign({[FINISH]: Infinity}, graph[START]);

    // Первая волна родительских нод
    const parents = { [FINISH]: null };
    Object.keys(graph[START]).reduce((acc, child) => (acc[child] = START) && acc, parents)

    const visited = [];
    let node;

    // Ищем «дешёвого» родителя, отмечаем пройденные
    do {
        node = lowestCostNode(costs, visited);
        let children = graph[node];
        for (let n in children) {
            let newCost = costs[node] + children[n];

            // Ещё не оценена или нашёлся более дешёвый переход
            if (!costs[n] || costs[n] > newCost) {
                costs[n] = newCost;
                parents[n] = node;
            }
        }
        visited.push(node);
    } while (node)

    return {
        distance: costs[FINISH],
        path: optimalPath(parents)
    };

    // Возврат назад по самым «дешёвым» родителям
    function optimalPath(parents) {
        let optimalPath = [FINISH];
        let parent = parents[FINISH];
        while (parent && parent !== START) {
            optimalPath.push(parent);
            parent = parents[parent];
        }
        optimalPath.push(START);
        return optimalPath.reverse();
    }

    // Минимальная стоимость из текущей ноды среди непросмотренных
    function lowestCostNode(costs, visited) {
        return Object.keys(costs).reduce((lowest, node) => {
            if (lowest === null || costs[node] < costs[lowest]) {
                if (!visited.includes(node)) {
                    lowest = node;
                }
            }

            return lowest;
        }, null);
    };
};

任务 3:活动日历

它是由界面开发人员 Sergey Kazakov 和 Alexander Podskrebkin 编写的。

条件

写一个迷你日历来显示您的日程安排。 您可以选择任何您喜欢的时间表。 比如2019年前端会议日程。

日历应该看起来像一个列表。 没有其他设计要求。 可以提前 3、7 和 14 天设置事件提醒。 首次从互联网下载后,日历应打开并离线运行。

有用的资源

前端会议日程:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

服务人员:
developer.mozilla.org/ru/docs/Web/API/Service_Worker_API/Using_Service_Workers
Developers.google.com/web/fundamentals/primers/service-workers

通知API:
developer.mozilla.org/ru/docs/Web/API/Notifications_API

第三个任务是测试中最有趣的,因为有很多可能的解决方案,每个都有自己的解决方案。 我们检查了候选人如何处理不熟悉的技术——他是否知道如何研究,是否测试了他的解决方案。

标准

折叠日历。 是的,它仍然需要布置。 还有一些人过于字面地理解了这个条件,没有插入一行 CSS 代码。 看起来不太吸引人,但如果一切顺利的话,积分并不会减少。

从源获取事件列表。 这不是一个布局任务,因此其中包含的事件列表没有被计算在内。 您随时可以取消会议、重新安排会议或添加新会议。 所以需要从外部接收数据,并根据接收到的JSON来渲染布局。 以任何方式获取数据(使用 fetch 方法或使用 XMLHttpRequest)都很重要。 如果一个人添加了一个用于 fetch 的 polyfill 并在自述文件中标记了他的选择,这被算作一个加号。

Service Worker 注册没有错误 并在第一次下载后离线工作。 下面是一个例子 Service Worker 在首次启动时进行计划缓存。 有关服务工作线程、其功能以及使用它们的方式(使用缓存、离线工作的策略)的详细信息可以在此处找到。

能够设置提醒所以它实际上在 3、7、14 天后起作用。 有必要了解通知 API, 链接到哪个 是正确的任务。 我们并不期望有任何具体的实现来检查是否是时候推送了。 任何工作选项都被接受:存储在 localStorage、IndexDB 中或由服务工作者定期轮询。 甚至可以制作一个推送服务器(这里 例子),但它无法离线工作。 在页面关闭后以及一段时间后打开后接收推送同样重要。 如果提醒在页面关闭的同时消失,则解决方案不计算在内。 当这些人考虑到审稿人并让现在就获得推送成为可能时,这真是太酷了 - 以免等待 3 天。

能够在桌面上放置图标 (PWA)。 我们检查了文件的存在 的manifest.json 使用正确的图标。 有些人制作了这个文件(或者让它在 CreateReactApp 中生成) - 但没有添加正确的图标。 然后,在尝试安装时,出现“需要不同的图标”之类的错误。

代码风格和项目结构。 与第二个任务一样,我们研究了单一代码风格(即使它与我们的代码风格不一致)。 有些人搞砸了短绒 - 这太棒了。

控制台错误。 如果控制台上有一个指示器表明出了问题,而参与者没有注意到它,那么我们就会扣分。

结果

参与者的决定有什么有趣的地方:

  • 一份调查问卷包含以下文字:“一位程序员朋友帮助我构建了一个 React 应用程序。 我连珠炮般地问他如何以及为什么,他告诉了我。 我真的很喜欢它,我想了解更多。” 我们全心全意地支持这个申请,但不幸的是,候选人的朋友对申请的成功并没有多大帮助。
  • 一位候选人发送了一个 RAR 存档所在的 GitHub 链接 - 对此很难发表评论。 🙂
  • 另一位候选人在solution.js文件第一行的评论中诚实地承认他复制了该算法。

我们收到了 76 名候选人的申请,最终选定了 23 人。 我们不仅收到了来自明斯克的问卷调查,还收到了来自莫斯科、圣彼得堡甚至鞑靼斯坦的问卷调查。 其中一些人目前的职业让我们感到惊讶:其中一个是法医专家,另一个是医学生。

结果是完成任务的成功率的有趣分布。 参与者平均完成了第一个任务的 60%,第二个任务完成了 50%,第三个任务是最困难的,平均完成了 40%。

乍一看,这些任务看起来既复杂又耗时。 原因并不是我们想淘汰尽可能多的候选人。 在学习期间,学生面临着现实生活中的任务 - 聊天、为儿童设计 Yandex.Music 或为依赖天气的人设计 Yandex.Weather。 为此,您需要一个起始基地。

我记得两年前看到我的 SRI 入学任务并认为我永远无法解决它。 此时最主要的是坐下来,仔细阅读条件并开始做。 事实证明,这些条件几乎包含了 80% 的解决方案。 例如,在第三个任务(最困难的)的情况下,我们在 MDN 上添加了 Service Worker 和Notifications API 的链接。 研究了链接内容的学生毫无困难地完成了它。

我真的希望那些计划将来进入 SRI 的考生、无法进入明斯克学校的考生或正在开始执行任何其他考试任务的考生阅读这篇文章。 正如您所看到的,这样做是完全有可能的。 您只需要相信自己并听取作者的所有提示即可。

来源: habr.com

添加评论