Jest单元测试
由于格式和图片解析问题,可前往 阅读原文
前端自动化测试在提高代码质量、减少错误、提高团队协作和加速交付流程方面发挥着重要作用。它是现代软件开发中不可或缺的一部分,可以帮助开发团队构建可靠、高质量的应用程序
单元测试(Unit Testing)和端到端测试(End-to-End Testing)是两种常见的测试方法,它们在测试的范围、目的和执行方式上有所不同。单元测试和端到端测试不是相互排斥的,而是互补的。它们在不同的层面和阶段提供了不同的价值,共同构成了一个全面的测试策略
单测和端测区别
单元测试(Unit)
- 单元测试关注于最小的可测试单元,如函数、方法或模块
- 目的是验证代码中的每个独立单元(如函数)是否按照预期工作
- 通常是自动化的、快速执行的,且不依赖于外部资源或其他模块
- 验证单个代码单元的行为,提供快速反馈,并帮助捕获和修复问题
端到端测试(End-to-End)
- 从用户角度出发,测试整个应用程序的功能和流程
- 模拟真实的用户交互和场景,从应用程序的外部进行测试。跨多个模块、组件和服务进行,以确保整个应用程序的各个部分正常协同工作
- 涉及用户界面(UI)交互、网络请求、数据库操作等,以验证整个应用程序的功能和可用性
总之,单元测试主要关注代码内部的正确性,而端到端测试关注整体功能和用户体验。结合使用这两种测试方法可以提高软件的质量和可靠性。在项目中尤其是公共依赖如组件库至少都需要单测,端测相对来说比较繁琐点,但是也是程序稳定的重要验证渠道
单元测试 - Jest
这里使用Jest作为单元测试工具,Jest 是一个用于 JavaScript 应用程序的开源测试框架。它是由 Facebook 开发和维护的,通常用于单元测试。Jest 具有简单易用的 API、丰富的功能和强大的断言库,广泛应用于前端开发和 Node.js 环境中
安装
➜ npm install jest -D
初始化
使用npx进行交互式生成默认的配置文件,它会提示你每步的选择:
➜ npx jest --init
The following questions will help Jest to create a suitable configuration for your project✔ Would you like to use Jest when running "test" script in "package.json"? … yes
✔ Would you like to use Typescript for the configuration file? … no
✔ Choose the test environment that will be used for testing › jsdom (browser-like)
✔ Do you want Jest to add coverage reports? … yes
✔ Which provider should be used to instrument code for coverage? › v8
✔ Automatically clear mock calls, instances, contexts and results before every test? … yes✏️ Modified test/package.json📝 Configuration file created at test/jest.config.js
默认配置文件大概是下面的内容:配置中有很多注释提供我们参考,对于默认的配置就不用删除多语的注释了,方便参考。通常都是对需要的配置项做修改即可
const config = {// All imported modules in your tests should be mocked automatically// automock: false,// Automatically clear mock calls, instances, contexts and results before every testclearMocks: true,// Indicates whether the coverage information should be collected while executing the testcollectCoverage: true,// An array of glob patterns indicating a set of files for which coverage information should be collected// collectCoverageFrom: undefined,// The directory where Jest should output its coverage filescoverageDirectory: "coverage",// An array of regexp pattern strings used to skip coverage collection// coveragePathIgnorePatterns: [// "/node_modules/"// ],// Indicates which provider should be used to instrument code for coveragecoverageProvider: "v8",// Make calling deprecated APIs throw helpful error messages// errorOnDeprecated: false,// A list of paths to directories that Jest should use to search for files in// roots: [// "<rootDir>"// ],// The test environment that will be used for testingtestEnvironment: "jsdom",// 省略其他...
};module.exports = config;
常用的配置:
-
collectCoverage:boolean值,用来生成覆盖率报告,通常也可以使用命令行
--coverage
参数生成 -
moduleFileExtensions:对于引入文件可以省去文件后缀,jest会根据规则一一匹配
-
moduleNameMapper:模块匹配规则,告诉jest改模块的匹配路径
{moduleNameMapper: {// 当匹配到 .css 等结尾的文件时对应 /__mocks__/style-mock.ts 文件"\\.(css|less|scss|sass)$": "<rootDir>/__mocks__/style-mock.ts",// 当匹配 @ui 开头的的对应到 src 文件夹"@ui/(.*)": "<rootDir>/src/$1",}, }
-
setupFiles:在测试环境准备后和安装jest框架前做一些配置,常用来添加一些全局环境模拟数据
-
setupFilesAfterEnv:在安装jest框架后对jest做一些扩展,相比setupFiles更加通用
-
testEnvironment:jest模拟的环境,可以选择node、jsdom来模拟node和浏览器环境
-
testMatch:指定要测试哪些文件
-
transform:使用一些插件对代码进行转义以便jest可以理解,如设置tsx转义
以上是最基本的配置,jest的配置还是很多的,还要官方有列举了一个表可以随时翻阅不用死记
转译器
Jest中有转义器的概念来帮助它理解编写的代码,可以比做babel对代码做一些转换来兼容浏览器,差不多一样的道理
-
模块引用转换
在单个测试文件中都会引入我们编写的代码,然后对此代码的功能进行测试,而前端通常都是以esmodule的形式进行函数的导出,jest默认使用的是commonjs,对于module语法jest不认识就会报错
import { sum } from "../core"; // 报错describe("第一个测试", () => {// ... })
那么可以对jest添加转义器将esmodule模块的代码转换成commonjs就可以了。打开配置文件:
// jest.config.js {transform: {"^.+\\.(ts|tsx|js|jsx)$": ["babel-jest",{presets: [["@babel/preset-env", { targets: { node: "current" } }]]},],}, }
上面使用了
babel-jest
和@babel/preset-env
的依赖包需要安装下:➜ npm i babel-jest @babel/preset-env -D
这样就可以解决esmodule语法不识别的问题
-
转换typescript:目前项目中的文件都是以ts编写的,而默认情况下jest只识别js文件的,那么就需要对ts进行转译让jest识别
// jest.config.js {transform: {"^.+\\.(ts|tsx|js|jsx)$": ["babel-jest",{presets: [/* 其它... */["@babel/preset-typescript"]]},],}, }
需要安装对应的
@babel/preset-typescript
;除了使用ts转义器也可以使用ts-jest
直接运行ts代码得益于ts的转译插件可以让jest的测试文件(或配置文件)都写成ts类型的,而在ts文件中对于不识别的jest工具会报错或者没有提示,安装jest的类型文件包
@types/jest
来告诉ts对应的jest类型,然后进行配置:// tsconfig.json {"types": ["jest"] }
-
转换jsx:假如项目中使用了jsx那么也要对jsx进行转义,这里以vue jsx为例
// jest.config.ts {transform: {"^.+\\.(ts|tsx|js|jsx)$": ["babel-jest",{// 省略其他plugins: ["@vue/babel-plugin-jsx"],},],}, }
基本断言
基本环境配置好后,就到了测试的时间了,我们先来最简单的配置用起
// __tests__/demo.spec.ts
import { sum } from "src/utils";describe("第一个测试", () => {it("分组1", () => {expect(sum(1, 2)).toBe(3);});
});// 或者不用分组
test("第一个测试", () => {expect(sum(1, 2)).toBe(3);
});
这里介绍下几个关键字基本概念:
- describe:用来描述当前测试的整体内容
- it:用来分组测试
- test:用来描述当前测试,无分组
- expect:判断参数的值,其的返回值有多个断言方法,上面使用了
toBe
也就是等于的意思。除了次此断言有很多断言的条件,你可以点击这里阅读官方文档
执行测试
# 现在package中配置 jest 脚本,然后执行测试
➜ npm run test # npx jestPASS __tests__/demo.spec.ts第一个测试✓ 分组1 (2 ms)----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 | utils.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.519 s
Ran all test suites.
✨ Done in 1.02s.
可以看到对应的测试文件、分组以及测试覆盖率
路径映射
上面在测试代码时会先引入对应的工具代码,如果都使用相对路径引入会显得很麻烦。在项目中通常都喜欢使用@
这种方式引入文件,在测试环境依然可以使用,这样也可以和项目中的文件路径保持一致
配置路径映射需要满足两个条件:
- jest识别路径映射
- ts识别路径映射(如果项目中用了ts)
配置jest路径映射
// jest.config.ts
{moduleNameMapper: {"@/(.*)": "<rootDir>/src/$1",},
}
配置tsconfig
// tsconfig.json
{"paths": {"@/*": ["src/*"]}
}
这样在测试文件中就可以使用路径映射降低心智负担
// __tests__/demo.spec.ts
import { sum } from "@/utils";
除了手动设置外还可以将tsconfig中的path直接作为路径映射,这样就减少了多处的修改。实现这一功能需要借助ts-jest
工具包,不同这个自己也可以写个逻辑实现
// jest.config.ts
const { pathsToModuleNameMapper } = require('ts-jest/utils')
const { compilerOptions } = require('./tsconfig')export default {moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {prefix: "<rootDir>/",}),
}
dom测试
jest支持浏览器环境,使用浏览器环境时需要安装对应的包,请根据版本可以选择jsdom
或jest-environment-jsdom
包进行安装,这里jest版本为28+
使用后者。测试文件修改如下:
// __tests__/demo.spec.ts
describe("第一个测试", () => {it("分组1", () => {// 使用 localStorage APIlocalStorage.setItem('a', '1');expect(localStorage.getItem(('a'))).toBe('1')});
});
运行测试用例:
➜ npm run test
PASS __tests__/demo.spec.ts第一个测试✓ 分组1 (2 ms)----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.701 s, estimated 1 s
Ran all test suites.
✨ Done in 1.13s.
异步测试
jest可以使用多种方式进行异步代码测试,通常使用promise、async就可以了
- 使用promise
- async/await
- 回调
这里模拟一个异步方法,通过上面的三种方式进行测试
// src/utils
export function getUser(name: string) {return new Promise((resolve) => {setTimeout(() => resolve(name), 1000);});
}
使用Promise
// __tests__/demo.spec.ts
import { getUser } from "@/utils";describe("测试异步代码", () => {it("promise调用方式测试", () => {const user = "小明";// 使用thengetUser(user).then((res) => {expect(res).toBe(user);});});it("使用resolves测试promise", () => {const user = "小李";// 使用 .resolves 方式,注意这里要 returnreturn expect(getUser(user)).resolves.toBe(user);})
});
使用async测试
// __tests__/demo.spec.ts
import { getUser } from "@/utils";describe("测试异步代码", () => {it("使用async测试", async () => {const user = "小明";const res = await getUser(user)expect(res).toBe(user);})
});
使用回调函数
回调函数默认通常是以前那种回调写法,这里需要对以上的异步函数进行调整,让其换成回调函数模式
// 接受一个cb,这里固定返回的值为true,没有错误
export function getUser(cb: (error: any, data: any) => void) {setTimeout(() => {cb(null, true);}, 500);
}// 定义测试
describe("测试异步代码", () => {it("使用回调函数", (done) => {function cb(error: any, data: any) {if (error) {done(error);return;}try {expect(data).toBe(true);done();} catch (err) {done(err); // 这里一定要使用try catch,防止出错时没有执行done}}getUser(cb);});
});
回调模式一定要执行done
函数,如果没有执行则会被认为超时错误
模拟函数
假设要模拟一个工具函数的内部实现,可以使用mock函数来判断函数内部的值是否达到预期
定义个待测试的函数forEach
export function forEach(items: number[], callback: (num: number) => void) {for (let index = 0; index < items.length; index++) {callback(items[index]);}
}
添加测试用例:
// __tests__/demo.spec.ts
import { forEach } from "@/utils";// 模拟函数
const mockFn = jest.fn((x: number) => x + 1);test("模拟函数", () => {forEach([0, 1], mockFn);expect(mockFn.mock.calls).toHaveLength(2);expect(mockFn.mock.calls[0][0]).toBe(0);expect(mockFn.mock.calls[1][0]).toBe(1);expect(mockFn.mock.results[0].value).toBe(1);
});
更多关于模拟函数的例子请查看文档 和 API
定时器
Jest可以通过一个函数转换计时器以便允许你控制时间流量
假设测试如下定时器代码:
export function useTimer(cb?: Function) {setTimeout(() => cb && cb(), 1000);
}
编写测试用例:
import { useTimer } from "@/utils";jest.useFakeTimers();
jest.spyOn(global, "setTimeout");test("test timer", () => {const cb = jest.fn();useTimer(cb);expect(cb).not.toBeCalled();// 执行所有的定时器jest.runAllTimers();expect(cb).toBeCalled();
});
更多见官方文档
setup配置
写测试的时候你经常需要在运行测试前做一些准备工作,和在运行测试后进行一些收尾工作。 Jest 提供辅助函数来处理这个问题
这其中包括beforeEach、afterEach、beforeAll、afterAll,其中前两者在每个测试前都会执行一次,后者在文件中只会执行一次
覆盖率
除了对程序进行断言外,jest还收集代码的测试覆盖率并生成对应的报告,包括:某个函数内部的测试覆盖率、整个文件的覆盖率,要想达到覆盖率100%,就要测试到每个文件的所有代码、每个函数内部的所有分支条件
开启覆盖率
可以通过配置文件
// jest.config.ts
// 主要涉及到这两个配置
export default {collectCoverage: true, // 启用coverageDirectory: "coverage", // 报告生成位置
}
通过cli,执行脚本时带上参数
➜ npx jest --coverage
测试覆盖率
假设我们有这么一个函数
export function whatType(arg: any) {const type = Object.prototype.toString.call(arg)if (type === '[object String]') {return 'string';} else if (type === '[object Boolean]') {return 'boolean';}
}
添加测试用例
import { whatType } from "@/utils";describe("测试覆盖率", () => {it("函数条件覆盖率", () => {expect(whatType(true)).toBe("boolean");});
});
执行测试用例
➜ npm run testPASS __tests__/demo.spec.ts测试覆盖率✓ 函数条件覆盖率 (1 ms)----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 96.77 | 50 | 100 | 96.77 | index.ts | 96.77 | 50 | 100 | 96.77 | 4
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.486 s, estimated 1 s
- File:测试的文件
- Stmts:测试中被执行的代码语句的比例
- Branch:测试代码条件分支比例
- Funcs:测试中被执行函数比例
- Lines:测试中被执行代码行数比例
- Uncovered Line:没有测试到的行数
除了查看终端的表格外,还可以使用更直观的报告,文件报告的结构大概如下:
coverage
├── clover.xml # xml格式
├── coverage-final.json # json格式
├── lcov-report # html格式
│ ├── base.css
│ ├── block-navigation.js
│ ├── favicon.png
│ ├── index.html # 主页面入口
│ ├── index.ts.html
│ ├── other.ts.html
│ ├── prettify.css
│ ├── prettify.js
│ ├── sort-arrow-sprite.png
│ └── sorter.js
└── lcov.info
一般都来查看HTML报告,打开报告页面
可以点击对应的文件查看更详细的报告
Vue组件测试
jest也可以对vue组件进行测试,vue官方提供了 vue2版本工具包(vue-test) 和 vue3版本工具包(@vue/test-utils),这里基于vue3组件进行测试
安装对应的依赖:
➜ npm install @vue/test-utils -D
对于Jestv28+以上版本还需要添加以下配置:
// jest.config.ts
export default {testEnvironmentOptions: {customExportConditions: ["node", "node-addons"],},
}
创建一个简单的Button组件:
import { defineComponent } from "vue";export default defineComponent({render(){return <button>按钮</button>}
})
添加测试用例:
import { mount } from "@vue/test-utils";
import Button from "@/components/Button";test("测试vue组件", () => {const wrapper = mount({setup() {return () => {return <Button />;};},});expect(wrapper.text()).toBe('按钮')
})
运行测试
➜ npm run testPASS __tests__/demo.spec.tsx✓ 测试vue组件 (9 ms)------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 | Button.tsx | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.633 s
添加全局组件,当单测某个组件时,组件内部引用的其它组件会因为没有引用而报错,定义全局组件可以解决这个问题
// jest.setup.ts
import { config } from "@vue/test-utils";
import Button from "@/button/src/button";
import Icon from "@/button/src/icon";config.global.components = {Button,Icon,
};
配置jest
// jest.config.ts
export default {setupFiles: ["<rootDir>/jest.setup.ts"],
}
这里不对vue工具包API过多的解释,更多的API使用可以查看官方文档,vue2版本的可以查看这里
由于格式和图片解析问题,可前往 阅读原文
相关文章:
Jest单元测试
由于格式和图片解析问题,可前往 阅读原文 前端自动化测试在提高代码质量、减少错误、提高团队协作和加速交付流程方面发挥着重要作用。它是现代软件开发中不可或缺的一部分,可以帮助开发团队构建可靠、高质量的应用程序 单元测试(Unit Testi…...
Lineageos 22.1(Android 15) 开机向导制作
一、前言 开机向导原理其实就是将特定的category的Activity加入ComponentResolver,如下 <category android:name"android.intent.category.SETUP_WIZARD"/>然后我们开机启动的时候,FallbackHome结束,然后启动Launcher的时候…...
前沿计组知识入门
这份PDF文件是一份关于计算机体系结构的讲义,涵盖了从基础概念到高级主题的多个方面。以下是详细的总结和分析: 计算机体系结构概述 定义:计算机体系结构是计算机系统的理论组成部分,根据其属性和功能进行划分,包括计…...
力扣 最长递增子序列
动态规划,二分查找。 题目 由题,从数组中找一个最长子序列,不难想到,当这个子序列递增子序列的数越接近时是越容易拉长的。从dp上看,当遍历到这个数,会从前面的dp选一个最大的数加上当前数,注意…...
在项目中调用本地Deepseek(接入本地Deepseek)
前言 之前发表的文章已经讲了如何本地部署Deepseek模型,并且如何给Deepseek模型投喂数据、搭建本地知识库,但大部分人不知道怎么应用,让自己的项目接入AI模型。 文末有彩蛋哦!!! 要接入本地部署的deepsee…...
已解决IDEA无法输入中文问题(亲测有效)
前言 在使用IDEA的时候,比如我们想写个注释,可能不经意间,输入法就无法输入中文了,但是在其他地方打字,输入法仍然能够正常工作。这是什么原因呢,这篇文章带你解决这个问题! 快捷键 如果你的I…...
Java 语法新特性(Records、Pattern Matching、Sealed Classes)深度解析(11/17/21)✨
一、Records(Java 16) 📝 核心价值:简化不可变数据载体的定义 // 传统POJO vs Record public record User(String name, int age) {} // 自动生成:构造方法/equals()/hashCode()/toString() User user new User(&qu…...
书评与笔记:《如何有效报告Bug》
文章目录 书评笔记核心原则1. 首要目标:让程序员亲眼看到问题2. 次要目标:详细描述问题3. 保持冷静,避免误操作4. 提供额外信息5. 清晰、准确地表达 实用建议不要自作聪明地诊断问题类比:看医生时的症状描述程序员的心理 总结 原文…...
Node.js 中的 fs 模块详解
fs(File System)模块是 Node.js 的核心模块之一,用于处理文件系统的操作,包括文件的读取、写入、删除、重命名等。它提供了同步和异步两种操作方式,适用于不同的场景。 1. 前置知识 1.1 文件系统 文件系统是操作系统…...
【深度学习】如何一步步实现SGD随机梯度下降算法
如何一步步实现SGD随机梯度下降算法 文章目录 如何一步步实现SGD随机梯度下降算法SGD随机梯度下降算法的作用MNIST_SAMPLE数据集SGD算法的七大步骤Step1. 初始化模型参数Step2. 计算预测值predictionsStep3. 计算损失lossStep4. 计算梯度gradientsStep5. 更新模型参数Step6. 重…...
Android Hal AIDL 简介 (一)
Android 接口定义语言 (AIDL) 是一款可供用户用来抽象化 IPC 的工具。 以在 .aidl 文件中指定的接口为例,各种构建系统都会使用 aidl 二进制文件构造 C++ 或 Java 绑定,以便跨进程使用该接口(无论其运行时环境或位数如何)。 AIDL 可以在 Android 中的任何进程之间使用:在…...
【数据分析】2.数据分析业务全流程
业务流程方法论:3阶段6步骤 一、课程核心内容结构 1. 方法论概述 目标:系统性地解决商业中的关键问题框架:分为三个阶段,每个阶段包含两个步骤适用场景:适用于数据分析师、业务经理等需要通过数据分析支持决策的从业…...
如何使用Spark SQL进行复杂的数据查询和分析
使用Spark SQL进行复杂的数据查询和分析是一个涉及多个步骤和技术的过程。以下是如何使用Spark SQL进行复杂数据查询和分析的详细指南: 一、准备阶段 环境搭建: 确保已经安装并配置好了Apache Spark环境。准备好数据源,可以是CSV文件、JSON…...
【Spring+MyBatis】_图书管理系统(下篇)
图书管理系统上篇、中篇如下: 【SpringMyBatis】_图书管理系统(上篇)-CSDN博客 【SpringMyBatis】_图书管理系统(中篇)-CSDN博客 目录 功能5:删除图书 6.1 约定前后端交互接口 6.2 后端接口 6.3 前端…...
goland无法debug项目
1、其实个原因是因为正在使用的Delve调试器版本太旧,无法兼容当前的Go语言版本1.2。Delve是Go语言的一个调试工具,用于提供源码级别的调试功能。Go语言每隔一段时间会发布新版本,而相应的调试器Delve也可能会更新以提供新的特性或修复已知问题…...
001-监控你的文件-FSWatch-C++开源库108杰
fswatch 原理与应用简介fswatch 安装fswatch 实践应用具体应用场景与细节补充 1. 简介 有些知识,你知道了不算厉害,但你要是不知道,就容易出乱。 很多时候,程序需要及时获取磁盘上某个文件对象(文件夹、文件࿰…...
leetcode203.移除链表元素
目录 问题描述示例提示 具体思路思路一思路二 代码实现 问题描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 题目链接:移除链表元素 示例 提示 列表中的节点数目在范围…...
代码随想录算法训练营第六天| 242.有效的字母异位词 、349. 两个数组的交集、202. 快乐数 、1. 两数之和
242.有效的字母异位词 题目链接:242.有效的字母异位词 文档讲解:代码随想录有效的字母异位词 视频讲解:LeetCode:有效的字母异位词 状态:学会了 思路: 数组其实是简单哈希表。 哈希表用来快速判断元素是否在…...
DL/CV领域常见指标术语(FLOPS/mIoU/混淆矩阵/F1-measure)------一篇入门
1. FLOPS、FLOPs和GFLOPs FLOPS: floating-point operations per second,每秒浮点运算次数,用来衡量硬件性能。 FLOPs:floating point of operations,是浮点运算次数,用来衡量算法、模型的复杂度。 GFLOPSÿ…...
rknn 板端运行程序Invalid RKNN model version 6, Meet unsupported rknn target type
E RKNN: [09:15:53.053] 6, 1 E RKNN: [09:15:53.053] Invalid RKNN model version 6 E RKNN: [09:15:53.053] rknn_init, load model failed! [NN_ERROR] rknn_init fail! ret-1 或者报错: E RKNN: [08:35:30.804] Meet unsupported target type: 0x46495247 E…...
Linux 内核中的 container_of 宏:以 ipoib_rx_poll_rss 函数为例
在 Linux 内核编程中,container_of 是一个非常实用的宏,主要用于通过结构体的成员指针来获取包含该成员的整个结构体的指针。rx_ring = container_of(napi, struct ipoib_recv_ring, napi); 在代码中就是利用了这个宏,下面我们详细分析它的作用和工作原理。 背景知识 在内…...
【数据结构-红黑树】
文章目录 红黑树红黑树介绍红黑树的五个基本性质红黑树的平衡原理红黑树的操作红黑树的操作 代码实现节点实现插入和查询操作 红黑树 红黑树介绍 红黑树(Red-Black Tree)是一种自平衡的二叉查找树(Binary Search Tree, BST)&…...
一个简洁高效的Flask用户管理示例
Flask-Login 是 Flask 的用户管理扩展,提供 用户身份验证、会话管理、权限控制 等功能。 适用于: • 用户登录、登出 • 记住用户(“记住我” 功能) • 限制未登录用户访问某些页面 • 用户会话管理 1. 安装 Flask-Login pi…...
用Nginx打造防盗链护盾
用Nginx打造防盗链护盾 一、你的网站正在"为他人做嫁衣"? 想象一下这个场景: 你精心拍摄的摄影作品、录制的课程视频、设计的原创素材,被其他网站直接盗用链接。 更气人的是——当用户在他们网站查看这些资源时,消耗的…...
VS Code 如何搭建C/C++开发环境
目录 1.VS Code是什么 2. VS Code的下载和安装 2.1 下载和安装 2.2.1 下载 2.2.2 安装 2.2 环境的介绍 2.3 安装中文插件 3. VS Code配置C/C开发环境 3.1 下载和配置MinGW-w64编译器套件 3.1.1 下载 3.1.2 配置 3.2 安装C/C插件 3.3 重启VSCode 4. 在VSCode上编写…...
DeepSeek、微信、硅基流动、纳米搜索、秘塔搜索……十种不同方法实现DeepSeek使用自由
为了让大家实现 DeepSeek 使用自由,今天分享 10 个畅用 DeepSeek 的平台。 一、官方满血版:DeepSeek官网与APP 首推,肯定是 DeepSeek 的官网和 APP,可以使用满血版 R1 和 V3 模型,以及联网功能。 网址: htt…...
【Java】Enum类的常用方法、实现接口及其实际应用
Enum类的常用方法 package com.star.enum03;/** * author : Starshine */public class TestSeason { //这是一个main方法,是程序的入口: public static void main(String[] args) { //用enum关键字创建的Season枚举类上面的父类是ÿ…...
Linux | 进程控制(进程终止与进程等待)
文章目录 Linux | 进程控制 — 进程终止 & 进程等待1、进程终止进程常见退出方法1.1退出码基本概念获取退出码的方式常见退出码约定使用场景 1.2 strerror函数 & errno宏1.3 _exit函数1.4_exit和exit的区别1.4.1 所属头文件与函数原型1.4.2 执行过程差异**结合现象分析…...
三、tsp学习笔记——屏幕移植
泰山派-6寸猫屏转接板 - 立创开源硬件平台 泰山派樱猫的教程,屏资料链接: https://pan.baidu.com/s/1pNAKH33r7LtZG6EwHJ-HNA?pwdnsde 提取码: nsde (不要浪费时间下载,没有用,下载gitee上的) leefei/tspi-disp-6…...
python全栈-python进阶
python进阶 文章目录 python进阶异常except自定义异常类 文件操作序列化和反序列化CSV文件os模块os.path模块shutil模块 拷贝压缩 模块--modulefrom 模块 import 成员包package库LibraryPIP库 GUI编程-tkinter版使用类定义的GUI界面设置控件的属性方式Label标签的常用属性Butto…...
SpringBoot如何配置开发环境(JDK、Maven、IDEA等)
目录 1. 安装JDK 一、JDK介绍JRE(Java Runtime Envirnment):Java运行环境 二、下载JDK官网地址:Java Downloads | Oracle 三、安装JDK点击下载下来的安装包进行安装 四、配置JDK进入到环境变量中(下面介绍两种进入…...
图片粘贴上传实现
图片上传 html demo 直接粘贴本地运行查看效果即可,有看不懂的直接喂给 deepseek 会解释的很清晰 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"…...
C++--STL库-List
目录 1.list 的基本使用 1.1 创建和初始化 1.2. 插入元素 1.3. 删除元素 1.4. 访问元素 1.5 遍历 1.6 总结 list是C标准库(STL)中的双向链表容器,属于<list>头文件。 它的特点是: 动态大小:可以随时插入…...
kubeadm拉起的k8s集群证书过期的做法集群已奔溃也可以解决
kubeadm拉起的k8s集群证书过期的做法 这个是很久之前遇到的了,今天有空(心血来潮)就都回忆回忆写在这里为爱发光,部分内容来自arch先生(死党)的帮助。有时候有很多部门提了建k8s的需求,有些是临…...
idea连接gitee(使用idea远程兼容gitee)
文章目录 先登录你的gitee拿到你的邮箱找到idea的设置选择密码方式登录填写你的邮箱和密码登录成功 先登录你的gitee拿到你的邮箱 具体位置在gitee–>设置–>邮箱管理 找到idea的设置 选择密码方式登录 填写你的邮箱和密码 登录成功...
Kafka 简介
Kafka 简介 Apache Kafka 是一个开源的分布式流处理平台,广泛应用于实时数据流处理、日志管理、消息传递等场景。Kafka 最初由 LinkedIn 开发,并于 2011 年捐献给 Apache 软件基金会。 Kafka 的设计目标是高吞吐量、低延迟和高可用性,它能够…...
Ubuntu22.04 Deepseek-R1本地容器化部署/内网穿透/OPENWEBUI,打造个人AI助手!
1. 前言 本地部署DeepSeek并实现内网穿透,为家庭成员提供强大的AI支持。通过使用Ollama、Docker、OpenWebUI和Nginx,内网穿透,我们可以轻松实现快速响应和实时搜索功能。 2.软硬件环境 系统:ubuntu22.04, cuda12GPU: RTX3080Ti …...
红蓝对抗之常见网络安全事件研判、了解网络安全设备、Webshell入侵检测
文章目录 研判(入侵检测) 设备 经典网络云网络 异常HTTP请求Webshell分析 Webshell 的分类Webshell 的检测 主机层面流量层面 附录 常见端口漏洞…...
Linux部署DeepSeek r1 模型训练
之前写过一篇windows下部署deepseekR1的文章,有小伙伴反馈提供一篇linux下部署DeepSeek r1 模型训练教程,在 Linux 环境下,我找了足够的相关资料,花费了一些时间,我成功部署了 DeepSeek R1 模型训练任务,结…...
【大模型】DeepSeek:AI浪潮中的破局者
【大模型】DeepSeek:AI浪潮中的破局者 引言:AI 新时代的弄潮儿DeepSeek:横空出世展锋芒(一)诞生背景与发展历程(二)全球影响力初显 探秘 DeepSeek 的技术内核(一)独特的模…...
寒假学习总结
整个寒假都走在数据结构与算法的路上,深入学习了其中多个板块,刷了一些与之对应的题目,下面来一期总结(c) (emmm,主播在寒假试着去学习了几大语言的语法基础(丢丢) 如Ja…...
自愈网络的定义、其为用户带来的益处、具体的使用案例
在当今高度互联的世界中,网络稳定性和可靠性对于各种应用场景至关重要。无论是企业的日常运营、智能家居的便捷控制,还是工业网络的自动化管理,网络的任何中断都可能带来不可估量的损失和不便。正是基于这种需求,以太联—Intellin…...
NumPy的基本使用
在 Python 的数据科学与数值计算领域,NumPy 无疑是一颗耀眼的明星。作为 Python 中用于科学计算的基础库,NumPy 提供了高效的多维数组对象以及处理这些数组的各种工具。本文将带您深入了解 NumPy 的基本使用,感受它的强大魅力。 一、安装与导…...
HTTP 与 HTTPS:协议详解与对比
文章目录 概要 一. HTTP 协议 1.1 概述 1.2 工作原理 1.3 请求方法 1.4 状态码 二. HTTPS 协议 2.1 概述 2.2 工作原理 2.3 SSL/TLS 协议 2.4 证书 三. HTTP 与 HTTPS 的区别 四. 应用场景 4.1 HTTP 的应用场景 4.2 HTTPS 的应用场景 概要 HTTP(Hy…...
从零开始构建一个语言模型中vocab_size(词汇表大小)的设定规则
从零开始构建一个语言模型就要设计一个模型框架,其中要配置很多参数。在自然语言处理任务中,vocab_size(词汇表大小) 的设定是模型设计的关键参数之一,它直接影响模型的输入输出结构、计算效率和内存消耗。 本文是在我前文的基础上讲解的:从零开始构建一个小型字符级语言…...
斐波那契数列模型:在动态规划的丝绸之路上追寻斐波那契的足迹(上)
文章目录 引言递归与动态规划的对比递归解法的初探动态规划的优雅与高效自顶向下的记忆化搜索自底向上的迭代法 性能分析与比较小结 引言 斐波那契数列,这一数列如同一条无形的丝线,穿越千年时光,悄然延续其魅力。其定义简单而优美ÿ…...
RT-Thread+STM32L475VET6——ADC采集电压
文章目录 前言一、板载资源二、具体步骤1.打开CubeMX进行配置1.1 使用外部高速时钟,并修改时钟树1.2 打开ADC1的通道3,并配置为连续采集模式(ADC根据自己需求调整)1.3 打开串口1.4 生成工程 2. 配置ADC2.1 打开ADC驱动2.2 声明ADC2.3 剪切stm…...
基于Django快递物流管理可视化分析系统(完整系统源码+数据库+详细开发文档+万字详细论文+答辩PPT+详细部署教程等资料)
文章目录 基于Django快递物流管理可视化分析系统(完整系统源码数据库详细开发文档万字详细论文答辩PPT详细部署教程等资料)一、项目概述二、项目说明三、研究意义四、系统设计技术架构 五、功能实现六、完整系统源码数据库详细开发文档万字详细论文答辩P…...
【Pandas】pandas Series reindex_like
Pandas2.2 Series Computations descriptive stats 方法描述Series.align(other[, join, axis, level, …])用于将两个 Series 对齐,使其具有相同的索引Series.case_when(caselist)用于根据条件列表对 Series 中的元素进行条件判断并返回相应的值Series.drop([lab…...
Ollama安装和迁移,以及部署DeepSeek模型
什么是 Ollama Ollama 是大语言模型管理工具,它的主要作用是简化大语言模型的本地化部署和运行。如果你想调用本地模型,保护个人隐私,构建个人知识库,那你可以考虑使用 Ollama。 Ollama 的官网是 https://ollama.com/,正如官网所说,“Get up and running with large l…...