Normal view

There are new articles available, click to refresh the page.
Before yesterday中原驿站

回调之 Node.js VS 串行之 Python

By: 胡中元
12 April 2018 at 18:46

Node 与 Python,都是脚本语言,有着类似的使用场景,所以在各个地方早已经互相 pk、比较过无数回了。虽然我知道编程语言之间的 VS 是一个很 low 的行为,因为他们必定是各有优势的。但今天我还是特别的想说说自己的心得体会。

Node 是我曾经特别喜欢,也是非常熟练的编程语言。Python 我还处于学习阶段,不敢说深入了解。

使用场景

如果要评论手机 App 开发,自然是有着一堆框架的 Node 胜出,而如果站在科学计算领域,那胜利者绝对是 Python。所以本文主要还是对简单的日常场景进行对比 ———— 代替 Shell 的那些操作、作为服务器中间件与数据库打交道等等。

Python 脚本

前几个周我写了数个 Python 脚本,这便是其中一个。将 NAS 中我收集的漂亮壁纸的分辨率、时间信息记录到 SQLite 数据库中,再定时从数据库中随机取出近期未使用过的壁纸,让桌面壁纸换一换。

Python 对于这种事情确实在行。另外我根据爬虫创建的翻墙规则 Shadowrocket-ADBlock-Rules 也是使用 Python 生成的,5 线程爬虫协同工作,代码清晰简洁。

Node 脚本

Node 上面提到的那些,相对而言更适合较大的项目。比如我开发的 XSYU-GMS 教务系统,就是一个前后端全栈 Javascript 项目。

对于 web 中间件,例如监听 443 端口提供数据相关的 API 调用服务。Node 原生可作为一个守护进程保持运行,灵活维护一些常量(Python 也是这样,只是感觉工作量会更大一点),作为脚本语言的高维护性体现出来,并且 Node “以事务驱动单进程” 的特性在极限情况下可以实现超高的性能。

Node 成败均在回调

继续上文。虽说 Node “以事务驱动单进程” 的特性在极限情况下可以实现超高的性能。但是对于大多数情况下,Python 也是可以撑住的。低负载的情况下,Node 引以为傲的 “事务驱动” 就变成了可怕的 “回调地狱”,在性能提升不大的情况下,严重影响了开发效率,甚至是提高了程序复杂度所导致的出错率。

我曾经在用 Node 开发 RSS 爬虫时,认真思考每一步之间的相互依赖关系,哪些可以并行,哪些必须等待。然后精确地实现,代码看起来非常复杂。实际上的效率提升其实真不是很重要,全部都用串行实现,岂不一样可以达到目的。

毕竟,要最追求效率那我应该选择 C 甚至是汇编,既然选择了 Node 这样的脚本语言,那就是为了开发方便。 实际上,计算机编程语言的发展,就是在不断地用运行效率换取开发效率。当然,不会因为开发效率彻底代替运行效率。

Promise 与 Async Function

这大概就是拯救 Node 回调地狱的存在吧,确实,程序写起来体验好太多了。但是…… 这又导致了 await 地狱…… >o<

下面是我今天的代码,功能从数据库中获取部分 Email 地址,给他们发送邮件。

(async function() {
    let maxTimeStr = new Date().toUTCString();

    ret = await sqlP(`select username from user WHERE 
        d=0 AND status=1 AND created_at line.username);


    for(addr of emailList) {
        try {
            await sendMailForTK(addr);
        }
        catch(e) {
            console.log('sendMail failed', addr, e);
            await sleep(61);
            contine;
        }

        // send Done
        sqlP('update user SET d=88 WHERE username="' + addr + '"');

        await sleep(6);
    }

    process.exit();
})();

/**
三步串行操作:
1. 从数据库取得邮箱地址
2. 发送邮件
3,将记录写回数据库
*/

代码中的 sqlP(), sleep(), sendMailForTK(),都是我自己封装的 Promise Object,虽然封装不是个麻烦事,但我有一种感觉 —— 以后几乎所有的 Node 开发,都要经历这一步了。同时必须要经过的一步那就是在调用的时候用上 await,这就是 await 地狱。

于是问题来了,既然我们 80% 需要的程序逻辑都是串行,那么把这 80% 的代码特殊处理还真是一键麻烦的没必要的事情。像 Python 那样默认为串行,在 20% 的时候再使用多线程,在我看来是一种更合适、更通用的模式。

事件驱动是 JS 的核心,所以 Node 自然以后也只能保持这种模式了。

对 Node 的总结

我认为,Node 的最佳使用场景仅限于需要其特点:”异步回调” 的时候,可以带来高性能。而其他时候,这只会带来麻烦。

当然,Node 超级给力的模块机制,以及与简单易学的 JS 搭配实现的 web 开发语言前后端同一等等,使得 JS 永远充满魅力。

Python 的缺点

就并行串行而言,Python 我更偏好,但是这门语言我还是有一些需要吐槽的地方。

1. 编程风格

对于初学的我来说,完全不能赞同 Python 那些语法就是 “优雅的编程”,而 C 风格的大括号、分号就有多难看。在 class 里面,最多只能一个空行,而不能 2 个。使用 Python 编程让我有种被限制的感觉(也许还是因为我不熟悉吧)

总之我认为 “非 C 风格编程” 是一个缺点。

2. 相比 Node 包管理机制更弱

这不是 Python 太差,而是 Node 太叼了。Node 只提供底层 API,提倡使用第三方包完成你的工作(这也是导致 JS 项目层出不穷的原因),而 Python 并没有这种提倡。

关于 GMS 教务系统

By: 胡中元
27 February 2017 at 11:22

 简介 

这是一个用于高校毕业生毕业流程线上管理的教务系统,由 Moshel 独立开发,并与 2016 年末开始被应用在西安石油大学计算机学院内。

毕业生在毕业设计时,需要学生与老师所出的题目建立一个多对一的关系,教师出题需要两层审核,而学生拥有三轮选题的机会,并且学生之间可相互竞选题目,此外,管理员可统揽全局,控制教务流程的进行,以及对相关数据的处理。这些就是本系统的大致功能。

答辩环节的完全线上化将是本系统的下一个主要开发方向。

链接:http://bkbysj.xsyu.edu.cn/(限西石大内网访问)

 系统功能 

作为一个完善的业务系统,除了 “选题” 功能外,还拥有完善的账号管理系统及附件管理系统等。

这张用例图是系统设计阶段所画,目前系统的功能已不局限于此。

教师拥有的功能

  

(↑ 点击可查看大图)

教师可以出题,并且实时跟踪自己题目的状态,历年所出题目会形成一个自己的题库以供复用,题目支持上传附件。这些特性弥补了旧选题系统的遗憾。

值得一说的是,本系统中所有的用户头像均不相同,根据用户 UID 哈希生成的随机矢量风格,避免了所有老师学生都使用默认头像的尴尬又无聊的景象。

学生角色

学生是本系统中最简单的角色,可进行选题,以及在选题成功之后通过此系统向老师发送文件。

在选题方面设计了 2 个人性化的特性:1、能看到某道题当前已选人数,这大大避免某道题被大家集中选择。2、在教师查看你的选题志愿之前,可以取消申请,并另选一道题。(事实上在此系统中所有的状态转移均支持最大程度的撤销操作)

管理员信息统揽

(↑ 点击可查看大图)

专门为管理员设计的功能占整个系统工作量的 70% 以上。管理员面板中,可以管理所有的用户类型,设定每位用户的类型,也可以看到现在所有选题配对情况。

值得一说的是,管理员支持使用 Excel 批量导入每届学生老师信息,系统会自动解析 xlsx 文档,并创建对应的登陆账号。

此外,本系统网页中所有可见的表格信息均可一键导出为 Excel 或 Word 文档,方便进一步办公处理。

仪表盘

数据可视化算是最近几年的技术热点,所以我为管理员开发了一个单独的仪表盘页面,用于总览整个选题流程的进行。

在这里,可以直观的看到待选题目和学生总数的柱状对比图,也可以分专业以饼状图的形式看到当前各专业学生的选题状态分布。这些都是选题流程中管理员需要掌握的数据。

数据库备份还原

 

本系统还拥有一个强大的自动备份还原功能,系统会自动在每天凌晨 3 时进行一次数据库备份,同时自动删除 15 天前的备份(不支持手动删除),当然,用户可以选择在需要的时候随时手动创建一个备份。

这样的设计使得系统更加稳定,无论是管理员的误操作,还是被任何形式的恶意攻击,都不会对系统造成很大的影响。

公告系统

 

(↑ 点击可查看大图)

本系统拥有完善的公告系统,支持富文本编辑、设置置顶、支持设置公告对不同类型用户的可见性,以及附件支持。

 关于技术 

以上说的是功能介绍,关于技术的细节欢迎大家点击以下两个链接继续阅读:

1、我在 2016 年 9 月写的:Meteor + React 教务系统开发经历

2、我在 2016 年 10 月发的相关论文:A High Performance Information System for College Graduation Management Cloud

技术亮点预告

1、使用 Javascript 全栈开发,包括 Node 作为后端,React 作为前端框架,MongoDB 作为数据库。

2、使用 Websocket 进行前后端通信,而不是 HTML 或者 AJAX。

3、使用黑科技实现前端浏览器直接操作数据库。

❌
❌