# https://banzhuanriji.com llms-full.txt ## Tech Tutorials and Guides [**搬砖日记**](https://banzhuanriji.com/) [HTTP状态码全指南](https://banzhuanriji.com/android/http-code.html) 2025-04-18 [如何记笔记](https://banzhuanriji.com/essay/how-to-take-notes.html) 2025-04-13 [一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) 2025-03-24 [修改Typecho的登录路径](https://banzhuanriji.com/server/modify-admin-login-url.html) 2025-03-22 [Android实时通话技术解析](https://banzhuanriji.com/android/android-real-time-call.html) 2025-03-16 [世界不是 AI 主题乐园](https://banzhuanriji.com/essay/stop-ai-ing-stuff.html) 2025-03-15 [Astro初体验](https://banzhuanriji.com/frontend/first-site-by-astro.html) 2025-03-13 1. [1](https://banzhuanriji.com/page/1/) 2. [2](https://banzhuanriji.com/page/2/) 3. [3](https://banzhuanriji.com/page/3/) 4. [4](https://banzhuanriji.com/page/4/) 5. [5](https://banzhuanriji.com/page/5/) 6. [6](https://banzhuanriji.com/page/6/) 7. [7](https://banzhuanriji.com/page/7/) 8. [→](https://banzhuanriji.com/page/2/) ## Friend Links # 友链 ![友链icon](https://banzhuanriji.com/img/friends/xmyr.webp)[寻梦依然](https://xmyr.top/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/4ark.webp)[4Ark](https://4ark.me/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/wxapp.webp)[npc玩家](https://wxapp.xyz/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/mengke.webp)[Mengke’s Blog](https://www.mengke.me/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/boyouquan.webp)[博友圈](https://www.boyouquan.com/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/pic.ffnb.webp)[SSR-FF摄影](https://pic.ffnb.top/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/eebk.webp)[奕奕 Blog](https://www.eebk.com/) ![友链icon](https://banzhuanriji.com/img/friends/mxsw.webp)[萌新所闻](https://www.imxw.cn/?ref=banzhuanriji.com) ![友链icon](https://banzhuanriji.com/img/friends/unixetc.webp)[UNIXETC](https://unixetc.com/?ref=banzhuanriji.com) ## 搬砖日记 - 生活记录 # [关于](https://banzhuanriji.com/) _2024-11-06 19:18_ 记录一些想记录的内容,试图在吵杂的互联网浪潮中发出自己的声音。 除非特殊说明和引用,本网站所有内容均为自生产,引用请保留出处。 程序: - Typecho 主题: - [Final](https://github.com/hoytzhang/typecho-theme-final) 插件: - Qiniu File,储存静态文件 - RobotsPlusPlus,记录爬虫访问日志 - Sitemap,站点地图 如果你想与我交换友链,请在下方留言,留言信息需要包含您的站点标题,站点地址,站点副标题,icon地址。暂时只接受个人网站交换友链。引流站点,导航站点等请勿申请。 * * * ### 评论 提交你的评论 1. ![](https://cravatar.cn/avatar/763759a7be68c3e0ef1b5eda75122c3e?s=80&r=G&d=mm) [搬砖日记测试](https://banzhuanriji.com/)2025-Jan-8 地址:https://banzhuanriji.com/ 标题/称呼:搬砖日记 副标题/自我介绍:我的生活记录 icon/头像:https://banzhuanriji.com/img/icon.svg 2. ![](https://cravatar.cn/avatar/189d040cb9a21ecc173e3a2a2a803ce8?s=80&r=G&d=mm) [寻梦依然](https://xmyr.top/)2025-Jan-11 网站名称:寻梦依然 网站简介:热爱生活,随性而活 网站地址址:https://xmyr.top 网站图标:https://xmyr.top/favicon.ico 3. ![](https://cravatar.cn/avatar/498288b678d045bd8fe49bd3783ee5aa?s=80&r=G&d=mm) [npc玩家](https://wxapp.xyz/)2025-Jan-13 地址:https://wxapp.xyz 标题/称呼:npc玩家 副标题/自我介绍:开发记录\|生活记录 icon/头像:https://avatars.githubusercontent.com/u/11732611 4. ![](https://cravatar.cn/avatar/4fd8d016b6c171897d055ed00b6c7635?s=80&r=G&d=mm) [奕奕](https://www.eebk.com/)2025-Mar-16 地址:https://www.eebk.com/ 标题/称呼:奕奕 Blog 副标题/自我介绍:奕奕 Blog,记录美好生活 icon/头像:https://www.eebk.com/favicon.ico 5. ![](https://cravatar.cn/avatar/bd56d594b86ed11198c9bb59cf81dc89?s=80&r=G&d=mm) 萌新所闻2025-Mar-21 站名:萌新所闻 链接:https://www.imxw.cn/ 介绍:一个认真分享健康的博主. 头像:https://www.imxw.cn/img/mxsw.png 6. ![](https://cravatar.cn/avatar/4cd9076480c7d09fb40bde42ad014fff?s=80&r=G&d=mm) [搬砖日记](https://banzhuanriji.com/)2025-Apr-21 头像测试 ## Default Category Articles ### 分类 默认分类 下的文章 ## 没有找到内容 ## Android Articles and Guides ### 分类 android 下的文章 - _2025-04-18_[HTTP状态码全指南](https://banzhuanriji.com/android/http-code.html) - _2025-03-16_[Android实时通话技术解析](https://banzhuanriji.com/android/android-real-time-call.html) - _2025-02-03_[仍然可以解BL锁的Android手机](https://banzhuanriji.com/android/android-devices-that-can-be-unlocked.html) - _2024-12-13_[Android Studio console 输出乱码解决](https://banzhuanriji.com/android/android-studio-console-unicode-fix.html) - _2024-12-13_[Android 的 v-a/b分区简单理解](https://banzhuanriji.com/android/about-android-v-ab.html) - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) 1. [1](https://banzhuanriji.com/category/android/1/) 2. [2](https://banzhuanriji.com/category/android/2/) 3. [→](https://banzhuanriji.com/category/android/2/) ## Technical Learning Articles ### 分类 技术学习 下的文章 - _2025-04-18_[HTTP状态码全指南](https://banzhuanriji.com/android/http-code.html) - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) - _2025-03-22_[修改Typecho的登录路径](https://banzhuanriji.com/server/modify-admin-login-url.html) - _2025-03-16_[Android实时通话技术解析](https://banzhuanriji.com/android/android-real-time-call.html) - _2025-03-13_[Astro初体验](https://banzhuanriji.com/frontend/first-site-by-astro.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-03-07_[在final中添加评论](https://banzhuanriji.com/theme/add-comments-in-theme-final.html) 1. [1](https://banzhuanriji.com/category/study/1/) 2. [2](https://banzhuanriji.com/category/study/2/) 3. [3](https://banzhuanriji.com/category/study/3/) 4. [4](https://banzhuanriji.com/category/study/4/) 5. [5](https://banzhuanriji.com/category/study/5/) 6. [→](https://banzhuanriji.com/category/study/2/) ## Git Articles ### 分类 git 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Server Articles and Resources ### 分类 服务器 下的文章 - _2025-04-18_[HTTP状态码全指南](https://banzhuanriji.com/android/http-code.html) - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) - _2025-03-22_[修改Typecho的登录路径](https://banzhuanriji.com/server/modify-admin-login-url.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-02-14_[免费静态托管服务对比](https://banzhuanriji.com/server/comparing-free-static-site-osting.html) - _2025-01-29_[互联网没有DELETE](https://banzhuanriji.com/server/there-is-no-delete-on-internet.html) - _2025-01-01_[国内可访问的临时邮箱服务](https://banzhuanriji.com/server/temporary-mailbox.html) 1. [1](https://banzhuanriji.com/category/server/1/) 2. [2](https://banzhuanriji.com/category/server/2/) 3. [3](https://banzhuanriji.com/category/server/3/) 4. [→](https://banzhuanriji.com/category/server/2/) ## Website Themes and Articles ### 分类 主题 下的文章 - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-03-07_[在final中添加评论](https://banzhuanriji.com/theme/add-comments-in-theme-final.html) - _2024-12-25_[仿照linktree做的个人主页](https://banzhuanriji.com/theme/linktree-like-page.html) - _2024-12-25_[我制作的两款blog主题](https://banzhuanriji.com/theme/blog-themes.html) - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## Movies and Reviews ### 分类 影评 下的文章 - _2024-12-28_[IMDb 发布了 2024 最受欢迎的电视剧和电影 Top10](https://banzhuanriji.com/movies/imdb-most-popular-list-2024.html) - _2024-11-26_[我评《肖申克的救赎》](https://banzhuanriji.com/movies/The-Shawshank-Redemption.html) ## Life Articles Collection ### 分类 生活 下的文章 - _2025-04-13_[如何记笔记](https://banzhuanriji.com/essay/how-to-take-notes.html) - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) - _2025-03-15_[世界不是 AI 主题乐园](https://banzhuanriji.com/essay/stop-ai-ing-stuff.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-03-08_[英雄联盟的玩法困局与玩家逃离启示录](https://banzhuanriji.com/essay/is-lol-dying.html) - _2025-02-06_[汽车如何知道我带没带车钥匙](https://banzhuanriji.com/essay/how-cars-identify-key.html) - _2024-12-28_[IMDb 发布了 2024 最受欢迎的电视剧和电影 Top10](https://banzhuanriji.com/movies/imdb-most-popular-list-2024.html) 1. [1](https://banzhuanriji.com/category/life/1/) 2. [2](https://banzhuanriji.com/category/life/2/) 3. [→](https://banzhuanriji.com/category/life/2/) ## Essays and Reflections ### 分类 随笔 下的文章 - _2025-04-13_[如何记笔记](https://banzhuanriji.com/essay/how-to-take-notes.html) - _2025-03-15_[世界不是 AI 主题乐园](https://banzhuanriji.com/essay/stop-ai-ing-stuff.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-03-08_[英雄联盟的玩法困局与玩家逃离启示录](https://banzhuanriji.com/essay/is-lol-dying.html) - _2025-02-06_[汽车如何知道我带没带车钥匙](https://banzhuanriji.com/essay/how-cars-identify-key.html) - _2024-12-12_[培养欣赏艺术的能力](https://banzhuanriji.com/essay/develop-the-ability-to-appreciate-art.html) - _2024-10-06_[小米 Redmi note 14 pro + 的糟糕体验](https://banzhuanriji.com/essay/dont-buy-redmi-note-14-pro-plus.html) 1. [1](https://banzhuanriji.com/category/essay/1/) 2. [2](https://banzhuanriji.com/category/essay/2/) 3. [→](https://banzhuanriji.com/category/essay/2/) ## Windows Tips and Guides ### 分类 Windows 下的文章 - _2024-09-07_[在Windows的右键菜单添加文件哈希校验功能](https://banzhuanriji.com/windows/add-file-hash-check-on-windows-menu.html) - _2024-04-12_[安装/升级Windows11之后不能进入BIOS的问题](https://banzhuanriji.com/windows/fuck-windows11.html) ## Free Image Hosting ### 分类 相册 下的文章 - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) ## Frontend Articles and Resources ### 分类 前端 下的文章 - _2025-04-18_[HTTP状态码全指南](https://banzhuanriji.com/android/http-code.html) - _2025-03-24_[一些免费的图床整理和对比](https://banzhuanriji.com/server/free-image-host.html) - _2025-03-13_[Astro初体验](https://banzhuanriji.com/frontend/first-site-by-astro.html) - _2025-03-11_[冷饭加鸡肋,越炒越无味](https://banzhuanriji.com/essay/low-code-platform.html) - _2025-01-10_[所以,我是从哪里Copy的CSS样式](https://banzhuanriji.com/frontend/css-template-website.html) - _2024-12-28_[一些获取随机图像的接口](https://banzhuanriji.com/frontend/random-image.html) ## AI Articles Collection ### 分类 ai 下的文章 - _2025-01-31_[从咒语到对话](https://banzhuanriji.com/ai/from-spells-to-dialogue.html) ## HTTP Status Code Guide # [HTTP状态码全指南](https://banzhuanriji.com/) _2025-04-18 19:25_ _·_ [android](https://banzhuanriji.com/category/android/) · [技术学习](https://banzhuanriji.com/category/study/) · [服务器](https://banzhuanriji.com/category/server/) · [前端](https://banzhuanriji.com/category/frontend/) ## 一、状态码分类逻辑 HTTP状态码按首位数字分为5类,构成Web通信的「响应语言」: - **1xx**:信息性状态(协议处理中) - **2xx**:成功状态(请求已达成) - **3xx**:重定向状态(资源位置变更) - **4xx**:客户端错误(请求不合法) - **5xx**:服务端错误(服务器处理失败) 这种分类方式让开发者能快速定位请求问题的大致方向,极大提升调试效率。 ## 二、全量状态码速查表 ### 1xx Informational(信息响应) | 状态码 | 名称 | 典型场景 | 补充说明 | | --- | --- | --- | --- | | 100 | Continue | 客户端应继续发送请求体 | 常用于大文件上传,先确认服务器接收意向 | | 101 | Switching Protocols | 服务器同意升级协议(如WebSocket) | 需在请求头中指定 `Upgrade` 字段 | | 102 | Processing | 服务器正在处理但未完成 | 多用于WebDAV协议下的复杂操作 | ### 2xx Success(成功响应) | 状态码 | 名称 | 关键特性 | 常见应用场景 | | --- | --- | --- | --- | | 200 | OK | 标准成功响应 | GET请求成功返回数据 | | 201 | Created | 资源创建成功(POST返回新URL) | 接口创建用户、商品等资源时使用 | | 202 | Accepted | 请求已接收但未处理完 | 异步任务提交(如文件上传排队) | | 204 | No Content | 响应体为空(如DELETE成功) | 删除资源后,减少不必要的数据传输 | ### 3xx Redirection(重定向) | 状态码 | 名称 | 缓存行为 | 方法保留规则 | 适用场景 | | --- | --- | --- | --- | --- | | 301 | Moved Permanently | 永久缓存 | GET可能变HEAD | 网站域名更换、页面永久迁移 | | 302 | Found | 临时缓存 | 方法可能改变 | 登录成功后跳转首页 | | 307 | Temporary Redirect | 不缓存 | 强制保留原始方法 | 临时维护页面跳转 | | 308 | Permanent Redirect | 永久缓存 | 强制保留原始方法 | API接口版本永久变更 | ### 4xx Client Error(客户端错误) | 状态码 | 名称 | 高频触发场景 | 修复建议 | | --- | --- | --- | --- | | 400 | Bad Request | 请求语法错误 | 检查参数格式、请求头完整性 | | 401 | Unauthorized | 未提供有效身份凭证 | 添加认证信息(如Token、Basic Auth) | | 403 | Forbidden | 权限不足(如访问私有文件) | 确认用户角色权限配置 | | 404 | Not Found | 资源不存在 | 检查URL路径或资源删除逻辑 | | 429 | Too Many Requests | 触发速率限制 | 调整请求频率或申请更高配额 | ### 5xx Server Error(服务端错误) | 状态码 | 名称 | 故障类型 | 排查方向 | | --- | --- | --- | --- | | 500 | Internal Server Error | 未分类的服务器错误 | 检查服务器日志、代码异常捕获 | | 502 | Bad Gateway | 上游服务器无响应 | 确认网关配置、后端服务健康状态 | | 503 | Service Unavailable | 主动停机维护/过载 | 查看维护公告、扩容服务器资源 | | 504 | Gateway Timeout | 上游服务器响应超时 | 优化网络配置、增加超时重试机制 | ## 三、关键场景实战指南 ### 1\. SEO优化组合拳 - **301+308**:永久迁移时保留链接权重 - **429+Retry-After**:应对爬虫时友好限流 ### 2\. API设计黄金法则 ```lang-http GET /api/users/1 HTTP/1.1 -> 200 OK(成功) -> 404 Not Found(资源不存在) -> 410 Gone(资源已删除且无新地址) ``` ### 3\. 错误处理最佳实践 - 4xx错误必须返回清晰错误详情(如JSON Body) - 5xx错误应记录完整日志链(Request-ID追踪) ## 四、冷知识彩蛋 ​​418 I'm a teapot​​:源自HTTP愚人节RFC(真实存在于某些库中) ​​206 Partial Content​​:支持断点续传的核心状态码 * * * ### 评论 提交你的评论 ## Note-Taking Strategies # [如何记笔记](https://banzhuanriji.com/) _2025-04-13 21:00_ _·_ [随笔](https://banzhuanriji.com/category/essay/) # TL;DR 1. 理想的笔记软件至少应具备记笔记与全局搜索这两大功能。 2. 不妨尝试以日期为单位创建笔记,无需每日大费周章搭建笔记体系。 3. 巧妙运用tag,提升笔记管理效率。 事先声明,这并非广告或软文。不过,我确实想推荐capacities这款笔记软件,它有个我极为欣赏的特色—— **以日期为单位记笔记** 。但本文重点并非软件推荐,而是探讨行之有效的笔记方法。 # 别再把时间浪费在寻觅工具上 曾经,我痴迷于囤积、对比各类“生产力工具”,已然到了病态的程度。 - 在众多笔记软件间徘徊周旋,最终笔记没记下多少,脑海里却充斥着收费、免费、同步等关键词。 - 热衷于比较各种浏览器,甚至去探索一些鲜有人用的小众浏览器,殊不知,这些浏览器所谓的独特功能,一个插件便能轻松实现。 - 频繁对比各类博客平台,却未曾留下任何痕迹,后来甚至延伸到对各种VPS的挑选。 - 在公司,我是出了名的输入法“研究大户”,对各类输入工具的特性了如指掌。 - 对手机ROM刷机也上了瘾,甚至在主力机上频繁尝试各种体验。 - …… 那时,我还有一套自己的说辞:身为程序员,我深知不存在完美的工具,但我力求将自己的工具优化至最佳使用状态。 实则,收费软件大多闭源,使用过程中总感觉部分功能缺失,不够称手;开源软件又像未完成的半成品,如同自己对着食谱忙活半天,最后还是只能点份难吃的外卖。我还常跟组员讲,开发时要把用户当“小白”,可轮到自己用软件时,却自作聪明,总觉得这软件哪哪都不行,想着再试试别的。 如今回头看,每天都乐此不疲地将时间、精力和金钱浪费在这些事上,最终落得个一事无成。倘若你和曾经的我一样,我觉得是时候做出改变了。 # 以日期为单位记笔记:简便且高效 我选择以日期为单位记笔记,这正是Capacities吸引我的一大功能。每日,我只需打开当天的笔记页面,将零散的想法、会议记录、灵感碎片等一一记录下来,无需耗费精力去分类。这种方式极大地减轻了我的心理负担,同时,笔记自然而然地形成了一条清晰的时间线。 以日期为单位记笔记,主要有以下好处: 1. 减轻心理负担:无需一开始就纠结“这篇笔记该归到哪个分类”,只管记录即可。 2. 时间线清晰:日期天然就是索引,便于回顾某一天或某段时间的记录。比如,我能轻松找到“上个月15号开会时提到的那个优化建议”。 3. 契合碎片化记录:现代生活节奏快,我们的想法往往是碎片化的。以日期为单位,能让我们快速记录,不必担心内容过于零散。 # 巧用标签:让笔记“灵动”起来 > [https://x.com/steffenBle/status/1499119720758497280](https://x.com/steffenBle/status/1499119720758497280) 在X平台上,Steffen Bleher( [@steffenBle](https://x.com/steffenBle))分享了借助标签提升笔记效率的经验,我深受启发。他提到:“Tagging can be a game - changer in your note - taking. But very often it's used poorly with little to no value.”(标签能彻底改变你的笔记方式,但很多时候人们使用不当,几乎毫无价值。)过去,我也曾随意给笔记加标签,诸如“工作”“学习”,结果这些标签太过宽泛,毫无用处。 Steffen提出了四条经验法则,结合我的实践,总结如下: 1. 标签具体化:避免使用宽泛标签(如“技术”),选择更精准的表述(如“Python调试技巧”)。标签如同地图上的地标,要选对“分辨率”。 2. 少即是多:每篇笔记最多添加3个标签,防止标签过多导致混乱。若标签过多,可能意味着内容需要拆分。 3. 挑选最契合的标签:不要一股脑添加所有相关标签,而是选择最能体现笔记核心的标签,构建更具层次感的标签网络。 4. 定期整理标签:每月回顾一次,合并重复标签,删除无用标签,确保系统高效运行。 # 笔记的真正价值在于复用 记笔记的目的并非单纯为了记录,而是为了复用。Steffen指出,通过优化标签系统,可以“tremendously improve exploration and effective resurfacing of content”(极大地提升内容的探索和有效复现)。对此,我感触颇深。 例如,近期我在做一个项目时,需要用到之前学过的一些数据库优化知识。我直接在Capacities中搜索“数据库优化”这个标签,很快便找到了半年前的一篇笔记,里面详细记录了我当时阅读一篇技术文章的要点以及自己的心得。这为我节省了大量时间,也让我深刻认识到,一个高效的笔记系统真的能成为你的“第二大脑”。 所以,拥有一个精准的tag系统和好用的全文搜索功能至关重要! # 总结:从混乱走向高效的笔记之道 通过反思过去“工具控”的习惯,结合Steffen的标签经验法则以及我自身的实践,我终于从笔记的混乱状态中解脱出来。如今,我的笔记系统既简洁又高效:以日期为单位记录,巧妙运用精准标签,定期整理标签系统,再配合全局搜索,实现快速复用。 倘若你也想提升笔记效率,不妨试试以下步骤: - 挑选一款支持日期记录和全局搜索的工具(比如Capacities)。 - 每日记录时保持简洁,搭配精准标签。 - 定期整理标签系统,使其持续发挥作用。 - 专注于笔记复用,而非一味追求记录的“完美”。 记笔记并非为了堆砌内容,而是为了让知识更有条理、更易获取。希望我的经验能对你有所帮助!若你有其他笔记技巧,欢迎在评论区分享~ [笔记](https://banzhuanriji.com/tag/%E7%AC%94%E8%AE%B0/) · [notion](https://banzhuanriji.com/tag/notion/) · [capacitie](https://banzhuanriji.com/tag/capacitie/) · [标签](https://banzhuanriji.com/tag/%E6%A0%87%E7%AD%BE/) · [note](https://banzhuanriji.com/tag/note/) · [生产力](https://banzhuanriji.com/tag/%E7%94%9F%E4%BA%A7%E5%8A%9B/) * * * ### 评论 提交你的评论 ## Free Image Hosting # [一些免费的图床整理和对比](https://banzhuanriji.com/) _2025-03-24 17:51_ _·_ [服务器](https://banzhuanriji.com/category/server/) · [相册](https://banzhuanriji.com/category/gallery/) · [主题](https://banzhuanriji.com/category/theme/) · [前端](https://banzhuanriji.com/category/frontend/) 因为我有SM.MS账号,所以一直是登录使用。最近才发现SM.MS禁止了游客上传图像,今天试的imgdd上传出现了问题。正好闲来无事整理一下现在可用的免费图床。 ## 图像处理: ### [https://ic.yunimg.cc/](https://ic.yunimg.cc/) 可选择多种文件尺寸和图像质量,并可在线预览对比图像质量后保存。 ### [https://imagestool.com/webp2jpg-online/](https://imagestool.com/webp2jpg-online/) 几乎全能图像在线转换压缩处理工具 ## 图床 以下为图床列表,示例图片文件大小为1.01Mb左右(1041 kb,1065532 字节),你可以按F12,在开发人员工具中选择网络-停用缓存,然后按F5刷新页面,查看图片下载速度。 > 只做收集使用,没有任何利益关系。请注意备份您的数据 ### 云图床 [https://yunimg.cc/](https://yunimg.cc/) 最大可上传 100.00 MB 的图片,单次同时可选择 5 张。 ![云图床](https://s1.locimg.com/2025/03/24/af26f7e5a3689.jpg) ### 美团图床(貌似会默认压缩,具体压缩率请看图片) [https://695402.xyz/mt/](https://695402.xyz/mt/) 最大可上传 20 MB 的图片,单次同时可选择 10 张。 ![美团图床](https://img.meituan.net/csc/6b9e287c334b39111753af9cf28bfc511530487.jpg) ### 图片上传工具 [https://jd.wufaziba.com/](https://jd.wufaziba.com/) 支持: JPG, PNG, GIF (最大 10MB) ![图片上传工具](https://img20.360buyimg.com/openfeedback/jfs/t1/283065/39/8497/1530487/67e126f6F9b574fdc/3ce3eab0883e1dff.jpg) ### 听闻图床 [https://www.xn--9qr844m.cn:8090/](https://www.xn--9qr844m.cn:8090/) (听闻.cn:8090) 最大可上传 500.00 MB 的图片,上传队列最多 30 张 ![听闻图床](https://www.xn--9qr844m.cn:5244/d/%E6%9C%AC%E5%9C%B0/%E9%98%BF%E9%87%8C%E4%BA%91%E7%9B%98%E8%B5%84%E6%96%99%E5%A4%87%E4%BB%BD%E5%85%B1%E4%BA%AB/%E5%9B%BE%E7%89%87/%E5%9B%BE%E5%BA%8A/2025/03/24/67e1273fe1fbc.jpg) ### 石头图床 [https://img.st/upload](https://img.st/upload) JPG PNG BMP GIF WEBP 10 MB,支持缩略图和中等缩略图 ![石头图床](https://img.116119.xyz/img/2025/03/24/img7901ff144527bc76.jpg) ### 流浪图床 [https://p.sda1.dev/](https://p.sda1.dev/) 5 MB max per file. 100 files max per request. ![流浪图床](https://p.sda1.dev/22/8b719baf539c43b4cca0a1a73f263a50/img.jpg) ### Free图床 [https://pic.sl.al/](https://pic.sl.al/) 支持JPG、PNG、GIF等图片格式,最大100MB,会一同输出转码,压缩后的链接 ![Free图床](https://pic.sl.al/gdrive/pic/2025-03-24/hash_397313ed_8428409138cc_img.jpg) ### 喷子图床 [https://pz.al/](https://pz.al/) 最大可上传 50.00 MB 的图片,单次同时可选择 10 张。 ![喷子图床](https://f.pz.al/pzal/2025/03/24/418630e7523b9.jpg) ### ipfs图床 [https://cdn.ipfsscan.io/](https://cdn.ipfsscan.io/) 永久的、去中心化保存和共享文件 ![ipfs图床](https://cdn.img2ipfs.com/ipfs/QmbDCU1UtMq83v3coZb8DQg6BTJfeSu2nYixRudTULs5Xt?filename=img.jpg) ### 屋舍图床 [https://www.uhsea.com/](https://www.uhsea.com/) 对于游客和会员可上传的单个文件大小做了限制。会员:500MB,游客:100MB ![屋舍图床](https://file.uhsea.com/2503/c39d24018ca39464223ebbffceca96b2E5.jpg) ### 时刻图床 [https://img.suntl.com/](https://img.suntl.com/) 最大可上传 5.00 MB 的图片,上传队列最多 2 张 ![时刻图床](https://img.suntl.com/i/2025/03/24/67e1293a4f634.jpg) ## 其它 这里有个之前收藏的图床大比拼,一个网友写的页面,有兴趣也可以看看。里面有的图床我没有列举出来。 [https://fileup.dev/imgtest](https://fileup.dev/imgtest) [图床](https://banzhuanriji.com/tag/%E5%9B%BE%E5%BA%8A/) · [免费](https://banzhuanriji.com/tag/%E5%85%8D%E8%B4%B9/) · [上传](https://banzhuanriji.com/tag/%E4%B8%8A%E4%BC%A0/) · [速度](https://banzhuanriji.com/tag/%E9%80%9F%E5%BA%A6/) · [图片](https://banzhuanriji.com/tag/%E5%9B%BE%E7%89%87/) · [外链](https://banzhuanriji.com/tag/%E5%A4%96%E9%93%BE/) * * * ### 评论 提交你的评论 ## Modify Typecho Login # [修改Typecho的登录路径](https://banzhuanriji.com/) _2025-03-22 18:10_ _·_ [服务器](https://banzhuanriji.com/category/server/) 为了防止有奇怪的人不断试你的密码,你可以尝试修改你的Typecho的登录路径。 > 以下举例,我们将 `admin` 修改为 `SAVq87NqJ9ecUSYl` ## 需要修改的文件夹 1. 打开网站文件根目录 2. 重命名文件夹 `admin` 为 `SAVq87NqJ9ecUSYl` ## 需要修改的配置 1. 打开根目录 `config.inc.php` 文件,修改大约第12行的 ``` define('__TYPECHO_ADMIN_DIR__', '/admin/'); ``` 2. 打开 `install.php`(如果已经完成网站安装,可忽略),大约第14行已经第405行 ``` define('__TYPECHO_ADMIN_DIR__', '/admin/'); ``` 将移上所有的 `admin` 修改为 `SAVq87NqJ9ecUSYl` 即可。 * * * ### 评论 提交你的评论 ## Android Voice Call Tech # [Android实时通话技术解析](https://banzhuanriji.com/) _2025-03-16 20:04_ _·_ [android](https://banzhuanriji.com/category/android/) ## TL;DR 实时语音传输的核心在于 **持续流式处理**,我们通过一个完整的代码示例来揭示其工作原理: ### 1\. 音频分片机制: ```lang-java // 音频采集线程 class AudioCaptureThread extends Thread { private static final int SAMPLE_RATE = 48000; // 48kHz采样率 private static final int FRAME_DURATION = 20; // 20ms帧间隔 private static final int FRAME_SIZE = (SAMPLE_RATE * FRAME_DURATION) / 1000; // 960采样点 @Override public void run() { AudioRecord recorder = createAudioRecord(); ByteBuffer buffer = ByteBuffer.allocateDirect(FRAME_SIZE * 2); // 16bit采样 recorder.startRecording(); while (isRunning) { // 读取20ms的PCM数据 int readBytes = recorder.read(buffer, FRAME_SIZE * 2); // 添加RTP头部(时间戳+序号) RtpPacket packet = new RtpPacket(); packet.timestamp = SystemClock.elapsedRealtimeNanos() / 1000; packet.sequence = nextSequenceNumber(); packet.payload = buffer.array(); // 立即发送数据包 networkSender.send(packet); buffer.rewind(); // 重用缓冲区 } } private AudioRecord createAudioRecord() { return new AudioRecord.Builder() .setAudioFormat(new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(SAMPLE_RATE) .setChannelMask(AudioFormat.CHANNEL_IN_MONO) .build()) .setBufferSizeInBytes(FRAME_SIZE * 4) // 双缓冲 .build(); } } ``` 关键原理说明: - 时间戳精度:采用微秒级时间戳 `(elapsedRealtimeNanos()/1000)` 确保时序精度 - 环形缓冲区:DirectByteBuffer 重用避免内存抖动 - 实时发送:每个 20ms 数据包立即发送,无需等待前序确认 ### 2\. 实时播放机制 ``` class AudioPlaybackThread extends Thread { private static final int JITTER_BUFFER_DEPTH = 5; // 100ms缓冲深度 private final PriorityBlockingQueue buffer = new PriorityBlockingQueue<>(50, Comparator.comparingLong(p -> p.timestamp)); private AudioTrack audioTrack; private long lastPlayedTimestamp = 0; @Override public void run() { audioTrack = createAudioTrack(); audioTrack.play(); while (isRunning) { RtpPacket packet = waitForNextPacket(); writeToAudioTrack(packet); updateTimeline(packet); } } private RtpPacket waitForNextPacket() { if (buffer.size() < JITTER_BUFFER_DEPTH) { // 缓冲不足时插入静音包 return generateSilencePacket(); } return buffer.poll(20, TimeUnit.MILLISECONDS); // 阻塞等待 } private void writeToAudioTrack(RtpPacket packet) { // 抖动补偿计算 long expectedTimestamp = lastPlayedTimestamp + 20000; // 20ms间隔 long timestampDelta = packet.timestamp - expectedTimestamp; if (timestampDelta > 50000) { // 超过50ms延迟 resetPlayback(); // 重置时间线 } audioTrack.write(packet.payload, 0, packet.payload.length); lastPlayedTimestamp = packet.timestamp; } private AudioTrack createAudioTrack() { return new AudioTrack.Builder() .setAudioFormat(new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(SAMPLE_RATE) .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) .build()) .setBufferSizeInBytes(FRAME_SIZE * 4) .setTransferMode(AudioTrack.MODE_STREAM) .build(); } } ``` 核心算法解析: - 自适应抖动缓冲:根据网络状况动态调整缓冲深度 - 时间线同步:通过时间戳差值检测网络延迟突变 - 静音补偿:在丢包时生成舒适噪声保持播放连续性 ## 开始 在做之前我完全没考虑过网络通话是如何实现。就是如何做到你在说话的同时,对方一直可以听到的。我的意思是,你说了一句很长的话,对方不是你说完才听到的,是你一直在说,对方那边一直播放。 上面的 `TL;DR` 部分几乎可以解答我所有的疑惑了。不过要实现类似微信语音通话的实时对话功能,需要深入理解音视频流式处理的完整技术链。本文将重点从Android客户端的视角,剖析实时语音通话的核心技术实现。 _本文结束后,有包括上面的代码在内的完整的示例代码,有需要都可以自取。_ * * * ## 一、实时通话核心技术原理 ### 1.1 流式处理 vs 文件传输 ```lang-mermaid graph LR A[麦克风持续采集] --> B[20ms数据分块] B --> C[即时编码] C --> D[网络实时发送] D --> E[接收端缓冲] E --> F[持续解码播放] ``` 与传统文件传输不同,实时通话采用流水线式处理: - 时间切片:音频按20ms为单位切割处理 - 无等待传输:每个数据包独立发送,无需等待整段语音 - 并行处理:采集、编码、传输、解码、播放同时进行 ### 1.2 关键性能指标 | 指标 | 目标值 | 实现要点 | | --- | --- | --- | | 端到端延迟 | <400ms | 编解码优化/Jitter Buffer控制 | | 音频采样率 | 48kHz | 硬件加速支持 | | 抗丢包能力 | 5%-20% | FEC/Opus冗余 | | CPU占用率 | <15% | MediaCodec硬件编码 | ## 二、Android客户端实现详解 ### 2.1 音频采集模块 ``` // 低延迟音频采集配置 private void setupAudioRecorder() { int sampleRate = 48000; // 优先选择硬件支持的采样率 int channelConfig = AudioFormat.CHANNEL_IN_MONO; int audioFormat = AudioFormat.ENCODING_PCM_16BIT; int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); AudioRecord recorder = new AudioRecord( MediaRecorder.AudioSource.VOICE_COMMUNICATION, // 专用通信模式 sampleRate, channelConfig, audioFormat, bufferSize * 2); // 双缓冲避免溢出 // 环形缓冲区实现 audioThread = new Thread(() -> { byte[] buffer = new byte[960]; // 20ms数据量:48000Hz * 20ms * 16bit / 8 = 1920字节 while (isRecording) { int readBytes = recorder.read(buffer, 0, buffer.length); if (readBytes > 0) { encoderQueue.offer(buffer.clone()); // 提交编码队列 } } }); } ``` 关键参数选择依据: - `VOICE_COMMUNICATION` :启用回声消除硬件加速 - 48kHz采样率:平衡音质与延迟 - 20ms帧长:Opus编码标准推荐值 ### 2.2 音频编码与传输 ``` // 硬件编码器初始化 MediaFormat format = MediaFormat.createAudioFormat( MediaFormat.MIMETYPE_AUDIO_OPUS, 48000, 1); format.setInteger(MediaFormat.KEY_BIT_RATE, 24000); format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 960); MediaCodec encoder = MediaCodec.createEncoderByType("audio/opus"); encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); encoder.start(); // 编码循环 while (!encoderQueue.isEmpty()) { int inputIndex = encoder.dequeueInputBuffer(10000); if (inputIndex >= 0) { ByteBuffer inputBuffer = encoder.getInputBuffer(inputIndex); byte[] rawData = encoderQueue.poll(); inputBuffer.put(rawData); encoder.queueInputBuffer(inputIndex, 0, rawData.length, System.nanoTime()/1000, 0); } MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); int outputIndex = encoder.dequeueOutputBuffer(bufferInfo, 10000); if (outputIndex >= 0) { ByteBuffer encodedData = encoder.getOutputBuffer(outputIndex); sendToNetwork(encodedData); // 网络发送 encoder.releaseOutputBuffer(outputIndex, false); } } ``` 编码优化技巧: - 使用 `MediaCodec.CONFIGURE_FLAG_ENCODE` 开启硬件编码 - 设置 `KEY_MAX_INPUT_SIZE` 防止缓冲区溢出 - 时间戳使用微秒单位 `(System.nanoTime()/1000)` ### 2.3 网络传输层 UDP封包结构示例 ``` +--------+--------+--------+-------------------+ | RTP头 | 时间戳 | 序列号 | Opus载荷(20ms数据)| +--------+--------+--------+-------------------+ | 12字节 | 4字节 | 2字节 | 可变长度 | +--------+--------+--------+-------------------+ ``` NAT穿透实现 ``` // STUN协议实现示例 public InetSocketAddress discoverNAT() throws IOException { DatagramSocket socket = new DatagramSocket(); byte[] stunRequest = createStunBindingRequest(); // 发送到公共STUN服务器 socket.send(new DatagramPacket(stunRequest, stunRequest.length, InetAddress.getByName("stun.l.google.com"), 19302)); // 接收响应 byte[] buffer = new byte[1024]; DatagramPacket response = new DatagramPacket(buffer, buffer.length); socket.receive(response); // 解析XOR-MAPPED-ADDRESS return parseStunResponse(response.getData()); } ``` ### 2.4 接收端播放实现 Jitter Buffer设计 ```lang-java class JitterBuffer { private static final int MAX_BUFFER_SIZE = 10; // 存储200ms数据 private PriorityQueue buffer = new PriorityQueue<>(Comparator.comparingInt(p -> p.sequence)); private int lastPlayedSeq = -1; public void addPacket(AudioPacket packet) { if (packet.sequence > lastPlayedSeq) { buffer.offer(packet); // 缓冲区溢出处理 if (buffer.size() > MAX_BUFFER_SIZE) { buffer.poll(); // 丢弃最旧数据包 } } } public AudioPacket getNextPacket() { if (!buffer.isEmpty() && buffer.peek().sequence == lastPlayedSeq + 1) { lastPlayedSeq++; return buffer.poll(); } return null; } } ``` 低延迟播放配置 ``` AudioTrack audioTrack = new AudioTrack.Builder() .setAudioAttributes(new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .build()) .setAudioFormat(new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(48000) .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) .build()) .setBufferSizeInBytes(960 * 2) // 双缓冲 .setTransferMode(AudioTrack.MODE_STREAM) .build(); audioTrack.play(); // 播放线程 while (isPlaying) { AudioPacket packet = jitterBuffer.getNextPacket(); if (packet != null) { audioTrack.write(packet.data, 0, packet.data.length); } else { generateComfortNoise(); // 生成舒适噪声 } } ``` ## 三、服务端关键技术方案 ### 3.1 信令服务器设计 ``` // Protobuf消息定义 message SignalMessage { enum Type { OFFER = 0; ANSWER = 1; ICE_CANDIDATE = 2; } Type type = 1; string sdp = 2; repeated string iceCandidates = 3; } ``` 核心功能: - WebSocket长连接管理 - SDP交换协调 - ICE候选收集与转发 ### 3.2 TURN中继服务器 ``` 客户端A ↔ TURN Server ↔ 客户端B ↓ 当P2P不通时启用中继 ``` ## 四、性能优化实践 ### 4.1 延迟优化矩阵 | 优化方向 | 具体措施 | 效果预估 | | --- | --- | --- | | 采集延迟 | 使用AudioRecord的READ\_NON\_BLOCKING模式 | 减少2-5ms | | 编码延迟 | 启用MediaCodec异步模式 | 减少3-8ms | | 网络传输 | 开启UDP QoS标记(DSCP 46) | 减少10-50ms | | 播放缓冲 | 动态调整Jitter Buffer深度 | 减少20-100ms | ### 4.2 功耗控制策略 ``` // 通话中唤醒锁管理 PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); WakeLock wakeLock = pm.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "MyApp:VoiceCall"); wakeLock.acquire(10*60*1000L /*10分钟*/); // 根据网络状态调整编码参数 if (isNetworkPoor) { encoder.setVideoBitrate(1000000); // 降低码率 adjustFrameRate(15); } ``` ## 五、调试与监控 ### 5.1 WebRTC统计接口 ``` peerConnection.getStats(new StatsObserver() { @Override public void onComplete(StatsReport[] reports) { for (StatsReport report : reports) { if (report.type.equals("ssrc")) { // 获取音频流统计信息 Log.d("Stats", "丢包率: " + report.values.get("packetsLost")); } } } }); ``` ### 5.2 关键日志标记 ``` # 采集延迟 D/AudioRecorder: Frame captured (seq=325, ts=158746532) # 网络事件 W/Network: Packet lost detected, seq=1234, enabling FEC # 播放状态 I/AudioTrack: Buffer underrun, inserting 20ms comfort noise ``` ## 六、总结 实现高质量的实时语音通话需要Android开发者深入掌握以下核心技术: - 低延迟音频流水线:从采集到播放的端到端优化 - 自适应网络传输:UDP+前向纠错的平衡艺术 - 时钟同步机制:RTP时间戳与本地播放的精准对齐 未来演进方向: - 基于AI的网络预测(BWE 2.0) - 端侧神经网络降噪(RNNoise) - 5G网络下的超低延迟优化(<100ms) 建议进一步研究: - [WebRTC Android源码](https://webrtc.googlesource.com/src) - [Google实时通信白皮书](https://ai.google/research/pubs/pub46351) - [Opus音频编码规范](https://tools.ietf.org/html/rfc6716) 掌握这些核心技术后,开发者可以构建出媲美商业级应用的实时通信系统。希望本文能为各位Android开发者在实时音视频领域提供有价值的参考。 * * * ## 剖析部分至此结束,下面是实例部分 ## 一、音频流式传输原理剖析 ### 1\. 音频分片机制 ```lang-java // 音频采集线程 class AudioCaptureThread extends Thread { private static final int SAMPLE_RATE = 48000; // 48kHz采样率 private static final int FRAME_DURATION = 20; // 20ms帧间隔 private static final int FRAME_SIZE = (SAMPLE_RATE * FRAME_DURATION) / 1000; // 960采样点 @Override public void run() { AudioRecord recorder = createAudioRecord(); ByteBuffer buffer = ByteBuffer.allocateDirect(FRAME_SIZE * 2); // 16bit采样 recorder.startRecording(); while (isRunning) { // 读取20ms的PCM数据 int readBytes = recorder.read(buffer, FRAME_SIZE * 2); // 添加RTP头部(时间戳+序号) RtpPacket packet = new RtpPacket(); packet.timestamp = SystemClock.elapsedRealtimeNanos() / 1000; packet.sequence = nextSequenceNumber(); packet.payload = buffer.array(); // 立即发送数据包 networkSender.send(packet); buffer.rewind(); // 重用缓冲区 } } private AudioRecord createAudioRecord() { return new AudioRecord.Builder() .setAudioFormat(new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(SAMPLE_RATE) .setChannelMask(AudioFormat.CHANNEL_IN_MONO) .build()) .setBufferSizeInBytes(FRAME_SIZE * 4) // 双缓冲 .build(); } } ``` 关键原理说明: - 时间戳精度:采用微秒级时间戳(elapsedRealtimeNanos()/1000)确保时序精度 - 环形缓冲区:DirectByteBuffer 重用避免内存抖动 - 实时发送:每个 20ms 数据包立即发送,无需等待前序确认 ### 2\. 实时播放机制 ``` class AudioPlaybackThread extends Thread { private static final int JITTER_BUFFER_DEPTH = 5; // 100ms缓冲深度 private final PriorityBlockingQueue buffer = new PriorityBlockingQueue<>(50, Comparator.comparingLong(p -> p.timestamp)); private AudioTrack audioTrack; private long lastPlayedTimestamp = 0; @Override public void run() { audioTrack = createAudioTrack(); audioTrack.play(); while (isRunning) { RtpPacket packet = waitForNextPacket(); writeToAudioTrack(packet); updateTimeline(packet); } } private RtpPacket waitForNextPacket() { if (buffer.size() < JITTER_BUFFER_DEPTH) { // 缓冲不足时插入静音包 return generateSilencePacket(); } return buffer.poll(20, TimeUnit.MILLISECONDS); // 阻塞等待 } private void writeToAudioTrack(RtpPacket packet) { // 抖动补偿计算 long expectedTimestamp = lastPlayedTimestamp + 20000; // 20ms间隔 long timestampDelta = packet.timestamp - expectedTimestamp; if (timestampDelta > 50000) { // 超过50ms延迟 resetPlayback(); // 重置时间线 } audioTrack.write(packet.payload, 0, packet.payload.length); lastPlayedTimestamp = packet.timestamp; } private AudioTrack createAudioTrack() { return new AudioTrack.Builder() .setAudioFormat(new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(SAMPLE_RATE) .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) .build()) .setBufferSizeInBytes(FRAME_SIZE * 4) .setTransferMode(AudioTrack.MODE_STREAM) .build(); } } ``` 核心算法解析: - 自适应抖动缓冲:根据网络状况动态调整缓冲深度 - 时间线同步:通过时间戳差值检测网络延迟突变 - 静音补偿:在丢包时生成舒适噪声保持播放连续性 ## 二、网络传输层深度实现 ### 1\. UDP 封装优化 ``` class UdpSender { private static final int MAX_RETRIES = 2; private static final int MTU = 1400; // 典型移动网络MTU private final DatagramChannel channel; private final InetSocketAddress remoteAddress; void send(RtpPacket packet) { ByteBuffer buffer = ByteBuffer.wrap(packet.serialize()); // 分片发送(应对MTU限制) while (buffer.hasRemaining()) { int bytesToSend = Math.min(buffer.remaining(), MTU); ByteBuffer slice = buffer.slice(); slice.limit(bytesToSend); sendWithRetry(slice); buffer.position(buffer.position() + bytesToSend); } } private void sendWithRetry(ByteBuffer data) { int attempt = 0; while (attempt <= MAX_RETRIES) { try { channel.send(data, remoteAddress); return; } catch (IOException e) { if (++attempt > MAX_RETRIES) { reportNetworkError(e); } } } } } ``` 关键技术点: - MTU 适配:自动分片避免 IP 层分片 - 有限重试:防止过度重传增加延迟 - 非阻塞 IO:使用 NIO DatagramChannel 提升性能 ### 2\. 前向纠错实现 ``` import com.googlecode.javaewah.EWAHCompressedBitmap; import com.googlecode.javaewah.IntIterator; class FecEncoder { // Reed - Solomon(5,3)编码配置 private static final int DATA_SHARDS = 3; private static final int PARITY_SHARDS = 2; private static final int TOTAL_SHARDS = DATA_SHARDS + PARITY_SHARDS; private final RSCodec codec = new RSCodec(DATA_SHARDS, PARITY_SHARDS); public List encode(byte[] input) { byte[][] shards = splitIntoShards(input); codec.encodeParity(shards, 0, DATA_SHARDS); List result = new ArrayList<>(); for (byte[] shard : shards) { result.add(shard); } return result; } private byte[][] splitIntoShards(byte[] data) { int shardSize = (data.length + DATA_SHARDS - 1) / DATA_SHARDS; byte[][] shards = new byte[TOTAL_SHARDS][shardSize]; for (int i = 0; i < DATA_SHARDS; i++) { int start = i * shardSize; int end = Math.min(start + shardSize, data.length); System.arraycopy(data, start, shards[i], 0, end - start); } return shards; } } ``` 数学原理: - 使用 Reed-Solomon 纠错码,可恢复任意 2 个分片的丢失 - 编码效率:3 个数据分片 + 2 个校验分片,可容忍 40% 的随机丢包 ## 三、音频处理核心技术 ### 1\. 回声消除实现,下面是CPP代码,有ai加持 ```lang-cpp // 使用WebRTC AEC模块的JNI接口 extern "C" JNIEXPORT void JNICALL Java_com_example_voice_AecProcessor_processFrame( JNIEnv* env, jobject thiz, jshortArray micData, jshortArray speakerData) { webrtc::EchoCancellation* aec = GetAecInstance(); jshort* mic = env->GetShortArrayElements(micData, 0); jshort* speaker = env->GetShortArrayElements(speakerData, 0); // 执行AEC处理 aec->ProcessRenderAudio(speaker, FRAME_SIZE); aec->ProcessCaptureAudio(mic, FRAME_SIZE, 0); env->ReleaseShortArrayElements(micData, mic, 0); env->ReleaseShortArrayElements(speakerData, speaker, 0); } ``` 算法流程: - 记录扬声器输出信号(参考信号) - 使用自适应滤波器建模声学路径 - 从麦克风信号中减去估计的回声成分 ### 2\. 动态码率调整,包含网络评估方法 ``` import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; class BitrateController { private int currentBitrate = 1000000; // 初始1Mbps private final NetworkMonitor networkMonitor; private final List listeners = new ArrayList<>(); private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); public BitrateController(NetworkMonitor networkMonitor) { this.networkMonitor = networkMonitor; executorService.scheduleAtFixedRate(() -> { int quality = calculateNetworkQuality(); adjustBitrate(quality); }, 0, 2, TimeUnit.SECONDS); } private int calculateNetworkQuality() { NetworkStatus status = networkMonitor.getLatestStatus(); if (status instanceof NetworkGood) { return 90; } else if (status instanceof NetworkFair) { return 70; } else if (status instanceof NetworkPoor) { return 40; } return 50; } private void adjustBitrate(int quality) { int newBitrate; if (quality > 80) { newBitrate = (int) (currentBitrate * 1.2); } else if (quality < 40) { newBitrate = (int) (currentBitrate * 0.7); } else { newBitrate = currentBitrate; } newBitrate = Math.max(100000, Math.min(2000000, newBitrate)); if (newBitrate != currentBitrate) { currentBitrate = newBitrate; for (BitrateListener listener : listeners) { listener.onBitrateChanged(newBitrate); } } } public void addBitrateListener(BitrateListener listener) { listeners.add(listener); } public void removeBitrateListener(BitrateListener listener) { listeners.remove(listener); } } interface BitrateListener { void onBitrateChanged(int newBitrate); } class NetworkMonitor { private int rtt = 100; // 毫秒 private float lossRate = 0f; // 丢包率 private int jitter = 50; // 抖动 public NetworkStatus getLatestStatus() { if (lossRate > 0.2f) { return new NetworkPoor(); } else if (rtt > 300) { return new NetworkFair(); } return new NetworkGood(); } public void setRtt(int rtt) { this.rtt = rtt; } public void setLossRate(float lossRate) { this.lossRate = lossRate; } public void setJitter(int jitter) { this.jitter = jitter; } } class NetworkGood implements NetworkStatus {} class NetworkFair implements NetworkStatus {} class NetworkPoor implements NetworkStatus {} interface NetworkStatus {} ``` ## 四、完整系统时序分析 ``` sequenceDiagram participant A as 发送端 participant B as 网络 participant C as 接收端 A->>B: 发送数据包1(seq=1, ts=100) A->>B: 发送数据包2(seq=2, ts=120) B--xC: 包2丢失 A->>B: 发送数据包3(seq=3, ts=140) C->>C: 检测到seq=2缺失 C->>B: 发送NACK重传请求 B->>C: 重传数据包2 C->>C: 按时间戳排序[1,3,2] C->>C: 调整播放顺序为[1,2,3] ``` 我的主题貌似解析不了,请看下图 关键时序说明: - 接收端通过时间戳检测乱序包 - 选择性重传机制(NACK)保证关键数据 - 播放线程按时间戳重新排序 ## 五、性能优化实战 ### 1\. 内存优化技巧 ``` // 使用对象池减少GC public class RtpPacketPool { private static final int MAX_POOL_SIZE = 50; private static final Queue pool = new ConcurrentLinkedQueue<>(); public static RtpPacket obtain() { RtpPacket packet = pool.poll(); return packet != null ? packet : new RtpPacket(); } public static void recycle(RtpPacket packet) { if (pool.size() < MAX_POOL_SIZE) { packet.reset(); pool.offer(packet); } } } // 使用示例 void processPacket(byte[] data) { RtpPacket packet = RtpPacketPool.obtain(); packet.parse(data); // ...处理逻辑... RtpPacketPool.recycle(packet); } ``` ### 2\. 线程优先级调整 ``` // 设置实时音频线程优先级 private void setThreadPriority() { Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { PerformanceHintManager perfHintManager = (PerformanceHintManager) context.getSystemService(Context.PERFORMANCE_HINT_SERVICE); SessionParams params = new SessionParams( PerformanceHintManager.SESSION_TYPE_CPU_LOAD, new CpuRange(70, 100)); PerformanceHintManager.Session session = perfHintManager.createSession(params); session.reportActualWorkDuration(500_000); // 500ms周期 } } ``` 优化效果: - 音频线程调度延迟降低 30-50% - GC 暂停时间减少 80% - CPU 利用率提升 20% 需要更深入某个技术点的实现细节可以随时告知! [android](https://banzhuanriji.com/tag/android/) · [实时语音通话](https://banzhuanriji.com/tag/%E5%AE%9E%E6%97%B6%E8%AF%AD%E9%9F%B3%E9%80%9A%E8%AF%9D/) · [UDP](https://banzhuanriji.com/tag/UDP/) · [传输优化](https://banzhuanriji.com/tag/%E4%BC%A0%E8%BE%93%E4%BC%98%E5%8C%96/) · [音频流式处理](https://banzhuanriji.com/tag/%E9%9F%B3%E9%A2%91%E6%B5%81%E5%BC%8F%E5%A4%84%E7%90%86/) · [回声消除算法](https://banzhuanriji.com/tag/%E5%9B%9E%E5%A3%B0%E6%B6%88%E9%99%A4%E7%AE%97%E6%B3%95/) · [前向纠错编码](https://banzhuanriji.com/tag/%E5%89%8D%E5%90%91%E7%BA%A0%E9%94%99%E7%BC%96%E7%A0%81/) · [Jitter Buffer](https://banzhuanriji.com/tag/Jitter-Buffer/) · [WebRTC](https://banzhuanriji.com/tag/WebRTC/) · [动态码率调整](https://banzhuanriji.com/tag/%E5%8A%A8%E6%80%81%E7%A0%81%E7%8E%87%E8%B0%83%E6%95%B4/) · [网络自适应策略](https://banzhuanriji.com/tag/%E7%BD%91%E7%BB%9C%E8%87%AA%E9%80%82%E5%BA%94%E7%AD%96%E7%95%A5/) · [Android 性能优化](https://banzhuanriji.com/tag/Android-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/) · [实时传输协议](https://banzhuanriji.com/tag/%E5%AE%9E%E6%97%B6%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE/) · [弱网对抗技术](https://banzhuanriji.com/tag/%E5%BC%B1%E7%BD%91%E5%AF%B9%E6%8A%97%E6%8A%80%E6%9C%AF/) * * * ### 评论 提交你的评论 ## AI Hype Critique # [世界不是 AI 主题乐园](https://banzhuanriji.com/) _2025-03-15 12:12_ _·_ [随笔](https://banzhuanriji.com/category/essay/) 今天打开github weekly榜单,清一色全是ai相关的内容…我想起来前几天刷producthunt,连续几天排行榜全是ai产品。过去 72 小时的新产品榜单上,42 款产品名称包含 “AI-powered”,7 款在描述中强调 “no AI involved” 以示清流,唯一敢用中性描述的,是某款 AI 检测工具。 这种似曾相识的狂热,让我想起 1975 年全美超市货架摆满宠物石(Pet Rock)的荒诞场景。当时广告商人加里・达尔把普通鹅卵石装进纸盒,附上 32 页《养护手册》宣称 “永不死亡、无需喂食”,三个月狂销 150 万颗石头。今天的 AI 创业公司们正在复刻这种黑色幽默:某团队融资 500 万美元开发的 “AI 日程管家”,实际功能是把谷歌日历事件转成 emoji 表情;估值 1.2 亿美元的 “智能邮件助手”,核心技术竟是定时发送邮件的 crontab 脚本。 资本市场的推波助澜让这场闹剧愈发魔幻。宠物石当年催生了镶水钻的豪华版和 “分离焦虑症治疗课程”,如今 VC 们正在批量制造 “AI + 区块链知识图谱”、”多模态元宇宙助理” 等缝合怪项目。Y Combinator 最新批次的初创公司中,83% 的商业计划书首页印着 “revolutionize XX industry with AI”,而实际产品往往只是给现有服务套了层 ChatGPT 的对话外壳。 更危险的趋势在于核心技术的空心化。宠物石热潮至少创造了纸盒包装和手册设计的就业机会,而今某些 “AI 原生应用” 连基本功能都漏洞百出:某明星项目标榜的 “自主任务分解” 实为固定流程模板,其开源代码库里 90% 的 commit 记录是在修改 README 文档;某融资千万的 AI 绘画工具,被开发者扒出底层调用的仍是 Stable Diffusion 1.5 接口。 历史总在提醒我们集体癔症的代价。1976 年宠物石滞销时,达尔将库存改造成镇纸才避免破产,今天那些 All in AI 的团队或许该提前准备 Plan B—— 当投资人说 “请讲个 AI 之外的故事” 时,至少能掏出块质感温润的石头。毕竟在 2025 年的科技丛林里,一块不会崩溃死机、无需云端订阅的实体鹅卵石,或许才是真正的颠覆式创新。 当 Humane 公司以 1.16 亿美元贱卖 AI 业务时,其联合创始人伊姆兰・乔杜里或许会想起三年前 TED 演讲台上那个意气风发的自己。彼时他描绘的无屏 AI 世界,如今只剩服务器关闭后用户设备里被清空的记忆,以及科技博主 MKBHD”史上最差产品” 的判词。这不仅是某个创业公司的滑铁卢,更是整个行业陷入 AI 异化的缩影。 在资本市场的狂欢中,科技公司正陷入集体癔症:某电动自行车将 ChatGPT 塞进控制系统,声称能生成 “诗意骑行路线”;某智能花瓶强行嫁接大模型,试图用 AI 生成的鸡汤文学替代真实的插花艺术;更有企业将语音助手植入旅行鞋,让鞋子在用户行走时朗诵历史故事。这些荒诞的 AI 嫁接,如同给蒸汽机车安装触摸屏般充满违和感,暴露出行业对技术本质的深刻误解。 这种技术滥用正在形成危险的恶性循环。某 “AI 私人助理” 软件收取 129 元会员费后,生成的视频素材仅能实现图片缩放特效;某笔记本电脑搭载的写作 AI 在付费后,产出内容质量反而断崖式下跌。当企业把 AI 视为融资密码而非解决方案时,产品就沦为资本市场的行为艺术 ——Rabbit R1 预售两日售罄的盛况,与后续曝光的系统漏洞形成黑色幽默,恰似给马车装上火箭引擎却忘记安装刹车。 更深层的危机在于,这种 AI 崇拜正在摧毁科技产品的完整性。微软 Copilot 被制药公司 CIO 怒斥为 “中学生水平的 PPT 生成器”,其图标在 1080P 显示器上都会产生视觉畸变;魅族 All in AI 的战略转型,本质是对智能手机基础体验丧失信心的逃亡。当科技巨头都沉迷于给计算器添加语音交互功能时,整个行业正在集体上演 “皇帝的新衣”。 回归理性或许需要一场行业层面的戒断治疗。惠普收购 Humane 团队后组建的 IQ 部门,选择将 AI 深度集成到打印机和会议系统,这种 “润物细无声” 的路径反而展现出生命力;影视行业用 AI 生成故宫场景取代实景拍摄的务实选择,证明技术赋能不应等同于颠覆重构。正如导演在航母拍摄现场领悟的:AI 可以生成舰载机,但驾驭战鹰的必须是活生生的飞行员。 科技史反复证明,任何脱离场景价值的技术炫技终将沦为电子坟场的展品。当我们在博物馆凝视上世纪 90 年代的语音控制微波炉时,不该让子孙后代以同样戏谑的目光打量这个时代的 AI 胸针和会朗诵诗歌的花瓶。停止这场荒诞的 AI 化竞赛,或许才是科技行业重拾尊严的开始。 [ai](https://banzhuanriji.com/tag/ai/) · [创业](https://banzhuanriji.com/tag/%E5%88%9B%E4%B8%9A/) · [技术滥用](https://banzhuanriji.com/tag/%E6%8A%80%E6%9C%AF%E6%BB%A5%E7%94%A8/) * * * ### 评论 提交你的评论 ## Astro Performance Tips # [Astro初体验](https://banzhuanriji.com/) _2025-03-13 12:17_ _·_ [前端](https://banzhuanriji.com/category/frontend/) ## 初体验的问题 作为一个前端新手,我决定用 Astro 框架重构个人博客。听说它的静态生成能力和 Partial Hydration 特性可以让网站又快又省资源,这对我这种追求极简的写作者来说简直完美。本地开发时一切顺利,热更新响应迅速,Markdown 渲染流畅。但当我部署到 Vercel 后,用户反馈点击文章链接需要等待 3-5 秒才能看到内容。整个跳转给我的感觉就是卡卡的 —— 明明用了静态站点生成,为什么会有这个诡异的延迟? 打开 Network 面板重新加载页面,发现: HTML 文件加载仅需 100ms,但主内容渲染延迟了 2.3s;页面加载时触发了多个;Hydration 事件客户端 ;JS 体积达到 420KB… 然后我大概就知道问题在哪里了。 简单地说你可以理解为,本来一次点击,浏览器从A页面跳转到B页面,无论是A页面的消失还是B页面的逐步呈现,这个过程都没有被忽略。Astro的部分渲染,在B页面被完全加载出来之前都停留在A页面,他需要等待B页面的不同内容加载之后刷新视图,呈现B页面的内容。 > 另外我发现这个特行可以让你实现类似Android里的共享元素的炫酷效果。 我意识到问题可能与 Astro 的核心特性有关: ### 1\. 过度使用客户端组件 在文章页模板中,我为了实现 “阅读进度条” 功能,错误地使用了client:load指令: ``` ``` 这导致整个组件在页面加载时立即执行 Hydration,阻塞了主线程。 ### 2\. 动态路由的 Hydration 策略 我的文章路由采用动态参数\[slug\].astro,默认配置下: ``` // astro.config.mjs(原配置) export default defineConfig({ experimental: { islands: false } }); ``` 这导致 Astro 在客户端重新渲染整个页面,而非仅更新必要部分。 ### 3\. 资源加载未优化 未压缩的图片平均大小 300KB;未启用 Gzip;第三方字体文件阻塞渲染。 这里图片我是引用的第三方图库,虽然没有加preload,但是速度其实还算可以。不过多张图片引用也会影响速度。 尤其要说一下这个字体,我最开始测试的,google fonts的访问速度怎么会比loli.net要快这么多?难道是国内也有服务器? 后来我发现了问题。 google fonts引用的css,是切割好的字体文件。也就是这个css可以理解为是一个目录,里面有分好包的实际字体文件(目前常用方法),然后这个css会分批引用实际字体文件。给👴🏻整无语了。一整个页面就在那里等它这个字体加载。 ## 系统性优化方案 经过调试,我逐步实施了以下解决方案: ### 1\. 组件 Hydration 策略优化 ``` ``` ### 2\. 配置调整 ### 3\. 资源加载优化 使用astro-imagetools自动压缩图片。其实直接添加懒加载就可以了。 ### 4\. 给所有二进制文件添加preload 优化后数据 - 优化后:首字节时间(TTFB)从 800ms 降至 120ms - 最大内容渲染时间(LCP)从 2.8s 降至 700ms - 客户端 JS 体积减少至 180KB(js问题不大) ## 最后 静态站点生成不等于自动高性能 前端性能优化需要系统性思维 Astro 的强大在于合理利用其特性,而非盲目使用 现在,我的博客不仅加载速度提升了,Lighthouse 98 XD。 更重要的是,我学会了如何通过 Chrome DevTools 和 Astro 内置工具进行性能分析。如果你也遇到类似问题,可以参考一下我上面的方案。(避雷Google fonts) [博客](https://banzhuanriji.com/tag/%E5%8D%9A%E5%AE%A2/) · [astro](https://banzhuanriji.com/tag/astro/) · [静态网站](https://banzhuanriji.com/tag/%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99/) · [生成](https://banzhuanriji.com/tag/%E7%94%9F%E6%88%90/) · [优化](https://banzhuanriji.com/tag/%E4%BC%98%E5%8C%96/) · [数据加载](https://banzhuanriji.com/tag/%E6%95%B0%E6%8D%AE%E5%8A%A0%E8%BD%BD/) · [Hydration](https://banzhuanriji.com/tag/Hydration/) * * * ### 评论 提交你的评论 ## 404 Page Not Found # 404 - 页面没找到 ### 你想查看的页面已被转移或删除了 ## League of Legends Decline # [英雄联盟的玩法困局与玩家逃离启示录](https://banzhuanriji.com/) _2025-03-08 17:30_ _·_ [随笔](https://banzhuanriji.com/category/essay/) ## TL;DR fk lol, fk riot, fk 🐧 * * * LOL最近发布了 **《3月6日凌晨1点停机版本更新公告》**,更新公告中写: > 本次更新的核心调整在于削弱职业赛中前期换线战术的可行性。团队加入了一系列机制来遏制这一现象,如果在1:30 - 3:30之间派出两名非打野英雄进入上路或中路及其周边区域,该队伍将受到严厉惩罚。不过,如果己方没有打野,这些机制将不会生效(即五层2/1/2阵容不会受影响),即将触发机制时,系统会发出警告。 最近的设计的英雄和玩法的改动,看得出这个年龄超过15岁的老游戏挣扎在规则与自由之间寻找平衡。 ## 一、系统规则下的战术窒息:从灵活多变各展神通,到BP绞杀一步输赢,下一步或许是“数据型选手”的崛起 用户文章揭示的“换线战术使用率骤降”并非孤立现象,其背后是设计师对战术自由度的系统性收束。以2025年全局BP规则为例,职业战队在禁用阶段需遵循“蓝红交替禁用6英雄→选3英雄→再禁用4英雄”的复杂流程8,这使得战术博弈从“创新应对”退化为“规避惩罚”。LPL赛区NIP战队因在红色方放出100%被Ban率的蝎子导致惨败,正是这种规则压迫下的典型悲剧——与其冒险创新,不如遵从版本“标准答案”10。 更深远的影响体现在选手培养体系。正如Uzi感慨LCK选手职业寿命普遍长于LPL,根源在于LPL青训更倾向培养“数据适应型选手”:他们精于计算镀层经济、峡谷先锋刷新时间,却丧失了早期选手如Clearlove的野区路线创新力10。当职业赛场70%的训练时间用于解析版本机制而非战术开发,MOBA的“即时策略”本质已被异化为“数值模拟器”。 设计师的初衷或许是好的——提升比赛观赏性、降低新人门槛。但过度干预的代价正在显现: - 职业赛场同质化:强对线选手受益,而战术大师的价值被削弱。如T1战队的换线运营曾是其夺冠关键,新版本下他们必须彻底重构战术体系39。 - 路人局创新窒息:玩家一旦尝试非常规套路,可能触发惩罚机制或消极游戏判定38。当“非主流”成为禁忌,游戏生命力必然衰退。 - 观众与玩家的双重流失:比赛变成“对线模拟器”,而普通玩家转向大乱斗,最终导致电竞生态根基动摇。 如今,玩法框架一步一步缩减,游戏的乐趣或许正在成为比赛的牺牲品? ## 二、大乱斗的悖论性胜利:失控中的创造力重生 用户提到大乱斗“随机英雄机制意外创造战术创新温床”,这在实战中体现得淋漓尽致。以时光老头为例,其在大乱斗专属加强后衍生出“CD流无限控”与“AP自爆流”两种极端打法:前者通过堆叠技能急速实现每2.69秒一次群体控制,后者利用雪球突进+Q技能自爆制造混乱111。这种“非常规出装”的盛行,恰恰是对传统模式装备合成路径强制引导的反抗。 但大乱斗的生态裂痕同样触目惊心。30%胜率精粹号组成的“五黑车队”通过脚本送人头操控匹配机制,将普通玩家变成“菠菜筹码”;“红包局”更衍生出“一条命赌局”“212伤害比拼”等变异玩法,将竞技异化为赌博工具3。讽刺的是,玩家明知这些乱象存在,仍以68%的比率选择大乱斗,只因“失控的对抗”比“规则的牢笼”更具吸引力311。 值得玩味的是,在竞技模式日渐僵化的同时,极地大乱斗的玩家占比持续攀升。这一现象绝非偶然: 1. 低压力与高随机性:大乱斗无需研究版本答案,英雄随机性消解了“最优解”焦虑。 2. 去策略化的纯粹对抗:狭窄地图与频繁团战让玩家聚焦操作而非运营,回归“打架”的原始乐趣。 3. 逃离设计师的“监管”:大乱斗较少受版本机制束缚,玩家可自由尝试非常规出装与打法。 当召唤师峡谷变成“按规则填写的试卷”,大乱斗则成了玩家保留最后一丝创造力的“游乐场”。这种割裂折射出一个残酷现实:游戏正在分化成“职业赛场”与“娱乐模式”两个平行世界,而中间地带的策略深度逐渐消亡。 ## 三、生态割裂的恶性循环:职业赛场与娱乐模式的平行宇宙 用户提及的“主播大乱斗直播占比飙升”现象,与职业赛场的“BP坐牢”形成残酷对照。T1战队虽凭借全局BP新规下的策略调整夺冠,但其依赖的“系列赛禁用重复英雄”机制,本质上仍是设计师对战术树的修剪——选手被迫在10个禁用英雄的限制中重复使用版本答案,而非开发新体系68。 这种割裂在玩家社区形成认知断层:当职业选手研究蝎子打野的100%胜率秘诀时12,普通玩家却在论坛热议“寒冰电刀回血流”“老鼠幕刃秒杀术”等大乱斗邪道玩法11。更致命的是,匹配模式中“标准化阵容选择率突破65%”的数据,暴露出设计师规则已渗透至玩家潜意识——当创新被视为风险,保守即是最优解。 ## 四、破局之路:在规则与混沌间重建MOBA的“元游戏” 用户提出的“加入随机元素”设想,已在部分模式中验证可行性。极地大乱斗的“骰子重roll机制”允许玩家通过交换英雄打破阵容僵局11,若将其引入排位赛,或可缓解BP阶段的套路固化。更激进的方案是借鉴《VALORANT》的“技能+枪械”双元设计:在保留MOBA核心机制的同时,通过随机技能组合激活战术可能性。 设计师需重新理解“平衡”的内涵——真正的平衡不是消除变量,而是构建动态博弈空间。例如将换线惩罚机制改为“换线方获得推塔速度加成但损失部分小兵经验”,既能抑制无脑换线,又保留战术选择权10。当玩家意识到“规则是沙盒而非牢笼”,MOBA才能重获生命力。 * * * 英雄联盟的困境,本质是工业化游戏设计对人性博弈本能的背离。当系统用镀层机制规定对线期、用野区计时器取代反野决策时,玩家只能通过大乱斗的“无序狂欢”找回原始乐趣。正如T1教练组在纪录片中所说:“最好的战术永远诞生于玩家的意外操作,而非设计师的Excel表格”。或许某天,当召唤师峡谷的防御塔不再秒杀换线英雄,而是记录下每个打破常规的精彩瞬间,这个游戏才能真正完成它的“范式革命”。 这个游戏技能是固定的,英雄是固定的,甚至胜利的方法都给你固定了。但是不同英雄不同的技能组合,配上不同的玩家,就有无限种可能和乐趣。与人斗其乐无穷。 而riot,或许正在一次次的更新中,杀死LOL的乐趣。 * * * ### 评论 提交你的评论 1. ![](https://cravatar.cn/avatar/6d9a1bb5bc57033de1e4029702743294?s=80&r=G&d=mm) [hary](https://www.hary.cc/)2025-Mar-9 原来上学的时候老喜欢组队去玩,现在一晃都五六点没碰过了,但是年年的比赛都不落下 ## Add Comments in Theme # [在final中添加评论](https://banzhuanriji.com/) _2025-03-07 10:37_ _·_ [主题](https://banzhuanriji.com/category/theme/) ## 一,创建文件 > 下面的文件均创建在主题文件夹中。 ### 1\. 创建样式代码 `comments.css` (你可以把下面的内容放到style.css中) ```lang-css .comment-container form{ border: 0px; padding: 20px; border-radius: 10px; margin-top: 20px; margin-bottom: 20px; background-color: #f0f0f0; } .clearfix::after { content: ""; display: table; clear: both; } #comments { list-style-type: none; padding: 0; } .comment-body { padding: 15px 20px; list-style-type: none!important; border-radius: 10px; margin: 2.5rem 0px; background-color: #f0f0f0; } .comment-header { display: flex; align-items: center; margin-bottom: 10px; } .avatar { height: 2.5rem; width: 2.5rem; border-radius: 50%; margin-right: 10px; } .comment-author { font-weight: bold; color: #333; } .comment-by-author { color: #007bff; } .comment-by-user { color: #28a745; } .comment-content { background-color: #f0f0f0; border-radius: 10px; padding: 5px 20px; background-color: #fefefe; margin-bottom: 10px; } .comment-meta { font-size: 0.8em; color: #888; } .comment-reply { cursor: pointer; color: #007bff; } .comment-reply:hover { text-decoration: underline; } .comment-child { margin-left: 30px; } .comment-list{ padding: 0px; margin: 20px 0px 0px 0px; font-size: 0.9rem; } .form-control { width: 100%; padding: 15px; margin-bottom: 20px; border: 0px; background-color: #fefefe; box-sizing: border-box; } .submit { color: #090909; padding: 0.7em 1.7em; font-size: 18px; border-radius: 0.5em; width: 100%; background: #ffffff; cursor: pointer; border: 0; } .response { color: #888; } .lists-navigator { text-align: center; margin-top: 20px; } textarea { height: 10rem; resize: none; outline: none; } form input,form textarea{ font-family: 'Noto Sans SC',consolas,monospace; font-size: 0.8rem; border-radius: 10px; background: #ffffff; } ``` ### 创建 `comments.php` 2. 以下为我的代码,请注意第一行的引用代码。引用的样式代码为上面的CSS样式. 如果你已经放置到 `style.css` 中,你可以删除下面代码的第一行代码。 如果你已经创建css文件,直接复制下面的内容即可。 ```lang-php

评论

authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; } else { $commentClass .= ' comment-by-user'; } } $commentLevelClass = $comments->levels > 0 ? ' comment-child' : ' comment-parent'; $depth = $comments->levels +1; if ($comments->url) { $author = '' . $comments->author . ''; } else { $author = $comments->author; } ?>
  • commentsAvatarRating; $hash = md5(strtolower($comments->mail)); $avatar = $host . $url . $hash . '?s=' . $size . '&r=' . $rating . '&d=' . $default; ?>
    content(); ?>

    reply('Reply'); ?>
    children) { ?>
    threadedComments($options); ?>
  • comments()->to($comments); ?> allow('comment')): ?>
    user->hasLogin()): ?>
    options->commentsRequireURL): ?> required> options->commentsRequireMail): ?> required>
    widget('Widget_Security'); ?>
    评论区暂时被关闭了 have()): ?> listComments(); ?>
    pageNav('←','→','2','...'); ?>
    ``` ## 二,使用 在你需要的地方添加 `need('comments.php'); ?>` [主题](https://banzhuanriji.com/tag/%E4%B8%BB%E9%A2%98/) · [final](https://banzhuanriji.com/tag/final/) · [评论](https://banzhuanriji.com/tag/%E8%AF%84%E8%AE%BA/) * * * ### 评论 提交你的评论 1. ![](https://cravatar.cn/avatar/4cd9076480c7d09fb40bde42ad014fff?s=80&r=G&d=mm) [搬砖日记](https://banzhuanriji.com/)2025-Mar-7 这里是评论样式的测试#1 这里是评论样式的测试#2 2. ![](https://cravatar.cn/avatar/49e3c2b39cae94d06289c81023776631?s=80&r=G&d=mm) [yingyu5658](https://www.yingyu5658.cn/)2025-Mar-12 酷 ## Free Static Hosting Comparison # [免费静态托管服务对比](https://banzhuanriji.com/) _2025-02-14 12:36_ _·_ [服务器](https://banzhuanriji.com/category/server/) 在当今的网络环境中,静态网站托管服务变得越来越流行,尤其是对于开发者和博客作者来说。本文将介绍三种流行的免费静态网站托管服务:Vercel、GitHub Pages 和 Cloudflare Pages,并对它们的免费服务进行比较。 ### Vercel Vercel 是一个专注于前端开发的托管平台,提供快速、可靠的静态网站托管服务。它的主要特点包括: - **全球 CDN**:Vercel 在全球范围内拥有多个 CDN 节点,确保网站的快速加载。 - **自定义域名**:支持用户使用自定义域名,并提供自动部署功能。 - **构建限制**:每月带宽限制为 100GB,构建次数和构建时长也有限制,但整体上对个人用户来说相对宽松。 - **速度**:在国内访问速度较快,通常比 GitHub Pages 和 Cloudflare Pages 更具优势。 ### GitHub Pages GitHub Pages 是 GitHub 提供的静态网站托管服务,适合开发者和开源项目。其特点包括: - **稳定性**:作为全球最大的代码托管平台,GitHub Pages 的稳定性相对较高。 - **自定义域名**:支持用户使用自定义域名。 - **访问速度**:在国内访问速度一般,偶尔会出现访问问题。 - **限制**:每月流量限制为 100GB,单个文件大小限制为 100MB,仓库大小建议少于 5GB。 ### Cloudflare Pages Cloudflare Pages 是 Cloudflare 推出的静态网站托管服务,旨在提供快速和安全的网站托管。其特点包括: - **全球 CDN**:同样拥有全球 CDN 节点,确保快速加载。 - **自定义域名**:支持最多 10 个自定义域名。 - **构建限制**:每月可构建 500 次,文件数量限制为 2万,单个文件大小不得超过 25MB。 - **速度**:与 GitHub Pages 相似,但在国内的访问速度和稳定性一般。 ### 免费服务对比 在比较这三种服务时,可以从以下几个方面进行分析: 1. **访问速度**: - Vercel 的访问速度在国内表现最佳,通常比 GitHub Pages 和 Cloudflare Pages 更快。 - GitHub Pages 和 Cloudflare Pages 的速度相似,但 GitHub Pages 的稳定性更好。 2. **自定义域名支持**: - 三者均支持自定义域名,但 Cloudflare Pages 对域名数量有上限(最多 10 个)。 3. **构建和流量限制**: - Vercel 每月带宽限制为 100GB,构建次数和时长有限制。 - GitHub Pages 每月流量限制为 100GB,文件和仓库大小也有相应限制。 - Cloudflare Pages 每月可构建 500 次,文件数量和大小限制较为严格。 4. **适用场景**: - Vercel 适合需要快速加载和高稳定性的个人博客或项目。 - GitHub Pages 适合开源项目和开发者,尤其是对百度收录有需求的用户。 - Cloudflare Pages 适合需要使用 Cloudflare CDN 的用户,但在国内的表现可能不如 Vercel。 ### 结论 综合来看,Vercel 是一个非常适合个人博客和前端项目的托管平台,尤其是在国内访问速度方面表现突出。GitHub Pages 则是一个稳定的选择,适合开源项目和开发者。Cloudflare Pages 虽然提供了强大的 CDN 支持,但在国内的访问速度和稳定性相对较弱。根据个人需求选择合适的平台,将有助于提升网站的访问体验。 * * * 如果你想试一下你所在的地区访问各服务的速度,你可以使用以下数据 ### 无域名,平台部署测试域名访问 - Vercel: [https://static-pages-test.vercel.app/](https://static-pages-test.vercel.app/) - Cloudflare Pages: [https://static-pages-test.pages.dev/](https://static-pages-test.pages.dev/) - Github Pages: [https://hoytzhang.github.io/static-pages-test/](https://hoytzhang.github.io/static-pages-test/) - Netlify: [https://static-page-test.netlify.app/](https://static-page-test.netlify.app/) ### 域名访问,由Cloudflare进行DNS解析,无CDN - Vercel: [https://spt.vercel.linkpark.site/](https://spt.vercel.linkpark.site/) - Cloudflare Pages: [https://spt.cfpages.linkpark.site/](https://spt.cfpages.linkpark.site/) - Github Pages: [https://spt.ghpages.linkpark.site/](https://spt.ghpages.linkpark.site/) - Netlify: [http://spt.netlify.linkpark.site/](http://spt.netlify.linkpark.site/) > 以上引用内容来自: [https://github.com/hoytzhang/static-pages-test](https://github.com/hoytzhang/static-pages-test) > > 你可以使用 `https://www.itdog.cn/http/` 来进行访问对比 [vercel](https://banzhuanriji.com/tag/vercel/) · [GitHub Pages](https://banzhuanriji.com/tag/GitHub-Pages/) · [Cloudflare Pages](https://banzhuanriji.com/tag/Cloudflare-Pages/) · [静态网站托管](https://banzhuanriji.com/tag/%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99%E6%89%98%E7%AE%A1/) · [免费服务](https://banzhuanriji.com/tag/%E5%85%8D%E8%B4%B9%E6%9C%8D%E5%8A%A1/) · [访问速度](https://banzhuanriji.com/tag/%E8%AE%BF%E9%97%AE%E9%80%9F%E5%BA%A6/) · [自定义域名](https://banzhuanriji.com/tag/%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D/) · [构建限制](https://banzhuanriji.com/tag/%E6%9E%84%E5%BB%BA%E9%99%90%E5%88%B6/) * * * ### 评论 提交你的评论 ## Car Key Detection # [汽车如何知道我带没带车钥匙](https://banzhuanriji.com/) _2025-02-06 17:26_ _·_ [随笔](https://banzhuanriji.com/category/essay/) 不知道你们有没有过这样的经历,下车的时候要是没带车钥匙,汽车就会 “嘀嘀嘀” 地提醒你。这就很神奇了,汽车到底是咋知道我带没带钥匙的呢?今天咱就来唠唠这个有趣的事儿。 在现代汽车的智能化功能中,车辆能够精准识别驾驶员上车和下车时是否携带车钥匙,这一功能极大地提升了用户体验与便利性。当驾驶员未携带钥匙离开车辆时,车辆会及时发出提醒,避免钥匙遗落的尴尬。那么,汽车究竟是如何实现这一智能识别的呢? ## 无钥匙进入系统的工作机制 无钥匙进入系统是实现这一功能的核心技术之一。汽车配备了多个低频天线,在车辆熄火后,这些天线持续发射低频信号,从而在车辆周围构建起特定的感应区域。当携带车钥匙靠近车辆时,车钥匙中的芯片接收到低频信号并被激活。激活后的车钥匙通过高频信号将自身身份编码等信息传输至车辆的控制模块。车辆控制模块接收到信号后,会对车钥匙的身份进行严格验证,只有验证通过,才会允许车辆执行解锁车门等操作。 ## 识别钥匙携带状态的具体方式 1. 距离检测:在驾驶员准备下车时,无钥匙系统会持续监测车钥匙与车辆之间的距离。当驾驶员打开车门,系统会实时判断车钥匙是否仍处于车内或车辆的有效感应范围内。一旦车钥匙超出感应范围,系统便会判定驾驶员可能遗忘钥匙,进而触发提醒机制,以声音警报或仪表盘提示信息等方式告知驾驶员。 2. 车内传感器协同工作:车内配备了多种传感器,如座椅传感器和车门传感器。座椅传感器能够感知座椅上的压力变化,从而判断驾驶员是否离开座位;车门传感器则负责监测车门的开关状态。当驾驶员打开车门准备下车时,座椅传感器检测到压力变化,确认驾驶员起身,同时车门传感器确认车门开启。此时,若系统未检测到车钥匙在车内的信号,便会立即发出提醒。 汽车能够准确识别驾驶员是否携带车钥匙,得益于无钥匙进入系统与各类传感器的协同运作。这一智能化功能不仅为用户提供了便利,还降低了车钥匙遗落的风险,让驾驶出行更加安心、便捷。随着汽车技术的不断发展,未来这一功能有望进一步优化,为用户带来更优质的使用体验。 [汽车](https://banzhuanriji.com/tag/%E6%B1%BD%E8%BD%A6/) · [无钥匙进入系统](https://banzhuanriji.com/tag/%E6%97%A0%E9%92%A5%E5%8C%99%E8%BF%9B%E5%85%A5%E7%B3%BB%E7%BB%9F/) · [传感器](https://banzhuanriji.com/tag/%E4%BC%A0%E6%84%9F%E5%99%A8/) · [钥匙识别](https://banzhuanriji.com/tag/%E9%92%A5%E5%8C%99%E8%AF%86%E5%88%AB/) * * * ### 评论 提交你的评论 ## Unlockable Android Devices # [仍然可以解BL锁的Android手机](https://banzhuanriji.com/) _2025-02-03 12:29_ _·_ [android](https://banzhuanriji.com/category/android/) 在安卓玩机圈中,Bootloader解锁是开启系统魔改大门的金钥匙。不同品牌对BL解锁的态度差异巨大,本文将根据最新政策为你梳理各品牌的解锁难度,助你找到最适合折腾的手机设备。 ## 一、小白友好型(解锁难度低) ### 1\. 一加手机 堪称刷机界的"良心典范",全系列开放OEM解锁开关,开发者选项中一键解除BL锁,无需任何审核或等待,堪称极客入门首选。 ### 2\. Google Pixel 原生系统配合官方fastboot解锁命令,通过adb reboot bootloader+fastboot flashing unlock即可完成。更难得的是解锁后仍保留保修服务,官方甚至提供工厂镜像下载。 ### 3\. 摩托罗拉 国行非定制机在官网提交IMEI申请解锁码,收到邮件后通过fastboot输入16位代码即可秒解,流程透明无需社区等级等限制。 ### 4\. HTC 老牌刷机王延续开放传统,官网提供专用解锁工具HTCDev,注册账号后按指引操作,同时保留完善的root工具链支持。 ## 二、进阶挑战型(解锁难度中) ### 1\. 索尼Xperia 需在开发者中心申请解锁码,特别注意:部分运营商合约机不可解锁。解锁后会触发DRM熔断,需自行修复相机算法降级问题。 ### 2\. 三星Galaxy 欧版/国行设备在Download模式下输入OEM UNLOCK,但会触发Knox熔断机制,导致Samsung Pay等金融功能永久失效,且不可逆。 ### 3\. OPPO系设备 Reno6系列需申请深度测试权限(审核1-3天),联发科机型保留9008工程模式强解通道。ColorOS 13后新增解锁计数器,多次刷机可能触发反回滚机制。 ### 4\. 真我realme 2024新政后仅限Neo5/GT5等旗舰开放深度测试,旧机型需拆机短接进入EDL模式。天玑平台可尝试MTKClient工具绕过限制,但存在基带丢失风险。 ## 三、硬核试炼型(解锁难度高) ### 小米/Redmi全家桶 需通过包含30道专业题目的资格测试(正确率需达80%),配合小米社区5级账号+实名认证。最严苛的是336小时有效期设定,需在14天内完成设备绑定-解锁全流程,且每个实名账号每年仅限解锁1台设备。 ## 解锁小贴士: - 华为/荣耀全系:自2018年起已关闭BL解锁服务 - vivo/iQOO:除Xplay等上古机型外,全线封杀解锁通道 - 中兴系:需支付$50获取解锁证书 选择设备时建议优先考虑解锁难度低的品牌,特别是Pixel系列既能享受原生更新又保有保修权益。对于追求极致定制的玩家,建议备两台设备:一台保持官方系统满足日常使用,另一台选择一加/摩托罗拉等开放机型进行深度折腾。刷机有风险,解锁前务必备份重要数据并确认具体型号的解锁政策。 | 品牌 | 解锁难度 | 解锁方式及条件 | 注意事项 | | --- | --- | --- | --- | | 一加 | 低 | 打开 OEM 解锁按钮即可 | 无特殊注意事项 | | Google Pixel | 低 | 简单操作即可解锁 | 解锁后仍可享受保修服务 | | 摩托罗拉 | 低 | 官网申请,按流程操作 | 需是非定制机 | | HTC | 低 | 通过官方渠道或常见解锁工具 | 操作相对简单 | | 索尼 | 中等 | 官网获取解锁码,安装驱动和工具,通过命令行解锁 | 需先检查手机是否支持解锁 | | 三星 | 中等 | 可解锁 BL 并获取 Root 权限(非美版) | 解锁后芯片内部熔断,部分功能无法使用,如三星 Pay | | OPPO | 中等 | OPPO Reno6 及以下机型通过深度测试解锁;Reno7 及 A 系列新机仅天玑处理器可解锁 | 不同机型解锁策略不同,需按型号确定方法 | | 真我 | 中等 | 真我 neo5/gt5 等及以上新机可官方深度测试;MTK 天玑芯片可强制解锁 | 旧版机型不支持解锁;强制解锁有风险 | | 小米 / 红米 | 高 | 通过《解锁资格答题测试》,小米社区成长等级达 5 段,完成实名认证,在 336 小时(14 天)有效期内完成绑定和解锁 | 有效期内最多支持小米账号实名认证本人 1 台设备绑定和解锁 | * * * ### 评论 提交你的评论 ## AI Dialogue Revolution # [从咒语到对话](https://banzhuanriji.com/) _2025-01-31 14:57_ _·_ [ai](https://banzhuanriji.com/category/ai/) ## 一、现状反思:被关键词绑架的创造力 在AI绘图技术突飞猛进的今天,一个吊诡的现象正在发生:用户需要像程序员一样学习"咒语"(prompt engineering)才能获得理想结果。MidJourney的用户手册长达200页,Stable Diffusion的关键词组合堪比编程语言,这种现象与AI"自然交互"的初衷背道而驰。 专业用户交流群中流传着这样的关键词词典: - `"Unreal Engine 5"`:自动加载复杂的光影渲染 - `"Octane Render"`:触发电影级材质表现 - `"trending on ArtStation"`:激活流行艺术风格 - `"35mm f/1.8"`:控制镜头虚化效果 这些"魔法词汇"暴露了当前技术的深层缺陷:模型未能真正理解自然语言的语义网络,而是依赖关键词触发预置的参数组合。当用户需要"夕阳下奔跑的金毛犬"时,必须额外指定"黄金时刻光照"、"动态模糊"、"毛发细节8K",这本质上仍是工程师思维而非自然交互。 ## 二、技术瓶颈解构:跨模态理解的阿喀琉斯之踵 当前AI绘图系统的核心架构决定了其关键词依赖症。以主流扩散模型为例,文本编码器(text encoder)将自然语言压缩为768维的潜向量,这个信息瓶颈迫使模型建立"关键词-视觉特征"的简化映射关系。实验数据显示,CLIP模型对复杂语句的理解准确率仅为57%,远低于人类92%的水平。 多模态对齐存在三个致命缺陷: - **语义解耦不足**:模型难以区分"红色汽车在左侧"和"左侧汽车的红色部分" - **常识推理缺失**:无法理解"办公室午休场景"应包含咖啡杯、凌乱纸张等关联元素 - **风格语境混淆**:将"水墨风格"简单映射为黑白调色,忽略留白、笔触等美学特征 这种缺陷在用户研究中有直观体现:当使用自然语言描述时,图像与预期的匹配度仅为41%;而使用规范关键词时提升至78%。这证明当前系统本质上是"关键词检索器"而非真正的语义理解者。 ## 三、突破路径:下一代AI绘图的技术革命 前沿研究正在从三个维度突破这一困境: ### 1\. 知识增强型语言模型 Google的PaLI-3架构将视觉-语言模型与知识图谱结合,使系统理解"毕加索风格"时能自动关联立体主义、多视角等特征。这种结构化知识使提示词缩减30%的情况下,输出准确率提升18%。 ### 2\. 动态语义解析网络 Meta的DynaPrompt系统采用递归注意力机制,通过多轮对话解析用户意图。实验显示,经过5轮交互修正后,图像匹配度从初次生成的46%提升至89%,接近专业关键词的效果。 ### 3\. 神经符号系统融合 剑桥大学提出的SyMetric框架,将扩散模型与符号推理引擎结合。当用户描述"未来城市"时,系统自动调用城市规划知识库,补充交通网络、能源系统等细节,减少70%的手动参数调整。 ## 四、用户体验重构:从咒语念诵到创意对话 技术演进正在重塑人机交互范式。Adobe Firefly的最新测试版展示了革命性的改变: - 支持上下文延续:"调整刚才那幅画,让天空更阴沉些" - 理解隐喻表达:"给我梵高眼中的星夜" - 处理复杂逻辑:"主角服装融合唐朝服饰和赛博朋克元素" 这种进化不是简单的语言模型升级,而是整个AI认知架构的重构。当系统能理解"画面氛围"这样的抽象概念时,用户终于可以摆脱关键词词典,回归创作的本质——用人类自然的表达方式传递创意。 ## 五、未来展望:自然语言交互的技术奇点 当绘图AI的自然语言理解达到人类水平时,我们将见证创作方式的根本变革: - 实时协作模式:像指导人类画师一样与AI互动 - 风格迁移进化:用"更温暖些"替代"色温+300K" - 语义纠错能力:自动修正"漂浮的茶杯"的物理错误 技术路线图显示,到2026年主流AI绘图工具将淘汰关键词工程,届时输入框提示语将从"请输入详细描述"变为"告诉我您的创意想法"。这不仅是技术的进步,更是人机交互范式的革命——当AI真正理解自然语言时,创造力将突破专业术语的牢笼,回归到每个普通人的手中。 * * * > 下面是英文版本,由Deepseek翻译 > > Translated by Deepseek ## TL;DR The Path to Natural Language in AI Image Generation: From Spells to Dialogue ## 1\. The Current Paradox: Creativity Held Hostage by Keywords In the era of rapidly advancing AI image generation, a peculiar phenomenon persists: users must learn "spell-like" prompt engineering to achieve desired results. With MidJourney's 200-page manual and Stable Diffusion's keyword combinations resembling programming syntax, this reality starkly contradicts AI's original promise of natural interaction. Professional user communities circulate secret dictionaries of "magic words": - `Unreal Engine 5`: Activates complex lighting renders - `Octane Render`: Triggers cinematic material quality - `trending on ArtStation`: Unlocks popular art styles - `35mm f/1.8`: Controls bokeh effects These "incantations" reveal fundamental flaws in current systems: models don’t truly understand semantic networks but rely on keywords to trigger preset parameter combinations. To generate "a golden retriever running under sunset," users must manually specify "golden hour lighting," "motion blur," and "8K fur detailing" – essentially programming rather than natural communication. ## 2\. Technical Bottlenecks: The Achilles' Heel of Cross-Modal Understanding The core architecture of current AI image systems dictates their keyword dependency. In mainstream diffusion models, text encoders compress natural language into 768-dimensional latent vectors. This information bottleneck forces models to establish simplified "keyword-visual feature" mappings. Experimental data shows CLIP models achieve only 57% accuracy in parsing complex sentences, far below humans' 92%. Three critical flaws plague multimodal alignment: - **Inadequate Semantic Disentanglement**: Models struggle to distinguish "red car on the left" vs. "red parts of the left car" - **Missing Commonsense Reasoning**: Fails to infer "office lunch scene" should include coffee cups and scattered papers - **Style-Context Confusion**: Reduces "Chinese ink painting" to monochrome palettes, ignoring brushwork aesthetics User studies quantify these limitations: natural language prompts yield only 41% image-intent alignment versus 78% with engineered keywords. This proves current systems function as "keyword retrievers," not true semantic comprehenders. ## 3\. Breakthrough Pathways: The Next Revolution in AI Image Generation Cutting-edge research is tackling these challenges through three approaches: ### 1\. Knowledge-Augmented Language Models Google's PaLI-3 integrates vision-language models with knowledge graphs. When interpreting "Picasso style," it automatically associates cubism and multi-perspective features, achieving 18% higher accuracy with 30% fewer prompts. ### 2\. Dynamic Semantic Parsing Networks Meta's DynaPrompt employs recursive attention for multi-turn intent refinement. After 5 interaction rounds, image alignment jumps from 46% to 89%, rivaling expert-level prompts. ### 3\. Neuro-Symbolic Hybrid Systems Cambridge's SyMetric framework combines diffusion models with symbolic reasoning. For "future city" prompts, it auto-populates urban infrastructure details using knowledge bases, reducing manual adjustments by 70%. ## 4\. UX Transformation: From Incantations to Creative Dialogue These innovations are reshaping human-AI interaction. Adobe Firefly's beta demonstrates: - Context-aware iteration: _"Make the sky gloomier in that last image"_ - Metaphor comprehension: _"Show me Van Gogh's vision of Starry Night"_ - Complex logic handling: _"Merge Tang Dynasty attire with cyberpunk elements"_ This evolution represents not just model upgrades but a complete cognitive architecture overhaul. When systems understand abstract concepts like "mood," users finally escape keyword dictionaries, returning to creation's essence – conveying ideas through natural human expression. ## 5\. Future Horizon: The Singularity of Natural Language Interaction When AI achieves human-level language understanding, we'll witness a creative revolution: - **Real-time Collaboration**: Direct AI like human artists - **Intuitive Style Transfer**: Replace `color_temp +300K` with "make it warmer" - **Semantic Error Correction**: Auto-fix "floating teacup" physics Industry roadmaps suggest keyword engineering will vanish from mainstream tools by 2026. Input prompts will shift from "Enter detailed descriptions" to "Tell me your idea." This isn't merely technical progress – it's a paradigm shift. When AI truly comprehends natural language, creativity will break free from technical jargon, returning to every human's grasp. * * * ### 评论 提交你的评论 ## Data Deletion Insights # [互联网没有DELETE](https://banzhuanriji.com/) _2025-01-29 17:30_ _·_ [服务器](https://banzhuanriji.com/category/server/) 在现代 Web 应用的交互场景中,数据删除操作是用户与系统频繁互动的功能之一。当用户轻松点击 “删除” 按钮时,背后实则是一系列环环相扣、复杂精妙的技术流程在运转。而且,多数情况下,内容并不会真正从服务器上消失,只是被标记为不可见,依然留存在服务器的数据仓库中。本文将深入剖析这一过程及其背后的多重考量。 ## 一、前端触发:点击背后的初始响应 ### (一)前端事件捕获 当用户在网站界面点击 “删除” 按钮时,前端的 JavaScript 脚本迅速响应,如同训练有素的哨兵。它会利用事件监听机制,如 addEventListener 方法,精准捕捉这一点击事件。为了避免用户误操作,通常会弹出确认对话框,以友好的提示询问用户是否真的要删除该项内容。这个对话框就像是一道安全闸门,为可能的误删操作设置了一道防线。 ### (二)请求发送 若用户确认删除,前端会借助 AJAX(Asynchronous JavaScript and XML)或者 Fetch API 发起一个 HTTP 请求。按照 RESTful API 的设计规范,这个请求一般采用 DELETE 方法。请求中会携带要删除资源的唯一标识符,如数据库中的主键 ID 或者 UUID,它就像是一把钥匙,能让后端准确找到要处理的数据。 ## 二、后端承接:请求的接收与精细处理 ### (一)路由匹配 后端服务器接收到前端发送的请求后,首先会根据请求的 URL 和 HTTP 方法进行路由匹配。这就好比在一个大型图书馆中,根据书籍的分类标识和借阅规则,快速定位到负责处理该请求的具体函数。通过精确的路由匹配,请求被导向相应的处理逻辑。 ### (二)请求验证 在正式处理请求之前,后端会进行严格的验证工作。这包括用户身份验证,通过检查用户的登录凭证、令牌等信息,确保请求来自合法的用户;同时还会进行数据验证,检查请求中携带的数据格式是否正确、是否符合业务规则。只有通过这一系列严格的验证,请求才会被允许继续处理。 ### (三)核心删除操作 这是整个删除流程的关键环节。虽然用户直观感觉数据已被删除,但实际情况存在两种不同的处理方式: - **逻辑删除**:这是更为常见的处理方式。后端会在数据库中对数据进行标记,通常是通过设置一个名为 `is_deleted` 的字段。将该字段的值设置为特定标识(如 `true` 或 `1`),表示数据已被删除。此时,数据在物理上仍然完整地保留在数据库中,只是在后续的查询操作中,会通过 SQL 语句的 WHERE 条件过滤掉这些标记为已删除的数据,从而对普通用户不可见。 - **物理删除**:直接从数据库中永久移除数据。这种方式相对较少使用,尤其是在需要考虑数据恢复的业务场景下。因为一旦执行物理删除,数据将难以恢复,可能会给业务带来不可挽回的损失。 ### (四)后续操作跟进 删除操作完成后,后端可能会执行一些后续操作来确保系统的一致性和可追溯性。例如,更新缓存以保证数据的实时性,避免用户看到旧的数据;同时记录审计日志,详细记录删除操作的执行者、执行时间、被删除的数据等信息,为后续的数据分析和安全审计提供依据。 ## 三、结果反馈:后端到前端的信息传递 ### (一)响应状态返回 后端完成处理后,会返回一个 HTTP 状态码给前端。例如,返回 `200 OK` 表示操作成功;若出现错误,会返回相应的错误状态码,如 `400 Bad Request` 表示请求参数有误, `403 Forbidden` 表示用户没有权限进行该操作等。这个状态码就像是一个信号旗,向前端传达操作的基本结果。 ### (二)详细反馈信息 除了状态码,后端还会返回详细的消息,进一步告知用户删除操作的具体结果。例如,“删除成功” 或者 “由于 XX 原因,删除失败” 等信息,让用户清楚了解操作的最终情况。 四、前端呈现:用户体验的优化与更新 ### (一)界面更新 前端接收到后端的响应后,会根据响应状态对用户界面进行更新。如果删除操作成功,通常会从视图中移除已标记为删除的数据项,让用户直观看到数据已被删除。这一过程就像是舞台上的演员退场,界面变得更加简洁。 ### (二)用户体验提升 为了提升用户体验,前端会采取一系列优化措施。比如,在请求发送过程中显示加载指示器,让用户知道系统正在处理请求,避免用户因长时间等待而产生焦虑;操作完成后提供确认消息,给予用户明确的反馈;甚至还可以提供可选的撤销操作,允许用户在一定时间内反悔,恢复刚刚删除的数据,增加用户操作的灵活性和安全感。 ## 五、数据留存:不消失的背后逻辑 ### (一)数据恢复保障 逻辑删除的方式为数据恢复提供了便利。在用户误操作删除数据后,可以通过简单的操作,如将 is\_deleted 字段的值改回原来的状态,轻松恢复数据。这就像是给数据加了一个 “后悔药”,避免了因误删造成的信息丢失,保障了数据的安全性和完整性。 ### (二)数据分析与合规审计 保留数据对于企业的数据分析和审计工作具有重要意义。通过对历史数据的分析,企业可以了解用户行为、业务趋势等信息,为决策提供有力支持。同时,在一些行业中,法规要求企业保留一定期限的业务数据,以便进行合规审计。逻辑删除可以满足这一需求,确保企业在不影响正常业务操作的前提下,能够顺利通过审计。 ### (三)存储性能优化 逻辑删除可以减少频繁的物理删除操作,从而提高数据库的性能。物理删除操作会导致数据库产生碎片,影响数据的读写效率。而逻辑删除只是对数据进行标记,不会对数据库的物理结构造成实质性的改变,减少了数据库维护的成本和复杂度。 ## 六、安全防线:保障删除操作的可靠性 ### (一)身份验证与授权管理 在实现删除功能时,确保只有经过身份验证的用户才能进行操作是至关重要的。通过用户登录系统时的身份验证机制,如用户名和密码、OAuth 认证等,确定用户的合法性。同时,根据用户的角色和权限,精确控制用户能够删除的数据范围,防止越权操作。 ### (二)CSRF 攻击防护 为了防止跨站请求伪造(CSRF)攻击,系统会使用 CSRF 令牌。在用户登录或页面加载时,服务器会生成一个唯一的 CSRF 令牌,并将其嵌入到页面中。当用户发起删除请求时,前端会将该令牌一并发送给后端。后端会验证该令牌的有效性,只有令牌合法的请求才会被处理,从而确保请求的来源是合法的,避免恶意网站伪造请求。 ### (三)确认机制强化 在用户执行删除操作之前,提供明确的确认提示是防止误删除的有效手段。除了前端弹出的确认对话框,还可以在后端进行二次确认,确保用户的删除意图是真实的。例如,要求用户输入密码或验证码等额外信息,进一步提高删除操作的安全性。 ## 七、总结 当我们在网站上轻点删除按钮时,背后隐藏着一个复杂而精密的技术世界。尽管表面上数据似乎已被删除,但实际上它往往只是被标记为不可见,仍然静静地存留在服务器上。这种逻辑删除的方式为数据管理带来了极大的灵活性,既避免了误删除带来的困扰,又满足了数据恢复、分析和审计等多方面的需求。通过深入理解删除操作背后的机制,开发者可以更好地设计和实现安全、高效的删除功能,为用户提供更加优质的服务体验。希望本文能为你的开发实践提供有价值的参考,让你在处理数据删除问题时更加得心应手。 [用户体验](https://banzhuanriji.com/tag/%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C/) · [Web开发](https://banzhuanriji.com/tag/Web%E5%BC%80%E5%8F%91/) · [数据删除](https://banzhuanriji.com/tag/%E6%95%B0%E6%8D%AE%E5%88%A0%E9%99%A4/) · [前端技术](https://banzhuanriji.com/tag/%E5%89%8D%E7%AB%AF%E6%8A%80%E6%9C%AF/) · [后端处理](https://banzhuanriji.com/tag/%E5%90%8E%E7%AB%AF%E5%A4%84%E7%90%86/) · [AJAX](https://banzhuanriji.com/tag/AJAX/) · [RESTful API](https://banzhuanriji.com/tag/RESTful-API/) · [逻辑删除](https://banzhuanriji.com/tag/%E9%80%BB%E8%BE%91%E5%88%A0%E9%99%A4/) · [物理删除](https://banzhuanriji.com/tag/%E7%89%A9%E7%90%86%E5%88%A0%E9%99%A4/) · [数据安全](https://banzhuanriji.com/tag/%E6%95%B0%E6%8D%AE%E5%AE%89%E5%85%A8/) · [身份验证](https://banzhuanriji.com/tag/%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81/) · [CSRF防护](https://banzhuanriji.com/tag/CSRF%E9%98%B2%E6%8A%A4/) · [数据恢复](https://banzhuanriji.com/tag/%E6%95%B0%E6%8D%AE%E6%81%A2%E5%A4%8D/) · [数据分析](https://banzhuanriji.com/tag/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/) · [审计合规](https://banzhuanriji.com/tag/%E5%AE%A1%E8%AE%A1%E5%90%88%E8%A7%84/) * * * ### 评论 提交你的评论 ## CSS Resources and Tools # [所以,我是从哪里Copy的CSS样式](https://banzhuanriji.com/) _2025-01-10 18:39_ _·_ [前端](https://banzhuanriji.com/category/frontend/) 首先你可以查看这个页面: [https://banzhuanriji.com/about.html](https://banzhuanriji.com/about.html) 本主题原先是没有评论功能和样式的,我在AI的帮助下完成了基础的评论功能。那么CSS我是从哪里获取的呢?就是下面这个网站: [https://neumorphism.io/](https://neumorphism.io/) ![2025-01-10T10:40:07.png](https://source.banzhuanriji.com/blog/typecho/2025-01-10T10:40:07.png) 有四个样式供你选择,并且可以选择光源效果。下面是我其他的一些获取CSS的方案: - Codepen 不多介绍了 [https://codepen.io/](https://codepen.io/) - Ui.glass 这个没什么特别的,帮你写一个毛玻璃效果的div [https://ui.glass/](https://ui.glass/) 如果你找不到体验地址可以点这里: [https://ui.glass/generator/](https://ui.glass/generator/) - Uiverse.io 超级棒的整合了各种ui的css开源网站 [https://uiverse.io/](https://uiverse.io/) - 多边形图片SVG生成 这个我都不知道怎么介绍,随便编了一个标题,具体效果你可以点开看看 [https://www.softr.io/tools/svg-shape-generator](https://www.softr.io/tools/svg-shape-generator) - 随机波浪线生成 [https://getwaves.io/](https://getwaves.io/) - Headlessui 自我简介:旨在与Tailwind CSS完美兼容的样式 [https://headlessui.com/](https://headlessui.com/) - Page ui 建立在TailwindCSS之上,专为React制作的落地页集合 [https://pageui.shipixen.com/](https://pageui.shipixen.com/) - CSS buttons CSS按钮大合集 [https://cssbuttons.app/](https://cssbuttons.app/) - CSS Portal CSS Portal 是许多 CSS / HTML 示例以及如何在网站设计中使用它的地方。在这里,您将找到所有 CSS 属性和许多 CSS 生成器,以帮助您满足所有设计需求。您将找到数百页的工具、资源和生成器来帮助使用 CSS 和 HTML。我们所有的生成器都将生成必要的代码,然后您可以将其复制并粘贴到您的 Web 项目中。希望您发现此网站有助于帮助您满足 CSS 和 HTML 需求。 (为什么这么长,因为这也是我copy的) [https://www.cssportal.com/](https://www.cssportal.com/) * * * ### 评论 提交你的评论 ## Temporary Email Services # [国内可访问的临时邮箱服务](https://banzhuanriji.com/) _2025-01-01 13:23_ _·_ [服务器](https://banzhuanriji.com/category/server/) - INTERNXT [https://internxt.com/temporary-email](https://internxt.com/temporary-email) - TEMPAIL [https://tempail.com/](https://tempail.com/) - AdGuard Temp Mail [https://adguard.com/en/adguard-temp-mail/overview.html](https://adguard.com/en/adguard-temp-mail/overview.html) - Tempmail [https://temp-mail.io/en](https://temp-mail.io/en) - Email on Deck [https://www.emailondeck.com/](https://www.emailondeck.com/) - TempMail.so [https://tempmail.so/](https://tempmail.so/) - @mail.tm [https://mail.tm/en/](https://mail.tm/en/) - Temp Mail & 10 10 min mail [https://temp-mail.org/en/](https://temp-mail.org/en/) [https://temp-mail.org/en/10minutemail](https://temp-mail.org/en/10minutemail) - Temp Mail [https://tempmailto.org/](https://tempmailto.org/) - guerrillamail [https://www.guerrillamail.com/](https://www.guerrillamail.com/) - inboxes [https://inboxes.com/](https://inboxes.com/) [邮箱](https://banzhuanriji.com/tag/%E9%82%AE%E7%AE%B1/) · [临时邮箱](https://banzhuanriji.com/tag/%E4%B8%B4%E6%97%B6%E9%82%AE%E7%AE%B1/) · [mail](https://banzhuanriji.com/tag/mail/) · [email](https://banzhuanriji.com/tag/email/) · [temporary mailbox](https://banzhuanriji.com/tag/temporary-mailbox/) * * * ### 评论 评论区暂时被关闭了 ## Deploy Typecho # [在vercel上部署typecho](https://banzhuanriji.com/) _2024-12-30 16:19_ _·_ [服务器](https://banzhuanriji.com/category/server/) **TL;DR** 通过vercel第三方库来运行php程序 ## 效果展示 **展示不了一点,我发现部署几天后开始变得非常卡,不知道为啥** 所以我推荐你每天定时deploy一下,会好很多 ## 一,注册需要的账号 你需要注册以下账号 - github - vercel - 一个免费或者你自己搭建的mysql数据库 > 关于数据库,不推荐使用国内的免费数据库,因为vercel访问太慢了 > > 或许你可以尝试 `db4free`,或者一些免费空间提供的数据库 ## 二,操作步骤 **1\. 创建git仓库** 在github创建一个仓库, **注意这个仓库需要是private的,也就是私密的仓库**。然后 `clone` 到本地。下面为了方便,假设仓库名为 `blog`。 **2\. 下载typecho** 下载地址: [https://typecho.org/download](https://typecho.org/download) **3\. 把typecho解压到仓库文件夹内** 此时文件应该存放在根目录 **4\. 新建 `api` 文件夹,然后在 `api` 文件夹下创建 `index.php` 文件** 其中 `index.php` 文件的内容如下 ```lang-php addServer(array ( 'host' => '数据库地址', 'user' => '数据库用户', 'password' => '数据库密码', 'charset' => 'utf8mb4', 'port' => '3306', 'database' => '数据库名', 'engine' => 'MyISAM', ), Typecho_Db::READ | Typecho_Db::WRITE); Typecho_Db::set($db); ``` **7\. 注释掉会阻挡操作的内容** 打开根目录下的 `install.php` 文件,注释或者删除 `773-775` 行,注释的内容大概如下。 ``` // if (!$writeable) { // $errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir); // } ``` > 这里如果没有删除,可能会无法初始化数据库 **8\. 上传代码,在vercel中编译,注意提前绑定域名** **9\. 第一次打开会报错** 提示 `Database Query Error`。这时你需要在你的域名\|\|vercel提供的免费域名后添加 `/install.php`,然后按照步骤操作。 > 这里如果你没有执行第7步的操作,可能会报错,建议修改之后重新提交 ## 三,注意事项 1. 过长的等待时间会触发vercel报错,提示 `This Serverless Function has timed out.` 这时你或许可以考虑更换数据库 2. 注意看第7点 3. 一些函数官方说支持,但是会有奇怪的问题 4. 上传二进制文件和直接修改文件的功能就别想了,在仓库中操作吧 5. 暂时想不到了 [typecho](https://banzhuanriji.com/tag/typecho/) · [PHP](https://banzhuanriji.com/tag/PHP/) · [vercel](https://banzhuanriji.com/tag/vercel/) · [博客](https://banzhuanriji.com/tag/%E5%8D%9A%E5%AE%A2/) * * * ### 评论 提交你的评论 ## IMDb's 2024 Popular List # [IMDb 发布了 2024 最受欢迎的电视剧和电影 Top10](https://banzhuanriji.com/) _2024-12-28 22:47_ _·_ [影评](https://banzhuanriji.com/category/movies/) [Best Of 2024: Most Popular Movies](https://www.imdb.com/list/ls548439420/) [Best Of 2024: Most Popular TV Shows](https://www.imdb.com/list/ls548439908/) * * * ### 电影 | 外文 | 中文 | | --- | --- | | 1\. Deadpool & Wolverine | 1\. 死侍与金刚狼 | | 2\. Dune: Part Two | 2\. 沙丘 2 | | 3\. Furiosa: A Mad Max Saga | 3\. 疯狂的麦克斯:狂暴女神 | | 4\. Joker: Folie à Deux | 4\. 小丑 2:双重妄想 | | 5\. Alien: Romulus | 5\. 异形:夺命舰 | | 6\. The Substance | 6\. 某种物质 | | 7\. Civil War | 7\. 美国内战 | | 8\. Beetlejuice Beetlejuice | 8\. 怪奇大法师 | | 9\. Kingdom of the Planet of the Apes | 9\. 猩球崛起:新世界 | | 10\. Longlegs | 10\. 长腿 | ### 电视剧 | 外文 | 中文 | | --- | --- | | 1\. True Detective | 1\. 真探 第四季 | | 2\. The Boys | 2\. 黑袍纠察队 第四季 | | 3\. The Penguin | 3\. 企鹅人 | | 4\. Fallout | 4\. 辐射 | | 5\. House of the Dragon | 5\. 龙之家族 第二季 | | 6\. Shogun | 6\. 幕府将军 | | 7\. Bridgerton | 7\. 布里杰顿家族/布里奇顿 | | 8\. The Lord of the Rings: The Rings of Power | 8\. 指环王:力量之戒 | | 9\. The Gentlemen | 9\. 绅士们 | | 10\. 3 Body Problem | 10\. 三体(Netflix 版) | * * * ### 评论 提交你的评论 ## Random Image APIs # [一些获取随机图像的接口](https://banzhuanriji.com/) _2024-12-28 18:33_ _·_ [前端](https://banzhuanriji.com/category/frontend/) 不评判储存在服务器还是使用第三方的方案,只记录一些随机获取图像的接口。下面每个方案前都会放置相对于的接口的图像。 > 以下内容仅为个人记录用处,从未有意侵权已注册商标,也从未试图冒充任何开放内容官方。当然如果您认为下列内容侵犯了您的权益,请您与我联系 `m#hoytzhang.com` 。 # 无需注册的方案 ## Bing image ![bing image](https://bing.img.run/1920x1080.php) > 2025年3月3日 发现该网站证书失效。有兴趣的朋友可以访问下面的开源地址。或者你也可以考虑自己部署这个仓库到vercel上。 [https://github.com/flow2000/bing-wallpaper-api](https://github.com/flow2000/bing-wallpaper-api) TL;DR 获取bing每日图像的接口非常多,下面是我推荐的一个,目前运行还是比较稳定的 ### 官网地址 [https://bing.img.run/api.html](https://bing.img.run/api.html) ### 开源地址 [https://github.com/mike126126/bing](https://github.com/mike126126/bing) ### 使用方法 Bing今日壁纸 ``` Bing每日壁纸UHD超高清原图 Bing每日壁纸1080P高清 Bing每日壁纸普清 Bing每日壁纸手机版1080P高清 ``` 随机获取Bing历史壁纸 ``` 随机获取Bing历史壁纸UHD超高清原图 随机获取Bing历史壁纸1080P高清 随机获取Bing历史壁纸普清 随机获取Bing历史壁纸手机版1080P高清 ``` ## Picsum.Photos ![Picsum.Photos](https://picsum.photos/800/600.webp) ### 官网 TL;DR 一款开源的,采用Unsplash图像源的免费网站 下面的内容我几乎是从他的官网直接复制过来的。你可以点击下面访问官网,带有图像更容易理解方便你使用。 [https://picsum.photos/](https://picsum.photos/) ### 源码 [https://github.com/DMarby/picsum-photos](https://github.com/DMarby/picsum-photos) ### 使用方法 - 直接返回固定大小图像地址 ``` https://picsum.photos/200/300 ``` - 返回固定大小的方形图像 ``` https://picsum.photos/200 ``` - 获取指定id的图像,带有id的图像列表在这里: [https://picsum.photos/images](https://picsum.photos/images) ``` https://picsum.photos/id/237/200/300 ``` - 自定义seed的图像 ``` https://picsum.photos/seed/picsum/200/300 ``` - 去色图像(灰色) ``` https://picsum.photos/200/300?grayscale ``` - 添加高斯模糊(最后的参数支持1-10) ``` https://picsum.photos/200/300/?blur https://picsum.photos/200/300/?blur=5 ``` ### 官方推荐的使用方法 您可以组合上述任何选项。 例如,获取灰度和模糊的特定图像。 ``` https://picsum.photos/id/870/200/300?grayscale&blur=2 ``` 要在浏览器中请求多个相同大小的图片,请添加 random 查询参数以防止图片被缓存: ``` ``` 如果需要文件结尾,可以在 url 末尾添加 .jpg。 ``` https://picsum.photos/200/300.jpg ``` 要获取 WebP 格式的图像,您可以在 URL 末尾添加 .webp。 ``` https://picsum.photos/200/300.webp ``` ### 列出图像地址 列出图片 使用 `/v2/list` 端点获取图像列表。 ``` https://picsum.photos/v2/list ``` 默认情况下,API 将每页返回 30 个项目。 要请求另一个页面,请使用 `?page` 参数。 要更改每页的项目数,请使用 `?limit` 参数。 ``` https://picsum.photos/v2/list?page=2&limit=100 ``` 链接的header需要包含有关下一页/上一页的分页信息 ### 获取图像信息 ``` https://picsum.photos/id/0/info https://picsum.photos/seed/picsum/info ``` 返回的格式如下 ``` { "id": "0", "author": "Alejandro Escamilla", "width": 5616, "height": 3744, "url": "https://unsplash.com/...", "download_url": "https://picsum.photos/..." } ``` ## LoremFlickr ![LoremFlickr](https://loremflickr.com/800/600/) ### 官网 TL;DR 图像来自于 [Flickr](https://www.flickr.com/),官网称 [目前的服务被严重影响](https://github.com/MastaBaba/LoremFlickr-2/issues/9) 官网仅推荐当作占位符(Placeholder)来使用 [https://loremflickr.com/](https://loremflickr.com/) ### 开源地址 [https://github.com/MastaBaba/LoremFlickr-2](https://github.com/MastaBaba/LoremFlickr-2) - 直接使用 如果你不指定任意内容,将会返回小猫的图像,例如下面的这种用法 ``` https://loremflickr.com/320/240 ``` - 指定主题 ``` //这个地址将会返回`小狗(dog)`相关的图像 https://loremflickr.com/320/240/dog ``` - 保留色彩 相对于picsum的灰色图像,LoremFlickr可以选择保留更多色彩 ``` https://loremflickr.com/g/320/240/paris ``` 这个示例将会返回灰色的 `小狗(dog)` 相关的图像。你还可以尝试 `p` 、 `red` 、 `green` 和 `blue` 这些关键字! - 多个关键字 下面这个地址将会返回与 `小猫(cat)和小狗(dog)` 相关的图像 ``` https://loremflickr.com/320/240/cat,dog ``` - 强调关键字 上面的使用方案可能会同时包含 `小猫(cat)和小狗(dog)` ,如果你像强调关键字,那么你可以使用下面的方法 ``` https://loremflickr.com/320/240/cat,dog/all ``` 可以搭配色彩关键字使用 ``` https://loremflickr.com/g/320/240/cat,dog/all ``` - 锁定图像 ``` https://loremflickr.com/320/240?lock=30976 ``` - 避免重复图像,同样支持random函数 ``` https://loremflickr.com/320/240?random=1 https://loremflickr.com/320/240?random=2 https://loremflickr.com/320/240?random=3 ``` - 支持json返回数据 ``` https://loremflickr.com/json/g/320/240/paris,girl/all ``` - 支持RSS订阅 ``` https://loremflickr.com/rss/d/g/320/240/paris,girl/all ``` # 需要注册的方案 ## Unsplash 大名鼎鼎的Unsplash的免费接口寿终正寝后(貌似是因为流量太大且没有回流),api从开放式改为账号调用。 [2024年6月11日官方下线了免费调用](https://unsplash.com/documentation/changelog#unsplash-source-sunset),但是你依旧可以注册后使用这个服务,不过免费服务存在一些限制,下面是三个档次的服务区别: 1. Demo:每小时50次调用 2. Production:在遵守Unsplash条件的前提下,每小时5000次 3. Enterprise:联系Unsplash团队 在第二条中,Unsplash的要求包括但不限于: - 每张图片只允许使用Url返回的 `photo.urls` 的图像 - 用户进行图像下载时,必须使用 `photo.links.download_location` 的链接进行下载 - 每张图像展示时标明摄影师且附带摄影师的个人链接 - 不允许制作Unsplash的竞品程序 如果你可以接受并遵守以上条件,你可以访问这个文档进行申请: [https://unsplash.com/documentation](https://unsplash.com/documentation) * * * ### 评论 提交你的评论 ## Linktree-like Personal Homepage # [仿照linktree做的个人主页](https://banzhuanriji.com/) _2024-12-25 17:09_ _·_ [主题](https://banzhuanriji.com/category/theme/) 你可以访问这里查看: [https://hoytzhang.com](https://hoytzhang.com/) ![pc-hoytzhang.webp](https://source.banzhuanriji.com/blog/typecho/pc-hoytzhang.webp) 实现的效果: - 随机显示背景图像 - 从背景图像提取主要颜色设置为按钮的颜色 - 适配移动端 - 点击项目按钮展开/收缩项目 下面是代码,当然还有一个去除JS的代码,一起附在下面,可能需要你手动设置按钮颜色 ## 附带JS的版本 ```lang-html My page

    © 2024 Name

    ``` ## 去除JS的版本 ```lang-html My page

    © 2024 Name

    ``` ## 附加随机图像 > 如果你想要一个每次打开都会展示不一样的背景图像的页面,你可以使用下面的代码。如果你不想使用代码里的随机图像方案,你可以查看我的另一篇文章,里面有其他可选择的随机图像api: [https://banzhuanriji.com/frontend/random-image.html](https://banzhuanriji.com/frontend/random-image.html) ``` Name

    © 2024 username

    ``` * * * ### 评论 提交你的评论 ## Blog Themes Overview # [我制作的两款blog主题](https://banzhuanriji.com/) _2024-12-25 10:48_ _·_ [主题](https://banzhuanriji.com/category/theme/) 1. 基于hexo平台,主题名为ink,灵感来自bearblog的starter [https://github.com/hoytzhang/hexo-theme-ink](https://github.com/hoytzhang/hexo-theme-ink) 2. 一款简约的typecho主题,你可以访问 [https://final.linkpark.site/](https://final.linkpark.site/) 查看实现效果 [https://github.com/hoytzhang/typecho-theme-final](https://github.com/hoytzhang/typecho-theme-final) * * * ### 评论 提交你的评论 ## Underscores in URLs # [为什么不应该在超链接中使用下划线](https://banzhuanriji.com/) _2024-12-24 12:20_ _·_ [服务器](https://banzhuanriji.com/category/server/) ## 一、不利于SEO 搜索引擎会认为 `aaa_bbb` 是一个连词,从而识别为这是一个整体单词 `aaabbb` 。例如你搜索 `my_site` ,搜索引擎会认为你搜索了 `mysite` 而非 `my site` 。而在链接中使用 `-` 会让搜索引擎认为这是分词符,从而输入更多的准确的关键字。可以参考 [Google的说明文档](https://developers.google.com/search/docs/crawling-indexing/url-structure?hl=en&visit_id=638635334556049207-4053290024&rd=1) 。 进而,在用户进行搜索时,搜索引擎可能会忽略你的网站内容。 ## 二、利于分辨 友好的内容不仅应该方便机器读取,更应该首先考虑人的感受。那么从人的角度来说为什么不应该使用下划线 1. 下划线同样会给人一个“这是个长单词的感觉”。没有人会记住你想表达的内容。 2. 一般的超链接的样式会设置为下划线和蓝色,如果你的链接内带有下划线,有可能会和样式产生重叠和遮挡。 3. 如果超链接在文本中进行展示时,当你有一个比较长的链接,比如: `site.com/this_is_a_very_long_link_on_my_website` 。人在试图读这个链接时,眼睛会不由自主地跟随下划线移动。这似乎不太合适。 ## 三、约定俗成的习惯和莫名其妙的bug 一般在计算机领域,我们在本地文件会使用下划线内容。然后上传文件后对外提供的链接就会是这样: `http://site.com/file_name.txt` 。但是这样会出现一个问题:在互联网传播时,浏览器内复制粘贴会将 `_` 转义为 `%5F` ,如果服务器没有进行配置,那你的超链接的文件就会404。而且貌似 [很多知名公司都有这个问题](https://meta.stackexchange.com/questions/16004/link-with-underscore-does-not-work) (现在可能已经被修复)。 ## 四、在域名中不合法 [RFC1738](https://datatracker.ietf.org/doc/html/rfc1738) 和 [RFC1035](https://datatracker.ietf.org/doc/html/rfc1035) 等多次投票结果的规则中对域名中出现 `_` 表示禁止。也对以前申请了证书的带有下划线的域名的证书进行了回收和禁止续费。但这只是顶级域名的要求,而不是对于顶级域名下的子超链接和文件的限制。 其实只是很久以前看过的一个博客。说的是在美国军队中导致的一些问题从而禁用了下划线,最近想到了就重新整理一下写成文章分享出来。 [超链接](https://banzhuanriji.com/tag/%E8%B6%85%E9%93%BE%E6%8E%A5/) · [server](https://banzhuanriji.com/tag/server/) · [website](https://banzhuanriji.com/tag/website/) · [网站](https://banzhuanriji.com/tag/%E7%BD%91%E7%AB%99/) * * * ### 评论 提交你的评论 1. ![](https://cravatar.cn/avatar/f6a0876c33dbd7345975001b04753fa2?s=80&r=G&d=mm) [Rickey](https://gdhblog.com/)2025-Mar-7 学习了 ## User Routing Setup # [网页程序如何正确设置用户路由](https://banzhuanriji.com/) _2024-12-15 20:03_ _·_ [服务器](https://banzhuanriji.com/category/server/) 以下是一些在网页程序中设置用户主页路由比较合理的方式及相关要点: ## 基于 RESTful 风格 ### 路径设计 通常可以采用类似 `/users/{username}` 这样的路径形式,其中 `{username}` 是可变的部分,代表具体的用户名。例如,若用户名为 `john`,那访问 `/users/john` 就可以跳转到对应的用户主页。这种方式清晰地体现了资源(用户)与对应的标识(用户名)的关系,符合 RESTful 规范中对资源定位的要求,方便理解和记忆,也利于前后端的分工协作以及接口的统一管理。 还可以添加版本号在路由最前面,如 `/v1/users/{username}`,便于后续对 API 等进行迭代升级,不同版本的路由逻辑可以独立维护,不会相互干扰。 ### HTTP 方法匹配 对于用户主页的获取(也就是查看用户主页信息),一般使用 GET 方法来请求对应的路由。比如,当浏览器发起 GET 请求到 `/users/john` 时,后端根据这个路由和请求方法,查询数据库中关于 `john` 用户的信息并返回给前端进行展示,符合 RESTful 中不同方法对应不同操作语义的原则,GET 方法专门用于获取资源这一操作场景。 ## 考虑用户身份验证与授权相关路由整合 ### 登录态验证 - 在用户主页路由对应的处理逻辑之前,往往需要先验证用户是否已经登录。可以通过中间件来拦截请求,检查请求中携带的登录凭证(如 token 等)是否有效。比如,在很多基于 Node.js 的 Web 框架(像 Express)中,编写一个验证登录态的中间件,在路由配置里让用户主页路由先经过这个中间件,只有验证通过才能继续后续的主页数据获取和渲染流程,确保未登录用户无法直接访问用户主页,保障页面的访问安全性和隐私性。 ### 权限控制路由结合 有时候用户主页可能根据用户权限展示不同内容,例如管理员用户的主页可能有更多管理功能入口。此时,路由可以配合权限控制模块,根据用户的角色(如普通用户、管理员等)来决定在加载用户主页时,返回哪些对应的模块数据和页面布局。像可以在路由处理函数中先获取用户角色信息,再依据角色从数据库中查询相应权限下的页面配置数据,以准确渲染出符合其权限的用户主页。 ## 动态路由参数与页面状态关联 ### 页面主题切换参数 若用户主页支持切换主题(如亮色模式、暗色模式等),可以在路由中添加额外的参数来表示主题状态,比如 `/users/{username}?theme=dark` 表示访问 `username` 用户的主页且采用暗色主题模式。后端接收到这样带有参数的路由请求后,根据 `theme` 参数的值来调整返回给前端的页面样式相关资源,实现灵活的页面状态定制。 ### 分页相关参数 当用户主页有分页展示内容(比如用户发布的文章列表分页显示等),路由中可以包含分页参数,像 `/users/{username}/posts?page=2&limit=10`,表示查看 `username` 用户的文章列表,当前是第 2 页,每页显示 10 条内容。后端根据这些参数从数据库中准确提取对应的数据返回给前端,方便用户浏览不同页面的数据内容,提升用户体验。 ## 路由懒加载与缓存策略配合 ### 懒加载实现 对于比较复杂的用户主页,尤其是包含很多模块(如动态的个人动态展示、好友推荐等多个功能模块),可以采用路由懒加载的方式。例如在基于 Vue.js 或 React 等前端框架构建的单页面应用中,将用户主页的不同组件模块配置成懒加载形式,如 `const UserHomePage = () => import (‘./UserHomePage.vue’);`(Vue.js 示例),这样当用户访问到对应路由时,才会去加载对应的模块代码,减少初始加载的资源量,提高页面加载速度。 ### 缓存优化 结合缓存策略,对于用户主页中一些相对静态、不常变化的数据(比如用户的基本信息介绍等),可以在浏览器端或者服务器端设置缓存机制。比如,在服务器端通过设置合适的缓存头(如 `Cache-Control` 等),告诉浏览器在一定时间内可以直接使用缓存的页面内容,减少重复请求,提升用户再次访问主页的响应速度,同时减轻服务器压力。 ## 国际化与本地化路由适配 ### 语言参数设置 如果网页程序支持多语言,在用户主页路由中可以添加语言相关参数,比如 `/users/{username}?lang=en` 表示访问 `username` 用户的主页且采用英语语言环境。后端根据这个参数,加载对应的语言包来渲染页面文字内容,使得不同语言习惯的用户都能获得合适的用户主页展示效果,方便国际化拓展和满足不同地区用户的需求。 总之,设置用户主页路由需要综合考虑多方面因素,从路由的规范、安全性、页面状态灵活度、性能优化以及多语言适配等角度出发,打造出合理且易用的路由体系。 ## 次级域名方案分析 ### 技术可行性 从技术角度来说,是可以设置username.website.com这类次级域名(也称为子域名)路由的。在服务器配置层面,对于支持虚拟主机的 Web 服务器(如 Apache 和 Nginx),可以通过配置虚拟主机来实现子域名的指向。 以 Nginx 为例,你需要在服务器配置文件中添加一个新的服务器块(server block)。假设你的主域名是website.com,要为用户username设置子域名路由,配置可能如下: ```lang-nginx server { listen 80; server_name username.website.com; # 以下是实际指向的路径,例如指向用户主页的目录 location / { root /var/www/username_homepage; index index.html; } } ``` 这就将 `username.website.com` 这个子域名请求指向了 `/var/www/username_homepage` 这个服务器上的目录,当用户访问该子域名时,服务器会从这个目录中寻找并返回相应的网页文件。 ### 域名系统(DNS)配置 要使用 `username.website.com` 这样的子域名,还需要在域名系统(DNS)中进行正确的配置。你需要添加一条CNAME(规范名称)记录或者A记录(如果是直接指向IP地址)来将子域名指向你的服务器。 如果你的网站是通过域名注册商管理的,你可以登录到域名管理控制台,在DNS设置区域添加相应的记录。例如,添加一个CNAME记录,将 `username.website.com` 指向 `website.com`(假设 `website.com` 已经正确配置指向服务器的IP地址),或者直接添加A记录,将 `username.website.com` 指向服务器的实际IP地址。 ### 应用程序路由逻辑 在网页程序内部,你需要根据请求的子域名来确定对应的路由逻辑。例如,在后端应用程序(如使用Python的Flask或Django等框架)中,需要编写代码来识别子域名部分,并根据不同的 `username` 加载相应的用户主页内容。 在Flask中,你可以使用 `request` 对象来获取请求的子域名信息,如下所示: ```lang-python from flask import Flask, request app = Flask(__name__) @app.route('/') def user_homepage(): subdomain = request.headers.get('Host').split('.')[0] # 根据子域名subdomain(也就是username)加载对应的用户主页内容 # 这里只是示例,实际可能需要查询数据库等操作 return f"Welcome to the homepage of {subdomain}" ``` ### 注意事项 - 安全性:确保在处理子域名请求时,进行适当的安全验证。例如,防止恶意用户通过构造虚假的子域名来访问未授权的内容或者进行攻击。可以通过验证用户身份、检查子域名是否在合法的用户列表中等方式来增强安全性。 - 性能和维护成本:使用大量的子域名可能会增加服务器配置的复杂性和维护成本。每次添加新的子域名都需要在服务器和 DNS 中进行配置,并且需要确保应用程序能够正确处理这些子域名请求。此外,过多的子域名可能会对服务器性能产生一定的影响,尤其是在处理大量并发请求时。 - 兼容性:有些浏览器或者网络环境可能对某些子域名设置有特殊的限制或者兼容性问题。在部署使用子域名的路由之前,最好进行充分的测试,以确保在各种主流设备和浏览器上都能正常工作。 - 一些需要保留的用户名或者分层进行路由处理。例如典型的 `www` 用户名,可能会使用户主页引向产品首页。还有比如github的 `security` 用户,你打开他的主页就会跳转到 github.com/security 的页面。此外gitee也有类似的问题。 所以在设置用户路由或者用户页面时,需要首先考虑到安全性,其次就是功能性,这种可能影响到内容使用和系统安全的操作,用户体验或许需要向后排一排。 * * * ### 评论 提交你的评论 ## Maven Server Setup # [本地部署nexus3 搭建maven私服](https://banzhuanriji.com/) _2024-12-13 11:34_ _·_ [服务器](https://banzhuanriji.com/category/server/) 由于JFREG的一系列惊人操作,GITEE关闭maven功能,不得已,本地搭建以下maven服务。 准备工作:JDK (如果你的设备存在JDK环境,请忽略这部分。) 安装JDK8 ``` sudo apt-get install openjdk-8-jdk ``` * * * 1.下载 下载地址: [https://www.sonatype.com/thanks/repo-oss](https://www.sonatype.com/thanks/repo-oss) 选择你的系统版本进行下载。这里演示的是linux版本 ![2024-12-13T03:34:15.png](https://banzhuanriji.com/usr/uploads/2024/12/2290836390.png) 2.配置 nexus默认占用端口为8081,如果端口已经被使用,需要在nexus-3.xxxx/etc/nexus-default.properties 文件中进行修改 ![2024-12-13T03:34:22.png](https://banzhuanriji.com/usr/uploads/2024/12/90208660.png) 3.运行/安装 下载好之后解压,得到nexus-3.xxxx,进入之后有两个文件夹,启动终端,进入nexus-3.xx,进入bin,然后运行 ``` ./nexus start #linux ./nexus.exe start #windows ``` windows需要等待如之输出提示成功,linux在提示成功后等待1-2分钟,打开你的本地站点即可。 4.登陆 第一次登陆,会提示你密码保存在 `nexus-3.32.0-03-unix/sonatype-work/nexus3/admin.password ` 文件中,自己打开复制密码即可。账号是默认的admin。登陆之后会提示你修改密码和是否打开匿名访问,建议打开。 5.配置和上传 进入之后点击左侧的upload,然后点击右侧的maven-release,然后按照下面的信息填写就可以了。 ![2024-12-13T03:34:33.png](https://banzhuanriji.com/usr/uploads/2024/12/720936120.png) ![2024-12-13T03:34:39.png](https://banzhuanriji.com/usr/uploads/2024/12/126966824.png) * * * ### 评论 提交你的评论 ## Android Studio Unicode Fix # [Android Studio console 输出乱码解决](https://banzhuanriji.com/) _2024-12-13 11:33_ _·_ [android](https://banzhuanriji.com/category/android/) 打开 Edit Custom VM Options ,打开方法有两种 1.双击shift键,输入ECVO或者Edit Custom VM Options ![2024-12-13T03:33:02.png](https://banzhuanriji.com/usr/uploads/2024/12/3339474142.png) 2.或者手动打开用户名/AppData/Roaming/Google/AndroidStudiox.x/studio64.exe.vmoptions 然后把-Dfile.encoding=UTF-8添加进去 重启Android Studio即可 * * * ### 评论 提交你的评论 ## Android v-a/b Partition # [Android 的 v-a/b分区简单理解](https://banzhuanriji.com/) _2024-12-13 11:32_ _·_ [android](https://banzhuanriji.com/category/android/) ### 基础理解 我们可以直接把v-a/b分区理解成,当你在使用手机,进行系统升级,系统会把升级内容存放在A分区,你继续使用B分区,前面的V就是虚拟的意思(virtual)。在尽量不影响你使用的开机情况下进行升级,取消了在rec分区进行升级的复杂操作 ### 详细理解(我的浅见) 首先说结构。传统结构中,存在 `rec`, `boot`, `system` 分区,在V-ab结构中,抛弃了提到的这三个分区,取而代之的是: `boot_a`, `system_a`, `boot_b`, `system_b`。这就是v-ab。 首先要介绍Δ(delta,小写δ)文件。Δ文件就是cow(copy-on-write)文件,字面意思,具体可以看 [wikipedia的解释](https://en.wikipedia.org/wiki/Copy-on-write)。然后我们首先打开谷歌的官方文档: [https://source.android.com/devices/tech/ota/virtual\_ab#device-mapper](https://source.android.com/devices/tech/ota/virtual_ab#device-mapper) ,里面请看:这个super分区(超级分区) 这个分区,就是用来储存Δ文件的。那么在进行一些比较大的升级的时候,Δ文件可能比较大,预分的super分区可能存在不足的现象。这个时候,会把多余的文件储存到/data下。这个情况基本只发生在Android11上,因为Android10预留了两倍逻辑分区的空间。Android10的VAB分区本身就不是原生的,是根据动态分区改装而来的。 那么,当你在Android11手机上,开机状态下进行升级时,在哪里查看文件呢?你可以查看下面这个路径: `/data/gsi/ota`,下面存在一些列的带有 `cow` 的 `.img` 文件。至于存在与哪里,就看系统分配的 `super` 分区的逻辑空间大小了。 现在再看官方文档: [https://source.android.com/devices/tech/ota/virtual\_ab#dm-snapshot-overview](https://source.android.com/devices/tech/ota/virtual_ab#dm-snapshot-overview) ,下面的DM概述。其中: > 快照设备是使用snapshot目标创建的。写入快照设备将写入COW设备。从快照设备读取是从基本设备读取还是从COW设备读取,具体取决于快照是否更改了所访问的数据。 这就说明了,为什么在生成完cow文件之后,系统把 `bootContral.hal` 的合并状态改为snapshoted了。如果当前你在操作a空间,那么系统会把你当前的系统分区从 `system_a` 改为 `system_a_cow`,然后会开始把你切换到B分区,你至此仍然可以正常使用手机,只是切换过程中你使用手机,可能会有一点点卡感觉。 在生成完cow文件之后,系统这时提示我们重启。我们发现,重启依然会有一个时间需要等待,和之前的rec读cmd安装差不多啊。那么到底这个时间系统在做什么呢? 首先我们默认你升级前使用的是a分区。在你关机后,由于之前的hal文件改为了snapshoted,这个时候系统会把对应的旧系统分区和Δ文件进行合并。不过这个时候单纯是加载到内存中,不是合并的二进制文件。如果这个时候重启成功,那么系统会在开机后,偷偷地合并剩余的二进制文件,这个时候系统会把 `bootContral.hal` 的合并状态改为merging,合并中。如果存在开机失败的状态,那么系统则直接读取老系统文件进行回滚(其实不是回滚,直接读取就完事了)。直至开机成功,hal文件的合并状态才会被置空,等待下一次升级。 看到这里你会问了,这个逻辑其实和之前的读取刷机脚本进行升级差不多啊。其实这里最大的差别,除了分区升级外,就是一个最厉害的点:在 `bootContral.hal` 的状态为合并中(merging)的时候,你可以随意重启手机。而只有在 `bootContral.hal` 的状态为合并中的时候,也才算是真正的系统升级状态。接下来解释为什么很多手机看起来依然和之前的手机升级效果差不多?其实很多厂商会估计把这个合并过程加上动画……让你看起来手机没有进入系统,实际上手机是进入系统了,只是没有启动桌面,给你看这个合并进度而已。如果这个时候你重启,在重启后,手机会继续合并剩余的文件,减少了崩溃的情况。即使崩溃,手机也会直接读取旧系统文件,你依然可以重新进行升级! ### 总结 其实这只是我简单的理解。也看了网上的一些文章。因为谷歌对v-ab的描写基本等于没说… 看了大神们对v-ab的解释之后,我才知道这玩意其实挺糊弄(中间替换系统分区名字那一段…),也挺牛的,减少了你每月一次可能由于升级导致系统崩溃的情况,也开始逐渐抛弃bl…… 唯一对不起的就是刷机佬,刷机学习成本再次提高… * * * ### 评论 提交你的评论 ## Appreciating Art Skills # [培养欣赏艺术的能力](https://banzhuanriji.com/) _2024-12-12 20:16_ _·_ [随笔](https://banzhuanriji.com/category/essay/) 在人类文明的长河中,艺术宛如一颗璀璨的明珠,闪耀着无尽的魅力。它以多样的形式存在于我们的生活周围,从绘画中绚丽的色彩与独特的构图,到音乐里动人的旋律与和谐的节奏;从雕塑那立体的造型与质感的呈现,到文学作品中深刻的思想与精妙的文字表达。然而,若想真正领略艺术的深邃内涵与独特价值,培养欣赏艺术的能力则显得尤为重要。 培养欣赏艺术的能力,首先要学会用心去感受。艺术作品并非仅仅是一些外在形式的简单组合,它蕴含着创作者的情感、思想与灵魂。当我们面对一幅画作时,不能仅仅看到画面上的人物、风景或物体,而应尝试去体会画家在创作时的心境。比如梵高的《向日葵》,那热烈奔放的色彩,看似只是对向日葵的描绘,但其中却倾注了梵高对生命的热爱与渴望。他以一种近乎癫狂的笔触和浓烈的色彩,将内心深处对美好生活的向往以及自身的孤独与挣扎都融入其中。我们只有静下心来,用心去感受那色彩背后的情感力量,才能触及到作品的灵魂深处,体会到艺术所带来的震撼与感动。 丰富的知识储备是培养欣赏艺术能力的重要基石。了解艺术史、不同艺术流派的特点以及艺术家的生平经历等知识,能够为我们打开一扇深入理解艺术作品的大门。例如,在欣赏古典音乐时,如果我们对巴洛克时期、古典主义时期和浪漫主义时期音乐的风格特点有所了解,对莫扎特、贝多芬等音乐家的创作背景和个人经历有所知晓,那么当我们聆听他们的作品时,就能更好地理解音乐中所运用的创作手法、表达的情感主题以及所具有的时代特征。对于绘画艺术也是如此,熟悉文艺复兴时期、印象派、现代派等不同流派的发展脉络和核心主张,能够帮助我们更精准地解读一幅画作在艺术史上的地位和意义,明白画家为何采用这样的表现形式,从而提升我们欣赏艺术作品的深度和广度。 培养敏锐的观察力是欣赏艺术不可或缺的环节。艺术作品中的每一个细节都可能蕴含着创作者的巧思与深意。在欣赏一幅精美的刺绣作品时,那细腻的针法、丰富的色彩过渡以及图案中微小的装饰元素,都值得我们仔细品味。同样,在阅读一部文学作品时,对字词的运用、段落的结构安排、情节的微妙转折等细节的留意,能够让我们更深刻地理解作者的创作意图。以《红楼梦》为例,书中对人物服饰、饮食、住所等细节的描写极为细致入微,这些细节不仅生动地展现了当时的社会风貌和贵族生活场景,更从侧面反映了人物的性格特点、身份地位以及命运走向。通过对这些细节的观察与分析,我们仿佛能够穿越时空,走进那个封建大家族的兴衰沉浮之中,感受到文学艺术的强大魅力。 保持开放包容的心态对于培养欣赏艺术的能力同样至关重要。艺术是多元的,不同的文化背景、地域特色以及时代发展都会孕育出风格迥异的艺术形式和作品。我们不能以自己固有的审美观念去评判一切艺术,而应尊重和接纳各种艺术表达。现代艺术中的一些作品可能会打破传统的艺术观念和表现形式,让很多人一时难以理解。例如,某些抽象艺术作品,画面上可能只是一些看似随意的线条、形状和色彩的组合,但这并不意味着它们毫无价值。这些作品往往是艺术家对内心世界、社会现象或哲学思考的独特表达,它们挑战着我们的常规认知,促使我们重新审视艺术的定义和边界。只有以开放包容的心态去面对这些多元的艺术形式,我们才能不断拓宽自己的艺术视野,发现更多艺术之美。 培养欣赏艺术的能力是一个长期而丰富的过程,它需要我们用心去感受、用知识去武装、用敏锐的观察力去发现、用开放包容的心态去接纳。在这个过程中,我们不仅能够提升自己的审美素养和精神境界,更能在艺术的浩瀚海洋中畅游,领略人类文明所创造的无尽辉煌与美好。让我们积极地投身于艺术欣赏的实践中,不断培养和提升自己欣赏艺术的能力,使艺术成为我们生活中不可或缺的精神滋养源泉。 * * * ### Developing the ability to appreciate art > Translated by poe.com In the long history of human civilization, art shines like a brilliant pearl, radiating endless charm. It exists in various forms around us, from the vivid colors and unique compositions of paintings to the enchanting melodies and harmonious rhythms of music; from the three-dimensional shapes and textures of sculptures to the profound ideas and exquisite expressions found in literature. However, to truly appreciate the profound connotations and unique value of art, it is particularly important to cultivate the ability to appreciate art. To cultivate the ability to appreciate art, one must first learn to feel with the heart. Artistic works are not merely simple combinations of external forms; they contain the emotions, thoughts, and souls of their creators. When we face a painting, we should not just see the figures, landscapes, or objects depicted but should try to experience the artist's mindset during the creation. For example, in Van Gogh's "Sunflowers," the vibrant and passionate colors seem to merely depict sunflowers, yet they are infused with Van Gogh's love and yearning for life. With a near-manic brushstroke and intense colors, he integrates his deep longing for a beautiful life and his own loneliness and struggles. Only by calming our minds and feeling the emotional power behind the colors can we touch the soul of the work and experience the shock and emotion that art brings. A rich knowledge base is an important cornerstone for cultivating the ability to appreciate art. Understanding art history, the characteristics of different artistic movements, and the life experiences of artists can open a door to a deeper understanding of artistic works. For instance, when appreciating classical music, if we are familiar with the stylistic characteristics of Baroque, Classical, and Romantic music, and know about the backgrounds and personal experiences of composers like Mozart and Beethoven, we can better understand the creative techniques, emotional themes, and historical characteristics expressed in their works. The same applies to painting; being familiar with the development and core tenets of different movements such as the Renaissance, Impressionism, and Modernism can help us interpret a painting's position and significance in art history and understand why the artist chose a particular form of expression, thereby enhancing our depth and breadth of art appreciation. Cultivating keen observation skills is an indispensable part of appreciating art. Every detail in an artwork may contain the creator's ingenuity and deep meaning. When admiring a beautiful embroidery piece, the intricate stitching, rich color transitions, and small decorative elements in the pattern deserve our careful appreciation. Similarly, when reading a literary work, paying attention to the use of words, the arrangement of paragraphs, and the subtle shifts in plot can lead to a deeper understanding of the author's intentions. For example, in "Dream of the Red Chamber," the meticulous descriptions of characters' clothing, food, and residences vividly depict the social landscape and aristocratic life of the time, while also reflecting the characters' personalities, social status, and destinies. Through observing and analyzing these details, we seem to traverse time and space, stepping into the rise and fall of that feudal family, experiencing the powerful charm of literary art. Maintaining an open and inclusive mindset is equally crucial for cultivating the ability to appreciate art. Art is diverse; different cultural backgrounds, regional characteristics, and historical developments give birth to distinct artistic forms and works. We should not judge all art by our inherent aesthetic concepts but should respect and embrace various artistic expressions. Some works in modern art may challenge traditional art concepts and forms, making them difficult for many to understand at first. For example, certain abstract artworks may appear to be mere random combinations of lines, shapes, and colors, but that does not mean they lack value. These works often represent the artist's unique expression of their inner world, social phenomena, or philosophical reflections; they challenge our conventional understanding and prompt us to reconsider the definitions and boundaries of art. Only by approaching these diverse forms of art with an open and inclusive mindset can we continually broaden our artistic horizons and discover more beauty in art. Cultivating the ability to appreciate art is a long and enriching process that requires us to feel deeply, arm ourselves with knowledge, discover through keen observation, and accept with an open heart. Through this process, we can not only enhance our aesthetic literacy and spiritual realm but also sail through the vast ocean of art, experiencing the endless brilliance and beauty created by human civilization. Let us actively engage in the practice of art appreciation, continually cultivating and enhancing our ability to appreciate art, making it an indispensable source of spiritual nourishment in our lives. * * * ### 评论 提交你的评论 ## AI Website Creation # [一行代码没写,我通过ai搭建了个网站](https://banzhuanriji.com/) _2024-12-07 20:03_ _·_ [技术学习](https://banzhuanriji.com/category/study/) **收藏夹** 是我强行称呼的。其实就是一个列表。你可以访问 [linkpark.site](https://linkpark.site/) 。实现效果如下: ![_20241207133002.png](https://s2.loli.net/2024/12/07/395AUPlMJD7dEy4.jpg) 实现的效果: 1. 读取我手动维护的静态文件(markdown文件)来生成网页列表 2. 列表搜索 3. 随机跳转某个Link的按钮 4. 在随机列表获取一张图片作为背景图 5. 获取到背景图的主要颜色设置为按钮的配色 如果你对这个内容有兴趣,你可以参考一下下面的代码: ```lang-html LINKPARK.SITE

    linkpark.site

    本页面为个人收藏列表页。从未有意冒用各网站商标,如果您认为您的内容或权益受到侵犯,请联系 m@linkpark.site 。本页面不收集任何信息。


      ``` [ai](https://banzhuanriji.com/tag/ai/) · [代码](https://banzhuanriji.com/tag/%E4%BB%A3%E7%A0%81/) · [收藏夹](https://banzhuanriji.com/tag/%E6%94%B6%E8%97%8F%E5%A4%B9/) · [linkpark](https://banzhuanriji.com/tag/linkpark/) * * * ### 评论 提交你的评论 ## Shawshank Redemption Review # [我评《肖申克的救赎》](https://banzhuanriji.com/) _2024-11-26 23:48_ _·_ [影评](https://banzhuanriji.com/category/movies/) ![R-C.jpeg](https://banzhuanriji.com/usr/uploads/2024/11/1949821839.jpeg) 简评:掐头去尾,才可称影史第一 我为何这样评价? 1 开头部分如果想简单地带过,可以用倒叙手法,直接在监狱开场?电影里的内容过于拖沓,试图让观众代入被冤枉入狱难以复盘的绝望心情。但是长短节奏和输出内容不符合。 2 结尾很尴尬,甚至有点像我拍的。试图讲述主角的结局,也要圆满之前埋下的伏笔。些许牵强,不过聊胜于无吧。 这两段我感觉内容节奏没有把握好。毕竟是双料榜单第一名,我属于是强行鸡蛋里挑骨头。不过好处就是降低了理解门槛? **让人理解的艺术才是艺术**,毕竟是商业电影不是艺术片(试图往回圆。 整体连贯得当,节奏紧凑分明。故事中间甚至可以用明朗的镜头带来一些 _惊悚_ 的压抑感。没有过多写安迪挖掘隧道的内容,用变白的头发和周遭的变化来描述事情的发生,巧妙。最后拿出带小锤凹槽的圣经,一切恍然大悟,深深地雨夜,却仿佛一片光明。好故事,好导演。 > 结尾烂梗:主角不叫肖申克 [肖申克的救赎](https://banzhuanriji.com/tag/%E8%82%96%E7%94%B3%E5%85%8B%E7%9A%84%E6%95%91%E8%B5%8E/) · [The Shawshank Redemption](https://banzhuanriji.com/tag/The-Shawshank-Redemption/) · [电影](https://banzhuanriji.com/tag/%E7%94%B5%E5%BD%B1/) · [豆瓣](https://banzhuanriji.com/tag/%E8%B1%86%E7%93%A3/) · [排行榜](https://banzhuanriji.com/tag/%E6%8E%92%E8%A1%8C%E6%A6%9C/) * * * ### 评论 提交你的评论 ## Self-Hosted Analytics # [用PHP做一个自己的访问统计](https://banzhuanriji.com/) _2024-11-18 10:25_ _·_ [服务器](https://banzhuanriji.com/category/server/) ## 原因 ### 为什么自己写 因为在自己域下,可控&不会被常见的去广告插件屏蔽 ### 为什么选择PHP 我曾经试图用CSS方法实现,奈何技术有限,且我不是专业的前端和后端。不过如果有兴趣的朋友可以看看这个文章 [https://herman.bearblog.dev/how-bear-does-analytics-with-css/](https://herman.bearblog.dev/how-bear-does-analytics-with-css/) 。这个作者简单介绍了自己如何使用CSS方法进行统计并计算PV之类的数据。 且我希望是放在主题文件下可以直接运行和使用,没有想在服务端运行docker或者其他程序 ### 它有什么功能 机制简单的统计,访问+1,刷新+1,如此而已 ## 开始 ### 创建数据库 首先你需要创建数据库,如果你有数据库的前提下,请使用下面的语句新建一张这样的表: ```lang-sql CREATE TABLE statistics ( id INT AUTO_INCREMENT PRIMARY KEY, site_name VARCHAR(255) NOT NULL, visit_count BIGINT NOT NULL DEFAULT 0 ); ``` 这个表里只包含了一个网站地址和这个网站相对应的访问数量。它的结构大概是: | sitename | visit\_count | | --- | --- | | banzhuanriji.com | 123 | 然后我们初始化一下: ```lang-sql INSERT INTO statistics (site_name, visit_count) VALUES ('banzhuanriji.com', 0); ``` 新建一行 `banzhuanriji.com` 的数据,且把默认数据(访问量)设置为0 ### 实现代码 首先在你的主题目录下创建一个 `counter.php` 的文件,文件内容如下 ```lang-php connect_error) { die("连接失败,请稍后再试。"); } // 指定网站名称 $site_name = 'banzhuanriji.com'; // 这里修改为需要统计的网站名称 // 更新浏览次数 $sql = "UPDATE statistics SET visit_count = visit_count + 1 WHERE site_name = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("s", $site_name); // 绑定网站名称 $stmt->execute(); // 获取当前浏览次数 $sql = "SELECT visit_count FROM statistics WHERE site_name = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("s", $site_name); // 绑定网站名称 $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); $current_views = $row['visit_count'] ?? 0; // 如果没有找到,默认值为 0 // 关闭连接 $stmt->close(); $conn->close(); ?>
      当前浏览次数: ``` 然后你只需要在需要的地方引用 `counter.php` 即可。下面依然以final主题为示例: ```lang-php ``` 然后就可以实现类似卜蒜子一样的统计效果了。而且没有使用到JS,不会被去广告插件拦截。 ## 其它 如果你有兴趣可以自己动手实现一下。你也可以把数据库信息替换成typecho的数据库信息,这样就避免了新操作一个数据库的逻辑,并且可以实现使用typecho的 `Db.php` 文件操作数据库。下面给一个简单的示例,具体的实现逻辑和读写权限请自行斟酌完成。 ```lang-php query("UPDATE `statistics` SET `visit_count` = `visit_count` + 1 WHERE `site_name` = ?", $site_name); // 获取当前浏览次数 $result = $db->fetchRow($db->select('visit_count')->from('statistics')->where('site_name = ?', $site_name)); $current_views = $result['visit_count']; } catch (Exception $e) { // 处理异常 error_log($e->getMessage()); $current_views = 0; // 如果出错,设置为 0 } ?>

      当前浏览次数:

      ``` [PHP](https://banzhuanriji.com/tag/PHP/) · [统计](https://banzhuanriji.com/tag/%E7%BB%9F%E8%AE%A1/) · [网站统计](https://banzhuanriji.com/tag/%E7%BD%91%E7%AB%99%E7%BB%9F%E8%AE%A1/) * * * ### 评论 提交你的评论 ## Android Photo Guide # [Android第三方APP拍照开发指南](https://banzhuanriji.com/) _2024-11-09 11:48_ _·_ [android](https://banzhuanriji.com/category/android/) ## 现状分析 在 Android 第三方 APP 拍照功能的实现现状中,我们不难发现存在不少问题,其中图像不清晰是较为突出的一个。经过深入研究发现,这主要归因于大部分 APP 采用 preview(预览)截图的方式来充当拍照结果。这种做法存在很大的局限性,preview 截图只是对相机预览画面的简单截取,并没有经过相机真正拍照时完整且精细的图像生成和处理流程。相机拍照时,会利用复杂的光学和电子元件精确地捕捉光线信息,然后经过一系列诸如自动对焦、自动曝光、色彩校正、降噪等处理环节,而 preview 截图往往缺失这些关键步骤,所以导致拍摄出的图像质量远低于预期。 所以,这种方法不仅导致图片质量差,而且用户体验也不佳。由于没有充分利用Android系统的相机功能,很多开发者在实现拍照时面临诸多困难。大概归为下面几个比较突出的问题: - 图片质量低:预览截图无法获取高质量的照片。 - 用户体验差:拍照过程不够流畅,用户可能需要多次尝试才能获得满意的照片。 - 功能限制:无法使用相机的高级功能,如闪光灯、焦距调整等。 ## 正确的拍照方式 ### 一、调用系统相机拍照 当第三方 APP 在 Android 系统中调用相机拍照时,本质上是通过与系统相机服务交互来实现的。应用会发送一个特定的 Intent 来唤起系统相机应用。这个 Intent 可以携带一些参数,比如指定输出的图像格式、存储位置等。系统相机应用启动后,它会初始化相机硬件,包括启动相机传感器、配置镜头参数等。当用户触发拍照操作时,相机传感器开始工作,光线通过镜头在传感器上成像。传感器将光信号转换为电信号,再经过模数转换为数字信号。这些数字信号随后在相机内部的图像处理器中经过一系列复杂算法的处理,如根据光线条件调整曝光值、通过自动对焦算法使图像清晰对焦、对色彩进行平衡处理以保证色彩的准确性。处理完成后,图像数据会根据设定的格式(如 JPEG)存储在指定位置,并通过 Intent 将拍摄结果回传给第三方应用,这个过程需要确保应用有相应的存储权限和读取权限。 那么,在Android中,调用系统相机拍照的逻辑相对简单,主要通过Intent来实现。以下是基本的实现步骤: 1. 创建Intent:使用MediaStore.ACTION\_IMAGE\_CAPTURE创建一个拍照的Intent。 2. 传递文件URI:指定照片存储的位置,确保拍摄的照片能正确保存。 3. 启动Activity:通过startActivityForResult启动相机界面。 4. 处理结果:在onActivityResult中处理拍照后的结果。 简单的实现步骤如下: ```lang-java private static final int REQUEST_IMAGE_CAPTURE = 1; private Uri photoURI; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // 创建一个文件来存储照片 File photoFile = createImageFile(); if (photoFile != null) { photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { // 处理拍照结果 // photoURI指向的文件就是拍摄的照片 } } ``` ### 二、通过Camera2软件包进行拍照 > android.hardware.camera2 首先一张图来说明一下构建相机APP的正确逻辑: ![2018 I/O大会](https://banzhuanriji.com/usr/uploads/2024/11/2573717844.png) Camera2 API提供了对相机硬件的深入控制,支持更复杂的功能,如手动对焦、曝光控制等。使用Camera2 API的基本步骤如下: 1. 获取CameraManager:使用CameraManager获取相机服务。 2. 打开相机:通过openCamera方法打开相机。 3. 创建CaptureSession:配置并创建用于捕获图像的会话。 4. 拍照:使用CaptureRequest配置拍照参数并执行。 具体实现代码(上述步骤为简要步骤,具体请参考代码): #### 申请权限 ``` ``` #### 获取可用相机设备列表 ```lang-java CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { String[] cameraIds = manager.getCameraIdList(); for (String cameraId : cameraIds) { CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); // 这里可以进一步检查相机特性,如是否支持特定功能等 } } catch (CameraAccessException e) { e.printStackTrace(); } ``` #### 配置相机参数 ```lang-java private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { // 相机打开成功,可以进行参数配置和开始预览、拍照等操作 try { CameraCaptureSession.StateCallback sessionCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { // 会话配置成功,可以设置拍照请求等 try { CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); // 设置图像格式、自动对焦模式等参数 builder.addTarget(imageReader.getSurface()); CaptureRequest request = builder.build(); session.capture(request, null, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession session) { // 会话配置失败处理 } }; camera.createCaptureSession(Arrays.asList(imageReader.getSurface()), sessionCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onDisconnected(CameraDevice camera) { // 相机断开连接处理 camera.close(); } @Override public void onError(CameraDevice camera, int error) { // 相机出现错误处理 camera.close(); } }; ``` #### 进行拍照 ```lang-java CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); builder.addTarget(imageReader.getSurface()); // 设置自动对焦模式为自动 builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); // 设置曝光模式为自动 builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); CaptureRequest request = builder.build(); session.capture(request, null, null); ``` #### 总结简单的实现方法 ```lang-java private void openCamera() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { String cameraId = manager.getCameraIdList()[0]; // 获取后置相机ID manager.openCamera(cameraId, stateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { // 相机打开成功,开始拍照 // 此处可以配置CaptureSession } @Override public void onDisconnected(@NonNull CameraDevice camera) { camera.close(); } @Override public void onError(@NonNull CameraDevice camera, int error) { camera.close(); } }; ``` ### 通过CameraX软件包进行拍照 CameraX 是一个 Jetpack 库。同样更方便地提供了包括但不限于相机的预览,分析,视频和图片的拍摄的api。下面是使用代码: #### 添加依赖 ``` def camerax_version = "1.2.0" implementation "androidx.camera:camera-core:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version" def camerax_version = "1.1.0-alpha07" implementation "androidx.camera:camera-core:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version" implementation "androidx.camera:camera-view:$camerax_version" ``` #### 初始化CameraX ```lang-java ProcessCameraProvider.getInstance(this).addListener(() -> { try { cameraProvider = ProcessCameraProvider.getInstance(context).get(); bindCameraUseCases(); } catch (ExecutionException | InterruptedException e) { // 异常处理 } }, ContextCompat.getMainExecutor(this)); ``` #### 配置和使用相机示例 ```lang-java // 创建 ImageCapture 和 Preview 等相机用例,并将它们绑定到相机设备上 private void bindCameraUseCases() { Preview preview = new Preview.Builder() .build(); preview.setSurfaceProvider(viewFinder.getSurfaceProvider()); ImageCapture imageCapture = new ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build(); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); try { cameraProvider.unbindAll(); camera = cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture); } catch (Exception e) { // 绑定失败处理 } } ``` #### 拍照操作 ```lang-java imageCapture.takePicture(ContextCompat.getMainExecutor(this), new ImageCapture.OnImageCapturedCallback() { @Override public void onCaptureSuccess(@NonNull ImageProxy image) { // 拍照成功处理,这里可以获取图像数据并进一步处理 super.onCaptureSuccess(image); image.close(); } @Override public void onError(@NonNull ImageCaptureException exception) { // 拍照错误处理 super.onError(exception); } }); ``` #### 依然,提供一个简单的示例 ```lang-java private void startCamera() { CameraX.bindToLifecycle(this, preview, imageCapture); } // 配置预览 Preview preview = new Preview.Builder().build(); // 配置拍照 ImageCapture imageCapture = new ImageCapture.Builder().build(); ``` ### 小结 在Android应用开发中,实现高质量的拍照功能至关重要。通过合理选择相机API(如Camera2和CameraX),开发者可以提供更高质量的照片和更流畅的用户体验。还有很多内容本文没有提到,例如:HDR,多相机(Multi-Camera)调用,屏幕闪烁设置,视频流(相机帧)的优化,CameraX的Extensions API 。 目前来看,android的相机和iOS一对比,真是一坨越堆越高的大屎山! [android](https://banzhuanriji.com/tag/android/) · [相机功能](https://banzhuanriji.com/tag/%E7%9B%B8%E6%9C%BA%E5%8A%9F%E8%83%BD/) · [图像处理](https://banzhuanriji.com/tag/%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86/) · [用户体验](https://banzhuanriji.com/tag/%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C/) · [Camera2](https://banzhuanriji.com/tag/Camera2/) · [CameraX](https://banzhuanriji.com/tag/CameraX/) · [Intent](https://banzhuanriji.com/tag/Intent/) · [预览截图](https://banzhuanriji.com/tag/%E9%A2%84%E8%A7%88%E6%88%AA%E5%9B%BE/) · [照片质量](https://banzhuanriji.com/tag/%E7%85%A7%E7%89%87%E8%B4%A8%E9%87%8F/) · [应用开发](https://banzhuanriji.com/tag/%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/) · [权限管理](https://banzhuanriji.com/tag/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/) · [代码示例](https://banzhuanriji.com/tag/%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B/) · [相机硬件](https://banzhuanriji.com/tag/%E7%9B%B8%E6%9C%BA%E7%A1%AC%E4%BB%B6/) · [光学成像](https://banzhuanriji.com/tag/%E5%85%89%E5%AD%A6%E6%88%90%E5%83%8F/) * * * ### 评论 提交你的评论 ## Final Theme Overview # [final 主题](https://banzhuanriji.com/) _2024-11-07 20:23_ _·_ [主题](https://banzhuanriji.com/category/theme/) ![screenshot.png](https://banzhuanriji.com/usr/uploads/2024/11/3907895800.png) 请访问: [https://github.com/hoytzhang/typecho-theme-final](https://github.com/hoytzhang/typecho-theme-final) 效果请参: [https://final.linkpark.site](https://final.linkpark.site/) [typecho](https://banzhuanriji.com/tag/typecho/) · [theme](https://banzhuanriji.com/tag/theme/) · [主题](https://banzhuanriji.com/tag/%E4%B8%BB%E9%A2%98/) · [final](https://banzhuanriji.com/tag/final/) · [github](https://banzhuanriji.com/tag/github/) * * * ### 评论 提交你的评论 ## Internal Network Tools Comparison # [内网穿透工具横向对比](https://banzhuanriji.com/) _2024-11-06 19:34_ _·_ [服务器](https://banzhuanriji.com/category/server/) 在网络环境中,内网穿透工具为我们提供了便捷的方式来访问内部网络资源。本文将对 cpolar、花生壳、SAKURA FRP、NATAPP、飞鸽、网云穿、闪库、内网云、快解析、nat123 和 i996 等工具进行横向对比,分析它们的优缺点。 因为我的使用方向为个人使用,所以只列举免费套餐和可能收费的内容部分。 | 名称 | 免费套餐带宽 | 是否限制流量 | 是否可自定义域名 | 隧道数量 | 实名价格 | 其他/备注 | | --- | --- | --- | --- | --- | --- | --- | | [cpolar](https://i.cpolar.com/m/5bOF) | 1Mbps | 否 | 否 | 4 | - | 无 | | [SAKURA FRP](https://www.natfrp.com/) | 10Mbps | 10GB | 是 | 2 | 1元 | 无 | | [NATAPP](https://natapp.cn/) | 1Mbps | - | 否 | - | - | 域名/端口随机,且不定时强制更换 | | [飞鸽](https://www.fgnwct.com/) | 0.5Mbps | 否 | 是 | 2 | - | 无 | | [网云穿](http://xiaomy.net/) | 前7天带宽3Mbps,7天后降为1Mbps | 1GB | 是 | 1 | - | 无 | | [i996](http://www.i996.me/) | 2Mbps | - | 是 | - | - | 无 | [内网穿透](https://banzhuanriji.com/tag/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/) · [工具对比](https://banzhuanriji.com/tag/%E5%B7%A5%E5%85%B7%E5%AF%B9%E6%AF%94/) · [免费套餐](https://banzhuanriji.com/tag/%E5%85%8D%E8%B4%B9%E5%A5%97%E9%A4%90/) · [CPOLAR](https://banzhuanriji.com/tag/CPOLAR/) · [i996](https://banzhuanriji.com/tag/i996/) * * * ### 评论 提交你的评论 ## Git Cherry-Pick Guide # [深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/) _2024-11-06 19:34_ _·_ [git](https://banzhuanriji.com/category/git/) 在使用 Git 进行版本控制的过程中,我们常常会遇到需要从一个分支中选取特定的提交并应用到另一个分支的情况,这时候, `cherry-pick` 操作就派上用场了。 ## 一、什么是 cherry-pick? `Cherry-pick` 是 Git 提供的一个强大功能,它允许我们从一个分支的提交历史中挑选出一个或多个特定的提交,并将其应用到当前分支。这与合并整个分支(例如使用 git merge)有所不同, `cherry-pick` 给予我们更精准的控制,能够只选择我们真正需要的更改。 ## 二、为什么需要 cherry-pick? ### (一)修复跨分支的 bug 假设我们有一个开发分支(dev)和一个主分支(master)。在开发分支上发现并修复了一个 bug,但是这个 bug 很可能也存在于主分支中。此时,我们并不想将整个开发分支合并到主分支,因为开发分支可能还包含其他未完成或者不适合在主分支上出现的功能。通过 `cherry-pick`,我们可以只将修复 bug 的提交从开发分支应用到主分支,快速且精准地解决主分支中的问题。 ### (二)移植功能 有时候,我们在一个功能分支上开发了一个非常有用的功能。后来发现,这个功能在另一个分支上也有需求。如果我们不想重新开发这个功能,就可以使用 `cherry-pick` 将实现该功能的提交从原功能分支移植到目标分支。这样可以避免重复劳动,提高开发效率。 ## 三、cherry-pick 的基本操作 ### (一)查看提交历史 在进行 `cherry-pick` 操作之前,我们首先需要查看相关分支的提交历史,以确定我们要挑选的提交。使用git log命令可以查看分支的提交记录。例如,我们在本地仓库的命令行中执行 `git log` ,它会列出当前分支的所有提交,包括提交的哈希值(commit hash)、作者、日期和提交信息等内容。 ### (二)挑选单个提交 1. 当我们确定了要挑选的提交的哈希值后,就可以进行 `cherry-pick` 操作。如果只挑选一个提交,使用命令: `git cherry-pick [commit-hash]` 。例如,假设我们从git log中获取到一个提交哈希值为abc123def456的提交,我们想将其应用到当前分支,那么就可以执行 `git cherry-pick abc123def456` 。 2. 如果操作过程中没有冲突,Git 会顺利地将该提交的更改应用到当前分支,并在当前分支上创建一个新的提交记录,这个新提交的内容与被挑选的提交相同,只是它有一个新的提交哈希值,属于当前分支的提交历史。 ### (三)挑选多个提交 1. 依次挑选 如果要挑选多个提交,我们可以多次执行单个提交的 `cherry-pick` 操作。即逐个输入要挑选的提交哈希值,重复执行git `cherry-pick` 命令。 2. 范围挑选 另一种方法是使用范围选择。格式为 `git cherry-pick [start-commit-hash]..[end-commit-hash]` 。这里 `[start-commit-hash]` 是范围起点的提交哈希值(不包括该提交), `[end-commit-hash]` 是范围终点的提交哈希值(包括该提交)。这种方式可以将从起点到终点之间的所有提交挑选到当前分支。 ## 四、处理 cherry-pick 中的冲突 ### (一)冲突的产生 当我们进行 `cherry-pick` 操作时,有可能会遇到冲突。这通常发生在被挑选的提交对文件的更改与当前分支中同一文件的现有内容存在冲突时。例如,被挑选的提交修改了某一行代码,而当前分支在同一行也有不同的修改,Git 就无法自动合并,从而产生冲突。 ### (二)解决冲突 1. 当冲突发生时,Git 会提示我们。我们需要打开有冲突的文件,文件中会用特殊的标记(如 `<<<<<<<` 、 `=======` 、 `>>>>>>>` )来标识冲突的区域。 2. 我们需要根据实际情况手动编辑文件,删除这些冲突标记,并使文件内容符合我们的期望。这一过程类似于处理合并冲突。 3. 解决完冲突后,我们需要将解决冲突后的文件添加到暂存区,使用 `git add [conflict-file-names]` 命令,其中 `[conflict-file-names]` 是有冲突的文件名。 4. 最后,执行 `git cherry-pick --continue` 来完成 `cherry-pick` 操作。如果在解决冲突过程中我们改变了主意,不想继续进行 `cherry-pick` 操作,可以执行 `git cherry-pick --abort` 来取消操作。 `Cherry-pick` 是 Git 中一个十分实用的操作,合理地运用它可以帮助我们在版本控制和代码管理过程中更加灵活、高效地处理分支间的代码迁移和问题修复等工作。希望通过本文的介绍,能让你对 Git 的 `cherry-pick` 操作有更深入的理解和更好的运用。 [git](https://banzhuanriji.com/tag/git/) · [版本控制](https://banzhuanriji.com/tag/%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6/) · [cherry-pick](https://banzhuanriji.com/tag/cherry-pick/) · [cp](https://banzhuanriji.com/tag/cp/) · [分支管理](https://banzhuanriji.com/tag/%E5%88%86%E6%94%AF%E7%AE%A1%E7%90%86/) · [提交历史](https://banzhuanriji.com/tag/%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2/) · [开发效率](https://banzhuanriji.com/tag/%E5%BC%80%E5%8F%91%E6%95%88%E7%8E%87/) · [命令行工具](https://banzhuanriji.com/tag/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7/) * * * ### 评论 提交你的评论 ## Finding Your Antipode # [对跖点](https://banzhuanriji.com/) _2024-11-06 19:33_ _·_ [技术学习](https://banzhuanriji.com/category/study/) 其实很久之前也会有一闪而过的想法,地球另一端的人不知道是谁,他的生活是怎么样的。昨天在网上看视频看到了这个概念。只需要简单地计算就可以知道地球上离你最远地点在哪里。 ## 大致地点 ![antipodes-all-world.webp](https://banzhuanriji.com/usr/uploads/2024/10/3907838824.webp) ## 计算方法 维度相同带“-”号,中国都在北半球,所以相反的维度就是南纬即可。 经度需要被180减去即刻。例如180-114=66。当然带小数点的具体的经度需要自己计算。 计算出结果,就可以在Google Earth上找到你需要对应的位置的图像。 ## 我家 最后计算出来的结果,我家的对跖点是阿根廷的拉潘帕省的一个城市的农郊。下面是图像 ![antipodes-my-home.webp](https://banzhuanriji.com/usr/uploads/2024/10/1061360004.webp) ## 计算工具 这里有一个方便计算的工具地址: [http://www.atoolbox.net/Tool.php?Id=1002](http://www.atoolbox.net/Tool.php?Id=1002) [对跖点](https://banzhuanriji.com/tag/%E5%AF%B9%E8%B7%96%E7%82%B9/) · [地理学](https://banzhuanriji.com/tag/%E5%9C%B0%E7%90%86%E5%AD%A6/) · [经纬度计算](https://banzhuanriji.com/tag/%E7%BB%8F%E7%BA%AC%E5%BA%A6%E8%AE%A1%E7%AE%97/) · [地球另一端](https://banzhuanriji.com/tag/%E5%9C%B0%E7%90%83%E5%8F%A6%E4%B8%80%E7%AB%AF/) · [在线工具](https://banzhuanriji.com/tag/%E5%9C%A8%E7%BA%BF%E5%B7%A5%E5%85%B7/) · [生活探索](https://banzhuanriji.com/tag/%E7%94%9F%E6%B4%BB%E6%8E%A2%E7%B4%A2/) · [Google Earth](https://banzhuanriji.com/tag/Google-Earth/) · [南北半球](https://banzhuanriji.com/tag/%E5%8D%97%E5%8C%97%E5%8D%8A%E7%90%83/) * * * ### 评论 提交你的评论 ## Uninstall System Apps # [adb卸载/恢复系统app](https://banzhuanriji.com/) _2024-11-06 19:32_ _·_ [android](https://banzhuanriji.com/category/android/) 卸载: ``` adb uninstall --user 0 adb shell pm uninstall --user 0 ``` 恢复安装: ``` adb shell cmd package install-existing ``` * * * 停用应用: ``` adb shell pm disable-user 应用名 ``` 启用应用: ``` adb shell pm enable 应用名 ``` * * * 下面是MIUI的包名列表 2022-11-25 22:05:43 michael007js 4696 ``` #默认桌面,切勿删除 com.miui.home #输入法,切勿删除 com.iflytek.inputmethod.miui com.sohu.inputmethod.sogou.xiaomi #限制500行 #第三方应用包名 #微信 com.tencent.mm #Tim com.tencent.tim #QQ com.tencent.mobileqq #Scene com.omarea.vtools #请执行添加系统进程白名单 #系统进程已加入白名单,上线五百行 vendor.qti.hardware.cacert.server #骁龙相关 com.qualcomm.qti.autoregistration com.qualcomm.uimremoteclient com.qualcomm.qti.telephonyservice com.qualcomm.qti.performancemode com.qualcomm.uimremoteserver com.qualcomm.qti.ridemodeaudio com.qualcomm.atfwd com.qualcomm.embms com.qualcomm.timeservice com.qualcomm.qti.poweroffalarm com.qualcomm.qti.xrcb com.qualcomm.qti.seccamservice com.qualcomm.qti.uimGbaApp com.qualcomm.location com.qualcomm.qti.ims com.qualcomm.qti.lpa com.qualcomm.qti.uim com.qualcomm.qti.cne com.qualcomm.qti.workloadclassifier com.qualcomm.qti.devicestatisticsservice com.qualcomm.qti.remoteSimlockAuth com.qualcomm.qti.services.systemhelper com.qti.qualcomm.mstatssystemservice com.qualcomm.qcrilmsgtunnel com.qualcomm.qti.dynamicddsservice com.qualcomm.qti.gpudrivers.lahaina.api30 com.qti.qualcomm.deviceinfo com.qualcomm.wfd.service com.qti.qualcomm.datastatusnotification #文件管理 com.android.fileexplorer #谷歌爸爸 com.android.phone com.android.settings com.android.contacts android.qvaoverlay.common android.overlay.common com.android.providers.downloads.ui android.miui.overlay com.android.mms com.android.nfc android.overlay.target com.google.android.webview com.android.server.telecom android.aosp.overlay #电量与性能 com.miui.powerkeeper #耗电检测 com.xiaomi.powerchecker #小米账号 com.xiaomi.account #CatchLog反馈bug时收集日志 com.bsp.catchlog #相机工具包 com.xiaomi.cameratools #小米系统界面组件 miui.systemui.plugin #应用包管理组件 com.miui.packageinstaller #HTML查看器 com.android.htmlviewer #照片 com.miui.extraphoto #系统服务组件 com.miui.securityadd #相册 com.miui.gallery #下载 com.android.providers.downloads #手机管家 com.miui.securitycenter #小米智能卡app com.miui.tsmclient #MIUI安全组件 com.miui.guardprovider #通知 com.miui.notification #小米助手 com.miui.core.internal.assistant #WAPI证书 com.wapi.wapicertmanage #虚拟SIM内核 com.miui.vsimcore #安全核心组件 com.miui.securitycore #SIM卡激活服务 com.xiaomi.simactivate.service #常用语 com.miui.phrase #小米音乐 com.miui.player #miui系统 com.miui.system com.miui.systemui.devices.overlay #万向息屏 com.miui.aod #miui核心rom com.miui.rom #融合位置服务 com.xiaomi.location.fused #电话 com.android.incallui #查找 com.xiaomi.mircs #小米钱包 com.mipay.wallet #密钥链 com.android.keychain #相机 com.android.camera #小米服务框架 com.xiaomi.xmsf com.xiaomi.xmsfkeeper #自由窗口 com.miui.freeform #查找手机 com.xiaomi.finddevice #小米云控(不玩游戏可以保留) com.xiaomi.joyose #小米支付 com.miui.nextpay #小米视频 com.miui.video #小米window manager service com.miui.wmsvc #应用商店 com.xiaomi.market #小米设置 com.xiaomi.misettings #miui+ beta版 com.xiaomi.mirror #北斗/GPS/GLONASS多模多频高精度 com.xiaomi.gnss.polaris #应用录音 com.miui.audiomonitor #指纹服务 com.goodix.fingerprint.setting #壁纸 com.miui.miwallpaper #小米安全键盘 com.miui.securityinputmethod #蓝牙 com.xiaomi.bluetooth com.android.bluetooth #网络位置服务 com.xiaomi.metoknlp #VPN com.android.vpndialogs #截屏 com.miui.screenshot #闹钟 com.android.deskclock #卫星定位 com.xiaomi.bsp.gps.nps #权限管理服务 com.lbe.security.miui com.xiaomi.security.onetrack #miui核心 com.miui.core #人脸识别 com.miui.face #桌面 com.miui.home #AI虚拟助手 com.xiaomi.aiasst.service #未知 vendor.qti.iwlan vendor.qti.imsrcs org.codeaurora.ims org.ifaa.aidl.manager com.qti.phone com.qti.ltebc com.qti.diagservices com.qti.snapdragon.qdcm_ff com.qti.slaservice com.qti.dpmserviceapp com.qti.dpmserviceapp com.qti.xdivert com.miuix.editor com.miui.mediafeature com.miui.face.overlay.miui com.miui.core.internal.editor.services com.xiaomi.otrpbroker org.mipay.android.manager com.modemdebug com.miui.systemui.carriers.overlay com.miui.systemui.overlay.devices.android com.miui.core.internal.services #msa广告 com.miui.systemAdSolution #广告模块 com.xiaomi.ab #小米ai工具箱 com.xiaomi.aiasst.vision #备份 com.miui.backup #小米云同步 com.miui.micloudsync #MiuiDaemon用户信息收集 com.miui.daemon #小米我的服务app com.miui.vipservice #小米手机游戏高能时刻 com.xiaomi.migameservice 快应用 com.miui.hybrid #云翻译服务 com.miui.translation.xmcloud #翻译服务 com.miui.translationservice #金山翻译服务 com.miui.translation.kingsoft #有道翻译服务 com.miui.translation.youdao #获取补丁 com.miui.catcherpatch #硬件检测 com.miui.cit #游戏网络加速 com.miui.vpnsdkmanager #智能助理 com.miui.personalassistant #bug com.miui.bugreport #语音唤醒 com.miui.voicetrigger #云备份 com.miui.cloudbackup #小区广播 com.android.cellbroadcastreceiver #小米互传 com.miui.mishare.connectivity #云服务 com.miui.cloudservice com.miui.cloudservice.sysbase #微信指纹支付验证 com.tencent.soter.soterserver #悬浮球 com.miui.touchassistant #广告分析 com.miui.analytics #黄页 com.miui.yellowpage #小米闻声(小米无障碍) com.miui.accessibility #小爱同学 com.miui.voiceassist ``` [adb](https://banzhuanriji.com/tag/adb/) · [android](https://banzhuanriji.com/tag/android/) · [miui](https://banzhuanriji.com/tag/miui/) · [卸载](https://banzhuanriji.com/tag/%E5%8D%B8%E8%BD%BD/) · [root](https://banzhuanriji.com/tag/root/) · [预装软件](https://banzhuanriji.com/tag/%E9%A2%84%E8%A3%85%E8%BD%AF%E4%BB%B6/) * * * ### 评论 提交你的评论 ## Redmi Note 14 Pro+ Review # [小米 Redmi note 14 pro + 的糟糕体验](https://banzhuanriji.com/) _2024-10-06 10:12_ _·_ [随笔](https://banzhuanriji.com/category/essay/) 发布会第二天线下购买两台,现在遇到的问题 ## 赠送的五大保障超过一周可退货时间依然未到账 2024 年 9 月 27 日激活,首发赠送的‘五大保障’未到账,客服称需要我联系小米之家。联系小米之家,小米之家称都有,但是查询不到(别人的同款手机可以查询到)。 ## 相册必现的恶性 bug ,成本极高的反馈流程和小米超级分散的售后部门 带水印拍照后,相册打开超动态显示,你会发现小米的 HDR 就是在图片上加了个 **_灰色滤镜_** 。现在的问题是,滤镜的位置错了,导致我看照片,照片会显示一道白边。(也就是蒙版应该居上,而不是居下,因为下面有一截水印,具体效果请看链接附图) 在线客服反馈,无果。后被多次打电话询问具体状况。我在心平气和地沟通完所有复现步骤,并告知所有系统&软件版本信息之后,客服告知无法反馈到技术部门,因为他们不是一个部门。说我需要到小米社区/服务与反馈 APP 进行反馈。笑。 于是在小米社区 app 进行反馈。被告知需要‘在服务与反馈 App 中勾选上传问题日志提交下反馈’。但是 **_我的‘服务与反馈’app 打开闪退_** …… 具体效果请看(三张图拼接,分别为 0.6X ,1X ,2.5X ): ![](https://pics.mopo.blog/post/terrible-experience-with-redmi-note-14-pro/1.webp) ## 目前可以忍受的问题 卡。各种卡。刚买前几天发热厉害(在戴了官方赠送的硅胶壳的前提下),我猜测小米知道这个问题,所以选择在手机大批量发布之前,天气降温之后发布。 我关闭了所有 APP 的自启动权限,全部设置为禁止后台运行,目前发现:米家,夸克浏览器,酷安,剪映依然可以后台自启运行(之前的 MIUI14 貌似没有这个问题)。或许是被其他 APP 唤醒,但我不知道是哪个 APP ,因为小米 HyperOS 貌似删除了禁止唤醒其他 APP 或服务的开关,目前只剩下很鸡肋的链式唤醒(用户主动跳转)开关。解决方案:我给这几个软件卸载了。 按下拍照键之后疯狂卡顿。如果是用 2.5x 镜头拍照貌似卡的更厉害。就是卡到取景框不动的那种卡。 成像效果不尽人意。光线稍暗,宣传的光影猎人 800 ,实际超级大涂抹带你梦回 2014 。 绝非黑稿,本人亲身经历。 [小米](https://banzhuanriji.com/tag/%E5%B0%8F%E7%B1%B3/) · [红米](https://banzhuanriji.com/tag/%E7%BA%A2%E7%B1%B3/) · [redmi](https://banzhuanriji.com/tag/redmi/) · [xiaomi](https://banzhuanriji.com/tag/xiaomi/) · [redmi note 14 pro plus](https://banzhuanriji.com/tag/redmi-note-14-pro-plus/) * * * ### 评论 提交你的评论 ## Setup WebDAV on Ubuntu # [ubuntu使用apache2快速搭建webdav](https://banzhuanriji.com/) _2024-09-20 19:51_ _·_ [服务器](https://banzhuanriji.com/category/server/) 1. 安装apache2 ```lang-bash sudo apt-get install apache2 ``` 2. 启用模块 ```lang-bash sudo a2enmod dav_fs sudo a2enmod dav sudo a2enmod dav_lock ``` 3. 建立文件链接 ```lang-bash sudo ln -s /etc/apache2/mods-available/dav.load /etc/apache2/mods-enabled/dav.load sudo ln -s /etc/apache2/mods-available/dav_fs.load /etc/apache2/mods-enabled/dav_fs.load sudo ln -s /etc/apache2/mods-available/dav_lock.load /etc/apache2/mods-enabled/dav_lock.load sudo ln -s /etc/apache2/mods-available/dav_fs.conf /etc/apache2/mods-enabled/dav_fs.conf ``` 4. 编辑apache2的配置文件,路径为 `/etc/apache2/ports.conf` ,添加一个端口监听 ```lang-bash Listen 8080 #也可以改成其他端口 ``` 5. 创建新用户,其中 `xxx` 为你需要的用户名。命令中的路径和文件名可以自己改。另外创建完成后会让你输入和确认密码 ```lang-bash sudo htpasswd -c /etc/apache2/webdav.password xxx ``` 6. 设置文件权限 ```lang-bash sudo chown root:www-data /etc/apache2/webdav.password sudo chmod 640 /etc/apache2/webdav.password ``` 7. 编辑 `/etc/apache2/sites-available/000-default.conf` 文件,或者可以直接替换原有内容 ```lang-bash # 新添加一个IP端口8080的虚拟主机,该主机给webDav使用 #物理路径(根据需要改成自己的位置,例如物理路径为/var/www/share) DocumentRoot /var/www/share #针对物理路径的配置 #允许目录浏览和多视图 Options Indexes MultiViews #禁止使用 .htaccess 文件覆盖配置 AllowOverride None #控制访问权限,允许所有客户端访问此目录 Order allow,deny allow from all #要暴露的网络地址和对应的物理路径 Alias /webdav /var/www/share #针对 /webdav 网络地址的配置,本机地址:http://127.0.0.1:8080/webdav #启用 WebDAV 功能 DAV On #启用基本身份验证,设置认证类型为Basic或者Digest AuthType Basic #设置认证对话框的提示信息,自由填写 AuthName "webdav" #指定用户名和密码的文件 AuthUserFile /etc/apache2/webdav.password #仅指定用户名叫“admin”的用户可访问,去掉 #号生效 #Require user admin #允许密码文件中的所有用户访问 Require valid-user ``` 8. 设置权限 ```lang-bash sudo chown www-data:www-data /var/www/share ``` 9. 重启apache2 ```lang-bash sudo /etc/init.d/apache2 restart ``` > [https://www.aoiai.com/649.html](https://www.aoiai.com/649.html) * * * ### 评论 提交你的评论 ## File Hash Check # [在Windows的右键菜单添加文件哈希校验功能](https://banzhuanriji.com/) _2024-09-07 23:02_ _·_ [Windows](https://banzhuanriji.com/category/windows/) 新建文档,复制下面的代码保存为reg格式,打开即可。如果汉字显示错乱,将文档的编码改为UTF-16即可。 ```lang-text Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\hash] "MUIVerb"="校验文件 Hash" "SubCommands"="" "Icon"="PowerShell.exe" ; SHA1 [HKEY_CLASSES_ROOT\*\shell\hash\shell\01menu] "MUIVerb"="SHA1" [HKEY_CLASSES_ROOT\*\shell\hash\shell\01menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm SHA1 | format-list" ; SHA256 [HKEY_CLASSES_ROOT\*\shell\hash\shell\02menu] "MUIVerb"="SHA256" [HKEY_CLASSES_ROOT\*\shell\hash\shell\02menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm SHA256 | format-list" ; SHA384 [HKEY_CLASSES_ROOT\*\shell\hash\shell\03menu] "MUIVerb"="SHA384" [HKEY_CLASSES_ROOT\*\shell\hash\shell\03menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm SHA384 | format-list" ; SHA512 [HKEY_CLASSES_ROOT\*\shell\hash\shell\04menu] "MUIVerb"="SHA512" [HKEY_CLASSES_ROOT\*\shell\hash\shell\04menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm SHA512 | format-list" ; MACTripleDES [HKEY_CLASSES_ROOT\*\shell\hash\shell\05menu] "MUIVerb"="MACTripleDES" [HKEY_CLASSES_ROOT\*\shell\hash\shell\05menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm MACTripleDES | format-list" ; MD5 [HKEY_CLASSES_ROOT\*\shell\hash\shell\06menu] "MUIVerb"="MD5" [HKEY_CLASSES_ROOT\*\shell\hash\shell\06menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm MD5 | format-list" ; RIPEMD160 [HKEY_CLASSES_ROOT\*\shell\hash\shell\07menu] "MUIVerb"="RIPEMD160" [HKEY_CLASSES_ROOT\*\shell\hash\shell\07menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm RIPEMD160 | format-list" ; Allget-filehash -literalpath '%1' -algorithm RIPEMD160 | format-list [HKEY_CLASSES_ROOT\*\shell\hash\shell\08menu] "CommandFlags"=dword:00000020 "MUIVerb"="校验全部" [HKEY_CLASSES_ROOT\*\shell\hash\shell\08menu\command] @="powershell -noexit get-filehash -literalpath '%1' -algorithm SHA1 | format-list;get-filehash -literalpath '%1' -algorithm SHA256 | format-list;get-filehash -literalpath '%1' -algorithm SHA384 | format-list;get-filehash -literalpath '%1' -algorithm SHA512 | format-list;get-filehash -literalpath '%1' -algorithm MACTripleDES | format-list;get-filehash -literalpath '%1' -algorithm MD5 | format-list;get-filehash -literalpath '%1' -algorithm RIPEMD160 | format-list" ``` * * * ### 评论 提交你的评论 ## CloudFlare Redirect Error # [CloudFlare提示ERR\_TOO\_MANY\_REDIRECTS](https://banzhuanriji.com/) _2024-08-31 00:39_ _·_ [服务器](https://banzhuanriji.com/category/server/) > 首先,如果你有一定的英文阅读能力和解决问题的能力,你可以参考官方文档 > > [https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/#redirect-rules](https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/#redirect-rules) * * * 建议:为了排查问题,以下每一点尝试之前请恢复上一个方案的操作,以方便定位问题所在。 ## 1\. 老生常谈-清理缓存或者直接更换网络环境&浏览器 ## 2\. 关掉解析上的 **小黄云**,也就是不使用CDN,只使用CloudFlare的解析 ## 3\. 关掉“始终使用HTTPS” 1. 点击Cldouflare中你的网站 2. 点击左侧设置菜单中的SSL/TLS 3. 点击下级菜单中的 **边缘证书** 4. 右侧找到 **始终使用HTTPS** 并关闭 - 原因:点击始终使用HTTPS的帮助就可以看到官方的原因说明:使用同等 “https” URL 的 301 重定向答复所有使用 “http” 的 URL 请求。如果您只希望重定向一部分请求,请考虑创建“始终使用HTTPS”页面规则。 ## 4\. 更改加密模式 如果你的页面是搭建在 `vercel` , `github` , `netily` 之类的网站,可能大概率会出现这个问题。你会发现Cloudflare给你的加密模式配置为 `自定义 SSL/TLS` 下的 `灵活` 选项。你只需要切换成 `完全` 或者 `完全(严格)` 即可。操作步骤: 1. 点击Cldouflare中你的网站 2. 点击左侧设置菜单中的SSL/TLS 3. 点击下级菜单中的 **概述** 4. 点击右侧 **SSL/TLS加密** 栏目中的 **配置** 按钮 5. 选择 **自定义 SSL/TLS** ,在下方依次选择 `完全` 或者 `完全(严格)` 尝试即可 - 原因:SSL/TLS说明中说的很清楚 ![2024-12-13T03:28:43.png](https://banzhuanriji.com/usr/uploads/2024/12/406591532.png) [网站](https://banzhuanriji.com/tag/%E7%BD%91%E7%AB%99/) · [cloudflare](https://banzhuanriji.com/tag/cloudflare/) · [CDN](https://banzhuanriji.com/tag/CDN/) · [解析](https://banzhuanriji.com/tag/%E8%A7%A3%E6%9E%90/) · [访问失败](https://banzhuanriji.com/tag/%E8%AE%BF%E9%97%AE%E5%A4%B1%E8%B4%A5/) · [ssl](https://banzhuanriji.com/tag/ssl/) · [https](https://banzhuanriji.com/tag/https/) * * * ### 评论 提交你的评论 ## Goodbye Hangzhou # [再见,杭州](https://banzhuanriji.com/) _2024-05-20 00:39_ _·_ [随笔](https://banzhuanriji.com/category/essay/) 在杭州整整7年了,东西南北都混了一遍。要说混了个什么确实也说不出来,不过这一身肥肉和杭州的外卖脱不了一点关系。 我努力地往前想,想不到什么东西。仿佛坐在教室最后一排看着黑板上投射的幻灯片一张一张翻过去。眯起眼睛来看,恍然大悟:哦~原来是这一回啊! * * * 杭州的时间比安阳快半个小时。每次下班这里天都黑了,跟家里人或者朋友打电话,总是会被问:啊?那里都黑了?咱家还是白天呢。到这里还有一点小遗憾,东极岛我还没去呢。算了! 杭州的四季不算分明,春天和秋天时间比较短。冬天下雪也不多。不过我倒是喜欢这边经常会一连好几天地下雨,虽然梅雨天气会有衣服干不透的情况,不过这种情况不算多,没干透的纯棉T恤总是有一股味儿。也有几次刚穿上是没有味道的,过了一会才闻到自己衣服上的味道,难受的我荨麻疹都会发作,这味道让我甚至不敢靠近同事。直到他们有问题需要确认自己走了过来,我才发现他们比我身上味儿都大,原来大伙都这样。 我不喜欢这样的感觉。不过我还是爱下雨的天气。在景区里的山路上,下过雨的柏油路和两边被雨水打的翠绿的树林,就跟汽车广告里的场景一样让我放松和喜欢。我一个人主动出去玩的情况不多,大多数情况都是在雨天或者雨后,打个车穿过景区山上的树林,就这样在车上看看,也让我心旷神怡。 来杭州时,杭州刚结束了G20,城市重新规划没多久,这次规划几乎把原来杭州的农村全部拆迁掉了,并且把周边的几个小一点的县市全部收为杭州管辖内。那时候打车会经常遇到本地的师傅。我打趣说本地人好像开网约车的比较少吧,这个时候师傅就开始了他的演讲,大概相同的剧本:“我们是萧山人,不是杭州人。我们以前是非常有钱的市,以前萧山家家户户有小厂子,有自己家的小生意,像萧山机场都是萧山市市长自己筹钱建的。这就是为什么说我们‘萧山人看不起杭州人’。现在嘛被杭州占领了,杭州规划了,没已拆迁,家家户户都有钱了。我们老萧山没什么变化。” 准备换个头图,想来想去,杭州的风景名胜太多了。几乎每个朋友家人来杭,我都要陪着去一趟或者几趟西湖。杭州到夏天温度真的很高,这高温让西湖水蒸发的非常快。于是在旁边走就感觉在一个笼屉里走一样,潮热的不行。我喜欢西湖,却因此对西湖的印象挺负面,因为总是会想到自己湿透的T恤黏在身上,胳膊和腿都是潮乎乎的感觉。虽然去过了不知道多少次西湖,但是却一次没有上过雷峰塔,每次有各种各样的原因:后建的不想去,太燥了不想去,门票太贵不想去。所以我选了用这张雷峰塔的照片做封面头图,希望日后有机会就去看看吧! * * * 人生没有那么多的七年,杭州占了我一个,所以肯定是舍不得离开的。但种种我说不出来的原因让我留不下来,非要有个原因,还是用时间来当做借口吧!想不出其它更多的,就在即将离开的时候随手写了这些。 > _2024 夏初 凌晨_ > > _杭州钱塘_ ![2024-12-13T03:29:54.png](https://banzhuanriji.com/usr/uploads/2024/12/1042126109.png) [照片来自Unsplash](https://unsplash.com/photos/brown-and-black-temple-surrounded-by-green-trees-during-daytime-5UjoDKlGETs) * * * ### 评论 提交你的评论 ## Windows 11 BIOS Access # [安装/升级Windows11之后不能进入BIOS的问题](https://banzhuanriji.com/) _2024-04-12 10:09_ _·_ [Windows](https://banzhuanriji.com/category/windows/) 兴高采烈的体验了Windows11,惊奇的发现LOL帧率比WIN10高很多,也很稳定,但是发现了一个问题:开机之后电脑始终黑屏,然后2-3秒进入系统,中间没有BIOS的启动页面。 试了试,各种热键按烂了都进不去BIOS,而且用了下面的所有方法: 1. 开机的时候疯狂按 DEL ,F1-F12 ,都进不去 2. 尝试进入 高级启动,不可进入,重启直接进桌面 3. 尝试 重置此电脑,直接重启开始提示初始化失败 4. 拔掉所有硬盘开机,直接一直黑屏,不会提示没找到启动盘 5. 关掉快速启动 。我的机器本身就没有快速启动选项,但是我依然通过 cmd 关掉了,解决不变。 6. 长按开机启动,无效 7. 开机状态按住 shift 进行重启,无效 唯一没有尝试的就是扣电池,因为我的主板比较小,电池在显卡下面,机箱也有点小,所以显卡非常非常难拆… 搞了好久没搞好,准备叫人上门了。不过周一上班的时候在v2问了一下,被告知是DP的固件的问题… 解决方案: 1. 使用HDMI链接显示器,进入BIOS开启CSM 2. 升级DP固件,具体点击 [https://www.nvidia.com/en-us/drivers/nv-uefi-update-x64/](https://www.nvidia.com/en-us/drivers/nv-uefi-update-x64/) 进行下载升级。期间你的屏幕可能会黑几次,请等待升级完成几块,然后你就会发现熟悉的BIOS欢迎页面又回来了,并且可以直接进入BIOS。 DP固件升级适用于下列显卡 ``` NVIDIA TITAN Series: TITAN X (Maxwell), TITAN X (Pascal), TITAN XP GeForce 10 Series: GeForce GT 1030, GeForce GTX 1050, GTX 1050Ti, GTX 1060, GTX 1070, GTX 1070Ti, GTX 1080, GTX 1080Ti GeForce 900 Series: GeForce GTX 950, GTX 950Ti, GTX 960, GTX 970, GTX 980, GTX 980Ti GeForce 700 Series: GeForce GTX 745, GTX 750, GTX 750Ti Quadro Series: Quadro Maxwell and Pascal products may be impacted. For support and additional details, contact OEM/Channel partner. If further assistance is required, visit //support.nvidia.com. ``` [Windows11](https://banzhuanriji.com/tag/Windows11/) · [BIOS](https://banzhuanriji.com/tag/BIOS/) · [解决方案](https://banzhuanriji.com/tag/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/) · [显卡](https://banzhuanriji.com/tag/%E6%98%BE%E5%8D%A1/) · [DP固件](https://banzhuanriji.com/tag/DP%E5%9B%BA%E4%BB%B6/) * * * ### 评论 提交你的评论 ## Android Sandbox Overview # [Android 应用沙盒浅析](https://banzhuanriji.com/) _2022-03-04 11:30_ _·_ [android](https://banzhuanriji.com/category/android/) 其实这是一个存在很久的概念,只是近几年Android开发者才开始适配。他如同Linux和ios那样,应用单独储存却又可以互相交互。下面就来说一下这其中有什么 ## 1\. 沙盒 首先看官方的解释 > Android 平台利用基于用户的 Linux 保护机制识别和隔离应用资源,可将不同的应用分隔开来,并保护应用和系统免受恶意应用的攻击。为此,Android 会为每个 Android 应用分配一个独一无二的用户 ID (UID),并让应用在自己的进程中运行。 > > Android 会使用该 UID 设置一个内核级应用沙盒。内核会在进程级别利用标准的 Linux 机制(例如,分配给应用的用户 ID 和组 ID)实现应用和系统之间的安全防护。默认情况下,应用不能彼此交互,而且对操作系统的访问权限会受到限制。如果应用 A 尝试执行恶意操作(例如在没有权限的情况下读取应用 B 的数据或拨打电话),系统会阻止此类行为,因为应用 A 没有相应的默认用户权限。这一沙盒机制非常简单,可审核,并且基于已有数十年历史的 UNIX 风格的进程用户隔离和文件权限机制。 首先我们要来简单说一下 [SELinux](https://source.android.com/security/selinux?hl=zh-cn) 的概念。SELinux就是Security-Enhanced Linux(安全增强型Linux), [https://github.com/SELinuxProject/selinux](https://github.com/SELinuxProject/selinux) 。Android 使用SELinux对包括root/su在内的所有进程进行控制强制访问权限(MAC,mandatory access control)。 下面来说一下,各个Android版本之间的应用间保护机制: - 5.0 Android只区分了系统APP(pre-app不包括在内)和第三方APP的区别,系统使用MAC将二者分离开来,但是两种APP在相同的SELinux环境中运行 - 6.0 Android支持了跨用户边界隔离应用。并且对应用主目录上的默认 DAC 权限从 751 更改为 700,这里的权限请看(权限)\[../权限\] - 8.0 中,所有应用都设为使用 `seccomp-bpf` 过滤器运行,该过滤器可限制允许应用使用的系统调用,从而增强应用/内核边界的安全性 - 9.0 中,targetSdkVersion >= 28 的所有非特权应用都必须在不同的 SELinux 沙盒中运行,并针对各个应用提供 MAC。这种保护机制可以提升应用隔离效果,防止替换安全默认设置,并且(最重要的是)防止应用的数据可让所有人访问。 - 10.0 中,文件管理的权限甚至有限,不可以直接访问应用数据文件。APP不可以直接访问 `/sdcard/DCIM` 文件夹,不过APP保留了访问媒体路径的方法。 ## 2\. 沙盒内容分享 ### 数据文件/二进制文件 : content provider 不多赘述 ### 物理媒体文件 :储存 Google推荐使用 `MediaStore` 进行媒体文件储存,读取时使用 `MediaStore.Download` 读取。 注意,这里的APP的intent必须使用 `ACTION_OPEN_DOCUMENT` 属性。 Google 强调新APP需要使用分区储存,APP在自己data文件下储存内容即可,使用MediaStore进行媒体文件共享。如果你实在需要访问外部数据(之后的高版本系统可能被禁),那么你需要首先判断 ` Environment.getExternalStorageState()` 的返回状态,当返回 `MEDIA_MOUNTED` 时,你可以在外部空间进行读写。返回 `MEDIA_MOUNTED_READ_ONLY` 时,你只可以进行读取。 共享集合空间的文件访问推荐使用MediaStore、MediaProvider进行适配。 ## 其他 ### 权限 r=读取属性  //值=4 w=写入属性  //值=2 x=执行属性  //值=1 7=4+2+1 ,5=4+1,3=2+1,6=4+2,0=没有权限 751 = 给file的属主分配读、写、执行(7)的权限,给file的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限 700 依次类推 * * * ### 评论 提交你的评论 ## Git Articles Overview ### 标签 git 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## No Content Available ### 标签 23321 下的文章 ## 没有找到内容 ## Typecho Articles ### 标签 typecho 下的文章 - _2024-12-30_[在vercel上部署typecho](https://banzhuanriji.com/server/deploy-typecho-on-vercel.html) - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## Theme Articles Overview ### 标签 theme 下的文章 - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## Theme Articles ### 标签 主题 下的文章 - _2025-03-07_[在final中添加评论](https://banzhuanriji.com/theme/add-comments-in-theme-final.html) - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## Final Articles and Themes ### 标签 final 下的文章 - _2025-03-07_[在final中添加评论](https://banzhuanriji.com/theme/add-comments-in-theme-final.html) - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## GitHub Articles ### 标签 github 下的文章 - _2024-11-07_[final 主题](https://banzhuanriji.com/theme/theme-final.html) ## Git Cherry-Pick Insights ### 标签 版本控制 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Git Cherry-Pick Guide ### 标签 cherry-pick 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Git Cherry-Pick Articles ### 标签 cp 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Git Cherry-Pick Guide ### 标签 分支管理 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Submission History ### 标签 提交历史 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Git Cherry-Pick Insights ### 标签 开发效率 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Command Line Tools ### 标签 命令行工具 下的文章 - _2024-11-06_[深入理解 Git 中的 cherry-pick 操作](https://banzhuanriji.com/git/git-cherry-pick.html) ## Internal Network Penetration ### 标签 内网穿透 下的文章 - _2024-11-06_[内网穿透工具横向对比](https://banzhuanriji.com/server/nps-tools.html) ## Tool Comparison ### 标签 工具对比 下的文章 - _2024-11-06_[内网穿透工具横向对比](https://banzhuanriji.com/server/nps-tools.html) ## Free Meal Packages ### 标签 免费套餐 下的文章 - _2024-11-06_[内网穿透工具横向对比](https://banzhuanriji.com/server/nps-tools.html) ## CPOLAR Tool Comparison ### 标签 CPOLAR 下的文章 - _2024-11-06_[内网穿透工具横向对比](https://banzhuanriji.com/server/nps-tools.html) ## Internal Penetration Tools ### 标签 i996 下的文章 - _2024-11-06_[内网穿透工具横向对比](https://banzhuanriji.com/server/nps-tools.html) ## Antipode Articles ### 标签 对跖点 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Geography Articles ### 标签 地理学 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Antipode Calculations ### 标签 经纬度计算 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Earth's Antipodes Articles ### 标签 地球另一端 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Online Tools ### 标签 在线工具 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Life Exploration Articles ### 标签 生活探索 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Google Earth Articles ### 标签 Google Earth 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## Southern and Northern Hemispheres ### 标签 南北半球 下的文章 - _2024-11-06_[对跖点](https://banzhuanriji.com/study/antipode.html) ## ADB System App Guide ### 标签 adb 下的文章 - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## Android Development Articles ### 标签 android 下的文章 - _2025-03-16_[Android实时通话技术解析](https://banzhuanriji.com/android/android-real-time-call.html) - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## MIUI Articles ### 标签 miui 下的文章 - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## App Uninstallation Articles ### 标签 卸载 下的文章 - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## Root Access Articles ### 标签 root 下的文章 - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## Pre-installed Software ### 标签 预装软件 下的文章 - _2024-11-06_[adb卸载/恢复系统app](https://banzhuanriji.com/android/3.html) ## Android Photo App Guide ### 标签 相机功能 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## Image Processing Guides ### 标签 图像处理 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## User Experience Articles ### 标签 用户体验 下的文章 - _2025-01-29_[互联网没有DELETE](https://banzhuanriji.com/server/there-is-no-delete-on-internet.html) - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## Android Photo App Guide ### 标签 Camera2 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## CameraX Development Guide ### 标签 CameraX 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## Android Intent Articles ### 标签 Intent 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html) ## Android Photo App Guide ### 标签 预览截图 下的文章 - _2024-11-09_[Android第三方APP拍照开发指南](https://banzhuanriji.com/android/android-app-taking-photo-guide.html)