2024年8月26日

如何使用 GPG 加密和签名消息

介绍 GPG,即 GNU Privacy Guard,是一种公钥加密实现。它允许各方之间安全地传输信息,并可用于验证消息来源的真实性。 在本指南中,我们将讨论 GPG 的工作原理以及如何实现它。我们将使用 Ubuntu 16.04 服务器进行此演示,但也将包括其他发行版的说明。 公钥加密的工作原理 许多用户面临的一个问题是如何安全地进行通信并验证他们正在交谈的一方的身份。许多试图回答这个问题的方案至少在某些时候需要通过不安全的媒介传输密码或其他身份证明。 确保只有预期方可以读取 为了解决这个问题,GPG 依赖于一种称为公钥加密的安全概念。其理念是,您可以将传输的加密和解密阶段分成两个独立的部分。这样,只要您确保解密部分的安全,您就可以自由分发加密部分。 这将允许单向消息传输,任何人都可以创建和加密,但只能由指定用户(拥有私钥解密的用户)解密。…
2024年8月26日

使用 Jest 进行模拟函数概述

高阶函数接受一个函数并返回一个函数。Jest提供了一种方法来确保您给出的函数被正确使用。 测试高阶函数 假设你想写一个记忆函数。它可能看起来像这样: // memoize.js export default function memoize(func) { return function (key) { const registry = new Map(); let value = registry.get(key); if (typeof value === 'undefined') { value = func(key); registry.set(key, value); } return value; } } 为了测试它,你会得到类似的东西: import memoize from './memoize'; it('memoizes `func`.', () => { // `func` here…
2024年8月26日

Jest 中的异步测试

并非所有事物都同步执行,因此并非所有事物都应该同步测试。 Jest 提供了一些异步测试选项。 使用回调 如果您的函数接受一个参数,Jest 将为其提供一个done回调;测试将运行,直到done或被done.fail调用或超时。这对于测试可观察对象非常有用: // Let's say you're testing a cup that emits an event when it is full or spills. it('fills without spilling.', (done) => { const smartCup = new SmartCup(); // The event happened, so call `done`. smartCup.on('full', () => done()); // If a failing condition happens, you can call `…
2024年8月26日

如何在 Linux Mint 21/20 上使用 pgAdmin4 安装 PostgreSQL

pgAdmin是一个功能丰富的开源前端管理工具,允许您从 Web 浏览器轻松管理您的PostgreSQL关系数据库。 它提供了一个易于使用的用户界面,简化了数据库和数据库对象的创建和监控。PgAdmin 4是早期pgAdmin工具的改进,可用于 Linux、Windows、macOS 系统,甚至 Docker 容器。 在本教程中,您将学习如何在Linux Mint 21和Linux Mint 20上使用pgAdmin4安装PostgreSQL。 步骤1:在Linux Mint上安装PostgreSQL数据库 1.首先,启动您的终端并使用apt 包管理器更新您的包,如图所示。 $ sudo apt update -y 更新完成后,继续下一步。 由于pgAdmin4为PostgreSQL数据库对象的管理提供了前端界面,因此必须首先安装PostgreSQL。 2.为…
2024年8月26日

Jest Mock 计时器

测试超时的最大障碍之一是等待超时。Jest提供了一种解决方法。 运行所有定时器 假设您正在测试一个程序,该程序会在一段时间后发出一个事件,但您不想等待该事件实际发出的时间太长。Jest 为您提供了通过setTimeout函数立即运行设置的回调的选项jest.runAllTimers。 // This has to be called before using fake timers. jest.useFakeTimers(); it('closes some time after being opened.', (done) => { // An automatic door that fires a `closed` event. const autoDoor = new AutoDoor(); autoDoor.on('closed', done); autoDoor.open(…
2024年8月26日

在 Flow 中使用枚举

如果您曾经接触过更传统的面向对象语言(C、C#、Java),那么您可能见过枚举数据类型。虽然 JavaScript 不支持枚举,但Flow 的类型检查可以弥补这一点。 枚举在哪些地方有用? 假设您正在编写一个处理扑克筹码的程序。筹码的颜色是一个字符串(即“红色”、“蓝色”等)。因此您的Chip类型看起来应该类似于: type Chip = { color: string, }; …创建芯片的函数是: function createChip(color: string): Chip { return { color, }; } 但您要确保它只使用有效的颜色: // This should be valid. createChip('red'); // This should not. createChip('cyan'); // This isn't even a color. createCh…
2024年8月26日

Flow 中的通用函数

Flow从面向对象程序中借鉴的最佳概念之一是泛型的概念。在许多情况下,泛型对于细化类型检查至关重要。 泛型在哪些地方有用? 假设你有一个函数memoize。使用 Flow 类型,它可能看起来像这样: function memoize(func: (key: any) => any): (key: any) => any { const registry = new Map(); return function(key: any): any { let value = registry.get(key); if (typeof value === 'undefined') { value = func(key); registry.set(key, value); } return value; }; } 问题是它会吞噬以下细节func: // Type is (val: number) => bo…
2024年8月26日

流中的参数变化

有时你可能希望函数能够采用不同类型的参数。有点像TypeScript 中的联合类型。让我们看看如何使用Flow来实现。 创建一个接受多种类型参数的函数 这只是列出可能的类型的问题,用|: function capitalize( // `capitalize` can take a string or an array of strings. words: string | Array<string>, // `capitalize` will return an array of strings either way. ): Array<string> { // At this point, Flow does not know if `words` is a string or an array, // so properties or methods specific to those type…
2024年8月26日

流程通用约束

在Flow中,在某些情况下你会想要创建一个通用函数或类,但想要限制可以作为类型参数传递的内容。 通用约束的用途 假设您有一个包装 Map 的类,但在插入之前进行了浅拷贝: class ShallowMap<T> { map: Map<string, T>; constructor() { this.map = new Map(); } get(key: string) { return this.map.get(key); } set(key: string, value: T) { // Make a shallow copy. Flow will give an error on this line. const copy = {...value}; this.map.set(key, copy); } } Flow 不允许您这样做,因为虽然对象可以传播,但其他类型不能: // This…
2024年8月26日

流类型别名

当仅以文字形式书写时,Flow 很快就会变得非常冗长。将重复的类型声明为类型别名通常很有用。 声明类型别名 假设你正在编写函数来操作待办事项列表: // Add a new todo item to `todos` and return the new item. function addTodo( todos: Array<{id: number, name: string, completed: boolean}>, name: string, ): {id: number, name: string, completed: boolean} { // Implementation omitted for brevity. } // Get a todo item from `todos` by `id`. function getTodo( todos: Array<{id: number, na…