跳到主要内容

TS 中 module 和 namespace

· 阅读需 2 分钟

模块和名称空间,实际用起来没什么区别,但是概念上有些不同。

模块的设计理念是分割和组织代码文件,一个文件就是一个module。在一个文件中访问另一个文件必须要加载(import或者require)它。

引用TS官网的一句话:

It’s important to note that in TypeScript 1.5, the nomenclature has changed. “Internal modules” are now “namespaces”. “External modules” are now simply “modules”

自 TS 1.5 以后,namespace 可以看作是内部模块,modules 就是它原本的意思(外部模块)。命名空间顾名思义,提供了一个空间,在这里面定义的变量、接口、函数等,与其他空间隔离,也就是说他们的名称相同也不会互相影响,就像 Java 中的包。

示例

/// <reference path = "..." />,这个指令会引入要加载的ts文件,然后就可以使用其中的内容。

下面这些代码,在不同文件里共同定义了一个名称空间 Card,该名称空间下暴露了几个类,分别是 Circle, Triangle, Square。并在名称空间之外,定义了一个 Drawable 接口。

/// <reference path = "./Shape.ts" />

// Circle.ts
namespace Card {
export class Circle implements Drawable {
type = 'Circle';
constructor(){

}
draw() {
console.log('Draw Circle.');
}
}
}
// Shape.ts
interface Drawable {
draw(); // 定义抽象 draw 方法
}

namespace Card {
export class Triangle implements Drawable {
// 实现 draw 方法
draw() {
console.log('Draw Triangle.');
}
}
export class Square implements Drawable {
draw() {
console.log('Draw Square.');
}
}
}
/// <reference path="./Circle.ts" />
/// <reference path="./Shape.ts" />

// Test.ts
function testCircle(shape: Card.Circle) {
shape.draw();
}

function testTriangle(shape: Card.Triangle) {
shape.draw();
}

function testSquare(shape: Card.Square) {
shape.draw();
}

testCircle(new Card.Circle());
标签:

JS 递归过滤 JSON 数据

· 阅读需 5 分钟
Hanasaki
阿巴阿巴阿巴

负责人布置了个任务,写一个过滤 JSON 数据的方法,处理一下模型数据。递归绕的我真晕,脑子内存还是不太够。

样例数据

规则:bosclass 值为 boqs 的是树节点,bosclass 值为 wps 的是纯数据。如果树节点的 children 是空数组,那么把树节点移除掉。树的层级是无法预估的,可能有很多层。以下是过滤后的数据:

[
{
"bosclass": "boqs",
"children": [
{
"bosclass": "boqs",
"children": [
{
"bosclass": "wps",
"guid": "fa01a4a1f1d448a3bfb315dac41e1914"
},
{
"bosclass": "wps",
"guid": "cbf47dc52b2243c1a9d46bb046d8a13d"
}
],
"guid": "f785b4a061714dfe8fea367d12ddd29c"
}
],
"guid": "8bc6c9026bb9472f8a3e23b382f87ac1"
}
]

如何过滤呢?首先想到的方法是递归!

Git 根据已有分支新建分支开发

· 阅读需 3 分钟
Hanasaki
阿巴阿巴阿巴

当需要根据一个已有分支,来创建一个新分支并在上面开发时,这篇内容会很有用。

一般情景是,在 dev 分支开发,此时遇到了一些 bug 需要修复,要根据 dev 分支创建一个 bugfix 分支,在此分支把问题解决,然后推送并发起 pull request 将代码合并到 dev 分支。

步骤

1.新建分支

依据:git checkout -b <new-branch> [<start-point>],创建并切换到 new-branch 分支,如果写上了 start-point 参数,则新分支的 HEAD 将指向它,不写则需要手动设置上游。

start-point:The new branch head will point to this commit. It may be given as a branch name, a commit-id, or a tag. If this option is omitted, the current HEAD will be used instead.

现在以远程的 origin/dev 分支为上游,新建了一个 bugfix 分支。

git checkout -b bugfix origin/dev

2.代码开发

在 bugfix 分支进行开发。

3.设置上游分支

现在的上游是 origin/dev,推送时会推到远程 dev 分支。 设置上游可以根据这条命令 git branch -u, --set-upstream-to <upstream>-u 简写比较方便,也可以使用完整参数 --set-upstream-to

git branch -u origin/bugfix

但是这里还不能这样用,因为还没有把本地创建的新分支推送到远程,无法设置远程的上游。因此需要推送并设置上游

git push -u origin bugfix

4.推送

可以推送到远程仓库

git push

如果没手动设置上游,需要次次都手动推送到指定分支

git push origin bugfix

在这之后,就可以在仓库看到了 bugfix 分支,可以发起合并请求了

Git Rebase 简要说明

· 阅读需 5 分钟
Hanasaki
阿巴阿巴阿巴

Git Rebase 自己压根没用过,正巧公司团队要用到,学习总结一下。

使用场景

合并提交:完成一个 feature 提交了很多次,有很多杂乱连续的 commit,团队对提交规范要求一个特性对应一次提交,此时需要合并多个提交为一个。

分支变基:多人协作开发时,用 merge 合并分支会多出一个 Merge Commit 的提交,这个提交是两个分支的最新节点的合并项。分支树呈现的是一条线从 main 分支叉出去,经过几个提交,又汇合到 main,汇合处形成了一个提交节点。团队想要让提交记录是线性的,也不想要这个多余的提交,此时适合进行变基。

举例

有一个提交结点树,C1是首次提交,C4是 hotfix 分支第一次提交。主线是 main 分支。

               C4 <- C5
/
C1 <- C2 <- C3 <- C6

初探 Nodejs 内存泄漏

· 阅读需 3 分钟
Hanasaki
阿巴阿巴阿巴

这两天吃饱撑着,在探究为什么我的 Node 程序 Heap Usage 一直居高不下,而且会越来越多。

如何调试 NodeJS 程序

在VSCode中可以直接调试,选择Debug,显示所有自动调试配置,选择要运行的命令,就进入了调试模式,侧栏会显示出调试的信息。可以捕获 Heap 快照,拿到 ChromeDevTool 里面导入分析。

用 Node 的 --inspect 参数搭配 Chrome 实时分析

运行以下命令,进入了调试模式

node --inspect serve.js

在 Chrome 中打开 chrome://inspect,就可以看到 Open dedicated DevTool for Node,点击进入 Node 调试工具,就可以开始分析了。

放大问题

很多时候,人工是难以准确排查出问题的,因为会有很多不可预料的误差,导致每次运行的结果数据不准。这时候,要放大问题,大量测试多次触发漏洞,就能很清楚的发现问题。

k6 对接口进行测试,运行下列测试程序 k6 run test.js

// test.js
import http from 'k6/http';

export let options = {
vus: 100,
duration: '20s',
};

export default function () {
let res = http.post("http://localhost:5000/monitor/start", JSON.stringify({ phone: Math.random()*100000 }), { headers: { 'Content-Type': 'application/json' } })

console.log(res.body);
}

通过对比前后的 Heap Size,确实管用,明显增加了将近 8MB。

接着调用了一下其他的接口,调用 processMap.clear() 把保存子进程的 processMap 清空。内存果然又降回去了,但并没有和最开始一样,而是稍稍高出了一点点。

得出结论,引用计数法回收垃圾是实实在在的,这个例子验证了它。但是仍然困扰我的是,Heap 里的 [compiled code] 这部分会一直增加,无法被回收,增加的量很小...

未解之谜:每次访问接口,即使是访问 / 路径,返回一段文本, [compiled code] 也会不断增加?