Compare commits

...

50 Commits

Author SHA1 Message Date
82324f6274 docs(web): 更新javascript基础文档中函数部分的描述
添加函数声明格式说明并完善函数定义描述
2025-12-05 13:32:37 +08:00
3531360974 Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-12-01 15:21:44 +08:00
da188afd82 docs(web): 修正HTML列表与语义布局文档的标题
将文档标题从"test"修改为"html 列表与语义布局",使其更准确地反映文档内容
2025-12-01 15:21:37 +08:00
祀梦
8ad5c45a42 docs: 添加站点域名配置以启用SEO优化 2025-11-21 19:38:57 +08:00
祀梦
bca2e0619c docs: 修正文档中的日期格式
将createTime的日期格式从"2025年11月11日 13:54:02"统一修改为"2025/11/11 13:54:02"
2025-11-11 21:44:20 +08:00
祀梦
5d510b0433 docs: 添加免费大模型API整合文档
添加一篇详细介绍百度千帆、讯飞星火、腾讯混元和SCNet平台免费/低价大模型API的文档
包含各平台API调用示例、价格对比和使用建议
2025-11-11 21:34:46 +08:00
2f55fc7184 docs(web): 添加 JavaScript 基础知识文档
添加 JavaScript 基础知识文档,包含变量、数据类型、运算符、条件语句、循环、函数和 DOM 操作等内容,为初学者提供全面的学习资源
2025-11-10 14:45:12 +08:00
474f335e94 docs(web): 添加HTML列表与语义布局文档
添加关于HTML列表(ul/ol/li)和语义化标签(header/nav/main等)的详细文档,包含基础语法说明、代码示例和练习作业,帮助初学者掌握HTML结构化编写
2025-11-02 20:50:33 +08:00
祀梦
2b9e5f9bd1 docs(web): 修正HTML标签文档中的代码格式和描述
统一使用反引号标记HTML标签,提高文档可读性和一致性
2025-11-02 20:43:42 +08:00
祀梦
43aa3f07e5 Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-11-02 20:32:39 +08:00
祀梦
c3e8cad947 ci: 添加构建和发布文档的批处理脚本
添加 build-and-publish.bat 脚本用于自动化文档构建和发布流程,包含依赖安装、构建、Git仓库更新和发布功能
2025-11-02 20:32:34 +08:00
b7c97d0f17 docs(web): 添加div标签和class属性的详细说明
扩展HTML文档,新增关于div标签和class属性的详细解释和使用示例,包括:
- div标签的基本特点和用途
- class属性的作用和实际应用场景
- 相关代码示例和练习作业
2025-11-02 20:21:36 +08:00
2391018d79 chore: 更新mermaid依赖至11.12.1并删除过时文档
删除html2.md文档并简化html-tags-attributes.md内容
2025-11-02 19:59:19 +08:00
祀梦
b28ed8ebfe docs(web): 添加HTML常用标签与属性文档
新增HTML常用标签与属性的详细教程文档,包含基础标签使用、语义化布局、媒体元素等内容,并附带示例代码和练习作业
2025-11-02 19:44:44 +08:00
799551073c docs(web): 添加HTML基础语法第二课文档
新增HTML基础语法第二课文档,介绍div标签和class属性的基本概念及用法
2025-11-02 19:13:40 +08:00
祀梦
3f8169ae56 Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-29 22:12:23 +08:00
祀梦
8c7e8ea6e3 docs(cryptography): 添加置换密码文档并更新导航配置
添加关于古典加密算法中置换密码的详细文档,包括栅栏密码和列移位置换的工作原理、数学表示及安全性分析。同时更新笔记导航配置以包含新文档链接。

新增信创竞赛环境搭建指南文档,包含系统配置要求和详细操作步骤。
2025-10-29 22:12:12 +08:00
669f62549e Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-29 14:10:04 +08:00
c95b09f329 docs(notes): 修改文档标题为"仲夏夜之梦"
更新HTML示例中的文档标题,从"祀梦的花园"改为"仲夏夜之梦",保持文档内容的一致性
2025-10-29 14:09:59 +08:00
祀梦
868cc9b514 docs(密码学): 添加基础概念与术语章节和现代密码简述
为初学者添加密码学核心概念解释,包括明文/密文、加密/解密、密钥类型等基础术语。同时补充现代密码学中对称加密、非对称加密和数字签名的简要说明,帮助建立基本认知框架。
2025-10-29 13:45:37 +08:00
祀梦
60b9923302 Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-29 11:46:37 +08:00
祀梦
4db01489ee 测试新的编译脚本 2025-10-29 11:46:35 +08:00
c365afbd8a 更改首页信息 2025-10-29 11:35:44 +08:00
祀梦
b860b75dc8 docs: 移除contributors配置的注释
清理不再需要的注释以保持代码整洁

主要是测试服务器端的新的部署脚本
2025-10-29 09:49:07 +08:00
祀梦
a037e09c17 docs: 移除配置文件中冗余的注释
清理了VuePress配置文件中的注释,保持配置简洁
2025-10-29 09:43:01 +08:00
祀梦
faac3d94ff docs: 更新友链列表和网站标题
- 在friends.md中添加小小夏的友链信息
- 将网站标题从"祀梦的花园"改为"仲夏夜之梦"
2025-10-29 09:27:42 +08:00
祀梦
09ce0b7b78 docs(web): 更新Web开发学习笔记内容与结构
重构README文档,扩展Web开发概览内容并添加学习路径
- 重新组织文档结构,增加基础概念解释
- 添加前后端协作流程说明
- 提供详细学习路径与资源推荐
- 更新创建时间与标题以反映内容变化
2025-10-28 23:43:05 +08:00
祀梦
95de5b4d3e docs(web): 添加web开发学习笔记及配置
添加web开发学习笔记目录及相关文档,包括HTML/CSS/JavaScript基础知识讲解和练习示例。同时更新vuepress配置以支持新内容:
1. 新增web开发导航栏入口
2. 添加web笔记模块配置
3. 启用demo插件支持
2025-10-28 23:27:00 +08:00
祀梦
7b04ffbedd docs(英语语法): 完善核心语法与句型文档内容
添加详细的语法知识点,包括时态语态、从句分类、非谓语动词、倒装虚拟等核心内容,以及句式分析和长难句拆解策略
2025-10-27 19:55:57 +08:00
祀梦
c51e0977d7 docs(blog): 移除文档中的密码注释并设置实际密码
将文档中的密码字段从注释状态改为实际设置状态,以便保护相关内容
2025-10-27 19:38:35 +08:00
祀梦
7e1131844f Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-27 19:29:43 +08:00
祀梦
566b6cd385 feat(docs): 添加密码学基础文档和mermaid支持
新增密码学基础文档,包含古典加密算法和现代密码学介绍
添加mermaid图表支持以展示密码学概念
在导航栏新增技术理论分类
更新package.json添加mermaid依赖
2025-10-27 19:29:40 +08:00
12181dbdcd 日期 2025-10-27 14:55:53 +08:00
02ec95b12d Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-27 14:43:05 +08:00
e097e53603 修改phonics和文章 2025-10-27 14:42:57 +08:00
f3dda6078c 更新新文章以及phonics 2025-10-27 14:42:29 +08:00
祀梦
5dba6ac5b4 docs: 完善安装指南并增强启动脚本功能
- 扩展 README.md 中的安装说明,增加环境要求、详细步骤和常见问题排查
- 重写 start.bat 脚本,支持参数化配置并添加多重回退机制
- 优化开发服务器启动流程,提升不同环境下的兼容性
2025-10-22 16:26:29 +08:00
d7d342fd55 更新每日英语读物 2025-10-22 13:00:56 +08:00
b734f403b3 拆分阅读和写作模块 2025-10-22 11:13:21 +08:00
祀梦
086835d409 docs(solidity): 更新memory和storage存储类型的文档
补充关于Solidity中memory和storage存储类型的详细说明,包括生命周期、成本、默认行为、拷贝语义、内部函数引用传递、动态数组限制等内容。添加代码示例和最佳实践建议,帮助开发者更好地理解和使用不同存储类型。
2025-10-20 20:25:23 +08:00
祀梦
69312a780e feat(english): 添加英语学习笔记文档和导航配置
添加英语学习相关文档,包括基础配置、词汇、语法、听说读写等模块
更新导航栏和侧边栏配置以支持英语学习笔记
修改首页标题和描述以更符合内容定位
2025-10-20 19:55:15 +08:00
祀梦
b3b5198eac docs: 更新关于页面中的欢迎语
将欢迎语从"泥嚎~"改为更常见的"嗨~",使语气更加自然友好
2025-10-20 14:41:24 +08:00
祀梦
771fa51fb9 docs(solidity): 修正hardhat初始化命令的拼写错误
将`--init`改为正确的`init`命令
2025-10-17 23:32:49 +08:00
祀梦
90ed801658 Merge branch 'main' of https://gitea.simengweb.com/si-meng-spec/SiMengWebSite_Notes 2025-10-14 15:39:37 +08:00
祀梦
f0e768d66f 更新 2025-10-14 15:39:08 +08:00
祀梦
6a508cc8d4 更新文章 2025-10-14 15:38:57 +08:00
祀梦
6ac5000c86 更新文章 2025-10-11 23:48:28 +08:00
祀梦
df01754706 更新文章 2025-10-10 17:33:17 +08:00
祀梦
7e413866c2 文章更新 2025-10-10 10:54:35 +08:00
95dc8fecf9 更新文章 2025-10-05 17:43:04 +08:00
38 changed files with 5837 additions and 203 deletions

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@ docs/.vuepress/dist
.trae/ .trae/
.DS_Store .DS_Store
*.log *.log
_publish/

View File

@@ -22,10 +22,42 @@
## 安装 ## 安装
确保您的 Node.js 版本符合要求(^20.6.0 || >=22.0.0),然后执行以下命令 - 环境要求
- Node.js`^20.6.0``>=22.0.0`(推荐使用当前 LTS 或稳定版)
- npm`>=10`
- 安装步骤:
1. 在项目根目录执行依赖安装:
```sh ```sh
npm i npm install
```
2. 启动开发服务器(任选其一):
- 常规方式:
```sh
npm run docs:dev
```
- Windows 快捷方式(尝试监听 `0.0.0.0` 以便局域网访问):
```bat
.\start.bat
```
- 若端口或权限受限,使用备用命令(绑定到本机并更换端口):
```sh
npx vuepress@2.0.0-rc.24 dev docs --port 5173 --host localhost
```
3. 打开浏览器访问:
- `http://localhost:4567/`(默认)或
- `http://localhost:5173/`(如果使用备用命令)
- 常见问题与排查:
- “`vuepress` 不是内部或外部命令”:通常为依赖未安装或安装失败,执行 `npm install` 后重试。
- “listen EACCES: permission denied 0.0.0.0:4567”端口或绑定权限受限改用 `--host localhost` 或更换端口(如 `--port 5173`)。
- 需要清理缓存后重试:
```sh
npm run docs:dev-clean
```
- 更换端口示例(以 8080 为例):
```sh
npx vuepress dev docs --port 8080 --host localhost
``` ```
## 使用 ## 使用

133
build-and-publish.bat Normal file
View File

@@ -0,0 +1,133 @@
@echo off
setlocal EnableExtensions
chcp 65001 >nul
REM Paths and settings
set "ROOT_DIR=%~dp0"
set "PROJECT_DIR=%ROOT_DIR%"
set "DIST_DIR=%PROJECT_DIR%docs\.vuepress\dist"
set "PUBLISH_DIR=%PROJECT_DIR%_publish"
set "REMOTE_URL=https://gitea.simengweb.com/si-meng-spec/build_notes_simengweb.git"
set "BRANCH=main"
REM Args
set "LIGHT_FLAG=%~1"
set "COMMIT_MSG=%~2"
echo [Info] Working dir: %PROJECT_DIR%
REM Pre-checks
where npm >nul 2>&1
if errorlevel 1 goto :npm_missing
where git >nul 2>&1
if errorlevel 1 goto :git_missing
REM Install deps on first run
if not exist "%PROJECT_DIR%node_modules" (
echo [Info] Installing deps ^(npm ci^)...
call npm ci
if errorlevel 1 goto :fail
) else (
echo [Info] node_modules exists, skip install.
)
REM Light build mode
if /I "%LIGHT_FLAG%"=="light" (
set "LIGHT_BUILD=1"
echo [Info] LIGHT_BUILD=1 enabled
)
set "NODE_OPTIONS=--max-old-space-size=4096"
echo [Info] Building docs...
call npm run docs:build
if errorlevel 1 goto :fail
if not exist "%DIST_DIR%" goto :no_dist
REM Prepare publish repo
if not exist "%PUBLISH_DIR%\.git" (
echo [Info] Cloning publish repo...
git clone "%REMOTE_URL%" "%PUBLISH_DIR%"
if errorlevel 1 goto :fail
) else (
echo [Info] Updating publish repo...
pushd "%PUBLISH_DIR%"
git fetch --all
if errorlevel 1 goto :gitfail
git checkout "%BRANCH%"
if errorlevel 1 goto :gitfail
git reset --hard "origin/%BRANCH%"
if errorlevel 1 goto :gitfail
popd
)
echo [Info] Cleaning publish directory ^(keep .git^)...
pushd "%PUBLISH_DIR%"
for /f "delims=" %%F in ('dir /a /b') do (
if /I not "%%F"==".git" (
if exist "%%F" (
attrib -R "%%F" >nul 2>&1
rd /s /q "%%F" 2>nul
del /f /q "%%F" 2>nul
)
)
)
popd
echo [Info] Copying dist to publish...
robocopy "%DIST_DIR%" "%PUBLISH_DIR%" *.* /E /NFL /NDL /NP /NJH /NJS >nul
if errorlevel 8 goto :fail
pushd "%PUBLISH_DIR%"
if defined GIT_USERNAME git config user.name "%GIT_USERNAME%"
if defined GIT_EMAIL git config user.email "%GIT_EMAIL%"
git add -A
if "%COMMIT_MSG%"=="" set "COMMIT_MSG=Build: %DATE% %TIME%"
set "HAS_CHANGES=1"
git diff --cached --quiet
if not errorlevel 1 set "HAS_CHANGES=0"
if "%HAS_CHANGES%"=="0" (
echo [Info] No changes to commit; skipping push.
) else (
git commit -m "%COMMIT_MSG%"
if errorlevel 1 (
popd
goto :fail
)
git push origin "%BRANCH%"
if errorlevel 1 (
popd
goto :fail
)
echo [Info] Pushed to %REMOTE_URL% ^(branch %BRANCH%^).
)
popd
echo [Success] Build and publish done.
exit /b 0
:npm_missing
echo [ERROR] npm not found. Please install Node.js.
goto :fail
:git_missing
echo [ERROR] git not found. Please install Git.
goto :fail
:no_dist
echo [ERROR] Dist directory not found: %DIST_DIR%
goto :fail
:gitfail
echo [ERROR] Git operation failed.
popd
goto :fail
:fail
exit /b 1

View File

@@ -7,21 +7,30 @@ import { umamiAnalyticsPlugin } from '@vuepress/plugin-umami-analytics'
export default defineUserConfig({ export default defineUserConfig({
base: '/', base: '/',
lang: 'zh-CN', lang: 'zh-CN',
title: '祀梦的花园', title: '仲夏夜之梦',
description: '爱与回忆的小世界,记录生活中的每一份温暖与感动', description: '爱与回忆的小世界,记录生活中的每一份温暖与感动',
head: [ head: [
// 配置站点图标
['link', { rel: 'icon', type: 'image/png', href: 'https://theme-plume.vuejs.press/favicon-32x32.png' }], ['link', { rel: 'icon', type: 'image/png', href: 'https://theme-plume.vuejs.press/favicon-32x32.png' }],
], ],
bundler: viteBundler(), bundler: viteBundler(),
shouldPrefetch: false, // 站点较大,页面数量较多时,不建议启用 shouldPrefetch: false,
theme: plumeTheme({ theme: plumeTheme({
/* 站点域名,启动 SEO 优化 */
hostname: 'https://notes.simengweb.com',
/* 博客文章页面链接前缀 */ /* 博客文章页面链接前缀 */
article: '/article/', article: '/article/',
/* 启用数学公式支持和Mermaid图表 */
markdown: {
math: {
type: 'katex',
},
mermaid: true,
demo: true,
},
/** /**
* 编译缓存,加快编译速度 * 编译缓存,加快编译速度
*/ */
@@ -44,7 +53,6 @@ export default defineUserConfig({
/** /**
* 文章贡献者配置 * 文章贡献者配置
*/ */
// 修改contributors配置
contributors: { contributors: {
mode: 'inline', mode: 'inline',
info: [ info: [
@@ -64,9 +72,6 @@ export default defineUserConfig({
git: true git: true
}, },
/**
* 代码块配置
*/
codeHighlighter: { codeHighlighter: {
lineNumbers: true, lineNumbers: true,
} }

View File

@@ -9,6 +9,15 @@ export default defineNavbarConfig([
text: '博客', text: '博客',
link: '/blog/', link: '/blog/',
}, },
{
text: '学科知识',
items: [
{
text: '英语学习笔记',
link: '/subject/english/',
},
],
},
{ {
text: '编程笔记', text: '编程笔记',
items: [ items: [
@@ -24,8 +33,21 @@ export default defineNavbarConfig([
text: 'Solidity', text: 'Solidity',
link: '/programming/solidity/', link: '/programming/solidity/',
}, },
{
text: 'Web 开发',
link: '/programming/web/',
}
], ],
}, },
{
text:"技术理论",
items:[
{
text: '密码学基础',
link: '/theory/cryptography/',
},
]
},
{ {
text: '运维', text: '运维',
items: [ items: [

View File

@@ -27,6 +27,53 @@ const cPlusPlus = defineNoteConfig({
} }
] ]
}) })
const english = defineNoteConfig({
dir: 'subject',
link: '/subject/english/',
sidebar: [
{ text: "英语学习笔记", link: "/subject/english/" },
{
text: "学习环境与工具", prefix: "/basis", items: [
{ text: "英语环境配置", link: "/subject/english/basis/" }
]
},
{
text: "词汇与记忆", prefix: "/vocabulary", items: [
{ text: "词汇学习与记忆法", link: "/subject/english/vocabulary/" }
]
},
{
text: "语法与句法", prefix: "/grammar", items: [
{ text: "核心语法与句型", link: "/subject/english/grammar/" }
]
},
{
text: "听力与口语", prefix: "/listening-speaking", items: [
{ text: "听力口语训练", link: "/subject/english/listening-speaking/" }
]
},
{
text: "阅读与写作", prefix: "/reading-writing", items: [
{ text: "阅读提升", link: "/subject/english/reading-writing/" }
]
},
{
text: "写译", prefix: "/writing-translation", items: [
{ text: "写作与翻译指南", link: "/subject/english/writing-translation/" }
]
},
{
text: "考试与备考", prefix: "/exam", items: [
{ text: "英语四级 (CET-4) 备考指南", link: "/subject/english/exam/cet-4/" }
]
},
{
text: "资源与工具", prefix: "/resources", items: [
{ text: "学习资源与工具", link: "/subject/english/resources/" }
]
}
]
})
const solidity = defineNoteConfig({ const solidity = defineNoteConfig({
dir: 'programming', dir: 'programming',
link: '/programming/solidity/', link: '/programming/solidity/',
@@ -35,10 +82,34 @@ const solidity = defineNoteConfig({
{ {
text: "基础语法", prefix: "/basic-syntax", items: [ text: "基础语法", prefix: "/basic-syntax", items: [
{ text: "Solidity 基础语法与数据类型", link: "/programming/solidity/basic-syntax/" } { text: "Solidity 基础语法与数据类型", link: "/programming/solidity/basic-syntax/" }
] ],
},
{
text: "项目实例", prefix: "/basic-syntax", items: [
{ text: "Solidity 代码实例", link: "/programming/solidity/analysis/case-analysis/" }
],
},
{
text: "杂项", prefix: "/other", items: [
{ text: "Hardhat 相关知识", link: "/programming/solidity/other/hardhat/" },
{ text: "一些没分类的小知识", link: "/programming/solidity/other/miscellaneous/" }
],
} }
] ]
}) })
const cryptography = defineNoteConfig({
dir: 'theory',
link: '/theory/cryptography/',
sidebar: [
{ text: "密码学基础", link: "/theory/cryptography/" },
{
text: "古典加密算法", prefix: "/theory", items: [
{ text: "替换密码", link: "/theory/cryptography/substitution-ciphers/" },
{ text: "置换密码", link: "/theory/cryptography/permutation-encryption/" },
]
},
]
})
const blockchain = defineNoteConfig({ const blockchain = defineNoteConfig({
dir: 'ops', dir: 'ops',
link: '/ops/blockchain', link: '/ops/blockchain',
@@ -71,11 +142,26 @@ const linux = defineNoteConfig({
} }
] ]
}) })
const web = defineNoteConfig({
dir: 'programming',
link: '/programming/web/',
sidebar: [
{ text: "Web 开发学习笔记", link: "/programming/web/" },
{
text: "基础知识", prefix: "/basic-syntax", items: [
{ text: "Web 前端基础讲解", link: "/programming/web/basic-syntax/html-css-js/" },
{ text: "HTML 常用标签与属性", link: "/programming/web/basic-syntax/html-tags-attributes/" },
{ text: "HTML 列表与语义布局", link: "/programming/web/basic-syntax/html-lists-and-semantic-layout/" },
{ text: "JavaScript 基础知识", link: "/programming/web/basic-syntax/javascript-basics/" },
],
},
]
})
/** /**
* 导出所有的 note * 导出所有的 note
*/ */
export default defineNotesConfig({ export default defineNotesConfig({
dir: 'notes', dir: 'notes',
link: '/', link: '/',
notes: [LeetCode, cPlusPlus, solidity, blockchain, linux], notes: [LeetCode, english, cPlusPlus, solidity, blockchain, linux, cryptography, web],
}) })

View File

@@ -7,16 +7,12 @@ config:
full: true full: true
background: tint-plate background: tint-plate
hero: hero:
name: 祀梦的花园 name: 仲夏夜之梦
tagline: 爱与回忆的小世界 tagline: 祀梦和小小夏的花园
text: 在这里,每一个文字都承载着温暖与美好 🌸 text: 在这里,每一个文字都承载着温暖与美好 🌸
actions: actions:
- -
theme: brand theme: brand
text: 博客 text: 博客
link: /blog/ link: /blog/
-
theme: alt
text: 探索笔记 →
link: /notes/
--- ---

View File

@@ -9,7 +9,7 @@ permalink: /about/
# 👋 这里是祀梦的小窝! # 👋 这里是祀梦的小窝!
泥嚎~ 欢迎来到祀梦的个人博客,这是我在这个小站发布的第一篇文章哦~ (✧ω✧) ~ 欢迎来到祀梦的个人博客,这是我在这个小站发布的第一篇文章哦~ (✧ω✧)
## 关于站长我呀~ 🌸 ## 关于站长我呀~ 🌸

View File

@@ -0,0 +1,249 @@
---
title: 便宜免费的大模型 API 整合 2025年11月11日
createTime: 2025/11/11 13:54:02
permalink: /article/free_model_api/
---
## 免费的大模型 API 整合
嗨~如果你在找既温柔又省荷包的小模型,就把它们悄悄收进这里吧!它们也许不是夜空最亮的那颗星,却能在摘要、划重点、轻声问答的小角落里,给你软软又稳稳的陪伴哦~
### 百度千帆大模型平台
先从千帆开始吧~下面是常用模型的参考价格:
| 模型名称 | 版本名称 | 服务内容 | 子项 | 在线推理 | 批量推理 | 单位 |
|---|---|---|---|---|---|---|
| ERNIE Speed | ernie-speed-128k | 推理服务 | 输入 | 0 | 0.00012 | 元/千tokens |
| ERNIE Speed | ernie-speed-128k | 推理服务 | 输出 | 0 | 0.00024 | 元/千tokens |
| ERNIE Lite | ernie-lite-8k | 推理服务 | 输入 | 0 | 0.0012 | 元/千tokens |
| ERNIE Lite | ernie-lite-8k | 推理服务 | 输出 | 0 | 0.0024 | 元/千tokens |
| ERNIE Tiny | ernie-tiny-8k | 推理服务 | 输入 | 0 | 0.00008 | 元/千tokens |
| ERNIE Tiny | ernie-tiny-8k | 推理服务 | 输出 | 0 | 0.00016 | 元/千tokens |
> 提示:单纯调用 API 接口属于在线推理,当前显示为 0 元;批量推理按量计费。
#### 快速上手
1. 访问控制台并获取 API Key。
2. 使用下方示例进行快速测试。
3. 若遇错误,请检查模型名称与凭证有效期。
控制台:[https://console.bce.baidu.com/qianfan/ais/console/apiKey](https://console.bce.baidu.com/qianfan/ais/console/apiKey)
```python
import requests
import json
def main():
url = "https://qianfan.baidubce.com/v2/chat/completions"
API_KEY = 'YOUR_API_KEY'
payload = json.dumps({
"model": "ernie-speed-128k",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "你好"
}
]
})
headers = {
'Content-Type': 'application/json',
'Authorization': F'Bearer {API_KEY}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
if __name__ == '__main__':
main()
```
> 小贴士:将 `YOUR_API_KEY` 替换为你的密钥,建议使用环境变量管理凭证;请勿在公共仓库提交 Key。
更多文档:[https://cloud.baidu.com/doc/qianfan-api/s/3m9b5lqft](https://cloud.baidu.com/doc/qianfan-api/s/3m9b5lqft)
### 讯飞星火大模型
接着,我们轻盈地来到星火~
- 官网:[https://xinghuo.xfyun.cn/sparkapi](https://xinghuo.xfyun.cn/sparkapi)
- 控制台:[https://console.xfyun.cn/services/cbm?from=desk](https://console.xfyun.cn/services/cbm?from=desk)
- 模型说明:可见 Spark LiteToken 余量为无限。
#### 快速上手
> 小贴士:如需联网检索,启用 `web_search`;流式输出可以提升交互体验。
1. 在控制台获取授权凭证并替换到示例中。
2. 选择 `Lite` 模型,按需开启 `web_search``stream`
3. 若需要长内容输出,注意 8K tokens 限制,合理裁剪上下文。
```python
# encoding:UTF-8
import json
import requests
# 请替换XXXXXXXXXX为您的 APIpassword, 获取地址https://console.xfyun.cn/services/bmx1
api_key = "Bearer XXXXXXXXXX"
url = "https://spark-api-open.xf-yun.com/v1/chat/completions"
# 请求模型,并将结果输出
def get_answer(message):
#初始化请求体
headers = {
'Authorization':api_key,
'content-type': "application/json"
}
body = {
"model": "Lite",
"user": "user_id",
"messages": message,
# 下面是可选参数
"stream": True,
"tools": [
{
"type": "web_search",
"web_search": {
"enable": True,
"search_mode":"deep"
}
}
]
}
full_response = "" # 存储返回结果
isFirstContent = True # 首帧标识
response = requests.post(url=url,json= body,headers= headers,stream= True)
# print(response)
for chunks in response.iter_lines():
# 打印返回的每帧内容
# print(chunks)
if (chunks and '[DONE]' not in str(chunks)):
data_org = chunks[6:]
# print(f"DEBUG: raw data_org: {data_org}")
chunk = json.loads(data_org)
text = chunk['choices'][0]['delta']
# 判断最终结果状态并输出
if ('content' in text and '' != text['content']):
content = text["content"]
if (True == isFirstContent):
isFirstContent = False
print(content, end="")
full_response += content
return full_response
# 管理对话历史,按序编为列表
def getText(text,role, content):
jsoncon = {}
jsoncon["role"] = role
jsoncon["content"] = content
text.append(jsoncon)
return text
# 获取对话中的所有角色的content长度
def getlength(text):
length = 0
for content in text:
temp = content["content"]
leng = len(temp)
length += leng
return length
# 判断长度是否超长当前限制8K tokens
def checklen(text):
while (getlength(text) > 11000):
del text[0]
return text
#主程序入口
if __name__ =='__main__':
#对话历史存储列表
chatHistory = []
#循环对话轮次
while (1):
# 等待控制台输入
Input = input("\n" + "我:")
question = checklen(getText(chatHistory,"user", Input))
# 开始输出模型内容
print("星火:", end="")
getText(chatHistory,"assistant", get_answer(question))
```
### 腾讯混元大模型
- 计费与价格:[https://cloud.tencent.com/document/product/1729/97731](https://cloud.tencent.com/document/product/1729/97731)
- 文档与控制台:[https://cloud.tencent.com/document/product/1729/111008](https://cloud.tencent.com/document/product/1729/111008)
- 模型说明:`hunyuan-lite` 免费可用,适合轻量任务。
```python
import os
from openai import OpenAI
# 构造 client建议使用环境变量管理密钥
api_key = os.getenv("HUNYUAN_API_KEY", "YOUR_API_KEY")
client = OpenAI(
api_key=api_key, # 混元 APIKey
base_url="https://api.hunyuan.cloud.tencent.com/v1", # 混元 endpoint
)
completion = client.chat.completions.create(
model="hunyuan-lite",
messages=[
{
"role": "user",
"content": "泥嚎"
}
],
extra_body={
"enable_enhancement": True,
},
)
print(completion.choices[0].message.content)
```
> 小贴士:请勿在公共仓库提交任何真实密钥;使用环境变量或密钥管理服务更安全。
## 低价大模型
### SCNet 平台
#### 简介
SCNet 是一个面向人工智能和科学计算的一站式算力与 AI 平台,提供从数据管理、模型训练到部署的完整链路服务,同时结合国产超算硬件和多模态模型生态,让企业和开发者能更高效地使用 AI。
#### 链接与文档
- 官网:[https://www.scnet.cn/](https://www.scnet.cn/)
#### 价格一览
| 模型 | 上下文长度 | 百万 tokens 输入价格 | 百万 tokens 输出价格 |
|---|---|---|---|
| Qwen3-235B-A22B | 32K | 0.1 元 | 0.1 元 |
| DeepSeek-R1-Distill-Qwen-7B | 32K | 0.1 元 | 0.1 元 |
| DeepSeek-R1-Distill-Qwen-32B | 32K | 1 元 | 4 元 |
| DeepSeek-R1-Distill-Llama-70B | 32K | 0.1 元 | 6 元 |
| QwQ-32B | 32K | 1 元 | 4 元 |
| Qwen3-30B-A3B | 128K | 1 元 | 6 元 |
| Qwen3-Embedding-8B | - | 0.1 元 | - |
- 文档(计费与说明):[https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/modulefee.html](https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/modulefee.html)
目前看到的价格最低的 Qwen3-235B-A22B 模型的 API相比前面的免费模型性能更强。
- API 接口使用样例:[https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/apicall.html](https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/apicall.html)
## 小结
把上面这些“零钱包”级别的模型都翻完啦~
- 百度千帆、讯飞星火、腾讯混元都给出「免费在线额度」,日常轻量问答、摘要、润色完全够用;记得把 Key 藏进环境变量,别手滑推到 GitHub。
- 如果任务量突然暴涨SCNet 的 Qwen3-235B-A22B 只要 0.1 元/百万 tokens性价比直接拉满当“备胎”也安心。
一句话:先薅免费的,薅不动再掏 0.1 元,让荷包和模型一起“稳稳幸福”吧!

View File

@@ -2,7 +2,7 @@
title: 2025 一带一路金砖 - 区块链应用开发与运维 样题详解 title: 2025 一带一路金砖 - 区块链应用开发与运维 样题详解
createTime: 2025/09/30 19:57:14 createTime: 2025/09/30 19:57:14
permalink: /article/2025-BR-BRICS-BC-App-Develop-Op-Sample-Q&A/ permalink: /article/2025-BR-BRICS-BC-App-Develop-Op-Sample-Q&A/
# password: simeng password: simeng
--- ---
## 第一部分:区块链平台运维 ## 第一部分:区块链平台运维

View File

@@ -0,0 +1,75 @@
---
title: Linux 系统适配环境搭建
createTime: 2025/10/29 15:39:35
permalink: /article/xinchuang-competition-2025/
password: simeng
---
## 赛题要求
- yum 仓库地址http://192.168.122.1:58000/content
- 软件包下载地址http://192.168.122.1:58000/software
系统信息列表
| 序号 | 标签名称 | 操作系统 | 账号信息 |
|----|---------|----------|----------|
| 1 | Server1 | openEuler 22.03(已安装) | root / openEuler12#$ |
| 2 | Server2 | openEuler 22.03(已安装) | root / openEuler12#$ |
| 3 | Server3 | openEuler 22.03(待安装) | N/A |
| 4 | Desktop | Kylin v10已安装 | admin / admin@0000 |
## 第一部分 【适配环境搭建】
### 基础配置 yum 源
这里题目中没有提到,但是需要进行一下配置
### 系统安装与配置
为 Server3 安装 openEuler 操作系统
配置系统语言English
配置系统时区Asia/Shanghai
配置安装类型Server
系统启动分区保持不变,其他分区要求如下:
位置 容量 文件系统
| 挂载点 | 容量 | 文件系统 |
|--------|------|----------|
| / | 剩余所有容量 | ext4 |
| swap | 4G | swap |
| /opt | 40G | xfs |
其他未提及的配置内容保持系统默认设置。
确认并且配置服务器地址及名称:
| 服务器 | FQDN | IP |
|---------|-----------------------|------------------|
| Server1 | app1.system.org.cn | 172.16.50.101/24 |
| Server2 | app2.system.org.cn | 172.16.50.102/24 |
| Server3 | sts.system.org.cn | 172.16.50.103/24 |
| Desktop | - | 172.16.50.111/24 |
```bash title='配置服务器地址以及名称'
hostnamectl
```
确认并且配置系统网关为 172.16.50.1,确保服务器能与网关通信。
为所有 Server 主机启用防火墙,防火墙区域为 public ,根据不同服务在防火墙中使用添加端口的方式添加策略。
确认并且保持 root 用户密码为admin@0000,确保该账户能够通过 SSH 远程登录
为所有 Server 主机生成 2 组RSA 算法和国密算法SSH 公私钥对,其中 RSA 密钥长度为 4096。配置实现 Server 主机之间的 SSH 免密登录。
所有主机间的访问均通过 FQDN 的形式进行访问。
使用 chrony 进行时间同步。Server1 与 172.16.50.1 进行时间同步,同时为其他服务器提供时间服务。
## 第一部分
## 第一部分
## 第一部分

View File

@@ -22,4 +22,9 @@ list:
link: https://www.ajohn.top/ link: https://www.ajohn.top/
avatar: https://github.com/zzyAJohn.png avatar: https://github.com/zzyAJohn.png
desc: 我希望正在读这句话的人永远开心 desc: 我希望正在读这句话的人永远开心
-
name: 小小夏
link: https://notes.simengweb.com
avatar: https://image.simengweb.com/images/xxx.jpg
desc: Kawasaki天下第一
--- ---

View File

@@ -1,5 +1,5 @@
--- ---
title: fisco-bcos-node-type title: 区块链的节点
createTime: 2025/10/05 13:07:05 createTime: 2025/10/05 13:07:05
permalink: /ops/blockchain/theory/fisco-bcos-node-type/ permalink: /ops/blockchain/theory/fisco-bcos-node-type/
--- ---

View File

@@ -7,3 +7,15 @@ permalink: /programming/solidity/
## Solidity 智能合约概述 ## Solidity 智能合约概述
Solidity 是一种用于编写智能合约的静态类型编程语言它运行在以太坊虚拟机EVM上。
## 推荐的资料
推荐的编辑器
Remix IDE[https://remix.ethereum.org/](https://remix.ethereum.org/)
有在线版本,也可以下载之后使用,而且可以通过 Docker 部署,很方便
Solidity 学习资料:
- [Solidity 官方文档](https://docs.soliditylang.org/zh-cn/latest/index.html)
- [cryptozombies](https://cryptozombies.io/zh/course)

View File

@@ -6,180 +6,83 @@ permalink: /programming/solidity/basic-syntax/
# Solidity 基础语法与数据类型~(≧∇≦)ノ # Solidity 基础语法与数据类型~(≧∇≦)ノ
嗨~欢迎来到 Solidity 基础语法的学习时间!今天我们要一起探索 Solidity 这门神奇语言的基本结构和数据类型哦准备好了吗Let's go(๑>◡<) ## Solidity 文件基础框架
## 智能合约的基本结构 🏗️ Solidity 文件的基础框架通常包含以下几个部分:
让我们先来看一个最简单的 Solidity 智能合约是什么样子的吧 1. **SPDX 许可证标识符 (SPDX License Identifier)**:为了避免法律问题和明确智能合约的开源许可证,建议在合约的开头添加 SPDX 许可证标识符。
2. **Solidity 版本声明 (Pragma)**:这会告诉编译器您希望使用哪个版本的 Solidity 来编译您的代码。
3. **ABI编码编译指示**:通过`pragma abicoder v1``pragma abicoder v2`来指定ABI编码版本。
4. **合约定义 (Contract Definition)**:这是您编写智能合约代码的主体部分。
下面是一个基础的 Solidity 文件框架示例,您可以直接使用:
```solidity ```solidity
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.20;
pragma experimental ABIEncoderV2;
contract HelloWorld {
// 状态变量
string public greeting = "Hello, World!";
// 函数
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
function getGreeting() public view returns (string memory) {
return greeting;
}
}
```
是不是看起来有点像其他编程语言呀让我们来一点一点地了解它吧
## 版本声明和许可证 📜
Solidity 合约的最开始我们需要添加两行重要的声明
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
```
- **许可证声明**告诉别人你的代码使用什么许可证可以自由使用吗
- **版本声明**指定合约使用的 Solidity 编译器版本`^0.8.0` 表示可以使用 0.8.0 及以上的版本哦
## 数据类型 🌈
Solidity 有很多有趣的数据类型让我们来认识一下它们吧
### 值类型
这些类型在赋值时会直接复制值哦
#### 布尔型 (Boolean)
```solidity
bool public isActive = true;
bool public isPaused = false;
```
布尔型只有两个值`true` `false`就像开关一样简单(˘˘)
#### 整型 (Integer)
```solidity
int public negativeNumber = -42;
uint public positiveNumber = 42;
// 你还可以指定位数哦~
uint8 public smallNumber = 255; // 0-255
uint256 public bigNumber = 1000000000000000000; // 这是 1 以太币的 wei 值哦~
```
整型分为有符号`int`和无符号`uint`两种可以存储正数和负数呢
#### 地址型 (Address)
```solidity
address public owner = 0x71C7656EC7ab88b098defB751B7401B5f6d8976F;
// 可以转账的地址类型
address payable public recipient = payable(0x71C7656EC7ab88b098defB751B7401B5f6d8976F);
```
地址类型非常特别它用于存储以太坊账户的地址就像是账户的身份证号码一样`address payable` 还可以接收以太币转账呢
### 引用类型
这些类型在赋值时只会传递引用而不是复制整个值哦
#### 字符串 (String)
```solidity
string public message = "Hello, Solidity!";
string public name = "祀梦";
```
字符串用于存储文本数据就像你平时写的便签一样
#### 数组 (Array)
```solidity
// 固定大小的数组
uint[5] public fixedArray = [1, 2, 3, 4, 5];
// 动态大小的数组
uint[] public dynamicArray;
// 你还可以在函数中这样使用哦~
function addNumber(uint _number) public {
dynamicArray.push(_number);
}
```
数组就像是一个收纳盒可以按顺序存放多个相同类型的数据呢
#### 映射 (Mapping)
```solidity
// 映射:地址 => 余额
mapping(address => uint) public balances;
// 使用方式
function deposit() public payable {
balances[msg.sender] += msg.value;
}
```
映射是 Solidity 中非常强大的数据结构就像是一个魔法字典可以通过键快速找到对应的值
## 变量作用域 🔍
Solidity 变量有不同的作用域哦
### 状态变量
```solidity
contract MyContract { contract MyContract {
// 状态变量:存储在区块链上的 // 在这里编写您的合约代码
uint public myStateVariable = 42;
} }
``` ```
状态变量是存储在区块链上的所有合约函数都可以访问它们就像是合约的公共记忆一样 ## Solidity 基础数据类型
### 局部变量 - 布尔类型bool值为 `true``false`
- 运算符:`!`(逻辑非)、`&&`(逻辑与)、`||`(逻辑或)、`==`(等于)、`!=`(不等于)
- 整形int/uint
- 有符号整数int可以表示负数和零。
- 无符号整数uint只能表示非负数。
- 整数类型可以是8位、16位、32位、64位或256位。只要是八的倍数都可以
- 例如:`int8``uint256`等。
- 运算符:
- 比较运算符:`<=`,`<`,`>=`,`>`
- 位运算符:`&`(按位与)、`|`(按位或)、`^`(按位异或)、`~`(按位取反)
- 移位运算符:`<<`(左移)、`>>`(右移)
- 算数运算符:`+`(加法)、`-`(减法)、`*`(乘法)、`/`(除法)、`%`(取余)
- 对于一个整数类型`X`,可以使用`type(X).min``type(X).max`来获取其最小值和最大值。
## Solidity 基础语法结构
## Solidity 基础操作
### 导入其他源文件
Solidity 支持导入其他源文件,使用`import`语句。例如:
```solidity ```solidity
function myFunction() public { import "filename.sol";
// 局部变量:只在函数内部可见
uint myLocalVariable = 100;
}
``` ```
局部变量只在定义它们的函数内部可见函数执行结束后就会消失哦 这将导入`filename.sol`文件中的合约代码。
### 全局变量 还可以创建一个新的全局符号
```solidity ```solidity
function getSender() public view returns (address) { import * as NewName from "filename.sol"
// msg.sender 是一个全局变量,包含当前调用者的地址
return msg.sender;
}
``` ```
全局变量是 Solidity 内置的特殊变量可以在任何地方使用它们提供了关于区块链和交易的重要信息呢 这将创建一个新的全局符号`NewName`,您可以在合约中使用它来引用`filename.sol`文件中的合约,例如`NewName.ContractName`
## 小练习 🏋️‍♀️ 还可以在导入的同时重命名符号:`import {symbol1 as alias, symbol2} from "filename";`
现在让我们来做一个小练习吧试着编写一个简单的计数器合约包含以下功能 ### 注释
1. 一个状态变量来存储计数值 Solidity 支持两种类型的注释:
2. 一个函数来增加计数
3. 一个函数来减少计数
4. 一个函数来获取当前计数值
你可以做到吗相信自己你一定可以的(̀ㅂ́)و 1. **行注释**:使用`//`来注释单行代码。
2. **块注释**:使用`/*``*/`来注释多行代码。
## 写在最后~💌 例如:
今天我们学习了 Solidity 的基础语法和数据类型这些都是构建智能合约的基石哦虽然一开始可能会觉得有点复杂但只要多练习你一定会越来越熟练的下节课我们将学习 Solidity 的函数和修饰器敬请期待吧 ```solidity
// 这是一个行注释
如果有任何问题欢迎随时提问哦让我们一起在区块链的世界里快乐地探索吧( 3 ̄) /*
这是一个
块注释
*/
```

View File

@@ -0,0 +1,922 @@
---
title: 十份代码实例
createTime: 2025/10/10 11:07:11
permalink: /programming/solidity/analysis/case-analysis/
password: simeng
---
## 题目一
原题:
1.食品信息FoodInfoItem的接口编码
1编写食品信息实体的接口完成可溯源食品信息初始化实现可追溯的原始生产商食品信息上链功能
2编写分销商食品上链信息接口根据食品溯源智能合约地址获取分销商上链食品的信息
3编写超市进行食品上链信息的接口根据食品溯源智能合约地址获取超市上链食品信息。
2.食品溯源(Trace)的接口编码
1编写食品溯源智能合约生产商Producer添加食品接口必须生产商才能添加可溯源的食品实现溯源功能
2编写食品溯源智能合约分销商Distributor添加食品接口必须分销商才能添加可溯源的食品实现溯源功能
3编写食品溯源智能合约超市Retailer添加食品接口必须超市才能添加可溯源的食品实现溯源功能
3.角色Role管理的接口编码
1编写食品溯源增加角色接口必须是未增加的角色才能被添加实现添加角色的功能
2编写食品溯源移除角色接口必须是已增加的角色才能被移除实现移除角色的功能
3编写食品溯源角色授权接口必须是授权的角色地址实现角色权限管理功能
::: code-tabs
@tab Distributor.sol
```solidity
pragma solidity ^0.4.25;
import "./Roles.sol";
//中间商角色
contract Distributor {
using Roles for Roles.Role;
event DistributorAdded(address indexed account);
event DistributorRemoved(address indexed account);
Roles.Role private _distributors;
constructor (address distributor ) public {
_addDistributor(distributor);
}
modifier onlyDistributor() {
require(isDistributor(msg.sender), "DistributorRole: caller does not have the Distributor role");
_;
}
function isDistributor(address account) public view returns (bool) {
return _distributors.has(account);
}
function addDistributor(address account) public onlyDistributor {
_addDistributor(account);
}
function renounceDistributor() public {
_removeDistributor(msg.sender);
}
function _addDistributor(address account) internal {
_distributors.add(account);
emit DistributorAdded(account);
}
function _removeDistributor(address account) internal {
_distributors.remove(account);
emit DistributorRemoved(account);
}
}
```
@tab FoodInfoItem.sol
```solidity
pragma solidity >=0.4.22 <0.5.0;
pragma experimental ABIEncoderV2;
//食品信息管理合约
// 1. 保存食品基本信息:时间戳(流转过程中),用户名(流转过程中),用户地址信息(流转过程中),食品质量(流转过程中),食物名称,当前用户名称,质量,状态.
// 2. 对食品基本信息进行初始化
// 3. 实现两个方法:中间商添加食品信息;超市添加食品信息
// 4. 实现显示食品信息的方法
contract FoodInfoItem{
uint[] _timestamp;//①保存食品流转过程中各个阶段的时间戳
string[] _traceName;//②保存食品流转过程各个阶段的用户名
address[] _traceAddress;//③保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
uint8[] _traceQuality;//④保存食品流转过程中各个阶段的质量
string _name;//⑤食品名称
string _currentTraceName;//⑥当前用户名称
uint8 _quality;//⑦质量0=优质 1=合格 2=不合格)
uint8 _status;//⑧状态0:生产 1:分销 2:出售)
address _owner;//⑨初始化owner
constructor (string name, string traceName, uint8 quality, address producer) public {
_timestamp.push(now);
_traceName.push(traceName);
_traceAddress.push(producer);
_traceQuality.push(quality);
_name = name;
_currentTraceName = traceName;
_quality = quality;
_status = 0;
_owner = msg.sender;
}
function addTraceInfoByDistributor(string traceName,address distributor, uint8 quality) public returns(bool) {
require(_status == 0 , "status must be producing");
require(_owner == msg.sender,"only trace contract can invoke")
//②
_timestamp.push(now);
_traceName.push(traceName);
_currentTraceName = traceName;
_traceAddress.push(distributor);
_quality = quality;
//③
//④
_traceQuality.push(_quality);
_status = 1;
return true;
}
function addTraceInfoByRetailer(string traceName,address retailer, uint8 quality) public returns(bool) {
require(_status == 1 , "status must be distributing");
require(_owner == msg.sender,"only trace contract can invoke")
//②
_timestamp.push(now);
_traceName.push(traceName);
_currentTraceName = traceName;
_traceAddress.push(retailer);
_quality = quality;
//③
//④
_traceQuality.push(_quality);
_status = 2;
return true;
}
function getTraceInfo() public constant returns(uint[], string[], address[], uint8[]) {
return(_timestamp, _traceName, _traceAddress, _traceQuality);
}
function getFood() public constant returns(uint, string, string, string, address, uint8) {
return(_timestamp[0], _traceName[0], _name, _currentTraceName, _traceAddress[0], _quality);
}
}
```
@tab Producer.sol
```solidity
pragma solidity ^0.4.25;
import "./Roles.sol";
//生产者角色
contract Producer {
using Roles for Roles.Role;
event ProducerAdded(address indexed account);
event ProducerRemoved(address indexed account);
Roles.Role private _producers;
constructor (address producer) public {
_addProducer(producer);
}
modifier onlyProducer() {
require(isProducer(msg.sender), "ProducerRole: caller does not have the Producer role");
_;
}
function isProducer(address account) public view returns (bool) {
return _producers.has(account);
}
function addProducer(address account) public onlyProducer {
_addProducer(account);
}
function renounceProducer() public {
_removeProducer(msg.sender);
}
function _addProducer(address account) internal {
_producers.add(account);
emit ProducerAdded(account);
}
function _removeProducer(address account) internal {
_producers.remove(account);
emit ProducerRemoved(account);
}
}
```
@tab Retailer.sol
```solidity
pragma solidity ^0.4.25;
import "./Roles.sol";
//零售商角色(超市)
contract Retailer {
using Roles for Roles.Role;
event RetailerAdded(address indexed account);
event RetailerRemoved(address indexed account);
Roles.Role private _retailers;
constructor (address retailer) public {
_addRetailer(retailer);
}
modifier onlyRetailer() {
require(isRetailer(msg.sender), "RetailerRole: caller does not have the Retailer role");
_;
}
function isRetailer(address account) public view returns (bool) {
return _retailers.has(account);
}
function addRetailer(address account) public onlyRetailer {
_addRetailer(account);
}
function renounceRetailer() public {
_removeRetailer(msg.sender);
}
function _addRetailer(address account) internal {
_retailers.add(account);
emit RetailerAdded(account);
}
function _removeRetailer(address account) internal {
_retailers.remove(account);
emit RetailerRemoved(account);
}
}
```
@tab Roles.sol
```solidity
pragma solidity ^0.4.25;
//角色库(管理所有角色地址)
// 1. 实现增加角色地址
// 2. 移除角色地址
// 3. 判断角色地址是否被授权
library Roles {
struct Role {
mapping (address => bool) bearer;
}
function add(Role storage role, address account) internal {
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
function remove(Role storage role, address account) internal {
require(has(role, account), "Roles: account does not have role");
role.bearer[account] = false;
}
function has(Role storage role, address account) internal returns (bool) {
require(account != address(0), "Roles: account is the zero address");
return role.bearer[account];
}
}
```
@tab Trace.sol
```solidity
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2;
import "./FoodInfoItem.sol";
import "./Distributor.sol";
import "./Producer.sol";
import "./Retailer.sol";
//食品溯源合约(负责具体食品溯源信息的生成)
// 1.实现生产食品的方法(新建食品信息)
// 2.实现食品分销过程中增加溯源信息的接口
// 3.实现食品出售过程中增加溯源信息的接口
// 4.实现获取食品溯源信息接口
contract Trace is Producer, Distributor, Retailer{
mapping (uint256 => address) foods;//食品溯源id到具体食品溯源合约的映射表
uint[] foodList;
//构造函数
constructor(address producer, address distributor, address retailer)
public Producer(producer)
Distributor(distributor)
Retailer(retailer){
}
//生成食品溯源信息接口
//只有Producer能调用
//name 食品名称
//traceNumber 食品溯源id
//traceName 当前用户名称
//quality 当前食品质量
function newFood(string name,uint256 traceNumber, string traceName, uint8 quality)
public onlyProducer returns(uint)
{
require(foods[traceNumber] == address(0),"traceName already exist");//④
FoodInfoItem food = new FoodInfoItem(name,traceName,quality,msg.sender);//⑤
foods[traceNumber] = food;//⑥
foodList.push(traceNumber);//⑦
retur food;//⑧
}
//食品分销过程中增加溯源信息的接口
//只有Distributor能调用
//traceNumber 食品溯源id
//traceName 当前用户名称
//quality 当前食品质量
function addTraceInfoByDistributor(uint256 traceNumber,string traceName, uint8 quality)
public onlyRetailer returns(bool) {
require(foods[traceNumber] != address(0),"traceNumber does not exist");
//③
return FoodInfoItem(foods[traceNumber]).addTraceInfoByDistributor(traceName,msg.sender, quality);
}
//食品出售过程中增加溯源信息的接口
//只有Retailer能调用
//traceNumber 食品溯源id
//traceName 当前用户名称
//quality 当前食品质量
function addTraceInfoByRetailer(uint256 traceNumber,string traceName, uint8 quality)
public onlyRetailer returns(bool) {
require(foods[traceNumber != address(0)], "traceNumber does not exist");
return FoodInfoItem(foods[traceNumber]).addTraceInfoByRetailer(traceName,msg.sender, quality);
}
//获取食品溯源信息接口
//string[] 保存食品流转过程中各个阶段的相关信息
//address[] 保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
//uint8[] 保存食品流转过程中各个阶段的状态变化
function getTraceInfo(uint256 traceNumber) public constant returns(uint[], string[], address[], uint8[]) {
require(foods[traceNumber] != address(0), "traceNumber does not exist");
return FoodInfoItem(foods[traceNumber]).getTraceInfo();
}
function getFood(uint256 traceNumber) public constant returns(uint, string, string, string, address, uint8) {
require(foods[traceNumber] != address(0), "traceNumber does not exist");
return FoodInfoItem(foods[traceNumber]).getFood();
}
function getAllFood() public constant returns (uint[]) {
return foodList;
}
}
```
:::
## 题目二
题目:
1.供应链金融实体信息编码6分
1编写供应链金融智能合约的实体接口完成实体通用数据的初始化实现企业和票据实体信息上链的功能2分
2编写企业上链信息接口实现供应链金融的企业信息上链2分
3基于给定的智能合约代码以及注释完成银行向企业交易的接口函数2分
2.供应链金融公司与公司接口编码6分
1编写公司与公司之间进行交易的历史存证上链接口实现公司与公司之间的交易功能2分
2编写创建存证的接口实现创建存证的功能2分
3编写交易金额数量变化的接口实现凭证交易双方资金的变化功能2分
3.供应链金融公司与银行交易的接口编码4分
1编写公司与银行之间进行交易的历史存证上链接口实现公司与银行之间的交易功能2分
2编写创建存证的接口实现创建存证的功能1分
3编写交易金额数量变化的接口实现凭证交易双方资金的变化功能1分
::: code-tabs
@tab xxx.sol
```solidity
```
@tab xxx.sol
```solidity
```
@tab xxx.sol
```solidity
```
:::
## 题目三
题目:
子任务2-2-1太阳能板管理接口编码
1. 根据文档要求,编写太阳能板新增接口功能,必须将新增太阳能板数据存入指定表中,在存储完成后需触发后事件并返回存储与否的标识;
2. 根据文档要求,编写太阳能板修改接口,必须通过指定表修改完成数据更新,在完成更新后需触发事件并返回更新与否的标识。
子任务2-2-2能源管理接口编码
1. 根据文档要求,编写能源新增接口功能,必须将新增能源数据存入指定表中,在存储完成后需触发后事件并返回存储与否的标识;
2. 根据文档要求,编写能源修改接口,必须通过指定表修改完成数据更新,在完成更新后需触发事件并返回更新与否的标识。
子任务2-2-3合约部署和调用
1. 解决代码错误和警告正确编译并部署合约成功获取部署的合约地址和ABI
2. 调用太阳能板查询合约接口,完整验证业务流程;
3. 调用能源查询合约接口,完整验证业务流程。
::: code-tabs
@tab xxx.sol
```solidity
```
@tab xxx.sol
```solidity
```
@tab xxx.sol
```solidity
```
:::
## 题目四
原题:
1.编写原材料接口newMaterial初始化原材料信息返回合约地址并实现原材料信息上链功能。
2.编写获取存原材料接口getMaterial根据合约地址获取原材料信息
3.编写食品物流上链接口addLogistic实现食品物流信息上链功能
4.编写获取食品物流信息的接口getLogistics根据食品产品编号获取物流信息
::: code-tabs
@tab Logistics.sol
```solidity
pragma solidity 0.6.10;
pragma experimental ABIEncoderV2;
contract Logistics {
struct LogisticsData {
address cargo; //货物合约地址
address orgin; //货物上级合约地址
address destination; //货物下级合约地址
string memo; //备注信息
uint createdAt; //创建时间
uint queryCount; //已查询次数
}
LogisticsData[] private _logisticsData; //全部物流信息数组
uint public recordCount;//所有记录条数
uint public queryCount;//所有查询次数
//可自行添加形参和返回值
function addLogistics(address _cargo,address _orgin,【请补充】) public {
//TODO”请补充缺失代码
}
//可自行添加形参和返回值
function getLogisticsInfo(address _cargo) public returns(LogisticsData[] memory _cargoLogisticsData) {
//TODO”请补充缺失代码
}
}
```
@tab Material.sol
```solidity
pragma solidity 0.6.10;
contract Material {
struct Material {
address owner;
string name;
string id;
string memo;
uint createdAt;
bool exist;
}
mapping(string => Material) public materials;
//可自行添加形参和返回值
function newMaterial(string memory _name,string memory _id,【请补充】) public {
//TODO”请补充缺失代码
}
//可自行添加形参和返回值
function getMaterial(string memory id) public view returns(【请补充】) {
//TODO”请补充缺失代码
}
}
```
:::
参考答案:
::: code-tabs
@tab Logistics.sol
```solidity
pragma solidity 0.6.10;
pragma experimental ABIEncoderV2;
contract Logistics {
struct LogisticsData {
address cargo; //货物合约地址
address orgin; //货物上级合约地址
address destination; //货物下级合约地址
string memo; //备注信息
uint createdAt; //创建时间
uint queryCount; //已查询次数
}
LogisticsData[] private _logisticsData; //全部物流信息数组
uint public recordCount;//所有记录条数
uint public queryCount;//所有查询次数
//可自行添加形参和返回值
function addLogistics(address _cargo,address _orgin,【请补充】) public {
//TODO”请补充缺失代码
}
//可自行添加形参和返回值
function getLogisticsInfo(address _cargo) public returns(LogisticsData[] memory _cargoLogisticsData) {
//TODO”请补充缺失代码
}
}
```
@tab Material.sol
```solidity
pragma solidity 0.6.10;
contract Material {
struct Material {
address owner;
string name;
string id;
string memo;
uint createdAt;
bool exist;
}
mapping(string => Material) public materials;
//可自行添加形参和返回值
function newMaterial(string memory _name,string memory _id,【请补充】) public {
//TODO”请补充缺失代码
}
//可自行添加形参和返回值
function getMaterial(string memory id) public view returns(【请补充】) {
//TODO”请补充缺失代码
}
}
```
:::
## 题目五
题目:
1.个人签章信息接口编码
1编写个人签章智能合约的实体接口完成实体通用数据的初始化实现签章和用户实体信息上链的功能
2编写签章信息上链的接口实现Seal合约的构造函数
3基于给定的智能合约代码以及注释完成ElectronicSeal合约判断多人签章文件编号是否存在的函数。
2.电子印章接口编码
1基于给定的智能合约代码以及注释完成ElectronicSeal合约获取多人签章信息函数
2基于给定的智能合约代码以及注释完成ElectronicSeal合约多人签章函数。
::: code-tabs
@tab xxx.sol
```solidity
```
:::
## 题目六
题目:
1.食品信息Food、成员信息(Member)、生产订单信息(Productions)的结构体功能编码6分
1编写食品信息实体功能。2分
2完善智能合约中用户结构体内容2分
3编写生产订单(Productions)结构体信息。2分
2.食品溯源(Trace)的接口编码6分
1根据食品信息结构体完成食品信息添加相应功能2分
2编写食品溯源收购商创建收购订单功能。
3编写食品溯源创建运输订单功能。
3.角色Role管理的接口编码4分
1编写食品溯源增加角色接口实现添加角色的功能。1分
2编写食品溯源获取角色功能。1分
3编写食品溯源修改角色功能。2分
::: code-tabs
@tab xxx.sol
```
```
:::
## 题目七
原题:
**子任务2-2-1航班延误保险购买合约编码5分**
1编写航班保险购买上链接口完成只有购买机票的用户可以购买保险、必须缴纳正确的保费金额、购买保险的时间不能超过购买机票后的0.5小时的功能符合条件则用户可以购买保险将用户购买保险状态上链3分
2编写退保接口完成保险公司预存赔偿金后用户无法退保反之用户可退保的功能将用户退保状态上链并退还用户保费功能。2分
**子任务2-2-2航班信息存证上链合约编码**
1编写获取航班信息接口实现依据航班号获得航班号对应的计划起飞时间、实际起飞时间、到达时间、是否延误状态的功能
2编写判断航班是否延误接口实现依据航班号获得航班号对应的航班是否延误得到航班是否延误的结果功能。
**子任务2-2-3航班延误险理赔合约编码**
1编写客户理赔接口实现如果航班延误超过4小时将赔偿金赔偿给乘客的功能
2编写保险公司收取保费接口实现如果航班没有延误或者延误时间少于4小时将保费转账给保险公司并退还赔偿金的功能。
::: code-tabs
@tab Claims.sol
```solidity
pragma solidity ^0.6.10;
import "./FlightDelayInsurance.sol";
contract Claims is FlightDelayInsurance{
// 定义航班信息结构体
struct Flight {
uint256 departureTime; // 航班出发时间
uint256 delayTime; // 航班延误时间
bool isDelayed; // 航班是否延误
bool isInsured; // 航班是否购买保险
}
// 定义保险公司地址
address public insuranceCompany;
// 定义航班信息映射
mapping(bytes32 => Flight) public flights;
// 定义购买保险事件
event BuyInsurance(bytes32 flightKey, address passenger, uint256 premium);
// 定义航班延误事件
event FlightDelay(bytes32 flightKey, uint256 delayTime);
// 定义理赔事件
event Claim(bytes32 flightKey, address passenger, uint256 amount);
// 定义保险公司预存的赔偿金
uint256 public compensationNew;
// 构造函数,初始化保险公司地址和赔偿金
constructor() FlightDelayInsurance(platformS,airlineV,insuranceCompanyC,premium,compensation) public {
insuranceCompany = msg.sender;
compensationNew = compensation;
}
// 更新航班信息函数
function updateFlight(bytes32 flightKey, uint256 departureTime, uint256 delayTime, bool isDelayed) payable public {
// 判断调用者是否为保险公司
require(msg.sender == insuranceCompany, "Only insurance company can update flight information");
// 更新航班信息
flights[flightKey].departureTime = departureTime;
flights[flightKey].isDelayed = isDelayed;
/*********** 客户理赔接口 **********/
//任务2-2-3请编写合约代码
/********** 客户理赔接口 ***********/
/*********** 保险公司收取保费接口开发 **********/
//任务2-2-3请编写合约代码
/********** 保险公司收取保费接口开发 ***********/
// 触发航班延误事件
emit FlightDelay(flightKey, delayTime);
}
}
```
@tab FlightDelayInsurance.sol
```solidity
pragma solidity ^0.6.10;
contract FlightDelayInsurance {
address public platformS; // 平台S的地址
address public airlineV; // 航空公司V的地址
address public insuranceCompanyC; // 保险公司C的地址
uint public premium; // 保险费
uint public compensation; // 赔偿金额
uint public purchaseTime; // 购买保险的时间
uint public depositTime; // 存入赔偿金额的时间
bool public purchased; // 是否购买了保险
bool public deposited; // 是否存入了赔偿金额
mapping(address => bool) public insured; // 已退保的用户
mapping(address => bool) public policy; // 已生成保单的用户
mapping(address => bool) public purchasedTicket; // 已购买机票的用户
constructor(address _platformS, address _airlineV, address _insuranceCompanyC, uint _premium, uint _compensation) public {
platformS = _platformS; // 初始化平台S的地址
airlineV = _airlineV; // 初始化航空公司V的地址
insuranceCompanyC = _insuranceCompanyC; // 初始化保险公司C的地址
premium = _premium; // 初始化保险费
compensation = _compensation; // 初始化赔偿金额
}
function purchaseTicket() public {
require(!purchasedTicket[msg.sender], "Ticket has already been purchased"); // 该用户已购买机票
purchasedTicket[msg.sender] = true; // 标记该用户已购买机票
purchaseTime = block.timestamp;
}
/*********** 航班保险购买上链接口开发 **********/
//任务2-2-1请编写合约代码
/********** 航班保险购买上链接口开发 ***********/
function depositCompensation() public payable {
require(msg.sender == insuranceCompanyC, "Only insurance company C can deposit compensation"); // 只有保险公司C可以存入赔偿金额
require(msg.value == compensation, "Compensation amount is incorrect"); // 赔偿金额不正确
require(block.timestamp < depositTime + 2 hours, "Deposit time has expired"); // 存入赔偿金额的时间已过期
deposited = true; // 标记已存入赔偿金额
}
/*********** 退保接口开发 **********/
//任务2-2-1请编写合约代码
/********** 退保接口开发 ***********/
function generatePolicy() public {
require(deposited, "Compensation has not been deposited"); // 赔偿金额未存入,无法生成保单
require(msg.sender == platformS, "Only platform S can generate policy"); // 只有平台S可以生成保单
require(!policy[msg.sender], "Policy has already been generated"); // 该用户已生成保单
policy[msg.sender] = true; // 标记该用户已生成保单
}
}
```
@tab FlightManagement.sol
```solidity
pragma solidity ^0.6.10;
contract FlightManagement {
// 航班结构体
struct Flight {
string flightNumber; // 航班号
uint256 scheduledDepartureTime; // 计划起飞时间
uint256 actualDepartureTime; // 实际起飞时间
uint256 arrivalTime; // 到达时间
bool delayed; // 是否延误
}
// 航班号到航班信息的映射
mapping(string => Flight) flights;
// 添加航班
function addFlight(string memory _flightNumber, uint256 _scheduledDepartureTime, uint256 _arrivalTime) public {
flights[_flightNumber] = Flight(_flightNumber, _scheduledDepartureTime, 0, _arrivalTime, false);
}
// 更新实际起飞时间
function updateActualDepartureTime(string memory _flightNumber, uint256 _actualDepartureTime) public {
flights[_flightNumber].actualDepartureTime = _actualDepartureTime;
}
/*********** 获取航班信息接口开发 **********/
//任务2-2-2请编写合约代码
/********** 获取航班信息接口开发 ***********/
/*********** 编写判断航班是否延误接口开发 **********/
//任务2-2-2请编写合约代码
/********** 编写判断航班是否延误接口开发 ***********/
}
```
:::
## 题目八
题目:
子任务2-2-1信息管理合约编码
1. 编写检索个人信息接口,完成患者通过身份证号检索其姓名、性别、年龄的功能;
2. 编写信息管理接口,完成允许患者与医院和科室进行信息管理,通过身份证号检索到患者的个人信息,将预约信息显示给患者,并发送到患者的账户地址中的功能;
子任务2-2-2病历管理合约编码
1. 编写新建病历接口,实现检索病人对应科室既往病历,授权医生查看,如果没有既往病历则创建一个新的病历功能;
2. 编写结束就诊接口,实现检查病历是否已经填写,并结束病历咨询的功能。
子任务2-2-3病历查看合约编码
根据需求用例文档在待补充源码中完成病历查看合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的检查退款请求状态、自动批准退款请求接口功能。
1编写查看病人个人信息接口实现获取指定病人个人信息功能
2编写查看病人病情描述接口实现获取指定病人病情描述功能。
::: code-tabs
@tab xxx.sol
```
```
:::
## 题目九
题目:
子任务2-2-1合同管理合约编码
1编写房东签署合同接口完成本合同位置只允许房东签署通过合同中的信息生成租赁合同的链上哈希触发协议签署合同的功能其中合同中的信息包括房东链上账户、租客链上账户、租赁开始时间、租赁结束时间、月租金额、押金金额、交租时间
2编写租金支付接口完成只允许租客支付租金的规则检查支付的租金金额是否正确触发记录租金支付情况的功能。
子任务2-2-2违约管理合约编码
1编写房东终止合同接口实现房东终止合同判断如果租客已经终止合同则合同无效如果合同有效对合同终止状态进行标记将剩余押金退还给租客的功能
2编写租客终止合同接口实现租客终止合同判断如果房东已经终止合同则合同无效如果合同有效对合同终止状态进行标记将剩余押金退还给房东的功能。
子任务2-2-3押金管理合约编码
根据需求用例文档在待补充源码中完成押金管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的租客缴纳押金情况查询、房东收取押金情况查询接口功能。
1编写租客缴纳押金情况查询接口实现查询租客是狗已缴纳押金功能
2编写房东收取押金情况查询接口实现房东是否已收到押金的功能。
::: code-tabs
@tab xxx.sol
```
```
:::
## 题目十
题目:
子任务2-2-1账户管理合约编码
根据需求用例文档在待补充源码中完成账户管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确。需要编写生成账户接口,完成从外部部门检索姓名、年龄、雇主、开始日期、工资、缴费基数,将人员信息进行综合存储功能。
子任务2-2-2费用管理合约编码
根据需求用例文档在待补充源码中完成费用管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行添加新职工账户、添加新雇主账户。
1编写添加新职工账户接口实现当账户不存在只有管理员可以添加职工账户职工新账户中账户余额为0未被赞助的功能
2编写添加新雇主账户接口实现当账户不存在只有管理员可以添加雇主账户雇主新账户中账户余额为0已被赞助的功能
子任务2-2-3保险转移合约编码
根据需求用例文档在待补充源码中完成保险转移合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的申请转移关系、接收账户转移接口。
1编写申请转移关系接口实现创建申请、添加到申请列表功能其中创建申请需要设置申请人地址、原城市、目标城市、停缴状态、批准状态
2编写接收账户转移接口实现获取账户进行账户授权状态、接收状态、个人账户基金、统筹账户基金、养老保险账户的信息设置
::: code-tabs
@tab xxx.sol
```
```
:::

View File

@@ -0,0 +1,56 @@
---
title: Hardhat 相关知识
createTime: 2025/10/14 14:57:06
permalink: /programming/solidity/other/hardhat/
---
## HardHat2 部署
### Node.js v16 安装
HardHat2 需要 Node.js v16 及以上的版本
这里给出的是通过 npm 来将旧版本升级到 Node.js v16 的,如果想要直接安装的话通过 `yum install nodejs` 或者 `apt install nodejs` 来即可。
```bash
npm config set registry https://registry.npmmirror.com
sudo npm install -g n
sudo n 16
```
安装完成之后可以查看版本,如果没有更新可以重新刷新一下环境(直接退出重连最简单)
```bash
node -v
# v16.20.2
npm -v
# 6.14.15
```
### 安装 Hardhat2
创建一个 hardhat2-project 目录,初始化 npm 项目,注意这里不要用 hardhat 作为项目名
```bash
mkdir ~/hardhat2-project
cd ~/hardhat2-project
npm init -y
```
安装 Hardhat 2
```bash
npm install --save-dev hardhat@^2.23.0
```
初始化 Hardhat2 项目
```bash
npx hardhat init
```
选择
```bash
✔ What do you want to do? · Create a JavaScript project
✔ Hardhat project root: · /root/hardhat2-project
✔ Do you want to add a .gitignore? (Y/n) · y
✔ Help us improve Hardhat with anonymous crash reports & basic usage data? (Y/n) · y
✔ Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)? (Y/n) · y
```
## 使用 Hardhat2 编译测试合约
在 hardhat2-project 目录下,执行以下命令来编译合约
合约都会放在 `contracts` 目录下,这里我们选择了一个默认的合约,因此可以直接编译
```bash
# 测试编译
npx hardhat compile
# 运行测试
npx hardhat test
# 查看可用任务
npx hardhat help
```

View File

@@ -0,0 +1,88 @@
---
title: 一些没分类的小知识
createTime: 2025/10/12 15:34:38
permalink: /programming/solidity/other/miscellaneous/
---
## 关于 memory 和 storage 存储类型
- `storage`:合约的持久化状态数据,保存在链上状态。对 `storage` 的写入最昂贵,读取也比内存贵;修改会永久生效。
- `memory`:函数调用期间的临时数据,函数返回后即释放。对 `memory` 的更改不会持久化。
- (补充)`calldata`:外部函数参数的只读数据位置,零拷贝、不可修改,用于节省 gas。
### 生命周期与成本
- `storage` 写入昂贵、读取较贵;适合保存需要长期存在的状态。
- `memory` 在函数结束时释放,读取/写入相对便宜;适合临时计算与返回值。
- 复杂引用类型(数组、`struct``mapping``string``bytes`)在函数参数或局部变量处通常必须显式标注数据位置。
### 默认与必须声明
- 状态变量总是位于 `storage`(例如 `User[] public users;`)。
- 外部函数(`external`)的复杂类型参数默认是 `calldata`;内部/公共函数需要显式标注 `memory``storage`
- 局部变量的复杂类型必须指定数据位置,否则编译报错。
### 拷贝与引用语义
-`storage` 读取到 `memory` 会“复制”数据;修改 `memory` 副本不影响原始 `storage`
- 使用 `storage` 局部变量可以得到对状态数据的“引用”,对其赋值会持久化。
```solidity
pragma solidity ^0.8.20;
contract Users {
struct User { string name; uint age; }
User[] public users;
function add(string memory name, uint age) external {
users.push(User(name, age)); // 写入 storage
}
function updateName(uint i, string memory newName) external {
User storage u = users[i]; // storage 引用(指向链上状态)
u.name = newName; // 修改持久化生效
}
function tryUpdate(uint i) external {
User memory u = users[i]; // 从 storage 复制到 memory
u.age = 99; // 仅修改副本,不会影响链上状态
}
}
```
### 在内部函数传递 storage 引用
- 仅内部/私有函数可以接收 `storage` 引用参数,从而直接修改状态;外部函数参数不能是 `storage`
```solidity
pragma solidity ^0.8.20;
contract Users2 {
struct User { string name; uint age; }
User[] public users;
function _inc(User storage u) internal { u.age += 1; }
function birthday(uint i) external {
_inc(users[i]); // 传递 storage 引用,持久化修改
}
}
```
### 动态 memory 数组与限制
- 可在 `memory` 中构造动态数组:`new uint[](n)`;适合作为返回值或临时计算。
- `mapping` 只能存在于 `storage`,不能在 `memory` 中创建或拷贝。
```solidity
pragma solidity ^0.8.20;
contract Arrays {
function make(uint n) external pure returns (uint[] memory a) {
a = new uint[](n);
for (uint i = 0; i < n; i++) a[i] = i;
}
}
```
### 常见坑与实践建议
-`storage` 变量整体赋值会进行深拷贝或引用变更(依据类型),要明确拷贝成本与语义。
- 修改 `memory` 副本不会持久化;要修改链上状态请使用 `storage` 引用。
- 大型 `string/bytes/数组``memory↔storage` 间复制成本高,尽量减少不必要的复制。
- 外部函数能用 `calldata` 的地方尽量使用(只读参数),节省 gas。

View File

@@ -0,0 +1,90 @@
---
title: Web 概览与学习路径
permalink: /programming/web/
createTime: 2025/10/28 22:20:00
---
# Web 是什么?
Web万维网是一个基于浏览器与服务器的“信息与应用平台”。用户通过浏览器访问网站浏览器通过 **HTTP/HTTPS** 与服务器交互,服务器返回页面或数据,最终在浏览器中呈现并产生交互。
- 浏览器渲染页面HTML/CSS/JS、执行脚本、发起网络请求。
- 服务器:处理业务逻辑、读写数据库、对外提供 API。
- 数据库持久化存储MySQL/PostgreSQL/MongoDB 等)。
简而言之:浏览器负责“看与用”,服务器负责“算与存”。
## 前端基础概念
- HTML结构与语义页面“骨架”
- CSS表现与布局页面“外观”
- JavaScript交互与逻辑页面“大脑”
- 现代前端模块化、构建工具、组件化框架Vue/React/Svelte 等)。
入门建议:先掌握原生 HTML/CSS/JS再学习框架。你可以从本站文章开始
- 基础教程 → `/programming/web/basic-syntax/html-css-js/`
## 后端基础概念
- 服务器与框架Node.jsExpress/NestJS、PythonFlask/Django/FastAPI、JavaSpring Boot、GoGin/Fiber
- API 风格REST常见、GraphQL灵活查询
- 数据库与 ORMMySQL/PostgreSQL关系型、MongoDB文档型ORM 如 Prisma/TypeORM/SQLAlchemy。
- 常见能力认证授权Session/JWT/OAuth、文件上传、任务队列、缓存、日志与监控。
## 前后端如何协作
- 约定接口路径、方法GET/POST/PUT/DELETE、参数与返回 JSON。
- 跨域与安全CORS、CSRF/XSS/SQL 注入防护、HTTPS。
- 开发流程:
1) 需求与原型 → 2) API 设计 → 3) 前端页面与交互 → 4) 后端实现与测试 → 5) 联调与验收 → 6) 部署与监控。
## 学习路径(从 0 到 1
1. 基础三件套HTML + CSS + JavaScript建议用 VSCode + Live Server
2. 工具与方法Git/GitHub、浏览器开发者工具、HTTP/REST、请求调试Postman/Insomnia
3. 进阶前端布局Flex/Grid、响应式、ES6+、模块化、打包与构建Vite/Webpack
4. 后端入门:选择一种语言与框架(如 Node.js + Express完成 CRUD 与认证。
5. 数据库:会建表、会写基本查询;理解事务与索引。
6. 部署与上线Nginx 反向代理、Docker、环境变量、日志与监控。
建议开发一个“待办清单 + 登录 + 数据持久化”的完整小项目,贯穿前后端与部署。
## 推荐学习资源
通用与入门:
- [MDN Web DocsHTML/CSS/JS 全面权威)](https://developer.mozilla.org/)
- [freeCodeCamp系统课程与练习](https://www.freecodecamp.org/)
- [Roadmap.sh前端/后端学习路径图)](https://roadmap.sh/)
前端:
- [HTML/CSS 基础MDN](https://developer.mozilla.org/en-US/docs/Learn)
- [CSS-Tricks样式与布局技巧](https://css-tricks.com/)
- [JavaScript 基础与进阶MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
- [Vue 官方文档](https://vuejs.org/)
后端:
- [Node.js 文档](https://nodejs.org/en/docs)
- [Express](https://expressjs.com/)
- [NestJS](https://docs.nestjs.com/)
- [Spring Boot](https://spring.io/projects/spring-boot)
- [Django](https://docs.djangoproject.com/)
- [Flask](https://flask.palletsprojects.com/)
- [FastAPI](https://fastapi.tiangolo.com/)
数据库与 ORM
- [MySQL](https://dev.mysql.com/doc/)
- [PostgreSQL](https://www.postgresql.org/docs/)
- [MongoDB](https://www.mongodb.com/docs/)
- [PrismaNode.js ORM](https://www.prisma.io/docs)
- [TypeORM](https://typeorm.io/)
工具:
- [VSCode](https://code.visualstudio.com/)
- [Postman](https://www.postman.com/)
- [Insomnia](https://insomnia.rest/)
- [Docker](https://docs.docker.com/)
## 本站相关内容
- Web 前端基础讲解 → `/programming/web/basic-syntax/html-css-js/`
- 后续将补充:前端工程化、接口联调、部署与运维实战等专题。

View File

@@ -0,0 +1,535 @@
---
title: Web 前端基础讲解
createTime: 2025/10/28 21:23:48
permalink: /programming/web/basic-syntax/html-css-js/
---
## 前端开发到底是什么?
前端开发,简单来说,就是**你能在网页上看到和互动的一切**。
想象一下你正在看一个网站:
* **文字、图片、按钮、菜单**:这些都是前端开发人员用代码“画”出来的。
* **点击按钮会发生什么、输入框能打字、图片能放大缩小**:这些互动效果也是前端开发人员用代码实现的。
所以,前端开发就是负责把设计师画好的网站样子,用代码变成用户可以在浏览器里真实看到、摸到、用的东西。它主要涉及三种技术:
1. **HTML**:就像网页的“骨架”,决定了网页上有什么内容(标题、段落、图片等)。
2. **CSS**:就像网页的“衣服”,决定了网页看起来怎么样(颜色、字体、布局等)。
3. **JavaScript**:就像网页的“大脑”,决定了网页能做什么(动画、交互、数据处理等)。
总而言之,前端开发就是让网站变得好看、好用、能互动。
## 开发工具
进行前端开发,我们需要一个好用的“工具箱”。其中,**Visual Studio Code (VS Code)** 是一个非常受欢迎且功能强大的选择。
VsCode 官网:[https://code.visualstudio.com/](https://code.visualstudio.com/)
**为什么推荐 VS Code**
* **免费且开源**:你可以免费使用它,并且它的代码是公开的,有很多人一起维护和改进。
* **轻量级但功能强大**:它启动速度快,占用资源少,但通过安装各种“插件”,可以实现非常多的功能,比如代码高亮、智能提示、调试、版本控制等等。
* **支持多种语言**:不仅对 HTML、CSS、JavaScript 有很好的支持,也支持其他很多编程语言。
* **丰富的生态系统**:有大量的插件可以帮助你提高开发效率,比如 Live Server实时预览网页、Prettier代码格式化等。
* **跨平台**:无论你使用 Windows、macOS 还是 Linux都可以安装和使用 VS Code。
### VsCode 前端开发插件推荐
- **Chinese (Simplified) Language Pack for Visual Studio Code**:中文语言包,方便中文用户使用。
- **Live Server**:实时预览网页,修改代码后自动刷新。
- **Prettier**:代码格式化,保持代码风格统一。
- **HTML CSS Support**HTML 和 CSS 代码智能提示。
参考文章:
1. [VSCode安装配置使用教程最新版超详细保姆级含插件一文就够了](https://blog.csdn.net/2303_82176667/article/details/137193809)
2. [快速上手web前端开发超详细教程](https://blog.csdn.net/2303_82176667/article/details/137193809)
## HTML5 基础知识讲解
HTML 是一种用来描述网页的语言,用于描述网页的结构和内容。
HTML 并不是一种编程语言,而是一种标记语言。它使用标签来描述网页上的不同元素,比如标题、段落、图片、链接等。
标签指的是由尖括号 `<``>` 包围的关键词,通常成对出现,用来表示元素的开始和结束。
一个简单的 HTML 实例,用于初步的了解效果:
```html title='index.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦(notes.simengweb.com)</title>
</head>
<body>
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
</body>
</html>
```
小提示:可以将代码复制到 VsCode 中,然后使用 Live Server 插件就可以实时预览效果啦。
### HTML5 文档分析
我们以前面的样例代码为例,来对 HTML 文档进行讲解
第一行:`<!DOCTYPE html>`,这是一个文档类型声明,用于告诉浏览器这是一个 HTML5 文档。
第二行:`<html>`,这是 HTML 文档的根元素,所有其他元素都必须嵌套在这个元素中,`<html>` 和 `</html>` 之间的内容就是文档的主体。
第三行到第六行:`<head>`,这是文档的头部元素,用于包含文档的元数据(比如标题、字符编码、外部资源引用等)。
第四行:`<meta charset="utf-8">`,这是一个元数据标签,用于指定文档的字符编码为 UTF-8。UTF-8 是一种常用的字符编码,能够表示世界上几乎所有的字符。如果不写的话可能会导致中文乱码的问题。
第五行:`<title>仲夏夜之梦(notes.simengweb.com)</title>`,这是文档的标题,会显示在浏览器的标题栏或标签页上。
第七行:`<body>`,这是文档的主体元素,用于包含文档的可见内容(比如文字、图片、按钮等),`<body>` 和 `</body>` 之间的内容就是文档的主体内容。
第八行:`<h1>我的第一个标题</h1>`,这是一个一级标题元素,用于表示文档的主要主题。`h1` 元素的内容会显示为较大的字体,通常用于页面的主标题。
第九行:`<p>我的第一个段落。</p>`,这是一个段落元素,用于表示文档中的一个段落。`p` 元素的内容会显示为普通的段落文本。
小提示:在浏览器中打开 F12 开启开发者工具,就可以查看和调试 HTML 文档啦。
## CSS3 基础知识讲解
CSS 是一种用来描述 HTML 文档“长什么样”的语言,专门负责网页的样式、排版与视觉效果。
CSS 也不是编程语言,而是一种“样式表”语言。它通过“选择器”找到 HTML 元素,再给它挂上一条或多条“声明”,告诉浏览器“这个元素应该是什么颜色、多大字号、放在哪里”。
一条 CSS 声明由“属性”和“值”组成,用冒号分隔,以分号结尾;多条声明放在花括号里,就组成了一条“样式规则”。
一个最简单的 CSS 示例,让页面里的标题变成红色、居中显示:
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦(notes.simengweb.com)</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
</body>
</html>
```
@tab style.css
```css
body {
background-color:#d0e4fe;
}
h1 {
color:orange;
text-align:center;
}
p {
font-family:"Times New Roman";
font-size:20px;
}
```
:::
这里的 index.html 中需要添加一条语句,用于引入 CSS 样式表。
```html
<link rel="stylesheet" href="style.css">
```
然后通过浏览器打开 index.html 就可以看到效果啦。
### CSS 文档分析
我们以前面的样例代码为例,来对 CSS 文档进行讲解
第一到三行:`body { background-color:#d0e4fe; }`,这是一条针对 `<body>` 元素的样式规则。
- `body` 是“选择器”,表示要把样式应用到整个网页主体。
- `background-color` 是属性,用来设置背景颜色;`#d0e4fe` 是一个淡蓝色色值,因此整个页面会呈现淡蓝色背景。
第四行到第七行:`h1 { color:orange; text-align:center; }`,这是一条针对 `<h1>` 元素的样式规则。
- `h1` 是“选择器”,对应 HTML 中的一级标题。
- `color:orange;` 把标题文字设为橙色。
- `text-align:center;` 让标题在水平方向上居中显示。
第八行到第十一行:`p { font-family:"Times New Roman"; font-size:20px; }`,这是一条针对 `<p>` 元素的样式规则。
- `p` 是“选择器”,对应 HTML 中的段落。
- `font-family:"Times New Roman";` 指定段落使用 Times New Roman 字体。
- `font-size:20px;` 把段落文字大小设为 20 像素,让文字看起来更大、更清晰。
小提示:在 VsCode 中安装“Live Server”插件后修改并保存 CSS 文件,浏览器会自动刷新,立即看到样式变化,方便调试。
## JavaScript 基础知识讲解
JavaScript简称 JS是让网页“动起来、能互动”的语言。它可以
- 响应用户操作(点击、输入、滚动等)
- 修改页面内容与样式(增删节点、改文字/颜色)
- 与服务器通信、处理数据与状态
- 实现动画与复杂交互逻辑
下面用一个小示例,演示 JS 如何让页面产生交互效果:
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦(notes.simengweb.com)</title>
<link rel="stylesheet" href="style.css">
<!-- 样式写在外部 CSS 中 -->
<!-- JavaScript 推荐放在 body 末尾,或使用 defer 属性 -->
<!-- 这里在 body 末尾通过 src 引入外部脚本 -->
</head>
<body>
<h1>我的第一个标题</h1>
<p id="message">我的第一个段落。</p>
<button id="btn">点我试试</button>
<input id="name" placeholder="输入你的名字" />
<script src="script.js"></script>
</body>
</html>
```
@tab script.js
```js
// 等页面元素加载完成后再执行(避免找不到节点)
document.addEventListener('DOMContentLoaded', () => {
const msg = document.getElementById('message'); // 选择段落节点
const btn = document.getElementById('btn'); // 选择按钮
const nameInput = document.getElementById('name'); // 选择输入框
// 点击按钮,修改段落文本与颜色
btn.addEventListener('click', () => {
msg.textContent = '你点击了按钮!';
msg.style.color = 'green';
console.log('按钮被点击'); // 打开浏览器控制台可见
});
// 输入时,实时更新欢迎语
nameInput.addEventListener('input', (e) => {
const name = e.target.value.trim();
msg.textContent = name ? `你好,${name}` : '我的第一个段落。';
});
});
```
:::
### JavaScript 文档分析
我们以前面的样例代码为例,来对 JS 的关键点进行讲解:
- `<script src="script.js"></script>`:在 HTML 中通过 `script` 标签引入外部 JS 文件。常见放置位置是 `</body>` 之前,避免脚本执行时页面元素尚未加载。
- `document.addEventListener('DOMContentLoaded', ...)`:等待文档结构加载完成再运行 JS确保能获取到页面元素。
- `document.getElementById('...')`:选择页面中的元素节点,便于后续读写或绑定事件。
- `addEventListener('click'/'input', ...)`:给元素绑定事件监听器,描述“发生什么事时要做什么”。
- `textContent / style`:修改文本与内联样式,从而即时改变页面显示效果。
- `console.log(...)`:在开发者工具控制台输出调试信息,便于观察程序执行。
### 小提示
- 打开浏览器开发者工具F12切到“Console”能查看 `console.log` 输出;在 “Elements”/“Inspector” 面板能查看并调试 DOM 结构与样式。
- 在 VSCode 中使用 “Live Server”保存 `script.js` 后浏览器会自动刷新,方便快速迭代。
- 现代 JS 推荐使用 `const` 与 `let` 替代 `var`;多用箭头函数与模板字符串(如 `` `你好,${name}` ``)让代码更简洁。
到这里,我们已经分别了解了 HTML结构、CSS样式与 JavaScript交互三者如何协同工作。接下来可以尝试把它们组合起来做一个小页面练手。
## 动手练习:小作业(只改 HTML/CSSJS 已提供)
目标:做一个“欢迎卡片”,包含标题、说明文字、输入框与按钮。
- 点击按钮时切换页面主题(浅色/深色JS 会自动完成;
- 输入名字时实时显示欢迎语;
- 你只需要修改 HTML 和 CSS 来达到视觉与布局效果。
### 作业要求(验收标准)
- 卡片居中显示,具有圆角、阴影与内边距;
- 标题居中,段落有合适的行高与间距;
- 按钮有悬停hover与按下active的视觉反馈
- 输入框获得焦点focus时有明显强调样式
- 在移动端(窄屏)不溢出,布局能自适应;
- 深色主题下文字可读、对比度合理。提示JS 会在 `<body>` 上切换 `theme-dark` 类,你可以在 CSS 中基于该类进行主题覆盖。
### 起步模板
将以下三份代码保存为同目录下的 `index.html`、`style.css` 与 `script.js`,用 VSCode 的 Live Server 打开 `index.html` 进行预览。完成作业时,请只修改 HTML 和 CSS保留 JS 的 id 与类名依赖)。
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>小作业:欢迎卡片</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="page">
<div class="card" id="card">
<h1 class="card__title">欢迎来到我的页面</h1>
<p class="card__text" id="message">请点击按钮或输入你的名字</p>
<div class="card__actions">
<input id="name" class="input" placeholder="输入你的名字" />
<button id="btn" class="btn btn--primary">点我切换主题</button>
</div>
</div>
</div>
<script src="script.js" defer></script>
<!-- 注意JS 依赖 #message、#btn、#name 这几个 id请不要改动它们的命名 -->
<!-- 你可以新增或调整 class 名,或增删结构,来实现更好的视觉与布局 -->
</body>
</html>
```
@tab style.css
```css
/* 目标:只通过 CSS 实现卡片的视觉与响应式,并支持深色主题 */
/* 建议:使用 CSS 变量管理主题;在 .theme-dark 上覆盖变量 */
:root {
--bg: #f7f9fc;
--text: #222;
--primary: #ff7a45; /* 可调整为你的品牌色 */
--card-bg: #fff;
--card-shadow: 0 10px 20px rgba(0,0,0,0.08);
}
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: system-ui, -apple-system, Segoe UI, Roboto, 'Helvetica Neue', Arial;
}
.page {
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
}
.card {
width: min(640px, 100%);
background: var(--card-bg);
border-radius: 16px;
box-shadow: var(--card-shadow);
padding: 24px;
}
.card__title {
margin: 0 0 12px;
text-align: center;
}
.card__text {
margin: 0 0 16px;
line-height: 1.6;
text-align: center;
}
.card__actions {
display: flex;
gap: 12px;
justify-content: center;
flex-wrap: wrap;
}
.input {
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 8px;
outline: none;
min-width: 220px;
}
.input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(255, 122, 69, 0.2);
}
.btn {
padding: 10px 16px;
border: none;
border-radius: 999px;
cursor: pointer;
transition: transform .08s ease, box-shadow .2s ease, background-color .2s ease;
}
.btn--primary {
background: var(--primary);
color: #fff;
box-shadow: 0 6px 12px rgba(255, 122, 69, .3);
}
.btn--primary:hover {
transform: translateY(-1px);
box-shadow: 0 8px 16px rgba(255, 122, 69, .4);
}
.btn--primary:active {
transform: translateY(0);
box-shadow: 0 4px 8px rgba(255, 122, 69, .3);
}
/* 任务为深色主题定义样式。JS 会在 <body> 上切换 `.theme-dark` 类。*/
body.theme-dark {
--bg: #0f172a;
--text: #e5e7eb;
--primary: #60a5fa; /* 深色下可更柔和 */
--card-bg: #1f2937;
--card-shadow: none;
}
/* 可选:为移动端优化 */
@media (max-width: 480px) {
.card { padding: 18px; }
.input { min-width: 100%; }
}
```
@tab script.js
```js
// JS 已提供:负责交互逻辑,切换主题与显示欢迎语
// 你只需要改 HTML 和 CSS 即可达成作业要求
document.addEventListener('DOMContentLoaded', () => {
const msg = document.getElementById('message');
const btn = document.getElementById('btn');
const nameInput = document.getElementById('name');
// 切换深色主题(在 <body> 上切换 theme-dark 类)
btn.addEventListener('click', () => {
document.body.classList.toggle('theme-dark');
const dark = document.body.classList.contains('theme-dark');
msg.textContent = dark ? '深色主题已开启' : '浅色主题已开启';
});
// 实时欢迎语
nameInput.addEventListener('input', (e) => {
const name = e.target.value.trim();
msg.textContent = name ? `你好,${name}` : '请点击按钮或输入你的名字';
});
});
```
:::
### 提示与加分项
- 可以用 `:root`+CSS 变量统一管理主题色,在 `.theme-dark` 中覆盖变量即可完成切换;
- 尝试为按钮增加平滑过渡与阴影层次感;
- 在移动端下让输入框占满一行,按钮在下一行显示;
- 可自行优化字体、字号与间距,让视觉更加舒适;
- 加分:实现卡片在深色主题下的微动效(例如背景色淡入)。
## 入门版(更简单,建议先做这个)
目标:做一个“欢迎卡片”,内容包括标题、说明文字、一个输入框和一个按钮。
- 点击按钮时高亮卡片JS 已完成,你只需让 `.card.highlight` 在 CSS 里更显眼)。
- 输入名字时实时显示欢迎语JS 已完成)。
- 你只需要修改 HTML 和 CSS让页面好看、布局合理即可。
验收标准(入门)
- 卡片居中、圆角、阴影、内边距,整体观感舒适。
- 按钮有 `hover/active` 反馈,输入框 `focus` 有强调样式。
- 窄屏下不溢出,内容能自适应。
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>入门版小作业</title>
<link rel="stylesheet" href="style.css">
<!-- 保留以下 idmessage / btn / name / card -->
</head>
<body>
<div class="page">
<div class="card" id="card">
<h1>欢迎</h1>
<p id="message">在输入框里写下你的名字</p>
<input id="name" placeholder="输入你的名字">
<button id="btn">高亮卡片</button>
</div>
</div>
<script src="script.js"></script>
<!-- 用 VSCode Live Server 打开 index.html 预览效果 -->
<!-- 完成作业时,请只修改 HTML 和 CSS -->
<!-- 你可以自由调整颜色、间距、字体与布局,使页面更美观 -->
</body>
</html>
```
@tab style.css
```css
/* 极简样式:你可以在此基础上美化与调整 */
body {
margin: 0;
background: #f5f7fa;
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial;
}
.page {
min-height: 100vh;
display: grid;
place-items: center;
padding: 16px;
}
.card {
width: min(360px, 100%);
background: #fff;
border-radius: 12px;
box-shadow: 0 6px 12px rgba(0,0,0,0.08);
padding: 16px;
text-align: center;
}
input {
width: 100%;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 8px;
outline: none;
margin-bottom: 12px;
}
input:focus {
border-color: #1677ff;
box-shadow: 0 0 0 2px rgba(22,119,255,.2);
}
button {
padding: 8px 12px;
border: none;
border-radius: 8px;
background: #1677ff;
color: #fff;
cursor: pointer;
}
button:hover { filter: brightness(1.05); }
button:active { filter: brightness(0.95); }
/* JS 点击按钮时会在卡片上切换 .highlight 类 */
.card.highlight {
background: #fffbe6; /* 浅黄色高亮 */
box-shadow: 0 8px 16px rgba(0,0,0,0.10);
}
```
@tab script.js
```js
// JS 已提供:负责简单交互。请只改 HTML/CSS。
document.addEventListener('DOMContentLoaded', () => {
const msg = document.getElementById('message');
const btn = document.getElementById('btn');
const nameInput = document.getElementById('name');
const card = document.getElementById('card');
// 实时欢迎语
nameInput.addEventListener('input', (e) => {
const name = e.target.value.trim();
msg.textContent = name ? `你好,${name}` : '在输入框里写下你的名字';
});
// 切换卡片高亮
btn.addEventListener('click', () => {
card.classList.toggle('highlight');
});
});
```
:::

View File

@@ -0,0 +1,468 @@
---
title: html 列表与语义布局
createTime: 2025/11/02 20:47:50
permalink: /programming/web/basic-syntax/html-lists-and-semantic-layout/
---
## 四、列表UL/OL/LI
无序列表(圆点):
```html title="index.html"
<ul>
<li>学习笔记</li>
<li>工具推荐</li>
<li>友情链接</li>
</ul>
```
有序列表(数字):
```html title="index.html"
<ol>
<li>需求与原型</li>
<li>API 设计</li>
<li>联调与验收</li>
</ol>
```
**小案例:展示清单与步骤**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>列表案例</title>
<link rel="stylesheet" href="style.css">
<script defer src="app.js"></script>
</head>
<body>
<h2>我的清单</h2>
<ul>
<li>学习笔记</li>
<li>工具推荐</li>
<li>友情链接</li>
</ul>
<h2>项目步骤</h2>
<ol>
<li>需求与原型</li>
<li>API 设计</li>
<li>联调与验收</li>
</ol>
</body>
</html>
```
@tab style.css
```css
ul, ol { margin: .5rem 0 1rem; padding-left: 1.5rem; }
li { margin: .25rem 0; }
```
@tab app.js
```js
document.querySelectorAll('li').forEach(li => li.addEventListener('click', () => li.classList.toggle('done')));
```
:::
**小作业:做一个“今日任务清单”**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>今日任务清单</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>今天要做的事</h1>
<ul>
<li>阅读 30 分钟</li>
<li>练习 1 个算法题</li>
<li>整理房间</li>
</ul>
</body>
</html>
```
@tab style.css
```css
body { font-family: system-ui; margin: 2rem; }
li { cursor: pointer; }
.done { text-decoration: line-through; color: #888; }
```
:::
## 五、语义化布局Header/Nav/Main/Section/Article/Aside/Footer
语义化标签让结构更清晰,搜索引擎更友好:
```html title="index.html"
<header>
<h1>我的网站</h1>
<nav>
<a href="/blog/">博客</a>
<a href="/notes/">笔记</a>
</nav>
<!-- 注意:更复杂的导航通常配合 CSS/JS 做响应式菜单 -->
<!-- 小提示:块级容器的外层仍可使用 <div> 来做网格或栅格布局 -->
<!-- 例如 <div class="container"> 包裹全站 -->
<!-- 只是这些语义标签会让搜索引擎更理解结构 -->
<!-- 语义标签与 <div> 并不冲突,可以配合使用 -->
<!-- 选择语义标签能让你的 HTML 更“有含义”而非只是分区 -->
<!-- 如果仅用于布局、无明确语义,用 <div> 即可 -->
<!-- 这段说明旨在帮助你建立语义化与布局之间的直觉 -->
<!-- 逐步养成好的结构化写法 -->
<!-- 让内容更可维护,更易被机器理解 -->
<!-- (继续往下看,还会介绍 Article/Section 等) -->
```
> 语义化标签的要点:这些标签表达了“这是什么内容”,而不是“怎么显示”。更容易被搜索引擎和读屏工具理解。
**小案例:语义化布局入门**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>语义化布局案例</title>
<link rel="stylesheet" href="style.css">
<script defer src="app.js"></script>
</head>
<body>
<header>
<h1>我的网站</h1>
<nav>
<a href="#home">首页</a>
<a href="#blog">博客</a>
</nav>
</header>
<main>
<section>
<h2>最新文章</h2>
<article>
<h3>用语义标签改造你的页面</h3>
<p>示例段落:用 header/nav/main/section/article/aside/footer 组织结构。</p>
</article>
</section>
<aside>
<h2>侧栏</h2>
<p>这里可以放导航、标签云或广告位。</p>
</aside>
</main>
<footer>© 2025 祀梦</footer>
</body>
</html>
```
@tab style.css
```css
body { font-family: system-ui; margin: 0; }
header, footer { padding: 1rem 2rem; background: #f7f7f7; }
nav { display: flex; gap: 1rem; }
main { display: grid; grid-template-columns: 1fr 240px; gap: 1rem; padding: 1rem 2rem; }
article { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
aside { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
```
@tab app.js
```js
document.querySelectorAll('nav a').forEach(a => a.addEventListener('click', () => {
document.querySelectorAll('nav a').forEach(x => x.classList.remove('active'));
a.classList.add('active');
}));
```
:::
**小作业:用语义标签搭一个博客首页**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>博客首页</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>博客名称</h1>
<nav>
<a href="#">首页</a>
<a href="#">归档</a>
<a href="#">关于</a>
</nav>
</header>
<main>
<section>
<article>
<h2>第一篇文章标题</h2>
<p>摘要内容……</p>
</article>
<article>
<h2>第二篇文章标题</h2>
<p>摘要内容……</p>
</article>
</section>
<aside>
<h2>侧栏</h2>
<p>分类、标签或个人简介。</p>
</aside>
</main>
<footer>© 2025 你的名字</footer>
</body>
</html>
```
@tab style.css
```css
/* 与案例类似的栅格布局样式 */
main { display: grid; grid-template-columns: 1fr 240px; gap: 1rem; padding: 1rem 2rem; }
article { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
aside { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
```
:::
## 六、表格Table/TR/TH/TD
```html title="index.html"
<table>
<thead>
<tr>
<th>姓名</th>
<th>职业</th>
</tr>
</thead>
<tbody>
<tr>
<td>祀梦</td>
<td>开发者</td>
</tr>
</tbody>
</table>
```
小提示:表格样式通常用 CSS 来美化(边框、间距、对齐等)。
**小案例:信息表格**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>信息表格案例</title>
<link rel="stylesheet" href="style.css">
<script defer src="app.js"></script>
</head>
<body>
<table>
<thead>
<tr><th>姓名</th><th>职业</th><th>城市</th></tr>
</thead>
<tbody>
<tr><td>祀梦</td><td>开发者</td><td>上海</td></tr>
<tr><td>小李</td><td>产品经理</td><td>杭州</td></tr>
<tr><td>小王</td><td>设计师</td><td>北京</td></tr>
</tbody>
</table>
</body>
</html>
```
@tab style.css
```css
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: .5rem .75rem; text-align: left; }
thead th { background: #f7f7f7; }
tbody tr:nth-child(odd) { background: #fafafa; }
```
@tab app.js
```js
document.querySelectorAll('tbody tr').forEach(tr => tr.addEventListener('click', () => tr.classList.toggle('highlight')));
```
:::
**小作业:制作“课程表”**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>课程表</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<table>
<thead>
<tr><th>时间</th><th>课程</th><th>教室</th></tr>
</thead>
<tbody>
<tr><td>周一 9:00</td><td>数学</td><td>A101</td></tr>
<tr><td>周三 14:00</td><td>英语</td><td>B302</td></tr>
<tr><td>周五 10:00</td><td>计算机</td><td>C210</td></tr>
</tbody>
</table>
</body>
</html>
```
@tab style.css
```css
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: .5rem .75rem; }
thead th { background: #f0f0f0; }
```
:::
## 七、媒体Audio/Video/Source
```html title="index.html"
<audio src="bgm.mp3" controls loop></audio>
<video src="intro.mp4" controls width="480" poster="cover.jpg" muted></video>
<!-- 常用属性controls / autoplay / loop / muted / poster封面 -->
```
补充说明:
- `controls` 提供播放控制;一般不建议隐藏,保证可用性。
- `autoplay` 可能被浏览器限制;若需自动播放,通常需同时设置 `muted`。
- `preload` 控制预加载策略(`none`/`metadata`/`auto`),根据页面性能需求选择。
- `poster` 为视频未播放时的封面图;音频没有封面属性。
- 使用 `<source>` 指定多种格式与 MIME 类型,提升兼容性:`<source src="xxx.mp4" type="video/mp4">`。
**小案例:嵌入音视频**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>媒体案例</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>背景音乐</h2>
<audio src="bgm.mp3" controls loop></audio>
<h2>介绍视频</h2>
<video src="intro.mp4" controls width="480" poster="cover.jpg" muted></video>
</body>
</html>
```
@tab style.css
```css
video { display: block; margin-top: .5rem; }
```
:::
**小作业:添加一段你喜欢的音乐与视频**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>我的媒体</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<audio src="music.mp3" controls></audio>
<video src="movie.mp4" controls width="480" poster="cover.jpg"></video>
</body>
</html>
```
@tab style.css
```css
audio, video { display: block; margin: .5rem 0; }
```
:::
## 八、全局常用属性(任何标签几乎都能用)
- `id`:唯一标识,用于 JS/CSS 精确选择。
- `class`:分组与样式选择(上一课已讲)。
- `style`:内联样式(不推荐大量使用,建议写到 CSS 文件)。
- `title`:悬停提示文字。
- `data-*`:自定义数据属性(如 `data-user-id="42"`)。
- `aria-*`:无障碍相关属性,帮助读屏工具理解(如 `aria-label`)。
**小案例:使用 id/class/data/title/aria**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>全局属性案例</title>
<link rel="stylesheet" href="style.css">
<script defer src="app.js"></script>
</head>
<body>
<button id="likeBtn" class="btn" title="点赞一下" data-count="0" aria-label="点赞">👍 喜欢</button>
<p id="msg" class="note" aria-live="polite">点击按钮试试。</p>
</body>
</html>
```
@tab style.css
```css
.btn { padding: .5rem .75rem; border: 1px solid #ccc; border-radius: 6px; background: #fff; }
.note { color: #555; }
```
@tab app.js
```js
const btn = document.getElementById('likeBtn');
const msg = document.getElementById('msg');
btn.addEventListener('click', () => {
const count = Number(btn.dataset.count || 0) + 1;
btn.dataset.count = String(count);
msg.textContent = `已点赞 ${count} 次`;
});
```
:::
**小作业:做一个带计数的按钮**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>计数按钮</title>
<link rel="stylesheet" href="style.css">
<script defer src="app.js"></script>
</head>
<body>
<button id="counter" class="btn" title="点击增加" data-count="0">点击我</button>
<p id="status" class="note">当前计数0</p>
</body>
</html>
```
@tab style.css
```css
.btn { padding: .5rem .75rem; border: 1px solid #ccc; border-radius: 6px; background: #fff; }
.note { margin-top: .5rem; }
```
@tab app.js
```js
const counter = document.getElementById('counter');
const statusEl = document.getElementById('status');
counter.addEventListener('click', () => {
const count = Number(counter.dataset.count || 0) + 1;
counter.dataset.count = String(count);
statusEl.textContent = `当前计数:${count}`;
});
```
:::
## 结尾:先结构清晰,再上样式与交互
写网页像搭房子先把房间结构标签安排好再选家具颜色CSS最后加智能设备JS
建议你先用这些常用标签做一个“个人名片页”,含标题、段落、头像图片、导航链接和一个简单表单。练熟后再加样式与交互。
**延伸阅读**
- HTML 规范与参考MDNhttps://developer.mozilla.org/en-US/docs/Web/HTML
- 无障碍与语义化https://developer.mozilla.org/en-US/docs/Glossary/Semantics

View File

@@ -0,0 +1,424 @@
---
title: HTML 常用标签与属性
createTime: 2025/11/2 19:30:00
permalink: /programming/web/basic-syntax/html-tags-attributes/
---
## 文本与标题H/P/Span/Strong/Em/Div
**标题**:从重要到不重要,`<h1>` ~ `<h6>`
```html title="index.html"
<h1>我的网站</h1>
<h2>关于我</h2>
<h3>联系方式</h3>
```
### 认识div标签
**什么是 `<div>`**
`<div>` 是 "division"(分区)的缩写,可以理解为网页中的"容器"或"盒子"。
想象一下搬家时的纸箱:
* 网页 = 整个房间
* `<div>` = 一个个纸箱
* 箱子里 = 可以放各种物品(文字、图片、按钮等)
### `<div>` 的基本特点
1. 块级元素
`<div>` 是块级元素,这意味着:
* 默认会占据整行的宽度
* 前后会自动换行
* 就像段落一样,每个`<div>`都会从新的一行开始
**`<div>` 本身没有特定含义,它只是用来分组和布局。**
### 为什么要使用 `<div>`
没有`<div>`的情况:
```html title='index.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦</title>
</head>
<body>
<h1>我的网站</h1>
<p>欢迎来到我的个人网站!</p>
<img src="photo.jpg" alt="我的照片">
<p>这是我的个人介绍...</p>
<button>联系我</button>
</body>
</html>
```
所有元素都堆在一起,很难分别控制样式。
使用 `<div>` 的情况:
```html title='index.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦</title>
</head>
<body>
<div class="header">
<h1>我的网站</h1>
<p>欢迎来到我的个人网站!</p>
</div>
<div class="content">
<img src="photo.jpg" alt="我的照片">
<p>这是我的个人介绍...</p>
</div>
<div class="footer">
<button>联系我</button>
</div>
</body>
</html>
```
这样我就可以分别控制每个部分的样式啦!
这个时候又有聪明的小朋友问了这个class是什么呀难道说是**起的名字!!**
太好了恭喜你答对了那么我们为什么要用class呢
### Class
Class 可以理解为给 HTML 元素起的"组名"或"类别名",让 CSS 能够精确地找到并美化特定的元素。
想象一个学校:
* HTML 元素 = 学生
* Class = 学生的身份(如"三年级一班"、"篮球队员"
* CSS = 老师,根据身份给学生安排不同的任务和服装
class基本用法此处就不举例了详情参照上面的代码。
如果没有class的情况
```html title='index.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦</title>
</head>
<body>
<h1>我的网站</h1>
<p>普通段落</p>
<p>个人介绍</p>
<p>重要提示</p>
<button>普通按钮</button>
<button>重要按钮</button>
</body>
</html>
```
如果我们想给"重要提示"和"重要按钮"设置特殊样式很难精确选择像之前我教的一样css直接用p或者h1来选择的话就无法区分具体每一段的区别了。
这时候就可以用class了
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仲夏夜之梦</title>
</head>
<body>
<h1>我的网站</h1>
<p class="normal">普通段落</p>
<p class="intro">个人介绍</p>
<p class="warning">重要提示</p>
<button class="normal-btn">普通按钮</button>
<button class="important-btn">重要按钮</button>
</body>
</html>
```
@tab style.css
```css
.warning {
color: red;
font-weight: bold;
}
.important-btn {
background-color: red;
color: white;
}
```
:::
**现在自己动手尝试一下**
## 动手练习:小作业
运用所学的 HTML 和 CSS 知识,创建一个美观的个人名片页面。不确定的时候翻翻文档
```html title='index.html'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 在这里添加字符编码和标题 -->
</head>
<body>
<!-- 创建一个名片容器 divclass 为 "card" -->
<!-- 在卡片内部分为三个区域: -->
<!-- 1. 头部区域:包含姓名和职位 -->
<div class="card-header">
<!-- 添加 h1 标题显示你的姓名 -->
<!-- 添加 p 段落显示你的职位或专业 -->
</div>
<!-- 2. 主体区域:包含联系信息 -->
<div class="card-body">
<!-- 添加至少3个联系信息使用 p 标签 -->
<!-- 例如:电话、邮箱、地址等 -->
</div>
<!-- 3. 底部区域:包含个人简介 -->
<div class="card-footer">
<!-- 添加一个个人简介段落 -->
</div>
</body>
</html>
```
css样式自定发挥自己的创作力创建一个独特的个人名片页面。
**段落与换行**
```html title="index.html"
<p>这是一个段落,里面可以有<strong>加粗</strong>和<em>强调</em>。</p>
<p>这是另一个段落。<br>需要换行时用 <code>&lt;br&gt;</code>。</p>
<hr> <!-- 水平分割线 -->
```
**行内 vs 块级**
- `<div>` 是块级元素(换行占整行),用于分区布局;
- `<span>` 是行内元素(不换行),用于强调局部文字。
使用建议与解释:
- 语义优先:`<strong>` 表示“语义上的重点”,`<b>` 仅表示“加粗外观”;`<em>` 表示“语气强调”,`<i>` 仅表示“斜体外观”。优先使用语义标签,样式交给 CSS。
- 标题层级:通常一个页面只有一个 `<h1>`,下面按层级组织为 `<h2>/<h3>...`。不要为求大小随意跳级或用标题替代普通文本。
- 段落与换行:换行请优先使用分段(`<p>`),只有在同段内需要视觉换行时使用 `<br>`。`<hr>` 适合用于内容分隔或主题切换。
**小案例:文本与标题**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>文本与标题案例</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>我的网站</h1>
<h2>关于我</h2>
<p>我是一名<strong>前端开发者</strong>,喜欢<em>简洁的设计</em>与清晰的结构。</p>
<hr>
<h3>联系方式</h3>
<p>Email: hello@example.com</p>
</body>
</html>
```
@tab style.css
```css
body { font-family: system-ui; margin: 2rem; }
h1 { font-size: 2rem; margin-bottom: .5rem; }
h2 { margin-top: 1.5rem; }
p { margin: .5rem 0; }
```
:::
**小作业:写一段个人简介**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>个人简介</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>你的名字</h1>
<h2>一句话介绍</h2>
<p>用两段文字,分别写你现在在做什么、你感兴趣的方向。</p>
<p>使用 <strong>strong</strong> 与 <em>em</em> 做重点强调。</p>
</body>
</html>
```
@tab style.css
```css
body { font-family: system-ui; margin: 2rem; line-height: 1.8; }
p { max-width: 60ch; }
```
:::
## 三、链接与图片A/IMG
### 什么是 `<img>` 标签
`<img>` 标签用于在网页中插入图片,它是自闭合标签(不需要结束标签)。
### `<img>` 标签的基本属性
* src指定图片的路径必填
* alt指定图片的替代文本必填用于图片加载失败时显示
* width指定图片的宽度可选
* height指定图片的高度可选
基本语法:
```html title='index.html'
<img src="photo.jpg" alt="我的照片" width="200" height="300">
```
### HTML 超链接
HTML 链接Anchor是网页之间跳转的核心部分。
HTML 使用链接与网络上的另一个文档相连。
HTML中的链接是一种用于在不同网页之间导航的元素。
链接通常用于将一个网页与另一个网页或资源(如文档、图像、音频文件等)相关联。
链接允许用户在浏览网页时单击文本或图像来跳转到其他位置,从而实现网页之间的互联。
HTML 链接 通过 `<a>` 标签创建,通常用于将用户从一个页面导航到另一个页面、从一个部分跳转到页面中的另一个部分、下载文件、打开电子邮件应用程序或执行 JavaScript 函数等。
超链接可以是一个字,一个词,或者一组词,也可以是一幅图像,可以点击这些内容来跳转到新的文档或者当前文档中的某个部分。
当把鼠标指针移动到网页中的某个链接上时,箭头会变为**一只小手**。
## `<a>` 标签的基本属性
* href指定链接的目标 URL必填
* target指定链接在何处打开可选
* _blank在新窗口或标签页中打开链接
* _self在当前窗口或标签页中打开链接默认
* _parent在父框架中打开链接
* _top在顶部框架中打开链接
基本语法:
```html title='index.html'
<a href="https://www.example.com">链接文本</a>
```
- `<a>` 标签定义了一个超链接anchor。它是 HTML 中用来创建可点击链接的主要标签。
- href 属性:指定目标 URL当点击链接时浏览器将导航到此 URL。
**这里还有一个target 属性**
- _blank在新窗口或标签页中打开链接
- _self在当前窗口或标签页中打开链接默认
- _parent在父框架中打开链接
- _top在顶部框架中打开链接
```html title='index.html'
<!DOCTYPE html>
<html>
<head>
<title>target属性示例</title>
</head>
<body>
<h2>target属性示例</h2>
<!-- 在当前窗口打开(默认) -->
<a href="https://www.baidu.com" target="_self">当前窗口打开</a>
<!-- 在新窗口打开 -->
<a href="https://www.baidu.com" target="_blank">新窗口打开</a>
<!-- 在父窗口打开 -->
<a href="https://www.baidu.com" target="_parent">父窗口打开</a>
<!-- 建议:新窗口打开外部链接 -->
<a href="https://www.example.com" target="_blank" rel="noopener">
外部网站(安全的新窗口)
</a>
</body>
</html>
```
复制代码到自己的html文件中尝试一下不同的target属性值。
常用属性:
- `href`:目标地址;
- `target="_blank"`:新窗口打开;
- `rel="noopener"`:安全与性能(避免旧窗口被新页面控制)。
补充说明:
- 链接安全:外链新窗口打开时同时设置 `rel="noopener"` 或 `rel="noreferrer"`,避免安全与性能问题。
- 图片可使用 `loading="lazy"` 懒加载,减少首屏资源压力;`alt` 请写出图片用途或内容摘要。
- 设定 `width/height` 可以预留占位减少页面布局抖动CLS。复杂场景可考虑 `<picture>` + `<source>` 做响应式图片。
- 与图片相关的配套标签:`<figure>` + `<figcaption>` 用于图片与说明文字的组合。
**小案例:链接与图片**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>链接与图片案例</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav>
<a href="/" >首页</a>
<a href="https://developer.mozilla.org/" target="_blank" rel="noopener">MDN</a>
</nav>
<img src="avatar.jpg" alt="我的头像" width="160" height="160">
</body>
</html>
```
@tab style.css
```css
nav { display: flex; gap: 1rem; margin-bottom: 1rem; }
nav a { color: #06c; text-decoration: none; }
nav a:hover { text-decoration: underline; }
img { border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,.1); }
```
:::
**小作业:做一个“友链”与头像区块**
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>友链与头像</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section>
<h2>友情链接</h2>
<p>
<a href="https://notes.simengweb.com" target="_blank" rel="noopener">祀梦笔记</a>
·
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue.js</a>
</p>
</section>
<section>
<h2>头像</h2>
<img src="avatar.jpg" alt="你的头像" width="160" height="160">
</section>
</body>
</html>
```
@tab style.css
```css
section { margin-bottom: 1rem; }
img { border: 2px solid #eee; border-radius: 50%; }
```
:::

View File

@@ -0,0 +1,606 @@
---
title: JavaScript 基础知识
createTime: 2025/11/2 21:30:00
permalink: /programming/web/basic-syntax/javascript-basics/
---
## JavaScript 是什么?
JavaScript 是一种广泛用于网页开发的脚本语言,它使网页能够实现交互式功能。与 HTML负责结构和 CSS负责样式不同JavaScript 专注于**行为**,可以让网页变得动态和响应式。
## 第一个 JavaScript 程序
JavaScript 代码可以直接写在 HTML 文件中,通常放在 `<body>` 标签的底部,使用 `<script>` 标签包裹。
```html title="index.html"
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>我的第一个 JavaScript 程序</title>
</head>
<body>
<h1>你好,世界!</h1>
<script>
// 这是注释,不会被执行
console.log('Hello, JavaScript!'); // 在控制台输出文本
alert('欢迎学习 JavaScript'); // 弹出提示框
</script>
</body>
</html>
```
**提示**:你可以在浏览器中按下 F12 打开开发者工具,然后切换到 "Console" 标签查看 `console.log()` 的输出。
`console.log()` 是 JavaScript 中最常用、最重要的调试工具,可以说是每个开发者的"最佳朋友"
### 基本输出 ###
```javascript
// 输出字符串
console.log("Hello World!");
// 输出变量
const name = "小明";
console.log(name);
// 输出多个值
const age = 18;
const isStudent = true;
console.log("学生信息:", name, age, isStudent);
```
### 输出不同类型的数据 ###
```javascript
// 各种数据类型
console.log("字符串:", "Hello");
console.log("数字:", 42);
console.log("布尔值:", true);
console.log("数组:", [1, 2, 3]);
console.log("对象:", {name: "李华", age: 20});
console.log("函数:", function() {});
console.log("undefined:", undefined);
console.log("null:", null);
```
### 字符串插值 ###
```javascript
const userName = "张三";
const userAge = 25;
const score = 95.5;
// 传统方式
console.log("用户 " + userName + " 年龄 " + userAge + " 分数 " + score);
// 模板字符串(推荐)
console.log(`用户 ${userName} 年龄 ${userAge} 分数 ${score}`);
// 带表达式的插值
console.log(`${userName} 是 ${userAge >= 18 ? "成年人" : "未成年人"}`);
```
### 格式化输出 ###
```javascript
const product = {
name: "笔记本电脑",
price: 5999,
brand: "Dell",
inStock: true
};
// %s - 字符串
console.log("产品名称: %s", product.name);
// %d - 数字
console.log("价格: %d 元", product.price);
// %f - 浮点数
console.log("折扣价: %f", product.price * 0.9);
// %o - 对象
console.log("完整产品信息: %o", product);
// %c - CSS样式
console.log("%c重要信息!", "color: red; font-size: 20px; font-weight: bold;");
```
## JavaScript 变量
变量是用来存储信息的容器。在 JavaScript 中,我们使用 `let`、`const` 或 `var` 关键字来声明变量。
### 变量声明方式
```javascript
// 使用 let 声明可变变量
let name = "小明";
name = "小红"; // 可以修改
// 使用 const 声明常量(不可变)
const PI = 3.14159;
// PI = 3.14; // 错误!常量不能修改
// 使用 var 声明变量(旧方式,现在推荐使用 let 和 const
var age = 25;
```
**注意**
- 使用 `let` 声明的变量可以重新赋值
- 使用 `const` 声明的变量不能重新赋值(常量)
- 尽量避免使用 `var`,因为它有一些奇怪的作用域规则
## 数据类型
JavaScript 有几种基本数据类型:
### 1. 字符串String
用于表示文本,可以使用单引号或双引号。
```javascript
const greeting = "你好";
const name = 'JavaScript';
const message = `${greeting}, ${name}!`; // 使用模板字符串ES6 特性)
console.log(message); // 输出:你好, JavaScript!
```
### 2. 数字Number
用于表示数值。
```javascript
const age = 25;
const price = 99.99;
const PI = 3.14159;
```
### 3. 布尔值Boolean
用于表示真或假,只有两个值:`true` 和 `false`。
```javascript
const isStudent = true;
const hasGraduated = false;
```
### 4. 数组Array
用于存储多个值的集合。
```javascript
const fruits = ["苹果", "香蕉", "橙子"];
console.log(fruits[0]); // 输出苹果数组索引从0开始
// 添加元素
fruits.push("葡萄");
console.log(fruits); // 输出:["苹果", "香蕉", "橙子", "葡萄"]
```
### 5. 对象Object
用于存储键值对集合。
```javascript
const person = {
name: "小明",
age: 25,
isStudent: true,
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
console.log(person.name); // 输出:小明
person.greet(); // 输出:你好,我是小明!
```
## 运算符
### 算术运算符
```javascript
const a = 10;
const b = 5;
console.log(a + b); // 15 加法
console.log(a - b); // 5 减法
console.log(a * b); // 50 乘法
console.log(a / b); // 2 除法
console.log(a % b); // 0 取余
console.log(a ** b); // 100000 幂运算ES6
```
### 赋值运算符
```javascript
const x = 10;
x += 5; // 等同于 x = x + 5
console.log(x); // 15
x -= 3; // 等同于 x = x - 3
console.log(x); // 12
```
### 比较运算符
```javascript
const a = 10;
const b = 5;
console.log(a > b); // true
console.log(a < b); // false
console.log(a >= b); // true
console.log(a <= b); // false
console.log(a === b); // false严格相等比较值和类型
console.log(a == b); // false宽松相等只比较值
console.log(a !== b); // true严格不相等
```
## 条件语句
### if 语句
```javascript
const age = 18;
if (age >= 18) {
console.log("你已经成年了!");
} else if (age >= 13) {
console.log("你是青少年。");
} else {
console.log("你还是个孩子。");
}
```
## 循环
### for 循环
```javascript
// 打印1到5
for (const i = 1; i <= 5; i++) {
console.log(i);
}
// 遍历数组
const fruits = ["苹果", "香蕉", "橙子"];
for (const i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 使用 for...of 遍历ES6
for (const fruit of fruits) {
console.log(fruit);
}
```
### while 循环
```javascript
const count = 1;
while (count <= 5) {
console.log(count);
count++;
}
```
## 函数
函数是一段可重复使用的代码块,可以接受输入(参数),执行操作,并返回输出(返回值)。
### 函数声明
```javascript
function greet(name) {
return `你好,${name}`;
}
const message = greet("小明");
console.log(message); // 输出:你好,小明!
```
格式如下
```javascript
function 函数名(参数1, 参数2, ...参数N) {
// 函数体:要执行的代码
return 返回值; // 可选
}
```
### 箭头函数ES6
```javascript
const sum = (a, b) => {
return a + b;
};
// 简化写法(当只有一行返回语句时)
const multiply = (a, b) => a * b;
console.log(sum(3, 4)); // 7
console.log(multiply(3, 4)); // 12
```
## DOM 操作
DOM文档对象模型是 HTML 和 XML 文档的编程接口。JavaScript 可以通过 DOM 来操作网页元素。
### 选择元素
```javascript
// 通过 id 选择元素
const title = document.getElementById("title");
// 通过 class 选择元素(返回元素集合)
const items = document.getElementsByClassName("item");
// 通过标签名选择元素
const paragraphs = document.getElementsByTagName("p");
// 通过 CSS 选择器选择元素ES5+
const header = document.querySelector("header"); // 选择第一个匹配的元素
const allLinks = document.querySelectorAll("a"); // 选择所有匹配的元素
```
### 修改元素内容
```javascript
// 修改文本内容
const title = document.getElementById("title");
title.textContent = "新标题";
// 修改 HTML 内容
title.innerHTML = "<strong>加粗的新标题</strong>";
```
### 修改元素样式
```javascript
const element = document.getElementById("box");
element.style.color = "red";
element.style.fontSize = "20px";
element.style.backgroundColor = "#f0f0f0";
```
### 添加事件监听器
```javascript
const button = document.getElementById("myButton");
button.addEventListener("click", function() {
console.log("按钮被点击了!");
alert("你好,欢迎使用!");
});
```
## 小案例:交互式计算器
下面是一个简单的交互式计算器示例,演示如何结合 HTML、CSS 和 JavaScript。
::: code-tabs
@tab index.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>简易计算器</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="calculator">
<h2>简易计算器</h2>
<input type="number" id="num1" placeholder="输入第一个数字">
<select id="operation">
<option value="add">+</option>
<option value="subtract">-</option>
<option value="multiply">×</option>
<option value="divide">÷</option>
</select>
<input type="number" id="num2" placeholder="输入第二个数字">
<button id="calculate">计算</button>
<div id="result">结果将显示在这里</div>
</div>
<script src="script.js"></script>
</body>
</html>
```
@tab style.css
```css
.calculator {
max-width: 300px;
margin: 2rem auto;
padding: 1.5rem;
border: 1px solid #ddd;
border-radius: 8px;
text-align: center;
font-family: system-ui;
}
input, select, button {
margin: 0.5rem 0;
padding: 0.5rem;
width: 100%;
box-sizing: border-box;
}
button {
background: #007bff;
color: white;
border: none;
cursor: pointer;
border-radius: 4px;
}
button:hover {
background: #0056b3;
}
#result {
margin-top: 1rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 4px;
}
```
@tab script.js
```javascript
// 获取DOM元素
const num1Input = document.getElementById('num1');
const num2Input = document.getElementById('num2');
const operationSelect = document.getElementById('operation');
const calculateButton = document.getElementById('calculate');
const resultDiv = document.getElementById('result');
// 添加点击事件监听器
calculateButton.addEventListener('click', function() {
// 获取输入值
const num1 = parseFloat(num1Input.value);
const num2 = parseFloat(num2Input.value);
const operation = operationSelect.value;
const result;
// 检查输入是否有效
if (isNaN(num1) || isNaN(num2)) {
resultDiv.textContent = '请输入有效的数字!';
return;
}
// 执行计算
switch (operation) {
case 'add':
result = num1 + num2;
break;
case 'subtract':
result = num1 - num2;
break;
case 'multiply':
result = num1 * num2;
break;
case 'divide':
// 检查除数是否为0
if (num2 === 0) {
resultDiv.textContent = '除数不能为0';
return;
}
result = num1 / num2;
break;
}
// 显示结果
resultDiv.textContent = `计算结果:${result}`;
});
```
:::
## JavaScript 的异步编程
JavaScript 是单线程的,但它可以通过异步编程模型来处理耗时操作,如网络请求、定时器等。
### setTimeout 和 setInterval
```javascript
// setTimeout - 延迟执行一次
setTimeout(function() {
console.log('2秒后执行');
}, 2000);
// setInterval - 定期重复执行
const count = 0;
const timer = setInterval(function() {
count++;
console.log(`执行第 ${count} 次`);
if (count >= 5) {
clearInterval(timer); // 清除定时器
console.log('定时器已停止');
}
}, 1000);
```
### PromiseES6
Promise 是异步编程的一种解决方案,用于处理异步操作。
```javascript
// 创建一个Promise
const fetchData = new Promise((resolve, reject) => {
// 模拟网络请求
setTimeout(() => {
const success = true;
if (success) {
resolve('数据获取成功');
} else {
reject('数据获取失败');
}
}, 2000);
});
// 使用Promise
fetchData
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
```
## 常见错误和调试技巧
### 常见错误
1. **语法错误**:代码不符合 JavaScript 语法规则
2. **引用错误**:使用了未定义的变量或函数
3. **类型错误**:对错误类型的值进行操作
4. **范围错误**:数值超出有效范围
### 调试技巧
1. **使用 console.log()**:在控制台输出变量值或执行流程
2. **使用断点**:在浏览器开发者工具中设置断点,逐步执行代码
3. **检查错误信息**:仔细阅读错误提示,找出问题所在
4. **检查变量类型**:使用 `typeof` 操作符检查变量类型
```javascript
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"(数组也是对象的一种)
```
## 实践练习
### 练习1创建一个简单的待办事项列表
使用 HTML、CSS 和 JavaScript 创建一个待办事项列表,包含添加、删除和标记完成功能。
提示:
- 使用数组存储待办事项
- 使用 DOM 操作动态更新列表
- 为按钮添加事件监听器
### 练习2实现一个数字猜谜游戏
计算机随机生成一个1到100之间的数字玩家通过输入框猜测程序提示"猜大了"或"猜小了",直到猜对为止。
提示:
- 使用 `Math.random()` 生成随机数
- 使用条件语句判断猜测结果
- 记录并显示猜测次数
## 总结
JavaScript 是现代 web 开发的核心技术之一,它可以让网页变得动态和交互。通过学习变量、数据类型、运算符、条件语句、循环、函数和 DOM 操作等基础知识,你已经迈出了学习 JavaScript 的第一步。
继续练习和探索,你会发现 JavaScript 的强大功能和灵活性!

View File

@@ -0,0 +1,22 @@
---
title: 英语学习笔记
createTime: 2025/10/20 16:34:20
permalink: /subject/english/
---
# 英语学习笔记
这是一个英语学习笔记的总览页。下面是目录与分区入口:
## 目录
- 学习环境与工具 → `/subject/english/basis/`
- 词汇与记忆 → `/subject/english/vocabulary/`
- 语法与句法 → `/subject/english/grammar/`
- 听力与口语 → `/subject/english/listening-speaking/`
- 阅读 → `/subject/english/reading-writing/`
- 考试与备考(含四级) → `/subject/english/exam/cet-4/`
- 学习资源与工具 → `/subject/english/resources/`
- 写译 → `/subject/english/writing-translation/`
你可以从以上入口进入对应的专题,随时扩展各章节内容。

View File

@@ -0,0 +1,15 @@
---
title: 英语环境配置
createTime: 2025/10/20 16:34:20
permalink: /subject/english/basis/
---
# 英语环境配置
这里是英语学习的入门环境配置示例模版:
- 推荐词典与工具
- 输入法与语音资源
- 常用学习网站与 App
你可以按需补充具体内容。

View File

@@ -0,0 +1,42 @@
---
title: 英语四级 (CET-4) 备考指南
createTime: 2025/10/20 16:42:00
permalink: /subject/english/exam/cet-4/
---
# 英语四级 (CET-4) 备考指南
## 考试结构概览
- 听力 (25%):新闻、长对话、讲座/采访
- 阅读 (35%):仔细阅读、选词填空
- 翻译 (15%):汉译英
- 写作 (25%):应用文与观点写作
## 核心备考策略
- 词汇:高频词与真题语块,使用 SRS 间隔重复
- 语法:时态、非谓语、从句,针对写作与翻译的准确表达
- 听力:精听 + 跟读shadowing积累场景表达
- 阅读:结构化分析段落逻辑,题型定位与干扰项识别
- 写作:模板+素材库+改写练习,关注连贯与准确
## 时间分配建议
- 写作 30 分钟:审题→列纲→写作→快速校对
- 阅读 40 分钟:定位→分析→作答→标记不确定
- 听力 按机考节奏:提前熟悉说明与做题界面
- 翻译 20 分钟:分句翻译→语法检查→润色
## 真题与模拟
- 使用近 3-5 年真题按套训练;分析错因并归档到词汇/语法/方法类别
- 每周至少一次全真模拟,记录分配与状态调整
## 考场技巧
- 先易后难;不确定题目标记后回看
- 注意题干限制词与语义线索especially/only/not/except 等)
- 写作与翻译建议使用简单准确句式,避免长难句错误
## 推荐资源
- 真题:教育部考试中心官方题库与解析
- 听力BBC 6 Minute English、VOA Learning English
- 写作:常用应用文格式与常见开头结尾句
> 后续我会补充各模块的详细练习清单与示例。

View File

@@ -0,0 +1,84 @@
---
title: 核心语法与句型
createTime: 2025/10/20 16:40:00
permalink: /subject/english/grammar/
---
# 核心语法与句型
## 时态与语态
- 16 种时态的构成与用法(一般/进行/完成/完成进行 × 现在/过去/将来/过去将来)
- 被动语态的转换规则与适用场景
- 时态一致原则(主将从现、过去时一致等)
- 情态动词 + 完成体must have done / should have done 等)的推测与虚拟含义
## 从句
### 名词性从句
- 主语从句That he failed surprised us. / Whether she comes matters.
- 宾语从句I think (that) you are right.
- 表语从句The truth is that he lied.
- 同位语从句The fact that he lied shocked us.
### 定语从句
- 限定性 vs. 非限定性
- 关系代词who / whom / whose / which / that与关系副词when / where / why
- 介词 + 关系代词the house in which I live
- 省略与替代the book (that) I bought; the place (where) we met
### 状语从句
- 时间when / while / before / after / as soon as / until
- 条件if / unless / provided that / on condition that
- 让步though / although / even if / while
- 原因because / since / as / now that
- 结果so...that / such...that
- 目的so that / in order that
- 比较than / as...as / the more...the more
## 非谓语动词
- 不定式to do作主语、宾语、定语、状语、补语
- 动名词doing作主语、宾语、表语、定语
- 现在分词doing与过去分词done作定语、状语、补语、表语
- 独立主格结构with + O + OC; N + doing / done...
- 非谓语动词的时态与语态to be doing / to have done / being done / having been done
## 倒装与虚拟
### 倒装
- 否定副词置前Never have I seen...
- Only + 状语置前Only then did I realize...
- So / Such 置前So fast did he run that...
- 方位/时间副词置前Out rushed the children.
- 虚拟条件句省略 ifWere I you... / Had I known...
### 虚拟语气
- 与现在事实相反If I were you, I would...
- 与过去事实相反If I had known, I would have...
- 与将来事实相反If it should rain tomorrow...
- 省略 if 的倒装Were / Should / Had...
- 含蓄虚拟without / but for / otherwise
- 名词性从句中的虚拟insist that... (should) do; It is important that... (should) do
## 句式与信息焦点
### 强调结构
- It is / was...that / who...It was John that/who broke the window.
- 助动词 do / does / didShe did tell me the truth.
- 副词强调absolutely / definitely / simply
### 分裂句Cleft Sentence
- 主语分裂What I need is time.
- 宾语分裂What he bought was a Ferrari.
- 状语分裂Where we met was in Paris.
### 平行与省略
- 并列结构中的省略He likes tea and she coffee.
- 比较结构中的省略I like her better than him.
- 替代do / so / one / that / those
### 插入语与同位语
- 破折号、括号、逗号插入The book—which I bought yesterday—is amazing.
- 同位语短语Mr. Smith, CEO of the company, will attend.
### 长难句拆解策略
- 找谓语,定主干
- 划从句,标连接词
- 去插入,还省略
- 调语序,还原文

View File

@@ -0,0 +1,89 @@
---
title: 听力口语训练
createTime: 2025/10/20 16:40:00
permalink: /subject/english/listening-speaking/
---
# 听力口语训练
- 音素与连读弱读
- 听力材料选择与精听泛听
- 跟读与复述shadowing & retelling
- 场景对话与表达
## 自然拼读法Phonics
Phonics自然拼音或叫“英语自然拼读法”更容易理解。拼读什么就是看到英文字母或字母的组合能自然地读出、读对它的发音。这里首先要区分“读音”(Name)与“发音”(Sound)。A-Z的26个字母几乎大家都认识、都能念出来而念出来的就是字母本身的“读音”而自然发音指的是字母的“发音”。发音不同于读音。看到字母后不管读音找对发音。这就Phonics要学的。理论可以讲很多很深但Phonics注重的是方法与实践。因此知道怎么正确发音就行了。
下面给你放一个基本发音规则的表,虽然看不到完整版但是足够了也足够大致理解发音规律了
```
https://wenku.so.com/tfd/b97611df865df13967a3b93a66d9e904?src=360ss&ocpc_id=139916&plan_id=2327941041&group_id=687803892&keyword=%E8%8B%B1%E8%AF%AD%E8%87%AA%E7%84%B6%E6%8B%BC%E8%AF%BB%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88%E5%8F%91%E9%9F%B3&qhclickid=2ee0322320520786
```
英文的26个字母分为元音和辅音其中元音只有5个即aeiou其余字母均为辅音。
对于大多数辅音来说,它们的发音是一对一的,而有少数几个辅音字母,每个字母有两个或以上的发音。
### 二、有多个发音的辅音
#### c 字母
c后面接aou的时候c的发音与字母k发音相同叫做“hard c sound”
```
cat, capcallcoatcup
```
当字母c后面接ei或y的时候通常c的发音与字母s发音相同叫做“soft c sound”
```
city, ice, rice, face, cell, cent, voice, pencil, juice
```
有时在e或i前面c会发/sh/音:
```
ocean, racial, social
```
#### g 字母
g后面接aou的时候所发的音叫做“hard g sound”
```
girl, gas, get, give, go
```
当字母g后面接ei或y的时候有时g的发音与字母j的发音相同叫做“soft g sound”
```
age, change, ginger, Egypt, gentle, giraffe, badge
```
特例forget, give, girl中的g发hard sound。
#### x 字母
x在单词中间或结尾时发/ks/音:
```
box, next, fix, mix, tax
```
x在单词中间时有时发/gz/音:
```
exit, exam, exact
```
x在单词起始位置时发/z/音:
```
xylophone, xerox。
```
#### y 字母
y在单词起始位置时发音为辅音
```
yes, you, yard, year, yell
```
y在单词或音节中间或结尾时被当做元音
y在结尾单词只有一个音节时y发长/i/音y在结尾单词有两个或以上音节时y发长/e/音y在单词或音节中间时发短/i/音。
- 小测试:
- my, cry, fly, sky, baby, happy
- puppy, hurrygym, nymph

View File

@@ -0,0 +1,11 @@
---
title: 阅读提升
createTime: 2025/10/20 16:40:00
permalink: /subject/english/reading-writing/
---
# 阅读提升
- 阅读策略(略读、扫读、精读)
- 篇章结构与逻辑(指代、连接、修饰)

View File

@@ -0,0 +1,50 @@
---
title: 学习资源与工具
createTime: 2025/10/20 16:40:00
permalink: /subject/english/resources/
---
# 学习资源与工具
- 词典与语法书:牛津、朗文、柯林斯
- 学习 App扇贝、欧路、Grammarly
- 新闻来源BBC、VOA、The Economist
- 社区与练习Reddit、StackExchange English、写作论坛
## 每日读物
希望每天都能读一篇简单的小文章,将不会的单词标出,不理解的句子记下来。通过有道词典等工具查询后能够自己理解并通读。
### 下面是今日份读物推荐~
解析将稍后更新~
### 2025.10.27
```
https://web.shanbay.com/reading/web-news/articles/umxci
```
复制链接至浏览器后点击APP内打开点击短文登陆注册后找到这篇文章可读性更强且自带单词查询功能
不过个人建议先盲读,尝试用自己认识的单词推理拼凑一篇文章吧~
#### Study Finds Minimal Link Between phone Use and Adult Well-Being
Despite previous findings, Oregon-led research has determined that smartphone use isn't necessarily related to the well-being of adults.
The study conducted by the University of Oregon and Google Research found that younger adults experience lower moods when using social media in one particular stance, but the link between mental health and digital surfing was "either weak or statistically insignificant" when assessing longer time periods.
According to UO, Nicholas Allen — a psychology professor and director of the Center for Digital Mental Health — led the team that conducted the study.For four weeks, researchers recorded the smartphone activity and daily moods of more than 10,000 participants who were at least 18 years of age.
The university noted that previous studies have included self-reported data, which scientists claimed aren't as reliable.
"Our findings challenge the popular assumption that smartphone use is inherently harmful to mental health and well-being," Allen said in a release."There's been a lot of public concern and policy discussion often based on small, self-reported studies.This large-scale, objective data suggests the relationship is far more nuanced and, in most cases, minimal — at least over this time frame."
The findings, which were published in the National Library of Medicine earlier this week, show that demographics like age and gender were more likely to negatively impact mental well-being than smartphone usage.Notably, researchers discovered that younger adults and women experienced lower moods despite how often they surfed social media.
"Smartphones are part of the context of our daily lives; they're not inherently good or bad.The key is understanding how people use them and how technology can be designed to support well-being rather than detract from it," Allen added.
#### 将生词整理到纸或本子上吧~熟记这些单词和使用时的语境会在你意想不到的时候帮助到你哦!

View File

@@ -0,0 +1,12 @@
---
title: 词汇学习与记忆法
createTime: 2025/10/20 16:40:00
permalink: /subject/english/vocabulary/
---
# 词汇学习与记忆法
- 高频词与词根词缀
- 主题词汇(校园、科技、社会等)
- 间隔重复SRS与记忆曲线
- 固定搭配与语块collocations & chunks

View File

@@ -0,0 +1,11 @@
---
title: 写译
createTime: 2025/10/22 10:26:07
permalink: /subject/english/writing-translation/
---
# 写译
- 写作模板与常用句式
- 改写与润色(句式多样化、语法准确性)
- 翻译(语法、词汇、上下文)

View File

@@ -0,0 +1,193 @@
---
title: 密码学基础
createTime: 2025/10/27 10:38:57
permalink: /theory/cryptography/
---
# 密码学基础
## 1. 密码学的定义
### 1.1 基本概念
**密码学Cryptography** 是一门研究信息安全的学科,主要关注如何在不安全的环境中实现安全通信。其核心是通过数学方法对信息进行变换,使得只有授权方能够理解信息内容。
### 1.2 核心目标
密码学追求以下四个主要安全目标:
- **机密性Confidentiality**:确保信息只能被授权的人访问
- **完整性Integrity**:确保信息在传输过程中不被篡改
- **认证性Authentication**:确认通信双方的身份真实性
- **不可否认性Non-repudiation**:防止发送方事后否认发送过信息
### 1.3 重要作用
密码学在现代信息安全中扮演着至关重要的角色:
- 保护个人隐私和商业机密
- 确保金融交易的安全性
- 维护国家安全和军事通信
- 支撑互联网基础设施的安全运行
### 1.4 主要应用场景
- **网络安全**HTTPS、VPN、SSL/TLS协议
- **数字身份认证**:数字证书、数字签名、双因素认证
- **区块链技术**:加密货币、智能合约、分布式账本
- **移动通信**SIM卡加密、移动支付安全
- **物联网安全**:设备身份认证、数据传输加密
### 1.5 基础概念与术语(入门)
为方便初学者快速建立直觉,先认识密码学中最核心的几个概念:
**明文Plaintext与密文Ciphertext**
- 明文未加密的原始消息例如“HELLO”。
- 密文:加密后的消息,人类或未授权系统难以直接理解。
**加密Encryption与解密Decryption**
- 加密:用密钥将明文转换为密文,记为:
$$
C = E_k(P)
$$
- 解密:用密钥将密文还原为明文,记为:
$$
P = D_k(C)
$$
其中,$P$ 表示明文,$C$ 表示密文,$k$ 表示密钥,$E$ 为加密算法,$D$ 为解密算法。
**密钥Key对称密钥 vs 非对称密钥**
- 对称密钥:加密和解密使用相同的密钥,速度快,但密钥分发与管理是难点。
- 非对称密钥(公钥密码):加密使用“公钥”,解密使用“私钥”,便于密钥分发,还能支持数字签名。
对称加密流程示意(同一把密钥):
```mermaid
flowchart LR
S[发送者] -- 使用共享密钥 K 加密 --> C[(密文)]
C -- 使用共享密钥 K 解密 --> R[接收者]
```
非对称加密流程示意(公钥/私钥):
```mermaid
flowchart LR
S[发送者] -- 使用接收者公钥加密 --> C[(密文)]
C -- 使用接收者私钥解密 --> R[接收者]
```
在典型的 RSA 公钥体制中,还可以用一个简洁的数学表达式表示加解密:
$$
\begin{aligned}
c &= m^{e} \bmod n,\\
m &= c^{d} \bmod n,
\end{aligned}
$$
其中 $(e, n)$ 为公钥,$(d, n)$ 为私钥,$m$ 为明文,$c$ 为密文。
**常见攻击模型简介(只需直观理解)**
- 唯密文攻击COA攻击者只有密文尝试恢复明文或密钥。
- 已知明文攻击KPA攻击者拥有部分“明文-密文”对,用于分析算法或密钥。
- 选择明文攻击CPA攻击者可选择明文并获取其密文用于推断密钥或算法结构。
- 选择密文攻击CCA攻击者可选择密文并得到其解密结果进一步分析系统弱点。
直观结论:设计良好的现代密码系统,应当在这些攻击模型下仍保持安全(在合理的参数与假设下)。
## 2. 密码学历史简述
### 2.1 古代密码学(公元前-15世纪
**凯撒密码Caesar Cipher**
- 时间公元前1世纪
- 原理:字母移位加密
- 示例将字母向后移动3位A→DB→E
**斯巴达密码棒Scytale**
- 时间公元前5世纪
- 原理:缠绕在特定直径木棒上的皮条
古典密码简述:
- 核心思路:替换或移位(重新排列)字符。
- 代表示例:凯撒(替换)、栅栏(移位)、维吉尼亚(多表替换)。
- 直觉目标:混淆结构、增加猜测难度;但易受频率分析。
### 2.2 文艺复兴时期15-18世纪
**维吉尼亚密码Vigenère Cipher**
- 时间16世纪
- 原理:多表替换密码
- 特点:比单表替换更安全
**博福特密码Beaufort Cipher**
- 时间18世纪
- 原理:改进的维吉尼亚密码
### 2.3 近代密码学19-20世纪中期
**恩尼格玛密码机Enigma**
- 时间:二战时期
- 原理:机械转子密码机
- 重要性:推动了现代密码分析的发展
**香农的信息论**
- 时间1949年
- 贡献:为密码学奠定了数学理论基础
### 2.4 现代密码学1970年代至今
**DES算法**
- 时间1977年
- 意义:第一个公开的加密标准
**RSA算法**
- 时间1977年
- 意义:第一个实用的公钥密码系统
**AES算法**
- 时间2001年
- 意义取代DES的新一代加密标准
现代密码简述:
- 对称加密同一密钥加解密适合大量数据示例AES/DES/3DES
$$
C = E_k(P), \quad P = D_k(C)
$$
- 非对称加密公钥加密、私钥解密便于密钥分发与数字签名示例RSA/ECC
$$
c = m^{e} \bmod n, \quad m = c^{d} \bmod n
$$
- 密钥交换DiffieHellman 在不安全信道建立共享密钥。
- 数字签名:私钥签名、公钥验证,保障真实性与不可否认性。
### 2.5 关键历史时间线
```
公元前5世纪斯巴达密码棒
公元前1世纪凯撒密码
16世纪维吉尼亚密码
1918年一次一密密码本
1949年香农信息论
1977年DES和RSA算法
2001年AES标准
```
## 总结
密码学作为信息安全的基石,经历了从简单替换到复杂数学算法的漫长发展历程。现代密码学建立在严格的数学基础之上,通过对称加密、非对称加密等多种技术手段,为数字世界提供了可靠的安全保障。
理解密码学的基本原理和分类,有助于我们更好地应用这些技术来保护信息安全,同时也为深入学习更高级的密码学概念奠定基础。
本篇笔记的所有代码开源于:[https://gitea.simengweb.com/si-meng-spec/cryptography-example-code](https://gitea.simengweb.com/si-meng-spec/cryptography-example-code)

View File

@@ -0,0 +1,107 @@
---
title: 置换密码 - 等待完善
createTime: 2025/10/29 13:50:49
permalink: /theory/cryptography/permutation-encryption/
---
# 置换密码Permutation / Transposition Ciphers
置换密码的核心思想不是“把字母换成别的字母”(替换),而是**重新排列明文字符的位置**。也就是说:
- 明文字母的集合不变,顺序发生了改变;
- 由于字母频率不变,置换密码依然会暴露统计特征,但单词的结构与位置模式被打散。
与“替换密码”相比,置换密码更像是“洗牌”:把原本顺序排列的牌重新打乱。单独使用时并不安全,但与替换联合使用(乘积密码)能显著增强安全性。
```mermaid
flowchart LR
P[明文] --> A{根据密钥生成位置}
A --> B[重新排列字符]
B --> C[密文]
```
## 一、栅栏密码Rail Fence Cipher
**工作原理**
将明文按“Z字形”写入若干行称为“栅栏/轨道”),再按行依次读出即得到密文。轨道数即为密钥。
**示意**(以 3 轨为例):
```
轨1: 0 4 8 ...
轨2: 1 3 5 7 9 ...
轨3: 2 6 ...
```
**示例**
明文:`HELLOWORLD`
轨道数:`3`
- 轨1索引 0,4,8`H O L`
- 轨2索引 1,3,5,7,9`E L W R D`
- 轨3索引 2,6`L O`
密文为各轨串联:`HOL` + `ELWRD` + `LO``HOLELWRDLO`
**数学表示**
设明文 $P = p_0 p_1 \dots p_{n-1}$,根据密钥生成一个位置序列 $s_0, s_1, \dots, s_{n-1}$(即置换次序),则:
$$
C_j = p_{s_j}, \quad j = 0,1,\dots,n-1
$$
解密使用逆序列 $t = s^{-1}$
$$
p_i = C_{t_i}, \quad i = 0,1,\dots,n-1
$$
**特点**
- 实现简单,直观“打乱顺序”
- 频率不变,难以抵抗纯统计分析;但位置模式被破坏,较难直接猜词
- 作为教学与与替换密码的组合(乘积密码)更有价值
## 二、列移位置换Columnar Transposition
**工作原理**
选择一个关键词,将明文按列填入表格,再按关键词的字母排序对列进行重排,最终按列或按行读出密文。
```mermaid
flowchart LR
A[明文填入表格] --> B{按关键词排序列}
B --> C[重排读取]
C --> D[密文]
```
**简例(概念演示)**
明文:`ATTACKATDAWN`
关键词:`ZEBRA`(按字母表排序为 `A B E R Z`
1) 将明文逐行填入 5 列表格;
2) 按关键词排序A→B→E→R→Z重排列
3) 按重排后的列依次读出密文。
(实际实现时需要处理明文长度不足一整行的填充策略,如使用 `X` 或留空。)
**数学表示(一般置换模型)**
关键词决定一个列置换 $\pi$,其作用是重新排列列索引。若把明文按列读取为序列 $P$,加密可抽象为:
$$
C = \operatorname{Permute}_{\pi}(P), \quad P = \operatorname{Permute}_{\pi^{-1}}(C)
$$
**特点**
- 比栅栏更灵活,关键词让置换更“难猜”
- 仍保留频率分布,易受已知明文/选择明文的结构分析攻击
- 常与替换结合形成更强的乘积密码(如 ADFGX/ADFGVX 密码)
## 三、联合与加固:置换 × 替换
将“替换”与“置换”组合(先替换后置换,或多轮交替)能显著增强安全性:
- 替换打乱统计特征(字母频率分布变平)
- 置换打乱位置结构(模式与相邻关系被破坏)
这种思路在现代密码设计中仍然常见(“混淆与扩散”理念),尽管算法形式已经大为不同。
## 四、安全性与弱点(直观理解)
- 单独的置换密码不改变字母频率,抵抗统计攻击能力有限
- 容易受到已知明文/选择明文攻击(通过结构猜测置换)
- 多轮、复杂置换能提高攻击成本,但不建议单独用于实际安全场景
## 五、小练习(可选)
试着把你自己的名字用 3 轨栅栏加密;然后写出解密过程(先确定轨道索引,再按逆序重建原文)。
## 附件:
具体的使用样例代码请参考:[https://gitea.simengweb.com/si-meng-spec/cryptography-example-code](https://gitea.simengweb.com/si-meng-spec/cryptography-example-code)

View File

@@ -0,0 +1,170 @@
---
title: 替换密码
createTime: 2025/10/27 10:47:42
permalink: /theory/cryptography/substitution-ciphers/
---
# 替换密码Substitution Ciphers
我们一起来系统梳理古典加密算法Classical Ciphers。这些算法虽然在现代已不再安全但它们是密码学发展的基石蕴含了替换、置换、密钥等核心思想非常适合理解密码学的基本原理。
替换密码的核心思想是“一对一”或“多对一”的字符映射:把明文中的每一个字母(或符号)按照事先约定好的规则,替换成另一个字母(或符号)。
这种映射可以是固定不变的(如凯撒密码的“统一移位”),也可以是依赖密钥动态变化的(如维吉尼亚密码的“周期移位”)。
由于密文保留了原始字母的出现频率,只是“换了一张皮”,所以替换密码在本质上没有改变字母的统计特性,这也为频率分析攻击留下了突破口。
替换操作可以手工完成,也可以通过查表、转盘、甚至机械电路实现,是后续更复杂多表替换与乘积密码的雏形。
## 一、凯撒密码Caesar Cipher
**工作原理**
凯撒密码是一种循环移位密码,将字母表视为一个环形结构。加密时每个字母向后移动固定位置 $k$,解密时向前移动相同位置。
**数学表示**
设字母 A-Z 对应数字 0-25
加密公式:
$$E(x) = (x + k) \mod 26$$
解密公式:
$$D(x) = (x - k) \mod 26$$
其中 $x$ 是明文字母编号,$k$ 是密钥0 ≤ k ≤ 25
**特点**
- 实现简单,易于理解
- 密钥空间仅 $26$ 种可能,安全性极低
- 易受频率分析攻击
- 主要具有教学价值
## 二、单表替换密码Simple Substitution Cipher
**工作原理**
单表替换密码是凯撒密码的泛化形式,它使用一个随机的字母替换表,而不是固定的移位。每个明文字母都被唯一地映射到一个密文字母,形成一对一的替换关系。
```mermaid
graph LR
A[明文字母] --> B{替换表}
B --> C[密文字母]
```
**数学表示**
设字母表 $\Sigma = \{A,B,C,...,Z\}$,替换函数 $f: \Sigma \rightarrow \Sigma$ 是一个双射(一一对应),则:
加密公式:
$$E(x) = f(x)$$
解密公式:
$$D(y) = f^{-1}(y)$$
其中 $f^{-1}$ 是 $f$ 的逆函数。
**密钥空间**
单表替换密码的密钥空间是所有可能的字母排列,大小为:
$$|K| = 26! \approx 4.03 \times 10^{26}$$
这个巨大的密钥空间使得暴力破解在计算上不可行。
**示例**
假设替换表为:
```
A→Q, B→W, C→E, D→R, E→T, F→Y, G→U, H→I, I→O, J→P,
K→A, L→S, M→D, N→F, O→G, P→H, Q→J, R→K, S→L, T→Z,
U→X, V→C, W→V, X→B, Y→N, Z→M
```
```mermaid
flowchart LR
A[明文: HELLO] --> B[替换加密]
B --> C[密文: ITSSG]
C --> D[逆替换解密]
D --> E[明文: HELLO]
```
**安全性分析**
虽然单表替换密码的密钥空间巨大,但它仍然易受**频率分析攻击**。因为:
1. **字母频率保留**高频字母如E、T、A在密文中仍然是高频
2. **单词模式保留**:常见单词模式(如"THE"、"ING")在密文中保持相同模式
3. **双字母频率**:常见字母对(如"TH"、"ER")的频率特征仍然存在
**攻击方法**
- 单字母频率分析
- 双字母频率分析
- 单词长度和模式分析
- 已知明文攻击
**特点**
- 密钥空间巨大($26!$),理论上难以暴力破解
- 仍然易受统计攻击
- 是密码学历史上重要的里程碑
- 为现代密码学提供了重要启示
## 三、维吉尼亚密码Vigenère Cipher
**工作原理**
维吉尼亚密码是一种多表替换密码,它使用一个关键词来决定每次替换的凯撒密码移位量。关键词的每个字母对应一个移位量,明文的每个字母根据关键词的循环使用进行替换。
```mermaid
graph LR
A[明文] --> B{关键词循环扩展}
B --> C[明文与关键词按位组合]
C --> D{多表替换}
D --> E[密文]
```
**数学表示**
设字母 A-Z 对应数字 0-25。
明文 $P = p_0 p_1 ... p_{n-1}$
关键词 $K = k_0 k_1 ... k_{m-1}$ (长度为 $m$)
加密公式:
$$E(p_i) = (p_i + k_{i \pmod m}) \mod 26$$
解密公式:
$$D(c_i) = (c_i - k_{i \pmod m}) \mod 26$$
其中 $p_i$ 是明文第 $i$ 个字母的数字表示,$k_{i \pmod m}$ 是关键词循环后对应第 $i$ 个字母的数字表示,$c_i$ 是密文第 $i$ 个字母的数字表示。
**示例**
明文:`ATTACKATDAWN`
关键词:`LEMON`
1. **关键词循环扩展**
将关键词 `LEMON` 循环扩展至与明文等长:`LEMONLEMONLE`
2. **明文与关键词按位组合(数字表示)**
将明文和扩展后的关键词转换为数字 (A=0, B=1, ..., Z=25)。
明文数字: `0 19 19 0 2 10 0 19 3 0 22 13`
关键词数字: `11 4 12 14 13 11 4 12 14 13 11 4`
3. **加密运算**
对每对明文数字 $p_i$ 和关键词数字 $k_{i \pmod m}$ 执行 $(p_i + k_{i \pmod m}) \mod 26$ 运算。
例如:
- 第一个字母:明文 A (0) + 关键词 L (11) = $(0 + 11) \mod 26 = 11 \rightarrow L$
- 第二个字母:明文 T (19) + 关键词 E (4) = $(19 + 4) \mod 26 = 23 \rightarrow X$
- 第三个字母:明文 T (19) + 关键词 M (12) = $(19 + 12) \mod 26 = 5 \rightarrow F$
...
最终密文:`LXFOPVEFRNHR`
**安全性分析**
维吉尼亚密码比单表替换密码更安全,因为它引入了**多表替换**,使得密文的字母频率分布趋于平坦,从而抵抗了简单的频率分析攻击。
然而,它并非绝对安全,主要弱点在于**关键词的周期性**
1. **Kasiski 测试**:通过分析密文中重复出现的字母组,可以推断出关键词的长度。
2. **频率分析(针对子密码)**:一旦关键词长度确定,密文可以被分成若干个凯撒密码,然后对每个子密码进行频率分析。
**特点**
- 多表替换,比单表替换密码更安全
- 引入了关键词的概念,增强了密钥的复杂性
- 易受Kasiski测试和频率分析的组合攻击
- 在历史上曾被认为是“牢不可破的密码”
## 附件:
具体的使用样例代码请参考:[https://gitea.simengweb.com/si-meng-spec/cryptography-example-code](https://gitea.simengweb.com/si-meng-spec/cryptography-example-code)

1116
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@
"node": "^20.6.0 || >=22.0.0" "node": "^20.6.0 || >=22.0.0"
}, },
"scripts": { "scripts": {
"docs:dev": "vuepress dev docs", "docs:dev": "vuepress dev docs --port 4567",
"docs:dev-clean": "vuepress dev docs --clean-cache --clean-temp", "docs:dev-clean": "vuepress dev docs --clean-cache --clean-temp --port 4567",
"docs:build": "vuepress build docs --clean-cache --clean-temp", "docs:build": "vuepress build docs --clean-cache --clean-temp",
"docs:preview": "http-server docs/.vuepress/dist", "docs:preview": "http-server docs/.vuepress/dist",
"vp-update": "npx vp-update" "vp-update": "npx vp-update"
@@ -25,6 +25,7 @@
"vuepress-theme-plume": "1.0.0-rc.164" "vuepress-theme-plume": "1.0.0-rc.164"
}, },
"dependencies": { "dependencies": {
"@waline/client": "^3.6.0" "@waline/client": "^3.6.0",
"mermaid": "^11.12.1"
} }
} }

59
start.bat Normal file
View File

@@ -0,0 +1,59 @@
@echo off
setlocal ENABLEDELAYEDEXPANSION
REM Usage:
REM start.bat [host] [port]
REM Examples:
REM start.bat -> try 0.0.0.0:4567, fallback to localhost and 5173
REM start.bat local 8080 -> localhost:8080
REM start.bat lan 4567 -> 0.0.0.0:4567
set HOST=%~1
if "%HOST%"=="" set HOST=0.0.0.0
if /I "%HOST%"=="lan" set HOST=0.0.0.0
if /I "%HOST%"=="local" set HOST=localhost
set PORT=%~2
if "%PORT%"=="" set PORT=4567
set FALLBACK_PORT=5173
echo [Start] VuePress dev on host %HOST% port %PORT%
call npx vuepress@2.0.0-rc.24 dev docs --host %HOST% --port %PORT%
if %ERRORLEVEL% EQU 0 goto success
REM Fallback 1: switch to localhost same port
if NOT "%HOST%"=="localhost" (
echo [Fallback] switch to localhost on same port %PORT%...
call npx vuepress@2.0.0-rc.24 dev docs --host localhost --port %PORT%
if %ERRORLEVEL% EQU 0 goto success
)
REM Fallback 2: clean cache and use localhost on fallback port
if NOT "%PORT%"=="%FALLBACK_PORT%" (
echo [Fallback] clean cache and start on localhost:%FALLBACK_PORT%...
call npx vuepress@2.0.0-rc.24 dev docs --clean-cache --clean-temp --host localhost --port %FALLBACK_PORT%
if %ERRORLEVEL% EQU 0 (
set HOST=localhost
set PORT=%FALLBACK_PORT%
goto success
)
)
REM Fallback 3: try another common port
set ALT_PORT=8080
if NOT "%PORT%"=="%ALT_PORT%" (
echo [Fallback] try localhost:%ALT_PORT%...
call npx vuepress@2.0.0-rc.24 dev docs --host localhost --port %ALT_PORT%
if %ERRORLEVEL% EQU 0 (
set HOST=localhost
set PORT=%ALT_PORT%
goto success
)
)
echo [Error] Failed to start dev server. Please check firewall or port usage.
exit /b 1
:success
echo [Ready] Open http://localhost:%PORT%/ (or http://%HOST%:%PORT%/ if accessible)
exit /b 0