字节跳动青训营项目 ByteCode 展示

暑假报名了第一届字节跳动青训营,选拔进入进阶班后,需要小组合作做一个项目,进行展示和评比。于是,我们小组选择做一个叫ByteCode的项目。这是一个为用户创造自主学习环境的在线代码教学平台,用户可以得到即时反馈,从而锻炼编程技能。

在这个项目中,开发时长超过400分钟。基本上所有开发内容都是我负责的,包括React前端、node中间层及Go后端。因为没有规划好时间,在评比前一天才开始着手开发。

最终,在评比阶段,项目在11个小组中获得第三名,奖励字节水杯一个。花了不到一天的时间,获得三等奖,我自然是感到惊喜和得意的。但其实,仔细想想,只不过是自己长期对各类技术进行积累,才能让我在短期内快速堆砌各类技术栈,实现一个花俏的架构设计。Monorepo、GraphQL、gRPC、TailwindCSS、Apollo、微服务,就差把rxjs、webgl、k8s给加上去了,各类时髦的词语往上一堆,颇有种对自己涉猎广泛的得意洋洋。

然而,脱离实用的学习是在耽误时间。点技能树时,我不应当盲目追求广泛,也不应该过度执着于深度、难度。学习是为了创造价值,而不是让自己与众不同。我需要认真思考自己到底需要什么,能为社会和更多人做些什么。在后现代社会,这是防止自己滑向虚无的重要屏障。

以下是项目展示时我写的文档。

前言

ByteCode是字节跳动青训营的项目。这是一个为用户创造自主学习环境的在线代码教学平台,用户可以得到即时反馈,从而锻炼编程技能。

项目仓库:(MIT开源)

https://gitee.com/yar2001/byte-code

项目架构

项目功能展示

主页

题目选择

题目分类和内容,包括验证用户代码是否正确的脚本,都是在后端MySQL数据库中储存。因此,不需要修改项目,即可添加分类和题目。

教学和在线编程

登录

关于

项目技术展示

前端

前端使用CRA脚手架搭建,以TypeScript作为语言,React Router为路由,Apollo Client为状态管理工具,GraphQL为查询语言,TailwindCSS为UI框架,THREE.js作为图形渲染框架进行开发的。

基于ProxyWeb Workerwith语法的前端沙箱:用户输入的代码会进入JS沙箱,和事先写好的验证代码一起运行,从而判断代码是否符合要求。为了防止用户输入死循环代码,造成页面卡死,我们将沙箱放在了Web Worker中。

同时,考虑到未来可能有代码分享的功能,为了防止恶意代码破坏页面,基于Proxy+with的组合,可以让用户的代码无法逃逸出沙箱,确保平台的安全性。

我们重视项目的性能。

优化一个网页的响应时长,关键在于减少IO请求次数,提高缓存率。通过Apollo Client的标准化缓存,可以让我们做的这一点。

标准化缓存Apollo Client是一个借助GraphQL、比Redux抽象程度更高的状态管理工具。通过Apollo,我们将业务划分为几个领域模型(例如User、Question、Problem、Category等),通过GraphQL中Query和Mutation的概念发起API请求,实现效率更高的标准化缓存和请求查询。

我们重视开发效率和可维护性。

在业务开发中,我们的时间和精力应当放在核心逻辑上。然而,如果没有对开发流程进行恰当的设计,很多工作量都可能会被boilerplating所浪费,心智资源可能投入到难以理解的代码中。久而久之,这些代码将成为项目健康度的重要威胁,不利于长期维护和功能变更。

通过开源社区的基础设施GraphQL CodeGen,我们可以自动化生成接口代码。

自动化接口代码生成GraphQL Code Generator通过读取GraphQL的Schema,可以直接生成Apollo对应的查询接口函数和TypeScript类型声明。

我们拥抱变化,是敏捷开发思想的践行者。

在互联网时代,作为前端工程师的我们,必须面临业务需求快速变化的挑战。复杂冗长的文档已经过时,只有积极的接纳新技术、新思想,为业务注入与时代同行的活力,才能在竞争日益激烈的市场中做出有沉淀的产品。

基于领域模型的接口查询:领域模型的实质是业务的高度抽象化。因此,无论技术细节和架构如何变更,只要业务没有变化,基于模型的Schema就不会发生变化,可以长期使用。因此,GraphQL所提供的模型抽象,让我们有信心在面对未来的变化时秩序井然,为重构提供基石。

中间层

中间层使用Node.js,以Nest.js作为MVC框架,TypeScript为语言,Apollo Server为接口查询工具,MongoDB为数据库,JWT作为登录状态管理,实现基于Stateless Process,高性能的登录服务器。

中间层并不直接处理业务,而是负责所有业务中通用逻辑,例如登录、注册、身份验证、GraphQL查询请求等。Node出色的异步特性和架构设计时的无状态进程,可以让它适应流量的快速变化,在特定场景下迅速进行拓展,实现高可用高并发的目标。

在后期,项目规模达到一定程度时,使用这一系列技术栈有助于容器化、分布式部署。

基于Class模板的领域模型:Nest的装饰器大大提高了开发效率和代码可理解性。我们只需要定义一次,就可以在MongoDB和GraphQL同时完成模型的构建。

通过JWT和Guard装饰器进行身份验证:以洋葱模型为核心的Nest,让我们有机会通过Guard拦截请求,并对每个请求进行身份验证。同时,这一系列操作不需要在服务端中储存Session,降低了系统复杂度。

用户数据储存在MongoDB中

后端

后端以Go作为语言,MySQL作为数据库,gRPC作为接口调用协议,接收中间层Node的请求处理业务。

通过Go协程和可编译到二进制码的语言特性,相比于传统后端语言,Go提升了综合性能及并发性。作为高并发时代的基础设施,使用Go可以让项目未来获得更多资源。

gRPC接口协议:gRPC是Google推出的微服务rpc协议,在http2的基础上,通过protobuf对接口进行建模,实现基于二进制的数据传输,相比于REST,大大提高了性能和开发效率。

题目和分类储存在MySQL中

项目理念

通过ByteCode,我们对教育公平进行了初步探索。我们希望找到可持续降低教学成本的方案,让更多人更容易的获得时代发展的红利。

教育公平

目前,我国高等院校农村籍生源占比仅15%左右,较上世纪80年代减少了一半。重点院校如北京大学,在1978年~1998年农村籍大学生占比20%~40%,而到2000年以后则降至10%~15%。

同时,我国对教育投入占GDP比重达4%以上,在面临有限的社会资源情况下,只有降低教育成本,才是缓解区域发展不平衡的出路,才能从根本解决阶层流动减缓的问题。

发展权力和共同富裕

促进社会公平,是每一个有担当的企业的责任。作为互联网从业者,我们有机会为实现可复用的教学资源提供发展思路和方向。通过积极创造教学资源,降低进一步接受教育的成本,才能让中国庞大的人口,转化为推动新时代发展所需要的高科技素质人才。

欢迎来到Yari的网站:yar2001 » 字节跳动青训营项目 ByteCode 展示