qlc解决了什么问题

目前遇到的问题

作为一名前端工程师,陆陆续续负责了不少项目,这些项目中,有一些是正在迭代的,其他同事同时在负责的项目,但是也有不少项目,要么就是老旧项目维护的同事已经离职或转岗了的,要么就是新项目从 0 开始的,再加上前端代码积累速度和迭代速度都比较快,其中暴露了不少问题。

我身边的大多数程序员都有一个特点,就是喜欢把具体的东西抽象化,我们通常会抽象出公共的函数或方法、公共的类或HOC,放在一起,集中在项目的某一个文件夹下,叫做 js 文件夹或 lib 文件夹(以下我们用 js 文件夹代表公共函数文件夹 )。

这样做的确带来了很多便利,但同时也有一些隐患:

  • js 文件夹下代码越来越多,而且大多数鹅厂小伙伴的作风是 0 文档 0 注释,这给新接手项目的同学熟悉项目带来了极大的麻烦。
  • 不同项目都有自己的 js 文件夹,在开发一个新项目时,我们通常的做法是:
    • 直接将原有项目的 js 文件夹拷贝到新项目中,这样在新项目中,我们也可以直接使用这些公共函数了。
    • 将原有项目的部分 js 文件拷贝到新项目中,并且随着新项目的开发,增量拷贝。
    • 以上两种做法,本质区别不大,前者会直接给新项目增加很多无用代码(原有项目中所谓的公共函数在新项目中并不一定会用到),而对这两种方式,如果我们要修复一个 bug,修改或升级公共代码中的一个文件,那么我们就要一个一个的,将修复好的文件拷贝到不同的项目中,如果项目多了并且已经交由不同的人维护了,这简直是一个灾难。
  • 由于公共 js 文件夹下内容比较多,并且有的开发同学习惯以 ‘urlUtils.js’、’strUtils.js’ 这种方式来整合一些小的函数集,这样会造成函数重复的隐患(毕竟我们一个文件一行行的去分析目前的公共库已经有了哪些能力是不现实的),我观察过之前自己接手的一个不算复杂的项目(潘多拉),其仅仅是从 url 解析 query 这种功能函数,就有多达 3个(甚至更多),分布在 js 文件夹以及 node_modules 里面,这显然是不同的维护人员由于信息不对称重复引入的。
  • 对于怎么样才能算作“公共”函数,目前是缺乏一个 review 过程的,任何项目开发人员,几乎都可以无限制地在公共 js 文件夹下增加内容,并在之后被携带着拷贝到其他项目中,这其中有些函数,也许并不适合在这里。
阅读更多

使用Nodejs打造多用户实时监控系统

背景概述

首先描述一下笔者遇到的问题,我们可以设定这样一个场景:现在有一个实时监控系统的开发需求,要求同时支持多个用户(这里我们为了简化,暂时不涉及登陆态,假定一个设备即为一个用户),对于不同的用户来讲,他们需要监控的一部分内容是完全相同的,比如设备的 CPU 信息、内存信息等,而另外一部分内容是部分用户重叠的,比如对某一区域的用户来说某些监控信息是相同的,而还有一些信息,则是用户之间完全不同的。

对于每个用户来讲,当其进入页面之后即表明其开始监控,需要持续地进行数据更新,而当其退出界面或者手动点击停止监控,则停止监控。

阅读更多

从源码分析sentry的错误信息收集

raven.js 是 sentry 为 JavaScript 错误上报提供的 JS-SDK,本篇我们基于其源代码对其原理进行分析,本篇文章只分析前端部分,对应的文件目录是https://github.com/getsentry/sentry-javascript/tree/master/packages/raven-js

首先抛出几个问题:

  • raven.js 是如何收集浏览器错误信息的?
  • raven.js 上报的错误信息格式是什么样的?又是如何把这些信息传给后端?支不支持合并上报?
  • 面包屑(breadcrumbs)是什么?raven.js 如何来收集面包屑信息?
  • raven.js 如何和框架配合使用(比如 vue、react)?
阅读更多

浅谈前端中的二进制数据类型

目前在一个项目中,WebSocket部分由于后端使用了gzip压缩,前端处理起来废了一点时间,从而发现自己在二进制数据类型这个知识点还存在一定的盲区,因此这里进行总结。

阅读更多

JS的静态作用域

静态作用域

我们先来看下面这个小程序:

 //JS版本:
 function sub1() {
        var x;
        function sub2() { alert(x); }
        function sub3() { var x; x=3; sub4(sub2); }
        function sub4(subx) { var x; x=4; subx(); }
        x = 1;
        sub3();
    }

    sub1();
    
 #Python版本
def sub1():
    def sub2():
        print x
    def sub3():
        x=3
        sub4(sub2)
    def sub4(subx):
        x=4
        subx()
    x = 1
    sub3()

sub1()   

不用亲自运行,实际上输出结果都是1,这可能不难猜到,但是需要解释一番,鉴于Python和JS在这一点上表现的类似,我就以JS来分析。

我们知道,JS是静态作用域的,所谓静态作用域就是作用域在编译时确定,所以sub2中引用的x,实际上和x=3以及x=4的x没有任何关系,指向第二行的var x;

子程序的引用环境

实际上这里面还有一个子程序(注:子程序和函数不是很一样,但我们可以认为子程序包括函数,也约等于函数)的概念,sub2、sub3、sub4都是子程序,对于允许嵌套子程序的语言,应该如何使用执行传递的子程序的引用环境?

  • 浅绑定:如果这样的话,应该输出4,这对动态作用域的语言来说比较自然。
  • 深绑定:也就是输出1的情况,这对静态作用域的语言来说比较自然。
  • Ad hoc binding: 这是第三种,将子程序作为实际参数传递到调用语句的环境。

参数传递类型

参数传递类型我们普遍认为有按值传递和按引用传递两种,实际上不止。

下面是一张图:

这张图对应的第一种传递方式,叫做Pass-by-Value(In mode),第二种是Pass-by-Result(Out mode),第三种是Pass-by-Value-Result(Inout mode),图上说的比较明白,实际上如果有result就是说明最后把结果再赋值给参数。

第二种和第三种编程语言用的少,原因如下:

Potential problem: sub(p1, p1)
With the two corresponding formal parameters having different names, whichever formal parameter is copied back last will represent current value of p1