世界杯举办地_世界杯预选赛巴西 - emsxbc.com

如何编写出整洁的代码

原文: How to Write Clean Code – Tips for Developers with Examples

试想一下,一个房间里衣服、书籍和各种物品散落得到处都是。在这样的凌乱环境里,你觉得要找到一样东西会不会很困难呢?

现在来想一想,当我们写出乱糟糟的代码时,它是不是也会使人感到困惑,甚至比凌乱的房间还要让人头疼呢!

相反,简洁的代码就像一个井然有序的房间:你可以轻松找到所需的内容,和快速理解正在发生的事情,使你更快地完成工作。

现在,我们来瞧瞧这个图表。该图表呈现并对照了两种不同的代码编写方式,以及它们对添加更多代码行所需要时间的影响:

⚠️ 仓促 & 混乱的代码(红线):这种代码是在没有规划和整理的情况下匆忙写出的代码。起初,这种方式看起来高效,但随着代码行数增加,代码结构变得越来越难以理解和维护。因此,随着时间推移,每添加一行代码所需的时间都会越来越长。

⚡ 谨慎 & 整洁的代码(蓝线):这种代码是经过精心规划和整理的,使其更容易理解和修改。虽然一开始可能会稍微慢一些,但随着代码的增长,它依然保持清晰易读,因此添加新代码不会变得越来越困难。

简单来说,编写整洁的代码一开始可能会缓慢一些,但从长远来看,它能节省后续所耗费的时间,让工作更轻松。同时,还能提高软件的可靠性,打造更优质的产品。

编写整洁的代码是专业开发人员培养的一种良好习惯,体现了专业人员对质量的承诺和坚定的职业操守。在本文中,我将带领你了解一些保持代码整洁的最佳实践。

我们将涵盖的内容

使用有意义的名称

遵循单一责任原则 (SRP)

避免不必要的注释

提高代码可读性

编写单元测试

谨慎处理依赖项

合理组织项目结构

保持一致的代码格式

避免硬编码

限制函数长度

总结

编写整洁代码的 10 个实用技巧

为了帮助你开启编写整洁代码的旅程,这里为你提供了 10 个实用技巧,可以帮助你保持代码的可读性、条理性和高效性。

1. 使用有意义的名称

在为变量、函数和类命名时,选择能清晰描述其用途的名称。

不要简单地命名变量为 b,试着用 numberOfUsers这样的名称。这样,任何阅读你的代码的人都能毫不费力地理解其用途,而无需额外注释。一个有意义的名称可以减少猜测,避免产生混淆。

示例:

// 正确的例子

let numberOfUsers = 5; // 清晰易懂

// 错误的示范

let b = 5; // 含糊不清

💡 命名技巧

变量:使用描述数据的名词,例如 userAge 或 totalAmount。

函数:使用动词,如 calculateTotal() 或 fetchUserData()。

类:使用单数名词来表示其含义,如 User 或 Order 来表示它们的类型。

// 变量:描述其存储的数据

let userAge = 25;

// 函数:使用动词来描述其功能

function calculateTotal(price, quantity) {

return price * quantity;

}

// 类:单数名词,表示一种对象类型

class User {

constructor(name, age) {

this.name = name;

this.age = age;

}

}

2. 遵循单一责任原则(SRP)

单一职责原则意味着每个函数或方法都应该只负责一项特定的任务。

这样可以让你的函数保持简洁、专注,从而提高代码的可读性,有便于后续的测试和维护。

想象一下一个工具箱,其中每个工具都有其独特的用途——干净的代码函数也应如此运作。

例如,如果你有一个名为 calculateTotal 的函数,它就只应该负责计算总和。如果你给它添加额外的任务,可能会导致代码变得混乱,难以维护。

下面是一个示范例子,展示了为什么保持函数的单一职责很重要:

假定您期望计算一个总和并返回一个带有额外信息的对象,诸如谁进行了计算,以及何时计算的。与其直接将这些内容添加到 calculateTotal 中,不如我们创建第二个函数来处理额外的信息。

优良范例(任务分离)

// 此函数仅用于计算总和

function calculateTotal(a, b) {

return a + b;

}

// 此函数用于创建包含额外信息的对象

function createCalculationRecord(a, b, user) {

let sum = calculateTotal(a, b); // 调用上面的计算总和函数

return {

user: user,

total: sum,

timestamp: new Date()

};

}

let record = createCalculationRecord(5, 10, "Shahan");

console.log(record);

👍 为什么这样更好:这样使每个函数都有一个明确且集中的任务。其中 calculateTotal 只需负责数学运算,而 createCalculationRecord 则负责添加额外的细节。如果你想更改总数的计算方式,只需更新 calculateTotal函数;如果你想改变记录格式,只需更新 createCalculationRecord的函数。

错误示例(在一个函数中混合多个任务)

// 此函数在一个步骤中同时计算总和创建对象

function calculateTotalAndReturnRecord(a, b, user) {

let sum = a + b;

return {

user: user,

total: sum,

timestamp: new Date()

};

}

let record = calculateTotalAndReturnRecord(5, 10, "Shahan");

console.log(record);

👎 为什么这样不好:函数名称 calculateTotalAndReturnRecord 表明它试图完成多项任务。如果你只想使用计算部分,就无法在不涉及记录部分的情况下复用这个函数。此外,单独更新和测试每一项任务也会更困难。

3. 避免不必要的注释

一个良好的代码应该能够具有自身的解释性,而不需要过多的注释来解释。而专注于编写清晰且易于理解的代码,便使其本身就能表达出意图。

注释在解释复杂逻辑或特殊实现时很有用,但同时过多的注释会使代码显得杂乱无章,难以阅读和理解。

💬 什么时候使用注释:

用于说明为什么要以特定方式进行操作。

在处理复杂的算法或计算时。

添加有关潜在局限性的注释。

示例:

// 命名清晰,无需注释

let userAge = 25;

// 命名不清晰,需要注释

let a; // 用户的年龄

4. 提高代码可读性

可读性良好的代码使用缩进、换行和空格来保持整洁和有序。

可以把它想象成写一篇故事文章:段落的划分能让阅读变得更轻松,同样,在代码中,合理的换行可以起到相同的作用,使其更易于理解。

示例:

// 优良范例的代码结构

if (isLoggedIn) {

console.log("欢迎回来!");

} else {

console.log("请登入账号。");

}

// 错误示例的代码结构

if(isLoggedIn){console.log("欢迎回来!");}else{console.log("请登入账号。");}

在 VS Code 中,Prettier 和 Black 是常见的代码格式化工具,可以自动为多种编程语言应用整洁的代码风格。

PyCharm 和 IntelliJ 具备强大的内置格式化功能,并支持自定义规则,例如 Python 中的 PEP 8 代码风格指南和其他标准规范。这些工具可以帮助项目保持一致的代码格式,减少手动调整的工作量,从而提高代码的可读性和维护性。

5. 编写单元测试

单元测试有助于确保代码的每个部分按预期运行。

通过测试小的、独立的部分(比如函数),你可以尽早发现错误,并防止其蔓延到代码的其他部分。

具体来说,单元测试实际上是对你代码的每个部分所进行的小型质量检查,从而确保它们按预期来工作。

🍎 现实中的案例:

让我们来看一下,如何测试具有多个方法的复杂 JavaScript 对象,以 Calculator 类为例。

这种方法将帮助你明白,为何要让每个方法专注于一项任务,并通过单元测试确保每个方法都能正确运行。

这里有一个 Calculator 类,其中包含执行基本算术运算的方法:加法、减法、乘法和除法。

class Calculator {

constructor() {

this.result = 0;

}

add(a, b) {

return a + b;

}

subtract(a, b) {

return a - b;

}

multiply(a, b) {

return a * b;

}

divide(a, b) {

if (b === 0) throw new Error("无法除以零");

return a / b;

}

}

如你所见,每个方法都执行一个特定的操作。其中,divide 方法有额外的逻辑来处理除以零的情况,否则这会导致错误。

现在,我们将编写单元测试来验证每个方法是否按预期工作。🔬

🧪 为每个方法编写单元测试

为了测试我们的 Calculator 类,我们可以编写单元测试,涵盖正常情况和边缘情况。以下是如何为每个方法设置测试的示例:

// 初始化 Calculator 实例

const calculator = new Calculator();

// 测试 add 方法

console.assert(calculator.add(2, 3) === 5, '测试失败: 2 + 3 应该等于 5');

console.assert(calculator.add(-1, 1) === 0, '测试失败: -1 + 1 应该等于 0');

// 测试 subtract 方法

console.assert(calculator.subtract(5, 3) === 2, '测试失败: 5 - 3 应该等于 2');

console.assert(calculator.subtract(0, 0) === 0, '测试失败: 0 - 0 应该等于 0');

// 测试 multiply 方法

console.assert(calculator.multiply(2, 3) === 6, '测试失败: 2 * 3 应该等于 6');

console.assert(calculator.multiply(-1, 2) === -2, '测试失败: -1 * 2 应该等于 -2');

// 测试 divide 方法

console.assert(calculator.divide(6, 3) === 2, '测试失败: 6 / 3 应该等于 2');

try {

calculator.divide(1, 0);

console.assert(false, '测试失败: 除以零应该抛出错误');

} catch (e) {

console.assert(e.message === "无法除以零", '测试失败: 除以零的错误信息不正确');

}

🫧 测试解释:

加法(add 方法):我们测试 add(2, 3) 返回 5,以及 add(-1, 1) 返回 0。如果这些测试通过,就说明我们的加法逻辑是正确的。

减法(subtract 方法):我们验证 subtract(5, 3) 返回 2,以及 subtract(0, 0) 返回 0。这些检查确保减法计算准确无误。

乘法(multiply 方法):我们测试乘法函数,包括正数和负数的情况,确保 multiply(2, 3) 返回 6,以及 multiply(-1, 2) 返回 -2。

除法(divide 方法):我们验证 6 除以 3 返回 2。对于除以零的情况,我们使用 try...catch 块来确保方法抛出正确的错误消息。这可以验证该方法是否能正确处理错误情况。

你可以看到,如果任何方法失败,测试都会生成清晰的错误消息,使我们能够迅速识别并修复问题。单独测试方法有助于我们在项目发展过程中尽早发现错误,并保持可靠、整洁的代码。

6. 谨慎处理依赖项

依赖项,是指你的代码所依赖的外部软件组件。🔌

想象一下,您正在构建一个能发送电子邮件的网络应用程序。与其自己编写邮件发送功能,你可以使用像 Nodemailer 这样的外部库。在这种情况下,Nodemailer就是一个依赖项——你的应用依赖它来处理邮件发送功能。

示例:

const nodemailer = require('nodemailer');

function sendEmail(to, subject, message) {

const transporter = nodemailer.createTransport({

service: 'gmail',

auth: {

user: 'your-email@gmail.com',

pass: 'your-email-password'

}

});

const mailOptions = {

from: 'your-email@gmail.com',

to: to,

subject: subject,

text: message

};

return transporter.sendMail(mailOptions);

}

在这段代码中,nodemailer 被引入并用于创建一个邮件发送的传输器。如果没有它,你将不得不从零编写整个邮件发送功能,这将非常复杂且耗时。通过使用 Nodemailer 作为依赖项,你的应用可以轻松实现邮件发送功能。

尽管依赖项非常有用,但过度依赖外部软件或库可能会带来问题。因此,只有当它们能简化你的工作或提供重要功能时,才应该使用依赖项。

有效管理依赖是编写简洁代码的关键。以下是一些提示:

限制依赖项:仅包含对项目真正必要的库或模块,避免不必要的依赖项。

保持版本更新:使用最新版本的库,以减少安全风险。

分离核心逻辑:尽可能自己编写核心功能,这样即使未来需要移除某个依赖,也不会影响你代码的正常运行。

让我用之前的 Nodemailer 代码来给你举个例子,说明如何在代码中实现逻辑分离。

你可以创建一个封装函数,将发送电子邮件的细节抽象出来。这样,你就可以更改底层的电子邮件服务或移除对 Nodemailer 的依赖,而不影响到代码的其他部分。

以下是如何组织代码以实现此目的:

const nodemailer = require('nodemailer');

// 用于发送电子邮件的核心函数

function sendEmail(to, subject, message) {

const transporter = createTransporter();

const mailOptions = createMailOptions(to, subject, message);

return transporter.sendMail(mailOptions);

}

// 创建邮件发送器的函数

function createTransporter() {

return nodemailer.createTransport({

service: 'gmail',

auth: {

user: 'your-email@gmail.com',

pass: 'your-email-password'

}

});

}

// 创建邮件选项的函数

function createMailOptions(to, subject, message) {

return {

from: 'your-email@gmail.com',

to: to,

subject: subject,

text: message

};

}

// 示例用法

sendEmail('recipient@example.com', 'Test Subject', 'Hello, this is a test email.')

.then(() => {

console.log('Email sent successfully!');

})

.catch((error) => {

console.error('Error sending email:', error);

});

🗝️ 关键要点:

核心函数:sendEmail、createTransporter 和 createMailOptions 的函数是相互独立的,这样你就可以修改其中一个而不影响其他函数。

轻松修改:如果您希望在将来切换到其它电子邮件服务,你只需修改 createTransporter 的函数即可。

可维护性:这种结构使你的代码更易于维护和理解。

7. 合理组织项目结构

一个良好的项目结构与代码本身同样重要。

可以这样想,就像整理你的工作空间一样——你需要为每样东西指定位置,这样就能轻松找到它们。对于编码项目,应该为不同的部分创建专门的文件夹,例如 components、utils 和 services等格式。

📂 如何组织你的项目

为了建立一个整洁有序的项目,你应当将代码的不同部分的分类放入指定的文件夹中。以下是一个组织良好的项目结构的简单示例:

myProject # 我的项目

├── src # 资源文件夹

│ ├── components # 组件文件夹

│ ├── services # 服务文件夹

│ ├── utils # 实用工具文件夹

└── tests # 测试文件夹

项目结构解析:

myProject(我的项目):这是你项目的根文件夹。包含与您的应用所有相关的内容。

src(资源):此文件夹包含您项目的所有源代码。您大部分时间都将在这里编码。

components(组件):此子文件夹用于存放可复用的 UI 组件。例如,如果你正在构建网络应用程序,你可能会在这里存放按钮、导航栏、表单等组件的单独文件。每个组件都应有独立的文件,以保持模块化。

components 中的示例结构:

components

├── Button.js # 按钮组件文件

├── Header.js # 头部导航组件文件

└── Form.js # 表单组件文件

services(服务):此文件夹用于存放执行特定任务或处理业务逻辑的函数。例如,如果你的应用涉及发送邮件,你可以在这里创建一个专门的文件来管理所有与邮件相关的功能。

services 中的示例结构:

services

├── emailService.js # 邮件服务文件

├── userService.js # 用户服务文件

└── productService.js # 产品服务文件

utils(实用工具):在这里,你可以放置一些可以跨项目使用的辅助函数。这些通常包括格式化日期、验证输入或其他不属于特定组件或服务的通用任务。

utils 目录内的示例结构:

utils

├── formatDate.js # 格式化日期文件

├── validateEmail.js # 验证邮箱格式文件

└── generateId.js # 生成客户ID号码文件

tests(测试):此文件夹专用于存放测试文件。保持测试的有序排列有助于确保在构建新功能时,你可以轻松地测试它们,而无需在代码库中四处查找相关文件。

tests 目录内的示例结构:

tests

├── emailService.test.js # 测试邮件服务的功能

├── userService.test.js # 测试用户服务的功能

└── component.test.js # 测试 UI 组件的功能

📨 真实案例:使用 Nodemailer 进行邮件发送

假设你正在构建一个向用户发送电子邮件的应用程序。你可以按照以下结构组织项目:

myEmailApp # 我的邮件应用程序

├── src # 资源文件夹

│ ├── components # 存放组件的文件夹

│ │ ├── EmailForm.js # 邮件表单组件

│ │ └── SuccessMessage.js # 邮件发送成功消息的组件

│ ├── services # 存放服务组件的文件夹

│ │ └── emailService.js # 处理邮件服务功能的组件

│ ├── utils # 存放工具组件的文件夹

│ │ └── validateEmail.js # 验证邮箱格式的组件

└── tests # 存放测试组件的文件夹

├── emailService.test.js # 测试邮件服务的组件

└── EmailForm.test.js # 测试邮件表单组件

EmailForm.js:此组件负责处理发送电子邮件的用户界面,例如收件人、主题和邮件正文的输入字段。

SuccessMessage.js:这个组件在邮件发送成功后显示一条成功消息。

emailService.js:该服务包含使用 Nodemailer 发送电子邮件的逻辑,使你的代码保持模块化和清晰。

validateEmail.js:一个实用的工具函数,用于检查电子邮件地址格式是否正确。

tests:该文件夹用于编写测试代码,以确保你的电子邮件服务和组件按预期运行。

🍱 良好项目组织的优势

易于导航:查看你的项目的任何人都可以快速了解,在哪里找到特定部分的代码,帮助理解其结构。

更好的协作:如果你与他人合作,清晰的结构可以帮助团队成员明确各自的贡献范围,避免相互干扰。

良好的扩展性:随着项目的发展,保持清晰的结构有助于管理复杂性,并保持代码库的整洁。

提高可维护性:当你需要更新或修复某些内容时,可以快速找到相关文件,从而节省时间并减少错误。

8. 保持一致的代码格式

一致的代码格式 有助于提高可读性,使代码更加清晰、有条理。

为你的项目确立一种编写代码的模式,例如使用两个空格缩进,或者在注释前始终包括一个换行符。

遵循一致的代码格式可以让代码更易读、更易维护,并提升项目的整体质量。

🛠️ 代码格式化工具

Prettier:基于一套规则自动格式化代码,确保代码风格一致。这里有一个教程,其中讲解如何在 VSCode 中设置和使用 Prettier,从而来帮助提高你的代码的可读性。

ESLint:用于强制执行编码规范,突出潜在问题。这里有一个教程,其中包含关于为你的项目设置 ESLint 的实用且深入的部分。

9. 避免硬编码

硬编码指的是,直接在代码中嵌入数据值,例如将用户 ID 设置为 123 而不是使用变量。

避免硬编码可以提高代码的复用性,减少手动修改的需求。相反,你应该将值存储在变量、常量或配置文件中,以便更灵活地调整和管理数据。

以下是硬编码可能导致问题的一个场景::

// 错误示例:硬编码的用户限制

function createUser(name) {

let numberOfUsers = 100; // 硬编码值

if (numberOfUsers >= 100) {

return '用户数量已达上限。';

}

// 创建用户的代码

return '用户已创建。';

}

在这个错误示例中,numberOfUsers 被硬编码为 100。如果您想要更改用户限制,您必须在代码中找到并修改此值。如果这个值在多个地方被重复使用,那么修改起来会变得繁琐且容易出错。

🏗️ 使用常量的优化示例

现在,让我们对代码进行重构,使用常量来替代硬编码:

// 良好示例:使用常量

const MAX_USERS = 100; // 将限制存储在常量中

function createUser(name) {

let numberOfUsers = getCurrentUserCount(); // 从函数或数据库获取当前计数

if (numberOfUsers >= MAX_USERS) {

return '用户数量已达上限。';

}

// 创建用户的代码

return '用户已创建。';

}

// 获取当前用户数量的示例函数

function getCurrentUserCount() {

// 模拟从数据库获取当前计数

return 90; // 示例计数

}

🥣 优化示例解析:

使用常量:MAX_USERS 常量被定义在代码顶部。如果未来需要更改最大用户数,只需修改这一处,而不必在代码中四处查找并修改硬编码的值

动态值:getCurrentUserCount() 函数会从数据库或其他数据源中动态获取当前的用户数量。这种方法避免了对数量进行硬编码,便于轻松更改。

可维护性:将值存储在常量中,使你的代码更易于维护。如果业务需求发生变化,并且您需要将用户限制增加到 150,只需将 MAX_USERS 从 100 更改为 150,整个应用程序都会反映出这一更改。

清晰性:为常量使用描述性的名称(如 MAX_USERS)可提高代码的可读性。任何查看您代码的人都能迅速明白这个值所代表的含义。

🤐 何时使用配置文件

在大型应用程序中,你可能还会考虑使用配置文件(如 JSON、YAML 或环境变量)来存储在不同环境(开发、预发布、生产)之间可能会改变的值。

例如,在你的 config.json 文件中,你可以将 maxUsers 硬编码(但请注意,在 config.json 中,建议使用驼峰命名法,以保持格式一致性):

{

"maxUsers": 100,

"emailService": {

"service": "gmail",

"user": "your-email@gmail.com",

"pass": "your-email-password"

}

}

🪴 在代码中使用配置文件:

const config = require('./config.json');

function createUser(name) {

let numberOfUsers = getCurrentUserCount();

if (numberOfUsers >= config.maxUsers) {

return 'User limit reached.';

}

// 代码以创建用户

return 'User created.';

}

10. 限制函数长度

较长的函数难以理解和维护。

虽然没有严格的规定,但通常来说,函数的长度最好控制在 20 到 30 行以内。如果一个函数承担了多个职责或包含过多的步骤,这往往意味着它太长了。需将这些函数拆分成为较小的“辅助”函数,可以使代码更易管理和理解。

下面是一个冗长而复杂的函数示例:

function updateCart(cart, item, discountCode) {

// 将商品加入购物车

cart.items.push(item);

// 计算新的总价

let total = 0;

cart.items.forEach(cartItem => {

total += cartItem.price * cartItem.quantity;

});

// 如果有折扣码则应用折扣

if (discountCode) {

total = applyDiscount(total, discountCode);

}

// 记录交易

console.log(`Item added: ${item.name}, New total: $${total}`);

return total;

}

⚠️ 这个函数执行了多个任务:

将商品加入购物车。

计算总价格。

如果有折扣码,则应用折扣。

记录交易信息。

虽然该函数目前看起来可以管理,但如果继续增加任务,它会迅速变得难以调试和维护。

让我们将这个冗长的函数拆分为更小、单一职责的函数:

function updateCart(cart, item, discountCode) {

addItemToCart(cart, item);

let total = calculateTotal(cart);

if (discountCode) {

total = applyDiscount(total, discountCode);

}

logTransaction(item, total);

return total;

}

function addItemToCart(cart, item) {

cart.items.push(item);

}

function calculateTotal(cart) {

return cart.items.reduce((total, cartItem) => total + cartItem.price * cartItem.quantity, 0);

}

function logTransaction(item, total) {

console.log(`Item added: ${item.name}, New total: $${total}`);

}

🧩 详细解释:

addItemToCart:该函数仅负责将商品添加到购物车。它简单且目标明确,不包含任何额外逻辑。

calculateTotal:函数计算购物车内所有商品的总价。这样代码更易读、易理解,如果你未来需要修改计算方式,只需调整这个函数即可。

logTransaction:负责记录详细信息。如果你以后需要更改日志内容(例如,添加时间戳),只需修改该函数,而不会影响其他部分。

updateCart:作为主函数,它现在更像是一个流程总结——先添加商品,然后计算总价、再应用折扣,最好记录交易结果。这种方式使代码一目了然,更清晰易懂。

📒 让我们总结一下限制函数长度的要点:

🎯 专注于单一任务: 每个函数最好只执行一个任务。如果一个函数同时处理多个任务,不妨考虑将其拆分成更小的函数。。

🩼 使用辅助函数: :辅助函数是小型且专注的函数,用于执行特定任务并支持主函数的运行。例如,上述示例中的addItemToCart、calculateTotal 和 logTransaction 就是辅助函数。

🪦 使用描述性命名: 函数名称应该能够清楚表达其功能(例如 addItemToCart),这样可以让代码自解释,减少对额外注释的依赖。

整洁代码的最佳实践

现在我们已经介绍了一些重要的技巧,现在让我们来看一下整洁代码背后的核心原则:

🎏 简单性: 始终让代码尽可能简单,避免不必要的复杂度。

🧂 一致性: 保持代码在风格和结构上的统一性,使其更易读和维护。

🌾 清晰性: 代码应该清楚地表达它的功能,无需额外的解释。

⛽ 高效性: 在不牺牲可读性的前提下,编写优化的代码,以提升性能。

这些原则表明,编写代码不仅仅是写代码,更是设计解决方案。整洁代码是一种需要不断练习的技能,所以请保持学习,不断提升自己!

🔌 关于依赖项的说明

与其直接在代码中硬编码依赖项,不如使用包管理工具来管理它们,如 npm(用于 JavaScript)或 pip(用于 Python)这样的包管理器来统一规划它们。这样,你可以轻松更新或移除依赖项,确保代码的灵活性和可维护性。

总结 🏁

编写整洁的代码就像为房子打下坚实的地基。它能让整个项目井然有序,使你在项目扩展时轻松添加新功能或修复问题。

掌握这些技巧后,你可以逐步养成让代码更易读、更易维护的良好习惯,同时让编写代码变得更加高效且愉悦。

建议的下一步 📘

如果你想在六个月内成为后端开发者,可以参考我的后端开发人员路线图。该路线图旨在帮助初学者按照每周目标稳步学习,其中涵盖关键的技能、工具和技术。这个路线图可以让你的学习过程更加有条理、易坚持。

你可以在 𝕏 上关注我,以获取实时更新。

期待我们的下次再见!