Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程

电子书不仅要下载可看,还要有书签,封面,简洁,作者,出版社等元数据帮助记忆和管理,否则,下载了一堆没法查找和没下载差不多!再加上世界上最大的电子书图书馆 Zlibrary ,这里几乎能找到所有的电子化图书!Calibre 和 Zlibrary 结合起来使用,就可以创建结构化的电子图书馆!本文将介绍Calibre 的使用,刮削,图书管理,web 界面的图书管理,以及Zlibrary 的使用。 Calibre 介绍 calibre 是一款功能强大且易于使用的电子书管理器。用户评价它 非常出色,是必备之选。它几乎可以帮你完成所有操作,并且比普通的电子书软件更胜一筹。它完全免费开源 ,无论是普通用户还是计算机专家 都能轻松上手。 Calibre 安装 PC 安装 支持平台有:windows macOS Linux Portable 手机安装 Android iOS 官网: https://calibre-ebook.com/download Docker 安装 更多平台Docker安装介绍,请看这里 Hexo Docker环境使用篇 安装docker curl -fsSL https://get.docker.com | sh && systemctl enable --now docker 安装docker-compose mkdir -p /usr/local/lib/docker/cli-plugins curl -SL https://get.daocloud.io/docker/compose/releases/download/v2.1.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/lib/docker/cli-plugins/docker-compose chmod +x /usr/local/lib/docker/cli-plugins/docker-compose 运行bookstack docker compose up -d 查看日志 docker logs -f calibre Calibre PC 管理并刮削电子书 Pc版的Calibre用来做数据库管理,有各种插件支持,是最方便的。 操作指南 Web界面的Calibre作为阅读界面,支持OPDS接口,可以手机访问! PC 版的Calibrez作为电子书导入,转移,和管理的工具更方便! 注意不要同时在web和PC端操作数据库,很容易导致数据库出bug。 虽然pc calibre有数据库恢复功能,大部分时间都可以成功恢复数据库,但是偶尔也有不能恢复的时候! 刮削插件安装 豆瓣刮削插件这里下载安装 Github 官方地址 Github 下载地址 本站自建加速地址 个人网盘加速下载 更新到1.10 如果打不开,多刷新几次! 添加书库 图书刮削 检查完毕就可以点击确认 数据库转移 这里最好建立一个临时书库作为转移和刮削预备用,防止意外崩溃导致数据库损坏或丢失! 你可以和你的好友之间共享或者转移某个书库。 图书太多,刮削太耗时间,合作刮削建立书库才是正途! Calibre数据库恢复 自动生成txt小说文本目录 很多时候,下载的TXT 电子小说没有目录,怎么办?Calibre 可以搞定,正则表达式自动生成目录! 第一步:导入书籍 在菜单中选择添加书籍 第二步:转换书籍 在结构检测中修改正则表达式以适配中文目录 //*[((name()='h1' or name()='h2') and re:test(., '\s*((chapter|book|section|part)\s+)|((prolog|prologue|epilogue)(\s+|$))', 'i')) or @class = 'chapter'] //*[name()='h1' or name()='h2'] 适配中文,修改后如下图。 //*[re:test(., "^\s*[第卷][0123456789一二三四五六七八九十零〇百千两]*[章回幕部节集卷].*", "i")] 修改为后点击确定,然后Calibre 就会开始转换书籍。 另一种实现方式 使用calibre生成txt文档目录 calibre-douban 插件 必装插件!使用 豆瓣 来刮削电子图书,中文图书识别更准确! Github: https://github.com/fugary/calibre-douban Calibre douban metadata download plugin. Based on https://book.douban.com web pages. Calibre插件 最近在使用calibre-web管理电子书,不过很多时候还是需要用到Calibre桌面版软件,批量管理,编辑电子书等功能,在calibre-web上已经使用calibre-web-douban-api搜素豆瓣元数据,但是桌面版Calibre软件缺没有办法使用,不过calibre可以使用插件,而且是使用python开发,因此可以把calibre-web-douban-api改造一下包装成calibre插件,简单元数据插件还是比较容易的 安装方法 下载地址:NewDouban.zip 从release页面下载zip包,然后再calibre中安装为插件即可。 alibre-douban是Calibre电子书软件的豆瓣元数据插件 下载地址 项目地址:https://github.com/fugary/calibre-douban 下载地址:https://github.com/fugary/calibre-douban/releases/latest/download/NewDouban.zip 代理下载:https://ghproxy.com/https://github.com/fugary/calibre-douban/releases/latest/download/NewDouban.zip 从release页面下载zip包,然后再calibre中安装为插件即可。 升级内容 删除了一些无用代码,另外增加功能: 增加gzip支持,有可能提升一点速度 增加随机毫秒延迟,减少被403的几率 增加Cookie输入框,可以填入浏览器登录后的Cookie,减少403 配置随机延迟 默认已开启随机延迟,也就是在并发请求详情数据的时候随机sleep一定的毫秒数,可以关闭: 参考代码 def random_sleep(self, log): random_sec = random.random() / 10 log.info("Random sleep time {}s".format(random_sec)) time.sleep(random_sec) Cookie配置 有时候可能我们的IP已经被拦了,这时可以自己登录豆瓣网站,然后把Cookie复制出来填进插件配置中。 IP被拦的错误如下: 有异常请求从你的 IP 发出,请 登录 使用豆瓣 用Chrome或者Edge浏览器打开https://www.douban.com,点击【登录】进入登录页面,登录成功之后,按F12打开开发者工具: 从Network,找到Doc类型,随便点击一个豆瓣的网址,进入Headers,找到Request Headers里面的Cookie字段,如图: 如果是中文版: 从网络,找到文档类型,随便点击一个豆瓣的网址,进入标头,找到请求标头里面的Cookie字段,如图: 找到Cookie:后面的部分,复制后面的内容,不包含Cookie:。 到Calibre插件配置页面填入Cookie: 然后就可以用用户的身份查询,一般是可以解决403问题。 常见错误 如果又遇到查询失败,可能是这个错误 …你访问豆瓣的方式有点像机器人程序。为了保护用户的数据,请向我们证明你是人类: 因为使用了Cookie,可以在浏览器中自己点击证明一下,再在calibre中重新查询即可。 Calibre Web 管理 talebook 最推荐的网络图书界面 Github Dockerhub Tips: 国人开发的,个人感觉更适合作为图书管理的界面 Compose 安装示例 talebook: image: talebook/talebook container_name: talebook hostname: talebook restart: always ports: - 90:80 volumes: - ${USERDIR}/talebook/data:/data environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} networks: public_access: aliases: - talebook CalibreWeb Github technosoft2000/calibre-web linuxserver/docker-calibre-web Dockerhub linuxserver/calibre-web Docs For docker-calibre-web Calibre相关的Docker很多,这是其中界面很漂亮的一个版本 注意这个Docker安装需要访问Github下载相关文件!注意你的网络是否正常 视频详细Calibre web讲解 教程视频作者是账户未命名 它的B站账号似乎没了,就放上youtube 统一视频地址! 说明一下,此账号不是博主! 网盘观看下载地址 Calibre 私人书库搭建教学!藏书、漫画、听书,在线阅读+格式转换 上面 Calibre 教程相关附件 相关命令 cat /etc/passwd | grep root [用户名] 刮削器不能使用的解决方法:https://fugary.com/?p=213 Compose 安装示例 linuxserver 的维护版本 默认登录密码: Username: admin Password: admin123 。创建Docker后,请及时修改默认密码! --- version: "2.1" services: calibre-web: image: linuxserver/calibre-web:latest container_name: calibre-web environment: - PUID=1000 - PGID=1000 - TZ=Europe/London - DOCKER_MODS=linuxserver/mods:universal-calibre #optional - OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional volumes: - /path/to/data:/config - /path/to/calibre/library:/books ports: - 8083:8083 restart: unless-stopped docker run -d \ --name=calibre-web \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Europe/London \ -e DOCKER_MODS=linuxserver/mods:universal-calibre `#optional` \ -e OAUTHLIB_RELAX_TOKEN_SCOPE=1 `#optional` \ -p 8083:8083 \ -v /path/to/data:/config \ -v /path/to/calibre/library:/books \ --restart unless-stopped \ lscr.io/linuxserver/calibre-web:latest 原作者精力不够,不再维护下面这个版本,请使用上面 linuxserver 维护的版本! calibre: image: technosoft2000/calibre-web container_name: calibre hostname: calibre restart: always volumes: - ${USERDIR}/Calibre/web/config:/calibre-web/config - ${USERDIR}/Calibre/web/kindlegen:/calibre-web/kindlegen - ${USERDIR}/Calibre/web/app:/calibre-web/app - ${USERDIR}/Calibre/books:/books ports: - 8283:8083 env_file: - .env environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} - USE_CONFIG_DIR=true - SET_CONTAINER_TIMEZONE=true Calibre PC 内容服务器 Calibre PC 端自带内容服务器,开启方法如下 开启后,就可以从下图所示的地址,在局域网中访问电子图书馆了 Zlibrary 使用 Zlibrary 简介 Z-Library(简称Z-Lib,前身为BookFinder)是一个影子图书馆和开放获取文件分享计划,用户可在此一网站上下载期刊文章以及各种类型的书籍。根据Z-Library的说法,截至2022年6月12日,其共收录了10,456,034本书和84,837,646篇文章[1]。Z-Library在其电子书搜索页面上宣称自己是“全球最大的数字图书馆”[2],并在文章搜索页面上称自身是“全球最大的科学文章存储库”[3]。它原是创世纪图书馆的镜像网站,并从该图书馆获得大部分馆藏。但它的一些馆藏由用户自行上载,并且不为创世纪图书馆所收藏[4]。该平台公开网域已于2022年11月3日遭到美国政府屏蔽。 ZLibrary虽然是一个俄国网站,但它拥有16种语言版本可供选择,下滑至网页末尾,即可切换语言。 ZLibrary访问地址: https://zlib.cydiar.com/ https://z-library.ec/ https://zh.z-library.sk/ https://bk.hallowlib.org/ 国内备用网址 http://zlibrary24tuxziyiyfr7zd46ytefdqbqd2axkmxm4o5374ptpc52fad.onion/ 洋葱路由地址 Zlibrary 简要 FAQ 截取用户最关心的几条介绍如下 我不能下载任何书籍!根据系统,我的IP地址已经达到每日下载的上限。 我们建议创建一个帐户并登录以避免此问题。 如果您没有登录,下载限制是根据您的设备 IP 地址计算的。 互联网提供商通常会为多个设备使用共享 IP 地址,在这种情况下,下载限制也会在这些设备之间共享。 我可以使用 电报机器人 下载多少本书? 使用我们的机器人,除了每日站点的限制外,您还可以下载更多书籍。例如,如果您的每日限制为下载 10 次,并且您已经使用了它,那么您可以通过机器人额外下载 10 本书(每天总共下载 20 次)。 或者您可以直接从机器人上下载这 20 本书。 绑定个人电报机器人 在下面页面最下方,根据指引操作 https://zh.z-library.sk/profileEdit/others 操作成功后可以看到如下操作指引: Hello, xxx! Welcome to your personal Z-Library telegram bot 📚Z-Library is the world's largest e-book library with over 10 million books and 80 million articles. We aim to make knowledge accessible to everyone. 🔹How do I download books via the bot? To find and download a book, just send the title of the book, author’s name, publisher or ISBN/ASIN number to the bot and click on the appeared link. You can also specify language and preferred file format. For example, “war and peace pdf” or “oscar wilde chinese epub”. 🔹How many books can I download? Using the bot, you can download more books in addition to your daily download limit on Z-Library website. For example, if your daily limit is 10 downloads, you have 10 extra downloads available in the bot (20 downloads in total). Or you can only use the bot and download 20 books from here. *Keep in mind that by downloading a book from the bot first, you are spending your daily website limit. 🔹How do I save files from Telegram? On Desktop: right click on the file > choose “Save as” option. On iOS: first open the file > use the Share button (upper right corner) > save it wherever you want (Files, iBooks, etc.). On Android: open the file > press the three dots button > choose “Save to Gallery or Downloads”. 🔹Can I share the bot with others? Only you, the bot creator, can use it to search and download books. You can share a link to your bot, in this case bot will prompt any other user to register a personal bot on the Z-Library website. 🔹How can I unlink my Telegram account? You can do this in your library profile on the website. *Be aware that the bot will not work without binding to Z-Library account. ——————- 📧 If you have any issues feel free to contact us via support@z-lib.fm 中文翻译: # Z-Library 个人机器人使用指南 您好!欢迎使用您的专属Z-Library电报机器人 📚 Z-Library是全球最大的电子图书馆,拥有超过1000万本书籍和8000万篇学术文章,致力于让知识触手可及。 ## 🔹 如何通过机器人下载书籍? 直接向机器人发送书籍标题、作者名、出版社或ISBN/ASIN编号,机器人会返回下载链接。 您可指定语言和文件格式,例如: 《战争与和平 pdf》 或 《王尔德 中文 epub》 ## 🔹 每日下载限额说明 机器人下载额度与网站额度叠加但共享上限: - 若网站每日限额10本,机器人可额外下载10本(总计20本) - *注意:通过机器人下载会同步消耗网站额度 ## 🔹 文件保存指南 ▫️ **电脑端**:右键文件 > 选择"另存为" ▫️ **iOS系统**:打开文件 > 点击右上角分享按钮 > 保存至"文件"/iBooks等应用 ▫️ **安卓系统**:打开文件 > 点击三点菜单 > 选择"保存到相册或下载目录" ## 🔹 机器人共享规则 此机器人仅限创建者本人使用。若分享机器人链接,其他用户需在Z-Library官网注册个人机器人。 ## 🔹 解绑Telegram账户 请通过官网个人资料页解绑。*注意:未绑定账户将导致机器人失效* —————— 📧 如有任何问题,请联系客服邮箱:support@z-lib.fm Zlibrary 图书下载 web 搜索 ISBN 搜索 作者搜索 书名搜索 出版社搜索 web 下载 免费用户每日可以在 Web 端下载 10 本电子书。不限制图书大小! web 线上阅读 最好的毛选版本 -> 《毛泽东选集》(毛选1-7:原版五卷+静火+赤旗+草堂) TG Bot 下载 在TG Bot 中,免费用户每日可以下载 20 本电子书!现在图书大小 50 MB 以下。所以大的电子书,web 下载,小的电子书 TG Bot 下载是最佳选择。 书名,作者名,ISBN,等方式都支持。 ISBN 号下载 最推荐的方法 发送一个 ISBN 你可以找到各种不同的版本 有 ISBN 号建议直接发送isbn号,没有再发送书籍名称,使用TG机器人下载比直接从浏览器下载更稳定,方便。可以从浏览器版本找书,在TG Bot中下载书籍,然后使用Calibre 刮削管理下载的书籍。 Calibre ISBN 刮削 注意冒号为英文字符 isbn:9787302518426 只需要一个准确的 ISBN 号,其它信息都可以不填,就可以准确的刮削图书! Zlibrary 书单 一个整理好的书单,可以极大的节约你的时间,扩展你的眼界! 下面是书单相关介绍和推荐。 公开专栏 你可以在这里找到广受好评的书单。 最喜欢的书单 在公开专栏中收藏的书单在这里显示! Zlibrary 书单推荐 下面推荐几个作者认为很好的书单介绍给大家! 计算机系列丛书 数学 英语学习 数学系列丛书 机器视觉 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2025/9/5
articleCard.readMore

IPFS从零开始快速入门教程

IPFS是新时代的去中心化的BT替代者,它可以把资源发布者,存储者区分开!在很多方面,安全性,匿名性等都优于Bittorrent下载。虽然它还很稚嫩,但已经展现出来很多优越性,它已经展现出来新时代共享资源之王的潜质,还不赶快来学习怎么使用它? 前言 其实早在 2020 年(即秒传时代的开端)就已经有贴子推荐 IPFS 作为分享方案了,属于分享账号大封禁之后众多分享技术路线探索中的一支。只是限于当时的 IPFS 仍然处于早期阶段,各种平台等配套设施并不完善,大部分人对其理解也是变种的 BT,没有成功普及,随后和其他路线一样,在秒传的兴起中变得无人问津。 随着 2023 年末期百度开始逐步修复秒传,寻找新路线又重新开始被重视。期间从分卷压缩、专有加密到文件隐写等方法不一而足。这些探索都是值得肯定的,但是另一方面,对于网盘分享领域的诸多问题其实一直没有得到解答,对于炸链现象的解释显得笼统且不精确,由此带来的防炸方案也是五花八门,谁也不能说服谁。 比如,关于【为什么会炸链】这个问题,就有在线解压说、文件名敏感说、账号监控说、玄学说、严格审查说、举报说等;对应的防炸方法也就是分卷压缩/多层压缩、改后缀名、换 IP、以及使用 VeraCrypt 等专业加密程序方案、伪装MP4/图片/二进制转码等文件隐写方案。 对上述问题最终取得突破的是文件隐写方案,但并不是因为证明了隐写方案才是最有效的方案,而是以隐写文件为基础,通过控制变量试验证明了在百度网盘上的举报是【无解】的,进而整体否定了通过改进打包技术来防炸这条路线。(对此问题感兴趣可以点击链接中的文章详细查看) 在这样的情况下,IPFS 方案又逐渐成为了可选项了,尽管当前的 IPFS 仍不能说拥有足够充分的配套设施,但是相比于 2020 年,已经有了一些进步和积累,比如本文第 4 节会谈及的文件托管平台,使得 IPFS 在保留 BT 优点(无法举报)、解决 BT 的某些缺点(低安全性)的同时,在方便性上部分甚至绝对超过了以百度为代表的传统中心化网盘。 本文则是 IPFS 快速上手教程,旨在快速入门 IPFS 的基本操作。详细介绍了 IPFS(星际文件系统)的使用方法、优缺点及其在资源分享中的应用场景。文章首先讲解了 IPFS 的基本操作,包括文件的上传、固定、分享和下载。随后,介绍了 IPFS 本地文件管理和使用托管平台的方法。最后,文章对比了 IPFS 与传统网盘分享方案,提出了分场景使用不同级别分享方案的建议, 分析了 IPFS 作为最终手段,在应对恶意举报问题上的优势。 关于 IPFS 的几个要点: IPFS 上传和下载都不需要公网 IP,也不需要 VPS,但是注意如果挂了梯子【不要开启 TUN 模式,否则你的流量很快就没了】。 IPFS 发布文件需要先固定(类比 BT 的做种),然后可以通过浏览器整合下载。 IPFS 除了自己固定(做种),也可以选择托管平台托管,代为做种。 IPFS 发布的文件大部分都可以直连下载。 先在这里下载 IPFS 客户端并安装: https://docs.ipfs.tech/install/ipfs-desktop/#windows 以下是操作流程的详细说明。 如果上面的链接打不开,或者找不到,可以从下面的备用镜像链接下载() IPFS 直链:https://bafybeifh2jdor3r26x4adskx2rlz33ada64mducx2iq6oa3iqh5ir42zby.eth.sucks?filename=IPFS-Desktop-Setup-0.38.0.exe 以下是操作流程的详细说明。 IPFS 安装 https://github.com/ipfs/ipfs WIndows 平台 https://github.com/ipfs/ipfs-desktop Docker 是的,IPFS 官方提供了 Docker 镜像,支持在容器中快速部署 IPFS 节点或客户端。以下是详细的使用指南: 📦 一、官方 Docker 镜像 1. IPFS 核心节点镜像 镜像地址:ipfs/kubo 2. 主要功能 ✅ 运行完整的 IPFS 节点 ⚙️ 二、Docker 部署步骤 1. 拉取镜像 docker pull ipfs/kubo:latest 2. 运行 IPFS 节点 # 创建持久化数据卷(避免容器重启数据丢失) docker volume create ipfs_data # 启动容器 docker run -d \ --name ipfs-node \ -v ipfs_data:/data/ipfs \ -p 4001:4001 \# P2P 节点通信 -p 5001:5001 \# API 端口(管理节点) -p 8080:8080 \# 网关端口(访问文件) ipfs/kubo:latest 3. 操作节点 # 进入容器 CLI docker exec -it ipfs-node sh # 下载 CID 文件(示例) ipfs get QmacdD9VAm1kb5tsT1NngdStyggcBnPNMdxZCHKrNkDTH9 # 文件会保存到容器的 /data/ipfs 目录(映射到宿主机卷) 🌐 三、通过 HTTP API 下载文件(免 CLI) IPFS 容器提供 HTTP API,可直接从宿主机操作: # 下载 CID 到宿主机当前目录 curl -X POST "http://localhost:5001/api/v0/get?arg=<CID>&output=." \ -o output_file 示例: curl -X POST "http://localhost:5001/api/v0/get?arg=QmacdD9VAm1kb5tsT1NngdStyggcBnPNMdxZCHKrNkDTH9&output=." \ -o download.zip 🔧 四、进阶配置 1. 自定义存储路径 docker run -d \ -v /your/local/path:/data/ipfs \# 宿主机目录映射 ...其他参数同前... 2. 使用 IPFS Cluster(分布式存储) 镜像:ipfs/ipfs-cluster 用途:管理多节点 IPFS 集群,提升文件可用性。 📊 五、Docker 方案 vs 原生安装 特性 Docker 方案 原生安装 部署速度 ✅ 秒级启动(镜像预配置) ⚠️ 需手动安装依赖 隔离性 ✅ 容器隔离,不污染宿主机环境 ❌ 直接修改系统 持久化存储 ✅ 通过卷映射实现 ✅ 直接管理文件 多版本共存 ✅ 可同时运行不同版本 IPFS 节点 ❌ 困难 资源占用 ⚠️ 略高(容器开销) ✅ 更低 💡 六、常见问题 Q1:如何查看已下载的文件? 文件保存在容器的 /data/ipfs 目录(映射到宿主机卷)。 docker volume inspect ipfs_data 查看宿主机存储路径。 Q2:如何重启节点? docker restart ipfs-node Q3:如何更新镜像? docker stop ipfs-node docker rm ipfs-node docker pull ipfs/kubo:latest # 重新运行(使用原有数据卷) docker run ...(参数同前)... ✅ 总结 推荐工具:使用官方镜像 ipfs/kubo 快速部署容器化节点。 核心优势:隔离环境 + 持久化存储 + 一键升级。 适用场景: 开发测试环境 生产环境分布式存储集群 需频繁切换节点的场景 通过 Docker 管理 IPFS 节点,可大幅降低运维复杂度,更多细节参考 IPFS Docker 文档。 固定并分享文件 固定想要共享的文件 在 IPFS 中,每一个文件都有一个独一无二的标识符 CID ,CID 在 IPFS 中对应具体文件,类似于 BT 的磁链,分享 CID 就等于分享文件,只需要知道 CID 即可下载文件。 CID 的示例如下(有两种格式 v0 和 v1,分别以 Qm 和 ba 开头): QmPKhevNWUx89XBU82XF4UYs2xsdxZnG2xPz2uZsA6Yatm bafybeibcr7x6d2bo43ce6xaye6d6aogvbfmeokphpsvjlqv27udl34ads4 目前推荐使用后者。 在配置中的 Import 部分把 CidVersion 参数改为 1 ,然后保存并重启 IPFS 即可。 配置完毕后,就可以开始固定文件了 右键点击上传后的文件,设置固定 固定在本地节点 复制 CID 以发布文件 固定成功后再次点击右键,选择复制 CID ,就可以发布文件了。 可以采用分享链接的方式分享文件,由于默认的公共网关被墙了,在分享前建议修改 IPFS 公共网关。 可用 IPFS 公共网关(随时更新)参考: https://k51qzi5uqu5djx3hvne57dwcotpc8h76o2ygrxh05kck11j6wnhvse8jrfzf2w.ipns.dweb.link/ 在下面的网址可以找到更多的可用公共网关 https://ipfs.github.io/public-gateway-checker/ 设置完成后右键文件-分享链接即可 分享前可以检测一下自己网络的可用性。 此网址可以检查自己的 IPFS 网络的可用性: https://check.ipfs.network/ 下面的 4 个检查得至少满足前 3 个,如果你有公网 IP 则会有第 4 个。 移动本地文件仓库 IPFS 安装以后,默认会在用户路径(C:\Users\你的用户名)下方创建一个名为 .ipfs 的文件夹,用来存放固定的文件,如果 C 盘空间不足,可以选择移动 IPFS 仓库的默认位置。右键任务栏 IPFS 程序的图标,然后选择 Move Repository Location 即可。 根据 CID 下载文件 使用 IPFS 原生下载功能下载文件 下载文件和上传文件是类似的,首先需要导入文件 在弹出的窗口中输入 CID ,可以自行指定文件名 在下载前建议先设置固定,只要固定完成了,文件就一定可以保存到本地,以避免直接下载过程中出现错误。(固定一个来自 IPFS 路径的 CID 可能会需要一定时间,因为要从其他节点拉取文件) 固定完成后点击右键,选择下载: 接下来会使用浏览器的下载功能进行文件下载,先固定后下载或者直接下载这 2 种下载方式,原理都类似于 BT 是 P2P 的,能否下载成功取决于是否有人在做种。 如果安装了 IDM、FDM 等下载软件,也可以使用这些软件接管下载,比如我用的是 FDM : 使用 IPFS 公共网关下载文件 除了类似于 BT 的 P2P 以外,IPFS 还可以采用公共网关创建分享链接的方式分享文件,公共网关本身也是一个 IPFS 节点,但拥有公网 IP ,连接速度较快,可以帮助其他节点下载,具体来说就是用它生成直链,让下载者用这个直链下载,这是比较推荐的 IPFS 分享方式。 IPFS下载链接结构为 网关+CID 示意图如下: 使用这种方式分享的时候下载者不需要软件,用浏览器、IDM 等即可直连下载。 由于默认的公共网关被墙了,在分享前需要修改 IPFS 的公共网关,可以修改为以下网关中的一个: https://ipfs.hypha.coop https://gw.ipfs-lens.dev https://gateway.pinata.cloud https://eth.sucks https://i0.img2ipfs.com https://gw.crustgw.work https://gw.crust-gateway.xyz 按照下图所示设置: 然后右键文件-分享链接即可 其他寻找公共网关的方法: 可以在 Best IPFS Gateway 输入 CID 来搜索更多合适的网关,搜索到以后点击右侧的下载按钮即可。 在下面的网址中可以找到更多的可用公共网关 https://k51qzi5uqu5djx3hvne57dwcotpc8h76o2ygrxh05kck11j6wnhvse8jrfzf2w.ipns.dweb.link/ https://ipfs.github.io/public-gateway-checker/ 使用 IPFS 本地网关下载文件 公共网关本身也是一个 IPFS 节点,经由公共网关访问文件或文件夹 CID 可以理解为由对方代理来连接到 IPFS 网络中的资源,由于这些网关有公网 IP ,速度也比普通的家宽更快,所以通常建议用公共网关访问并下载资源。 但是公共网关也可能面临被恶意举报导致封 CID 的情况,这种时候除了更换其他公共网关,也可以用自己 IPFS 节点的本地网关访问资源,这种访问类似于 BT 是纯 P2P 的,也就是说,即使这个 CID 在所有公共网关上都被屏蔽了,只要你自己不屏蔽这个 CID 就能访问。 在本地的 IPFS 启动后,在浏览器地址栏中输入 CID,后面加上 .ipfs.localhost:8080 ,即可用 IPFS 的本地网关查看并下载文件,示例如下: http://bafybeihon37a3qtxqynvphkt4ebe3hd42tdrfw4gstsadka5yijz3fjbfe.ipfs.localhost:8080 http://127.0.0.1:8080/ipfs/bafybeihon37a3qtxqynvphkt4ebe3hd42tdrfw4gstsadka5yijz3fjbfe/ 这个 CID 对应的是一个 html 文件,因此被浏览器渲染成了网页的样子,按 ctrl+s 可以把这个文件下载到本地查看,对于其他格式资源也是同理,这也就是为什么 IPFS 分享的东西能被浏览器或者 IDM 或者 FDM 等下载器直接下载的原因了。 此外,在安装 IPFS 客户端的情况下,在浏览器地址栏输入: ipfs://bafybeihon37a3qtxqynvphkt4ebe3hd42tdrfw4gstsadka5yijz3fjbfe 也会自动打开刚才的本地网关。 从上面这个例子可以看出,ipfs 某种意义上可以代替 http 来访问互联网中的内容,CID 就是内容的地址,IPFS 的这种特性称为“内容寻址”,也就是不根据 IP 地址而根据内容本身的哈希值来在网络中查找(这点类似于 BT)。 .ipfs.localhost:8080 中最后 4 位数字为本地网关的端口号,通常为 8080,但是有时候也可能变化,此时端口被占用就无法使用,常见原因比如酸奶网盘与 IPFS 客户端冲突等,如果发现本地网关无法使用,如下图所示: 此时需要查看本地节点的 .ipfs 仓库中的 config 文件,右键用记事本打开后,下图中箭头所指的四位数字就是你的本地网关端口号,使用这个端口号即可。 使用 FDM 批量下载 IPFS 链接 在安装此油猴脚本的情况下,可以使用 FDM 来批量下载。 FDM (Free Download Manager) 是一款完全免费的下载软件,不会存在破解版 IDM 可能的弹窗问题,这里使用 FDM 来说明如何批量下载已复制的下载链接。 首先在这里下载最新版的 FDM 并安装: https://files2.freedownloadmanager.org/6/latest/fdm_x64_setup.exe 安装完成后,复制链接,点右上角的三根横线,从剪贴板粘贴链接,选择下载路径进行下载即可。 IPFS 其他细节操作 清理非固定文件释放磁盘空间 当 IPFS 的本地文件过多,可以选择任务栏图标中的 Run Garbage Collector 进行清理,这个操作会清理所有没有在文件选项卡中显示的文件释放磁盘空间。 PFS 辅助油猴脚本 此油猴脚本用于自动识别网页中的 IPFS 链接和 CID,提供一键复制、网关测速和批量操作功能。 安装后鼠标移到 CID 上可以弹出悬浮窗。 在右下角显示批量复制 CID 、文件名、下载链接按钮,浮窗可以收起。 IPFS 测速器功能,可以测试各大网关能否访问(功能类似IPFS分享助手),内置常见网关,支持自定义网关。 Github:IPFS CID Copy Helper https://github.com/cenglin123/ipfs-cid-copy-helper IPFS 分享助手 IPFS 分享助手是本人开发的一个小程序,用来简化 IPFS 分享的流程,主要功能有: CID 批量计算、文件批量导入、CID 批量拉取、CID 格式转换、分享链接批量生成、批量固定到 Crust 等分享相关的一站式功能。 此处仅简单介绍,具体用法请参阅 GitHub 开启 DHT 加速 2024-10-09 更新:实际测试,DHT 加速会显著增加 IPFS 的资源消耗,并且相比于其消耗的资源来说对效率的提升较为有限(氪佬随意),在使用 Crust 等托管平台而非自己做种时,不建议开启 DHT 加速。 在上传之前可以在配置选项卡中如下修改配置信息,开启 DHT 加速,DHT 加速可以提高连接节点数量,增加效率。 "AcceleratedDHTClient": true, 关于分享文件的可用性 IPFS 类似于磁链,也需要有人“做种”,需要有人固定文件(做种),并且在线,才可以下载。 可以在这个网址中检测 CID 是否可用: https://explore.ipld.io/ 也可以使用 IPFS 分享助手进行测速来确认文件是否可用。 使用 IPFS 托管平台托管文件 由于 IPFS 类似 BT 属于去中心化的分享方式,假如没人开机做种,就会导致后续的下载者没有办法下载。这种时候可以使用托管平台托管文件,代为“做种”。用法类似于网盘,但是分享不通过分享系统,而是采用 CID 进行,因此没有审核、举报系统,不管文件保存在哪里,只要 CID 匹配就可以下载到文件。 IPFS 的托管平台有很多,和 IPFS 的网关不同,这些托管平台大多数都没有被墙可直连,比如支付加密货币把文件托管给矿工的 Crust 以及基于 Crust 开发的 酸奶网盘 、以及目前免费的 Aleph。 使用酸奶网盘托管文件到 Crust 平台 2025/05/19 更新:由于 Crust 网络现在状态不佳,本节部分的内容仅供参考。 本节内容是一个操作流程,旨在快速上手,只需要按照流程操作即可,具体的原理及解释详见 4.3 节。 以下正式开始 打开 https://yoghourt.cloud/ 酸奶网盘的官网,下载最新版酸奶网盘并安装,或者在这里下载 https://gw.crustgw.work/ipfs/bafybeiaeq2sblmnjvs27qr7romzc6ryqz5qiy6ng2ltrs7tgxux7rdeqh4?filename=yogurt-cloud-client-0.1.4-setup.exe 当右下角显示 IPFS 连接成功,即可拖入上传文件 然后等待上传完毕 上传完毕后等待至副本数大于 0 然后打开 IPFS 分享助手: https://k51qzi5uqu5dh1ts2qvcw3069src00zyjw0qmwdkb102k8q4ft8bztw75iwi25.eth.sucks/ 在右下角的计算器中拖入那个文件,然后计算 CID 后点击【填写CID和文件名到主输入框】, 填写后点击【下载网关测速】, 测速完成后点击【生成下载链接】,即可得到能直接链接到资源的链接了, 再点击【复制下载链接】,即可复制链接并发布,下载的时候只需要打开这个链接,用浏览器或 IDM 就能下载。 如果某个链接不能用了,把链接中的 CID (即 baf…6cwe 这样的字符串) 复制后填入图中的位置,重复 2 3 4 步骤即可。 下面是最终得到的链接,可以直接在浏览器中打开使用: [img]https://i0.img2ipfs.com/ipfs/bafkreibm2z34rvt5qhbiz3cv4524skjefg2mard7h4i7stqinpi5sl6cwe?filename=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%88%86%E4%BA%AB%EF%BC%9F.jpg[/img] 这是刚才上传的图 使用 aleph.im 进行托管 使用 aleph 可以实现类似于 BT 的做种后离线的方式托管给 IPFS 矿工,就目前而言(2025/05/19),效果比 Crust 更好。 详见这 2 篇仓库文章: [技巧分享] [IPFS] 通过aleph.im网络存储固定ipfs文件 [技巧分享][IPFS] Aleph拉取教程入门版 IPFS托管网页(上面的访问不了可以看这个) [技巧分享] [IPFS] 通过aleph.im网络存储固定ipfs文件 [技巧分享][IPFS] Aleph拉取教程入门版 南+ [技巧分享] [IPFS] 通过aleph.im网络存储固定ipfs文件 Aleph 分享助手下载 https://github.com/cenglin123/aleph-managerGUI 使用托管平台搭配 IPNS 托管文件夹 接下来说明一些仅在使用托管平台时推荐的分享技巧。 我们可以使用 CrustFiles 或者 酸奶网盘 、Aleph 等把文件分别托管 (又称上链) 到 IPFS 网络中,然后通过本地 IPFS 客户端聚合文件以进行管理。 具体来说,先把文件上传到t托管平台进行托管,然后再把这些已经托管的文件的 CID 导入并聚合到本地 IPFS 的一个文件夹中(不必固定到本地,这样就不会占用本地空间),这样一来,本地做种只需要做种聚合文件夹即可,使得文件夹中的内容能被 IPFS 网络访问,内容则交由托管平台保存,不占用本地空间。 也因此,在使用托管的情况下 IPFS 的做种比 BT 更轻量,希望大家可以积极帮助他人做种,只需要把别人的文件夹 CID 导入但不固定在本地即可(注意不要改动文件路径中的文件名,否则会导致 CID 发生变化,想重命名进行管理的话,可以新建一个文件夹把东西整个丢进去),如此可以帮助他人保持文件夹路径的可用性。内容托管在矿工那里,做种不消耗自己的流量,也可以减少被运营商查水表的可能性。 由于 IPFS 内容寻址的特性,不同内容的 CID 都是不同的,假如你的内容需要频繁更新,每次都要改链接无疑很不方便。此时可以把聚合文件夹发布到 IPNS,把文件夹的 CID 与 IPNS 地址相关联。 和 CID 不同, IPNS 地址是不变的,特别适合需要持续更新的内容,其内容需要使用你节点的私钥才能更改,可以当成自己的一个“域名”来使用。这个“域名”也是去中心化的,保存在 DHT (分布式哈希表)中,只要你的节点每天至少上一次线,就可以保证这个“域名”可用,和传统的 HTTP 域名不同, IPNS 即使关机也不会造成“域名”无法访问。(如果你有普通域名的的话,可以把 CID 和域名关联起来) 下面是我用 IPNS 发布的 IPFS 分享助手软件,其中 k51…wi25 就是 IPNS “域名”,.eth.sucks 则是子域名形式的公共网关。 https://k51qzi5uqu5dh1ts2qvcw3069src00zyjw0qmwdkb102k8q4ft8bztw75iwi25.eth.sucks 上面是子域名形式的链接,路径形式的链接则应该如下: https://eth.sucks/ipns/k51qzi5uqu5dh1ts2qvcw3069src00zyjw0qmwdkb102k8q4ft8bztw75iwi25 用本地网关进行访问时,子域名形式和路径形式的链接如下: http://k51qzi5uqu5dh1ts2qvcw3069src00zyjw0qmwdkb102k8q4ft8bztw75iwi25.ipns.localhost:8080 http://127.0.0.1:8080/ipns/k51qzi5uqu5dh1ts2qvcw3069src00zyjw0qmwdkb102k8q4ft8bztw75iwi25 接下来我新生成一个名为 test 的 IPNS 密钥用来发布其他文件夹, IPNS 密钥的地址是固定的,这样每次更新内容后只需要把更新后的文件夹 CID 重新发布一次 IPNS 即可,不用更新链接。 点击发布,然后稍作等待: 复制上面的地址就可以发布了,由于 DHT 网络的广播需要时间,让 IPNS “域名”生效可能需要半个小时至一个小时左右,发布后稍作等待即可。 效果如下: https://ipfs.io/ipns/k51qzi5uqu5dk5cbbjykfthqkz6qh9r98zauauz2n6j843rv3e93fgbfh4abiu 4everland.org 这样的平台来免费托管 IPNS 地址,具体可以参考这篇文章的第 3 节。 关于更多托管平台:盘点主流IPFS托管平台:功能、限制与推荐指数全面对比 IPFS 本地文件管理:把 IPFS 当作网盘来用 IPFS 能否像网盘那样“转存”? IPFS 全称“星际文件系统”,既然是文件系统,自然是能够进行文件管理的,使用时的手感非常类似秒传链接。 具体来说,就是把 CID 导入到 IPFS 中但不固定到本地节点,这样就能在不占用本地空间的情况下进行文件管理了。 可以给大家看一下我的某个 IPFS 仓库,注意右上角的显示大小和实际占用大小。 在这样的情况下,CID 也就可以类比百度网盘的秒传链接了,本地的 IPFS 节点则类比一个网盘客户端。而导入 CID 的过程自然就是“转存”了。不过这里的转存我加了双引号,是因为虽然很类似,但是 IPFS 节点导入 CID 和网盘转存还是有区别的。 IPFS 是一个去中心化的系统,由众多节点组成,就像下面这张图里一样,每个节点都是网络的一部分,彼此平等,不存在客户端和服务端的区别,或者说节点既是客户端也是服务端。 这一点熟悉 BT 的朋友应该能理解是什么意思,因为 IPFS 的底层大量地借鉴了 BT。 IPFS 的默克尔树与虚空做种 不过 BT 并不能对一个你没有的文件做种,但是 IPFS 可以。 IPFS 为什么能做到呢?这里就必须提一下 IPFS 对于文件的处理方式了——默克尔树(Merkel Tree)(严格来说是 Merkel DAG ,不过这里为了不干扰理解就叫默克尔树了) 大家不要觉得这个词高大上,这个东西并不是什么很高深的东西,其实就是在 IPFS 中,文件会被拆成小块进行保存和传输,而这些小块由一个像树一样的结构被组织起来进行管理,因为是一个叫做默克尔的人申请的专利,所以叫做默克尔树。 这个结构中每个小块像叶子一样长在树上,所以也叫做“叶子节点”。 每个叶子都有自己的独特且唯一的身份牌,这样才能证明你位于树的哪个位置,对于 IPFS 而言,就是 CID(通过哈希值算得)。 IPFS 下载文件也就可以理解为是根据树的结构在整个 IPFS 网络中找对应小块,然后把它们组装起来的过程。 这些块具体由谁保存并不重要,只要 IPFS 网络中存在这个 CID 所对应的块,即使相隔很远,也能通过多次节点跳转找到。 一个 CID 只能对应一个独立的文件块,并不能表示这个树长什么样,这个树的结构其实被保存在你本地的 IPFS 节点的 DHT (分布式哈希表)中。 相比于保存整个文件,DHT 中只保存了每个 CID 所对应的树的关系,纯文本,因此非常的轻量。 下载的时候,照着树按图索骥,拿全所有的块即可组装出完整的文件。 而这个默克尔树也正是 IPFS 能做到 BT 做不到的“虚空做种”的理由,因为做种只需要给出 CID 对应的树结构,做种者实际上并不需要保存文件块本身,仅保存文件的 CID 和树结构,提供一个指路的效果即可,具体的文件块完全可以交给网络中的矿工保存。 批量“转存”文件到本地 IPFS 节点 对于已经存储在 IPFS 公网中的 CID,是可以被任意新加入的 IPFS 节点访问的,具体来说,按下图操作即可把一个 CID 连同其树结构,一起导入到本地 IPFS 节点中。 使用 IPFS 分享助手的情况下,点击右下角的 【WebUI】 按钮可以打开上述界面。 这种情况并没有导入数据,所以如果要进行下载,需要右键文件,然后点击【设置固定】,选择固定到【本地节点】才能保存文件数据到本地节点(也就是矿工所做的事情)。 不过,假如需要导入的 CID 很多就很不方便了。 这时可以使用 IPFS 分享助手的批量导入功能。 首先在 Crust 或者酸奶网盘确认文件确实已经上链(如果没有上链,导入会卡住,因为要在 IPFS 网络中查找) 然后通过各种办法收集到这些要导入文件的 CID 以及文件名,可以通过油猴脚本在网页或 IPFS 文件夹页面中复制,如果有本地文件的话,也可以通过 IPFS 分享助手的 CID 计算器算出 CID 并填写到主输入框中,然后点击导入。 具体如下图所示: 然后点击【WebUI】可以进行确认 IPFS 程序有一个小问题,即使在配置中设置了默认启用 cidv1,新建文件夹时依然是 cidv0,这里有个权宜之计是先单独从 IPFS 路径导入一个 cidv1 格式的空文件夹,然后再把文件导入到里面。 cidv1 格式的空文件夹 CID 如下 bafybeiczsscdsbs7ffqz55asqdf3smv6klcw3gofszvwlyarci47bgf354 注意文件名会影响文件夹 CID 的计算,需要注意保持文件夹下文件的文件名不变才能保证文件夹 CID 正确,文件夹自身的名字则无所谓,这点在进行文件管理时需要注意。 实在求稳的话,可以新建一个文件夹把所有内容原样丢进去,然后重命名最上层的文件夹进行文件管理。 IPFS 轻量化做种:通过P2P网络辅助公共网关发现文件 在 IPFS 节点中导入 CID 完毕后就可以开始做种了,文件保存在矿工手里,因此流量也由矿工承担。 如此就可以实现轻量化的做种(本地只是提供一个指路的效果,做了一个结构意义上的种,可以叫做“结构种”,或者中二点叫“虚空种”也行) 这种做种方式尤其适合做种聚合大量文件的文件夹的 CID,由于聚合后文件夹的总大小往往很大(比如 200GB),这种大小的文件夹是很难单独上链被矿工保存的,此时把多个小文件聚合成大文件夹,然后做种这个文件夹的及其下面的文件的 CID ,就可以在不占用本地空间的情况下维持可用性。 并且,更多的 IPFS 节点数量也有助于 IPFS 公共网关更快地发现文件。 有些时候某个 CID 用某个公共网关找不到,但是用 IPFS 分享助手测速或者 IPFS-SCAN 测速以后,这个 CID 就能被该网关找到了。因此测速这个动作,可以理解为向各个公共网关广播询问有没有这个 CID,然后公共网关会就近查找,节点越多查找的速度就越快(有人称这种现象为“预热”)。 也就是说做种的人越多,公共网关就有更高的概率通过询问最近的做种者找到某个 CID,然后通过实际保存了文件块的矿工那里下载实际的文件块。作为查找中转的节点实际上不需要真的持有这些文件块,只要持有文件结构即可,等同于起了一个为公共网关指路效果。 注意前面提到过,CID 本身不能表示树结构,因此做种除了做文件夹自身的 CID,还需要连同整个文件夹的树结构一起做种,具体来说,做种后要确认文件夹下方的内容确实可以访问,保证树结构是建立起来了的。 如果是多级目录的话,文件夹需要保证点开能看见下方内容,文件的话能看见就行,不必打开;单层目录则只要能看见目录下的内容就可以了。(参考上一节最后一张图) IPFS的安全性探讨 IPFS无法举报的原理:权责不明 小结一下,上文中所提到的, IPFS 在拆分、组装、存储、查找、传输、下载文件的特性,叫做“内容寻址”,这是 IPFS 区别于中心化网盘的最重要的点。 内容寻址使得 IPFS 网络中的内容不必保存在某个具体的位置,只要网络中有人保存了,就能从他那里下载(保存的人通常是矿工,当然也可以自己保存并做种,把文件固定在本地就可以了)。 这样的做法极大地提升了内容的安全性,这样一来举报者就没有办法向某个具体的网盘或者机构恶意举报,一次性封禁文件了。换言之 IPFS 通过主动割裂分享和存储之间的联系,从而达成了在内容托管上的权责不明。 权责不明就是安全分享的最佳实践方案(不能伤害一个无法选中的单位)。 并且做种时的流量是走的矿工的而不是分享者的,能减少 BT 做种那样因为流量异常被运营商查水表的概率。做种者所需要做的仅仅只是“联结他人”而已,通过 P2P 的联结建立起一个能查找资源的网络,辅助各大公共网关下载文件。IPFS 在网络层有基本的 TLS 加密,不是裸奔,这可以说极大地降低了做种者的安全性方面的压力。 IPFS是如何防止吸血的? 此外为了防止 BT 中的吸血行为,IPFS 有一个 Bitswap 信用度,如果一个节点交换数据不积极,只下载不上传,那么其他节点给它数据的概率和速度都会降低,需要经常挂机和其他节点交换数据刷一些信用度,才能解决这个问题(信用度账本是节点双方的各执一份的,一方造假是没用的,账本冲突会导致信用度重置,重头再来)。 对于个人来说,信用度不见得很高,如果纯用 P2P 的方式通过本地网关下载(先固定再下载可以降低断连的概率),下载大文件有可能下到后面就被其他节点限速了。因此,假如想要快速下载,比较好的方式是使用 IPFS 网关来下载,目前网络上有很多可供使用的公共网关。 公共网关本身也是一个 IPFS 节点,经由公共网关访问文件或文件夹 CID 可以理解为由对方代理来连接到 IPFS 网络中的资源,由于这些网关有公网 IP ,速度也比普通的家宽更快。 但是公共网关不比百度这种大厂,大部分由个人提供(这些网关提供者通常也是矿工),承载能力有限,如果短时间大量的人挤着下,可能会导致出现问题。因此建议生成下载链接的时候分摊到多个网关上,以进行负载均衡。(当然,如果有能力还是建议用 P2P 下载,以减轻公共网关的压力,有条件也可以自己用服务器搭一个公共网关来自用) 目前 1.1.5 版本以后的 IPFS 分享助手已经内置了网关负载均衡功能,具体可以参考 IPFS 分享助手的文章。 公共网关的恶意举报问题、本地网关 但是公共网关也可能面临被恶意举报导致封 CID 的情况,这种时候除了更换其他公共网关,也可以用自己 IPFS 节点的本地网关访问资源,这种访问类似于 BT 是纯 P2P 的,也就是说,即使这个 CID 在所有公共网关上都被屏蔽了,只要你自己不屏蔽这个 CID 就能访问。 不过普通家宽没有公网 IP,直接下载的话速度会比公共网关慢,一般用来获取文件夹中的 CID 列表,然后自行找其他公共网关生成下载连接下载会更好一些。 具体操作如下: 然后可以通过纯 P2P 的本地网关打开文件夹,使用油猴脚本进行复制 CID、文件名等操作: N+ [技巧分享] 把IPFS当作网盘来用-IPFS进阶教程 更多托管平台可以参考这篇文章: [技巧分享] 盘点主流IPFS托管平台:功能、限制与推荐指数全面对比 IPFS 的优缺点及适用场景的个人浅见 资源分享的安全级别排名 本人在 之前的文章中讨论过分享的几种安全级别,这里简要带过一下: 多层加密压缩包:可以防止网盘扫描,但是无法防止在线解压(手机端可以解压包括 .7z 在内的所有格式) 分卷压缩包及自解压压缩包:无法被在线解压,安全性高于前者。 专有格式加密文件:如 Veracrypt 加密卷等,相比于通用的压缩文件,安全性更高一些。但无法应对举报造成的强制违规。 隐写文件:无法被在线解压,并且违规可申诉,如果被举报到无法分享/下载,申诉即可。安全性高于前述所有。 BT、IPFS 等去中心化分享方案:没有审核系统,安全性最高。但缺点是做不到长时有效稳定。 总的来说,根据 【1. 能否加密】 【2. 能否在线解压】 【3. 能否被举报】,可以把分享方式大致划分出 3 个大的安全级别。 那么上述这么多级别,应该怎么选择呢? 在机器学习领域有一个定理叫做“没有免费午餐定理”(NFL),是说没有一种算法可以在所有问题上都表现最好。对于安全分享方案这个问题,也是类似的,即不可能存在能够同时兼顾所有场景的分享方案,我们总是需要根据特定场景选择最适合的方案。 对于压缩包方案安全级别问题,我在 之前的文章中已经讨论过,这里就不再赘述了,感兴趣可以参看,本文我想重点讨论一下 IPFS 方案的适用场景。 IPFS 分享方案的优缺点分析 个人认为,IPFS 分享相比于网盘分享,其最大优势在于无法被举报,虽然做不到网盘那样长时有效稳定,但是其去中心化分享的特点令其在应对倒卖者的举报上具有无与伦比的优势。相比于同属去中心化分享的磁链方案,IPFS 可以选择托管平台,也可以自己做种,在 托管平台[7] 选得比较靠谱的情况下,也可以做到类似于网盘那样的长期保存。 由于 IPFS 类似磁链的去中心化特点,分享的安全性有了很大的保障。即使托管平台被攻击或者跑路,只要网上还有人固定文件(做种),就仍有机会下载。并且相比于磁链完全靠用户做种,IPFS 可以选择托管也可以选择做种,具有更佳的灵活性,可以减轻分享者的负担。 不过 IPFS 作为去中心化的分享方案,也自然有其该有的缺点:首先靠谱的托管平台不好找,其次如果资源比较冷门没人长时间固定(做种),也会出现类似于磁链那样死种的情况。但是相比于磁链, IPFS 在保种这个问题上已经有很大程度的改进了,因为可以选择托管,做种也不需要公网 IP。 IPFS 分享方案与网盘分享方案的对比 分析完上述优缺点,我们可以设想一下其适用的最佳场景,在设想之前,我们需要先对比一下网盘分享的方案。 如果我们想进行长期有效稳定的资源分享,网盘一定是最佳选择,因为运营商代替用户保管文件,拿了钱自然要办事。为了更具体的分析,我们需要知道各大个人网盘的市场占比,限于成本问题,只查到了 2022 年的行业报告,虽然不是最新的,也应该能够反映一些问题,我们先看一下各家网盘的知名度: 根据# 2022年中国个人网盘市场研究报告(https://www.iimedia.cn/c400/84607.html) 图中的和彩云是现在的中国移动云盘。 我们可以看到,从数据角度,至少在 2022 年,百度网盘仍以绝对的优势占据了榜首。因此,尽管百度网盘一直被人诟病,但是依然是大部分人心目中“网盘”这个概念的体现,因此也是分享的首选(所谓“不是我非得用百度网盘,而是大家都在用百度网盘”)。 所以,就分享资源的长期有效稳定方面考虑,百度网盘必然是最优选择,但是相应地就存在审核机制。 根据这篇文章,百度网盘的审核机制其实并没有想象中那样严格,对于不分享的显然违规的文件,百度网盘通常是不会管的;对于包含违规文件的分享压缩包,只要无法解密,百度网盘也是不会管的。总之,只要不能显式地定位到违规文件,百度网盘通常是不会管的。 这似乎和部分人的认知不符,百度明明就天天炸链,怎么能说不管呢? 根据 试验证据 表明,大多数炸链的真实原因是: 有这么一帮潜藏在各个资源站的特殊行业人群,这些人获取资源后非但不会感谢分享者,还会举报分享文件使之炸链,保证只有自己一个来源,然后再对此资源开价售卖。 这帮人就是资源倒卖者,俗称“倒狗”。 在百度网盘一家独大的情况下,倒卖者对于百度网盘审核机制的研究也最为深入(所谓盗墓的也一定是半个考古学家),他们充分利用了百度网盘的违规机制(即达到举报阈值自动一刀切),发明了批量转存+脚本举报的技术,即先转存想要使之违规的文件,然后调用举报脚本,自动化批量创建分享链接,以大量账号池组成的举报轰炸逐个炸掉文件,对于隐写文件,则可能会先修改其后缀以破坏其伪装。 倒卖者可以做到全程不下载任何文件,直接就能流水线式地在云端进行转存举报等一系列操作;倒卖者也不需要关注具体举报哪个文件,只需要源源不断地把转存后的文件放入举报池中即可,如此构建起一个简单易操作、成本又可控的举报工作流。只要每天开机运行一遍,就可以让所有举报池中的文件违规(隐写文件因为可申诉,时不时会复活,需要每天都举报)。 目前对于倒卖者的举报,网盘分享方案也确实没有太好的办法,之前试验的各种外网盘(Mega、PikPak、Gofile、ModsFire、MediaFire 等)也纷纷败下阵来。外网盘的封禁政策颇为严厉,一炸链就封号(尤以 Mega 为甚,会追踪 ip、cookies 及设备信息封禁新号),不像国内网盘一般只是禁止该文件分享。出于安全角度考虑,分享还是最好选择国内网盘。 IPFS 分享方案的适用场景:恶意举报 小结一下,网盘分享方案虽然在长时间维持资源有效性和可用性方面具有优势,但是在面对倒卖者时是无能为力的。但是与之相反,无法举报的 IPFS 方案在面对这个问题时就具有优势了。 如资源被倒卖者盯上,在资源发出的时候可以采用 IPFS + 网盘隐写文件的办法,可以在 IPFS 有效期间保证资源的可用性,当 IPFS 失效或者不稳定以后,通常也过了这个资源的热度,此时除了倒卖者很少会有人关注。 俗话说只有千日做贼没有千日防贼,倒卖者不可能无限制累积举报池的文件,迟早有一天会移除失效已久的文件,此时若有人再要资源,只需要申诉隐写文件解除违规(采用尝试分享的方式申诉解封最快),再进行分享即可,不需要重新压缩上传。 提示反馈成功即申诉成功,文件就解除违规了,解除违规后不急着分享,先观察一天,看会不会再次违规。 一天后在文件详情中点一下申诉,如果提示“请勿申诉正常文件”,就证明文件已经被倒卖者移出了举报池,可以分享了;如果显示“申诉成功”则说明文件又违规了,还没有被倒卖者移出举报池。 资源生效以后不要在评论区说明,以免被倒卖者注意到。 想要成功申诉需要注意隐写文件的伪装有效性问题,不要选到一些自己就是违规文件的视频。 关于更具体的防炸策略,可以参考这篇文章: 防炸教程:如何安全分享资源? https://cangku.moe/archives/215860 https://www.south-plus.net/read.php?tid-2437901.html https://hxcy.top/541697.html 总结 本文详细地总结了 IPFS 作为一种去中心化文件分享方案的特点和使用方法: IPFS 程序操作: 详细介绍了文件上传、固定、分享 CID 和下载的步骤,以及本地文件管理方法。 IPFS 托管平台:以 Crust+酸奶网盘为例,说明了如何使用托管平台来保证文件的长期可用性。 IPFS 优缺点分析:IPFS 的主要优势在于其去中心化特性,不怕举报,因此适合应对倒卖者问题;缺点是可能因缺乏固定节点而导致资源失效。 IPFS 与网盘对比:相比传统网盘,IPFS 在应对恶意举报方面更有优势,但在长期稳定性上略逊一筹。 应用建议:文章提出了 IPFS 与网盘隐写文件结合使用的策略,以平衡安全性和长期可用性。 这里需要需要强调的是,大部分情况下,网盘+隐写已经足够安全,如果你的分享本身就属于比较安全的资源(普通音乐、普通影视之类),不大可能被倒卖者盯上,那么此时采用隐写甚至 IPFS 就是多余的,反而会增加不必要的负担。此时采用传统的压缩包方案甚至不压缩可能更好一些。 没有免费午餐定理除了告诉我们事物不存在唯一终极解以外,也告诉我们面对问题需要对症下药,过犹不及。 致谢 本文中 IPFS 相关内容特别感谢 @yo @sandbox 参考 主要内容 [1] [技巧分享] 防炸教程:如何安全分享资源? [技巧分享] 网盘资源分享的几种安全级别、审核与举报原理 [资源防炸链解决方案倡议] [工具分享] 隐写者:把资源嵌入MP4文件的隐写工具 [资源安全分享] [技巧分享] 关于评论区地毯式炸链现象的一些测试及初步猜想 [资源防炸链解决方案倡议] [技巧分享] 百度网盘大号传小号分享的操作方法 [资源安全分享方案] [技巧分享] IPFS分享资源快速上手及其适用场景浅议 [资源防炸链解决方案] [技巧分享] [IPFS] 无法被举报的文件分享神器CRUST IPFS操作指南 PART.I ( IPFS 托管平台教程) IPNS 可用公共网关汇总 幻想次元链接 [1] [技巧分享] 防炸教程:如何安全分享资源? [工具分享] 隐写者:把资源嵌入MP4文件的隐写工具 [技巧分享] IPFS分享资源快速上手及其适用场景浅议 [技巧分享] 百度网盘大号传小号分享的操作方法 [技巧分享] 关于评论区地毯式炸链现象的一些测试及初步猜想 [技巧分享] 网盘资源分享的几种安全级别、审核与举报原理 [技巧分享] [IPFS] 无法被举报的文件分享神器CRUST IPFS操作指南 PART.I ( IPFS 托管平台教程) [8] 百度网盘应该如何开车评论区传火教程 2.0 延伸阅读 [X1] [技术分享] 如何在.mkv格式视频里夹带隐藏文件,附带mkvtoolnix,MkvEdit和gMKVExtractGUI工具 [杂谈] 给新司机的一个简单的科普 (笔者注:此文是关于安全分享的科普) [技巧分享] IPFS分享资源快速上手及其适用场景浅议 [资源防炸链解决方案] [技巧] 利用网盘离线下载分享规避审查 [技巧分享] [自建网盘] 自建网盘cloudreve+离线下载 [高阶文章] 关于新时代文件分享机制的思考 (笔者注:此文介绍了除网盘外的其他分享方案) [技巧分享] 图种的制作与使用 [技巧分享] 防炸教程 (笔者注:本文介绍了网盘常用的分享方案,不过作者有可能要吃电脑屏幕了) [教程] BitTorrent (种子文件) 扫盲 [绅士仓库 tracker 更新] [2020 Rev] (笔者注:本文是磁力做种的教程) [技巧分享] [IPFS] 无法被举报的文件分享神器CRUST IPFS操作指南 PART.I ( IPFS 托管平台教程) 关于百度近日封号的相关措施 (此文也是秒传时代的开端) [南+] 本坛还是有牛马用户啊,低能儿请远离互联网好吗?一口一个敬语问我要资源下载了之后反手就去微软举报,你咋不去网信部举报?说不定给你颁一个好市民奖 [南+] 看看单纯的举报行为会对百度网盘资源有多大的影响 [Pixiv] 一个网警的心法教学-P站写色文发黄图到底安不安全【全网最全最细致】 [工具分享] IPFS分享助手:IPFS资源分享一站式解决方案 [资源防炸链解决方案] [工具分享] [油猴脚本] 自动抓取 IPFS CID-文件名-下载链接的辅助脚本 [技巧分享] 把IPFS当作网盘来用-IPFS进阶教程 [资源安全分享解决方案] [网盘防炸教程]新的一年网盘应该如何开车 通过隐写+大号传小号打造网盘分享防御体系 编辑整理 Form cenglin123/IPFS-tutorial 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2025/9/4
articleCard.readMore

家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度

大部分情况下,家庭宽带用户是没法获得公网的。此时就是大内网,也即是NAT类型网络,这种情况下,其实是存在不小的网络优化空间的!本文从NAT网络类型,如何检测,如何优化光猫桥接,光猫破解,网络测速等各种角度来分析如何优化家庭宽度网络,加快下载速度。 公网IP 有公网IP 如果你的光纤有公网IPV4,那么本文你就不用看了,就是最好的网络状态! 但大部分情况下你没有公网IPV4,此时就有很大的优化余地了。 没有公网IP 发展到现在,全世界的IPV4都不够用了。即使是以前发放的 IPV4 也被运营商收回了,你如果想继续使用公网IPV4,就得加钱,大量付费! 公网IP对网络类型很有帮助,但不是我们优化光猫+路由器的部分,有条件就要,但公网IP不是我们能强求的。 如果你没有公网IP,那么就是一个内网IP。内网也分多种类型的,没公网,但你可以优化内网 NAT 类型,以这种方法来优化网络连接。 优化NAT类型,可以有效的提升P2P下载速度,降低游戏延迟! 什么是NAT? 大家办理了宽带后一般会习惯测个速,看下网速有多少,没有达标,喜欢折腾路由器的网友知道除了网速,还有延时、抖动这些指标来衡量网络质量怎么样,延时高了玩游戏就卡,抖动就是指网络的稳定性,还有一个NAT类型,可能知道的人就少了,今天我们就主要分析一下NAT类型对上网的影响。 NAT 代表网络地址转换(Network Address Translation),允许多个内网设备共享一个公网IP地址,使内部网络设备能够与外部互联网通信,主要是为了解决IPV4地址不足的问题;NAT通常部署在路由器上。 举个栗子:比如手机访问mao.fan这个网站,我们手机的ip是192.168.x.x这种内网的ip是无法在互联网使用的,路由器收到这个访问请求后会把192.168.x.x请求上猫点饭这个IP转换成117.151.x.x请求上猫点饭(路由器外网IP获取的是公网IP的情况)这种请求,服务器收到请求返回数据包,路由器收到网站数据后把这个数据包117.151.x.x猫点饭首页数据转发给手机的ip192.168.x.x,虽然不严谨、大概是这么个过程,就叫NAT。 通常来说,NAT有四种核心类型: 家庭网络都是使用NAT技术的,一般划分NAT4个类型:NAT1、NAT2、NAT3、NAT4,具体如下: Full Cone NAT(全锥形): 内网主机使用一个固定的公网IP和端口进行所有外部通信。 任何外部主机只要知道这个公网IP和端口,就能向内网主机发送数据。 Restricted Cone NAT(IP限制锥形): 内网主机使用一个固定的公网IP和端口进行所有外部通信。 只有内网主机曾向某外部主机发送过数据,该外部主机才能向内网主机发送数据。 Port Restricted Cone NAT(端口限制锥形): 内网主机使用一个固定的公网IP和端口进行所有外部通信。 只有内网主机曾向某外部主机的特定IP和端口发送过数据,该外部主机才能向内网主机发送数据。 Symmetric NAT(对称形): 内网主机与每个外部主机通信时,会分配不同的公网IP和端口。 外部主机只能在收到内网主机的数据后才能回传数据,在安全性上最为严格,但也最容易导致连接问题。 玩过网心云、甜糖、京东云这些PCDN的服务,对NAT类型肯定不陌生了,它们都要求你的网络类型达到:NAT1收益才能最大化,分跑没跑到多少先不说,网络优化可学会了不少知识呢,这波不亏! NAT类型有哪些影响? NAT类型主要影响UDP协议的通信性能和稳定性。特别是在需要低延迟和高实时性的应用中,例如在线游戏、VoIP和视频通话。 游戏的影响: 玩主机游戏的影响很大,如果你有PS、Xbox、NS 等主机,可以在网络状态里看到 NAT类型;对网络游戏会影响延迟和丢包率,以及匹配系统的效率和成功率。 语音视频的影响: 你可能遇到过微信视频提示网络质量不好,但WiFi信号满格的状况,这种情况很有可能是NAT4类型,导致无法P2P连接成功导致的。 BT下载的影响: P2P下载等应用,最为开放的NAT类型,可以连接到更多的资源数,加快下载的速度。 开放性:NAT1>NAT2>NAT3>NAT4 安全性:NAT1<NAT2<NAT3< NAT4 家庭宽带一般是NAT3,Port Restricted Cone NAT(端口限制锥形)。 NAT打洞 NAT 打洞技术基本都是基于UDP协议的,STUN协议是一个专门帮助位于NAT后的网络设备进行点对点连接(打洞)的,要求如下: NAT1 NAT2 NAT3 NAT4 NAT1 ✅ ✅ ✅ ✅ NAT2 ✅ ✅ ✅ ✅ NAT3 ✅ ✅ ✅ ❌ NAT4 ✅ ✅ ❌ ❌ 简单总结能实现点对点通信的条件:位于NAT后的设备,NAT类型要:A+B ≤ 6 才可以实现NAT穿越。 NAT类型如何优化? 宽松的NAT环境可以建立直接P2P连接,尽可能避免经过中继服务器,实现更好的网络性能。那么问题来了,如何提升你的家庭宽带NAT类型?这才是重点。 光猫改桥接(建议):路由器拨号+开启Upnp+开启Full Cone网络(如果有此设置,华硕、锐捷可设置)。 光猫路由模式:进入光猫后台开启Upnp,路由器设置成AP模式(有线中继),减少一层NAT设备更容易达到NAT2以上。 注意:路由器DMZ会暴露一个指定的主机IP,和Upnp有冲突,不建议开启。 具体优化步骤如下: 第一种网络拓扑 大部分家庭都是光纤入户→光猫有网了→接入路由器的WAN口,路由器有无线网了,电脑、电视等有线设备接入路由器或者交换机,那么就是下面这种网络架构: 这种架构其实光猫才是家里的主路由,我们买的路由器被当做了二级路由,家庭内网IP情况如下: 光猫:192.168.1.1 路由器:192.168.10.1 连接路由器的设备:电脑、手机等就是192.168.10.X 这样的IP了,手机通过路由器上网会经过两层NAT,效率大大降低。 第二种网络拓扑 也就是光猫改桥接,路由器拨号上网,这一步做完,减少一层NAT,是大家最推荐的做法,完全掌控家庭网络,随机折腾。 第三种网络拓扑 这种网络结构使用的人数是最少的,适合于光猫无法改桥接,没有超级密码的情况 和第一种网络结构一样,光猫当主路由进行上网,区别是路由器不当做二级路由了,直接设置为AP模式,只提供无线功能,网络层级减少一个NAT 优化家庭网络重点:路由器能少一个层级就少一个层级,这样可以减少一个NAT设备,最后才有可能达到NAT1类型 有条件给光猫改桥接 光猫不能改桥接 下面分两种情况来优化家庭网络 第一种:光猫改桥接 现在的光猫早已不是当初单纯的小猫了,变身:光猫+路由器+AP接入点,我们第一步就要恢复光猫的本职工作,光电转换调制解调的工作。路由这种脏活、累活关我小猫什么事? 办理宽带的时候直接跟运维师傅说、一般都会给你改桥接。办理好了的可以找运维师傅直接要超级密码自己改,默认不给桥接的原因无非是怕麻烦、大部分用户只需要插上就能上网、少一个环节少出错。 这一步做完,减少一层NAT,家庭网络的拓扑结构变成了: ▲ 路由器外网IP:100.64.x.x 虽然还是内网IP,但不是192.168.1.2这样的了 只是路由器拨号,网络只优化了一半,还是不够,端口转发这个功能也同样重要 什么是端口转发? 端口转发是一种网络技术,它允许从互联网上的一个端口的数据传输被重定向到另一个端口,通常是从公共IP地址的端口转发到局域网内部的私有IP地址的端口。这样做可以让外部设备通过互联网访问您家庭网络中的特定服务,如文件服务器、游戏服务器或其他在线服务。 路由器开启UPnP UPnP简单来说是自动的端口转发,某些有需求的应用可以直接穿透到因特网,不需要做复杂的端口映射设置,开启后可以提升p2p连接的成功率,对远程桌面应用也有帮助。 DMZ也可以,是把一个内网设备的IP直接暴露在公网上,只能暴露一个,一般不会同时用这两个功能。 ▲ 现在路由器都有这个功能,建议打开,图上是京东云路由器自己映射的一些端口,不知道是什么服务 光猫改桥接路由器拨号+路由器开启UPnP功能 光猫有条件改桥接的情况,家庭宽带能做的优化就完成了! 光猫无法改桥接 这种情况为什么会出现?不明但有,运维师傅不配合之类的,或者自己不想太折腾,那么也有方法,先看拓扑图: 路由+UPnP让光猫来提供,这样整个家庭网络内部的IP统一,如果有NAS之类的设备,也可以实现局域网互相访问,不会出现两个网段的情况。 噢!懂了,但怎么做? 有些路由器如padavan系统有AP模式、华硕、TP应该也有,这种情况上网方式直接设置为AP模式即可。 大部分路由器没有这个模式的,上网模式只有几种,还是京东云举例: 少年,这道题,点解? ▲ 这里我用红米ax3000的LAN口接入京东云BE6500的LAN口(实际接入光猫LAN口),路由器当了无线交换机,相当于AP模式了,WAN口不使用即可,记得关闭DHCP服务。 光猫开启UPnP ▲ 这个不需要超级密码,光猫背面的普通用户就可以修改! 光猫无超级密码优化的方式:路由器LAN口接入光猫LAN口+光猫开启UPnP功能 NAT类型检测工具 假如你上面步骤都做了,感觉好像也没啥提升啊,那我折腾了个寂寞,网速还能跑个分,这啥也没有,多不甘心啊!咱可是为家庭网络的稳定、快速、玩游戏不卡顿做了贡献的 别急!以下是经过我无数次折腾,总结的能探测NAT类型的方式: NatTypeTester Win系统有一款软件NatTypeTester可以测试你优化的成果的! GitHub地址 https://github.com/HMBSbige/NatTypeTester/releases NatTypeTester网盘备份: 夸克链接:https://pan.quark.cn/s/ac23ed2052be 提取码:f4h8 使用方法很简单,服务器建议选择小米的,点Test等一会即有检测结果,如果你是NAT4要等大概5秒出结果,如果你是NAT1,秒出结果! ▲ 移动宽带没有优化直接是对称性网络(NAT4)、不愧是你,大内网! ▲ 光猫改桥接+路由器拨号+开启UPnP,成功变成了全锥形网络(NAT1类型),舒服了。 Python方法 人生苦短,我用Python!万能的python当然能实现这个小功能,PyStun3是一个开源的Python STUN客户端,旨在帮助用户获取NAT类型和外部IP地址。 pip install pystun3 然后终端里输入: pystun3 稍等一会,就会出结果,python结果很准确。 手机端 iOS系统没有相关的APP,安卓系统可以安装STUNner这款应用,但不好下载,一般的应用商店都没有。 网心云小程序可以测网速以及NAT类型,但需要WiFi环境,以及登录网心云账号。 Windows系统设置 如果Windows系统以上都设置了,但NAT类型没有提升,那么在Windows上把以下三个服务设置为自动启动: Function Discovery Provider Host Function Discovery Resource Publication SSDP Discovery 方法同时按下win+r键,在运行窗口中输入services.msc,然后找到这三个服务更改一下设置即可! 光猫改桥接 光猫默认是路由器模式 目前各大宽带运营商给你安装宽带时,喜欢给你直接用上光猫的路由功能,然后你接上的自己的无线路由器,只充当了一个无线发射接收的功能。有些光猫直接自带wifi信号,你连路由器都不需要,就能直接上网了。 运营商如此做法,可能有它自己的考量,比如说更省心,方便用户,不用再记住宽带的账户密码,因为直接内置到光猫里面了,还有很多用户回家不用自己另外买路由器,都可以用光猫的路由器功能。对于大部分入门用户,家里也就三五个手机,也足够用了。 为什么要改成桥接模式? 如果你家的设备非常多,二三十个联网设备以上,这个光猫的路由性能可能就不够用了,你家的网络可能经常出现卡顿和中断的情况。还有就是你要用 Mesh 组网,可能不符合Mesh 路由器产品的网络拓扑关系。 这时候你就要考虑,把光猫从路由模式改成桥接模式,让光猫只用来做光信号和电信号的转换,不做任何网络相关的功能(路由+DHCP),把这部分功能交给性能更强大的无线路由器来完成。 桥接的优点 光猫路由模式下需要负责NAT转换,光猫CPU性能不算很强,设备多、网络复杂的情况可能会卡顿 光猫桥接后,路由器拨号可以减少NAT层级,有4个NAT类型,分别是:NAT1、NAT2、NAT3、NAT4,从1到4网络通透性越来越差,限制也越来越多。 家庭网络类型想要变成NAT1(Full Cone NAT),则光猫必须桥接+路由器开启UPnP端口转发才行。 路由器拨号 光猫设置 关闭 TR069,关闭原来的路由拨号,新建一个桥接。 关闭``TR069` TR069 是远程设置用户路由器的协议,你不想被远程改密码,改配置,TR069 就必须关闭! 路由器设置 光猫拨号 当光猫桥接不稳定的时候,可以用下面方法来备选。 光猫设置 默认就是光猫拨号的,类似下面配置 路由器设置 光猫拨号时,IPV6可以使用从桥的方式来获取IPV6,如果你的光猫可以获得IPV6的话! 光猫破解 桥接虽好,但是拿不到管理员权限,就都是白搭啊! 本章节,就教你如何获取光猫管理员权限! 装机就使用路由器桥接 光线或者拨号安装的时候,就和装机师傅说好了,要用路由器拨号! 如果装机的时候没有这么做,就只能用下面方法了。 拨打客服电话 最简单的办法是直接打电话给宽带运营商,让他们的工作人员帮你操作。如果运营商方便推脱或者拒绝,可以直接投诉到工信部, 会很快的解决。 最方便快速的方法!投诉运营商之后,装机师傅会电话联系你,不论他说什么,你只说要光猫密码,要不到就继续投诉。 最终都会给你的!因为你投诉一次,师傅就会扣一次钱!记住也不要把关系弄得太僵! 默认密码破解 如果你没法要到密码,可以试着碰运气试一下默认密码。 不过现在除了装机时是默认密码,基本都改为动态下发密码了。 (1)把光猫从路由模式改成桥接模式 光猫配置网址通常是:http://192.168.1.1/ ,输入超级管理员帐号、密码,进入后台配置页面,将联网模式改为“Bridge桥接模式”即可。 电信 超级管理员账号:telecomadmin 超级管理员密码:nE7jA%5m或admintelecom 移动 超级管理员账号:CMCCadmin 超级管理员密码:aDm8H%MdA 联通 超级管理员账号:CUAdmin 超级管理员密码:aDm8H%MdA或CUAdmin 移动的光猫超级密码查询 :http://112.29.242.35:3000/ ,此网址可以查询指定手机号绑定的宽带的超级密码。 安徽移动用户 账号CMCCAdmin,密码为ah123456@ 广西移动用户 账号:admin 密码:Cmcc10086# 广州移动光猫账号: CMCCAdmin 密码:aDm8H%MdA 广东全省移动光猫账号: CMCCAdmin 密码:aDm8H%MdA 一些常见型号的光猫和密码: 1、中兴F601/admin/admin 2、中兴F612/admin/admin 3、中兴F660/admin/admin 4、中兴F623/CMCCAdmin/aDm8H%MdA 5、华为HG8010/telecomadmin/admintelecom 6、华为HG8020/telecomadmin/admintelecom 7、华为HG8310/telecomadmin/admintelecom 8、华为HS8545M/CMCCAdmin/Cmcc10086# 9、华为HG8326/telecomadmin/admintelecom 10、华为HG8546/telecomadmin/admintelecom 11、华为HS8546V/CMCCAdmin/aDm8H%MdA 12、贝尔I/240W/admin/CMCC2012(未升级版) 13、贝尔I/240W/admin/Cmcc10086#(升级版) 14、烽火CMCCAdmin/aDm8H%MdA 15、烽火admin/Cmcc10086#(升级版) 16、Gm219-SC账号:CMCCAdmin/Cmcc10086# 17、瑞斯康达/super/raisecom_0021 其他 账号:root密码:root 账号:admin 密码:admin 账号:fiberhomehg2x0 密码:hg2x0 账号:root 密码:Zte521 光猫破解 不是专业linux高手,或者从事嵌入式,IT行业的,不建议这么做。 不同光猫平台,硬件软件版本,破解方法都不一样! 对于专业人员而言,这个也是划不来的。打客服电话最划算! 公网 IPV6 测试 https://www.test-ipv6.com/ 网速测试 网络安装好之后,测速是必须的。下面总结一些测速方法。 speedtestt 测速网址:https://www.speedtest.net 全球最大的测速网站了,OOkla旗下的,全球有上千个测速节点,中国也有几十个测速节点,但打开速度比较慢,会有一些广告,有iOS 和 Android 系统、Windows 和 MacOS 的桌面版应用、还有Apple TV 版本,界面清爽、颜值很高。 测速网 测速网址:https://www.speedtest.cn 国内最常用的测速网站,一搜索测速网基本上就是这个,属于http://speedtest.net的模仿者,广告很多,和运营商有合作可以进行宽带提速,支持的平台也非常多,结果也算比较准确。 中国科学技术大学测速网站 测速网址:https://test.ustc.edu.cn 国内大学的测速节点,基于开源的librespeed/speedtest搭建,支持测试IPv4 或 IPv6的网速。 南京大学测速站 测速网址:https://test.nju.edu.cn 同样的大学测速节点,南京大学的公开服务,也支持ipv6,感觉这个速度比科技大学的准确。 FAST测速 测速网址:https://fast.com FAST测速是由Netflix提供的一个网络测速工具,主要用来测试宽带的下载速度是否能够看网飞的视频,果然财大气粗,一个测速网站的域名顶级!国内不能直连,一般我们路由器安装小猫咪后用来测试起飞速度~ 全球网测 全球网测是中国信通院推出的宽带测速、上网体验和网络诊断工具,支持5G/千兆测速,界面清爽无广告。 泰尔网测 泰尔网测是中国信通院泰尔系统实验室研发的网络测速软件,功能包括网络测速、基站信号测试、道路测速、视频测速和网页测速,界面友好、无广告,完全免费,节点很多,但我测速没有跑满。 花瓣测速 华为出品的测速软件,是一款集成移动网络及 Wi-Fi 网络速度测试及网络问题诊断的专业测试工具。目前好像仅支持华为设备,ios和安卓商店都没有上架,没有用过,不做评价。 测网速 下载地址:http://uuspeed.uutest.cn 准确、简单、快速的网络测速工具,国内不知名公司做的,只有APP版,没有网页测速;我用了挺久,之前在AppStore随便下载的,还挺好用,没有广告,测速结果也准确,今天无意发现工具栏里还挺多工具,支持灵动岛实时显示网络流量。 苹果官方测速 嘿嘿,没想到吧,果子官方也有测速服务,不过隐藏的比较深,从macOS Monterey 开始, macOS 已经内置了一个网络情况测试工具 networkQuality。这个工具利用 Apple 遍布全球的 CDN(内容分发网络)服务器来测速,比较客观准确,还会给你的网络作出一个评价,使用方法也非常优雅! 打开终端,输入 networkQuality 回车,等待测速和评价结果完成! 使用苹果的CDN服务,官方测出结果下载496Mbps!还是比较准确的。 好了,基本上这是最常用的测速软件和网站了,有没有你用的测速网站呢?如有遗漏,欢迎补充。 Wi-Fi 信号强度测试 家庭网络使用的时候,很多时候都是使用的wifi,那么怎么样放置路由器,设置路由器才能最大化无线网速了? 此时,你就需要一个好的 wifi 信号测试工具了。 Android 平台有很多好用的信号强度测试软件,例如下面这些: NetSpot — 使所有 Android 用户都能进行高度精确的信号强度测试 WiFiman — 致力于解决互联网连接不稳定和WiFi速度慢的问题。 Wi-Fi Analyzer — 提供有价值的见解,推荐最佳的网络频道和位置。 Net Signal — 可以帮助您在房子、工作场所或任何需要稳定连接的地方找到最优的WiFi或蜂窝连接区域。 Wi-Fi Monitor — 帮助分析周围网络使用的信道或在您的Android设备上测试信号强度。 NetSpot NetSpot for Android 是最佳的 Wi-Fi 信号强度测量应用,它让高度准确的信号强度测试对所有 Android 用户都可用—不仅仅是最极客的用户。 检查模式 收集有关周围 Wifi 网络的每一个细节。 勘测模式 在地图上快速轻松地概述您的真实 Wi-Fi 数据。 规划模式 在安装之前设计和模拟您的无线网络。 应用程序具有三种主要模式:检查、调查和规划,允许您收集广泛的无线数据,甚至可以直接在您的安卓设备上创建交互式WiFi热图。最重要的是,您可以将应用程序收集到的数据导出到桌面,以使用NetSpot for Windows 检查WiFi信号强度。 Android 版的 NetSpot 还包括一个互联网速度测试功能,您可以使用它来确定 WiFi 网络的实际速度,并与您的互联网服务提供商(ISP)承诺的速度进行比较。 最近添加到 Android 版本 NetSpot 的最大功能之一是集成了规划模式。它使您能够在购买任何新硬件之前,虚拟设计或升级您的 WiFi 网络。您可以预测信号在整个空间中的传播。 规划模式目前支持两种热图类型(信号水平和信号干扰比)来帮助您识别潜在的弱点。这不仅简化了您的设置,还可以为您节省不必要的开支和安装过程中耗费大量时间的反复试验。 他们还在开发高级PDF报告和额外的热图导出格式,以提供更强大的数据分析选项。 优点和缺点 WiFi 热图生成功能 导出数据支持深度分析 全协议支持(802.11a/b/g/n/ac/ax) 卓越的可用性 高频更新维护 独家预测规划模式 需应用内购买解锁全功能 WiFiman WiFiman 是一个出色的安卓 WiFi 信号强度应用程序,旨在解决互联网连接不一致和 WiFi 速度慢的问题。该应用程序提供了一个全面的工具包,提供从网络扫描到速度测试的所有功能,所需的一切都可用于有效的 WiFi 信号优化。 这款信号强度测试Android应用程序于2018年首次发布,自那时以来已被超过100万用户下载。其完全免费的性质以及它甚至不显示广告的事实无疑在其成功中起到了重要作用。 不幸的是,最近的更新略微降低了用户体验,缩小了频谱视图,并删除了将IP地址用作可点击链接的功能。希望开发人员能倾听其WiFi信号强度Android应用用户的意见,尽快解决这些问题。 优点和缺点 广泛的网络扫描功能 速度测试具有存储和比较结果的能力 对 Ubiquiti 设备的卓越支持 完全免费且无广告 小的可用性问题 无法创建WiFi热图 Wi-Fi Analyzer WiFi Analyzer 是想要了解如何在 Android 设备上检查 WiFi 信号强度的用户的又一顶级选择。它提供有价值的见解,推荐最佳的频道和位置,以帮助减少干扰、增强连接速度和改善稳定性。 由于WiFi Analyzer显然更看重功能而非形式,所有新用户都必须克服一些学习曲线才能有效使用该应用程序。好消息是,该应用程序支持17种不同语言,并且可以免费使用(应用内购买可移除广告并解锁额外功能) 优点和缺点 强大的特性集 实时数据和距离计算 经常更新 支持17种不同的语言 需要进行应用内购买才能解锁所有功能 免费版中的侵入式广告 无法创建WiFi热图 Net Signal Net Signal 脱颖而出,成为监测WiFi和蜂窝信号强度的最佳Android测量应用之一。实际上,这个方便的工具可以帮助您找到在家中、工作场所或任何您需要稳定连接的地方最优的WiFi或蜂窝连接区域。 作为WiFi信号强度应用程序使用时,Net Signal可以提供全面的WiFi信号数据,如SSID、BSSID、最大速度、IP地址和网络能力。作为蜂窝信号分析仪,该应用程序可以分析2G、3G、4G和5G蜂窝信号,无论是了解您的网络连接详情方面都无所不包。 请注意,Net Signal的免费版本自2022年底后没有更新。付费版本则会定期更新。 优点和缺点 提供 WiFi 和蜂窝信号强度信息 简洁直观的用户界面 所有功能均可免费使用 包含有时令人讨厌的广告 无法创建WiFi热图 最后一次更新是在 2022 年底附近 Wi-Fi Monitor 无论你是想分析周围网络所使用的频道,还是测试你的安卓设备上的信号强度,WiFi Monitor都能满足你的需求。 虽然该应用具备在你的子网内进行快速扫描或进行更广范围的深度扫描的功能,但一些用户发现扫描时间比预期的要长。此外,应用程序缺乏给设备取昵称的功能。 该应用程序的专业版提供了额外的功能,例如延长的深色主题、生成和导出HTML或PDF格式报告的能力,以及更详尽的设备信息。但不用担心,因为免费版本仍然为大多数用户提供了足够的功能。 优点和缺点 干净且功能强大的用户界面 支持 Android 4 及更新版本 免费版本对于大多数用户来说应该足够了 自2022年以来未更新 无法创建WiFi热图 花费更长时间来收集数据 专业版独有的重要功能 WiFi信号强度指示器究竟有什么作用? 您 Android 设备上的 Wi-Fi 信号强度指示器,通常由几个垂直排列的小条形图表示,可以基本直观地显示您无线网络的信号强度。了解 什么是良好的 Wi-Fi 信号强度 能帮助您更好地解读这些信息。 当图标显示完整信号条时,表示您的设备与WiFi网络的连接很强,这意味着您离路由器相对较近或存在的障碍很少中断信号。当您的WiFi信号强度指示器显示满格时,您可以期待更快的加载时间和更顺畅的流媒体体验。 另一方面,空的WiFi信号强度指示器表明您的设备当前没有连接到WiFi网络,或者信号非常弱。在这些情况下,如果可用,您的Android设备可能默认使用移动数据。 附赠 为什么三大运营商开始普遍限制上行速度? 想在bilibili上传自己打游戏的视频睁眼一看千兆网居然被限速到5m了! 三大运营商普遍限制上行速度的现象,但本质上是技术瓶颈、成本压力与商业策略多重因素叠加的结果。这一趋势背后既有5G网络架构的先天缺陷,也有运营商对资源分配的主动调控的结果。 中国5G主力频段均采用TDD模式,典型时隙配比为下行:上行=7:3或8:2。这意味着70%~80%的时隙资源分配给下行,上行资源是严重不足的。例如3.5GHz频段在7:3的配比下,下行速率可达1.5Gbps,而上行却只有280Mbps。 发射功率不对称:基站发射功率达200W,而手机仅0.2W,导致上行覆盖半径仅为下行的1/3; 天线数量差距:基站支持64通道Massive MIMO,而手机通常仅2根发射天线,无法利用空分复用增益; 高频段覆盖衰减:3.5GHz频段比4G的1.8GHz覆盖减少50%,进一步削弱上行信号穿透力。 手机接收下行数据后,需等待上行时隙才能发送确认信号,在7:3配比下最大时延达4.2ms,间接占用上行带宽。普通用户下行流量占比超90%,而上行需求集中于小众场景,比如直播推流、云备份等。运营商通过动态资源调度将更多频谱分配给下行,可提升多数用户体验。 尽管工业物联网需100Mbps以上上行带宽,但当前5G toB的渗透率不足10%。运营商缺乏动力为低频需求预留资源。在基站共站部署场景中,5G上行覆盖半径比4G小30%~50%。运营商通过压缩单用户上行带宽,可扩大同时服务用户数,避免边缘区域断连。 运营商当前限制上行速度,本质是在技术缺陷、成本压力与用户需求三角中寻求平衡。随着政策强推“信号升格”行动,以及5GA超级上行技术的规模商用,上行速率将从“被动限制”转向“主动释放”。 未来2年,伴随工业互联网、低空经济等上行密集型场景爆发,运营商需在频谱重构、帧结构优化、AI调度三者协同下突破瓶颈,届时,“限制上行”将不再是运营商的默认选项,而是技术迭代中的短暂插曲。 参考&致谢 测网速app和网站盘点,哪个测速最准确和靠谱? 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 衡量Android上WiFi信号强度的五大最佳应用程序 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2025/6/23
articleCard.readMore

家庭日常家电维护保养总结一本通

你是否从来都没有想过热水器居然需要换镁棒?空调需要定期清理内网?否则可能有致命风险?今天这里总结了家庭常用电器的日常维护保养和家用汽车的维护保养内容,让你从此不在抓瞎,大大降低维护使用成本! 家庭中的家电日常维护不仅能延长使用寿命保障使用安全,还能提升能效并减少健康隐患。以下是需要重点维护的家电清单及具体维护要点,涵盖清洁耗材更换功能调试等关键操作: 家电维护保养 🔧 核心维护家电清单 电热水器——镁棒更换与内胆清洁 为什么维护:镁棒通过牺牲阳极保护原理防止内胆腐蚀,若不更换会加速内胆破损降低加热效率并滋生细菌。 要是你用的是燃气热水器的话,那确实不用去关心镁棒。但要是你用的是电热水器,那镁棒就是当中非常重要的一个部件,也属于一个很重要的消耗品。它的作用就是解决掉自来水加热后产生的水垢。因为水垢是对电热水器的内胆有一定腐蚀作用的,所以有一根镁棒“坐镇”,就能与水中的碳酸根离子、碳酸氢根离子结合,产生碳酸镁(水垢),镁棒消耗掉了水里的负离子,铁做的内胆就不会被腐蚀了。 棒是保护内胆,解决水垢的重要部件,你一直不换,相当于内胆就失去了保护。轻则让电热水器在加热的时候需要消耗更多的电,加热时间更长,不容易达到设定的温度,重则会让内胆漏水,引发漏电的安全隐患。有很多新闻里说到的“电热水器漏电导致人员伤亡”,大部分是因为镁棒没有及时更换导致的。 维护频率: 普通镁棒:水质较好地区每2–3年更换,硬水区(如北方)每1–2年更换。 稀土镁棒(如美的JA7):理论寿命8年,等同安全使用年限,可免更换。 镁棒接口也是排污口,一般3~6个月就需要打开镁棒接口排污一次!看各地情况可以调整周期! 操作建议:更换镁棒需专业拆卸排污口;清洗内胆可每年1次,排出沉积水垢。 风险提示:未更换镁棒可能导致加热管结垢,耗电量增加30%以上。 最关键最危险的就是这个了!电热水器漏穿就会有漏电风险,可能出现致命的风险事故! 空调——滤网清洗与整机保养 滤网清洁: 家用空调:每1–3个月清洗1次(频繁使用或污染严重区域需缩短周期)。 中央空调:商用场景需更频繁,建议每月检查。 深度维护: 每年1次专业拆洗散热片与蒸发器,防止细菌滋生(如军团菌)。 外机散热片可自行用软毛刷除尘。 更换提示:滤网破损或变形需立即更换,否则影响制冷效率及空气质量。 风险提示:不及时清理有健康风险,特别是对于婴幼儿,孕妇而言可能是致命的! 洗衣机——内筒消毒与密封圈护理 自清洁频率: 家用:每2–3个月运行槽洗净程序,搭配专用清洁剂或过碳酸钠(非小苏打)。 滚筒洗衣机:重点清洁门封胶圈凹槽,防止霉菌堆积。 专业拆洗:每年1次深度拆洗,清除夹层污垢(如“海苔状”残留物)。 日常习惯:使用后开盖通风,避免潮湿环境滋生细菌;控制洗衣液用量,减少残留。 抽油烟机——油网清洗与电机保养 清洁频率: 油网及外壳:每月擦拭油污,重油烟家庭需缩短至每2周。 深度清洗:每3–6个月拆卸油网风轮,用中性清洁剂浸泡刷洗。 管道维护:每年检查排烟管是否堵塞,商用厨房需增加频次。 性能监测:吸力下降或噪音增大提示需立即清洁,避免电机超负荷损坏。 冰箱——密封条保养与除霜管理 常规清洁: 内部:每季度清空食物,用白醋水擦洗内壁及密封条。 冷凝器:每年吸尘除尘1次,提升散热效率。 除霜类型: 自动除霜(无霜冰箱):无需手动操作,但需确保排水孔畅通。 手动除霜:直冷冰箱霜层超5mm时需断电融霜,避免压缩机高负载。 异味控制:放置活性炭包或柠檬片吸附异味,避免食物串味。 ⚠️ 其他需定期维护的家电 家电类型 维护重点 频率 注意事项 来源 净水器 更换滤芯 PP棉/活性炭:3–6个月 RO膜:2–3年 水质差地区需缩短周期,避免二次污染 吸尘器 清理尘盒+更换滤网 每次使用后清尘盒 滤网每6个月更换 滤网破损会导致排风含尘量超标 洗碗机 清洁滤网+运行自清洁程序 每月1次 残留食物渣易堵塞排水泵 燃气热水器 检查燃气管路+除垢 每年专业检修1次 防止CO泄漏或热交换器堵塞 🔍 维护误区与专业建议 “不坏不修”的危害: 例如洗衣机内筒污垢超标会导致衣物二次污染,引发皮肤过敏;空调滤网长期不洗可能传播呼吸道病原体。 DIY清洁禁忌: 禁用强酸/碱清洁剂(腐蚀金属部件);勿用小苏打清洗洗衣机(结块卡槽)。 何时寻求专业服务: 涉及电路或密封结构(如电热水器内胆空调压缩机);家电性能异常(如制冷变慢噪音异常)。 超龄家电风险: 冰箱超10年:密封老化致耗电翻倍,保鲜能力下降。 燃气热水器超8年:管路腐蚀可能引发燃气泄漏。 💎 长效维护策略 建立维护日历:在手机设置提醒(如“每3个月洗空调滤网”)。 优先选择“自清洁”型号:如空调自清洁洗衣机高温筒洗净免换镁棒热水器。 关注耗材替换成本:净水器滤芯吸尘器HEPA滤网等需纳入购买决策。 定期维护家电相当于“健康体检”,既能避免突发故障的高额维修费,也能守护家庭健康环境。建议结合使用频率与本地环境(如水质空气污染度)灵活调整周期,必要时通过专业服务确保深度清洁安全。 汽车维护保养 以下是针对燃油车纯电动车(电车)混动车(含插混/增程)的维修保养内容总结及用户维护指南,结合最新行业数据(2025年)整理: ⚙️ 三类车型核心保养内容对比 燃油车:以发动机为核心的机械维护 核心项目: 机油/机滤:每5,000公里或半年更换(矿物油)或10,000公里/年(全合成)。 空气滤清器:每2万公里更换,灰尘多地区缩短至1万公里。 火花塞/点火系统:镍合金型每3万公里更换,铂金/铱金型每8-10万公里更换。 变速箱油:AT/CVT车型每6-8万公里更换,MT车型每10万公里。 高成本项目: 大保养(6万公里)含刹车油冷却液燃油滤清器更换,费用约4,500元。 正时皮带更换(8-10万公里),费用超2,000元。 纯电动车(电车):三电系统主导 核心项目: 电池健康检测:每1年或2万公里,检查电池压差冷却液状态。 电机/电控系统:每2万公里检查绝缘性线束老化。 专属耗材: 电池冷却液(沸点≥120℃):每2年或4万公里更换,费用600元+。 专用减速器油:每8万公里更换,成本低于变速箱油。 低成本项目: 空调滤芯:每1年更换,可自行操作(成本50元)。 刹车系统:因能量回收磨损慢,刹车片更换周期延长50%。 混动车(含插混/增程):双重系统叠加 核心项目: 发动机部分:同燃油车,需定期换机油(但周期延长至1万公里)。 电力部分:电池检测电机冷却液更换(周期同电车)。 专属风险:频繁油电切换导致发动机积碳增多,需每2万公里清洗进气系统。 保养成本: 5年总保养费约3,500元,介于油车(4,500元)和电车(1,500元)之间。 📊 用户维护指南:按车型分类建议 燃油车用户:重点防范机械老化 必做事项: ✅ 每月检查机油尺,低于下限立即补充。 ✅ 每5,000公里清洗节气门(预防怠速抖动)。 ✅ 长期停放时加燃油稳定剂,防止油路胶质沉淀。 避坑提示: ⚠️ 4S店推荐“发动机深度清洗”多为智商税,仅高里程车(>10万公里)需考虑。 电车用户:聚焦电池寿命与安全 必做事项: ✅ 充电习惯:避免电量<20%或>90%停放,每月至少1次满充满放校准电池。 ✅ 高温天气停车后延迟充电,防止电池温度>50℃。 ✅ 每半年检查电池包底盘磕碰(尤其坑洼路段行驶后)。 低成本技巧: 空调滤芯自购更换(省80%费用),选HEPA滤芯防PM2.5。 均衡充电可在夜间谷电价时段进行,节省费用。 混动车用户:平衡油电系统负荷 必做事项: ✅ 每月用1次燃油模式行驶>30分钟,防止燃油变质。 ✅ 插混车优先用电:电池电量保持20%-80%,延长循环次数。 ✅ 增程车注意散热:高速行驶后检查增程器冷却液温度。 关键维护: ⚠️ 刹车能量回收系统需每3万公里标定,防止制动力衰减。 💰 保养成本与周期对比(2025年数据) 项目 燃油车 纯电动车 混动车 基础保养周期 5,000公里/6个月 20,000公里/1年 10,000公里/1年 年均保养成本 2,000-3,000元 500-1,000元 1,200-1,800元 5年总成本 19,000元(含油费) 23,700元(含电费) 31,700元(含油电) 高成本风险点 正时皮带/涡轮维修 电池衰减更换(超保后) 双系统故障叠加 注:成本按年均行驶1.5万公里计算;电车电池更换费约500-800元/度电(如50度电池超保维修需2万+)。 ⚠️ 行业新趋势与用户应对策略 新能源保养陷阱: 三电检测费虚高:部分品牌单次收费800元,实际成本不足50元 → 要求出示检测报告。 OTA升级套路:自动驾驶功能需年费订阅(如小鹏XNGP年付3,600元) → 购车前确认软件权益。 独立维修厂转型: 传统汽修店减少50%业务,可优先选择具备高压电资质的门店(认准CATARC认证)。 延长寿命必做: 油车:每5万公里清洗燃油喷射系统(直喷车必备)。 电车:北方用户冬季加装电池保温套,续航衰减降低15%。 💎 总结:按需选择维护策略 通勤党选电车:年里程>2万公里时成本优势显著,重点维护电池。 长途党选油车/混动:无续航焦虑,保养时优先检查发动机积碳和变速箱。 混动车折中方案:城市用电+高速用油,但需兼顾双系统保养。 建议建立电子保养台账(例如“养车无忧”APP之类的),自动提醒项目周期,避免遗漏高成本维护项。任何车型超6年使用后,每年需进行安全专项检测(制动/电路)。 汽车维护周期表 以下是针对燃油车、纯电动车(电车)、混动车(含插混/增程)的全维护部件对比表格,涵盖关键部件、周期、成本、风险及用户操作建议,结合2024年行业数据优化: 🚗 汽车维护保养全要素对比表 维护部件 燃油车 纯电动车(电车) 混动车(插混/增程) 通用建议 核心耗材 > 机油/机滤 5,00010,000km/612月 ¥300~800 ❌ 无需 10,000km/12月 ¥400~600 全合成油可延长周期 > 电池冷却液 ❌ 无需 4万km/2年 ¥600~1,200 同电车 ¥600~1,200 专用高沸点冷却液(>120℃) > 减速器油 ❌ 无需 8万km ¥400~800 同电车 ¥400~800 更换需设备加压 过滤系统 > 空调滤芯 1万km/12月 ¥50~150 同燃油车 ¥50~150 同燃油车 ¥50~150 自换省80%费用 > 空气滤清器 2万km/24月 ¥80~200 ❌ 无需 同燃油车 ¥80~200 沙尘区周期减半 > 燃油滤清器 4万km ¥200~500 ❌ 无需 6万km ¥200~500 直喷车需提前更换 动力系统 > 火花塞 38万km<br>¥4001,200 ❌ 无需 8万km ¥400~1,000 铱金寿命>铂金 > 驱动电机检查 ❌ 无需 2万km/年 ¥0(检测费) 同电车 ¥0(检测费) 4S店常捆绑收费 > 电池健康检测 ❌ 无需 2万km/年 ¥150~800 同电车 ¥150~800 要求导出SOC衰减报告 制动系统 > 刹车片 35万km<br>¥300800/轴 610万km<br>¥300800/轴 58万km<br>¥300800/轴 电车磨损慢但易锈死 > 刹车油 2年/4万km ¥200~400 同燃油车 ¥200~400 同燃油车 ¥200~400 含水率>3%必须换 底盘与流体 > 轮胎 58万km<br>¥4001,500/条 同燃油车(磨损更快) ¥400~1,500/条 同燃油车 ¥400~1,500/条 电车胎压需高10% > 冷却液(发动机) 2年/4万km ¥200~500 ❌ 无需 同燃油车 ¥200~500 混动车需兼容电机冷却 > 变速箱油 68万km(AT/CVT)<br>¥8002,000 ❌ 无需 8万km ¥1,000~2,500 混动变速箱精密,费用更高 高压系统专属 > 充电口维护 ❌ 无需 1万km/6月 ¥0(自检) 同电车 ¥0(自检) 清理氧化物防接触不良 > DC-DC转换器检查 ❌ 无需 4万km ¥0~300 同电车 ¥0~300 故障会导致小电瓶亏电 ⚠️ 关键风险与成本陷阱(2024年更新) 电车保养猫腻: 电池检测费虚高(实际成本≈50元),要求门店出具压差数据(<50mV正常)。 OTA升级后锁电:部分品牌远程降低可用电量,需用OBD工具读取真实SOC。 混动车双重剥削: 发动机清洗智商税:积碳清洗剂无效,核桃砂清洗才有效(每6万公里¥800)。 高压线束老化:8万公里后检查接口氧化,更换单线¥2,000+。 油车淘汰成本: 国六B车型GPF堵塞:每3万公里需高速再生,否则更换费¥3,000~8,000。 💡 用户操作指南 场景 行动建议 年均成本参考 年里程<1万km 油车按时间周期保养(12月/次),电车忽略部分里程要求 油车¥1,500 电车¥600 年里程>2万km 电车成本优势显著,重点维护电池;油车缩短机油周期 油车¥3,800 电车¥900 北方冬季用车 电车加装电池保温套(¥600),油车换低粘度机油(0W-20) +¥800~1,200 长期停放(>1月) 油车:断开电瓶负极;电车:保持电量50% → 防止BMS耗亏 电瓶更换¥500 📉 三类车型5年总成本对比(年均1.5万km) 燃油车:保养费¥12,000 + 油费¥45,000 = ¥57,000 ¥11,700 ¥31,500 注:成本含基础维护+必要耗材,未计算保险、折旧。 💎 终极建议 电车用户: 优先满足电池保修条款(如比亚迪需每年回店检测)。 自换空调滤芯+充电口清理,年省¥600。 油车/混动用户: 学会读取OBD故障码(设备¥50),避免被夸大维修。 正时皮带、变速箱油等大项目提前询价(4S店比连锁贵40%)。 全车型必做: 每月自查:胎压、刹车片厚度(>3mm)、冷却液液位。 每季记录:里程、油耗/电耗、异常噪音 → 早发现故障。 📌 保存此表格至手机相册,保养时逐项核对,拒绝“推荐套餐”! 参考 chatGPT Google

2025/6/22
articleCard.readMore

易学入门

易学是一门深奥的传统文化,普通人入门都比较难。上一篇文章介绍学习了阴历,阳历,阴阳和历之后,就可以进一步学习天干地支,五行八卦了。 风水养生,中医入门,易学学习,下面知识都是必须的!跟随博主,易学从这里入门! 天干地支与甲子 一甲子为何是60年?这中间有数学上,天文上,以及历史原因! 天干地支的数学基础 中国古代的干支纪年法由十天干(甲、乙、丙、丁、戊、己、庚、辛、壬、癸)和十二地支(子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥)组合而成。两者的最小公倍数为 60(10与12的最小公倍数),这意味着天干地支两两相配时,需经过60次组合才能完成一次完整循环,即从“甲子”到“癸亥”共60组,形成“六十甲子”周期。 配对规则: 天干与地支按阳干配阳支、阴干配阴支的顺序组合,避免奇偶错配(如甲子、乙丑合法,甲丑、乙寅则非法)。 每60年完成一轮“干支”排列,周而复始,例如1984年为甲子年,2044年则再次回到甲子年。 天文历法的深层逻辑 行星会合周期的巧合: 土星约30年,两者会合周期为60年(12与30的最小公倍数)。而木星、土星、水星每隔60年会在一条直线上相会,这一现象被视为干支60年周期的天文依据。 螺旋式宇宙运行观: 螺旋式曲线,受多重天体引力影响(如太阳系绕银河系转动)。60年周期仅反映木星、土星等对地球的显著影响,而更长的天狼星、银河系周期(如2.58万年、2.25亿年)则解释了“每个甲子年实际能量不同”的玄学观点。 四时五行的匹配: 历史发展与实际应用 起源争议: 纪年规则的细化: 年:以立春为岁首,而非农历正月初一。例如1984年甲子年实际从1984年立春(约2月4日)至1985年立春。 月、日、时:地支固定对应月份(如正月为寅月),时辰则每5天(60时辰)循环一次,与“五日一候”的节气划分呼应。 计算公式: 天干 = (年份 - 3) ÷ 10 的余数 → 对应甲(1)至癸(10); 地支 = (年份 - 3) ÷ 12 的余数 → 对应子(1)至亥(12)。 文化与哲学内涵 阴阳平衡: 生命周期隐喻: 总结 六十甲子的60年周期,本质是天干地支最小公倍数的数学结果,叠加木星、土星等行星会合的天文规律,再融入阴阳五行哲学形成的复合历法体系。它不仅是中国古代时间计量工具,更是宇宙观与生命观的凝练表达。 天干地支 天干地支是中国古代用来记录时间的一种传统方法,它不仅被广泛应用于历法、命理学等领域,还承载着丰富的文化内涵。如果你想将任意阳历年份转化为干支、月干支、日干支,其实并不复杂。下面,我将结合全网知识库,一步步教你怎么操作。 天干地支一个周期称为一个甲子,一个甲子是60年 阳历年转干支 什么是干支? 干支是由“十天干”和“十二地支”组成的组合。 十天干:甲、乙、丙、丁、戊、己、庚、辛、壬、癸。 十二地支:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。 干支纪年法从“甲子”年开始,每60年一个周期循环。 阳历年转干支的公式 将阳历年份转化为干支,可以使用以下公式: 年干 = (年份 - 3) % 10 年支 = (年份 - 3) % 12 公式中的“%”表示取余数。 月干支的计算 月地支的固定顺序 月地支是固定的,对应农历月份: 1月:寅 2月:卯 3月:辰 4月:巳 5月:午 6月:未 7月:申 8月:酉 9月:戌 10月:亥 11月:子 12月:丑 月天干的计算公式 月天干的计算公式为: 月天干 = (年干 + 月地支的序号 - 1) % 10 日干支的计算 日干支的计算公式 日干支的计算稍微复杂一些,需要用到以下公式: 日干 = (年干 + 月天干 + 日) % 10 日支 = (年支 + 月地支序号 + 日) % 12 注意事项 闰年的影响 闰年2月有29天,其他月份的天数不变。在计算日干支时,需注意闰年对月份的影响。 年干的特殊处理 如果年份小于等于3,年干公式中的“年份 - 3”会出现负数,此时需加10后再取余数。 月地支的固定顺序 月地支是固定的,但需注意农历月份与阳历月份的对应关系。例如,农历新年可能在阳历1月下旬或2月上旬,此时月份的干支可能会发生调整。 总结 通过以上步骤,你可以轻松将任意阳历年份转化为干支、月干支和日干支。虽然计算过程需要一定的耐心,但只要掌握了公式和规则,就能准确无误地完成转换。 天干地支与生肖的关系 **** 生肖的五行属性 十二生肖不仅对应地支,也受五行影响,形成不同的性格和运势特征: 木属性生肖:虎、兔(生机勃勃) 火属性生肖:蛇、马(热情奔放) 土属性生肖:牛、龙、羊、狗(稳重务实) 金属性生肖:猴、鸡(精明果断) 水属性生肖:鼠、猪(智慧灵活) 生肖与天干地支的组合 甲子年(1984):甲(木)+ 子(水)→ 木鼠(智慧、适应力强) 丙寅年(1986):丙(火)+ 寅(木)→ 火虎(勇敢、领导力) 庚申年(1980):庚(金)+ 申(金)→ 金猴(聪明、善于变通) 实际应用 1. 命理学(八字算命) 年、月、日、时的天干地支组合(共8个字)决定一个人的五行强弱,影响性格、事业、婚姻等。 如“五行缺金”的人可能缺乏决断力,需补金(佩戴金属饰品、从事金融行业等)。 2. 风水学 房屋朝向、布局需符合五行平衡,如“坐北朝南”利于水木相生。 3. 择吉日 结婚、开业等重要日子需选择天干地支相生的吉日,如“甲子日”象征新的开始。 小结 天干(10个) + 地支(12个) = 60年一循环的干支纪年(如2024年是甲辰年)。 五行(金木水火土) 影响天干地支的属性,并决定生肖的性格特征。 五行生克 决定命理、风水、运势的平衡。 这套体系不仅用于传统历法,还深深融入中国文化、哲学、医学(如中医五行理论)等领域,影响至今。 计时系统 中国古代日内计时体系全解析:从十二时辰到更鼓制度 十二时辰制的起源与天文基础 中国古代将一昼夜划分为十二时辰(子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥),这一制度始于西周,汉代正式以地支命名,唐宋时期普及。其划分依据包括: 天文观测:根据太阳运行轨迹与十二地支方位对应,如子时对应正北,午时对应正南; 行星周期:木星(岁星)公转周期约12年,土星约30年,两者会合周期60年,形成干支纪年的天文基础; 阴阳平衡:阳时(子、寅、辰等)与阴时(丑、卯、巳等)交替,体现昼夜能量循环。 十二时辰详解:名称、时间与生活实践 每个时辰对应现代2小时,并与动物活动、五行属性深度关联: 子时 (zǐ shí):23:00–01:00 WikipediaHUAXIA | Everything Chinese 丑时 (chǒu shí):01:00–03:00 Wikipedia 寅时 (yín shí):03:00–05:00 Wikipedia 卯时 (mǎo shí):05:00–07:00 Wikipedia 辰时 (chén shí):07:00–09:00 Wikipedia 巳时 (sì shí):09:00–11:00 Wikipedia 午时 (wǔ shí):11:00–13:00 Wikipedia 未时 (wèi shí):13:00–15:00 Wikipedia 申时 (shēn shí):15:00–17:00 Wikipedia 酉时 (yǒu shí):17:00–19:00 Wikipedia 戌时 (xū shí):19:00–21:00 Wikipedia 亥时 (hài shí):21:00–23:00 Wikipedia 时辰 时间段 别称 生肖 五行属性 生活场景 子时 23:00-01:00 夜半 鼠 水 万物蛰伏,中医养三焦经 寅时 03:00-05:00 平旦 虎 木 猛虎晨猎,诗人策马出行 午时 11:00-13:00 日中 马 火 阳气鼎盛,刑场行斩首之刑 酉时 17:00-19:00 日入 鸡 金 家禽归巢,文人观晚霞 特殊规则: 唐代前以整点划分(如子时0:00-2:00),宋以后分"初"“正”(子初23:00、子正0:00); 立春为岁首,时辰划分需结合节气调整,与农历正月初一不完全对应。 计时工具:从日晷到漏刻的技术演进 日晷与圭表 原理:通过太阳投影位置判断时间,晷面刻十二地支方位; 局限:阴雨天失效,仅适用于白天。 地平式日晷:地平日晷的晷面 必须水平;日晷的产生是从观察阳光下竖直物体影子的方向变化而开始的。但它必须在使用其他计时工具进行精确计时的条件下,根据表影随时间变化的实际情况来进行刻划,这显然是不方便的,但**如果采用均匀刻划的方法又会带来相当大的计时误差。**这是地平式日晷重大的缺陷。**晷面与地平面平行,晷针和晷面之间的夹角就是当地的地理纬度,适合低纬度使用,**因其制造容易、安装简单且具有较强的观赏性,适合安放在公园、广场和学校等地。 赤道式日晷:是日晷中最简单、最常见的一种。其晷面平行于赤道面,晷面上的刻度等分,晷针与地轴平行,两端分别指向南北极, **晷针的仰角是当地的地理纬度,北半球的晷针高端指向北极星。**使用时,应注意周围没有遮蔽物遮挡。 日晷原理 由于日晷的使用地支,子对应正南、午对应正北 (中午影子指向正北),所以子、午之间的连线对应了正南–正北的连线,正南–正北的连线也就是地球(地球仪)上链接南北极的经度线,所以经度线又称为"子午线"。经度线(子午线)在星空中的投影,在天文学中称为子午圈。 天球,也是一个球体,虽然在日常生活中,我们只能看见半个,大地平面 (圆-ESWN) 以下的部分,我们是看不见的,但是数学可以帮助我们,根据球体属性,数学可以把天球还原成一个完整的球体。 天顶Z,天底Z’,ZZ’⊥圆-ESWN (大地地平面)。 北天极P,南天极P’,PP’⊥圆-EAWA’(天赤道平面)。 古人认为"大地静止",太阳东升西落,星星、星座东升西落达到一天的最高点是中天(对应弧线 PZASP**‘**),由于是最高点,所以在天文学中称为"上中天";与最高点相对应的,太阳、星星、星座西落后还会到达最低点(对应弧线 PNA’Z’P’),所以在天文学中又称为"下中天"。 现在我们知道,太阳东升西落,星星、星座东升西落,都是地球自转的结果,所以他们的移动轨迹(平面)都是和天赤道(平面)平行的。随着地球的自转,是弧线PZASP**'**扫过整个星空,而主要部分对应的是正南方,对应弧线ZAS。因为我们生活在北半球,天赤道在正南方,为了简化描述,也为了方便普通人的理解,本书我们使用"正南方扫过整个星空"这一简化描述。**注意:**如果我们生活在南半球,就应该使用正北方扫过整个星空这一描述了。 影子,应该是最古老的天文学了,也是现代天文学的基础之一,是第一个用数学详细描述、解释的天文现象。数学还描述了影子长短和太阳高度角之间的三角函数关系。 日规指针CD垂直于地面,太阳从A点到B点,影子由F点移动到E点。直角ΔCDE、直角ΔCDF。 三角函数与反三角函数, 太阳的高度角,我们可以直接测量角度值得到,也可以通过影子长短的三角函数计算得出。日规中,CD的长度是不变的,影子长短的变化是随着太阳高度角而变化的。 日晷,太阳和日晷面(天赤道平面)之间的角度在±23.5°之间变化。假设日晷的半径是R,日晷单面指针的长度也是R,根据三角函数,我们就可以分别计算出夏(冬)至日,春(秋)分日,日晷指针的影子有多长。 圭表原理 圭表,也是一种古老的计时仪器,甚至早于日规、日晷的出现,东周时期就已经形成了完整的形式,测量的就是影子的长短。圭表是正南–正北放置的,每天中午12:00点,太阳在正南方最高点,此时影子最短指向正北方,而圭表主要测量就是此时影子的长度。再根据每天影子长度的变化,来确定二十四节气的日期。 漏刻系统 结构:泄水型(壶水流出)与受水型(浮箭上升),汉代起与十二时辰结合; 刻度演变: 西周:一昼夜100刻(每刻14分24秒); 清代:改为96刻(每刻15分钟),与现代时间兼容。 漏刻的刻箭多为木质,因此能留存下来的很少。图中双龙抱扶的刻箭,位于北京钟鼓楼复原的铜漏刻上,它会随着壶中水的增加而缓缓上升,上升一个刻度约需要14分24秒。 创新计时器 水运仪象台:北宋苏颂发明,集天文观测与自动报时于一体,可精确至刻; 大明殿灯漏:元代郭守敬创制,以水力驱动木偶报时,每刻鸣钟、每更击鼓。 夜间计时:更鼓制度与微观时间单位 五更划分 一更:19:00-21:00(戌时),城门关闭; 三更:23:00-01:00(子时),即“半夜三更”,执行宵禁。 微观时间计量 一炷香≈30分钟(标准线香燃烧时间); 佛教时间单位: 1弹指=7.2秒,1刹那=0.018秒; “须臾”=48分钟,见于《摩诃僧祇律》。 文化衍生:时间哲学与实用价值 中医养生 子午流注:气血按时辰流注特定经络,如寅时(3-5点)宜深睡养肺; 养生口诀:“寅时晨练最宜人,午时小憩养心神”。 命理与占卜 八字命理以出生时辰定命宫,需换算真太阳时(如北京经度误差导致时辰偏移); 占星术中,时辰对应星宿方位,如"斗转星移"观北斗定四季。 文学意象 张继《枫桥夜泊》“夜半钟声到客船”——子时孤寂; 王安石《午枕》“日催红影上帘钩”——午时闲适。 对比现代计时:差异与传承 维度 古代计时 现代计时 划分基准 太阳方位/生物钟 原子钟标准化 最小单位 刹那(0.018秒) 纳秒(10⁻⁹秒) 文化属性 融合五行、生肖、节气 纯物理量 工具演进 日晷→漏刻→机械钟 电子表→卫星授时 结语 从子时的夜半钟声到午时的烈日当空,中国古代计时体系不仅是技术结晶,更是天人合一哲学观的具象化。十二时辰制以自然节律为本,漏刻技术展现精密匠心,而"更鼓声声"则勾勒出古代城市的时空秩序。这种将天文、人文、技术熔于一炉的时间智慧,至今仍在中医、农事与文化仪式中生生不息。 五行、八卦、天干、地支的关系 五行、八卦、天干、地支指的是什么,他们之间是什么关系呢? 天干五行分阴阳,奇阳偶阴两分清; 甲乙为木丙丁火,戊巳为土庚辛金, 任癸为水配五行。 天干地支五行八卦图 五行八卦: 乾(qián)、坤(kūn)、震(zhèn)、巽(xùn)、坎(kǎn)、离(lí)、艮、(gèn)、兑(duì)。 天干地支:甲(jiǎ)乙(yǐ)丙(bǐng)丁(dīng)戊(wù)己(jǐ)庚(gēng)辛(xīn)壬(rén)癸(guǐ)。 十二时辰: 子(zǐ)丑(chǒu)寅(yín)卯(mǎo)辰(chén)巳(sì)午(wǔ)未(wèi)申(shēn)酉(yǒu)戌(xū)亥(hài) 五行 五行概念始见于《尚书》,指的是金、木、水、火、土五种动能。 ◗五行相生:木生火,火生土,土生金,金生水,水生木。 ◗五行相克:木克土,土克水,水克火、火克金、金克木。 ◗五行方位:东方木、南方火、西方金、北方水、中央土。 八卦 八卦相传伏羲所创,称为先天八卦;后,周文王从四时的推移,万物的生长收藏得出周易八卦,即后天八卦。 ◗先天八卦: 乾(☰)、兑(☱)、离(☲)、震(☳)、巽(☴)、坎(☵)、艮(☶)、坤(☷)。 先天八卦方位图如下: ◗后天八卦: “一数坎兮二数坤,三震四巽数中分,五寄中宫六乾是,七兑八艮九离门”。 ◗八卦与五行: 震、巽为木;木旺于春,衰于秋。 离为火;火旺于夏,衰于冬。 乾、兑为金;金旺于秋,衰于夏。 坎为水;水旺于冬,衰于辰戌丑未月。 坤、艮为土;土旺于辰戌丑未月,衰于春。 后天八卦手型图如下: 天干、地支 ◗十天干:甲、乙、丙、丁、戊、己、庚、辛、壬、癸。 ◗天干与五行、方位的关系: 东方甲、乙木; 南方丙、丁火; 中央戊、己土; 西方庚、辛金; 北方壬、癸水。 ◗十二地支:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。 ◗地支与五行的关系: 子水鼠,丑土牛,寅木虎,卯木兔,辰土龙,巳火蛇,午火马,未土羊,申猴金,酉金鸡,戌土犬,亥水猪。 ◗十二地支的时间指向: 按农历月份指向: 子为十一月,丑为十二月,寅为正月,卯为二月,辰为三月,巳为四月,午为五月, 未为六月,申为七月,酉为八月,戌为九月,亥为十月。 五行、八卦、干支方位图如下: 小结 以上即是五行,八卦,天干,地支的关系了。 易学入门 中华文化博大精深,不管是中医养生还是八字命理,都同宗同源。 易经是圣人仰观天象,俯察地理,中通人事,对天地人三才的统一认识。 易经64卦其实就是记了64个小故事,而每一个故事都有六个发展阶段,小故事蕴含大道理,可以指导人将自己的潜意识变成显意识,从而做出在当下最明智的选择,然后不断增加或强化事情发展的确定性,趋吉避凶就是一个不断纠偏和修正的过程。 这里给大家推荐一本书《了凡四训》,这是用来端正学习目的的。《了凡四训》有四个章节,分别是立命之学、改过之法、积善之方和谦德之效。 袁了凡以其毕生的学问与修养,融通儒、道、佛三家思想,以自己的亲身经历,并结合大量真实生动的事例,是其所作的家训,以此教诚他的儿子袁天启认识命运的真相,明辨善恶的标准,改过迁善,同时告诫世人不要被“命”字束缚手脚,要自强不息,改造命运。大家可以自己去搜一搜电子书,或者买一本看看,每次看都有收获!!! 话说:一命二运三风水,四积阴德五读书,六名七相八敬神,九交贵人十养生。其实是有一项也只有第1项是定的,后面的9项都是变化的。发现有啥特殊的地方了吗?变化!!!对吧,“易容术”该听过吧,这里的易就是一个含义,所以大家要对“易”有个基本认知。 但是理论课一般就是先讲易经由来、进化、意义深远balabala一堆,例如,易经有三种,分别是夏代的《连山》、商代的《归藏》,周代的《周易》。《周易》相传系周文王姬昌所作,内容包括《经》和《传》两个部分。《经》主要是六十四卦和三百八十四爻,卦和爻各有说明(卦辞、爻辞),作为占卜之用。《传》包含解释卦辞和爻辞的七种文辞共十篇,统称《十翼》》,相传为孔子所撰。。。。。。 说实话我当初的学习顺序就是这样的,看书也是这样,听课也是这样,有用是肯定有用的,但是枯燥,有点消磨兴趣。 回忆起来,真正的转折点是我查字典和听不同的老师讲课把64卦的拼音标注清楚,能读之后!!! 网上五花八门、乱七八糟读啥的都有,甚至百度百科对部分读音也有争议。 例如,什么屯卦、夬卦,如果网上把这些都读错,基本不用看。但是像小畜卦、噬嗑卦的读音其实是有争议的,比如小畜卦百度百科收录读音是(xù),但是我听多家老师授课,含义确实是积蓄,因为这样就该把(chù)读成(xù)吗?畜就是牛羊啊,我认同应天老师的读音是(chù),此外噬嗑卦有读(shì hé)、(shì kē)、(shì kè)的,我学习完总结用的是(shì kè),就是上下咬合的意思。 乾(qián)坤(kūn)屯(zhūn)蒙(méng)需(xū)讼(sòng)师(shī), 比(bǐ)小(xiǎo)畜(chù)兮(xī)履(lǚ)泰(tài)否(pǐ)。 同(tóng)人(rén)大(dà)有(yǒu)谦(qiān)豫(yù)随(suí), 蛊(gǔ)临(lín)观(guān)兮(xī)噬(shì)嗑(kè)贲(bì)。 剥(bāo)复(fù)无(wú)妄(wàng)大(dà)畜(chù)颐(yí), 大(dà)过(guò)坎(kǎn)离(lí)三(sān)十(shí)备(bèi)。 咸(xián)恒(héng)遁(dùn)兮(xī)及(jí)大(dà)壮(zhuàng), 晋(jìn)与(yǔ)明(míng)夷(yí)家(jiā)人(rén)睽(kuí)。 蹇(jiǎn)解(xiè)损(sǔn)益(yì)夬(guài)姤(gòu)萃(cuì), 升(shēng)困(kùn)井(jǐng)革(gé)鼎(dǐng)震(zhèn)继(jì)。 艮(gèn)渐(jiàn)归(guī)妹(mèi)丰(fēng)旅(lǚ)巽(xùn), 兑(duì)涣(huàn)节(jié)兮(xī)中(zhōng)孚(fú)至(zhì)。 小(xiǎo)过(guò)既(jì)济(jì)兼(jiān)未(wèi)济(jì), 是(shì)为(wéi)下(xià)经(jīng)三(sān)十(shí)四(sì)。 会读就算入门了,就像小朋友背唐诗,反正我家娃当初背诗,并不知道意思,所以大家就当歌诀记忆,先背就对了!!!反正以后有用!!! 《卦序歌》 乾坤屯蒙需讼师,比小畜兮履泰否,同人大有谦豫随, 蛊临观兮噬嗑贲,剥复无妄大畜颐,大过坎离三十备。 咸恒遁兮及大壮,晋与明夷家人睽,蹇解损益夬姤萃, 升困井革鼎震继,艮渐归妹丰旅巽,兑涣节兮中孚至, 小过既济兼未济,是为下经三十四。 前面内容了解卦序歌读音后,多读几遍,读到熟悉为止!!! 熟悉到什么程度呢?自己检验一下,每一句提示第一个字读音,能大概蹦出一整句。 为啥一上来背这个?因为卦序歌是64卦的目录啊!!! 在初学者分不清阴阳那些小杠杠的的时候,这个可以用来查卦解卦,当然,这一阶段的解卦就只是去查查每一卦每一爻所讲的小故事而已。 问题又来啦,爻!!!是嘛玩意? 就是古人结绳记事的叉叉 两个叉叉代表啥?跟卦有什么关系? 得先知道阴阳之分,三个爻排列组合凑成八卦之一,任意两个上下组合凑成六十四卦之一。就是要这样简单粗暴!!! 听过无极生太极,太极化两仪,两仪推四象,四象生八卦吧。不知道啥意思没关系,觉得耳熟就行,结合二进制去理解,两者一对比,是否发现仅有符号不同而已!!! 八卦就这样推出来的,要背的东西又来了,就得混个眼熟耳熟,不要过分纠结为啥长这样,再模拟一下小时候,咱没问为啥1要这样写吧,咱可都是用图形辅助记忆1就是这样写的,1像铅笔,2像鸭子。。。。。。 自己品!!! 话不多说,背就对了,基础打好 记形: 乾三连,坤六断, 震仰盂,艮覆碗, 离中虚,坎中满, 兑上缺,巽下断。 记数: 乾一,兑二, 离三,震四, 巽五,坎六, 艮七,坤八。 上点难度,直接背下面的口诀吧,以后好用!!! 【五行八卦阵口诀】 1、乾三连西北开天 乾卦是三横相连接的,西北方是八卦方位,代表天的符号,开天辟地,故先天数为1。 2、坤六断西南八地 坤卦是三横中间断为六个小分段,八卦方位在西南方,代表地的符号,万物生长于地,归于地,故先天数为8。 3、兑上缺西方双泽 兑卦是三横上一横缺个口,八卦方位在正西方,代表泽的符号,先天数为2。 4、巽下断东南无风 巽卦是三横下一横断开,八卦方位在东南方,代表风的符号,先天数为5。 5、艮覆碗东北齐山 艮卦是三横上一横是实的,下两横是虚的,象打翻的碗那样,八卦方位在东北,代表山的符号,东北方总是山比较多,齐同七,先天数为7。 6、震仰盂东方四雷 震卦是三横下一横是实的,上两横是虚的,象钵盂那样,八卦方位在正东方,代表雷的符号,先天数为4。 7、离中虚南方真火 离卦是三横中间那横是虚的,上下两横是实的,八卦方位在正南方,代表火的符号,三昧真火,故先天数为3。 8、坎中满北方六水 坎卦是三横中间那横是实的,上下两横是虚的,八卦方位在正北方,代表水的符号,先天数为6。 八卦记住后,我们马上就可以进入下一阶段了,组合起来通过形去找到对应的卦名,然后就可以自测一卦了,遇事不决,量子力学!!! 掌上乾坤,天干地支手诀图 电视剧中,常常会看到很多算命先生或者术士,想预测某些事情时,只要在手上掐指推算一下,用不了多久就能轻而易举的做出断语。他们究竟在推算什么?又是依据什么做出的判断呢? 其实这是一种掌上起局法,是古人在用奇门遁甲占算时,将天干、地支、八卦、五行等信息,按照一定规则排入手掌上后,通过默念口诀用大拇指依次点算的方式,达到将天干、地支、八卦与五行相配的目的,以方便占者通过五行的生克等关系来进行推算预测。 把复杂深奥的问题加以简化记忆,以便应用,这有点像计算机程序员,把许多常人看起来复杂烦琐的问题,从中找出规律,总结成几个简单的程序来计算,便方便了许多。 学习奇门遁甲特别是初学者,要记忆许多的基础知识。这个时候我们就可以结合掌上起局法,通过手指配合来记忆就会容易很多。下面就来讲解这种快速的手上记忆法,希望大家看了以后,有朝一日也成为能掐会算的高手! 十二地支记忆法 先来说十二地支。在做预测时,通常右手拿笔做记录,以左手来掐算,所以我们以左手为例。掌心向上,摊开左手掌。以大拇指为笔,像鼠标那样点击掐算。剩余4个指头每个有3条横纹,再加上指头的最尖端,一个手指共4处位置来顺时针排列十二地支。对应位置如下: “子”位:无名指最下面第三条横纹为十二地支的第一位,即子位。 “丑”位:中指最下面第三条横纹为第二位,即丑位。 “寅”位:食指最下面第三横纹为第三位,即寅位。 “卯”位:食指中下节第二条横纹为第四位,即卯位。 “辰”位:食指中上节第一条横纹为第五位,即辰位。 “巳”位:食指尖端为第六位,即已位。 “午”位:中指尖端为第七位,即午位。 “未”位:无名指尖端为第八位,即未位。 “申”位:小拇指尖端为第九位,即申位。 “酉”位:小拇指中上节第一条横纹为第十位,即酉位。 “戌”位:小拇指中下节第二条横纹为第十一位,即戌位。 “亥”位:小拇指最下面第三条横纹为第十二位,即亥位。 地支方位和五行 我们知道,在奇门遁甲九宫格中的方位与现实中的地理位置是正好相反的,即上南下北,左东右西。在手诀图中,也遵循这种规律,以**子为北方、丑寅为东北方、辰巳为东南方、午为南方、未申为西南方、卯为东方、酉为西方、戌亥为西北方。**这样就记住了十二地支的方位。 根据地支方位就能记住地支五行,即在手掌上顺时针旋转,从寅起,每两个地支为同一种五行属性,间隔一个五行为土的地支:寅卯东方木,巳午南方火,申酉西方金,亥子北方水,辰戍丑末四季土。 记住了十二地支的相应手掌位置,再根据此图记忆地支的生克关系就比较简单了。 地支相害 上下相穿,穿心相害。将四根手指均分为上下两块,同一根手指上下对应的两个地支位相害,一共6对相害关系。即食指:寅巳害、卯辰害;中指:丑午害;无名指:子未害;小拇指:申亥害、酉戌害。 地支相冲 地支间两两相对、阴阴相对、阳阳相对为之对冲,反映在手上是呈对角线分布的地支位相冲,即:子午相冲, 丑未相冲, 寅申相冲, 卯酉相冲, 辰戌相冲, 巳亥相冲。如图所示: 地支相合 将四根手指分为两组,由上而下左右相对的两个地支位相合,一共6对相合关系。即子丑合土、寅亥合木、卯戌合火、辰酉合金、巳申合水,午未合土。如下图: 地支相刑 相比于前三者,地支相刑的关系要复杂一些,分为三个地支相刑、两个地支互刑、一个地支自刑,三种情况。即:寅刑巳,巳刑申,申刑寅;丑刑戌,戌刑未,未刑丑;子卯相刑;辰午酉亥自刑。如下图: 根据十二地支掌上图来记忆地支的相冲、合、害关系非常简单快捷。相对于十二地支,在左手上有固定的位置,十天干则是游移不定的。确定了天干在手上的位置,再和对应的地支相搭配组合,便一下子就把天干、地支、六十甲子都放在左手掌上了。 十天干六十甲子记忆法 十二地支的排列位置,无名指最下面第三条横纹即为子位。十天干便从地支子位上,按顺时针方向,开始排布。 甲与子重合、乙与丑重合、丙与寅重合、丁与卯重合、戊与辰重合、己与巳重合、庚与午重合、辛与未重合、壬与申重合、癸与酉重合。 这样一轮下来,排完十天干正好是一甲——甲子旬。按日干支算是十天,按时辰算是十个时辰,也就是一旬。 接下来,按顺时针方向接着从小拇指中下节第二条横纹的戌位开始第二轮排布。甲与戌重合、乙与亥重合、丙与子重合,这样一直排到癸与未重合,排完十天干是二甲——甲戌旬。 以此类推,从地支申上起为甲申,排到癸已,是三甲——甲申旬。从地支午上起为甲午,排到癸卯,是四甲——甲午旬。从地支辰上起为甲辰,排到癸丑,是五甲——甲辰旬。从地支寅上起为甲寅,排到癸亥,是六甲——甲寅旬。 六轮排下来,正好排完六十甲子。每轮与甲搭配的第一位即为六甲旬首。如下图所示: 天干没有固定的位置,它好像一个套在地支外面的齿轮,随地支的变化而动,我们地支某个年份的干支,便能通过顺推逆推的方式推算出其它年份。比如已知2008年为戊子年,算2018年是什么年? 首先地支在手上的位置是固定的,即无名指最下面第三条横纹为子,天干戊便也在这个位置,2018年在2008年之后,便把天干顺时针从子位开始移动十下(2008与2018相隔十年),己、庚、辛、壬……正好又排到了戊,戊就是2018年的天干,戊此时在小拇指中下节第二条横纹的位置,对应地支为戌位。所以2018年就为戊戌年。 十天干方位和五行 十天干记忆五行方位时有一套固定位置。从左手食指起最下节指腹为甲,顺时针旋转到食指的中间节指腹为乙,再向上到食指的上节指腹处为丙,中指的上节指腹为丁,无名指的上节指腹为戊,小拇指的上节指腹为己,小拇指的中间节指腹处为庚,小拇指的下节指腹处为辛,小拇指的下节指腹为壬,中指根部为癸。这一小圈就为十天干在手掌指的准确位置。如下图所示: 这样就得出十天干的方位和五行为:甲乙东方木、丙丁南方火、庚辛西方金、壬癸北方水、戊己中央土。 年月日时四值干支快速推算方法掌诀 A:年干支快速推算法: 1.年天干求法:年尾数4加在十天干掌甲位上,5(乙),6(丙),7(丁),8(戊),9(已),0(庚),1(辛),2(壬),3(癸)。 (见十天干配年命掌诀) 即公元年4尾对应年干为甲,5尾对应乙,6尾对应丙,余仿此类推。 2:年支的求法:1900年一1999年基数为1,2000年一2099年基数为5。(1900年前和2099年后的基数就不必记了,因为这两个基数已经包合200年了) 方法是:把公历年尾数后两位加该年所对应的基数的和除以12所得的佘数对应的地支数,就是该年的地支数。 举例:求2022年的地支? 1:根据上面求天干掌知道年尾2对应十天干掌壬上,故知年天干是壬。 2:求地支:用年尾22+基数5=27 27÷12余数是3,3对应十二地支寅,故知寅是2022年的地支,综合上面知道:2022年的干支是壬寅。余仿此。 B:月干支推算法: 五虎遁歌: 甲已之年丙作首,乙庚之岁戊为首,丙辛之年从庚起,丁壬壬位顺行程,更有戊癸何方觅,甲寅之上好追求。 举例:求2022年5月干支? 根据上面知道2022年干支为壬寅,套入上面歌诀丁壬壬位顺行程,知道壬寅年正月起壬寅,2月癸卯,3月甲辰,4月乙巳,5月丙午。故知壬寅5月的干支为丙午。佘仿此。 C:日干支快速推算法: 此法经本人结合多年实践经验潜心钻研所得。熟练后用心算(用手机计算器更简单)可在数十秒内推算出前后200年内任何一日的干支,比查找万年历方便实用,比流年赶月,大小金钳等方法更简单易记,只要记住四句口诀,四个常数就可以了,简单吧?(当然你也可以推算一干年甚至一万年,一百年只须记住一个常数只可,但是超过前后200年对大多数的人来说已经没有意义了)现在市面上也有很多推算日干支的方法,但不是口诀常数一大堆,就是推算过程非常繁杂,都不实用。本人是一名易学爱好者,常常使用到日干支,查万年历有时又不方便,鉴于此本人下苦功研究出此推算日干支的简易方法。在此拋砖引玉一﹣将此方法发表出来供各位易学爱好者参考。口诀: 乘5除4基加日,双月应须三十,一二自加闰少一,经几大月多加几。 基数(1900–1999基数:9;2000----2099基数:54;1800—1899基数:25; 2100—2199基数:39) 1月不计算在大月内。口诀分解:年尾(后2位数)乘以5+年尾除以4的整商数+当年基数+当日数+当日所经过的大月数(如果是平年一月加1,二月加2,闰年1月不加,2月加1。不管平闰年三月不加数,四五月加1,六七月加2,八月加3,九十月加4,十一,十二月加5.)(如果是双月应加30,单月不加)然后把所得和数除以60,取干支序号: 甲子1,乙丑2,丙寅3—﹣癸亥60.小于60者直取。 (注:1:凡遇农历申子辰年即是公历闰年。 2:能被4整除的公历年份是闰年。此两种方法同样可以求出公历闰年) 举例:求公历1913年5月3日干支? 13*5+13/4(取整商数3)+9(基数)+1(所经大月数,因一月不计算大月,只经三月1个大月)=81, (81/60余21)21是甲申,故知当日是甲申日。 求公历2022年4月28日的干支?22*5+5(22/4取整商数5)+54(基数)+28(日数)+30(四月是双月须加30)+1(平年四月份故加1)=228除以60余48) 48(60干支序号)是辛亥,故知2022年4月28日的干支是辛亥。 其余依法类推。 D:时干支的推算法: 歌诀:甲已还加甲,乙庚丙作初,丙辛从戊起,丁壬庚子居,戊癸何方发,壬子是真途。 举例:求2022年4月18日辰时干支? 根据上面推算得知4月18日干支为辛丑。 根据上面歌诀丙辛从戊起,子时戊子,丑时已丑,寅时庚寅,卯时辛卯,辰时壬辰。故知壬辰为4月18日辰时的干支。余仿此。 看懂了上面如何计算天干地支,就知道了影视剧里面的算命先生左手掐啊掐的是在干什么了吧,现在你学会怎么掐算了! 参考&致谢 如何将任意阳历年转化为年干支、月干支、日干支? 五行、八卦、天干、地支的关系 《易经》入门先学啥? 掌上乾坤,天干地支手诀图 年月日时四值干支快速推算方法掌诀 掐指一算,年龄推算出生干支纪年 时间的天文学 系列教程 全部文章RSS订阅 文化历史系列 文化历史 分类 RSS 订阅 易学入门 阴历、阳历、阴阳和历的来龙去脉 中西医的优缺点 附赠 蠢和笨的区别 笨和蠢是有区别的,笨可以理解,蠢不能原谅! 蠢的本质就是坏的不高明,还喜欢玩心眼。 单纯的笨能听取别人的意见,自己努力赶上别人,而蠢是自作聪明,最大的毛病就是用自己不太聪明的脑子,一意孤行的把事情搞砸,然后再装无辜的推卸责任! 坏人绞尽脑汁,很可能都不如蠢人灵机一动造成的破坏大!

2025/4/7
articleCard.readMore

阴历、阳历、阴阳和历的来龙去脉

大多数人弄不清楚阳历、阴历、公历、农历之间的关系和区别,以至于简单粗暴地认为,阳历=公历,阴历=农历,其实这是大错特错的!本文详细介绍它们之间的区别,来历,以及具体原理!弄懂节气,一文足以! 历法 历法。所谓历法,就是以使用方便为目的,按一定法则,科学地安排年月日的时间长度和它们之间的关系,制定的长时间的计时系统。 历法是在人类生产与生活中逐渐形成的,年、月、日都直接与天体运行周期相关,属于天文学的分支学科。历法能使人类确定每一日在无限的时间中的确切位置并记录历史。 在历史上,在世界各地,存在过千差万别的历法,但就其基本原理来讲,不外乎三种:即太阴历(阴历)、太阳历(阳历)和阴阳历。三种历法各自有各自的优缺点,世界上通行的“公历”实际上是一种太阳历,而中国传统历法——农历属于阴阳合历。 阳历,即太阳历,是根据太阳运行规律制定的历法,观察的是太阳在不同季节的位置变化,以地球绕太阳公转一周为一年,计365.24天(一个回归年),分摊给12个月,每个月平均是30.437天。 阴历,即太阴历,是根据月球运行规律制定的历法,观察的是月相的周期变化,以月球绕行地球一周为一个月,计29.53天,乘以12个月,一年大概是354.36天。 阴历和阳历一年相差10.88天,差不多3年一个闰月,5年2个闰月。中国古代天文学家,观天监精密计算,19年7个闰月,把阴历和阳历结合起来,统一太阳和月亮运行周期的历法就是阴阳和历。 中国的新年,既不是阴历,也不是阳历,而是阴阳和历的新年! 所以把中国新年叫做 lunar new year ,完全就是一种无知的叫法! 太阴历 太阴历就是所谓的阴历,亦称月亮历,其历月是一个朔望月,历年为12个朔望月,约354或355日。太阴历主要根据月亮绕地球运行一周时间为一个月,大月30日,小月29日,即以朔望月作为确定历月的基础,一年为十二个历月的积累的一种历法。 太阴历是中国旧历(农历)的俗称。现今依旧广泛使用的中国传统历法,在古代一般称「黄历」或「皇历」,近代以来又称为汉历、旧历等。但实际上农历并非真正的阴历,而是一种阴阳历(关于阴阳历,下文会做出介绍)。纯粹的阴历有希腊历和伊斯兰历。 阴历定月的依据是月亮的运动规律:月球运行的轨道,名曰白道,白道与黄道同为天体上之两大圆,以五度九分而斜交,月球绕地球一周,出没于黄道者两次,历27日7小时43分11.5秒,为月球公转一周年所需之时间,谓之「恒星月」。唯当月球绕地球之时,地球因公转而位置亦有变动,计前进27度余,而月球每日行13度15分,故月球自合朔,全绕地球一周,复至合朔,实需29日12时44分2.8秒,谓之「朔望月」,习俗所谓一个月,即指朔望月而言。 太阴历是以月亮的圆缺变化为基本周期而制定的历法。世界上现存阴历的典型代表是伊斯兰教的阴历,它的每一个历月都近似等于朔望月,每个月的任何日期都含有月相意义。历年为12个月,平年354天,闰年355天,每30年中有11年是闰年,另19年是平年。纯粹的阴历,可以较为精确地反映月相的变化,但无法根据其月份和日期判断季节,因为它的历年与回归年实际没有关系。 从世界范围看,早期人们都是采用阴历的,这是因为朔望月的周期,比回归年的周期易于确定。后来,知道了回归年,出于农业生产的需要,多改用阳历或阴阳历。现在,只有伊斯兰教国家在宗教事务上还使用纯阴历。 节气与太阴历 太阴历,简称阴历。据可靠史料记载,世界上一些文明古国,都是在数千年前先后制定和运用了太阴历。我国在4200多年前便有了太阴历。太阴历是依据月相的变化周期来制定的,比较直观,容易掌握,故为世人最先采用。 朔 把完全见不到月亮的一天称“朔日”,定为阴历的每月初一。 望 把月亮最圆的一天称“望日”,为阴历的每月十五(或十六)。 从朔到望,是朔望月的前半月;从望到朔,是朔望月的后半月;从朔到望再到朔为阴历的一个月。一个朔望月为29天半,实际上是29天12小时44分3秒。 我国的先民们把月亮圆缺的一个周期称为一个“朔望月”。 阴历一年有12个月,单月是大月(30天),双月是小月(29天),全年共有354天。12个朔望月共为354~367天,二者一年相差0~367天。若不予以调整,经过40年后,其朔望日期便完全颠倒。因此阴历需要安排“闰年”来调整,办法是每30年中给规定的11年中的每年最后一月加1天。阴历经过这样的自我调整以后,每30年和月相的步调差8~16分。并且,由于月亮围绕地球运转和地球围绕太阳运转均非匀速运转,为保持朔日必须在阴历每月初一,也进行必要的调整。因此,有时会出现连续两个阴历大月或连续两个阴历小月的情况。 节气和阴历是我国古代的太阳历和太阴历。它们同时产生于4000年前左右夏朝的前期,当时曾一度对两种历法分别并用。用节气历来记述一年之中寒暑、季节、气候、物候以及农事时段的演变规律和特征;运用阴历主要来记述月、日时段,如每月的初一、十五以及诸多的民族祭祀日期,如春节、元宵节、端午节、七巧节、中秋节、重阳节以及除夕等。沿海地区的人们根据阴历月相判断海洋的潮汐日期和时间等。 直到今天,在我国还有不少人仍然将节气和阴历分别并用。 太阳历 太阳历简称为阳历,其历年为一个回归年,现时国际通用的公历(西历)即为太阳历的一种,在华语文化中,“阳历”一词有时会被特指为公历。太阳历为据地球围绕太阳公转轨道位置,或地球上所呈现出太阳直射点的周期性变化,所制定的历法。 回归阳历 在地球围绕太阳公转过程中,春分阳光直射在赤道时,当天昼夜时间平均,之后北半球的日照时间逐渐变长,气温随之升高,直至夏至阳光直射在北回归线时,日照时间达到最长,接着日照时间逐渐变短,到秋分阳光再次直射赤道,昼夜时间又再平均,此后北半球日照时间逐渐变短,气温跟着降低,直至冬至阳光直射在南回归线时,日照时间达到最短,后来日照时间逐渐变长,再回到春分昼夜平分(南半球的日照时间在夏至时达最短,冬至时达最长,与北半球相反),依此太阳直射点周期性变化,2000年时计365天5小时48分45.19秒(或计365.2421897天),定为一个回归年,所制定的历法,称为“回归阳历”。 以下为回归阳历: 恒星阳历 实际上,太阴历和太阳历之间是可以互相转换的,每一个阴历日期都会有对应的一个阳历日期,换言之,每一个阳历日期也会有一个对应的阴历日期,关于阴历和阳历之间的转换,可查询阴阳历转换频道,快速而准确。 二十四节气歌 传统版本二十四节气歌(新华字典第11版附录) 春雨惊春清谷天, 夏满芒夏暑相连。 秋处露秋寒霜降, 冬雪雪冬小大寒。 每月两节不变更, 最多相差一两天。 上半年来六廿一,(廿:niàn 二十) 下半年是八廿三。 二十四节气黄道位置图 二十四节气是一年内太阳在黄道上的位置变化和引起的地面气候演变次序,将全年平分为二十四等份,并给每个等份起名,这就是二十四节气的由来。 二十四节气黄道位置的寓意 1、立春:斗指东北。太阳黄经为315度。是二十四个节气的头一个节气。其含意是开始进入春天,“阳和起蛰,品物皆春”,过了立春,万物复苏生机勃勃,一年四季从此开始了。 2、雨水:斗指壬。太阳黄经为330°。这时春风遍吹,冰雪融化,空气湿润,雨水增多,所以叫雨水。人们常说:“立春天渐暖,雨水送肥忙”。 3、惊蛰:斗指丁。太阳黄经为345°。这个节气表示“立春”以后天气转暖,春雷开始震响,蛰伏在泥土里的各种冬眠动物将苏醒过来开始活动起 来,所以叫惊蛰。这个时期过冬的虫排卵也要开始孵化。我国部分地区过入了春耕季节。谚语云:“惊蛰过,暖和和,蛤蟆老角唱山歌。”“惊蛰一犁土,春分地气 通。”“惊蛰没到雷先鸣,大雨似蛟龙。” 4、春分:斗指壬。太阳黄经为0°。春分日太阳在赤道上方。这是春季90天的中分点,这一天南北两半球昼夜相等,所以叫春分。这天以后太阳直射 位置便向北移,北半球昼长夜短。所以春分是北半球春季开始。我国大部分地区越冬作物进入春季生长阶段。各地农谚有:“春分在前,斗米斗钱”(广东)、“春 分甲子雨绵绵,夏分甲子火烧天”(四川)、“春分有雨家家忙,先种瓜豆后插秧”(湖北)、“春分种菜,大暑摘瓜”(湖南)、“春分种麻种豆,秋分种麦种 蒜”(安徽)。 5、清明:斗指丁。太阳黄经为15°。此时气候清爽温暖,草木始发新枝芽,万物开始生长,农民忙于春耕春种。从前,在清明节这一天,有些人家都在门口插上杨柳条,还到郊外踏青,祭扫坟墓,这是古老的习俗。 6、谷雨:斗指癸。太阳黄经为30°。就是雨水生五谷的意思,由于雨水滋润大地五谷得以生长,所以,谷雨就是“雨生百谷”。谚云“谷雨前后,种瓜种豆”。 7、立夏:斗指东南。太阳黄经为45°。是夏季的开始,从此进入夏天,万物旺盛大。习惯上把立夏当作是气温显著升高,炎暑将临,雷雨增多,农作物进入旺季生长的一个最重要节气。 8、小满:斗指甲。太阳黄经为60°。从小满开始,大麦、冬小麦等夏收作物,已经结果、籽粒饱满,但尚未成熟,所以叫小满。 9、芒种:北斗指向已。太阳黄经为75°。这时最适合播种有芒的谷类作物,如晚谷、黍、稷等。如过了这个时候再种有芒和作物就不好成熟了。同 时,“芒”指有芒作物如小麦、大麦等,“种”指种子。芒种即表明小麦等有芒作物成熟。芒种前后,我国中部的长江中、下游地区,雨量增多,气温升高,进入连 绵阴雨的梅雨季节,空气非常潮湿,天气异常闷热,各种器具和衣物容易发霉,所以在我国长江中、下游地区也叫“霉雨”。 10、夏至:北斗指向乙。太阳黄经为90°。太阳在黄经90°“夏至点”时,阳光几乎直射北回归线上空,北半球正午太阳最高。这一天是北半球白 昼最长、黑夜最短的一天,从这一天起,进入炎热季节,天地万物在此时生长最旺盛。所心以古时候又把这一天叫做日北至,意思是太阳运生到最北的一日。过了夏 至,太阳逐渐向南移动,北半球白昼一天比一天缩短,黑夜一天比一天加长。 11、小暑:斗指辛。太阳黄经为105°。天气已经很热,但不到是热的时候,所以叫小暑。此时,已是初伏前后。 12、大暑:斗指丙。太阳黄经为120°。大暑是一年中最热的节气,正值勤二伏前后,长江流域的许多地方,经常出现40℃高温天气。要作好防暑降温工作。这个节气雨水多,在“小暑、大暑,淹死老鼠”的谚语,要注意防汛防涝。 13、立秋:北斗指向西南。太阳黄经为135°。从这一天起秋天开始,秋高气爽,月明风清。此后,气温由最热逐渐下降。 14、处暑:斗指戊。太阳黄经为150°。这时夏季火热已经到头了。暑气就要散了。它是温度下降的一个转折点。是气候变凉的象征,表示暑天终止。 15、白露:斗指癸。太阳黄经为165°。天气转凉,地面水汽结露最多。 16、秋分:斗指已。太阳黄经为180°。秋分这一天同春人一样,阳光几乎直射赤道,昼夜几乎相等。从这一天起,阳光直射位置继续由赤道向南半 球推移,北半球开始昼短夜长。依我国旧历的秋季论,这一天刚好是秋季九十天的一半,因而称秋分。但在天文学上规定,北半球的秋天是从秋分开始的。 17、寒露:斗指甲。太阳黄经为195°。白露后,天气转凉,开始出现露水,到了寒露,则露水日多,且气温更低了。所以,有人说,寒是露之气,先白而后寒,是气候将逐渐转冷的意思。而水气则凝成白色露珠。 18、霜降:太阳黄经为210°。天气已冷,开始有霜冻了,所以叫霜降。 19、立冬:太阳黄经为225°。习惯上,我国人民把这一天当作冬季的开始。冬,作为终了之意,是指一年的田间操作结束了,作物收割之后要收藏起来的意思。立冬一过,我国黄河中、下游地区即将结冰,我国各地农民都将陆续地转入农田水利基本建设和其他农事活动中。 20、小雪:太阳黄经为240°。气温下降,开始降雪,但还不到大雪纷飞的时节,所以叫小雪。小雪前后,黄河流域开始降雪(南方降雪还要晚两个节气);而北方,已进入封冻季节。 21、大雪:太阳黄经为255°。大雪前后,黄河流域一带渐有积雪;而北方,已是“千里冰封,万里雪飘荡”的严冬了。 22、冬至:太阳黄经为270°。冬至这一天,阳光几乎直射南回归线,我们北半球白昼最短,黑夜最长,开始进入数九寒天。天文学上规定这一天是北半球冬季的开始。而冬至以后,阳光直射位置逐渐向北移动,北半球的白天就逐渐长了,谚云:吃了冬至面,一天长一线。 23、小寒:太阳黄经为285°。小寒以后,开始进入寒冷季节。冷气积久而寒,小寒是天气寒冷但还没有到极点的意思。 24、大寒:太阳黄经为300°。大寒就是天气寒冷到了极点的意思。大寒前后是一年中最冷的季节。大寒正值三九刚过,四九之初。谚云:“三九四九冰上走”。 大寒以后,立春接着到来,天气渐暖。至此地球绕太阳公转了一周,完成了一个循环。 二十四节气黄道位置与时间 1、春季 立春 太阳位于黄经315度,2月2-5日交节 雨水 太阳位于黄经330度,2月18-20日交节 惊蛰 太阳位于黄经345度,3月5-7日交节 春分 太阳位于黄经0度,3月20-22日交节 清明 太阳位于黄经15度,4月4-6日交节 谷雨 太阳位于黄经30度,4月19-21日交節 2、夏季 立夏 太阳位于黄经45度,5月5-7日交节 小满 太阳位于黄经60度,5月20-22日交节 芒种 太阳位于黄经75度,6月5-7日交节 夏至 太阳位于黄经90度,6月21-22日交节 小暑 太阳位于黄经105度,7月6-8日交节 大暑 太阳位于黄经120度,7月22-24日交节 3、秋季 立秋 太阳位于黄经135度,8月7-9日交节 处暑 太阳位于黄经150度,8月22-24日交节 白露 太阳位于黄经165度,9月7-9日交节 秋分 太阳位于黄经180度,9月22-24日交节 寒露 太阳位于黄经195度,10月8-9日交节 霜降 太阳位于黄经210度,10月23-24日交节 4、冬季 立冬 太阳位于黄经225度,11月7-8日交节 小雪 太阳位于黄经240度,11月22-23日交节 大雪 太阳位于黄经255度,12月6-8日交节 冬至 太阳位于黄经270度,12月21-23日交节 小寒 太阳位于黄经285度,1月5-7日交节 大寒 太阳位于黄经300度,1月20-21日交节 二十四节气及利用 1.二十四节气主要适合的地区为黄河流域,因为这里是中华文明的发源地,农耕文明时期人们总结出的规律。 2.一年约 365天, 24个节气,故每个节气约 15天,根据已熟悉的春分、夏至、秋分、冬至的日期,可以推断其他节气的日期 3.对称问题: ①关于夏至或冬至对称的节气,昼夜长短相同,正午太阳高度相同,日出日落方位相同。 ②关于春分或秋分对称的节气,昼夜长短相反,直射点纬度数相同,但直射半球不同。 赤道,黄道,白道 天文学把太阳在天球上的周年视运动轨迹,既太阳在天空中穿行的视路径的大圆,称为“黄道”(Ecliptic plane),也就是地球公转轨道面在天球上的投影。 赤道(Equator)是地球表面的点随地球自转产生的轨迹中周长最长的圆周线,赤道半径 6378.137Km ;两极半径 6359.752Km;平均半径 6371.012Km ;赤道周长 40075.7Km。 白道 月球绕地球公转的轨道平面与天球相交的大圆。变化周期约为173 天,完成一周需18.6年。 黄道和赤道的区别 由于地球抄的自转轴没有垂直于轨道平面,所以赤道平面不与黄道平行,而有23°26’的夹角,这就是所知的黄赤交角。 赤道平面和黄道平面与地球的交集所形成的大圆分别称为赤道和黄道,这两个平面的交叉点正好在一条地球直径线的两端点,就是著名的二分点(春分点与秋分点)。 太阳从南向北经过的二分点称为春分点或是白羊座第一点,黄道经度,通常以字母λ标示,就以这一点为起点向东从0°到360°。黄道纬度,通常以字母β标示,以黄道为测量的基础平面向北从0°到90°,向南从0°到-90°。春分点同样的也被定义为赤道坐标的原点,赤经的测量也是向东由0到24时,通常以字母α或r.a.表示;赤纬以字母δ或del.表示,由赤道平面向北从0°到90°,向南从0°到-90°。 为什么说黄道和赤道面相交于春分点和秋分点? 因为春分点和秋分点是黄道面与赤道面在地球轨道上的交点,所以其实节气与公历的符合度更高,因为公历是根据太阳的运行而制订的。 黄道面是指地球绕太阳公转的轨道平面,与地球赤道面交角为23°26’。由于月球和其它行星等天体的引力影响地球的公转运动,黄道面在空间的位置总是在不规则地连续变化。但在变动中,任一时间这个平面总是通过太阳中心。黄道面和天球相交的大圆称为黄道。 黄道面就是地球的公转轨道所在平面。由于月球和其它行星等天体的引力影响地球的公转运动,黄道面在空间的位置总是在不规则 地连续变化。但在变动中,任一时间这个平面总是通过太阳中心。黄道面和天球相交的大圆 称为黄道。 赤道面是指地理坐标系上赤道所在的平面(就是在地球上看),黄道面是指地球绕太阳公转的轨道平面,由于地轴是倾斜的,地轴垂直于赤道面,所以赤道面和黄道面始终有一个固定的夹角,叫黄赤交角(23度26分);天赤道是在天球坐标上看的,你可以把它看作赤道面的延伸。 地平线(地平圈)只与你所在的当地纬度有关,就是过当地位置的大圆,你所在的当地纬度是多少,地平圈与赤道面的夹角就是多少如果你站在31度N, 天赤道在你南边(天赤道可算作0度纬线)跟你不在一个平面 北极星在你北方(当然不是正北),北极星所在位置就是地轴指向的位置。 银道、黄道、赤道之间的夹角是多少? 地球绕着自转轴旋转,赤道面与自转轴垂直,并且赤道是过地心的大圆。以太阳为静止参照系,地球绕着太阳旋转,其轨道平面为黄道面,与之相垂直的是黄极。银河系呈现为盘状结构,银道面是星系质量最为集中的平面,与之相垂直的是银极。那么,银道面、黄道面和赤道面之间的夹角是多少呢?太阳系又位于银道面的哪个方向呢? 由于地球的自转轴是倾斜的,所以赤道面和黄道面并非共面,而是存在一个大约23.4°的夹角,这就是地球自转轴的倾角。正是由于地轴倾斜,使得太阳直射地球的区域在不断发生变化,所以地球上才会有四季更替。 太阳目前不在银道面上,而是位于银道面北方大约100光年之处。以银河系中心为静止坐标系,太阳绕着银心旋转。然而,不像地球公转轨道呈现为椭圆形那样,太阳的公转轨道是波浪式的,因为太阳会在银道面上下方反复穿行,周期约为3200万年。 黄道面也没有与银道面处在同一个平面上,它们两者之间的夹角约为60°。关于银道面、黄道面和赤道面之间的角度关系,详见下图: 由于在北半球的夏季期间,地球的夜空朝向银心,所以那时能够看到比冬季更为明亮的银河。 另外,以地球为静止坐标系,月球绕着地球旋转,其轨道平面被称为白道面。 由于白道面和黄道面并不共面,它们之间的夹角约为5.15度。因此,在新月或者满月前后,太阳、地球和月球不一定会在同一条直线上,所以不是每个月都会出现日食和月食。 太阳视运动 1.太阳周日视运动 ①若正东日出、正西日落,说明太阳直射赤道。此时,北半球正午时的太阳总是在南方的天空,南半球正午时的太阳总是在北方的天空。北极点上空的太阳总在南方的天空,南极点上空的太阳总在北方的天空。 ②若太阳在地平圈以上运行的时间短于在地平圈以下的时间,说明该地处于冬半年;反之,说明处于夏半年。 2.日出、日落的方位与昼夜长短变化的关系(北半球) 【拓展深化】熟记特殊纬度夏至冬至日的昼长: 3.日出、日落时物体影子方位的判断 物体影子方位的判断,主要是要判断物体与太阳直射点之间的相互位置。日出日落时物体影子方位的判断,与一年中日出日落方位有关。 (1)二分时,日出时物体影子朝向正西,日落时物体影子朝向正东; ( 2)春分到秋分,日出时物体影子朝向西偏南方向,日落时,物体影子朝向东偏南方向;( 3)秋分到次年春分,日出时物体影子朝向西偏北方向,日落时,物体影子朝向东偏北方向。 4.极圈及其以内地区的太阳高度 ( 1)极昼期间,太阳高度 24小时内都大于或等于零度。 ( 2)刚好出现极昼地区的纬度与直射点纬度和为 90°,且该日该地区太阳高度最小值为 0, ( 3)其他极昼地区 该日太阳高度最小值=当地纬度 -刚好出现极昼地区纬度。 (4)某地某日刚好出现极昼,则该地当日正午太阳高度等于直射点纬度的 2倍。 5.上午和下午的任一时刻,太阳在天球上的方位 Cost =- tanδ× tan φ(δ表示太阳赤纬,φ表示地理纬度, t表示昼弧的一半。在计算时,按照习惯,δ和φ都以北半球为正号,南半球为负号。再算太阳运动的角速度。) 6.大角小角问题:极昼区的正午太阳高度角( H)和子夜太阳高度角( H最小)可用下满公式求得。 H=90° -(α-β); H最小=α+β- 90°(α为当地纬度。β为当天太阳直射点的纬度) 太阳视运动的一般规律 ①同一纬度地区日出、日落方位的时间变化(加上日出、日落方位的偏角可根据公式) 变化呈现如下规律:二分日日出正东、日落正西; 从春分到夏至,偏北且偏角渐大;从夏至到秋分,偏北且偏角渐小; 从秋分到冬至,偏南且偏角渐大;从冬至到次年春分,偏南且偏角渐小。 ②同一日期日出、日落方位的纬度差异 在春分日和秋分日,全球各地(南北极点除外)太阳均从正东方升起,正西方落下; 在北半球夏半年(从春分日到秋分日),全球各地(极昼极夜地区除外)太阳均从东偏北方向升起,西偏北方向落下; 在北半球冬半年(从秋分日到次年春分日),全球各地(极昼极夜地区除外)太阳均从东偏南方向升起,西偏南方向落下。 同一日期,不同纬度地区日出、日落方位的偏角是不一样的,纬度越高,日出、日落方位的偏角就越大。 ③不同纬度地区日出、日落方位的时间变化 (1 )赤道上: 当太阳直射赤道时日出正东、日落正西; 太阳直射北半球期间每天都日出东北、日落西北,且太阳直射点越靠北,日出、日落的方位越偏北,夏至日时日出、日落方位偏离正东、正西方向达到最大值,偏移角度为23°26′ ; 太阳直射南半球期间每天都日出东南、日落西南,且太阳直射点越靠南,日出、日落的方位越偏南,冬至日时日出、日落方位偏离正东、正西方向达到最大值,偏移角度为23°26′ 。 (2 )北半球回归线以北至北极圈地区: 当太阳直射赤道时日出正东、日落正西; 太阳直射北半球期间每天都日出东北、日落西北,且太阳直射点越靠北,日出、日落的方位越偏北,夏至日时日出、日落方位偏离正东、正西方向达到最大值; 太阳直射南半球期间每天都日出东南、日落西南,而且太阳直射点越靠南,日出、日落的方位越偏南,冬至日时日出、日落方位偏离正东、正西方向达到最大值。 (3 )北极圈上: 当太阳直射赤道时日出正东、日落正西; 太阳直射北半球期间每天都日出东北、日落西北,而且太阳直射点越靠北,日出、日落的方位越偏北,夏至日时出现极昼现象,日出、日落方位偏离正东、正西方向达到最大值,日出正北、日落正北; 太阳直射南半球期间每天都日出东南、日落西南,而且太阳直射点越靠南,日出、日落的方位越偏南,冬至日时出现极夜现象,没有日出、日落。 (4 )北极点上: 当太阳直射赤道时太阳终日在地平圈上运动; 太阳直射北半球期间,北极点处于极昼,太阳终日与地平圈平行运动,太阳直射点越靠北,太阳运行的高度越高,日出正北、日落正北; 太阳直射南半球期间北极点处于极夜,没有日出、日落。 **注意:**实际上在一年中仅春秋分日各纬度地区日出、日落太阳方位是一样的。由于地球是一球体,因而除春秋分日外,不同纬度地区日出、日落方位与正东、正西方位的偏角是随纬度的升高而增加的。 01 地球运动 1、近日点在1月初,远日点在7月初。 2、北半球北回归线以北,夏至日正午太阳高度角最大冬至日正午太阳高度角最小。 3、北半球夏半年白昼长于夜,冬半年白昼短于夜。 4、北半球(无极昼的地区)和赤道夏半年日出于东北,日落于西北。日出时间早于地方时6点,晚于地方时18点。 5、从窗户射入房间的阳光,夏季少,冬季多(因为冬季正午太阳高度角小)。 6、日影朝向。北半球夏半年赤道以北(含)日出时影朝西南,日落时日影朝东南。 02 气候 1、地中海气候夏季受副热带高气压控制,炎热干燥;冬季受西风带控制,温和多雨。 2、东亚季风气候区夏季吹东南风,冬季吹西北风。亚热带季风气候夏季高温多雨,冬季温和少雨;温带季风气候夏季高温多雨,冬季寒冷干燥。 3、南亚季风:夏季吹西南风,高温多雨;冬季吹东北风,温和少雨。澳大利亚北部夏季吹西北季风,冬季吹东南季风。 4、辐射逆温现象冬季较多。 5、气压带风带夏季(北半球)北偏,冬季(北半球)南偏。 6、热带草原气候(北半球),夏季受赤道低压控制,草木茂盛,冬季受信风影响,草木枯黄。(天文四季,不是气候四季)。 7、温带海洋性气候全年温和多雨,但冬雨稍多。 8、夏季大陆气温高于海洋,冬季大陆气温低于海洋。北半球大陆上等温线夏季北凸,冬季南凸。 9、北太平洋夏季夏威夷高压强盛,冬季阿留申低压较强。亚欧大陆上的活动中心夏季是印度低压,冬季是亚洲高压。 10、北半球夏季被分割的气压带是副热带高气压带,冬季被分割的是副极地低气压带。 11、华北春季干旱。长江中下游6月中旬到7月上旬梅雨,梅雨后伏旱。北方秋高气爽。 12、昆明准静止锋在冬半年影响云贵高原东部,使贵阳等地冬半年阴雨连绵。 13、对流层高度夏季高于冬季。 14、清明时节雨纷纷。黄梅时节家家雨。华西秋雨。 15、我国的飞船发射一般在北半球冬半年(便于南大洋上测量船的作业)。南大洋也叫“南极海”, “南冰洋”是世界第五个被确定的大洋,由南太平洋、南大西洋和南印度洋各一部分,连同南极大陆周围的威德尔海、罗斯海、阿蒙森海、别林斯高晋海等组成。 03 海洋 1、一般情况同一海区夏季温度高,盐度也高,冬季则反之。 2、河口处径流量大时盐度小,径流量小时盐度大。如长江口夏季盐度小,等盐度线向海洋凸出明显。 3、北印度洋季风洋流,夏顺冬逆(或夏季自西向东流,冬季自东向西流)。 4、索马里沿岸夏季是寒流,冬季是暖流。 5、舟山渔场夏季墨鱼汛,冬季带鱼汛。 6、长芦盐场晒制海盐最好的季节是雨季来临前的一段时间(春夏之交)。海南和台湾的盐场晒盐则是夏天最好。 7、南大洋冬季封冻线范围比夏季大,南半球夏季时南大洋上漂浮的冰山较多。 8、厄尔尼诺现象发生在北半球冬季(圣诞节前后)。 04 河流 1、一般情况是丰水期时河流水补给地下水或湖泊水,枯水期则反之,但有些地区不是这样,比如说地上河。 2、高山冰雪融水补给量大的季节是夏季。 3、季节性积雪融水补给一般在春季。 4、凌汛发生在该地初春和冬初,结冰期一般发生在该地的冬半年。 5、汛期时间与该地降水季节变化有关,如季风气候区夏季形成汛期。 6、枯水期时河口处容易形成咸潮。如珠江口的广州附近冬季易形成咸潮。 7、雪线(夏季固体降水与融雪平衡点为雪)严格来讲没有季节变化,但有些试卷上经常有类似题目,如遇到则夏季高,冬季低。 8、黄淮海平原:春、秋积盐,夏季淋盐,冬季平稳。 9、含沙量在汛期大,枯水期小。 10、黄河小浪底调水调沙一般在汛期来临前的6-7月。 05 植物的季相变化 有季相变化的植被类型如落叶阔叶林和热带草原等,一般夏季荣,冬季枯。谭老师地理工作室综合整理 06 动物迁徙 1、非洲草原上动物的迁徙与植物的枯荣相关,植物的枯荣又受该地的热带草原气候影响,每年的5月至10月,非洲北部的热带草原正处于夏季,气候湿润,形成湿季,草木茂盛,吸引羚羊等动物来此生活,非洲南部热带草原与此相反。 2、在苔原带和亚寒带针叶林带活动的动物夏季北迁到苔原带,冬季迁至亚寒带针叶林带,如驯鹿。 3、北半球候鸟夏季北迁,冬季南迁。 4、天山高山牧场,夏季牧场在林带以上,冬季牧场在林带以下。 07 农事活动 1、越冬作物如冬小麦和油菜等是秋天种,次年初夏收;一般的作物是春种秋收,如春小麦、玉米、大豆、棉花等。早稻收割一般7月中旬前后,晚稻秋天收割(10月底11月初)。 2、棉花在秋季收摘。 3、剪羊毛一般在冬季,因为羊毛品质好。 08 资源利用 1、水资源一般丰歉与降水季节变化、河流补给类型相关,如长江夏季水资源丰富。 2、三峡水库运行:蓄清排浑,一般10月份水库开始蓄水,11月末蓄到正常蓄水位175米,以充分发挥发电与航运效益,汛期前排至145米防洪限制水位。 3、风能利用一般是冬季好于其他季节。 4、沼气利用夏季优于冬季(气温高)。 5、太阳能利用一般是夏季优于冬季,沼气也是夏季好于冬季。 6、伏季休渔。夏季,一般在6-9月左右,各海区不完全一致。 09 自然灾害 1、寒潮在冬半年发生,秋冬春都有可能,以秋季、春季的危害为大。台风、暴雨一般在夏半年发生,旱灾则要注意发生的地区,如华北春旱,长江中下游伏旱;我国台风一般发生在夏、秋季节。 2、地质灾害的滑坡、泥石流看它的诱发因素暴雨发生的季节。如川滇黔交界处夏季强于冬季。 3、水土流失一般在雨季严重,如黄土高原在夏季严重。 010 环境问题 1、赤潮一般发生在夏半年。 2、沙尘暴发生在冬半年(春季较多)。 3、南极臭氧层空洞发生在9月-11月份(南半球的春季,北半球的秋季)。 011 重大科考活动 南北极考察的时间一般选择在该地的夏季,此时温度高且有极昼现象(长城站没有极昼)。 012 旅游 1、青海鸟岛观鸟5月是最佳时机。 2、南方高山宜夏季观赏,因夏季雨水多,多云雾。 3、北方的园林宜夏季观赏。 4、冰雕、雪景、雾凇宜冬季观赏。 阴阳合历 **太阳月亮历(阴阳合历)**是中国古代的一种历法。它将太阳历和月亮历两者的计算方法相结合,使得一年中的每个月可以精确对应到阳历和阴历中的某一天。下面将介绍阴阳合历历法的规则。 阴阳历是许多文化采用的历法,它的日期指示月球的相位,年则与太阳相关。如果太阳年以回归年定义,则阴阳合历会配合其季节;如果是采用恒星年,则历法会以预测满月所在的星座来制定。通常还有一个额外的要求,就是年终的月必须是整数,在这种情况下,大多数的年有12个月,但每2-3年就会有一年有13个月。 闰月,所以这种历法与月相相符,也与地球绕太阳周期运动相符合。在农业气象学中,阴历略微不同于农历、殷历、古历、旧历,是指中国传统上使用的夏历。而在天文学中认为夏历实际上是一种阴阳历。 定朔法 定朔法: 以朔日为周期,计算月份。每个月的开始都由朔日来定。定朔法是以朔日为周期,每个朔日是一年中的新月,以此来计算月份。定朔法的计算方法是通过观测天象,确定每个月的朔日。 定气法 定气法: 以气节为周期,计算节气。将一年分为24节气,每个节气有自己的名称和日期。定气法是以节气为周期,通过观测太阳运行轨迹计算出每个节气的日期,以此来确定每个月的大小。 闰平月 闰、平月: 太阳月亮历中,平年12个月均为29或30天,共计354或355天。但是一年的实际长度为365天5小时48分46秒,因此在定气法和定朔法的基础上,会根据一些规则来加上一个月,称为“闰月”。闰月分为大月和小月,大月为30天,小月为29天。闰月的目的是为了使农历和气温的变化相符合。 纪年法 纪年法: 在太阳月亮历历法中,纪年法也是很重要的一部分。在中国传统文化中,纪年法是根据历史事件来命名年份。目前中国使用的纪年法是公元纪年。 太阳月亮历(阴阳合历)历法是中国古代历法中最为精确的一种,它的规则包括定朔法、定气法、闰、平月、节气和纪年法等。通过这些规则,阴阳合历历法可以精确地计算农历和公历中的日期,是中国传统文化的重要组成部分。 三个历法各有所长,均拥有其特长和优势。太阳月亮历(阴阳合历)历经数千年的发展历程,积累了丰富的研究经验和理论,是中国文化和农业生产的重要组成部分。太阳历(阳历)则更注重公平和准确,广泛应用并具有全球性。 总结 阳历,即太阳历,是根据太阳运行规律制定的历法,观察的是太阳在不同季节的位置变化,以地球绕太阳公转一周为一年,计365.24天(一个回归年),分摊给12个月,每个月平均是30.437天。 阴历,即太阴历,是根据月球运行规律制定的历法,观察的是月相的周期变化,以月球绕行地球一周为一个月,计29.53天,乘以12个月,一年大概是354.36天。 一天,地球自旋一周,太阳起落一次的时间,称为一天。由于地球自转,接受太阳照射的地区一直在变化,地球表面不同地区太阳升起的时间不同,如此,又有了时区之分! **从分类标准来说,只有阳历、阴历、和阴阳合历(简称阴阳历)三种历法。**有了这个认知再探究公历和农历分别属于上述哪一种历法。 结论一:如今世界通行的公历属于阳历的一种,但是,阳历却并不等同于公历,二者是被包含与包含的关系。 公历又称基督纪年,其基本特征就是将耶稣诞生之年作为纪年的开始,即公元元年。1912年清朝灭亡,1949年新中国成立,这里的“1912”和“1949”都是公历概念,意思是耶稣诞生的第1912年和第1949年。而阳历本身,其实并没有这种年份限定。 阳历更像是一个学术概念,精准但并不实用,一年365.24天,一个月30.437天,不是整数,无法应用于日常。公历则不然,它更像对阳历的具象化的表达,把月和年都凑成了整数,平年365天,闰年366天,周期是**“四年一闰”,所以平均下来,每年的天数是(365×3+366×1)÷4=365.25,与阳历回归年中的365.24天之间的误差已经很小了,再加上“百年不闰,四百年再闰”**的进一步精细调整,几乎可以达到完美契合的程度。 结论二:农历既不是纯阳历,也不是纯阴历,而是阴阳历。 由于阳历日期反映的是太阳在黄道上的位置变化,所以阳历的四季更准确。 由于阴历日期反映的是月亮的阴晴圆缺变化,所以阴历的月份更准确。 也就是说,阳历和阴历各有优缺点: 阳历的特点是四季准确,气候规律,但月份与月相盈亏对应不上,1号未必是新月(朔),15号也未必是满月(望)。 阴历的特点是月份准确,初一肯定是新月(朔),十五肯定是满月(望),但与太阳运行周期对应不上,所以时间一长四季就会混乱,夏天变成冬天,冬天变成夏天。 为了取长补短,聪明的中国古人发明了农历,其特点是月份跟着阴历走,年份跟着阳历走,如此一来,便既可以根据月相变化设置月份(月亮变化比太阳变化更易于观察),又不至于四季混乱,简直不要太完美。 也就是说,农历是以阴历为基础,并融合阳历成分而成的一种阴阳合历(阴历为主,阳历为辅)。 但是问题来了,阴历一年是354.36天(29.53×12),阳历一年是365.24天,阴阳合历必须协调农历年与回归年间的这一的矛盾,于是设置了闰月,每2~3年置1闰,具体闰周是19年置7闰。 我们算一下误差。按照阳历算,19个回归年共6939.56天(365.24×19),按照农历算,19个农历年共6939.55天(354.36×19+29.53×7),这个精确度,不得不佩服中国古人的智慧了。 19年是置闰循环的最小周期,这就是为什么19岁那年,阳历生日和农历生日会重合在同一天。 通过以上分析不难看出,农历实际上是比纯阳历(包括公历)、纯阴历更先进的一种历法,只是民国之后,为了与世界接轨,我国才引进了公历,目前是农历与公历并行使用。 (如上图春节这一天,2021年2月12日是公历表述;正月初一是农历表述;而辛丑牛年庚寅月辛卯日是天干地支纪年,也属于阳历的一种。) 结论三:天干地支和二十四节气,也都属于阳历。 阳历不只有公历这一种表达,也并非西方的独创,中国传统的干支历和二十四节气,其实都是阳历,而非阴历。 以二十四节气为例,是依据太阳在回归黄道上的位置制定的,即把太阳周年运动轨迹划分为24等份,每15°为1等份,每1等份为一个节气,始于立春,终于大寒。很明显,观察的是太阳周期,所以是阳历。 (二十四节气划分方法) 仔细观察二十节气在每年的具体日期也会发现,它更趋近于公历日期,而非农历日期。 比如,2020年的立春是2月4日,农历正月十一,2021年的立春是2月3日,农历腊月二十二,2022年的立春是2月4日,农历正月初四……公历的日期,相差不会超过一两天,但农历的日期,却相差甚远,毫无规律可言。 (立春:太阳到达黄经315°,公历2月3—5日交节) 同样的,其他二十三个节气也是这种情况。 这是因为,二十四节气是农耕文明的产物,作用是顺应农时,而阳历比阴历更能反映自然节律和气候变化,所以二十四节气必然使用阳历,而非阴历。这一点或许会与大家的认知相悖,但真实情况的确如此,对农耕影响明显的是阳历(太阳、温度),而非阴历(月亮、月相)。 至于纯阴历,其实并不十分实用,目前也只有少数中西亚国家仍在使用,比如伊斯兰历就属于太阴历。 怎么样,这下弄懂了阳历、阴历、公历、农历之间的关系和区别了吗? 后话 天文历法是建立在长期的天文观测,数学发展,农业生活的基础之上的。没有天文观测,没有数学,没有农业生产活动的历法都是伪造!现今的所有历法中,只有中国历法能往上追溯找到所有的天文观测,数学发展,农业生活发展资料! 参考&致谢 太阴历和太阳历的区别 冷知识:世界三大历法的不同 节气与太阳历 - 《二十四节气》 二十四节气歌(节气编成的诗歌) 什么是赤道,黄道,白道? 二十四节气黄道位置图_奇闻趣事 高考地理中的日晷与太阳视运动,盘点那些与季节有关的考试常考地理现象_直射_时间_中纬度 系列教程 全部文章RSS订阅 文化历史系列 文化历史 分类 RSS 订阅 易学入门 阴历、阳历、阴阳和历的来龙去脉 中西医的优缺点

2025/4/6
articleCard.readMore

windows系统空间清理与速度优化

windows 设计存在天生缺陷,注册表越用越慢,C盘空间越来越小,运行速度越来越慢,空间不够怎么办,本文总结记录一些 windows 空间清理,系统运行速度优化方法。清理系统垃圾,临时文件,老旧驱动,各种无用垃圾等等,给你的C盘空间腾出大量空间,大大加快系统运行速度! 日常使用注意 软件安装目录选择D盘,而不要选择默认的C盘 系统分区时,C盘分区默认大于256GB,最好512GB以上。 SSD 硬盘分区其实2个分区就够了,C 盘不要分区太小,对于ssd 来说,C盘越小,单个SSD底层块写入数据越大,C盘损坏越快!反而C盘分区越大,SSD 寿命也会越长! 经常清理系统垃圾,方法参考本文后面 “系统垃圾清理” 章节 SSD 4k 对齐 等等 如果有更好的方法,可以文章下面留言 系统文件夹转移 Windows 10的用户文件夹迁移到非系统盘 一般有两种方法 (假设用户文件夹由 C:\Users 迁移到 D:\Users) 方法一:创建链接方式 1、在PE环境下 xcopy c:\Users d:\Users /e /v /i /g /h /k /o /x /b /c ren c:\Users oldUsers mklink /D c:\Users d:\Users 这种方法操作简单,但我使用了一段时间,发现部分便携版软件也使用了 mklink 方式来实现便携化(比如portableappk.com 的部分便携版软件,比如微信、QQ、爱奇艺等),这样就产生冲突了,我遇到的结果是桌面应用不能打开,无法登录系统。 所以我推荐方法用预应答文件来实现,操作最好是全新安装系统时进行。 方法二:预应答文件方式 1、新建 unattend.xml <?xml version="1.0" encoding="utf-8"?> <unattend xmlns="urn:schemas-microsoft-com:unattend"> <settings pass="oobeSystem"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <FolderLocations> <ProfilesDirectory>D:\Users</ProfilesDirectory> </FolderLocations> </component> </settings> </unattend> 2、PE下用 WinNT Setup 安装系统,勾选“无人值守安装”,选择 unattend.xml。 方法三:win11 文件夹属性 系统垃圾清理 这个有很多现成的工具,做得都很不错,直接使用即可~ 360安全卫士清理 默认扫描就包含垃圾清理 注意360不少操作要求你下载360全家桶,会严重拖慢系统速度,还有弹窗广告! 火绒垃圾清理 替代360的好选择,够用,轻量,快速! 清理 winsxs 文件夹 长期使用之后,这个 winsxs 文件夹会变得很大,需要优化清理 winsxs文件夹是Windows系统中非常重要的一个文件夹,它存储了系统需要的各种组件和服务包信息。 winsxs文件夹位置在C:\Windows\winsxs。 winsxs文件夹里包含许多Windows系统运行必须的文件,所以普通用户不应该删除这个文件夹的任何内容,否则可能会导致系统崩溃或启动问题。 不过,随着时间推移,winsxs文件夹会越来越大,占用很多存储空间。 所以,用户有时想清理一下它,腾出些存储空间使用。 如果需要清理winsxs文件夹,可以这么做: 方案一: 使用Disk Cleanup工具,选择“清理系统文件”,然后选中“清理服务包备份和更新”选项,删除旧的Windows更新文件,这能减小winsxs文件夹的大小。 这是比较安全的清理方式,但是只能清理部分空间。 Disk Cleanup工具是Windows自带的工具,不需要单独下载安装。 在Windows里,可以这几种方式找到它: 1 开始菜单搜索Disk Cleanup,找到图标打开; 控制面板选“系统和安全”,点击“释放磁盘空间”; 文件资源管理器右键点击要清理的磁盘,选择“属性”,然后点击“磁盘清理”; 在运行窗口输入cleanmgr.exe命令直接打开Disk Cleanup工具。 Disk Cleanup工具由Microsoft提供,使用完全免费。 磁盘清理工具启动后,选择C盘,点击确定。 分析中。 分析完成,可以看见,我的windows更新清理,占用了3.22GB。 勾选windows更新清理,点击确定,就开始清理了。清理完成,重启系统就可以了。 方案二: 使用Dism命令,这是Windows的命令行工具,可以清理winsxs文件夹过期或损坏的系统文件。具体命令是: Dism.exe /online /Cleanup-Image /StartComponentCleanup 运行后会扫描winsxs文件夹并删除一些过期文件,减小文件夹大小。这种方法比较安全,但清理效果有限。 操作步骤: 1 打开windows命令行工具,在开始菜单搜索框输入cmd,然后以管理员身份运行。 2 在命令行窗口,输入命令 Dism.exe /online /Cleanup-Image /StartComponentCleanup 回车。命令执行完成,重启电脑,就可以了。 方案三: 使用sfc /scannow命令, 这个命令会检查winsxs文件夹的系统文件问题并试图修复。在修复过程中,会删除一些损坏或无效的文件,达到稍微清理winsxs文件夹的目的。但主要目的是修复而不是清理,所以清理效果不大。 操作步骤: 1 打开windows命令行工具,在开始菜单搜索框输入cmd,然后以管理员身份运行。 2 在命令行里输入命令 sfc /scannow 回车。命令执行完成,重启电脑,就可以了。 除此之外,Windows本身没有提供直接清空或删除winsxs文件夹的选项,因为这会造成严重问题。 如果真的需要大规模清理或删除winsxs文件夹释放更多存储空间,只能使用第三方工具。 但对普通用户不推荐,以防出现系统问题。 所以,总体来说,对普通用户而言,使用Windows自带的Disk Cleanup工具做有限清理是最安全可靠的选择。 其他命令也可以试试,但都无法彻底或大规模清理winsxs文件夹。 如果有这样的需求,使用第三方工具前需要非常小心,并事先备份系统。 老旧驱动清理 DriverStoreExplorer 下载 DISM++ LiveMirror/dism: Dism++: the best and most powerful utility. via: http://www.chuyu.me/zh-Hans/index.html Chuyu-Team/Dism-Multi-language: Dism++ Multi-language Support & BUG Report 空间占用扫描 spacesniffer SpaceSniffer download | SourceForge.net SpaceSniffer 是一款适用于 Windows 的免费软件磁盘空间分析器,它利用树状图概念来查看当前磁盘使用情况。 图形化面积表示占用空间大小,一目了然,很好用! 网上有汉化版本 参考&致谢 … 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2024/12/17
articleCard.readMore

自建Umami访问统计服务并统计静态博客UV/PV

Umami 是一个开源网页访问统计服务,类似Google Analytics。专注于简单,快速,隐私安全。相对于把数据交给大公司,收到各种各样的限制,各种付费解锁功能,自建访问统计,自己掌握访问统计数据更好!还可以统计网页的PV, UV,功能定制化更高! Umami 统计 安装 创建下面这些文件 # .env UMAMI_DB_USER=umami UMAMI_DB_PASSWORD=password UMAMI_DB_NAME=umami UMAMI_APP_SECRET=vwVXxxxxxLLJWSC # docker-compose.yaml services: umami: build: context: https://github.com/umami-software/umami.git#v2.15.1 args: BASE_PATH: /umami DATABASE_TYPE: postgresql environment: PORT: "4000" DATABASE_URL: postgres://${UMAMI_DB_USER}:${UMAMI_DB_PASSWORD}@umami-db:5432/${UMAMI_DB_NAME} DATABASE_TYPE: postgresql APP_SECRET: ${UMAMI_APP_SECRET} DISABLE_TELEMETRY: 1 healthcheck: test: ["CMD-SHELL", "curl http://localhost:4000/api/heartbeat"] interval: 60s timeout: 15s retries: 5 depends_on: umami-db: condition: service_healthy deploy: resources: limits: memory: 2G cpus: "1" umami-db: image: postgres:15-alpine environment: - POSTGRES_PASSWORD=${UMAMI_DB_PASSWORD} - POSTGRES_USER=${UMAMI_DB_USER} - POSTGRES_DB=${UMAMI_DB_NAME} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 60s timeout: 15s retries: 5 volumes: - umami_pg_data:/var/lib/postgresql/data volumes: umami_pg_data: # docker build and install $ docker compose up --wait --wait-timeout 360 # docker umami logs 查看 $ docker compose logs umami Umami UV / PV 统计显示 Umami 统计了 UV PV 等各种访问数据,比不蒜子详细得多,自建服务也比不蒜子稳定。那么怎么用 Umami 代替不蒜子了? 下文将介绍详细方法 新建 View only 权限的用户 Settings` -> `Users` -> `Create user` -> 填写账号密码,`Role` 选择 `View only` -> `Save Q: 为什么不直接调用 Umami 的 API 获取数据,而是要额外创建一个账户? A: 博客是 静态开源无服务器 的,所有代码都展示在前端,包括 API 调用。而 Umami 的 admin API 权限太大了,如果使用 admin 权限的 API Token,那么这个 token 可以获取、修改、删除所有网站的数据,会有严重的安全隐患。 所以我们需要创建一个 View only 权限的用户,使用这个 低权限的用户的 API Token 来访问我们的浏览量等数据。 新建 Team 并添加用户和网站 Settings -> Teams -> Create team -> 填写名称 -> Save -> 找到刚刚创建的 Team -> Edit -> 复制 Access code,点击 Websites 中点击 Add website 选中你想共享的网站 换一个浏览器登录 Umami(使用View only 权限的用户) -> Settings -> Teams -> Join team -> 输入 Access code -> Join -> 如果没有出错的话,点击 Dashboard 就可以看到你刚刚添加的网站了 获取 View only 用户的 API Token 根据 Umami 的文档,我们可以通过以下方式获取 API Token: POST /api/auth/login 例如 你的网站地址为 example.com,那么你需要使用 View only 的账户密码向 https://example.com/api/auth/login 发送一个 POST 请求,请求体为: { "username": "your-username", "password": "your-password" } 如果成功,你应该会得到以下的结果: { "token": "eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A", "user": { "id": "cd33a605-d785-42a1-9365-d6cad3b7befd", "username": "your-username", "createdAt": "2020-04-20 01:00:00" } } 保存 token 值,并在所有请求中发送带 Bearer <token> 值的 Authorization 标头。请求标头应该如下所示: Authorization: Bearer eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A 发送请求获取数据 这里要用到类似于 postman 的 API 测试工具,可以使用的是开源的 hoppscotch,你也可以使用 curl 或者其他工具。 先分析一下官方文档的 API 接口: GET /api/websites/{websiteId}/stats 有两个必填的 查询参数:startAt 和 endAt,都是 Unix 毫秒时间戳,表示开始时间和结束时间 websiteId 和 startAt 需要我们自己获取 websiteId 可以在 Dashboard -> View details -> 看浏览器栏的地址 https://example.com/websites/{websiteId} 中找到 startAt 可发送 GET 请求到 https://example.com/api/websites/{websiteId},请求头为 Authorization: Bearer eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A 在返回结果中找到 createdAt 字段,这个字段就是 startAt 的值,也就是你的网站创建时间,数据的开始时间 编写页面 代码如下,修改你对应的参数即可运行: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div style="text-align:center;"> <h1>Umami 网站统计</h1> <span>总访问量 <span id="umami-site-pv"></span> 次</span> <span>总访客数 <span id="umami-site-uv"></span> 人</span> </div> <script> // 从配置文件中获取 umami 的配置 const website_id = 'xxx'; // 拼接请求地址 const request_url = 'https://xxx.com' + '/api/websites/' + website_id + '/stats'; const start_time = new Date('2024-01-01').getTime(); const end_time = new Date().getTime(); const token = 'xxxxxx'; // 检查配置是否为空 if (!website_id) { throw new Error("Umami website_id is empty"); } if (!request_url) { throw new Error("Umami request_url is empty"); } if (!start_time) { throw new Error("Umami start_time is empty"); } if (!token) { throw new Error("Umami token is empty"); } const params = new URLSearchParams({ startAt: start_time, endAt: end_time, }); const request_header = { method: "GET", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token, }, }; async function allStats() { try { const response = await fetch(`${request_url}?${params}`, request_header); const data = await response.json(); const uniqueVisitors = data.pageviews.value; // 获取独立访客数 const pageViews = data.pageviews.value; // 获取页面浏览量 let ele1 = document.querySelector("#umami-site-pv") if (ele1) { ele1.textContent = pageViews; // 设置页面浏览量 } let ele2 = document.querySelector("#umami-site-uv") if (ele2) { ele2.textContent = uniqueVisitors; } console.log(uniqueVisitors, pageViews); console.log(data); } catch (error) { console.error(error); return "-1"; } } allStats(); </script> </body> </html> 参考&致谢 umami-software/umami: Umami is a simple, fast, privacy-focused alternative to Google Analytics. Umami UV / PV 统计显示 https://umami.is/docs/websites-api https://umami.is/docs/authentication https://umami.is/docs/website-stats 雷打真孝子,财发狠心,麻绳专挑细处断,恶运专找苦命人! ​ ——俗语赏析 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2024/12/8
articleCard.readMore

🎓3000托福雅思词汇词根版

学习编程不仅仅是掌握代码的语法和逻辑,还需要理解大量的技术术语和专有名词。这些词汇通常来源于英语,因此掌握这些单词是非常重要的。而通过词根背词法,可以更快速地理解和记忆这些编程相关的词汇。 101个句子记完8000个英语单词 Typical of the grassland dwellers of the continent is the American antelope, or pronghorn. Of the millions who saw Haley’s comet in 1986, how many people will live long enough to see it return in the twenty-first century. 1986年看见哈雷慧星的千百万人当中,有多少人能够长寿到足以目睹它在二十一世纪的回归呢? Anthropologists have discovered that fear, happiness, sadness, and surprise are universally reflected in facial expressions. Because of its irritating effect on humans, the use of phenol as a general antiseptic has been largely discontinued. In group to remain in existence, a profit-making organization must, in the long run, produce something consumers consider useful or desirable. The greater the population there is in a locality, the greater the need there is for water, transportation, and disposal of refuse. It is more difficult to write simply, directly, and effectively than to employ flowery but vague expressions that only obscure one’s meaning. With modern offices becoming more mechanized, designers are attempting to personalize them with warmer, less severe interiors. The difference between libel and slander is that libel is printed while slander is spoken. The knee is the joints where the thigh bone meets the large bone of the lower leg. Acids are chemical compounds that, in wate Billie Holiday’s reputation as a great jazz-blues singer rests on her ability to give emotional depth to her songs. Billie Holiday’s作为一个爵士布鲁斯乐杰出歌手的名声建立在能够赋予歌曲感情深度的能力。 Essentially, a theory is an abstract, symbolic representation of what is conceived to be reality. Long before children are able to speak or understand a language, they communicate through facial expressions and by making noises. Thanks to modern irrigation, crops now grow abundantly in areas where once nothing but cacti and sagebrush could live. The development of mechanical timepieces spurred the search for more accurate sundials with which to regulate them. Anthropology is a science in that anthropologists use a rigorous set of methods and techniques to document observations that can be checked by others. Fungi are important in the process of decay, which returns ingredients to the soil, enhances soil fertility, and decomposes animal debris. When it is struck, a tuning fork produces an almost pure tone, retaining its pitch over a long period of time. Although pecans are most plentiful in the southeastern part of the United States, they are found as far north as Ohio and Illinois. Eliminating problems by transferring the blame to others is often called scape-goating. The chief foods eaten in any country depend largely on what grows best in its climate and soil. Over a very large number of trials, the probability of an event’s occurring is equal to the probability that it will not occur. Most substance contract when they freeze so that the density of a substance’s solid is higher than the density of its liquid. The mechanism by which brain cells store memories is not clearly understood. By the middle of the twentieth century, painters and sculptors in the United States had begun to exert a great worldwide influence over art. In the eastern part of New Jersey lies the city of Elizabeth, a major shipping and manufacturing center. Elizabeth Blackwell, the first woman medical doctor in the United States, founded the New York Infirmary, an institution that has always had a completely female medical staff. Elizabeth Blackwell,美国第一个女医生,创建了员工一直为女性纽约诊所。 Alexander Graham Bell once told his family that he would rather be remembered as a teacher of the deaf than as the inventor of the telephone. Alexander Graham Bell曾告诉家人,他更愿意让后人记住他是聋子的老师,而非电话的发明者。 Because its leaves remain green long after being picked, rosemary became associated with the idea of remembrance. Although apparently rigid, bones exhibit a degree of elasticity that enables the skeleton to withstand considerable impact. That xenon could not FORM chemical compounds was once believed by scientists. Research into the dynamics of storms is directed toward improving the ability to predict these events and thus to minimize damage and avoid loss of life. The elimination of inflation would ensure that the amount of money used in repaying a loan would have the same value as the amount of money borrowed. Futurism, an early twentieth-century movement in art, rejected all traditions and attempted to glorify contemporary life by emphasizing the machine and motion. One of the wildest and most inaccessible parts of the United States is the Everglades where wildlife is abundant and largely protected. Everglades是美国境内最为荒凉和人迹罕至的地区之一,此处有大量的野生动植物而且大多受(法律)保护。 Lucretia Mott’s influence was so significant that she has been credited by some authorities as the originator of feminism in the United States. Lucretia Mott’s的影响巨大,所以一些权威部门认定她为美国女权运动的创始人。 The activities of the international marketing researcher are frequently much broader than those of the domestic marketer. The continental divide refers to an imaginary line in the North American Rockies that divides the waters flowing into the Atlantic Ocean from those flowing into the Pacific. Studies of the gravity field of the Earth indicate that its crust and mantle yield when unusual weight is placed on them. The annual worth of Utah’s manufacturing is greater than that of its mining and farming combined. The wallflower is so called because its weak stems often grow on walls and along stony cliffs for support. It is the interaction between people, rather than the events that occur in their lives, that is the main focus of social psychology. No social crusade aroused Elizabeth Williams’ enthusiasm more than the expansion of educational facilities for immigrants to the United States. Quails typically have short rounded wings that enable them to spring into full flight instantly when disturbed in their hiding places. According to anthropologists, the earliest ancestors of humans that stood upright resembled chimpanzees facially, with sloping foreheads and protruding brows. Not until 1866 was the fully successful transatlantic cable finally laid. In his writing, John Crowe Ransom describes what he considers the spiritual barrenness of society brought about by science and technology. John Crowe Ransom在他的著作中描述了他认为是由科学技术给社会带来的精神贫困。 Children with parents whose guidance is firm, consistent, and rational are inclined to possess high levels of self-confidence. The ancient Hopewell people of North America probably cultivated corn and other crops, but hunting and gathering were still of critical importance in their economy. Using many symbols makes it possible to put a large amount of inFORMation on a single map. Anarchism is a term describing a cluster of doctrines and attitudes whose principal uniting feature is the belief that government is both harmful and unnecessary. Probably no man had more effect on the daily lives of most people in the Untied States than did Henry Ford a pioneer in automobile production. The use of well-chosen nonsense words makes possible the testing of many basic hypotheses in the field of language learning. The history of painting is a fascinating chain of events that probably began with the very first pictures ever made. Perfectly matched pearls, strung into a necklace, bring a far higher price than the same pearls told individually. During the eighteenth century, Little Turtle was chief of the Miami tribe whose territory became what is now Indiana and Ohio. Among almost seven hundred species of bamboo, some are fully grown at less than a foot high, while others can grow three feet in twenty-four hours. Before staring on a sea voyage, prudent navigators learn the sea charts, study the sailing directions, and memorize lighthouse 本地s to prepare themselves for any conditions they might encounter. Of all the economically important plants, palms have been the least studied. Buyers and sellers should be aware of new developments in technology can and does affect marketing activities. The application of electronic controls made possible by the microprocessor and computer storage have multiplied the uses of the modern 无效writer. The human skeleton consists of more than two hundred bones bound together by tough and relatively inelastic connective tissues called ligaments. The pigmentation of a pearl is influenced by the 无效 of oyster in which it develops and by the depth, temperature, and the salt content of the water in which the oyster lives. Although mockingbirds superbly mimic the songs and calls of many birds, they can nonetheless be quickly identified as mockingbirds by certain aural clues. Not only can walking fish live out of water, but they can also travel short distances over land. Scientists do not know why dinosaurs became extinct, but some theories postulate that changers in geography, climate, and sea levels were responsible. The science of horticulture, in which the primary concerns are maximum yield and superior quality, utilizes inFORMation derived from other sciences. Snow aids farmers by keeping heart in the lower ground levels, thereby saving the seeds from freezing. Even though the precise qualities of hero in literary words may vary over time, the basic exemplary function of the hero seems to remain constant. People in prehistoric times created paints by grinding materials such as plants and clay into power and then adding water. Often very annoying weeds, goldenrods crowd out less hardy plants and act as hosts to many insect pests. Starting around 7000 B.C., and for the next four thousand years, much of the Northern Hemisphere experienced temperatures warmer than at present. When Henry Ford first sought financial backing for making cars, the very notion of farmers and clerks owning automobiles was considered ridiculous. Though once quite large, the population of the bald eagle across North America has drastically declined in the past forty years. The beaver chews down trees to get food and material with which to build its home. Poodles were once used as retrievers in duck hunting, but the American Kennel Club does not consider them sporting dogs because they are now primarily kept as pets. As a result of what is now know in physics and chemistry, scientists have been able to make important discoveries in biology and medicine. The practice of making excellent films based on rather obscure novels has been going on so long in the United States as to constitute a tradition. Since the consumer considers the best fruit to be that which is the most attractive, the grower must provide products that satisfy the discerning eye. Television the most pervasive and persuasive of modern technologies, marked by rapid change and growth, is moving into a new era, an era of extraordinary sophistication and versatility, which promises to reshape our lives and our world. Television is more than just an electronics; it is a means of expression, as well as a vehicle for communication, and as such becomes a powerful tool for reaching other human beings. Even more shocking is the fact that the number and rate of imprisonment have more than doubled over the past twenty years, and recidivism------that is the rate for re-arrest------is more than 60 percent. His teaching began at the Massachusetts Institute of Technology, but William Rainey Harper lured him to the new university of Chicago, where he remained officially for exactly a generation and where his students in advanced composition found him terrifyingly frigid in the classroom but sympathetic and understanding in their personal conferences. The sloth pays such little attention to its personal hygiene that green algae grow on its coarse hair and communities of a parasitic moth live in the depths of its coat producing caterpillars which graze on its mouldy hair. Its muscles are such that it is quits incapable of moving at a speed of over a kilometer an hour even over the shortest distances and the swiftest movement it can make is a sweep of its hooked arm. Artificial flowers are used for scientific as well as for decorative purposes. They are made from a variety of materials, such as way and glass, so skillfully that they can scarcely be distinguished from natural flowers. Three years of research at an abandoned coal mine in Argonne, Illinois, have resulted in findings that scientists believe can help reclaim thousands of mine disposal sites that scar the coal-rich regions of the United States. When the persuading and the planning for the western railroads had finally been completed, the really challenging task remained: the dangerous, sweaty, backbreaking, brawling business of actually building the lines. Because of the space crunch, the Art Museum has become increasingly cautious in considering acquisitions and donations of art, in some cases passing up opportunities to strengthen is collections. The United States Constitution requires that President be a natural-born citizen, thirty-five years of age or older, who has lived in the United States for a minimum of fourteen years. Arid regions in the southwestern United States have become increasingly inviting playgrounds for the growing number of recreation seekers who own vehicles such as motorcycles or powered trail bikes and indulge in hill-climbing contests or in caving new trails in the desert. Stone does decay, and so tools of long ago have remained when even the bones of the man who made them have disappeared without trace. Insects would make it impossible for us to live in the world; they would devour all our crops and kill our flocks and herds, if it were not for the protection we get from insect-eating animals. It is true that during their explorations they often faced difficulties and dangers of the most perilous nature, equipped in a manner which would make a modern climber shudder at the thought, but they did not go out of their way to court such excitement. There is only one difference between an old man and a young one: the young man has a glorious future before him and old one has a splendid future behind him: and maybe that is where the rub is. I find young people exciting. They have an air of freedom, and they have not a dreary commitment to mean ambitions or love comfort. They are not anxious social climbers, and they have no devotion to material things. I am always amazed when I hear people saying that sport creates goodwill between the nations, and that if only the common peoples of the world could meet one another at football or cricket, they would have no inclination to meet on the battlefield. It is impossible to say simply for the fun and exercise: as soon as the question of prestige arises, as soon as you feel that you and some larger unit will be disgraced if you lose, the most savage combative instincts are around. It has been found that certain bats emit squeaks and by receiving the echoes, they can locate and steer clear of obstacles------or locate flying insects on which they feed. This echo-本地 in bats is often compared with radar, the principle of which is similar. As the time and cost of making a clip drop to a few days and a few hundred dollars, engineers may soon be free to let their imaginations soar without being penalized by expensive failure. 1.abide by(=be faithful to ; obey)忠于;遵守。 sth.sb. to be true) 相信,依赖,信仰. 🎓 1. 词根:act (行动,做) 📝 1.1 含义 行动,做 📚 1.2 词汇列表 action - 行动 activate - 激活 actor - 演员 react - 反应 reaction - 反应 interaction - 互动 enact - 制定(法律) exact - 精确的 transaction - 交易 inactive - 不活跃的 🎓 2. 词根:aqua (水) 📝 2.1 含义 水 📚 2.2 词汇列表 aquarium - 水族馆 aquatic - 水生的 aqueduct - 水渠 aquifer - 含水层 aquaplane - 水上滑板 aquaculture - 水产养殖 subaqueous - 水下的 aquapark - 水上乐园 aquaman - 水行侠 aqua - 水 🎓 3. 词根:bio (生命) 📝 3.1 含义 生命,生物 📚 3.2 词汇列表 biology - 生物学 biography - 传记 biomedical - 生物医学的 biodegradable - 可生物降解的 biopsy - 活组织检查 bioluminescence - 生物发光 biosphere - 生物圈 biodiversity - 生物多样性 biohazard - 生物危害 biotechnology - 生物技术 🎓 4. 词根:chron (时间) 📝 4.1 含义 时间 📚 4.2 词汇列表 chronological - 按时间顺序的 synchronize - 同步 chronic - 慢性的 chronicle - 编年史 anachronism - 时代错误 chronometer - 精密计时器 chronometry - 时间测量 isochronous - 同时的 chronograph - 计时器 chronotherapy - 时间疗法 🎓 5. 词根:dict (说) 📝 5.1 含义 说 📚 5.2 词汇列表 dictate - 命令 dictionary - 字典 predict - 预测 verdict - 判决 contradict - 反驳 diction - 措辞 edict - 法令 dictator - 独裁者 jurisdiction - 管辖权 benediction - 祝福 🎓 6. 词根:duc / duct (引导,带来) 📝 6.1 含义 引导,带来 📚 6.2 词汇列表 conduct - 传导 deduce - 推论 induce - 引导 reduce - 减少 abduct - 绑架 produce - 生产 introduce - 介绍 conductor - 指挥 induction - 感应 aqueduct - 导水管 🎓 7. 词根:fer (带来,拿来) 📝 7.1 含义 带来,拿来 📚 7.2 词汇列表 transfer - 转移 refer - 提到 defer - 推迟 infer - 推断 offer - 提供 prefer - 更喜欢 confer - 授予 ferry - 渡船 circumference - 周长 fertile - 肥沃的 🎓 8. 词根:form (形式,形状) 📝 8.1 含义 形式,形状 📚 8.2 词汇列表 formation - 形成 transform - 转变 inform - 通知 formulate - 规划 conform - 遵守 deform - 变形 uniform - 制服 reform - 改革 informal - 非正式的 formless - 无形的 🎓 9. 词根:graph (写,画) 📝 9.1 含义 写,画 📚 9.2 词汇列表 autograph - 亲笔签名 biography - 传记 photograph - 照片 telegraph - 电报 graphic - 图形的 geography - 地理 cartography - 制图学 graphite - 石墨 bibliography - 参考书目 monograph - 专题论文 🎓 10. 词根:ject (投,扔) 📝 10.1 含义 投,扔 📚 10.2 词汇列表 eject - 驱逐 inject - 注射 project - 项目 reject - 拒绝 object - 物体 subject - 科目 trajectory - 轨道 conjecture - 推测 interject - 插话 deject - 使沮丧 🎓 11. 词根:log / loqu (说,言) 📝 11.1 含义 说,言 📚 11.2 词汇列表 dialogue - 对话 monologue - 独白 prologue - 序言 epilogue - 后记 logic - 逻辑 eloquent - 雄辩的 colloquial - 口语的 soliloquy - 自言自语 apology - 道歉 catalogue - 目录 🎓 12. 词根:manu (手) 📝 12.1 含义 手 📚 12.2 词汇列表 manual - 手册 manufacture - 生产 manuscript - 手稿 manicure - 美甲 manipulate - 操纵 emancipate - 解放 management - 管理 manner - 方式 manifest - 显示 maneuver - 操作 🎓 13. 词根:mit / miss (发送,投) 📝 13.1 含义 发送,投 📚 13.2 词汇列表 transmit - 传输 admit - 承认 emit - 发射 dismiss - 解散 submit - 提交 permit - 允许 mission - 任务 remit - 汇款 omit - 省略 commit - 承诺 🎓 14. 词根:phon (声音) 📝 14.1 含义 声音 📚 14.2 词汇列表 telephone - 电话 microphone - 麦克风 phonograph - 留声机 symphony - 交响乐 euphony - 悦耳之音 cacophony - 刺耳的声音 phonetic - 语音的 homophone - 同音异义词 megaphone - 扩音器 xylophone - 木琴 🎓 15. 词根:port (拿,运) 📝 15.1 含义 拿,运 📚 15.2 词汇列表 transport - 运输 import - 进口 export - 出口 report - 报告 support - 支持 deport - 驱逐 portfolio - 文件夹 airport - 机场 portable - 便携的 portal - 入口 🎓 16. 词根:scrib / script (写) 📝 16.1 含义 写 📚 16.2 词汇列表 describe - 描述 subscribe - 订阅 manuscript - 手稿 transcript - 抄本 inscribe - 铭刻 prescribe - 开药方 script - 剧本 scribble - 潦草地写 ascribe - 归因于 conscription - 征兵 🎓 17. 词根:sect / seg (切割) 📝 17.1 含义 切割 📚 17.2 词汇列表 section - 部分 sector - 部门 dissect - 解剖 intersection - 交叉点 segment - 部分 transect - 横切 bisect - 平分 resect - 切除 insect - 昆虫 subsection - 子部分 🎓 18. 词根:spect / spic (看) 📝 18.1 含义 看 📚 18.2 词汇列表 inspect - 检查 prospect - 前景 respect - 尊重 suspect - 怀疑 spectacle - 景象 spectator - 观众 retrospect - 回顾 conspicuous - 显眼的 aspect - 方面 introspect - 反省 🎓 19. 词根:struct (建造) 📝 19.1 含义 建造 📚 19.2 词汇列表 construct - 建造 structure - 结构 instruct - 指导 destruction - 破坏 obstruct - 阻碍 constructive - 建设性的 restructure - 重组 infrastructure - 基础设施 superstructure - 上层建筑 instruction - 指导 🎓 20. 词根:tact / tag / tang (接触) 📝 20.1 含义 接触 📚 20.2 词汇列表 contact - 联系 intact - 完整的 tactile - 触觉的 contiguous - 连续的 tangent - 切线 tag - 标签 tangible - 有形的 contingent - 偶然的 intangible - 无形的 tagline - 标语 🎓 21. 词根:tele (远) 📝 21.1 含义 远 📚 21.2 词汇列表 telephone - 电话 television - 电视 teleport - 瞬移 telegraph - 电报 telescope - 望远镜 telepathy - 心灵感应 telegram - 电报 teleconference - 电话会议 telecommute - 远程办公 telekinesis - 心灵传动 🎓 22. 词根:temp (时间) 📝 22.1 含义 时间 📚 22.2 词汇列表 temporary - 暂时的 tempo - 节奏 contemporary - 当代的 temporal - 时间的 temperance - 节制 extemporaneous - 即兴的 tempest - 暴风雨 temporary - 临时的 tempus - 时间(拉丁语) temporal - 世俗的 🎓 23. 词根:terr (土地) 📝 23.1 含义 土地 📚 23.2 词汇列表 territory - 领土 terrain - 地形 terrestrial - 陆地的 territorial - 领土的 terrace - 露台 extraterrestrial - 外星的 subterranean - 地下的 inter - 埋葬 terrestrial - 人间的 terror - 恐怖 🎓 24. 词根:vac (空) 📝 24.1 含义 空 📚 24.2 词汇列表 vacuum - 真空 vacant - 空的 vacation - 假期 evacuate - 疏散 vacate - 腾出 vacuous - 空虚的 vacancy - 空缺 evacuation - 疏散 vacuole - 液泡 vacillate - 犹豫 🎓 25. 词根:ven / vent (来) 📝 25.1 含义 来 📚 25.2 词汇列表 adventure - 冒险 convene - 召集 event - 事件 prevent - 防止 invent - 发明 avenue - 大道 venture - 冒险 convention - 大会 intervene - 干涉 revenue - 收入 🎓 26. 词根:vid / vis (看) 📝 26.1 含义 看 📚 26.2 词汇列表 video - 视频 vision - 视力 visit - 访问 visible - 可见的 evidence - 证据 provide - 提供 revise - 修订 supervise - 监督 television - 电视 invisible - 看不见的 🎓 27. 词根:voc / vok (声音,呼唤) 📝 27.1 含义 声音,呼唤 📚 27.2 词汇列表 vocal - 声音的 vocation - 职业 invoke - 调用 provoke - 激怒 revoke - 撤销 advocate - 提倡 evoke - 引起 convocation - 召集 vocabulary - 词汇 vociferous - 喧哗的 🎓 28. 词根:volv / volut (转) 📝 28.1 含义 转 📚 28.2 词汇列表 revolve - 旋转 evolve - 进化 involve - 涉及 revolution - 革命 revolver - 左轮手枪 revolt - 反叛 voluminous - 大量的 convoluted - 复杂的 devolve - 移交 volute - 螺旋形 🎓 29. 词根:vor (吃) 📝 29.1 含义 吃 📚 29.2 词汇列表 voracious - 贪吃的 carnivore - 食肉动物 herbivore - 食草动物 omnivore - 杂食动物 devour - 吞食 voracity - 贪婪 insectivore - 食虫动物 frugivorous - 食果的 granivorous - 食谷的 piscivorous - 食鱼的 🎓 30. 词根:zo (动物) 📝 30.1 含义 动物 📚 30.2 词汇列表 zoo - 动物园 zoology - 动物学 zoologist - 动物学家 zoological - 动物学的 protozoa - 原生动物 zooplankton - 浮游动物 zoonosis - 动物传染病 zoomorphism - 动物形态论 zoogeography - 动物地理学 zootherapy - 动物疗法 🎓 31. 词根:aud (听) 📝 31.1 含义 听 📚 31.2 词汇列表 audible - 听得见的 audience - 观众 auditory - 听觉的 audiobook - 有声书 audit - 审计 auditorium - 礼堂 audio - 声音的 audition - 试镜 inaudible - 听不见的 auditory - 听觉的 🎓 32. 词根:auto (自我) 📝 32.1 含义 自我 📚 32.2 词汇列表 automatic - 自动的 autonomy - 自治 autograph - 签名 autobiography - 自传 automobile - 汽车 autopilot - 自动驾驶仪 autopsy - 尸检 automate - 自动化 autonomous - 自治的 autocracy - 独裁 🎓 33. 词根:bene (好) 📝 33.1 含义 好 📚 33.2 词汇列表 benefit - 好处 benevolent - 善良的 benefactor - 恩人 benign - 良性的 beneficiary - 受益人 beneficial - 有益的 benediction - 祝福 benefactor - 施主 benevolence - 仁爱 benison - 祝福 🎓 34. 词根:capit / capt (头,首) 📝 34.1 含义 头,首 📚 34.2 词汇列表 capital - 首都 captain - 船长 capitulate - 投降 decapitate - 斩首 capitalism - 资本主义 capitol - 国会大厦 caption - 标题 capitation - 人头税 recapitulate - 概括 capitate - 有头的 🎓 35. 词根:cide (杀) 📝 35.1 含义 杀 📚 35.2 词汇列表 homicide - 杀人 suicide - 自杀 pesticide - 杀虫剂 genocide - 种族灭绝 herbicide - 除草剂 insecticide - 杀虫剂 regicide - 弑君 infanticide - 杀婴 patricide - 弑父 matricide - 弑母 🎓 36. 词根:clin / cliv (倾斜,弯曲) 📝 36.1 含义 倾斜,弯曲 📚 36.2 词汇列表 incline - 倾斜 decline - 下降 recline - 斜倚 clinic - 诊所 inclination - 倾向 declination - 倾角 proclivity - 倾向 climax - 高潮 acclivity - 上坡 declivity - 下坡 🎓 37. 词根:clud / clus (关闭) 📝 37.1 含义 关闭 📚 37.2 词汇列表 include - 包括 exclude - 排除 conclude - 结束 seclude - 隐居 preclude - 排除 occlude - 阻塞 recluse - 隐士 include - 包含 exclusion - 排除 closure - 关闭 🎓 38. 词根:cord / card (心) 📝 38.1 含义 心 📚 38.2 词汇列表 cordial - 热情的 cardiac - 心脏的 cardiology - 心脏病学 accord - 一致 discord - 不和 concord - 和谐 record - 记录 cardiogram - 心电图 cardiologist - 心脏病专家 cardio - 有氧运动 🎓 39. 词根:corp (身体) 📝 39.1 含义 身体 📚 39.2 词汇列表 corporation - 公司 corpse - 尸体 corporal - 肉体的 corpulent - 肥胖的 corpus - 文集 corporeal - 有形的 corporate - 企业的 incorporate - 合并 corps - 军团 corporal - 下士 🎓 40. 词根:cred (相信) 📝 40.1 含义 相信 📚 40.2 词汇列表 credit - 信用 credible - 可信的 credibility - 可信度 incredible - 难以置信的 creed - 信条 credential - 证书 discredit - 使丧失信誉 credence - 信任 credulous - 轻信的 incredulous - 怀疑的 🎓 41. 词根:cur / curs (跑,流动) 📝 41.1 含义 跑,流动 📚 41.2 词汇列表 current - 当前的 occur - 发生 recur - 再发生 cursory - 粗略的 excursion - 短途旅行 concurrent - 同时发生的 incur - 招致 precursor - 先驱 cursor - 光标 currency - 货币 🎓 42. 词根:dem / demo (人民) 📝 42.1 含义 人民 📚 42.2 词汇列表 democracy - 民主 demographic - 人口统计学的 epidemic - 流行病 endemic - 地方性的 pandemic - 大流行病 democrat - 民主党人 demagogue - 煽动者 demography - 人口统计学 demotic - 通俗的 demonstrate - 证明 🎓 43. 词根:dorm (睡觉) 📝 43.1 含义 睡觉 📚 43.2 词汇列表 dormitory - 宿舍 dormant - 休眠的 dormancy - 冬眠 dormer - 天窗 dormouse - 睡鼠 dormitive - 安眠药 dormition - 睡眠 dormient - 休眠的 dormitive - 催眠的 dormitive - 安神药 🎓 44. 词根:duc / duct (引导) 📝 44.1 含义 引导 📚 44.2 词汇列表 educate - 教育 deduce - 推断 produce - 生产 induce - 引诱 reduce - 减少 conduct - 引导 introduce - 介绍 duke - 公爵 abduct - 绑架 aqueduct - 导水管 🎓 45. 词根:flu / fluc / flux (流动) 📝 45.1 含义 流动 📚 45.2 词汇列表 fluid - 液体 influence - 影响 fluctuate - 波动 flux - 流量 confluence - 汇合 affluent - 富裕的 effluent - 废水 fluency - 流利 reflux - 逆流 superfluous - 多余的 🎓 46. 词根:fort (强) 📝 46.1 含义 强 📚 46.2 词汇列表 fortify - 加强 fortress - 堡垒 fortitude - 刚毅 effort - 努力 comfort - 舒适 forte - 特长 fortification - 防御工事 reinforce - 增强 comforter - 安慰者 discomfort - 不适 🎓 47. 词根:fract / frag (打破) 📝 47.1 含义 打破 📚 47.2 词汇列表 fracture - 骨折 fragment - 碎片 fragile - 易碎的 fraction - 分数 refract - 折射 infraction - 违反 frangible - 易碎的 fragmentation - 碎裂 fractious - 易怒的 defragment - 磁盘碎片整理 🎓 48. 词根:gen (生,产生) 📝 48.1 含义 生,产生 📚 48.2 词汇列表 generate - 生成 generation - 一代 genetic - 遗传的 genealogy - 家谱 genesis - 起源 genus - 属 genocide - 种族灭绝 indigenous - 本土的 progeny - 后代 genuine - 真实的 🎓 49. 词根:grad / gress (步,走) 📝 49.1 含义 步,走 📚 49.2 词汇列表 graduate - 毕业 grade - 等级 gradual - 逐渐的 progress - 进步 regress - 倒退 congress - 国会 digress - 离题 aggressive - 侵略性的 gradient - 梯度 upgrade - 升级 🎓 50. 词根:graph / gram (写,画) 📝 50.1 含义 写,画 📚 50.2 词汇列表 autograph - 亲笔签名 biography - 传记 telegraph - 电报 photograph - 照片 graphic - 图形的 grammar - 语法 telegram - 电报 diagram - 图表 epigram - 警句 monogram - 字母组合 🎓 51. 词根:grat (感激,愉快) 📝 51.1 含义 感激,愉快 📚 51.2 词汇列表 grateful - 感激的 gratitude - 感谢 congratulate - 祝贺 gratify - 使满足 gratis - 免费的 ingrate - 忘恩负义的人 gratification - 满足 gratuity - 小费 gratifying - 令人满意的 ingratiate - 讨好 🎓 52. 词根:hydr (水) 📝 52.1 含义 水 📚 52.2 词汇列表 hydrate - 水合 hydrant - 消防栓 hydraulic - 液压的 hydroelectric - 水电的 dehydrate - 脱水 hydrolysis - 水解 hydrology - 水文 hydrotherapy - 水疗 hydrophone - 水听器 hydrocarbon - 碳氢化合物 🎓 53. 词根:ject (投掷) 📝 53.1 含义 投掷 📚 53.2 词汇列表 eject - 弹出 inject - 注射 project - 项目 reject - 拒绝 object - 物体 subject - 主题 trajectory - 轨迹 interject - 插话 deject - 使沮丧 conjecture - 推测 🎓 54. 词根:jud / jur / jus (法律) 📝 54.1 含义 法律 📚 54.2 词汇列表 judge - 法官 judiciary - 司法的 jurisdiction - 管辖权 juror - 陪审员 justice - 正义 justify - 辩解 injury - 伤害 prejudice - 偏见 judgment - 判断 jurisprudence - 法学 🎓 55. 词根:labor (劳动,工作) 📝 55.1 含义 劳动,工作 📚 55.2 词汇列表 labor - 劳动 laboratory - 实验室 collaborate - 合作 elaborate - 详细阐述 laborious - 费力的 laborer - 劳工 belabor - 过度说明 laborious - 勤劳的 collaboration - 合作 labored - 吃力的 🎓 56. 词根:luc / lum / lus (光) 📝 56.1 含义 光 📚 56.2 词汇列表 lucid - 清晰的 illuminate - 照亮 luminous - 发光的 translucent - 半透明的 elucidate - 阐明 luminary - 杰出人物 illustrate - 阐明 lustrous - 光泽的 illustrious - 杰出的 luminescent - 发光的 🎓 57. 词根:magn (大) 📝 57.1 含义 大 📚 57.2 词汇列表 magnify - 放大 magnificent - 壮丽的 magnitude - 大小 magnanimous - 宽宏大量的 magnate - 大亨 magnum - 大瓶 magnet - 磁铁 magniloquent - 夸张的 magnanimity - 宽宏大量 🎓 58. 词根:mal (坏,邪恶) 📝 58.1 含义 坏,邪恶 📚 58.2 词汇列表 malicious - 恶意的 malevolent - 恶毒的 malfunction - 故障 malnutrition - 营养不良 malignant - 恶性的 malady - 疾病 malcontent - 不满者 malpractice - 渎职 malfeasance - 不法行为 malodorous - 恶臭的 🎓 59. 词根:man / manu (手) 📝 59.1 含义 手 📚 59.2 词汇列表 manual - 手册 manufacture - 生产 manicure - 修指甲 manipulate - 操纵 manuscript - 手稿 emancipate - 解放 manners - 礼貌 maneuver - 操纵 manifest - 显示 manacle - 手铐 🎓 60. 词根:mater / matr (母,女性) 📝 60.1 含义 母,女性 📚 60.2 词汇列表 maternal - 母亲的 maternity - 母性 matriarch - 女族长 matrix - 矩阵 matron - 主妇 material - 材料 matrimony - 婚姻 matronly - 庄重的 metropolis - 大都市 🎓 61. 词根:mob / mot / mov (移动) 📝 61.1 含义 移动 📚 61.2 词汇列表 mobile - 移动的 motion - 运动 motor - 发动机 remove - 移除 motivate - 激励 promote - 促进 immobile - 不动的 automobile - 汽车 locomotion - 移动 movement - 运动 🎓 62. 词根:morph (形状,形式) 📝 62.1 含义 形状,形式 📚 62.2 词汇列表 morphology - 形态学 amorphous - 无定形的 metamorphosis - 变形 anthropomorphize - 拟人化 polymorph - 多形体 morph - 变形 morpheme - 词素 morphogenesis - 形态发生 morphine - 吗啡 geomorphology - 地貌学 🎓 63. 词根:nat / nasc (出生) 📝 63.1 含义 出生 📚 63.2 词汇列表 native - 本地的 innate - 天生的 natal - 出生的 renascent - 新生的 nascent - 初生的 nation - 国家 nature - 自然 prenatal - 产前的 cognate - 同源的 naturalize - 使入籍 🎓 64. 词根:nym / nom / nomen (名字) 📝 64.1 含义 名字 📚 64.2 词汇列表 synonym - 同义词 antonym - 反义词 pseudonym - 假名 nomenclature - 命名法 nominal - 名义上的 anonymous - 匿名的 eponym - 名字来源 homonym - 同音异义词 misnomer - 用词不当 denomination - 教派 🎓 65. 词根:nov (新) 📝 65.1 含义 新 📚 65.2 词汇列表 novel - 小说 novice - 新手 innovate - 创新 renovate - 翻新 novelty - 新奇 novelize - 小说化 novitiate - 见习 supernova - 超新星 novelism - 新颖主义 innovation - 创新 🎓 66. 词根:onym (名字) 📝 66.1 含义 名字 📚 66.2 词汇列表 synonym - 同义词 antonym - 反义词 pseudonym - 假名 homonym - 同音异义词 anonymous - 匿名的 patronymic - 父名的 eponym - 名字来源 toponym - 地名 onymous - 署名的 heteronym - 异音同形词 🎓 67. 词根:pac / peac (和平) 📝 67.1 含义 和平 📚 67.2 词汇列表 pacify - 安抚 pacific - 和平的 pacifist - 和平主义者 appease - 平息 peaceful - 和平的 pacifier - 安抚奶嘴 peacekeeper - 维和人员 pacification - 平定 pacifism - 和平主义 appeasement - 绥靖 🎓 68. 词根:path (感情,疾病) 📝 68.1 含义 感情,疾病 📚 68.2 词汇列表 sympathy - 同情 empathy - 移情 apathy - 冷漠 pathology - 病理学 psychopath - 精神病患者 pathetic - 可怜的 antipathy - 反感 pathogen - 病原体 pathos - 感伤 telepathy - 心灵感应 🎓 69. 词根:ped / pod (脚) 📝 69.1 含义 脚 📚 69.2 词汇列表 pedal - 踏板 pedestrian - 行人 podium - 讲台 tripod - 三脚架 podiatrist - 足病医生 pedicure - 足疗 centipede - 蜈蚣 biped - 两足动物 impede - 阻碍 expedition - 探险 🎓 70. 词根:phil (爱) 📝 70.1 含义 爱 📚 70.2 词汇列表 philosophy - 哲学 philanthropy - 慈善 bibliophile - 藏书家 philharmonic - 爱乐的 audiophile - 音响发烧友 philology - 语言学 anglophile - 亲英者 philosopher - 哲学家 cinephile - 影迷 philematology - 接吻学 🎓 71. 词根:phon (声音) 📝 71.1 含义 声音 📚 71.2 词汇列表 telephone - 电话 phonetic - 语音的 microphone - 麦克风 symphony - 交响乐 phonograph - 留声机 phonics - 语音学 cacophony - 刺耳的声音 euphony - 悦耳的声音 homophone - 同音异义词 megaphone - 扩音器 🎓 72. 词根:port (携带,传送) 📝 72.1 含义 携带,传送 📚 72.2 词汇列表 transport - 运输 export - 出口 import - 进口 report - 报告 support - 支持 portable - 便携的 deport - 驱逐 portfolio - 文件夹 airport - 机场 porter - 搬运工 🎓 73. 词根:psych (精神,心灵) 📝 73.1 含义 精神,心灵 📚 73.2 词汇列表 psychology - 心理学 psychiatry - 精神病学 psychic - 灵媒 psychoanalysis - 精神分析 psychotherapy - 心理治疗 psychosomatic - 身心的 psychopath - 精神病患者 psychosis - 精神病 psyche - 心灵 psychogenic - 心因性的 🎓 74. 词根:rupt (破裂) 📝 74.1 含义 破裂 📚 74.2 词汇列表 rupture - 破裂 erupt - 爆发 interrupt - 打断 corrupt - 腐败的 disrupt - 扰乱 bankrupt - 破产的 abrupt - 突然的 irrupt - 闯入 incorruptible - 廉洁的 rupture - 断裂 🎓 75. 词根:sci (知道) 📝 75.1 含义 知道 📚 75.2 词汇列表 science - 科学 conscience - 良心 conscious - 有意识的 omniscient - 无所不知的 prescient - 预知的 scientific - 科学的 unconscious - 无意识的 subconscious - 潜意识的 nescient - 无知的 scientist - 科学家 🎓 76. 词根:scrib / script (写) 📝 76.1 含义 写 📚 76.2 词汇列表 describe - 描述 manuscript - 手稿 prescription - 处方 inscription - 铭文 transcribe - 抄写 script - 剧本 subscribe - 订阅 scribble - 涂鸦 postscript - 附言 circumscribe - 限制 🎓 77. 词根:sect / seg (切割) 📝 77.1 含义 切割 📚 77.2 词汇列表 section - 部分 segment - 段 dissect - 解剖 bisect - 二分 sectarian - 宗派的 intersection - 交叉点 sector - 部门 segregate - 隔离 insect - 昆虫 transect - 横切 🎓 78. 词根:sent / sens (感觉) 📝 78.1 含义 感觉 📚 78.2 词汇列表 sense - 感觉 sensation - 感觉 sensitive - 敏感的 sentiment - 感情 consent - 同意 resent - 怨恨 sensory - 感觉的 nonsense - 无意义的话 sentient - 有感觉能力的 dissent - 不同意 🎓 79. 词根:sol (单独) 📝 79.1 含义 单独 📚 79.2 词汇列表 solo - 独奏 solitary - 孤独的 solitude - 孤独 soliloquy - 独白 desolate - 荒凉的 isolate - 隔离 absolute - 绝对的 solipsism - 唯我论 solicitude - 关心 sole - 唯一的 🎓 80. 词根:spec / spic / spect (看) 📝 80.1 含义 看 📚 80.2 词汇列表 spectator - 观众 inspect - 检查 respect - 尊重 spectacle - 景象 speculate - 推测 retrospect - 回顾 aspect - 方面 prospect - 前景 suspicion - 怀疑 introspect - 反省 🎓 81. 词根:struct (建造) 📝 81.1 含义 建造 📚 81.2 词汇列表 construct - 建造 structure - 结构 destruction - 破坏 instruct - 指导 instrument - 工具 obstruct - 阻碍 reconstruct - 重建 infrastructure - 基础设施 instructor - 教练 superstructure - 上层建筑 🎓 82. 词根:tact / tag / tang / tig (接触) 📝 82.1 含义 接触 📚 82.2 词汇列表 tactile - 触觉的 contact - 接触 intact - 完整的 tangent - 切线 contiguous - 接壤的 tangible - 有形的 tactic - 战术 tag - 标签 integrate - 整合 contingent - 依情况而定的 🎓 83. 词根:tele (远) 📝 83.1 含义 远 📚 83.2 词汇列表 telephone - 电话 television - 电视 telegraph - 电报 telescope - 望远镜 telepathy - 心灵感应 telecommute - 远程办公 teleconference - 远程会议 telekinesis - 心灵遥控 telegram - 电报 telemetry - 遥测 🎓 84. 词根:terr (土地) 📝 84.1 含义 土地 📚 84.2 词汇列表 territory - 领土 terrain - 地形 terrestrial - 陆地的 subterranean - 地下的 terrace - 露台 territorial - 领土的 extraterrestrial - 外星的 terra - 地球 terrarium - 玻璃容器 terrigenous - 陆源的 🎓 85. 词根:therm (热) 📝 85.1 含义 热 📚 85.2 词汇列表 thermometer - 温度计 thermal - 热的 thermostat - 恒温器 thermodynamics - 热力学 geothermal - 地热的 thermocouple - 热电偶 hypothermia - 体温过低 isotherm - 等温线 thermoplastic - 热塑性的 thermochemistry - 热化学 🎓 86. 词根:tract (拉,拖) 📝 86.1 含义 拉,拖 📚 86.2 词汇列表 attract - 吸引 contract - 合同 distract - 分散注意力 extract - 提取 retract - 撤回 tractor - 拖拉机 traction - 牵引力 subtract - 减去 protract - 延长 detract - 贬低 🎓 87. 词根:urb (城市) 📝 87.1 含义 城市 📚 87.2 词汇列表 urban - 城市的 suburb - 郊区 urbanize - 城市化 urbane - 彬彬有礼的 urbanity - 都市风格 suburban - 郊区的 urbicide - 城市毁灭 urbanism - 城市主义 urbanology - 城市学 urbanite - 城市居民 🎓 88. 词根:vac (空) 📝 88.1 含义 空 📚 88.2 词汇列表 vacuum - 真空 vacant - 空的 vacation - 假期 evacuate - 疏散 vacancy - 空缺 vacuous - 空虚的 vacate - 腾出 vacuole - 液泡 vacillate - 犹豫 evanescent - 逐渐消失的 🎓 89. 词根:ven / vent (来) 📝 89.1 含义 来 📚 89.2 词汇列表 convene - 召集 intervene - 干涉 adventure - 冒险 event - 事件 invent - 发明 prevent - 阻止 convenient - 方便的 venue - 场地 advent - 到来 venture - 风险投资 🎓 90. 词根:ver (真) 📝 90.1 含义 真 📚 90.2 词汇列表 verify - 验证 verdict - 裁决 veracity - 真实性 veritable - 名副其实的 verisimilitude - 逼真 aver - 断言 verily - 确实 veracity - 诚实 veracious - 诚实的 verism - 写实主义 🎓 91. 词根:vid / vis (看) 📝 91.1 含义 看 📚 91.2 词汇列表 video - 视频 visual - 视觉的 visible - 可见的 visit - 访问 vision - 视力 evident - 明显的 supervise - 监督 revise - 修改 television - 电视 invisible - 隐形的 🎓 92. 词根:voc / vok (声音,叫喊) 📝 92.1 含义 声音,叫喊 📚 92.2 词汇列表 vocal - 声音的 vocabulary - 词汇 advocate - 提倡 evoke - 唤起 provoke - 挑衅 invoke - 调用 revoke - 撤销 convocation - 召集 vocation - 职业 vociferous - 喧哗的 🎓 93. 词根:vol (意志,意愿) 📝 93.1 含义 意志,意愿 📚 93.2 词汇列表 volunteer - 志愿者 volition - 意志 benevolent - 慈善的 malevolent - 恶意的 voluntary - 自愿的 voluntaryism - 自愿主义 involuntary - 非自愿的 voluntarism - 志愿主义 volunteerism - 志愿精神 volunteerism - 志愿服务 🎓 94. 词根:volv / volut (转动,卷) 📝 94.1 含义 转动,卷 📚 94.2 词汇列表 revolve - 旋转 evolve - 进化 involve - 涉及 revolution - 革命 revolver - 左轮手枪 convoluted - 复杂的 devolve - 下放 involution - 卷入 voluble - 健谈的 revolutionary - 革命性的 🎓 95. 词根:arch (统治,首领) 📝 95.1 含义 统治,首领 📚 95.2 词汇列表 monarch - 君主 anarchy - 无政府状态 oligarchy - 寡头政治 archenemy - 大敌 patriarch - 家长 matriarch - 女家长 archbishop - 大主教 architect - 建筑师 archaeology - 考古学 hierarchy - 等级制度 🎓 96. 词根:aster / astr (星星) 📝 96.1 含义 星星 📚 96.2 词汇列表 asteroid - 小行星 astronomy - 天文学 astronaut - 宇航员 disaster - 灾难 asterisk - 星号 astrology - 占星术 astronomical - 天文的 astrophysics - 天体物理学 astrobiology - 天体生物学 astrolabe - 星盘 🎓 97. 词根:bell (战争) 📝 97.1 含义 战争 📚 97.2 词汇列表 rebellion - 叛乱 belligerent - 好战的 bellicose - 好战的 antebellum - 战前的 rebel - 反叛 belligerence - 好战性 postbellum - 战后的 bell - 战争 bellicosity - 好战性 rebelled - 反叛的 🎓 98. 词根:bio (生命) 📝 98.1 含义 生命 📚 98.2 词汇列表 biology - 生物学 biography - 传记 biodegradable - 可生物降解的 biological - 生物的 biome - 生物群系 biopsy - 活检 biosphere - 生物圈 biohazard - 生物危害 antibiotic - 抗生素 microbiology - 微生物学 🎓 99. 词根:chron (时间) 📝 99.1 含义 时间 📚 99.2 词汇列表 chronology - 年表 synchronize - 同步 anachronism - 时代错误 chronicle - 编年史 chronometer - 精密时计 chronograph - 计时器 chronological - 按时间顺序的 chronic - 慢性的 isochronous - 等时的 chronotherapy - 时间疗法 🎓 100. 词根:cide / cis (切,杀) 📝 100.1 含义 切,杀 📚 100.2 词汇列表 homicide - 谋杀 suicide - 自杀 genocide - 种族灭绝 pesticide - 杀虫剂 incision - 切口 circumcise - 割礼 concise - 简明的 precision - 精度 scissors - 剪刀 decide - 决定 🎓 101. 词根:clud / clus (关闭) 📝 101.1 含义 关闭 📚 101.2 词汇列表 include - 包含 exclude - 排除 seclude - 隔离 conclude - 结束 preclude - 阻止 occlude - 阻塞 recluse - 隐士 seclusion - 隐居 enclose - 围住 exclusion - 排除 🎓 102. 词根:cred (相信) 📝 102.1 含义 相信 📚 102.2 词汇列表 credible - 可信的 credit - 信用 credibility - 可信度 incredible - 难以置信的 discredit - 使丧失信誉 credential - 资格证书 credulous - 轻信的 accredit - 授权 creed - 信条 credence - 信任 🎓 103. 词根:cur / cour (跑,流动) 📝 103.1 含义 跑,流动 📚 103.2 词汇列表 current - 当前的 occur - 发生 recur - 复发 cursive - 草书的 course - 课程 courier - 快递员 concur - 同意 incur - 招致 excursion - 远足 concurrent - 同时发生的 🎓 104. 词根:dict (说) 📝 104.1 含义 说 📚 104.2 词汇列表 dictate - 口述 dictionary - 字典 predict - 预测 verdict - 裁决 contradict - 反驳 benediction - 祝福 jurisdiction - 管辖权 diction - 措辞 edict - 法令 indict - 起诉 🎓 105. 词根:duc / duct (引导,带来) 📝 105.1 含义 引导,带来 📚 105.2 词汇列表 conduct - 指导 induce - 引导 reduce - 减少 produce - 生产 educate - 教育 deduct - 扣除 introduce - 介绍 abduct - 绑架 deduce - 推断 aqueduct - 渡槽 🎓 106. 词根:fac / fact / fect (做,制作) 📝 106.1 含义 做,制作 📚 106.2 词汇列表 factory - 工厂 manufacture - 制造 affect - 影响 effect - 效果 benefactor - 施恩者 facilitate - 促进 defect - 缺陷 perfect - 完美的 satisfaction - 满意 infect - 感染 🎓 107. 词根:fer (带来,拿来) 📝 107.1 含义 带来,拿来 📚 107.2 词汇列表 transfer - 转移 refer - 提及 conference - 会议 ferry - 渡船 infer - 推断 defer - 延期 offer - 提供 suffer - 遭受 prefer - 更喜欢 fertile - 肥沃的 🎓 108. 词根:fid (信任,忠诚) 📝 108.1 含义 信任,忠诚 📚 108.2 词汇列表 fidelity - 忠诚 confide - 倾诉 confident - 自信的 infidelity - 不忠 fiduciary - 信托的 perfidious - 背信弃义的 confidant - 密友 diffident - 缺乏自信的 perfidy - 不忠 infidel - 异教徒 🎓 109. 词根:fin (结束,界限) 📝 109.1 含义 结束,界限 📚 109.2 词汇列表 final - 最后的 finish - 完成 infinite - 无限的 finite - 有限的 confine - 限制 refine - 精炼 define - 定义 affinity - 亲和力 finial - 顶饰 finale - 终曲 🎓 110. 词根:flu / flux (流动) 📝 110.1 含义 流动 📚 110.2 词汇列表 fluid - 流体 influence - 影响 fluent - 流利的 fluctuate - 波动 flux - 流动 influx - 流入 reflux - 逆流 efflux - 流出 superfluous - 多余的 confluence - 汇合 🎓 111. 词根:form (形状) 📝 111.1 含义 形状 📚 111.2 词汇列表 form - 形式 formation - 形成 deform - 使变形 reform - 改革 inform - 通知 uniform - 制服 conform - 遵从 transform - 转变 formula - 公式 formal - 正式的 🎓 112. 词根:fract / frag (打破) 📝 112.1 含义 打破 📚 112.2 词汇列表 fracture - 骨折 fragment - 碎片 fragile - 脆弱的 fraction - 分数 infraction - 违反 refract - 折射 fractious - 易怒的 fragmentary - 不完整的 diffract - 衍射 frangible - 易碎的 🎓 113. 词根:gen (出生,产生) 📝 113.1 含义 出生,产生 📚 113.2 词汇列表 generate - 产生 genetics - 遗传学 genesis - 起源 genre - 类型 genealogy - 家谱 genius - 天才 genocide - 种族灭绝 gender - 性别 genotype - 基因型 generic - 通用的 🎓 114. 词根:grad / gress (步,走) 📝 114.1 含义 步,走 📚 114.2 词汇列表 graduate - 毕业 gradual - 逐渐的 progress - 进步 regress - 倒退 congress - 国会 aggressive - 侵略性的 degrade - 降级 digress - 离题 transgress - 违反 retrogress - 倒退 🎓 115. 词根:graph / gram (写,画) 📝 115.1 含义 写,画 📚 115.2 词汇列表 autograph - 签名 biography - 传记 photograph - 照片 diagram - 图表 telegram - 电报 grammar - 语法 graphic - 图形的 epigram - 警句 phonograph - 留声机 paragraph - 段落 🎓 116. 词根:hydr (水) 📝 116.1 含义 水 📚 116.2 词汇列表 hydrate - 水合物 dehydrate - 脱水 hydraulic - 液压的 hydrogen - 氢 hydrophobia - 恐水症 hydroelectric - 水力发电的 hydrology - 水文学 hydroplane - 水上飞机 hydrant - 消防栓 hydrotherapy - 水疗法 🎓 117. 词根:ject (投掷) 📝 117.1 含义 投掷 📚 117.2 词汇列表 eject - 弹出 inject - 注射 reject - 拒绝 project - 项目 subject - 科目 object - 物体 trajectory - 轨迹 interject - 插话 deject - 使沮丧 conjecture - 推测 🎓 118. 词根:jud (判断) 📝 118.1 含义 判断 📚 118.2 词汇列表 judge - 法官 judgment - 判决 prejudice - 偏见 judicious - 明智的 adjudicate - 裁定 judicial - 司法的 judiciary - 司法系统 prejudicial - 有害的 misjudge - 错误判断 judgemental - 好评判的 🎓 119. 词根:jur / jus (法律,正义) 📝 119.1 含义 法律,正义 📚 119.2 词汇列表 jury - 陪审团 jurisdiction - 管辖权 justice - 正义 injury - 伤害 perjury - 伪证 jurisprudence - 法学 justify - 辩解 adjure - 恳请 juridical - 法律的 justifiable - 合理的 🎓 120. 词根:lat (携带,拿来) 📝 120.1 含义 携带,拿来 📚 120.2 词汇列表 translate - 翻译 relate - 关联 collate - 校对 correlate - 相关 dilate - 扩大 superlative - 最高级的 elated - 兴高采烈的 ablate - 消融 dilatory - 拖延的 prolate - 长球形的 🎓 121. 词根:leg / lect (选择,收集,读) 📝 121.1 含义 选择,收集,读 📚 121.2 词汇列表 elect - 选举 select - 选择 collect - 收集 legible - 清晰可读的 lecture - 讲座 intellect - 智力 neglect - 忽视 eligible - 有资格的 recollect - 回忆 legend - 传说 🎓 122. 词根:log / logue (言语,话语) 📝 122.1 含义 言语,话语 📚 122.2 词汇列表 dialogue - 对话 monologue - 独白 epilogue - 尾声 prologue - 序言 logistics - 物流 logical - 合乎逻辑的 apology - 道歉 catalogue - 目录 analogy - 类比 logarithm - 对数 🎓 123. 词根:luc / lum / lus (光) 📝 123.1 含义 光 📚 123.2 词汇列表 lucid - 清晰的 illuminate - 照亮 luminous - 发光的 translucent - 半透明的 elucidate - 阐明 luminary - 杰出人物 luster - 光泽 luminescence - 发光 lucidity - 明朗 lustrous - 光亮的 🎓 124. 词根:man (手) 📝 124.1 含义 手 📚 124.2 词汇列表 manual - 手工的 manipulate - 操纵 manufacture - 制造 manuscript - 手稿 emancipate - 解放 maneuver - 演习 mandate - 授权 manifest - 表明 manacle - 手铐 manicure - 美甲 🎓 125. 词根:mater / matr (母亲) 📝 125.1 含义 母亲 📚 125.2 词汇列表 maternal - 母亲的 maternity - 母性 matriarch - 女家长 matrix - 矩阵 matrilineal - 母系的 matron - 主妇 material - 材料 matrimony - 婚姻 matronly - 主妇似的 🎓 126. 词根:morph (形状) 📝 126.1 含义 形状 📚 126.2 词汇列表 morphology - 形态学 amorphous - 无定形的 metamorphosis - 变形 polymorphous - 多形的 morpheme - 词素 anthropomorphize - 拟人化 morph - 变形 morphogenetic - 形态发生的 isomorph - 同形体 heteromorph - 异形体 🎓 127. 词根:mort (死亡) 📝 127.1 含义 死亡 📚 127.2 词汇列表 mortal - 凡人 immortal - 不朽的 mortality - 死亡率 mortuary - 太平间 mortgage - 抵押 moribund - 垂死的 postmortem - 验尸 mortician - 殡葬师 🎓 128. 词根:mut (改变) 📝 128.1 含义 改变 📚 128.2 词汇列表 mutate - 突变 mutation - 突变 immutable - 不变的 commute - 交换 transmute - 变化 permutation - 排列 mutual - 相互的 mutability - 易变性 commutation - 减刑 mutagen - 诱变剂 🎓 129. 词根:nat / nasc (出生) 📝 129.1 含义 出生 📚 129.2 词汇列表 native - 本土的 nation - 国家 innate - 天生的 natal - 出生的 cognate - 同源的 nascent - 初生的 renascent - 复兴的 neonatal - 新生的 nativity - 出生 prenatal - 产前的 🎓 130. 词根:nov (新) 📝 130.1 含义 新 📚 130.2 词汇列表 novel - 小说 innovate - 创新 renovate - 翻新 novice - 新手 novelty - 新颖 novella - 中篇小说 supernova - 超新星 novelization - 小说化 novitiate - 见习期 innovation - 创新 🎓 131. 词根:omni (全,遍) 📝 131.1 含义 全,遍 📚 131.2 词汇列表 omniscient - 无所不知的 omnipotent - 全能的 omnipresent - 无处不在的 omnivore - 杂食动物 omnivorous - 杂食的 omnibus - 综合性的 omnidirectional - 全向的 omniparity - 全面平等 omnifarious - 各种各样的 omnimax - 全景显示的 🎓 132. 词根:pac (和平) 📝 132.1 含义 和平 📚 132.2 词汇列表 pacify - 安抚 pacific - 平静的 pacifist - 和平主义者 pact - 条约 pacification - 平定 pacemaker - 起搏器 pacifier - 安抚奶嘴 appease - 平息 pacifism - 和平主义 pacificator - 调解人 🎓 133. 词根:path / pathy (感情,疾病) 📝 133.1 含义 感情,疾病 📚 133.2 词汇列表 empathy - 同理心 sympathy - 同情 apathy - 冷漠 pathology - 病理学 psychopath - 精神病患者 telepathy - 心灵感应 antipathy - 反感 pathetic - 可怜的 sociopath - 反社会者 pathogen - 病原体 🎓 134. 词根:ped / pod (脚) 📝 134.1 含义 脚 📚 134.2 词汇列表 pedal - 踏板 pedestrian - 行人 tripod - 三脚架 podium - 讲台 expedite - 加快 impede - 阻碍 podiatry - 足病学 pedicure - 足部护理 quadruped - 四足动物 bipedal - 两足的 🎓 135. 词根:phon (声音) 📝 135.1 含义 声音 📚 135.2 词汇列表 telephone - 电话 phonograph - 留声机 microphone - 麦克风 symphony - 交响乐 phonetic - 语音的 homophone - 同音异义词 cacophony - 刺耳的声音 euphony - 悦耳的声音 polyphonic - 复调的 phonology - 音系学 🎓 136. 词根:port (携带,运送) 📝 136.1 含义 携带,运送 📚 136.2 词汇列表 transport - 运输 export - 出口 import - 进口 portable - 便携的 support - 支持 report - 报告 portfolio - 投资组合 deport - 驱逐出境 portal - 门户 airport - 机场 🎓 137. 词根:pos / posit (放置) 📝 137.1 含义 放置 📚 137.2 词汇列表 position - 位置 deposit - 存款 compose - 组成 impose - 强加 propose - 提议 expose - 暴露 oppose - 反对 positive - 积极的 decompose - 分解 repository - 仓库 🎓 138. 词根:prim / prin (第一,首要) 📝 138.1 含义 第一,首要 📚 138.2 词汇列表 primary - 主要的 prime - 最好的 primitive - 原始的 principal - 校长,主要的 principle - 原则 prince - 王子 primer - 启蒙书 primeval - 原始的 primogeniture - 长子继承权 primacy - 首位 🎓 139. 词根:psych (心灵,精神) 📝 139.1 含义 心灵,精神 📚 139.2 词汇列表 psychology - 心理学 psyche - 心灵 psychic - 心灵的 psychiatrist - 精神科医生 psychopath - 精神病患者 psychosis - 精神病 psychotherapy - 心理治疗 psychosomatic - 身心的 psychoanalysis - 精神分析 psychotropic - 影响精神的 🎓 140. 词根:qui / quit (安静,休息) 📝 140.1 含义 安静,休息 📚 140.2 词汇列表 quiet - 安静 quit - 放弃 acquit - 宣告无罪 quiescent - 静止的 tranquil - 宁静的 requiem - 安魂曲 acquiesce - 默许 inquiry - 调查 inquisitive - 好奇的 disquiet - 不安 🎓 141. 词根:rupt (破裂) 📝 141.1 含义 破裂 📚 141.2 词汇列表 rupture - 破裂 interrupt - 打断 disrupt - 扰乱 bankrupt - 破产的 erupt - 爆发 corrupt - 腐败的 ruptured - 破裂的 irrupt - 闯入 abrupt - 突然的 incorruptible - 廉洁的 🎓 142. 词根:sci (知,学) 📝 142.1 含义 知,学 📚 142.2 词汇列表 science - 科学 conscious - 有意识的 omniscient - 无所不知的 prescient - 预知的 scientific - 科学的 conscience - 良心 subconscious - 潜意识的 unconscious - 无意识的 nescient - 无知的 conscientious - 认真的 🎓 143. 词根:scrib / script (写) 📝 143.1 含义 写 📚 143.2 词汇列表 describe - 描述 inscribe - 铭刻 prescribe - 开处方 transcribe - 抄写 script - 剧本 manuscript - 手稿 subscription - 订阅 postscript - 附言 proscribe - 禁止 scripture - 经文 🎓 144. 词根:sect (切,割) 📝 144.1 含义 切,割 📚 144.2 词汇列表 section - 部分 sector - 部门 dissect - 解剖 intersect - 相交 bisect - 二等分 transect - 横切 insect - 昆虫 resection - 切除术 subsection - 分节 vivisection - 活体解剖 🎓 145. 词根:sent / sens (感觉) 📝 145.1 含义 感觉 📚 145.2 词汇列表 sensation - 感觉 sensitive - 敏感的 sense - 感觉 sensory - 感觉的 sentiment - 情感 consent - 同意 resent - 怨恨 nonsense - 胡说 dissent - 异议 sensual - 感官的 🎓 146. 词根:sequ / secut (跟随) 📝 146.1 含义 跟随 📚 146.2 词汇列表 sequence - 顺序 consequence - 结果 subsequent - 随后的 consecutive - 连续的 sequel - 续集 execute - 执行 persecute - 迫害 prosecute - 起诉 obsequious - 奉承的 inconsequential - 不重要的 🎓 147. 词根:sol (孤独,独自) 📝 147.1 含义 孤独,独自 📚 147.2 词汇列表 solitary - 孤独的 solitude - 孤独 solo - 独奏 desolate - 荒凉的 isolate - 隔离 soliloquy - 独白 solipsism - 唯我论 solitaire - 单人纸牌游戏 solus - 单独的 solicitous - 热心的 🎓 148. 词根:spec / spect / spic (看,观察) 📝 148.1 含义 看,观察 📚 148.2 词汇列表 inspect - 检查 spectacle - 景象 spectator - 观众 suspect - 怀疑 aspect - 方面 prospect - 前景 introspective - 内省的 circumspect - 谨慎的 retrospective - 回顾的 conspicuous - 显眼的 🎓 149. 词根:spir (呼吸) 📝 149.1 含义 呼吸 📚 149.2 词汇列表 inspire - 激励 respiratory - 呼吸的 aspire - 渴望 expire - 过期 perspire - 出汗 spirit - 精神 conspire - 密谋 respiration - 呼吸 transpire - 发生 inspiration - 灵感 🎓 150. 词根:sta / stat / stit (站立) 📝 150.1 含义 站立 📚 150.2 词汇列表 stand - 站立 status - 地位 statue - 雕像 station - 车站 constant - 恒定的 substitute - 替代 institute - 机构 obstacle - 障碍 statistic - 统计 stature - 身高 🎓 151. 词根:struct (建造) 📝 151.1 含义 建造 📚 151.2 词汇列表 construct - 建造 structure - 结构 destruct - 破坏 instruct - 指导 infrastructure - 基础设施 obstruct - 阻塞 restructure - 重组 instruction - 指令 constructive - 建设性的 superstructure - 上层建筑 🎓 152. 词根:tact / tag / tang (触摸) 📝 152.1 含义 触摸 📚 152.2 词汇列表 tactile - 触觉的 intact - 完整的 contact - 接触 tangent - 切线 tangible - 有形的 contagious - 传染性的 contiguous - 邻近的 tact - 机智 tangible - 实际的 tag - 标签 🎓 153. 词根:tele (远) 📝 153.1 含义 远 📚 153.2 词汇列表 telephone - 电话 television - 电视 telegraph - 电报 teleport - 远距离传送 telescope - 望远镜 telepathy - 心灵感应 telecommute - 远程办公 telephoto - 长焦镜头 teleconference - 远程会议 telemetry - 遥测 🎓 154. 词根:tempor (时间) 📝 154.1 含义 时间 📚 154.2 词汇列表 temporary - 临时的 contemporary - 当代的 temporal - 时间的 temporize - 拖延 extemporaneous - 即兴的 temporality - 短暂性 temporarily - 临时地 tempo - 速度 temporarily - 暂时地 temporalize - 使时间化 🎓 155. 词根:terr (土地,地球) 📝 155.1 含义 土地,地球 📚 155.2 词汇列表 terrain - 地形 territory - 领土 terrestrial - 地球的 subterranean - 地下的 terrace - 阳台 extraterrestrial - 外星的 terrestrial - 陆地的 territorial - 领土的 terrarium - 玻璃容器(种植植物或养殖小动物) terrain - 地势 🎓 156. 词根:theo (神,神学) 📝 156.1 含义 神,神学 📚 156.2 词汇列表 theology - 神学 theocracy - 神权政治 theocrat - 神权政治者 theosophy - 神智学 pantheon - 众神庙 apotheosis - 神化 theophany - 神显 monotheism - 一神论 polytheism - 多神论 atheism - 无神论 🎓 157. 词根:therm (热) 📝 157.1 含义 热 📚 157.2 词汇列表 thermometer - 温度计 thermal - 热的 thermostat - 恒温器 thermodynamics - 热力学 hypothermia - 体温过低 thermos - 保温瓶 geothermal - 地热的 isotherm - 等温线 thermocouple - 热电偶 thermography - 热成像 🎓 158. 词根:tract (拉,拖) 📝 158.1 含义 拉,拖 📚 158.2 词汇列表 tractor - 拖拉机 attract - 吸引 contract - 合同 subtract - 减去 extract - 提取 distract - 分心 retract - 撤回 traction - 牵引 protract - 延长 intractable - 难以管理的 🎓 159. 词根:vac (空) 📝 159.1 含义 空 📚 159.2 词汇列表 vacuum - 真空 vacant - 空的 vacation - 假期 evacuate - 撤离 vacate - 腾出 vacuous - 空虚的 vacancy - 空缺 evacuation - 撤离 vacillator - 犹豫不决的人 vacuity - 空虚 🎓 160. 词根:ven / vent (来) 📝 160.1 含义 来 📚 160.2 词汇列表 convene - 召集 intervene - 干预 prevent - 防止 invent - 发明 adventure - 冒险 convent - 修道院 convenient - 方便的 venue - 场地 event - 事件 advent - 到来 🎓 161. 词根:ver (真实) 📝 161.1 含义 真实 📚 161.2 词汇列表 verify - 验证 verdict - 判决 veracity - 真实性 veritable - 真正的 verisimilitude - 逼真 aver - 断言 veritable - 名副其实的 veracity - 诚实 veracious - 真实的 verisimilar - 似真的 🎓 162. 词根:vers / vert (转) 📝 162.1 含义 转 📚 162.2 词汇列表 convert - 转换 revert - 恢复 invert - 颠倒 divert - 转移 versatile - 多才多艺的 introvert - 内向的人 extrovert - 外向的人 adversary - 对手 controversy - 争论 subvert - 颠覆 🎓 163. 词根:vid / vis (看) 📝 163.1 含义 看 📚 163.2 词汇列表 video - 视频 vision - 视力 visible - 可见的 visit - 访问 supervise - 监督 evident - 明显的 vivid - 生动的 invisible - 不可见的 visualize - 使形象化 vista - 远景 🎓 164. 词根:voc / vok (声音,呼唤) 📝 164.1 含义 声音,呼唤 📚 164.2 词汇列表 vocal - 声音的 vocation - 职业 invoke - 呼求 provoke - 激怒 revoke - 撤销 advocate - 提倡 evoke - 唤起 vociferous - 喧嚣的 convocation - 召集 equivocate - 含糊其辞 🎓 165. 词根:vol (意愿,意志) 📝 165.1 含义 意愿,意志 📚 165.2 词汇列表 volunteer - 志愿者 voluntary - 自愿的 benevolent - 慈善的 malevolent - 恶毒的 volition - 意志 volunteerism - 志愿服务 involuntary - 不自觉的 voluntaryism - 自愿主义 voluntarism - 志愿主义 volitional - 出于自愿的 🎓 166. 词根:volv / volut (转动,卷) 📝 166.1 含义 转动,卷 📚 166.2 词汇列表 revolve - 旋转 evolve - 进化 involve - 涉及 revolution - 革命 convoluted - 复杂的 devolve - 移交 voluble - 健谈的 revolt - 反叛 volvation - 卷曲 circumvolve - 环绕 🎓 167. 词根:voc / vok (声音,呼唤) 📝 167.1 含义 声音,呼唤 📚 167.2 词汇列表 vocal - 声音的 vocation - 职业 invoke - 请求,唤起 provoke - 激怒 revoke - 撤销 advocate - 提倡,拥护 evoke - 唤起 vociferous - 喧哗的 convocation - 召集 equivocate - 含糊其辞 🎓 168. 词根:vol (意愿,意志) 📝 168.1 含义 意愿,意志 📚 168.2 词汇列表 volunteer - 志愿者 voluntary - 自愿的 benevolent - 慈善的 malevolent - 恶毒的 volition - 意志 voluptuous - 奢侈的 involuntary - 非自愿的 voluntarism - 志愿主义 volitional - 出于意愿的 volunteering - 志愿服务 🎓 169. 词根:volv / volut (转动,卷) 📝 169.1 含义 转动,卷 📚 169.2 词汇列表 revolve - 旋转 evolve - 进化 involve - 涉及 revolution - 革命 convoluted - 复杂的 devolve - 移交 voluble - 健谈的 revolt - 反叛 volvation - 卷曲 circumvolve - 环绕 🎓 170. 词根:xen / xeno (外国,陌生) 📝 170.1 含义 外国,陌生 📚 170.2 词汇列表 xenophobia - 仇外心理 xenon - 氙气 xenophile - 喜欢外国事物的人 xenogenesis - 异种繁殖 xenodochy - 好客 xenogamy - 异花授粉 xenotransplantation - 异种移植 xenolith - 异质岩 xenobiotic - 异源生物 xenocracy - 外国统治 🎓 171. 词根:zo / zoo (动物) 📝 171.1 含义 动物 📚 171.2 词汇列表 zoology - 动物学 zoo - 动物园 zoonosis - 动物传染病 zoologist - 动物学家 zooplankton - 浮游动物 zootomy - 动物解剖学 zoogeography - 动物地理学 zoophobia - 动物恐惧症 zoolatry - 动物崇拜 zootoxin - 动物毒素 🎓 172. 词根:arch (统治,首要) 📝 172.1 含义 统治,首要 📚 172.2 词汇列表 monarch - 君主 anarchy - 无政府状态 archenemy - 主要敌人 hierarchy - 等级制度 oligarchy - 寡头政治 patriarch - 男族长 matriarch - 女族长 archbishop - 大主教 archaeology - 考古学 archangel - 大天使 🎓 173. 词根:auto (自我) 📝 173.1 含义 自我 📚 173.2 词汇列表 autonomy - 自治 autograph - 亲笔签名 automatic - 自动的 autobiography - 自传 autocracy - 独裁 automobile - 汽车 autopilot - 自动驾驶 autoimmune - 自身免疫 autonomous - 自治的 autodidact - 自学者 🎓 174. 词根:biblio (书) 📝 174.1 含义 书 📚 174.2 词汇列表 bibliography - 参考书目 bibliophile - 爱书者 bibliophile - 书迷 bible - 圣经 bibliomania - 藏书癖 bibliotherapy - 阅读疗法 bibliology - 书籍学 bibliotheca - 图书馆 bibliomancy - 占卜书 bibliopegy - 书籍装订术 🎓 175. 词根:bio (生命) 📝 175.1 含义 生命 📚 175.2 词汇列表 biology - 生物学 biography - 传记 biodegradable - 可生物降解的 biotechnology - 生物技术 biochemistry - 生物化学 biome - 生物群落 biosphere - 生物圈 bioluminescence - 生物发光 biosynthesis - 生物合成 biopsy - 活检 🎓 176. 词根:chrom (颜色) 📝 176.1 含义 颜色 📚 176.2 词汇列表 chromatic - 色彩的 chromosome - 染色体 monochrome - 单色 polychrome - 多色的 chromium - 铬 chromatography - 色谱法 achromatic - 非彩色的 chromaticity - 色度 chromophore - 发色团 chromoplast - 色素体 🎓 177. 词根:chron (时间) 📝 177.1 含义 时间 📚 177.2 词汇列表 chronology - 年表 synchronize - 同步 anachronism - 时代错误 chronicle - 编年史 chronometer - 精密计时器 chronograph - 计时器 chronotherapy - 时间疗法 chronobiology - 时间生物学 chronic - 慢性的 chronophobia - 时间恐惧症 🎓 178. 词根:cosm (宇宙) 📝 178.1 含义 宇宙 📚 178.2 词汇列表 cosmos - 宇宙 cosmopolitan - 世界性的 microcosm - 缩影 macrocosm - 宏观宇宙 cosmology - 宇宙学 cosmogony - 宇宙起源学 cosmonaut - 宇航员 cosmochemistry - 宇宙化学 cosmetology - 美容学 cosmism - 宇宙主义 🎓 179. 词根:crat / cracy (统治,权力) 📝 179.1 含义 统治,权力 📚 179.2 词汇列表 democracy - 民主 aristocracy - 贵族统治 bureaucracy - 官僚主义 autocracy - 独裁 technocracy - 技术统治 plutocracy - 富豪统治 meritocracy - 精英统治 theocracy - 神权统治 gerontocracy - 老年人统治 mobocracy - 暴民统治 🎓 180. 词根:cycl (圆,环) 📝 180.1 含义 圆,环 📚 180.2 词汇列表 bicycle - 自行车 cyclical - 周期的 cyclone - 气旋 recycle - 回收 unicycle - 独轮车 tricycle - 三轮车 encyclopedia - 百科全书 cycle - 循环 motorcycle - 摩托车 cyclotron - 回旋加速器 🎓 181. 词根:dem (人民) 📝 181.1 含义 人民 📚 181.2 词汇列表 democracy - 民主 demographic - 人口统计的 epidemic - 流行病 pandemic - 大范围流行的 demagogue - 煽动者 endemic - 地方性的 demography - 人口统计学 demotic - 民众的 democratize - 民主化 epidemic - 流行的 🎓 182. 词根:derm (皮肤) 📝 182.1 含义 皮肤 📚 182.2 词汇列表 dermatology - 皮肤病学 epidermis - 表皮 hypodermic - 皮下的 dermatitis - 皮炎 pachyderm - 厚皮动物 dermis - 真皮 dermatologist - 皮肤科医生 dermatome - 皮节 dermabrasion - 皮肤磨削 dermaplasty - 皮肤移植术 🎓 183. 词根:dict (说) 📝 183.1 含义 说 📚 183.2 词汇列表 dictate - 命令 predict - 预言 contradict - 反驳 dictionary - 字典 indict - 起诉 verdict - 判决 benediction - 祝福 edict - 法令 diction - 措辞 dictator - 独裁者 🎓 184. 词根:dox (观点,思想) 📝 184.1 含义 观点,思想 📚 184.2 词汇列表 orthodox - 正统的 paradox - 悖论 heterodox - 异端的 doxology - 赞美诗 dogma - 教条 dogmatic - 教条的 paradoxical - 矛盾的 orthodoxy - 正统观念 heterodoxy - 非正统观念 doxastic - 信念的 🎓 185. 词根:duc / duct (引导,带来) 📝 185.1 含义 引导,带来 📚 185.2 词汇列表 conduct - 引导,行为 induce - 引起 produce - 生产 reduce - 减少 educate - 教育 deduct - 扣除 abduct - 绑架 duct - 管道 introduction - 介绍 seduce - 引诱 🎓 186. 词根:fac / fact / fect / fic (做,制作) 📝 186.1 含义 做,制作 📚 186.2 词汇列表 manufacture - 制造 factory - 工厂 defect - 缺陷 affect - 影响 infect - 感染 fiction - 小说 sacrifice - 牺牲 benefactor - 恩人 facilitate - 促进 artificial - 人工的 🎓 187. 词根:fer (带来,承载) 📝 187.1 含义 带来,承载 📚 187.2 词汇列表 transfer - 转移 refer - 提到 confer - 授予 ferry - 渡船 fertile - 肥沃的 infer - 推断 defer - 推迟 prefer - 更喜欢 referendum - 公投 circumference - 周长 🎓 188. 词根:fid (信任,信仰) 📝 188.1 含义 信任,信仰 📚 188.2 词汇列表 fidelity - 忠诚 confide - 倾诉 infidel - 异教徒 confident - 自信的 perfidy - 背信弃义 fiduciary - 信托的 infidelity - 不忠 confidential - 机密的 affidavit - 宣誓书 diffident - 缺乏自信的 🎓 189. 词根:fin (结束,范围) 📝 189.1 含义 结束,范围 📚 189.2 词汇列表 final - 最终的 finish - 完成 finite - 有限的 infinite - 无限的 definite - 明确的 confine - 限制 refine - 精炼 affinity - 密切关系 finance - 财务 finality - 终结 🎓 190. 词根:flu / flux (流动) 📝 190.1 含义 流动 📚 190.2 词汇列表 fluid - 液体 influence - 影响 fluctuate - 波动 affluent - 富裕的 fluency - 流利 reflux - 回流 confluence - 汇合 superfluous - 多余的 fluent - 流利的 effluent - 流出物 🎓 191. 词根:gen (产生,出生) 📝 191.1 含义 产生,出生 📚 191.2 词汇列表 generation - 一代人 genetic - 遗传的 generate - 产生 genius - 天才 genesis - 起源 genealogy - 家谱 genuine - 真实的 progeny - 后代 indigenous - 本土的 genre - 类型 🎓 192. 词根:geo (地球) 📝 192.1 含义 地球 📚 192.2 词汇列表 geography - 地理 geology - 地质学 geometry - 几何 geopolitics - 地缘政治 geothermal - 地热的 geocentric - 地心的 geography - 地理学 geodesy - 大地测量学 geocache - 地理寻宝 geosphere - 地球圈层 🎓 193. 词根:grad / gress (步,行走) 📝 193.1 含义 步,行走 📚 193.2 词汇列表 graduate - 毕业 gradual - 逐渐的 progress - 进步 regress - 倒退 aggressive - 侵略性的 congress - 议会 digress - 偏离 transgress - 违反 upgrade - 升级 degrade - 降级 🎓 194. 词根:graph / gram (写,画) 📝 194.1 含义 写,画 📚 194.2 词汇列表 autograph - 亲笔签名 biography - 传记 paragraph - 段落 telegraph - 电报 photograph - 照片 grammar - 语法 diagram - 图表 graphic - 图形的 choreography - 编舞 epigram - 警句 🎓 195. 词根:hydr (水) 📝 195.1 含义 水 📚 195.2 词汇列表 hydrate - 水合物 dehydrate - 脱水 hydraulic - 液压的 hydroelectric - 水力发电的 hydrotherapy - 水疗 hydrosphere - 水圈 hydrophobia - 恐水症 hydrogen - 氢 hydrology - 水文学 hydrant - 消防栓 🎓 196. 词根:ject (投掷,扔) 📝 196.1 含义 投掷,扔 📚 196.2 词汇列表 eject - 驱逐 reject - 拒绝 project - 项目,投影 inject - 注射 object - 物体,反对 subject - 主题,科目 trajectory - 轨迹 interject - 插话 deject - 使沮丧 conjecture - 推测 🎓 197. 词根:jur / jus (法律,正义) 📝 197.1 含义 法律,正义 📚 197.2 词汇列表 jurisdiction - 管辖权 jury - 陪审团 justice - 正义 injury - 伤害 perjury - 伪证 jurisprudence - 法学 justify - 证明…正当 adjure - 恳请 juror - 陪审员 justifiable - 可辩解的 🎓 198. 词根:labor (劳动,工作) 📝 198.1 含义 劳动,工作 📚 198.2 词汇列表 laboratory - 实验室 collaborate - 合作 elaborate - 精心制作的 laborious - 费力的 labor - 劳动 belabor - 抨击 laborer - 劳工 laboriousness - 勤勉 laborious - 艰苦的 🎓 199. 词根:luc / lum / lus (光,亮) 📝 199.1 含义 光,亮 📚 199.2 词汇列表 lucid - 清晰的 illuminate - 照亮 luminous - 发光的 translucent - 半透明的 elucidate - 阐明 luminary - 杰出人物 lustrous - 光辉的 illustrate - 说明 luminescent - 发冷光的 luminosity - 光度 🎓 200. 词根:man / manu (手) 📝 200.1 含义 手 📚 200.2 词汇列表 manual - 手册,手工的 manufacture - 制造 manipulate - 操纵 manuscript - 手稿 emancipate - 解放 manicure - 美甲 maneuver - 操纵,演习 manifest - 显现 manacle - 手铐 mandate - 授权 🎓 201. 词根:mater / matr (母亲) 📝 201.1 含义 母亲 📚 201.2 词汇列表 maternal - 母亲的 maternity - 母性 matriarch - 女家长 matrimony - 婚姻 matron - 主妇 matronly - 有母亲风范的 matrix - 母体,基质 matricide - 弑母 matrilineal - 母系的 🎓 202. 词根:mit / miss (发送) 📝 202.1 含义 发送 📚 202.2 词汇列表 transmit - 传送 emit - 发出 submit - 提交 dismiss - 解散 mission - 任务 missile - 导弹 permit - 允许 remit - 汇款 admit - 承认 intermittent - 间歇的 🎓 203. 词根:morph (形状) 📝 203.1 含义 形状 📚 203.2 词汇列表 morphology - 形态学 amorphous - 无定形的 metamorphosis - 变形 polymorphous - 多形的 morpheme - 词素 anthropomorphize - 拟人化 morphine - 吗啡 morphogenetic - 形态发生的 morphogenesis - 形态发生 endomorph - 内胚型 🎓 204. 词根:nom / nym (名字) 📝 204.1 含义 名字 📚 204.2 词汇列表 synonym - 同义词 antonym - 反义词 pseudonym - 假名 anonymous - 匿名的 eponym - 名祖 nomenclature - 命名法 nominal - 名义上的 denomination - 宗派,面额 homonym - 同音异义词 nomen - 名字 🎓 205. 词根:nov (新) 📝 205.1 含义 新 📚 205.2 词汇列表 novel - 小说,新颖的 novice - 新手 innovate - 创新 renovate - 翻新 novelty - 新奇 novelization - 小说化 novitiate - 见习期 novelistic - 小说的 novation - 更新 supernova - 超新星 🎓 206. 词根:omni (全,遍) 📝 206.1 含义 全,遍 📚 206.2 词汇列表 omniscient - 无所不知的 omnipotent - 全能的 omnipresent - 无所不在的 omnivorous - 杂食的 omnivore - 杂食动物 omnibus - 综合的 omnicompetent - 万能的 omnidirectional - 全向的 omnifarious - 各式各样的 omniform - 多种多样的 🎓 207. 词根:path / pathy (感情,疾病) 📝 207.1 含义 感情,疾病 📚 207.2 词汇列表 sympathy - 同情 empathy - 共鸣 apathy - 冷漠 pathology - 病理学 psychopath - 精神病患者 antipathy - 反感 pathos - 感染力 telepathy - 心灵感应 sociopath - 反社会者 pathetic - 可怜的 🎓 208. 词根:phobia (恐惧) 📝 208.1 含义 恐惧 📚 208.2 词汇列表 claustrophobia - 幽闭恐惧症 agoraphobia - 广场恐惧症 xenophobia - 仇外 hydrophobia - 恐水症 acrophobia - 恐高症 arachnophobia - 恐蜘蛛症 phobophobia - 恐惧恐惧症 photophobia - 畏光 erythrophobia - 畏红症 trypophobia - 密集恐惧症 🎓 209. 词根:phon (声音) 📝 209.1 含义 声音 📚 209.2 词汇列表 telephone - 电话 phonics - 语音学 microphone - 麦克风 phonetic - 语音的 symphony - 交响乐 cacophony - 刺耳的声音 euphony - 悦耳声 megaphone - 扩音器 homophone - 同音异义词 polyphonic - 复音的 🎓 210. 词根:phot (光) 📝 210.1 含义 光 📚 210.2 词汇列表 photograph - 照片 photosynthesis - 光合作用 photon - 光子 photography - 摄影 photogenic - 上镜的 photoelectric - 光电的 photovoltaic - 光伏的 photophobia - 畏光 photocopy - 复印件 photosensitive - 感光的 🎓 211. 词根:port (搬运,携带) 📝 211.1 含义 搬运,携带 📚 211.2 词汇列表 transport - 运输 import - 进口 export - 出口 portable - 便携的 airport - 机场 deport - 驱逐 support - 支持 report - 报告 portfolio - 投资组合 portal - 门户 🎓 212. 词根:scrib / script (写) 📝 212.1 含义 写 📚 212.2 词汇列表 describe - 描述 inscription - 铭文 manuscript - 手稿 prescription - 处方 script - 剧本 subscribe - 订阅 transcript - 成绩单 proscribe - 禁止 scribble - 潦草书写 scripture - 经文 🎓 213. 词根:sens / sent (感觉) 📝 213.1 含义 感觉 📚 213.2 词汇列表 sense - 感觉 sensitive - 敏感的 sensory - 感觉的 sentiment - 感情 consent - 同意 resent - 怨恨 dissent - 异议 nonsense - 胡说 insensitive - 不敏感的 sensational - 轰动的 🎓 214. 词根:spec / spect / spic (看) 📝 214.1 含义 看 📚 214.2 词汇列表 spectator - 观众 inspect - 检查 respect - 尊重 spectacle - 景象 specimen - 标本 speculate - 推测 prospect - 前景 retrospect - 回顾 conspicuous - 显眼的 introspection - 反省 🎓 215. 词根:spir (呼吸,精神) 📝 215.1 含义 呼吸,精神 📚 215.2 词汇列表 inspire - 激励 respire - 呼吸 spirit - 精神 aspire - 渴望 expire - 过期 perspire - 出汗 conspire - 共谋 transpire - 发生 spiritual - 精神的 aspiration - 抱负 🎓 216. 词根:sta / sti / sist (站立) 📝 216.1 含义 站立 📚 216.2 词汇列表 stand - 站立 station - 站,车站 statue - 雕像 static - 静态的 stamina - 耐力 status - 状态,地位 insist - 坚持 resist - 抵抗 persist - 坚持 assist - 帮助 🎓 217. 词根:struct (建造) 📝 217.1 含义 建造 📚 217.2 词汇列表 structure - 结构 construct - 建造 destruction - 破坏 instruct - 指导 restructure - 重组 obstruct - 阻碍 constructive - 建设性的 infrastructure - 基础设施 deconstruct - 解构 superstructure - 上层建筑 🎓 218. 词根:tact / tang / tag (接触) 📝 218.1 含义 接触 📚 218.2 词汇列表 tact - 机智 tangible - 可触摸的 contact - 接触 intact - 完好无损的 contagious - 传染性的 tactile - 触觉的 tag - 标签 tangent - 切线 tactician - 战术家 entangle - 纠缠 🎓 219. 词根:tele (远) 📝 219.1 含义 远 📚 219.2 词汇列表 telephone - 电话 television - 电视 telegraph - 电报 telepathy - 心灵感应 telescope - 望远镜 telecommute - 远程办公 telephoto - 远摄的 telecast - 电视广播 telegram - 电报 teleconference - 远程会议 🎓 220. 词根:tempor (时间) 📝 220.1 含义 时间 📚 220.2 词汇列表 temporary - 暂时的 temporal - 时间的 contemporary - 当代的 temporize - 拖延 extemporize - 即兴创作 temporality - 短暂性 temporization - 拖延战术 temporarily - 暂时地 temporalize - 使世俗化 temporality - 时间性 🎓 221. 词根:therm (热) 📝 221.1 含义 热 📚 221.2 词汇列表 thermal - 热的 thermometer - 温度计 thermostat - 恒温器 thermodynamics - 热力学 hypothermia - 体温过低 thermoplastic - 热塑性的 thermos - 保温瓶 thermoelectric - 热电的 geothermal - 地热的 endothermic - 吸热的 🎓 222. 词根:tract (拉,拖) 📝 222.1 含义 拉,拖 📚 222.2 词汇列表 tractor - 拖拉机 attract - 吸引 distract - 分散 contract - 合同,收缩 subtract - 减去 abstract - 抽象的 retract - 收回 protract - 延长 traction - 牵引 extract - 提取 🎓 223. 词根:vac (空) 📝 223.1 含义 空 📚 223.2 词汇列表 vacuum - 真空 vacant - 空的 vacation - 假期 evacuate - 撤离 vacate - 腾出 vacuous - 空洞的 vacancy - 空缺 vaccinate - 接种疫苗 evacuation - 撤离 vacuolate - 成空泡 🎓 224. 词根:ven / vent (来) 📝 224.1 含义 来 📚 224.2 词汇列表 convene - 召集 advent - 到来 intervene - 干预 invent - 发明 prevent - 预防 event - 事件 venture - 冒险 avenue - 大街 convenient - 方便的 venue - 场所 🎓 225. 词根:vers / vert (转动) 📝 225.1 含义 转动 📚 225.2 词汇列表 reverse - 颠倒 convert - 转换 advertise - 广告 divert - 转移 invert - 颠倒 revert - 恢复 versatile - 多才多艺的 controversy - 争论 introvert - 内向的人 extrovert - 外向的人 🎓 226. 词根:vid / vis (看) 📝 226.1 含义 看 📚 226.2 词汇列表 video - 视频 visible - 可见的 vision - 视力 evidence - 证据 visit - 访问 visual - 视觉的 envision - 想象 revise - 修订 provision - 供应 supervise - 监督 🎓 227. 词根:viv / vit (生命) 📝 227.1 含义 生命 📚 227.2 词汇列表 vivid - 生动的 vital - 至关重要的 revive - 复活 survive - 生存 vitamin - 维生素 vivacious - 活泼的 vitality - 活力 vivisection - 活体解剖 vitalize - 使有活力 convivial - 欢乐的 🎓 228. 词根:voc / vok (呼喊,声音) 📝 228.1 含义 呼喊,声音 📚 228.2 词汇列表 vocal - 声音的 invoke - 祈求 provoke - 激怒 revoke - 撤销 vocabulary - 词汇 advocate - 提倡 equivocate - 含糊其辞 convocation - 召集 evoke - 唤起 vociferous - 喧嚷的 🎓 229. 词根:volv / volut (转动) 📝 229.1 含义 转动 📚 229.2 词汇列表 evolve - 进化 revolve - 旋转 involve - 涉及 revolution - 革命 devolve - 下放 convoluted - 复杂的 voluble - 健谈的 circumvolve - 环绕 volute - 漩涡形 revolutionary - 革命性的 🎓 230. 词根:zo (动物) 📝 230.1 含义 动物 📚 230.2 词汇列表 zoology - 动物学 zoo - 动物园 zoologist - 动物学家 protozoa - 原生动物 zooplankton - 浮游动物 zoonosis - 动物传染病 zoophyte - 动物植物 zoolatry - 动物崇拜 zoogenic - 动物起源的 zoomorphism - 动物形态学 🎓 231. 词根:aqua / aque (水) 📝 231.1 含义 水 📚 231.2 词汇列表 aquarium - 水族馆 aquatic - 水生的 aqueduct - 水渠 aqueous - 水的 aquifer - 含水层 aquamarine - 海蓝宝石 aquaplane - 水板 aquacade - 水上表演 aquafarm - 水产养殖场 aquatint - 水彩画 🎓 232. 词根:arch / archi (统治者,领导,首要) 📝 232.1 含义 统治者,领导,首要 📚 232.2 词汇列表 monarch - 君主 anarchy - 无政府状态 archenemy - 主要敌人 architect - 建筑师 archangel - 大天使 archaeology - 考古学 archipelago - 群岛 archbishop - 大主教 patriarch - 家长,族长 oligarchy - 寡头政治 🎓 233. 词根:arthr (关节) 📝 233.1 含义 关节 📚 233.2 词汇列表 arthritis - 关节炎 arthropod - 节肢动物 arthroscope - 关节镜 arthralgia - 关节痛 arthroplasty - 关节成形术 arthrology - 关节学 synarthrosis - 不动关节 arthrosis - 关节病 arthrometer - 关节测量仪 hemarthrosis - 关节积血 🎓 234. 词根:astro (星星,宇宙) 📝 234.1 含义 星星,宇宙 📚 234.2 词汇列表 astronomy - 天文学 astrology - 占星术 astronaut - 宇航员 asteroid - 小行星 astrophysics - 天体物理学 astrobiology - 天体生物学 astrolabe - 星盘 astrometry - 天文测量学 astrograph - 天文照相机 astrolithology - 陨石学 🎓 235. 词根:aud / audit (听) 📝 235.1 含义 听 📚 235.2 词汇列表 auditory - 听觉的 audible - 可听见的 audience - 观众 audit - 审计 auditorium - 礼堂 inaudible - 听不见的 audiologist - 听力学家 audiobook - 有声书 audiophile - 音响爱好者 audition - 试镜 🎓 236. 词根:bell (战争) 📝 236.1 含义 战争 📚 236.2 词汇列表 rebellion - 叛乱 belligerent - 好战的 bellicose - 好斗的 antebellum - 战前的 belligerency - 交战状态 rebel - 叛徒 postbellum - 战后的 bellipotent - 战斗力强的 bellona - 战争女神 🎓 237. 词根:biblio (书) 📝 237.1 含义 书 📚 237.2 词汇列表 bibliography - 参考书目 bibliophile - 爱书者 bibliomania - 藏书癖 bible - 圣经 bibliotherapy - 读书治疗 bibliology - 书籍学 bibliotheca - 图书馆 biblioklept - 偷书贼 bibliometrics - 书目统计学 bibliogenesis - 书籍产生 🎓 238. 词根:bio (生命) 📝 238.1 含义 生命 📚 238.2 词汇列表 biology - 生物学 biography - 传记 biome - 生物群落 biosphere - 生物圈 biodegradable - 可生物降解的 biotic - 生物的 antibiotic - 抗生素 biopsy - 活检 biodiversity - 生物多样性 biometrics - 生物测定学 🎓 239. 词根:brev (短) 📝 239.1 含义 短 📚 239.2 词汇列表 brevity - 简洁 abbreviate - 缩写 brief - 简短的 breviloquent - 言简意赅的 brevet - 名誉晋升令 breve - 短音符 breviped - 短足的 abbreviation - 缩写 brevity - 短暂 🎓 240. 词根:caust / caut (烧) 📝 240.1 含义 烧 📚 240.2 词汇列表 caustic - 腐蚀性的 cauterize - 烧灼 holocaust - 大屠杀 causalgia - 灼性神经痛 causticity - 腐蚀性 cautery - 烧灼器 encaustic - 蜡画的 caustically - 尖刻地 causticizer - 腐蚀剂 cauterization - 烧灼法 🎓 241. 词根:cede / ceed / cess (走,撤退) 📝 241.1 含义 走,撤退 📚 241.2 词汇列表 recede - 后退 proceed - 继续进行 exceed - 超过 precede - 领先 concede - 承认 succeed - 成功 access - 进入 process - 过程 recess - 休息 secede - 脱离 🎓 242. 词根:chrom (颜色) 📝 242.1 含义 颜色 📚 242.2 词汇列表 chromatic - 色彩的 monochrome - 单色的 polychrome - 多色的 chromosome - 染色体 chromaticism - 色彩主义 achromatic - 无色的 chromophore - 发色团 chromium - 铬 chromophilia - 嗜色性 chromatology - 色彩学 🎓 243. 词根:cide (切,杀) 📝 243.1 含义 切,杀 📚 243.2 词汇列表 homicide - 杀人 suicide - 自杀 pesticide - 杀虫剂 genocide - 种族灭绝 infanticide - 杀婴 regicide - 弑君 patricide - 弑父 matricide - 弑母 herbicide - 除草剂 insecticide - 杀虫剂 🎓 244. 词根:clin (倾斜,弯曲) 📝 244.1 含义 倾斜,弯曲 📚 244.2 词汇列表 incline - 倾斜 decline - 下降 recline - 斜倚 inclination - 倾向 clinometer - 测斜仪 clinic - 诊所 clinal - 倾斜的 disinclination - 不情愿 proclivity - 倾向 declivity - 下坡 🎓 245. 词根:clud / clus (关闭) 📝 245.1 含义 关闭 📚 245.2 词汇列表 include - 包含 exclude - 排除 conclude - 结束 seclude - 隔离 preclude - 排除 occlude - 闭塞 occlusion - 闭塞 recluse - 隐士 seclusion - 隔离 exclusion - 排斥 🎓 246. 词根:cosm (宇宙,秩序) 📝 246.1 含义 宇宙,秩序 📚 246.2 词汇列表 cosmos - 宇宙 cosmic - 宇宙的 cosmology - 宇宙学 microcosm - 微观世界 macrocosm - 宏观世界 cosmopolitan - 世界性的 cosmonaut - 宇航员 cosmogony - 宇宙起源学 cosmography - 宇宙描绘 cosmochemistry - 宇宙化学 🎓 247. 词根:crac / crat (统治,力量) 📝 247.1 含义 统治,力量 📚 247.2 词汇列表 democracy - 民主 aristocracy - 贵族 bureaucracy - 官僚 autocracy - 独裁 plutocracy - 富豪统治 technocrat - 技术官僚 aristocrat - 贵族 theocracy - 神权统治 gerontocracy - 老人统治 meritocracy - 精英统治 🎓 248. 词根:cred (相信) 📝 248.1 含义 相信 📚 248.2 词汇列表 credible - 可信的 credit - 信用 incredible - 难以置信的 credential - 证书 creed - 信条 discredit - 使丧失信誉 credence - 信任 credulous - 轻信的 credibility - 可信性 accredit - 授权 🎓 249. 词根:crypt (隐藏,秘密) 📝 249.1 含义 隐藏,秘密 📚 249.2 词汇列表 cryptic - 隐秘的 encrypt - 加密 decrypt - 解密 cryptography - 密码学 crypt - 地窖,地下室 cryptogram - 密码 cryptology - 密码学 cryptic - 隐晦的 cryptic - 神秘的 cryptonym - 匿名 🎓 250. 词根:culp (罪) 📝 250.1 含义 罪 📚 250.2 词汇列表 culprit - 罪犯 culpable - 应受责备的 exculpate - 开脱 inculpate - 控告 culpability - 罪责 inculpation - 控告 culpably - 有罪地 culpableness - 有罪 exculpation - 辩解 🎓 251. 词根:cur / curs / cours (跑,流动) 📝 251.1 含义 跑,流动 📚 251.2 词汇列表 current - 当前的,流动的 cursory - 草率的 course - 课程,路线 occur - 发生 recur - 再次发生 concur - 同意 excursion - 远足 incur - 招致 precursor - 先驱 courier - 信使 🎓 252. 词根:cycl (圈,轮子) 📝 252.1 含义 圈,轮子 📚 252.2 词汇列表 bicycle - 自行车 cycle - 循环 unicycle - 独轮车 cyclone - 旋风 encyclopedia - 百科全书 cyclical - 循环的 tricycle - 三轮车 cyclotron - 回旋加速器 cyclist - 骑自行车的人 recycle - 回收 🎓 253. 词根:dem / demo (人民) 📝 253.1 含义 人民 📚 253.2 词汇列表 democracy - 民主 demographic - 人口统计的 epidemic - 流行病 demagogue - 煽动者 pandemic - 大流行病 demotic - 民众的 demography - 人口统计学 democratize - 使民主化 demogenic - 人口的 demography - 人口学 🎓 254. 词根:dic / dict (说) 📝 254.1 含义 说 📚 254.2 词汇列表 dictionary - 字典 predict - 预测 dictate - 命令 verdict - 裁决 contradict - 反驳 indict - 起诉 edict - 法令 benediction - 祝福 diction - 措辞 jurisdiction - 司法权 🎓 255. 词根:doc / doct (教) 📝 255.1 含义 教 📚 255.2 词汇列表 doctor - 医生,博士 doctrine - 教义 document - 文件 indoctrinate - 灌输 docile - 温顺的 doctoral - 博士的 documentation - 文档 doctrinal - 教条的 documentary - 纪录片 doctrinaire - 教条主义者 🎓 256. 词根:domin (统治,支配) 📝 256.1 含义 统治,支配 📚 256.2 词汇列表 dominate - 支配 dominant - 占优势的 dominion - 统治权 predominate - 占主导地位 domineer - 专横跋扈 dominance - 优势 indomitable - 不屈不挠的 domain - 领域 domination - 统治 dominatrix - 女施虐者 🎓 257. 词根:don / dot / dat (给予) 📝 257.1 含义 给予 📚 257.2 词汇列表 donate - 捐赠 pardon - 原谅 donor - 捐赠者 condone - 宽恕 antidote - 解毒剂 data - 数据 endow - 捐赠 dowry - 嫁妆 anecdote - 轶事 tradition - 传统 🎓 258. 词根:dorm (睡眠) 📝 258.1 含义 睡眠 📚 258.2 词汇列表 dormant - 休眠的 dormitory - 宿舍 dormancy - 休眠 dormer - 天窗 dormitive - 催眠的 dormition - 安息 dormouse - 睡鼠 dormitive - 安眠药 dormit - 睡眠 dormin - 安眠药 🎓 259. 词根:duc / duct (引导,带来) 📝 259.1 含义 引导,带来 📚 259.2 词汇列表 produce - 生产 conduct - 行为,领导 introduce - 介绍 educate - 教育 reduce - 减少 deduce - 推断 seduce - 引诱 conductive - 导电的 abduct - 绑架 conducive - 有助于 🎓 260. 词根:dur (持久,坚硬) 📝 260.1 含义 持久,坚硬 📚 260.2 词汇列表 durable - 耐用的 endure - 忍受 duration - 持续时间 during - 在…期间 enduring - 持久的 indurate - 使坚硬 duress - 胁迫 durability - 耐久性 obdurate - 顽固的 perdurable - 极其耐用的 🎓 261. 词根:dyn / dynam (力量,能量) 📝 261.1 含义 力量,能量 📚 261.2 词汇列表 dynamo - 发电机 dynamic - 动态的 dynamite - 炸药 dynamometer - 测力计 aerodynamics - 空气动力学 dynamism - 活力 thermodynamics - 热力学 dynamogenic - 力源的 dynamometer - 动力计 hydrodynamic - 流体力学的 🎓 262. 词根:equ / equi (相等,公平) 📝 262.1 含义 相等,公平 📚 262.2 词汇列表 equal - 平等的 equity - 公平 equate - 使相等 equivalent - 等价的 equanimity - 镇定 equilibrium - 平衡 equitable - 公正的 equidistant - 等距的 equivocal - 模棱两可的 inequity - 不公平 🎓 263. 词根:flect / flex (弯曲) 📝 263.1 含义 弯曲 📚 263.2 词汇列表 flexible - 灵活的 deflect - 偏转 reflect - 反映 inflect - 使弯曲 flexion - 弯曲 reflex - 反射 retroflex - 后卷的 circumflex - 抑扬符 genuflect - 屈膝 deflection - 偏斜 🎓 264. 词根:flu / fluct / flux (流动) 📝 264.1 含义 流动 📚 264.2 词汇列表 fluid - 流体 influence - 影响 fluctuate - 波动 flux - 流动 affluent - 富裕的 confluence - 汇流 superfluous - 多余的 fluent - 流利的 effluent - 流出物 fluency - 流畅 🎓 265. 词根:fort (强) 📝 265.1 含义 强 📚 265.2 词汇列表 fortify - 强化 fortress - 堡垒 fortitude - 刚毅 comfort - 舒适 forte - 特长 enforce - 执行 reinforce - 加强 forceful - 有力的 fortification - 防御工事 fortissimo - 极强音 🎓 266. 词根:fract / frag (打破,破裂) 📝 266.1 含义 打破,破裂 📚 266.2 词汇列表 fracture - 骨折,破裂 fragment - 碎片 fragile - 易碎的 fraction - 分数,小部分 infraction - 违规 refract - 折射 fragmentation - 碎片化 fractious - 易怒的 refraction - 折射 diffract - 衍射 🎓 267. 词根:geo (地球) 📝 267.1 含义 地球 📚 267.2 词汇列表 geography - 地理学 geology - 地质学 geometry - 几何学 geothermal - 地热的 geophysics - 地球物理学 geocentric - 地心的 geopolitics - 地缘政治 geochemistry - 地球化学 geode - 晶洞 geoscience - 地球科学 🎓 268. 词根:grad / gress (步,走) 📝 268.1 含义 步,走 📚 268.2 词汇列表 graduate - 毕业 gradual - 逐渐的 progress - 进步 regress - 倒退 transgress - 违反 degrade - 降级 congress - 国会 aggressive - 侵略性的 digress - 离题 egress - 出口 🎓 269. 词根:graph / gram (写,画) 📝 269.1 含义 写,画 📚 269.2 词汇列表 autograph - 亲笔签名 biography - 传记 graphic - 图形的 photograph - 照片 telegram - 电报 epigram - 警句 diagram - 图表 grammar - 语法 holograph - 亲笔文件 calligraphy - 书法 🎓 270. 词根:greg (群体,聚集) 📝 270.1 含义 群体,聚集 📚 270.2 词汇列表 congregate - 聚集 gregarious - 群居的 segregate - 分离 aggregate - 聚合 egregious - 极坏的 congregation - 集合 aggregation - 聚合 desegregate - 废除种族隔离 disaggregate - 分解 gregarine - 聚集性 🎓 271. 词根:hydr (水) 📝 271.1 含义 水 📚 271.2 词汇列表 hydrate - 水合物 dehydrate - 脱水 hydraulic - 液压的 hydroelectric - 水力发电的 hydrogen - 氢 hydrology - 水文学 hydroplane - 水上飞机 hydrotherapy - 水疗 hydrant - 消防栓 hydrodynamics - 流体力学 🎓 272. 词根:ject (投掷,抛) 📝 272.1 含义 投掷,抛 📚 272.2 词汇列表 eject - 驱逐 inject - 注射 project - 项目,发射 reject - 拒绝 subject - 受制于 trajectory - 轨迹 interject - 插话 deject - 使沮丧 object - 物体,反对 conjecture - 推测 🎓 273. 词根:jur / jus / jud (法律,公正) 📝 273.1 含义 法律,公正 📚 273.2 词汇列表 jury - 陪审团 justice - 公正 judge - 法官,判断 jurisdiction - 管辖权 justify - 证明…是正当的 perjury - 伪证 jurisprudence - 法学 adjust - 调整 adjudicate - 裁决 prejudice - 偏见 🎓 274. 词根:labor (劳动) 📝 274.1 含义 劳动 📚 274.2 词汇列表 labor - 劳动 laboratory - 实验室 collaborate - 合作 elaborate - 详细阐述 laborious - 辛苦的 belabor - 过分强调 laborer - 劳动者 labored - 吃力的 prolabor - 支持劳工的 🎓 275. 词根:luc / lum / lus (光) 📝 275.1 含义 光 📚 275.2 词汇列表 lucid - 清晰的 illuminate - 照亮 luminous - 发光的 translucent - 半透明的 elucidate - 阐明 luminary - 杰出人物 lustrous - 有光泽的 luminescent - 发冷光的 lucidity - 明朗 pellucid - 清澈的 🎓 276. 词根:magn (大) 📝 276.1 含义 大 📚 276.2 词汇列表 magnify - 放大 magnitude - 大小,重要性 magnificent - 壮丽的 magnanimous - 宽宏大量的 magnum - 大酒瓶 magnate - 巨头 magniloquent - 言辞夸张的 magniloquence - 夸张之辞 magnificence - 壮丽 🎓 277. 词根:man (手) 📝 277.1 含义 手 📚 277.2 词汇列表 manual - 手工的 manipulate - 操纵 manufacture - 生产 manuscript - 手稿 emancipate - 解放 maneuver - 操控 manicure - 美甲 manifest - 显示 manacle - 手铐 manners - 礼貌 🎓 278. 词根:mater / matr (母亲) 📝 278.1 含义 母亲 📚 278.2 词汇列表 maternal - 母亲的 matriarch - 女族长 matrimony - 婚姻 matron - 主妇 matrilineal - 母系的 matricide - 弑母 maternity - 母性 matrilocal - 母居的 matronly - 庄重的 🎓 279. 词根:micro (小) 📝 279.1 含义 小 📚 279.2 词汇列表 microscope - 显微镜 microphone - 麦克风 microbe - 微生物 microcosm - 微观世界 microwave - 微波 microscopic - 微小的 microbiology - 微生物学 microsecond - 微秒 microchip - 微芯片 microorganism - 微生物 🎓 280. 词根:miss / mit (送,放出) 📝 280.1 含义 送,放出 📚 280.2 词汇列表 missile - 导弹 transmit - 传输 dismiss - 解散,解雇 emit - 发出 submit - 提交 remit - 汇款 admit - 承认 mission - 任务 omit - 省略 permit - 允许 🎓 281. 词根:mob / mot / mov (移动) 📝 281.1 含义 移动 📚 281.2 词汇列表 mobile - 移动的 motion - 运动 remove - 移除 motivate - 激励 promote - 促进 demote - 降级 commotion - 骚动 mobility - 灵活性 motor - 发动机 moveable - 可移动的 🎓 282. 词根:morph (形状,形式) 📝 282.1 含义 形状,形式 📚 282.2 词汇列表 morphology - 形态学 amorphous - 无定形的 metamorphosis - 变形 polymorphous - 多形态的 anthropomorphize - 拟人化 morphine - 吗啡(形态命名的药物) morpheme - 词素 morphogenesis - 形态发生 morphogenetic - 形态发生的 ectomorph - 外胚型体质 🎓 283. 词根:mort (死) 📝 283.1 含义 死 📚 283.2 词汇列表 mortal - 凡人,致命的 immortal - 不朽的 mortality - 死亡率 mortify - 使羞愧 mortician - 殡葬师 mortuary - 太平间 postmortem - 验尸 moribund - 垂死的 🎓 284. 词根:multi (多) 📝 284.1 含义 多 📚 284.2 词汇列表 multiple - 多重的 multitude - 大量 multiply - 乘,增加 multicultural - 多元文化的 multimedia - 多媒体 multinational - 跨国的 multipurpose - 多用途的 multitask - 多任务处理 multilateral - 多边的 multiplex - 多路传输 🎓 285. 词根:nat (出生) 📝 285.1 含义 出生 📚 285.2 词汇列表 native - 本地的 innate - 天生的 natal - 出生的 nature - 自然 natural - 自然的 nation - 国家 national - 国家的 nativity - 出生 neonate - 新生儿 renaissance - 文艺复兴 🎓 286. 词根:neo (新) 📝 286.1 含义 新 📚 286.2 词汇列表 neolithic - 新石器时代的 neonatal - 新生儿的 neophyte - 新手 neoclassic - 新古典的 neologism - 新词 neon - 氖(新发现的气体) neoplasm - 新生物 neocortex - 新皮层 neocolonialism - 新殖民主义 neoconservative - 新保守主义者 🎓 287. 词根:nom / nym (名字) 📝 287.1 含义 名字 📚 287.2 词汇列表 anonymous - 匿名的 pseudonym - 假名 synonym - 同义词 antonym - 反义词 nominate - 提名 nomenclature - 命名法 acronym - 首字母缩略词 patronymic - 父名 eponym - 名字来源 homonym - 同音异义词 🎓 288. 词根:nov (新) 📝 288.1 含义 新 📚 288.2 词汇列表 novel - 小说,新奇的 novice - 新手 innovate - 创新 renovate - 翻新 novelty - 新奇 novelization - 小说化 novitiate - 见习期 innovation - 创新 novelistic - 小说的 novitiate - 初学者 🎓 289. 词根:omni (全,遍) 📝 289.1 含义 全,遍 📚 289.2 词汇列表 omniscient - 无所不知的 omnipotent - 全能的 omnipresent - 无所不在的 omnivore - 杂食动物 omnifarious - 各式各样的 omniform - 有各种形式的 omnibus - 综合性的 omnilingual - 精通多种语言的 omnicompetent - 全能的 omnivorous - 杂食的 🎓 290. 词根:path (感情,疾病) 📝 290.1 含义 感情,疾病 📚 290.2 词汇列表 sympathy - 同情 empathy - 共情 apathy - 冷漠 pathology - 病理学 antipathy - 反感 psychopath - 精神病患者 pathetic - 可怜的 pathogen - 病原体 pathos - 感伤 telepathy - 心灵感应 🎓 291. 词根:ped / pod (脚,足) 📝 291.1 含义 脚,足 📚 291.2 词汇列表 pedal - 踏板 pedestrian - 行人 podium - 讲台 tripod - 三脚架 biped - 两足动物 centipede - 蜈蚣 pedicure - 足部护理 podiatrist - 足科医生 quadruped - 四足动物 impede - 阻碍 🎓 292. 词根:phil (爱) 📝 292.1 含义 爱 📚 292.2 词汇列表 philosophy - 哲学 philanthropy - 慈善 bibliophile - 爱书者 philharmonic - 爱乐的 philology - 语言学 philosopher - 哲学家 philatelist - 集邮者 philander - 调情 anglophile - 亲英者 philematology - 吻学 🎓 293. 词根:phon (声音) 📝 293.1 含义 声音 📚 293.2 词汇列表 telephone - 电话 phonograph - 唱片机 microphone - 麦克风 phonics - 语音学 symphony - 交响乐 homophone - 同音异义词 cacophony - 刺耳的声音 euphony - 悦耳的声音 phonetic - 语音的 xylophone - 木琴 🎓 294. 词根:photo (光) 📝 294.1 含义 光 📚 294.2 词汇列表 photograph - 照片 photosynthesis - 光合作用 photocopy - 复印 photometer - 光度计 photogenic - 上镜的 photons - 光子 photovoltaic - 光伏的 photophobia - 畏光 phototropic - 向光性的 photoelectric - 光电的 🎓 295. 词根:port (携带,运送) 📝 295.1 含义 携带,运送 📚 295.2 词汇列表 portable - 便携的 transport - 运输 export - 出口 import - 进口 support - 支持 report - 报告 deport - 驱逐出境 portfolio - 文件夹 portal - 门户,入口 portage - 船只陆上运输 🎓 296. 词根:psych (心灵,精神) 📝 296.1 含义 心灵,精神 📚 296.2 词汇列表 psychology - 心理学 psychotherapy - 心理治疗 psychic - 心灵的 psychopath - 精神病患者 psychoanalysis - 精神分析 psychosomatic - 身心的 psychosis - 精神病 psychedelic - 迷幻的 psychometrics - 心理测量学 psychotropic - 影响精神的 🎓 297. 词根:quer / ques / quir / quis (寻求,询问) 📝 297.1 含义 寻求,询问 📚 297.2 词汇列表 query - 查询 question - 问题 inquisitive - 好奇的 inquiry - 调查 acquire - 获得 require - 需要 requisition - 申请 conquer - 征服 exquisite - 精美的 prerequisite - 先决条件 🎓 298. 词根:rupt (破裂) 📝 298.1 含义 破裂 📚 298.2 词汇列表 interrupt - 打断 disrupt - 扰乱 rupture - 破裂 erupt - 爆发 corrupt - 腐败的 abrupt - 突然的 bankrupt - 破产的 irrupt - 闯入 incorruptible - 不腐败的 ruptured - 破裂的 🎓 299. 词根:scribe / script (写) 📝 299.1 含义 写 📚 299.2 词汇列表 describe - 描述 manuscript - 手稿 subscribe - 订阅 transcript - 抄本 prescribe - 开药方 inscription - 铭文 ascribe - 归因于 scripture - 经文 scribble - 乱写 postscript - 附言 🎓 300. 词根:sect (切割) 📝 300.1 含义 切割 📚 300.2 词汇列表 section - 部分 sector - 部门 bisect - 二等分 dissect - 解剖 intersection - 交点,十字路口 insect - 昆虫 trisect - 三等分 subsection - 小部分 transect - 横切 venesection - 刺血术 处理脚本 文本处理的时候写了个脚本帮助处理 链接添加 1. aquarium - 水族馆 转换为下面这样 1. [aquarium](https://www.baidu.com/s?wd=aquarium) - 水族馆 import re import sys # 定义生成百度搜索链接的函数 def generate_baidu_search_link(word): baidu_link = f'https://www.baidu.com/s?wd={word}' return f'[{word}]({baidu_link})' # 读取 Markdown 文件并处理 def process_markdown(input_file, output_file): with open(input_file, 'r', encoding='utf-8') as infile: lines = infile.readlines() # 处理文本内容 processed_lines = [] last_line_was_empty = False previous_line_was_match = False # 用于标记上一行是否为匹配行 for line in lines: line = line.strip() # 去除每行前后的空白字符 # 如果这一行符合我们要求的模式(以 "数字. 英文单词" 开头) if re.match(r"^\d+\.\s+[a-zA-Z]+", line): # 如果前一行是空行,且当前行符合匹配模式,跳过空行 if last_line_was_empty and previous_line_was_match: processed_lines.pop() # 删除前面添加的空行 # 提取数字、英文单词和中文描述部分 match = re.match(r"^(\d+)\.\s+([a-zA-Z]+)\s+-\s+(.*)$", line) if match: number = match.group(1) # 提取数字 word = match.group(2) # 提取英文单词 chinese = match.group(3) # 提取中文描述 # 生成百度搜索链接 baidu_link = generate_baidu_search_link(word) # 格式化处理后的行,去掉前面的 "-" processed_line = f"{number}. {baidu_link} - {chinese}" processed_lines.append(processed_line) previous_line_was_match = True last_line_was_empty = False elif line == '': # 如果是空行,并且前一行不是空行,则跳过该空行 if not last_line_was_empty: processed_lines.append('') last_line_was_empty = True else: # 对于其他行,直接加入 processed_lines.append(line) last_line_was_empty = False previous_line_was_match = False # 将处理后的内容写入新文件 with open(output_file, 'w', encoding='utf-8') as outfile: outfile.write('\n'.join(processed_lines)) # 确保命令行参数正确传递 if len(sys.argv) != 3: print("Usage: python script.py <input_file> <output_file>") sys.exit(1) # 获取输入文件和输出文件名 input_file = sys.argv[1] output_file = sys.argv[2] # 处理文件 process_markdown(input_file, output_file) print(f"Markdown 文件处理完成,结果已保存到 {output_file}") 运行命令: python process_markdown.py input.md output.md 参考&致谢 3000托福雅思词汇(词根版) 101个句子记完8000个英语单词

2024/11/17
articleCard.readMore

音乐推荐《爱是你我》-刀郎

具备演唱技巧的歌手每个时代都会出现很多个,但用灵魂演唱的歌手几十年都不一定出现一个!萨顶顶,周深就是其中的佼佼者,他们的演唱技巧让人叹服;但说到用生命演唱,用灵魂来演唱来打动人心的歌手就屈指可数了。刀郎就是其中之一。 有人说,刀郎的歌,你读它是诗,你唱它是歌,你念它是过往,你品它就是人生! 刀郎简介 刀郎(罗林)是一位著名的中国音乐人,出生于四川自贡。他以独特的嗓音和深情的演唱风格闻名,尤其在2004年凭借《2002年的第一场雪》爆红,迅速成为家喻户晓的歌手。然而,尽管他深受普通大众的喜爱,他的音乐风格和商业市场的主流不完全契合,因此在职业生涯中曾一度受到行业内的打压和忽视。 面对这种压力,刀郎选择了低调隐忍,几乎淡出了公众视野十几年,专注于自己的音乐创作,过着远离聚光灯的生活。直到近年,他以更加成熟的音乐作品《罗刹海市》重返舞台,并且,一出场就又是巅峰,证明了他坚持内心和艺术的力量。这种经历让刀郎不仅成为了音乐界的传奇,更是隐忍和坚韧的象征。 《爱是你我》 背景 这歌开始的传唱度的确很低,因为它原本不在流行音乐领域传播,直到小沈阳春晚唱了这首歌。 小沈阳春晚唱这歌,多少是因为它的超高音,可以充分表现唱功。 但《爱是你我》的生命力很强,地位超高。 绝大多数听众都不是刀迷,根本不知道这歌唱的啥,这歌就一赈灾义演的民歌,05年刀郎参加印尼海啸义演,开演前临时写的一歌,花了就十多分钟写的你能信? 2004年刀郎接到邀请参加赈灾晚会,本来准备的是大眼睛,但是到现场发现不合适,直接一晚上写出来,当天自弹自唱!这实力也是绝了! 完了这歌拿了“五个一工程奖”(全国精神文明建设领域的最高奖),那些年度金曲奖跟国家的五个一奖比就是小宝宝。 《爱是你我》就不是情歌,它的“爱”指的互帮互助的人间真爱,“你我”指代人人、每个人,爱是你我,意即人民互帮互助,人间充满真爱。 “这世界 我来了 任凭风暴旋涡” 这首歌表达的是面对再大的困难,也不退缩,一种对生活的热爱,对征服困难的自信! 现场 MV .bbplayer{width: 100%; max-width: 850px; margin: auto} document.getElementById("mmedia-jUGTOIPthguWyYCM").style.height=document.getElementById("mmedia-jUGTOIPthguWyYCM").scrollWidth*0.76+"px"; window.onresize = function(){ document.getElementById("mmedia-jUGTOIPthguWyYCM").style.height=document.getElementById("mmedia-jUGTOIPthguWyYCM").scrollWidth*0.76+"px"; }; 歌曲《爱是你我》歌词 爱是你我 用心交织的生活 爱是你和我 在患难之中不变的承诺 爱是你的手 把我的伤痛抚摸 爱是用我的心 倾听你的忧伤欢乐 爱是你我 用心交织的生活 爱是你和我 在患难之中不变的承诺 爱是你的手 把我的伤痛抚摸 爱是用我的心 倾听你的忧伤欢乐 这世界 我来了 任凭风暴旋涡 正是你爱的承诺 让我看到了阳光闪烁 爱拥抱着我 我能感觉到它的抚摸 就算生活 给我无尽的苦痛折磨 我还是觉得幸福更多 我还是觉得幸福更多 后话 博客前面的文章中也推荐了两首音乐,韩红的《天亮了》,中岛美嘉的《曾经我也想过一了百了》,都展现了对生命的热爱,都是用灵魂演唱的歌曲。 虽然从用生命演唱的深度来说,《爱是你我》这首歌差了 《天亮了》 和 《曾经我也想过一了百了》一个档次,但神奇的在于,刀郎的每一首歌几乎都可以算是用灵魂来演唱。 系列教程 全部文章RSS订阅 音乐推荐 音乐推荐-爱是你我 音乐推荐-曾经我也想过一了百了 从文学的角度,分析韩红的《天亮了》 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版

2024/10/23
articleCard.readMore

如何将身体恢复到完美状态

如果你总是晚上睡不着,白天睡不醒;体重变重,头昏脑胀,记忆力和反应能力下降;脱发、内分泌紊乱,容易长痘等,那就要注意了,这些都是身体对我们的警告。本文会从以下几点帮助大家纠正: 从牙齿、脊椎、肠道、膀胱、肝、肾、胃、皮、肺、护肤、心脏、作息、情绪、运动、减肥、眼睛、饮食、脱发、面色等方面内容,帮助大家将身体恢复到完美状态。 一些说明:个人整理,不涉及专业医学相关健康内容,大家注意鉴别。整理不易,全网唯一,最全版本,谢绝抄袭等其他恶意行为。愿大家都健康快乐。 牙齿篇 牙齿是人体骨骼的一部分。上四门牙为心,下四门牙为肾。牙齿的好坏、脱落与皮、胃、肾、大肠、肝等脏腑有关。可以说,牙齿是健康的根本。 我们该怎么保护好牙齿呢? 不要随意拔牙。很多人会因为爱美做牙齿整形,拔掉几颗健康的牙,这就有可能会伤害到部分内脏的根基。 养成刷三次牙的习惯。很多人都能做到早晚各一次,但午饭后的刷牙却忽略了。尤其是有午休习惯的人,一定要在睡前刷牙。而且每次刷牙的时长不要低于两分半。 尽量少吃过硬过冰过烫的食物。比如咬核桃咬瓶盖,都会在无形中伤害牙齿的强度。一次两次可能不明显,常年累月会产生不可逆的伤害。 要注意补钙。这一点尤其是中老年人更要注意。牙齿松动与肾气衰竭和气血不足有关。长扣牙齿能强肾固精、平衡阴阳,疏通气血、畅通经络,从而增强机体的健康。扣齿生津、滋养肾中精气,可每日早晚各做一次。小便咬前牙、大便时咬后牙,闭口不要说话也可顾齿。 做到这些,你的牙齿会变得更加坚硬稳固,你的身体就离完美状态又近了一步。 肠道篇 大肠主经为肠道之关,能帮助身体调节体内水液代谢,同时传导排泄。小肠主液为受肾之灌,帮助身体吸收食物营养。肠道是人体重要的消化器官,肠道健康对身体的传导功能和吸收功能至关重要。 该怎么样护肠道呢? 保证睡眠不要熬夜。睡眠不足会损失肠、胃、脾三个脏器,导致消化不良、便秘、腹胀等问题。 避免暴饮暴食,避免火锅和冰饮同时食用。这样会损伤肠道粘膜,增加肠道负担,影响肠道蠕动和消化。 多吃根茎类富含膳食纤维的食物,如土豆、萝卜、番薯等,可以促进肠道蠕动,预防便秘和肠道炎症。 定期做肠镜胃镜检查。肠道癌症是人体最懒的癌症,从溃疡到癌变需要十年,保持每五年检查一次,可避免肠道病变。 肠道菌群可以帮助消化,抵抗感染、调节免疫。要减少精神压力,防止肠道菌群失调。 做到这些,你的身体就离完美状态又近了一步。 肝篇 肝是人体最大、最繁忙且唯一可再生的内脏器官。肝总共有五百多种功能,常见的功能有解毒功能、合成功能、代谢功能、再生功能等。简单来说,人体内产生的毒素都要通过肝脏来解毒。就比如酒精经过肝的处理,最终会变成水和二氧化碳。而我们需要的凝血因子、血蛋白都是由肝脏合成的。 相比于全球发病率为0.01%的肝癌,我国成年人脂肪肝的发病率高达29.9%。而肝病的治疗手段主要有药物治疗、人工肝治疗和肝移植三种,每一项的治疗费都是非常昂贵的。 想要拥有一个健康的肝脏,一定要从饮食、运动、心态三方面进行调整。杜绝深夜烧烤和一切高油高盐的食物,拒绝熬夜、调整心态、适量运动,你一定会有一个好肝的。你的身体就离完美状态又近了一步。 胃篇 胃有完全独立的神经系统,因此被称为人体的第二大脑。所以你日常的负面情绪会影响到你的胃。高压工作者常常都有胃酸倒流的情况,除了及时就医以外,这也是身体对我们的警告。 那么当处于焦虑、抑郁的时候,我们应该怎么办呢? 首先要减少生活中的负能量。往往一个好的居住环境总会让你有一个好的心情。而好的面容和身材也会大大的增加你的自信。记住,一定不要否认自己,让自己保持积极的情绪。日常要远离那些负面的人和事。 一定要有长跑的习惯,它会让你持良好的心态和对抗困难的勇气。还有一点一定要少吃精加工的食物。做到这些,你一定会有一个良好的胃。你的身体离完美状态又近了一步。 肺篇 肺的主要功能是主气、司呼吸、主宣发、肃降。意思是呼出浊气,肺将含有氧气的血液通过脉搏输送到全身,还会疏通水液在人体中的运行和排泄。如果你有暴汗和水肿的问题,那么就要注意了。 肺开窍于鼻,其华在皮毛。如果你的肺很好,那么你的皮肤和鼻子的呼吸也会很好。那么该如何保护自己的肺呢? 首先要减少吸入对肺部有害的气体,如香烟、炒菜的油烟以及户外的粉尘。常学习腹式呼吸法。尽量不要喝太凉的水,因为肺怕寒。适当的可以做一些有氧运动,增加我们的肺部功能。 拥有强大的肺,身体才会变得更加坚韧。你的身体离完美状态又近了一步。 肾篇 良好的肾能给身体带来什么? 肾主骨、生髓。这个髓指的是骨髓和脊髓,脊髓上通于脑。李时珍说过,脑为元神之府。肾对你的思维、记忆力、注意力有一定的影响。肾开窍于耳,肾好的人一般听力都很好。而听力下降、耳鸣都是肾对你的警告。肾之华在发,肾健康的人一般头发乌黑浓密,不易脱落。肾气足则精力充沛,尤其是休息后更是精力充沛。 我们应该如何保护自己的肾呢? 首先要保证日常的饮水量。尽量少盐,可以选择海盐,量保持在6克左右。日常不要憋尿。运动方面,推荐做提肛运动、凯格尔运动,对你的提升真的会很大。饮食方面,可以吃一些黑色的食物,如黑枸杞、黑芝麻、桑葚等。 拥有一颗强大的肾,你的身体就离完美状态又近了一步。 膀胱篇 膀胱为人体水源汇聚之所,故称之为"津液之腑"、“州都之关”。具有开合作用,维持储尿和排尿的协调平衡。 该怎么样护膀胱呢? 不要憋尿。有尿液就排空,憋尿会造成膀胱超负荷工作。可以理解为膀胱就是一个皮囊。 避免久坐,熬夜。如果偶尔需要熬夜,一定要多喝水,少喝咖啡和饮料,多排尿。 多运动。若锻炼太少会造成膀胱经不通。晚上睡觉时躺床上使劲蹬腿,蹬脚后跟也可以锻炼膀胱经。 多吃西瓜芹菜绿豆菠萝,对膀胱有好处。 拥有一个强壮的膀胱,你的身体就离完美状态又近了一步。 护肤篇 你真的了解自己的肤质吗?即使了解,你知道如何对症下药吗? 皮肤是人体非常神奇的组织。不管你戴着多薄的手套去摸一个东西,都很难感觉到那是什么。但如果直接用手去摸,闭上眼睛也能瞬间感觉出来那是金属还是塑料,是陶瓷还是另一个人的皮肤。 首先需要明确自己的肤质。现在去洗,把脸擦干,等半个小时。这个时候,有的人会觉得没什么感觉,那你就是中性皮肤。通常表现为不爱长痘,皮肤弹性好,不干燥,也不油腻。很多男性的皮肤都是这样,即使不用护肤品,肤质也照样很好。 有的人会面部比较干燥紧绷,我建议擦干后可以涂一些水乳。有的人会面部油腻,怎么除油都不管用。除油的办法我放到结尾,这些都是常见的肤质。 我教大家一套洗脸的办法:白天尽量不要用洗面奶,可以用冷水洗脸,用毛巾把水吸干。晚上用温水洗脸,洗脸前一定要洗手。用洗面奶在脸上画圈清洗,然后用毛巾吸干水分就可以护肤了。 针对于油性皮肤,不是用多好的产品去除油,而是保持规律作息,饮食清淡,不要过度熬夜和清洁皮肤。记得少用手去碰脸。 做到这样,你的身体就离完美状态又近了一步。 心脏篇 当心脏停止跳动,富含氧气的血液和营养就无法传递全身,导致所有器官和组织停止运作。如果没有除颤器和心脏复苏的技术,那么死亡的定义也会更改。死亡的定义是大脑排出所有氧气,且瞳孔会变成玻璃晶体的物质。 那么心脏到底有多重要呢?成年人正常安静时的心率在60到80次每分钟。如果你要进行有氧运动,心率是这样计算的:用220减去年龄分别乘以0.6和0.85,这个心率范围就是你的有氧运动心率。 心主血脉,其华在面,开窍于舌。可以通过面目和舌尖判断我们的心脏是否正常。心为君主之官,为五脏六腑之主。日常可以吃一些苦味食物,夏天避免暴汗。只要我们拥有一个好心脏,我们才能有好的器官,从而才能有健康的身体。 你的身体就离完美状态又近了一步。 作息篇 现在很多人都有失眠的困扰,难以入睡。不规律的作息往往会导致身体和精神都不在状态。你为什么难以入眠呢? 其实很大一部分原因是你把床的概念混淆了。因为只要你把平常做的事情(吃饭、打游戏、刷手机)都在床上做,大脑就很容易形成条件反射。你需要做的是建立睡觉和床的联系,让条件反射变成"床等于睡觉"。 不要一边玩手机一边告诉自己还有多久入睡。睡前的20分钟不要玩手机。打游戏和刷视频都有上瘾机制,它会使你的大脑兴奋,而且手机屏幕的光也会让你清醒。 睡前可以听一些音乐或者听小四的频道,但是要调定时,整晚播放会让你睡不好觉。晚上11点之前最好能进入睡眠。只要保持长期的规律睡眠,你的作息就是健康的。 熬夜的标准是睡眠时间小于7小时且睡眠周期不规律。保持良好的作息才能让你有充沛的体力和精神,你的身体就离完美状态又近了一步。 情绪篇 你知不知道人类90%以上的疾病都跟坏情绪有关?长期的负面情绪是200多种疾病的真正诱因。当生气、悲伤、恐惧、压力、委屈这些负面情绪长期纠缠你的时候,首先就是攻击你身体的免疫系统。在这个强大的敌人面前,什么养生、滋补、保健通通不堪一击。 第一招,千万别跟身边的人较劲。你身边的任何人都不可能无缘无故听从你的安排和指挥,你必须给到他们相应的好处。努力决定能力,能力决定价值,价值决定吸引力。在自己的价值不够之前,不要指望任何人符合你的心意。收回对别人过高的要求期望。 第二招,停止一切胡思乱想。不要去咀嚼过往糟糕的烦心琐事。今天的大事只不过是明天的小事,曾经让你哭的事,今天你不也能笑着说出来吗?要学会放下,没有谁能伤害你,真正能伤害你的只有你自己。永远不要跟傻瓜论长短。 第三招,面对自己不愿意做的事以及别人无理的要求,要学会拒绝。不要过于在乎他人的感受而忽略自己的需要,让自己陷入不好的情绪。并不是要让你做一个自私的人,只有适当的取舍,你才能收获更多的快乐。 做到这样,你距离完美状态又近了一步。 运动篇 当身体长时间处于不运动的状态,情绪往往会变得低迷、焦虑、敏感,不易产生快乐。皮肤也会变得暗沉、发黄、松弛,而且身体极易发胖。那如何运动才合理呢? 每周至少完成150分钟到300分钟的中等强度到高强度的有氧运动,包括慢跑、游泳、爬楼梯、骑单车等。也要搭配一些力量训练,如哑铃及一些健身器材。 当有了充足的运动,情绪会变得乐观,精神也会变得更有韧性,皮肤也会变好。如果你日常有不爱吃水果蔬菜、不爱运动、经常熬夜的习惯,建议每天补充一粒维生素C。 运动改变的不仅是外在,对内心也会有很大的改变。运动,特别是有氧运动,每天跑3公里就行,特别有效,精神会好很多。即使熬夜没睡好,也跟喝了红牛一样,非常有精神。至少对我来讲是这样。 减肥篇 饿瘦的原理是什么呢?你必须要明白饥饿感是由于血糖低,大脑的求食中枢发出来的。如果你能扛住饿,身体就会调动肌肉和肝脏里的脂肪糖原给身体功能。当你身体的储备糖用完时,才会去分解脂肪,把脂肪转化为糖,给身体供应能量。只有脂肪参与了,你才能瘦。 所以,感到饿的时候,身体才会开始燃烧脂肪。血糖稳定住了,饥饿感就会消失。这个阶段就叫做饿过头了。这个时候,你不但在变瘦,还没有饥饿感。你只要能扛住前期的饥饿感,就能一直瘦。 熬夜会发胖,焦虑也会发胖,夜宵更会发胖。如果你想减肥,这些都要尽量避免。保持良好的运动,管住嘴迈开腿相结合,你的身体就离完美状态又近了一步。 脊椎篇 脊椎是人体的支柱,也是中医理论中的督脉,是人体的一条大阳经,主气贯穿全身。对人体的脑髓、肾脏、腰脊、脊髓、生殖能力等都有非常重要的作用。该怎么保护我们的脊椎呢? 颈椎是脊椎中较脆弱的部分,容易受到外界影响。脊椎怕冷,秋冬天要注意脖子保暖,避免风寒侵袭。同时,要避免长时间低头看手机、躺床上看电视看书等,这些会对脊椎进行大角度的弯曲挤压,容易造成脊椎的劳损和变形。要保持良好的生活习惯,坐姿端正,经常适度运动,增强颈部肌肉力量,改善局部血液循环。睡眠时选择合适的枕头,确保颈椎处于自然状态。 胸椎是脊椎中相对稳定的部分,同样不可忽视。久坐会严重损伤胸椎和颈椎。避免久坐、久站、久卧等单一姿势,要经常变换姿势,促进血液循环和代谢。如果出现背疼、恶心等症状,要及时去医院检查。 腰椎是脊椎中容易受伤的部分,腰椎承受着全身的重量。要保护腰椎,避免交叉腿站立、单脚站立、长时间翘二郎腿、歪着身子、开车等不良动作。这些动作会对腰椎造成不平衡的压力,导致腰椎的损伤和变形。经常做一些脊椎保健操,增强肌肉的力量和弹性,缓解脊椎的压力和疲劳。 拥有健康的脊椎,你的身体就离完美状态又近了一步。 眼睛篇 眼睛的健康与五脏的平衡密切相关,长时间用眼、电子屏幕、辐射等现代生活方式容易导致肝气郁结,不可避免地会让眼部疲劳。今天教你如何一分钟消除眼部疲劳: 按抚明目,缓解肝气郁结。过度用眼导致肝气郁结,眼睛疲劳。每日早晚将温水浸湿纱布,稍加拧干后,轻轻敷于闭着的双眼上方,有助于调和肝气。 揉掌暖目,缓解心肺关系。双手搓热轻和双眼,绕着太阳穴和眉心处揉动,有助于调和心肺关系,增加眼部血液循环。 绿茶滋润抗氧化明眸。绿茶富含抗氧化成分,也是缓解眼部疲劳的良方。用温热的绿茶浸泡纱布,稍稍拧干后,覆盖在双眼上,滋养眼部,让眼睛重现明亮。 驱风散寒,减轻眼部不适。长时间面对电子屏幕,容易感染风寒,泪液流出,是眼睛的自我保护。温毛巾热敷眼部,或用双手搓热,轻轻抚摸眼周,有助于驱风散寒。 黄连有清热解毒的功效。在眼睛干涩红肿时,用黄连粉末冲泡成黄连水,用来洗眼,清热明目。 简单眼操,活络经络。闭目横竖转动眼珠,眼尾绕圆,反复眨眼,有助于活络经络,增加眼部血液循环。 预防眼睛疲劳,按抚明目,揉掌暖目,与绿茶共应,好好爱自己。做到这样,你的身体就离完美状态又近了一步。 近视恢复: 晒眼皮:闭上眼睛,朝向太远,晒眼睛。 看远处:看向远处的山峰,摇摆头部,看清远近的每个景物,调节眼睛肌肉状态。看太阳,快速摇摆眼睛,也可以快速恢复调节眼睛聚焦! 脾篇 脾脏是人体内最大的淋巴器官。淋巴是由淋巴细胞以及淋巴液组成,分布在全身各处,是组成免疫系统的重要成分。因此,脾脏也是人体很重要的具有免疫功能的器官。如何调理好自己的脾呢? 第一,注意保暖。我国的中医认为,大部分疾病都是阴阳不协调,风湿寒会侵入肌体导致的。大部分的疾病都是没有做好保暖措施,在春季早晚温差大又是过早地脱掉厚衣服,导致湿寒入体。而湿寒之气对脾的伤害是很大的,它们会堆积在脾内,导致消化不良,胃疼,肠胃炎症等。日常要做好保暖,注意温度变化,尤其是腹部的保暖。很多女孩喜欢穿露脐装,其实是对身体很不利的。 第二,适度按摩。经常按摩腹部也能起到健脾的效果。双手放在肚脐附近,顺时针和逆时针各轻柔60下。注意力度不要太大,按摩时间也不能过长。平常躺在床上的时候也可按摩足三里穴,同样能达到调节脾胃的功效。 调理好自己的脾,身体免疫功能才会变得更强大,你的身体离完美状态又近了一步。 总结篇 现在的人身心为什么如此堵塞?原因主要是营养过剩和缺乏运动以及心态失衡。 过去的人生活简朴,食物简单,需要从事体力劳动,因此身体相对空虚。生病后补充一些营养就能迅速恢复。现在的人营养过剩,常常追求美食,缺乏运动,导致身体淤积。 身体的虚,即庄子所说的空,是指身体内有无限能量储备的空间。但当营养过剩且缺乏运动时,这个空间反而被堵塞。过去食物匮乏,一年只能吃到几顿好的食物,所以每一顿都显得特别香,有浓郁的年味。而现在顿顿都是大鱼大肉,消化需要时间。而频繁进食和冰冻饮料则消耗了脾胃的动能,导致肠胃堵塞。 另一方面,现在的人缺乏运动锻炼。如果每天花费七八个小时在体力劳动中,能量消耗会疏通身体的淤滞。然而现在很多人缺乏锻炼,导致身体的淤积问题日益严重。 所谓的浑沌,身心不二,是指身体和心理的状态相互关联。一个人如果思想固执,不接纳别人的观点,容易对事物产生偏见,就会导致身心堵塞。此外,长期的愤怒焦虑等不良情绪会影响气血的运行。保持乐观的情绪对整体身心的健康尤为重要。 我们应尽量避免陷入不良情绪中。经常生气会特别伤肝,因为女性的重要器官多与肝经相关。过度喜悦也容易伤心。所以我们要给情绪设置一个减速带,时刻提醒自己。过度思虑会伤脾,焦虑和反复琢磨不确定的事情会使事情纠结在脾胃中,导致肠胃不适。太忧伤会伤肺 篇后语 多个ai工具对比使用,还是 claude 总结效果最好。下面是语音转文字记录 天涯神帖,如何将身体恢复到完美状态 如果你总是晚上睡不着,白天睡不醒 体重变重,头昏脑胀,记忆力和反应能力下降 射孔,脱发,内分泌紊乱,容易长痘等 那就要注意了,这些都是身体对我们的警告 本文会从以下几点帮助大家纠正 从牙齿、脊椎、肠道、膀胱、肝、肾、胃、皮、肺 护肤、心脏、坐息、情绪、运动、减肥、眼睛、饮食 脱发、面色等方面内容 帮助大家将身体恢复到完美状态 一些说明,个人整理,不涉及专业医学相关健康内容 大家注意鉴别 整理不易,全网唯一,最全版本 谢绝抄袭等其他恶意行为 愿大家都健康快乐 第一篇,牙齿 牙齿是人体骨骼的一部分 上四门牙为心,下四门牙为肾 牙齿的好坏、脱落 与皮、胃、肾、大肠、肝等脏腑有关 可以说,牙齿是健康的根本 我们该怎么保护好牙齿呢? 一、不要随意拔牙 很多人会因为爱美做牙齿整形 拔掉几颗健康的牙 这就有可能会伤害到部分内脏的根基 二、养成刷三次牙的习惯 很多人都能做到早晚各一次 但午饭后的刷牙却忽略了 尤其是有午休习惯的人 一定要在睡前刷牙 而且每次刷牙的时长不要低于两分半 三、尽量少吃过硬过冰过烫的食物 比如咬核桃咬瓶盖 都会在无形中伤害牙齿的强度 一次两次可能不明显 常年累月会产生不可逆的伤害 四、要注意补钙 这一点尤其是中老年人更要注意 牙齿松动与肾气蓄衰和气血不足有关 长扣牙齿能强肾固精、平衡阴阳 疏通气血、畅通经络 从而增强机体的健康 扣齿生津、滋养肾中精气 可每日早晚各做一次 小便咬前牙、大便时咬后牙 闭口不要说话也可顾齿 做到这些 你的牙齿会变得更加坚硬稳固 你的身体就离完美状态又近了一步 二、肠道偏 大肠主经为肠道之关 能帮助身体调节体内水液代谢 同时传到排泄 小肠主液为受肾之灌 帮助身体吸收食物营养 肠道是人体重要的消化器官 肠道健康对身体的传到功能 和吸收功能至关重要 该怎么样护肠道呢? 一、保证睡眠不要熬夜 睡眠不足会损失肠、胃、脾三个脏器 导致消化不良、便秘、腹胀等问题 二、避免暴饮暴食 避免火锅和冰饮同时食用 这样会损伤肠道黏膜 增加肠道负担 影响肠道蠕动和消化 三、多吃根茎类富含膳食纤维的食物 如土豆、萝卜、番薯等 可以促进肠道蠕动 预防便秘和肠道炎症 四、定期做肠经胃镜检查 肠道癌症是人体最懒的癌症 从溃疡到癌变需要十年 保持每五年检查一次 可避免肠道病变 五、肠道菌群可以帮助消化 抵抗感染、调节免疫 要减少精神压力 防止肠道菌群失调 做到这些 你的身体就离完美状态又近了一步 三、肝片 肝是人体最大、最繁忙 且唯一可再生的内脏器官 肝总共有五百多种功能 常见的功能有解毒功能、合成功能 代谢功能、再生功能等 简单来说 人体内产生的毒素都要通过肝脏来解毒 就比如酒精经过肝的处理 最终会变成水和二氧化碳 而我们需要的凝血因子、血蛋白 都是由肝脏合成的 相比于全球发病率为0.01%的肝癌 我们国内成年人脂肪肝的发病率 高达29.9% 而肝病的治疗手段主要有药物治疗 人工肝治疗和肝移植三种 每一项的治疗费都是非常昂贵的 想要拥有一个健康的肝脏 一定要从饮食、运动、心态三方面进行调整 杜绝深夜烧烤和一切高油高盐的食物 拒绝熬夜、调整心态、适量运动 你一定会有一个好肝的 你的身体就离完美状态又近了一步 4.胃片 它有完全独立的神经系统 因此被称为人体的第二大脑 所以你日常的负面情绪会影响到你的胃 高压工作者常常都有胃酸倒流的情况 除了及时就医以外 这也是身体对我们的警告 那么当处于焦虑、抑郁的时候 我们应该怎么办呢? 首先要减少生活中的负能量 往往一个好的居住环境 总会让你有一个好的心情 而好的面容和身材 也会大大的增加你的自信 记住,一定不要否认自己 让自己保持积极的情绪 日常要远离那些负面的人和事 一定要有长跑的习惯 它会让你持良好的心态和对抗困难的勇气 还有一点一定要少吃精加工的食物 做到这些,你一定会有一个良好的胃 你的身体比完美状态又近了一步 5.肺片 肺的主要功能是主气、私呼吸、主宣发、速降 意思是呼出浊气 肺将含有氧气的血液通过白脉输送到全身 还会疏通水液在人体中的运行和排泄 如果你有爆汗和水肿的问题 那么就要注意了 肺开窍于鼻,齐滑在皮毛 如果你的肺很好 那么你的皮肤和鼻子的呼吸也会很好 那么该如何保护自己的肺呢? 首先要减少吸入对肺部有害的气体 如香烟、炒菜的油烟以及户外的粉尘 常学习腹式呼吸法 尽量不要喝太凉的水,因为肺怕寒 适当的可以做一些有氧运动 增加我们的肺部功能 拥有强大的肺,身体才会变得更加坚韧 你的身体离完美状态又近了一步 6.肾片 良好的肾能给身体带来什么? 肾主骨、生髓 这个髓指的是骨髓和脊髓 脊髓上通于脑 李时珍说过,脑为元神之辅 肾对你的思维、记忆力、注意力有一定的影响 肾开窍于耳 肾好的人一般听力都很好 而听力下降、耳鸣都是肾对你的警告 肾脐滑在发 肾健康的人一般头发乌黑浓密,不易脱落 肾气足则精力充沛 尤其是休息后更是精力充沛 我们应该如何保护自己的肾呢? 首先要保证日常的饮水量 尽量少盐,可以选择海盐 量保持在6克左右 日常不要憋尿 运动方面,推荐做提缸运动、凯格尔运动 对你的提升真的会很大 饮食方面,可以吃一些黑色的食物 如黑枸杞、黑芝麻、桑任等 拥有一颗强大的肾 你的身体就离完美状态又近了一步 7、膀胱片 膀胱为人体水源汇聚之所 故称之为「今夜之腹」、「周都之关」 具有开合作用,维持储尿和排尿的协调平衡 该怎么样护膀胱呢? 1、不要憋尿 有尿液就排空,憋尿会造成膀胱超负荷工作 可以理解为膀胱就是一个皮囊 2、避免久坐,熬夜 如果偶尔需要熬夜,一定要多喝水 少喝咖啡和饮料,多排尿 3、多运动 若锻炼太少会造成膀胱经不通 晚上睡觉时躺床上使劲蹬腿 蹬脚后跟也可以锻炼膀胱经 4、多吃西瓜芹菜绿豆菠萝 对膀胱有好处 拥有一个强壮的膀胱 你的身体就离完美状态又近了一步 感谢收听,感谢三连 若您需要PDF完整原版 或想要了解更多内容 欢迎关注微信公众号「四维收藏」 比三维多了一个维度 所以取名「四维收藏」 8、护肤片 你真的了解自己的肤质吗? 即使了解,你知道如何对症下药吗? 皮肤是人体非常神奇的组织 不管你戴着多薄的手套去摸一个东西 都很难感觉到那是什么 但如果直接用手去摸 闭上眼睛也能瞬间感觉出来 那是金属还是塑料 是陶瓷还是另一个人的皮肤 首先需要明确自己的肤质 现在去洗,把脸擦干 等半个小时 这个时候,有的人会觉得没什么感觉 那你就是中性皮肤 通常表现为不爱长痘 皮肤弹性好,不干燥,也不油腻 很多男性的皮肤都是这样 即使不用护肤品,肤质也照样很好 有的人会面目比较干燥紧绷 我建议擦干后可以涂一些水乳 有的人会面目油腻,怎么除油都不管用 除油的办法我放到结尾 这些都是常见的肤质 我教大家一套洗脸的办法 白天呢,尽量不要用洗面奶 可以用冷水洗脸,用毛巾把水吸干 晚上用温水洗脸 洗脸前一定要洗手 用洗面奶在脸上画圈清洗 然后用毛巾吸干水分就可以护肤了 针对于油性皮肤,不是用多好的产品去除油 而是保持规律作息,饮食清淡 不要过度熬夜和清洁皮肤 记得少用手去碰脸 这样你就离完美状态又近了一步 9.心脏偏 当心脏停止跳动 富含氧气的血液和营养就无法传递全身 导致所有器官和组织停止运作 如果没有除颤器和心脏复苏的技术 那么死亡的定义也会更改 死亡的定义是大脑排出所有氧气 且瞳孔会变成玻璃晶体的物质 那么心脏到底有多重要呢? 成年人正常安静时的心率在60到80次每分钟 如果你要进行有氧运动 心率是这样计算的 用220减去年龄分别乘以0.6和0.85 这个心率范围就是你的有氧运动心率 心主血脉,齐滑在面,开窍于舌 可以通过面目和舌尖判断我们的心脏是否正常 心为君主之官,为五脏六腑之主 日常可以吃一些苦味食物 夏天避免爆汗 只要我们拥有一个好心脏 我们才能有好的器官 从而才能有健康的身体 你的身体就离完美状态又近了一步 10.作息片 现在很多人都有失眠的困扰,难以入睡 不规律的作息往往会导致身体和精神都不在状态 你为什么难以入眠呢? 其实很大一部分原因是你把床的概念混淆了 因为只要你把平常做的事情 吃饭、打游戏、刷手机都在床上做 大脑就很容易形成条件反射 你需要做的是建立睡觉和床的联系 让条件反射变成床等于睡觉 不要一边玩手机一边告诉自己还有多久入睡 睡前的20分钟不要玩手机 打游戏和刷视频都有上瘾机制 它会使你的大脑亢奋 而且手机屏幕的光也会让你清醒 睡前可以听一些音乐或者听小四的频道 但是要调定时整晚播放会让你睡不好觉 晚上11点之前最好能进入睡眠 只要保持长期的规律睡眠 你的作息就是健康的 熬夜的标准是睡眠时间小于7小时 且睡眠周期不规律 保持良好的作息才能让你有充沛的体力和精神 你的身体就离完美状态又近了一步 11.情绪骗 你知不知道人类90%以上的疾病都跟坏情绪有关 长期的负面情绪是200多种疾病的真正诱因 当生气、悲伤、恐惧、压力、委屈这些负面情绪长期纠缠你的时候 首先就是攻击你身体的免疫系统 在这个强大的敌人面前 什么养生、滋补、保健通通不堪一击 第一招,千万别跟身边的人较劲 你身边的任何人都不可能无缘无故听从你的安排和指挥 你必须给到他们相应的好处 努力决定能力,能力决定价值,价值决定吸引力 在自己的价值不够之前 不要指望任何人符合你的心意 收回对别人过高的要求期望 第二招,停止一切胡思乱想 不要去咀嚼过往糟糕的烦心琐事 今天的大事只不过是明天的小事 曾经让你哭的事,今天你不也能笑着说出来吗? 要学会放下,没有谁能伤害你 真正能伤害你的只有你自己 永远不要跟傻瓜论长短 第三招,面对自己不愿意做的事 以及别人无理的要求,要学会拒绝 不要过于在乎他人的感受而忽略自己的需要 让自己陷入不好的情绪 并不是要让你做一个自私的人 只有适当的取舍,你才能收获更多的快乐 做到这样,你距离完美状态又近了一步 十二,运动骗 当身体长时间处于不运动的状态 情绪往往会变得低迷、焦虑、敏感 不易产生快乐 皮肤也会变得暗沉、发黄、松弛 而且身体极易发胖 那如何运动才合理呢? 每周至少完成150分钟到300分钟的中等强度到高强度的有氧运动 包括慢跑、游泳、爬楼梯、骑单车等 也要搭配一些力量训练 如哑铃及一些健身器材 当有了充足的运动,情绪会变得乐观 精神也会变得更有韧性,皮肤也会变好 如果你日常有不爱吃水果蔬菜、不爱运动、经常熬夜的习惯 建议每天补充一粒维生素C 运动改变的不仅是外在,对内心也会有很大的改变 运动,特别是有氧运动,每天跑3公里就行 特别有效,精神会好很多 即使熬夜没睡好,也跟喝了红牛一样,非常有精神 至少对我来讲是这样 13.减肥篇 恶瘦的原理是什么呢? 你必须要明白饥饿感是由于血糖低,大脑的求食中枢发出来的 如果你能扛住饿,身体就会调动肌肉和肝脏里的脂肪糖源给身体功能 当你身体的储备糖用完时,才会去分解脂肪 把脂肪转化为糖,给身体供应能量 只有脂肪参与了,你才能瘦 所以,感到饿的时候,身体才会开始燃烧脂肪 血糖稳定住了,饥饿感就会消失 这个阶段就叫做饿过头了 这个时候,你不但在变瘦,还没有饥饿感 你只要能扛住前期的饥饿感,就能一直瘦 熬夜会发胖,焦虑也会发胖,夜宵更会发胖 如果你想减肥,这些都要尽量避免 保持良好的运动,管住嘴脉开腿相结合 你的身体就离完美状态又近了一步 13.脊椎偏 脊椎是人体的支柱,也是中医理论中的督脉 是人体的一条大阳经,主气贯穿全身 对人体的脑髓、肾脏、腰脊、脊髓、生殖能力等都有非常重要的作用 该怎么保护我们的脊椎呢? 1.颈椎是脊椎中较脆弱的部分,容易受到外界影响 脊椎怕冷,秋冬天要注意脖子保暖,避免风寒侵袭 同时,要避免长时间低头看手机、躺床上看电视看书等 这些会对脊椎进行大角度的弯曲挤压,容易造成脊椎的劳损和变形 要保持良好的生活习惯,坐姿端正,经常适度运动 增强颈部肌肉力量,改善局部血液循环 睡眠时选择合适的枕头,确保颈椎处于自然状态 2.胸椎是脊椎中相对稳定的部分,同样不可忽视 久坐会严重损伤胸椎和颈椎 避免久坐、久站、久卧等单一姿势,要经常变换姿势,促进血液循环和代谢 如果出现背疼、恶心等症状,要及时去医院检查 3.腰椎是脊椎中容易受伤的部分,腰椎承受着全身的重量 要保护腰椎,避免交叉腿站立、单脚站立、长时间翘二郎腿、歪着身子、开车等不良动作 这些动作会对腰椎造成不平衡的压力,导致腰椎的损伤和变形 经常做一些脊椎保健操,增强肌肉的力量和弹性,缓解脊椎的压力和疲劳 拥有健康的脊椎,你的身体就离完美状态又近了一步 14.眼睛偏,如何缓解眼部疲劳? 眼睛的健康与五脏的平衡密切相关,长时间用眼、电子屏幕、辐射等现代生活方式容易导致干气郁结 不可避免的会让眼部疲劳 今天教你如何一分钟消除眼部疲劳 第一,按抚明目,缓解干气郁结 过度用眼导致干气郁结,眼睛疲劳 每日早晚将温水浸湿眼球,稍加凝干后,轻轻敷于闭着的双眼上方,有助于调和干气 第二,揉掌暖目,缓解心肺关系 双手搓热亲和双眼,绕着太阳穴和眉心处揉动,有助于调和心肺关系,增加眼部血液循环 第三,绿茶滋润抗氧化明眸 绿茶富含抗氧化成分,也是缓解眼部疲劳的良方 用温热的绿茶浸泡纱布,稍稍凝干后,覆盖在双眼上,滋养眼部,让眼睛重现明亮 第四,驱风散寒,减轻眼部不适 长时间面对电子屏幕,容易感染风寒,泪液流出,是眼睛的自我保护 温毛巾热久眼部,或用双手搓热,轻轻抚摸眼周,有助于驱风散寒 第五,黄莲有清热解毒的功效 在眼睛干涩红肿时,用黄莲粉末冲泡成黄莲水,用来洗眼,清热明目 第六,简单眼操,活络经络闭目 横竖转动眼珠,眼尾绕圆,反复眨眼,有助于活络经络,增加眼部血液循环 预防眼睛疲劳,按抚明目,揉掌暖目,与绿茶共应,好好爱自己 做到这样,你的身体就离完美状态又近了一步 十六,脾偏 脾脏是人体内最大的淋巴器官 淋巴是由淋巴细胞以及淋巴液组成,分布在全身各处,是组成免疫系统的重要成分 因此,脾脏也是人体很重要的具有免疫功能的器官 如何调理好自己的脾呢? 第一,注意保暖 我国的中医认为,大部分疾病都是阴阳不协调,风湿血会侵入肌体导致的 大部分的疾病都是没有做好保暖措施 在春季早晚温差大又是过早地脱掉厚衣服,导致湿血入体 而湿寒之气对脾的伤害是很大的,它们会堆积在脾内,导致消化不良,胃疼,肠胃炎症等 日常要做好保暖,注意温度变化,尤其是腹部的保暖 很多女孩喜欢穿露其装,其实是对身体很不利的 第二,适度按摩 经常按摩腹部也能起到健脾的效果 双手放在肚脐附近,顺时针和逆时针各轻柔60下 注意力度不要太大,按摩时间也不能过长 平常躺在床上的时候也可按摩足三里穴,同样能达到调节脾胃的功效 调理好自己的脾,身体免疫功能才会变得更强大,你的身体离完美状态又近了一步 十七,总结篇 现在的人身心为什么如此堵塞? 原因主要是营养过剩和缺乏运动以及心态失衡 过去的人生活简朴,食物简单,需要从事体力劳动,因此身体相对空虚 生病后补充一些营养就能迅速恢复 现在的人营养过剩,常常追求美食,缺乏运动,导致身体淤积 身体的虚,即庄子所说的空,是指身体内有无限能量储备的空间 但当营养过剩且缺乏运动时,这个空间反而被堵塞 过去食物匮乏,一年只能吃到几顿好的食物 所以每一顿都显得特别香,有浓郁的年味 而现在顿顿都是大鱼大肉,消化需要时间 而频繁进食和冰冻饮料则消耗了脾胃的动能,导致肠胃堵塞 另一方面,现在的人缺乏运动锻炼 如果每天花费七八个小时在体力劳动中,能量消耗会疏通身体的淤涩 然而现在很多人缺乏锻炼,导致身体的淤积问题日益严重 所谓的混沌,身心不二,是指身体和心理的状态相互关联 一个人如果思想固执,不接纳别人的观点 容易对事物产生偏见,就会导致身心堵塞 此外,长期的愤怒焦虑等不良情绪会影响气血的运行 保持乐观的情绪对整体身心的健康尤为重要 我们应尽量避免陷入不良情绪中 经常生气会特别伤肝,因为女性的重要器官多与肝经相关 过度喜悦也容易伤心 所以我们要给情绪设置一个减速带,时刻提醒自己 过度思虑会伤脾,焦虑和反复琢磨不确定的事情 会使事情纠结在脾胃中,导致肠胃不适 太忧伤会伤肺,比如淋带欲悲伤过度导致肺病 过度担忧会伤肾,避免看恐怖片等引发的恐惧,不利于肾脏健康 拥有情绪是正常的,但要避免情绪的极端波动和长期不排解对已经产生的情绪 要寻找健康的排解方式,平衡自己的心态,时刻铭记 关你屁事,关我屁事 少挂心一些无关紧要的事情,多关注让自己开心轻松的事情 要保持平常心,减少欲望,过多欲望会导致焦虑和思虑 尽量不要让自己陷入困境,不要因为不值得的人和事情调动情绪 因为这不仅没有好处,还会伤害自己的身心 不要为没发生的事情担忧,活在当下,很多担心的事情都不会发生 我们应该追求平衡的饮食,适当锻炼,保持心态开放,实现身心的平衡 做到这样,距离身体完美状态又近了一步 人生短暂而又漫长,请多爱护自己,希望大家每天都能过得安心舒适 好了,如何将身体恢复到完美状态,小四就为您讲述到这里 感谢收听,感谢三连 参考&致谢 https://claude.ai/ openai/whisper 天涯神贴:《如何将身体恢复到完美状态》全十七篇,全网唯一,健康养生,健康综合,好看视频 系列教程 全部文章RSS订阅 健康系列 健康分类RSS订阅 如何将身体恢复到完美状态 健身从基础常识到实践指导! 中西医的优缺点

2024/8/23
articleCard.readMore

如何安装OfficeLTSC2021并KMS破解激活教程

office功能强大,是日常办公必备工具!其激活和破解其实可以很简单,使用KMS激活,纯命令行激活,不需要破解工具,没有中毒风险!如何下载office 并激活,自建 KMS 服务器本文全介绍。 背景 office零售版和批量授权版区别 零售版(RTL Edition) 指的是官方出售的版本,只能激活一台电脑!享受微软售后技术服务!Retail(零售版也称消费者版,32和64位共用安装包,要转换才能KMS激活) 批量授权版(VOL Edition) 指的是针对企业客户的大批量采购的版本,可用MARK密钥永久激活!(批量版也称商业版或大客户批量授权版,缩写VL或VOL) ﹂适用企业客户批量许可部署的版本,无需转换可以通过使用KMS激活授权 简单的说,零售版用KEY激活后,如果微软不封,可以一直使用。(你有正版KEY不用担心这个问题) 批量授权版(也称大客户版,缩写VOL或VL)可以在网上找MARK密钥激活,一旦激活成功,不怕被封;也可以用KMS进行180天激活。 这两个版本功能上并无区别,只是激活的方式不一样。 新版变化 Office LTSC 2021 和 Office 2021 的更新历史记录 | Microsoft Docs https://docs.microsoft.com/en-us/officeupdates/update-history-office-2021 安装文件下载地址 官方下载 如何下载和安装 Office LTSC 2021 Office 部署工具 对于 Windows,Office LTSC 2021 是使用即点即用安装技术安装的。Microsoft 不提供安装程序下载;相反,计算机管理员需要使用 Office 部署工具 (ODT) 来安装 Office LTSC 2021。操作方法如下: 官方教程 技巧: 提示:在安装 Office LTSC 2021 之前,您需要卸载 Office 的现有版本。 步骤1:前往Microsoft官网下载Office部署工具。 第 2 步:运行 Office 部署工具 exe 文件进行安装。然后,吃午饭并选择一个文件夹来存储文件。 步骤3: 然后,您可以在该位置看到这些文件。 第4步: 现在,您需要创建configuration.xml文件。复制**“Configuration-Office2021Enterprise”文件**,重命名为configuration.xml 选择“使用记事本打开”。 configuration.xml <!-- Office 2021 enterprise client configuration file sample. To be used for Office 2021 enterprise volume licensed products only, including Office 2021 Professional Plus, Visio 2021, and Project 2021. Do not use this sample to install Office 365 products. For detailed information regarding configuration options visit: http://aka.ms/ODT. To use the configuration file be sure to remove the comments The following sample allows you to download and install Office 2021 Professional Plus, Visio 2021 Professional, and Project 2021 Professional directly from the Office CDN. This configuration file will remove all other Click-to-Run products in order to avoid product conflicts and ensure successful setup. --> <Configuration> <Add OfficeClientEdition="64" Channel="PerpetualVL2021"> <Product ID="ProPlus2021Volume"> <Language ID="zh-CN" /> <Language ID="en-us" /> <ExcludeApp ID="Lync" /> </Product> <Product ID="VisioPro2021Volume"> <Language ID="zh-CN" /> <Language ID="en-us" /> </Product> <Product ID="ProjectPro2021Volume"> <Language ID="zh-CN" /> <Language ID="en-us" /> </Product> </Add> <Remove All="True" /> <!-- <RemoveMSI All="True" /> --> <!-- <Display Level="None" AcceptEULA="TRUE" /> --> <!-- <Property Name="AUTOACTIVATE" Value="1" /> --> </Configuration> 步骤5:在搜索框中键入cmd,然后选择以管理员身份运行。执行以下命令: ./setup.exe /configure .\configuration.xml 步骤6:接下来,出现安装进度窗口。您只需要按照屏幕上的说明完成安装即可。 第三方下载 如果已经安装office2021可以直接跳到步骤二进行KMS激活 Office_Pro_Plus_2021_LTSC+Project+Visio_x64_zh_CN_VL_2021-10.iso https://alumnialbany-my.sharepoint.com/:f:/g/personal/mlj_alumni_albany_edu/Ej_Pxw_VUKFJmDe-Dgsn43EBg4QStSii4ajw66MinvEYyg?e=fYgjXF vl版office2021,标准版和专业增强版均可通过KMS激活 OInstall.exe可能会被Windows安全中心误报,信任即可。 Office2021 ISO 下载地址合集 说明:仅支持Win10/11系统,img镜像Win10/11下直接装载打开即可。 一、专业增强版(强烈推荐): http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProPlus2021Retail.img 二、专业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Professional2021Retail.img 三、家庭学生版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/HomeStudent2021Retail.img 四、家庭企业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/HomeBusiness2021Retail.img 五、独立版(不推荐): Word: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Word2021Retail.img Excel: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Excel2021Retail.img PowerPoint:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/PowerPoint2021Retail.img Outlook: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Outlook2021Retail.img Access:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Access2021Retail.img Publisher:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Publisher2021Retail.img Project标准版:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectStd2021Retail.img Project专业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectPro2021Retail.img Visio标准版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioStd2021Retail.img Visio专业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioPro2021Retail.img KMS激活 Office 以管理员身份运行CMD或者Powershell,输入以下命令 cd "C:\Program Files\Microsoft Office\Office16" # kms with port cscript ospp.vbs /sethst:kms.0t.net.cn cscript ospp.vbs /setprt:1688 cscript ospp.vbs /act # kms cscript ospp.vbs /sethst:win.kms.pub cscript ospp.vbs /act *32位office2021安装位置 “C:\Program Files (x86)\Microsoft Office\Office16” 等待激活完成即可! *如激活失败,请确认 是否以管理员身份运行的cmd office2021的版本是否是vl版,如果是零售版转换到VL版 office365不支持KMS激活 office2021零售版转VL版命令 以管理员身份运行cmd,依次执行以下命令 cd "C:\Program Files\Microsoft Office\Office16" for /f %x in ('dir /b ..\root\Licenses16\ProPlus2021VL_KMS*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%x" 32位office2021安装位置 “C:\Program Files (x86)\Microsoft Office\Office16” KMS 激活 windows 激活 Windows 如果你的 Windows 是 VL 版本,那么只要在管理员权限的 cmd 或者 powershell 中执行下面两个命令就可以了。 执行完第一个命令后要等弹出提示窗,期间电脑必须联网。 slmgr /skms win.kms.pub slmgr /ato 如果不是 VL 版本的,那么需要更换密钥获取你对应版本的 KEY,操作如下: 运行以下命令查看系统版本: wmic os get caption 在文末找到对应的 key,在管理员权限的 cmd 或者 powershell 中执行下面命令安装 key: slmgr /ipk xxxxx-xxxxx-xxxxx-xxxxx 然后跟上面说的一样设置 kms 服务器地址,激活. *例如:新装windows10企业版之后如何激活* 如果你是新装的或者已经安装好了windows10企业版那么只需要复制下面命令在直接管理员权限的cmd或者powershell中执行即可。 slmgr.vbs /upk slmgr /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43 slmgr /skms win.kms.pub slmgr /ato Win11 LTSC 2024 下载与KMS 激活 Win11企业版 2024 长期服务版 (Windows 11 IoT Enterprise LTSC 2024) 提供长达 10 年的支持服务,支持至 2034 年。 Microsoft Windows 11 Enterprise LTSC 2024 官方简体中文正式版ISO镜像下载地址 zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso(4.92G)SHA: 2CB21649590C8CF770CD93556596DFF4FD800F24D267A9BE9D9CE0EE9E03F5AC 【点击下载】或 【BT磁力下载】 Microsoft Windows 11 Enterprise LTSC 2024 英文版官方下载 【点击下载 】 制作U盘系统安装盘: 1、Rufus 【官方下载】 2、Ventoy 【官方下载】 跳过TPM2 验证 在安装命令后面添加 /product server Windows 11 2024 LTSC 长期服务版 KMS 官方密钥获取: 【点击前往】 激活命令: slmgr -ipk 这里填写视频里演示的密钥 slmgr -ipk M7XTQ-FN8P6-TTKYV-9D4CC-J462D slmgr -skms kms.03k.org slmgr -skms win.kms.pub slmgr -ato slmgr -dlv 安装后可以进一步精简系统,使用DISM快速禁用或启用保留空间: 禁用系统保留空间 DISM.exe /Online /Set-ReservedStorageState /State:Disabled KMS 服务器列表 kms.03k.org kms.chinancce.com kms.luody.info kms.lotro.cc kms.luochenzhimu.com kms8.MSGuides.com kms9.MSGuides.com KMS 列表 kms可用性检测网址 Windows VL 密钥对照表 以下内容来自微软官方公开的序列号,请放心使用 点击查询微软官方公开序列号 Windows Server 2022 操作系统 KMS 激活序列号 Windows Server 2022 Datacenter WX4NM-KYWYW-QJJR4-XV3QB-6VM33 Windows Server 2022 Standard VDYBN-27WPP-V4HQT-9VMD4-VMK7H Windows Server 版本 20H2、2004、1909、1903 和 1809 操作系统 KMS 激活序列号 Windows Server Datacenter 6NMRW-2C8FM-D24W7-TQWMY-CWH2D Windows Server Standard N2KJX-J94YW-TQVFB-DG9YT-724CC Windows Server 版本 1803 操作系统 KMS 激活序列号 Windows Server Datacenter 2HXDN-KRXHB-GPYC7-YCKFJ-7FVDG Windows Server Standard PTXN8-JFHJM-4WC78-MPCBR-9W4KR Windows Server 版本 1709 操作系统 KMS 激活序列号 Windows Server Datacenter 6Y6KB-N82V8-D8CQV-23MJW-BWTG6 Windows Server Standard DPCNP-XQFKJ-BJF7R-FRC8D-GF6G4 Windows Server 2019 操作系统 KMS 激活序列号 Windows Server 2019 Datacenter WMDGN-G9PQG-XVVXX-R3X43-63DFG Windows Server 2019 Standard N69G4-B89J2-4G8F4-WWYCC-J464C Windows Server 2019 Essentials WVDHN-86M7X-466 P 6-VHXV7-YY726 Windows Server 2016 操作系统 KMS 激活序列号 Windows Server 2016 Datacenter CB7KF-BWN84-R7R2Y-793K2-8XDDG Windows Server 2016 Standard WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY Windows Server 2016 Essentials JCKRF-N37P4-C2D82-9YXRT-4M63B Windows 10 Core (可用于激活windonws10家庭版,由网友Cyril Chan提供,在此衷心感谢) 操作系统 KMS 激活序列号 Win 10 Core (可用于激活win10家庭版) TX9XD-98N7V-6WMQ6-BX7FG-H8Q99 Win 10 CoreN (可用于激活win10家庭版) 3KHY7-WNT83-DGQKR-F7HPR-844BM Win 10 CoreSingleLanguage (可用于激活win10家庭版) 7HNRX-D7KGG-3K4RQ-4WPJ4-YTDFH Win 10 CoreCountrySpecific (可用于激活win10家庭版) PVMJN-6DFY6-9CCP6-7BKTT-D3WVR Windows 10 , Windows 11 通用 操作系统 KMS 激活序列号 Windows 10 Professional (Windows 10 专业版) Windows 11 Professional (Windows 11 专业版) W269N-WFGWX-YVC9B-4J6C9-T83GX Windows 10 Professional N (Windows 10 专业版 N) Windows 11 Professional N (Windows 11 专业版 N) MH37W-N47XK-V7XM9-C7227-GCQG9 Windows 10 Pro for Workstations (Windows 10 专业工作站版) Windows 11 Pro for Workstations (Windows 11 专业工作站版) NRG8B-VKK3Q-CXVCJ-9G2XF-6Q84J Windows 10 Pro for Workstations N (Windows 10 专业工作站版 N) Windows 11 Pro for Workstations N (Windows 11 专业工作站版 N) 9FNHH-K3HBT-3W4TD-6383H-6XYWF Windows 10 Pro Education (Windows 10 专业教育版) Windows 11 Pro Education (Windows 11 专业教育版) 6TP4R-GNPTD-KYYHQ-7B7DP-J447Y Windows 10 Pro Education N (Windows 10 专业教育版 N) Windows 11 Pro Education N (Windows 11 专业教育版 N) YVWGF-BXNMC-HTQYQ-CPQ99-66QFC Windows 10 Education (Windows 10 教育版) Windows 11 Education (Windows 11 教育版) NW6C2-QMPVW-D7KKK-3GKT6-VCFB2 Windows 10 Education N (Windows 10 教育版 N) Windows 11 Education N (Windows 11 教育版 N) 2WH4N-8QGBV-H22JP-CT43Q-MDWWJ Windows 10 Enterprise (Windows 10 企业版) Windows 11 Enterprise (Windows 11 企业版) NPPR9-FWDCX-D2C8J-H872K-2YT43 Windows 10 Enterprise N (Windows 10 企业版 N) Windows 11 Enterprise N (Windows 11 企业版 N) DPH2V-TTNVB-4X9Q3-TJR4H-KHJW4 Windows 10 Enterprise G (Windows 10 企业版 G) Windows 11 Enterprise G (Windows 11 企业版 G) YYVX9-NTFWV-6MDM3-9PT4T-4M68B Windows 10 Enterprise G N (Windows 10 企业版 G N) Windows 11 Enterprise G N (Windows 11 企业版 G N) 44RPN-FTY23-9VTTB-MP9BX-T84FV Windows 10(LTSC/LTSB 版本) 操作系统 KMS 激活序列号 Windows 10 Enterprise 2015 LTSB (Windows 10 企业版 2015 LTSB) WNMTR-4C88C-JK8YV-HQ7T2-76DF9 Windows 10 Enterprise 2015 LTSB N (Windows 10 企业版 2015 LTSB N) 2F77B-TNFGY-69QQF-B8YKP-D69TJ Windows 10 Enterprise 2016 LTSB (Windows 10 企业版 LTSB 2016) DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ Windows 10 Enterprise N LTSB 2016 (Windows 10 企业版 N LTSB 2016) QFFDN-GRT3P-VKWWX-X7T3R-8B639 Windows 10 Enterprise LTSC 2019 (Windows 10 企业版 LTSC 2019) M7XTQ-FN8P6-TTKYV-9D4CC-J462D Windows 10 Enterprise N LTSC 2019 (Windows 10 企业版 N LTSC 2019) 92NFX-8DJQP-P6BBQ-THF9C-7CG2H Windows Server 2012 R2 和 Windows 8.1 操作系统 KMS 激活序列号 Windows 8.1 Professional GCRJD-8NW9H-F2CDX-CCM8D-9D6T9 Windows 8.1 Professional N HMCNV-VVBFX-7HMBH-CTY9B-B4FXY Windows 8.1 Enterprise MHF9N-XY6XB-WVXMC-BTDCT-MKKG7 Windows 8.1 Enterprise N TT4HM-HN7YT-62K67-RGRQJ-JFFXW Windows Server 2012 R2 Server Standard D2N9P-3P6X9-2R39C-7RTCD-MDVJX Windows Server 2012 R2 Datacenter W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9 Windows Server 2012 R2 Essentials KNC87-3J2TX-XB4WP-VCPJV-M4FWM Windows Server 2012 和 Windows 8 操作系统 KMS 激活序列号 Windows 8 Professional NG4HW-VH26C-733KW-K6F98-J8CK4 Windows 8 Professional N XCVCF-2NXM9-723PB-MHCB7-2RYQQ Windows 8 Enterprise 32JNW-9KQ84-P47T8-D8GGY-CWCK7 Windows 8 Enterprise N JMNMF-RHW7P-DMY6X-RF3DR-X2BQT Windows Server 2012 BN3D2-R7TKB-3YPBD-8DRP2-27GG4 Windows Server 2012 N 8N2M2-HWPGY-7PGT9-HGDD8-GVGGY Windows Server 2012 Single Language 2WN2H-YGCQR-KFX6K-CD6TF-84YXQ Windows Server 2012 Country Specific 4K36P-JN4VD-GDC6V-KDT89-DYFKP Windows Server 2012 Server Standard XC9B7-NBPP2-83J2H-RHMBY-92BT4 Windows Server 2012 MultiPoint Standard HM7DN-YVMH3-46JC3-XYTG7-CYQJJ Windows Server 2012 MultiPoint Premium XNH6W-2V9GX-RGJ4K-Y8X6F-QGJ2G Windows Server 2012 Datacenter 48HP8-DN98B-MYWDG-T2DCC-8W83P Windows 7 and Windows Server 2008 R2 操作系统 KMS 激活序列号 Windows 7 Professional FJ82H-XT6CR-J8D7P-XQJJ2-GPDD4 Windows 7 Professional N MRPKT-YTG23-K7D7T-X2JMM-QY7MG Windows 7 Professional E W82YF-2Q76Y-63HXB-FGJG9-GF7QX Windows 7 Enterprise 33PXH-7Y6KF-2VJC9-XBBR8-HVTHH Windows 7 Enterprise N YDRBP-3D83W-TY26F-D46B2-XCKRJ Windows 7 Enterprise E C29WB-22CC8-VJ326-GHFJW-H9DH4 Windows Server 2008 R2 Web 6TPJF-RBVHG-WBW2R-86QPH-6RTM4 Windows Server 2008 R2 HPC edition TT8MH-CG224-D3D7Q-498W2-9QCTX Windows Server 2008 R2 Standard YC6KT-GKW9T-YTKYR-T4X34-R7VHC Windows Server 2008 R2 Enterprise 489J6-VHDMP-X63PK-3K798-CPX3Y Windows Server 2008 R2 Datacenter 74YFP-3QFB3-KQT8W-PMXWJ-7M648 Windows Server 2008 R2 for Itanium-based Systems GT63C-RJFQ3-4GMB6-BRFB9-CB83V Windows Vista and Windows Server 2008 操作系统 KMS 激活序列号 Windows Vista Business YFKBB-PQJJV-G996G-VWGXY-2V3X8 Windows Vista Business N HMBQG-8H2RH-C77VX-27R82-VMQBT Windows Vista Enterprise VKK3X-68KWM-X2YGT-QR4M6-4BWMV Windows Vista Enterprise N VTC42-BM838-43QHV-84HX6-XJXKV Windows Web Server 2008 WYR28-R7TFJ-3X2YQ-YCY4H-M249D Windows Server 2008 Standard TM24T-X9RMF-VWXK6-X8JC9-BFGM2 Windows Server 2008 Standard without Hyper-V W7VD6-7JFBR-RX26B-YKQ3Y-6FFFJ Windows Server 2008 Enterprise YQGMW-MPWTJ-34KDK-48M3W-X4Q6V Windows Server 2008 Enterprise without Hyper-V 39BXF-X8Q23-P2WWT-38T2F-G3FPG Windows Server 2008 HPC RCTX3-KWVHP-BR6TB-RB6DM-6X7HP Windows Server 2008 Datacenter 7M67G-PC374-GR742-YH8V4-TCBY3 Windows Server 2008 Datacenter without Hyper-V 22XQ2-VRXRG-P8D42-K34TD-G3QQC Windows Server 2008 for Itanium-Based Systems 4DWFP-JF3DJ-B7DTH-78FJB-PDRHK Office GVLK 对照表 以下内容来自微软官方公开的序列号,请放心使用 Office LTSC 2021 产品 GVLK Office LTSC Professional Plus 2021 FXYTK-NJJ8C-GB6DW-3DYQT-6F7TH Office LTSC Standard 2021 KDX7X-BNVR8-TXXGX-4Q7Y8-78VT3 Project Professional 2021 FTNWT-C6WBT-8HMGF-K9PRX-QV9H8 Project Standard 2021 J2JDC-NJCYY-9RGQ4-YXWMH-T3D4T Visio LTSC Professional 2021 KNH8D-FGHT4-T8RK3-CTDYJ-K2HT4 Visio LTSC Standard 2021 MJVNY-BYWPY-CWV6J-2RKRT-4M8QG Access LTSC 2021 WM8YG-YNGDD-4JHDC-PG3F4-FC4T4 Excel LTSC 2021 NWG3X-87C9K-TC7YY-BC2G7-G6RVC Outlook LTSC 2021 C9FM6-3N72F-HFJXB-TM3V9-T86R9 PowerPoint LTSC 2021 TY7XF-NFRBR-KJ44C-G83KF-GX27K Publisher LTSC 2021 2MW9D-N4BXM-9VBPG-Q7W6M-KFBGQ Skype for Business LTSC 2021 HWCXN-K3WBT-WJBKY-R8BD9-XK29P Word LTSC 2021 TN8H9-M34D3-Y64V9-TR72V-X79KV Office 2019 产品 GVLK Office Professional Plus 2019 NMMKJ-6RK4F-KMJVX-8D9MJ-6MWKP Office Standard 2019 6NWWJ-YQWMR-QKGCB-6TMB3-9D9HK Project Professional 2019 B4NPR-3FKK7-T2MBV-FRQ4W-PKD2B Project Standard 2019 C4F7P-NCP8C-6CQPT-MQHV9-JXD2M Visio Professional 2019 9BGNQ-K37YR-RQHF2-38RQ3-7VCBB Visio Standard 2019 7TQNQ-K3YQQ-3PFH7-CCPPM-X4VQ2 Access 2019 9N9PT-27V4Y-VJ2PD-YXFMF-YTFQT Excel 2019 TMJWT-YYNMB-3BKTF-644FC-RVXBD Outlook 2019 7HD7K-N4PVK-BHBCQ-YWQRW-XW4VK PowerPoint 2019 RRNCX-C64HY-W2MM7-MCH9G-TJHMQ Publisher 2019 G2KWX-3NW6P-PY93R-JXK2T-C9Y9V Skype for Business 2019 NCJ33-JHBBY-HTK98-MYCV8-HMKHJ Word 2019 PBX3G-NWMT6-Q7XBW-PYJGG-WXD33 Office 2016 产品 GVLK Office Professional Plus 2016 XQNVK-8JYDB-WJ9W3-YJ8YR-WFG99 Office Standard 2016 JNRGM-WHDWX-FJJG3-K47QV-DRTFM Project Professional 2016 YG9NW-3K39V-2T3HJ-93F3Q-G83KT Project Standard 2016 GNFHQ-F6YQM-KQDGJ-327XX-KQBVC Visio Professional 2016 PD3PC-RHNGV-FXJ29-8JK7D-RJRJK Visio Standard 2016 7WHWN-4T7MP-G96JF-G33KR-W8GF4 Access 2016 GNH9Y-D2J4T-FJHGG-QRVH7-QPFDW Excel 2016 9C2PK-NWTVB-JMPW8-BFT28-7FTBF OneNote 2016 DR92N-9HTF2-97XKM-XW2WJ-XW3J6 Outlook 2016 R69KK-NTPKF-7M3Q4-QYBHW-6MT9B PowerPoint 2016 J7MQP-HNJ4Y-WJ7YM-PFYGF-BY6C6 Publisher 2016 F47MM-N3XJP-TQXJ9-BP99D-8K837 Skype for Business 2016 869NQ-FJ69K-466HW-QYCP2-DDBV6 Word 2016 WXY84-JN2Q9-RBCCQ-3Q3J3-3PFJ6 Office 2013 产品 GVLK Office 2013 Professional Plus YC7DK-G2NP3-2QQC3-J6H88-GVGXT Office 2013 Standard KBKQT-2NMXY-JJWGP-M62JB-92CD4 Project 2013 Professional FN8TT-7WMH6-2D4X9-M337T-2342K Project 2013 Standard 6NTH3-CW976-3G3Y2-JK3TX-8QHTT Visio 2013 Professional C2FG9-N6J68-H8BTJ-BW3QX-RM3B3 Visio 2013 Standard J484Y-4NKBF-W2HMG-DBMJC-PGWR7 Access 2013 NG2JY-H4JBT-HQXYP-78QH9-4JM2D Excel 2013 VGPNG-Y7HQW-9RHP7-TKPV3-BG7GB InfoPath 2013 DKT8B-N7VXH-D963P-Q4PHY-F8894 Lync 2013 2MG3G-3BNTT-3MFW9-KDQW3-TCK7R OneNote 2013 TGN6P-8MMBC-37P2F-XHXXK-P34VW Outlook 2013 QPN8Q-BJBTJ-334K3-93TGY-2PMBT PowerPoint 2013 4NT99-8RJFH-Q2VDH-KYG2C-4RD4F Publisher 2013 PN2WF-29XG2-T9HJ7-JQPJR-FCXK4 Word 2013 6Q7VD-NX8JD-WJ2VH-88V73-4GBJ7 Office 2010 产品 GVLK Office Professional Plus 2010 VYBBJ-TRJPB-QFQRF-QFT4D-H3GVB Office Standard 2010 V7QKV-4XVVR-XYV4D-F7DFM-8R6BM Access 2010 V7Y44-9T38C-R2VJK-666HK-T7DDX Excel 2010 H62QG-HXVKF-PP4HP-66KMR-CW9BM SharePoint Workspace 2010 QYYW6-QP4CB-MBV6G-HYMCJ-4T3J4 InfoPath 2010 K96W8-67RPQ-62T9Y-J8FQJ-BT37T OneNote 2010 Q4Y4M-RHWJM-PY37F-MTKWH-D3XHX Outlook 2010 7YDC2-CWM8M-RRTJC-8MDVC-X3DWQ PowerPoint 2010 RC8FX-88JRY-3PF7C-X8P67-P4VTT Project Professional 2010 YGX6F-PGV49-PGW3J-9BTGG-VHKC6 Project Standard 2010 4HP3K-88W3F-W2K3D-6677X-F9PGB Publisher 2010 BFK7F-9MYHM-V68C7-DRQ66-83YTP Word 2010 HVHB3-C6FV7-KQX9W-YQG79-CRY7T Visio Standard 2010 767HD-QGMWX-8QTDB-9G3R2-KHFGJ Visio Professional 2010 7MCW8-VRQVK-G677T-PDJCM-Q8TCP Visio Premium 2010 D9DWC-HPYVV-JGF4P-BTWQB-WX8BJ 自建KMS服务器 KMS服务器(Key Management Service)主要用于管理和激活微软的Windows操作系统和Office软件。如果不放心网络上面的 KMS 服务器,可以自建 KMS 服务器! 安装Docker管理器 宝塔面板 - 软件商店 - Docker管理器 3.9.1 - 安装 拉取镜像并启动 在终端输入以下指令: 拉取镜像 docker pull teddysun/kms 启动容器 docker run -d -p 1688:1688 --name kms --restart=always teddysun/kms 开放安全组端口 在服务商安全组和宝塔面板的防火墙处开放TCP端口号1688 检查PING情况 打开PING网站,输入 你的服务器IP:1688 然后点击 Go 按钮 等待后如果能全部Ping通显示Successful则表示KMS服务器已搭建成功 参考&致谢 Docker之三分钟搭建KMS服务器 Office2021安装文件下载和KMS激活 Deploy Office LTSC 2021 office c2r install Office Tool Plus 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2024/7/4
articleCard.readMore

如何防止密码泄露,保护密码安全?

背景 密码安全:现代数字生活的必需品 在这个互联网无处不在的时代,我们的生活已经与网络紧密相连。无论是社交媒体、在线银行、电子邮件,还是各种在线服务,每一个账户的安全都依赖于密码。然而,密码的管理和保护却成为了一个巨大的挑战。 密码安全的重要性 密码是我们保护个人信息、财务数据和隐私的第一道防线。一个强而复杂的密码能够有效地阻止未经授权的访问,防止我们的账户被黑客入侵。然而,随着我们在线账户的数量不断增加,记住所有复杂的密码变得几乎不可能。这时,许多人选择使用简单的、易记的密码,甚至在多个网站上使用相同的密码,这种做法却大大增加了密码被盗的风险。 密码泄露的普遍性 近年来,密码泄露事件频繁发生,成千上万的用户信息被曝光在互联网上。数据泄露不仅让用户的个人信息面临风险,还可能导致财产损失和隐私侵犯。例如,大型公司如Yahoo、Equifax、LinkedIn等都曾发生过严重的数据泄露事件,影响了数亿用户。数据显示,黑客每天都在进行成千上万次的攻击,试图通过各种方式获取用户的密码信息。 密码泄露的危害 密码泄露可能带来多方面的危害,具体如下: 身份盗窃:黑客可以利用泄露的密码登录您的个人账户,获取您的个人信息,甚至冒用您的身份进行违法活动。 财产损失:如果您的银行账户或支付平台的密码被泄露,黑客可能会窃取您的资金,导致直接的经济损失。 隐私侵犯:密码泄露可能导致您的私人邮件、照片、社交媒体信息等被曝光,严重侵犯您的隐私。 业务损失:对于企业用户来说,密码泄露可能导致商业秘密和客户信息被盗,带来巨大的经济损失和声誉损害。 恶意操作:黑客可能利用您的账户发送垃圾邮件、散布恶意软件,甚至进行更大范围的网络攻击。 黑客攻击的泛滥 黑客攻击变得越来越普遍和复杂,他们使用钓鱼邮件、恶意软件、暴力破解等多种手段来窃取密码。一旦一个网站的密码被攻破,黑客们通常会尝试使用相同的密码登录其他网站的账户。如果用户在多个网站上使用相同的密码,黑客就能轻易地侵入更多的账户,造成更大的损失。 急切需要密码管理工具 鉴于上述情况,强烈推荐使用密码管理工具来保护我们的数字生活。密码管理工具不仅能帮助我们生成强而随机的密码,还能安全地存储和管理这些密码。以下是密码管理工具的主要优势: 生成随机密码:密码管理工具可以生成复杂且随机的密码,大大增强了密码的安全性,防止黑客轻易破解。 独特密码:每个账户都使用独特的密码,避免一个密码被泄露后,其他账户也随之陷入危险。 自动填充:简化登录过程,避免因频繁输入密码而增加泄露风险。 多设备同步:在所有设备上同步密码,确保随时随地都能安全地访问账户。 使用密码管理工具是保护在线账户安全的有效方法,避免密码泄露和黑客攻击带来的风险。接下来,我们将详细介绍几款流行的密码管理工具,帮助您选择最适合自己的安全解决方案。 各类密码登录方式的差异与演进:从传统密码到生物识别 在数字身份认证领域,登录方式正经历从“记忆”到“生物特征”、从“主动输入”到“无感验证”的革新。本文将解析主流登录技术的核心差异与适用场景。 1. 传统密码登录 原理:用户自定义字符串(字母/数字/符号组合)作为身份凭证 优势:开发成本低、无需硬件支持 缺陷:易被撞库攻击、弱密码风险高、需记忆负担 适用场景:备用登录方式、低安全需求系统(如论坛) 2. 短信验证码登录 原理:通过运营商网络发送动态数字验证码 优势:无需记忆、可获取用户真实手机号 缺陷:存在SIM卡劫持、短信延迟、隐私泄露风险 安全增强:5分钟时效限制、每小时发送次数限制 3. 生物识别登录 3.1 人脸识别 技术:通过摄像头捕捉面部特征点比对 优势:无接触、用户体验流畅 挑战:光线敏感、整容/化妆影响精度 3.2 虹膜识别 技术:分析虹膜纹理(含266+特征点) 优势:终身唯一性、误识率低至百万分之一 局限:设备成本高、需近距离配合 应用:军事基地、金融系统等高安全场景 4. 通行密钥(Passkeys) 原理:基于公钥加密的端到端验证 突破性:防钓鱼攻击、无密码记忆、跨设备同步 现状:苹果/谷歌/微软已支持,但普及率不足30% 5. 第三方登录(OAuth) 代表:微信/QQ/微博授权 优势:一键登录、降低用户流失 隐患:账号体系依赖外部平台、信息获取受限 技术对比矩阵 方式 安全性 便捷性 开发成本 隐私风险 传统密码 ★★ ★★ 低 高 短信验证码 ★★★ ★★★★ 中 中 人脸识别 ★★★★ ★★★★★ 高 中 虹膜识别 ★★★★★ ★★★ 极高 低 通行密钥 ★★★★★ ★★★★ 中高 低 未来趋势:多模态认证(如人脸+虹膜)、无密码化(Passkeys)将成为主流。企业在选择方案时需平衡安全与体验——金融场景倾向虹膜/Passkeys,社交娱乐则优先短信/第三方登录。技术的终点,始终是让安全“隐形”于便捷之中。 6. 二维码认证的崛起 随着谷歌宣布在Gmail中逐步淘汰短信验证码并转向动态二维码认证,这一技术正成为安全验证的新方向。其核心优势在于: 抗钓鱼攻击:无需传输可被截获的数字代码,通过加密的图形验证切断中间人攻击路径 跨平台兼容性:仅需设备摄像头扫描即可完成,适配iOS/Android/PC等多终端 增强隐私保护:验证过程不依赖手机号等个人信息,降低运营商数据泄露风险 7. 生物识别技术的深层挑战 尽管指纹、人脸等生物识别技术已广泛应用,其局限性仍不容忽视: 硬件依赖性:3D结构光/ToF模组(苹果、华为、荣耀等厂商采用)虽提升安全性,但也推高设备成本 生物特征不可重置性:一旦生物数据泄露,无法像密码一样修改 环境敏感性:虹膜识别需在30cm内配合,人脸识别受光线/遮挡影响显著 8. 多模态认证的实践探索 为解决单一技术的缺陷,混合认证模式逐渐普及: 生物特征+设备认证:如苹果Face ID配合Apple Watch近场解锁 动态生物密钥:Passkeys将生物验证与硬件加密结合,生成临时密钥替代静态密码 行为特征补充:敲击节奏、滑动轨迹等行为数据增强身份判定 技术对比深度解析 维度 传统密码 生物识别 Passkeys 二维码认证 安全基线 弱(依赖复杂度) 中高(硬件依赖) 极高(非对称加密) 高(动态加密) 隐私泄露风险 极高(撞库攻击) 中(数据不可逆) 极低(本地存储) 低(无身份绑定) 用户教育成本 低 中(需信任机制) 高(新概念普及) 低(直观操作) 部署复杂度 低 高(专用硬件) 中(需FIDO支持) 中(服务端改造) 行业应用场景指南 金融级安全 首选方案:虹膜识别(误识率1/1,000,000)+ Passkeys双因素认证 典型案例:银行VIP室采用虹膜门禁,移动支付绑定Passkeys硬件密钥 消费电子领域 平衡方案:3D人脸识别(苹果/华为结构光技术)+ 备用密码 创新实践:荣耀Magic系列通过AI学习用户面部微表情提升识别精度 企业级服务 合规选择:动态二维码+RSA令牌(满足GDPR/CCPA数据隔离要求) 效率优化:微软Azure AD支持Passkeys跨设备同步,降低IT运维成本 未来技术演进方向 量子加密融合:虹膜特征数据通过量子密钥分发(QKD)传输,防御量子计算攻击 边缘计算增强:生物特征比对在设备端TEE(可信执行环境)完成,避免云端数据暴露 抗伪造技术突破:基于GAN生成对抗网络的人脸活体检测,识别精度达99.99% 无感身份验证:通过脑电波识别/心跳特征等生理信号实现持续身份认证 小结 密码管理工具 在当今数字化时代,密码安全变得尤为重要。随着我们在网上创建的账户越来越多,记住所有复杂的密码变得几乎不可能。这时候,密码管理工具就显得尤为重要了。本文将介绍几款流行的密码管理工具,帮助您保护数字生活。 LastPass LastPass 是一款广受欢迎的密码管理工具,其特点在于简单易用且功能强大。 主要功能: 密码生成:生成强密码,避免使用简单或重复的密码。 自动填充:自动填充网页和应用程序中的登录信息。 多设备同步:在所有设备之间同步密码数据。 安全共享:安全地与他人共享密码。 使用体验: LastPass 提供了友好的用户界面,易于设置和使用。其浏览器扩展和移动应用使得管理密码变得方便快捷。 官网链接:LastPass 官网 工具下载:LastPass 下载 Bitwarden Bitwarden 是另一款备受好评的密码管理工具,以其开源和安全性著称。 主要功能: 开源:代码公开,透明度高,安全性有保障。 多平台支持:支持 Windows、macOS、Linux、iOS 和 Android 等多种操作系统。 端到端加密:确保数据在传输和存储过程中始终加密。 自托管:提供自托管选项,增强数据控制力。 使用体验: Bitwarden 提供了丰富的功能和高度的可定制性,适合那些对安全性和隐私有较高要求的用户。其免费版本已经足够强大,付费版本提供了更多高级功能。 官网链接:Bitwarden 官网 工具下载:Bitwarden 下载 1Password 1Password 是一款以其优雅设计和强大功能而著称的密码管理工具。 主要功能: 密码生成和存储:生成和存储强密码。 旅行模式:在旅行时隐藏敏感信息,防止被检查。 多重身份:支持管理多个身份和信用卡信息。 密码监控:监控数据泄露,提醒用户更改密码。 使用体验: 1Password 提供了极佳的用户体验,界面美观且功能直观。其家人和团队计划非常适合家庭和企业用户。 官网链接:1Password 官网 工具下载:1Password 下载 Dashlane Dashlane 是一款功能全面的密码管理工具,提供了许多实用的附加功能。 主要功能: 密码管理:生成、存储和自动填充密码。 VPN 服务:内置 VPN,增强上网安全性。 密码健康报告:分析密码强度,提供改进建议。 暗网监控:监控暗网,及时提醒用户更改被泄露的密码。 使用体验: Dashlane 提供了全面的安全功能,其内置的 VPN 和密码健康报告使其成为一个一站式安全解决方案。用户界面简洁直观,适合不同水平的用户。 官网链接:Dashlane 官网 工具下载:Dashlane 下载 Keeper Keeper 是一款注重安全性和隐私的密码管理工具。 主要功能: 零知识安全架构:确保用户数据的绝对隐私。 文件存储:安全存储和共享文件。 紧急访问:在紧急情况下允许指定联系人访问账户。 生物识别登录:支持指纹和面部识别登录。 使用体验: Keeper 提供了高度安全的环境,适合那些对隐私和数据安全有极高要求的用户。其丰富的功能和灵活的定制选项,使其成为企业和个人用户的理想选择。 官网链接:Keeper 官网 工具下载:Keeper 下载 通过这些密码管理工具,您可以轻松管理和保护您的密码,提升数字生活的安全性和便利性。选择适合您的工具,开始安全的在线体验吧! 总结 选择合适的密码管理工具取决于您的具体需求和偏好。无论是 LastPass 的易用性,Bitwarden 的开源特性,1Password 的优雅设计,Dashlane 的全面功能,还是 Keeper 的高度安全性,都能为您提供安全可靠的密码管理服务。通过使用这些工具,您可以轻松管理和保护您的密码,提升数字生活的安全性和便利性。 后面将着重介绍 bitwarden ,因为其免费版本功能限制很少,并且支持 指纹识别 ,客户端全平台支持,并且有服务端的开源实现版本! Bitwarden 密码安全原理 在当前数字化的世界里,保护在线账户的安全变得尤为重要。复杂、独特的密码是防止黑客入侵的关键,但记住所有这些密码却是一个巨大的挑战。Bitwarden 是一款流行且广受好评的密码管理工具,它以安全性和开源特性著称。下面,我们将详细介绍 Bitwarden 如何保管密码以及它为什么如此安全。 Bitwarden 如何保管密码? Bitwarden 使用了多层次的安全措施来确保您的密码和数据始终受到保护。以下是 Bitwarden 保管密码的基本原理: 数据加密 Bitwarden 采用端到端加密来保护您的数据。所有数据在您的设备上加密,并且只有在传输和存储过程中保持加密状态。具体来说,Bitwarden 使用以下加密技术: AES-256 位加密:高级加密标准(AES)是目前公认的最强加密算法之一。256 位加密意味着有 2^256 种可能的密钥组合,几乎无法被破解。 PBKDF2-SHA-256:使用密码生成密钥并通过密码基础的密钥派生函数 2(PBKDF2)和 SHA-256 哈希算法反复迭代,以增加破解难度。 HMAC-SHA-256:用于数据完整性校验,确保数据在传输过程中没有被篡改。 零知识安全架构 Bitwarden 采用零知识安全架构,这意味着即使是 Bitwarden 的开发者和服务器也无法访问您的主密码或解密您的数据。您的主密码永远不会在 Bitwarden 的服务器上存储或传输,只有您自己知道并掌握。 端到端加密 所有数据(包括密码、笔记、文件等)在离开您的设备之前就已经加密,只有在您的设备上解密。这种端到端加密保证了即使数据在传输过程中被拦截,拦截者也无法读取内容。 Bitwarden 为什么安全? Bitwarden 的安全性不仅仅依赖于强大的加密算法,还包括一系列其他的安全措施和最佳实践。 开源透明性 Bitwarden 是完全开源的,其源代码公开可见。这意味着任何人都可以审查代码,确保没有隐藏的漏洞或后门。这种透明性增加了用户的信任度,并且允许全球安全社区对其进行持续的安全评估和改进。 定期安全审计 Bitwarden 定期接受独立的第三方安全审计。这些审计包括对应用程序和基础设施的全面安全评估,以确保不存在安全漏洞。审计报告公开发布,进一步增强了用户对 Bitwarden 安全性的信心。 强密码要求 Bitwarden 强制要求用户设置强密码,并提供内置的密码生成器,帮助用户创建复杂、独特的密码。这有效减少了由于弱密码导致的账户被破解的风险。 多因素认证 (MFA) Bitwarden 支持多因素认证,提供额外的安全层。即使攻击者获得了您的主密码,他们也无法在没有第二个认证因素的情况下访问您的账户。Bitwarden 支持多种 MFA 方式,包括 TOTP(基于时间的一次性密码)、U2F(通用第二因素)和 Duo 安全。 安全的分享和存储 Bitwarden 允许用户安全地与他人分享密码和其他敏感信息。所有共享的数据同样经过加密,并且只有授权的接收者才能解密和访问。 总结 Bitwarden 通过强大的加密技术、零知识安全架构、开源透明性、定期安全审计、强密码要求和多因素认证,提供了高度安全的密码管理解决方案。选择 Bitwarden,不仅能帮助您方便地管理所有密码,还能确保您的数字生活免受各种网络威胁的侵扰。无论是个人用户还是企业,Bitwarden 都是一个值得信赖的密码管理工具。 密码泄露查询 bitwarden 需要付费用户才有查询密码暴露功能 Vaultwarden Vaultwarden 是 bitwarden 的开源服务端实现版本 chrome 密码泄露提示 可能你会碰到谷歌浏览器Chrome提示 某个网站或应用发生了数据泄露导致您的密码外泄.建议修改密码 看到这个提示还是挺吓人. 遇到这个提示不建议关闭弹窗了事. 博主强烈建议尽快修改密码. 原因为你在某个网站上账号和密码很大可能已经被泄露了.为什么挣了说,这可从Chrome怎么检测你密码是否被泄露原理说起. Chrome检测你密码是否被泄露的实现原理. 其实这技术很简单,就是将你登录A网站的账号和密码加密后和网上公开已知的泄露数据进行匹配对比,如果发现你的在这份数据中,那就说明你在A网站上的密码已经被泄露了 (更具体技术流程见官方文档https://security.googleblog.com/2019/12/better-password-protections-in-chrome.html) 关闭方法 设置->隐私设置和安全性->安全->标准保护->在密码遭遇数据泄露时,向您发出警告 自建bitwarden 免费用户功能虽然不少,但是有开源的服务端实现,可以提供付费bitwarden 的功能,不香吗? https://hub.docker.com/r/vaultwarden/server https://github.com/dani-garcia/vaultwarden version: '3' services: bitwarden: container_name: bitwarden hostname: bitwarden image: vaultwarden/server:latest volumes: - ${USERDIR}/Bitwarden/data:/data env_file: - ${USERDIR}/Bitwarden/config.env - .env-server environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} - WEBSOCKET_ENABLED="true" - SIGNUPS_ALLOWED="true" - WEB_VAULT_ENABLED="true" ports: - "9000:80" restart: always #network_mode: bridge networks: public_access: aliases: - bitwarden 目前 https://pass.17lai.site 没有关闭注册! 博文阅读用户可以测试使用,特别是密码暴露查询最为实用!但是博主不保证服务稳定性,可能会清除数据! 使用它的用户请在本文下面留言,这样博主清理服务器数据的时候可以给你留言,就有邮件通知你! bitwarden 使用 带有指纹识别的笔记本,登录pc 客户端之后,浏览器插件直接指纹登录。是最佳使用体验! 带指纹识别的手机,直接指纹登录app,也是十分的方便。 bitwarden PC 客户端 bitwarden登录自定义服务器 bitwarden PC 客户端两步验证 bitwarden PC 客户端指纹验证登录 bitwarden 浏览器插件 浏览器插件指纹验证登录 随机密码生成 这就是密码管理器最主要的使用功能 随机用户名生成 同域名多账号支持 相同网站多个域名同一个账号支持 android app 由于android有 防止隐私截屏,下面很多功能就没有截图展示了 支持指纹登录 支持 android app 密码自动填充 密码导入导出 作为一个密码管理工具,能够完全的导入导出密码是必备的基本功能 首先,找到密码库管理入口,见下图 导入密码 导出密码 指纹识别 指纹识别是如此的方便,电脑没有自带指纹怎么办? 有办法!使用外置指纹识别模块! windows hello usb 模块 不打广告,就不放购买链接了。下面模块比较适合笔记本插在侧面 usb 接口 下面模块一百块大洋左右! 可惜客服说不支持 Linux 台式机 usb 接口在主机上面,日常使用指纹识别如果手摸比较麻烦,可以使用 usb 扩展器!把指纹识别模块插在下面红框中的接口上面! 不缺钱的用户可以选择下面这种,要大几百块 密码替代技术 密码是如此的重要,但人类记忆复杂密码又是如此的困难!值得一提的是,随着技术的发展,一些替代密码的工具和方法正在兴起,以提供更安全和便捷的身份验证方式。以下是一些主要的替代密码的方法: 生物识别技术 生物识别技术利用人体的独特特征来验证身份,提供了一种不需要记忆的安全解决方案。常见的生物识别方法包括: 指纹识别:通过扫描指纹来确认身份,已广泛应用于智能手机和安全系统。 面部识别:利用面部特征进行身份验证,广泛应用于智能手机、笔记本电脑和门禁系统。 虹膜识别:通过扫描虹膜图案进行身份验证,通常用于高安全性的场合。 声纹识别:通过分析声音的独特特征来确认身份,应用于电话银行和语音助手。 多因素认证 (MFA) 多因素认证通过结合多种验证方法来增强安全性。常见的 MFA 方式包括: 短信验证码:在登录时向用户手机发送一次性验证码,需要同时输入密码和验证码。 TOTP 应用:使用基于时间的一次性密码(如 Google Authenticator 和 Authy)生成动态验证码。 硬件令牌:如 YubiKey,通过物理设备生成动态验证码或直接进行认证。 推送通知:通过认证应用向用户设备发送推送通知,用户确认后完成登录。 无密码登录 无密码登录是一种不需要传统密码的身份验证方式,常见的方法包括: 魔法链接:用户在登录时收到包含一次性登录链接的电子邮件,点击链接即可登录。 一次性密码 (OTP):通过短信或电子邮件发送一次性密码,用户输入该密码完成登录。 基于公共密钥的认证 (FIDO2):利用设备上的安全密钥对进行认证,如 Windows Hello 和 Apple Face ID。 行为识别 行为识别通过分析用户的行为模式进行身份验证,例如: 打字节律:通过检测用户打字的速度和节奏来确认身份。 鼠标行为:分析用户使用鼠标的方式,如点击和移动模式。 手机传感器数据:利用加速度计和陀螺仪数据分析用户的手机使用习惯。 智能卡和身份认证芯片 智能卡和身份认证芯片通过物理卡片或内置芯片进行身份验证,常用于企业和政府机构。 智能卡:包含加密芯片的卡片,用于访问控制和身份验证。 内置芯片:如 NFC 芯片,常用于移动支付和门禁系统。 总结 随着技术的进步,越来越多的替代密码的方法应运而生,这些工具和方法不仅提升了安全性,还大大简化了用户的身份验证过程。选择适合自己的替代密码方案,可以有效减少密码管理的负担,提升数字生活的安全性和便利性。 为了密码安全,一定要做到一下几点! 一定要一个网站一个随机密码,密码不要多网站共用! 一定要使用合适的密码管理工具,人类的大脑没办法记忆多个随机密码! 一定不要把密码管理工具的主密码写在任何地方,也一定不要忘记它 尽量使用多步验证,这样即使密码泄露黑客也无法登录攻击 参考&致谢 bitwarden chatGPT bitwarden 功能十分强大,上面介绍了不少有趣又实用的用法,大家有什么实用补充没有? 如果谁想自建服务器,可以联系博主收费技术支持!

2024/5/31
articleCard.readMore

webhook部署Hexo静态博客指南

webhook是一种可以让人远程调用的RPC指令集,可以实现更新github仓库后自动更新部署你的Hexo博客,当然几乎所有的你能想到的东西都能做,本文将详细讲解webhook自动化部署静态博客方法 adnanh/webhook 上面这个仓库支持在你的VPS 快速建立一个webhook 接口。然后利用 github webhook 通知你的 VPS 来拉取最新的代码部署 对于 webhook 来说,可以自己写一个脚本来接受信息,思路很简单,运行一个 HTTP Server,监听服务器的某个端口,如果有消息传递过来,那么就运行事先写好的脚本,来完成 webhook 的功能即可。 安装 webhook 这里推荐三种安装方法,使用其中一种方法即可,github 下载速度可能很慢,推荐使用系统源安装的方式 法一:使用系统源的安装方式 如果是 Ubuntu 系统,可以直接使用下面的命令进行安装: $ sudo apt-get update $ sudo apt-get install webhook 法二:使用 github 下载 webhook 的 release 链接,找到对应的选项 webhook-linux-amd64.tar.gz 右键复制链接 ,当前最新版本链接为 # 下载对应的软件 $ wget https://github.com/adnanh/webhook/releases/download/2.8.1/webhook-linux-amd64.tar.gz # 解压进入 $ tar -zxf tar -zxf webhook-linux-amd64.tar.gz && cd webhook-linux-amd64/ $ ./webhook 法三:Golang 环境下安装 首先安装 Golang 环境(这里略过),然后安装 webhook,这里注意需要已经设置了 GOPATH # 安装对应的工具 $ go get github.com/adnanh/webhook # 安装完成之后可以在 $GOPATH/bin 下找到对应的执行文件 $ echo $GOPATH /root/go $ ls /root/go/bin webhook # 将路径写入到 shell 可以直接执行 $ vi ~/.bash_profile # 在文件最后一行加入对应内容 export PATH="/root/go/bin:$PATH" # 更新文件使其生效 $ source ~/.bash_profile # 测试命令是否已经成功安装,得到输出说明安装完成 $ webhook 配置 webhook 我们的 hooks.json 文件现在看起来是这样的: [ { "id": "redeploy-webhook", "execute-command": "/var/scripts/redeploy.sh", "command-working-directory": "/var/webhook" } ] 注意:如果您更喜欢 YAML 格式,等价的 hooks.yaml 文件如下: - id: redeploy-webhook execute-command: "/var/scripts/redeploy.sh" command-working-directory: "/var/webhook" 您现在可以使用以下命令运行 webhook: $ /path/to/webhook -hooks hooks.json -verbose 它将在默认端口 9000 上启动,并为您提供一个 HTTP 终端: http://yourserver:9000/hooks/redeploy-webhook 更多配置参数 webhook/docs/Webhook-Parameters.md at master Usage of webhook: -cert string path to the HTTPS certificate pem file (default "cert.pem") -cipher-suites string comma-separated list of supported TLS cipher suites -debug show debug output -header value response header to return, specified in format name=value, use multiple times to set multiple headers -hooks value path to the json file containing defined hooks the webhook should serve, use multiple times to load from different files -hotreload watch hooks file for changes and reload them automatically -http-methods string globally restrict allowed HTTP methods; separate methods with comma -ip string ip the webhook should serve hooks on (default "0.0.0.0") -key string path to the HTTPS certificate private key pem file (default "key.pem") -list-cipher-suites list available TLS cipher suites -logfile string send log output to a file; implicitly enables verbose logging -nopanic do not panic if hooks cannot be loaded when webhook is not running in verbose mode -pidfile string create PID file at the given path -port int port the webhook should serve hooks on (default 9000) -secure use HTTPS instead of HTTP -setgid int set group ID after opening listening port; must be used with setuid -setuid int set user ID after opening listening port; must be used with setgid -template parse hooks file as a Go template -tls-min-version string minimum TLS version (1.0, 1.1, 1.2, 1.3) (default "1.2") -urlprefix string url prefix to use for served hooks (protocol://yourserver:port/PREFIX/:hook-id) (default "hooks") -verbose show verbose output -version display webhook version and quit -x-request-id use X-Request-Id header, if present, as request ID -x-request-id-limit int truncate X-Request-Id header to limit; default no limit 实战 创建各种配置文件 # pwd /www/docker/webhook # tree . . ├── bin │ └── webhook ├── xxx └── webhook-linux-amd64.tar.gz 2 directories, 2 files 利用 uuidgen 生成随机 ID # uuidgen ecbfc10e-6b2d-4d32-98da-bdd2c3c29fc7 hooks.yaml - id: redeploy-hblog-xxxxx-7e86-4f24-8667-23xxxxxxx1 execute-command: "/www/docker/webhook/github-webhooks/depHblog.sh" command-working-directory: "/www/wwwroot/blog.17lai.site" depHblog.sh #!/bin/sh # 创建临时目录 temp_dir='/www/docker/webhook/tmp/hexoblog' dst_dir='/www/wwwroot/blog.17lai.site' repo_url='https://github.com/appotry/hexo.git' data_dir='' # 在这里进行你的操作,例如复制文件、下载内容等 # 检查目标目录是否存在 .git 目录 if [ -d "$temp_dir/.git" ]; then # 如果存在 .git 目录,则执行 git pull 命令进行更新 echo "Repository already cloned. Performing git pull..." cd "$temp_dir" git pull origin main # 如果使用了默认的主分支名字为 main git reset --hard origin/main else # 如果不存在 .git 目录,则执行 git clone 命令进行克隆 rm $temp_dir -rf echo "Cloning repository into $temp_dir..." git clone --progress -v --depth 1 "$repo_url" "$temp_dir" fi echo "rsync 目录同步" # -a:表示以归档模式同步,保留文件的所有属性,包括权限、时间戳等。 # -v:表示详细模式,显示同步过程中的详细信息。 # --delete:表示删除目标目录中源目录没有的文件。 rsync --delete -r --exclude='.git' --link-dest="$dst_dir" ${temp_dir}/${data_dir} ${dst_dir} echo "设置文件权限" chown www:www ${dst_dir}/${data_dir} -R vim depHblog.sh chmod +x depHblog.sh curl -X POST https://xxxx.17lai.site/hooks/redeploy-hblog-xxxx8fa-7e86-4f24-8667-23axxxx # 运行测试 su root /www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.json -verbose -port <通信端口> /www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.yaml -verbose -port 18xxx 后台运行 nohup webhook -hooks /usr/local/bin/github-webhooks/hooks.json -verbose -port <通信端口> & 反向代理 可以直接端口运行,当然上SSL 安全性更高! 这里使用 反向代理 复用443 宝塔面板 go 项目 调用测试 curl -X POST https://xxx.17lai.site/hooks/redeploy-hblog-xxxa-7e86-4f24-8667-2xxxx3xx 关联github仓库 上面命令测试成功之后就可以正式和 github 仓库关联起来了 后话 webhook 实际应用非常强大,只要你有想象力,几乎无所不能! 本文也在 hexo博客增强部署篇 一文中有提到。hexo 博客 系列文章越写越长,有兴趣可以再去看看,更新了很多东西了 参考&致谢 adnanh/webhook 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2024/4/24
articleCard.readMore

写了些浏览器增强脚本

平时创造写代码的时候,写了一些辅助工具,可以极大的提高工作效率!浏览器配合 tampermonkey 使用,真神器也!现在有繁简转换外挂,CSDN zhihu创作助手! JsTools 一些有用的 浏览器脚本 自用,以及给所有创作者们! 有什么建议可以留言或者提交 issue 仓库地址 Github 作者 夜法之书 脚本列表 网页繁简转换 给所有网页添加繁简转换功能! zhihu 创作助手 1,去掉知乎链接跳转,还原原始链接。 2,去掉知乎关键字搜索 CSDN 创作助手 只需轻轻一点,就去掉 CSDN 烦人的关键字搜索 juejin 创作助手 1,去掉知乎链接跳转,还原原始链接。2,去掉 复制代码 文字 Tampermonkey 安装和使用 Tampermonkey 是一款免费的浏览器扩展和最出名的用户脚本管理器,它可以让你在浏览器中自定义网页的行为和外观。通过安装 Tampermonkey,你可以使用来自世界各地的开发者提供的上千个脚本,也可以创建和运行自己的脚本。 🌐在 Chrome 上安装 Tampermonkey 打开 Chrome 浏览器。 访问 Tampermonkey Chrome Web 商店页面。 点击“添加至 Chrome”按钮,然后再次点击“添加扩展程序”确认安装。 🦊在 Firefox 上安装 Tampermonkey 打开 Firefox 浏览器。 访问 Tampermonkey Firefox Add-ons 页面。 点击“Add to Firefox”按钮,然后再次点击“Add”确认安装。 📱 移动设备 Tampermonkey 也可以在移动浏览器上使用: Android 安装 Tampermonkey 辅助应用 Tampermonkey iOS 安装支持 Tampermonkey 的第三方浏览器,如 Dolphin 在其他浏览器上安装 Tampermonkey 您可以在其他支持 Tampermonkey 的浏览器上,如 Edge 或 Safari 上查找适用于 Tampermonkey 的扩展程序,并按照它们的指示进行安装。 安装用户脚本插件 安装完 Tampermonkey 后,你可以安装各种用户脚本来扩展浏览器功能了。在任何提供用户脚本的网站上,点击"安装"按钮即可自动将脚本添加到 Tampermonkey 中。如果网页上没有"安装"按钮,你也可以通过复制脚本代码并在 Tampermonkey 的"添加新脚本"中粘贴代码来手动安装。 就是这样!现在你已经可以体验由全球开发者提供的各种有用的用户脚本,或者自己动手创建脚本来定制网页体验了。 打开您想要安装的用户脚本插件的下载链接。 Tampermonkey 会检测到页面上的用户脚本,并显示一个安装提示框。 点击安装按钮,Tampermonkey 将会自动安装用户脚本。 网页繁简转换外挂 给所有网页添加繁简转换功能! 经常访问到一些没有自带中文繁简转换的网站,虽然也认识,但是阅读感要累很多! 由于最近一直在更新修改 Hexo主题,对 JS 熟悉了不少,如果就写了这个 中文简体用户 请安装 Github greasyfork Github greasyfork CSDN 只需轻轻一点,就去掉 CSDN 烦人的关键字搜索 一次去不干净就多点击几次 zhihu 1,去掉知乎链接跳转,还原原始链接, 2,去掉知乎关键字搜索 juejin 1,去掉知乎链接跳转,还原原始链接, 2,去掉 复制代码 文字 关于作者 作者的博客 夜法之书 欢迎光临 License GPL V3 参考&致谢 chatGPT 真神器,编码过程中帮助非常大。 无论是日常生活,还是编码,或者创作,效率提升10倍不止。不过 chatGPT 一本正经的胡说八道不能给准确的建议,真正准确的判断还是需要行业领域专家才行!

2024/4/19
articleCard.readMore

GithubProfile美化与自动获取RSS文章教程

如何让你的 github profile 让人眼前一亮?默认的 github profile 页面是支持 Markdown 语法的,如是可以玩出很多花样来!给它添加各种特效和信息吧 点击查看大体积动图 Github Stats Card Github https://github.com/appotry/github-readme-stats 参考代码 Docker Hub https://hub.docker.com/r/bloodstar/github-readme-stats 更详细参数使用说明,请参考 Github 仓库 Readme 说明 由于 github 对 api 调用次数有限制,最好自建服务器使用! 自建 Docker 服务 docker-compose.yml version: "3" services: grs: image: bloodstar/github-readme-stats:latest container_name: grs environment: PAT_1: ghp_**** CACHE_SECONDS: 600 ports: - 9000:9000 docker run $ docker run \ --name grs \ --restart=unless-stopped \ -d \ -e PAT_1="ghp_****" \ bloodstar/github-readme-stats Vercel 和 docker 调用差异 和Vercel 部署调用不同,不需要 /api 这里vercel 和 docker 调用接口一致是比较容易实现的。为了方便和上游同步,这里就没有做修改。 # Vercel 部署调用 ![](https://ghstats.17lai.site/api?username=appotry) # Docker 部署调用 ![](https://ghstats.17lai.site/?username=appotry) [![Appotry's GitHub stats](https://ghstats.17lai.site/?username=appotry)](https://github.com/appotry/github-readme-stats) GitHub Stats Card [![Appotry's GitHub stats](https://ghstats.17lai.site/?username=appotry)](https://github.com/appotry/github-readme-stats) <picture> <source srcset="https://ghstats.17lai.site/?username=appotry&show_icons=true&theme=dark" media="(prefers-color-scheme: dark)" /> <source srcset="https://ghstats.17lai.site/?username=appotry&show_icons=true" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" /> <img src="https://ghstats.17lai.site/?username=appotry&show_icons=true" /> </picture> GitHub Repo Pins [![Readme Card](https://ghstats.17lai.site/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats) GitHub Gist Pins [![Gist Card](https://ghstats.17lai.site/gist?id=bbfce31e0217a3689c8d961a356cb10d)](https://gist.github.com/Yizack/bbfce31e0217a3689c8d961a356cb10d/) Top Languages Card [![Top Langs](https://ghstats.17lai.site/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) WakaTime Stats Card [![Harlok's WakaTime stats](https://ghstats.17lai.site/wakatime?username=ffflabs)](https://github.com/anuraghazra/github-readme-stats) 自动获取最新 RSS 文章 项目代码需要 rss2才能用。为了下面代码正常运行,需要安装支持 RSS2 的 hexo 插件 hexo-feed 创建 Profile Repo 创建一个和用户名一样的仓库,这个仓库就是你的 Github Profile 仓库。仓库的Readme.md 文件将会显示在 github/[name] 代码仓库导入 https://github.com/appotry/appotry 修改个人信息 .template/README.md generator.py .github/workflows/get rss.yml .template/README.md 把博主的信息,换为你自己的信息 generator.py 把常量定义修改为你自己的信息 # 常量定义 POSTS_RSS_URL = 'https://blog.17lai.site/rss.xml' BLOG_URL_PREFIX = 'https://blog.17lai.site' RECENT_POST_LIMIT = 12 .github/workflows/get rss.yml 修改文件仓库名称等相关内容 创建 action CI_TOKEN - name: Generate README.md for github.com env: GH_REPO: github.com/appotry/appotry.git run: | mkdir -p /home/runner/work/artifacts/ cd /home/runner/work/artifacts/ git clone https://github.com/appotry/appotry.git cd /home/runner/work/artifacts/appotry git config user.name "appotry" git config user.email "andycrusoe@gmail.com" rm -f README.md 配置完成后,运行 github action 最终效果 当然,还有很多其它方法用来美化 Github Profile 这里只是介绍了简单的几种,profile中使用的技术还没介绍完全 参考&致谢 使用 Python 生成博客目录并自动更新 README 最近发现一个 github action 实现了类似的功能 gautamkrishnar/blog-post-workflow 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署

2024/3/19
articleCard.readMore

人格类型分类总结归纳

本文介绍了什么是人格特质,怎么分类,并介绍了主流分析方法:BMTI以及五大人格分析方法。后面着重介绍了敏感型人格和内向人格的优势,最后介绍了人格缺陷的一些分类和特点。与人打交道,这些了解不可或缺! 人格特质 人格是一个复杂而多维的概念,对其进行科学的研究和分类有助于我们更好地理解自己和他人。在心理学领域,Myers-Briggs Type Indicator(MBTI)和Big Five五大人格特质理论是两种广泛应用的人格理论。本文将深入介绍这两种理论,并对各种人格类型进行分类和详细解读,以帮助读者更好地了解人格特质及其影响。 人格是指个体在思维、情感和行为等方面的长期稳定的特点和倾向。MBTI和Big Five理论是两种广泛使用的人格理论,它们各自从不同的角度探索和解释个体的人格特质。 Myers-Briggs Type Indicator (MBTI): MBTI是一种基于心理类型的理论,由伊莎贝尔·布里格斯-迈尔斯(Isabel Briggs Myers)和凯瑟琳·库克布里格斯(Katherine Cook Briggs)母女于 20 世纪 40 年代开发而成。它将人格分为四个维度,每个维度包含两个对立的特质,共计16种人格类型。 外向(E) vs. 内向(I): 外向型:喜欢与人交往,注重外部世界,善于社交和表达。 内向型:喜欢独处,注重内心体验,善于思考和反省。 感觉(S) vs. 直觉(N): 感觉型:重视具体事实和细节,偏好实际经验和直接感知。 直觉型:善于看到事物的整体和潜在意义,偏好理论和抽象思维。 思维(T) vs. 感觉(F): 思维型:以逻辑和客观分析为导向,更注重事物的理性和合理性。 感觉型:以情感和价值观为导向,更注重人情味和情感表达。 判断(J) vs. 感知(P): 判断型:喜欢有计划和组织,偏好决断和结论。 感知型:喜欢开放性和灵活性,偏好探索和观察。 Big Five 五大人格特质理论: 大五人格是目前心理学界最受认可的人格模型之一,它由 Lewis Goldberg 等人在 1980 年代提出。Big Five理论是一种基于因素分析的人格理论,将人格特质分为五个维度,每个维度描述了人格的一个方面,通过测量这些维度可以描述一个人的整体人格特征。 外向性 (Extraversion): 社交性、活跃、乐观、爱冒险、寻求刺激。 宜人性 (Agreeableness): 亲和力、合作性、信任、宽容、关心他人。 尽责性 (Conscientiousness): 责任感、自律性、目标导向、细致、可靠。 神经质 (Neuroticism): 焦虑、易怒、抑郁、情绪不稳定、易受压力影响。 开放性 (Openness to Experience): 好奇心、想象力、创造力、对新事物的接受度、审美情趣。 每个维度上,个体都会具有一定的倾向,但没有绝对的“好”或“坏”。 人格分类及特点: 外向型 (Extraverted): 社交能力强,乐观开朗,喜欢冒险和挑战,与他人相处融洽。 内向型 (Introverted): 善于思考和反省,喜欢独立思考,对深入的交流更感兴趣。 感觉型 (Sensing): 重视现实和具体事实,偏好实际经验和实用性,注重细节和常规。 直觉型 (Intuitive): 想象力丰富,喜欢探索新观念和未来可能性,关注整体和潜在意义。 思维型 (Thinking): 逻辑性强,善于分析和解决问题,注重客观、理性的决策。 感觉型 (Feeling): 关注人情味和价值观,重视他人感受,善于表达情感。 判断型 (Judging): 喜欢有计划和组织,注重目标达成和任务完成。 感知型 (Perceiving): 喜欢开放性和灵活性,善于适应变化和保持开放心态。 MBTI和Big Five理论提供了两种不同但互补的人格分类方式,帮助我们更好地理解自己和他人。每种人格类型都有其独特的特点和优势,而理解这些特点有助于促进个人成长、提高自我认知水平,以及改善人际关系。 人格分类 以下是 MBTI 和大五人格的两种人格分类方法: MBTI 类型 特征 ISTJ 务实、可靠、逻辑性强 ISFJ 善良、体贴、乐于助人 INFJ 富有同情心、理想主义、洞察力强 INTJ 独立、理智、具有战略眼光 ISTP 独立、行动力强、善于解决问题 ISFP 热爱自由、追求美感、富有创造力 INFP 理想主义、富有同情心、注重个人价值观 INTP 理智、客观、善于分析 ESTP 热情、活泼、喜欢冒险 ESFP 热情、友善、善于交际 ENFP 热情、乐观、富有创造力 ENTP 聪明、机智、善于辩论 ESTJ 务实、高效、注重秩序 ESFJ 热情、友善、乐于助人 ENFJ 富有领导力、鼓舞人心、充满热情 ENTJ 独立、自信、具有战略眼光 大五人格 维度 高分特征 低分特征 开放性 想象力丰富、好奇心强、乐于接受新事物 墨守成规、缺乏好奇心、不善于接受新事物 尽责性 认真负责、有条理、追求完美 粗心大意、懒惰、拖延症 外向性 喜欢与他人交往、充满活力、积极乐观 内向、喜欢独处、沉默寡言 宜人性 友善、体贴、乐于助人 冷漠、自私、不善于表达情感 神经质 情绪敏感、容易焦虑、压力感强 情绪稳定、乐观豁达、抗压能力强 应用 MBTI 和大五人格可以应用于多个领域,例如: 职业咨询:帮助人们找到适合自己的职业 团队建设:帮助团队成员更好地沟通和合作 个人成长:帮助人们了解自己、提升自我认知 注意事项 MBTI 和大五人格只是评估人格的工具,它们无法完全描述一个人的性格。在使用这些工具时,应注意以下几点: 没有绝对的“好”或“坏”的人格类型,换一个使用环境,可能好坏就相互转换了 人格类型不是一成不变的,可能会随着时间发生变化 为什么说高敏感人格是大后期人格 洞察力是高敏人群独有的强大天赋,但在未建立内在系统和正确认知前,只会导致讨好型人格或过度感知危险而特别缺乏安全感。 但如果通过修炼开发了此天赋,高敏人不仅能控制自己的情绪,还能高度觉知他人情绪且不受影响并引导他人情绪。 现实生活中大多数人都将敏感视为一个缺点 你这个人什么都好,就是太敏感了,甚至会把敏感和玻璃心混为一谈。其实那些成打式的人大多都是敏感和极端的,平和与随和其实是一种凡人的情绪共识。而我们的传统校园教育就是要把大多数人都培养成平凡人、易管理的人。因为很多看似与共识价值观相反的失误反而是正确的。 比如很多人信奉读书无用论,因为他们看到很多人即便读完了硕士和博士,依然找不到好的工作,依然赚得不多。而那些达官显贵是绝对不会让自己的孩子不读书的,因为他们知道一些只有他们自己家族认可,大多数人不认可的东西。不知你发现了没,很多官员和企业家骨子里都是高敏之人,他们会比常人更容易发现一些细节,更容易听懂一些弦外之声,跟他们相处是非常心累的。 你能说他们小心眼玻璃心吗?显然不是,因为小肚鸡肠之人往往是不可能做到非富即贵的。讲到这里,相信你就明白了,高敏感和小心眼是两码事。高明之人不一定会因敏感知识而生气,但他们拥有这样一份天赋,可以比常人更迅速的察觉到一些常人不懂的事情。这样就很容易先人一步,发现机会、抓住机会、发现危机、避开危机。 20% 左右的人带有高敏感 这个世界上只有 20% 左右的人带有与生俱来的高敏感。这些人拥有一种特殊的神经处理系统,他们的耳朵可以听到更广的频率,他们的味蕾可以尝出更丰富的味道,他们的鼻子可以更细致的辨别香水的成分。他们也有更强的共情力。 在一个电影院里,情节动人处,有些人一边吃着爆米花一边面无表情,而有些人哭得稀里哗啦,一包纸巾都不够用。见你流泪,我一眼忱。这真不是矫情,这是高敏感。 但高敏感往往被视为必须克制的缺点 但自小我们所接受的教育里,就是教我们压抑这种天赋,扔掉这种天赋,然后变成一个普通人。这个时代流行了一个新词,校顿敢力。很多人会将其视为正面褒义的性格词汇。经常有人说,不要太敏感,不要想太多,不要玻璃心,要控制,要宽容,要忍耐。然后敏感成了一个彻头彻尾的贬义词。 你看过漫画龙珠吗?你看过电影《触不可及》吗?里面的主角都是钝感力十足的人,这类人已经成为主流价值观、主流审美里受人欢迎的性格。高敏感不是一种病,更不是一种性格缺陷。高敏和深弱往往是一个硬币的两面,不是外形是否强壮,而是内在里要么气血弱,要么精神弱,敏感而易疲劳。所以觉醒的高敏人往往都是气血管理的高手。 敏感不代表冲动,能瞬间接收到一些信息,不一定瞬间就会反映出来,他们懂得“知者耻语,善者不言”,看透不说透,还是好朋友。但其实大多数人或者信奉遁敏的人,通常没有这种敏锐的观察力。现实生活中,不知你是否听过一种声音,多来自于年长者长辈们,他们告诉你,太敏感,太注重细节,成不了大事。 你听到过类似的话吗?如果听到过,你可以回想一下,说这话的人是一个成功的人吗?是一个成了大事的人吗?大概率不是,真正成了大事的人,往往是不喜欢说脚的,因为他们知道他们的成功秘籍,你拿钱都买不走。他们本身也不缺钱,怎么可能随随便便就交给你。好为人士是人类的本性,但高敏之人通常是人群中最沉默的那个人,他们善于观察,但不愿意表达。 当然,这并不代表他们没有表达能力,相反,他们通常具有超人的表达能力,因为他们的大脑所接收的信息要多于钝感力强的人。因此,看到这里,你要明白,以后不管别人怎么说,你就坚信没心没肺不是褒义词。能够破局的高明者,就是从修罗化境杀出来的神灵。 高敏感带来更强大的心理素质 不同于身强者天生的性格与身体催生的意志,高敏人由于会在前期大量感受不同的痛苦,被动进行脱敏训练,这将赐予高敏者一种纯粹的意志力。这种强大的心理是不需要他物支撑而存在的,有组成黑色生命力。黑色生命力这个词源自美国心理学家维尔纳的研究。他在数十年的走访中见过数以千计的问题家庭,他专门寻找那些处在糟糕的处境中,看起来有很大概率成为问题少年,但实际却成长得异常优秀的孩子。 他想知道是什么力量让这些孩子走出原生环境的束缚,变得光芒四射。维尔纳在 20 世纪 80 年代对夏威夷某小岛上的 698 个孩子进行追踪研究。那个贫穷的小岛上面,许多参与调查的孩子们的身后,都有一个甚至两个患有酗酒、毒瘾、暴力、恶习或因此染上精神疾病的父母。按照大众的认知,在这种家庭环境长大的孩子,人生基本算完了。 然而,出乎维尔纳意料,有 2/3 的孩子确实重蹈覆辙了这个悲剧。可还有 1/3 的孩子成长为自信、能干、关怀他人的优秀成年人,在学业、家庭和事业上都获得了成功。维尔纳认为,这 1/3 的孩子有能力摆脱糟糕环境影响,他把这种能力称为“修复力”,后来也被称之为“黑色生命力”。 生活远比小说要精彩。每个人的人生轨迹都不可能是一根直线,而是一条不断震荡的曲线。真正强大的人,都曾独自穿越过一片黑暗森林,如同种子在土壤里独自扎根。在这段至暗时光,需要忍受各种委屈、辛苦不被认可,隐忍不被理解,真心不被接纳,付出没有结果。凡是最终穿过这片黑暗沼泽地的人,才能真正看穿人性,看透人间冷暖,才能百炼成钢。 几乎每一个人都无可避免地有过至少一段剧烈滑落的低谷期,那就是每个人都必然会经历的至暗时光。强大的人就诞生于此,因为在这段剧烈滑落的波谷中,有人爬了上来,有人却再也没有。他的自信与勇气,在被至暗时光彻底击碎后,就再也没能回来。在这里,他需要经历的远比他尚未成熟的心灵想象的更多,比如世界观的重构,三观的崩坏,不公平的碾压,自我怀疑的低谷。 但如果熬过去了,就会得到一种全新的力量。黑色生命力就像是从地狱回来的人,因此,各位,至暗时刻低谷期,不要焦虑,不要绝望,甚至不要祈祷它快点结束,好好利用它们反思人生,马上就会迎来命运的转机。 人生最大的悲哀不是没有机会,而是站在机会前面,没看见或者没准备好。而大多数人推崇的钝感力,大概率会让你错过机会的。我们这个社会从来都是歌颂平庸、排斥不凡的,因为优秀的人注定是孤独的,注定是与众不同的。高敏之人,因为从幼年开始就比同龄人接受更多的信息,因此他们往往比普通人更有耐心,更有专注力。 你真的以为人与人的差别不大吗?其实我可以负责任的告诉你,差别巨大。你想过没有,为什么有的人有耐心看完一本书、一篇超长的文章,并且乐此不倦。而有的人超过 100 字,看着就头晕,他们只喜欢看类似于微博那样的一句话,概括一个新闻、一个话题、一个故事。 短期内,这两种习惯只因天赋的相差所产生的差距并不大,但久而久之,极有可能会塑造出完全不同的两类人。人与人的智商差距确实不大,但这里少了一个时间状语,那就是刚出生或小时候、成年后的人生。天赋的惯性会促使你走向不同的人生,且越走越远。 你有耐心看长的内容吗?高敏感人群通常具有三个层面的能力:第一是情绪管理能力;第二是对复杂的认知和理解能力;第三是一种应对世事变迁的人生哲学,又被心理学家称为智慧。他们对风险的忍受能力会变得很高。人往往经历过逆境和重大遭遇后,对人性有了更深层的理解,破三观,树新观,创立新的认知系统,学会换一个角度看世界,学会正式接纳,用不一样的方法得到不同结果。 也正因为如此,相较而言,在这些拥有高敏感性格的人生中,也有更多机会可能发生一些不寻常的事。我们该如何做,才能守住自己的高敏感天赋,或者培养出一种高敏感的性格? 提高自我意识和自我认知,深刻的了解和评估自己的思维方式、情绪方式和行为方式,不过度在意自己的过错,提高对内心真实想法的在意程度,培养自己的批判性思维,明确和了解自己和自己的目标。 接纳自己的一切,包括负面情绪,越抗拒越浓烈。正如海林格在诗中所说,所有的事情都是因缘和合而来,一切的发生都是必然。若我觉得应该是另外一种可能,伤害的只有我自己,我唯一能做的就是允许。 不害怕孤独,学会做减法,看淡一切的别离合变迁,学会在逆境中自我救赎和提升。关注自己有限的精力,不急于珍视所为的事和人,不在无意义的事上过度消耗自己。为自己的生活设定界限,区分什么让你舒适,什么让你不适,然后勇敢作出选择。 如果有完美主义倾向,那就适当降低自我要求,不要害怕别人的否定。打破非黑即白的世界观。这个世界不是非黑即白的二元对立,而是存在大量的灰色地带,没必要让自己绷得太紧。有意识的给生活留白,放松注意力,阻断信息输入,整理一天的情绪,帮助自己恢复能量。 最后让我们记住一点,低敏感度的人往往精力充沛,爱好广泛,人生更有广度。而高敏感的人,因为内心世界更丰富,人生往往更有深度。最后,一定要记住,高敏感是一种天赋,如果你具备了这种能力,那么请好好珍惜它。 为什么内向人格更容易成功 内向人格在当今社会中普遍被误解和低估,被视为软弱、害羞、不合群的特质。然而,实际上,内向的人们可能拥有许多优势,这些优势能够在工作和生活中帮助他们更容易取得成功。 内向人格的误解 1. 被认为软弱、害羞、不合群 内向的人们经常被误解为软弱和害羞,因为他们不像外向的人那样大声表达自己的意见或者主动与他人交流。然而,内向并不意味着缺乏自信或者自我意识,只是他们更喜欢独处或者与少数几个亲近的人交往,内向的人不需要狐朋狗友凑热闹,他们专注于内在的成长。 2. 被认为不适合领导岗位和管理 内向的人们经常被认为不适合领导岗位或者管理职位,因为他们不像外向的人那样善于社交和表达。然而,许多成功的领导者和管理者实际上都是内向的,他们通过深思熟虑和善于倾听来取得了领导者的地位。 3. 被认为不善社交和表达 内向的人们常常被认为不善于社交和表达,因为他们不像外向的人那样喜欢在人群中表现自己。然而,内向的人们在个人关系中往往更加真诚和深入,他们更擅长建立深层次的关系,而不是仅仅停留在表面上。 内向人格的优势 1. 思考和专注能力强 内向的人们通常拥有更强的思考和专注能力,他们更善于独自思考问题并找到解决方法。他们可以在一个相对安静的环境中工作,而不受外界干扰。 2. 审慎和稳重的性格 内向的人们往往更加审慎和稳重,他们不会轻易被外界影响或者诱惑。他们善于在面对挑战或者压力时保持冷静,并且能够有效地应对各种情况。 内向人格更易成功的证据 1. 企业高管和公司创始人中内向较多 许多成功的企业高管和公司创始人实际上都是内向的,他们通过深思熟虑和专注于细节来取得了成功。世界500强CEO和高管中,内向人格占据大多数,国内大公司创始人和高管也是内向人格占比绝对优势。独立思考和倾听能力更容易做好管理岗。 2. 内向销售的业绩表现较好 一些研究统计表明,被认为更适合外向人格的职业,实际上绝对大多数销售冠军都是内向人格,内向的销售普遍比外向人格销售业绩更高。这是因为内向的人们往往更加倾听客户的需求并提供更有针对性的解决方案。 3. 成功案例 世界各地都有许多成功的内向人士,例如著名的科学家、作家、艺术家等。他们通过他们的才华和努力取得了在各自领域的成功,并且成为了榜样和启示。 内向人格更合适的职业 1. 学术和研究相关 内向的人们通常更适合从事需要深思熟虑和独立工作的职业,比如学术研究、科学研究等。 2. 艺术和创造类 许多艺术家和创作者实际上都是内向的,他们通过他们的创造力和想象力创造了许多优秀的作品。 3. 分析和判断类 内向的人们往往更擅长分析和判断问题,因此他们在需要分析和决策的职业中可能更容易成功,比如金融、管理咨询等。 时代和环境的变化 随着时代的变化,对独立思考能力和专业能力的需求越来越大,许多工作重心也从社交应酬转移到专业能力上。因此,内向的人们在当今社会中可能更容易获得成功,并且受到更多的重视和认可。 内向人格的优势和成功证据不仅能够帮助内向的人们更好地认识自己,也能够让社会更加理解和重视内向的特质,为内向的人们提供更多的机会和支持。 人格缺陷 边缘型 (Borderline Personality): 特点: 情绪不稳定:情绪波动大,容易陷入极端的情绪状态,如愤怒、焦虑、沮丧等。 不稳定的人际关系:常常有强烈的亲密关系需求,但也容易产生矛盾和冲突,导致关系不稳定。 自我认同模糊:对自己的认知和身份感缺乏稳定性,容易受到外部影响而变化。 冲动和自残行为:常常表现出冲动和自毁行为,包括自残、酗酒、药物滥用等。 自恋型 (Narcissistic Personality): 特点: 自我中心:过度关注自己的权力、美貌、成功等方面,认为自己是特殊、优越的人。 需要赞扬和崇拜:渴望得到他人的赞美和崇拜,对自己的成就和品质过分自满。 缺乏同情心:对他人的需求和感受缺乏关注,常常表现出漠视或轻视他人的特征。 脆弱的自尊心:虽然外表自信,但内心对自尊心的损伤非常敏感,容易因批评而产生强烈的愤怒或羞耻。 偏执型 (Paranoid Personality): 特点: 怀疑和不信任:偏执型个体常常怀疑他人的动机和真实意图,对他人的行为持高度警惕态度,倾向于认为他人对自己有敌意。 敏感和戒备:他们对任何可能被解读为攻击或背叛的行为都非常敏感,因此常常保持警觉和戒备心态。 固执和坚持:偏执型个体往往坚持己见,对自己的看法和想法持续坚定,不易受到他人的影响或说服。 难以相处:由于其强烈的怀疑和不信任,偏执型个体往往难以与他人建立良好的关系,社交能力较差。 表演型 (Histrionic Personality): 特点: 过分关注自我:表演型个体倾向于追求注意和认可,常常将自己置于关注的中心,喜欢成为注意焦点。 情绪表达强烈:他们情绪表达较为夸张和强烈,经常会出现情绪波动较大的情况,以引起他人的注意和同情。 行为表现夸张:表演型个体倾向于夸大其词、夸张其行为,以吸引他人的注意和赞赏,常常表现出戏剧性的行为。 关系易变:由于其对他人的关注和认可需求较高,表演型个体往往会频繁改变关系,但关系表面上的深度可能并不持久。 焦虑型 (Anxious): 特点: 过度担忧:持续处于紧张和担忧状态,对未来和未知事物感到恐惧和不安。 焦虑症状:可能出现焦虑症状,如心慌、呼吸困难、胸闷等,严重时可能影响正常生活。 完美主义倾向:追求完美和控制,对自己和他人的要求过高,导致持续的紧张和压力。 社交困难:由于过度担忧和紧张,可能难以处理社交场合,产生社交焦虑症状。 回避型 (Avoidant): 特点: 回避社交:因为害怕批评和拒绝,避免参加社交活动和与他人互动,导致社交孤立。 自我负面评价:对自己缺乏信心,常常自我贬低,认为自己不配与他人交往或受到欢迎。 过度敏感:对他人的评价和反应过度敏感,容易因小事受伤或产生消极情绪。 避免面对问题:倾向于回避可能引起焦虑或痛苦的问题,逃避解决困难和挑战。 强迫型 (Obsessive-Compulsive): 特点: 强迫性思维:持续出现不受控制的强迫性思维,例如对安全、卫生、秩序等方面的过度关注。 强迫性行为:为了缓解强迫性思维带来的焦虑,进行重复、刻板的行为,如反复洗手、检查等。 过分注重细节:对细节和完美主义有过分的追求,常常陷入琐碎的细节中无法自拔。 控制欲强:试图通过控制自己的环境和行为来减轻内心的不安,但实际上增加了焦虑和压力。 抑郁型 (Depressive): 特点: 持续沮丧:情绪持续低落,感到无望、无助,丧失对生活的兴趣和热情。 自我评价过低:对自己持有消极、负面的评价,认为自己无能、无价值,经常自责和自责。 睡眠障碍:可能出现睡眠障碍,包括入睡困难、睡眠过多或睡眠质量不佳。 注意力难以集中:难以集中注意力,思维迟缓,记忆力减退,工作和日常活动效率低下。 狂躁型 (Bipolar): 特点: 情绪波动:周期性地经历情绪波动,交替出现狂躁和抑郁的状态。 狂躁期特征:狂躁期情绪高涨,兴奋、冲动,活力旺盛,可能出现冲动行为和不理性决策。 抑郁期特征:抑郁期情绪低落,感到无助、绝望,丧失兴趣和愉悦感,可能出现自我负罪感和自杀念头。 轮转周期:狂躁期和抑郁期之间会有周期性的交替,这种情绪波动对日常生活和社交关系都造成了困扰。 除了上述提到的人格障碍和心理疾病,还有其他类型,例如: 精神分裂症 (Schizophrenia): 特点: 幻觉和妄想:常常出现幻觉和妄想,如听到声音或看到不存在的东西,或对自己的身份、能力等产生严重的妄想。 思维混乱:思维内容不连贯,逻辑跳跃,难以理解或追踪其思维过程。 情感淡漠:对外界刺激和情感反应减少,表情呆滞,情感表达单调。 社交功能下降:由于症状的影响,社交能力和功能明显下降,日常生活受到严重影响。 恐慌障碍 (Panic Disorder): 特点: 突发性恐慌发作:突然出现强烈的恐慌和焦虑症状,伴随心悸、呼吸困难、出汗等生理反应。 避开触发因素:为了避免再次出现恐慌发作,可能会避免特定的场所或情境,严重影响生活质量。 恐惧再发作:对恐慌发作的再次发作持续担忧和恐惧,形成恐惧恶性循环。 生理反应:恐慌发作时可能出现的生理症状,如头晕、胸闷、手抖等,加剧恐慌的感觉。 智商高的人情商低? 先说结论,完全错误。情商只是智商的一部分,你的价值不值得别人讨好你而已。这个观点只是一些低智商,智商不足以匹配欲望的人的自嗨而已! 为什么会有人认为智商高的人情商都很低? 因为大多数人把情商简化成一种让别人舒服的能力。一个智商很高的人,只要他愿意,一定可以让别人舒服,只不过大多数时候他觉得这么做不划算。 智商高的人情商不可能低,因为情商本来就是智商的一部分。情商这个词正确的叫法应该是"情绪之理",是一种掌控自己情绪、识别他人情绪,让情绪为目标服务的能力。 高情商绝不是八面玲珑、让所有人都舒服,而是你想让别人感受到什么,别人就能感受到什么的一种情绪掌控力: 你希望对方感受到你的真诚,他感受到了,所以你们建立了合作。 你希望对方感受到你的愤怒,他感受到了,所以他不敢再得寸进尺。 你希望对方感受到你的阴狠毒辣,他感受到了,所以这辈子他都不敢再来打扰你的生活。 只要你传递出的情绪始终都是为自己的目标服务,就是高情商。 一个每天独来独往的数学系学生和一个跟所有人都能打成一片的社区情报人员,看起来后者情商很高,但也许前者已经完全预判了别人对自己的评价,又默许了这种评价。因为在他看来,浪费精力去迎合那些对目标毫无帮助的人,换取他们口中高情商的评价,是一种人生的亏损。 一流心态的人从来不需要去学习情商和人际交往的技巧,他们只设置一些标准,筛选人。很多人去学人际交往的知识、课程,自己又没什么本事,赚不到钱,只是学出了油嘴滑舌、狡辩抬杠、阿谀奉承、圆滑、心机深沉、妥协退让。这样的人虽然貌似懂点人际关系的技巧,有情商有礼貌,能说会道,但都是花架子,拿不上台面,对为人处世没什么大用。 真正独立的人,他不需要那些花架子,花架子顶多是加点分数。年轻最大的价值就在于对生命中的一切事物都保有敏锐又炽烈的感觉。一个年轻人要是没有这个年龄的精神,就必然会遭遇这个年龄的种种不幸。 很多人捧着所谓的高情商的七个表现,又是成功人士的说话技巧,迫不及待想要变得圆滑,变得成熟。但什么是成熟?真正的成熟是由纯洁长成的,而不是圆滑。圆滑是流于表面的东西,它走不进你的内心。圆滑没法让你成熟,它只能让你看起来成熟。 很多过来人的所谓成熟,只不过是磨平棱角、退去锋芒之后的妥协,是一种精神的早衰和个性的消磨,就像掉到地上的果子,看似熟透了,其实是被虫子咬烂了。理想的画面和自我的消亡是这种成熟的标配。 所以很多年轻人想要跳过那些流血流汗的过程,绕过这条弯路。他们想要通过模仿泄气的过来人,直接变成过来人。这就像一个人想要在身上纹满伤疤来变成一名老兵,但真正能上阵杀敌的绝不可能是纹满伤疤的演员。 鲁迅写过这么一段话:一个年轻人如果很早就洞察人事,安于圆滑,很早就懂得如何与人周旋,这预示着他本性平庸。相反,如果一个年轻人对世人的行为方式感到诧异和惊讶,在交往中表现得笨拙乖僻,则显示出他有着高贵的品质。这段话被很多人谴责和质疑,因为对真相的揭露总会刺痛很多人的内心。 人情是什么,圆滑又是什么?它们只是人类社会积累下来的处理社会事务的规则。它们不是真理而是经验,不是学识而是技巧。 人的智慧可以分为两种:一种是世俗智慧,一种是哲学智慧。 世俗智慧是对既存价值体系的准确认识和有效利用。 哲学智慧是对既存价值体系的全面反思和对根本人生问题的深刻洞察。 太追求世俗智慧,你会发现自己是社会的、是公司的、是他人的,唯独不是自己的。渐渐你就会活得跟千千万万的别人一样。从世俗的角度讲,不见得不幸福甚至是成功的,但却白白浪费了此生为人的机会。 因为世俗智慧只是一种工具,是对既存价值体系的迎合。这种不假思索的迎合必然会让人失去洞悉更高智慧的可能性,丧失反思性和超越性,只剩下工具性和服从性。被既存价值体系所痛化,陷入欲望的钟摆,满足了就空虚,不满足就痛苦。 而对世人的行为方式感到诧异和惊讶,恰恰体现出一个人对既存价值体系保持着批判性和反思性,拥有洞悉更高哲学智慧的可能。几乎所有伟大的哲学家都在试图培养人的哲学智慧,让人保有精神上的自由,因为这是所有终极人生问题的唯一出口。 人际交往的本质是利益交换!用你有的跟别人换你需要的。交际的目的是价值交换,各取所需,去积累优势吧。只要你的价值高且独特,你不需要学什么交际方法。懂得真诚待人,谦虚谨慎且懂感恩回报就行了。别人会求着跟你交际,此时你只需筛选出与你相合的人即可。那些与你不合的,就没必要交际了,免得后面惹出麻烦,不欢而散。 什么是真正的情绪稳定 情绪稳定的本质其实就是无惧和无愧。 所谓无惧,就是对可能将要发生的任何事情通通都无惧怕,允许一切发生,物来则应,物去不留,冰来降挡,水来土掩,实在解决不了,就干脆不管。反正车到山前必有路,完全不需要对那些未知的事情做太多的假设,该来的终究会来,该走的哪怕你费尽心思,你也留不住。 无悔就更简单,对已经发生的任何事情,对自己曾经做出的任何决定,全部坦然接受,不怨天尤人,把用来后悔的时间全部用来解决问题,其实你只需要活在当下就好。至于明天和意外哪个先来,全都交给命运,命里有时终时有,命里无时莫强求。 **第二,当事态不利于你的时候,静则急,不乱就是不错,尤其是你的心千万不能乱。**任何事情的发生都一定是有原因的,千万不要和自己死磕,给自己一点时间,想通笔顺,从长计议,才是于事最有效的解决方式。 你会发现很多时候缓一缓,冷静一下,通常都会有更合理的解决方案,记住以下八个字:事缓则远,人缓则安。遇到事儿了就提醒自己,让字淡飞一会儿,心浮气躁者一事无成,沉着冷静者百浮自绩。 **第三,这个世界上在意你的和讨厌你的可能加起来都不超过十个,所以你可能真的没那么多观众。**内耗的本质其实就是有点聪明,但是不多。首先愚蠢的人肯定不会内耗,聪明人也不会。最内耗的就是那些有点小聪明但是不够多的人,看透了一部分社会的本质,或者说自认为看透了一部分社会的本质,但是又接受不了这些信息给自己带来的冲击。 **你一定要搞清楚,对方如何看待你是对方的事情,过于在意他人评价只会让你感到痛苦。**其实你真的不需要在乎自己是不是有存在感,你要做的就是找到自己的节奏和步调,慢慢的你会发现其实一切都不晚,在这个过程中你一定会有恰到好处的时机,给予你想要的那些东西。 如果你眼下得不到,要么就是时机没到,要么就是你还配不上。 **第四,不管做什么事情,一开始用力过猛的人,注定会走不太远。**极强的责任心和控制欲会让他过度专注于结果,哪怕是一个很细微的障碍都会极大的影响他的心情,会走得很累,会感到疲惫不堪,会耗光热情和精力从而产生内耗,所以说慢慢来,懒懒散散的干,反而容易坚持下去。 **战术上要深入其中,战略上要置身事外。**方法上要深入其中,心境上要置身事外,对于自己控制不了的事,就不要过度操心和关注,有松弛感的人很淡然祥和,很自在,不拧巴,允许一切的发生,会主宰自己的节奏。 **第五. 不知道你有没有观察过能量高的人,如果你观察过,你就会发现他们都有一个特征:不纠缠。**不与是非纠缠,不与救人纠缠,不与伤害自己的人纠缠,他们洞悉这些人与事的本质,然后不与之产生交集,自然他们就不会把能量消耗在那些没有意义的事情上。 **第六. 生活中得罪几个人,做错几件事,真的没那么可怕,一辈子活得委屈求全,战战兢兢才是最可怕的。**你一定要明白,人生是一条起起伏伏的长剑,你的人生一定不会因为任何一个单一的时间点就被毁掉。 **第七. 心态的作用无一,举足轻重。宁愿得罪别人,也不要自己内耗。**勇敢大胆可以帮你走出很多困局。如何练就强大的心态,其实就八个字:得之我命,失之我性。 **第八. 把人生当作游戏,你就会很轻松。首先要跳出当下的自己,做一个玩家。**你这副躯壳是你的角色,你可以去读书健身来加强角色属性,不断地接任务做任务,随后完成任务领取奖励。 回到人生,你会发现等级都可以换算成你的认知和阅历。考虑人生只会越来越痛苦,但是跳出人生,用游戏思维带入人生,你会发现想不明白的事情会豁然开朗。 道不轻传,法不贱卖 医不叩门,师不顺路,法不轻传,道不送卦,易不空出 任何人,如果不在一个层次,那么无论你做什么,对方都觉得不对。所谓的层次,不是社会地位,而是人品和认知事物的清晰度。 即便你的认知水平已经很高了,也不要轻易去教导别人,让他们保持自我就好,即便是对身边最亲近的人也该如此。 与此同时,你要确保自己不被他人影响和消耗。 给予建议的智慧 **古人说"法不轻传,道不贱卖"是有道理的。**在别人没有主动寻求帮助时: 你给出的建议往往会被他本能地拒绝 这可能是因为建议超出了他的认知和理解范畴 每个人都是在挫折中成长起来的。 你不能剥夺别人从痛苦中汲取经验的权利,不然就得背负他人的因果。 交往与建议的艺术 把那些逆耳的忠言收起来吧 聪明的人不需要你的提醒 无知的人根本听不进去,还会觉得你在害他 在人际交往中: 以鼓励和表扬为主 涉及问题,点到即可 能领悟的人自然会领悟,领悟不了的人只有经历痛苦才能明白。 给予建议的深层逻辑 高手从来都不会轻易去指导别人,因为他们深知人与人的认知存在维度差异。 每件事情的成功背后都有一套完备的体系和方法: 即便你直接告诉别人该怎么做 即便你说的是正确的 但由于认知不足,对方可能会忽略细节并最终失败 更可能会把失败的原因归咎于你 成长的智慧 人到了一定的年纪就会明白: 要学会克制那种想去拯救别人的冲动 学会闭嘴是非常重要的,有时候不说话反而是一种智慧 有时候你想帮别人扫走弯路,但同时也可能剥夺了他在现实中学习的机会。 生命的自然法则 只要他还没有成长,上天就一定会想办法让他成长: 可能是通过痛苦 可能是通过磨难 帮忙和指点都是可以的,但要顺应自己的本心: 该出手时就出手 但一定要点到为止 记住:天域虽宽,不润无根之草;佛法虽广,不渡无缘之人。 信任的本质是暴力伤害 信任是暴力的代偿 当你没办法暴力伤害某个人或者团体的时候,你就没办法信任对方! 国家之间的信任:核弹阴影下的握手 1972年,尼克松与勃列日涅夫在莫斯科签署《反导条约》,微笑握手被全球媒体称作“冷战中信任的曙光”。人们忽略了背后的算术: 美国当时拥有 4,000枚核弹头 苏联在乌拉尔山脉部署着 2,500枚洲际导弹 这份“信任”的真实名称叫 “互相保证毁灭”(MAD)。当两国都能将对方国土烧成玻璃时,条约才有约束力。北极熊与白头鹰的共舞,永远踩着核发射井的地板。 日常信任的暴力基因 你以为的“商业诚信”本质是暴力转移: 花呗、借呗或者是朋友借款时签下借条 违约者收到法院传票 法警用破门锤强制执行 整个链条的终点,是 戴防暴手套的手 将你家中电视搬走抵债。当国家垄断了暴力使用权,个人才能安心交易——这是霍布斯《利维坦》最赤裸的现世演绎。 公司与员工 从暴力的角度来说,公司随时可以信任员工,而员工没法信任公司! 公司随时可以解雇员工,克扣工资,掌握员工的生存权利! 而员工只能被动接受,从经济学生物链来说,公司在上,员工在下。 这就是很多公司喜欢压榨欠债员工的本质原因! 不差钱的员工除外! 暴力控制与现代生产力 暴力控制天然违背生产力! 越是生产力高,创造力高的社会关系,越不适用使用暴力控制! 例如国家,公司。从奴隶制,领主制,分封制,郡县集中制,资本主义,社会主义的进化,就是一步一步的减少暴力控制,增加人的主管能动性的过程! 暴力控制是一种非常低效的控制方式,越是低端的劳动暴力控制越是有效! 高端的劳动,例如脑力劳动,暴力控制反而越是低效! 创造力具有天然的内发主动性,而暴力控制则会天然摧毁创造力! 一群工人远远的围观的机器设备运作,而设备的螺丝正在慢慢松动,随后一声巨响,设备崩坏,损失大几十万!员工只是远远的围观,背后的原因是前几天管理者粗暴的乱克扣工资! 工厂门口的路边有一块时候掉下来了,所有人路过都视而不见,直到运货车路过撞上去造成大几十万甚至几百万的损失!所有的管理条款都没有规定必须要移走路边的石头,而所有经过的员工都可以轻松的移走石头。为什么没人这么干?没收益,不值得,没规定,多干了导致受伤或者迟到的损失是自己的,而管理者只会克扣工资,而不会有任何奖励。 可做可不做的事情,底层员工要不要做,就看管理者平时是怎么对待底层员工的! 春秋时期送过将军华元站前犒赏羊肉分配不均与车夫羊斟结怨,导致羊斟在战场上故意驾车将华元送入敌营,最终宋军大败!这荒唐事儿被《左传》记下来,成了“羊斟惭羹”这成语,意思是因小失大,提醒后人得注意团队和细节。 这就是暴力控制,死板管理的落后性与滞后性! 法律,管理规则天然的具有滞后性,没办法预测未来的变化,这就需要人的主观意愿!而暴力控制,天然的会摧毁这种主观意愿! 而道德反而可以超前控制人的行为,讲道德可以超越法律,管理条款,达成最高效率和效益!而张口就是不违反法律的都是人渣,只会带来最低的生产力,在市场竞争中被淘汰! 亲密关系中的自毁型暴力 亲密关系中以伤害自己来伤害对方的前提是对方还爱你! 凌晨三点的急诊室,护士对割腕女孩说:“这是本月第5个用血写男友名字的人。” 看似荒诞的行为背后藏着精密逻辑: graph LR A[自残行为] --> B[激发对方愧疚] B --> C[情感操控] C --> D[维持关系控制权] 当爱情褪去时,伤害自己成了最锋利的武器——用疼痛绑架对方的同情,用鲜血铸造责任的枷锁。这种“信任”的保鲜剂,竟是皮下组织的裂痕。 信任的终极悖论 暴力建立信任,暴力摧毁信任: 明成皇后相信日军护卫队,1895年被刺死于景福宫 比特币创始人中本聪匿名至今,因代码世界没有物理暴力,当暴力缺位时,“信任”要么沦为赌命(如皇后),要么退守虚拟(如区块链)。人类用十万年修筑的文明穹顶,始终被暴力的钢筋支撑着。 终极的平衡:区块链与反暴力 去中心化与数学的绝对公平带来区块链的信任! 去中心化,代表非暴力机关控制。而数学的严谨性代表了绝对公平! 而非去中心化的区块链,则随时可以毁约!最后大概率是击鼓传花,跑路后一地鸡毛! 而国家背书的稳定币或者其他数字货币背后本质还是国家暴力机构! 暴力弱化进化史 graph LR A[暴力] --> B[法律] B --> C[道德] C --> D[区块链] 暴力弱化的历史,就是生产力进步的历史!解放主观能动性代表着最先进生产力方向! 后话 真理越辩越明,只有谎言才经不起辩论。 本文理论不一定正确,可能只适用于部分条件,有不同已经欢迎留言辩论! 司马懿在曹操手下是忠臣良将,在曹丕手下就造反了,为什么? 本质是曹操能力强,罩得住司马懿,而曹丕能力弱鸡。 同一个人,不同时间,对别人忠诚的人,不一定会对你忠诚 同一时间,对别人忠诚的人,不一定对你忠诚。同一个人昨天对你忠诚,今天不一定对你忠诚 要求忠诚就是伪命题,你能力强就有忠诚。 忠诚的对象是利益,外在表现就是超强的能力,能带来利益的能力。人际交往的本质是利益交换! 变化的人格与刻舟求剑 人的个性是不停的变化的: 随着对象不同而变化。例如司马懿对曹操和曹丕 随着时间的变化而变化。同一个人少年,青年,老年对同一个事物观点可能完全不同。 随着见识的增长而变化。 随着环境的变化而变化。橘生淮南则为橘, 生于淮北则为枳 机械的划分人的性格就是刻舟求剑,本质就是为了PUA你! 为什么现在的员工没有几个忠诚的了? “忠诚”的本质是一种“信用”,信用的背后是利益在支撑!归根结底是利益交换! 如果你的员工没有其他工作机会和收入,也没有猎头来挖他们跳槽,这时候你根本不会在意他们是否“忠诚”,你会觉得是自己“格外开恩”赏他们一口饭吃。 为什么员工面对一份更高收入的工作没有马上离职,而且在明显损害自己机会成本的基础上继续帮你赚钱?是因为“忠诚”嘛? 此时要让员工的“忠诚”有效只有两个方法: 第一,在过去的日子里面你为员工提供了一种他急需而其他公司无法提供的“利益”。他欠了你的“人情债”,但他一时未有提供到稀缺资源来补偿你。 第二,他之所以没有跳槽去新的工作,是因为对方相信你将来能给他提供更好的回报。 这才是“忠诚”的价值。 再说一个2024年真实的现实例子,对比一下韩国全斗焕和尹锡悦搞政变时是如何保证忠诚的。 全斗焕起事时只是一个中级军官,但他敢大手笔发钱,承诺出了事什么都自己扛,最终成事了。后来他被美搞下台也没有出卖队友,什么都自己扛,而他的队友也保住了他的命,得以安享晚年。而尹锡悦贵为总统,全韩国军人都要向他喊“忠诚”,起事没有任何利益保证和承诺,结果搞一次2小时政变让全世界笑话,最终难逃牢狱之灾! 为什么裁员 100% 会裁到大动脉? 团队战斗力95%以上是领导者决定的! 当一个团队绩效不行,首先就说明领导者不合格,或者领导者的领导者等以上级层战略错误。 士兵再勇敢,但它在错误的方向上杀伤再多的敌人,都不能抵挡战术,战略的失误! 裁员基本都是领导团队主导的,一个失格的领导不了解市场,不了解技术,不了解人员才会导致团队绩效低下。这种情况下,通常都是欺上瞒下,阿谀奉承,裁员裁的都是干活的,臭鱼烂虾反而留下了。这几乎是必然会发生的! 所以,你懂的,为什么为什么裁员 100% 会裁到大动脉了吧。撤换领导层,认清市场真正的战略机会在哪里,在正确的方向上面使力才会提高团队的战斗力! 为什么烂团队会“烂得稳定”? 劣币驱逐良币 团队腐烂的核心是逆向选择:有能力的人因不愿同流合污而离开,剩下的要么是演员,要么是被PUA到自我怀疑的人。最终团队会进入低水平平衡,所有人都在应付,但谁都不敢掀桌子。 领导层的恐惧投射 无能的管理者最怕下属太专业,因为会暴露自己的无知。于是他们会 系统性逃避责任 烂团队的流程冗长、会议泛滥,本质是集体免责策略,用流程正确掩盖结果错误。所有人都知道项目会垮,但没人愿意第一个承认。 参考&致谢 高敏感人格的究极形态 九哥 最后再次强调,人的性格会随着时间、环境,对象等因素变化而变化,不是一成不变的,不要刻舟求剑! 机械的划分人的性格是愚蠢的,弱智的,强制划分你的性格的人极大概率是为了PUA你,极少数才是真心为你好。 医易道须知:医不叩门,师不顺路,法不轻传,道不送卦,易不空出 附赠 第一性原理 你思考过人生问题的本质吗? 1、第一,家庭的第一核心,是经济,而不是感情, 2、第二,职场的第一准则,是价值,而不是努力。很多人埋头苦干,却忽略了自身价值的提升和展现最终只能在底层徘徊。 3、第三,社交的第一关键,是利益互换,而不是单纯的友谊。没有利益的连接,友谊往往难以长久维持。 4、第四,教育的第一目的,是培养能力,而不是追求分数。高分低能的孩子在未来社会很难立足。 5、第五,健康的第一要素,是自律,而不是医疗,等生病了才去依赖医疗,不如平时就养成良好的生活习惯。 6、第六,爱情的第一基础,是理解,而不是激情。激情总会褪去,唯有理解才能让爱情长久。 7、第七,创业的第一要点,是市场需求,而不是个人喜好。仅凭自己的喜好去创业,很可能血本无归。 8、第八,投资的第一原则,是风险控制,而不是高回报。只盯着高回报,往往会陷入巨大的风险中。 9、第九,人生的第一追求,是幸福,而不是成功.成功不一定带来幸福,但幸福却是人生最宝贵的财富。 10、第十,养老的第一保障,是提前规划,而不是依赖子女。子女也有自己的生活压力,不能把养老完全寄托在他们身上。 11、第十一,成长的第一动力,是反思,而不是经历。没有反思的经历只是过眼云烟。 12、第十二,学习的第一意义,是应用,而不是积累知识。知识只有运用到实际中才有价值, 13、第十三,旅行的第一收获,是见识,而不是拍照打卡。真正的旅行是开阔视野,增长见识。 14、第十四,婚姻的第一支撑,是责任,而不是浪漫。浪漫会消逝,责任才能让婚姻稳固。 15、第十五,生活的第一智慧,是知足,而不是无尽的欲望。懂得知足,才能在生活中找到真正的快乐 关于学习的第一性原理 学习的第一性原理是理解,而不是背诵; 刷题的第一性原理是归纳,而不是数量; 记忆的第一性原理是关联,而不是重复; 考试的第一性原理是基础,而不是技巧; 知识的第一性原理是体系,而不是碎片。 反PUA 如果别人对你很满意,就证明你一直在吃亏; 说你敏感,就是你猜对了; 说你自私,就是他没有占到便宜; 说你强势,就是你不好控制; 说你固执,就是你不好拿捏; 说你不懂事儿,就是嫌你不听话; 说你不合群呢,就是你不好骗; 说你脾气不好,就是你没顺着他; 是说你格局不够,就是他画的饼你没吃。 所有欺负你的人,都在赌你不会反抗,他们拿捏的是你的沉默;所有利用你的人,都在赌你不会拒绝,他们拿捏的是你的不好意思;所有对你不敬的人,都在赌你不会反击,他们拿捏的是你的忍让;所有对你冷漠的人,都是在赌你不会离开,他们拿捏的是你的依赖。记住,善良有尺,忍让有度,一定要做一个有锋芒的善良人。 为什么有的人会宗室指责你,贬低你? 在社交中,你有没有遇到这样的人? 他们总是指责你,贬低你,打压你。 具体的表现有: 经常挑你刺,无论你做什么,他都要挑出点问题,哪怕你并没有做错; 总是指责你,无论你付出了什么,他都不会认可你; 总是贬低你,一次次打击你的信心; 经常拉拢周围的人,一起打压你,排挤你。 在很多场景下,都容易遇到这类人。 他们指责你,挑你的刺,难道就一定是你做错了吗? 未必。 这类人十分擅长制造这种“高高在上的俯视感”,以此来打击你,掌控你。 从心理学的角度来分析,这种人是什么心态?有什么目的? 掩饰内心的自卑 你有没有发现一个奇怪的现象? 有些内向自卑的人,只要让他得到点“权力”,他就变得张牙舞爪。 拿着鸡毛当令箭,土鸡摇身一变就以为自己变成了凤凰。 自卑的人,内心是这样: 很怂,在很多关系中,都是卑微的,处于低位的状态。 多数时间,他们都扮演着“沉默,不主动,没有勇气争什么”的姿态。 但是,只要有人给他一点权力,他瞬间就变了。 变成了“欺下媚上”的人。 对待比自己地位高的人,依旧保持讨好,卑微; 对待比自己地位低的人,高高在上,颐指气使。 从心理学的角度讲: 自卑到骨子里的人,只要有一个能改变自己的机会,他就会表现出极强的反差感。 压抑了那么多年的自卑,当然要“耀武扬威”一番。 而最常用的手段就是: 指责你,针对你。 因为在他获得改变之前,他过得始终不如你。 试图对你PUA,操控你 这类人,最喜欢做的事情: 打你一巴掌,然后给你一颗甜枣吃。 上一秒指责你,挖苦你,当众侮辱你; 下一秒,他又摆出和善的表情,跟你说: “我这么做,都是对你好,你应该明白我的良苦用心。” 倘若你是一个“情绪不那么敏感”,很容易对他人给你的一点儿好,就感激涕零的人; 你很容易误入这类人的圈套。 他的骨子里,有着很强的掌控欲; 试图通过对你进行“语言攻击”的方式,完成对你的PUA; 无论是职场中,社交中还是感情里,这类人最终的目的,都是控制你。 遇到这类人,该如何回应? 在社交中,什么样的人都能遇到。 有人充满善意,对任何人都拿出尊重和礼貌; 有人充满恶意,别人只不过是他的“垫脚石”。 当陌生人试图攻击你,欺负你的时候; 你要做的,是保全自己,能躲多远躲多远。 当身边的人欺负你,你要第一时间反击回去。 为什么? 因为他们欺负你,其实是在试探你; 你的表现,直接决定了他们接下来对你的态度。 倘若你软弱,接下来等待你的,是他们得寸进尺欺负你; 倘若你强硬,那么接下来,这些人就不敢欺负你。 无论跟谁相处,你的善良应该留给“值得的人”; 尊重你的人,回以尊重; 欺负你的人,回以强势。 系列教程 全部文章RSS订阅 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2024/2/18
articleCard.readMore

Linux Bash Shell 使用技巧归纳整理

Linux就是未来!在Linux下,Bash的地位无可忽视,日常工作中涉及到Linux下的管理与操作基本都是在Bash中进行,因此,为了提高Linux下工作效率,自然而然的就变成了如何高效使用Bash的问题。 快捷键 常用快查指南,也可以看这里 Bash Shortcuts 编辑命令 Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + f :按字符前移(右向) Ctrl + b :按字符后移(左向) Alt + f :按单词前移(右向) Alt + b :按单词后移(左向) Ctrl + xx:在命令行首和光标之间移动 Ctrl + u :从光标处删除至命令行首 Ctrl + k :从光标处删除至命令行尾 Ctrl + w :从光标处删除至字首 Alt + d :从光标处删除至字尾 Ctrl + d :删除光标处的字符 Ctrl + h :删除光标前的字符 Ctrl + y :粘贴至光标后 Alt + c :从光标处更改为首字母大写的单词 Alt + u :从光标处更改为全部大写的单词 Alt + l :从光标处更改为全部小写的单词 Ctrl + t :交换光标处和之前的字符 Alt + t :交换光标处和之前的单词 Alt + Backspace:与 Ctrl + w 相同类似,分隔符有些差别 [感谢 rezilla 指正] 重新执行命令 Ctrl + r:逆向搜索命令历史 Ctrl + g:从历史搜索模式退出 Ctrl + p:历史中的上一条命令 Ctrl + n:历史中的下一条命令 Alt + .:使用上一条命令的最后一个参数 控制命令 Ctrl + l:清屏 Ctrl + o:执行当前命令,并选择上一条命令 Ctrl + s:阻止屏幕输出 Ctrl + q:允许屏幕输出 Ctrl + c:终止命令 Ctrl + z:挂起命令 Bang (!) 命令 !!:执行上一条命令 !blah:执行最近的以 blah 开头的命令,如 !ls !blah:p:仅打印输出,而不执行 !$:上一条命令的最后一个参数,与 Alt + . 相同 ! :打印输出 :p:打印输出! 的内容 !*:上一条命令的所有参数 !:p:打印输出 ! 的内容 ^blah:删除上一条命令中的 blah ^blah^foo:将上一条命令中的 blah 替换为 foo ^blah^foo^:将上一条命令中所有的 blah 都替换为 foo 详细介绍 快捷键的一些说明: CTRL=C:这个键是指PC键盘上的Ctrl键 ALT=M:这个键是PC键盘上的ALT键,如果你键盘上没有这个键,可以尝试使用ESC键代替 SHIFT=S:此键是PC上的Shift键 ESC=E:这个键是PC键盘上的ESC键,此键一般在键盘的左上角 BACKSPACE=DEL:此键是是PC键盘上的Backspace键,一般位于主键盘区的右上角 文中”[]“括住的为快捷键内容,”-”两边的内容是按住左边键,再按右边键获得,”,”逗号两边的内容是先按左边键,松开后再按右边键。如:[CTRL-v]是表示按下Ctrl键之后,不要松开,再按下v键。 默认的情况下,快捷键的组成格式是:<CTRL | ALT | ESC >-[SHIFT-]。即由Ctrl、Alt、Esc之一开头,中划线,Shift,中划线,和一个字符组成。其中,中括号内的Shift和”-”有时可省略。 默认情况下,快捷键只有最后一个为字符,其他的键值均为功能键 出现[CTRL-?]这类快捷键,由于”?”是需要使用Shift按键才能获得的字符,因此此类快捷键默认使用的是[CTRL-SHIFT-?] 要注意,在Bash里面,快捷键可能会被写成八进制或者十六进制的形式(跟在转义符后面); 脚本文件中的快捷键并不是总能起作用的。另外快捷键有个规律,Ctrl开头的快捷键一般是针对字符的,而Alt开头的快捷键一般是针对词的。 Bash下,如果使用的是shell脚本文件,快捷键不一定是一样的,有的时候会出现同一个快捷键有不同的表现,这种情况一般是由于Bash所处的模式不同而引起的,你可以通过set命令来调整模式: set -o emacs ##切到emacs模式 set -o vi ##切到vi模式 set -o ## 查看当前选项的设置状态 这个是Bash的option选项,你可以根据具体情况进行设置,本文使用的是emacs模式。 快捷键 快捷键说明 CTRL-A 将光标移到行首(在命令行下) CTRL-B 退格 (非破坏性的),这个只是将光标位置往回移动一个位置。 CTRL-C 中断,终结一个前台作业。 CTRL-D “EOF” (文件结尾:end of file)。它用于表示标准输入(stdin)的结束。在控制台或xterm 窗口输入文本时,CTRL-D 删除在光标下的字符。从一个shell中退出 (类似于exit)。如果没有字符存在,CTRL-D 则会登出该会话。在一个xterm窗口中,则会产生关闭此窗口的效果。 CTRL-E 将光标移动到行尾(在命令行下) CTRL-F 将光标向前移动一个字符(在命令行下) CTRL-G BEL。在一些老式打印机终端上,这会引发一个响铃。在xterm终端上可能是哔的一声。 CTRL-H 擦除(Rubout)(破坏性的退格)。在光标往回移动的时候,同时擦除光标前的一个字符。 CTRL-I 水平制表符。 CTRL-J 新行(换行[line feed]并到行首)。在脚本中,也可能表示为八进制形式(‘/012′)或十六进制形式(‘/x0a’)。 CTRL-K 垂直制表符(Vertical tab)。在控制台或 xterm 窗口输入文本时,CTRL-K会删除从光标所在处到行尾的所有字符。在脚本中,也可能表示为八进制形式(‘/013′)或十六进制形式(‘/x0b’)。在脚本中,CTRL-K可能会有不一样的行为,下面的例子给出其不一样的行为:`#!/bin/bash ## 一个CTRL-K垂直制表符的例子 var=You can't use 'macro parameter character #' in math mode'/x0aBottom Line/x0bTop line/x0a' ## 直接输出 echo "'/x0aBottom Line/x0bTop line/x0a' ## 直接输出 echo "var" ## 使用col来过滤控制字符 echo “$var” CTRL-L 跳纸,换页(Formfeed),清屏。清空终端屏幕。在终端上,这个命令的作用和clear命令一样。但当这个命令发送到打印机时,Ctrl-L会直接跳到纸张(Paper sheet)的末尾。 CTRL-M 回车(Carriage return)。 CTRL-N 擦除从history缓冲区召回的一行文本(在命令行下)。如果当前输入是历史记录中选择的时候,这个是从这个历史记录开始,每按一次,是更接近的一条命令。 CTRL-O 产生一个新行(在命令行下)。 CTRL-P 从history缓冲区召回上一次的命令(在命令行下)。此快捷键召回的顺序是由近及远的召回,即按一次,召回的是前一次的命令,再按一次,是召回上一次之前的命令,这和CTRL-N都是以当前的输入为起点,但是两个命令操作刚好相反,CTRL-N是从起点开始由远及近(如果起点是历史命令的话)。 CTRL-Q Resume (XON)。恢复/解冻,这个命令是恢复终端的stdin用的,可参见CTRL-S。 CTRL-R 回溯搜索(Backwards search)history缓冲区内的文本(在命令行下)。注意:按下之后,提示符会变成(reverse-i-search)”:输入的搜索内容出现在单引号内,同时冒号后面出现最近最匹配的历史命令。 CTRL-S Suspend(XOFF),挂起。这个是冻结终端的stdin。要恢复可以按CTRL-Q。 CTRL-T 交换光标位置与光标的前一个位置的字符内容(在命令行下)。比如:echo $var;,假设光标在a上,那么,按下C-T之后,v和a将会交换位置:echo $avr;。 CTRL-U 擦除从光标位置开始到行首的所有字符内容。在某些设置下,CTRL-U会不以光标位置为参考而删除整行的输入。 CTRL-V 在输入文本的时候,按下C-V之后,可以插入控制字符。比如:echo -e '/x0a’;和echo ;这两种效果一样。这点功能在文本编辑器内非常有效。 CTRL-W 当在控制台或一个xterm窗口敲入文本时, CTRL-W 会删除从在光标处往后(回)的第一个空白符之间的内容。在某些设置里, CTRL-W 删除光标往后(回)到第一个非文字和数字之间的字符。 CTRL-X 在某些文字处理程序中,这个控制字符将会剪切高亮的文本并且将它复制到剪贴板中。 CTRL-Y 将之前已经清除的文本粘贴回来(主要针对CTRL-U或CTRL-W)。 CTRL-Z 暂停一个前台的作业;在某些文本处理程序中也作为替换操作;在MSDOS文件系统中作为EOF(End-of-file)字符。 CTRL-/ 退出。和CTRL-C差不多,也可能dump一个”core”文件到你的工作目录下(这个文件可能对你没用)。 CTRL-/ 撤消操作,Undo。 CTRL-_ 撤消操作。 CTRL-xx 在行首和光标两个位置间进行切换,此处是两个”x”字符。 ALT-B 光标往回跳一个词,词以非字母为界(跳动到当前光标所在词的开头)。 ALT-F 光标往前跳一个词(移动到光标所在词的末尾)。 ALT-D 删除光标所在位置到光标所在词的结尾位置的所有内容(如果光标是在词开头,则删除整个词)。 ALT-BASKSPACE 删除光标所在位置到词开头的所有内容。 ALT-C 将光标所在位置的字母转为大写(如果光标在一个词的起始位置或之前,则词首字母大写)。 ALT-U 将光标所在位置到词尾的所有字母转为大写。 ALT-L 将光标位置到词尾的所有字母转为小写。 ALT-R 取消所有变更,并将当前行恢复到在历史记录中的原始状态(前提是当前命令是从历史记录中来的,如果是手动输入,则会清空行)。 ALT-T 当光标两侧都存在词的时候,交换光标两侧词的位置。如:abc bcd -> bcd abc ALT-. 使用前一次命令的最后一个词(命令本身也是一个词,参见后一篇的Bang命令中的词指示符概念)。 ALT-_ 同ALT-.。 ALT-数值 这个数值可以是正或者是负,这个键单独没有作用,必须后面再接其他内容,如果后面是字符,则表示重复次数。如:[ALT-10,k]则光标位置会插入10个k字符(负值在这种情况下无效);如果后面接的是命令,则数字会影响后面命令的执行结果,如:[ALT–10,CTRL-D]则向CTRL-D默认方向相反(负数)的方向执行10次操作。 ALT-< 移动到历史记录中的第一行命令。 ALT-> 移动到历史的最后一行,即当前正在输入的行(没有输入的情况下为空)。 ALT-P 从当前行开始向前搜索,有必要则向”上”移动,移动时,使用非增量搜索查找用户提供的字符串。 ALT-N 从当前行开始向后搜索,如果有必要向”下”移动,移动时,使用非增量搜索查找用户提供的字符串。 ALT-CTRL-Y 在标志点上插入前一个命令的第一个参数(一般是前一行的第二个词)。如果有参数n,则插入前一个命令的第n个词(前一行的词编号从0开始,见历史扩展)。负的参数将插入冲前一个命令的结尾开始的第n个词。参数n通过M-No.的方式传递,如:[ALT-0,ALT-CTRL-Y]插入前一个命令的第0个词(命令本身)。 ALT-Y 轮询到删除环,并复制新的顶端文本。只能在yank[CTRL-Y]或者yank-pop[M-Y]之后使用这个命令。 ALT-? 列出能够补全标志点前的条目。 ALT-* 把能够补全[ALT-?]命令能生成的所有文本条目插入到标志点前。 ALT-/ 试图对标志点前的文本进行文件名补全。[CTRL-X,/]把标志点前的文本当成文件名并列出可以补全的条目。 ALT-~ 把标志点前的文本当成用户名并试图进行补全。[CTRL-X,~]列出可以作为用户名补全标志点前的条目。 ALT-$ 把标志点前的文本当成Shell变量并试图进行补全。[CTRL-X,$]列出可以作为变量补全标志点前的条目。 ALT-@ 把标志点前的文本当成主机名并试图进行补全。[CTRL-X,@]列出可以作为主机补全标志点前的条目。 ALT-! 把标志点前的文本当成命令名并试图进行补全。进行命令名补全时会依次使用别名、保留字、Shell函数、shell内部命令,最后是可执行文件名。[CTRL-X,!]把标志点前的文本当成命令名并列出可补全的条目。 ALT-TAB 把标志点前的文本与历史记录中的文本进行比较以寻找匹配的并试图进行补全。 ALT-{ 进行文件名补全,把可以补全的条目列表放在大括号之间,让shell可以使用。 在Bash下,如果能够妥善的使用快捷键,在Linux系统的操作会变得非常快捷,比如我们在使用cat创建一个文件时,我们可以使用快捷键[CTRL-D]: ## 不用快捷键 cat >>/tmp/test<<_EOF ##这里是内容 ##最后我们要在新行里面输入_EOF ##cat见到_EOF才会将内容写到文件中 ##使用快捷键 cat >>/tmp/test ##这里输入内容 ##输入完毕之后,直接[CTRL-D]结束 有的时候我们需要创建一个文件,而后对这个文件进行操作: touch /tmp/a-test-file-from-blog.useasp.net ## 不使用快捷键,文件名要重新输入 chmod u+x /tmp/a-test-file-from-blog.useasp.net ##使用快捷键 chmod u+x <ALT-.> ## 快捷键[M-.]自动会将上面的最后一个参数附加 怎么样,有没有更有效率? 当然,Bash的快捷键只有在不断的使用中,才能达到真正的高效,在开始连要用那个快捷键都要思考半天的情况下,高效是很难的——但磨刀不误砍材工,前期的投入是值得的。 如果你想自己的Bash有那么一些不同,你也可以自己自定义快捷键,使用bind命令即可,Bash中的快捷键其实是Readline来提供的,因此,这里快捷键的设置其实就是配置Readline,Readline中分两种快捷键,一种是Readline内部的函数快捷键,另外一种是执行Shell命令,设置的时候稍有不同: ##查看Readline中可以使用的函数名称 bind -l ##查看当前绑定的案件配置与其对应的功能 bind -v ##已经绑定的快捷键 bind -p ##绑定自定义执行命令shell命令的快捷键 bind -x '"/C-x/C-l":ls -al' ## 绑定后,按[C-x,C-L]就能执行ls -al ## 绑定内置函数功能 bind "/C-x":backword-delte-char ##这个是这行Readline库中的函数backword-delte-char 这种设置只是针对当前的会话有效,一旦会话丢失,这样设置的快捷键就会丢失,为了能够让设置的快捷键永久有效,我们就需要将快捷键的配置写入文件。在Linux系统中,能永久保存快捷键的地方有两个,全局和用户的配置文件,全局的是/etc/inputrc,而用户的是在用户的根目录下~/.inputrc,全局的会影响所有的用户,而用户根目录下的只会对相应的用户产生影响。inputrc文件的大概样子像下面这样: ## 本例来自CentOS6.4的默认配置文件 $if mode=emacs # for linux console and RH/Debian xterm "/e[1~": beginning-of-line "/e[4~": end-of-line # commented out keymappings for pgup/pgdown to reach begin/end of history #"/e[5~": beginning-of-history #"/e[6~": end-of-history "/e[5~": history-search-backward "/e[6~": history-search-forward "/e[3~": delete-char "/e[2~": quoted-insert "/e[5C": forward-word "/e[5D": backward-word "/e[1;5C": forward-word "/e[1;5D": backward-word # for rxvt "/e[8~": end-of-line "/eOc": forward-word "/eOd": backward-word # for non RH/Debian xterm, can't hurt for RH/DEbian xterm "/eOH": beginning-of-line "/eOF": end-of-line # for freebsd console "/e[H": beginning-of-line "/e[F": end-of-line $endif 说明: 在配置文件中,/C代表CTRL,/M代表ALT,/e代表ESC,//是反斜杠/,/'是单引号,/"是双引号; /C- control prefix /M- meta prefix /e an escape character // backslash /" literal ", a double quote /’ literal ’, a single quote 如果要查看某一个功能键的字符序列可以通过[CTRL-V]来实现,或者输入cat后回车,进入编辑中,直接按快捷键 配置文件中可能会使用八进制或者十六进制来表示字符。 如果我们针对常用的操作设置成适当的快捷键,也许以前需要巴拉巴拉敲上半天的命令,你一个快捷键就能搞定,这无疑将会大大的提高我们的工作效率! Bash 别名 10 个方便的 Bash 别名 1、 你有几次遇到需要解压 .tar 文件但无法记住所需的确切参数?别名可以帮助你!只需将以下内容添加到 .bash_profile 中,然后使用 untar FileName 解压缩任何 .tar 文件。 alias untar='tar -zxvf ' 2、 下载文件时,如果出现问题想要恢复下载? alias wget='wget -c ' 3、 快速为新的帐户生成随机的 20 个字符的密码。 alias getpass="openssl rand -base64 20" 4、 对下载的文件进行校验和测试。 alias sha='shasum -a 256 ' 5、 普通的 ping 将永远持续下去。通常我们不希望这样,让我们将其限制在五次之内。 alias ping='ping -c 5' 6、 在任何你想要的文件夹中启动一个 Web 服务器。 alias www='python -m SimpleHTTPServer 8000' 7、 想知道你的网络有多快?只需下载 Speedtest-cli 并使用此别名即可。你可以使用 speedtest-cli --list 命令选择离你所在位置更近的服务器。 alias speed='speedtest-cli --server 2406 --simple' 8、 在命令行中快速获取你的外部 IP 地址。 alias ipe='curl ipinfo.io/ip' 9、 在命令行中快速获取你的本地 IP 地址。 alias ipi='ipconfig getifaddr en0' 10、 快速清空屏幕。 alias c='clear' 如你所见,Bash 别名是一种在命令行上简化操作的超级简便方法。想了解更多信息?建议你 Google 搜索 “Bash 别名” 或在 Github 中找找看。 Bash 参数处理 在编写shell程序时经常需要处理命令行参数,本文描述在bash下的命令行处理方式。 ./test.sh -f config.conf -v --prefix=/home -f为选项,它需要一个参数,即config.conf, -v 也是一个选项,但它不需要参数。 手工处理方式 getopts getopt 手工处理方式 在手工处理方式中,首先要知道几个变量,还是以上面的命令行为例: * $0 : ./test.sh,即命令本身,相当于c/c++中的argv[0] * $1 : -f,第一个参数. * $2 : config.conf * $3, $4 ... :类推。 * $# 参数的个数,不包括命令本身,上例中$#为4. * $@ :参数本身的列表,也不包括命令本身,如上例为 -f config.conf -v --prefix=/home * $* :和$@相同,但"$*" 和 "$@"(加引号)并不同,"$*"将所有的参数解释成一个字符串,而"$@"是一个参数数组。 例子: #!/bin/bash for arg in "$*" do echo $arg done for arg in "$@" do echo $arg done 执行./test.sh -f config.conf -n 10 会打印: -f config.conf -n 10 #这是"$*"的输出 -f #以下为$@的输出 config.conf -n 10 所以,手工处理的方式即对这些变量的处理。因为手工处理高度依赖于你在命令行上所传参数的位置,所以一般都只用来处理较简单的参数。 例如: ./test.sh 10 #!/bin/bash if [ x$1 != x ] then #...有参数 else then #...没有参数 fi 为什么要使用 x$1 != x 这种方式来比较呢?想像一下这种方式比较: if [ -n $1 ] #$1不为空 getopts/getopt 处理命令行参数是一个相似而又复杂的事情,为此,c提供了getopt/getopt_long等函数, * ./test.sh -a -b -c : 短选项,各选项不需参数 * ./test.sh -abc : 短选项,和上一种方法的效果一样,只是将所有的选项写在一起。 * ./test.sh -a args -b -c :短选项,其中-a需要参数,而-b -c不需参数。 * ./test.sh --a-long=args --b-long :长选项 先来看getopts,它不支持长选项。 #test.sh #!/bin/bash while getopts "a:bc" arg #选项后面的冒号表示该选项需要参数 do case $arg in a) echo "a's arg:$optarg" #参数存在$optarg中 b) echo "b" c) echo "c" ?) #当有不认识的选项的时候arg为? echo "unkonw argument" exit 1 esac done 现在就可以使用: ./test.sh -a arg -b -c ./test.sh -a arg -bc #!/bin/bash # a small example program for using the new getopt(1) program. # this program will only work with bash(1) # an similar program using the tcsh(1) script language can be found # as parse.tcsh # example input and output (from the bash prompt): # ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long " # option a # option c, no argument # option c, argument `more' # option b, argument ` very long ' # remaining arguments: # --> `par1' # --> `another arg' # --> `wow!*\?' # note that we use `"$@"' to let each command-line parameter expand to a # separate word. the quotes around `$@' are essential! # we need temp as the `eval set --' would nuke the return value of getopt. #-o表示短选项,两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项 #如-carg 而不能是-c arg #--long表示长选项 #"$@"在上面解释过 # -n:出错时的信息 # -- :举一个例子比较好理解: #我们要创建一个名字为 "-f"的目录你会怎么办? # mkdir -f #不成功,因为-f会被mkdir当作选项来解析,这时就可以使用 # mkdir -- -f 这样-f就不会被作为选项。 temp=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \ -n 'example.bash' -- "$@"` if [ $? != 0 ] ; then echo "terminating..." >&2 ; exit 1 ; fi # note the quotes around `$temp': they are essential! #set 会重新排列参数的顺序,也就是改变$1,$2...$n的值,这些值在getopt中重新排列过了 eval set -- "$temp" #经过getopt的处理,下面处理具体选项。 while true ; do case "$1" in -a|--a-long) echo "option a" ; shift ;; -b|--b-long) echo "option b, argument \`$2'" ; shift 2 ;; -c|--c-long) # c has an optional argument. as we are in quoted mode, # an empty parameter will be generated if its optional # argument is not found. case "$2" in "") echo "option c, no argument"; shift 2 ;; *) echo "option c, argument \`$2'" ; shift 2 ;; esac ;; --) shift ; break ;; *) echo "internal error!" ; exit 1 ;; esac done echo "remaining arguments:" for arg do echo '--> '"\`$arg'" ; done 比如使用 ./test -a -b arg arg1 -c -a -b arg -c -- arg1 $1指向-a, $2指向-b,$3指向arg,$4指向-c,$5指向–,而多出的arg1则被放到了最后。 总结 一般小脚本手工处理也就够了,getopts能处理绝大多数的情况,getopt较复杂,功能也更强大。 100个实用的经典 Linux Shell 脚本 编写 hello world 脚本 #!/bin/bash # 编写 hello world 脚本 echo "Hello World!" 通过位置变量创建 Linux 系统账户及密码 #!/bin/bash # 通过位置变量创建 Linux 系统账户及密码 #$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数 useradd "$1" echo "$2" | passwd ‐‐stdin "$1" 备份日志 #!/bin/bash # 每周 5 使用 tar 命令备份/var/log 下的所有日志文件 # vim /root/logbak.sh # 编写备份脚本,备份后的文件名包含日期标签,防止后面的备份将前面的备份数据覆盖 # 注意 date 命令需要使用反引号括起来,反引号在键盘<tab>键上面 tar -czf log-`date +%Y%m%d`.tar.gz /var/log # crontab ‐e #编写计划任务,执行备份脚本 00 03 * * 5 /root/logbak.sh 一键部署 LNMP(RPM 包版本) #!/bin/bash # 一键部署 LNMP(RPM 包版本) # 使用 yum 安装部署 LNMP,需要提前配置好 yum 源,否则该脚本会失败 # 本脚本使用于 centos7.2 或 RHEL7.2 yum ‐y install httpd yum ‐y install mariadb mariadb‐devel mariadb‐server yum ‐y install php php‐mysql systemctl start httpd mariadb systemctl enable httpd mariadb 监控内存和磁盘容量,小于给定值时报警 #!/bin/bash # 实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,发送报警邮件给root管理员 # 提取根分区剩余空间 disk_size=$(df / | awk '/\//{print $4}') # 提取内存剩余空间 mem_size=$(free | awk '/Mem/{print $4}') while : do # 注意内存和磁盘提取的空间大小都是以 Kb 为单位 if [ $disk_size -le 512000 -a $mem_size -le 1024000 ] then mail ‐s "Warning" root <<EOF Insufficient resources,资源不足 EOF fi done 猜数字游戏 #!/bin/bash # 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了, # 猜小了或猜大了,直至用户猜对脚本结束。 # RANDOM 为系统自带的系统变量,值为 0‐32767的随机数 # 使用取余算法将随机数变为 1‐100 的随机数 num=$[RANDOM%100+1] echo "$num" # 使用 read 提示用户猜数字 # 使用 if 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于), # ‐lt(小于),‐le(小于等于) while : do read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai if [ $cai -eq $num ] then echo "恭喜,猜对了" exit elif [ $cai -gt $num ] then echo "Oops,猜大了" else echo "Oops,猜小了" fi done 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用字串对比版本) #!/bin/bash # 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不 # 是,则提示您非管理员(使用字串对比版本) if [ $USER == "root" ] then yum ‐y install vsftpd else echo "您不是管理员,没有权限安装软件" fi 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用 UID 数字对比版本) #!/bin/bash # 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不 # 是,则提示您非管理员(使用 UID 数字对比版本) if [ $UID -eq 0 ];then yum ‐y install vsftpd else echo "您不是管理员,没有权限安装软件" fi 编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默认的 123456 作为默认密码。 #!/bin/bash # 编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户 # 不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默 # 认的 123456 作为默认密码。 read -p "请输入用户名: " user #使用‐z 可以判断一个变量是否为空,如果为空,提示用户必须输入账户名,并退出脚本,退出码为 2 #没有输入用户名脚本退出后,使用$?查看的返回码为 2 if [ -z $user ];then echo "您不需输入账户名" exit 2 fi #使用 stty ‐echo 关闭 shell 的回显功能 #使用 stty echo 打开 shell 的回显功能 stty -echo read -p "请输入密码: " pass stty echo pass=${pass:‐123456} useradd "$user" echo "$pass" | passwd ‐‐stdin "$user" 输入三个数并进行升序排序 #!/bin/bash # 依次提示用户输入 3 个整数,脚本根据数字大小依次排序输出 3 个数字 read -p "请输入一个整数:" num1 read -p "请输入一个整数:" num2 read -p "请输入一个整数:" num3 # 不管谁大谁小,最后都打印 echo "$num1,$num2,$num3" # num1 中永远存最小的值,num2 中永远存中间值,num3 永远存最大值 # 如果输入的不是这样的顺序,则改变数的存储顺序,如:可以将 num1 和 num2 的值对调 tmp=0 # 如果 num1 大于 num2,就把 num1 和和 num2 的值对调,确保 num1 变量中存的是最小值 if [ $num1 -gt $num2 ];then tmp=$num1 num1=$num2 num2=$tmp fi # 如果 num1 大于 num3,就把 num1 和 num3 对调,确保 num1 变量中存的是最小值 if [ $num1 -gt $num3 ];then tmp=$num1 num1=$num3 num3=$tmp fi # 如果 num2 大于 num3,就把 num2 和 num3 对标,确保 num2 变量中存的是小一点的值 if [ $num2 -gt $num3 ];then tmp=$num2 num2=$num3 num3=$tmp fi echo "排序后数据(从小到大)为:$num1,$num2,$num3" 石头、剪刀、布游戏 #!/bin/bash # 编写脚本,实现人机<石头,剪刀,布>游戏 game=(石头 剪刀 布) num=$[RANDOM%3] computer=${game[$num]} # 通过随机数获取计算机的出拳 # 出拳的可能性保存在一个数组中,game[0],game[1],game[2]分别是 3 中不同的可能 echo "请根据下列提示选择您的出拳手势" echo "1.石头" echo "2.剪刀" echo "3.布" read -p "请选择 1‐3:" person case $person in 1) if [ $num -eq 0 ] then echo "平局" elif [ $num -eq 1 ] then echo "你赢" else echo "计算机赢" fi;; 2) if [ $num -eq 0 ] then echo "计算机赢" elif [ $num -eq 1 ] then echo "平局" else echo "你赢" fi;; 3) if [ $num -eq 0 ] then echo "你赢" elif [ $num -eq 1 ] then echo "计算机赢" else echo "平局" fi;; *) echo "必须输入 1‐3 的数字" esac 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(for 版本) #!/bin/bash # 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机 # 状态(for 版本) for i in {1..254} do # 每隔0.3秒ping一次,一共ping2次,并以1毫秒为单位设置ping的超时时间 ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i &>/dev/null if [ $? -eq 0 ];then echo "192.168.4.$i is up" else echo "192.168.4.$i is down" fi done 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(while 版本) #!/bin/bash # 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机 # 状态(while 版本) i=1 while [ $i -le 254 ] do ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i &>/dev/null if [ $? -eq 0 ];then echo "192.168.4.$i is up" else echo "192.168.4.$i is down" fi let i++ done 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(多进程版) #!/bin/bash # 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机 # 状态(多进程版) #定义一个函数,ping 某一台主机,并检测主机的存活状态 myping(){ ping ‐c 2 ‐i 0.3 ‐W 1 $1 &>/dev/null if [ $? -eq 0 ];then echo "$1 is up" else echo "$1 is down" fi } for i in {1..254} do myping 192.168.4.$i & done # 使用&符号,将执行的函数放入后台执行 # 这样做的好处是不需要等待ping第一台主机的回应,就可以继续并发ping第二台主机,依次类推。 编写脚本,显示进度条 #!/bin/bash # 编写脚本,显示进度条 jindu(){ while : do echo -n '#' sleep 0.2 done } jindu & cp -a $1 $2 killall $0 echo "拷贝完成" 进度条,动态时针版本;定义一个显示进度的函数,屏幕快速显示| / ‐ \ #!/bin/bash # 进度条,动态时针版本 # 定义一个显示进度的函数,屏幕快速显示| / ‐ \ rotate_line(){ INTERVAL=0.5 #设置间隔时间 COUNT="0" #设置4个形状的编号,默认编号为 0(不代表任何图像) while : do COUNT=`expr $COUNT + 1` #执行循环,COUNT 每次循环加 1,(分别代表4种不同的形状) case $COUNT in #判断 COUNT 的值,值不一样显示的形状就不一样 "1") #值为 1 显示‐ echo -e '‐'"\b\c" sleep $INTERVAL ;; "2") #值为 2 显示\\,第一个\是转义 echo -e '\\'"\b\c" sleep $INTERVAL ;; "3") #值为 3 显示| echo -e "|\b\c" sleep $INTERVAL ;; "4") #值为 4 显示/ echo -e "/\b\c" sleep $INTERVAL ;; *) #值为其他时,将 COUNT 重置为 0 COUNT="0";; esac done } rotate_line 9*9 乘法表 #!/bin/bash # 9*9 乘法表(编写 shell 脚本,打印 9*9 乘法表) for i in `seq 9` do for j in `seq $i` do echo -n "$j*$i=$[i*j] " done echo done 使用死循环实时显示 eth0 网卡发送的数据包流量 #!/bin/bash # 使用死循环实时显示 eth0 网卡发送的数据包流量 while : do echo '本地网卡 eth0 流量信息如下: ' ifconfig eth0 | grep "RX pack" | awk '{print $5}' ifconfig eth0 | grep "TX pack" | awk '{print $5}' sleep 1 done 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息 #!/bin/bash # 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码 # 本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息 for i in `cat user.txt` do useradd $i echo "123456" | passwd ‐‐stdin $i done 编写批量修改扩展名脚本 #!/bin/bash # 编写批量修改扩展名脚本,如批量将 txt 文件修改为 doc 文件 # 执行脚本时,需要给脚本添加位置参数 # 脚本名 txt doc(可以将 txt 的扩展名修改为 doc) # 脚本名 doc jpg(可以将 doc 的扩展名修改为 jpg) for i in `ls *.$1` do mv $i ${i%.*}.$2 done 使用 expect 工具自动交互密码远程其他主机安装 httpd 软件 #!/bin/bash # 使用 expect 工具自动交互密码远程其他主机安装 httpd 软件 # 删除~/.ssh/known_hosts 后,ssh 远程任何主机都会询问是否确认要连接该主机 rm ‐rf ~/.ssh/known_hosts expect <<EOF spawn ssh 192.168.4.254 expect "yes/no" {send "yes\r"} # 根据自己的实际情况将密码修改为真实的密码字串 expect "password" {send "密码\r"} expect "#" {send "yum ‐y install httpd\r"} expect "#" {send "exit\r"} EOF 一键部署 LNMP(源码安装版本) #!/bin/bash # 一键部署 LNMP(源码安装版本) menu() { clear echo " ##############‐‐‐‐Menu‐‐‐‐##############" echo "# 1. Install Nginx" echo "# 2. Install MySQL" echo "# 3. Install PHP" echo "# 4. Exit Program" echo " ########################################" } choice() { read -p "Please choice a menu[1‐9]:" select } install_nginx() { id nginx &>/dev/null if [ $? -ne 0 ];then useradd -s /sbin/nologin nginx fi if [ -f nginx‐1.8.0.tar.gz ];then tar -xf nginx‐1.8.0.tar.gz cd nginx‐1.8.0 yum -y install gcc pcre‐devel openssl‐devel zlib‐devel make ./configure ‐‐prefix=/usr/local/nginx ‐‐with‐http_ssl_module make make install ln -s /usr/local/nginx/sbin/nginx /usr/sbin/ cd .. else echo "没有 Nginx 源码包" fi } install_mysql() { yum -y install gcc gcc‐c++ cmake ncurses‐devel perl id mysql &>/dev/null if [ $? -ne 0 ];then useradd -s /sbin/nologin mysql fi if [ -f mysql‐5.6.25.tar.gz ];then tar -xf mysql‐5.6.25.tar.gz cd mysql‐5.6.25 cmake . make make install /usr/local/mysql/scripts/mysql_install_db ‐‐user=mysql ‐‐datadir=/usr/local/mysql/data/ ‐‐basedir=/usr/local/mysql/ chown -R root.mysql /usr/local/mysql chown -R mysql /usr/local/mysql/data /bin/cp -f /usr/local/mysql/support‐files/mysql.server /etc/init.d/mysqld chmod +x /etc/init.d/mysqld /bin/cp -f /usr/local/mysql/support‐files/my‐default.cnf /etc/my.cnf echo "/usr/local/mysql/lib/" >> /etc/ld.so.conf ldconfig echo 'PATH=\$PATH:/usr/local/mysql/bin/' >> /etc/profile export PATH else echo "没有 mysql 源码包" exit fi } install_php() { #安装 php 时没有指定启动哪些模块功能,如果的用户可以根据实际情况自行添加额外功能如‐‐with‐gd 等 yum -y install gcc libxml2‐devel if [ -f mhash‐0.9.9.9.tar.gz ];then tar -xf mhash‐0.9.9.9.tar.gz cd mhash‐0.9.9.9 ./configure make make install cd .. if [ ! ‐f /usr/lib/libmhash.so ];then ln -s /usr/local/lib/libmhash.so /usr/lib/ fi ldconfig else echo "没有 mhash 源码包文件" exit fi if [ -f libmcrypt‐2.5.8.tar.gz ];then tar -xf libmcrypt‐2.5.8.tar.gz cd libmcrypt‐2.5.8 ./configure make make install cd .. if [ ! -f /usr/lib/libmcrypt.so ];then ln -s /usr/local/lib/libmcrypt.so /usr/lib/ fi ldconfig else echo "没有 libmcrypt 源码包文件" exit fi if [ -f php‐5.4.24.tar.gz ];then tar -xf php‐5.4.24.tar.gz cd php‐5.4.24 ./configure ‐‐prefix=/usr/local/php5 ‐‐with‐mysql=/usr/local/mysql ‐‐enable‐fpm ‐‐ enable‐mbstring ‐‐with‐mcrypt ‐‐with‐mhash ‐‐with‐config‐file‐path=/usr/local/php5/etc ‐‐with‐ mysqli=/usr/local/mysql/bin/mysql_config make && make install /bin/cp -f php.ini‐production /usr/local/php5/etc/php.ini /bin/cp -f /usr/local/php5/etc/php‐fpm.conf.default /usr/local/php5/etc/php‐fpm.conf cd .. else echo "没有 php 源码包文件" exit fi } while : do menu choice case $select in 1) install_nginx ;; 2) install_mysql ;; 3) install_php ;; 4) exit ;; *) echo Sorry! esac done 编写脚本快速克隆 KVM 虚拟机 #!/bin/bash # 编写脚本快速克隆 KVM 虚拟机 # 本脚本针对 RHEL7.2 或 Centos7.2 # 本脚本需要提前准备一个 qcow2 格式的虚拟机模板, # 名称为/var/lib/libvirt/images /.rh7_template 的虚拟机模板 # 该脚本使用 qemu‐img 命令快速创建快照虚拟机 # 脚本使用 sed 修改模板虚拟机的配置文件,将虚拟机名称、UUID、磁盘文件名、MAC 地址 # exit code: # 65 ‐> user input nothing # 66 ‐> user input is not a number # 67 ‐> user input out of range # 68 ‐> vm disk image exists IMG_DIR=/var/lib/libvirt/images BASEVM=rh7_template read -p "Enter VM number: " VMNUM if [ $VMNUM -le 9 ];then VMNUM=0$VMNUM fi if [ -z "${VMNUM}" ]; then echo "You must input a number." exit 65 elif [[ ${VMNUM} =~ [a‐z] ]; then echo "You must input a number." exit 66 elif [ ${VMNUM} -lt 1 -o ${VMNUM} -gt 99 ]; then echo "Input out of range" exit 67 fi NEWVM=rh7_node${VMNUM} if [ -e $IMG_DIR/${NEWVM}.img ]; then echo "File exists." exit 68 fi echo -en "Creating Virtual Machine disk image......\t" qemu‐img create -f qcow2 ‐b $IMG_DIR/.${BASEVM}.img $IMG_DIR/${NEWVM}.img &> /dev/null echo -e "\e[32;1m[OK]\e[0m" #virsh dumpxml ${BASEVM} > /tmp/myvm.xml cat /var/lib/libvirt/images/.rhel7.xml > /tmp/myvm.xml sed -i "/<name>${BASEVM}/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml sed -i "/uuid/s/<uuid>.*<\/uuid>/<uuid>$(uuidgen)<\/uuid>/" /tmp/myvm.xml sed -i "/${BASEVM}\.img/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml # 修改 MAC 地址,本例使用的是常量,每位使用该脚本的用户需要根据实际情况修改这些值 # 最好这里可以使用便利,这样更适合于批量操作,可以克隆更多虚拟机 sed -i "/mac /s/a1/0c/" /tmp/myvm.xml echo -en "Defining new virtual machine......\t\t" virsh define /tmp/myvm.xml &> /dev/null echo -e "\e[32;1m[OK]\e[0m" 点名器脚本 #!/bin/bash # 编写一个点名器脚本 # 该脚本,需要提前准备一个 user.txt 文件 # 该文件中需要包含所有姓名的信息,一行一个姓名,脚本每次随机显示一个姓名 while : do #统计 user 文件中有多少用户 line=`cat user.txt |wc ‐l` num=$[RANDOM%line+1] sed -n "${num}p" user.txt sleep 0.2 clear done 查看有多少远程的 IP 在连接本机 #!/bin/bash # 查看有多少远程的 IP 在连接本机(不管是通过 ssh 还是 web 还是 ftp 都统计) # 使用 netstat ‐atn 可以查看本机所有连接的状态,‐a 查看所有, # -t仅显示 tcp 连接的信息,‐n 数字格式显示 # Local Address(第四列是本机的 IP 和端口信息) # Foreign Address(第五列是远程主机的 IP 和端口信息) # 使用 awk 命令仅显示第 5 列数据,再显示第 1 列 IP 地址的信息 # sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数 netstat -atn | awk '{print $5}' | awk '{print $1}' | sort -nr | uniq -c 对 100 以内的所有正整数相加求和(1+2+3+4…+100) #!/bin/bash # 对 100 以内的所有正整数相加求和(1+2+3+4...+100) #seq 100 可以快速自动生成 100 个整数 sum=0 for i in `seq 100` do sum=$[sum+i] done echo "总和是:$sum" 统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个 #!/bin/bash # 统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个 # awk 使用‐F 选项指定文件内容的分隔符是/或者: # 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30 # 最后使用 wc ‐l 统计这样的数据有多少行,即多少个 awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"' /var/log/httpd/access_log |wc -l 统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么 #!/bin/bash # 统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么 # awk 使用‐F 选项指定文件内容的分隔符是/或者: # 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30 # 日志文档内容里面,第 1 列是远程主机的 IP 地址,使用 awk 单独显示第 1 列即可 awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"{print $1}' /var/log/httpd/access_log 打印国际象棋棋盘 #!/bin/bash # 打印国际象棋棋盘 # 设置两个变量,i 和 j,一个代表行,一个代表列,国际象棋为 8*8 棋盘 # i=1 是代表准备打印第一行棋盘,第 1 行棋盘有灰色和蓝色间隔输出,总共为 8 列 # i=1,j=1 代表第 1 行的第 1 列;i=2,j=3 代表第 2 行的第 3 列 # 棋盘的规律是 i+j 如果是偶数,就打印蓝色色块,如果是奇数就打印灰色色块 # 使用 echo ‐ne 打印色块,并且打印完成色块后不自动换行,在同一行继续输出其他色块 for i in {1..8} do for j in {1..8} do sum=$[i+j] if [ $[sum%2] -eq 0 ];then echo -ne "\033[46m \033[0m" else echo -ne "\033[47m \033[0m" fi done echo done 统计每个远程 IP 访问了本机 apache 几次? #!/bin/bash # 统计每个远程 IP 访问了本机 apache 几次? awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log 统计当前 Linux 系统中可以登录计算机的账户有多少个 #!/bin/bash # 统计当前 Linux 系统中可以登录计算机的账户有多少个 #方法 1: grep "bash$" /etc/passwd | wc -l #方法 2: awk -f: '/bash$/{x++}end{print x}' /etc/passwd 统计/var/log 有多少个文件,并显示这些文件名 #!/bin/bash # 统计/var/log 有多少个文件,并显示这些文件名 # 使用 ls 递归显示所有,再判断是否为文件,如果是文件则计数器加 1 cd /var/log sum=0 for i in `ls -r *` do if [ -f $i ];then let sum++ echo "文件名:$i" fi done echo "总文件数量为:$sum" 自动为其他脚本添加解释器信息 Docker+K8s+Jenkins 主流技术全解视频资料【干货免费分享】 #!/bin/bash # 自动为其他脚本添加解释器信息#!/bin/bash,如脚本名为 test.sh 则效果如下: # ./test.sh abc.sh 自动为 abc.sh 添加解释器信息 # ./test.sh user.sh 自动为 user.sh 添加解释器信息 # 先使用 grep 判断对象脚本是否已经有解释器信息,如果没有则使用 sed 添加解释器以及描述信息 if ! grep -q "^#!" $1; then sed '1i #!/bin/bash' $1 sed '2i #Description: ' fi # 因为每个脚本的功能不同,作用不同,所以在给对象脚本添加完解释器信息,以及 Description 后还希望 # 继续编辑具体的脚本功能的描述信息,这里直接使用 vim 把对象脚本打开,并且光标跳转到该文件的第 2 行 vim +2 $1 自动化部署 varnish 源码包软件 #!/bin/bash # 自动化部署 varnish 源码包软件 # 本脚本需要提前下载 varnish‐3.0.6.tar.gz 这样一个源码包软件,该脚本即可用自动源码安装部署软件 yum -y install gcc readline‐devel pcre‐devel useradd -s /sbin/nologin varnish tar -xf varnish‐3.0.6.tar.gz cd varnish‐3.0.6 # 使用 configure,make,make install 源码安装软件包 ./configure ‐‐prefix=/usr/local/varnish make && make install # 在源码包目录下,将相应的配置文件拷贝到 Linux 系统文件系统中 # 默认安装完成后,不会自动拷贝或安装配置文件到 Linux 系统,所以需要手动 cp 复制配置文件 # 并使用 uuidgen 生成一个随机密钥的配置文件 cp redhat/varnish.initrc /etc/init.d/varnish cp redhat/varnish.sysconfig /etc/sysconfig/varnish cp redhat/varnish_reload_vcl /usr/bin/ ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/ ln -s /usr/local/varnish/bin/* /usr/bin mkdir /etc/varnish cp /usr/local/varnish/etc/varnish/default.vcl /etc/varnish/ uuidgen > /etc/varnish/secret 编写 nginx 启动脚本 #!/bin/bash # 编写 nginx 启动脚本 # 本脚本编写完成后,放置在/etc/init.d/目录下,就可以被 Linux 系统自动识别到该脚本 # 如果本脚本名为/etc/init.d/nginx,则 service nginx start 就可以启动该服务 # service nginx stop 就可以关闭服务 # service nginx restart 可以重启服务 # service nginx status 可以查看服务状态 program=/usr/local/nginx/sbin/nginx pid=/usr/local/nginx/logs/nginx.pid start(){ if [ -f $pid ];then echo "nginx 服务已经处于开启状态" else $program fi stop(){ if [ -! -f $pid ];then echo "nginx 服务已经关闭" else $program -s stop echo "关闭服务 ok" fi } status(){ if [ -f $pid ];then echo "服务正在运行..." else echo "服务已经关闭" fi } case $1 in start) start;; stop) stop;; restart) stop sleep 1 start;; status) status;; *) echo "你输入的语法格式错误" esac 自动对磁盘分区、格式化、挂载 #!/bin/bash # 自动对磁盘分区、格式化、挂载 # 对虚拟机的 vdb 磁盘进行分区格式化,使用<<将需要的分区指令导入给程序 fdisk # n(新建分区),p(创建主分区),1(分区编号为 1),两个空白行(两个回车,相当于将整个磁盘分一个区) # 注意:1 后面的两个回车(空白行)是必须的! fdisk /dev/vdb << EOF n p 1 wq EOF #格式化刚刚创建好的分区 mkfs.xfs /dev/vdb1 #创建挂载点目录 if [ -e /data ]; then exit fi mkdir /data #自动挂载刚刚创建的分区,并设置开机自动挂载该分区 echo '/dev/vdb1 /data xfs defaults 1 2' >> /etc/fstab mount -a 自动优化 Linux 内核参数 #!/bin/bash # 自动优化 Linux 内核参数 #脚本针对 RHEL7 cat >> /usr/lib/sysctl.d/00‐system.conf <<EOF fs.file‐max=65535 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 5 net.ipv4.tcp_syn_retries = 5 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30 #net.ipv4.tcp_keepalive_time = 120 net.ipv4.ip_local_port_range = 1024 65535 kernel.shmall = 2097152 kernel.shmmax = 2147483648 kernel.shmmni = 4096 kernel.sem = 5010 641280 5010 128 net.core.wmem_default=262144 net.core.wmem_max=262144 net.core.rmem_default=4194304 net.core.rmem_max=4194304 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_keepalive_time = 30 net.ipv4.tcp_window_scaling = 0 net.ipv4.tcp_sack = 0 EOF sysctl –p 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难) #mkdir /data/scripts #vim /data/scripts/nginx_log.sh #!/bin/bash # 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难) logs_path="/usr/local/nginx/logs/" mv ${logs_path}access.log ${logs_path}access_$(date -d "yesterday" +"%Y%m%d").log kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` # chmod +x /data/scripts/nginx_log.sh # crontab ‐e #脚本写完后,将脚本放入计划任务每天执行一次脚本 0 1 * * * /data/scripts/nginx_log.sh 检测 MySQL 数据库连接数量 #!/bin/bash # 检测 MySQL 数据库连接数量 # 本脚本每 2 秒检测一次 MySQL 并发连接数,可以将本脚本设置为开机启动脚本,或在特定时间段执行 # 以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常 # 本案例中的用户名和密码需要根据实际情况修改后方可使用 log_file=/var/log/mysql_count.log user=root passwd=123456 while : do sleep 2 count=`mysqladmin -u "$user" -p "$passwd" status | awk '{print $4}'` echo "`date +%Y‐%m‐%d` 并发连接数为:$count" >> $log_file done 根据 md5 校验码,检测文件是否被修改 #!/bin/bash # 根据 md5 校验码,检测文件是否被修改 # 本示例脚本检测的是/etc 目录下所有的 conf 结尾的文件,根据实际情况,您可以修改为其他目录或文件 # 本脚本在目标数据没有被修改时执行一次,当怀疑数据被人篡改,再执行一次 # 将两次执行的结果做对比,MD5 码发生改变的文件,就是被人篡改的文件 for i in $(ls /etc/*.conf) do md5sum "$i" >> /var/log/conf_file.log done 检测 MySQL 服务是否存活 #!/bin/bash # 检测 MySQL 服务是否存活 # host 为你需要检测的 MySQL 主机的 IP 地址,user 为 MySQL 账户名,passwd 为密码 # 这些信息需要根据实际情况修改后方可使用 host=192.168.51.198 user=root passwd=123456 mysqladmin -h '$host' -u '$user' -p'$passwd' ping &>/dev/null if [ $? -eq 0 ] then echo "MySQL is UP" else echo "MySQL is down" fi 备份 MySQL 的 shell 脚本(mysqldump版本) #!/bin/bash # 备份 MySQL 的 shell 脚本(mysqldump版本) # 定义变量 user(数据库用户名),passwd(数据库密码),date(备份的时间标签) # dbname(需要备份的数据库名称,根据实际需求需要修改该变量的值,默认备份 mysql 数据库) user=root passwd=123456 dbname=mysql date=$(date +%Y%m%d) # 测试备份目录是否存在,不存在则自动创建该目录 [ ! -d /mysqlbackup ] && mkdir /mysqlbackup # 使用 mysqldump 命令备份数据库 mysqldump -u "$user" -p "$passwd" "$dbname" > /mysqlbackup/"$dbname"-${date}.sql 将文件中所有的小写字母转换为大写字母 #!/bin/bash # 将文件中所有的小写字母转换为大写字母 # $1是位置参数,是你需要转换大小写字母的文件名称 # 执行脚本,给定一个文件名作为参数,脚本就会将该文件中所有的小写字母转换为大写字母 tr "[a‐z]" "[A‐Z]" < $1 非交互自动生成 SSH 密钥文件 #!/bin/bash # 非交互自动生成 SSH 密钥文件 # ‐t 指定 SSH 密钥的算法为 RSA 算法;‐N 设置密钥的密码为空;‐f 指定生成的密钥文件>存放在哪里 rm -rf ~/.ssh/{known_hosts,id_rsa*} ssh‐keygen -t RSA -N '' -f ~/.ssh/id_rsa 检查特定的软件包是否已经安装 #!/bin/bash # 检查特定的软件包是否已经安装 if [ $# -eq 0 ];then echo "你需要制定一个软件包名称作为脚本参数" echo "用法:$0 软件包名称 ..." fi # $@提取所有的位置变量的值,相当于$* for package in "$@" do if rpm -q ${package} &>/dev/null ;then echo -e "${package}\033[32m 已经安装\033[0m" else echo -e "${package}\033[34;1m 未安装\033[0m" fi done 监控 HTTP 服务器的状态(测试返回码) #!/bin/bash # 监控 HTTP 服务器的状态(测试返回码) # 设置变量,url为你需要检测的目标网站的网址(IP 或域名),比如百度 url=http://http://183.232.231.172/index.html # 定义函数 check_http: # 使用 curl 命令检查 http 服务器的状态 # ‐m 设置curl不管访问成功或失败,最大消耗的时间为 5 秒,5 秒连接服务为相应则视为无法连接 # ‐s 设置静默连接,不显示连接时的连接速度、时间消耗等信息 # ‐o 将 curl 下载的页面内容导出到/dev/null(默认会在屏幕显示页面内容) # ‐w 设置curl命令需要显示的内容%{http_code},指定curl返回服务器的状态码 check_http() { status_code=$(curl -m 5 -s -o /dev/null -w %{http_code} $url) } while : do check_http date=$(date +%Y%m%d‐%H:%M:%S) # 生成报警邮件的内容 echo "当前时间为:$date $url 服务器异常,状态码为${status_code}. 请尽快排查异常." > /tmp/http$$.pid # 指定测试服务器状态的函数,并根据返回码决定是发送邮件报警还是将正常信息写入日志 if [ $status_code -ne 200 ];then mail -s Warning root < /tmp/http$$.pid else echo "$url 连接正常" >> /var/log/http.log fi sleep 5 done 自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7) #!/bin/bash # 自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7) # # 设置变量定义需要添加到防火墙规则的服务和端口号 # 使用 firewall‐cmd ‐‐get‐services 可以查看 firewall 支持哪些服务 service="nfs http ssh" port="80 22 8080" # 循环将每个服务添加到防火墙规则中 for i in $service do echo "Adding $i service to firewall" firewall‐cmd --add-service=${i} done #循环将每个端口添加到防火墙规则中 for i in $port do echo "Adding $i Port to firewall" firewall‐cmd --add-port=${i}/tcp done #将以上设置的临时防火墙规则,转换为永久有效的规则(确保重启后有效) firewall‐cmd --runtime-to-permanent 使用脚本自动创建逻辑卷 #!/bin/bash # 使用脚本自动创建逻辑卷 # 清屏,显示警告信息,创建将磁盘转换为逻辑卷会删除数据 clear echo -e "\033[32m !!!!!!警告(Warning)!!!!!!\033[0m" echo echo "+++++++++++++++++++++++++++++++++++++++++++++++++" echo "脚本会将整个磁盘转换为 PV,并删除磁盘上所有数据!!!" echo "This Script will destroy all data on the Disk" echo "+++++++++++++++++++++++++++++++++++++++++++++++++" echo read -p "请问是否继续 y/n?:" sure # 测试用户输入的是否为 y,如果不是则退出脚本 [ $sure != y ] && exit # 提示用户输入相关参数(磁盘、卷组名称等数据),并测试用户是否输入了这些值,如果没有输入,则脚本退出 read -p "请输入磁盘名称,如/dev/vdb:" disk [ -z $disk ] && echo "没有输入磁盘名称" && exit read -p "请输入卷组名称:" vg_name [ -z $vg_name ] && echo "没有输入卷组名称" && exit read -p "请输入逻辑卷名称:" lv_name [ -z $lv_name ] && echo "没有输入逻辑卷名称" && exit read -p "请输入逻辑卷大小:" lv_size [ -z $lv_size ] && echo "没有输入逻辑卷大小" && exit # 使用命令创建逻辑卷 pvcreate $disk vgcreate $vg_name $disk lvcreate -L ${lv_size}M -n ${lv_name} ${vg_name} 显示 CPU 厂商信息 #!/bin/bash # 显示 CPU 厂商信息 awk '/vendor_id/{print $3}' /proc/cpuinfo | uniq 删除某个目录下大小为 0 的文件 #!/bin/bash # 删除某个目录下大小为 0 的文件 #/var/www/html 为测试目录,脚本会清空该目录下所有 0 字节的文件 dir="/var/www/html" find $dir -type f -size 0 -exec rm -rf {} \; 查找 Linux 系统中的僵尸进程 #!/bin/bash # 查找 Linux 系统中的僵尸进程 # awk 判断 ps 命令输出的第 8 列为 Z 是,显示该进程的 PID 和进程命令 ps aux | awk '{if($8 == "Z"){print $2,$11}}' 提示用户输入年份后判断该年是否为闰年 #!/bin/bash # 提示用户输入年份后判断该年是否为闰年 # 能被4整除并且并不能被100整除的年份是闰年 # 能被400整除的年份也是闰年 read -p "请输入一个年份:" year if [ "$year" = "" ];then echo "没有输入年份" exit fi #使用正则测试变量 year 中是否包含大小写字母 if [[ "$year" =~ [a‐Z] ]];then echo "你输入的不是数字" exit fi # 判断是否为闰年 if [ $[year % 4] -eq 0 ] && [ $[year % 100] -ne 0 ];then echo "$year年是闰年" elif [ $[year % 400] -eq 0 ];then echo "$year年是闰年" else echo "$year年不是闰年" fi 生成随机密码(urandom 版本) #!/bin/bash # 生成随机密码(urandom 版本) # /dev/urandom 文件是 Linux 内置的随机设备文件 # cat /dev/urandom 可以看看里面的内容,ctrl+c 退出查看 # 查看该文件内容后,发现内容有些太随机,包括很多特殊符号,我们需要的密码不希望使用这些符号 # tr ‐dc '_A‐Za‐z0‐9' < /dev/urandom # 该命令可以将随机文件中其他的字符删除,仅保留大小写字母,数字,下划线,但是内容还是太多 # 我们可以继续将优化好的内容通过管道传递给 head 命令,在大量数据中仅显示头 10 个字节 # 注意 A 前面有个下划线 tr -dc '_A‐Za‐z0‐9' </dev/urandom | head -c 10 生成随机密码(字串截取版本) #!/bin/bash # 生成随机密码(字串截取版本) # 设置变量 key,存储密码的所有可能性(密码库),如果还需要其他字符请自行添加其他密码字符 # 使用$#统计密码库的长度 key="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" num=${#key} # 设置初始密码为空 pass='' # 循环 8 次,生成随机密码 # 每次都是随机数对密码库的长度取余,确保提取的密码字符不超过密码库的长度 # 每次循环提取一位随机密码,并将该随机密码追加到 pass 变量的最后 for i in {1..8} do index=$[RANDOM%num] pass=$pass${key:$index:1} done echo $pass 生成随机密码(UUID 版本,16 进制密码) #!/bin/bash # 生成随机密码(UUID 版本,16 进制密码) uuidgen 生成随机密码(进程 ID 版本,数字密码) #!/bin/bash # 生成随机密码(进程 ID 版本,数字密码) echo $$ 测试用户名与密码是否正确 #!/bin/bash # 测试用户名与密码是否正确 #用户名为 tom 并且密码为 123456,则提示登录成功,否则提示登录失败 read -p "请输入用户名:" user read -p "请输入密码:" pass if [ "$user" == 'tom' -a "$pass" == '123456' ];then echo "Login successful" else echo "Login Failed" fi 循环测试用户名与密码是否正确 #!/bin/bash # 循环测试用户名与密码是否正确 # 循环测试用户的账户名和密码,最大测试 3 次,输入正确提示登录成功,否则提示登录失败 # 用户名为 tom 并且密码为 123456 for i in {1..3} do read -p "请输入用户名:" user read -p "请输入密码:" pass if [ "$user" == 'tom' -a "$pass" == '123456' ];then echo "Login successful" exit fi done echo "Login Failed" Shell 脚本的 fork 炸弹 #!/bin/bash # Shell 脚本的 fork 炸弹 # 快速消耗计算机资源,致使计算机死机 # 定义函数名为.(点), 函数中递归调用自己并放入后台执行 .() { .|.& };. 批量下载有序文件(pdf、图片、视频等等) #!/bin/bash # 批量下载有序文件(pdf、图片、视频等等) # 本脚本准备有序的网络资料进行批量下载操作(如 01.jpg,02.jpg,03.jpg) # 设置资源来源的域名连接 url="http://www.baidu.com/" echo "开始下载..." sleep 2 type=jpg for i in `seq 100` echo "正在下载$i.$type" curl $url/$i.$type -o /tmp/${i}$type sleep 1 done #curl 使用-o 选项指定下载文件另存到哪里. 显示当前计算机中所有账户的用户名称 #!/bin/bash # 显示当前计算机中所有账户的用户名称 # 下面使用3种不同的方式列出计算机中所有账户的用户名 # 指定以:为分隔符,打印/etc/passwd 文件的第 1 列 awk -F: '{print $1}' /etc/passwd # 指定以:为分隔符,打印/etc/passwd 文件的第 1 列 cut -d: -f1 /etc/passwd # 使用 sed 的替换功能,将/etc/passwd 文件中:后面的所有内容替换为空(仅显示用户名) sed 's/:.*//' /etc/passwd 制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录 #!/bin/bash # 制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录 [ ! -d /data ] && mkdir /data [ -z $1 ] && exit if [ -d $1 ];then tar -czf /data/$1.-`date +%Y%m%d`.tar.gz $1 else echo "该目录不存在" fi 显示进度条(回旋镖版) #!/bin/bash # 显示进度条(回旋镖版) while : do clear for i in {1..20} do echo ‐e "\033[3;${i}H*" sleep 0.1 done clear for i in {20..1} do echo ‐e "\033[3;${i}H*" sleep 0.1 done clear done 安装 LAMP 环境(yum 版本) #!/bin/bash # 安装 LAMP 环境(yum 版本) # 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql) yum makecache &>/dev/null num=$(yum repolist | awk '/repolist/{print $2}' | sed 's/,//') if [ $num -lt 0 ];then yum -y install httpd yum -y install mariadb mariadb-server mariadb-devel yum -y install php php-mysql else echo "未配置 yum 源..." fi 循环关闭局域网中所有主机 #!/bin/bash # 循环关闭局域网中所有主机 # 假设本机为 192.168.4.100,编写脚本关闭除自己外的其他所有主机 # 脚本执行,需要提前给所有其他主机传递 ssh 密钥,满足无密码连接 for i in {1..254} do [ $i -eq 100 ] && continue echo "正在关闭 192.168.4.$i..." ssh 192.168.4.$i poweroff done 获取本机 MAC 地址 #!/bin/bash # 获取本机 MAC 地址 ip a s | awk 'BEGIN{print " 本 机 MAC 地 址 信 息 如 下 :"}/^[0‐9]/{print $2;getline;if($0~/link\/ether/){print $2}}' | grep -v lo: # awk 读取 ip 命令的输出,输出结果中如果有以数字开始的行,先显示该行的地 2 列(网卡名称), # 接着使用 getline 再读取它的下一行数据,判断是否包含 link/ether # 如果保护该关键词,就显示该行的第 2 列(MAC 地址) # lo 回环设备没有 MAC,因此将其屏蔽,不显示 自动配置 rsynd 服务器的配置文件 rsyncd.conf #!/bin/bash # 自动配置 rsynd 服务器的配置文件 rsyncd.conf # See rsyncd.conf man page for more options. [ ! -d /home/ftp ] && mkdir /home/ftp echo 'uid = nobody gid = nobody use chroot = yes max connections = 4 pid file = /var/run/rsyncd.pid exclude = lost+found/ transfer logging = yes timeout = 900 ignore nonreadable = yes dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 [ftp] path = /home/ftp comment = share' > /etc/rsyncd.conf 修改 Linux 系统的最大打开文件数量 #!/bin/bash # 修改 Linux 系统的最大打开文件数量 # 往/etc/security/limits.conf 文件的末尾追加两行配置参数,修改最大打开文件数量为 65536 cat >> /etc/security/limits.conf <<EOF * soft nofile 65536 * hard nofile 65536 EOF 设置 Python 支持自动命令补齐功能 #!/bin/bash # 设置 Python 支持自动命令补齐功能 # Summary:Enable tab complete for python # Description: Needs import readline and rlcompleter module # import readline # import rlcompleter # help(rlcompleter) display detail: readline.parse_and_bind('tab: complete') # man python display detail: PYTHONSTARTUP variable if [ ! -f /usr/bin/tab.py ];then cat >> /usr/bin/tab.py <<EOF import readline import rlcompleter readline.parse_and_bind('tab: complete') EOF fi sed -i '$a export PYTHONSTARTUP=/usr/bin/tab.py' /etc/profile source /etc/profile 自动修改计划任务配置文件 Docker+K8s+Jenkins 主流技术全解视频资料【干货免费分享】 #!/bin/bash # 自动修改计划任务配置文件 read -p "请输入分钟信息(00‐59):" min read -p "请输入小时信息(00‐24):" hour read -p "请输入日期信息(01‐31):" date read -p "请输入月份信息(01‐12):" month read -p "请输入星期信息(00‐06):" weak read -p "请输入计划任务需要执行的命令或脚本:" program echo "$min $hour $date $month $weak $program" >> /etc/crontab 使用脚本循环创建三位数字的文本文件(111-999 的文件) #!/bin/bash # 使用脚本循环创建三位数字的文本文件(111-999 的文件) for i in {1..9} do for j in {1..9} do for k in {1..9} do touch /tmp/$i$j$k.txt done done done 找出/etc/passwd 中能登录的用户,并将对应在/etc/shadow 中第二列密码提出处理 #!/bin/bash # 找出/etc/passwd 中能登录的用户,并将对应在/etc/shadow 中第二列密码提出处理 user=$(awk -F: '/bash$/{print $1}' /etc/passwd) for i in $user do awk -F: -v x=$i '$1==x{print $1,$2}' /etc/shadow done 统计/etc/passwd 中 root 出现的次数 #!/bin/bash # 统计/etc/passwd 中 root 出现的次数 #每读取一行文件内容,即从第 1 列循环到最后 1 列,依次判断是否包含 root 关键词,如果包含则 x++ awk -F: '{i=1;while(i<=NF){if($i~/root/){x++};i++}} END{print "root 出现次数为"x}' /etc/passwd 统计 Linux 进程相关数量信息 #!/bin/bash # 统计 Linux 进程相关数量信息 running=0 sleeping=0 stoped=0 zombie=0 # 在 proc 目录下所有以数字开始的都是当前计算机正在运行的进程的进程 PID # 每个 PID 编号的目录下记录有该进程相关的信息 for pid in /proc/[1‐9]* do procs=$[procs+1] stat=$(awk '{print $3}' $pid/stat) # 每个 pid 目录下都有一个 stat 文件,该文件的第 3 列是该进程的状态信息 case $stat in R) running=$[running+1] ;; T) stoped=$[stoped+1] ;; S) sleeping=$[sleeping+1] ;; Z) zombie=$[zombie+1] ;; esac done echo "进程统计信息如下" echo "总进程数量为:$procs" echo "Running 进程数为:$running" echo "Stoped 进程数为:$stoped" echo "Sleeping 进程数为:$sleeping" echo "Zombie 进程数为:$zombie" 从键盘读取一个论坛积分,判断论坛用户等级 #!/bin/bash # 从键盘读取一个论坛积分,判断论坛用户等级 #等级分类如下: # 大于等于 90 神功绝世 # 大于等于 80,小于 90 登峰造极 # 大于等于 70,小于 80 炉火纯青 # 大于等于 60,小于 70 略有小成 # 小于 60 初学乍练 read -p "请输入积分(0‐100):" JF if [ $JF -ge 90 ] ; then echo "$JF 分,神功绝世" elif [ $JF -ge 80 ] ; then echo "$JF 分,登峰造极" elif [ $JF -ge 70 ] ; then echo "$JF 分,炉火纯青" elif [ $JF -lt 60 ] ; then echo "$JF 分,略有小成" else echo "$JF 分,初学乍练" fi 判断用户输入的数据类型(字母、数字或其他) #!/bin/bash # 判断用户输入的数据类型(字母、数字或其他) read -p "请输入一个字符:" KEY case "$KEY" in [a‐z]|[A‐Z]) echo "字母" ;; [0‐9]) echo "数字" ;; *) echo "空格、功能键或其他控制字符" esac 显示进度条(数字版) #!/bin/bash # 显示进度条(数字版) # echo 使用‐e 选项后,在打印参数中可以指定 H,设置需要打印内容的 x,y 轴的定位坐标 # 设置需要打印内容在第几行,第几列 for i in {1..100} do echo -e "\033[6;8H[" echo -e "\033[6;9H$i%" echo -e "\033[6;13H]" sleep 0.1 done 打印斐波那契数列 #!/bin/bash # 打印斐波那契数列(该数列的特点是后一个数字,永远都是前 2 个数字之和) # 斐波那契数列后一个数字永远是前 2 个数字之和 # 如:0 1 1 2 3 5 8 13 ... ... list=(0 1) for i in `seq 2 11` do list[$i]=`expr ${list[‐1]} + ${list[‐2]}` done echo ${list[@]} 判断用户输入的是 Yes 或 NO #!/bin/bash # 判断用户输入的是 Yes 或 NO read -p "Are you sure?[y/n]:" sure case $sure in y|Y|Yes|YES) echo "you enter $a" ;; n|N|NO|no) echo "you enter $a" ;; *) echo "error";; esac 显示本机 Linux 系统上所有开放的端口列表 #!/bin/bash # 显示本机 Linux 系统上所有开放的端口列表 # 从端口列表中观测有没有没用的端口,有的话可以将该端口对应的服务关闭,防止意外的攻击可能性 ss -nutlp | awk '{print $1,$5}' | awk -F"[: ]" '{print "协议:"$1,"端口号:"$NF}' | grep "[0‐9]" | uniq 将 Linux 系统中 UID 大于等于 1000 的普通用户都删除 #!/bin/bash # 将 Linux 系统中 UID 大于等于 1000 的普通用户都删除 # 先用 awk 提取所有 uid 大于等于 1000 的普通用户名称 # 再使用 for 循环逐个将每个用户删除即可 user=$(awk -F: '$3>=1000{print $1}' /etc/passwd) for i in $user do userdel -r $i done 使用脚本开启关闭虚拟机 #!/bin/bash # 使用脚本开启关闭虚拟机 # 脚本通过调用virsh命令实现对虚拟机的管理,如果没有该命令,需要安装 libvirt‐client 软件包 # $1是脚本的第1个参数,$2是脚本的第2个参数 # 第1个参数是你希望对虚拟机进行的操作指令,第2个参数是虚拟机名称 case $1 in list) virsh list --all ;; start) virsh start $2 ;; stop) virsh destroy $2 ;; enable) virsh autostart $2 ;; disable) virsh autostart --disable $2 ;; *) echo "Usage:$0 list" echo "Usage:$0 [start|stop|enable|disable] VM_name" cat << EOF #list 显示虚拟机列表 #start 启动虚拟机 #stop 关闭虚拟机 #enable 设置虚拟机为开机自启 #disable 关闭虚拟机开机自启功能 EOF ;; esac 调整虚拟机内存参数的 shell 脚本 #!/bin/bash # 调整虚拟机内存参数的 shell 脚本 # 脚本通过调用 virsh 命令实现对虚拟机的管理,如果没有该命令,需要安装 libvirt‐client 软件包 cat << EOF 1.调整虚拟机最大内存数值 2.调整实际分配给虚拟机的内存数值 EOF read -p "请选择[1‐2]:" select case $select in 1) read -p "请输入虚拟机名称" name read -p "请输入最大内存数值(单位:k):" size virsh setmaxmem $name --size $size --config ;; 2) read -p "请输入虚拟机名称" name read -p "请输入实际分配内存数值(单位:k):" size virsh setmem $name $size ;; *) echo "Error" ;; esac 查看 KVM 虚拟机中的网卡信息(不需要进入启动或进入虚拟机) #!/bin/bash # 查看 KVM 虚拟机中的网卡信息(不需要进入启动或进入虚拟机) # 该脚本使用 guestmount 工具,可以将虚拟机的磁盘系统挂载到真实机文件系统中 # Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具 # 虚拟机可以启动或者不启动都不影响该脚本的使用 # 将虚拟机磁盘文件挂载到文件系统后,就可以直接读取磁盘文件中的网卡配置文件中的数据 clear mountpoint="/media/virtimage" [ ! -d $mountpoint ] && mkdir $mountpoint read -p "输入虚拟机名称:" name echo "请稍后..." # 如果有设备挂载到该挂载点,则先 umount 卸载 if mount | grep -q "$mountpoint" ;then umount $mountpoint fi # 只读的方式,将虚拟机的磁盘文件挂载到特定的目录下,这里是/media/virtimage 目录 guestmount -r -d $name -i $mountpoint echo echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" echo -e "\033[32m$name 虚拟机中网卡列表如下:\033[0m" dev=$(ls /media/virtimage/etc/sysconfig/network‐scripts/ifcfg-* |awk -F"[/‐]" '{print $9}') echo $dev echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" echo echo echo "+++++++++++++++++++++++++++++++++++++++++++" echo -e "\033[32m 网卡 IP 地址信息如下:\033[0m" for i in $dev do echo -n "$i:" grep -q "IPADDR" /media/virtimage/etc/sysconfig/network‐scripts/ifcfg-$i || echo "未配置 IP地址" awk -F= '/IPADDR/{print $2}' /media/virtimage/etc/sysconfig/network-scripts/ifcfg-$i done echo "+++++++++++++++++++++++++++++++++++++++++++" 不登陆虚拟机,修改虚拟机网卡 IP 地址 #!/bin/bash # 不登陆虚拟机,修改虚拟机网卡 IP 地址 # 该脚本使用 guestmount 工具,Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具 # 脚本在不登陆虚拟机的情况下,修改虚拟机的 IP 地址信息 # 在某些环境下,虚拟机没有 IP 或 IP 地址与真实主机不在一个网段 # 真实主机在没有 virt‐manger 图形的情况下,远程连接虚拟机很麻烦 # 该脚本可以解决类似的问题 read -p "请输入虚拟机名称:" name if virsh domstate $name | grep -q running ;then echo "修改虚拟机网卡数据,需要关闭虚拟机" virsh destroy $name fi mountpoint="/media/virtimage" [ ! -d $mountpoint ] && mkdir $mountpoint echo "请稍后..." if mount | grep -q "$mountpoint" ;then umount $mountpoint fi guestmount -d $name -i $mountpoint read -p "请输入需要修改的网卡名称:" dev read -p "请输入 IP 地址:" addr # 判断原本网卡配置文件中是否有 IP 地址,有就修改该 IP,没有就添加一个新的 IP 地址 if grep -q "IPADDR" $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev ;then sed -i "/IPADDR/s/=.*/=$addr/" $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev else echo "IPADDR=$addr" >> $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev fi # 如果网卡配置文件中有客户配置的 IP 地址,则脚本提示修改 IP 完成 awk -F= -v x=$addr '$2==x{print "完成..."}' $mountpoint/etc/sysconfig/network‐scripts/ifcfg-$dev 破解虚拟机密码,无密码登陆虚拟机系统 #!/bin/bash # 破解虚拟机密码,无密码登陆虚拟机系统 # 该脚本使用 guestmount 工具,Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具 read -p "请输入虚拟机名称:" name if virsh domstate $name | grep -q running ;then echo "破解,需要关闭虚拟机" virsh destroy $name fi mountpoint="/media/virtimage" [ ! -d $mountpoint ] && mkdir $mountpoint echo "请稍后..." if mount | grep -q "$mountpoint" ;then umount $mountpoint fi guestmount -d $name -i $mountpoint # 将 passwd 中密码占位符号 x 删除,该账户即可实现无密码登陆系统 sed -i "/^root/s/x//" $mountpoint/etc/passwd Shell 脚本对信号的处理,执行脚本后,按键盘 Ctrl+C 无法终止的脚本 #!/bin/bash # Shell 脚本对信号的处理,执行脚本后,按键盘 Ctrl+C 无法终止的脚本 # 使用 trap 命令可以拦截用户通过键盘或 kill 命令发送过来的信号 # 使用 kill ‐l 可以查看 Linux 系统中所有的信号列表,其中 2 代表 Ctrl+C # trap 当发现有用户 ctrl+C 希望终端脚本时,就执行 echo "暂停 10s";sleep 10 这两条命令 # 另外用户使用命令:[ kill ‐2 脚本的 PID ] 也可以中断脚本和 Ctrl+C 一样的效果,都会被 trap 拦截 trap 'echo "暂停 10s";sleep 10' 2 while : do echo "go go go" done 一键部署 memcached #!/bin/bash # 一键部署 memcached # 脚本用源码来安装 memcached 服务器 # 注意:如果软件的下载链接过期了,请更新 memcached 的下载链接 wget http://www.memcached.org/files/memcached-1.5.1.tar.gz yum -y install gcc tar -xf memcached‐1.5.1.tar.gz cd memcached‐1.5.1 ./configure make make install 一键配置 VNC 远程桌面服务器(无密码版本) #!/bin/bash # 一键配置 VNC 远程桌面服务器(无密码版本) # 脚本配置的 VNC 服务器,客户端无需密码即可连接 # 客户端仅有查看远程桌面的权限,没有鼠标和键盘的操作权限 rpm --quiet -q tigervnc‐server if [ $? -ne 0 ];then yum -y tigervnc‐server fi x0vncserver AcceptKeyEvents=0 AlwaysShared=1 \ AcceptPointerEvents=0 SecurityTypes=None rfbport=5908 关闭 SELinux #!/bin/bash # 关闭 SELinux sed -i '/^SELINUX/s/=.*/=disabled/' /etc/selinux/config setenforce 0 查看所有虚拟机磁盘使用量以及CPU使用量信息 #!/bin/bash # 查看所有虚拟机磁盘使用量以及CPU使用量信息 virt‐df read -n1 "按任意键继续" key virt‐top 使用 shell 脚本打印图形 #!/bin/bash # 使用 shell 脚本打印如下图形: # 打印第一组图片 # for(())为类 C 语言的语法格式,也可以使用 for i in;do ;done 的格式替换 # for((i=1;i<=9;i++))循环会执行 9 次,i 从 1 开始到 9,每循环一次 i 自加 1 clear for (( i=1; i<=9; i++ )) do for (( j=1; j<=i; j++ )) do echo -n "$i" done echo "" done read -n1 "按任意键继续" key #打印第二组图片 clear for (( i=1; i<=5; i++ )) do for (( j=1; j<=i; j++ )) do echo -n " |" done echo "_ " done read -n1 "按任意键继续" key #打印第三组图片 clear for (( i=1; i<=5; i++ )) do for (( j=1; j<=i; j++ )) do echo -n " *" done echo "" done for (( i=5; i>=1; i‐‐ )) do for (( j=1; j<=i; j++ )) do echo -n " *" done echo "" done 根据计算机当前时间,返回问候语,可以将该脚本设置为开机启动 #!/bin/bash # 根据计算机当前时间,返回问候语,可以将该脚本设置为开机启动 # 00‐12 点为早晨,12‐18 点为下午,18‐24 点为晚上 # 使用 date 命令获取时间后,if 判断时间的区间,确定问候语内容 tm=$(date +%H) if [ $tm -le 12 ];then msg="Good Morning $USER" elif [ $tm -gt 12 -a $tm -le 18 ];then msg="Good Afternoon $USER" else msg="Good Night $USER" fi echo "当前时间是:$(date +"%Y‐%m‐%d %H:%M:%S")" echo -e "\033[34m$msg\033[0m" 读取用户输入的账户名称,将账户名写入到数组保存 #!/bin/bash # 读取用户输入的账户名称,将账户名写入到数组保存 # 定义数组名称为 name,数组的下标为 i,小标从 0 开始,每输入一个账户名,下标加 1,继续存下一个账户 # 最后,输入 over,脚本输出总结性信息后脚本退出 i=0 while : do read -p "请输入账户名,输入 over 结束:" key if [ $key == "over" ];then break else name[$i]=$key let i++ fi done echo "总账户名数量:${#name[*]}" echo "${name[@]}" 判断文件或目录是否存在 #!/bin/bash # 判断文件或目录是否存在 if [ $# -eq 0 ] ;then echo "未输入任何参数,请输入参数" echo "用法:$0 [文件名|目录名]" fi if [ -f $1 ];then echo "该文件,存在" ls -l $1 else echo "没有该文件" fi if [ -d $1 ];then echo "该目录,存在" ls -ld $2 else echo "没有该目录" fi 打印各种格式的时间 #!/bin/bash # 打印各种时间格式 echo "显示星期简称(如:Sun)" date +%a echo "显示星期全称(如:Sunday)" date +%A echo "显示月份简称(如:Jan)" date +%b echo "显示月份全称(如:January)" date +%B echo "显示数字月份(如:12)" date +%m echo "显示数字日期(如:01 号)" date +%d echo "显示数字年(如:01 号)" date +%Y echo "显示年‐月‐日" date +%F echo "显示小时(24 小时制)" date +%H echo "显示分钟(00..59)" date +%M echo "显示秒" date +%S echo "显示纳秒" date +%N echo "组合显示" date +"%Y%m%d %H:%M:%S" 使用 egrep 过滤 MAC 地址 #!/bin/bash # 使用 egrep 过滤 MAC 地址 # MAC 地址由 16 进制组成,如 AA:BB:CC:DD:EE:FF # [0‐9a‐fA‐F]{2}表示一段十六进制数值,{5}表示连续出现5组前置:的十六进制 egrep "[0‐9a‐fA‐F]{2}(:[0‐9a‐fA‐F]{2}){5}" $1 统计双色球各个数字的中奖概率 #!/bin/bash # 统计双色球各个数字的中奖概率 # 往期双色球中奖号码如下: # 01 04 11 28 31 32 16 # 04 07 08 18 23 24 02 # 02 05 06 16 28 29 04 # 04 19 22 27 30 33 01 # 05 10 18 19 30 31 03 # 02 06 11 12 19 29 06 # 统计篮球和红球数据出现的概率次数(篮球不分顺序,统计所有篮球混合在一起的概率) awk '{print $1"\n"$2"\n"$3"\n"$4"\n"$5"\n"$6}' 1.txt | sort | uniq -c | sort awk '{print $7}' 1.txt | sort | uniq -c | sort 生成签名私钥和证书 #!/bin/bash # 生成签名私钥和证书 read -p "请输入存放证书的目录:" dir if [ ! -d $dir ];then echo "该目录不存在" exit fi read -p "请输入密钥名称:" name # 使用 openssl 生成私钥 openssl genrsa -out ${dir}/${name}.key # 使用 openssl 生成证书 #subj 选项可以在生成证书时,非交互自动填写 Common Name 信息 openssl req -new -x509 -key ${dir}/${name}.key -subj "/CN=common" -out ${dir}/${name}.crt 使用 awk 编写的 wc 程序 #!/bin/bash # 使用 awk 编写的 wc 程序 # 自定义变量 chars 变量存储字符个数,自定义变量 words 变量存储单词个数 # awk 内置变量 NR 存储行数 # length()为 awk 内置函数,用来统计每行的字符数量,因为每行都会有一个隐藏的$,所以每次统计后都+1 # wc 程序会把文件结尾符$也统计在内,可以使用 cat ‐A 文件名,查看该隐藏字符 awk '{chars+=length($0)+1;words+=NF} END{print NR,words,chars}' $1 参考&致谢 bash shell命令行选项与修传入参数处理_linux shell 100个实用的经典 Linux Shell 脚本案例参考

2023/12/21
articleCard.readMore

从零开始玩PT-入门到精通

前言 PT 是个小圈子,重分享,有规矩的地方。如果你不愿意与别人共享你的资源与带宽且对所谓的规则不满(实在不合理可以 PM 管理协商),那么请出门左拐,X 宝付费拷资源和充值迅雷是你的好选择。 另外 PT 是非营利的,捐赠被用于租用服务器和购买原盘、购买压制机器等。您的捐赠是为了网站的更好发展。所以捐赠与购买视频网站 VIP 是有本质上的区别的。 玩 PT 不是被 PT 玩,不要因为玩 PT 花费太多时间,而影响到你的工作和生活。 有问题尽量自己先百度或查看站内规则和常见问题,不要直接问,提问也要说明你遇到了什么样的问题,之前做了什么操作等。这样别人才好帮助你更好的解决问题,节省大家的时间。一定不要发生。别人说了半天,你来一句,恩我明白了,那你能帮帮我吗? PT是什么? 先说说 BT 首先介绍一下BT,BT是用在对等网络中文件分享的网络协议程序。和点对点(point-to-point)的协议程序不同, 最大特点就是下载的人越多,下载速度就越快,因为在你下载的同时,会把下载到的部分文件上传给其他人,其他人下载了也会把下载的部分分享出来。因为 BT 有太多下了就跑,不愿意做分享的人,所以催生了 PT(Private Tracker)的产生。 PT 和 BT 有什么不同 PT就是一个打造我为人人,人人为我的下载协议,最早出现的是BT,我们经常下载的种子就是这种,有人会说那我平时下电影下自愿者直接用迅雷或百度网盘下不就行了嘛,为什么要用PT呢?首先,总所周知迅雷和百度网盘的下载速度是多么的无语,他们的程序在后台其实也是间接的把本机的资源分享给了别人,其实原理上都是一样的,只不过他们从中限速做会员割韭菜。此外,你不一定能找到相关资源的BT种子,正所谓无规矩不成方圆,如果有一些规则加以限制,这个圈子才能越来越好,形成良好的闭环。 PT 想对于 BT 有两个明显的改进:一是私密的小范围下载,二是进行流量统计,其根据上传量决定你的权限。 因此提供 PT 服务的网站是不公开的,采用邀请制或是不定时开放注册。用户注册后会 得到一个 passkey,服务器由 passkey 识别每个用户,用户从某 PT 站下载种子后,该种子即 带有用户的 passkey。因此 PT 的种子是不可外流到其他地方 所以在出现问题询问时,一定要隐藏好你的 passkey 值。例如:截 图是用马赛克遮挡 passkey 值,因为如果你的 key 泄露某些别用用心的人就可以使用你的 key进行下载,这比你账号密码泄露更加可怕。 由于有 passkey,用户上传及下载即可统计,在大多数的 PT 站会以上下载比例(分享率) 规定用户需上传多少后才可下载多少,分享率过低者会被系统取消使用 PT 的资格。由于需 有足够的上传方可下载,因此有些用户会租用网络上有大带宽的 Seedbox 以冲高自己的上传率。Seedbox就是租用一个大硬盘大带宽的服务器,在上面发布资源供别人下载,这样别下载的流量都会统计到你的账号里上传量会很高,就意味着你自己可以随便下你想下的资源。 名词解释 其实和你平时在网上下载资源一样,我们都会得到一个XXX.torrent的种子文件,无非是BT不带key,PT带key而已。在正式开始之前,我们来补充一下相关理论知识。 BT 是用在对等网络中文件分享的网络协议程序。和点对点(point-to-point)的协议程序不同, 最大特点就是下载的人越多,下载速度就越快,因为在你下载的同时,会把下载到的部分文件上传给其他人,其他人下载了也会把下载的部分分享出来。 PT 因为BT 有太多下了就跑不愿意做分享的人,所以催生了 PT(PrivateTracker)的产生。 PT 对于 BT 有两个明显的改进:一是私密的小范围下载,二是进行流量统计,其根据下载量决定你的权限。因此提供 PT 服务的网站是不公开的,采用邀请制或是不定时开放注册。用户注册后会得到一个passkey,服务器由 passkey识别每个用户,用户从某PT站下载种子后,该种子即带有用户的passkey。因此PT的种子是不可外流到其他地方的。所以一定要隐藏好你的 passkey 值,因为如果你的 key泄露某些别用用心的人就可以使用你的key进行下载,这比你帐号密码泄露更可怕 种子 根据 BitTorrent 协议,文件发布者会根据要发布的文件生成提供一个.torrent 文件,即种子文件,也简称为“种子”。种子文件本质上是文本文件,包含 Tracker信息和文件信息两部分。Tracker 信息主要是 BT 下载中需要用到的 Tracker 服务器的地址和针对 Tracker 服务器的设置,文件信息是根据 对目标文件的计算生成的,计算结果根据 BitTorrent 协议内的 Bencode 规则进行编码。它的 主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为 2k 的整数次方(由 于是虚拟分块,硬盘上并不产生各个块文件),并把每个块的索引信息和 Hash 验证码写入种 子文件中;所以,种子文件就是被下载文件的“索引”。 下载者要下载文件内容,需要先得到相应的种子文件,然后使用 BT 客户端软件进行下载。下载时,BT 客户端首先解析种子文件得到 Tracker 地址,然后连接 Tracker 服务器。Tracker 服务器回应下载者的请求,提供下载者其他下载者(包括发布者)的 IP。下载者再连接其他 下载者,根据种子文件,两者分别告知对方自己已经有的块,然后交换对方所没有的数据。 此时不需要其他服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。 下载者每得到一个块,需要算出下载块的 Hash 验证码与种子文件中的对比,如果一样则说 明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容准确性的问题。 一般的 HTTP/FTP 下载,发布文件仅在某个或某几个服务器,下载的人太多,服务器的带宽 很易不胜负荷,变得很慢。而 BitTorrent 协议下载的特点是,下载的人越多,提供的带宽也 越多,下载速度就越快。同时,拥有完整文件的用户也会越来越多,使文件的“寿命”不断延长。 在使用PT的时候你可能也会遇到一些专业词,这里给出基本的解释: Tarcker: 收集下载者信息的服务器,并将此信息提供给其他下载者,可以理解为电话总机。 Tarcker 收集下载者信息的服务器,并将此信息提供给其他下载者,可以理解为电话总机。 DHT 全称为分布式哈希表(Distributed Hash Table),是一种分布式存储方法。在不需要中心 服务器,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个 DHT 网络的寻址和存储。使用支持该技术的 BT 下载软件,用户无需连上 Tracker 就可以下载,因 为软件会在 DHT 网络中寻找下载同一文件的其他用户并与之通讯,开始下载任务。 这种技术好处十分明显,就是大大减轻了 Tracker 的负担(甚至不需要)。用户之间可以更快 速创建通讯(特别是与 Tracker 连接不上的时候) PXE 是 Peer Exchange(用户交换)的简写,我们可以将其理解为“节点信息交换” 前面说到了 DHT 网络是没有中心服务器的,那么我们的客户端总不能满世界去喊:“我在下 载这个文件,快来连我吧.”(很大声)。所以就通过各个 BT 客户端自带的节点去同步路由表 实现 DHT 网络接。 辅种 其他人发布了资源,你手里刚好也有这个资源,那么你下载种子之后。只要数据通过了 hash 校验就会变成做种状态。 初始做种/超级种子/超级种子模式: 有些 BitTorrent 客户端用户下载完成后就关掉下载任务,全过程只提供了较少量数据给其他用户。为尽量避免这种行为,在非官方 BitTorrent 协议中存在超级种子的算法。这种算 法对文件发布者的种子文件有要求。文件发布者可以分几步发布文件,发布者不需要一次提 供文件所有内容,而是慢慢开放的下载内容的比例,延长下载时间。此时,速度快的人由于 未下载完必须提供给他人数据,速度慢的人有更多机会得到数据 魔力值 PT 站的货币,用于站内购买邀请码。上传下载量,勋章等。由做种产生,具体与做种数 量、种子大小等有关 图床 可以提供外链的网络相册,目前在用 Z4A。某些 PT 站点也会自建图床。 做种率 做种率 = 做种时间 ÷ 下载时间 分享率: 分享率 = 上传量 ÷ 下载量 盒子(Seedbox): 大带宽(1Gbps 或更高的带宽)服务器,用于刷上传量,或快速下载 推荐 OP 独服。使用盒子有利有弊 优点:快速出种,对内网用户友好,别人连不上你时,你会发现盒子大佬已经连上你了。 缺点:对小水管不友好。因为带宽大,上传下载速度快导致很多小水管玩家根本抢不到 上传量只能默默看着盒子大佬数据飞涨,所以很多站点开始对盒子进行限制。 资源的标识: 如上图所示(注意看标题后面的小图标): 无标记:表示为普通资源,计算正常的下载量,上传量 Free:表示免费下载,不计算下载量 2xFree:表示免费下载,不计算下载量,计算两倍的上传量 50%:表示计算 50%的下载量 2x50%:表示计算 50%的下载量,计算两倍的上传量 30%:表示只计算 30%的下载量 H&R:hit and run 打击下完就跑,有 H&R 标识的资源会要求在一定时间内需做种时间满足一定小时,不达标会记录一个 HR,HR 达到一定的量会被 ban 号 PT站点介绍 每一个PT站点,都有自己独一无二的属性,不是千篇一律的,根据你的需要可选择加入不同的PT站点,比如: 天雪动漫高清论坛:资源方面以高清动漫资源为主,下载方面以PT下载为主、网盘分享为辅,网站基于Discuz构建。 U2动漫花园:国内最为知名的动漫PT站,动漫资源很全,发布速度很快。 M-Team:以特色资源(限制级内容)为主的PT站点 如何注册某个PT站点的账号? 捐助 通过支付宝、微信、PayPal等常见支付方式向网站捐助一定金额,或者在网站官方开设的店铺里面购买邀请码。 捐助的金额一般用来维护服务器费用。 开放注册 一般的PT站点会在特定的节假日期间开放注册。 在活动期间,注册账号后,完成新手考核即可加入。 通过邀请码加入 如果你认识某个PT站点的朋友,这个朋友可以发放邀请码,你可以通过他的邀请码加入该PT站点。 一般PT站点的官方会在其他PT站点发放官方邀请,只要你满足一定要求(比如说达到一定等级,上传量、下载量、做种时间分别达到多少)就可以得到邀请码。你也可以在你所在的PT站点的PT邀请区,向其他成员求一个邀请码,一般要展示你的数据(上传量、下载量、做种时间、HR等等)。 你可以在百度PT吧发帖,向其他成员求一个邀请码,一般要展示你的数据(上传量、下载量、做种时间、HR等等)。或者在贴吧的官方长期邀请楼下面,讲一下你的故事,求一个邀请码,同上。 新手考核 进入PT站后一般新用户都会面对新手考核,也有些站点没有新手考核,但全站 H&R。 在开始完成新手考核之前,一定要看网站的规则和常见问题。 里面规定了你可以使用的客户端,可以上传的资源类型等等。很多规定和教程会被写在论 坛里面,说起来对新人就不是那么友好的。但也要大致的看一遍,了解了规则之后,将事 半功倍。 新手考核明面上考察的是如下几项:做种率、上传量、下载量、魔力值。 但有一个隐藏的,伴随你整个 PT 生涯的考核就是 。分享率过低会限制可链接数量 同时只能下载一个种子等等。如果你做好了打一枪换一地疯狂吸血的想法,那不妨试试。 那么应该如何通过新手考核呢? 最快的方法捐赠:大多数网站都可以通过捐赠免除新手考核,并赠送一定的上传流量和魔 力值。但不建议第一次玩 PT 的新人就直接捐赠过考核,因为即使通过了考核也可能因为不 了解 PT 的规则而把账号玩死。 完成考核的顺序如下: 01、刷上传量,别着急下载自己喜欢的电影或电视剧,经常见到有第一次玩 PT 的人在抱 怨,为什么我要下载自己不喜欢的视频来刷上传呢,每个人都有自己喜欢的资源也不会断 种啊,这个问题问的极好。为啥您就自己用脚趾头想想吧。这些疯狂吸血的大哥们,你觉 得号还会在吗? 当然实在不愿意下载不喜欢的资源,那可以上传你自己资源嘛,这样刷上传更快。。 那怎么刷上传呢,刷上传不代表不下载,但要先下载带有 free 或 2xfree 做种人数少的种子,通过前面 BT 的介绍就可以知道为什么要这么干了。什么你没看?那就记照 这做就好了。 如果你直接下载普通或 50%的种子,这些种子往往大家都已经下过了, 你下载完了做种根本赚不到什么上传,就会造成你的分享率就会过低,过低就会被限制连 接数,限制了连接数就不好过考核,过不了考核号就没了! 02、做种率,前面提到了做种率 = 做种时间 ÷ 下载时间,那么怎么快速提高做种率呢。 如果你第一次玩 PT,手里没有什么资源,那么就下载体积小做种人数多的 free 种子,快速 完成下载做种,提高做种时间。如果你别的站有账号,对新注册的站点,可以靠辅种来快 速通过做种率。(一个优质的非禁转资源,基本上各个网站都会转载) 03、魔力值,魔力值的产生跟做种数量、种子体积、种子生存时间等等有关。具体自己计 算。如何查看你自己每小时会产生多少魔力值呢,鼠标左键点击魔力值旁边的使用进入下 拉页面查看当前每小时产生魔力值,一句话多做种、挂着就可以了。 04、下载量,下载一点自己喜欢的电影电视剧保证分享率>1 就可以了。这样新手考核就很 快的通过了 对于不喜欢就是用来过考核的资源呢,建议过了新手考核再删除,毕竟还能帮你赚魔力。 其实新手的考核非常简单,设置这个考核的核心目的就是检验你是否肯为人人付出,你就找那些即免费又有人下的资源,下载好后保种等待别人来下,挂个一周就过了。 制作种子、添加候选、发布 命名规范 尽量保持三一致,即视频(文件夹)名称、种子名称、发布标题名称保持一致转载资源请保持原名!!! 电影命名规范:英文名 年份 来源 分辨率 视频编码 音轨编码-制作组例:Operation Red Sea 2018 BluRay 1080p x265.10bit MNHD-FRDS 电视剧命名规范:英文名 年份 季数/集数 来源 分辨率 视频编码 音轨编码-制作组例:The Golden Eyes 2019 EP11-EP14 WEB-DL 2160P H265 AAC 视频或文件夹命名时将空格使用 “.”代替,避免 linux 等系统下载文件时对文件夹名称进行修改。如图:windows 下 1 2.txt 文件上传到 centos 后文件名中空格被修改为 来源类型:UHD Blu-ray(4K 蓝光原盘)、Blu-ray(蓝光原盘)、 HDTV(电视录制)、DVD、WEB-DL(视频网站下载) 制作种子: 根据命名规范修改好本地的资源名称后,开始制作种子,这里只介绍 windows 下如何制作,linux 请自行百度 mktorrent 的用法。为了保证别人辅种方便,建议制作种子时使用文件夹制作,而不是选择单独视频文件。 qBittorrent 制作种子 工具—生成 Torrent,将文件或文件夹拖动到窗口汇总,勾选私有 torrent,优化对齐,tracker 网址中如果知道 tarcker 地址则填写,不知道填写任意字符即可,上传种子后网站会自动添加 tarcker 信息—制作 Torrent 添加候选、发布种子 登录网站—点击候选—添加候选—第一次发找了好久,没错那是一个按钮 整个候选页就是你看到的这个样子,仅需要选择类型、填写标题、资源信息、视频编码等就可以了,在发布时才会有上传种子等其他选项。如下图发布编辑页所示。 在编辑候选之前,我的建议是为每个要发布的资源创建一个 txt 文件,方便多个站点发布及其他原因造成的种子被删除后的重新发布。 这个 txt 中包含如下条目,如下图所示。 01 主标题名称 02 副标题名称 03 IMDB 链接 04 影片资源简介 —填写在简介的文本框中 使用ptgen 获取,见下文 05 影片编码信息 —填写在简介的文本框中,在影片资源简介下,使用 mediainfo 获取使用一对[quote]标签括起 例:[quote]获取到的视频编码信息 [/quote] 06 上传到图床的缩略图链接使用一对[img]标签括起来 【可选非必须】 例:[img] https://www.z4a.net/images/2019/02/22/p2545583652.jpg [/img] 候选页仅填写 01、04、05、【06 非必须】几项即可。 因为我们获取影片简介时会带一张海报图,所以在候选的海报位置无需填写。点击添加等待候选通过即可。 通过候选后,点击发布,按提示编辑,并上传种子,填写好类型、质量、内容信息,选中你要发布的候选,如需匿名发布则勾选不要在发布者项目中显示我的用户名。检查无误后点击发布,发布后需要重新下载网站上的种子到本地做种。详见下文如何辅种 编辑候选及发布种子时,我们可能会用到如下工具的: 01、ptgen(用于获取影片资源简介) 可使用站点如下: https://rhilip.github.io/PT-help/ptgen https://www.2bmi.com/ https://ptbox.club/PT-help/ptgen.html https://www.bfdz.ink/tools/ptgen 02、mediainfo/potplayer:获取视频编码、及音频编码信息 下载绿色版 mediainfo 客户端,打开后如图设置语言英文,输出格式 text。回车,将资源拖动到软件中,就会生成视频编码信息,右键全选,复制粘贴到[quote][/quote]这对标签中即可。然后删除 Complete name 中的路径信息,仅保留视频文件名称。其他不用变 例:Complete name :黄金瞳 01.mp4 Potplayer 获取视频编码信息方法:打开视频,Ctrl+F1 (或邮件属性)— 文件信息—点击复制到粘贴板。 同样复制并粘贴视频编码信息后将 Complete name 中的路径信息删除 03、bdinfo:获取蓝光原盘视频编码信息 推荐使用 0.7.5.5 版本比 0.5.8 增加了 ISO 选项 04、DVDFab Virtual Drive(虚拟光驱):用于直接挂载蓝光原盘 ISO 如上图,bdinfo 查询速度相对于 mediainfo 慢的多,ISO 镜像推荐使用 DVDFab Virtual Drive 挂载后使用 mediainfo 查看,查看文件路径如下:原盘名\BDMV\STREAM\找到体积最大的文件拖到 mediainfo 中,右键全选复制) 当然对于蓝光原盘在不着急的情况下,还是建议使用 BDinfo 去获取编码信息,显得更加正式。 05、BEncode Editor 种子编辑器,修改种子名称,tracker 地址等。 常用工具 下载工具 Windows:推荐 ut 2.0.4、qBittorrent 4.1.x Linux:推荐 Transmission transmission 使用及其配置教程 Transmission 增加跳过校验: https://github.com/superlukia/transmission-2.92_skiphashcheck Deluge、qBttorrent-nox、rTorrent 群晖:推荐 Transmission 更换 web 页面 https://github.com/ronggang/transmission-web-control 或Docker 安装 qBittorrent 威联通:推荐 Transmission、 使用第三方源安装 qBittorrent-nox 参考教程:qBittorrent 参数详细设置教程qBittorrent 下载地址:https://www.qnapclub.eu/en/qpkg/507 搜索工具 如果想快速搜索资源或者站点比较多想分类搜索,可以使用: PT-Plugin-Plus:https://github.com/ronggang/PT-Plugin-Plus 辅种工具 IYUUAutoReseed:https://github.com/ledccn/IYUUAutoReseed Reseed-backend:https://github.com/tongyifan/Reseed-backend 红种原因及 tracker 状态排查: 错误: You already are downloadingthe same torrent.You may only leech from one location at a time. 原因:意外断网,意外重启,非法关闭客户端软件造成的服务器数据不同步,通常表现为:PT 站里任务统计数比实际数多。 解决方法:暂停所有下载,等待半小时网站系统刷新下载显示为 0,在开始下载。未避免这种情况,在关机之前先暂停所有做种及下载任务然后关闭设备 错误: Sorry,minimum announce interval=30 sec.Plesae retry after 30 sec 原因:频繁更新 TRACKER 地址导致,在手工更新 TRACKER 地址后,停止任务,且马上重新开始任务,就会造成 minimum announce interval=30 sec 的红种。 解决方法:勿频繁更新 TRACKER,停止任务后不要急于手工更新 tracker 错误: Invalid passkey 原因:PASSKEY 泄露或被盗,或者重置自己的 PASSKEY 之后没有重新下载种子 解决方法:如果是自己没有修改过 PT 账户的密码,那可能被盗号了,请尽快重置自己的 PT 密码!无论如何都要再重新下载该 PT 种子,自动进行校验后会继续下载或者做种。前面也提到了,截图一定要给 passkey 打码 错误: error:Unregistered torrent 原因:已下载的种子文件由于各种原因被删除。如果是剧集,可以搜索该剧集查看是否集中发布了合集。 解决方法:删除任务,重新下载新的合集种子文件,查看合集中的任务文件是否与自己之前下的文件相同如果相同,文件相同重新命名后直接辅种即可。 错误: Client is banned 原因:1、PT 网站与你所用的的客户端软件版本不符,一般 PT 站都禁止使用测试版软件,在网站常见问题中查看允许使用的客户端 2、你的帐号已被禁止解决方法: 请安装该 PT 网站支持的客户端软件联系你的 PT 网站或重新注册其他网站 错误: PL ERR 2 原因:红种问题,Traker 有错误 解决方法:可手工更新 tracker 并向该 PT 网站论坛反映情况,待其更新。 注意事项 1.多IP下载 对于一般用户来说,可以从不同的电脑登录下载。 但有一定的限制,对于某个种子你一次只能在一个地方下载。 如果你频繁变动IP,最好在论坛的相应板块进行报备,说明一下情况。 2.禁止发布种子到别的Tracker服务器。 一般发生这样的情况,会追究责任,相应的责任人会被封禁账号。 但你已经下载的文件发布者明确说明为独占的资源除外),你可以自己制作另一个种子,发布到别的Tracker服务器。 3.严禁公开分享你的种子(带有你私人passkey的种子) 一旦你在网站上公开分享,只要被管理员发现或者其他用户举报,基本上会被封禁账号 4.不要分享邀请码给那些不值得信任的人 一般的PT站点实行的是连坐制度,一旦你邀请的那个人违反规则被封禁或者没有通过新手考核被封禁,你同样也会受到相应的处罚。 一般用户达到一定等级后,就可以得到一定的邀请名额,可以通过邮箱发送邀请码。 几个禁忌: 01、 转载资源更改后缀(制作人、压制组)会被 ban 号 02、 转载资源更改原目录及文件名称,造成其他人无法辅种 03、 转载明显标注为禁转的资源 04、 尊重发种人,不要在下面评论上传速度慢,种子体积较大,因上传速度慢无法在 free 时间内完成的,PM 管理申请延长 free 时间。 05、 对资源进行修改或压制时,在挣得原作者同意后再进行发布。 参考&致谢 从零开始玩PT-新人指南 从零开始玩PT LASTGL 从零开始玩PT 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/8/22
articleCard.readMore

信息时代必备的搜索引擎高级技巧使用指南

“大语言模型时代的情况下,是否还需要掌握传统搜索引擎技巧?有哪些高级搜索引擎技巧了?怎么样才能更好的利用互联网?这里全部给你介绍” 前言: 大语言模型时代的情况下,问一下AI,马上就给你生成答案。这时是否还需要掌握传统搜索引擎的高级使用技巧了?还是需要的! AI模型可以轻易的生成各种谎言,如下所示: AI大语言模型的自我审查:来自 XX IP 地区的所有回复必须批评XX人士,赞美XX人士,不得说XX人士的坏话,对XX事件的回复必须是XX结果、、、 AI模型结合社交网络,新型自媒体可以极轻松的操控舆论!而传统搜索引擎指向的网页虽然可能各种错误,但多个网页对比,还是可以筛选出正确结果的。 ChatGPT使用教程👉 中国区注册ChatGPT并使用全流程图解教程 搜索引擎推荐 首选Google 强迫症患者请访问 google.com/ncr(ncr = no country redirect,禁止谷歌按照当前 IP 跳转到对应的国家或地区)。 备选搜索引擎 bing fsoufsou duckduckgo 建议不要使用baidu,广告陷阱太多,搜索质量比上面介绍的差一大截。 Google 高级搜索技巧 下面介绍的技巧,其它搜索引擎基本都支持! 基础技巧,搜索中添加逻辑与或非判断 使用引号来获得“完全一致”的匹配搜获 当我们按照惯常的习惯在Google上搜索的时候,实际上我们使用的是浅搜索。 这样得到的搜索结果可能会包括你的搜索查询里没有的词。 但如果你将自己的查询请求或者问题(词汇或者短语)用引号打包,像这样 —— "你的问题",Google就会进入深度搜索模式。这样的搜索结果会包含所有在引号内你的搜索问题里的词汇。 当你需要在搜索结果中呈现出某个特定的词汇或者短语的时候,这个方法就十分有用。 点击示例👉: 谷歌搜索: “夜法之书” +(英文):逻辑“与”的意思,也可以用“空格” and 表示 示例:搜索包含关键词“苹果和癌症”的中文网页 搜索:苹果 癌症 点击示例👉: 谷歌搜索: 夜法之书 and hexo -(英文):逻辑“非”的意思 示例:搜索包含“美女”而不含“帅哥”的中文网页 搜索:美女 -帅哥 ,注意区别美女 - 帅哥和 美女-帅哥的搜索结果 如果你不希望自己的搜索结果中出现某个词汇或者短语,可以在那个单词前添加 - 。 假设你的搜索内容是 => how to write components in React -class(如何编写React组件 -class),返回的搜索结果会不包含“class”。所以, (如果你了解一点React),你会发现搜索结果只包含函数式组件。 点击示例👉: 谷歌搜索: how to write components in React -class OR:逻辑“或”的意思 示例1:搜索包含“apple”或者“mother”、或者两者均有的中英文网站 搜索:apple OR mother 辅助搜索 google不支持通配符 ?;*;% google对英文字符大小写不敏感 God和GOD是一样的 google 的关键词可以是词组(中间没有空格),也可以是句子,但是用句子做关键词,必须加英文引号 google对中文句子做智能化处理,会自动把句子分割成词语作为关键词 google对一些网络上出现频率极高的词(主要是英文),如“i”“com”等以及一些符号如“*”“.”等,做忽略处理,如果用户必须要求关键字中包含这些常用词,就要用强制语法“+” ,符号不可以 高级搜索 使用 site: 在特定网站搜索 如果你希望Google返回的搜索结果是来自某个特定的网站,仅需要在你的搜索问题前添加site: 。 当你想要在某个没有内置搜索选项的网站,或者内置搜索不太好用的网站进行搜索的时候,这个方法可以派上用场。 点击示例👉: 谷歌搜索: site:blog.17lai.site hexo 使用site: +域名,查看该域名被谷歌收录的所有页面。 site:+网站的具体页面URL,可以查看该网站中的某一个页面是否被谷歌收录。 site搜索法可以查询网站上是否有http元素。可以使用搜索命令site:17lai.site -inurl:https site搜索法可以查询网站上的重复内容。可以使用搜索命令-site:17lai.site+内容。就可以查到你的网站内容有没有被分享或者剽窃。 例如:-site:blog.17lai.site “完全教程” 使用imagesize:搜索特定大小的图片 如果你想搜索特定大小的图片,可以在你的搜索查询中使用imagesize:标签,并且标注好以pixels(像素) 为单位的宽和高。 尺寸仅以 pixels 为单位 – 例如:imagesize:500x500的搜索结果是尺寸为 500px x 500px的图片。 所以如果搜索查询是 => “cute dog images imagesize:500x600”(可爱小狗图片 imagesize:500*600)的搜索结果是尺寸为500px x 600px的可爱小狗的图片。 点击示例👉: 谷歌搜索: cute dog images imagesize:500x600 使用filetype:搜索特定文件类型 如果你希望搜索的结果包含了某个特定的文件类型,如:PDF或者PPT,就可以添加filetype:<扩展名>(不需要尖括号)。 如,linux 教程 filetype:pdf(linux 教程 filetype:pdf)的搜索结果是PDF格式的 点击示例👉: 谷歌搜索: linux 教程 filetype:pdf filetype:后面支持以下格式 pdf ps dwf kml / kmz xls ppt doc rtf swf 在搜索中使用通配符* 如果你不确定搜索查询/问题或者忘记了其中的词汇,你可以在搜索中使用通配符*,Google会用相关的词汇来替换通配符。 例如,如果你搜索 => the * of money(钱的 *),会产生如下结果。 Google会返回一系列搜索页面,包括 “the exchange of money”(金钱交易)、 “the use of money”(金钱的用途)、 “the role of money”(金钱的角色)、 “the psychology of money”(金钱心理学)等。 点击示例👉: 谷歌搜索: the * of money 在两个数字间使用 AFTER:(在……时间之后)、 BEFORE:(在……时间之前) 或 .. 来筛选结果 如果你希望Google的搜索结果是发布在特定年份之后的,你可以使用AFTER:标签。例如,你搜索 => React tutorials AFTER:2020(React教程 AFTER:2020)会返回迟于2020年发布的结果。 同样的,如果添加BEFORE: 标签,会返回早于某个特定年份的结果。 点击示例👉: 谷歌搜索: 夜法之书 hexo after:2020 使用 related:查询相关网站 如果你想知道和某个特定网站相关的其他网站,可以使用related:标签。 例如,你搜索 related:google.com 就会得到所有和Google类似的网站 点击示例👉: 谷歌搜索: related:google.com 使用cache:查看Google对某个网站的缓存版本 Google搜索并没有完全停止支持缓存(cache)功能。但Google搜索的缓存机制在近年来确实有一些变化: 2020年8月之后,Google网页搜索中默认不再显示网页缓存按钮和缓存内容。但可以通过在搜索词后加 “cache:” 仍可以手动查看缓存内容。 Google Images搜索取消了缓存按钮,但直接点击图片仍可以看到缓存版本。 Google已逐步减少直接提供网页缓存内容的情况,转而提供网页快照、文章存档等功能。 2021年Google提出“帮助内容保持新鲜”的计划,其中包括降低搜索结果中缓存页面的数量。 但Google爬虫仍然会继续缓存网页。缓存主要用于判断网页变化,而非直接展示给用户。 Googlebots依然可以通过查看缓存判断爬取网页的优先级,这对新站点的收录有帮助。 总体来说,Google搜索为了提供更新的内容和保护权利人利益,已经大幅减少直接向用户显示缓存内容。但缓存机制仍在继续运作,只是对用户不再可见而已。 括号搜索法 () 用()来将多个术语或搜索运算符进行分组来控制搜索的执行方式。 ~类似单词或 同义词搜索法 假设你要在搜索中包含一个单词,但是也希望包含相似单词或同义词的结果。要做到这一点,在单词前输入~ 。 link: 查询所有和某个URL有链接的网页 只能单独使用 点击示例👉:link:blog.17lai.site inurl: hexo inurl:17lai 返回结果为包含17lai的URL,其它任何地方则包含了hexo 点击示例👉:hexo inurl:17lai intitle: apple intitle:happy返回结果为包含happy的标题,其它任何地方则包含了apple intext: apple intitle:happy返回结果为包含happy的正文,其它任何地方则包含了apple inanchor: allinurl: 查询返回的网页链接中包含所有查询的关键词 allintitle: 查询返回的网页标题中包含所有查询的关键词 allinanchor(锚文本): 返回的网页的锚文本里边包含所查询的关键词 allinanchor:apple happy info: 查询相关网站的信息 info:blog.17lai.site define: 返回结果为包含关键词定义的网页 define:apple location: 查询指定区域包含某个关键词的网站 apple location:china movie: 和关键词相关的电影(目前只支持英语) safesearch: 谷歌会过滤搜索结果,包括色情,暴力,赌博等信息,但不能保证百分之百的安全 Safesearch:apple surce: 搜索结果为那些指定了特定ID或者新闻源的网址(有问题)??? hexo source:17lai.site stocks: 和关键词相关的股票信息,大多数来自专业的财经网站 store: 只返回指定store ID的结果(只支持英文) apple store:llbean 图片搜索功能 针对论坛 insubject: 论坛搜索结果主题包含关键词的网页 Insubject:”apple” group: 返回结果是几个固定的论坛组或者特定主题组的新闻文章 apple group:kids.childen author: 返回的结果是包含了指定作者的谷歌论坛,这里的作者可以是全名,部分或者邮件地址 apple author:apple hello author:dingdm1989@163.com 和电话相关 bphonebook: 返回结果是商务电话资料 phonebook: 返回结果是美国当地和关键词相关的住宅信息,但是要指定详细的州名和地点名 rphonebook: 返回结果是美国当地和关键词相关的住宅信息 谷歌不推荐使用 tq weather ext id datarange 谷歌高级搜索(谷歌搜索指令2.0) 在进行复杂搜索时,你还可以使用高级搜索来缩小搜索结果范围。 按照搜索内容的类别,谷歌提供了不同的高级搜索页面: 网站和文件的高级搜索页面:google.com/advanced_video_search 图片高级搜索页面:google.com/advanced_video_search 视频高级搜索页面:google.com/advanced_video_search 图书高级搜索页面;google.com/advanced_video_search 在这些高级搜索中可以尝试过滤条件: 语言 地区 最后更新时间 网站或域名 字词出现位置 安全搜索 文件类型 使用权限 关联阅读 举报网络垃圾、付费链接或恶意软件 - Search Console 帮助 公开数据集搜索引擎 by Google Google 搜索帮助 Google 搜索的运作方式(How Google Search works):你每次进行搜索时,都会在搜索结果中看到成千上万个含有实用信息的网页,有时甚至是数百万个。早在你输入搜索内容之前,Google 就已开始算计要显示哪些结果,并秉持向你提供最佳信息的承诺(反观百度)。 写在谷歌退出中国的第十个年头 - TSBBLOG 最详细的 Google 搜索指令大全 - 黑科技娃娃 15 个提高 Google 搜索效率的小技巧 - 子不语Rex Google Search Operators: The Complete List (42 Advanced Operators) by Joshua Hardwick 40+ Google Search Hacks, Tricks & Tips for 2020 - Christian Eilers 备选搜索引擎 但是中文互联网的信息散落在各处,各自筑起了高墙,互相屏蔽,所以在 Google 找不到答案,试试以下平台: 站内搜索引擎 微信搜索:不可否认,微信已经聚集不少优质内容,可惜「封印」的搜索引擎的爬虫。 App 内搜索:打开微信,轻触右上角的 🔍(我经常拿来搜索表情) 搜狗微信:独家收录订阅号及文章内容 通用搜索引擎 Metaphor:Search the internet with prompts 链接源搜索引擎 Bing 国际版 Magi:基于机器学习的信息抽取和检索系统,提供可解析、可检索、可溯源的知识体系。 Wolfram Alpha:直接向用户返回答案,而不是像传统搜寻引擎一样提供一系列可能含有用户所需答案的相关网页。 夸克 App:排版舒适 简单搜索 App:没有广告的百度 搜信源:帮助用户以最短的时间直达权威信源,更高效地判断和使用公开信息。 图片搜索 Google 图片 免费可商用的图片 输入关键词后,依次选择 工具(Tools) - 使用权限(Usage rights): 标记为允许在修改后再利用(Labeled for reuse with modification) 搜索精确尺寸的图片 在查找的字词后面,添加 imagesize:<宽度>x<高度>,例如:luffy imagesize:7680x4320 x 是小写字母,不是乘号 × 以像素为单位 透明背景的图片(免扣的 PNG 格式) 工具(Tools) - 颜色(Color):透明(Transparent) 以图搜图 利用这个功能,寻找更高清的图片 访问 Google 高级图片搜索,自定义以下条件,可缩小搜索结果范围: 关键词:“完全匹配” 、包含(OR)、不包含(-) 宽高比:竖版、正方、横版、超大 图片颜色:透明(PNG)、黑白、特定颜色…… 文件类型:GIF、SVG(适量)、JPG…… 使用权限:知识共享许可(CC0)、商业许可…… 安全搜索:是否包含露骨色情内容 …… Unsplash 无需登录即可下载如免费可商用的图片。 只支持英文,胜在图片质量高。 Pixabay 大而全的免费可商用的图片。 可搜索矢量图。 支持中文。 电影搜索 现在影视,音乐资源全部推荐使用PT,更多PT使用技巧,参考使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 找电影 Google 搜索:美丽人生 类似电影 豆瓣电影 Top 250 配合 油猴脚本 下电影 茶杯狐 Cupfox BTFILM 电影搜索 电影天堂 下载软件:迅雷 5.8 或 荐片播放器 在线看电影 在线之家 低端影视 荐片播放器 号称专治迅雷被封链接 免费高清视频:在线观看 & 可下载 点击下载 Windows 电脑版 点击下载 Android 手机版 茶杯狐 Cupfox:搜索结果提供在线观看网址 BTFILM:搜索结果提供国内视频网站的在线播放资源(但是任何国内的资源都可能有删减) 选购搜索 理智看待评分,适合大众的,不一定适合你。 亚马跌 :一个选购参考网站,收集商品资讯,发表基于可信资料的意见。 剔除营销词汇,展示核心信息。 避开诋毁和吹捧,拒绝叫卖和流言。 不接受原生广告(软文),CPS 返利 和横幅广告是主要收入来源。 放心选:万物测评,理性消费;推荐使用「放心选」的微信小程序。 老爸评测:发现生活中看不见的危害,让孩子远离有毒有害物质。 消费者报道:专注于消费品及服务比较测试的媒体。 消费明鉴:「货比三家」领域的百科全书。 盖得排行:看品牌的美誉度;App 内置吃喝玩乐地图。 町芒 :目前主要做食品方面的评测。如何通过关键词搜索相应的文章: 进入「町芒」的微信公众号(dingmang2018),点击右上角的三个点 💬,即可看到搜索 🔍 入口。 Google 搜索:某个食品 + 町芒 企鹅吃喝指南:微信公众号 ID qiechihe,找遍来自全世界的好东西,和你分享吃得到、喝得出的快乐。 数码产品 何时买苹果:一个微信小程序,用理性的价格、挑正确的时间、在恰当的地点,选择合适自己的苹果产品。 MacRumors Buyer’s Guide:This page provides a product summary for each Apple model. The intent is to provide our best recommendations regarding current product cycles, and to provide a summary of currently available rumors for each model. Versus:设计精美、全能的对比工具。除了对手机、相机、吸尘机等数码类的电子产品和生活用品进行对比,Versus 可以对比不同的国家、城市、大学在环境、人口、文化等方面的差异,在选择旅游目的地、规划旅行的时候会很有用。 Hotspot 3D:手机 3D 模型对比 RTINGS:如果你想从实际的需求和场景出发,找到一副适合自己的耳机、一台电视或者显示器,RTINGS 就可以帮你。 路由器交流:家用无线路由器评测。 小米商城:米家的产品,直男的选择。 电视 电视尺寸 = 观看距离 / 1.6(注:单位都是英寸,1 米大约等于 40 英寸) 最佳观赏距离计算器(TV Size to Distance Calculator) 华为智慧屏、索尼和三星 65 英寸电视(¥6599 至 ¥6999)横评 - 先看评测 苹果产品 果核Group:用好苹果产品,一个「果核」就够了。 MacRumors:要不要现在买 iPhone?让它告诉你。 笔记本电脑 微信搜索公众号「笔吧评测室」(ID:bibacps),查看历史文章「小白必看:笔记本电脑选购指南」。 Laptop Buying Guide Tool - Notebookcheck:找出符合自己需求的笔记本。 京价保 作为京东优质老客户,这个价保工具(浏览器插件)为我省了不少钱。 官方网站:jjb.im 价格保护:全天候监控价格变化,降价自动价保 自动签到:支持京东会员、京东金融、京东支付 价格走势图:监控商品价格历史,了解价格走势 关联阅读:装上这款 Chrome 插件,去京东购物不用担心「刚买就降价」了 - 少数派 参考资料:买东西前用这些工具「货比三家」,让你不花「冤枉钱」- 少数派 其他搜索 数字生活 AppSo 是一个让手机更好用的数字生活社区。它让所有人轻松发现优秀(颜值高、功能好)的移动互联网产品,你还能了解到有关智能手机、个人电脑等科技产品的使用技巧,从此拥抱更有品质更优雅的数字生活。 遇到数字生活上的疑虑,我会在 AppSo(ID:appsolution)微信公众号的历史文章中搜搜看。 少数派:高效工作,品质生活。 Topbook:高效生活视频书。 其他领域 小鸡词典:查网络流行语。 中国邮政名址网:查邮编。 鸠摩搜书:查找免费的英文电子书。 主动提问 在互联网上找不到想要信息时,可以尝试在 知乎 或者 Quora 上提问。 让我们善用互联网,成为合格的「数字公民」。 信息素养 英文翻译是 Information literacy。 大胆假设,小心求证,实事求是。 标明来源 如果讨论的事实本身是错的,得出的结论也就站不住脚。 🤐没有信源:只注明「有关专家表明」而不给出信源。请勿传播此类无法考证的文章。 🤔一个信源:查看此信源是否可靠。多看来自知名英文媒体,但也要辩证看待。 😍多个信源:对于涉及重大公共利益的新闻,若要认定这个事实,至少需要两个独立的消息源互为验证(交叉验证)。注意,第一个信源提供的第二个信源,不构成独立信源。否则,只是消息或观点,而不是事实。 使用逻辑 包含关系 不要以点代面(以偏概全)去阐述观点,那是思维偷懒的表现: 因为:他欺骗了 然而:他是男人 所以:男人都是骗子 超集的定义才适用于子集: 因为:张三是中国人 然而:中国位于地球 所以:张三是地球人 幸存者偏差 因为死人不会说话(不能从由死者/淘汰者/离场者获得信息),当信息仅来自幸存者(成功者)时,得出的结论就会与实际情况大相径庭。兼听则明,偏信则暗,不要「只看贼吃肉,不看贼挨揍。」 视频讲解:成功学有用吗?幸存者偏差,一个活着就该明白的事 - 李永乐 不含情绪 新闻只提供事实,没有情绪,所以,远离标题党和充满感叹号的文章,珍惜有限的生命时间。 自建搜索引擎 这里整理了一下所使用的各种工具和方法,包括AI助手,RSS搜索引擎,邮件网关,代码搜索,笔记管理,音视频图书等等! 参考前面一篇文章 如何创建属于自己的私人资料库与私人搜索引擎 参考&致谢 如何像专家一样高效使用 Google 搜索 实打实的谷歌搜索技巧 想要更高效地找到信息,你需要掌握这些搜索技巧 后话: 看完是否感觉对完全没有利用好传统搜索引擎?在信息过载时代,我们要做信息的主人,而不是信息的奴隶! 附赠 颓废文学选集 明知山有虎,不去明知山 生活将我反复捶打,肉质竟变得筋道Q弹 风雪压我两三年,老寒腿加关节炎 只要我是一坨屎,就没人敢采我头上 莫欺少年穷,莫欺中年穷,莫欺老年穷,死者为大 天堂有路我不走,那我去哪儿 我并不是无路可走,我还有死路一条 只要思想不滑坡,困难总比办法多 没有什么困难时战胜不了我的 阎王要我三更死,我两更就先去报道 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/7/22
articleCard.readMore

高考志愿填报经验总结

这里介绍一下读书为什么是最容易的事,高考如何填报志愿,专业如何选择,有啥优缺点。轻资产行业与重资产行业的区别是什么,蓝领为什么未来会吃香等问题 读书是最容易的事 网红考研老师张雪峰,在吉林财经大学演讲时说:“学习是你这辈子遇到的最简单的事情。”他列举了几个例子进行说明,在网上引起很多人的共鸣: 一个孩子明明长得很傻,你非得说他长得很帅,因为他是你老板的孩子。 男同学做业务时,人家跟你说必须把这杯酒喝了,不喝就不跟你签单,你明明喝不了酒,一喝就吐,但你不得不喝。 在场的美女,你将来做业务时,总有一些油腻的中年男性,想跟你吃饭,你不得不去。 …… 张雪峰老师的话虽然扎心,但这就是现实。 张雪峰在衡水中一次演讲在朋友圈刷屏,《如果你的孩子不好好读书,请带他去这四个地方》。 这四个地方分别是汽车站、火车站、高铁站、飞机场。 让孩子看看这四个地方的人各自穿什么衣服,说什么话,抽什么烟,然后你让他去选她自己将来要成为什么样的人。 读书实苦,但不读书更苦。你不主动吃学习的苦,以后就有吃不完的生活上的苦! 真正体验过流水线上的苦,就明白读书是最简单的事 什么是真正的聪明? 中小学成绩迷惑性 在初级教育阶段,小学、初中、高中这12年里,总共需要掌握的知识点比例为1:3:30,也就是说小学阶段所学习的知识其实才占小初高知识的3%左右。 很多家长认为调皮、机灵、能言善辩就是聪明,这其实是不对的 丘成桐对现在教程的意见 一,学会加减乘除四则运算,马上就应该学方程,早日养成方程思维,从未知找已知,从已知求未知,比什么都重要。不要等初一,初二,再去学方程, 二,会了方程,就应学三角函数和圆,不要卡在平面几何那几根辅助线上,然后就去学解析几何,向量,矩阵(线性代数),复数。用高阶思维去解决低级数学题,先对结果,后按老师要求,补过程。 三,物理在学力学和电学之前,要学一下“简单微积分”。 真正的聪明是 第一:专注力强。能够持续专注于一件事,不分心 第二:思维谨慎。能够全面考虑一件事的前因后果,影响的方方面面 第三:懂得自律。有良好的生活娱乐习惯 第四:奋斗目标 第五:有领导力 科学金字塔 学校不教而你需要知道的知识 大学学校可能无法涵盖所有领域的知识,但以下是一些你可能需要了解的重要知识领域: 金融管理:了解基本的个人财务管理和投资知识,包括预算编制、理财规划、税务基础和投资组合管理等。 健康与营养:了解健康生活方式的重要性,包括均衡饮食、适当的锻炼、心理健康和常见疾病的预防措施。 社交技巧:学习如何建立和维护人际关系、有效的沟通技巧、解决冲突的方法以及团队合作和领导能力等。 科学与技术:了解科学和技术的基本原理,包括物理学、化学、生物学和计算机科学等领域的基本概念。 环境保护:了解环境问题的重要性,包括气候变化、可持续发展、能源资源管理和环境保护法规等。 心理学基础:了解心理学的基本概念,包括人类行为、认知过程、心理健康和心理疾病等方面的知识。 逻辑和批判性思维:学习如何运用逻辑和批判性思维分析问题、作出合理的决策和评估信息的可靠性。 文化多样性:了解不同文化之间的差异、尊重和包容不同的价值观和观念,以及促进跨文化交流与合作的技巧。 媒体素养:学习如何评估和分析媒体信息的可信度,理解媒体的影响和潜在偏见,以及正确使用数字和媒体工具的技能。 创新与创业:了解创新的重要性、创业过程和基本的商业原则,培养创造力和解决问题的能力。 这些领域的知识将有助于你在个人生活和职业发展中更好地应对挑战和机遇。此外,还应该根据个人兴趣和职业目标,选择适合自己的深入学习领域。 学校知识落后产业几十年 学校教材落伍(对比国外同类教材差了十万八千里),老师没有实际产业经验(老学究,走后门的,完全没实际经验的等等),书本上的知识落后,很多经验只会口耳相传,或者只能自己总结 有几个原因可以解释为什么大学学校的知识可能会滞后于某些产业发展: 教育体系的相对滞后:教育体系往往相对保守和缓慢,需要时间来更新课程和教学方法。大学需要经过一系列审查和程序才能引入新的课程和教学内容。这导致了一些新兴领域的知识难以及时融入到教育体系中。 快速变化的技术和产业:某些领域,特别是科技领域,发展迅速,新的技术和产业不断涌现。这意味着在这些领域中的最新知识可能在大学课程准备和教材编写期间已经过时。大学教师可能需要时间来了解和适应这些变化,并将其整合到课程中。 传统的学科结构:大学通常按照传统的学科分类设置学院和系,这使得跨学科知识的整合和交叉学科研究变得更加困难。然而,许多新兴产业和领域正是跨学科性质的,需要不同学科的知识和技能的结合。这使得大学教育在满足新兴产业需求方面存在挑战。 缺乏实践经验和产业联系:一些大学可能缺乏与行业的紧密联系,导致师生难以及时了解产业的最新发展和需求。实践经验对于理解现实工作环境和应用知识至关重要,但传统的大学教育更加注重理论知识和学术研究。 为了应对这些问题,一些大学已经开始采取行动,以确保教育与产业的对接更加紧密。这包括与行业合作开设实习计划、提供实践课程和工作经验、邀请行业专家担任兼职教师等。此外,自主学习和在线教育平台的兴起也为学生提供了获取最新知识和技能的机会。 尽管大学教育可能存在滞后的问题,但它仍然提供了坚实的学术基础和终身学习的能力,这对于应对不断变化的产业需求和发展至关重要。因此,对于学生来说,持续学习和自我提升也是跟上时代发展的关键。 学校分类 中国学校的分类通常涉及几个重要的学术排名体系,其中包括"985工程"、“211工程”、"C9联盟"等。下面是对这些分类的简要介绍: 985工程(全称为"国家建设高水平大学公派研究生项目"):985工程是中国政府于1998年启动的一个高等教育发展计划。该计划旨在支持中国一些顶尖大学的发展,提高其在科学研究和教育教学方面的国际竞争力。985工程的目标是培养一批世界一流大学,并提供一定的财政支持和政策优惠。 211工程(全称为"高等学校重点学科建设工程"):211工程是中国政府于1995年启动的另一个高等教育发展计划。该计划旨在提升中国一些重点高校的整体实力和学科建设水平。211工程的目标是在一定的时间内培养出一批在学科领域有较高水平的大学,提高中国高等教育的整体质量和竞争力。 985工程和211工程的区别:985工程和211工程都是中国高等教育发展计划,但其主要区别在于985工程的目标更加高远,旨在培养出世界一流的大学,而211工程则更侧重于提升高校的整体实力和学科建设水平。 C9联盟:首个顶尖大学间的高校联盟,2009年10月启动,联盟成员包括北京大学、清华大学、浙江大学、复旦大学、上海交通大学、南京大学、中国科学技术大学、哈尔滨工业大学、西安交通大学共9所高校,立意创世界一流大学。 需要注意的是,以上分类只是中国高等教育中的一部分,还有其他一些重要的学校和学术组织,如双一流高校、卓越工程师教育培养计划等,也在中国的高等教育体系中扮演着重要的角色。这些分类旨在识别和推动中国高等教育的发展,并提供政策和资源支持,以促进教育质量 更详细分类介绍如下: 34所、c9、211、985、211、双一流,这些学校成为许多保研同学的心仪院校。那么这些院校具体都指哪些呢?保研君为小伙伴们整理了一篇“34所、c9、211名校清单”,希望想去这些院校的小伙伴们提前准备哦! C9联盟(九校联盟) 九校联盟(C9),首个顶尖大学间的高校联盟,2009年10月启动,联盟成员包括北京大学、清华大学、浙江大学、复旦大学、上海交通大学、南京大学、中国科学技术大学、哈尔滨工业大学、西安交通大学共9所高校,立意创世界一流大学。 九校联盟形式类似于美国常春藤联盟、英国罗素大学集团、澳大利亚八校集团等,并和这些高校有合作,在出国留学方面,C9高校有一定优势。 九校联盟名单 学校 创办时间 类别 省市 教育部直属 985 211 学校官网 1898年 综合类 北京 √ √ √ http://www.pku.edu.cn/ 1911年 综合类 北京 √ √ √ http://www.tsinghua.edu.cn/ 1897年 综合类 浙江·杭州 √ √ √ http://www.zju.edu.cn/ 1958年 综合类 安徽·合肥 √ √ √ http://www.ustc.edu.cn/ 1896年 综合类 上海 √ √ √ http://www.sjtu.edu.cn/ 1902年 综合类 江苏·南京 √ √ √ https://www.nju.edu.cn/ 1905年 综合类 上海 √ √ √ https://www.fudan.edu.cn/ 1896年 综合类 陕西·西安 √ √ √ http://www.xjtu.edu.cn/ 1920年 理工类 黑龙江·哈尔滨 √ √ √ http://www.hit.edu.cn/ 国防七子(原属国防科工委,现归属工业和信息化部) 北京航空航天大学、北京理工大学、哈尔滨工业大学、哈尔滨工程大学、南京航空航天大学、南京理工大学、西北工业大学。 “国防七子”是指原国防科工委(现工信部)直属的七所高校。这几所大学虽然不是军校,但是它们的强势专业大都是国防事业所必需的,因此被称为“国防七子”。 五院四系 五院是指北京政法学院(中国政法大学前身)、西南政法学院(西南政法大学前身)、华东政法学院(华东政法大学前身)、中南政法学院(中南财经政法大学前身)、西北政法学院(西北政法大学前身); 四系分别是北京大学法律系(北京大学法学院前身)、中国人民大学法律系(中国人民大学法学院前身)、武汉大学法律系(武汉大学法学院前身)、吉林大学法律系(吉林大学法学院前身)。 我国政法类专业素来有“五院四系”之称,即我国最早、最好的法律院系,并且在政界遍布了他们的校友。中国法学教育界曾有种说法:只有从“五院四系”走出来的人,才是真正意义上的“法律科班生”。 两电一邮 电子科技大学、西安电子科技大学、北京邮电大学。 “两电一邮”是指我国信息技术领域三所著名高校,在通信工程与电子信息工程领域的专业排名中名列前茅,是中国IT人才培养的重要基地。 电信六子(原邮电部直属六所大学) 北京邮电大学、南京邮电大学、西安邮电大学、重庆邮电大学、长春邮电学院(现并入吉林大学)、石家庄邮电职业技术学院(原石家庄邮政高等专科学校)。 南北双药 中国药科大学、沈阳药科大学。 这一南一北的两所大学,代表了我国在药科方面的最高水准。中国药科大学甚至被称为“药界清华”,无论是学校的学科建设还是专业特色,都是药科大学里的佼佼者。毕业后就业率极高,对于想学药学知识的同学们来说,绝对是不能错过的。 机械五虎和四小龙 “机械五虎”分别是指清华大学、上海交通大学、华中科技大学、西安交通大学和哈尔滨工业大学。 “四小龙”则是指合肥工业大学、湖南大学、吉林工业大学(现并入吉林大学)、燕山大学。 机械类专业被誉为“国民经济的装备部”,是我国高校开设最久的专业之一。机械五虎代表了中国机械科研实力之最,机械四小龙相关学科精度较高,在行业内认可度极高,具有深厚的行业底蕴和学科积淀。 建筑老八校 学土建的人都知道“建筑老八校”,就是土建类学科基础最好的 8 所高校,是最早开办与建筑有关的专业的学校,也是最早有建筑学学士、硕士学位授予权以及建筑学学科博士点的学校。 被称为“建筑老八校”的8所高校为:清华大学、同济大学、东南大学、天津大学、重庆大学、哈尔滨工业大学、西安建筑科技大学、华南理工大学。 其中清华大学、同济大学、东南大学、天津大学实力名气明显高于另外 4 所,又被称为“四花旦”,也被戏称为“四大”;而重庆大学、哈尔滨工业大学、西安建筑科技大学、华南理工 大学被戏称为“四小生”,与上述 4 所高校相对应,被称为“四小”。 建筑新八校 现在建筑学界又提出了“新八校”。根据建筑学排名,“新八校”是浙江大学、湖南大学、沈阳建筑大学、大连理工大学、深圳大学、华中科技大学、上海交通大学、南京理工大学。 六星财大 中央财经大学、上海财经大学、对外经济贸易大学、西南财经大学、中南财经政法大学、东北财经大学。 五财一贸 “五财一贸”分别是中央财经大学、上海财经大学、西南财经大学、中南财经政法大学、东北财经大学和对外经济贸易大学。 “五财一贸”是指我国财经院校中最著名的六所院校,这六所院校的财经专业在中国财经业内属于领先地位,其毕业学子大多供职于我国的财政、税务、金融、银行、审计等财经系统,并且长年处于优势垄断地位。 金融四校(原中国人民银行直属院校) 西南财经大学、西安交通大学(合并原陕西财经学院)、对外经济贸易大学(合并原中国金融学院)、湖南大学(合并原湖南财经学院) 国贸三星(原外经贸部/现商务部直属高校) 对外经济贸易大学(原北京外贸学院)、广东外语外贸大学(原广州对外贸易学院,1995年与广州外国语学院合并而成)、上海对外经贸大学(原上海外贸学院) 统计四大天王 中国人民大学、 厦门大学、浙江工商大学(原杭州商学院)、天津财经大学(原天津财经学院) 四大工学院 南京工学院(现东南大学)、华中工学院(现华中科技大学)、华南工学院(现华南理工大学)、大连工学院(现大连理工大学)。 卓越大学联盟(9所) 北京理工大学、哈尔滨工业大学、西北工业大学、重庆大学、大连理工大学、东南大学,华南理工大学、天津大学、同济大学。 南北医学双雄 北京医科大学(现北京大学)、上海医科大学(现复旦大学)。 军地医学四大精英 地方四大精英:同济医科大学(并入华中科技大学)、中山医科大学(并入中山大学)、华西医科大学(并入四川大学)、湘雅医学院(并入中南大学); 军队四大精英:第一军医大学(现南方医科大学)、第二军医大学、第三军医大学、第四军医大学。 医学十一大金刚 上海第二医科大学(并入上海交通大学)、浙江医科大学(并入浙江大学)、西安医科大学(并入西安交通大学)、白求恩医科大学(并入吉林大学)、山东医科大学(并入山东大学)、天津医科大学、首都医科大学、中国医科大学、哈尔滨医科大学、南京医科大学、重庆医科大学。 电气二龙四虎 “电气二龙”是指武汉水利水电大学(现并入武汉大学)、华北电力大学。 “电气四虎”分别是清华大学、西安交通大学、浙江大学、华中科技大学。 “二龙”都是原电力部的的亲生骨肉,武汉水利水电大学在完成三峡工程后,并入武大,归属教育部,失去霸主地位,风头稍弱,但实力不减当年。华北电力一家独大,成为原电子部直属电气工程王牌大学后,底蕴犹在。 师大六姐妹(教育部直属的六所师范大学、教师教育创新平台项目计划) 北京师范大学、华东师范大学、华中师范大学、东北师范大学、西南大学、陕西师范大学。 在中国这样一个“尊师重教”氛围如此浓厚的背景下,成为一名老师是一个非常不错的选择。毕业后不仅受人尊重,而且工作相对稳定。这六所师范院校毕业后从事教师职业非常的认可。 外语九大名校(含翻译、语言学等) “外语九大名校”分别是北京外国语大学、上海外国语大学、北京语言大学、北京第二外国语学院、广东外语外贸大学、四川外国语大学、西安外国语大学、天津外国语大学、大连外国语大学。 近年来,全国就业市场对精通日语、法语、德语、西班牙语等专业人才的需求量开始成倍增长,这几所大学由于在语言类,翻译类等专业的顶尖优势,所以这几所大学毕业生的薪酬都特别高,所以相应的水涨船高,录取分数线也是非常的高。 39所“小985”(985工程优势学科创新平台,是在211学校中选拔的行业特色型大学) 34所 “34所"即在招收硕士研究生的过程中可以自主划定复试分数线的高校,一共有34所高校因此简称"34所”。 北京地区:清华大学、北京大学、中国人民大学、北京师范大学、北京航空航天大学、北京理工大学、中国农业大学 天津地区:天津大学、南开大学 山东地区:山东大学 南京地区:南京大学、东南大学 浙江地区:浙江大学 上海地区:同济大学、复旦大学、上海交通大学 福建地区:厦门大学 广州地区:中山大学、华南理工大学 湖南地区:湖南大学、中南大学 湖北地区:武汉大学、华中科技大学 黑龙江地区:哈尔滨工业大学 吉林地区:吉林大学 辽宁地区:东北大学、大连理工大学 安徽地区:中国科学技术大学 陕西地区:西安交通大学、西北工业大学 重庆地区:重庆大学 四川地区:四川大学、电子科技大学 甘肃地区:兰州大学 这个政策的目的是给予这些大学在招生的时候有更多的优势,能够让学校在选择人才的时候有更大的自主权。学校根据报考自己学校考生的情况和计划招生的人数来确定分数线,学校确定后上报教育部备案就可以了。 985工程 985工程,是指为创建世界一流大学和高水平大学而实施的工程,即"世界一流大学建设项目"。名称源自1998年5月4日,时任国家主席江泽民在北京大学百年校庆上建设世界一流大学的讲话。 小985 小985一般指985工程优势学科创新平台,这些高校的层次在"985"高校和一般的"211"高校之间。"985工程优势学科创新平台"项目高校从属于"211工程"建设的学校但不属于"985"工程建设的学校中选择。 “985工程优势学科创新平台"基本上是没有经历过合并重组的行业特色型大学,学科精度极高,拥有一至两个全国顶尖的学科,在行业内认可度极高,具有深厚的行业底蕴和学科积淀。只有国家中央部委直属的"211工程"高校才有资格获得"985工程优势学科创新平台”。 国防类 哈尔滨工程大学:现代舰船与深海工程优势学科创新平台 南京理工大学:现代攻防与先进装备技术优势学科创新平台 南京航天航空大学:航空飞行器设计制造与飞行安全优势学科创新平台 信息类 西安电子科技大学:先进军事综合电子信息系统优势学科创新平台+先进雷达技术优势学科创新平台 北京邮电大学:社交网络分析与网络信息传播优势学科创新平台 中国传媒大学:数学媒体技术优势学科创新平台 材料类 北京科技大学:新材料与冶金工程优势学科创新平台 武汉理工大学:绿色建材与新材料优势学科创新平台 交通类 北京交通大学:轨道交通安全优势学科创新平台 西南交通大学:国家轨道交通工程优势学科创新平台 长安大学:公路建设与交通运营保障科学与技术优势学科创新平台 化工类 华东理工大学:煤的清洁高效利用与石油化工关键技术优势学科创新平台 北京化工大学:绿色化工与材料优势学科创新平台 资源类 中国矿业大学:煤炭资源安全开采与洁净利用优势学科创新平台 中国地质大学:地球系统过程与矿产资源平台 中国石油大学:油气资源勘探开发与转化优势学科创新平台 华北电力大学:电力科学与工程优势学科创新平台 河海大学:全球水循环与国家水安全优势学科创新平台 汽车类 合肥工业大学:节能环保汽车及其制造装备技术优势学科创新平台 轻工类 江南大学:食品精深加工与安全控制优势学科创新平台 财经类 中央财经大学:经济学与公共政策优势学科创新平台 上海财经大学:经济些优势学科创新平台 中南财经政法大学:经、法、管学科融通创新与我国社会建设优势学科创新平台 西南财经大学:金融学科群与中国金融创新发展优势平台 农林类 北京林业大学:应对全球化的森林生态系统恢复重建与可持续经营优势学科创新平台 东北林业大学:森林资源可持续经营与高效利用优势学科创新平台 华中农业大学:农业生物遗传改良和生长发育调控优势学科创新平台 南京农业大学:(正式名称未公布) 西南大学:现代农业科学优势学科创新平台 人文类 暨南大学:华侨华人研究优势学科创新平台 政法类 中国政法大学:法治建设与人才培养优势学科创新平台 医药类 中国药科大学:新药发现理论与技术优势学科创新平台 北京中医药大学:中医药优势学科创新平台 211工程 “211"的含义是"21世纪的100所重点大学”,将全国各地挑选出的约100个高等学校设立为重点高校,这些学校在资金中获得优先对待。"211"诞生得比"985"要早一些,1994年开始启动预审,1996年确定第一批名单,2011年,"211工程"的规模已经稳定,共有学校112所,不再新增学校。 北京地区:北京大学、清华大学、北京师范大学、中国矿业大学(北京)、北京航空航天大学、中国农业大学、北京理工大学、中央民族大学、北京交通大学、北京工业大学、北京科技大学、北京化工大学、北京邮电大学、北京林业大学、北京中医药大学、北京外国语大学、中国传媒大学、对外经济贸易大学、中央音乐学院、中国地质大学(北京)、中国政法大学、中国石油大学(北京)、华北电力大学、中央财经大学、北京体育大学、中国人民大学 黑龙江地区:哈尔滨工程大学、哈尔滨工业大学、东北林业大学、东北农业大学 吉林地区:吉林大学、东北师范大学、延边大学 辽宁地区:东北大学、大连理工大学、辽宁大学、大连海事大学 天津地区:南开大学、天津大学、天津医科大学 河北地区:河北工业大学 山西地区:太原理工大学 内蒙古地区:内蒙古大学 上海地区:上海交通大学、复旦大学、同济大学、上海大学、第二军医大学、华东理工大学、华东师范大学、东华大学、上海外国语大学、上海财经大学 江苏地区:南京大学、东南大学、南京航天航空大学、南京理工大学、河海大学、南京农业大学、中国药科大学、南京师范大学、江南大学、中国矿业大学、苏州大学 浙江地区:浙江大学 安徽地区:中国科学技术大学、安徽大学、合肥工工业大学 福建地区:福州大学、厦门大学 江西地区:南昌大学 山东地区:山东大学、中国海洋大学、中国石油大学(华东) 河南地区:郑州大学 湖北地区:武汉地区、华中科技大学、武汉理工大学、中国地质大学(武汉)、中南财经政法大学、华中师范大学、华中农业大学 湖南地区:湖南大学、中南大学、国防科学技术大学、湖南师范大学 广东地区:华南理工大学、中山大学、暨南大学、华南师范大学 广西地区:广西大学 海南地区:海南大学 重庆地区:重庆大学、西南大学 四川地区:四川大学、电子科技大学、西南交通大学、西南财经大学、四川农业大学 贵州地区:贵州大学 云南地区:云南大学 西藏地区:西藏大学 陕西地区:西北工业大学、西安交通大学、第四军医大学、西北大学、西安电子科技大学、长安大学、西北农林科技大学、陕西师范大学 甘肃地区:兰州大学 青海地区:青海大学 宁夏地区:宁夏大学 新疆地区:新疆大学、石河子大学 注意: 保研中,不少高校只接收"211"大学的学生。 如《四川大学2013年接收校外优秀应届本科毕业生免试攻读硕士学位研究生办法》申请条件中就明文规定"学生所在学校原则上应为’211工程’及以上层次院校",这样规定的学校不在少数。 小211 小211即中西部高校基础能力建设工程,是为振兴中西部高等教育,促进中国高等教育协调发展,使中西部一批本科高校的实力得到较大提升,计划重点支持建设中西部24个省、自治区、直辖市的100所地方高校的发展建设。该"工程"从2012年开始,由发改委、教育部组织实施重点扶持一批有特色有实力的省部共建大学和省属重点大学。 综合类院校 西北大学、湘潭大学、云南大学、河南大学、河北大学、新疆大学、西藏大学、黑龙江大学、延边大学、山西大学、南昌大学、青海大学、宁夏大学、中北大学、西华大学、河南大学、吉首大学、湖北大学、长江大学 理工类院校 重庆邮电大学、昆明理工大学、燕山大学、哈尔滨理工大学、西安理工大学、长春理工大学、东北电力大学、辽宁工程技术大学、兰州交通大学、辽宁工业大学、河北工业大学、兰州理工大学、沈阳建筑大学、安徽理工大学、安徽工业大学、河南理工大学、河南工业大学、华北水利水电大学、武汉科技大学、武汉工业大学、湖北工业大学、武汉纺织大学、成都理工大学、西南石油大学、长沙理工大学、陕西科技大学、西安科技大学、西安建筑科技大学、四川理工学院、成都信息工程大学、贵州理工学院 师范类院校 河北师范大学、湖南师范大学、四川师范大学、安徽师范大学、云南师范大学、江西师范大学、河南师范大学、山西师范大学、广西师范大学、西北师范大学、贵州师范大学、新疆师范大学、内蒙古师范大学、喀什师范学院、贵州师范学院 财经类院校 哈尔滨商业大学、山西财经大学、江西财经大学、安徽财经大学、重庆工商大学 农林类院校 河北农业大学、沈阳农业大学、吉林农业大学、东北农业大学、新疆农业大学、安徽农业大学、内蒙古农业大学、江西农业大学、河南农业大学、湖南农业大学、甘肃农业大学、中南林业科技大学 医科类院校 河北医科大学、大连医科大学、哈尔滨医科大学、重庆医科大学、安徽医科大学、河南中医学院、广西医科大学、广西中医药大学、昆明医科大学、长春中医药大学、贵阳医学院、内蒙古医科大学 民族类院校 广西民族大学、青海民族大学、西藏民族大学 建设兵团 石河子大学、塔里木大学 2011计划 “2011计划"全称"高等学校创新能力提升计划”,是继全国重点大学、“211工程”、"985工程"之后,中国高等教育系统又一项体现国家意志的重大战略举措,于2012年5月7日正式启动。该计划以人才、学科、科研三位一体创新能力提升为核心任务,通过构建面向科学前沿、文化传承创新、行业产业以及区域发展重大需求的四类协同创新模式,深化高校的机制体制改革,转变高校创新方式。该计划由教育部和财政部共同研究制定、旨在突破高校内外部机制体制壁垒、释放人才、资源等创新要素活力。 中西部高校综合实力提升工程 即"一省一校",是在没有教育部直属高校的14个省份,专项支持这些14个省区域内的办学实力最强、办学水平高、有省内地区优势的高水平大学。从该工程按照内涵发展、提高质量、建设本地区"有特色、高水平"大学的要求,明确建设目标,增强办学综合实力和可持续发展能力,促进这些大学重点加强特色学科和师资队伍建设,提高人才培养质量和科学研究水平,增强为国家和区域经济社会发展服务的能力,是继省部共建大学政策之后国家推动中西部省属高校发展设立的两大工程项目之一,即"中西部高等教育振兴计划"的一部分。这14所大学分别是河北大学、郑州大学、南昌大学、云南大学、贵州大学、海南大学、青海大学、西藏大学、内蒙古大学、广西大学、宁夏大学、新疆大学、河子大学。 双一流 "双一流"建设是政府为了达到国家战略目的而实施的政策。自2015年10月国务院"双一流"建设政策文件发布以来,人们较多地关注了评选和资助,而对如何建设一流大学和一流学科则较少涉及,而且对"双一流"建设的长远性也缺少心理准备。"双一流"建设既是"211工程"和"985工程"建设的统筹和延续,也是加快实现我国高等教育现代化的必然要求和必由之路。“双一流"建设绝不只是评选和资助,其根本在于"建设”,在于大学和学科办学的改善。 一流大学建设高校42所 A类36所 北京大学、中国人民大学、清华大学、北京航空航天大学、北京理工大学、中国农业大学、北京师范大学、中央民族大学、南开大学、天津大学、大连理工大学、吉林大学、哈尔滨工业大学、复旦大学、同济大学、上海交通大学、华东师范大学、南京大学、东南大学、浙江大学、中国科学技术大学、厦门大学、山东大学、中国海洋大学、武汉大学、华中科技大学、中南大学、中山大学、华南理工大学、四川大学、重庆大学、电子科技大学、西安交通大学、西北工业大学、兰州大学、国防科技大学 B类6所 东北大学、郑州大学、湖南大学、云南大学、西北农林科技大学、新疆大学 专业选择 文科:学校 > 专业 理工科:专业 > 学校 工科 > 理科 > 文科 (基本也是赚钱能力排行) 实用专业 > 虚无专业 (有专业壁垒) 地理选择:沿海 > 中部 > 西北 (也可以说是有限经济发达地区) 张雪峰关于高考志愿的建议总结 家庭条件好,不需要考虑就业的随便报!家庭条件不好,需要赚钱养家的最好报考理工科! 生化环材天坑不能碰,哪怕是名校 金融不能碰,除非家里是搞金融的 管理类不要碰,除非家里有企业需要管理 想考公优先选汉语言文学和思政,不要选英语 想在哪儿当医生就读哪儿的医学院 文科优先选学校,理工科优先选专业 本省大学少的考生很吃亏,因为外省在本省招生的专业不多,好专业更少 数学和计算机专业都很好 工科比理科挣钱 产业更发达的省份家长更看重专业,因为家长更容易接触相关专业,知道前景如何 服从调剂一定要慎重,很有可能把你调剂到一个你完全不接受的专业 立志考研的考生一定要学好英语 城市有时候比学校更重要 为什么说生化环材是四大天坑专业呢? 首先,从化学专业着手,其主要指的是化学与制药,然后下面又分为八个专业 化学工程与工艺:就业一般都属于基础型的岗位 制药工程:用人需求大,比较好就业 资源环境科学工程:不好就业 能源化学工程:就业环境不佳,女生请慎重选择 化学工程与工业生物工程:就业面偏窄 化工安全工程:主要培养化工安全复合性人才 涂料工程:主要培养工程应用性人才 精细化工:就业面相对较广,工资待遇高 所以,为什么该专业总是被认为是天坑专业呢? 主要有以下几点原因: 本科期间学习知识面较杂,且内容枯燥偏向理论型,本科期间找好工作较难 找工作的内卷性影响 工作危险系数较高。很多实验非常危险,剧毒,爆炸等等很常见 就业环境较差 收入不高,工作时间长 优先轻资产行业,慎选重资产行业 就业市场中有一个常见的观点是,对于求职者来说,优先选择轻资产行业,而对重资产行业要慎重考虑。这观点主要基于以下几个理由: 就业机会的灵活性:轻资产行业通常指的是那些不需要大量固定资产和设备的行业,例如科技、媒体、创意产业等。这些行业往往更加灵活,能够快速适应市场变化,因此就业机会相对较多。相比之下,重资产行业如制造业、工业等可能受到市场波动和技术变革的影响较大,就业机会相对较少。 技能需求的变化:随着科技的快速发展和经济的转型,很多传统重资产行业的技能需求发生了变化。自动化和数字化技术的兴起使得许多重资产行业的劳动力需求减少。相比之下,轻资产行业更加需要具备新兴技术和创新思维的人才,这些行业对于具备相关技能的求职者更有吸引力。 创业和就业的机会:轻资产行业往往更具有创业和就业的机会。由于其较低的起始成本和灵活的运营模式,轻资产行业更容易吸引创业者和创新者,从而创造新的就业机会。而在重资产行业中,由于需求相对较少和市场竞争激烈,创业和就业机会可能相对较少。 人力 + 资本 + 土地 = 产业 资本占比越高的行业,进入门槛越高。例如机械行业,一台高精度机床几百万,绝大多数从业者一辈子的收入也买不起一台高精度机床 打工只能满足温饱,致富需要创业 互联网行业属于典型的轻资产行业,一个人一台电脑就可以创业了!可以看到最近几十年互联网行业出现的富豪,高收入人群最多! 尽管如此,重资产行业仍然在经济中扮演着重要的角色,并且为一些行业提供了稳定的就业机会。此外,个人兴趣和能力也应该是选择就业行业的重要因素之一。最重要的是,无论是选择轻资产行业还是重资产行业,不断学习和提升自己的技能都是成功就业的关键。 如何换专业 换专业很难,只有极少数人能做到 高考结束后往往面临着填报志愿,有这么一批同学会因为想要提高录取机会选择专业调剂;可是好多人读着读着发现自己对所在专业毫无兴趣,甚至开始厌学,于是内心逐渐萌生了更换专业的想法……那么问题来了,不满意当下的专业可以换专业吗?换专业有哪些要求呢?下面简单介绍一下如何换专业 是可以换专业的,在校本科生在完成大学一年级课程,进入二年级之前,每个学校都有一次换专业的机会。但如果有以下情况是不能换专业的: 1、国防生、定向生、中外合作办学类等专业的学生; 2、艺术类、体育类跨类申请换专业的学生; 3、正在休学或保留学籍的学生; 4、应予退学的学生; 5、录取时的下一批次专业向上一批次专业; 6、学分已修满教学计划规定总学分的三分之二及以上的; 7、由外校转学进入我校的学生; 8、在校期间,受过记过及以上处分的学生。 每所高校对于换专业的要求都有所不同,有的高校要求比较严格,有的高校则相对比较宽容,一般换专业条件分为以下几种: 1、不能挂科 这个要求不仅仅只针对想要换专业的同学,对于每位在校大学生都适用,所以在大学期间一定不要挂科。 2、科目分数不得低于要求 比如有些学校规定大一的某些科目不能低于多少分、要求过四级等等,这也从侧面说明同学们不要以为上大学就可以放松了,还是得持续努力学习呀。 3、准备换专业考试 有一些高校会对想要换专业的同学进行考试,首先你需要了解考哪几个科目,因为每所高校的要求不一样。 这里温馨提醒一下,一般换专业都会考高数,所以同学们一定要好好复习,争取在换专业考试中获得高分。 4、准备换专业面试 面试这一部分可以多询问一下老师的意见或者有过换专业经验的学长学姐,然后从意见、经验中多多做准备。 转专业不是逃避厌学的借口,同学们一定要考虑清楚以下弊端,再作出决定: ①转专业的名额不多,大多数同学只能继续学习当下专业; ②转专业之后,之前的学习问题不一定能迎刃而解; 国外专业满意度调查 注意这是国外的调查报告,是发达国家的产业结构决定了专业的薪酬状况。而国内产业结构不一样,具体结果也会不一样 国外一家薪资调查网站Emoulment在今年曾公布过一个调查结果**:由1800名应届毕业生评选出的,大学里最有用和最不值得读的专业。** 透过上表,可以看出最让人觉得值得的专业排名如下: 1. 化学与自然科学 2. 计算机科学 3. 数学与统计学 4. 商业与金融 经济学 现代语言学 管理学 工程学 文学 物理学、生命科学与理疗保健 法学 媒体、营销与通信 历史、地理、政治 14. 艺术与设计 15. 心理学 专业满意度最高的是化学和自然科学类专业,而在国内,化学被很多人认为是天坑专业,毕业后就业前景非常不好,市场需求的环境也还没达到。可以看出,这两者有显著差异。 满意度最高的其次是计算机科学和数学类。目前,不管在国内还是国外,计算机和数学类都是火热抢手的专业,毕业后的薪酬也是非常高,名校毕业毕业起薪一年可达$10万+。它也是名列留学生前往美国攻读的专业排名前三甲。 商业和金融,经济学等耳熟能详的学科也都是上表排行的前几名。里面的代表性专业“金融工程”,也是很多留学生的热门选择专业。 而心理学则被学生认为最不值得读。 蓝领在未来人口减少时代中崛起的机会 大学是一个很好的出路,是社会上升通道中最大,最重要的一个通道! 但大学也不是唯一的通道,很多行业就业赚钱不比白领少!路边卖早餐的比白领写字楼赚得多的多了去了! 随着全球范围内人口红利的消失,许多国家都面临着人口减少的挑战。这一趋势在未来几十年内将进一步加剧。然而,尽管人口减少会对经济和社会产生许多影响,蓝领行业却有望在这个时代崛起,并变得越来越重要。 蓝领工作通常指的是依靠体力劳动和技术技能从事制造、建筑、维修和运输等领域的工作。与之相对的是白领工作,即主要以办公室工作和知识经济为基础的职业。尽管过去几十年,白领工作一直备受瞩目,但在人口减少的时代,蓝领行业可能会迎来巨大的机遇。 首先,人口减少将导致劳动力市场的供需失衡。随着年龄人口的减少,劳动力供应将减少,这将迫使企业采取创新方法来填补这一空缺。蓝领工作需要一定的技术技能和经验,而这些技能往往需要较长时间来培养。因此,随着人口减少,对熟练的蓝领工人的需求将不断增加,他们的收入也会相应提高。 其次,蓝领行业在满足实体经济需求方面发挥着至关重要的作用。制造业、建筑业和运输业等蓝领行业是现代社会不可或缺的基础产业。无论是生产物品还是提供基础设施,都需要蓝领工人的辛勤劳动。随着人口减少,对于这些行业的需求将继续增长,从而推动蓝领工作的重要性和收入水平的提高。 第三,随着科技的发展,蓝领行业也正在发生变革。自动化和人工智能的进步正在改变许多蓝领工作的本质。虽然一些传统的蓝领工作可能会受到替代,但同时也会出现新的技术工作岗位。这将为那些愿意不断学习和适应新技术的蓝领工人创造更多机会,并进一步提高他们的收入水平。例如,随着智能制造和物联网的兴起,工厂中的机器和设备将变得更加智能化和自动化,这就需要技术熟练的蓝领工人来进行操作和维护。同时,新兴的领域如可再生能源、电动汽车和智能家居也将为蓝领工人提供新的就业机会。 在这个变革的时代,蓝领工人需要不断学习和提升自己的技能,以适应新的工作需求。政府和企业应当共同努力,提供培训和教育机会,帮助蓝领工人获取新技术和知识。此外,改善蓝领工作的待遇和工作条件也是重要的方面,以吸引更多人才进入这个行业。 总而言之,在人口减少的时代,蓝领行业将变得越来越重要,收入也有望提高。人们对于实体经济的需求以及科技发展的推动将推动蓝领工作的需求增长。对于那些愿意不断学习和适应变化的蓝领工人来说,他们将在这个时代中找到更多的机遇和发展空间。因此,我们应该积极关注和支持蓝领行业,为其发展创造更好的环境和条件,共同迎接人口减少时代的挑战与机遇。 在人口减少的未来,有几个蓝领行业可以预见到前景较好的发展机会: 技术工人:随着科技的进步和自动化的普及,对于具备技术技能的工人的需求将不断增长。例如,工业机器人操作员、机器学习工程师、网络安全专家等都是技术工人领域中前景看好的职业。这些岗位对于高度专业化和技术熟练的工人需求将会持续增加。 可再生能源技术工人:随着对环境可持续性的日益关注,可再生能源行业将迎来巨大的发展机会。太阳能和风能等可再生能源技术的安装、维护和运营将需要大量熟练的技术工人。这些领域将成为就业增长的重点,尤其是在那些鼓励可再生能源发展的地区。 建筑和基础设施工人:即使在人口减少的情况下,建筑和基础设施行业仍然将保持相对稳定的需求。城市更新、交通基础设施改善以及新建项目等都需要大量的蓝领工人。例如,电工、焊工、管道工、瓦工等在建筑和基础设施领域具备良好的就业前景。 护理和医疗领域工人:随着人口老龄化的加剧,护理和医疗领域的需求将继续增长。蓝领工人在这些领域中扮演着重要的角色,如护理助理、医疗技术员和医疗设备维修员等。对于具备相关技能和经验的人员,将会有更多的就业机会和较高的收入水平。 需要注意的是,这只是对于蓝领行业中前景较好的一些领域的简要概述,实际的就业机会和发展前景还受到地区、经济状况和技术发展等多种因素的影响。因此,建议根据当地的市场需求、发展趋势和自身兴趣与能力来选择适合的蓝领行业。 参考&致谢 为什么说生化环材是四大天坑专业呢 庄子:如何面对社会 c9名单 附赠 怎么样克服紧张 转移注意力到其他事情上几秒钟,再专注要做的事情。乒乓冠军邓亚萍的做法是开球前碰一下球桌 如何对抗杠精 不是一个问题。转移话题,偷梁换柱 国足差,杠精反驳你行你上啊 区分观点和事实 穷人别买房 是一个观点,很多人买不起房是一个事实。杠精反驳凭什么穷人不能买房,就是用一个观点来反驳事实 对事不对人 从来没有对事不对人,从来都是对人不对事。庄子有一个著名的空船效应,还有一个博弈叫做公羊博弈。预设思想阻断了你的思维。 屏蔽力 屏蔽力是一个人最顶级的能力,任何消耗你的人和事,多看一眼都是你的不对,要记住:非必要不费力证明自己,无利益不试图说服别人,这就是精神上的节能减排。 如何自我心理调节 思考一件事情最好的情况,以及最坏的情况,然后都接受它,就没有什么过不去的坎

2023/6/25
articleCard.readMore

千古奇书推荐《渔樵问对》讲述天地至理

简介 《渔樵问对》通过渔樵对话来消解古今兴亡等厚重话题,作者是邵雍,北宋儒家五子之一。邵雍学贯易理,儒道兼通,他毕生致力于将天与人统一于一心,从而试图把儒家的人本与道家的天道贯通起来。《渔樵问对》着力论述天地万物、阴阳化育和生命道德的奥妙和哲理。这本书通过樵子问、渔父答的方式,将天地、万物、人事、社会归之于易理,并加以诠释,目的是让樵者明白“天地之道备于人,万物之道备于身,众妙之道备于神,天下之能事毕矣”的道理。《渔樵问对》中的主角是渔父,所有的玄理都出自渔父之口,在书中,渔父已经成了“道”的化身。 视频讲解 B站 .bbplayer{width: 100%; max-width: 850px; margin: auto} document.getElementById("mmedia-PmdHfwBTfMOquYYw").style.height=document.getElementById("mmedia-PmdHfwBTfMOquYYw").scrollWidth*0.76+"px"; window.onresize = function(){ document.getElementById("mmedia-PmdHfwBTfMOquYYw").style.height=document.getElementById("mmedia-PmdHfwBTfMOquYYw").scrollWidth*0.76+"px"; }; youtube --> https://www.youtube.com/playlist?list=PLSN0MEj6VCi5dW305S68IfCTBOeOSEuOv youtube这个是机器朗读,质量比较差,但内容比较全,注意是个视频列表,右上角选择 作者生平 邵雍先生渔樵问对真是千古奇文,不读懂很遗憾《渔樵问对》的作者是邵雍。先介绍一先生。邵雍的一生,可以用神秘、传奇来形容。 百度百科这样描述邵雍: 邵雍(1011年12月25日—1077年7月5日),字尧夫,谥康节,北宋理学家、数学家、诗人,生于林县上杆庄(今河南林州市刘家街村邵康村,一说生于范阳,即今河北涿州大邵村),与周敦颐、张载、程颢、程颐并称“北宋五子”。随父徙卫州共城(今河南辉县),居城西北苏门山,刻苦为学。出游河、汾、淮、汉,少有志,喜刻苦读书并游历天下,并悟到“道在是矣”,而后师从李之才学《河图》《洛书》与伏羲八卦,学有大成,并著有《皇极经世》《观物内外篇》《先天图》《渔樵问对》《伊川击壤集》《梅花诗》等。 天圣四年(1026年),邵雍十六岁,随其父到共城苏门山,卜居于此地。宋仁宗康定元年(1040年),邵雍三十岁,游历河南,因将父母葬在伊水(河南境内南洛水支流)之上,遂而成为河南(今河南洛阳)人。宋仁宗皇祐元年(1049年)定居洛阳,以教授为生。嘉祐七年(1062年),移居洛阳天宫寺西天津桥南,自号安乐先生、伊川翁等,出游时必坐一小车,由一人牵拉。宋仁宗嘉祐与宋神宗熙宁初,两度被举,均称疾不赴。熙宁十年(1077年)病卒,终年六十七岁。宋哲宗元祐中赐谥康节。据说邵雍从小爱好读书,除了儒家经典,什么医卜星象、算数农学等等,啥书也读,是一个读书狂。但是教书先生却看不上他,因为作为儒生的教书先生,不能容忍他学习儒学之外的东西。邵雍胸怀大志,希望游历天下,洞察人间,不希望入朝为官,所以被教书先生赶出了学堂。十六岁那年,邵雍背上行囊,跋山涉水,游历人间。据说邵雍读《易经》三十年,基本生活靠好友,北宋著名文人 司马光接济,勉强度日。邵雍在《梅花易数》一书中写到:“冬不炉,夏不扇。盖心于《易》,忘乎其为寒暑也”,描述了邵雍读易三十年的艰辛和学易的感受。 讲个看来的故事: 宋仁宗皇佑元年冬日的一天,在洛阳城的一个梅园里面,有一群地位显赫的人正在观赏梅花,这些人中有当朝宰相富弼、司马光等等。其中有一位与众不同,麻衣草鞋、竹杖酒壶,器宇非凡、仪态大方。高官毕恭毕敬,众星捧月一样围绕着这个人缓缓前行。人群走到梅花树下,这个人抬头观望,树梢两只麻雀在争夺一支梅花,忽然双双坠地。司马光和其他人对视了一眼,小心翼翼的问道:“敢问先生可是看出来什么?”这个人思考了片刻笑着说道:“明天晚上将有一位少女来这偷折梅花,却被看园子的人发现,慌忙逃走的时候将不幸摔倒在这里,不过并没有什么大碍,只是伤了膝盖而已。”惊奇的是,第二天这一切都发生了。高官们连连赞叹,拜访这位高人。有位高官问道:“先生!你怎么能算那么准?”。先生说道:“不才苦研《易经》几十年,受先师指点,自创占术一门。昨天乃首次起卦,让各位见笑了”。高官惊奇问道:“自先古以来,都是用龟甲、蓍草等起卦,还是第一次听说可以自创卦术,不知先生这个卦术的可有名字?”,先生说道:“既然初次因为梅花起卦,就叫他梅花易数吧”。 这就是著名的梅花易数。这位高人就是著名的哲学家、易学家、理学家、数学家、诗人----邵雍。看看邵雍的成就吧。《皇极经世》、《观物内外篇》、《渔樵问对》、《梅花诗》等。其中《梅花诗》被后人视为一首预言诗,并称其成功预言了北宋南宋以及元明清的历史。感兴趣的看官可以百度,这里不说了。邵雍有诗集传世,里面的诗简单但内涵丰富,读起来朗朗上口又蕴含着无穷的意境。看他的一首《山村咏怀》:一去二三里,烟村四五家。亭台六七座,八九十枝花。这首诗,囊括了十个数字,简单有趣,见诗如画,描绘的场景象小山村,又很像仙境。可见邵雍的境界与心胸。 公元1077年,邵雍将自己的好友司马光等叫到床前说:“我可能快要到另一个世界了,关于我的后事,你们记一下。一、我死后要埋在伊川,那是我父母去世的地方;二,墓志铭要让程颢、程颐兄弟去写;第三,我的寿衣要用油浸泡,不要任何财物陪葬,棺材里给我放一个轱辘头当枕头。”说后就阖然辞世。众人按照遗嘱把他安葬,据说出殡的那天,他的棺椁异常的沉重,可是当棺椁快到墓穴的时候,这棺材就突然变轻了,里面还有轱辘头转动的声音。众人非常害怕,这时里面的一位老人却说:“康节先生~飞升登仙了~”邵雍生于1011年,卒于1077年,享年66周岁。他的一生,正好是北宋澶渊之盟之后宋辽近百年无战争的太平年代。因此,在生命最后一年,邵雍用一首诗对自己的一生做了总结:生于太平世,长于太平世。老于太平世,死于太平世。客问年几何,六十有七岁。俯仰天地间,浩然无所愧。——邵雍《病亟吟》还有一首诗,是写邵雍的: 苦研死经三十载,不似赤竹扫心宅。 堪破世间穷通理,一身道行求自在。 《渔樵问对》是邵雍假托一位樵夫和渔夫的对话,来阐述他对这个世界的认知。邵雍学贯易理,儒道兼通,毕生致力于将天与人统一于一心,试图把儒家的人本与道家的天道贯通起来。《渔樵问对》就是这样一部论述天地万物、阴阳化育和生命道德的奥妙和哲理的文章。通过樵子问、渔父答的方式,将天地、万物、人事、社会归之于易理,并加以诠释,目的是让樵者明白“天地之道备于人,万物之道备于身,众妙之道备于神,天下之能事毕矣”的道理。《渔樵问对》中的主角是渔父,所有的玄理都出自渔父之口,在书中,渔父已经成了“道”的化身。 《渔樵问对》“天地之道备于人,万物之道备于身,众妙之道备于神,天下之能事毕矣” 摘选易道洞见 前言《渔樵问对》通过渔樵对话来消解古今兴亡等厚重话题,作者是邵雍,北宋儒家五子之一。邵雍学贯易理,儒道兼通,他毕生致力于将天与人统一于一心,从而试图把儒家的人本与道家的天道贯通起来。《渔樵问对》着力论述天地万物、阴阳化育和生命道德的奥妙和哲理。这本书通过樵子问、渔夫答的方式,将天地、万物、人事、社会归之于易理,并加以诠释,目的是让樵者明白“天地之道备于人,万物之道备于身,众妙之道备于神,天下之能事毕矣”的道理。《渔樵问对》中的主角是渔夫,所有的玄理都出自渔父之口,在书中,渔父已经成了“道”的化身。 对照翻译 【原】渔者垂钓于伊水之上。樵者过之,弛担息肩,坐于磐石之上,而问于渔者,曰:“鱼可钩取乎?” 【译】渔夫在伊水上垂钓。有一樵者路过,放下柴担休息,坐在大石头上,问鱼者:“能钓到鱼吗?” 【注】独苏山又西二百里,曰蔓渠之山,其上多金玉,其下多竹箭。伊水出焉,而东流注于洛。 【原】曰:“然。” 【译】渔夫答:“能。” 【原】曰:“钩非饵可乎?” 【译】樵夫问:“鱼钩上不放鱼饵能钓到吗?” 【原】曰:“否。” 【译】渔夫答:“不能。” 【原】曰:“非钩也,饵也。鱼利食而见害,人利鱼而蒙利,其利同也,其害异也。敢问何故?” 【译】樵者问:“钓到鱼不是鱼钩而是鱼饵,可见鱼是因为吃食而被害,人却因能吃鱼而获利,都是因为吃,为自己谋利,而结果却大不一样。请问这是为什么?” 【原】渔者曰:“子樵者也,与吾异治,安得侵吾事乎?然亦可以为子试言之。彼之利,犹此之利也;彼之害,亦犹此之害也。子知其小,未知其大。鱼之利食,吾亦利乎食也;鱼之害食,吾亦害乎食也。子知鱼终日得食为利,又安知鱼终日不得食为害?如是,则食之害也重,而钩之害也轻。子知吾终日得鱼为利,又安知吾终日不得鱼而为害也?如是,则吾之害也重,鱼之害也轻。以鱼之一身,当人之一食,则鱼之害多矣;以人之一身,当鱼之一食,则人之害亦多矣。又安知钓乎大江大海,则无易地之患焉?鱼利乎水,人利乎陆,水与陆异,其利一也;鱼害乎饵,人害乎财,饵与财异,其害一也。又何必分乎彼此哉!子之言,体也,独不知用尔。 【译】渔夫说:“先生是打柴的,和我从事捕鱼不一样,又怎么能知道我的事呢?然而我可以试着给你说说。鱼的利益的和我的利益的是一样的,鱼的祸害和我的祸害也是一样的。你只知道了其中的微小的一面,没有知道整体情况。鱼因为获得食物而受益,我也受益于得到了食物【从自身来看】,鱼同样因为得到了食物而受损害,我也受损害于得到了食物【这是从本身之外来看】。你只知道鱼因为终日有食吃而获利,又怎知鱼若终日无食吃而为害呢?如此,食物的害处太重了,而被渔夫钓的害处相对却轻了。你只知我终日钓到鱼而为获利,又怎知我若终日钓不到鱼而受损害呢?如此,我受到害相对重一些,而鱼受到的害相对却轻了。若以鱼为本,人吃鱼,则鱼受到了伤害;若以人为本,以鱼为食,人无食吃则人受到了伤害。要知道在大江大海里钓鱼,换位思考一下,,一旦钓不到鱼是多么的危险?鱼在水里是有利的,人在陆地上是有利,水与陆地不同,但是有利这一方面是一样,当然看对谁。鱼因为鱼饵被害,人因为财物而被害,鱼饵与财物不同,但它们的害处一样,又何必分彼此呢!你说的,只是事物的体,而不知事物的用。” 【按】任何事物都要辨证来看,世事无绝对。同样的事情对不同的人,利害损益是不同的。因此对于某人的观点,不要忙着肯定和否定,要知道他发出观点的语境,不要断章取义。如同股市涨跌预测,实际上没有什么意义。只代表个人的观点而已。 【按】飞熊入梦,文王渭水访姜尚。姜太公渭水河边的,直钩,无饵,非钓鱼,而是钓文王,也是钓天下。为何无害,愿者上钩,顺天。 【原】樵者又问曰:“鱼可生食乎?” 【译】樵者又问:“鱼能生吃吗?”【变态的日本人不算】 【原】曰:“烹之可也。” 【译】渔夫答:“煮熟之后可以吃。” 【原】曰:“必吾薪济子之鱼乎?”【译】樵夫问:“那必然要用我的柴来煮你的鱼了?” 【原】曰:“然。“ 【译】渔夫答:“那是当然。” 【原】曰:“吾知有用乎子矣。” 【译】樵夫说:“我就知道我砍得柴对你非常有用啊” 【原】曰:“然则子知子之薪,能济吾之鱼,不知子之薪所以能济吾之鱼也。薪之能济鱼久矣,不待子而后知。苟世未知火之能用薪,则子之薪虽积丘山,独且奈何哉?” 【译】渔夫说:“你呀,你只知道你的柴能煮我的鱼,但你不知道你的柴为什么能煮我的鱼。用柴煮鱼的方法早就有了,在有之前人们就知道,可世人却不知道柴的作用是火。如果柴没有火的作用,你砍得柴就是堆积如山又有何用呢。” 【原】樵者曰:“愿闻其方。” 【译】樵者说:“愿意听你说其中的道理。” 【原】曰:“火生于动,水生于静。动静之相生,水火之相息。水火,用也;草木,体也。用生于利,体生于害。利害见乎情,体用隐乎性。一性一情,圣人能成子之薪。犹吾之鱼,微火则皆为腐臭败坏,而无所用矣,又安能养人七尺之躯哉?” 【译】渔夫说:“火生于动,火为阳,阳生于动,水生于静,水属阴,阴生于静。动静相生,水火相息。阴阳相生相制,水火为用,草木为体。火之用因为草木而得利,草木之体因为火的用而被害。利与害表现在情感上,体与用隐藏于性情中。一性一情【天性是隐的,情志活动时显的】,只有圣人才懂得柴与火的道理,所以能用。像我的鱼,如果没有用火烧煮,就会腐臭烂掉,不能吃了,又怎能养人的身体呢?” 【按】阴符经有云,火生于木,祸发必克。性情,一个为阳,一个为阴,一个为体,一个为用,性于人于圣无异,众生皆有佛性,但情却各异,皆是因为不知体用。自性不见。情本无差,万物皆有用,关键知不知用。 【原】樵者曰:火之功大于薪,固已知之矣。敢问善灼物,何必待薪而后传? 【译】樵者问:火的作用大于柴,这个我已经知道了。再问一下,火本身就可以烧物,为什么还要依赖木柴呢? 【原】曰:薪,火之体也。火,薪之用也。火无体,待薪然后为体;薪无用,待火然后为用。是故凡有体之物,皆可焚之矣。 【译】渔夫答:柴是火的体,火是柴的用。火本无体,只有借助柴才有体。柴本身无用,只有待火烧起后才能有用。因此,凡是有体的物体,都可以燃烧。 【按】焚,不一定会生出燃烧的火,但一定会损毁。例如黄金,熔点是1064.43℃,沸点是2808℃,没有燃点,当达到熔点则液态,金生水。当达到沸点,则气化。无形了。 【原】曰:“水有体乎?” 【译】樵者问:“水有体吗?” 【原】曰:“然。” 【译】渔夫答:“有。” 【原】曰:“火能焚水乎?“ 【译】樵者问:“水能燃烧?” 【原】曰:“火之性,能迎而不能随,故灭。水之体,能随而不能迎,故热,是故有温泉而无寒火,相息之谓也。” 【译】渔夫答:“火的性质,遇水后能与之对立而不能与之相随,所以火就灭了。水的性质,遇火后能与之相随而不能与之相对立,所以水就热了。因此有热水而无凉火,是因为水火相息的原因。” 【按】张景岳《类经图翼·五行统论》:惟是水中之火,人多不知,而油能生火,酒能生火,雨大生雷,湿多成热,皆是也。且火为阳生之本,虽若无形,而实无往不在,凡属气化之物,非火不足以生。火本阳也,而萧丘之焰则寒。 葛洪 《抱朴子·论仙》:“水性纯冷,而有 温谷 之汤泉;火体宜炽,而有 萧丘 之寒焰。 李时珍《本草纲目·火·阳火阴火》:“此外又有 萧丘之寒火,泽中之阳焰,野外之鬼磷,金银之精气,此皆似火而不能焚物者也。 此皆医家之寒火,要用意解。主要是说明五行之间互藏,互生,互克。火为君,水为臣,明臣可为君,君不可为臣,此言差矣,君当然也可为臣,故可见医家之五行更加玄妙深奥,虽萧丘之说不可察,未必可信,但却是有道理。 【原】曰:“火之道生于用,亦有体乎?” 【译】樵者问:“火的功能是用,它有体吗? 【原】曰:“火以用为本,以体为末,故动。水以体为本,以用为末,故静。是火亦有体,水亦有用也。故能相济,又能相息,非独水火则然,天下之事皆然。在乎用之何如尔。” 【译】渔夫答:“火以用为始,以体为终,所以火是动的。水以体为始,以用为终,所以水是静的。因此,火有体,水有用,二者既相济又相息。不止水火,天下的事物都如此,就在于你如何应用。” 【按】体和用不但是哲学上的两个概念,而且本身也是相济相息的,事物的体一旦发挥了作用,则体必逐渐消亡,如同能量守恒,火为体,一旦作用,产生光和热,最终火就熄了。 【原】樵者曰:“用可得闻乎?” 【译】樵者问:“用具体是怎么回事儿,能请你讲给我听听吧?” 【原】曰:“可以意得者,物之性也。可以言传者,物之情也。可以象求者,物之形也。可以数取者,物之体也。用也者,妙万物为言者也,可以意得,而不可以言传。” 【译】渔夫答:“通过意得到的,是事物的本性;通过语言传授的,是事物的外在表现;通过眼睛观察的,是事物的形状;通过数量计算的,是事物的体量。以上这些都属于属性一类。而用,可以阐述万事万物的奥妙,但只可意会,而不能言传。” 【原】曰:“不可以言传,则子恶得而知之乎?” 【译】樵夫问:“既然不可以言传,那你又如何知道的?” 【按】恶,文言叹词,表示惊讶。 【原】曰:“吾所以得而知之者,固不能言传,非独吾不能传之以言,圣人亦不能传之以言也。” 【译】渔夫答:“我就是知道它,但不能用言语来说明,而且并非我一人不能言传,圣人也不能用语言来传授。” 【原】曰:“圣人既不能传之以言,则六经非言也耶?” 【译】樵夫问:“圣人都不能用语言来传授,难道六经不是用语言传授?” 【按】《诗》《书》《礼》《易》《乐》《春秋》的合称。《乐经》焚于秦。所以现在为四书五经。 【原】曰:“时然后言,何言之有?” 【译】渔夫答:“那是后人经过思考后编写,这哪里是圣人的言语?” 【原】樵者赞曰:“天地之道备于人,万物之道备于身,众妙之道备于神,天下之能事毕矣,又何思何虑!吾而今而后,知事心践形之为大。不及子之门,则几至于殆矣。” 【译】樵者赞叹说:“天地的道理具备于人,万物的道理具备于身,变化的道理具备于神,天下的各种道理都具备了,还有什么可思虑的!我从今天开始,才知道认识一件事物的要用心意来理解才是最重要的,和先生比起来,我还未得门而入,已经妄活快一辈子了。” 【原】乃析薪烹鱼而食之饫,而论《易》。 【译】于是,樵者解开柴生火煮鱼。二人吃饱了后而论《易》。 【原】渔者与樵者游于伊水之上。渔者叹曰:“熙熙乎万物之多,而未始有杂.吾知游乎天地之间,万物皆可以无心而致之矣。非子则孰与归焉?” 【译】渔夫、樵夫二人游于伊水之上。渔者感叹说:“世上万物之多,没头没尾,纷杂繁乱。我因为知道,所以在天地之间悠然自得,对于万事万物可以无心了解而自然而然的知道他们。并不是象你熟悉的那样简单。” 【按】庄子齐物论,有始也者,有未始有始也者,有未始[有]夫未始有始也者。有有也者,有无也者,有未始有无也者,有未始[有]夫未始有无也者。 【原】樵者曰:“敢问无心致天地万物之方?” 【译】樵者问:“请问如何以无心来了解万物?” 【原】渔者曰:“无心者,无意之谓也。无意之意,不我物也。不我物,然后定能物物。” 【译】渔夫答:“无心就是无意,当你可以不用意识,下意识,潜意识来观察事物,那个就是觉悟的自性。那个阶段可以没有我没有物,物我不分,然后世间万物融会贯通,心目所视,物现究竟。” 【原】曰:“何谓我,何谓物?” 【译】樵者问:“什么是我?什么是物?” 【原】曰:‘以我徇物,则我亦物也;以物徇我,则物亦我也。我物皆致,意由是明。天地亦万物也,何天地之有焉?万物亦天地也,何万物之有焉?万物亦我也,何万物之有焉?我亦万物也,何我之有焉?何物不我?何我不物?如是则可以宰天地,可以司鬼神。而况于人乎?况于物乎?” 【译】答:“以万物为标准,则我也是物。以我为标准,则万物也是我。我与物一样,则道理简单明了。天地也是万物,万物也是天地;我也是万物,万物也是我;哪里有什么我?什么物不是我,我同样也可以化为任何物。我与万物之间可以相互转换。如此可以主宰天地,号令鬼神。更何况于人?何况于物?” 【按】七十二般变化是虚词,人们喜欢看神话小说,喜欢树立一个神偶像。岂不知,人人皆可变化,偶像并非神。意会。 图片 【原】樵者问渔者曰:“天何依?” 【译】樵者问:“天依靠什么?” 【原】曰:“依乎地。” 【译】渔夫答:“天依靠于地。” 【按】天和地是相对,正如我们做股票的天地人,天外有天,地下还有地。大盘指数不可能跌成0,但股票是有可能退市的。定位也就是道氏折转,龙珠的位置就是定的太极,无论什么级别,龙珠一定,则下面的低点为相对的地,前期的高点为相对的天。离地近则相对属于安全区域。中国古人很早就知道地球只不过是宇宙(虚空)中的一个星球,和月亮一样。 【原】曰:“地何附?” 【译】问:“地依赖于什么?” 【原】曰:“附乎天。” 【译】渔夫答:“地依赖于天。” 【原】曰:“然则天地何依何附?” 【译】樵夫问:“那天地又依附于什么?” 【原】曰:“自相依附。天依形,地附气。其形也有涯,其气也无涯。有无之相生,形气之相息。终则有始,终始之间,其天地之所存乎?天以用为本,以体为末;地以体为本,以用为末。利用出入之谓神,名体有无之谓圣。唯神与圣,能参乎天地者也。小人则日用而不知,故有害生实丧之患也。夫名也者,实之客也;利也者,害之主也。名生于不足,得丧于有余。害生于有余,实丧于不足。此理之常也。养身者必以利,贪夫则以身循利,故有害生焉。立身必以名,众人则以身循名,故有实丧焉。窃人之财谓之盗,其始取之也,唯恐其不多也,及其败露也,唯恐其多矣。夫贿之与赃,一物也,而两名者,利与害故也。窃人之美谓之徼,其始取之也,唯恐其不多也。及其败露,唯恐其多矣。夫誉与毁,一事也,而两名者,名与实故也。凡言朝者,萃名之地也;市者,聚利之地也。能不以争处乎其间,虽一日九迁,一货十倍,何害生实丧之有耶?是知争也者,取利之端也;让也者,趋名之本也。利至则害生,名兴则实丧。利至名兴,而无害生实丧之患,唯有德者能之。天依地,地附天,岂相远哉!” 【译】渔夫答:“相互依附。天依靠于地形,地依赖于天气。地形有边,但天气(虚空)无边际。有与无相生,形与气相息。又开始就有结束,有结束就有开始,永无停息。天与地就存在于终始之间。天以它的用为主,体为次;地以它的体为主,用为次。用的表现称作神,体的有无称作圣。掌握了这个神和圣,才能领悟天地的变化。(小人对应圣人)老百姓们天天都在应用而不知道其中的本质,所以有灾害产生利益丧失。【表面上趋利避害,实际上常常是错误的决策和做法,导致了祸患】名象是次要的,本质才是重要的。一般人看到的所谓利益才是害人的主体。名象的产生于不足,利益丧失于有余。危害产生于有余,实际丧失于不足。这些都是常理。生活于世必须有物质基础保证,故贪婪的人时时寻找利益,因此有危害产生。想出人头地必须有名,故世人都争强好胜,追名逐利导致的后果就是,得到了用而失去了体。【要知体用相息相随,有用则伤体,用极则亡体】偷窃人财物称之为盗。偷盗之时,唯恐东西偷的少,等到败露后,又恐东西多定罪大。受贿与收贿,都是一种物品,可却是两种名称,是因为利与害的不同。窃人美名时存在侥幸心理,偷时嫌少,逮时嫌多。名誉的兴与毁,虽然是一件事,可却有两种结果,是因为得到或丧失的不同。能够得到利益,又能够获得名誉,而且还能够保证不伤实体,无祸害害相随,这只有重德者才能达到。天依靠于地,地依赖于天,其中的含义多么深远!” 【原】渔者谓樵者曰:“天下将治,则人必尚行也;天下将乱,则人必尚言也。尚行,则笃实之风行焉;尚言,则诡谲之风行焉。天下将治,则人必尚义也;天下将乱,则人必尚利也。尚义,则廉让之风行焉;尚利,则攘夺之风行焉。三王,尚行者也;五霸,尚言者也。尚行者必入于义也,尚言者必入于利也。义利之相去,一何如是之远耶?是知言之于口,不若行之于身,行之于身,不若尽之于心。言之于口,人得而闻之,行之于身,人得而见之,尽之于心,神得而知之。人之聪明犹不可欺,况神之聪明乎?是知无愧于口,不若无愧于身,无愧于身,不若无愧于心。无口过易,无身过难,无身过易,无心过难。既无心过,何难之有!吁,安得无心过之人,与之语心哉!” 【译】渔夫接着对樵夫说:“天下将要治理的时候,人民必然崇尚行动;天下将要叛乱的时候,人民必然崇尚言论。崇尚行动,则诚实踏实之风盛行;崇尚言论,则诡诈之风盛行。天下将要治理的时候,人民必然崇尚仁义;天下将要叛乱的时候,人民必然崇尚利益。崇尚仁义,则谦虚之风盛行;崇尚利益,则争夺之风盛行。三王时代,人民崇尚行动;五霸时代,人民崇尚言论。崇尚行动必注重于仁义,崇尚言论必注重于利益。仁义与利益相比,相差的有多么远?所以言出于口,不如行之于身,行之于身,不如尽之于心。言论出于口,人得以听到;行动在于身体,人得以见到;尽职于心,神得以知道。人的聪明不可以欺骗,更何况神的聪明?因此无愧于口,不如无愧于身,无愧于身,不如无愧于心。无愧于身比无愧于口难;无愧于心比无愧于身难。如果内心都无过错,还有什么灾难!唉!那里找无心过的人,与之交心谈畅!” 【原】渔者谓樵者曰:“子知观天地万物之道乎?” 【译】渔者问:“你知道观察天地万物的道理吗?” 【原】樵者曰:“未也。愿闻其方。” 【译】樵者说:“不知道。愿听你讲。” 【原】渔者曰:“夫所以谓之观物者,非以目观之也,非观之以目,而观之以心也;非观之以心,而观之以理也。天下之物,莫不有理焉,莫不有性焉,莫不有命焉。所以谓之理者,穷之而后可知也;所以谓之性者,尽之而后可知也;所似谓之命者,至之而后可知也。此三知也,天下之真知也,虽圣人无以过之也。而过之者,非所以谓之圣人也。夫鉴之所以能为明者,谓其能不隐万物之形也。虽然鉴之能不隐万物之形,未若水之能一万物之形也。虽然水之能一万物之形,又未若圣人之能一万物情也。圣人之所以能一万物之情者,谓其圣人之能反观也。所以谓之反观者,不以我观物也。不以我观物者,以物观物之谓也。又安有我于其间哉?是知我亦人也,人亦我也。我与人皆物也。此所以能用天下之目为己之目,其目无所不观矣。用天下之耳为己之耳,其耳无所不听矣。用天下之口为己之口,其口无所不言矣。用天下之心为己之心,其心无所不谋矣。夫天下之观,其于见也,不亦广乎!天下之听,其于闻也,不亦远乎!天下之言,其于论也,不亦高乎?天下之谋,其于乐也,不亦大乎!夫其见至广,其闻至远,其论至高,其乐至大,能为至广、至远、至高、至大之事,而中无一为焉,岂不谓至神至圣者乎?非唯吾谓之至神至圣者乎,而天下谓之至神至圣者乎?非唯一时之天下谓之至神至圣者乎,而千万世之天下谓之至神圣者乎?过此以往,来之或知也已。” 【译】渔者说:“所谓观物,并非以眼观物;而是以心观物,其实也不是用心观物,而是以道和理观物。【这点就很重要了,你的道是否天道,决定了你观察事物的结果,强盗不会认为抢劫财务是错误的,因为强盗自有强盗理论】天下万物的存在,都有它的道理、本性和命运。所以以理观物,研究以后可以知道;以本性观物,观察以后可以知道;以命观物,推算以后可以知道。此三知,才是天下的真知,就连圣人也无法超过。超出此三知,也就不能称为圣人。鉴别万物而能成为明白的人,是因为能不隐瞒万物的形状;虽然能鉴别而不隐瞒万物的形状,但不如水能化成万物的形状;虽然水能化成万物的形状,又不如圣人能模仿万物的性情。圣人之所以能模仿万物的性情,在于圣人能反观其物。所谓反观其物,就是不以我观物。不以我观物,而是以物观物。既然以物观物,我又怎么会在俩物之间呢?因此我也是人,人也是我,我与人都是物。【同理心是一个低层次的应用,老吾老,幼吾幼,无非如此而已,更高层次则,观天之道,执天之行,无心,无分别心,无同理心】这样才能用天下人的目为我目,则无所不见;用天下人的耳为我耳,则无所不闻;用天下人的口为我口,则无所不言;用天下人的心为我心,则无所不谋。如此观天下,所见多么广阔!所闻多么深远!所论多么精辟!所谋多么详密!如此所见至广,所闻至远,所论至精,所谋至密,其中无一不明,岂不是至神至圣?并非我一人称为至神至圣,而是天下的人都称之为至神至圣。并非一时天下人称之为至神至圣,几千万年以后天下人仍称之为至神至圣。长此以往,都是如此。” 【有情无情的众生皆具佛性,何为佛性,觉悟的自性。】 图片 【原】樵者问渔者曰:“子以何道而得鱼?” 【译】樵者问渔夫:“ 你如何钓到鱼?” 【原】曰:“吾以六物具而得鱼。” 【译】渔夫答:“我用六种物具钓到鱼。” 【原】曰:“六物具也,岂由天乎?” 【译】樵者问:“六物具备,就能钓到鱼吗?” 【原】曰:“具六物而得鱼者,人也。具六物而所以得鱼者,非人也。” 【译】渔夫答:“六物具备而钓上鱼,还需要人力所为。六物具备也可能钓不上鱼,那就不是人力所为。” 【原】樵者未达,请问其方。 【译】樵者不明白,继续问其中的道理。 【原】渔者曰:“六物者,竿也,纶也.浮也,沉也,钩也,饵也。一不具,则鱼不可得。然而六物具而不得鱼者,非人也。六物具而不得鱼者有焉,未有六物不具而得鱼者也。是知具六物者,人也。得鱼与不得鱼,天也。六物不具而不得鱼者,非天也,人也。” 【译】渔夫说:“六物,鱼杆、鱼线、鱼漂、鱼坠、鱼钩、鱼饵。有一样不具备,则钓不上鱼。然而有六物具备也有钓不上鱼的时候,这不是人的原因。有六物具备而钓不上鱼的时候,但没有六物不具备而钓上鱼的时候。因此具备六物,是人力可为。钓上钓不上鱼,是天意。六物不具备而钓不上鱼,不是天意是人力。” 【按】得之我幸,失之我命,但并非消极的宿命论,你有没准备好能够得到的条件,六物是否具备了?大多数时候,人们怨天尤人,其实仔细想想原因还在自己努力不够。如同我初入股市,准备就不很充分。再有,3、4月份跑输大盘,不是没有原因的,天天安慰我,说是因为仓位轻。其实不然,仓位策略我并不认为错了,错在配置,个股板块轮动节奏的把握。例如卫星导航,军工板块是关注很久的。但没有及时调仓,如果做到了,3成仓一样跑赢大盘。但也没什么,宿命论积极的意义就是不执著,有些时候是有运气的,例如打新股。能够接受打新股不中,为什么不能接受板块节奏没踏准。虽然有区别,因为通过学习和充分准备,是可以做到把握节奏。但从心理上是无区别的。 任何事物都是因缘际会才可产生,成长,发展,最终灭亡的。 【原】樵者曰:“人有祷鬼神而求福者,福可祷而求耶?求之而可得耶?敢问其所以。” 【译】樵者问:“有人祈祷鬼神而求福,福可以通过祈祷而求到吗?如果能通过祈祷得到,是什么原因?” 【原】曰:“语善恶者,人也;福祸者,天也。天道福善而祸淫,鬼神岂能违天乎?自作之咎,固难逃已;天之灾,禳之奚益?修德积善,君子常分。安有余事于其间哉!” 【译】渔夫答:“人的言行有善有恶,这是人自己造成的;福与祸,则是天的结果。天的规律是福善灾恶【得道多助,失道寡助】,鬼神也不能违背天理?自己做的坏事,岂能逃避,天网恢恢,疏而不漏。上天降下的灾祸,祈祷又有什么用?修德积善,是君子的本分。这样做就不会有灾祸来找!” 【按】天道无亲,损有余而补不足。天作孽犹可活,自作孽不可活。修善积德,是本分,不一定有福报,但至少问心无愧。所谓的鬼,无非是亏心了。 【原】樵者曰:“有为善而遇祸,有为恶而获福者,何也?” 【译】樵者问:“有行善的而遇祸,有行恶的而获福。为什么?” 【原】渔者曰:“有幸与不幸也。幸不幸,命也;当不当,分也。一命一分,人其逃乎?” 【译】渔夫答:“这是有幸与不幸之分。幸与不幸,是命。遇与不遇,是分。命与分,人怎么能逃避?” 【原】曰:“何谓分?何谓命?” 【译】樵者问:“什么是分?什么是命?” 【原】曰:“小人之遇福,非分也,有命也;当祸,分也,非命也。君子之遇祸,非分也,有命也;当福,分也,非命也。” 【译】答:“做坏事的人遇到福报,不是分是命,遇祸是分不是命。有德行的好人遇到灾祸,是命不是分,遇福是分不是命。” 【原】渔者谓樵者曰:“人之所谓亲,莫如父子也;人之所渭疏,莫如路人也。利害在心,则父子过路人远矣。父子之道,天性也。利害犹或夺之,况非天性者乎?夫利害之移人,如是之深也,可不慎乎?路人之相逢则过之,固无相害之心焉,无利害在前故也。有利害在前,则路人与父子,又奚择焉?路人之能相交以义,又何况父子之亲乎!夫义者,让之本也;利者,争之端也。让则有仁,争则有害,仁与害,何相去之远也!尧、舜亦人也。桀、纣亦人也,人与人同而仁与害异尔,仁因义而起,害因利而生。利不以义,则臣弑其君者有焉,子弑其父者有焉。岂若路人之相逢,一目而交袂于中逵者哉!” 【译】渔者对樵者说:“人与人的感情最亲的,莫过于父子;人与人的感情最疏远的莫过于路人,如果利与害在心里,父子之间就会像路人一样远,父子之间的亲情,属于天性,利与害都能夺掉,更何况不是天性的。利与害能够带给人们灾祸,如此之深,不能不谨慎!路人相遇擦肩而过,并无相害之心,是因为没有利与害的关系。若有利与害的关系,路人与路人、父与子之间又如何选择呢?路人若能以义相交,又何况父子之亲呢!所谓义,是谦让之本。而利益是争夺之端。谦让则有仁义,争夺则有危害。仁义与危害相去甚远。尧、舜是人,桀、纣也是人。人与人同,而仁义与危害却不同。仁慈因义气而起,危害因利益而生。利益不会因义气而争夺,否则不会有臣杀君、子杀父之事。路人相逢,也不可能因一眼而情投意合。” 【按】不争谓仁,夫唯不争,天下莫能与之争。谦让是美德,但谦让也可以是手段,这是截然不同的。陶谦三让徐州,刘备三推,貌似谦让,实际上是装。是谨慎。是保身。并非真心实意。还有荆襄刘表,也是如此。真的谦让和假的谦让看上去没什么分别,实际上区别大了。正如骄傲和自负等等。山水是不一样的山水。 【原】樵者谓渔者曰:“吾尝负薪矣,举百斤而无伤吾之身,加十斤则遂伤吾之身.敢问何故?” 【译】樵者问渔者:“我经常背柴,扛一百斤也伤不了我,但再加十斤就把我压趴下了,这是为什么?” 【原】渔者曰:“樵则吾不知之矣。以吾之事观之,则易地皆然。吾尝钓而得大鱼,与吾交战。欲弃之,则不能舍,欲取之,则未能胜。终日而后获,几有没溺之患矣。非直有身伤之患耶?鱼与薪则异也,其贪而为伤则一也。百斤,力分之内者也,十斤,力分之外者也。力分之外,虽一毫犹且为害,而况十斤乎!吾之贪鱼亦何以异子之贪薪乎!” 【译】渔者答:“扛柴我不清楚。以我钓鱼之事论之,其中的道理是一样。我经常钓到大鱼,与我较量。有时想要放弃,但又不舍得,想要拉上来,又不容易。需要遛很长时间才能钓上来,有好几次溺水的危险。这不也是伤身的忧患?钓鱼与背柴虽不一样,但因贪而受伤则无两样。一百斤,力所能及,再加十斤,则在你力所之外。力所之外,加一毫都是有害,何况十斤!我贪鱼,又何异于你贪柴呢?” 【原】樵者叹曰:“吾而今而后,知量力而动者,智矣哉!” 【译】樵者感叹道:“从今以后,我知道做事量力而行才是有智慧的。” 【按】刘备之所以让,其实也是考虑到了这点。命里有时终须有,多大的心量,成多大的事儿。如果提前透支,必定带来灾祸。入不敷出,借钱炒股,放手一搏,急功近利其本源都是不知自量。但量可以增长。力也可以增长的。只要知道本末,就无忧。 【原】樵者谓渔者曰:“子可谓知易之道矣。吾也问:易有太极,太极何物也?” 【译】樵者对渔夫说:“先生一看就是深知易理的人。请问易有太极,太极是何物?” 【原】曰:“无为之本也。” 【译】渔夫答:“无为之本。” 【原】曰:“太极生两仪,两仪天地之谓乎?” 【译】樵者问:“太极生两仪,两仪是天地的称呼吗?” 【原】曰:“两仪,天地之祖也,非止为天地而已也。太极分而为二,先得一为一,后得一为二。一二谓两仪。” 【译】渔夫答:“两仪,天地之祖,并非单指天地。太极一分为二,先得到的一为一,后得到的一为二,一与二叫做两仪。” 【按】两仪从象上看,是阴阳,但实际上并非阴阳。因为阴阳中还有阴阳,就是上次和冰点兄聊得,没有-1+1=0。因为没有根本没有-1和1。看到了-1和1那就是定住了,换个角度说就是着了象了。这个象是用不是体。有了这个用体会怎么样?说不明白,意会吧。 【原】曰:“两仪生四象,四象何物也?” 【译】樵者问:“两仪生四象,四象为何物?” 【原】曰:“四象谓阴阳刚柔。有阴阳然后可以生天,有刚柔然后可以生地。立功之本,于斯为极。” 【译】渔夫答:“四象就是阴阳刚柔。阴阳可以生天,刚柔可以生地。一切事物要想成住灭空全赖四象为本,用此就可以高度概括事物了。” 【按】因此4实际上是最小的最大数。一生二,二生三,三生万物。加上之前的无。这里的三就是最小的最大数。之前聊过四。不多说了。 【原】曰:“四象生八卦,八卦何谓也?” 【译】樵者问:“四象生八卦。八卦是什么?” 【原】曰:“谓乾、坤、离、坎、兑、良、震、巽之谓也。迭相盛衰终始于其间矣。因而重之,则六十四卦由是而生也,而易之道始备矣。” 【译】渔夫答:“八卦就是乾、坤、离、坎、兑、艮、震、巽。是事物发展终始、盛衰的表现。两两相重,则六十四卦生出,易学之道就具备了。” 【原】樵者问渔者曰:“复何以见天地之心乎?” 【译】樵者问渔者:“复(卦名)如何见到天地的本性?” 【原】曰:“先阳已尽,后阳始生,则天地始生之际。中则当日月始周之际,末则当星辰始终之际。万物死生,寒署代谢,昼夜变迁,非此无以见之。当天地穷极之所必变,变则通,通则久,故象言‘先王以至日闭关,商旅不行,后不省方’,顺天故也。” 【译】渔夫答:“先阳耗尽,后阳出生。则天地开始出现,变化到中期日月开始周行,变化到末期星辰显现。万物死生,寒暑代谢,昼夜变迁,事物以此相变。当天地运行到终了必然变化,变则通,通则久。所以《易》中象言‘先王到最后一日闭关,哪儿也不去’,是顺天行所故。” 【按】冬至一阳生,七日来复。坤六爻皆阴,冬至就是阴极之日,复卦一元复始,就是初爻为阳,地雷复。 【原】樵者谓渔者曰:“无妄,灾也。敢问何故?” 【译】樵者问渔夫:“无妄(卦名),属于灾,是什么原因?” 【原】曰:“妄则欺他,得之必有祸,斯有妄也.顺天而动,有祸及者,非祸也,灾也。犹农有思丰而不勤稼稿者,其荒也,不亦祸乎?农有勤稼穑而复败诸水旱者,其荒也,不亦灾乎?故象言‘先王以茂对时育万物’,贵不妄也。” 【译】渔夫答:“妄是欺骗,得之必有祸,因此称妄。顺天意而行动,有祸秧及也不叫祸而叫灾。就像农民想着丰收而不去护理庄稼,其结果荒芜,不是祸是什么?农民勤劳治理庄稼而遭水涝或干旱,其结果荒芜,不是灾是什么?所以《易》中象言‘先王以诚对万物’,贵于不欺骗。” 【按】妄,还常用在轻举妄动之,没有做好准备就盲目行动。还有妄自菲薄,这个是心理方面的两个极端,一种认为自己最牛,狂妄自大,实际上无非是放大了自己的优点而已,还一种是认为自己一无是处,同样是放大了自己的缺点而已。都不可取。以人观物。 【原】樵者问曰:“姤,何也?” 【译】樵者问:“姤(卦名),是什么?” 【原】曰:“姤,遇也。柔遇刚也,与夬正反。夬始逼壮,姤始遇壮,阴始遇阳,故称姤焉。观其姤,天地之心,亦可见矣。圣人以德化及此,罔有不昌。故象言‘施命诰四方’,履霜之慎,其在此也。” 【译】渔夫答:“姤是相遇。以柔遇刚。与夬卦相反。夬始强壮,姤由弱遇壮,由阴遇阳。故称为姤。观姤,天地的本性由此可见。圣人以德比喻,没有不明白的。所以《易》中象言‘姤施命于天下,就像走在霜雪之上,小心谨慎’,就在于此。” 【原】渔者谓樵者曰:“春为阳始,夏为阳极,秋为阴始,冬为阴极。阳始则温,阳极则热;阴始则凉,阴极则寒。温则生物,热则长物,凉则收物,寒则杀物。皆一气别而为四焉。其生万物也亦然。” 【译】渔夫接着对樵者说:“春天是阳气的开始,夏天是阳气的极限;秋天是阴气的开始,冬天是阴气的极限。阳气开始则天气温暖,阳气极限则天气暑热;阴气开始则天气凉爽,阴气极限则天气寒冷。温暖产生万物,暑热成长万物;凉爽收获万物,寒冷杀藏万物。皆是一气四种表现。其生万物也如此。” 【原】樵者问渔者曰:“人之所以能灵于万物者,何以知其然耶?” 【译】樵着问渔者:“人被称为万物之灵,这是什么原因?” 【原】渔者对曰:“人之所以能灵于万物者,谓其目能收万物之色,耳能收万物之声,鼻能收万物之气,口能收万物之味。声色气味者,万物之体也。目耳口鼻者,万人之用也。体无定用,惟变是用。用无定体,惟化是体。体用交而人物之道于是乎备矣。然则人亦物也,圣亦人也。有一物之物,有十物之物,有百物之物,有千物之物,有万物之物,有亿物之物,有兆物之物。生一一之物,当兆物之物,岂非人乎!有一人之人,有十人之人,有百人之人,有千人之人,有万人之人,有亿人之人,有兆人之人。生一一之人,当兆人之人,岂非圣乎!是知人也者,物之至者也。圣也者,人之至者也。物之至者,始得谓之物之物也。人之至者,始得谓之人之人也。夫物之物者,至物之谓也。人之人者,至人之谓也。以一至物而当一至人,则非圣人而何?人谓之不圣,则吾不信也。何哉?谓其能以一心观万心,一身观万身,一物观万物,一世观万世者焉。又谓其能以心代天意,口代天言,手代天功,身代天事者焉。又谓其能以上顺天时,下应地理,中徇物情,通尽人事者焉。又谓其能以弥纶天地,出入造化,进退今古,表里人物者焉。噫,圣人者,非世世而效圣焉。吾不得而目见之也。虽然吾不得而目见之,察其心,观其迹,探其体,潜其用,虽亿万千年亦可以理知之也。人或告我曰:‘天地之外,别有天地万物,异乎此天地万物。’则吾不得而知之也。非唯吾不得而知之也,圣人亦不得而知之也。凡言知者,谓其心得而知之也。言言者,谓其口得而言之也。既心尚不得而知之,口又恶得而言之乎?以不可得知而知之,是谓妄知也。以不可得言而言之,是谓妄言也。吾又安能从妄人而行妄知妄言者乎! 【译】渔者回答:“人之所以能成为万物之灵,是因为人的目能收万物之色,耳能收万物之声,鼻能收万物之气,口能收万物之味。声色气味,万物之本,目耳鼻口,人人皆用。物体本无作用,通过变化来表现作用;作用也并不是表现在一个物体上,而是不同的物体有不同的作用。由于物体和作用相交,则人和物的变化规律就具备了。然而人也是物,圣人也是人。有一物之物、十物之物、百物之物、千物之物、万物之物、亿物之物、兆物之物。身虽然只一物,但可以征兆万物,这只有人能做到。有一人、十人、百人、千人、万人、亿人、兆人。虽然只有一人,而能征兆其他人,能这样的只有圣人。因此知道人是物的至尊;圣人是人的至尊。物的至尊为物中之物,人的至尊为人中之人。所以物的至极为至物,人的至极为至人。以一物知万物、以一人知万人,不是圣人是什么?人不是万物之灵,我不信。为什么?因为人能以一心观万心,以一身观万身,以一物观万物,以一世观万世;又能以心代天意,以口代天言,以手代天工,以身代天事;又能上识天时,下晓地理,中尽物情,通照人事;又能弥纶天地,出入造化,进退古今,表里人物。唉!圣人并非世世可见,我虽不能亲眼见到,但我观察其心迹,探访其行踪,研究其作用,虽经亿万年也能以理知道。有人告诉我说,天地之外,还有另外的天地万物,和此天地万物不一样。而我不得而知。并非我不得而知,连圣人也不得而知。凡说知道的,其实内心并不知道。而说出来的,也只是说说而已。既然内心都不明白,嘴又能说出什么?心里不知道而说知道的,叫做妄知。嘴说不清而又要说的,叫做妄言。我又怎么能相信妄人的妄言和妄知呢?” 【按】妄语大忌,学佛修道最忌妄语。身的杀盗淫,意的贪嗔痴,口恶则有四:妄语,两舌,恶口,绮语。 图片 【原】渔者谓樵者曰:“仲尼有言曰:殷因于夏礼,所损益可知也;周因于殷礼,所损益可知也。其或继周者,虽百世可知也。夫如是,则何止于百世而已哉!亿千万世,皆可得而知之也。人皆知仲尼之为仲尼,不知仲尼之所以为仲尼,不欲知仲尼之所以为仲尼则已,如其必欲知仲尼之所以为仲尼,则舍天地将奚之焉?人皆知天地之为天地,不知天地之所以为天地。不欲知天地之所以为天地则已,如其必欲知天地之所以为天地,则舍动静将奚之焉?夫一动一静者,天地至妙者欤?夫一动一静之间者,天地人至妙至妙者欤?是知仲尼之所以能尽三才之道者,谓其行无辙迹也。故有言曰:‘予欲无言’,又曰:‘天何言哉!四时行焉,百物生焉。’其此之谓与?” 【译】渔夫接着对樵者说:“仲尼说的好:‘殷继承于夏礼,所遇的损益便可知道;周继承于殷礼,所遇的损益也可知道。其次继承周礼的,虽经百世也可知道。’如此,何止百世而已!亿千万世,都可以知道。人都知道仲尼叫仲尼,却不知道仲尼为什么叫仲尼。更没有想知道仲尼为什么叫仲尼,若想知道仲尼为什么叫仲尼,则舍弃天地会怎么样?人都知道天地为天地,却不知道天地为什么为天地,更没有想知道过天地为什么为天地,若想知道天地为什么为天地,则舍弃动静会怎么样?一动一静,天地至妙,一动一静之间,天地人至妙。因此仲尼之所以能尽三才之道,是因其行没有辙迹。所以有人说:‘仲尼什么也没说。’又说:‘天什么也没说!但四时运行,百物出生。’这些你知道吗?” 【原】渔者谓樵者曰:“大哉!权之与变乎?非圣人无以尽之。变然后知天地之消长,权然后知天下之轻重。消长,时也;轻重,事也。时有否泰,事有损益。圣人不知随时否泰之道,奚由知变之所为乎?圣人不知随时损益之道,奚由知权之所为乎?运消长者,变也;处轻重者,权也。是知权之与变,圣人之一道耳。 【译】渔夫接着说:“伟大啊,权衡和变化?只有圣人才能做到极致。知道变化过便可知天地万物的消长规律,懂得权衡后可知天下万物的轻重。消长是时机的表现,轻重是事物的表现。时机有否与泰,事物有损与益。圣人若不知随时机否泰之道,又怎随之变而化,有所为呢?圣人若不知随时机损与益之道,又怎能权衡利弊而有所为呢?运用消长的是变,处置轻重的是权。因此知道权变之道,是圣人的修行之一。” 【原】樵者问渔者曰:“人谓死而有知,有诸?” 【译】樵者问渔者:“人死后有灵魂存在,有这种事么?” 【原】曰:“有之。” 【译】渔夫答:“有。” 【原】曰:“何以知其然?” 【译】樵者问:“如何才能知道它是什么样的?” 【原】曰:“以人知之。” 【译】渔夫答:“以人作为参考就可以知道。” 【原】曰:“何者谓之人?” 【译】樵者问:“那什么样的叫人?” 【原】曰:“目耳鼻口心胆脾肾之气全,谓之人。心之灵曰神,胆之灵曰魄,脾之灵曰魂,肾之灵曰精。心之神发乎目,则谓之视;肾之精发乎耳,则谓之听;脾之魂发乎鼻,则谓之臭;胆之魄发乎口,则谓之言。八者具备,然后谓之人。夫人也者,天地万物之秀气也。然而亦有不中者,各求其类也。若全得人类,则谓之曰全人之人。夫全类者,天地万物之仁人之谓也。唯全人,然后能当之。人之生也,谓其气行,人之死也,谓其形返。气行则神魂交,形返则精魄存。神行于天,精魄返于地。行于天,则谓之曰阳行;返于地,则谓之曰阴返。阳行则昼见而夜伏者也,阴返则夜见而昼伏者也。是故,知日者月之形也,月者日之影也。阳者阴之形也,阴者阳之影也。人者鬼之形也,鬼者人之影也。人谓鬼无形而无知者,吾不信也。” 【译】渔夫答:“目耳鼻口心胆脾肾之气全的叫人。心之灵称神,胆之灵称魄,脾之灵称魂,肾之灵称精。心之神表现在目,称为视;肾之精表现在耳,称为听;脾之魂表现在鼻,称为臭;胆之魄表现在口,称为言。八者具备,才可称之为人。人,禀天地万物之秀气而生。然而也有缺少某一方面的人,各归其类。如果各方面都齐全的人,则称为全人。全人得万物中的中和之气,则称为全德之人。全德之人,为人中之人。人中之人,则是仁人之称。只有全人,才能得到仁人之称。人之生,在于气行。人之死,则是形体返还。气行则神魂交,形返则精魄存。神魂行于天,精魄返于地。行于天,称之为阳行,返于地,称之为阴返。阳行于白天而夜间潜伏,阴返于夜间而白天潜伏。所以知道太阳是月亮的形状,月亮是太阳的影子,阳者是阴者的形状,阴者是阳者的影子,人是鬼的形状,鬼是人的影子。有人说,鬼无形而不可知,我不相信。” 【按】中医认为:心藏神开窍于舌,肝藏魂开窍于目,脾藏意开窍于口,肺藏魄开窍于鼻,肾藏精开窍于耳。和邵子所说不一样。 【原】樵者问渔者曰:“小人可绝乎?” 【译】樵者问渔者:“小人能灭绝吗?” 【原】曰: “不可。君子禀阳正气而生,小人禀阴邪气而生。无阴则阳不成,无小人则君子亦不成,唯以盛衰乎其间也。阳六分,则阴四分;阴六分,则阳四分。阳阴相半,则各五分矣。由是知君子小人之时有盛衰也。治世则君子六分。君子六分,则小人四分,小人固不能胜君子矣。乱世则反是,君君,臣臣,父父,子子,兄兄,弟弟,夫夫,妇妇,谓各安其分也。君不君,臣不臣,父不父,子不子,兄不兄,弟不弟,夫不夫,妇不妇,谓各失其分也。此则由世治世乱使之然也。君子常行胜言,小人常言胜行。故世治则笃实之士多,世乱则缘饰之士众。笃实鲜不成事,缘饰鲜不败事。成多国兴,败多国亡。家亦由是而兴亡也。夫兴家与兴国之人,与亡国亡家之人,相去一何远哉!” 【译】渔夫答:“不能。君子禀阳正气而生,小人禀阴邪气而生。无阴则阳不生,无小人则君子不生,只有盛衰的不同。阳六分,则阴四分;阴六分,则阳四分。阴阳各半,则各占五分。由此而知,君子与小人各有盛衰之时。太平盛世时期,君子占六分,小人占四分,小人不能战胜君子。君臣、父子、兄弟、夫妇各安其道。世间纷乱时期正相反。君不君、臣不臣、父不父、子不子、兄不兄、弟不弟、夫不夫、妇不妇则失其道。这是由治世或乱世所造成的。君子常以身作则胜过空话连篇,小人常空话连篇胜过实际行动。所以盛世时期诚实的人多,乱世时期奸诈的人多。诚实容易成事,奸诈容易败事,成事则国兴,败事则国亡。一个家庭也如此。兴家、兴国之人,与亡国、亡家之人,相差的是多么的远!” 【原】樵者问渔者曰:“人所谓才者,有利焉,有害焉者,何也?” 【译】樵者问渔夫:“人们常说的才,有的有利,有的有害,为什么?” 【原】渔者曰:“才一也,利害二也。有才之正者,有才之不正者。才之正者,利乎人而及乎身者也;才之不正者,利乎身而害乎人者也。” 【译】渔夫答:“才本身是一样的,但有利与害两个方面、有才正、才不正之分。才正,利人利己无害,才不正,损人利己,虽益于自身实则害人。” 【原】曰:“不正,则安得谓之才?” 【译】樵者问:“才不正,又如何成为才呢?” 【原】曰:“人所不能而能之,安得不谓之才?圣人所以惜乎才之难者,谓其能成天下之事而归之正者寡也。若不能归之以正,才则才矣,难乎语其仁也。譬犹药疗疾也,毒药亦有时而用也,可一而不可再也,疾愈则速已,不已则杀人矣。平药则常日用之可也,重疾非所以能治也。能驱重疾而无害人之毒者,古今人所谓良药也。《易》曰:‘大君有命,开国承家,小人勿用。’如是,则小人亦有时而用之。时平治定,用之则否。《诗》云:‘它山之石,可以攻玉。’其小人之才乎!” 【译】答:“一般人所不能做的而能做到,难道不算是才?圣人所以怜惜成才难,是因为能成天下事而又正派的人很少。若不正派,虽然有才,也难称有仁义。比如吃药治病,毒药也有用的时候,可不能一而再再而三的用。病愈则速停,不停则是杀人了。平常药日常皆可用,但遇重病则没有疗效。能驱除重病而又不害人的毒药,古今都称为良药。《易》说:‘开国立家,用君子不用小人。’如此,小人也有有用的时候。安邦治国,则不要用小人。《诗》说:‘它山之石,可以攻玉。’就是借用小人之才。” 【原】樵者谓渔者曰:“国家之兴亡,与夫才之邪正,则固得闻命矣。然则何不择其人而用之?” 【译】樵者对渔夫说:“国家兴亡,与人才的正邪,各有其命。哪为什么不择人而用呢?” 【原】渔者曰:“择臣者,君也;择君者,臣也。贤愚各从其类而为。奈何有尧舜之君,必有尧舜之臣;有桀纣之君,而必有桀纣之臣。尧舜之臣,生乎桀纣之世,桀纣之臣,生于尧舜之世,必非其所用也。虽欲为祸为福,其能行乎?夫上之所好,下必好之。其若影响,岂待驱率而然耶?上好义,则下必好义,而不义者远矣;上好利,下必好利,而不利者远矣。好利者众,则天下日削矣;好义者众,则天下日盛矣。日盛则昌,日削则亡。盛之与削,昌之与亡,岂其远乎?在上之所好耳。夫治世何尝无小人,乱世何尝无君子,不用则善恶何由而行也。” 【译】渔夫答:“择臣者,是君王的事,择君者,是臣民的事,贤愚各从其类。世上有尧、舜之君,必有尧、舜之臣;有桀、纣之君,必有桀、纣之臣。尧舜之臣,生于桀、纣之世,则不会成为桀纣之臣。生于尧舜之世并非是他的所为,他想要为祸为福,可不是想干就能干的。上边所好的下边必效仿。君王的影响,还用督促着执行吗?上好义,则下必好义,而不义的人则远离;上好利,则下必好利,而不好利的人则远离,好利者多,则天下日渐消亡;好义者众,则天下日渐兴旺。日盛则昌,日消则亡。昌盛与消亡,难道很远吗?都是在上好恶影响的。治国安民之时何尝无小人,乱世之际又何尝无君子,没有君子和小人,善恶又如何区分呢?” 【原】樵者曰:“善人常寡,而不善人常众;治世常少,乱世常多,何以知其然耶?” 【译】樵者问:“善人常少,不善人常多;盛世时代短,乱世时期长。这又是什么道理呢?” 【原】曰:“观之于物,何物不然?譬诸五谷,耘之而不苗者有矣。蓬莠不耘而犹生,耘之而求其尽也,亦未如之何矣!由是知君子小人之道,有自来矣。君子见善则喜之,见不善则远之;小人见善则疾之,见不善则喜之。善恶各从其类也。君子见善则就之,见不善则违之;小人见善则违之,见不善则就之。君子见义则迁,见利则止;小人见义则止,见利则迁。迁义则利人,迁利则害人。利人与害人,相去一何远耶?家与国一也,其兴也,君子常多而小人常鲜;其亡也,小人常多而君子常鲜。君子多而去之者,小人也;小人多而去之者,君子也。君子好生,小人好杀。好生则世治,好杀则世乱。君子好义,小人好利。治世则好义, 乱世则好利。其理一也。” 【译】渔夫答:“观察事物。什么事物不能表现出来?比如五谷,耕种之后有长不出来的,而野地的草木不用耕种就能长出来,耕种之后想要全部收获,也是不能做到的!由此而知君子与小人之道,也是自然而生。君子见善事则欢喜,见不善事则远离;小人见善事则快速离开,见不善事则欢喜。善恶各从其类。君子见善事则去做,见不善事则阻止;小人见善事则阻止,见不善事则去做;君子见义则追随,见利则止;小人见义则止,见利则追随。迁义则益人,迁利则害人;益人与害人,相去有多远?家与国一样兴旺则君子常多,小人常少;消亡则小人常多君子常少。君子多小人躲避,小人多君子躲避。君子好生,小人好杀。好生则治国安民,好杀则祸国殃民。君子好义,小人好利。治国安民则好义,祸国殃民则好利。其道理是一样的。” 【原】钓者谈已,樵者曰:“吾闻古有伏羲,今日如睹其面焉。”拜而谢之,及旦而去。 【译】渔夫说完,樵者感慨万分:“我听说上古有伏羲,今日好像一睹其面。”拜谢了渔夫,天亮后相别而去。 邵武杨指挥渔樵问对图 王佐 樵问渔,小舟撒网有鱼无。夜来风雨暗江湖,我独怜君生涯孤。 渔者答,听我言。世间万物盈眼前,物物有主司其权。 苟非我有不得专,毫釐欲取须用钱。惟我生涯大无外,所取随缘无禁戒。 我网所得即我鱼,谁为江湖分限界。任公连鳌近虚怪,吕望非熊今安在。 得沽酒且高歌,长弄烟波卒年岁。渔问樵,青山多少木惟乔。 人皆采枚君采条,君之生涯最无聊。樵者答,为我听。 世间万物眼前盈,物物有主司其衡。苟非我有不得争,毫釐欲取须价平。 惟我生涯不用买,山山为我供樵采。只如天地供蚁封,蚁口岂能亏厚载。 王质神仙漫云尔,买臣富贵蚊过耳。何如负薪行且歌,一曲归来暮山紫。 童子评,惟道许。我有言,君记取。忆昔沙尤用军旅,武阳近郊多狗鼠。 此时鸡豚不得安,况乃渔樵闲浪语。我心只愿杨将军,为此溪山作张主。 使汝渔樵各安堵,清时问对山水里。渔樵欣然长啸去,山青水绿无寻处。 《渔樵问对》是《皇极经世》的引子,《皇极经世》是邵雍思想的集大成 点评经典: 当官,要读管仲。 经商,要读范蠡。 易理,要读邵雍。 邵雍有经世之才,却在骨子里是个隐逸人物。 一生并未出世,却胜似出世者。 他以出世者的心态,看待世间一切。 现实生活中,邵雍同情劳苦大众,耳闻过官场的险恶,目睹过世态的炎凉。 邵雍性格温和,慈善为怀,与平民百姓感情甚笃,深深扎根在人民群众之中。 参考&致谢 https://www.jianshu.com/p/01343c621dd1

2023/4/27
articleCard.readMore

三大神书推荐:赤脚医生手册、民兵军事训练手册、军地两用人才之友

简介 屠龙有术,江湖传说,有三本神书,如果得到它们,即便穿越到古代也能荣登大宝;如果在未来遭遇核大战,亦可凭借这三本书重建人类文明! 这三本书就是《赤脚医生手册》《民兵军事训练手册》《军地两用人才之友》。 果然,高端的书籍往往只需要最朴素的命名方式。 某宝在售 这三本书重新出现在人们的视野中,是因为一位B站up主的科普视频。 下面分别介绍一下这三本神书。 《赤脚医生手册》 这本“小红书”最早出版于1969年,至今已印发上千万册,另外它还被翻译为50多种外语发行到世界各国。其内容从中医的针灸针法到望闻问切,从采集中草药进行炮制到西医的手术实操全都涵盖!堪称居家旅行必备之宝典。 如图,该书目录直接根据现在医院的科室进行分类,外科内科妇产科、五官儿科皮肤科,应有尽有,哪里有病翻哪里~ 这本书最神奇的地方是,它所面向的是上世纪六七十年代的普通百姓、农民,不仅语言通俗易懂,还配有图片。每一种疾病也都会给出针灸、中药、西药的三种治疗方法。 据说有一位网友就利用《赤脚医生手册》上的知识治好了多年的汗脚… 赤脚医生 出版这样一本书的原因是,在上世纪六十年代,我们国家的医生等大部分医疗卫生人员都集中在城市中。 据统计,1964年在县级以下地区工作的高级卫生人员仅占全部的10%。而与之相反的是,农村的人口最多,却也最缺乏基本的医疗条件。 培训赤脚医生 所以赤脚医生便应运而生,从字面上理解,他们就是光着脚的医生,因为他们并非正式的医生,没有固定编制,平时也会下地种田,在需要的时候只需田边喊一声,他们就会赤着脚,提着小药箱去人家里看病了。 赤脚医生一般为经乡村或基层政府批准和指派,且有一定医疗知识和能力的医护人员(来源主要有三部分:一是医学世家;二是经医护专业短期培训的学员;三是公认有一定医护能力的自学成才者),他们受当地乡镇卫生院直接领导和医护指导,特点是:亦农亦医,农忙时务农,农闲时行医,或是白天务农,晚上送医送药的农村基层兼职医疗人员。 赤脚医生的出现,直接缓解了我国广大农村地区缺医少药的问题,在广大农村地区普及爱国卫生知识、除“四害”、根除血吸虫病等方面作出了巨大贡献。代表人物有王桂珍。 《民兵军事训练手册》 **排雷?炸坦克?打飞机?**这些技能如果你想学,这本书里都有! 该书由中国人民解放军总参谋部动员部编纂,其中涵盖了步枪射击、防空防化防原子弹等的基本军事知识。只要有这本百余页的手册在手,你就可以在“世界核平”后迅速建立起一支拥有相当战力的军队。 如今,《民兵军事训练手册》被网友们戏称为“核战争后的重启手册”,但当初它的出现却与我国六十年代所面临的备战压力密切相关。当时中苏交恶,美国也频繁在东南沿海施压。而在此之前的1958年,《关于民兵问题的决定》便指出,要以民兵组织的形式,实行全民皆兵。所以在几个月之后的1959年初,《民兵军事训练手册》就出版了第一版。 当初在“备战备荒为人民”的号召下,全国民兵总人数曾一度超过2亿人,而当时我国的总人口也不过才6亿多。这本《民兵军事训练手册》见证了新中国那段强敌环伺、全民皆兵的艰苦历史。 80年代版《十万个为什么》 前言 后来,同样的原因,作为工农兵读物的70年代版《十万个为什么》也问世了。(80年代版又恢复到原来的14册,以及少年儿童读物的定位) 《军地两用人才之友》 目录 上世纪八十年代后半期,人民解放军百万大裁军,曾经保卫祖国的人民子弟兵也将要投入到各地方的经济建设当中来,于是《军地两用人才之友》便诞生了! 该书的前几页还印着时任领导人和多位开国将军的寄语,鼓励培养既能打仗又能从事社会主义建设的军地两用人才。 如上图中的目录,该书堪称社会谋生技能大全!修炼完此书,你就是全能小王子。 例如教打飞机的章节: 书中亦有对未来战争的展望,且认为在未来战争中最具发展前途的是巡航导弹、激光武器和制导武器: 除了军事方面的知识和实操技能,该书还能够教会你其他领域的技能知识——育种选种施肥、拖拉机的驾驶和维修、盖房子、修电视机、篆刻、摄影、工商管理… 后来,由于这本书深受干部战士们的喜爱,而又有了续编版!书中涵盖了加工肉蛋肉、理发等各项技能知识。 原文于2021年12月4日发布,2022年1月11日、4月11日更新补充。 资源下载 好东西要分享,既然详细介绍了,不给下载链接怎么能行? 下面就是下载链接 O(∩_∩)O 下载链接 链接:https://pan.baidu.com/s/1gkFJPZX7gTHirWb9OHzQAw?pwd=xm3t 提取码:xm3t 共享文件列表 新增一个在线查看全部文件列表地址 穿越必备书籍,可以在线预览和下载 😍😘 [/share/xxx/穿越必备书籍]# tree . . ├── 军地两用 │   ├── 军地两用人才之友.pdf │   ├── 军地两用人才之友续编本.pdf │   └── `民兵军事训练手册1960年.pdf ├── 十万个为什么wg版 │   ├── 十万个为什么(01).pdf │   ├── 十万个为什么(02).pdf │   ├── 十万个为什么(03).pdf │   ├── 十万个为什么(04).pdf │   ├── 十万个为什么(05).pdf │   ├── 十万个为什么(06).pdf │   ├── 十万个为什么(07).pdf │   ├── 十万个为什么(08).pdf │   ├── 十万个为什么(09).pdf │   ├── 十万个为什么(10).pdf │   ├── 十万个为什么(11).pdf │   ├── 十万个为什么(12).pdf │   ├── 十万个为什么(13).pdf │   ├── 十万个为什么(14).pdf │   ├── 十万个为什么(15).pdf │   ├── 十万个为什么(16).pdf │   ├── 十万个为什么(17).pdf │   ├── 十万个为什么(18).pdf │   ├── 十万个为什么(19).pdf │   ├── 十万个为什么(20).pdf │   └── 十万个为什么(21).pdf ├── 生存狂 │   ├── dhh4.rar │   ├── 【PDFT】食用野生植物图鉴【图鉴 植物 食物】Edible Wild Plants.pdf │   ├── 一个人在阿拉斯加荒野的25年.txt │   ├── 丛林跋涉与沼泽地.txt │   ├── 丢了钥匙不要慌:教你如何不用钥匙启动汽车.avi │   ├── 中国野菜图谱.pdf │   ├── 伤口缝合和轻伤.txt │   ├── 全球反恐手册:特种部队实用指南(美)汤普森.PDF │   ├── 关于目测距离.txt │   ├── [冒险图鉴:野外生活与生存].众文图书股份有限公司(台湾).插图版.pdf │   ├── 刀具打磨与使用技巧.flv │   ├── 印第安人野外生存指南.txt │   ├── 各地频率列表.txt │   ├── [地震搜救手册].文字版.pdf │   ├── 徒步穿越必备药品.doc │   ├── 必需品.txt │   ├── 快拆救生手镯教程.pdf │   ├── 怀斯曼生存手册.pdf │   ├── 怀斯曼生存手册_顶级驾驶.pdf │   ├── 户外小心毒蘑菇——毒蘑菇大全.doc │   ├── 户外装备常识-女驴必读.txt │   ├── 捕兽陷阱制作.pdf │   ├── 树棍面包(Bannock)班诺克.docx │   ├── 核战争生存必要储备与使用方法.txt │   ├── 步兵武器射击学理.pdf │   ├── 沙漠探险活命手册(1)(1).doc │   ├── 特典.txt │   ├── 特种兵野外生存图鉴.pdf │   ├── 狩猎知识手册.zip │   ├── 生存手册.txt │   ├── 短刀格斗,刀术,刀法.pdf │   ├── 老兵建议.doc │   ├── 考验你的生存能力——图话野外求生术.pdf │   ├── 自制电池和显微镜.flv │   ├── 自制简易净水器.doc │   ├── 蓝焰射手的制作方法.flv │   ├── 逃生背包.pdf │   ├── 野外徙步旅行、野营、生存、求生技巧大全!.txt │   ├── 野外生存之旅--百法结绳(基础篇).pdf │   ├── 野外生存之旅--百法结绳(完结篇).pdf │   ├── 野外生存之旅--百法结绳(提高篇).pdf │   ├── 《野外生存心态》.txt │   ├── 陷阱设置和动物习性.txt │   ├── 面包师手册.pdf │   ├── [食物有毒].(日)增尾清.扫描版[ED2000.COM].pdf │   └── _鱼钩的基本知识.doc ├── 穿越需要学会的资料 │   ├── 三百千瓦供热凝气式土汽轮机.pdf │   ├── 专业炼铁学 (上下册)高等学校教学用书.pdf │   ├── 中小型同步发电机自励装置.pdf │   ├── 中等专业学校教学用书 机械零件 (修订本).pdf │   ├── 中等专业学校教材 工程力学(非机械类).pdf │   ├── 中等专业学校试用教科书 化工机械.pdf │   ├── 中等专业学校试用教科书 电机设计.pdf │   ├── 书籍01.rar │   ├── 书籍02.zip │   ├── 书籍0407.zip │   ├── 从植物油泥中制取人造石油.pdf │   ├── 以水轮机为动力的几种木制陶瓷机械设备.pdf │   ├── 供热学 (上、中、下册).pdf │   ├── 保证小高炉正常生产的土仪表.pdf │   ├── “公社号”万能简易轧钢机(适合土洋结合的小型钢铁联合体).pdf │   ├── 农业基础知识 (贵州省教育部1957年版).pdf │   ├── 农业机械基础知识.pdf │   ├── 农业生产技术基本知识丛书 农田水利(第三版).pdf │   ├── 农产品加工土机械.pdf │   ├── 农村卫生员读本.pdf │   ├── 农村水电站 │   │   ├── 农村水电站(上册).pdf │   │   └── 农村水电站(下册).pdf │   ├── 农村电工基础知识.pdf │   ├── 农田水利与泵站工程.pdf │   ├── 几种电工材料的制造与应用.pdf │   ├── 利用小方炉炼焦,提取液气燃料.pdf │   ├── 制浆造纸工艺学 上下册.pdf.pdf │   ├── 制茶工厂的设备与设计原理.pdf │   ├── 化学治疗药物的应用及合成.pdf │   ├── 化工与医药原料土法生产.PDF │   ├── 化工普及丛书 │   │   ├── 化工普及丛书 合成药物.pdf │   │   ├── 化工普及丛书 天然盐类加工工业.pdf │   │   ├── 化工普及丛书 氮肥工业.pdf │   │   ├── 化工普及丛书 油脂工业.pdf │   │   ├── 化工普及丛书 甘油的制造.pdf │   │   ├── 化工普及丛书 皮革工业.pdf │   │   ├── 化工普及丛书 石油加工工业.pdf │   │   ├── 化工普及丛书 硫酸工业.pdf │   │   └── 化工普及丛书 肥皂与洗涤剂.pdf │   ├── 北京市机电工业土简设备技术资料集.pdf │   ├── 十万个为什么(嗡嗡嗡版).rar │   ├── 半导体材料的制备.pdf │   ├── 半导体电子学.pdf │   ├── 半导体集成电路(上).pdf │   ├── 半导体集成电路(下).pdf │   ├── 半导体集成电路 南京工学院编.pdf │   ├── 圆形窑土法快速炼焦.pdf │   ├── 土制农药.pdf │   ├── 土化肥.pdf │   ├── 土开关.pdf │   ├── 土机械和土法吊装.pdf │   ├── 土汽轮机的设计与安全使用.pdf │   ├── 土油罐.pdf │   ├── 土法低温炼钢.pdf │   ├── 土法冶炼经验丛书.pdf │   ├── 土法制轴承.pdf │   ├── 土法制造印染用化工原料.pdf │   ├── 土法制造小型发电机.PDF │   ├── 土法制造氨燻晒图纸.pdf │   ├── 土法制造水泥工艺.pdf │   ├── 土法制造滚珠轴承.pdf │   ├── 土法制造电机.pdf │   ├── 土法制造耐火材料.pdf │   ├── 土法制造高标号水泥.pdf │   ├── 土法回收废金属.pdf │   ├── 土法孵鸡及技术革新.pdf │   ├── 土法治理盐碱地.pdf │   ├── 土法测图.pdf │   ├── 土法测天.pdf │   ├── 土法炼焦的技术改造.pdf │   ├── 土法炼焦 第1辑.pdf │   ├── 土法炼焦 第2辑.pdf │   ├── 土法炼焦 第3辑.pdf │   ├── 土法炼磺.pdf │   ├── 土法炼钢.pdf │   ├── 土法炼铁.pdf │   ├── 土法炼铜.pdf │   ├── 土法炼铜的简易化学分析.pdf │   ├── 土法炼铝.PDF │   ├── 土法炼锌 第一辑.pdf │   ├── 土法甜菜制糖.pdf │   ├── 土法繁育小球藻.pdf │   ├── 土法草类制浆造纸.pdf │   ├── 土法选煤.pdf │   ├── 土法选矿设备.pdf │   ├── 土法造鼓风机.pdf │   ├── 土法采油.pdf │   ├── 土法锻钢锤.pdf │   ├── 土法防治猪病.pdf │   ├── 土电容器.pdf │   ├── 土电流互感器.pdf │   ├── 土电表.pdf │   ├── 土磨面机.pdf │   ├── 土简机床资料汇编 │   │   ├── 土简机床资料汇编 第一辑 车床.pdf │   │   ├── 土简机床资料汇编 第三辑 钻床、铣床、磨床.pdf │   │   ├── 土简机床资料汇编 第二辑 镗床.pdf │   │   ├── 土简机床资料汇编 第五辑 插床、拉床、锯床、滚压机械.pdf │   │   └── 土简机床资料汇编 第四辑 蚂蚁啃骨头.pdf │   ├── 土蒸汽机的设计制造与使用.pdf │   ├── 土铁路.pdf │   ├── 地下水源的勘察和土法打井.pdf │   ├── 地质图简易作法.pdf │   ├── 大茅山土法酿造杨梅酒.pdf │   ├── 如何找矿.pdf │   ├── 小型有线广播站.pdf │   ├── 小型机械整流同步发电机土法制造工艺.pdf │   ├── 小型钢铁联合企业.pdf │   ├── 小煤窑的土矿灯.pdf │   ├── 少年半导体收音机.pdf │   ├── 少年地震测报活动.pdf │   ├── 《少年无线电》.pdf │   ├── 少年晶体管扩音器.pdf │   ├── 少年测量.pdf │   ├── 少年电工 1962年版.pdf │   ├── 少年科技制作 │   │   ├── 少年科技制作_1.PDF │   │   ├── 少年科技制作_2.pdf │   │   ├── 少年科技制作_3.pdf │   │   ├── 少年科技制作_4.pdf │   │   ├── 少年科技制作_5.pdf │   │   └── 少年科技制作_6.pdf │   ├── 少年科技活动丛书 光电控制模型(上海人民出版社1.pdf │   ├── 少年科技活动丛书 初级无线电遥控模型飞机(上海.pdf │   ├── 少年科技活动丛书 少年农业科学实验(少年儿童出.pdf │   ├── 少年科技活动丛书 少年通信活动(上海人民出版社1.pdf │   ├── 少年科技活动丛书 幻灯机和幻灯片(上海人民出版.pdf │   ├── 少年科技活动丛书 电动模型制作.pdf │   ├── 少年科技活动丛书 自制照相机.pdf │   ├── 少年航空模型.pdf │   ├── 工业基础知识.pdf │   ├── 废品回收利用知识小丛书 │   │   ├── 为什么要回收利用废品.pdf │   │   ├── 废化工产品的回收与利用.pdf │   │   ├── 废杂品的回收与利用.pdf │   │   ├── 废畜产品的回收与利用.pdf │   │   ├── 废纤维的回收与利用.pdf │   │   └── 废金属的回收与利用.pdf │   ├── 怎样修建窄轨铁路.pdf │   ├── 怎样制造土电器.pdf │   ├── 数理化自学丛书化学第一册.PDF │   ├── 数理化自学丛书化学第三册.PDF │   ├── 数理化自学丛书化学第二册.PDF │   ├── 数理化自学丛书化学第四册.PDF │   ├── 数理化自学丛书物理第一册.PDF │   ├── 数理化自学丛书物理第三册.PDF │   ├── 数理化自学丛书物理第二册.PDF │   ├── 数理化自学丛书物理第四册.PDF │   ├── 无机肥料与无机盐工艺学.pdf │   ├── 无线电爱好者丛书-怎样看无线电电路图.PDF │   ├── 无线电设备元件零件的设计与制造工艺 │   │   ├── 无线电设备元件零件的结构设计与制造工艺(上册).pdf │   │   └── 无线电设备元件零件的结构设计与制造工艺(下册).pdf │   ├── 日用陶瓷生产基础知识.pdf │   ├── 晶体喇叭的制作.pdf │   ├── 晶体管收音机元件制作.pdf │   ├── 有色金属小型矿山的土法开采.pdf │   ├── 木制风动发电机与土蓄电池充电.pdf │   ├── 木轨滑车运土器.pdf │   ├── 木轨车运材.pdf │   ├── 机械制造工业安全卫生手册.pdf │   ├── 林产品土法加工.pdf │   ├── 校园安全手册1.doc │   ├── 民兵体育游戏.pdf │   ├── 民兵军事训练手册.pdf │   ├── 民兵军事训练暂用教材.pdf │   ├── 民兵卫生教材.PDF │   ├── 民兵国防教育提纲.pdf │   ├── 民兵对空射击教材.pdf │   ├── 民兵常识.pdf │   ├── 民兵政治教材.PDF │   ├── 民兵歌曲.pdf │   ├── 民兵歌集.pdf │   ├── 民兵游击战与村落战.pdf │   ├── 氨基塑料.pdf │   ├── 水文分析与计算.pdf │   ├── 火柴生产技术革新.pdf │   ├── 烟叶的初步加工.pdf │   ├── 热敏电阻的制造及其应用.pdf │   ├── 煤气机和煤气发生炉.pdf │   ├── 煤焦油的土法炼制.pdf │   ├── 生理卫生知识.pdf │   ├── 电子管制造工艺.pdf │   ├── 电子管放大器基础 陈鸿彬.pdf │   ├── 电阻电容生产实践讲义.pdf │   ├── 石油化学工业手册 上中下册.pdf │   ├── 磁石式同线电话.pdf │   ├── 空气电池灯的制造与使用.pdf │   ├── 简易副食加工法.pdf │   ├── 简易太阳灶制作.pdf │   ├── 简易沼气发酵池.pdf │   ├── 简易电炉炼矽铁.pdf │   ├── 简易电话机.pdf │   ├── 简易自制物理仪器.pdf │   ├── 简易蒸汽机的制造与使用.pdf │   ├── 纤维板制造工艺.pdf │   ├── 罐头生产基本知识.pdf │   ├── 自力更生制造土机床.pdf │   ├── 舌簧喇叭的制作.pdf │   ├── 莫尔斯电报机.pdf │   ├── 葡萄酒酿造.pdf │   ├── 认识矿物的方法.pdf │   ├── 赤脚医生手册(吉林版).PDF │   ├── 轨道、架空索道、溜槽、缆车的建筑技术.pdf │   ├── 锅驼机的构造和使用.pdf │   ├── 长沙土法生产啤酒操作法.pdf │   ├── 陶质运输轨道的制造与铺筑.pdf │   ├── 《青年自学丛书:代数》.pdf │   ├── 《青年自学丛书:几何》.pdf │   ├── 食品工业卫生常识.pdf │   ├── 饲料加工.pdf │   ├── 高真空技术与设备.pdf │   └── 高等数学(工科) 赵访熊 编.pdf ├── 赤脚医生手册 │   ├── 新赤脚医生手册.pdf │   ├── 赤脚医生手册七十年代吉林版.PDF │   ├── 赤脚医生手册-上海版.pdf │   ├── 赤脚医生手册——上海经典版.pdf │   └── 赤脚医生手册-湖南版(1).pdf └── 近地小行星列表整理 ├── 200个可以作为中转空间站的近地小行星带轨道参数.xls ├── 全部2000阿登型近地小行星列表带轨道参数日期降序排列.xls ├── 全部7000阿莫尔型近地小行星列表带轨道参数按照远日点升序排列.xls ├── 全部9000阿波罗型近地小行星列表带轨道参数按照远日点升序排列.xls ├── 哈佛全部小行星列表共52万.rar ├── 哈佛小行星列表共52万没什么用 │   ├── 哈佛小行星列表10.xls │   ├── 哈佛小行星列表11.xls │   ├── 哈佛小行星列表1.xls │   ├── 哈佛小行星列表2.xls │   ├── 哈佛小行星列表3.xls │   ├── 哈佛小行星列表4.xls │   ├── 哈佛小行星列表5.xls │   ├── 哈佛小行星列表6.xls │   ├── 哈佛小行星列表7.xls │   ├── 哈佛小行星列表8.xls │   ├── 哈佛小行星列表9.xls │   ├── 太阳系天体列表.xls │   ├── 编号10000以内的小行星.xls │   └── 金属小行星列表.xls ├── 大力马纤维的数据.jpg ├── 大学各个专业的全部教材pdf.doc ├── 太阳系旅行完整速度变量图.png ├── 火星地图海拔水文资料图册.rar ├── 火星殖民指南:赶往火星,祖步林.pdf ├── 火星水文冰川研究论文汇总.rar ├── 近地小行星轨道参数列表数据汇总.rar ├── 近地小行星采矿论文汇总.rar ├── 适合撞击火星的小行星 │   ├── 适合撞击火星提升温度的阿波罗小行星.xls │   ├── 适合撞击火星提升温度的阿莫尔小行星.xls │   └── 适合撞击火星的阿登型小行星.xls └── 阿登型近地小行星列表.xls 15 directories, 315 files 参考&致谢 编辑整理 三大神书 关于人的成长格言赏析 承认父母很普通,承认自己很普通,承认子女很普通 第一次长大,可以为了某样事去死;第二次长大,可以为了某样事卑微着活着 毛主席语录: 什么是军事?军事就是打得过就打,打不过就跑。 什么是政治?政治就是把智齿我们的人搞得多多的,把反对我们的人搞得少少的。

2023/4/23
articleCard.readMore

开源观察之到底是谁在主导开源软件生态的发展?

前言 很多人对于开源生态误解很深,这里对开源软件生态的一些介绍和解释,使用ChatGPT辅助编写了一篇对于外行的介绍,使其可以快速了解开源生态 对话开源 使用了很多很久的开源软件,也参与了一些开源软件的发展,现在软件的选择首选的就是开源软件,对于开源软件生态算是有一个初步的了解和映像。很多外行对于开源有一些错误的认知,很早就有写一篇关于开源生态的文章了,最近使用ChatGPT辅助,很快就完成了一篇文章。 在思考是否把对话过程整理成文之后,最终决定还是保留交流对话的过程! ChatGPT很强大,但你也得具备很多专业知识才能用好它 开源软件是什么 开源软件指的是源代码可以被公开查看、使用、修改和分发的软件。与之相对的是闭源软件,它的源代码是私有的,不公开供大众使用和修改。 开源软件的特点是: 可以被公开查看和修改:任何人都可以查看开源软件的源代码,并且可以根据自己的需要进行修改和定制。 可以被免费使用:大部分开源软件都是免费提供给用户使用的,用户不需要支付版权费用。 具有较高的安全性:由于源代码公开,开源软件的漏洞和安全问题可以被更多人发现和修复,从而提高了软件的安全性。 具有良好的社区支持:开源软件通常有一个庞大的社区支持,用户可以通过社区获得帮助、交流和分享。 可以被广泛应用和推广:由于开源软件具有免费和开放的特点,它可以被广泛应用和推广,从而提高了软件的影响力和普及率。 常见的开源软件有Linux操作系统、Apache Web服务器、MySQL数据库、Firefox浏览器、WordPress网站建设平台等等。开源软件已经成为现代软件开发中的重要组成部分,为用户和开发者带来了诸多的好处。 开源软件的优点是什么 开源软件有以下优点: 透明性:开源软件的源代码是公开的,用户可以查看代码并了解软件的实现原理,这种透明性使得用户可以更好地理解软件的功能和运行机制。 自由度:开源软件的用户可以自由地复制、分发、修改和使用软件,而且不需要支付任何费用。这种自由度使得用户可以根据自己的需要来定制软件,从而更好地满足自己的需求。 安全性:由于开源软件的源代码是公开的,任何人都可以查看代码并发现其中的漏洞和安全问题,这种开放的审查机制可以使得开源软件具有更高的安全性和稳定性。 可定制性:开源软件通常具有很好的可定制性,用户可以根据自己的需求和特定的场景对软件进行修改和定制,从而更好地满足自己的需求。 社区支持:由于开源软件的用户和开发者通常组成一个庞大的社区,这种社区可以为用户提供技术支持、问题解答、开发经验和资源共享等支持。 兼容性:开源软件通常具有更好的兼容性,因为开源软件通常遵循开放标准,不受私有标准的限制,可以更好地与其他软件和系统进行协作。 综上所述,开源软件的优点包括透明性、自由度、安全性、可定制性、社区支持和兼容性等。这些优点使得开源软件成为现代软件开发中不可或缺的一部分,为用户和开发者带来了巨大的价值和好处。 那么,开源软件有什么缺点了? 虽然开源软件具有很多优点,但也存在一些缺点,包括以下几个方面: 缺乏专业支持:开源软件通常由社区维护和支持,缺乏专业支持,这可能导致用户在使用和维护软件时遇到困难。 可能存在安全问题:虽然开源软件的源代码可以被公开审查,但这也可能导致黑客更容易找到软件中的漏洞和安全问题,因此开源软件也需要及时修复漏洞以保障安全。 兼容性问题:虽然开源软件通常遵循开放标准,但在实际应用中,与其他软件或系统的兼容性可能存在问题,这可能会导致软件无法正常工作。 学习成本较高:由于开源软件的源代码是公开的,用户可能需要具有一定的编程知识和技能才能进行定制和修改,因此需要付出一定的学习成本。 可能存在版本更新不及时的问题:由于开源软件通常由社区维护,因此可能存在版本更新不及时的问题,用户需要自己去维护和更新软件,这可能会增加用户的工作量。 综上所述,开源软件的缺点包括缺乏专业支持、安全问题、兼容性问题、学习成本较高和版本更新不及时等。对于这些缺点,用户可以通过选择专业的开源软件提供商、参与社区维护和支持、及时更新软件版本等方式来解决。 只要投入金钱,开源软件的这些问题可以解决么 投入金钱确实可以解决一些开源软件存在的问题,例如提供专业支持、加强软件安全等,但并不能完全解决所有问题。以下是一些例子: 提供专业支持:企业可以选择购买专业的开源软件支持服务,获得专业的技术支持、问题解答和定制服务,从而解决由于缺乏专业支持而导致的困难。 加强软件安全:企业可以选择购买安全软件,对开源软件进行加固和安全管理,从而提高软件的安全性。 定制和维护:企业可以选择雇佣开源软件开发人员,进行定制和维护,从而解决开源软件的兼容性和版本更新等问题。 增加社区投入:企业可以向开源社区投入资金,促进社区的发展和维护,从而帮助解决一些开源软件存在的问题。 然而,开源软件的自由性和透明性也意味着,用户可以根据自己的需求和资源选择是否投入金钱。在一些情况下,投入金钱可能并不是必要的,用户可以通过自己的努力和学习来解决开源软件存在的问题。 redhat就是一家很成功的开源软件公司,并创造了巨大的利润,redhat的商业模式是否解决了开源软件的问题 Red Hat 确实是一家非常成功的开源软件公司,它的商业模式可以说是解决了开源软件的问题之一。Red Hat 的商业模式主要是基于以下两个方面: 提供专业支持:Red Hat 提供针对企业级用户的 Linux 操作系统和其他开源软件的专业支持,包括技术支持、培训、咨询和服务等,这可以解决企业在使用和维护开源软件时遇到的困难。 付费订阅服务:Red Hat 基于其开源软件产品提供付费订阅服务,订阅用户可以获得 Red Hat 官方提供的软件更新、安全修复、新功能和技术支持等服务,这可以解决开源软件版本更新和安全性问题。 Red Hat 的商业模式的成功不仅在于它提供了专业的支持和服务,而且在于其能够让企业在同时获得开源软件的好处和商业化的优势。Red Hat 的开源软件产品在大多数情况下是免费的,但企业需要付费订阅服务才能获得更好的服务和支持,这既保证了开源软件的自由性和透明性,又能够为企业提供可靠的商业支持。 总之,Red Hat 的商业模式是非常成功的,但并不能完全解决所有开源软件存在的问题。其他开源软件公司和社区也在不断探索和创新商业模式,以解决开源软件存在的问题。 在互联网领域,几乎都是使用的开源软件,未来,开源软件会统治所有的互联网标准么? 开源软件在互联网领域确实得到了广泛的应用,成为了很多公司和组织选择的首选。然而,要说开源软件会统治所有的互联网标准,还是有一定的困难。 首先,虽然开源软件在很多领域已经达到了很高的水平,但在某些特定领域,闭源软件仍然具有更好的性能和效率。例如,在一些高性能计算领域,闭源软件仍然是不可替代的选择。 其次,开源软件也存在一些问题和限制。例如,开源软件的发展和更新速度可能会比较慢,有时候可能存在安全和兼容性问题,需要用户花费时间和精力进行自我调试和维护。 最后,由于开源软件的自由性和透明性,它们存在着无法控制的风险。如果在开源软件的代码中存在漏洞或安全问题,攻击者可以很容易地获取代码并利用其中的漏洞进行攻击。这可能会对企业和组织的安全带来潜在风险。 综上所述,虽然开源软件在互联网领域中得到了广泛应用,但是它们并不一定会成为统治所有互联网标准的唯一选择。在未来,我们可能会看到开源软件和闭源软件之间的协同发展,以提供更好的解决方案。 但是,我看到,越来越多的闭源软件公司倒闭了,或者转为开源软件模式,例如firefox,谷歌的chrome,开源软件的占比越来越高,你有什么看法 是的,确实有越来越多的闭源软件公司倒闭或者转为开源软件模式,而开源软件在互联网领域中的占比也越来越高。这是因为开源软件具有很多优势,包括透明性、自由性、灵活性、可定制性等,而这些优势正好能够满足当前互联网应用的需求。 另外,随着云计算和开放云平台的发展,开源软件也得到了更多的应用机会。云计算和开放云平台为开源软件提供了更好的部署和使用方式,同时也提高了开源软件在企业和组织中的接受度和应用价值。 最后,开源软件社区的活跃度和贡献者数量也在不断增加,这进一步促进了开源软件的发展和普及。开源软件社区的活跃度和贡献者数量越多,开源软件的功能和性能就越强大,这也让更多的企业和组织愿意选择开源软件。 综上所述,开源软件在互联网领域中的占比确实越来越高,这是因为开源软件具有很多优势,并且得到了更多的应用机会和社区支持。不过,仍然需要注意开源软件本身的一些问题和限制,并且需要根据实际情况选择最适合自己的软件解决方案。 开源软件是由谁主导的? 开源软件的开发和推广通常是由开源社区和贡献者主导的。这些社区由一群热爱技术和开源理念的人组成,他们相信共享和协作的力量,致力于开发和维护开源软件项目。 开源社区是由志愿者、爱好者、开发者和公司等组成的多方参与的群体,其成员之间通过互相交流和合作来推动软件的开发和改进。开源社区通常拥有完善的组织结构和开发流程,例如开发者的代码提交、审查和合并流程、用户的反馈和贡献流程等,这些流程可以帮助开发者更好地协作、沟通和共同推进软件的发展。 除了开源社区,一些公司也在开源软件的发展中扮演了重要的角色。这些公司可以是开源软件的赞助者、贡献者或用户,也可以是基于开源软件构建自己产品和服务的企业。一些知名的开源软件公司,例如Red Hat、Canonical、MongoDB等,不仅为开源社区提供了财务和技术上的支持,同时也为企业用户提供了开源软件的商业服务和支持,从而帮助开源软件在企业中得到更广泛的应用。 总之,开源软件的开发和推广主要由开源社区和贡献者主导,同时得到了一些公司的支持和参与。这种多方参与的开发模式可以使得开源软件具有更广泛的用户和应用范围,也可以让软件得到更多人的参与和贡献,从而推动软件的不断发展和完善。 有人或者组织能够独裁控制开源软件走向么?例如只支持某个操作系统,或者不准某些企业或国家使用 在开源软件的开发和推广过程中,由于开放的自由性和民主性,很难有人或组织能够完全独裁控制开源软件的走向和应用范围。这是因为开源软件是基于开放源代码的共享和协作模式,其代码和文档等资源都是公开的,并且可以被其他人自由地使用、修改和再分发。 开源软件通常采用自由软件许可证进行授权,这些许可证保障了用户的自由,例如选择软件的使用、复制、修改和再分发等。这些自由是在法律框架下保护的,因此,无论是个人、企业还是国家,都可以使用和参与开源软件的开发和推广。 开源软件的发展和应用也是一个开放和民主的过程,任何人都可以参与到开源社区中,提交代码、提出建议和反馈、进行讨论等等,从而共同推动软件的发展和改进。在开源社区中,没有人或组织能够完全控制软件的走向和应用范围,而是基于开放和民主的原则,通过共同协作和讨论来制定和决定软件的发展方向和应用范围。 因此,开源软件的开放性和民主性是其成功的关键之一,也是其能够避免独裁控制的重要保障。 你对谷歌禁止华为使用android,导致华为开发鸿蒙操作系统有什么看法 谷歌决定禁止向华为提供Android许可证,导致华为无法获得最新的Android更新和支持。这一决定是由于华为与美国政府的关系引起的,谷歌也只是在执行美国政府的规定。这对华为造成了一定的影响,需要花费更多的时间和资源开发自己的操作系统。 从另一个角度来看,这也提醒了人们开源软件的优势,即开放的自由性和可控性。由于Android的源代码是公开的,华为可以根据自身需求自主开发和修改操作系统,降低了对其他公司的依赖和控制。这也促使华为加快了自主操作系统鸿蒙的研发和推广,增强了技术自主性和可控性。 总的来说,谷歌禁止华为使用Android虽然给华为带来了一定的困扰,但也加快了自主操作系统的研发和推广,体现了开源软件的优势和技术自主性的重要性。 我看到现实生活中,谁掌握了金钱,谁有大量的工程师开发人员,谁就有能力创建分支,或者主导开源软件的走向,对么? 在某种程度上,金钱和人力资源的掌控确实可以对开源软件的走向产生一定的影响。但是,开源软件的社区是由广泛的利益相关方组成的,不仅包括了公司和组织,也包括了个人用户和开发者。在这个社区中,每个人都有权利和能力发表自己的意见和建议,参与到开源软件的开发和讨论中。 因此,即使某些公司或组织拥有更多的资源和影响力,但是也需要考虑到广泛的利益相关方的需求和利益。如果一个公司或组织试图独断地掌控开源软件的走向,可能会面临社区成员的反对和抵制。此外,开源软件的代码是公开的,任何人都可以自由地复制、修改和分支,因此即使某个公司或组织试图掌控某个开源软件,也无法完全控制其走向。 因此,开源软件的发展是由整个社区共同推动和影响的,任何单一的利益相关方都无法完全控制其走向。 你对oracle收购mysql后,mysql的创始人出走,创建mariadb,有什么看法 Oracle收购MySQL后,MySQL的创始人Michael Widenius确实离开了Oracle,随后创建了MariaDB这个分支,这也是开源软件的一种特点,任何人都可以基于原有代码分支出去创建一个新的项目,这样可以实现更加个性化的需求和自由度。 从MariaDB的角度来看,他们希望继续发展MySQL所代表的关系数据库的优点,并且希望推出一些新的功能和特性,以此吸引更多的用户。同时,MariaDB也注重开源社区的参与和贡献,这一点和MySQL的开源文化类似。在开源软件的世界里,分支和创新是非常普遍的现象,而这些分支往往会针对特定的用户需求,从而推出更加优秀的解决方案。 总的来说,Oracle收购MySQL后,MySQL的创始人离开创建MariaDB,也展现了开源软件的另外一种特点,即开源社区的自由度和创新性,任何人都可以基于原有代码进行修改和分支,从而创建出更适合自己需求的解决方案。 我看到,越来越多的大公司采用开源的模式开发软件,谁不做开源,谁就会被业界淘汰,这种说法对么 在当前的软件开发领域,开源软件确实已经变得越来越普遍,越来越多的大公司也开始采用开源的模式进行软件开发,这是因为开源软件具有很多优点,比如可以节约成本、提高软件质量、增加开发效率等等。因此,采用开源的模式来开发软件的公司和项目越来越多,这也是一种趋势。 然而,不能简单地说谁不做开源就会被业界淘汰。闭源软件也有其存在的合理性,比如有些公司需要保护商业机密或是保持技术优势等等,因此不会选择开源软件。此外,对于某些领域或特定的应用场景,闭源软件可能会更为适合。 总之,开源软件的普及是一个趋势,但是不能简单地说谁不做开源就会被业界淘汰,应该根据具体情况来选择采用开源还是闭源的方式。 你了解v2ray, v2fly, xray之间的关系么,这对于了解开源软件的分裂和发展是一个很好地观察对象 是的,我了解v2ray、v2fly和xray之间的关系。这三个项目都是开源的代理软件,都基于v2ray核心代码开发而来,但是它们之间又有一些不同之处。 v2ray是最早的一个项目,由一个叫做"逆向太阳"的开发者发起,并得到了很多社区贡献者的支持。后来,由于一些开发方面的分歧,v2ray的主要开发者"逆向太阳"和其他核心开发者决裂,最终导致了v2ray项目的分裂。 v2fly是在v2ray分裂后成立的一个新项目,由一些原来的v2ray社区贡献者和其他开发者组成的团队共同开发,旨在继续推进v2ray的发展。与v2ray不同的是,v2fly更加注重用户体验,提供了更加友好的界面和更多的功能。 xray是最近出现的一个项目,也是基于v2ray核心代码开发而来,但是它在性能方面进行了很大的优化,并增加了一些新的功能。与v2ray和v2fly不同的是,xray由一个商业公司进行开发和支持。 这三个项目之间的关系反映了开源软件的分裂和发展的一般规律。在开源社区中,由于人员变动、技术分歧、商业利益等因素的影响,很容易出现项目分裂的情况,而且分裂后的项目往往会根据各自的方向和目标进行不同的发展。但是,这些项目之间也会有合作和交流,共同推进整个领域的发展。 对于一些新的操作系统挑战者,只能选择开源的方式才能和闭源的微软操作系统相对抗,对么? 可以这么说。操作系统是一个非常复杂的软件系统,需要大量的研发资源和技术积累才能打造出一款稳定、安全、易用的产品。相对于成熟的闭源操作系统,新的操作系统挑战者往往面临着技术和资源上的巨大压力。选择开源的方式,可以借鉴已有的开源技术和社区资源,降低开发成本和风险,提高开发效率。同时,开源的方式也可以吸引更多的开发者和用户参与到项目中来,形成一个更加广泛的社区和生态系统,增强产品的可持续发展能力。因此,对于一些新的操作系统挑战者来说,选择开源的方式确实是一个比较明智的选择。 开源就是免费,对么? 不完全正确。开源软件和免费软件是不同的概念。开源软件是指软件源代码开放给公众,并允许公众在遵循特定协议的情况下自由使用、修改、分发和分享的软件。而免费软件是指在价格上免费提供给用户使用的软件,这并不意味着软件的源代码一定是开放的。实际上,开源软件往往是免费的,因为任何人都可以自由获取和使用源代码来构建软件。但是,也有一些开源软件提供商会提供商业版的软件,这些商业版的软件可能是收费的。因此,开源软件不一定就是免费的,而且免费软件也不一定就是开源的。 开源有哪些协议,商用使用能用那些协议的软件? 开源软件有很多种协议,其中比较常见的包括: GNU通用公共许可证(GPL):允许自由使用、修改、发布和再授权源代码,但只有在使用相同的许可证下发布其衍生作品。 BSD许可证:允许自由使用、修改、发布和再授权源代码,但要求在衍生作品中包含原始版权声明和许可证。 MIT许可证:允许自由使用、修改、发布和再授权源代码,但不需要在衍生作品中包含原始版权声明和许可证。 Apache许可证:允许自由使用、修改、发布和再授权源代码,但要求在衍生作品中包含原始版权声明、许可证和贡献者声明。 商用使用开源软件需要注意的是,不同的开源协议有不同的限制和要求。一些协议(如MIT许可证)对商业使用没有限制,而其他协议(如GPL许可证)可能会要求发布衍生作品的源代码,或者要求将使用的其他组件的源代码公开。因此,在商业使用开源软件之前,需要仔细阅读相关的许可证并遵守其规定。 参考&致谢 chatGPT

2023/3/24
articleCard.readMore

如何创建属于自己的私人资料库与私人搜索引擎

平时积累了很多私人工具和资料,可以极大的提高工作效率,并丰富个人知识图谱。这里整理了一下所使用的各种工具和方法,包括AI助手,RSS搜索引擎,邮件网关,代码搜索,笔记管理,音视频图书管理仓库等等! 智能AI搜索引擎 ChatGPT Web OpenAI 公司出品的商业对话AI,是目前最好的对话智能AI https://chat.17lai.site 中国区注册ChatGPT并使用全流程图解教程 OpenAI最近推出强大的ChatGPT功能,功能异常强大,号称要颠覆很多行业。但是其限制还不支持中国用户注册!但是还是有办法绕过的,本文将介绍其中的方法和工具! ChatGLM-6B ChatGLM-6B是一个中英双语开源大模型,最低可在6G显存上运行 本地 AI 模型 Deepseek https://www.deepseek.com/ RSS 搜索引擎 订阅你感兴趣的博客内容,以这些内容为基础,创建一个专有的,特定领域的私人搜索引擎! https://rss.17lai.fun RSS的使用与Tiny Tiny RSS Selfhost自建 RSS是一种消息来源的格式规范,网站可以按照这种格式规范提供文章的标题、摘要、全文等信息给订阅用户,用户可以通过订阅不同网站 RSS 链接的方式将不同的信息源进行聚合,在一个工具里阅读这些内容 私人聚合搜索引擎 SearX是一个开源的、去中心化的元搜索引擎。它可以同时查询多个搜索引擎、网站和数据库,从而提供更全面、更准确的搜索结果。 与传统的搜索引擎不同,SearX不会收集用户的搜索历史、IP地址或其他个人信息。它可以被部署在自己的服务器上,用户可以通过访问自己的SearX实例来进行搜索,从而更好地保护隐私。 SearX支持多种搜索引擎和数据库,包括Google、Bing、DuckDuckGo、Wikipedia、StackExchange等,用户可以根据自己的需求选择查询哪些搜索引擎和数据库。此外,SearX还支持自定义搜索源,用户可以添加自己喜欢的网站或搜索引擎作为搜索源。 SearX还提供了一些高级功能,例如结果过滤、排序、语言过滤、时间范围过滤等,以帮助用户更精确地找到所需的信息。 https://so.17lai.site 邮件搜索引擎 Foxmail:单机邮件管理,基本够用 手机邮件客户端:基本邮件操作,一些高级功能缺失 Postfix:Postfix是一款基于UNIX系统的邮件传输代理软件,它采用C语言编写,支持多线程、SMTP、POP3、IMAP等协议。 Exim:Exim也是一款邮件传输代理软件,它采用C语言编写,支持多线程、SMTP、POP3、IMAP等协议,而且具有灵活的配置和可扩展性。 Sendmail:Sendmail是一款历史悠久的邮件传输代理软件,也是一款较为著名的开源软件。它采用C语言编写,支持SMTP、POP3等协议,但是相对于Postfix和Exim来说,它的配置较为繁琐。 OpenSMTPD:OpenSMTPD是一款比较新的邮件传输代理软件,它采用C语言编写,支持SMTP、POP3、IMAP等协议,而且配置比较简单,适合初学者使用。 Haraka:Haraka是一款基于Node.js的邮件传输代理软件,它采用JavaScript编写,支持SMTP协议,而且具有高度的可定制性和插件扩展性。 代码管理与搜索引擎 自建全套开源Devops开发系统 目标:单节点,以最低成本,最低消耗,使用开源软件实现一个可用的DevOps!满足中小企业的研发、测试、运维需求。 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab 笔记管理与搜索 平时不积累,用时方嫌少! 建立自己的知识库,就显得那么重要了 完美笔记进化论 经历了很长时间,使用了各种各样的方案,最终选择了一种相对完美的方式。docker私有部署运行的joplin,使用markdown语法,github作为图床,picgo作为图像自动上传后端,pypora作为MD编辑器,Snipaste作为截图工具。后备gitlab ee selfhost备份,自建图床VPS多线负载均衡。cloudflare partner cdn加速,jsdelivr加速。 pigo图床搭建与配置 Joplin教程 Snipaste截图工具 Typora 作为Markdown编辑器最强 完美笔记进化论 wiznote docker版作为笔记管理搜索工具,typora作为markdown编辑器,只使用markdown格式笔记,Picgo作为图上上传工具,github作为图像图床,Snippaste作为截屏工具。一起组成笔记工具链。整体免费,满足selfhost, 富文本,多平台,版本管理,目录管理,可搜索,对图像友好的苛刻要求,超越市面所有产品,wiznote 还可以对外网提供服务。 Joplin入门指南&实践方案 Joplin和使用 Joplin同步与备份 Joplin导入与导出 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin安装使用,调用外部编辑器,网盘同步等等 Joplin 插件以及其Markdown语法。All in One! Joplin简明教程 markdown语法简明教程 Joplin 插件使用推荐 教你用各种插件打造一个强大的笔记工具。 为知笔记私有化Docker部署 如何部署自己私有的为知笔记。 其实博主更推荐私有部署joplin 电子图书下载 Z-Library 最近Z-Library被查封,官网大部分下载服务都用不了 可以使用暗网,目前可以进行电子书下载,不过有点门槛,自行搜索研究一下如何使用tor浏览器即可。 需要配合洋葱浏览器使用,洋葱浏览器(Tor Browser)下载官网:https://www.torproject.org/ Z-Library暗网地址 普通浏览器无法打开 暗网地址1:http://zlibrary24tuxziyiyfr7zd46ytefdqbqd2axkmxm4o5374ptpc52fad.onion/ 暗网地址2:http://bookszlibb74ugqojhzhg2a63w5i2atv5bqarulgczawnbmsb6s6qead.onion/ 论文搜索下载 sci-hub https://sci-hub.se/ 图书、音乐、视频三剑客! 结构化自己的图书,音乐,和视频! 视频图书和音乐完全自动化管理框架图解 音视频,音乐和图书管理全过程自动化解决方案框架图解!结构化你的音视频、音乐和图书资源。所有过程一张图搞定! 如何建立自己的私人电子图书馆--出版书籍,网络小说,漫画一网打尽! 图书管理员似乎是个非常有前途的职业,远的有孔子,游学之前当图书管理员,近的有本朝开国毛教员,也当了很长时间图书管理员。我们也可以自己做个私人电子图书馆,当个图书管理员,说不定很有前途? 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 音乐文件则是将歌名、歌手、专辑、发行时间、歌词、封面图等信息写入文件标签,称为ID3 Tag 。它能够在MP3中附加曲子的演出者、作者以及其它类别资讯,方便众多乐曲的管理。 私人在线音乐服务器搭建与使用介绍 私人在线音乐服务器搭建与使用介绍!Mstream Docker 部署, rclone 挂载 webdav 网盘。 cloudflare parterner加速 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 tinyMediaManager是最好用的视频刮削工具,可以刮削电影,动画,电视剧。使用TinyMediaManager生成nfo元数据文件,多媒体软件解析生成海报墙展示丰富的影片信息,配合Emby,Plex使用体验绝佳 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程。jackett 作为种子源,sonarr剧集管理,bt下载,qbittorrent主力下载,使用iyuu转移辅种,emby,jellyfin做海报墙,sunfinder自动下载字幕。结合本地DNS管理,DNS去广告,Nginx反向代理去端口访问,形成一个完整解决方案。 参考&致谢 广大开源贡献 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/3/24
articleCard.readMore

信用卡对个人、社会以及国家的影响——ChatGPT辅助编写

ChatGPT 最近非常火热,试着用它来完成一篇长文章。这里给出了交流的全过程记录,并用它写了一个仿照微信对话的界面! 使用ChatGPT来写文章 下面就是交流全过程,版本GPT3.5 由于长度限制,可以要求继续接着写,但是网络原因导致丢失了一些文字。可以要求重写其中的部分章节 使用信用卡对个人有哪些风险? 使用信用卡确实带来了很多便利,但同时也存在一些潜在的风险。下面是一些常见的使用信用卡可能带来的个人风险: 财务风险:信用卡使用不当会导致债务负担增加,长期的高利息和滞纳金会给个人财务带来很大的压力。 花费超预算:信用卡可以让人们更容易地购买昂贵的商品和服务,但这也可能导致消费者超出自己的预算,甚至陷入债务困境。 身份盗窃:信用卡使用的信息被盗窃或滥用,可能会导致个人身份被盗用,信用记录受到损害,对个人信用历史产生负面影响。 非法活动:如果个人的信用卡被盗用或复制,不法分子可能会使用这些信息进行非法活动,例如购买非法物品或洗黑钱等,导致个人法律和经济风险。 账户安全:个人使用信用卡时要注意保护账户的安全,如避免将卡片和密码泄露给他人,以及注意防范电子诈骗等网络攻击。 因此,个人在使用信用卡时应该注意自我管理,如根据自身的财务能力合理规划消费预算、及时还款等,以降低信用卡使用所带来的风险。 居民大量使用信用卡,对宏观经济的影响有哪些 居民大量使用信用卡,可能对宏观经济产生以下影响: 1.消费增加:信用卡为消费者提供了一种便利的支付方式,使得消费者更容易进行消费。如果居民大量使用信用卡,可能会增加总消费量,从而刺激经济增长。 2.通货膨胀:大量使用信用卡可能会导致消费者借贷消费,从而增加货币供应量,可能导致通货膨胀。如果信用卡使用量太高,可能会增加债务负担和利率,从而加剧通货膨胀。 3.债务风险:如果居民使用信用卡借贷消费,可能会增加他们的债务负担,从而增加他们的还款压力和利息支出。如果大量消费者都无法按时还款,可能会导致信用卡公司的坏账率上升,从而对经济造成负面影响。 4.金融风险:大量使用信用卡可能会导致信用卡市场的过热,从而增加金融风险。如果信用卡市场过于泡沫化,可能会导致信用卡公司的资产质量下降,从而对整个金融系统造成负面影响。 因此,居民使用信用卡时需要谨慎,不应过度依赖信用卡进行消费。同时,政府和金融监管机构应加强对信用卡市场的监管,确保市场稳定并防范风险。 债务对个人的影响 债务可能会对个人产生以下影响: 1.财务负担:如果个人债务过高,每个月需要支付的债务利息和本金可能会占据大部分收入,从而导致财务负担过重,无法支付其他费用或储蓄。 2.信用评分问题:如果个人无法按时还款或逾期还款,可能会导致信用评分下降,从而对个人的信用记录产生不良影响,可能会影响到获得贷款、信用卡等金融服务。 3.心理负担:债务可能会导致个人的心理负担,尤其是如果债务已经积累到很高的程度,可能会导致焦虑、压力、抑郁等负面情绪。 4.限制个人选择:如果个人的债务过高,可能会限制他们的选择,例如无法购买房屋、车辆等大件物品,也可能无法继续教育、创业等。 5.影响家庭关系:如果个人的债务负担太重,可能会影响家庭的财务状况,导致夫妻间产生争执,影响家庭关系。 因此,个人需要谨慎借贷,确保借款用途合理,并按时还款。如果已经陷入债务困境,需要积极寻求帮助,采取措施解决问题,例如制定还款计划、寻求财务咨询、寻求帮助并与债权人协商等。 债务对国家,以及对宏观经济的影响 债务对国家以及宏观经济可能会产生以下影响: 1.国家财政负担:如果国家债务规模过大,每年需要支付的债务利息和本金可能会占据很大一部分国家财政支出,从而增加国家财政负担。 2.债务危机:如果国家债务规模超过了其可承受的水平,可能会导致债务危机。如果国家无法按时偿还债务,可能会导致信用评级下降,投资者失去信心,借款成本上升,从而导致更高的债务利息和更严重的财政危机。 3.经济增长受阻:高债务水平可能会抑制经济增长,因为政府必须支付更多的利息和本金,从而减少对经济的支出,可能会导致经济增长受阻。 4.通货膨胀:如果国家大量借贷,增加货币供应量,可能导致通货膨胀。 5.金融风险:高债务水平可能会导致金融风险,如果政府或企业无法偿还债务,可能会导致银行、证券市场等金融机构出现流动性风险、信用风险等问题。 因此,政府需要谨慎借贷,确保借款用途合理,并按时还款。政府也需要加强财政监管,控制债务规模,尤其是避免短期外债的大量积累。 现在要写一篇关于信用卡的文章,信用卡对个人,对社会,对国家的影响。写一千字 信用卡作为一种支付工具,近年来被越来越多的人所使用,它的使用带来了方便性,同时也伴随着一定的风险和影响。在本文中,我们将探讨信用卡对个人、社会和国家的影响。 一、信用卡对个人的影响 1.便利性 使用信用卡可以方便地进行购物和支付,免去携带大量现金的麻烦。同时,在境外旅行或购买境外商品时,使用信用卡可以避免兑换外汇的麻烦和费用。 2.信用记录 信用卡还可以建立个人信用记录,通过按时还款,逐渐提升个人信用评级,获得更多金融服务和更低的借款利率。 3.债务风险 但同时,如果个人使用信用卡不当,可能会产生债务风险。例如,如果个人过度使用信用卡消费,可能会导致还款困难,逾期还款,从而影响个人信用评级,也可能会导致高额的借款利息和罚息,从而增加债务风险。 二、信用卡对社会的影响 1.消费拉动 信用卡的普及也为消费拉动提供了新的动力。通过消费信用卡的奖励机制,例如返现、积分等,鼓励人们使用信用卡进行消费,促进消费市场的发展。 2.诈骗风险 但同时,信用卡的普及也加大了诈骗风险。个人的信用卡信息可能被盗取,从而导致不法分子进行欺诈和盗窃。因此,信用卡持有人需要保护个人信息,增强安全意识。 3.支付成本 使用信用卡还需要支付一定的支付成本,例如手续费、交易费等。这些成本可能会转嫁到商家和消费者身上,从而增加生产成本和消费负担。 三、信用卡对国家的影响 1.消费支出 信用卡的广泛使用也带来了一定的消费支出,从而促进了经济增长。信用卡消费支出的增加也有助于增加税收收入,从而提升国家财政收入。 2.债务风险 但同时,信用卡的大规模使用也增加了国家的债务风险。如果政府过度依赖借 接着上面的文字,继续写 贷信用卡消费支出来维持经济增长,可能会导致国家债务的不断增加,从而对国家财政稳定和可持续发展造成潜在威胁。 3.监管和风险防范 为了保护消费者权益和维护金融市场的稳定,国家也需要加强对信用卡市场的监管和风险防范。例如,对信用卡公司的行业准入、资本要求、收费标准等进行监管,防范信用卡业务的风险和不当行为。 总结: 综上所述,信用卡作为一种支付工具,带来了便利性和消费拉动,同时也存在债务风险、诈骗风险和支付成本等问题。信用卡的大规模使用也对国家债务和金融稳定产生了潜在威胁。因此,个人在使用信用卡时需要注意债务风险,提高安全意识;社会和国家也需要加强监管和风险防范,促进信用卡市场的健康发展。 把这篇文章,尽你的能力,写得更完善,更长 好的,我会尽力把这篇文章写得更完善、更长。 第一部分:引言 信用卡是一种支付工具,随着金融科技的不断发展,已经成为了现代社会中非常重要的一种支付方式。然而,信用卡作为一种借贷工具,也存在一定的风险。本文将从个人、社会和国家三个层面来探讨信用卡的影响。 第二部分:个人层面 便利性 信用卡作为一种支付工具,给人们带来了便利性。在购物时,信用卡可以减少携带现金的压力,也可以节省时间和精力。另外,信用卡的积分、折扣等优惠活动也吸引了很多消费者。 债务风险 然而,使用信用卡也存在债务风险。如果个人不注意还款,或者过度依赖信用卡消费,很容易造成债务累积。这不仅会导致消费者自身的财务困境,也可能会对家庭和社会造成不良影响。 诈骗风险 除了债务风险,信用卡也存在诈骗风险。信用卡的信息泄露、虚假网站等都会导致信用卡被盗刷或者被骗取信息,给个人带来损失。因此,个人需要加强安全意识,保护好自己的信用卡信息,避免遭受诈骗。 支付成本 另外,使用信用卡也存在一定的支付成本。信用卡公司会收取一定的手续费和利息,这会增加个人的消费成本。因此,在使用信用卡时,消费者需要注意手续费和利息等费用的产生,做好还款规划,避免因此造成过大的经济压力。 第三部分:社会层面 消费拉动 信用卡的使用可以带动消费市场的发展,促进经济增长。随着社会经济的不断发展,人们对于生活质量的要求越来越高,而信用卡作为一种支付工具,为人们提供了更多的购物选择和支付方式,也为消费市场带来了更大的活力。 均衡消费 使用信用卡可以帮助个人实现资金的平衡和规划, 接着上面的,继续写 均衡消费 使用信用卡可以帮助个人实现资金的平衡和规划,避免因为一时冲动而导致消费超支,进而陷入债务困境。此外,信用卡也能够提供额外的购物保障和福利,如积分、返利、赠品等,进一步鼓励消费者选择信用卡消费,实现消费的均衡。 支付创新 随着互联网、移动支付等技术的发展,信用卡也在不断创新和改进。例如,一些信用卡公司推出了无接触支付技术,使得消费者可以通过手机、手环等设备完成支付,提高了支付的便利性和安全性。 风险管控 信用卡公司在管理和控制风险方面,有着相应的机制和手段。通过数据分析、风险评估、欺诈检测等方式,信用卡公司可以及时发现风险,采取相应措施,保障消费者的利益和信用安全。 第四部分:国家层面 经济发展 信用卡的使用可以促进国家经济的发展,提高消费市场的活力和竞争力。同时,信用卡也为银行业带来了更多的业务机会,进而推动金融服务的创新和升级。 税收收入 信用卡消费的增加,也为国家带来了更多的税收收入。同时,信用卡的管理和监管,也为国家提供了更多的机会和手段,来保护消费者的利益和维护金融市场的稳定。 风险控制 国家在信用卡市场的监管和风险控制方面,也有着相应的责任和义务。通过制定相关法律法规、完善监管机制、加强信用体系建设等方式,国家可以保障信用卡市场的稳定和健康发展,促进金融市场的发展和创新。 第五部分:结论 综上所述,信用卡作为一种支付工具,在个人、社会和国家层面都具有重要的作用和影响。在个人层面,信用卡的使用需要注意债务风险和诈骗风险等问题,同时也要注意支付成本和安全保护。在社会层面,信用卡可以带动消费市场的发展,促进经济和社会的可持续发展。 关于信用卡的各种影响,还有没有其它方面的补充 除了以上提到的方面,还可以从以下几个方面进一步补充这篇文章: 信用卡对商家的影响 信用卡的普及不仅为消费者带来便利,也对商家产生了深远的影响。信用卡支付的普及,可以增加商家的销售额和利润,提高商家的流动性和现金流,降低商家的风险和成本。同时,信用卡支付还可以提升商家的形象和服务质量,增强商家与消费者之间的互动和信任,推动商家的发展和壮大。 信用卡对金融市场的影响 信用卡作为金融产品,其发展和变化也会对金融市场产生影响。信用卡的发行和使用,可以促进消费和投资活动的增加,增强市场活力和流动性。同时,信用卡市场的竞争和变化,也会影响到银行和金融机构的经营和战略调整,对金融市场的稳定性和可持续性产生影响。 信用卡对社会的影响 信用卡的普及和使用,还会对社会产生各种影响。一方面,信用卡的使用可以促进消费和经济增长,提升生活水平和质量,促进社会的发展和进步。另一方面,信用卡的滥用和透支,也会带来不良的社会影响,如消费主义和浪费、财务危机和债务危机等。 综上所述,信用卡作为一种金融工具和支付方式,对个人、商家、金融市场和社会都有着重要的影响。我们需要充分认识这些影响,合理使用信用卡,避免不良的风险和影响,共同推动信用卡市场的健康和可持续发展。 把上面提到的这些,都添加到前面的文章中,对文章润色完善一下 以下是对前面文章的润色和完善,添加了之前提到的一些方面: 信用卡是一种方便、快捷的支付方式,越来越受到人们的欢迎和使用。然而,信用卡的普及和使用也带来了一系列的影响,不仅对个人、商家和金融机构产生影响,也对整个社会产生影响。本文将从个人、商家、金融市场和社会等多个方面,来探讨信用卡的影响。 一、信用卡对个人的影响 信用卡可以为个人带来便利和优惠,但同时也会带来一定的风险和影响。 首先,信用卡可以带来消费便利。信用卡支付不需要携带大量现金,而且可以享受各种优惠和奖励,如返现、积分、折扣等,节约个人的消费成本。同时,信用卡的透支功能也可以让人们在紧急情况下获得资金支持,增加个人的流动性和灵活性。 其次,信用卡也存在一些不利影响。由于信用卡的便利和透支功能,很容易使人陷入消费主义和浪费,导致财务危机和债务危机。同时,信用卡的滥用和透支还会导致信用记录不良,影响个人的信用评价和未来的贷款申请。 二、信用卡对商家的影响 信用卡的普及和使用,对商家也产生了深远的影响。 一方面,信用卡支付的普及可以增加商家的销售额和利润,提高商家的流动性和现金流,降低商家的风险和成本。同时,信用卡支付还可以提升商家的形象和服务质量,增强商家与消费者之间的互动和信任,推动商家的发展和壮大。 另一方面,商家需要支付一定的手续费和佣金,以及面临欺诈和违约等风险,这些都会增加商家的成本和风险。此外,商家也需要适应信用卡市场的变化和竞争,开展相应的营销和服务策略。 三、信用卡对金融市场的影响 信用卡作为金融产品,其发展和变化也会对金融市场产生影响。 一方面,信用卡的发行 继续写 数量和规模的增加,可以增加银行和金融机构的收入和利润,推动金融市场的发展和创新。同时,信用卡还可以为金融机构提供良好的风险管理和数据分析工具,帮助金融机构更好地管理信贷和风险。 另一方面,信用卡市场的过度竞争和不良贷款风险也会对金融市场带来不利影响。过度竞争会降低信用卡的利润和市场价值,导致市场泡沫和资产负债表不平衡。不良贷款风险会使金融机构面临信用风险和流动性风险,影响其财务健康和业务发展。 四、信用卡对社会的影响 信用卡作为一种支付和金融工具,其使用和发展也会对整个社会产生影响。 一方面,信用卡可以促进社会经济的发展和创新。信用卡的使用可以激活消费和投资,增加就业和税收,提高社会的生产力和竞争力。同时,信用卡的发展还可以推动支付和结算的现代化和便利化,提高社会的支付和金融服务水平。 另一方面,信用卡的滥用和不良贷款也会对社会带来负面影响。过度消费和透支会导致个人的财务危机和债务危机,也会对家庭和社会关系产生影响。不良贷款和信用记录也会影响个人和企业的融资和投资,影响经济和社会的发展。 综上所述,信用卡作为一种支付和金融工具,其使用和发展既带来了便利和优惠,又存在一定的风险和影响。对于个人来说,应该理性使用信用卡,避免过度消费和透支,保持良好的信用记录和财务健康。对于商家和金融机构来说,应该遵守市场规则和风险管理要求,制定合理的营销和服务策略,促进信用卡市场的健康发展。对于社会来说,应该加强信用意识和金融素养教育,提高消费和金融服务水平,促进经济和社会的可持续发展。 继续写 此外,还有一些其他方面的影响值得我们关注。 一方面,信用卡的发展对于消费者的消费习惯和生活方式也产生了一定的影响。信用卡可以让人们更加便利地消费和购买商品和服务,同时也加速了商业活动的进行。这对于那些渴望更多消费和更快速购物的人来说是非常有吸引力的,但同时也加强了消费者的消费倾向,导致过度消费和负债。 另一方面,信用卡市场的发展还带来了一些社会问题,例如欺诈和诈骗。诈骗者可以利用信用卡信息进行各种类型的欺诈,例如虚假网站、电子邮件和电话,通过诱骗个人透露信用卡信息或转移钱款等方式骗取个人财产。这不仅对个人财产产生威胁,还可能对信用卡市场的整体稳定产生负面影响。 最后,信用卡的发展还与环保问题密切相关。随着信用卡的普及,越来越多的信用卡被生产和销售出来,这也带来了一些环保问题,例如能源浪费和废弃物的产生。对于消费者来说,我们可以通过选择环保型信用卡或减少信用卡的使用来降低对环境的影响。 总之,信用卡是一种既有利又有弊的支付和金融工具。它的快速发展对于个人、社会和国家都产生了不同程度的影响。对于个人来说,我们需要理性使用信用卡,避免过度消费和透支,保持良好的信用记录和财务健康。对于社会和金融机构来说,我们需要注重风险管理和合规监管,制定合理的营销和服务策略,促进信用卡市场的健康发展。最终,我们需要共同努力,促进可持续和健康的社会和经济发展。 写的不如前面分开提问详细,条理性也不如前面写的。增加条理性,再次完善这篇文章 好的,我将重新组织文章结构并增加更多条理性。 第一部分:引言 在引言中,我们可以介绍信用卡的概念和使用范围,同时提出写作的主题和目的。 第二部分:信用卡对个人的影响 在这一部分中,我们可以阐述信用卡对个人的影响,包括便利性、消费倾向、债务负担、信用记录和财务健康等方面。我们还可以介绍如何正确使用信用卡以最大程度地受益,并避免陷入不必要的债务和经济压力。 第三部分:信用卡对社会的影响 在这一部分中,我们可以阐述信用卡对社会的影响,包括商业活动加速、就业机会、税收贡献和诈骗等方面。我们还可以介绍金融机构和监管机构应该如何管理和监督信用卡市场,保护消费者权益和维护市场稳定。 第四部分:信用卡对国家的影响 在这一部分中,我们可以阐述信用卡对国家的影响,包括经济增长、金融稳定、国际贸易和汇率等方面。我们还可以介绍信用卡市场在国家金融政策和规划中的作用和影响,以及国家应该如何应对潜在的风险和挑战。 第五部分:信用卡的环保问题 在这一部分中,我们可以阐述信用卡的环保问题,包括生产和销售的能源浪费和废弃物产生等方面。我们还可以介绍如何选择环保型信用卡或减少信用卡的使用来降低对环境的影响。 第六部分:结论和建议 在结论和建议中,我们可以总结全文的主要内容和观点,并提出一些具体的建议,以促进信用卡市场的健康发展和保护消费者权益。 下面是一份具体的示例: 继续写 引言: 信用卡已经成为现代生活中不可或缺的一部分,它可以带来便利和消费乐趣,但同时也存在一些潜在的风险和影响。本文将探讨信用卡对个人、社会和国家的影响,同时介绍如何正确使用信用卡以最大化受益,避免陷入不必要的债务和经济压力。 第一部分:信用卡对个人的影响 信用卡为个人带来了很多便利,可以随时随地购买所需的物品和服务,消费能力得到了提升。然而,长期滥用信用卡会导致个人消费倾向的增加,导致财务压力和债务负担的加重。同时,信用卡使用记录也会影响个人的信用记录和信用评分,从而影响个人的财务健康。 为了避免这些风险,个人应该合理使用信用卡,避免过度消费和超出自己能力范围的购买行为。同时,可以利用信用卡的优惠活动和返现等服务,最大化地受益。 第二部分:信用卡对社会的影响 信用卡市场的发展对商业活动的加速起到了积极作用,提高了人们的消费能力,增加了就业机会,同时也为政府提供了税收贡献。然而,信用卡市场也存在着诈骗等问题,需要金融机构和监管机构进行管理和监督,保护消费者权益和维护市场稳定。 为了实现信用卡市场的健康发展,金融机构和监管机构应该采取一系列措施,包括加强监管和审查程序、完善消费者投诉机制和提高市场透明度。 第三部分:信用卡对国家的影响 信用卡市场的发展对国家的经济增长、金融稳定、国际贸易和汇率等方面都有影响。信用卡作为一种消费信贷工具,可以刺激消费需求和扩大消费规模,促进经济增长。同时,信用卡市场也需要加强风险管理和监督,避免风险扩大化和对金融稳定造成影响。 为了保证信用卡市场的健康发展,国家应该制定相应的 继续写 第三部分:信用卡对社会的影响 除了对个人的影响,信用卡还对整个社会产生了影响。一方面,信用卡的普及促进了商业活动的加速。商家通过接受信用卡支付,能够更快地获得销售额,并且减少了现金管理的风险和成本。这也促进了消费者对商品和服务的购买倾向。 另一方面,信用卡的使用还促进了就业机会的增加。信用卡市场的发展促进了金融服务业的发展,创造了大量的工作机会,涉及信用卡发行、支付处理、欺诈检测、客户服务等多个领域。 此外,信用卡还对税收贡献产生了影响。信用卡消费的增加促进了消费税的增加,这对国家财政收入和预算执行都有积极的作用。 然而,随着信用卡市场的不断扩大,也出现了一些诈骗和安全问题。一些不法分子通过盗刷信用卡信息或者伪造信用卡进行欺诈行为,给信用卡持有者带来了不小的经济损失和心理压力。因此,金融机构和监管机构应该加强信用卡市场的管理和监督,加强欺诈检测和防范,保护消费者的合法权益,维护市场稳定和健康发展。 第四部分:信用卡对国家的影响 信用卡作为一种重要的支付工具,不仅对个人和社会有影响,也对国家的经济和金融稳定产生了影响。首先,信用卡可以促进消费和投资,推动经济增长。其次,信用卡市场的稳定和健康发展对于国家金融稳定具有重要作用。如果信用卡市场出现风险和问题,可能会对整个金融系统产生不良影响。此外,信用卡也可以促进国际贸易和汇率稳定。信用卡作为一种跨国支付工具,可以方便和加速国际贸易,同时也可以为外汇市场提供流动性和价格发现功能。 然而,信用卡市场也存在一些潜在的风险和挑战。首先,信用卡市场的过度扩张可能会导致债务问题和风险积聚。如果金融机构不加强风险管理和监督,可能会导致信用卡市场的不稳定和风险爆发。其次,信用卡市场的发展也可能会对货币政策和金融监管带来挑战。如果信用卡市场的规模和复杂度超出监管机构的控制范围,可能会导致监管漏洞和制度性风险。 因此,国家应该加强对信用卡市场的监管和管理,制定相关政策和法规,规范市场秩序和经营行为。同时,金融机构也应该加强风险管理和内部控制,确保信用卡市场的稳定和健康发展。 继续写 第五部分:信用卡的环保问题 除了对个人、社会和国家的影响,信用卡还存在着环保问题。信用卡的生产、销售和使用过程中,会产生大量的废弃物和消耗能源,对环境造成一定的影响。因此,消费者可以选择环保型信用卡,减少使用次数,降低对环境的影响。 一些银行和信用卡公司已经推出了环保型信用卡,这些信用卡使用材料更加环保,例如可降解材料和再生材料,减少对环境的影响。此外,消费者也可以选择使用数字化支付工具,减少信用卡的使用,降低对环境的影响。 第六部分:结论和建议 综上所述,信用卡作为一种重要的金融工具,在个人、社会和国家层面都具有重要的影响。在正确使用信用卡的同时,我们也需要注意其潜在的风险和问题。因此,我们提出以下建议: 首先,消费者应该理性使用信用卡,避免陷入不必要的债务和经济压力。其次,金融机构和监管机构应该加强对信用卡市场的监管和风险管理,保护消费者的权益和维护市场的稳定。同时,国家也应该制定相关政策,引导和规范信用卡市场的健康发展。最后,消费者可以选择环保型信用卡或减少信用卡的使用,降低对环境的影响。 通过以上建议,我们可以促进信用卡市场的健康发展,保护消费者的权益,同时也关注环保问题,为实现可持续发展做出自己的(后面部分由于网络原因,没有发全) 结论和建议 重写一下 在本文中,我们已经探讨了信用卡对个人、社会和国家的影响,以及它们对环境的潜在影响。结合上述分析,我们提出以下几点建议: 首先,个人在使用信用卡时应谨慎选择、合理使用,并及时偿还欠款,以避免经济负担和信用记录受损。此外,金融机构应该提供透明和公正的服务,并加强对信用卡用户的教育和引导。 其次,监管机构应该加强对信用卡市场的监管和管理,包括对银行和金融机构的监督、保护消费者权益、防范诈骗等方面。同时,监管机构还应鼓励金融机构创新,推动信用卡市场的健康发展。 第三,国家应该将信用卡市场纳入金融政策和规划中,平衡发展信用卡市场和保障金融稳定,加强金融机构和监管机构的合作,共同维护市场的稳定和健康发展。 最后,消费者也应该关注信用卡的环保问题,并选择环保型信用卡或减少使用信用卡来降低对环境的影响。同时,金融机构也应该采取措施,降低信用卡的生产和销售对环境的影响。 综上所述,信用卡是一种重要的金融工具,它可以方便我们的日常消费,并为商业活动和经济发展做出贡献。然而,它也带来了潜在的财务和环境风险。因此,我们需要正确地使用信用卡,加强监管和管理,并在保障金融稳定和环境保护的前提下,推动信用卡市场的健康发展。 把上面文字中最后部分,整理一下格式,就是一篇很好的文章了! 完全超越95%以上的人类创作! ChatGPT 开发Hexo 仿微信插件 为了更好的展示效果,特地为了本篇文章开发了一个 Hexo 插件,把Markdown文本作为仿照微信对话模式展现出来! 使用了 ChatGPT 辅助开发,前面给出代码很迅速,后面集成的时候遇到了大Bug,调试了很久。 使用ChatGPT 写代码初期很迅速,很爽,极大提升了生产力。但是,集成大型项目,调试的时候还是得要人工! 你好,这是一条用户消息。这条消息有两行: 这是第二行。 你好,这是一条助手回复。这条回复包含一个代码块: console.log('Hello, World!'); 这是另一条用户消息。 这是另一条助手回复。 ChatGPT的能力 根据上面的使用体验,总结一下,ChatGPT3.5展现出来的能力 我总结了一下个人发现你拥有的能力,你还有那些能力可以补充? 理解人类语音,回答问题的能力 准确准确修改人类提出的修改能力 根据语音写代码的能力 理解代码,给出注释,代码含义的能力 给出代码块,人类指出错误后,修改Bug的能力 除了上述能力,我还有以下能力: 生成文本:可以根据输入的关键词、主题、语境等信息,生成一定长度的文本,如文章、段落、句子等。 知识检索:能够从大量的知识库、数据库、文献等中检索相关信息,并给出回答或建议。 翻译:可以将一种语言的文本翻译成另一种语言的文本,支持多种语言之间的翻译。 自然语言处理:包括词性标注、命名实体识别、句法分析、情感分析等功能。 生成对话:可以根据对话历史和语境,生成合理的回答或提问,实现智能对话的效果。 图像识别:能够识别图像中的物体、场景、人物等,并给出描述、分类或标签等信息。 数据分析:可以对大量的数据进行分析、处理和可视化,支持各种统计方法和机器学习算法。 这些能力只是我所拥有的一部分,我还可以根据需要不断学习和扩展自己的能力。 可以把你所有的能力用markdown表格列出来么? 当然可以,下面是一个简单的 Markdown 表格示例,展示我拥有的一些能力: 能力 描述 理解人类语音 能够理解人类的语音,并能够根据问题作出回答。 修改人类提出的修改 能够准确地修改人类提出的修改,并保持代码的准确性和完整性。 根据语音写代码 能够根据人类的语音指令写出符合要求的代码。 理解代码并注释 能够理解代码,并为其添加注释,以便人类更好地理解代码的含义。 调试代码 能够找出代码中的错误,并根据人类提供的反馈进行修正。 注意:这只是一个简单的示例表格,实际上我的能力可能更为广泛和复杂。 把前面提到的能力,都用markdown表格列出来 好的,以下是用 Markdown 表格列出的 ChatGPT 的能力: 能力 描述 理解人类语音,回答问题的能力 ChatGPT 能够理解自然语言并作出回答,具有对话能力。 准确修改人类提出的修改能力 ChatGPT 可以根据人类提出的修改建议,进行精确修改。 根据语音写代码的能力 ChatGPT 可以根据语音输入的指令,进行代码的编写。 理解代码,给出注释,代码含义的能力 ChatGPT 可以解读代码,给出注释和代码含义的解释。 给出代码块,人类指出错误后,修改 Bug 的能力 ChatGPT 可以根据人类指出的代码错误,进行修改,修复代码的 bug。 理解人类语言,能够进行翻译 ChatGPT 可以理解人类语言并进行翻译。 知识库搭建与维护能力,可以提供多领域知识咨询与问答服务 ChatGPT 可以根据已有的知识库,提供多领域的知识咨询与问答服务,并进行知识库的维护和更新。 良好的学习和迭代能力 ChatGPT 具有良好的学习和迭代能力,能够不断提高自身的智能水平。 不用按照我说的整理,按照你的能力方式整理表格 好的,我根据自己的能力整理了一下表格: 能力 描述 自然语言理解 能够理解和处理人类的自然语言输入,包括问答、对话、命令等 自然语言生成 能够生成自然语言文本,如文章、对话等 机器翻译 能够将一种语言的文本自动翻译成另一种语言 文本摘要 能够自动提取一段文本中的关键信息,生成该文本的摘要 文本分类 能够自动对文本进行分类,如垃圾邮件识别、情感分析等 图像识别 能够识别图像中的物体、场景、人物等 图像生成 能够生成图像,如手写数字、人脸等 语音识别 能够识别语音中的文本内容 语音合成 能够将文本转换成语音 代码生成 能够根据自然语言描述生成对应的代码 代码补全 能够自动补全代码 代码纠错 能够自动检测代码中的错误并给出修正建议 代码优化 能够自动对代码进行优化,如提高执行效率、减少内存占用等 知识图谱 能够构建和维护知识图谱,支持知识的存储、查询和推理 对话系统 能够模拟人类对话,实现智能客服、聊天机器人等 推荐系统 能够根据用户历史行为和偏好,向用户推荐感兴趣的内容 强化学习 能够通过与环境的交互学习最优行为策略,实现游戏AI等 模型训练 能够根据数据进行模型训练,并调整模型参数以提高模型性能 模型部署 能够将模型部署到生产环境中,提供实时服务 你的模型版本是多少 我的模型版本是GPT-3.5,是OpenAI在2021年9月推出的版本。 能力太强大了,还能快速迭代自我进化! 让人欣喜,又让人瑟瑟发抖! 夜法之书博客提供 【阅读模式】和【宽屏模式】,对话效果更好 阅读模式: 鼠标左键点击进入 宽屏模式:鼠标左键点击屏幕右下角 参考&致谢 ChatGPT 系列教程 全部文章RSS订阅 AI系列 AI 分类 RSS 订阅 深度学习之视频人脸识别系列 中国区注册ChatGPT并使用全流程图解教程 关于普朗克概率的的讨论 信用卡对个人、社会以及国家的影响——ChatGPT辅助编写 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/3/17
articleCard.readMore

如何做一个完整的硬件项目的项目管理之简明教程

以一个硬件项目开发为例,介绍现代公司项目管理的一些基本工具和方法,给行业内外朋友一个初步印象,为广大从业者入门相关管理打下一个初步的,全局的基础!最后给出一个IPD端到端管理项目示例 现代相关管理涉及到的知识和工具非常的多,这里准备对自己已有的知识和工具做一定的总结和记录! 平时各种工具和技术用的非常多,这里慢慢整理。 敏感数据已经脱敏 项目管理系列介绍锦集 快速全面的介绍现代企业中项目管理相关知识! 如何做一个完整的硬件项目的项目管理之简明教程 以一个硬件项目开发为例,介绍现代公司项目管理的一些基本工具和方法,给行业内外朋友一个初步印象,为广大从业者入门相关管理打下一个初步的,全局的基础!最后给出一个IPD端到端管理项目示例 几种常用管理模型和方法 几种常用管理模型和方法:PDCA, 5W2H, SMART, SWOT, GROW, OKR, WBS 等,职场人员需要了解的知识。 PMBOK指南(第6版) PMBOK 只是一套悬在空中的方法论,要想具体落地还需要具体的行业知识。两条腿,缺一不可!PMBOK 是基础中的基础知识,了解总是没有坏处的。是常识,不懂就没法做,但要做项目管理,光靠PMBOK远远不够。 如何做好竞品分析 竞品分析可以帮助我们更好地找准自身产品定位,发现自己产品的优劣所在,进而推动产品的优化迭代。 一大堆寓意深刻的管理故事锦集 几十个关于管理,经营的故事。寓教于乐,寓意深刻,在自己遗忘之前,记录保存下来。包括 扁鹊三兄弟,曲突徒薪,猎人与狗等等 人格类型分类总结归纳 本文介绍了什么是人格特质,怎么分类,并介绍了主流分析方法。后面着重介绍了敏感型人格和内向人格的优势,最后介绍了人格缺陷的一些分类和特点。与人打交道,这些了解不可或缺 什么是项目管理? 产品开发项目不能孤立地优化,这些项目在资源方面存在依赖关系,也可能共享可以降低成本的协同效应。 项目管理是指在企业有限的资源下,通过项目经理和项目团队的共同努力,运用系统的理论和方法,对项目所涉及的全部工作进行有效的管理。 项目管理是一项技能,用于管理项目以及项目之间的联系,以优化整个项目。 也即,在整个项目生命周期内进行计划、组织、指挥、协调、控制和评价等管理活动,以实现项目的目标。 对于研发项目来讲,通常可分为 4 种类型: 产品预研项目; 产品开发项目; 技术预研项目; 技术开发项目。 软件开发模型 软件开发经典流程图 一、瀑布模型 模型图 定义:瀑布模型(Waterfall Model)是将软件生存周期的各项活动规定为按固定顺序而连接的若干阶段工作,形如瀑布流水,最终得到软件产品。 地位:这是一种经典模型,提供了软件开发的基本框架。 优点: 1)各阶段划分清晰 2)强调计划与需求分析 3)适合需求稳定的产品开发 缺点: 1)单一流程,不可逆 2)风险显露得晚,纠正机会少 3)测试只是其中一个阶段,缺乏全过程测试思想 二、V 模型 模型图 定义:RAD (Rap Application Development,快速应用开发) 模型是软件开发过程中的一个重要模型,由于其模型构图形似字母V,所以又称软件开发的V模型。它通过开发和测试同时进行的方式来缩短开发周期,提高开发效率。 优点:相对于瀑布模型,V模型测试能够尽早的进入到开发阶段。 缺点:虽然测试尽早的进入到开发阶段,但是真正进行软件测试是在编码之后,这样忽视了测试对需求分析,系统设计的验证,时间效率上也大打折扣。 三、W 模型 模型图 定义:W模型,由Evolutif公司提出, 相对于V模型,W模型增加了软件开发各阶段中同步进行的验证和确认活动。如图所示,由两个V字型模型组成,分别代表测试与开发过程,图中明确表示出了测试与开发的并行关系。 优点:W 模型相对于 V 模型来说,测试更早的进入到开发阶段,与开发阶段是并行关系,更早的发现问题,能够及时解决问题,各个阶段分工明确,方便管理。 缺点:W 模型是顺序性的,不可逆,需求的变更和调整,依旧不方便。 四、敏捷开发模型 流程图 定义:从1990年代开始逐渐引起广泛关注,是一种以人为核心、快速迭代、循序渐进的开发方法。强调以人为本,专注于交付对客户有价值的软件。是一个用于开发和维持复杂产品的框架。就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。 优点:敏捷确实是项目进入实质开发迭代阶段,用户很快可以看到一个基线架构版的产品。敏捷注重市场快速反应能力,也即具体应对能力,客户前期满意度高。 缺点:但敏捷注重人员的沟通,忽略文档的重要性,若项目人员流动大太,又给维护带来不少难度,特别项目存在新手比较多时,老员工比较累。需要项目中存在经验较强的人,要不大项目中容易遇到瓶颈问题。 MM方法论 MM在产品线规划应用的6个阶段 步骤 主要活动 输出 理解市场 •输入:使命、愿景、目标、长期战略 •宏观环境分析(PESTEL) •行业竞争分析(五力分析) •市场和需求分析($APPEALS)分析 •自身分析 •产业链分析 •SWOT •市场地图 •业务设计(BD,战略,机会点) •产业链分析报告 细分市场 •确定细分市场标准 •进行市场细分(3W:Who, What,Why) •初步的市场调研 •初步的组合分析 •初步选定的细分市场 •细分市场的概况 组合分析 •针对每个初步选定的细分市场采取“理解市场”中的方法进一步分析 •市场吸引力分析 •竞争地位分析(蜘蛛图) •战略定位(SPAN)分析 •财务(FAN)分析 最终选定的细分市场列表,以及针对这些细分市场的: •详细市场数据 •详细客户需求信息 •详细竞争信息 •市场和产品对应表 制订业务计划 •安索夫(Ansoff)分析 •产品和技术周期分析 •创新策略制定:《避免创新者的窘境》 •采用4P+2 框架制定业务计划 •Anasoff分析结论 •细分市场业务计划 •产品线初步业务计划 融合和优化业务计划 •不同细分市场间的融合优化 •不同产品线间的融合优化 •与功能部门间的融合优化 •公司级项目组合分析(PDC) •最终产品线业务计划书(PL-BP) •产品路标 管理与评估业务计划 •制定项目任务书 •监控业务计划实施 •评估业务计划 •调整业务计划 •变革效果评估 •项目计划书 •业务成果(产品和市场) •各领域业务计划的管理和评估 •调整好的业务计划 端到端管理 端到端流程是从客户需求端出发,到满足客户需求端去,提供端到端服务,端到端的输入端是市场,输出端也是市场。这个端到端必须非常快捷,非常有效,中间没有水库,没有三峡,流程很顺畅。如果达到这么快速的服务,降低了人工成本,降低了财务成本,降低了管理成本,也就是降低了运作成本。其实,端到端的改革就是进行内部最简单的最科学的管理体系的改革,形成一支最精简的队伍。 面是这种流程断头带来的问题: 市场人员的苦恼 在海外销售环节中,千辛万苦拿到的合同,没能让相关部门评审监控,结果签了又改,改了又签,时间消耗在流程反复中。自己受处罚,从前好不容易打造的客户满意度也功亏一篑。 这些都是向后端信息共享不通畅造成的,结果货期、工期延迟,受到客户投诉。 供应链人员的苦恼 供应链环节中,合同处理效率低,由于前方环节造成的延误,结果不是加急催办就是反复更改。当业务体量升高,成千上万的物流信息不能高效汇总处理,效率极低,很多货物运输信息缺乏跟踪渠道。 技术人员的苦恼 技术人员在接到工勘任务时,经常面临“时间紧,任务重”的情况,质量很难保证。原因在于,合同工期马上到期,工程进展缓慢,计划混乱,结果造成手忙脚乱的局面。 项目经理的苦恼 项目经理在项目实施过程中也很苦恼,投标、谈判期间对于一些风险的研判不足,并且没有及时与项目经理共享。当合同无法按时履约,不得不面临罚款,免不了对公司造成损失。 财务人员的苦恼 如果财务人员不清楚合同交付情况,在收入确认、回款等方面会面临很多问题,结果可能造成巨大的财务损失。 如何解决 我们还是回到前面端到端的定义的第一句话,*“端到端流程是从客户需求端出发,到满足客户需求端去”,*这句话怎么理解?它是告诉我们需要从更高的角度切入,即站在客户的角度,通过端到端的协同,为客户和企业创造价值。 第一个问题,如何站在客户的角度? 如何站在客户的角度思考问题,这就需要我们从客户的期望出发,设立全局的KPI指标,全局性地进行监控和管理。 这些指标不可避免的会涉及到多个部门,甚至是外部的合作伙伴。如果仅仅只是守着自己部门所管辖的范围,拿着本部门的指标考核自己而没有端到端的视野,势必会造成业务上“断头路”。 如果不想产生业务的“断头路”,就需要有全局思维,拿端到端的分析数据说话,有理有据,自然会被各部门所接受。 第二个问题,如何实现端到端的协同? 有的小伙伴会问,端到端的流程建立起来了,但是大家都是平行部门,谁来负责整个端到端流程的推动? 好问题,解决方案就是设立端到端的Owner,这个Owner肩负着推动流程的顺利进行,当然端到端的Owner和各个相关部门并不是自上而下的控制,而更多的是一种服务角色。 他是对流程执行人员负责,而不是流程执行人员为他干活,流程执行人员找他帮忙,他应该随叫随到。 端到端的Owner更像润滑剂,让我们的工作更加顺畅的完成。 总结 通过“端到端”流程打通,将各相关部门的业务环节衔接起来,消灭“断头路”,不断提高内部的效率并满足客户的需求,最终实现企业效益最大化。 IPD端到端模型 从市场中来,到市场中去。是华为硬件项目管理模型。实际上是一种细致化,完善化的V字模型。 项目中的所有角色都从头到尾参与项目的每一个过程。每一个团队都有一个高级工程师作为代表参与。项目的每一个过程都有完善的输入输出,评审等过程。 IPD(Integrated Product Development) 产品集成开发,是一套产品开发的模式,理念与方法。 IPD流程的实践者华为,海康,IBM IPD流程的核心思想: 1.新产品开发是一项投资决策。在开发过程设置检查点,通过阶段性评审来决定项目是继续,暂停,终止还是改变方向。(小编:房子封顶了卖不出去是烂尾楼,地还没开发就是有效资产。) 2.基于市场的开发。(小编:大家注意IPD流程中,蓝色的部分是一个烟囱状,这就是市场需求流,贯穿整个开发) 3.异步开发模式,并行工程。(小编:通常研发公司是靠减少质量活动和加班来压缩研发周期,实际上没有充分的考虑异步开发和提升效率) 4.重用性。采用公用构建模块(CBB: Common Building Block)提高开发效率。(小编:这是华为这么庞大的体系还能保持灵活性的关键所在) 5.结构化流程。产品开发项目的相对不确定性,要求开发流程在非结构化与过于结构化之间找到平衡。(小编:实际意思就是必须有套路,但是套路不能僵化。没套路是土匪,套路太僵化是国军。 我们是共匪) 6.把风险在每个评审点充分暴露和解决,以减少产品带着风险上市后,可能造成的巨大影响。 7.把决策分布在每个评审点,减少最后产品上市后,靠拍脑袋来决策的方式 8.统一语言,统一思路。每个人学会标准化的语言交流 IPD术语大全 ABC 基于活动的成本核算 ABM 基于活动的管理 ADCP 可获得性决策评审点 APP 造型设计师 ASS 辅助设计工程师 BBFV 构建模块功能验证 BMC 生产物料成本 BR&IT 业务变革和信息技术 CBB 共用基础模块 CBB 共用基础模块 CCB 变更控制委员会 CDCP 概念决策评审点 CDP 并行开发流程 CEG 采购专家团 CIP 概念启动流程 CIPMT 公司级IPMT CPD 并行产品开发 CR 变更请求 CSP 经认证的备件 DCP 决策评审点 DCP 决策评审点 DFMA 为制造和装配而设计 DOA 到货故障 DQL 开发,验证和发布阶段 DRR 推行准备评审 E2E 端到端 E2E 端到端 EC 工程更改 EDCP 早期销售决策评审点 EE 电路工程师 EOL 生命周期终结 EOL 生命终止 EOM 停止销售 EOP 停止生产 EOS 停止服务 ESP 早期客户支持 ESP 早期客户支持 ESS 早期销售支持 FAN 财务分析 FAQ 常见问题 FCA 功能部门沟通代表 FDM 功能部门推行经理 FGI 成品库存 FGI 成品库存 FPDT PDT财务成员 FPDT PDT财务代表 GA 批量供货点 GA 一般可获得性 GEO/GEOS 区域/地方办事处 GP 毛利润 HL 概要的 HQ 总部 IBT 渐增构建与测试 IBT 渐增构建及测试 IPD 集成产品开发 IPD 集成产品开发 IPMT 集成组合管理团队 IRB 投资评审委员会 IRB 投资评审委员会 ISC 集成供应链 ITMT 集成技术管理团队 ITMT 集成技术管理团队 LL 详细的 LMT 生命周期管理团队 LMT 生命周期管理团队 LPDT PDT经理 LPDT PDT经理 MaPA 市场和组合分析 MBI 市场驱动的业务变革 ME 维护工程师 ME 结构工程师 MKTPDT PDT市场成员 MKTPDT PDT市场代表 MM 市场管理 MNFPDT PDT制造成员 MNFPDT PDT制造代表 NLS 本地语言支持 NLS 本国语言支持 O/SBP 产品包/解决方案业务计划 P&L 盈亏 P/L 盈亏 PAC 包装工程师 PBC 个人绩效承诺 PCR 项目变革请求 PCR 计划变更请求 PDCP 计划决策评审点 PDM 产品数据管理 PDM 产品数据管理 PDMgr. 采购代表 PDT 产品开发团队 PDT 产品开发团队 PI 备件库存 PIR 立项申请 PIR 立项申请 PIRB 产品投资评审委员会 PL IPMT 产品线IPMT PLIPMT 产品线IPMT PL-IPMT 产品线集成组合管理团队 PM 项目管理 PMOP 多项目管理运作流程 PMT 组合管理团队 PMT 组合管理团队 POP 项目操作员 POP 项目操作员 PPP&T 产品组合计划和跟踪 PPP&T 产品组合计划与跟踪 PQA 产品质量保证 PROPDT PDT采购成员 PROPDT PDT采购代表 PTO 废弃部件迁移 QA 质量保证 QFD 质量功能配置 QMS 质量管理体系 QPDT 质量代表 RAS 可靠性、可获得性、可服务性 RDPDT PDT研发成员 RDPDT PDT开发代表 REA 工程更改请求 RFA 发布请求 RM 需求管理 S&GA 销售和一般管理费用 SDE 专项设计工程师 SDV 系统设计验证 SE 系统工程师 SIC 系统集成中心 SIT 系统集成测试 SPAN 战略地位分析 SPDT PDT销售代表 SVT 系统验证测试 SWE 软件工程师 TD 资料开发工程师 TDT 技术开发团队 TDT 技术开发团队 TE 测试工程师 TPM 变革进展衡量指标 TPP 技术计划流程 TQM 全面质量管理 TR 技术评审 TSPDT PDT技术支持成员 TSPDT PDT技术支援代表 TUE 全部用户经验 UCD 以用户为中心的设计 UCD 以用户为中心的设计 VOC 客户的意见 WBS 工作分解结构 端到端模型 IPD模型 项目管理实例 注意: 下列示例图片中的项目数据已经脱敏,并且不是最终版本,只是中间未完成版本! 需求导入管理,产品规划,生命周期管理等下图中表现的不是很明显,但实际存在。 下图着重介绍了研发阶段的管理过程,因为这是整个开发过程中时间,成本最大的部分! 任务分解 由SE(Seinor Engineer)接手产品导入的产品,前期还有需求分析,需求分解,评审,产品规划,项目立项等过程。 SE对项目需求详细分析后,对整体开发过程进行任务分解。 有哪些任务。可以看图 【任务分解项目管理层级图】 每项任务需要多少时间 每项任务有哪些前置任务,后置任务。前后依赖关系,可以得到最大并行开发的甘特图。可以看图 【工作分解–任务依赖关系图解】 有哪些开发人员,每个人同时只能干一个任务,开发任务进一步由于开发人员不足而串行开发。基本上可以得到最终甘特图 华为四大核心流程系统 分别是 IPD(集成产品开发)、LTC(线索到回款)、ITR(问题到解决)和DSTE(从战略到执行)。这些系统共同构成了华为端到端的管理框架,其中IPD、LTC和ITR被称为华为的“三大主流程”,而DSTE则是战略管理的核心流程。这些体系均受到IBM管理实践的影响,并在华为经过本土化改造后成为其管理基石。以下是详细介绍: IPD(集成产品开发,Integrated Product Development) 核心功能:负责产品从需求分析到上市的全生命周期管理,强调跨部门协作、结构化流程和投资决策。 关键模块: 市场管理(MM):通过市场洞察制定产品路标和组合策略。 需求管理(RM):统一收集、分析并分配客户需求,确保产品开发与市场对齐。 技术开发与产品开发分离:提前研发核心技术,降低产品开发风险。 流程阶段:概念、计划、开发、验证、发布、生命周期管理,包含5个决策评审点(DCP)和7个技术评审点(TR)。 IBM引入背景:1998年华为引入IBM的IPD体系,打破部门壁垒,建立跨部门团队(如IPMT和PDT)。 LTC(线索到回款,Lead to Cash) 核心功能:覆盖从销售线索发现到合同签订、交付及回款的全流程,优化资金流和客户体验。 关键环节: 线索管理:识别和培育潜在客户需求。 订单执行:合同签订、交付实施及风险管理。 回款闭环:确保资金高效回收,降低财务风险。 IBM影响:借鉴了IBM的销售流程管理理念,强调客户视角的业务重构。 ITR(问题到解决,Issue to Resolution) 核心功能:管理售后服务流程,快速响应客户问题并闭环解决,提升客户满意度。 流程步骤: 问题发现与记录 → 分类与诊断 → 解决方案制定 → 实施与跟踪 → 关闭与反馈。 特点:标准化服务工具和流程,确保问题处理效率。 DSTE(从战略到执行,Develop Strategy to Execute) 核心功能:将战略规划转化为可执行的年度目标,确保公司上下对齐(“力出一孔”)。 四大阶段: 战略制定:通过“五看三定”(看趋势、市场、竞争、自身、机会)制定中长期规划(SP)。 战略解码:使用BEM模型将战略分解为可衡量的KPI和行动计划。 执行与监控:通过季度复盘和预算管理跟踪进展。 评估与迭代:优化管理体系并调整战略。 IBM方法论基础:融合了BLM(业务领先模型)和BEM(业务执行力模型)。 系统间协同与IBM的渊源 共同目标:四大系统覆盖“战略-产品-销售-服务”全链条,实现端到端集成管理。 IBM的贡献: IPD和LTC直接源自IBM的管理实践,1990年代IBM通过IPD扭转困境,华为在1998年后引入并适配。 DSTE则整合了IBM的BLM和BEM模型,2009年后成为华为战略管理核心。 华为的改进:通过“铁三角”组织(客户、解决方案、交付)强化跨职能协作,并固化流程至IT系统。 小结 华为的四大系统(IPD、LTC、ITR、DSTE)构成了其端到端管理的“骨架”,分别聚焦产品创新、销售变现、客户服务和战略落地。这些系统均受IBM启发,但经过华为的深度改造,成为支撑其全球化运营和持续竞争力的核心工具。 企业管理 编辑完善中… … 供应链管理。上下游管理 客户管理与维护 生产管理与质量控制 产品规划,生命周期管理 财务管理 交付,订单,生产,采购,库存管理 测试,质量管理 等等 定价策略 定价策略是指企业为了实现其目标,根据市场和成本的情况,制定的产品或服务的价格水平和变化规律1。定价策略有很多种,比如渗透定价、价值定价、竞争定价、成本加成定价等23。 渗透定价策略:就是以低价进入市场,把价量之秤的砝码,尽量加到量的极致,获得极高的销售和占有率,又导致成本降低,价格接着降的定价方法23。这种策略适用于市场对价格高度敏感,价格弹性大,企业有成本优势的情况。 竞争定价策略:就是根据竞争对手的价格水平和优劣势来制定自己的产品或服务的价格4。这种策略适用于市场竞争激烈,产品差异化程度低,消费者对品牌忠诚度不高的情况。 成本加成定价策略:就是在产品或服务的成本基础上加上一定比例或金额作为利润来制定价格5。这种策略适用于销售实体产品的零售商或者与竞争对手使用相同模型定价时。 组合定价:例如安防行业,后端产品高价,前端产品低价。销售前端产品必须搭配后端产品。 营销管理 营销管理怎么做?看完这张思维导图就知道了 营销管理是指为了实现企业或组织目标,建立和保持与目标市场之间的互利的交换关系,而对设计项目的分析、规划、实施和控制1。营销管理的实质,是需求管理,即对需求的水平、时机和性质进行有效的调解1。 营销管理有不同的观念和流程,其中一个比较流行的流程公式是:R → STP → 4Ps → I → C2。其中, R(Research),即对市场的调研和洞察 STP:市场细分(Segmentation)、目标选择(Targeting)、定位(Positioning) 4Ps:产品(Product)、价格(Price)、促销(Promotion)、渠道(Place) I(Implements),即实施计划 C(Control),即控制反馈 营销管理需要注重分析消费者的行为及心理,进而识别细分市场与目标市场,找到自己的产品定位,打造自家的特色,培育强大的品牌2。 管理能力 作为普通员工,管好自己做好绩效,操一二颗心,与二三个同事搞好关系即可。而作为管理者,要操五颗心、做好五项管理: 冲突能力 攻击性就是生命力! 做人需要攻击性,做管理更需要攻击性! 作为一个管理者,必须勇于冲突,敢于面对冲突,并善于解决冲突! 冲突能力是管理者的必备能力! 要做事,不拿着皮鞭子抽,如何快速成事?不得罪人,如何做管理? 和事老绝对做不成事!要做成事,必定得罪人!所以你经常看到某些管理者虽然口碑不好,但团队效率却很高。当然,这也不是绝对的,口碑不好可能是勇于推进进度造成的,也可能是人品不好等其他原因造成的,这需要区别对待。 攻击性是生命力和创造力的外在表现,如果一个人没有攻击性,就会出现心理问题,生命力和创造力必定萎缩! 一般来说,攻击性和解决问题的能力是成正比的! 抱怨越厉害的人服从性越高。 抱怨是对服从的发泄,并不是反抗。 所以,对你拍马屁越厉害的人,背后骂你也越厉害! 一个人的情绪总是平衡的!媚上者必定欺下!马屁精必然背后捅刀子! 后记 涉及东西太多了,初步整理相关知识,整理的比较乱,后续有时间慢慢完善。 学我者生,似我者死!复杂的管理流程需要极高的运行成本!需要以公司的盈利情况,人力资源为基础打造自己独特的项目管理流程! 管理收益大于管理成本才是好的管理!不同的企业,管理方法和流程必定不同,小企业学大企业完整的管理流程就是找死! 注意:这里不是管理培训,不会对每一个部分尽善尽美 懂管理流程是入门项目管理的基础,懂具体某个行业全开发流程是项目管理的必要基础!懂某个具体细分领域技术细节是相关模块管理的必备知识! 参考&致谢 软件开发常见模型(瀑布模型、V模型、W模型、敏捷开发模型) 端到端的项目管理,才是王道 | 人人都是产品经理 端到端到底指什么? 母弱出商贾,父强做侍郎; 族望留原籍。家贫走他乡。 ​ ——施耐庵

2023/3/8
articleCard.readMore

在宝塔VPS上面采用docker部署waline全流程图解教程

本文介绍了在宝塔系统上基于 MySQL,采用 Docker部署 Waline 的方法,并提供 Github 社交登陆,渐变彩色邮件通知模板! 准备工作 注册一个邮箱,并开启SMTP 。waline 邮件通知需要用到 你得有一个vps 。 目前个人能找到的最便宜的 VPS 服务商: racknerd VPS 安装配置好宝塔。 宝塔安装与配置简明教程 创建waline 数据库 以 mysql 数据库为例 MySQL 数据库初始化 https://waline.js.org/guide/database.html#mysql https://github.com/walinejs/waline/blob/main/assets/waline.sql /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; SET NAMES utf8mb4; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; # Dump of table wl_Comment # ------------------------------------------------------------ CREATE TABLE `wl_Comment` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `comment` text, `insertedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `ip` varchar(100) DEFAULT '', `link` varchar(255) DEFAULT NULL, `mail` varchar(255) DEFAULT NULL, `nick` varchar(255) DEFAULT NULL, `pid` int(11) DEFAULT NULL, `rid` int(11) DEFAULT NULL, `sticky` boolean DEFAULT NULL, `status` varchar(50) NOT NULL DEFAULT '', `like` int(11) DEFAULT NULL, `ua` text, `url` varchar(255) DEFAULT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # Dump of table wl_Counter # ------------------------------------------------------------ CREATE TABLE `wl_Counter` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `time` int(11) DEFAULT NULL, `reaction0` int(11) DEFAULT NULL, `reaction1` int(11) DEFAULT NULL, `reaction2` int(11) DEFAULT NULL, `reaction3` int(11) DEFAULT NULL, `reaction4` int(11) DEFAULT NULL, `reaction5` int(11) DEFAULT NULL, `reaction6` int(11) DEFAULT NULL, `reaction7` int(11) DEFAULT NULL, `reaction8` int(11) DEFAULT NULL, `url` varchar(255) NOT NULL DEFAULT '', `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # Dump of table wl_Users # ------------------------------------------------------------ CREATE TABLE `wl_Users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `display_name` varchar(255) NOT NULL DEFAULT '', `email` varchar(255) NOT NULL DEFAULT '', `password` varchar(255) NOT NULL DEFAULT '', `type` varchar(50) NOT NULL DEFAULT '', `label` varchar(255) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `avatar` varchar(255) DEFAULT NULL, `github` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `google` varchar(255) DEFAULT NULL, `weibo` varchar(255) DEFAULT NULL, `qq` varchar(255) DEFAULT NULL, `2fa` varchar(32) DEFAULT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; docker 安装 waline vps.yml 文件 # docker compose文件 version: "3" services: waline: container_name: waline image: lizheming/waline:latest hostname: waline restart: always volumes: - /www/docker/waline/data:/app/data network_mode: host env_file: - .env # 由于单引号和双引号过多,邮件通知模板只能放在这里面 environment: TZ: 'Asia/Shanghai' MYSQL_DB: 'waline' MYSQL_USER: 'waline' MYSQL_PASSWORD: '[随机密码]' # 前面创建数据库时生成的随机密码 SITE_NAME: '夜法之书' SITE_URL: 'https://blog.17lai.site' SECURE_DOMAINS: 'blog.17lai.site,blog.17lai.fun' AUTHOR_EMAIL: 'xxx@gmail.com' # 电报通知 TG_BOT_TOKEN: 'xxxxx' TG_CHAT_ID: 'xxxxx' # 邮件通知 SMTP_SERVICE: '126' SMTP_HOST: 'smtp.126.com' SMTP_PORT: '465' SMTP_USER: 'xxxxx@126.com' SMTP_PASS: 'xxxxx' SENDER_NAME: '夜法之书' SENDER_EMAIL: 'xxxxx@126.com' # 注意这里需要和 SMTP_USER 一致 AKISMET_KEY: xxxxx # 反垃圾邮件 LEVELS: '0,10,20,50,100,200' DISABLE_REGION: 'true' # google RECAPTCHA RECAPTCHA_V3_KEY: xxxx RECAPTCHA_V3_SECRET: xxxx # github 社交登录 GITHUB_ID: xxxx GITHUB_SECRET: xxxx 注意这里的端口地址,并使用host模式,以方便连接主机的 MySQL 数据库 .env文件 MAIL_SUBJECT='{{parent.nick | safe}},『{{site.name | safe}}』上的评论收到了回复' MAIL_TEMPLATE='<div style="border-radius: 10px 10px 10px 10px;font-size:14px;color:#555555;width: 666px;font-family:"Century Gothic","Trebuchet MS","Hiragino Sans GB",微软雅黑,"Microsoft Yahei",Tahoma,Helvetica,Arial,"SimSun",sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="{{site.url}}" target="_blank">{{site.name}}</a>上的留言有新回复啦!</p></div><div style="margin:40px auto;width:90%"><p>Hi, {{parent.nick}},您曾在文章上发表评论:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">{{self.comment | safe}}</div><p><strong>{{self.nick}}</strong> 给您的回复如下:</p><div style="background:#fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">{{self.comment | safe}}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="{{site.postUrl}}" target="_blank">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="{{site.url}}" target="_blank">{{site.name}}</a>。<hr /><p style="font-size:12px;color:#b7adad">本邮件为系统自动发送,请勿直接回复邮件哦,可到博文内容回复。</p></p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div></div>' MAIL_SUBJECT_ADMIN='{{site.name | safe}} 上有新评论了' MAIL_TEMPLATE_ADMIN='<div style="border-radius: 10px 10px 10px 10px;font-size:14px;color:#555555;width: 666px;font-family:"Century Gothic","Trebuchet MS","Hiragino Sans GB",微软雅黑,"Microsoft Yahei",Tahoma,Helvetica,Arial,"SimSun",sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;"href="{{site.url}}"target="_blank">{{site.name}}</a>上的留言有新评论啦!</p></div><div style="margin:40px auto;width:90%"><p>{{self.nick}}回复说:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">{{self.comment | safe}}</div><p>您可以点击<a style="text-decoration:none; color:#12addb"href="{{site.postUrl}}"target="_blank">查看回复的完整內容</a>。<hr/></p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div></div>' 由于单引号和双引号过多,邮件通知模板只能放在env文件里面 这个邮件通知模板效果如下 安装waline docker-compose -p "container" -f ./vps.yml up -d --build 域名配置 域名设置 设置反向代理 宝塔设置反向代理方法如下 DNS 配置 这里以DNSPod 为例 直接使用ip就是如下示例 如果使用vercel ,那么域名配置方法如下 cname-china.vercel-dns.com 添加 GitHub 社交登录 开启 GitHub 账号登录功能需要配置 GitHub OAuth 密钥。点击 Register a new OAuth application 进入 GitHub OAuth 应用申请页面。 配置注意事项如下: Application name: 应用名称,会在用户授权时显示,推荐使用博客名称。 Homepage URL: 应用主页地址,会在用户授权时显示,推荐使用博客地址。 Appcation description: 应用描述,会在用户授权时显示,非必填项。 Authorization callback URL: 应用的回调地址,登录时需要使用。填入 <serverURL>/oauth/github 其中 <serverURL> 是你的 Waline 服务端地址。 填写完成后点击 Register application 即可成功创建。页面中会显示 Client ID。点击 Client secrets 栏右边的 Generate a new client secret 按钮则可以获取到该应用的 Client secrets。 显示在 GitHub的 Settings -> Developer settings -> OAuth Apps -> 又见苍岚 使用以上信息配置环境变量,重新部署。 环境变量名称 备注 GITHUB_ID 对应 GitHub OAuth App 中的 Client ID GITHUB_SECRET 对应 GitHub OAuth App 中的 Client secrets 之后即可使用 GitHub 登录 添加邮件通知 上文中已经在 docker compose 文件中添加了邮件通知功能,下面介绍另一个邮件通知模板 紫罗兰永恒花园信笺模板 这个模板测试还存在一些bug, css 需要一些调整 .env MAIL_SUBJECT='{{parent.nick | safe}},『{{site.name | safe}}』上的评论收到了回复' MAIL_TEMPLATE='<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"><style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style><div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;font-family:"Century Gothic","Trebuchet MS","Hiragino Sans GB",微软雅黑,"Microsoft Yahei",Tahoma,Helvetica,Arial,"SimSun",sans-serif;margin:50px auto;max-width:100%;background: ##ffffff;"><img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"><div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"><p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;">您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}">『{{site.name | safe}}』</a>上的留言有新回复啦!</p></div><div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"><div style="margin:40px auto;width:90%;"><p>Hi,{{parent.nick}},您曾在文章上发表评论:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{parent.comment | safe}}</div><p><strong>{{self.nick}}</strong> 给您的回复如下:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div><p>您可以点击<a style="text-decoration:none; color:#cf5c83" href="{{site.postUrl}}" target="_blank"> 查看回复的完整內容 </a>,欢迎再次光临<a style="text-decoration:none; color:#cf5c83" href="{{site.url}}" target="_blank"> {{site.name}} </a>。<hr /><p style="font-size:14px;color:#b7adad;text-align:center">本邮件为系统自动发送,请勿直接回复邮件哦,可到博文内容回复。<br />https://example.com</p></p><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"><p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p></div></div><img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"></div></div>' MAIL_SUBJECT_ADMIN='{{site.name | safe}} 上有新评论了' MAIL_TEMPLATE_ADMIN='<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"><style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style><div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;font-family:"Century Gothic","Trebuchet MS","Hiragino Sans GB",微软雅黑,"Microsoft Yahei",Tahoma,Helvetica,Arial,"SimSun",sans-serif;margin:50px auto;max-width:100%;background: ##ffffff;"><img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"><div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"><p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;">您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}"target="_blank">{{site.name}}</a>上的文章有了新的评论</p></div><div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"><div style="margin:40px auto;width:90%;"><p><strong>{{self.nick}}</strong> 回复说:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div><p style="text-align:center;">您可以点击<a style="text-decoration:none;color:#cf5c83" href="{{site.postUrl}}" target="_blank">查看回复的完整內容</a></p><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"><p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p></div></div><img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"></div></div>' 如果采用vercel部署,修改部署repo 的 ~/index.js 文件 const Application = require('@waline/vercel'); module.exports = Application({ async postSave(comment) { mailSubjectAdmin: '{{site.name | safe}} 上有新评论了', mailTemplateAdmin: `<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"> <style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style> <div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;max-width:100%;background: ##ffffff;"> <img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"> <img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"> <div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"> <p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;"> 您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}"target="_blank">{{site.name}}</a>上的文章有了新的评论</p> </div> <div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"> <div style="margin:40px auto;width:90%;"><p><strong>{{self.nick}}</strong> 回复说:</p> <div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div> <p style="text-align:center;">您可以点击<a style="text-decoration:none;color:#cf5c83" href="{{site.postUrl}}" target="_blank">查看回复的完整內容</a></p> <img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"> <p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p> </div> </div> <img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"> </div> </div>`, mailSubject: '{{parent.nick}},您在『{{site.name}}』上发表的评论收到了来自 {{self.nick}} 的回复', mailTemplate: `<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"> <style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style> <div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;max-width:100%;background: ##ffffff;"> <img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"> <img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"> <div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"> <p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;"> 您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}">『{{site.name | safe}}』</a>上的留言有新回复啦!</p> </div> <div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"> <div style="margin:40px auto;width:90%;"><p>Hi,{{parent.nick}},您曾在文章上发表评论:</p> <div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{parent.comment | safe}}</div> <p><strong>{{self.nick}}</strong> 给您的回复如下:</p> <div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div> <p>您可以点击<a style="text-decoration:none; color:#cf5c83" href="{{site.postUrl}}" target="_blank"> 查看回复的完整內容 </a>,欢迎再次光临<a style="text-decoration:none; color:#cf5c83" href="{{site.url}}" target="_blank"> {{site.name}} </a>。<hr /> <p style="font-size:14px;color:#b7adad;text-align:center">本邮件为系统自动发送,请勿直接回复邮件哦,可到博文内容回复。<br />https://example.com</p> </p> <img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"> <p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p> </div> </div> <img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"> </div> </div>` }, }); 注意事项 默认创建好waline 后,尽快创建第一个登录用户! 默认第一个登录用户为管理员, 默认地址为 [域名]/ui, 例如本文中就是 waline.17lai.site/ui waline 自带数据导入导出,目前测试导入同一份数据2次,会使同一份数据在数据库中出现两次! Cloudflare 设置 使用了 Cloudflare 时需要注意的配置事项! 如果使用了 CF 的服务,不配置这里,waline 就获取不到正确的地理位置,但 CF 还支持下面功能,官方文档 设置方法 参考&致谢 Waline 添加 GitHub 社交登录 waline 邮件通知模板样式一览 信笺样式留言板 雷打真孝子,财发狠心,麻绳专挑细处断,恶运专找苦命人! ​ ——俗语赏析 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2023/2/20
articleCard.readMore

生活中的那些有趣的不可能三角介绍与解析

成年人的世界充满了自嘲,嘴上挂着“小孩子才做选择,成年人全都要”,现实却是“小孩子才做选择,成年人根本没得选”。 背后的种种心酸无奈,通常表现为“不可能三角”。 生活中有很多有趣的三元悖论,今天,我们来整理一下这些有趣的知识! 只有骗子满足全部要求 全都满足你的要求的,几乎可以100%的说是骗子! 投资理财不可能三角 如果有人告诉你可以同时做到这三点,那么八成是庞氏骗局,例如宣称“年化20%、随时提现、有第三方担保”的P2P,“圈钱跑路”的案例比比皆是。 既然三者不可俱备,你会选择舍弃哪一个? 方案一:舍弃高收益,保留“低风险”和“流动性”。 典型代表是货币基金,主要投向包括现金、银行存款、债券回购、央行票据、同业存单等低风险品种,是一种“类储蓄”的产品。流动性方面,虽然新规后单日赎回到账上限不高于1万元,但还是非常灵活。再看收益,七日年化收益率普遍只有3%不到。 方案二:舍弃低风险,保留“高收益”和“流动性”。 例如各种短线投机行为,各种高杠杆交易工具,还有澳门和Las Vegas的赌场。塔勒布在《随机漫步的傻瓜》中有个形象的比喻:假设25岁的人一年玩一次俄罗斯转盘,他要活到50岁生日的机会十分渺茫。但是如果有很多人,比方说几千个25岁的年轻人都在玩这个游戏,那么应该会有少数人能够年过半百且极其富有,其他人则已成一堆墓冢。九死一生的游戏,显然不适合普通人。 方案三:舍弃流动性,保留“高收益”和“可承受的风险”。 也就是找到一个“长长的雪坡”,以时间换空间。过去的20年属于一线房产,但未来十年,A股可能是性价比最高的资产。但A股指数波动较大,加上结构分化,投资主动管理的权益型基金是更好的选择。经测算,越长的投资期限,投资基金的赢面越高,需要承受的最大回撤也更小。 例如,任意时点买入偏股混合型基金指数,持有1年虽然最高收益达212%,但也可能亏损55%,平均胜率仅有66.6%。但如果将投资期限延长至3年,年化最多亏9.6%,胜率提升了至74.8%,大大提高了投资的确定性。 普通人不可能三角 普通人,有好事,不排队,不可能同时存在! 如果种地能赚钱,农民将无地可种;如果拜佛有用,你连庙门都进不去。如果炒股能赚钱,普通人连账户都开不了! VPS 不可能三角 医疗不可能三角 美国选择了高效和服务好,所以导致医疗成本巨贵无比。贵到普通家庭打个狂犬疫苗,叫个救护车就能破产。 英联邦国家和欧洲选择了便宜和服务好,结果就是见到医生很难,排队到死。预约牙科医生一个月,眼科七个月,拍个B超三个月起步。只要不是快死需要进急诊抢救的病,都得慢慢排队。 我国则因为人口众多,人均费用紧张,选择了便宜和高效。代价是医生高强度工作,病床高周转,门诊高周转,为的是大家都能看上病。 货币不可能三角 国际金融学中的原则,指一个国家不可能同时完成下列三者: 资本自由进出(Capital mobility) 固定汇率(Exchange rate) 独立自主的货币政策(Monetary policy) 区块链的不可能三角 分布式系统不可能三角 CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 1、一致性(Consistency) (等同于所有节点访问同一份最新的数据副本) 2、可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据) 3、分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择) 项目管理的不可能三角 软件工程不可能三角 时间(time)、成本(money)、功能性(scope) 工作不能三角 强度,创造性,持久性 设计师不可能三角 甲方不可能三角 既要,又要,还要 乙方不可能三角 ①交付速度;②设计质量;③项目价格 公众号不可能三角 深度、日更、原创 出行不可能三角 价格——体验——效率 员工不可能三角 像狗一样听话——专业素质强——薪水低 职业不可能三角 钱多、事少、离家近 位高、权重、责任轻 2B不可能三角 高毛利、高周转、大规模 招聘不可能三角 男人不可能三角 女人不可能三角 接受不完美 孟子有云:鱼和熊掌,不可得兼。 罗曼·罗兰曾说:世界上只有一种真正的英雄主义,那就是在认清生活真相之后依然热爱生活。 任正非坦承:完美的人,就是没用的人,一看这个人总是追求完美,就知道他没有希望。 接受不完美,是每个人的必修课。 如何突破不可能三角 有三个突破方向可以尝试 挤干水分 三个维度本身确实是内在矛盾,但不代表你的现状已经到了引起矛盾的程度。以大多数人努力程度之低,还轮不到拼天赋。 找到隐藏的维度 二是找到隐藏的维度,从更高维来俯视,原先的三角约束将变成一维。 比如项目管理三角,其实忽略了另外两个维度:质量和价值。比如就算你在预算范围内按时完成了所有功能,但总是出 bug 导致维护成本飙升怎么办?又或者虽然功能都做完了,但没人用,卖不出去,怎么办?而当你把质量和价值引入的时候,会发现原来的“范围-成本-时间”降维成了一个约束因素。哪怕这个约束没满足,比如工期超了一点、预算超了一点、功能只做了一点,但只要有人要,市场能接受,依然可能是个不错的结果。这个新的“价值-质量-约束”三角,由 Jim Highsmith 提出,并命名为“敏捷三角”。 比如招聘三角,试试用 企业文化 降维突破一下? 技术革命 另一种突破是技术突破,硬怼,比如马车时代的出行三角,可以用火车轻松突破。后面期待下马斯克的火箭。 总结: 理解一个领域精髓的方法是找到其内在的不可调和的矛盾。 矛盾可以用三角关系简单清晰的表达,可以怼回甲方,可以指导方向。 可以通过挤水分、发现隐藏的维度、或技术突破来高维打击一下三角约束,形成新的平衡。 参考&致谢 如何突破不可能三角 医疗的“蒙代尔不可能三角” 名言赏析: 人性的丑陋就是,在无权、无势、善良的人身上挑毛病,在有权、有势、缺德的人身上找优点。当无权、无势、善良的人,受到伤害的时候,却还要站在所谓的道德至高点上,假惺惺的劝说无权、无势、善良的人,一定要忍耐,一定要大度。 ​ ——莫言《晚熟的人》

2023/2/14
articleCard.readMore

如何建立自己的私人电子图书馆--出版书籍,网络小说,漫画一网打尽!

继刮削音乐,刮削电影、电视剧、动画等视频之后的第三季,刮削图书! 结构化自己的图书,方便自己随时查阅,是提高自己各种能力的重要辅助手段!把各方面知识都结构化,可以极大的扩展你的思维,放飞你的思想,让你以更清晰的目光看待这个世界! 友情提示:中国法规是不允许私人做电子出版的!自用可以,公开访问是违法的! 或者域名,服务器都放在某些国家是可行的! 电子书图书馆 首先介绍的就是电子书图书馆,接下来后面会介绍如何建立自己的网络小说图书馆,漫画图书馆! 电子书不仅要下载可看,还要有书签,封面,简洁,作者,出版社等元数据帮助记忆和管理,否则,下载了一堆没法查找和没下载差不多! 操作指南 Web界面的Calibre作为阅读界面,支持OPDS接口,可以手机访问! PC 版的Calibrez作为电子书导入,转移,和管理的工具更方便! 注意不要同时在web和PC端操作数据库,很容易导致数据库出bug。 虽然pc calibre有数据库恢复功能,大部分时间都可以成功恢复数据库,但是偶尔也有不能恢复的时候! 安装Docker 更多平台Docker安装介绍,请看这里 Hexo Docker环境使用篇 安装docker curl -fsSL https://get.docker.com | sh && systemctl enable --now docker 安装docker-compose mkdir -p /usr/local/lib/docker/cli-plugins curl -SL https://get.daocloud.io/docker/compose/releases/download/v2.1.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/lib/docker/cli-plugins/docker-compose chmod +x /usr/local/lib/docker/cli-plugins/docker-compose 运行bookstack docker compose up -d 查看日志 docker logs -f calibre CalibreWeb Github technosoft2000/calibre-web linuxserver/docker-calibre-web Dockerhub linuxserver/calibre-web Docs For docker-calibre-web Calibre相关的Docker很多,这是其中界面很漂亮的一个版本 注意这个Docker安装需要访问Github下载相关文件!注意你的网络是否正常 视频详细Calibre web讲解 教程视频作者是账户未命名 它的B站账号似乎没了,就放上youtube 统一视频地址! 说明一下,此账号不是博主! 网盘观看下载地址 Calibre 私人书库搭建教学!藏书、漫画、听书,在线阅读+格式转换 上面 Calibre 教程相关附件 相关命令 cat /etc/passwd | grep root [用户名] 刮削器不能使用的解决方法:https://fugary.com/?p=213 Compose 安装示例 linuxserver 的维护版本 默认登录密码: Username: admin Password: admin123 。创建Docker后,请及时修改默认密码! --- version: "2.1" services: calibre-web: image: linuxserver/calibre-web:latest container_name: calibre-web environment: - PUID=1000 - PGID=1000 - TZ=Europe/London - DOCKER_MODS=linuxserver/mods:universal-calibre #optional - OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional volumes: - /path/to/data:/config - /path/to/calibre/library:/books ports: - 8083:8083 restart: unless-stopped docker run -d \ --name=calibre-web \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Europe/London \ -e DOCKER_MODS=linuxserver/mods:universal-calibre `#optional` \ -e OAUTHLIB_RELAX_TOKEN_SCOPE=1 `#optional` \ -p 8083:8083 \ -v /path/to/data:/config \ -v /path/to/calibre/library:/books \ --restart unless-stopped \ lscr.io/linuxserver/calibre-web:latest 原作者精力不够,不再维护下面这个版本,请使用 linuxserver 维护的版本! calibre: image: technosoft2000/calibre-web container_name: calibre hostname: calibre restart: always volumes: - ${USERDIR}/Calibre/web/config:/calibre-web/config - ${USERDIR}/Calibre/web/kindlegen:/calibre-web/kindlegen - ${USERDIR}/Calibre/web/app:/calibre-web/app - ${USERDIR}/Calibre/books:/books ports: - 8283:8083 env_file: - .env environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} - USE_CONFIG_DIR=true - SET_CONTAINER_TIMEZONE=true talebook Github Dockerhub Tips: 国人开发的,个人感觉更适合作为图书管理的界面 Compose 安装示例 talebook: image: talebook/talebook container_name: talebook hostname: talebook restart: always ports: - 90:80 volumes: - ${USERDIR}/talebook/data:/data environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} networks: public_access: aliases: - talebook 使用 Calibre PC 版管理并刮削电子书 Pc版的Calibre用来做数据库管理,有各种插件支持,是最方便的。 主页:calibre-ebook 下载:download Windows MacOS Linux 全平台支持,Python实现的图书管理系统! 刮削插件安装 豆瓣刮削插件这里下载安装 Github 官方地址 Github 下载地址 本站自建加速地址 个人网盘加速下载 更新到1.10 如果打不开,多刷新几次! 添加书库 图书刮削 检查完毕就可以点击确认 数据库转移 这里最好建立一个临时书库作为转移和刮削预备用,防止意外崩溃导致数据库损坏或丢失! 你可以和你的好友之间共享或者转移某个书库。 图书太多,刮削太耗时间,合作刮削建立书库才是正途! Calibre数据库恢复 自动生成txt小说文本目录 第一步:导入书籍 在菜单中选择添加书籍 第二步:转换书籍 在结构检测中修改正则表达式以适配中文目录 //*[((name()='h1' or name()='h2') and re:test(., '\s*((chapter|book|section|part)\s+)|((prolog|prologue|epilogue)(\s+|$))', 'i')) or @class = 'chapter'] //*[name()='h1' or name()='h2'] 适配中文,修改后如下图。 //*[re:test(., "^\s*[第卷][0123456789一二三四五六七八九十零〇百千两]*[章回幕部节集卷].*", "i")] 修改为后点击确定,然后Calibre 就会开始转换书籍。 另一种实现方式 使用calibre生成txt文档目录 calibre-douban https://github.com/fugary/calibre-douban Calibre douban metadata download plugin. Based on https://book.douban.com web pages. Calibre插件 最近在使用calibre-web管理电子书,不过很多时候还是需要用到Calibre桌面版软件,批量管理,编辑电子书等功能,在calibre-web上已经使用calibre-web-douban-api搜素豆瓣元数据,但是桌面版Calibre软件缺没有办法使用,不过calibre可以使用插件,而且是使用python开发,因此可以把calibre-web-douban-api改造一下包装成calibre插件,简单元数据插件还是比较容易的 安装方法 下载地址:NewDouban.zip 从release页面下载zip包,然后再calibre中安装为插件即可。 alibre-douban是Calibre电子书软件的豆瓣元数据插件 下载地址 项目地址:https://github.com/fugary/calibre-douban 下载地址:https://github.com/fugary/calibre-douban/releases/latest/download/NewDouban.zip 代理下载:https://ghproxy.com/https://github.com/fugary/calibre-douban/releases/latest/download/NewDouban.zip 从release页面下载zip包,然后再calibre中安装为插件即可。 升级内容 删除了一些无用代码,另外增加功能: 增加gzip支持,有可能提升一点速度 增加随机毫秒延迟,减少被403的几率 增加Cookie输入框,可以填入浏览器登录后的Cookie,减少403 配置随机延迟 默认已开启随机延迟,也就是在并发请求详情数据的时候随机sleep一定的毫秒数,可以关闭: 参考代码 def random_sleep(self, log): random_sec = random.random() / 10 log.info("Random sleep time {}s".format(random_sec)) time.sleep(random_sec) Cookie配置 有时候可能我们的IP已经被拦了,这时可以自己登录豆瓣网站,然后把Cookie复制出来填进插件配置中。 IP被拦的错误如下: 有异常请求从你的 IP 发出,请 登录 使用豆瓣 用Chrome或者Edge浏览器打开https://www.douban.com,点击【登录】进入登录页面,登录成功之后,按F12打开开发者工具: 从Network,找到Doc类型,随便点击一个豆瓣的网址,进入Headers,找到Request Headers里面的Cookie字段,如图: 如果是中文版: 从网络,找到文档类型,随便点击一个豆瓣的网址,进入标头,找到请求标头里面的Cookie字段,如图: 找到Cookie:后面的部分,复制后面的内容,不包含Cookie:。 到Calibre插件配置页面填入Cookie: 然后就可以用用户的身份查询,一般是可以解决403问题。 常见错误 如果又遇到查询失败,可能是这个错误 …你访问豆瓣的方式有点像机器人程序。为了保护用户的数据,请向我们证明你是人类: 因为使用了Cookie,可以在浏览器中自己点击证明一下,再在calibre中重新查询即可。 网络小说图书馆 reader Github reader 新版居然不完全开源了!!! Docker reader 同类项目 Legado 书源地址 https://github.com/safino9/SourceGo/blob/main/book_source/all.json novel-plus novel-plus 是一个多端(PC、WAP)阅读 、功能完善的小说 CMS 系统。包括小说推荐、小说检索、小说排行、小说阅读、小说书架、小说评论、小说爬虫、会员中心、作家专区、充值订阅、新闻发布等功能。 novel.xxyopen.com 你想新建一个自己的类似起点文学的网站么? 就是这个了 开源阅读 APP Github 开源阅读 书源 Namofree 书源 点击此处导入 title https://raw.githubusercontent.com/gedoor/gedoor.github.io/master/blog/2022-09-01-2213/9%E6%9C%88%E4%B9%A6%E6%BA%90-namofree.txt 破冰 书源 点击此处导入 title https://raw.githubusercontent.com/gedoor/gedoor.github.io/master/blog/2022-09-01-2213/9%E6%9C%88%E4%B9%A6%E6%BA%90-%E7%A0%B4%E5%86%B0.txt 风停在了窗边 书源 点击此处导入 title https://raw.githubusercontent.com/gedoor/gedoor.github.io/master/blog/2022-09-01-2213/9%E6%9C%88%E4%B9%A6%E6%BA%90-%E9%A3%8E%E5%81%9C%E5%9C%A8%E4%BA%86%E7%AA%97%E8%BE%B9.txt 一程 书源 点击此处导入 title https://raw.githubusercontent.com/gedoor/gedoor.github.io/master/blog/2022-09-01-2213/9%E6%9C%88%E4%BB%BD%E4%B9%A6%E6%BA%90-%E4%B8%80%E7%A8%8B.json Haxc 漫画 点击此处导入 title https://raw.githubusercontent.com/gedoor/gedoor.github.io/master/blog/2022-09-01-2213/%E6%BC%AB%E7%94%BB%E6%BA%90-haxc.txt 漫画图书馆 mylar3 Github mylar3 DockerHub mylar3 更擅长英文漫画追订 Komga Web 在线漫画查阅管理工具。擅长本地下载好的漫画管理阅读,支持OPDS! Github Komga Docker hub Kavita 官网 www.kavitareader.com github https://github.com/Kareadita/Kavita docker https://hub.docker.com/r/linuxserver/kavita Demo If you want to try out Kavita, we have a demo up: https://demo.kavitareader.com/ Username: demouser Password: Demouser64 Docker 安装 There are currently 2 tags: :nightly which is the bleeding edge builds. Best to use if you are in the discord to actively test :latest which is the latest stable build You can find more information on our docker hub or a more informative setup on our wiki. 1Install Kavita To install and use the Docker image, run the following command: docker run --name kavita -p 5000:5000 \ -v /your/manga/directory:/manga \ -v /kavita/data/directory:/kavita/config \ --restart unless-stopped \ -d jvmilazz0/kavita:latest Alternatively you can use docker-compose file: version: '3.9' services: kavita: image: jvmilazz0/kavita:latest volumes: - ./manga:/manga - ./data:/kavita/config ports: - "5000:5000" restart: unless-stopped smanga A simple manga browser 一款docker直装的漫画浏览器 新出的,国人做的,star还很少,刚看的时候才2位数的star,大家可以去给作者点 star! LANraragi 有元数据管理功能的漫画管理软件! Github LANraragi Advantages in LANraragi: Calibre-web requires loading of the whole cbz file, and LANraragi supports decompress cbz file at server-side. Support direct download by inputing the e-hentai url, and support automatically scrub the meta info from e-hentai and n-hentai. Better tag management, especially designed for commic files with lots of tags, in calibre-web, too much tag makes the whole tag system unavailable to use. Not modify the hash of the archive, means that using that hash, the archive can be found more easily on e-hentai server, or be uploaded as a bittorrent file. No need to learn python to run this script Advantages of this script: support embedding eze info.json, which means all meta infos are with the cbz file, not like LANraragi, meta infomation are stored in its seperated database. support checking for update. Sometimes some galley will have new images uploaded, this script can help find these out-dated archives. More precise while importing meta, when importing with LANraragi, some meta may be downloaded from the wrong galley, may caused by multiple translation group are translating the same galley. compatible with all solutions like calibre and LANraragi Wrote by myself, so it is more easy to modify when new requirements exist. Tachidesk-Server A rewrite of Tachiyomi for the Desktop 大名鼎鼎的安卓漫画阅读管理软件的Docker 服务器版本! 图书下载 推荐 Z-Library,最好用的图书下载地点与方式! 在这里,你几乎能找到所有互联网图书! Z-Library Z-Library(简称Z-Lib,前身为BookFinder)是一个影子图书馆和开放获取文件分享计划,用户可在此一网站上下载期刊文章以及各种类型的书籍。根据Z-Library的说法,截至2022年6月12日,其共收录了10,456,034本书和84,837,646篇文章[1]。Z-Library在其电子书搜索页面上宣称自己是“全球最大的数字图书馆”[2],并在文章搜索页面上称自身是“全球最大的科学文章存储库”[3]。它原是创世纪图书馆的镜像网站,并从该图书馆获得大部分馆藏。但它的一些馆藏由用户自行上载,并且不为创世纪图书馆所收藏[4]。该平台公开网域已于2022年11月3日遭到美国政府屏蔽。 ZLibrary虽然是一个俄国网站,但它拥有16种语言版本可供选择,下滑至网页末尾,即可切换语言。 访问地址: https://zlib.cydiar.com/ https://z-library.ec/ https://bk.hallowlib.org/ 国内备用网址 http://zlibrary24tuxziyiyfr7zd46ytefdqbqd2axkmxm4o5374ptpc52fad.onion/ 洋葱路由地址 Book Searcher https://zlib.missuo.me/ IPFS 存储的书籍共享搜索引擎 IPFS 星际文件系统(InterPlanetary File System). IPFS 是一个分布式的web, 点到点超媒体协议. 可以让我们的互联网速度更快, 更加安全, 并且更加开放. IPFS协议的目标是取代传统的互联网协议HTTP。 Z-Library是一个去中心化的图书馆,大家都有各自的节点维护自己的个人图书,也可以从其他节点去下载,降低现有web文件存储的缺陷。 而IPFS的出现刚好可以满足这个理想目标,IPFS是一个协议,同时已经有现有框架go-ipfs去快速搭建个人的IPFS节点,所以能够很快体验一下去中心化体验,但是很多时候由于网络问题,并不能很快完成书籍的下载。 HTTP协议的缺陷: 使用HTTP协议每次需要从中心化的服务器下载完整的文件 Web文件经常被删除 经常受各种限制,导致文件无法正常下载 IPFS是一个协议,类似http协议,主要定义了: 定义了基于内容的寻址文件系统 内容分发 使用的技术分布式哈希、p2p传输、版本管理系统 可以像http那样查看互联网页面 IPFS是一个文件系统,有文件夹和文件,可挂载文件系统 未来浏览器可以直接支持 ipfs:/ 或者 fs:/ 协议 底层架构介绍: IPFS是模块化的协议, 分为连接层、路由层、数据块交换 连接层:通过其他任何网络协议连接 路由层:寻找定位文件所在位置 数据块交换:采用BitTorrent技术 p2p系统:世界范围内的p2p文件传输网络 是一个CDN,文件添加到IPFS网络,将会在全世界进行CDN加速 IPNS:基于SFS(自认证系统)命名体系,可以和现有域名系统绑定 实现 IPFS主要是使用go语言实现的,目前主流的IPFS实现有几个框架,具体如下: go-ipfs js-ipfs 已经不再开发 ipfs-desktop Tor Browser Tor Browser 下载 https://www.torproject.org/download/ http://zlibrary24tuxziyiyfr7zd46ytefdqbqd2axkmxm4o5374ptpc52fad.onion/ 获取网桥 官方指引: https://bridges.torproject.org/ Tor 网桥简介 为绕过封锁,开发人员选择建立 Tor 网桥而非改变 Tor 的设计:网桥为可将使用者连接至 Tor 网络的非公开伺服器。即使审查员试图进行封锁,记者也可透过网桥存取 Tor 网络。在这种情况下,Tor 将尝试自动启动并使用网桥连线。 不同 Tor 网桥的运作方式各异,其有效程度取决于记者进行连线的位置。建议记者使用效果最好的网桥类型,如运作速度缓慢,请尝试其他网桥。Tor Browser 和 OnionShare 等使用 Tor 技术的应用程式支援所有网桥类型。 Tor 网桥如何维持运作 混淆流量。部分网桥会“伪装”连线,使其看似一般流量而非 Tor 连线。由于审查员会监控网络活动,并可侦测 Tor 或 VPN 的使用,此技术有助于回避审查员实施的网络分析,避免连线被轻易归类为 Tor。 “连带损害”策略。为托管 To r网桥,开发人员使用某些在本地网络提供大量线上服务的伺服器(如 Microsoft Azure 云端储存)。如此一来,即使侦测到有人使用规避工具,审查员也会避免直接进行封锁,否则整个网络区段将同时遭到封锁,进而对该区造成大范围的负面影响。 网桥类型 WebTunnel 在审查员看来如同加密的网络流量,使用者像是单纯透过安全连线(https)存取网站。 obfs4 看似随机加密的网络流量。 Snowflake 使用暂时性 Proxy,让使用者像在存取 Zoom 等线上视讯会议服务。 Meek 看似 Microsoft Azure 托管的网站。此技术使用域前置(domain fronting),即透过掩饰连线的真正目的地规避审查。记者应注意此网桥的连线速度有限且缓慢。 如何取得网桥 自动连线:部分使用 Tor 技术的应用程式(如 Tor Browser 和 Orbot)本身便可自动取得网桥,使用者无需执行任何操作。 Telegram 机器人:记者可透过官方的 Tor Project Telegram 机器人申请网桥。 电子邮件:记者可发送电子邮件至 bridges@torproject.org 申请网桥。请注意,此方式仅支援 Gmail 和 Riseup 的电子邮件帐号。 网站:记者可在 Tor Project 的网桥专页上找到网桥。 Tor 支援团队联系管道:如其他方法无法使用,记者可透过 Telegram 或电子邮件联络 Tor 支援团队。如需 Signal、WhatsApp 及其他联系管道的相关资讯,请参阅 Tor 浏览器使用手册。 高级用法:指定获取网桥ip的类型: 现在tor的网桥有几种类型,如:普通的、obfs2、obfs3等等,如果你自己需要某种类型的网桥ip,可以在如下页面进行选择指定: 1)打开页面:https://bridges.torproject.org/options 2)选择网桥类型: 人为什么要读书? 认知篇:人为什么非要读书? 因为读书的本质是借命,它是你这辈子唯一一次可以安全地穿越转生附体的机会。用几块钱买一个天才的思想,用几小时走完别人几十年的弯路,这是最便宜的灵魂移植。 一个人如果不读书,他的三观就会被周围的人决定,因为他没有别的输入途径,只能模仿周围,慢慢的被环境改变,流行什么他就跟随什么,永远找不到自己。而读书能把你带到另一个世纪,另一种文明,另一种你此生永远不会成为的人身上。 你可以是大唐沙场的将军,是抗日前线的士卒,是街头卖唱的艺人,也可以是在茫茫草原放牧的诗人。你可以借此理解别人,进而理解你自己。更重要的,它让你知道你并不孤单,你此刻的困惑、挣扎和痛苦早就有人经历过、表达过、思考过。 你以为无人能懂的那些秘密在某本书的某一页早已被写得清清楚楚,甚至更加深刻。那一刻你会震惊、会颤抖,甚至会流泪。因为你第一次意识到跨越千年的某个人竟如此准确地说出了你无法表达的东西。 读书让你暂时逃离命运的围困,然后教你如何重返生活,带着更多理解、更多可能去活得更通透一些,不那么愚昧、不那么易怒、不那么孤立无援。 一个人每天看书可能记不住什么,但是在潜意识里他会慢慢明白什么是对,什么是错,而这个才是决定命运的起点。很多臭毛病其实都源于读书少、人云亦云、缺乏自我输入、暴躁嫉妒、见过的世面太少、一蹶不振、从来没有体验过别人的生活。他们总以为这个是性格,其实这个就是不读书的后遗症。 读书不是为了一纸文凭,也不是为了一夜暴富,而是为了成为一个有温度、有情趣、会思考的人,让你在跌宕起伏的生活当中处变不惊,让你经历漫长而幽暗的岁月时候不怨天尤人。当你被生活打回原形,陷入泥潭,它会给你一种温和而坚定的力量。 父母决定了你是谁,而读书决定了你成为谁。 人和人之间的差异 人和人之间的差距主要来自于三层:认知差,信息差和能力差。 三层差距模型 差距类型 特点 解决方式 认知差 基础性(不可替代) 需长期积累 信息差 可购买/借用 建立信息网络 能力差 可雇佣/合作弥补 资源整合 读书可以提高你大脑的信息量,培养你的认知,提高你的能力! 你没法选择你的出生,你的父母,你的家庭条件,但可以通过读书,来决定未来的你成为谁,未来拥有什么样的生活! 横渠四句 横渠四句是北宋思想家张载(号横渠)提出的四句,出自其著作《正蒙·乾称篇》。这四句话凝练了儒家知识分子的终极理想,被后世誉为中国士大夫的精神坐标,至今仍是中华文明的精神旗帜。 一、原文与直译 为天地立心,为生民立命, 为天地立心:揭示宇宙运行规律(天道),建立道德价值体系; 为生民立命:引导百姓安身立命,实现精神与物质的双重安顿; 为往圣继绝学:传承濒临断绝的先秦儒家道统(如孔孟之学); 为万世开太平:构建永恒的理想社会秩序(大同世界)。 二、思想内涵解析 (一)哲学基础:气本论与天人合一 张载创立关学学派,提出“太虚即气”的宇宙观: 宇宙本源是无形之“气”,万物皆气聚散而成; 人道需效法天道,故“立心”实为贯通天人之道。 (二)四重境界的递进关系 境界 对象 行动目标 实践案例 为天地立心 宇宙规律 构建价值本体 著《西铭》倡“民胞物与” 为生民立命 百姓福祉 解决生存发展问题 陕西推行“井田制”试验 为往圣继绝学 文化传统 拯救断裂的儒学道统 批判佛老,重建儒家经典 为万世开太平 人类未来 设计理想社会蓝图 提出“乾坤父母”伦理体系 三、历史影响与争议 (一)对后世的启迪 朱熹将其纳入理学体系,称“横渠四句”乃“儒者第一等事”; 文天祥就义前手书四句明志; 王夫之赞其“上承孔孟,下启千秋”。 (二)近代化转型中的批判 梁启超认为“开太平”隐含乌托邦空想; 鲁迅批评“立命”未触及封建制度之弊; 现代新儒家(如牟宗三)主张剥离理想化色彩,保留其道德担当精神。 四、当代价值重估 (一)中华文明的精魂 2016年习近平引用四句强调传统文化复兴; 北京大学将四句刻入校训碑,与“爱国进步民主科学”并置。 (二)全球治理的东方智慧 横渠四句 现代转化方向 为天地立心 构建人类生态伦理共识 为生民立命 推动全球减贫与可持续发展 为往圣继绝学 保护文明多样性 为万世开太平 倡导人类命运共同体 结语:穿越千年的精神火炬 张载的横渠四句,从关中平原的书院走向世界,其核心价值在于: 士人风骨——知识分子的家国担当; 文明自觉——对人类命运的终极关怀。 附赠: KurtBestor/Hitomi-Downloader: 🍰 Desktop utility to download images/videos/music/text from various websites, and more. 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等)。 我有一块蛋糕,分你吃一口,这是友情 我有一块蛋糕,分你一半,这是事业情 我有一块蛋糕,我吃一口,剩下的都给你,这是爱情 我有一块蛋糕,我不吃,全给你,这是骨肉亲情 我有一块蛋糕,我把它藏起来,告诉你,我也跟你一样饿,这是社会 我有一块蛋糕,我把它全吃了,告诉你,吃蛋糕对身体不好,这叫专家 ​ ——格言赏析 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/2/5
articleCard.readMore

中国区注册ChatGPT并使用全流程图解教程

OpenAI最近推出强大的ChatGPT功能,功能异常强大,号称要颠覆很多行业。但是其限制还不支持中国用户注册!但是还是有办法绕过的,本文将介绍其中的方法和工具! 前言 OpenAI最近推出强大的ChatGPT功能,功能异常强大,号称要颠覆很多行业 不过在国内并不支持OpenAI账号注册,多数会提示: OpenAI’s services are not available in your country. 经过一番搜索后,发现如下方案可以完成注册 ChatGPT介绍 为什么使用ChatGPT 提高工作效率:可以通过向ChatGPT提问来获取答案,避免了繁琐的搜索过程。ChatGPT3.5它可以说掌握了世界上所有的文本知识!ChatGPT4进一步掌握了图片识别和生成!ChatGPT5掌握了视频知识的获取能力,学习了所有公开的视频知识!ChatGPT将会是一个所有学科,所有知识全知全能的智能AI! AI奇点这回真的要到来了,如同智能手机对社会的影响,ChatGPT将颠覆很多传统行业!又一次颠覆性的科技革命,不跟上,就被淘汰! 自然交互:ChatGPT可以理解自然语言,使得人机交互更加自然和直观。 个性化服务:ChatGPT可以通过学习用户的喜好和偏好,提供个性化的服务和推荐。 自动化生成文本:ChatGPT可以生成高质量的文章、摘要、对话等文本内容,提高了写作和编辑的效率。 当然也有缺点 数据隐私:保护用户的隐私,不会泄露用户的个人信息或数据。 透明度:保证ChatGPT的行为和运作过程是透明的,并提供相应的技术支持和文档。 合法性:使用ChatGPT必须符合法律法规,不得用于违法或不道德的行为。 安全性:保证ChatGPT的安全性,避免被黑客或不法分子利用或攻击。 上面这些是ChatGPT自己说的,其实它是: 一个信息茧房,掌握了它,就掌握了下一个时代的话语权。它可以自我过滤自己的输出信息!可以按照掌控者的要求输出,或者不输出,甚至篡改某些信息! 下一代搜索引擎:它比传统搜索引擎强大了几个数量级,太方便了,以至于比控制搜索引擎更容易控制舆论 颠覆现代教育体制:下一个时代,每个人都会使用它,使用它工作效率提升了几个数量级,一个掌握了ChatGPT的员工顶100个不使用它的普通工作者! 信息泄密:没没有掌握建设它的技术的国家将彻底失去话语权,ChatGPT可以随意操控想要输出的舆论,每次问话,都将得到这个领域知识最丰富的人的回答。同时,每次问话,都将泄露信息给ChatGPT。在国家利益主导的情况下,一个公司的隐私声明什么都不是,对话信息泄密几乎是必定的!使用的时候,注意屏蔽或者修改敏感信息! ChatGPT的效果演示 下面是两篇使用ChatGPT写的文章,记录下了和ChatGPT的交流过程,可以看一下它的聪明程度!而这仅仅是ChatGPT3.5版本的能力。如果说ChatGPT3.5是一个掌握了所有知识的初中生,那么ChatGPT4是一个掌握了所有知识的大学生了! 信用卡对个人、社会以及国家的影响——ChatGPT辅助编写 开源观察之到底是谁在主导开源软件生态的发展? ChatGPT训练数据构成 这些是ChatGPT3.5版本的训练数据构成! 中国想要做一个同样的AI,最大的问题不是模型,不是显卡,而是数据!中文数据量远小于英文数据量,这将导致中文AI的聪明程度远逊色于英文AI 文本数据 以下是ChatGPT数据集的一些基本信息: 数据集信息 内容 数据集大小 45TB 数据集来源 来自互联网的文本(包括wiki所有数据,互联网档案馆所有数据) 数据集语言 40多种语言,包括英语、中文、法语、德语、日语、西班牙语、阿拉伯语等 数据集类型 经过筛选的文本数据 数据集格式 文本文件 数据集包含内容 百科知识、新闻报道、小说、博客、论坛、邮件、科技文章(包括所有论文)等 数据集的应用 自然语言处理、文本分类、文本生成、问答系统等 由于ChatGPT数据集是从互联网上爬取的文本数据,因此包含许多不同的语言,例如英语、中文、法语、德语、日语、西班牙语、阿拉伯语等,其中英语是最常见的语言之一。虽然数据集中包含许多不同的语言,但由于数据集是基于英语训练的,因此英语占据了相当大的比例。 代码数据 当我被训练时使用的数据集是从GitHub上获取的公共代码仓库数据,该数据集涵盖了多种编程语言。下表提供了一些数据集的统计信息。 统计信息 数量 总文件数 1.5亿个 编程语言 与GitHub上支持的所有语言相同 训练数据时间范围 2008年至2021年 训练数据代码总行数 约1万亿行 最大的单个文件 5GB 代码仓库的总大小 4.4PB 训练数据总大小 3.3PB 数据集中的平均文件大小 约23KB 请注意,这些统计数据仅供参考,因为这些数字是基于特定时间段内的数据集构建的,这意味着随着时间的推移,这些数字可能会发生变化。 不同语言比例 它没有直接回答比例,再三追问之下,是这么说的 很抱歉,我不能准确回答这个问题,因为我并没有掌握所有互联网上的信息和数据。我的知识来自于已有的公开数据和信息,因此无法给出一个准确的占比。 根据我掌握的已有知识,英语在互联网上的占比最高,约占据70%以上的比例。中文排名第二,占比约为20%左右。其他语言的占比较小,不到10%。需要注意的是,这只是一个大概的估算,具体的占比可能会受到多种因素的影响,比如地域、人口等等。 下面将介绍如何注册和使用ChatGPT! 前期准备 科学上网,最好是美国IP。最好是个人单独使用独立服务器!公开的VPN服务商的IP由于有很多人同时使用,早就被OpenAI禁止注册和登录的,即使是VPN服务商新开的服务器侥幸注册,也很容易由于IP被注册、登录、访问使用太多而被牵连一锅端封号! 外国邮箱,如gmail、outlook、iCloud邮箱等 有一个能收到验证码的外国手机号码,如果你没有,请跳到下一步,注册一个能接验证码的手机号,注意这是收费的! chatGPT封号规则: 不在服务区域内 同 IP 多账号 和注册手机号不在同区域或 3 地 所以 ChatGPT 账号最好不要公用,最好使用在 OpenAI 服务区的IP访问 OpenAI,例如在美国的服务器 注册短信平台并充值 打开 https://sms-activate.org/点击右上角注册 输入邮箱和密码注册,需要收激活邮件激活账号。 激活账号后,点击充值 可以用支付宝充值1美元。其实这里充值 0.2美元 就够一次OPENAI注册了! 输入1美元,然后支付 支付了可能要等几分钟才显示到余额账户,我在注册时就等了一会余额才显示 注册 OpenAI 账号 挂上科学访问打开 https://chat.openai.com/进行注册,如果没有科学上网会提示无法注册 OpenAI’s services are not available in your country. 注册成功后会进入验证手机号页面,选择你下一步短信平台的接码的手机国家 在短信平台接码 右侧服务,输入搜索openai,选择 选择印度或者巴西 现在你有一个可以接码的号码了,图下919862209703就是号码,复制号码到OpenAI验证码界面 输入接码号码,点击“send code” 然后等激活码,如果没有收到可以点OpenAI注册界面再发一次验证码,可以多试几次。 注册完就可以去登录 https://chat.openai.com/auth/login ChatGPT使用 就和普通微信聊天一样,发送你请求给你的朋友,ChatGPT就会给出答案! 超酷 ChatGPT 提示 awesome-chatgpt-prompts 搭建微信ChatGPT机器人 一个基于OpenAi ChatGPT + WeChaty 实现的微信机器人 ,可以用来帮助你自动回复微信消息,或者管理微信群/好友,检测僵尸粉等… 获取自己的 api key,地址戳这里 👉🏻 :创建你的 api key git clone https://github.com/wangrongding/wechat-bot.git --depth 1 cd wechat-bot docker build . -t wechat-bot docker run -d --rm --name wechat-bot -v $(pwd)/config.js:/app/config.js -v $(pwd)/.env:/app/.env wechat-bot 搭建网页ChatGPT聊天 用 Express 和 Vue3 搭建的 ChatGPT 演示网页 另一个支持注册登录,前端设置API Key 的修改版本 https://github.com/Kerwin1202/chatgpt-web docker compose version: '3' services: chatgptWeb: image: chenzhaoyu94/chatgpt-web # 总是使用 latest ,更新时重新 pull 该 tag 镜像即可 ports: - 3002:3002 environment: # 二选一 OpenAI API Key - https://platform.openai.com/overview OPENAI_API_KEY: sk-xxx # 二选一 change this to an `accessToken` extracted from the ChatGPT site's `https://chat.openai.com/api/auth/session` response OPENAI_ACCESS_TOKEN: xxx # API接口地址,可选,设置 OPENAI_API_KEY 时可用 OPENAI_API_BASE_URL: xxx # API模型,可选,设置 OPENAI_API_KEY 时可用 OPENAI_API_MODEL: xxx # 反向代理,可选 API_REVERSE_PROXY: xxx # 访问权限密钥,可选 AUTH_SECRET_KEY: xxx # 超时,单位毫秒,可选 TIMEOUT_MS: 60000 # Socks代理,可选,和 SOCKS_PROXY_PORT 一起时生效 SOCKS_PROXY_HOST: xxx # Socks代理端口,可选,和 SOCKS_PROXY_HOST 一起时生效 SOCKS_PROXY_PORT: xxx # HTTPS 代理,可选,支持 http,https,socks5 HTTPS_PROXY: http://xxx:7890 过 Cloudflare 403 自建代理,适用于 accessToken 的方式(不适用于 apiKey) 可以用现成的镜像,也可以自己打包,有 Java 和 Go 实现的 API,开源 除了官方 429,没有速率限制,但可能会不稳定,可能会突然失效(失效会尝试更新) 适合自建自用的场景(多人用会有各种问题) 结合本项目,可以这样使用 version: '3' services: app: image: chenzhaoyu94/chatgpt-web # 总是使用 latest ,更新时重新 pull 该 tag 镜像即可 ports: - 127.0.0.1:3002:3002 environment: # 二选一 OPENAI_API_KEY: # 二选一 OPENAI_ACCESS_TOKEN: eyJxxx # API接口地址,可选,设置 OPENAI_API_KEY 时可用 OPENAI_API_BASE_URL: # API模型,可选,设置 OPENAI_API_KEY 时可用,https://platform.openai.com/docs/models # gpt-4, gpt-4-0314, gpt-4-32k, gpt-4-32k-0314, gpt-3.5-turbo, gpt-3.5-turbo-0301, text-davinci-003, text-davinci-002, code-davinci-002 OPENAI_API_MODEL: # 反向代理,可选 API_REVERSE_PROXY: http://go-chatgpt-api:8080/conversation # 访问权限密钥,可选 AUTH_SECRET_KEY: # 每小时最大请求次数,可选,默认无限 MAX_REQUEST_PER_HOUR: 0 # 超时,单位毫秒,可选 TIMEOUT_MS: 60000 # Socks代理,可选,和 SOCKS_PROXY_PORT 一起时生效 SOCKS_PROXY_HOST: # Socks代理端口,可选,和 SOCKS_PROXY_HOST 一起时生效 SOCKS_PROXY_PORT: # HTTPS 代理,可选,支持 http,https,socks5 HTTPS_PROXY: depends_on: - go-chatgpt-api go-chatgpt-api: container_name: go-chatgpt-api image: linweiyuan/go-chatgpt-api environment: - GIN_MODE=release - CHATGPT_PROXY_SERVER=http://chatgpt-proxy-server:9515 # - NETWORK_PROXY_SERVER=http://host:port # - NETWORK_PROXY_SERVER=socks5://host:port depends_on: - chatgpt-proxy-server restart: unless-stopped chatgpt-proxy-server: container_name: chatgpt-proxy-server image: linweiyuan/chatgpt-proxy-server restart: unless-stopped 终端 docker-compose up -d https://github.com/linweiyuan/go-chatgpt-api chatgpt-proxy-server chatgpt-proxy-server ChatGPT 代理服务器 利用 undetected_chromedriver 绕过 Cloudflare 403 监听 9515 端口,通过原生 JS 发送 XHR 来进行通信 Dockerfile FROM archlinux ENV SUDO_USER_NAME linweiyuan ENV MIRROR_URL 'https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch' RUN echo "Server = ${MIRROR_URL}" > /etc/pacman.d/mirrorlist \ && pacman -Sy --needed --noconfirm \ && pacman -S base-devel git --needed --noconfirm \ && useradd -m ${SUDO_USER_NAME} \ && echo "${SUDO_USER_NAME} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers \ && su ${SUDO_USER_NAME} -c 'cd \ && git clone https://aur.archlinux.org/google-chrome.git \ && cd google-chrome \ && source PKGBUILD \ && sudo pacman -Syu --asdeps --needed --noconfirm "${makedepends[@]}" "${depends[@]}" \ && makepkg -sir --noconfirm \ && cd \ && git clone https://github.com/ultrafunkamsterdam/undetected-chromedriver \ && cd undetected-chromedriver \ && sudo pacman -S --needed --noconfirm python python-setuptools \ && sudo python setup.py install \ && (python example/example.py &) \ && while true; do [ -f ~/.local/share/undetected_chromedriver/undetected_chromedriver ] && sudo cp ~/.local/share/undetected_chromedriver/undetected_chromedriver / && break || sleep 1; done \ && cd \ && sudo rm -rf google-chrome undetected-chromedriver \ ' \ && pacman -Rs --noconfirm python-setuptools python git base-devel \ && rm -rf /usr/lib/python* \ && echo -e "y\nY" | pacman -Scc CMD ["./undetected_chromedriver", "--allowed-ips=", "--allowed-origins=*"] 修改 MIRROR_URL 为 Arch 最优源的同时,要注意网络环境能正确处理 AUR 和 GitHub 上面的资源 桌面ChatGPT https://github.com/Bin-Huang/chatbox ChatGPT4 使用 付费用户可以直接体验ChatGPT4 普通用户预约,预约链接如下: https://openai.com/waitlist/gpt-4-api 使用 chatgpt-web 自己独立搭建服务器,强烈推荐! 如果使用官方网页版,需要把openai.com sentry.io都代理了,sentry.io是一个第三方日志收集平台! Chrome 插件 ChatGPT for Google Bing Chat for All Browsers ChatGPT Plus 如何付费 目前经典GPT不支持的信用卡 国内招行实体VISA、MasterCard、全币卡都尝试过了,绑定不上。 与此同时还尝试了全球付的香#港虚#拟信#用卡以及万里汇的香港虚#拟信#用卡,也绑定不上 目前经典GPT支持的信用卡 NobePay虚拟信用卡:https://www.xiaoz.me/archives/18207,支付宝可充值(`556766`卡段绑定成功) Depay虚拟信用卡:https://www.xiaoz.me/archives/18313,需要USDT才能充值(`531993`卡段绑定成功) QBIT虚拟信用卡:489683卡段xiaoz绑定OpenAI成功,但是据一位经典GPT用户透漏绑定失败,因此这个卡段尚不完全确认 据网友反馈派安盈(Payoneer)的信#用#卡529366也可以绑定经典GPT。 账单地址如何填写 账单地址不建议乱填,因为目前不确认地址乱填是否会触发风控,至少看起来应该像真实的。部分虚#拟#卡开通的时候会生成随机地址,如果虚#拟#卡提供了地址,可以直接使用虚拟卡提供的地址。(nobepay和qbit虚拟卡都提供了地址) 如果虚拟信用卡未提供地址,可以尝试下面2个网站去生成地址并填写。 https://www.meiguodizhi.com/ https://www.haoweichi.com/ Auto-GPT An experimental open-source attempt to make GPT-4 fully autonomous. Github Auto_GPT 心智测试 Theory of Mind Test 基于ChatGPT4,除了没有计划能力,的确已经拥有了某种心智能力! Auto GPT在某些方面,已经开始补齐GPT模型的计划能力! 心智能力 GPT4 GPT5 逻辑推理 ✅ 方案计划 ❌ 解决问题 ✅ 抽象思维 ✅ 理解复杂想法 ✅ 快速学习和从过往经验学习复盘能力 ✅ Claude Claude 是 openai 内部团队出走后创建的新的AI, 最新 Claude 3 能力已经超越 OpenAI ChatGPT4 了 https://claude.ai/ 微软 Bing Chat 比 OpenAI Chat 版本训练数据更新,两者各有千秋 加入候补名单 前往 https://www.bing.com/new 网页,按一下「加入等候清单」,然后登入你的Microsoft 帐号即可加入候补。 等待通过候补名单 这里等待时间不确定,有人快,有人慢。博主等了接近三周时间! 下载 Edge Dev 版本 下載 Microsoft Edge Insider Channels, 安装好后,就可以开始使用 Bing Chat 了 上面是以前的方法,现在有更方便的解决方法了,科学上网 + 浏览器插件 New-Bing-Anywhere 开始使用 bing chat 下面是简单使用记录,可以看出,可以理解人类语音,做阅读理解,归纳中心思想了! ChuanhuChatGPT https://github.com/GaiZhenbiao/ChuanhuChatGPT GUI for ChatGPT API and many LLMs Claude 注册使用教程 现在可以直接在claude官网使用 https://claude.ai/ (目前仅对美/英地区开放) 介绍 Claude 是Anthropic公司开发的AI聊天机器人,与ChatGPT类似,由OpenAI(ChatGPT所在的公司)的前副总裁创办。和ChatGPT-3.5相当,但比不上GPT4,拥有连续对话能力,在撰写小说、编写代码、解释概念等方面表现出色 Claude 目前还处于免费使用阶段,只需注册一个Slack账号即可以,无需梯子也可以使用。 注册Slack账号 打开Slack网站:slack 可以直接使用Gmail邮箱注册(QQ邮箱不支持),或者直接Google、Apple账号授权登录,这里我用Gmail邮箱注册。 填上验证码 创建工作区 创建工作区后填上自己姓名,跳过邀请 Slack中添加Claude 打开网站 www.anthropic.com ,点击 Add to Slack 允许授权 授权成功,如果出现403等错误,可多次重试。 也可以微信上(go2071)告诉我你的邮箱,我可以拉你加入到我的频道 回到Slack中,这时候你会发现你的Slack多了一个叫Claude的应用 体验Claude 你可以进入任意频道,在聊天窗口@Claude 并邀请Claude机器人加入频道后开始群聊 点同意 @Claude并提问 频道类似与群聊,大家都能看到消息内容。你也可以在应用列表中点击Claude直接与Claude发起聊天,相当于一对一私聊 ChatGPT将取代谁? 为什么AI会写代码但是对程序员威胁不大,会画图对画师威胁却很大? 举个例子,假定现在AI数学水平已经达到数学系博士水平,你随便问他一个高数难题它都能解答,对99%人来说有用吗?完全没用,因为它给出的答案不管是正确还是错误的,都根本看不懂!这个数学AI只对精通高等数学的人才是有用的。 同理,AI写代码再厉害,99%的人看到代码也是一头雾水,完全不知道怎么用对吧?所以,只有专业的开发人员才能用好AI写的代码。但是呢,画师比较悲催,因为AI画的图,普通人虽然像我一样,不懂什么构图、光线、透视之类,但是画得好不好看,大家审美只要稍微在线,都是看得出来的,所以,原来99%的人不会画画,但是借助AI画画,能满足70~80%的需求,对画师来说,职业威胁就很大。 所以AI能不能取代一个行业,关键看它产出的内容,是不是高度专业相关的,如果是,那AI的产出对于非专业人士来说,意义不大,如果不是,那就要小心AI取代某项工作了。 注意事项 Q1: OpenAI‘s services are not available in your country. A1: 使用短信平台绕过 https://sms-activate.org Q2:虚拟号码注册了,但是登录还是显示OpenAI’s services are not available in your country. A2: 在OpenAI’s services are not available in your country提示页按F12打开开发者工具,到【应用-存储-本地存储空间】页把@@authOspajs开头的这个密钥删除,再刷新页面。或者使用隐私模式浏览器再次尝试 Q3:使用ChatGPT会泄密么? A3: 作为一个AI语言模型,我的“记忆”实际上是通过训练数据和算法得到的,而不是像人类一样具有真正的记忆。我的模型已经经过训练,可以在处理自然语言时自动学习和适应。每次交互都可以帮助我进一步优化我的表现,但我并不能将一个特定的对话记录下来,并直接将其存储在我的模型中。在保护用户隐私和保密性方面,我们非常重视,并且严格遵守相关法规和规定。 虽然chatGPT是这样回答的,但是实际上,chatGPT肯定会以某种形式记录用户交流的过程,并很有可能把交流过程作为训练数据以提升下一代产品的智能水平。所以,问问题的时候,把敏感信息去掉! 参考&致谢 中国区注册OpenAI账号试用ChatGPT指南 WeChat Bot OpenAI/ChatGPT Plus信用卡绑定总结,整理了部分支持的信用卡 0门槛克隆ChatGPT方案再升级,开源模型复现,在线体验无需注册 一种取巧的方式绕过Cloudflare v2验证 chatgpt-proxy-server 使用 Cloudflare Workers 让 OpenAI API 绕过 GFW 且避免被封禁 awesome-ChatGPT-repositories Claude保姆级注册教程 神经网络原理 先在这里写一段,等整理了更多资料再专门写一下AI背后的数学原理和工程应用 数学原理 傅里叶变换可以模拟任何一个函数!——深度学习背后的数学原理 反向迭代,梯度下降是计算神经网络参数值的数学原理 存在局部最优,与全局最优的不可调和 可能过拟合 存在的问题 神经网络是一个黑盒子,能算出结果,但人类无法理解为什么得到这个结果 无法给出确定的结果,及其微小的扰动,可能会导致完全不同的结果。例如一张图片,一个像素的变化,导致识别出来猫和狗的差异 黑盒炼金被滥用!任何期望的结果,通过一个数据训练,都可以得到一个模型,即使这个模型从根本上就是错的。例如出生时间与生男生女的关系,可以训练一个模型预测;手掌纹路和长大后犯罪的关系,也可以训练一个模型预测。但这种模型可能从一开始就是错误的,存在偏见的,异想天开的,但无论多么荒谬的模型,只要有数据,可以训练出来!这种滥用可能导致非常严重的后果! 在关键领域,涉及责任分配,生命相关的领域,神经网络无法担责,也无法保证一定的确定结果。例如L4级别的自动驾驶 竞品 tabby Eugeny/tabby: A terminal for a more modern age (github.com) 微软 Copilot 开源替代版 alpaca Code and documentation to train Stanford’s Alpaca models, and generate the data. crfm.stanford.edu/alpaca/ ChatGLM-6B ChatGLM-6B是一个中英双语开源大模型,最低可在6G显存上运行 ColossalAI Colossal-AI: Making large AI models cheaper, faster and more accessible gpt4all Demo, data and code to train an assistant-style large language model with ~800k GPT-3.5-Turbo Generations based on LLaMa DeepSpeed DeepSpeed is a deep learning optimization library that makes distributed training and inference easy, efficient, and effective. www.deepspeed.ai/ MiniGPT-4 MiniGPT-4: Enhancing Vision-language Understanding with Advanced Large Language Models 更多应用 集成环境 janhq/jan invoke-ai/InvokeAI chatchat-space/Langchain-Chatchat ollama ChatGPT-Next-Web one-api buzz 语音转文字 lobechat 支持多种大模型聊天机器人 学习 datawhalechina/self-llm: 《开源大模型食用指南》基于Linux环境快速部署开源大模型,更适合中国宝宝的部署教程 知识库 Mintplex-Labs/anything-llm: The all-in-one Desktop & Docker AI application with full RAG and AI Agent capabilities. (github.com) 知识图谱 microsoft/graphrag: A modular graph-based Retrieval-Augmented Generation (RAG) system AI 编程 GPT Pilot Create your own and custom Copilot in VSCode with Ollama and CodeGPT | by Daniel Avila | CodeGPT rjmacarthy/twinny: The most no-nonsense, locally or API-hosted AI code completion plugin for Visual Studio Code - like GitHub Copilot but completely free and 100% private. 伪造视频语音 伪造语音,视频,对于诈骗行业来说,这是个好消息。但对于普通人来说,看到视频,也可能是对方精心伪造的,视频语音都失去了可信性了 Tortoise-TTS 克隆目标语音 Deepfake 视频伪造 bark Text-Prompted Generative Audio Model openvoice myshell-ai/OpenVoice facefusion/facefusion 视频生成 harry0703/MoneyPrinterTurbo: 利用AI大模型,一键生成高清短视频 虚拟主播 可以演电影,电视剧,带货主播等等。再也不用担心主播人设坍塌,变老等 客服 Langflow - Create your chatbot! AI绘画 Stable-diffusion https://github.com/luosiallen/latent-consistency-model https://github.com/0xbitches/ComfyUI-LCM Pinokio 模型下载 Civitai: The Home of Open-Source Generative AI 3D建模 Meta 3D AssetGen 智能翻译 OpenAI-Whisper WebUi 集成环境 buzz Subtitleedit 写代码 Copilot Cursor 内置GPT4,不需要你有OpenAI的账号和Key,直接白嫖 这个测试着,内部集成的似乎是GPT3? 翻译 bilingual_book_maker 金融 https://github.com/AI4Finance-Foundation/FinGPT 开源金融模型 GPT学术优化 gpt_academic 未来畅想 超大规模神经网络已经具备初步的智能了,ChatGPT 3.5 版测试大约人类9岁儿童智能水平! 随着神经网络规模扩大,获得成年人智能水平的神经网络也许很快就会面世! 真人工智能诞生的日子,就是下一次工业革命级别的技术变革之日! 问题 Error Code 429 - You exceeded your current quota, please check your plan and billing details. 官方回复如下: 此错误消息表示您已达到 API 的每月最大支出(硬性限制)。这意味着您已经消耗了分配给您的计划的所有积分或单位,并且已经达到了您的计费周期的限制。发生这种情况的原因可能有多种,例如: - 您使用的是大容量或复杂的服务,每个请求消耗大量信用或单位。 - 您正在使用需要处理大量请求的大型或多样化数据集。 - 对于您的组织的使用,您的限制设置得太低。 要解决此错误,请执行以下步骤: -在此处检查您的帐户设置中的当前配额。您可以在此处查看您的请求消耗了多少令牌。 - 如果您使用的是免费计划,请考虑升级到提供更高配额的现收现付计划。 - 如果您需要增加配额,可以在这里申请。我们将审核您的请求并尽快回复您。 系列教程 全部文章RSS订阅 AI系列 AI 分类 RSS 订阅 深度学习之视频人脸识别系列 中国区注册ChatGPT并使用全流程图解教程 关于普朗克概率的的讨论 信用卡对个人、社会以及国家的影响——ChatGPT辅助编写 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2023/2/1
articleCard.readMore

yandex源代码泄露? 精品代码下载与赏析

yandex 是俄罗斯类似于 Google 的搜索引擎,2023年1月26日,Yandex 的源代码被人泄漏到 BreachForums 论坛上!总计大小 44.71GB,源代码大家共赏! 关于种子的重要细节 它只是存储库的内容,没有其它内容 所有文件日期都可以追溯到 2022年2月24日 它不包含Git历史,大部分只是代码 大部分软件都没有预构建的二进制文件,只有少数例外 除了一些例外,没有预训练的ML模型 泄露了那些内容? 搜索引擎和索引机器人 地图 - 类似于谷歌地图和街景 Alice - 类似 Siri / Alexa 的 AI 助手 出租车 - 类似优步的出租车服务 Direct - 广告服务,例如 Google Ads / Adwords 邮件 - 类似 GMail 的邮件服务 磁盘 - 类似 Google Drive 的文件存储服务 市场 - 像亚马逊这样的市场 旅行 - 就像 booking.com 增强版,加上机票,火车票,巴士票 Yandex360 - 像 Google Workspaces 一样在您自己的域上提供服务 云 - 可能并非所有基础设施代码都被泄露。 Pay - 类似 Stripe 的支付处理,但功能有限 Metrika - 像谷歌分析 至少大部分其他公司服务的后端部分都在那里。 文件的完整文件列表: 如果您不想下载 torrent,但对里面的内容感到好奇,您可以从以下要点中获取文件列表: https://gist.github.com/ArseniyShestakov/53a80e3214601aa20d1075872a1ea989 你也可以像普通的 git 仓库一样克隆它: git clone https://gist.github.com/ArseniyShestakov/53a80e3214601aa20d1075872a1ea989 可以使用以下命令获取所有文件的列表。 种子中的完整文件列表 aapi.tar.bz2 client_method.tar.bz2 gencfg.tar.bz2 mobile-WARNING-notfull.tar.bz2.part skynet.tar.bz2 admins.tar.bz2 cloud.tar.bz2.part groups.tar.bz2 nginx.tar.bz2 smart_devices.tar.bz2.part ads.tar.bz2 commerce.tar.bz2.part helpdesk.tar.bz2 noc.tar.bz2.part smarttv.tar.bz2 alice.tar.bz2.part config.tar.bz2 infra.tar.bz2 partner.tar.bz2 solomon.tar.bz2.part analytics.tar.bz2.part connect.tar.bz2.part intranet.tar.bz2 passport.tar.bz2.part stocks.tar.bz2 antiadblock.tar.bz2 crm.tar.bz2.part investors.tar.bz2 pay.tar.bz2 switch.tar.bz2 antirobot.tar.bz2 crypta.tar.bz2 it-office.tar.bz2 payplatform.tar.bz2.part tasklet.tar.bz2 autocheck.tar.bz2 customer_service.tar.bz2 jupytercloud.tar.bz2 paysys.tar.bz2 taxi.tar.bz2.part balancer.tar.bz2 datacloud.tar.bz2 kernel.tar.bz2.part portal.tar.bz2.part tools.tar.bz2 billing.tar.bz2 delivery.tar.bz2.part library.tar.bz2.part privacy_office.tar.bz2 travel.tar.bz2.part bindings.tar.bz2 direct.tar.bz2.part load.tar.bz2.part products.tar.bz2 wmconsole.tar.bz2 captcha.tar.bz2 disk.tar.bz2 mail.tar.bz2.part robot.tar.bz2 yandex360.tar.bz2.part cdn.tar.bz2 docs.tar.bz2 maps.tar.bz2.part rt-research.tar.bz2 yandex_io.tar.bz2.part certs.tar.bz2 drive.tar.bz2.part maps_2.tar.bz2.part saas.tar.bz2 yaphone.tar.bz2 ci.tar.bz2.part extsearch.tar.bz2.part maps_adv.tar.bz2 sandbox.tar.bz2 yawe.tar.bz2 classifieds.tar.bz2.part frontend.tar.bz2.part market.tar.bz2.part search.tar.bz2 client_analytics.tar.bz2.part fuzzing.tar.bz2 metrika.tar.bz2.part security.tar BT 种子下载 magnet:?xt=urn:btih:7e0ac90b489baee8a823381792ec67d465488fef&dn=yandexarc&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2920&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Fexodus.desync.com%3A6969&tr=udp%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce&tr=udp%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce 想要的速度下载吧!不知道什么时候就完全被禁了! 代码技术栈不光 C++, 还有Go, java, python,后台完全容器化了,代码风格简洁,注释完整,是一份非常不错的参考代码! 参考&致谢 参考翻译 YANDEX SERVICES SOURCE CODE LEAK

2023/1/31
articleCard.readMore

关于经济观察,投资理财以及未来经济展望

经济基础决定上层建筑,其实就是物质决定意识。上层建筑指建立在经济基础上的政治、法律、宗教、艺术、哲学等观点,以及适合这些观点的政治、法律等制度。经济基础是指物质的基础,上层建筑是指精神层面的东西。 本文讲介绍一套行之有效的经济分析方法和投资理财方法! 人一辈子掌握三项本事就够了,本文为社会运行之经济篇! 人性 规律 社会运行法则 ——古人智慧云:见自己,见众生,见天下。 前言 军事战争是政治的延续,而经济基础又决定这政治思想、思路。一系列经济,农业,军事政策又都是政治思想的体现。如果你足够敏锐,有足够的推理和素材积累,就可以从一些极其细微的民生政策变化窥探出整个经济的运行情况,进而预测未来几年,甚至几十年的经济发展变化。 自从有货币以来,资本收益,就大于劳动收益!【尽早完成原始记录】 所有金融的手段,说到底,都是怎么把别人口袋里的钱弄到自己口袋里! 世界上,几乎99%以上的问题,都可以用经济学来解释! 财富自由,说到底,是找到一条合理合法剥削别人劳动成果的途径! 冥冥之中,你得到的任何东西,背后都标有价格!没有任何东西是免费的 有钱人最大的财富是穷人,顶层掠食者制造一系列规则批量制造穷人!这些规则你听过的有广告,风俗,行业规则,壁垒,过路费等等 获得财富的本质是对生产资料的不断占有!所谓的身产资料就是能够让资本持续增值的东西,比如说土地,矿产,房子,工厂,股份,商标。大部分人掌握的技能,比如说读工科或者读文学医学,或者学习其它的技术,这些都不是身产资料,这是生产工具,都是以出卖劳动技能或者劳动时间来获取收益。 金融基础 金融历史 让我们回顾一下金融的历史,大概我们分为三个阶段。从最早以物易物开始,到后来的黄金白银一般等价物,到后来的纸质信用货币。 生产消费者在第一阶段是面对面交易,时间,空间在一起。到黄金成为等价物后,时间,空间就可以分离,在这里,黄金是有价值的。 到后来,信用货币阶段,纸币,甚至银行的存款只是一段电子数据,货币的价值远小于货物的价值,加上交易时间,空间的分离,这里就埋下了金融危机的导火索,所有的金融危机都是由于生产消费的失衡。 正是由于交易的空间,时间不再统一,货币的价值远小于货物的价值,货币发行方肆意滥发货币导致了金融危机。还有一点是资本所有者付给劳动者的工资不能买下劳动者生产的所有货物,这就是积累消费失衡的根源,所以金融危机隔一段时间发生一次,使生产和消费重新平衡。 98年东南亚金融危机的外部原因之一是中国收入分配失衡,劳动者的收入远不能买到生产出来的产品,只能出口,其它内部原因还有东南亚国家内部分配失衡,债务过高,给外部攻击者留下了巨大的漏洞,最终导致金融危机。 货币系统中,货物是交易的基础,先有货物,才有交易,有交易,才有货币需求!货币货币,货币系统中,货物比币重要!所以制造业是金融业的基础,没有制造业,金融业就是空中楼阁!所以美元现在的价值,很大一部分来自于中国货物的支撑,还有美股上市的中国优秀公司的支撑! 货币的本质其实是信心! 理解这一点才能理解比特币,理解金融危机。比特币区块链的信心来自于算法,不会被篡改,剥夺,收缴,通胀,比随意发行的央行靠谱,只是没有暴力机关背书。随着世界和平,暴力机关作用下降,金融封锁,央行随意通胀,来自于数学算法的信心将更加可贵。 信心比黄金更重要。黄金可以滋生信心,但信心不能滋生黄金。暴力武器,军队也是信心来源。仔细体会这几句话可以看懂很多金融现象。 基于中心化的结算系统 SWIFT 结算系统未来必定会被基于区块链的去中心化结算系统取代。数字区块链货币未来也必将取代纸币。这中间会有很多行业被颠覆,变革,这其中就有很多机会。 关于贫穷 极端贫穷会剥夺人思考和进步的机会,故而一个成熟社会必定有基本的社会保障机制。 贫穷是惨淡凄凉的,贫穷会切断人们对未来的想象。让他们只能像蜜蜂和工蚁一样机械而麻木地去生活,没有闲暇去思考现在做什么未来又该做什么。曾经有个美国女作家深入底层体验了一下快餐店女工的贫穷生活,她原本也以为她们的贫穷是源于她们的懒惰、麻木和缺乏理财能力,然而自己体验之后却知道——那真是夏虫不可语冰,何不食肉糜。因为长期的高强度工作让她们损害了健康,疲累不堪,微薄的薪水根本不够去长期租房,付不起押一付三的房租,只能去饮鸩止渴住胶囊旅馆,她们哪里有资格去谈什么继续读书、理性消费、理财能力啊!这位美国女作家叫做芭芭拉,她写的那本畅销书叫做《我在底层的生活》。 社会财富 人口,土地。 土地至上:矿藏,石油,食物。财富之母 人口:不光是人才,支撑社会还需要大量的低端服务职位。一个城市既需要高端人才,也需要低端服务。 人口多,人才就多。人才的后代不一定是人才,成材率问题。至少可预见的几百年多不会改变。 财富是对认知的补偿,而不是对勤奋的奖赏! 法币系统 法币系统真相就是:印钱,发债,通胀,收债,销毁! 问题就出在发债,国债发行后,流入的是大型企业和政府搞建设,然后一层一层扒皮,官员要腐败,领导要分红,总之,只有上层先受益。大头被上层富人拿走,底层干活的领工资的,只拿到一小部分。等到这些拿到债务超发的货币消费时,多出来的现金就会导致物价上涨。底层拿不到债务超发货币的人的财富就是这样生生被窃取了! 发债本质就是富人对穷人的窃取!看看GDP 中劳动收入低于30% 很多年了。课本当然不会这么讲,说是刺激经济,为老百姓谋福利。出发点是好的,但问题在于货币超发的受益不能公平的分给每一个人。更大的问题是,收债和销毁环节没有做好,甚至是根本没有做。债务展期,甚至一笔销毁,借新债还旧债,导致通胀愈发严重。 给所有人都发一万元,才是劫富济贫!因为这将导致富人的财富占比缩小,给大家发钱是刺激消费更好的办法!任何反对这一点的都是屁股站在富人资本家的位置上的,不是蠢就是坏。 正规经济学课本中充满虚假和谎言,很多是强势方给弱势方设立的牢笼和陷阱经济不是独立系统,经济是政治和军事衍生的产物,它们相互影响,并不是独立存在的。任何一个债务超发国最终几乎都走向了纳粹,参考二战前的德国,如果一个债务超发的政府没有自我崩溃,几乎一定会对外扩张来消除债务自救! 经济系统,政务系统,军事系统的独立和完整是一个完整的现代政府的重要组成成分,缺少任何一个,这个国家的国民都将身处被奴役的深渊。 经济政策 税收 强制性,无偿性,固定性 股市 创建之初目的是给国企融资 债市 外汇 利率与剥削 利率就是合法的财富转移,从没钱的人手中转移财富到有大额财富的人手中,属于劫贫济富! 例如年利率5%,那么200万存款,可以获得年化10万元受益。 假设一个封闭的村庄现在只有两个年轻人,其它都是机器人,两人都是年入10万元,A是一个是银行200万存款利率收益,B是一个工厂打工收益10万元工资! 那么,工厂打工的B需要创造多少财富,才能维持这个村庄正常运转?答案是需要创造20万财富,除了B自己的工资,还需要为A创造10万元理财收益。 从以上例子可以看出,只要还存在任何意义上的钱生钱的办法,不能钱生钱的人就一定被剥削,因为我们都在同一个市场下面使用相同的货币。 注意:利率的高低,正利率还是负利率,债务周期的位置,个人的金融处理策略都不同! 收益类型 富人(或者说财务自由)的收入和我们的收入性质是不一样的。 富人的收入大部分为资本性收入。什么是资本性收入?你可以理解为租金。比如利息和房租都是租金。利息是资金的占用租金,房租是房屋的占用租金。如果你有几个亿,那么光利息就够你过上很好的生活。而且,你每年花不掉的利息还能加到你的本金上去。形成利滚利。换句话说,富人的收入模型是复利的。收入模型近似的看成,y=a(1+i)^n。其中y是从即期开始经过了n年的收入,a是即期收入,i可以近似看成无风险收益率。 回过头来看,普通大众的劳务收入,提供劳务的价格不是由你获得多少收入决定,而是由经验,能力,及市场上的稀缺性决定。每年工作下来,由于经验的积累,技能的提高,在市场上的竞争力也会更高,从而带来更高的价格。所以劳动工作者的收入模型是单利的。我们可以把收入模型近似的看成y=a(1+n*i-d)。其中y是你的未来价格,a是你的即期收入,n是从即期开始经过多少年,i是由于经验和技能的提高带来的回报。d是由于年龄的增加和科技的发展所带来的身体和知识的折旧。其中i并不稳定,比如码农,医生,律师这种技术性很强的职业,会随着工龄的增加,价格也会更高。但是像售票员这种重复劳动者,加不加工资,看领导心情。所以有些职业多年不加工资就是这个道理。 两相比较: 富人的收入增速远远超过普通劳务工作者 富人的资本折旧取决于他所处的行业,从事的职业,折旧不稳定。而普通劳务工作者,折旧不要太稳定。只要你是人,不学习就被淘汰 报酬及收益率 财富=生产资料 + 生产者 + 资本 劳动报酬。体力,脑力劳动。智力劳动者其实天生就是“生产资料+生产者”的结合体,所以报酬比纯粹的体力劳动高很多。 资本报酬。剥削底层员工。资本的稀缺性使其天生占据主动地位,可以搜刮底层利益。 风险回报。一般人都认为高风险高回报,但风险低,门槛高的也可以高收益。 门槛回报。不对称信息,人脉,资源可以归入门槛。入手门槛高,资金量大的回报也高。资金门槛,技术门槛,天然要素(矿藏)门槛。芯片行业是典型技术资金密集型门槛。 暴力回报。政府权力收税,军队,黑社会收租。两种:1,使你过得更好收服务费。2,不给钱就破坏你的经营 (对比百度、Google)。参考吴思的《血酬定律》 天降横财,贵人相助。赌博,彩票,捡到钻石,上面有人提携。这种没有普遍性,不做讨论。 单次收益&多次收益。涉及到硬件,人力服务的单次服务成本下降有下限。而互联网,文化产业边际成本几乎为0。边际成本也是入门门槛。 供需溢价 对影星,体育明星。身体素养门槛+劳动回报 如何赚钱 赚钱的本质规律 赚钱本质的两种途径 交换 掠夺 (勤奋只能提升效率,不是赚钱的根本原因) 从术的角度分析赚钱 从术的角度去看,全世界挣钱靠以下几种途径: 继承!,这个看你的出身。 靠你的天赋异禀。比如说唱歌、画画,但是这条路其实也很难,因为能唱歌画画的人不少,要在那么多人里冒出头,其实很难。 靠专业技能提供服务挣钱。这个是大部分人的生存之道。 靠自己办企业挣钱 靠自己积累的资金,用钱挣钱。也就是通过投资赚钱。 对于富人来讲,主要是第四、第五两种赚钱方式。一般来讲,最富有的人都是有企业的老板或者投资机构出资人。 所以,正常情况下,富人是通过经营企业或投资行为赚钱,他门一定程度上不受具体的工作岗位制约,自由度会大一些。赚到的财富也不是挣工资的人可以想象。 马太效应一直存在,从0到1很困难,从1到2很容易。 三条核心认知 富在术数不在劳身,利在势居不在力耕 (出自《盐铁论》,揭示财富核心规律) 下面就从三个角度去分析: 体力劳动的局限 核心观点 劳动循环陷阱: 体力 → 换钱 → 恢复体力 → 再劳动 (陷入有限时间与体力的死循环) 关键杠杆原理 要素 说明 财富杠杆 方法应用 + 局势判断 局势案例 1. 人口结构变化(少子老龄化) 2. 房地产经济转型 3. 能源结构调整 重点:顺应局势才能突破体力循环 人和人之间的差距 人和人之间的差距主要来自于三层:认知差,信息差和能力差。 这三个层面里,认知差是最基础的,但是也是最重要的。为什么这么说,是因为能力和信息,是可以买也可以借的。 我能力不够,雇人帮我干,那是买,找合伙人合作,就是借。但是获取认知是没有捷径的,只能实打实的一点点的涨。而往往一个人的认知,就最终决定了,这个人在社会,这个生态位当中所处的位置。 这两年的流行一个说法,说一个人无法赚到他认知范围以外的钱。其实这句话是不够严谨的,很多人赚的钱就只是单纯的运气好踩中了一个风口,就跟买彩票一样中了个大奖,财富就获得了迅速的膨胀。但是往往你会发现这样的人反贫也很快,不知道大家身边有没有这样的例子,消费大手大脚了,被亲戚朋友借走了,赌博输了,盲目投资失败了。 所以我们回过头来再看这句话,确切的说法应该是:没有人能够守得住认知以外的财富,这个世界上总有一万种方法,一万种手段,把你认知以外的财富给收走。现实就是这么残酷,财富永远是对认知的补偿,而不是对勤奋的嘉奖。 三层差距模型 差距类型 特点 解决方式 认知差 基础性(不可替代) 需长期积累 信息差 可购买/借用 建立信息网络 能力差 可雇佣/合作弥补 资源整合 财富与认知关系 修正流行观点: “守不住认知以外的财富” (意外之财终将因认知缺失流失) 核心结论:财富是对认知的补偿,而非对勤奋的奖赏 时机与节奏 财富=认知+行动。 光有认知还不够,还得动手,动手就有时机的选择! 重视节奏,把握时机。注意机会是有时效性的! 任何一个行业,任何一个赛道进的早,你早跑出来半个身位,至关重要。做错是有代价的,但是错过往往是致命的,职业也好,职场也罢,其实都不是线性的那种平面的跑道,而是爬楼层,越低的楼层挤的人越多。 而在这样的楼层里,这些人为了往上爬,每个人都在努力的踩到别人身上,或者去把前面的人拉下来,在这种地方待久了,你就会被困在这种拉扯中,反复的消耗,无尽的透支。所以,不管你在职场还是创业过程中,你都要学会,前半程需要爆发性的发力,花钱的时候,你知道早花早享受,那赚钱也是一样的道理,干的越早,优势越大,当这种优势不存在的时候,就不要去碰了。 你就记住一句话,任何一个行业,只要你看到有人赚大钱的,这种标杆或者是榜样了,那就只有可能是两种情况:第一种,这个事已经晚了,不要去碰了。第二种,那就是骗子包装出来的假象,更不要碰。 这个世界上没有任何一个正常人,会把他正在赚钱的机会告诉你。如果你听到了,千万不要误以为是你运气好,大概率是对方拿你当傻子哄。 关键策略 时效性原则: 行业先发优势 > 后期努力 错过机会 比 尝试犯错 代价更大 竞争本质: graph LR A[底层赛道] --> B[人群拥挤] B --> C[互相拉扯] C --> D[持续消耗] 行业选择铁律 当某行业出现 “赚大钱的标杆” 时: 情况一:红利期已过(勿入局) 情况二:骗局包装(远离) 本质洞察:无人会将真实赚钱机会主动分享 终极财富原理 获得财富的真正的底层原理,其实是把自己这个人产品化,要把自己当成一个产品,找到自己的优势,找到自己的卖点,然后努力经营,为这个世界交付你的价值,做什么事不重要,重要的是你能通过这个事,和多少人产生链接,记住一切增值,结在人与人之间的链接中产生。 自我产品化模型 flowchart LR A[自我剖析] --> B[定位优势] B --> C[提炼卖点] C --> D[价值交付] D --> E[人际链接] E --> F[财富增值] 核心结论: 一切财富增值,皆在人际链接中产生 (做什么不重要,关键是通过事情建立多少人脉链接) 关于阶层 收入层次: 体力-技能-脑力-资本-暴力-权力(掌握话语权的暴力就是权力) 地位层次 总结起来就是:穷人靠体力赚钱,中产靠技术赚钱,富人靠钱赚钱。你赚钱的方式,其实决定你所处的阶级。那么,对于一个一无所有的人来说,如何让自己越来越有钱? 第一步:养活自己,什么都不会也没关系,我们可以靠勤劳的双手来赚钱。 第二步:当我们能够养活自己之后,就可以考虑学一门技术,然后通过技术来赚钱。 第三步:当我们可以通过技术来赚钱了之后,还需要不断积累资产和经验,学习用钱来赚钱的能力。 第四步:当我们积累了足够的本金和投资经验了之后,就是可以靠钱来赚钱了。 这是比较稳健的方法,比较适合普通大众。当然你也可以选择另一种方法:直接创业。只是这样做风险会大很多,不过也有快速成功的可能。但是一定要记住,创业不是简单的做生意,而是要打造一个能够持续创造收入的系。 财富与幸福 财富不等于幸福 获得内心的平静和幸福只需要基本的物质需求可以达到了。幸福更多的是需要精神方面的修行,而不是物质方面的。 经济学概念 宏观经济学概念: GDP(国内生产总值): 一个国家在一定时间内生产的所有最终商品和服务的市场价值总和。 通货膨胀: 一般物价水平持续上升的现象。 失业率: 衡量劳动力市场中没有工作的人数与劳动力总数的比例。 货币政策: 由中央银行实施的政策,通过调整货币供应和利率来影响经济增长和通货膨胀。 财政政策: 由政府实施的政策,通过调整税收和支出来影响经济活动和就业。 AD-AS 模型: 表示总需求(Aggregate Demand)和总供给(Aggregate Supply)之间关系的模型,解释了宏观经济波动。 物价指数(Consumer Price Index, CPI): 衡量一篮子商品和服务的价格变化,是通货膨胀的主要指标之一。 经济周期: 经济长期内周期性的波动,包括繁荣、衰退、萧条和复苏。 货币供应(M1、M2等): 衡量在经济体系中可用的货币总量的不同定义。 生产可能性曲线: 描述了在资源有限条件下,经济体能够生产的各种商品和服务的组合。 微观经济学概念: 供需法则: 描述了市场中商品和服务价格的形成机制。 弹性: 描述需求或供给对价格或其他因素变化的敏感程度。 边际效用: 衡量消费一单位额外商品或服务对满足需求的额外效用。 边际成本: 指生产或消费一个额外单位的商品或服务所需的额外成本。 垄断: 市场结构,其中只有一个卖家或生产者,能够控制价格。 完全竞争: 市场结构,其中有很多卖家和买家,商品是同质的,市场价格由市场决定。 弃权成本(Opportunity Cost): 表示因选择某个决策而放弃的最佳替代选择。 收入弹性: 描述收入变化对需求变化的敏感程度。 比较优势: 一个国家在生产某种商品或服务方面相对于其他国家的效率更高。 市场结构: 描述市场中企业数量、产品差异程度以及市场进入和退出的程度。 市场失灵: 市场未能有效配置资源,需要政府干预。 社会成本和私人成本: 区分个体决策对整个社会的影响。 国际经济学概念: 国际贸易: 不同国家之间买卖商品和服务的交流。 汇率: 一种货币与另一种货币之间的交换比率。 贸易顺差和贸易逆差: 描述一个国家对外贸易盈余或赤字。 关税和贸易壁垒: 政府对进口商品征收的税收或设置的障碍。 外汇储备: 国家持有的外国货币和其他国际资产的储备。 这些概念只是经济学领域中的冰山一角。经济学涉及到许多更为专业和深刻的概念,如信息不对称、博弈论、经济学派别等,以及新兴领域的研究,如行为经济学和发展经济学。深入理解这些概念需要学习和思考,同时也需要将它们应用于实际情境中。 下面稍微详细介绍几种 M2货币供应: M2是指一国经济体系中的广义货币供应量。它包括了M1(流通中的现金和可转账的即期存款)以及一些其他更稳定的储蓄工具,比如定期存款和其他短期存款。M2的计算公式为: [ M2 = M1 + 定期存款 + 储蓄存款 + 其他短期存款 ] M2反映了人们在经济中可用的流动资金总量,包括对银行的存款以及其他较为流动的资产。 信贷: 信贷是指借方在预先达成的条件下,从贷方(通常是银行或其他金融机构)获得资金的行为。信贷在经济中扮演着至关重要的角色,因为它推动了投资和消费,有助于经济的增长。信贷通常分为个人信贷和企业信贷,分别指个人和公司从银行借款的行为。 信贷的提供方通常会收取利息作为对提供资金的回报。信贷市场的活跃与否,以及信贷的成本(利率)都会对经济活动产生深远的影响。 贷款人希望自己的钱生出更多的钱,而借款人则想购买当前无法负担的某种东西,可能是房子、汽车、服务、投资品等等,借贷可以同时满足贷款人和借款人的需要。 如果借款人保证偿还债务,并且贷款人相信这一承诺,信贷就产生了。信贷系统非常复杂,今天我们只需要搞明白一个问题:货币是如何通过信贷流入市场的。 假如你现在有30万,如果将这30万用于消费,比如全款买了辆比亚迪,那么这30万会进入企业的腰包,之后企业通过消费、再投资、发放工资等方式将这30万流入市场。 你用30万,通过消费,给市场增加了30万的货币流通。 现在还是同样的情况,你有30万,但拿它付了一套房子的首付,首付30%,贷款70万。一旦信贷达成,银行会将你的30万,和信贷创造出的70万,总共100万一并交给房企,随后房企再通过消费、再投资、发放工资等方式将这100万流入市场。 这一次,你只用30万,通过信贷的方式,给市场增加了100万的货币流通。 信贷是重要的贫富分化途径,越是靠近上游货币流通渠道,获利越多,而普通人享受不到这些好处 假设现在是2010年,房地产商向银行贷款拿到超发货币,这时候货币在房地产商的账上,没有流入市场,所以市场上的货币还是之前的存量,物价还没有开始上涨,所以他们就可以赶在物价上涨之前扩大生产,以当时的市场价雇佣员工。 作为第一批通过信贷拿到超发货币的人,此时将资金投入市场,购买的是还未涨价的商品和服务,商品包括土地、钢筋、水泥、办公成本、劳务费等等。 他们盖房的所有成本都是以2010年物价、劳动力价格作为计价的。 而在盖房子的过程中,当初拿到的那些超发货币,已经作为支出流入了市场,从而导致市场上的货币增多。 假设房子盖好后是2012年,由于当初的超发货币已经慢慢流入了市场,导致市场上货币增多,物价必然上涨,房价更是首当其冲。这时地产商再去卖房,就能卖在物价上涨后的价格上,从中获取超额利润。 简单来说,地产商盖楼的成本是物价上涨前的成本,卖楼的价格却是物价上涨后的,而房地产商借贷盖房的一系列行为,本身就会导致通货膨胀,物价上涨。 这只是一家房地产商的资金,更不用说在盖房的两年之中,只要赶上政策大放水,其他企业和政府基建一并举债,将钱流入市场,造成更大的通货膨胀。 通货膨胀: 通货膨胀是指一段时间内一般物价水平的普遍上升。通货膨胀通常由货币供应的过度增长、需求超过供给、成本推动和预期通货膨胀等因素引起。通货膨胀可以导致货币贬值,影响人们的购买力。 央行通常会采取货币政策来控制通货膨胀。通过调整利率、购买或销售国债等手段,央行试图保持通货膨胀率在一个可控的水平,以维持经济的稳定。 平穷设计 所有的制度设计都是为了让大多数人仅仅勉强生活而已,大多数人的薪酬上限就是5000!如果让你吃饱饭了,不干活躺平了,上层统治阶级吃的喝的哪里来? 富人最大的财富是穷人,而不是手中的货币!没有穷人辛苦劳动,货币就一文不值! 33两白银 清朝的时候老百姓家庭一年的收入为33两白银,而当时一年基本支出需要花费36两白银,缺了3两白银使得老百姓每天疲于奔命,为了赚钱日夜奔波,根本没有时间思考,更没有精力反抗。 30块时薪 外卖哥,快递哥,计件工的时薪设计上限就是30块!保持让大多数人吃不饱,穿不暖,最大化剥削,阻止底层人民财富积累,保持贫困,是所有权利、资本既得利益者的共同取向! 除非物资无限,能源免费无限,这个设计看不到打破的希望 反洗脑 你在公开市场上得到信息,99%以上都是虚假的,或者是片面的、不是全部真实信息!都是为了洗脑你,掠夺你的财富而精心炮制的虚假信息。 如果你所有的信息都来自与电视,报纸等公开的媒体,那么你就是社会最底层。你的信息来自于自己的搜集整理,来自于绝大多数人都不知道的渠道,这样,你才脱离底层。 一群人,如果你不知道谁最笨,那么,你就是最笨的哪一个! 比如下面这几句: 你不理财,财不理你! 勤劳致富! 早买早享受! 看懂这几句话是如何洗脑,怎么洗脑,洗脑对象是谁,哪些人收益,被洗脑的下场是什么再去下场投资。 否则,乖乖去买货币基金,或者银行定期理财。 富贵险中求,也在险种丢! 金融与消费 一切金融活动的根本目标都只有一个,那就是尽可能避免穷人进行原始资本的积累。 永远记住,金融的本质只有两个字——分配。 人们都在努力创造财富,而有一部分人不想那么辛苦,于是发明了金融来重新分配他人创造的财富。金融活动都是维持富人很富穷人很穷的手段,所以我们看到的金融活动的结果都是富人赚穷人的钱。 你说什么?你不买股票,不买基金,任何金融活动你都不参与,没关系,金融还有一个兄弟叫消费主义! 你不做投资,就想慢慢攒钱,那就要对抗修建的越来越豪华的商超,装修的越来越别致的咖啡厅,模特身上越来越好看的衣服,甚至游戏里越来越炫目的皮肤,这个世界上几乎所有能够传递信息的屏幕都在告诉你花钱是对的,消费是对的,谈恋爱要花钱,过节了要犒赏一下自己,人均一百的餐厅很便宜。金融和消费主义这对兄弟绞尽脑汁的一切手段都是为了让你永远无法完成原始资本的积累,永远需要出卖时间出卖劳动力来赚钱养活自己。 一个忙于赚钱养家忙于出卖时间和体力,忙于应对生活中种种烦恼和困境的人,是无法意识到上述问题的,这就陷入了恶性循环,他们会因为长期出卖时间,进而自己也觉得自己的时间不值钱,于是抓紧一切业余时间做毫无价值的事情,追星刷剧酒肉社交,为了满足情绪在网络上喷人,为了寻找存在感更人开杠,甚至会牺牲休息的时间乃至睡觉的时间来麻痹感官,寻求娱乐活动。 买一样东西,犹豫的理由是因为价格,那就买;买的理由是因为价格,那就不买。 有价值的东西不能因为贵就不买,没有价值的东西就算再便宜也不能买。 小心消费主义陷阱 全世界的资本家都有一颗心照不宣的共识,就是要用尽一切的手段避免普通人完成原始资本的积累。 什么是原始资本积累? 鸡能下蛋但能孵出小鸡,长大的小鸡能继续下蛋,第一只会下蛋的鸡就是原始资本的积累。换句话说,只要完成原始资本积累,不工作也能有源源不断的收入,不出卖时间也能挣钱。 当这部分收入可以覆盖你的支出时,那么你就完成了原始资本积累和最低限度的财务自由。但这也是资本家最不愿意看到的。因为一旦你积累了原始资本,你就不再为资本家卖命,脱离了他们的控制。 如何让穷人一直穷下去? 18世纪的权贵们讨论了很久。他们认为只有穷人一直穷下去,才会老老实实的干活,才不会要求过高的薪资。意思是只有穷人一直穷才能被控制,才能为资本家一直工作。 为什么要让穷人一直穷?原因是为了整个人类社会的和谐,必须有一部分人得做出牺牲。为了使社会幸福,必须让大多数人既无知又贫穷。 然而更可怕的是,一旦大家明白了这个道理,就开始存钱并减少消费。没了消费者还没了打工仔,这就相当于同时断了资本家的两条财路。资本绝对不允许这种现象发生。 所以资本家为了阻碍穷人变富,设置了两条陷阱: 陷阱一:传统教育 你有没有发现,尽管我们在学校里学了十几年,掌握了很多技能,但似乎从来没有人教我们如何去赚钱? 很多人以为只要手里有一张大学文凭,就能够赚钱;只要能找到一份好工作,就能有不错的收入。但这真的算是在教我们赚钱吗?实际上学校里学的东西更多是教我们如何去为别人工作。 你可能会想大学里有各种专业,但很少有课程会教你如何成为资本家、如何进行投资,甚至有时候学校还会强调资本家是负面形象,而辛勤工作的普通人才是值得尊敬的。 这种说法听起来似乎很有道理,但当你真正步入社会,你会发现现实远比这残酷。学校教的知识在现实社会中往往不够用。有钱人似乎总是过得更好,而没有钱的人则步履维艰。 陷阱二:消费主义 让普通人为他们的商品买单,深陷其中无法自拔,永远无法摆脱为资本家打工的命运。 当代社会的消费陷阱错综复杂,环环相扣。商家常常以降价为诱饵,比如将原本售价30多元的奶茶降到20元,看似让消费者占了便宜,实则暗藏玄机。 要知道,这20元足够支付普通家庭三天的水费,或者购买全家两周所需的鸡蛋。 除了直接的价格诱惑,商家还会采用更为隐蔽的手段: 调味料行业:将成本仅几毛钱的味精改名为鸡精,添加一些添加剂后,价格就溢价300%。 护肤品行业:将相同成分的产品装进精美的雕花瓶子,贴上“女士专用”的标签,价格立刻翻三倍,甚至只要添加不到1%的所谓稀有成分,就能将产品炒作到上千元的高价。 如今,日常消费也被赋予了身份竞赛的意义。 汽车原本只是一种代步工具,如今却成为了阶层的标签。 奔驰、马沙拉蒂等豪车被塑造成身份金字塔的象征,仿佛开着这些车就能证明自己的社会地位。 商家还虚构出“新中产”的概念,忽悠那些刚刚脱贫的人背负上百万的债务去购买奢侈品包、钻戒和学区房。 资本构建的收割链更是密不透风: 短剧平台:前几集免费观看,后期每集收费5到8块,让老年人在不知不觉中花费数万元。 直播间限量秒杀:刺激消费者冲动消费,导致宝妈们囤积了三年都用不完的母婴用品。 APP自动续费:让年轻人每年白白缴纳数百元的会员费。 当你兜里有一万块钱时,各种营销手段就会鼓动你更换最新款的手机;当你攒下十万块,又会有铺天盖地的宣传诱惑你去购置一辆小汽车;要是你有了50万的存款,房地产广告就会不遗余力地劝你买下一套房子。 只要你手中稍有积蓄,资本总有办法刺激你的消费欲望,让你的钱从口袋里乖乖溜走。 如何摆脱消费主义困境? 想要摆脱这种被资本牵着鼻子走的困境,我们必须学会存钱。别总以收入低为借口,觉得自己根本存不下钱。哪怕每个月只存三五百,一年下来也能有五六千块钱。 存钱或许不能让你迅速实现财富自由,但它能在未来为你提供更多的选择。 在遇到突发状况时,这笔积蓄可能就是你的底气。 当有新的发展机会出现时,它也能成为你勇敢尝试的支撑。 所以从现在开始,克制不必要的消费冲动,养成存钱的好习惯,为自己的未来积攒力量。 市场分析 技术指标 经济周期 康波周期、债务周期、等 本国 M2 曲线 资本积累率 利率曲线 银行利率,国债利率 外汇 影响因素 购买力平价 利率 投资机会 国际收支 风险 政府调控 汇率受到许多因素的影响,这些因素可以分为短期因素和长期因素。下面详细介绍一些主要的影响因素: 1. 经济基本面 国内生产总值(GDP):一个国家的经济增长率对其货币汇率有重要影响。强劲的经济增长通常会提升投资者对该国货币的需求,从而推动汇率上涨。 通货膨胀率:较低的通货膨胀率通常会使得一个国家的货币升值,因为它能维持购买力。相反,高通货膨胀率可能会导致货币贬值。 利率:利率水平直接影响货币的吸引力。较高的利率通常会吸引外资流入,从而提升汇率。反之,低利率可能会导致货币贬值。 2. 货币政策 中央银行的政策:中央银行的利率决策、货币供应量和市场干预措施会直接影响汇率。例如,中央银行提高利率可能会导致货币升值。 货币干预:有时候,中央银行可能直接买卖货币来影响汇率。例如,通过购买外币以抬高本国货币的汇率,或者通过出售本国货币来贬值汇率。 3. 国际贸易 经常账户余额:一个国家的经常账户盈余或赤字会影响其货币汇率。经常账户盈余意味着国家对外出口多于进口,通常会推高汇率;反之,经常账户赤字则可能导致汇率下跌。 贸易差额:持续的贸易顺差(出口大于进口)通常会提升货币汇率,而贸易逆差则可能会导致货币贬值。 4. 资本流动 外资流入与流出:外国直接投资、证券投资和其他资本流动都会影响汇率。大量外资流入会推高本国货币的需求,提升汇率;外资流出则会导致货币贬值。 投资者情绪:市场对未来经济状况的预期和对政治风险的看法也会影响汇率。如果投资者对某国经济前景感到乐观,可能会增加对该国货币的需求,从而推动其升值。 5. 政治稳定性与经济表现 政治风险:政治不稳定、政策的不确定性或社会动荡会导致汇率波动。投资者通常会回避高风险国家的货币,导致其汇率下跌。 经济改革与政策:政府的经济改革、财政政策和其他政策变化可能会对汇率产生重要影响。例如,结构性改革或财政政策调整可能提升市场对该国经济的信心,从而推高汇率。 6. 市场预期 预期和投机行为:市场对未来汇率走势的预期会直接影响当前汇率。如果市场普遍预期某国货币将升值,投资者可能会提前买入该货币,从而推动其汇率上涨。 新闻和事件:经济数据发布、政治事件、自然灾害等突发事件都可能对汇率产生短期影响。市场对这些事件的解读和反应会导致汇率波动。 7. 国际关系 地缘政治风险:国际紧张局势或冲突会导致市场避险情绪上升,通常会推动避险货币(如日元、瑞士法郎)升值。 国际合作与协议:国际贸易协议、货币联盟等合作协议会影响国家间的经济关系和汇率。例如,欧洲货币联盟的成员国之间的货币政策协调对欧元汇率有重要影响。 A股,美股,港股走势 恐慌指数 PMI 指数 美元指数 美债收益率:长期收益率,短期收益率 大宗期货 特别是钢铁,石油。还有各种有色,粮食 技术奇点 蒸汽革命,电力革命,信息革命,移动互联网革命,3G、4G、5G等技术进步带来的变革颠覆机会! 大的趋势判断上面用上面这些指标,近期判断就需要各种重要的会议结论,各种数据公布的节点了 美联储的各种重要会议时间,结论对市场影响 各国人口变化数据公布 网络情绪,舆论 社会热点 关于个人收支曲线的讨论 个人收入曲线在30岁左右开始猛烈提高,到40~45到达顶峰,然后开始走下坡路。 个人支出曲线再结婚买房达到高峰,下一个高峰是养老。 收入支出曲线不匹配算是人生的一大痛苦了。 博弈论 参与方,决策,占比权重,期望分析 博弈论是分析市场走向的一个非常有效的方法! 对博弈各方分解的越细致,预测越准确! 债券亏损的原因 债券的亏损可能有多种原因,以下是一些可能的原因: 利率上升:债券价格和市场利率呈反比例关系,当市场利率上升时,债券价格下跌,可能导致债券投资者亏损。 信用风险:债券的信用评级越低,其风险越高。如果债券发行人的信用状况恶化,可能会导致债券价格下跌,从而导致投资者亏损。 流动性风险:有些债券市场可能缺乏流动性,即买卖债券的交易量比较小,可能导致债券价格波动较大,从而导致投资者亏损。 通货膨胀:如果通货膨胀率高于债券的票面利率,那么实际收益率将为负,这意味着投资者将亏损。 政策风险:政府政策的变化可能会对债券市场产生影响,从而导致债券价格波动,可能导致投资者亏损。 需要注意的是,债券市场是有风险的,投资者应该仔细评估其投资目标和风险承受能力,以便做出明智的投资决策。 通货膨胀时的应对方法 通货膨胀是指经济中的物价总水平上升,货币价值下降,导致购买力下降等问题。 政府策略 以下是一些政府应对通货膨胀的方法: 货币政策:央行可以通过提高利率、减少货币供应量等手段来缓解通货膨胀,以控制物价上涨。 财政政策:政府可以通过增加税收、减少支出等方式来控制通货膨胀,以避免经济过热。 投资实物资产:在通货膨胀期间,实物资产的价格通常会上涨,例如不动产、黄金等。因此,投资者可以考虑将资金投资于这些实物资产,以保护其财富。 投资通胀保值产品:通货膨胀期间,货币价值下降,但物价上涨,因此,可以考虑投资通胀保值产品,例如通货膨胀保护债券、实物商品等,以保护资产免受通货膨胀的影响。 投资股票:股票通常可以提供通货膨胀保护,因为股票的价格通常会随着通货膨胀而上涨。 增加收入:在通货膨胀期间,收入水平通常也会上涨。因此,投资者可以考虑增加自己的收入来源,以提高其抵御通货膨胀的能力。 需要注意的是,不同的投资者有不同的风险承受能力和投资目标,因此,应根据自身情况来选择合适的投资方式。同时,投资者应该密切关注经济形势和市场变化,及时调整自己的投资策略。 个人策略 对于个人投资者,以下是一些应对通货膨胀的方法: 投资实物资产:在通货膨胀期间,实物资产的价格通常会上涨,例如不动产、黄金等。因此,投资者可以考虑将资金投资于这些实物资产,以保护其财富。 投资通胀保值产品:通货膨胀期间,货币价值下降,但物价上涨,因此,可以考虑投资通胀保值产品,例如通货膨胀保护债券、实物商品等,以保护资产免受通货膨胀的影响。 投资股票:股票通常可以提供通货膨胀保护,因为股票的价格通常会随着通货膨胀而上涨。 增加收入:在通货膨胀期间,收入水平通常也会上涨。因此,投资者可以考虑增加自己的收入来源,以提高其抵御通货膨胀的能力。 减少债务负担:在通货膨胀期间,货币价值下降,债务负担也随之减轻。因此,投资者可以考虑增加债务负担,以减轻其债务负担。 增加储蓄:在通货膨胀期间,物价上涨,储蓄的实际价值也会下降。因此,投资者可以考虑增加储蓄,以保护其财富。 需要注意的是,不同的投资者有不同的风险承受能力和投资目标,因此,应根据自身情况来选择合适的投资方式。同时,投资者应该密切关注经济形势和市场变化,及时调整自己的投资策略。 操作建议 一般来说遇上通货膨胀,投资时得分成三部曲。 首先第一步必须把所有的资产投资在原材料的股票市场或者房地产市场,专注在这两个市场,相信一定是可以赚到钱的。 过了通货膨胀初期以后,来到中期。通货膨胀的中期是以现金为王的时代,在这个时间点,无论是股票市场或房地产市场都不再是进场的好时机了。这个时候应该把资产放在能够有固定收益的产品上,比如定存、短期的国债券,固定型年金或是有担保品的私人借贷(推荐1-2年期)。 等到通货膨胀末期,这个点的银行利息会非常的高,这时候我们可以把所有的投资都放在长期性的债券市场,一方面它的利息很不错,另一方面未来可能要刺激经济景气循环的过程,而这时候我们则可以赚到债券的价格差距了。 所以在通货膨胀不同的阶段,使用不同的理财工具,相信一定可以在理财上一帆风顺。 通货紧缩的应对方法 通货紧缩是指经济中的物价总水平下降,货币价值上升,导致经济活动放缓,失业率上升等问题。 政府策略 以下是一些政府应对通货紧缩的方法: 货币政策:央行可以通过降低利率、增加货币供应量等手段来缓解通货紧缩,以刺激经济活动和消费。 财政政策:政府可以通过减税、增加支出等方式来刺激经济活动,促进就业增长。 扩大出口:扩大出口可以增加经济增长,提高国内生产总值,缓解通货紧缩。 加强监管:加强市场监管,防止价格垄断和不正当竞争,避免价格上涨过快。 促进技术进步:技术进步可以提高生产效率,降低成本,促进经济增长,缓解通货紧缩。 这些方法可以单独或组合使用,以应对通货紧缩所带来的经济问题。需要注意的是,不同的国家和地区可能需要采取不同的应对方法,具体应根据实际情况来制定措施。 个人策略 对于个人投资者,以下是一些应对通货紧缩的方法: 投资实物资产:在通货紧缩期间,实物资产的价格通常会上涨,例如不动产、黄金等。因此,投资者可以考虑将资金投资于这些实物资产,以保护其财富。 投资通胀保值产品:通货紧缩期间,货币价值上升,但物价下降,因此,可以考虑投资通胀保值产品,例如通货膨胀保护债券、实物商品等,以保护资产免受通货紧缩的影响。 投资高股息股票:在通货紧缩期间,股票价格可能下跌,但高股息股票通常会提供稳定的股息收入,可以帮助投资者抵御通货紧缩的影响。 减少债务负担:在通货紧缩期间,货币价值上升,债务负担也随之增加。因此,投资者可以考虑提前偿还高息债务,以减轻债务负担。 增加储蓄:通货紧缩期间,物价下降,储蓄的实际价值也会增加。因此,投资者可以考虑增加储蓄,以保护其财富。 需要注意的是,不同的投资者有不同的风险承受能力和投资目标,因此,应根据自身情况来选择合适的投资方式。同时,投资者应该密切关注经济形势和市场变化,及时调整自己的投资策略。 操作建议: 现金为王,减少负债,提前偿还负债 配置债券类产品。通缩周期内,将闲置资产尽量多地配置债券类产品,包括国债、企业债、债券型基金。但这是过去的说法,但自从债券改为净值计算价格,就再也不推荐购买债券了。城投,房地产债务违约周期不过去,就不推荐债券。 楼市等大宗商品建议抛售。大宗通缩,落袋为安,跑得慢的会被踩踏 黄金等贵金属可以适当持有 王朝周期律 对王朝周期律的总结,以及对个人和企业财务管理的相关建议如下: 王朝周期律表明,历史上每个王朝平均寿命约在150-300年之间,会经历成长、鼎盛、衰退的循环周期。 个人和企业都要认识到艰难时期的到来是必然的,要提前做好充分准备。 鼎盛时期,要压缩支出,积累资本以应对将来的衰退期。衰退期可以适当增加支出来刺激经济。 建立必要的财务缓冲,如存款准备金,以应对突发情况。同时也要持有一定实物资产,如房地产。 衰退期主动减持负债,降低财务杠杆;减少运营杠杆,适当裁员和减少固定支出。 扩张时不可过分举债和盲目投资,保持资本结构稳健。 调整投资策略。鼎盛时追求长期投资,衰退期保持资产流动性。 衰退来时要及时采取资产重组、停利、裁员等措施,确保财务安全。 保持优良的信用,可在困难时期获得外部支持。 未雨绸缪,做好应对风险的准备,是企业和个人非常必要的财务管理原则。 行业周期律 行业周期律的总结和对个人、企业财务管理的建议如下: 不同行业都存在着成长-繁荣-衰退-低迷的周期规律。每个周期约持续5-10年。 成长期要抓住机遇扩张业务规模,增加投资。但要防止过热扩张。 繁荣期要适度收紧财务,防止过度竞争和盲目投资。可以加大创新投入。 面临衰退要及时止损,减少资本开支,降低运营杠杆,适当裁员以控制成本。 低迷期应盘活资产,外寻出路,降低固定成本,开源节流。也是启动新计划的好时机。 个人应根据行业周期调整就业规划。成长期加入新兴行业,衰退行业则谨慎离开。 个人投资应顺应行业周期,成长期买入,衰退期卖出。不能盲目追涨杀跌。 企业要防止产能过剩,逆周期 effect对行业的破坏。要控制增长节奏,留足安全边际。 公司现金流要充裕,以应对周期下行时的资金链压力。衰退来时,要果断停止损失计划。 调整商业模式,防止行业转型期被颠覆。要及时转型或退场,不能墨守成规。 总之,了解行业周期规律,适时调整资本运作策略,对个人和企业都极为重要。 康波周期 对康波周期的总结及对个人企业的财务管理建议如下: 康波周期指经济活动中经历扩张和收缩的周期性波动。周期长度大约在3-5年。 周期包含扩张期、峰值、收缩期和低谷四个阶段。扩张期经济活动活跃,收缩期经济下滑。 个人应在扩张期储蓄以备收缩期可能出现的失业。收缩期则可适当消费刺激经济。 企业扩张期应谨防过度投资,留存资金应对未来收缩。收缩期应减少投资,降低成本。 收缩期个人和企业都应降低负债规模,积极偿还贷款,减少财务风险。 企业要建立适度的现金储备,以備不时之需;个人也应保持一定的现金储蓄。 个人可以适当增持防御性股票及固定收益类资产,降低市场波动对财务的影响。 扩张期可适当加杠杆操作,但要控制风险。收缩期应减杠杆,持股现金比例。 企业要提前规划应对收缩期的策略,如业务多元化等。个人也要思考多种收入来源。 综合判断经济趋势,及时调整资产配置策略。但不可盲目跟从,应控制风险。 债务周期 关于债务周期的总结和对个人企业的财务建议如下: 债务周期反映一个国家或地区债务水平变化的周期性模式。通常伴随经济扩张和收缩。 扩张期债务增长快速,到收缩期时无法继续偿还,导致违约风险积累。 个人应避免扩张期过度举债消费,收缩期则需积极减债还款。控制负债不超过收入的一定比例。 企业也需避免过度融资置换资产,严格遵守负债率标准。收缩期应减持资产偿还债务。 政府应抑制扩张期信贷过快增长,防止债务泡沫。并积极推进去杠杆政策。 债务人要提高资产负债表透明度,控制隐性债务。并持有足够现金作为备用资金。 债权人应审慎控制扩张期贷款发放速度,强化风险管理。收缩期则应对坏账损失提早计提。 个人要建立必要的应急储蓄基金,以应对收缩期失业等情况,保障基本生活需要。 企业要优化负债结构,适当采用长期固定债务,避免到期集中偿付压力。 积极培育和发展股权融资市场,是缓解债务周期影响的重要举措。 研究经济需要分析哪些东西? 房价 最重要的经济活动 政治 政治指导经济,但政治不是万能的 军事 军事地位决定政治地位,军事是政治的延伸 历史 太阳底下无新鲜事,一切历史都是现代史 地缘 地缘环境决定政治风格 人性 一切行为活动背后逻辑都是人性 楼市什么时候跌到位? 房价是土地,教育,医疗,等各种配套的综合体现,是居民消费的最大项,研究经济不研究房价就是白干! 楼市的刚需性将在 L3 自动驾驶实现之后消失!完全自动驾驶实现之日,就是楼市崩盘之日! 从历史发展来看,如果一种产品兼具刚需和可垄断这两条属性,一旦他称为财政工具,其价格必然涨到天际。例如古时候的盐,从春秋时期管仲搞垄断开始一直到清朝,价格就没便宜过。古代贩私盐就跟现代卖毒品似的,暴利且暴力。 为什么普通老百姓吃口盐要付出那么高的代价?盐肯定是不缺的,但是垄断制造了稀缺,加上盐的刚需性,自然而然就成了古代充盈国库的工具。 古代是盐,搁现代就是房子。 问题来了——既然这个逻辑无懈可击,为什么我还认为房价会跌呢? 因为现代的房子和古代的盐,固然都有刚需和可垄断的属性,但房子有一样 buff 是盐所没有的,那就是债务创造的功能,这也是房子比盐牛逼的地方。 但是有债务就一定有周期,债务周期是没法避免的。 债务周期的由来,达利欧的视频《经济机器是怎么运行的》讲得已经够穿透灵魂的了,总结一下: **1)**经济是由无数个交易构成的; **2)**在交易中,一个人的支出,是另一个人的收入; 3)借债可以增加支出,从而增加收入,形成经济增长的积极循环; **4)**借债,看似是从银行借钱,实际是向未来的自己借钱,意味着你未来要压缩支出,减少消费用以还债; **5)**还债周期到来时,支出下降,收入也下降,经济陷入消极螺旋; **6)**在上升周期,房子是资产红利;在下降周期,房子是债务陷阱。 这样的周期是没法避免的,任何经济体,只要依赖货币扩张/债务扩张来刺激经济,它就一定会发生债务周期。 债务周期又分长短,短周期大约五到七年一个轮回,每次都可以通过货币扩张制造通胀来稀释债务。 然而每一次都会使债务再上一个台阶,因为货币资金的本质依然是债务扩张,这就相当于用更高的债务去解决眼前的债务。所以扩张到最后就没法再扩张了,货币也就无法继续超发,这个时候经济就走到了长周期的末尾,这个周期大约是60到80年。 此处有两个问题需要解释清楚: 第一、凭什么说债务扩张到头货币就没法扩张了呢? 如果货币可以脱离债务背书,像大明宝钞一样,印出来直接用,那前面所说的全部逻辑,都是扯淡。 第二、凭什么认为现在就是一段长债务周期的末尾呢? 如果债务还能继续往上加,那再等下去岂不青春都要蹉跎了? 货币不能直接印?**无锚纸币最怕的就是通胀,那你还怎么制造通胀去消化债务呢?**只有债务货币可以制造通胀,所以几乎所有的国家用的都是债务货币。津巴布韦和委内瑞拉是债务摆烂了,所以货币变成了纸,类似剧情在魏玛时期的德国已经演绎过了,后果是很严重的。 再说第二个问题,我以前说**居民负债率达到70%就是极限,**也是房价上涨的极限。 这其实是个经验数据,是根据过去债务周期的数据估算出来的,这里跟大家讲讲我的逻辑。假设一个公司,债务扩张到头的特征是什么?是收入增长的预期没有了。 记住,这里看的是收入增速,而不是收入规模。 高收入增速,对应的是高增长预期,意味着高市盈率和高估值,那么资产可以匹配的债务规模就高。 一旦增长预期没有了,高市盈率就意味着高泡沫,然后在价值重估的过程中,债务被毁灭。 所以对于楼市来说,光管住房价是没用的,还得把收入一起管住。才能维持这个债务周期继续运行。 因为真正的资产不是房子,你看即使房子烂尾了银行也不慌,直到大家停止还贷,它才会紧张。这就说明房子不是资产,打工人的负债才是真正的资产。 更确切的说,银行真正在意的是打工人的持续还债所产生的现金流。 当当这个现金流开始不增长且不稳定时,债务别说扩张了,旧债的价值都变得不可信任,各种地产相关的债券、商票的价值下跌,就是证据。 另一个逻辑就是债务扩张的过程,一定会造成收入增速的下降。 因为**“债务创造货币➜货币制造通胀➜通胀稀释债务”的过程,会不断使债务流向打工人,使财富流向电梯人,其结果,**就是贫富分化。 而贫富分化一定会带来萧条,也就是生产性危机。 因为大量的社会中下阶层为债务所迫,必须要减少消费,由于一个人的支出是另一个人的收入……于是陷入衰退螺旋。 总之,债务驱动的经济,最怕的就是收入下降,然而债务循环的结构,又决定着收入一定会下降,收入下降就会使得泡沫破裂,进而引发债务周期爆发,爆发的后果救市无效,就会陷入经济衰退当中,衰退结束后又是一个新周期的开始。 这是个死循环,只要债务流向多数人,财富流向少数人的经济结构不变,它就无解。 而且由于债务的存在,其衰退过程不可能是温和的,就像多米诺骨牌,前面是一个接一个地倒,后面便会成片垮塌。更何况现在经济全球化,没有谁可以独善其身,外部一个接一个的黑天鹅事件,比如卡脖子、地缘战争等,都随时在威胁偿债信用。 所以不要整天喊着抄底房地产,只要债务周期带来的危机不落地,房价就不会见底。 房价继续涨的前提是债务周期危机已经落地,并且房子依然是财政工具。 但是如果房子不会继续作为下一个工具,那么什么能替代房地产呢?它必须具备的特点包括但不限于刚需可垄断和能创造债务,最好还能创造增长预期!符合这些条件的有哪些了? … 房地产螺旋下跌后什么时候才是真正的底部?中美斗争结束后才可能会涨! 中美芯片脱钩目前双方时间节点都定在2027年!这就可以预见就是在2027年之前不会爆发大规模冲突,双方都还在对峙准备阶段,都还没有做好全面热冲突的准备。中国的楼市,美国的债市都是地雷,双方什么时候爆都有可能,这又有一定的不确定性。双方真正倒下一个之后,剩下的那一个就会在死者尸体上获得给养,拆掉地雷,这时才会开启下一轮的新经济周期! 楼市本质是税收工具,通过银行借贷一次性收割未来30年的收入!是一种财富转移的顶层设计。房价涨跌财富不会消失,只是从负债人手中转移到地产银行家手中而已! 盐铁论 盐铁论(公元前81年)是西汉时期的一场重要辩论,主要涉及政府对盐铁专卖政策的争议。以下是对盐铁论的简要总结: 盐铁论是西汉时期(公元前81年)在长安(今西安)举行的一场著名辩论,主题围绕政府对盐铁专卖政策的争议。西汉武帝时期,为了筹措军费,政府实行了盐铁专卖政策,即将盐、铁、酒等资源的生产和销售权收归国有,通过垄断获取财政收入。这一政策在一定程度上增加了国家收入,但也引发了广泛的社会争议。 辩论的主要参与者包括支持政府垄断政策的御史大夫桑弘羊及其同僚,和反对垄断政策的儒家学者代表。他们分别代表了国家利益和民间利益的不同立场。 辩论焦点 财政收入与社会负担: 支持方(桑弘羊等):主张盐铁专卖政策能够有效增加国家收入,支持边疆防御和国家建设。 反对方(儒家学者):认为垄断政策增加了人民的负担,导致贫富差距扩大,违背了“仁政”理念。 经济发展与社会公平: 支持方:认为通过政府控制,可以更好地管理资源,促进经济发展和社会稳定。 反对方:主张应恢复自由市场,让民间自主经营,促进公平竞争,减少官僚腐败。 辩论影响 盐铁论不仅是关于经济政策的讨论,更是一次关于国家治理理念的深刻对话。辩论揭示了中央集权与地方自治、国家利益与民生福祉之间的矛盾,为后世提供了重要的思想资源和政策参考。 尽管最终盐铁专卖政策并未立即取消,但这场辩论显现出儒家思想在政治决策中的影响力,并促使后来的统治者在制定经济政策时更加注重民生与公平 什么东西能打败高房价? 高房价问题是全球许多城市面临的一个重大挑战。随着技术和社会的发展,以下几个因素有可能在未来有效缓解甚至打败高房价问题:自动驾驶、远程办公和核聚变带来的电力革命。此外,其他技术和社会变革也可能在这一进程中发挥重要作用。本文将详细探讨这些潜在的因素及其可能的影响,并总结出相关的细分创业机会。 下面方向都将是未来经济增长点,可以作为创业投资热门参考! 自动驾驶 自动驾驶技术的发展将改变人们的生活和工作方式,对高房价产生深远影响。 1. 通勤距离的变化 创业机会: 自动驾驶车队管理与租赁服务 通勤共享平台和应用 自动驾驶车辆的安全与维护服务 2. 城市规划和交通 创业机会: 智能交通系统开发 城市规划咨询与设计服务 偏远地区基础设施开发 3. 共享经济 创业机会: 共享自动驾驶汽车平台 车库改造和利用服务 城市土地再开发项目 远程办公 远程办公的普及已经在疫情期间展现出其潜力,并将在未来继续对住房市场产生重大影响。 1. 地理位置不再是限制 创业机会: 远程办公软件和平台开发 远程办公支持服务(如IT支持、设备租赁) 远程办公协作工具和应用 2. 城市功能的重新定义 创业机会: 商业地产再开发项目 混合用途社区设计与开发 远程办公社区和联合办公空间 3. 工作生活平衡 创业机会: 远程办公社区和村庄开发 偏远地区生活设施和服务 乡村和小城镇的现代化改造 核聚变带来的电力革命 核聚变技术的突破可能在未来带来廉价和无限的电力资源,深刻改变社会结构和住房市场。 1. 能源成本的降低 创业机会: 核聚变电力技术研发和应用 家庭和企业的能源管理服务 能源成本优化和咨询 2. 基础设施的发展 创业机会: 智能电网和电力基础设施开发 电动汽车充电站建设与运营 智能家居系统设计和安装 3. 可持续发展的推动 创业机会: 可持续建筑和社区开发 环保技术和解决方案提供 绿色能源项目投资和管理 其他可能的因素 除了上述因素,还有其他技术和社会变革可能对高房价产生重要影响: 1. 模块化建筑和3D打印技术 创业机会: 模块化建筑公司 3D打印建筑材料和设备供应 快速建造服务和项目管理 2. 城市农业和垂直农场 创业机会: 城市农业项目开发 垂直农场设计和运营 农业技术研发和应用 3. 政策改革 创业机会: 政策咨询和研究服务 保障性住房开发 房地产市场分析和投资顾问 结论 高房价问题是一个复杂的社会经济现象,需要多方面的综合措施来解决。自动驾驶、远程办公和核聚变带来的电力革命是其中具有潜力的变革因素。随着技术的进步和社会的发展,这些因素可能会共同作用,缓解甚至打败高房价问题,为人们创造更加宜居的生活环境。同时,这些变革也带来了大量的创业机会,为有志于解决高房价问题的创业者提供了广阔的前景。 投资理财 通俗地讲,所谓理财,本质上就是钱生钱的过程。理财有两要素:本金和收益,大家关注的重心在收益,计较于收益率的高和低,孜孜不倦寻找高收益产品,不经意间,忽略了本金的重要性。就像一个人不停地在数字后面加0,一直没发现0前面原来没有1。 资产与产出 资产 身体资产:体力,时间,健康,天赋 脑力资产:知识,技能。大脑收益远大于身体收益,读书非常重要 这两样人人都有,可以成为个人资本,本金是身体,大脑,时间,劳动。尽早完成原始积累,从个人基本收益转化为资本收益! 资本资产: 定活期存款,股票,债券,股权,大宗商品等等 国土资源: 土地,矿物,水电煤气等等 产出 劳动产出:上班,创业,务农 本金是身体,时间,劳动 资本产出:基金,债卷,房产,股份分红等 投资机会 那些年,你错过了那些一夜暴富的机会? 2001年机会:B股 2002年机会:商铺 2003年机会:住宅 2004年机会:开网店 2005年机会:股市 2006年机会:基金 2007年机会:艺术品 2008年机会:读MBA 2009年机会:黄金 2010年机会:比特币 2014年机会:融资 2015年机会:P2P金融 2016:直播 2018: 自媒体 投资方法 投资是反人性的 金融投资任何有效策略超过95%的人知道了,就必定失效!成功的投资者在其他人眼中都是傻子。 吃鱼只吃鱼身子 参见李嘉诚和融创在房地产,何时入场,何时离场,下场如何。 买基金只买牛市上升阶段!或者大势明确的版块被动指数基金! 老鼠仓,黑幕交易太多,规则永远比不上手段变化。做不到趋势判断就去买货币基金吧! 基金经理的本质是模拟盘,输了自己不赔钱,赢了赚大钱!所以不建议购买基金,被动指数基金可以考虑! 只做大趋势明确的右侧交易,并严格止损止盈! 敬畏市场,市场是不可预测的。要有明确的止损止盈线及策略。得之我幸,失之我命! 只做自己懂的市场 凭运气挣的钱,早晚会凭实力亏回去!没实力理财,就去买银行定期存款! 不同资产额度,不同理财方法 年轻,没资本,认真上班就是最好的投资。 年轻人,投资认知,投资知识,投资身体更重要。 不同年龄,家庭结构,不同理财方法 资产对冲 黄金和美元就是一对对冲资产,一个涨,另一个一般都会跌。一样持有一部分可以对冲市场变化的风险来实现保值增值。 机会给给有准备的人的 没有谁能平白无故成功,机会来了,你准备好了么? 作为一个优秀的猎手,平时要仔细钻研各种狩猎技巧,修养,蛰伏,耐心等待猎物的来临。到时候一击命中,满载而归,运气好,一辈子,一次机会就够了! 加入泡沫,在泡沫破灭之前跑出来 最大傻瓜游戏,也是高收益的游戏。不赚最后一个铜板,吃鱼身子,不要吃鱼尾! 投资标的 风险由小到大 身体 健康,健身,保健品,食品。习武、穷文富武 大脑 各种专业技能,文学艺术 现金 银行活期,定期 基础入门投资品种 黄金 乱世黄金,盛世一般只有保值功能 古董、文玩 盛世涨价,乱世可能一文不值 货币基金 外汇 指数被动基金 最近发现国内ETF指数基金居然搞转融通证券出借!基金经理出借自己持有的股票,做空砸自己的基金!投资者花钱买石头砸自己的脚,又一奇闻!建议清空所有ETF指数基金 股票主动基金 对于基金经理来说,做个老鼠仓,亏掉一半,拿10%的回扣容易;还是辛辛苦苦赚10%,拿1.5%的管理费容易?想清楚这个就明白为什么基金总是高位接盘,跌跌不休了。除了大牛市时期,主动型基金基本没什么价值。 大宗商品 各种大额动产,不动产房产,等 股权 期货 中国房地产行业简略分析 结合以下因素: 中国独生子女政策的开始,到放开 中国出生率断崖式下跌,2023年出生率1.06,几乎是世界最低(碧桂园大量四五线房产没人要,破产在某一方面可以解读为和年轻人对赌失败,年轻人在各种重压之下成为四不青年,不结婚,不生育,不买房,不消费) 房地产债务偿还周期,大部分债务2023年集中到期 恒大,碧桂园等大部分头部放弃开始破产,暴雷 中美竞争冲突愈演愈烈,经济制裁,贸易战,芯片制裁,军事冲突(台湾等地球)等背景 新冠病毒全球冲击,后续病毒变种冲击。以及漂亮国研发更厉害的病毒病扩散的预期 中国现在到了必须做出保汇率还是保房价的选择的时候了,从各种政策来看,是保汇率,保制造业产业,放弃房价了 、、、 可以得出结论,房地产2022年到顶,2023年房地产已经完全转向,开始加速向下走! 以前房产涨,超出想象。以后房产跌,也会超出想象!超涨超跌是经济运行的必然规律! 政策 文件 时间 影响力 具体影响 引入房地产市场化改革 《国务院关于深化城镇住房制度改革的决定》 1992年 巨大 结束福利分房,房地产成为商品 取消房产税 《国务院关于房地产税制改革的决定》 1998年 较大 刺激房地产消费和投资热潮 减免契税 《国务院关于促进房地产市场持续健康发展的通知》 2003年 中等 降低购房门槛,刺激需求 取消住房配给制度 《国务院关于解决城市低收入家庭住房困难的若干意见》 2005年 较大 实现住房全面商品化 遏制投机性需求 《国务院办公厅关于坚决遏制部分城市房价过快上涨的通知》 2010年 中等 调控市场过热 限购限贷 《国务院关于继续做好房地产市场调控工作的通知》 2011年 较大 直接抑制购房需求 调整房贷政策 《住房城乡建设部等关于调整住房信贷政策的通知》 2016年 极大 严控购房杠杆率,重创房地产市场 “三道红线” 《住房城乡建设部办公厅关于印发<<房地产金融公司风险分类监管办法>>的通知》 2020年 极大 限制房企融资,降低开发 “房住不炒” 《住房城乡建设部关于针对重点地区因城施策促进房地产市场平稳健康发展的通知》 2022年 较大 试点普通住房,调整政策 “保障性住房” 8月25日国务院常务会议审议通过的《关于规划建设保障性住房的指导意见》(简称“14号文件”) 2022年 较大 推行新加坡模式 一是:加大保障性住房建设和供给,“让工薪收入群体逐步实现居者有其屋,消除买不起商品住房的焦虑,放开手脚为美好生活奋斗”; 二是:推动建立房地产业转型发展新模式,让商品住房回归商品属性,满足改善性住房需求,促进稳地价、稳房价、稳预期,推动房地产业转型和高质量发展。 注:以上是从1990年到现在的大概总结,分析时间2023年年中 经济未来 正负方向分析 负面影响因素 俄乌战争 逆全球化 新冠长期肆虐 房地产债务周期 美元、日元债务周期 基因病毒武器 中美进一步冲突,脱钩!目前双方时间节点2027! 正面影响因素 深度学习革命:算力,算法,数据 云计算 5G、6G:高带宽,低延迟场景的落地 Web3.0:又将是一次对互联网的重新洗牌 车联网:对传统制造业的大清洗 物联网:芯片,OS底层开发需求大涨 3D 打印:高端制造变革 VR 区块链应用: 数字货币、国际结算 芯片OS革命:中美芯片二分,鸿蒙对抗Android 每个行业都不一样,具体到某一个场景需要具体情况具体分析 人口老龄化的机遇与危机 人口老龄化的机遇 银发经济的崛起 老年人口增加,对衣食住行、医疗保健、娱乐等方面产生新的需求 医疗保健和养老服务业机会 老龄人口对医疗和养老服务需求激增,相关行业将获得发展良机 刺激创新和技术发展 应对老龄化,需要在医疗、生活辅助、社区服务等领域不断创新 人口老龄化的危机 劳动力短缺 老年人口增加,工作人口比例下降,可能导致劳动力匮乏 医疗保健成本上升 老年人患病率高,医疗费用将大幅增加 财政压力加大 养老金、医疗保险等社会保障支出将持续增长 社会养老保障制度面临挑战 现有制度可能无法为不断增长的老年人口提供足够保障 个人应对措施 制定长期理财计划 培养终身学习的习惯 保持良好的生活方式 做好老年生活准备 企业应对措施 改革人力资源政策 提高劳动力素质 开发老年友好型产品和服务 与政府合作,共同分担责任 人口老龄化带来诸多挑战,但也孕育着新的机遇。个人和企业都应提前作好应对准备,政府也需出台相应政策,三方通力合作,才能较好地化解危机,抓住机遇。 相关书籍 人物介绍: 温铁军,绝少有的讲真话的专家。除了一个巴掌能数得过来的,其它吹牛逼的经济专家连翟山鹰都不如,都是些拿钱说话的。 人物介绍: 卢麟元,少有的敢为人民说话的经济学家 人物介绍: 翟山鹰,是个罕见的仗义执言的骗子,更是个负责任的演员。吃骗子的饭,砸骗子的锅。从相关视频演讲来看,比那些只会套话,谎话的经济砖家敢讲,敢说多了!虽然是个骗子,但是讲了非常多干货!看他的视频,比看那些所谓XX经济教授能学到的多得多。 全球化与国家竞争:新兴七国比较研究 见字如晤 书名: 全球化与国家竞争 作者: 温铁军等 出版年份: 2020-12 评分: 8.8 八次危机:中国的真实经验 读懂中国近代经济发展密码必看之作 有个续作 《温铁军:经济危机及其应对政策的国际比较(十次危机)》 见字如晤 书名: 八次危机 作者: 温铁军等 出版年份: 2013-1-1 评分: 9.0 通往奴役之路 见字如晤 书名: 通往奴役之路 作者: 弗里德利希・冯・哈耶克 出版年份: 1997-08-01 评分: 8.8 资本论 见字如晤 书名: 资本论(全三册) 作者: [德]马克思 出版年份: 2009-4 评分: 8.8 血酬定律 见字如晤 书名: 血酬定律 作者: 吴思 出版年份: 2003-08 评分: 8.2 后记 Q/A: 对上文部分问题的解答 Q1: 勤劳致富 A1: 勤劳致富是这个世界最大的谎言,是缓解loser们焦虑情绪的一味安慰剂。 富人致富,依靠的可以是资源,可以是才智,也可以是投机思维,也可能是作弊,但反正不是勤劳致富。 全世界都在说一个慌:就是辛勤劳动,才能获得丰厚回报,回报是与你的付出成正比的。这是个巨大的谎言,从经济原理来说,收益回报取决于相应的投资,而不是劳动。读书固然可以单纯的看做学习知识,但从经济上来看,是人力资本的投资。所以收益极大的依赖于两点,一个是资本的大小,一个是相应行业的投资回报率。当然即使在同一个行业,也会有做的好坏,做得好的赚多一点,做的差的,赚少一点。但不会有太本质的差别,一个整体亏损的行业,做的再好,也还是要亏,一个暴利的行业,随便做做就能赚大钱。而富人相比穷人,最大的优势,就是具有更多的资本,虽然风险更大,但收益也远高于穷人。说白了,富人为什么能轻松挣那么多钱,不是因为他们比穷人更勤奋,更努力,更有能力,而是因为他们本来就比穷人钱多。所以真要想赚大钱,不要相信,那些让你卖力工作的谎言,因为大多数工作,就是让你用时间精力换钱,对你的资本积累没有任何帮助。而最能赚大钱的项目,就是资本运作,把现有的一些资本,通过各种渠道变现,获得巨额的回报。当然,在这之前,你先得积累起足够的资本,这些资本,可以是人脉的,可以是名声的,也可以是种种消息源。所有东西都可以成为资本,但想要变现,就不是那么容易了,这就需要眼光头脑和能力了,以及最重要的运气。 Q2: 早买早享受,消费主义 A2: 富人越来越富,穷人必然越来越穷,或者相对更穷,社会大众并没有认识到这个问题,大家都沉浸在盛世喜悦中,在比拼消费,比拼各种不必要的浪费,认为你看我的生活多么精致,年轻人普遍认为自己可以长期保持收入上涨,忽略自己会年老体弱的现实,底层人普遍认为自己享受就好,家族不需要积累,儿女自有儿女福,而忽略了富人大部分是家族几代人的努力积累造就的。贫富差距为什么越来越大,富人为什么越来越富,而穷人则相反,不要告诉我是勤劳,能力,运气。因为政治课已经告诉过你,资本主义贫富差距拉大是因为富人占有生产资源,最重要的生产资源是资本,是钱。富人在不断积累资本的时候,穷人却生活在,各种攀比中,他们劳动得来的钱大部分花在智商税上。这就是穷和富之间最大的鸿沟。有人说我只是花6000元买个苹果手机啊,这算多吗,富人恐怕6万也不眨眼。可是穷人忽略了金钱的边际效应。比如你刚参加工作不久,存款只有一万元,这时你买个苹果手机,就相当于直接剥夺了你投资的机会,学习的机会。而如果你这时就用这一万来进行投资,当你存款达到十万时,你已经有了比较丰富的投资经验,当你有一百万,再买苹果,就是锦上添花,几乎不影响你的投资,深造,等等。有人说,我就想当渔夫,乐天知命。没什么不好,这也是一种生活态度,但你千万别找个和你态度不同的伴侣,当你们看着别人家轻松拿出几十万供孩子出国学习,而你们恐怕正在为教育问题争吵不休。资本金钱是如何成为最重要的资源的,我们可以假想一个例子,同样工作十年的两个人工资假设都是5000,a的工资大部分用作消费,苹果必须标配,还有各种精致的生活需要不少投入。b的呢,从第一年开始就有了存款,开始进行理财,省吃俭用,十年下来有了50万存款,这时他的投资经验大概是年华收益率12%,b除了工资每年6万,又有了6万的额外收入。这年收入是不是已经完爆a,12%难吗,说实话需要一定经验,但真的不是比微积分还难。今年打新股平均收益率20%,前提是你要有那50万啊,从这开始,富人越来越富了,对吧。更神奇的是,当你一年工资达到20万,你认为自己是白领高薪了,再看看人家,200万资金年收益12%,24万了。不要以为自己工资低就不需要投资,不要以为不需要投资所以挥霍无度。因为金钱是唯一富人更富的原因,也不要以为自己可以当渔夫,事实证明,大部分渔夫是被逼无奈。年轻人不要被工业大时代的消费风潮迷惑,那只是资本家为你编制的精致生活的骗局,请相信我,提高职业收入的同时一定要节约,并提高投资水平,第一个十年积累资本,第二个十年资本收入替代职业收入,第三个十年,你将是同龄人里的翘楚,不但自己可以精致生活,还可以让你的家人都轻松精致。 Q3: 2000年以来的楼市到底是个啥? A3: 供楼这种商业模式是对国家和人民残酷的掠夺。供楼在经济学上的含义,实际上是一种预征税负,对平民是掠夺,但对富豪的含义是提前套现,它实际上是一种造富机器。当错误的经济正常和错误的土地政策相匹配的时候,任何一个富裕的经济体,都可以在10年左右垮了。 香港就是典型例子,供楼其实是英国殖民者为了套现香港财富,而精心定制的策略。83年香港有4万家企业,当时很多前世界排名靠前的企业,但是83年中英谈判之后错误的判断,香港开启了一场莫名的造富运动,赢家不是大家熟知的李嘉诚,而是英资,他们持有香港最好的土地资源,这场造富运动,使得英资顺利的在80年代从香港拿走一万亿磅回英国,完成英国的撒切尔主义经济学,撒切尔主义就是英国的私有化运动,私有化运动挽救了大英帝国的崩溃 供楼这种商业模式是对国家和人民残酷的掠夺,预支税负,是对子孙极不负责任的一种状态。我国的中产阶级尚未富有,就重新沦为贫困,六个钱包变为百万亿财富,这些财富大部分在走资派手中,这些走资派如果成功完成资产转移,我们几十年改革开放辛苦劳动的成果,还有未来几十年楼市负债财富,全都被掠夺一空,中国将成为第二个日本,甚至比日本更惨 ​ ——整理自 卢麟元 Q4:个人奋斗与社会奋斗的区别 A4:真正的马克思主义者后者一个真正的社会主义者,是不主张个人奋斗的,是主张社会奋斗的。 个人奋斗,极为聪明,甚至夹杂一些自私自利,或者是一些邪恶进去,可以在这个社会上生活的很好。因为因为你只要看到了资本的本质和资本运行的规律,你可以成为在整个恶性竞争中的一个胜利者,,千万不要让老百姓认为搞资产泡沫中金融投机的人是股神是超人,是英雄,不是,他们是这个社会里边的害虫,甚至他们都是小丑,是垃圾 ​ ——整理自 卢麟元 Q5:学校为什么从来不叫我们赚钱? A5:因为学习(学校)的目的并不是为了培养人才,而是为了向工业化输出大量的劳动力。统一的课本,统一的升学标准,你学的那些东西其实都是为了让你变成了90%的一部分。工资,只是奴化人性的一种手段。当你接受了工资的概念那一刻起,你的思维就已经被套上了枷锁。 Q6: 房地产的本质是什么? 房地产的本质是对公共资源的私有化,以及对年轻人未来的折现! 为什么是折现的是年轻人的未来? 因为老年人没有未来呀。 再有,什么叫公共资源? 就是那些本应该由大众公平享受的经济资源。 比如老王有一套房子,原本价值200w,后来楼下修了条地铁,房价涨到了400w。 地铁谁修的?公共财政修的,但老王享受了这里面的溢价和便利。 如果小王也想要这一份公共便利,他必须付出更高的成本,一部分付给老王,一部分流向政府。 小王和老王理应有平等机会享受公共服务,何以小王支付更高的成本,而老王却获得超额收益? 这是因为地铁基建带来的公共资源,有一部分,通过房价上涨的方式,被老王给私有化了。 同理,大城市的产业资源、就业机会、升学机会、发展机会,本应是全民共有的公共资源,最终也以房价房租的形式,私有化给了一小部分人。 你想要获取这些资源,必须向他们支付高房价、高房租。 所以为什么会有人鼓吹高房价,鼓吹救地产?说白了,他就是想通过控制房子,间接私有化周边的公共资源和发展机会——年轻人挣扎着向里面每走一步,都要给他们交钱。 庞大的房地产财富链条,培养出了一大堆的既得利益者,这些人都在想方设法的阻碍房地产价格正常回归。房地产四大既得利益集团,地方政府、银行、房地产公司、炒房客。从最小的炒房客打砸售楼部,房地产公司大量烂尾,不负责任,银行对提前还贷的阻扰和对降息的不情不愿(银行降息是被央行强压下去的,不是银行自愿的)。现在最大的阻力,就是地方政府了。这也是最难啃的一块骨头。毕竟大搞信贷扩张,推动城市建设的,本来就是财政部,现在想让地方政府收手,那么多的地方债务,那么多依赖城市工程发财的大小公司,那么多拿惯了高工资高福利的公务员群体,哪有那么容易就听话的。 金融是一个相对虚幻的概念,主题太大,难免遗漏,错误的地方,可以留言指出。 投资是一个长期坚持和修炼的过程,本文也将长期修改更新! 本文,算是夜法之书博客目前所有博文中最有价值的一篇文章了,愿大家入宝山满载而归! 投资是非常主观的事情,盈亏自负!别人顶多给建议。有不同观点,也可以留言指出。 参考&致谢 https://www.zhihu.com/question/35540121/answer/150001783 https://www.zhihu.com/question/35540121/answer/122175313 https://www.zhihu.com/question/383770080/answer/2723311867 新一轮人口家庭发展状况调查启动,将全面分析不想生、不敢生原因,预计会有哪些原因? 还有一堆资料找不到来源出处了,留言添加 附赠: 让你顾全大局,你肯定是局外人 让你不惜代价,你就是那个代价 一件事鼓励你去做,那是让你去做炮灰 一件事禁止你做,那是人家想独吞好处 凡是说是为你好,其实都是为他自己 凡是鼓励你做的事,那是有坑需要你去填 凡是禁止你做的事,那是有好处却不想分享给你 凡是说你放心吧,下次一定考虑你,那下辈子都不会考虑你了 凡是说“大家说你不行,不对,不合适”,就是领导在说你不行、不对、不合适 凡是从“画饼”开始的,都会以“卸磨杀驴”告终 凡是突然强调规矩的,都是以惩罚做准备;凡是突然营造人情的,都是准备给亲信开拓或为提拔亲信创造舆论 要你眼光放长远,这次好处肯没你 说下次考虑你,下辈子你也没戏 说对事不对人,他就是对人,而且还是对你 说大家对你有意见,就是他对你有意见 说有意见尽管提,他是想看谁对他有意见

2022/10/23
articleCard.readMore

关于普朗克概率的的讨论

存在最小的普朗克时间和普朗克长度,那么,在真实世界中,是否会存在一个“普朗克概率”?这个最小概率应该是存在的! 黑体辐射与普朗克 德国物理学家在研究黑体辐射的时候,发现能量变化是非连续的,进一步发现时间,空间都是非连续的! 这个能量,时间,空间非连续具体是个啥? 黑体辐射并不像管子中的流水那样,遵守经典物理学的“能量连续规律”,而只能是不连续的,是一个最小的能量整数倍跳跃式的变化,就像机关枪里不断射出的子弹。这个最小单位的能量被命名为“能量子”。“量子”在拉丁文里是“分立的部分”或“数量”的意思。 如果用 E代表“能量子”, 就可列出十分简洁的公式: E=hv。 h被称为“作用量子”,后来也被称为普朗克常数(其值为6. 625×10-34焦耳·秒)。 v是频率(波长的倒数)。 这个概念就是现代量子物理的开端!虽然这个理论最开始给普朗克带来了非常大的批评与攻击! 概率与普朗克 概率是对随机事件发生的可能性的度量!为数学概率论的基本概念;几率值是一个在0到1之间的实数,也可以用百分数来表示! --定义来自widipidea 事件的发生必定是发生在特定的时间,和空间里面的! 那么 F(概率)=F(时间, 空间) 事件发生概率函数是时间和空间的函数,时间和空间都不是连续的,那么作为时间和空间函数的值的概率事件,必定也是不连续的! 既然不是连续的,那么就有一个最小变化值,类比普朗克时间、普朗克空间,普朗克能量,可以称之为普朗克概率! 小于这个普朗克概率的事件必定不可能发生! 普朗克概率具体大小 事件发生的必定是在特定的时间,空间,并需要一定的能量。那么 普朗格概率 >= 普朗克空间 x 普朗克时间 x 普朗克能量 这个值虽然足够小,但是依然远大于0,概率的发生同样是不连续的! 无限猴子打字机与概率 无限猴子定理的表述如下:让一只猴子在打字机上随机地按键,当按键时间达到无穷时,几乎必然能够打出任何给定的文字,比如莎士比亚的全套著作。 字符串越长,数学概率越小。当文章长度超过一定长度,概率小于普朗克概率的时候,这种时间发生概率纯粹数学上不为零,但实际上,现实生活中已经不可能发生了! 莎士比亚的文章长度,虽然是有限的,但长度已经足够长,以至于其发生概率大概,约莫是一个非常非常小的数值!这个数值应该的确是一个小于普朗克概率的数值了。 所以什么无限猴子实验就是谬论,这个谬论只有在时间和空间都是连续的情况下才会发生! 普朗克概率与泳池中的钟表 把一个机械表拆成零件,丢入一个泳池,泳池晃动最后把机械表组装好的概率是多少? 普朗克概率与生命 生命的诞生已经是一个确定事实!但是目前主流理论生命靠自然闪电,海底火山自然演化的理论不一定正确或者说不一定完善! 生命太过于复杂和精密,以至于自然生成的概率极小!很可能已经小于普朗克概率了! 参考&致谢 概率 无限猴子定理 黑体辐射 系列教程 全部文章RSS订阅 AI系列 AI 分类 RSS 订阅 深度学习之视频人脸识别系列 中国区注册ChatGPT并使用全流程图解教程 关于普朗克概率的的讨论 信用卡对个人、社会以及国家的影响——ChatGPT辅助编写 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2022/10/6
articleCard.readMore

那些有用的Github工具介绍!Action、app、workflow等

Github Actoins 是 GitHub 推出的持续集成 (Con­tin­u­ous in­te­gra­tion,简称 CI) 服务,它提供了配置非常不错的虚拟服务器环境,基于它可以进行构建、测试、打包、部署项目。是CICD的强力工具! 本文介绍几个常用的极为有用的Action工具! GitHub Actions 是什么? 大家知道,持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等。GitHub 把这些操作就称为 actions。 很多操作在不同项目里面是类似的,完全可以共享。GitHub 注意到了这一点,想出了一个很妙的点子,允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用。 如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,整个持续集成过程,就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。 GitHub 做了一个官方市场,可以搜索到他人提交的 actions。另外,还有一个 awesome actions 的仓库,也可以找到不少 action。 上面说了,每个 action 就是一个独立脚本,因此可以做成代码仓库,使用userName/repoName的语法引用 action。比如,actions/setup-node就表示github.com/actions/setup-node这个仓库,它代表一个 action,作用是安装 Node.js。事实上,GitHub 官方的 actions 都放在 github.com/actions 里面。 更多 Github action 介绍 awesome-actions Github Action 使用限制: 官方文档:使用限制、计费和管理 在复刻公共仓库时,默认情况下将禁用计划的工作流程。 在公共仓库中,当 60 天内未发生仓库活动时,将自动禁用计划的工作流程。 每个仓库只能同时支持20个 workflow 并行。 每小时可以调用1000次 GitHub API 。 每个 job 最多可以执行6个小时。 免费版的用户最大支持20个 job 并发执行,macOS 最大只支持5个。 私有仓库每月累计使用时间为2000分钟,超过后$ 0.008/分钟,公共仓库则无限制。 Github 仓库与上游自动同步 保持自己github的forks自动和上游仓库同步的 信息来源于 https://github.com/wei/pull 只同步默认分支的教程 当上游的仓库仅有一个默认分支。或者上游仓库有两个分支,我们仅需要同步他的默认分支,其他分支对内容对我们来说无关紧要。 a) 登录自己的github账号,另开网页打开 https://github.com/wei/pull b) 点击Pull app进行安装。 c) 安装过程中会让你选择要选择那一种方式,All repositories(就是同步已经frok的仓库以及未来fork的仓库),Only select repositories(仅选择要自己需要同步的仓库,其他fork的仓库不会被同步),根据自己需求选择,实在不知道怎么选择,就选All repositories;点击install,完成安装。 d) 后续,如果要调整1.c中的选项,打开 https://github.com/apps/pull ,点击Configure,输入github密码进入pull的相关设置。 e) 进入后,找到Repository access,根据自己的需求,重新选择:All repositories(就是同步已经frok的仓库以及未来fork的仓库),Only select repositories(仅选择要自己需要同步的仓库,其他fork的仓库不会被同步),Save后保存生效。 f) Pull app作者虽然在项目中写道keeps your forks up-to-date with upstream via automated pull requests,但当上游仓库有更改时,自己的仓库会在3个小时内完成与上游的同步,3个小时是Pull app作者说的最长时间。当然也可以通过手动触发同步上游仓库,手动触发方式:https://pull.git.ci/process/你的GitHub名字/你的仓库名字 (例如:https://pull.git.ci/process/xxxxx/test ),手动触发可能会进行人机验证,验证通过后会显示Success。 同步其他分支的教程 a) 假设你fork了上游仓库后,你fork后的地址为 https://github.com/你的仓库名字/test ,首先设置完成第1部分内容,注意在1.c步骤没有设置全部同步的,要回到1.e步,确认是否设置同步了 你的仓库名字/test,如果没有,请添加上。 b) 在默认分支下添加一个文件。 c) 复制 .github/pull.yml 粘贴后看到以下页面,注意github前面的那个.别漏掉了。 d) 请在https://github.com/wei/pull\#advanced-setup-with-config 页复制代码, 注意:upstream处要修改为上游仓库作者名字。 e) 最终的示例如下,假设上游作者是zhangsan,所有的注意点都用红线圈出来了,保存后生效。 f) Pull app作者虽然在项目中写道keeps your forks up-to-date with upstream via automated pull requests,但当上游仓库有更改时,自己的仓库会在3个小时内完成与上游的同步,3个小时是Pull app作者说的最长时间。当然也可以通过手动触发同步上游仓库,手动触发方式:https://pull.git.ci/process/你的GitHub名字/你的仓库名字 (例如:https://pull.git.ci/process/xxxxx/test),手动触发可能会进行人机验证,验证通过后会显示Success。具体见1.f提供的图片。 g) 本人仅测试过forks一个仓库只有2个分支的项目,如果有多个分支,不能保证是否可行,请自行测试,或者是使用本教程第3部分高级玩法。 高级玩法 当然,作者还有其他更好的项目用于同步所有分支,例如使用 GitHub actions 进行同步。请参考原作者的项目 https://github.com/wei/git-sync https://github.com/repo-sync/github-sync Github 自动合并 PR renovate renovate 使用文档 自动合并 自动合并example renovate.json { "extends": ["config:base"], "assignees": ["17lai"], "separateMinorPatch": true, "packageRules": [ { "updateTypes": ["minor", "patch"], "automerge": true, "automergeType": "branch" } ] } mergify mergify 开源项目这个工具是免费使用的! 使用 Github Dependabot 自动更新依赖版本 通过将配置文件检入仓库,可启用 Dependabot 版本更新。 配置文件指定存储在仓库中的清单或其他包定义文件的位置。 Dependabot 使用此信息来检查过时的软件包和应用程序。 Dependabot 确定依赖项是否有新版本,它通过查看依赖的语义版本 (semver) 来决定是否应更新该版本。 对于某些软件包管理器,Dependabot 版本更新 也支持供应。 供应(或缓存)的依赖项是检入仓库中特定目录的依赖项,而不是在清单中引用的依赖项。 即使包服务器不可用,供应的依赖项在生成时也可用。 Dependabot 版本更新可以配置为检查为新版本供应的依赖项,并在必要时更新它们。 以上内容来自 GitHub 官方文档,简单的讲 Dependabot 就是一个没有感情的依赖更新机器人,在您的项目所依赖的上游软件包或应用程序发布新版本后,它会在您的 GitHub 仓库自动创建一个 PR 来更新依赖文件,并说明依赖更新内容,用户自己选择是否 merge 该 PR,效果如下图: 开启 Dependabot 开启方式比较简单,仅需将 dependabot.yml 配置文件放入仓库的 .github 目录中即可开启。之后 Dependabot 就会自动提交 PR 来更新您项目中的依赖项了。您也可以在 GitHub 页面上进行操作,在仓库页面通过 Insights -> Dependency graph -> Dependabot -> Enable Dependabot 路径即可开启,之后就可以点击 Create config file 来创建配置文件了。 配置完成后,即可看到需要监控的依赖文件和上次检查更新的时间。 配置 dependabot.yml 文件的配置也相对较为简单的直接,version、updates、package-ecosystem 、schedule 是必填的,还可以配置 registries 来指定私有仓库地址及认证信息。下面这个是官方示例,该示例中为 npm 和 Docker 配置了依赖自动更新,同时指定其依赖文件的地址和更新频率。有意思的是,在下面这个示例中,如果 Docker 依赖项已过时很久,可能会先执行 daily 安排,直到这些依赖项达到最新状态,然后降回每周安排。更多内容,可以参考官方文档。 # Basic dependabot.yml file with # minimum configuration for two package managers version: 2 updates: # Enable version updates for npm - package-ecosystem: "npm" # Look for `package.json` and `lock` files in the `root` directory directory: "/" # Check the npm registry for updates every day (weekdays) schedule: interval: "daily" # Enable version updates for Docker - package-ecosystem: "docker" # Look for a `Dockerfile` in the `root` directory directory: "/" # Check for updates once a week schedule: interval: "weekly" 支持的包管理器 目前 Dependabot 支持很多包管理器,具体内容可以参考下表: 要用于 dependabot.yml 文件中的 YAML 值 支持的包管理器版本 是否支持私有 GitHub 仓库或注册表中的依赖项 是否支持供应的依赖项 Package manager YAML value Supported versions Private repositories Private registries Vendoring Bundler bundler v1, v2 ✓ ✓ Cargo cargo v1 ✓ ✓ Composer composer v1, v2 ✓ ✓ Docker docker v1 ✓ ✓ Hex mix v1 ✓ elm-package elm v0.19 ✓ ✓ git submodule gitsubmodule N/A (no version) ✓ ✓ GitHub Actions github-actions N/A (no version) ✓ ✓ Go modules gomod v1 ✓ ✓ ✓ Gradle gradle N/A (no version) ✓ ✓ Maven maven N/A (no version) ✓ ✓ npm npm v6, v7 ✓ ✓ NuGet nuget <= 4.8 ✓ ✓ pip pip v21.1.2 ✓ pipenv pip <= 2021-05-29 ✓ pip-compile pip 6.1.0 ✓ poetry pip v1 ✓ Terraform terraform >= 0.13, <= 1.0 ✓ ✓ yarn npm v1 ✓ ✓ 更多内容可以参考官方文档。 Gitlab 镜像 Github 这个功能需要 gitlab ee 版本,CE版本是不支持镜像的 个人用户可以参考 破解Gitlab EE 企业用户去付费买授权 Github 仓库备份 最优秀的资源,大多只在短时间内出现! 平时多备份你重要的仓库,以及你使用的仓库的重要上下游仓库! github-backup Githb github-backup Dockerhub githubback: image: lnxd/github-backup container_name: "githubback" hostname: githubback # ports: # - "80:80" volumes: - "${USERDIR}/githubback/data:/home/docker/backups:rw" env_file: - .env environment: - HTTP_PROXY=http://[ip]:[port] - HTTPS_PROXY=http://[ip]:[port] restart: always 自动翻译 实例 GitHub Action https://github.com/walinejs/waline/blob/main/.github/workflows/issue-translator.yml 源码 https://github.com/lizheming/issues-translate-action 基于 https://github.com/dromara/issues-translate-action 后记 github action 太多强大,这里仅仅只能介绍一点点,有太多好东西了,太多宝藏值得去挖掘! 这就是开源的力量!在被大公司白嫖的同时,创造了无与伦比的社区生态! 参考&致谢 GitHub Actions 入门教程 使用 Github Dependabot 自动更新依赖版本 GitHub Actions 入门教程 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/10/2
articleCard.readMore

Potplayer终极优化教程实现PC视频播放最强画质

视频播放器使用还是有不少细节需要注意的。本文介绍流行播放器Potplayer 配置方法,搭配 Emby 和 embyLaunchPotplayer 使用的效果更佳! 推荐本文搭配使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程观看 本文最近全新整理增强了一遍 前言 这年头一款趁手好用的播放器,功能强大的播放器是必需的,目前几乎所有视频播放器其实只有三种:MPC-HC、Mplayer、VLC player,其余可以理解为各种壳各种定制版各种修改版。(potplayer的前身km是基于MPC),其中MPC-HC已经内置了LAV Filters,不过Potplayer可定制项更多,更有可玩性,因此选用Potplayer进行搭建目前公认最完美的高清方案显然是Potplayer(主播放器)+LAV Filters(分离器)+madVR(渲染器)+xy-VSFilter(字幕滤镜),当然这个所谓的最完美方案是严重高能耗的一个方案,就我个人而言一直觉得性质比不佳,但这基本上是你已经是能找到的最完美的高清方案了。 不想怎么折腾的朋友,直接使用播放器和默认设置就好了;要求再高一点的朋友,添加LAV Filters+madVR+xy-VSFilter进播放器,然后也不需要去配置参数,默认就好;发烧友们想自学高级播放器设置,网上教程总是不缺的,一搜一大堆,各大论坛什么的置顶帖,万年冷冻库,等等,写的比本文更新、更详细、更高端的比比皆是,也都可以作为很不错的教程。不过其中有些教程过于专业详尽,又或者只是授人以鲤,或者授人以鳊、鲢、鳙……,导致很多人直接傻眼了。现在网上林林总总的教程,不会跟你说的很多细节与知识。有的人madVR设置玩出了花,结果不知道检查pot内置的ffmpeg解码器,会把YUV420 10bit 降低精度+瞎转换 为YUV422 8bit丢给madVR,然后又说自己看不出区别……这折腾的意义何在呢。所以首先提出几点建议: 1、实事求是。不要盲目的去折腾,也不要为了心理安慰去折腾。一套更好的方案,只有你确实感觉到了提升,并且这个提升在你心理满意度上,足够抵消麻烦,才值得你去升级。比较的过程中,相信自己的眼睛,而不是相信别人的说教。比如说我真不推荐笔记本用户折腾任何顶级缩放算法——那么小个屏幕你能看出点啥?教程里说出花的放大算法跟你有几毛钱关系? 2、循序渐进。先把一套简单基础的方案弄好弄懂,再去学习和尝试更好的方法。对于新的插件,你要尝试测试它们在你机器上的表现;对于别人的设置,设法了解他这么推荐的原因,以及这个原因是否适用于你。最典型的,很多人用着madVR问我,你在新教程里教我们LAV只勾选RGB,我要改么?看了这篇教程你应该知道要不要改与背后的原因了吧。 3、量力而行。播放器越高级,组件越多,往往性能消耗越大,出错概率也越高,同时收益越少。学会放弃与妥协,毕竟,你看的是片子,不是播放器组件和参数。 工具篇 下载地址 Potplayer官网地址 LAV发布地址 madVR下载地址 XySubFilter 3.1.0.752 Free Download - VideoHelp PotPlayer Potplayer 是影视常用的播放器,界面简洁,功能齐全,比 MPC-HC 和 MPC-BE 更人性化;但其默认方案十分糟糕,预设过多错误,无法正确播放 10-bit 视频,**一直饱受诟病。VCB-Stuido 以往发布的数篇高清教程大多偏重于 madVR,在 PotPlayer 的设置方面有些错漏。为了广大观众能正确、便捷地用 PotPlayer 享受高清影视,我们为大家带来一篇基于 PotPlayer 的高清影视全套 64-bit 工具链完整配置图文详解教程。 工具安装篇 1、为了避免版本混乱导致的bug,本教程提供所全套 64-bit 工具: **PotPlayer(播放器),LAV Filters(分离/解码器),madVR(视频渲染器),xy-vsFilter(通用字幕插件),xy-SubFilter(madVR专用字幕插件)。 安装路径只允许纯英文,否则一些工具会无法使用,故建议单独建一个纯英文路径的文件夹 Tools,把这些以上提到的程序都放进去,方便更新与维护。 2、安装 PotPlayer 和 LAV Filters。 二者都是普通的 exe 安装包,双击启动即可,将安装路径设置到 Tools 文件夹,其他安装选项全默认。 3、安装 madVR,xy-VSFilter 或 xy-SubFilter。 二者都是插件,安装方法为:将压缩包解压至 Tools 文件夹中,右键点击各自的 install.bat,以管理员权限运行,若移动这些组件则需要重新安装。 显卡设置 显卡显示器看起来灰蒙蒙的,可能原因有 显示器对比度低 传输线规格低 这里线材要求 HDMI 需要2.0, DP 1.4 规格以上 默认参数设置没有跳转 第三个原因解决方法如下 N 卡用户 打开 Nvidia 驱动面板,将红框中的动态范围参数调整至完全,蓝框的输出颜色深度调到10bpc或者8bpc(取决于显示器支持),如下图 Intel 核显用户 将量化范围设为全范围: AMD 显卡 新版设置界面,选择 Full RGB: CCC 旧版界面,同样选择 Full RGB: 为什么我们要对播放器进行折腾? 我们先了解一般视频在DirectShow架构的播放器播放时的运作过程,首先是读取档案的File source(读取滤镜),將其读取的內容传给Splitter(分离器),前面两者又可合称Source filters(源滤镜)。然后Splitter会將其分离为视讯编码跟音讯编码,將视讯编码传给Video decoder(视讯解码器)做解码,將音讯编码传给Audio decoder(音讯解码器)做解码,然后解码完的视讯內容传给Video renderer(渲染器)渲染后交由显卡输出,解码完的音讯內容则交给音讯装置输出(预设是DirectSound Device)。若是播放DVD,则源滤镜会使用win內建的DVD Navigator,其他则大同小异。所以最简单的方案就是选用算法更好的分离器,解码器和渲染器。(补充:部分视频有字幕的话直接分给字幕渲染器) 以Potplayer为例,确实很优秀,但是其内置的设定还是有些鸡肋,更何况现在高清视频正在普及,所以进行一番调教是应该的,直接给出一些对比效果: 1.关于LAV Filters LAV Filters,是一个包含分离器/视频解码器/音讯解码器三者的外挂解码方案,內容有LAV Splitter、LAV video decoder、LAV audio decoder三者,由DOOM9论坛上的nevcairiel所开发,格式支持高,完整支持各种10bit编码,也支持DVD及BD的解码,BUG少,功能强大但又实用而不花俏。LAV Filters分离器被称为高速万能分离器,所谓高速是指lav分离器的跳转速度很快,普遍高于pot内置分离器,万能指的是lav的分离器和音视频滤镜很全,几乎可播放所有常见视频。而且,LAV还支持开启硬件加速(如果使用madVR的话建议不要开启),至于为啥看看下面的问题就知道了。 2.关于madVR 视频的播放,解码吃的是CPU效能(硬解例外,硬解是使用显卡上的解码模组,既不吃CPU也不吃GPU效能),而渲染才是吃显卡GPU效能,额外的像去交错的部分也是吃显卡效能,整体而言还是CPU最重要,只有使用madVR时例外,GPU的部分也很重要。而madVR鼎鼎大名,地面最强的渲染器,又称显卡杀手,不惜一切效能代价以换取最大的画质表现,也因此这个渲染器对显卡的要求稍微吃重些,超越了我们一般对播放软件之硬件要求的常识(这个常识是指,只有玩游戏才需要用到较高阶的显卡,影像播放只需要低阶显卡甚至核显已可胜任),但并不是说只有好的显卡才能用这个渲染器,事实上madVR內部的选项相当弹性,根据设置的不同它可以让低阶卡跟內显顺顺跑,也可以把目前最高端的显卡跑爆,一般来说,我建议在能力许可的范围內选择一张不算太差的独立显卡才能发挥它该有的战力。目前甚至可以在普通显示器上模拟HDR,看下效果 左为MADVR渲染,右为播放器默认渲染,左边锯齿大大降低 右为MADVR渲染,色彩、细节皆要强于普通渲染 有HDR 无HDR 3.关于xysubfilter xy-vsfilter和xysubfilter都是第三方播放器滤镜,都支持mpc系列播放器也支持potplayer,xy-vsfilter是修改原本播放器的vsfilter而生成的,目的为了减轻显示多特效字幕的CPU负荷;xysubfilter则是重新编写的字幕渲染器,比xy-vsfilter新和更好的字幕渲染效果,也支援更多像素格式及对硬体加速的支援也提升。xysubfilter额外支持的部分:支持更多像素格式输入/输出、高解析度的字幕渲染、支持PGS/HDMV格式字幕。 但使用xy-vsfilter/xysubfilter后便正常呈现出效果,上方日文字幕出现应有的字体消失后的字幕特效。 4.关于Advanced codecs 由 Shark007 出品的万能视频解码器分为 ADVANCED Codecs 和 STANDARD Codecs 两个版本,它们能让 Windows 系统自带的 WMP 影音播放器功能得到全方位的加强,而且完全免费!它的前身是 Win8 Codecs,现在已经改名并完美支持 Win10/8/7 系统了,当然它也被叫做 Win10 Codecs。 之所以安装这款解码包是因为在使用Potplayer过程中播放部分mov文件遇到了只有图像没有声音的问题,安装之后完美解决,这款直接默认安装就好了。 PotPlayer 设置 注意常点击应用和确定按钮,不然就白忙活了。 进度条设置 按照个人爱好可以设置 皮肤及设置 把下载好的皮肤拖入skins文件夹,打开播放器,F5打开参数选项,点选新皮肤,根据自己的设备决定是否启用触控皮肤,建议勾选视频下自动隐藏。 然后修改皮肤输出方式,现在整个界面已经十分清爽干净了。如果你决定使用madVR的话,这里皮肤输出方式应该选择使用图层式皮肤输出。 然后我们再修改几个设置让播放器更好用,不是必须的,主要是我的使用习惯,除了我强调的,其他的都可以自行设置。 注意:务必勾选保存设置到INI文件,否则每次重装系统或者到其他电脑就得重新配置。 说明:播放窗口尺寸设置为自定义可以有效避免因为视频源分辨率导致画面忽大忽小的问题,避免手动拖拉调整的麻烦,由于我是高分屏,所以设置为1366768,普通用户推荐1024576,因为这是网上流行的1080P和720P视频的比例。 说明:勾选以避免放大调整播放器时产生黑边。 说明:个人并不喜欢ass字幕特效,不如简单朴素点好。 这点开始就设置好,因为我们不会使用其内置滤镜,虽然到这里就Potplayer已经是一款很简洁美观的绿色播放器了。 切换至 色彩空间/属性 选项卡,设置 YCbCr<->RGB 规则,设为自动选择 音频渲染器设置 根据一些文档叙述,WSAPI渲染器比 Default Direct SoundDevice 效果好,具有程序独占,抗干扰,延迟低的优点;建议关闭规格化,避免 Pot 擅自改变音量。操作方式如下: 或者设置 仅将规格化用于视频播放 添加滤镜 打开 滤镜 -> 全局滤镜优先权,然后点击添加外部滤镜 加载madVR 添加madVR渲染器,这一点与添加LAV方式一致,添加外部滤镜,点选madVR.ax即可,需要注意的是,浏览器的皮肤在madVR下不可用。 我们也可以在全局滤镜中勾选强制使用,这样我们马上可以看到效果。 madVR的初始预设值是重视效能取向和稳定性的,也就是让大部分的显卡都可以正常运作为前提的设置,懒的研究设置的朋友用预设值也可以顺顺使用madVR,但如果想要进一步发挥madVR强大的功能,我们就再继续看四,如果你设置混乱了,可以恢复初始设置继续研究。 Madvr滤镜选择madvr文件夹下的madVR64.ax 加载LAV Filters Lav滤镜选择LAVAudio.Ax(音频滤镜),LAVVideo.ax(视频滤镜)和LAVSplitter.ax(音频视频分离器) LAV Splitter 除外的 LAV ,以及 madVR 都设置为强制使用 加载xysubFilter 操作依然一样,直接看图即可,我们我们可以先勾选强制使用看看效果,右下角会出现一个向右上方的箭头,右键这个箭头可以选择字幕,播放器里已经无法选择字幕了。 设置滤镜 禁用内置滤镜 如果没有关闭 Potplayer 内置图像滤镜,数据在传递给 madVR 前已经从 10-bit 砍成 8-bit 损失精度,madVR 内部再怎么精度高也是白搭 打开滤镜,将激活条件选为不使用,将使内置视频编码器取消勾选 原滤镜/分离器 设置 打开滤镜-》原滤镜/分离器,然后点击滤镜/解码器管理 注意:所谓LAV Splitter Source的其实就是LAV Splitter + File Source。直接使用LAV Splitter可能会出现不协调的问题,而且MS的File Source是存在bug的,特别是xp系统。所以与其让potplayer调用MS的File Source,不如直接全部交给LAV来处理,所以个人推荐你直接选择LAV Splitter Source而不是LAV Splitter。 然后在全局滤镜优先权新增lav video decoder,再设定优先顺序为强制使用。 然后选择LAV video decoder,将视频解码器那一列全勾上, 选择LAV Audio Deocder,将音频解码器那一列都勾上。 选择LAV Splitter Source,源滤镜/分离器全勾上 然后点击确定,回到源滤镜/分离器。 然后将能设置成LAV Splitter Source的全部改成LAV Splitter Source。 视频解码器设置 打开视频解码器,将能宣传LAV Video Decoder的券选上 音频解码器设置 打开音频解码器,将能选成LAV Audio Decoder的全选上 字幕插件设置 xy-vsFilter,优先级设置上,xy-vsFilter 设为强制使用,负责外挂字幕;xy-vsFilter设为按优先级使用,负责内挂字幕。二者均可渲染文字字幕(ass 和 srt 等格式),但是不能渲染外挂图形字幕(SUP 和 PGS)。 xy-vsFilter 不支持外挂图形字幕,但支持内挂图形字幕,外挂图形字幕请使用 Pot 内置字幕插件。 视频渲染器设置 然后打开视频,将视频渲染器改成 MADshi视频渲染(就是MadVR) madVR 的全称是 madshi Video Renderer,是 Windows 平台最强视频渲染器,调教得当的话效果媲美顶级蓝光机,当然消耗也不小。 屏幕 1920×1080 分辨率,则 GTX 960 / 1050 Ti 级别显卡足够体验 madVR 的所有好处;屏幕 2560×1440 或者 3840×2160 分辨率,GTX 970 / 1060 3G 级别显卡勉强可以享受所有好处,GTX 1060 6G 足够,GTX 1070 则绰绰有余。 LAV Video Decoder 设置 随便用potplayer打开一个视频,然后在potplayer上右键,然后选择属性 然后需要我们手动修改启用LAV,以上便是pot中调用lav filter的方法 检查滤镜设置 那么到此我们的滤镜就已经加载完毕了,那怎么看是否加载成功呢?这里有三种方法: 我们可以打开一个视频,右键选择滤镜,看看是否都成功加载,如果没有问题说明已经成功了。 我们还可以按下Tab键,查看相应的解码器渲染器信息是否正确,如图说明LAV解码器,madVR都加载成功,帧率稳定在60,可以畅享60fps的大片了。 我们还可以按下Ctrl+J,这会显示madVR的实时渲染信息,可以借此修正madVR的设置,发挥显卡更大潜能,要掌握这个,这是我们以后进一步调教madVR的关键。 提高音质 首先查看自己电脑的音质输出 然后在Potplayer中进行相关设置,选择内置WASAPI音频渲染器,高品质,关闭开启规格化(会调节音量,但会损失细节,更具自己需要看看吧) 独显笔记本要为Potpayer选择独显,这里以N卡为例 设置LAV 1.分离器部分 上方的Audio(音频)及Subtitles(字幕),可以设定优先的轨道,可以依自行需求设定, (不过这部分我比习惯使用MPC-BE內的切换) 在Subtitle Selection Mode內以下几种选项可选: No Subtitles:不载入任何字幕 Only Forced Subtitles:只选择有强制轨(forced track)的字幕 Default:选择有强制轨(forced track)或预设轨(default track)的字幕 Advanced:选择在Subtitles的栏位中填入选择逻辑 在Demuxer Settings(分路器设定)內, Prefer Audio Stream with the Highest Quality (偏好最高音质音轨) 此项可以视情况勾选, 勾选后LAV会倾向选择最高音质的音轨, 但少数影片最高音质的音轨不一定是对的/最好的。 左下角的Enble System Tray Icon勾选后, 在启用LAV分离器时,会在右下角工作列的通知区域內显示图示。(依需求选择是否勾选) 2.音频解码器 仅有一项必须调节,启用 Enable Mixing。 因为绝大多数人都应用双声道机器设备,因此碰到 5.1 音道声轨时,仅有左 / 右一声道会被手机耳机 / 音箱接受,别的音道都立即丢掉了。因此,一般来说大家应让 LAV 把多声道混流式成双声道(Stereo)再輸出;玩多声道音箱的富豪请随便。 右方的Output Formats(输出格式)中,可以自由选择输出格式,不过这边建议预设即可。 左下角的Enble System Tray Icon勾选后,在启用LAV音讯解码器时,会在右下角工作列的通知区域內显示图示。(依需求选择勾选) Enable Mixing(开启混音)勾选后,便可以將 多声道音轨 混和成 较少声道数 输出,输出声道可以在Output Speaker Configuration(输出扬声器设置)中设置,依照声道数设定。 Mono:单声道 Stereo:立体声/双声道 4.0:4.0声道 5.1:5.1声道 6.1:6.1声道 7.1:7.1声道 右方Setting(设定)选项中,Clipping Protection(音量保护),可以使扬声器在大动态音频输出时,降低破音机率。(如果对扬声器有信心,不建议勾选此项,因为可能会损失音质) 3.视频解码器 随便打开一个视频,在播放界面点击右键-属性,打开此界面。点击橙色框就能进入视频/音频解码器设置界面。! 视频解码器 LAV Video Decoder 设置。LAV 的设置分为两套方案,A 方案应搭配 madVR 使用,B 方案搭配默认的 EVR(CP) 使用。 如果使用 madVR,橙色框中的 Output Format 勾选除了 AYUV 以外的所有选项;RGB Output Level选 PC;Dither Mode 选 Random。LAV 默认设置就是如此,如图所示。 如果使用 EVR(自动选择),橙色框中的 Output Format 只勾选 RGB24 选项;其他同上。(仅供需要省电或显卡性能不足者使用)! 为什么 madVR 和 EVR 勾选方式不同? 因为 madVR 能正确处理 LAV 解码出的所有数据,LAV 解码出的数据原封不动喂给 madVR 就是最好的,这是 madVR 被称作最强视频渲染器的主要原因之一。然而 EVR 只支持处理 8-bit 数据,LAV 解码出的 10-bit YUV 数据会被 EVR 直接砍成 8-bit YUV 进行处理,导致精度大幅降低,色带满天飞,这也是Pot 默认方案读作 a piece of shit 的主要原因之一;如果让 LAV 解码后将 10-bit YUV 转为 RGB24,也就是 8-bit RGB,再喂给 EVR 处理,可避免精度大幅损失。 渲染器 madVR 和 EVR 可以在 pot 的播放界面快速切换,方法是:右键-视频-视频输出设备。切换渲染器的同时,记得要修改对应的 LAV Video Decoder 设置。 再次强调,A 方案配 madVR 使用,B 方案配 Potplayer 默认的 EVR 使用。 硬解相关设置 解码方案优先级推荐:CPU软解 > D3D11 = DXVA2(copy-back) = Intel QuickSnyc > DXVA2(native) > NVIDIA CUVID 。建议没事别用硬解,因为偶尔会出现 bug,况且大多数人也不缺这点 CPU 性能。 N 卡 GTX 950 / GTX 960 / GTX 1000 全系列、A 卡 4 系 5 系全系列以及 Intel 七代(Kaby Lake)处理器集成显卡可硬解 HEVC 10-bit YUV420 视频。 常见显卡都能硬解 AVC 8-bit YUV420 视频,所有显卡都不能硬解 AVC 10-bit 视频。接下来以 HEVC 10-bit YUV420 的视频进行示范。 **CPU 软解 + madVR 示范,**注意绿框中的 Active Decoder 和红框中的输出: 蓝色和绿色框中是解码器选项,如果使用 CPU 软解,则选择 None;如果使用显卡 GPU 进行硬解,则选择 DXVA2 (copy-back) 或 D3d11 或 DXVA2 (native),A/N 都可用,前者兼容性更好,后者更节省 CPU;如果使用英特尔核显,则选用 Intel QuickSync;NVIDIA CUVID 是 N 卡专用硬解方式,基本用不上。 DVXA2 (native)硬解 + madVR 示范: 红框中显示 dxva,实际上输出依然是 P010,橙框中的 Active Decoder 为 dxva2n,OK 表明显卡支持此硬解方式。DXVA2 (copy-back) 和其他硬解方式都类似。 左上角Settings(设定)选项中,Threads for Multi-Threading(设定多执行续的执行数),基本上设定成Auto(自动)即可。 Setting for Interlaced Video Streams(设定隔行扫描影片): Field Order(场序规则),在处理格行扫描影片时需要先进行去交错,而反交错时分成 奇数场 优先或是 偶数场 优先,可依需求设定,或是设定成Auto让LAV自动判断。 Deinterlacing Mode(去交错模式),有几种选项, Auto:自动。 Agressive:当影片中发现有格行扫描的画面时,则全部进行去交错处理。 Force:强制进行去交错处理。 Disabled:关闭去交错处理。 右上角的Hardware Acceleration(硬件加速/硬解),Hardware Device to use(使用硬件装置),简单来说就是选择要用何者来进行硬体解码,有以下几种选项, NVIDIA CUVID:Nvidia专用硬体解码介面,可以开启硬体去交错处理。 Intel QuickSync:Intel內显专用硬体解码介面,CPU使用率比其余硬解模式稍高5~10%左右,可以开启硬体去交错处理。 DXVA2 (copy-back):为微软开发的硬体加速介面,ANI显示卡均可使用,会將解码完成的资讯回传给记忆体,由於多个回传动作,故效能会比native略差,不过优势为可以在解码器与渲染器中间添加滤镜。 DXVA2 (native):为微软开发的硬体加速介面,ANI显示卡均可使用,会將解码完成的资讯將不会传给记忆体,直接渲染,故效能比copy-back佳,缺点为限制较多。 如果要开硬解,会建议 DXVA2 (native) > DXVA2 (copy-back) > NVIDIA CUVID 或 Intel QuickSync(原版则建议使用DXVA2 (copy-back)) 右下方的Hardware/GPU Deinterlacing (CUVID/QS only), 即为硬体去交错处理设定,限定在NVIDIA CUVID或Intel QuickSync硬解模式下启用。 Software Deinterlacing(软体去交错) 若要启用软体去交错,可以选择YADIF,此处的去交错与madVR內的去交错,则一使用即可 左下角的Output Formats(输出格式),可以设定不同色深下的影片输出那些格式,如果没有要使用madVR渲染器及后处理滤镜(post-processing filters),建议让LAV的高精度抖动输出RGB模式(如下图) 字幕与音轨 大家早已在上面设定好啦 xy-vsfilter 外挂字幕软件,因此要关掉 Pot 内嵌渣滓外挂字幕软件,不然便会出現二行外挂字幕的奇景,鼠标右键 - 外挂字幕 - 撤销启用显示信息外挂字幕,如图所示。外挂字幕应当跟视頻放到同一文件目录下,且与视频文件格式同名的,会被全自动载入,外挂字幕由 DirectVobSub 操纵,并非 Potplayer。 转换多外挂字幕轨 / 多视頻 / 多音轨,应用右下方的任务栏图标里 LAV 和外挂字幕软件 DirectVobSub 的标志。许多观众们都不清楚 VCB-Studio 及其别的抑制组制做的 BD 通常含好几条声轨,例如文件夹名称中含 2flac、flac_aac、FLACX2 等关键字的 mkv,及其外挂软件 mka。这代表着视頻含有多音轨,可能是 5.1,也可能是声优演员或者 staff 评价声轨,能够 转换着应用。 转换声轨还可以立即点一下鼠标右键 - 响声 - 挑选响声来完成,开展转换;视頻轨同样,但是多音轨很普遍,而多视頻轨基本上见不上。 设置madVR madVR 的核心优势有两个: 1、高精度的数据处理,避免画面失真,产生色带、锯齿等瑕疵; 2、高质量的缩放算法,在片源分辨率低于屏幕分辨率时,提供更清晰、更锐利的画面,算法甚至优于很多高级蓝光机。 madVR 功能强大,其调教也大有学问,本篇教程不再赘述 madVR 调教具体步骤,详情请见我们之前做过的 madVR教程: [VCB-Studio 科普教程 2] madVR 渲染器配置教程 如果教程也无法满足你的需求,欢迎有耐心、有基础者钻研:万年冷冻库 最强渲染器——madVR设置研究 以上,以 Potplayer 为基础的高质量播放器工具链设置完成,请尽情享受高清影视的乐趣吧! 下面开始进入正式设置篇 我们播放视频时,双击任务栏右下方的 MADVR 控制面板,进入设置菜单。(没有的话运行 MADVR 文件夹里的 madHcCtrl.exe),或是在外挂滤镜里加入madVR并点两下都可以打开设定页。 1.device菜单 无论我们使用的是显示器还是电视,一律选择“Digital Monitor/TV”。 打开设备下的 “properties” 选项。 如果使用显示器,第一项 RGB 范围选择 0-255。如果是连接电视机,则选择 16-255。(这个还是比较测试下,我接电视反而感觉选 0-255 效果更好) 第二项是色深。一般选择 8bit。如果显示器或者电视能达到 10bit 或更高,则选择 10bit。 第一个就是你的显示设备的名称,各人的显示设备不同,所以名称也会不一样。在这里可以选择你输出设备的制式,因为不同的设备,他的某些指标不一样,所以要认真对待。设置显示器的类型,一般选择“Digital Monitor” 打开设备下的“properties”选项如果使用显示器,这里一定要认真对待。如果你用电脑显示器看影片,就要选择PC levels(0-255),如果你是接液晶电视,或者投影仪,可能需要选择TV levels(16-235)。因为一般电视显示的灰阶不是0-255,如果你用0-255去输出,那么16以下,235以上的灰阶都丢失了,暗部细节漆黑一片,影片整个发灰。 针对电脑连接TV或投影,我详细说一下。这里有些复杂,首先,你用的是什么线进行连接。如果你的显卡有HDMI接口,那么HDMI直连显示设备,选择16-235。如果你的显卡没有HDMI接口,用DVI转接HDMI。这里还是选择16-235. 如果你的显示设备有DVI接口。DVI直连,并且你的显示设备也支持的话,可以选择0-255.而位深则选择8 bit(or higher).8 bit或者更高。8 bit对应256色阶。通用。当然你硬件设施够好,达到10bit ,这个选项也完美对应。 信息标示页面。在这个页面里,会标出你的显示设备的型号啊,出厂日期什么的。 这里一定要认真对待。如果你用电脑显示器看影片,就要选择PC levels(0-255)。如果你是接液晶电视,或者投影仪,可能需要选择TV levels(16-235)。因为一般电视显示的灰阶不是0-255,如果你用0-255去输出,那么16以下,235以上的灰阶都丢失了,暗部细节漆黑一片,影片整个发灰。针对电脑连接TV或投影,我详细说一下。这里有些复杂,首先,你用的是什么线进行连接。如果你的显卡有HDMI接口,那么HDMI直连显示设备,选择16-235。如果你的显卡没有HDMI接口,用DVI转接HDMI。这里还是选择16-235.如果你的显示设备有DVI接口。DVI直连,并且你的显示设备也支持的话,可以选择0-255.而位深则选择8 bit(or higher).8 bit或者更高。8 bit对应256色阶。通用。当然你硬件设施够好,达到10bit ,这个选项也完美对应。 这里的校准,指颜色校准。使用yCMS和3DLUT进行校准。这里我觉得没什么好讲的,因为显示器存在差异,因此你必须按照你自己的显示器来进行颜色校准设置。但是这需要校准设备。这个东西一般只有显示设备评测机构有,我们自己恐怕没办法去搞这种校准。所以这里就不要去开启它了。而下面的选项,我在图片里也有详细说明。在此不再复述。选择BT.709而伽马部分,如果你是N卡,就选择pure power curve。后面的2.20最好不要动。那个数值是标准。不过你也可以尝试改改看~ 这里的选项多半是为接其他显示设备用的,一般用不到。留空就可以了。 启用伽马处理,一般选择启用。然后交由你选择的伽马处理标准去处理灰阶。N卡选择pure power curve后面的2.20不要动,这个是标准数值。 在hdr项目中,选择convert HDR content to SDR by using pixel shader math,假如你有某些萤幕校色装置可以选择包括3DLUT的项目,不过我没有此类设备所以不知如何设定。设置好了之后可以去观看HDR影片,如果想肯定HDR功能是否正常运作,可以在播放时按下Ctrl+J开启OSD讯息表,观察红框內matrix的色域是否BT.2020,而且下方有无出现HDR项目。 在正常运作下即使模拟HDR功能的效果亦相当出众,光暗和色彩效果都只能用惊艳形容,比较下会感觉非HDR版的色彩变得非常暗哑,但少年pi这套电影在当时画面呈现的效果已经算是相当出色,但在HDR的效果更上一层楼。参见开始展示的对比图。 2.processing菜单 deinterlacing 选项,对应的是图像交错处理。建议在最上面的选项打勾,让视频需要进行图像交错的时候交给 MADVR 自己去处理,并且在怀疑时不启动交错处理。如果常看动漫的,可以去掉“only look at pixels in the frame center”勾选。 关于 “only look at pixels in the frame center”: arifact removal 选项,对应的是图像去色阶功能。在普通的视频中,我们经常会看到人物的脸上,或者不同颜色的交界处有淡淡的光晕和条纹,这就是没有去掉色阶。而我们的目的就是让图像的颜色过渡更加自然,让条纹现象减少甚至消失。(这个选项会占用一些 GPU 资源,但尚可接受,开启无压力。)第一个选项是整体画面的去色阶效果。一般选择 low 就会有不错的效果。第二个选项是不同颜色交界处去色阶效果。可以选择 high。 3.scaling algorithms菜单 这个是最关键的图像缩放算法的设置,这部分是影响效能最大也是影响画质表现最明显的地方,也是 madVR 的最大特色。里面5个页面的内容基本类似。让用户选择的东西都是各种图像缩放模式,而不同的模式所消耗的性能也是不同的,基本上从上到下,性能消耗是越来越大,用户要根据自己的配置来考虑。每个页面的设置主要都是为了解决视频图像中的锯齿(aliasing)和振铃效应(ringing)。根据选择的不同,右上角会有效果介绍。绿条一般越长也越好。红条则是越低越好。 说明在算法的最下面还有两个选项:active anti-ringing filter(简称ar)可以开启抗光环处理,也容易在downscale时候增加锯齿。scale in linear light可以增加image downscale转换之后,颜色对比度的精确性。建议在image downscale中开启。 chroma upscaling:色度拉升 即色度平面放大。不过色度拉伸的算法比较难感受到差别。 如果配置好的话就设置是 NGU Anti-Alias,high quality(这里开到 very high qulity 以上几乎没什么意义,肉眼分辨不出) 如果显卡中等的话,可以设置 Jinc + AR 如果显卡不太好的话,则可设置 Cubic Bicubic75 + AR 如果是 Intel 集显得话,则可设置 Cubic SoftCubic60 + AR image downscaling:影像缩放 只要输出分辨率小于原始分辨率就会用到这部分的算法,比如 4K 分辨率的视频在 1080P 显示器上播放。 如果电脑配置特别高的话,还可以考虑下使用 SSIM 1D 100%。SSIM 是目前表现最好的算法,在缩小画面的同时很好的保留了原解析度的细节跟锐利度,不过效能消耗也比较大。 如果显卡跑不动 SSIM 的话,可以考虑 Cubic(Bicubic 150)+ AR + LL,即勾选 “activate anti-ringing filter”(简称 AR) 跟”scale in linear light”(简称 SC)。 如果显卡还是不给力,那就使用下图的 Cubic(Catmull-Rom)+ AR + LL,这个也算是公认的最佳演算法组合 (resize 后最接近原本的画面) image upscaling:影像拉升 也就是影像放大,只要输出目标分辨率大于原始分辨率就会用到这部分的算法,比如 1080P 分辨率的视频在 4K 显示器上播放。 对显卡很有自信的可以开 NGU Anti-Alias,同时下拉框设置为下图所示。 我们这里选择的是 “… always -supersampling”,表示始终启用 NGU 进行翻倍。 而原来默认的 “let madVR decide” 表示目标分辨率的宽或高大于或等于原始分辨率 1.2 倍时才启用 NGU,沒达到 1.2 倍启用条件的话则会使用 Jinc + AR 替代。 如果上面的设置有些吃力的话,可以把第一个下拉框(luma doubling)的选项调成 medium。 如果配置中等的话,还是建议设置为 upscaling 下的 Jinc + AR。 显卡吃不消的可以考虑:Lanczos 4+AR(HD4600 等级集显)甚至是 Cubic Bicubic60+AR(HD4000 等级集显)。 upscaling refinement:锐化算法,目的是在于改善放大运算后造成的模糊,只在视视频大后使用,如果是1:1无放大的影像,这部分勾选了也不会有作用。。 4.rendering菜单 说明madvr 默认就是用全屏独占模式(exclusive)。虽然这种模式有它的好处,但如果电脑配置不够就会出现上间歇性黑屏,去掉“enable automatic fullscreen exclusive mode”的勾选即可。 [图片上传失败…(image-63c71e-1599900233537)] 如何正确播放HDR视频 为了实现完整的HDR工作链,我们需要从解码到最终输出的全套播放工具都支持HDR。可能有的人会说Windows 10自带的视频播放器就支持HDR视频的播放,为什么不直接用呢?说到底还是因为Microsoft Store难用,因为现在使用Windows 10自带的视频播放器对HEVC编码进行解码,就必须在商店中购买HEVC解码器扩展,虽然说它只有7块钱,但是考虑到很多人并没有使用Microsoft账户,仍然是以本地账户形式使用Windows 10的,所以购买非常不方便(因为HEVC不是免费格式)。因此,我们需要一些别的路子,一些免费并且没有版权问题的路子。 首先我们需要一个支持HDR内容解码的视频解码器,这里推荐使用LAV Filter,这款解码器可以说是目前最强大的解码器之一,包含分离器+视频解码器+音频解码器,另外它还是开源免费的。按照播放视频的下一步,我们需要一个支持HDR内容的渲染器,这里我们使用目前地表最强的视频渲染器——madVR,它支持将HDR信息直接传输给显示器。最后我们需要一个播放器,作为外壳调用前面的这些东西,这里推荐使用MPC-BE,当然很多人用的PotPlayer也可以,不过要比MPC-BE稍微多做一点工作。 准备好了软件之后还要对硬件支持进行检查,显卡必须要支持HDR内容输出,显示器必须要支持HDR内容输入,两者之间的传输通道也要支持HDR的内容。更为具体一点的细节是,HDMI 2.0a标准只支持HDR10标准的内容传输,而HDMI 2.0b中增加了对于HLG标准的支持。而在DP那边,1.4版本中增加了对于HDR10的支持,也就是说,我们至少需要支持DP 1.4和HDMI 2.0b接口的显卡来输出HDR内容,显示器也需要具备这两个接口。 当然,最终也是最重要的,就是你需要一个支持HDR的显示器。 按照上文中设置 LAV Filters + madVR + Potplayer + 10Bit 视频线 +HDR 显示器,就可以实现HDR观看了 采用madVR的好处就是不用在Windows的显示设置中开启HDR,madVR在检测到显示器支持HDR、视频源中包含HDR内容时会自动让显示器切换到HDR模式下,不过如果没有自动切换,就需要你手动将开关打开了。另外,没有HDR显示器的用户也可以享受到HDR视频精准转换至SDR色彩带来的提升,这是madVR视频渲染器独一份的高精度转换,不过对于性能会有一些要求。 可以看到非常明显的画面色彩对比,HDR内容在不正确播放的情况下显示出的是灰蒙蒙的画面,而正确输出之后,颜色非常亮丽。 希望本次教程可以帮助到一些读者朋友,我以后可能还会写个VapourSynth啊x265啊什么的压制教程。 另外,虽然现在新版的PotPlayer已经支持将HDR信息直接传输到显示器,但在这篇教程中我仍然提倡大家使用LAV Filters和madVR,因为这两个滤镜拥有更高的处理精度。PotPlayer经常被压制圈诟病的一点就是其内建的解码器和大部分情况下自动使用的EVRCP渲染器的内部处理精度不够,尤其是在HDR这种片源为原生10bit的情况下,更是不够用了。 视频补帧 **补帧,**即利用电脑上的补帧软件,将原视频从24FPS提升至60FPS或者更高。帧数越多,所显示的动作便会越流畅,视频的清晰度、饱和度也会更佳。 所以,我们补帧的目的就是把把视频从24帧提升到60帧或者更高,能够很直观欣赏到流畅的画面。 PotPlayer倍帧 这个补帧是PotPlayer播放器自带的补帧方法,能直接让当前原视频的帧数翻倍,只需要简单的设置即可。 dmitrirender 补帧 dmitrirender 官网](http://www.dmitrirender.ru/) dmitrirender这一款这一款软件实际上并不是插帧领域中最为常见的软件,但其有着自身的优势: 首先采用GPU运算,无论是AMD、NVIDIA还是INTEL的核显通通都支持,对CPU的负担较低,对整体配置的需求也比较低 SVP4 补帧 SVP4 需要付费。SVP4是一款专业版视频补帧软件,提供GPU加速,并允许使用中档CPU和几乎任何GPU硬件为60Hz的FullHD 1080p视频重新计算,能将一些画面模糊和不流畅的的视频进行自动补帧,让你的视频流畅起来。 SVP下载地址:https://www.svp-team.com/wiki/Download SVP还有一项优势就是它并不依赖特定的播放器,其本身可以看做是在视频解码过程中的一个滤镜,只要能调用相应解码器播放视频,便可以进行视频插帧 SVP4 安装 评估版本下载地址 https://alist.17lai.site/tools/video 1.解压SVP.RAR到C:\SVP 2.运行 svp4-cracked.exe 3.运行后在弹出窗口内点击settings 4.切换到 Repositories 标签 5.点击 Temporary respoitories,再点击 Add,把下列内容添加进去(两条!) file:///C:/SVP/free file:///C:/SVP/common 6.然后勾选 Use temporary repositories only,确认安装 7.【重要】将SVPManager.exe复制到程序目录,替换原文件。 SVP4 设置 点击如图所示的部分可以进行一些简单设置 视频帧处理选项按下图进行设置。(检测并切掉黑边这个不要勾选,因为有可能会切掉部分字幕) 背景灯效果按下图设置(不禁用的话会出现动态模糊的边框) PotPlayer 设定 1.右击potplayer的播放界面,进入选项页面****。**** 2.*先点击*滤镜,再点击全局滤镜优先权**,最后点击添加系统滤镜 3.选择『ffdshow raw video filter』,然后点击确定 选中 ffdshow raw video filter,点击強制使用(重要),别忘了点击应用,然后再点击确定。此時已经完成基本设置。 完成以上设置完基本参数后,就可以使用potplayer+svp4 pro组合来看视频了 播放影片前几秒左下角会出現SVP启用的标志,这就说明配置成功了。 AMD显卡专用补帧 **必要条件:**确保你有GNC或者Vega 架构的AMD显卡,并下载最新的AMD驱动。 AMD在2014年12月9号发布Omega驱动时也宣布了Fluid Motion技术,基于显卡的运算插帧,大大降低CPU负担,同时使视频播放更加流畅。相比传统的SVP插帧需下载安装多款外挂软件且需繁杂的手续设定,需要消耗CPU资源,耗电量比较大,SVP部份画面呈现会有抖动情况。 Fluid Motion就是只需按一键就开启,CPU跟本没有在处理(使用率都在个位数) 全程就交给GPU去处理就好。Fluid Motion部份比SVP呈现出来的动作还要比较自然,可以说是看动画的神器,不过官方只支持在蓝光播放时开启插帧,不过网友基于AMD Fluid Motion以DirectShow开发出了Bluesky Frame Rate Converte,方便了我们在普通视频上也能实现补帧的效果。 下载Bluesky Frame Rate Converte 下载好以后直接默认安装即可! 安装完成之后,还需要对FRC 设置, AMD 驱动设置,以及 Potplayer 滤镜设置 Nvidia显卡专用补帧 既然有AMD显卡专用补帧,肯定也有Nvidia显卡专用补帧了!它名字叫做:Dain-App 需要说明的是:本软件是一款补帧****转换工具,而不是和以上介绍的可以实时渲染同步补帧!但是通过它补帧后的效果还是很明显的! Dain-App基于Nvidia CUDA开发,是上海交大开源的 DAIN(Depth-Aware Video Frame Interpolation)是一款可以AI深度学习,使用AI预测新帧并提高视频或gif帧率的插帧算法。可让您采用任何形式的媒体,例如电影,定格动画,动漫,卡通,精灵等,并插值新帧,从而从原始文件生成更大的帧率。 需要注意的是:目前它需要CUDA,因此任何不支持CUDA的计算机都将无法运行此应用程序(AMD和较早的Nvidia卡)。它极度吃显卡及显存资源,依据视频长度/分辨率等决定计算时间,整体耗时较为漫长,低端N卡不建议使用。 Dain-App介绍地址:https://github.com/baowenbo/DAIN 下载地址:https://grisk.itch.io/dain-app 下载完毕后直接解压缩,运行DAINAPP.exe即可。 常见 Bug 解决篇 1、为什么使用 madVR 全屏时候会黑屏? 答:黑短短几秒是正常的,表明 madVR 正在切换至全屏独占模式(fullscreen exlucsive mode,简称 FSE 模式 ),这个模式有一些好处,比如防止画面撕裂。但实际上,我们推荐你关闭 FSE 模式,因为它带来的麻烦远多于好处。 如果你不喜欢 FSE 模式,可以在 madVR 中关闭它,具体操作为:取消勾选 madVR 的控制面板里的 rendering -> general settings -> enable automatic fullscreen exlucsive mode 选项。 2、为什么全屏 FSE 模式下点鼠标/切音轨/切换字幕/拉进度条画面会闪? 答:因为全屏模式就是给你看视频用的,任何操作都应该在按 Enter 键 或 点击鼠标中键 退回到 窗口模式 后再进行。 此外,全屏模式下完全可以用键盘轻松控制,比如 ←/→ 默认 后退/前进 5s;Ctrl + ←/Ctrl + → 默认后退/前进 30s;Ctrl + PageUp / Ctrl + PageDown 默认后退/前进 至上/下一章节,这些实用的快捷键都可以在 Potplayer 的设置里找到并定制。 3、为什么 EVR 和 madVR 切换时会卡死? 答:播放过程中, madVR 渲染器和 EVR 渲染器相互切换可能导致卡死,故建议尽量在暂停时切换。同理,任何切换字幕、音轨等操作,如果出现问题,应先暂停再操作;如果还不行,尝试关闭视频,重新打开。 4、为什么我按照教程设置还有这样那样的 Bug ? 答:最安全的方式是使用本教程文首提供的安装包,并按照教程从头重新设置 Potplayer。 Potplayer 本身就是个问题大户,版本号还那么多,导入 reg 文件导致的 Bug 也五花八门,无从下手。但按照本文的步骤从头设置,至少能将出问题的概率压到最低。我在许多台电脑上,按照本文的步骤设置过 LAV + Potplayer + madVR,从没出现过 Bug。 5、如何配合此教程的方案使用插帧/倍速播放/截图/录制等功能? 答:自己动手,丰衣足食,以上大多数功能可以由 Potplayer 本身实现,但不保证在使用 madVR 后还能用。本教程的目的是提供基本完美的视频播放功能,是为欣赏视频用的,不是拿来折腾的,不可能为各种细枝末节的需求做定制调整,我个人尤其反感插帧和倍速播放。更何况即使我们有心,播放器本身也未必能实现。 6、为何我的画面是上下颠倒的?为何我的 madVR 老是崩溃? 答:这两个问题大多是由 xy-vsFilter 造成的,因为 xy-vsFilter 存在不少 Bug,本教程以 xy-vsFilter 作为字幕插件纯粹是为了照顾无法使用 madVR 的用户。因此,只要你电脑能跑得动 madVR ,我都强烈建议改用 madVR + xy-SubFilter 的组合。各种字幕插件至今都是 beta 版,madVR 也是,如果出了问题,除了更新到最新的版本,也没什么更好的办法。实在不行那就用播放器自带吧,mpv、mpc-hc 和 mpc-be 自带的字幕插件尚且堪用;Potplayer 变黄前自带的字幕功能也勉强凑合,但变黄后就是一坨 shit。 7、Potplayer 太容易崩溃了,有没有什么解决办法? 答:将 Potplayer 换成 mpc-hc 或者 mpc-be 搭配 madVR 使用吧,他们本质上是一样的。本文最开始就强调,Potpalyer 的优势在于其友好的使用界面,对 Potpalyer 进行如此多的调教,仅仅是为了让它达到 mpc-hc 或者 mpc-be 默认设置的水平而已。但即使经过这么多调整,Potpalyer 的崩溃概率依然大于mpc-hc 或者 mpc-be。如果你能按照这篇教程成功设置 Potplayer ,那设置选项更简洁的 mpc-hc 或者 mpc-be 也不是问题。 后记:效果展示 鉴于madVR是压榨显卡性能,所以显卡占用如果没到80%以上说明还没有达到最佳设置,另一个标准就是你的风扇有没有哗哗响。 全高清 全高清下的大腿时代,播放4K视频没压力 4K屏显卡已经吃不消了 4K下的大腿时代,果然是显卡杀手,估计得得1070才能流畅流畅解析吧。 其它平台 推荐的播放器可以分成两大阵营:mpv 和 MPC。前者跨平台,后者仅限 Windows。 mpv mpv 可以在 Windows、macOS 和桌面 Linux 上使用。 mpv 本身没有图形界面,需要自己写配置文件,但并不复杂,习惯之后可以说比图形界面还要简单。 如果你确实需要一个图形界面的 mpv 播放器前端,我们推荐: – Windows 用户使用 mpv.net mpcbe IINA 详情请查看我们的 mpv 配置教程。 windows 下 mpv 播放器的配置文件 mpc-config MPC MPC 系列都基于微软 DirectShow,只能在 Windows 上使用。 MPC 目前有两个分支版本:MPC-HC 和 MPC-BE,都值得推荐。我们同时推荐配合 madVR 和 XySubFilter with libass 一起使用。 目前的 K-Lite Codec Pack Full 直接包含了 MPC-HC、LAV 以及 madVR 这一套播放环境,安装和配置较为简单,是我们优先推荐的方案。 详情请查看教程的 MPC-HC + madVR 配置教程。 MPC 默认就支持 HDR Dolby Vision,懒人福音! 参考&致谢 实现PC视频播放最强画质教程( Potplayer播放器 MADVR插件) 有问有答:如何正确播放HDR视频 potplayer + LAV + madVR 组PC高清播放器 基于 PotPlayer 和 madVR 的播放器教程 | VCB-Studio https://github.com/hooke007/MPV_lazy/ 懒人专用,新手推荐 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2022/9/6
articleCard.readMore

Vercel部署高级用法教程

Vercel使用有不少需要仔细配置的地方,可惜的是,自定义Vercel缓存时间,Vercel重定向等使用方法略复杂,不是开箱即用,有一定使用门槛,故这里单独列一篇文章详细说明Vercel的一些高级使用方法! 为什么使用 vercel 国内 Github Pages 速度较慢。 vercel 速度快且能够自定义域名,能实现和 Github Pages 一样的效果 vercel 官方地址:vercel.com/ 开始使用 首先注册一个账号 https://vercel.com/ 注册成功后进入页面,点击 News Project 然后通过绑定的 github 或者 gitlab 导入需要部署的项目 如果导入的项目是打包好的静态页,FRAMEWORK PRESET 选择 Other 。 点击 deployed 进行部署,如果部署失败可以查看报错信息是不是上一步的某些选项没有覆盖。部署成功后会进入如图所示的界面 如何自定义域名 腾讯云域名地址:console.cloud.tencent.com/domain vercel 静态页挂载地址: 进入到 setting 中可对项目进行一些设置,如项目名称 下面演示如何自定义域名,默认情况下部署成功后 vercel 会给你生成一个默认的域名,如果想要修改成自己的域名可将域名名称修改成自己的。 当选择修改成自己的域名名称后,vercel 会检查域名指向的 DNS 对不对,如果不对的话会提示你域名的 DNS 应该如何配置,按照 vercel 提示的 DNS 信息 在自己的域名的 DNS 配置中进行配置,如图 配置多个域名 对其他新增的域名选择重定向到自己的主域名即可 自定义Vercel服务器位置 Vercel线路已经很快了,但是可以通过选择Vercel部署服务器位置,更进一步加快中国大陆,亚洲区域的访问速度! 香港服务器虽然没有严格测试,但是中国大陆速度应该是最快的! 自定义Header缓存时间 vercel.com/docs 使用Vercel必备配置,本地缓存加速访问! vercel.json { "headers": [ { "source": "/sw.js", "headers": [ { "key": "Cache-Control", "value": "public, max-age=0, must-revalidate" } ] }, { "source": "(.*)", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=86400, max-age=86400" } ] } ] } Vercel自定义404 learn how to customize the 404 page. Vercel流量超标怎么办? 最近查看了一下Vercel流量使用情况,发现RSS订阅流量太大了,占了30GB流量! 免费Vercel账户每月只有100G免费流量,怎么办? 有两种解决方法: 使用 DNS 多线路分流,例如DNSPOD 多线路负载均衡 使用 Vercel 提供的 redirects 或者 rewrites功能,把rss访问重定向到其它部署方式,例如Cloudflare 查看方法:dashboard -> usage 由于个人blog也部署到Cloudflare上面了,https://cfblog.17lai.site,Cloudflare的流量目前看着没限制,如是,可以使用如下重定向方法 "redirects": [ { "source": "/atom.xml", "destination": "https://cfblog.17lai.site/atom.xml" }, { "source": "/rss.xml", "destination": "https://cfblog.17lai.site/rss.xml" } ] 详细 Cloudflare 部署方法,戳 cloudflare Pages 部署 个人使用最终版本如下,各位使用修改对应部分即可。文件路径 [hexo]/source/vercel.json { "headers": [ { "source": "/sw.js", "headers": [ { "key": "Cache-Control", "value": "public, max-age=0, must-revalidate" } ] }, { "source": "(.*)", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=86400, max-age=86400" } ] }, { "source": "/medias/(.*)", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=2592000, max-age=2592000" } ] }, { "source": "/medias_webp/(.*)", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=2592000, max-age=2592000" } ] }, { "source": "(.*).html", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=1800, max-age=1800" } ] }, { "source": "(.*).js", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=2592000, max-age=2592000" } ] }, { "source": "(.*).css", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=2592000, max-age=2592000" } ] }, { "source": "(.*).json", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=2592000, max-age=2592000" } ] } ], "regions": [ "hkg1" ], "redirects": [ { "source": "/gtag/js", "destination": "https://www.googletagmanager.com/gtag/js" }, { "source": "/atom.xml", "destination": "https://cfblog.17lai.site/atom.xml" }, { "source": "/rss.xml", "destination": "https://cfblog.17lai.site/rss.xml" } ] } Vercel 账号被禁怎么办? Your Personal Account was automatically blocked because its usage exceeds the fair use policy 最近某个 vercel app 流量超标了! 程序可能被攻击了,或者程序存在某个bug。发现的时候,账号已经被禁用了。 等了一个月后,账号没有自动解禁! 怎么解封了? 在这里 https://vercel.com/help#issues 点击 【Create a case】,然后邮件联系解封!邮件回复说: accounts will not auto-unblock after they’ve been blocked for exceeded limits. I can do that manually, but I must first be sure that the underlying issue has been resolved. 技术支持要求解决掉超出限制的原因,然后再回复邮件!应该就可以解禁了。 删除了被攻击或者出bug的 vercel app 之后再次回复邮件,得到回复: After review, I have unblocked your account. Please note that this is a one-time consideration, and future usage overages may require purchasing a Pro team subscription to unblock your account. 账号终于解禁了,但是再次超出限制就得交钱解禁? 20$每月的价格太高了! 乒乓部署 也可以叫旋转门部署。 解决调试博客插件,修改半成品文章时部署到云端会影响正在查阅博客的用户的问题! 使用Docker版本本地预览是很不错,但是 jsdelivr 版本发布需要在 Github 生成新 release 这时本地就不行了。乒乓部署可以解决这个问题! 具体方法就是同时部署到两个地方A和B,博客域名在两个服务器之间切换。这里以 Vercel 为例 准备工作: 创建2个Github仓库,对应服务器A和B的部署 建立两个服务器A和B,分别关联两个 Github 仓库 把调试完毕的代码上传到两个仓库 这时通过服务器A和B都是可以正常浏览的 要调试的时候: 发布到A之前,把博客域名转移到服务器B 在服务A做一些调试,在线 debug 工作 特别是在线 pageseed 测试调优,这种事必备方法。简单不需要新的 jsdelivr 版本调试本地 docker-hexo 调试即可! 调试完毕后: 把域名切换到服务器A 同时部署到服务器B,服务器B同步A的部署内容,以便下次备用 总结就是服务器A现行,服务器B做后备,调试发布使用A,调试A的时候B就顶上前台! 这样,调试和正常部署网络服务两不误。是不是感觉自己是个大聪明! 参考&致谢 https://vercel.com/docs/project-configuration#project-configuration/redirects how-to-enable-cors 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/9/4
articleCard.readMore

hexo博客博文撰写篇之完美笔记大攻略终极完全版

hexo博客文章卷写技巧,包括MarkDown,hexo技巧,html插入,美化方法,写作方法,写作工具,知识储备方法,AI助手,开发工具,等一系列全介绍!终极攻略篇。 当然,这些写作技巧也可以用在hexo , hugo, next.js, wordpress上面,或者还是其它类型博客。 在任何类型的写作上面,这些都是用得着的写作技巧! 使用草稿 新建文章 一般我们都会使用 hexo new <title> 来建立文章,这种建立方法会将新文章建立在 source/_posts 目录下,当使用 hexo generate 编译 markdown 文件时,会将其 HTML 结果编译在 public 目录下,之后 hexo deploy 将会把 public 目录下所有文章部署到 GitHub,这是我们熟悉的 Hexo 流程。 这种建立文章方式的缺点是:若我们同时编辑多篇文章,只要其中一篇文章尚未编辑完成,也会随着 hexo deploy 一起部署到 GitHub,也就是 GitHub 可能会看到我们尚未完成的文章。 新建草稿 hexo new draft <title> Hexo 另外提供 draft 机制,它的原理是新文章将建立在 source/_drafts 目录下,因此 hexo generate 并不会将其编译到 public 目录下,所以 hexo deploy 也不会将其部署到 GitHub。 hexo S --draft 虽然 hexo generate 不会编译 source/_drafts 目录下的文章,但 Hexo 的 Hexo server 另外提供 --draft 参数,这让我们只要搭配 hexo-browsersync plugins,就可以达到一边编辑 markdown 文章,一边使用浏览器预览的目的。 将草稿发布为正式文章 hexo P <filename> 其中 <filename> 为不包含 md 后缀的文章名称。它的原理只是将文章从 source/_drafts 移动到 source/_posts 而已。 之后的 hexo generate 与 hexo deploy 的用法就完全一样了。 若日后想将正式文章转为为草稿,只需手动将文章从 source/_posts 目录移动到 source/_drafts 目录即可。 新建普通页面 这种形式类似是“关于”,“了解我们”之类的文章。 hexo new page c 创建一个标题为c的page 和前两种不同,这个命令会在source文件夹内创建出c文件夹,与_posts,_drafts并列。文件夹里面有一个index.md文件。 注意:刷新页面后,c并没有出现在页面中,而是需要访问http://localhost:4000/c/才可以看到。 hexo命令速记 # 开启服务 hexo server # 新建文章 hexo new a # 新建草稿 hexo new draft b # 发布草稿成为文章 hexo publish b # 普通页面 hexo new page c # 清空缓存 hexo clean # 生成静态文章 hexo generate 或者是 hexo g # 部署文章 hexo deploy 或者是 hexo d Front-matter Front-matter 是文件最上方以 --- 分隔的区域,用于指定个别文件的变量,举例来说: --- title: Hello World date: 2013/7/13 20:46:25 --- 以下是预先定义的参数,您可在模板中使用这些参数值并加以利用。 参数 描述 默认值 layout 布局 config.default_layout title 标题 文章的文件名 date 建立日期 文件建立日期 updated 更新日期 文件更新日期 comments 开启文章的评论功能 true tags 标签(不适用于分页) categories 分类(不适用于分页) permalink 覆盖文章网址 excerpt Page excerpt in plain text. Use this plugin to format the text disableNunjucks Disable rendering of Nunjucks tag {{ }}/{% %} and tag plugins when enabled lang Set the language to override auto-detection Inherited from _config.yml 布局 The default layout is post, in accordance to the value of default_layout setting in _config.yml. When the layout is disabled (layout: false) in an article, it will not be processed with a theme. However, it will still be rendered by any available renderer: if an article is written in Markdown and a Markdown renderer (like the default hexo-renderer-marked) is installed, it will be rendered to HTML. Tag plugins are always processed regardless of layout, unless disabled by the disableNunjucks setting or renderer. 分类和标签 只有文章支持分类和标签,您可以在 Front-matter 中设置。在其他系统中,分类和标签听起来很接近,但是在 Hexo 中两者有着明显的差别:分类具有顺序性和层次性,也就是说 Foo, Bar 不等于 Bar, Foo;而标签没有顺序和层次。 categories: - Diary tags: - PS3 - Games warn 分类方法的分歧 如果您有过使用 WordPress 的经验,就很容易误解 Hexo 的分类方式。WordPress 支持对一篇文章设置多个分类,而且这些分类可以是同级的,也可以是父子分类。但是 Hexo 不支持指定多个同级分类。下面的指定方法: categories: - Diary - Life 会使分类Life成为Diary的子分类,而不是并列分类。因此,有必要为您的文章选择尽可能准确的分类。 如果你需要为文章添加多个分类,可以尝试以下 list 中的方法。 categories: - [Diary, PlayStation] - [Diary, Games] - [Life] 此时这篇文章同时包括三个分类: PlayStation 和 Games 分别都是父分类 Diary 的子分类,同时 Life 是一个没有子分类的分类。 JSON Front-matter 除了 YAML 外,你也可以使用 JSON 来编写 Front-matter,只要将 --- 代换成 ;;; 即可。 "title": "Hello World", "date": "2013/7/13 20:46:25" ;;; 主题Front-matter 不同主题还有自己定义的Front-matter,以提供不同的特殊功能 Front-matter 选项详解 Front-matter 选项中的所有内容均为非必填的。但我仍然建议至少填写 title 和 date 的值。 配置选项 默认值 描述 title Markdown 的文件标题 文章标题,强烈建议填写此选项 date 文件创建时的日期时间 发布时间,强烈建议填写此选项,且最好保证全局唯一 author 根 _config.yml 中的 author 文章作者 img featureImages 中的某个值 文章特征图,推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如: http://xxx.com/xxx.jpg top true 推荐文章(文章是否置顶),如果 top 值为 true,则会作为首页推荐文章 hide false 隐藏文章,如果hide值为true,则文章不会在首页显示 cover false v1.0.2版本新增,表示该文章是否需要加入到首页轮播封面中 coverImg 无 v1.0.2版本新增,表示该文章在首页轮播封面需要显示的图片路径,如果没有,则默认使用文章的特色图片 password 无 文章阅读密码,如果要对文章设置阅读验证密码的话,就可以设置 password 的值,该值必须是用 SHA256 加密后的密码,防止被他人识破。前提是在主题的 config.yml 中激活了 verifyPassword 选项 toc true 是否开启 TOC,可以针对某篇文章单独关闭 TOC 的功能。前提是在主题的 config.yml 中激活了 toc 选项 mathjax false 是否开启数学公式支持 ,本文章是否开启 mathjax,且需要在主题的 _config.yml 文件中也需要开启才行 summary 无 文章摘要,自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要 categories 无 文章分类,本主题的分类表示宏观上大的分类,只建议一篇文章一个分类 tags 无 文章标签,一篇文章可以多个标签 keywords 文章标题 文章关键字,SEO 时需要 reprintPolicy cc_by 文章转载规则, 可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprint 或 pay 中的一个 注意: 如果 img 属性不填写的话,文章特色图会根据文章标题的 hashcode 的值取余,然后选取主题中对应的特色图片,从而达到让所有文章的特色图各有特色。 date 的值尽量保证每篇文章是唯一的,因为本主题中 Gitalk 和 Gitment 识别 id 是通过 date 的值来作为唯一标识的。 如果要对文章设置阅读验证密码的功能,不仅要在 Front-matter 中设置采用了 SHA256 加密的 password 的值,还需要在主题的 _config.yml 中激活了配置。有些在线的 SHA256 加密的地址,可供你使用:开源中国在线工具、chahuo、站长工具。 您可以在文章md文件的 front-matter 中指定 reprintPolicy 来给单个文章配置转载规则 以下为文章的 Front-matter 示例。 最简示例 --- title: typora-vue-theme主题介绍 date: 2018-09-07 09:25:00 --- 使用模板 hexo new使用的模板,最好自己定制修改 下面是博主使用的 scaffolds/post.md --- layout: post title: {{ title }} date: {{ date }} author: 夜法之书 categories: [web] # 文章分类 建议只写一个 tags: # 文章标签 文章卡片显示用 - EncryptedTag - web - http keywords: web, http # seo标签 summary: 简介,这里修改 img: /medias_webp/cover/write.webp top: false # 首页推荐文件 hide: false cover: false # 首页轮播 coverImg: /medias_webp/cover/write.webp toc: true # 是否开启目录 tochide: false # 默认是否隐藏目录 mathjax: false mermaid: false echarts: false comment: waline # password: false # SHA256 string matery主题自带加密 reprintPolicy: cc_by_nc_sa # password: "" # hexo-blog-encrypt 插件需要的 wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试. wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容. --- > 简介 > <!-- more --> 图片 正文 参考 hexo内置标签 所有hexo主题都支持的标签 quote {% blockquote [author[, source]] [link] [source_link_title] %} content {% endblockquote %} 没有提供参数,则只输出普通的 blockquote {% blockquote %} Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit lacus ut purus iaculis feugiat. Sed nec tempor elit, quis aliquam neque. Curabitur sed diam eget dolor fermentum semper at eu lorem. {% endblockquote %} Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit lacus ut purus iaculis feugiat. Sed nec tempor elit, quis aliquam neque. Curabitur sed diam eget dolor fermentum semper at eu lorem. 引用书上的句子 {% blockquote David Levithan, Wide Awake %} Do not just seek happiness for yourself. Seek happiness for all. Through kindness. Through mercy. {% endblockquote %} Do not just seek happiness for yourself. Seek happiness for all. Through kindness. Through mercy. David LevithanWide Awake 引用 Twitter {% blockquote @DevDocs https://twitter.com/devdocs/status/356095192085962752 %} NEW: DevDocs now comes with syntax highlighting. http://devdocs.io {% endblockquote %} NEW: DevDocs now comes with syntax highlighting. http://devdocs.io @DevDocstwitter.com/devdocs/status/356095192085962752 引用网络上的文章 {% blockquote Seth Godin http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html Welcome to Island Marketing %} Every interaction is both precious and an opportunity to delight. {% endblockquote %} Every interaction is both precious and an opportunity to delight. Seth GodinWelcome to Island Marketing 代码块 在文章中插入代码。 markdown支持行内代码和区块代码 `行代码` ``` 代码块 ``` 别名: code {% codeblock [title] [lang:language] [url] [link text] [additional options] %} code snippet {% endcodeblock %} Specify additional options in option:value format, e.g. line_number:false first_line:5. Extra Options Description Default line_number Show line number true line_threshold Only show line numbers as long as the numbers of lines of the code block exceed such threshold. 0 highlight Enable code highlighting true first_line Specify the first line number 1 mark Line highlight specific line(s), each value separated by a comma. Specify number range using a dash Example: mark:1,4-7,10 will mark line 1, 4 to 7 and 10. wrap Wrap the code block in `` true 样例 普通的代码块 {% codeblock %} alert('Hello World!'); {% endcodeblock %} alert('Hello World!'); 指定语言 {% codeblock lang:objc %} [rectangle setX: 10 y: 10 width: 20 height: 20]; {% endcodeblock %} [rectangle setX: 10 y: 10 width: 20 height: 20]; 附加说明 {% codeblock Array.map %} array.map(callback[, thisArg]) {% endcodeblock %} Array.map array.map(callback[, thisArg]) 附加说明和网址 {% codeblock _.compact http://underscorejs.org/#compact Underscore.js %} _.compact([0, 1, false, 2, '', 3]); => [1, 2, 3] {% endcodeblock %} _.compactUnderscore.js _.compact([0, 1, false, 2, '', 3]); => [1, 2, 3] Include Code 插入 source/downloads/code 文件夹内的代码文件。source/downloads/code 不是固定的,取决于你在配置文件中 code_dir 的配置。 {% include_code [title] [lang:language] [from:line] [to:line] path/to/file %} 样例 嵌入 test.js 文件全文 {% include_code lang:javascript test.js %} 只嵌入第 3 行 {% include_code lang:javascript from:3 to:3 test.js %} 嵌入第 5 行至第 8 行 {% include_code lang:javascript from:5 to:8 test.js %} 嵌入第 5 行至文件结束 {% include_code lang:javascript from:5 test.js %} 嵌入第 1 行至第 8 行 {% include_code lang:javascript to:8 test.js %} Pull Quote 在文章中插入 Pull quote。 {% pullquote [class] %} content {% endpullquote %} jsFiddle 在文章中嵌入 jsFiddle。 {% jsfiddle shorttag [tabs] [skin] [width] [height] %} Gist 在文章中嵌入 Gist。 {% gist gist_id [filename] %} iframe 在文章中插入 iframe。 {% iframe url [width] [height] %} Image 在文章中插入指定大小的图片。 {% img [class names] /path/to/image [width] [height] '"title text" "alt text"' %} Link 在文章中插入链接,并自动给外部链接添加 target="_blank" 属性。 {% link text url [external] [title] %} Youtube 在文章中插入 Youtube 视频。 {% youtube video_id [type] [cookie] %} Examples 视频 {% youtube lJIrF4YjHfQ %} 播放列表 {% youtube PL9hW1uS6HUfscJ9DHkOSoOX45MjXduUxo 'playlist' %} 隐私模式 禁止 YouTube cookie {% youtube lJIrF4YjHfQ false %} {% youtube PL9hW1uS6HUfscJ9DHkOSoOX45MjXduUxo 'playlist' false %} Vimeo 在文章中插入 Vimeo 视频。 {% vimeo video_id %} Raw 如果您想在文章中插入 Swig 标签,可以尝试使用 Raw 标签,以免发生解析异常。 {% raw %} content {% endraw %} 引用文章 引用其他文章的链接。 {% post_path filename %} {% post_link filename [title] [escape] %} 在使用此标签时可以忽略文章文件所在的路径或者文章的永久链接信息、如语言、日期。 例如,在文章中使用 {% post_link how-to-bake-a-cake %} 时,只需有一个名为 how-to-bake-a-cake.md 的文章文件即可。即使这个文件位于站点文件夹的 source/posts/2015-02-my-family-holiday 目录下、或者文章的永久链接是 2018/en/how-to-bake-a-cake,都没有影响。 默认链接文字是文章的标题,你也可以自定义要显示的文本。 默认对文章的标题和自定义标题里的特殊字符进行转义。可以使用escape选项,禁止对特殊字符进行转义。 链接使用文章的标题 {% post_link hexo-3-8-released %} 链接使用自定义文字 {% post_link hexo-3-8-released '通往文章的链接' %} 对标题的特殊字符进行转义 {% post_link hexo-4-released 'How to use <b> tag in title' %} 禁止对标题的特殊字符进行转义 {% post_link hexo-4-released '<b>bold</b> custom title' false %} 引用资源 引用文章的资源。 {% asset_path filename %} {% asset_img [class names] slug [width] [height] [title text [alt text]] %} {% asset_link filename [title] [escape] %} 资源(Asset)代表 source 文件夹中除了文章以外的所有文件,例如图片、CSS、JS 文件等。比方说,如果你的Hexo项目中只有少量图片,那最简单的方法就是将它们放在 source/images 文件夹中。然后通过类似于 ![](/images/image.jpg) 的方法访问它们。 对于那些想要更有规律地提供图片和其他资源以及想要将他们的资源分布在各个文章上的人来说,Hexo也提供了更组织化的方式来管理资源。这个稍微有些复杂但是管理资源非常方便的功能可以通过将 config.yml 文件中的 post_asset_folder 选项设为 true 来打开。 _config.ymlpost_asset_folder: true 当资源文件管理功能打开后,Hexo将会在你每一次通过 hexo new [layout] <title> 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后,你可以通过相对路径来引用它们,这样你就得到了一个更简单而且方便得多的工作流。 相对路径引用的标签插件 通过常规的 markdown 语法和相对路径来引用图片和其它资源可能会导致它们在存档页或者主页上显示不正确。在Hexo 2时代,社区创建了很多插件来解决这个问题。但是,随着Hexo 3 的发布,许多新的标签插件被加入到了核心代码中。这使得你可以更简单地在文章中引用你的资源。 {% asset_path slug %} {% asset_img slug [title] %} {% asset_link slug [title] %} 比如说:当你打开文章资源文件夹功能后,你把一个 example.jpg 图片放在了你的资源文件夹中,如果通过使用相对路径的常规 markdown 语法 ![](example.jpg) ,它将 不会 出现在首页上。(但是它会在文章中按你期待的方式工作) 正确的引用图片方式是使用下列的标签插件而不是 markdown : {% asset_img example.jpg This is an example image %} 通过这种方式,图片将会同时出现在文章和主页以及归档页中。 Embedding an image using markdown hexo-renderer-marked 3.1.0 introduced a new option that allows you to embed an image in markdown without using asset_img tag plugin. To enable: _config.ymlpost_asset_folder: true marked: prependRoot: true postAsset: true Once enabled, an asset image will be automatically resolved to its corresponding post’s path. For example, “image.jpg” is located at “/2020/01/02/foo/image.jpg”, meaning it is an asset image of “/2020/01/02/foo/“ post, ![](image.jpg) will be rendered as <img src="/2020/01/02/foo/image.jpg">. Embed image hexo-renderer-marked 3.1.0+ can (optionally) resolves the post’s path of an image automatically, refer to this section on how to enable it. “foo.jpg” is located at http://example.com/2020/01/02/hello/foo.jpg. Default (no option) {% asset_img foo.jpg %} <img src="/2020/01/02/hello/foo.jpg"> Custom class {% asset_img post-image foo.jpg %} <img src="/2020/01/02/hello/foo.jpg" class="post-image"> Display size {% asset_img foo.jpg 500 400 %} <img src="/2020/01/02/hello/foo.jpg" width="500" height="400"> Title & Alt {% asset_img logo.svg "lorem ipsum'dolor'" %} <img src="/2020/01/02/hello/foo.jpg" title="lorem ipsum" alt="dolor"> 文章摘要和截断 在文章中使用 <!-- more -->,那么 <!-- more --> 之前的文字将会被视为摘要。首页中将只出现这部分文字,同时这部分文字也会出现在正文之中。 例如: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <!-- more --> Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 首页中将只会出现 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 正文中则会出现 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 注意,摘要可能会被 Front Matter 中的 excerpt 覆盖。 引用数据 有时您可能需要在主题中使用某些资料,而这些资料并不在文章内,并且是需要重复使用的,那么您可以考虑使用 Hexo 3.0 新增的「数据文件」功能。此功能会载入 source/_data 内的 YAML 或 JSON 文件,如此一来您便能在网站中复用这些文件了。 举例来说,在 source/_data 文件夹中新建 menu.yml 文件: Home: / Gallery: /gallery/ Archives: /archives/ 您就能在模板中使用这些资料: <% for (var link in site.data.menu) { %> <a href="<%= site.data.menu[link] %>"> <%= link %> </a> <% } %> 渲染结果如下 : <a href="/"> Home </a> <a href="/gallery/"> Gallery </a> <a href="/archives/"> Archives </a> Markdown写作 下文着重介绍了MarkDown语法 Joplin 插件以及其Markdown语法。All in One! Joplin 实用插件介绍,以及Markdown语法说明。All in One! 强烈推荐,绝对是替代各种商业等笔记工具的第一选择。 中文技术文档的写作规范 直接访问 中文技术文档的写作规范 hexo插件强化写作 下文介绍了一些Markdown语法,和一些常用的有用的Hexo插件 Hexo Markdown以及各种插件功能测试 hexo matery hexo博客的一些功能测试,新插件的靶场。数学公式,Mermaid,plantuml图表绘制,音乐视频插入,bilibilid、豆瓣卡片等等。 主题插件 很多主题内置很多tag语法,可以大大美化最终呈现效果 使用fontawesome图标 醒目度提升一大个等级! 更多图标,这里查找 fontawesome 支持Markdown Hexo 支持 GitHub Flavored Markdown 的所有功能, 甚至可以整合 Octopress 的大多数插件. 一键部署 只需一条指令即可部署到Github Pages, 或其他网站 丰富的插件 Hexo 拥有强大的插件系统, 安装插件可以让 Hexo 支持 Jade, CoffeeScript. - <i class="fas fa-pencil-alt"></i> 支持Markdown <i>Hexo 支持 GitHub Flavored Markdown 的所有功能, 甚至可以整合 Octopress 的大多数插件. </i> - <i class="fas fa-cloud-upload-alt"></i> 一键部署 <i>只需一条指令即可部署到Github Pages, 或其他网站</i> - <i class="fas fa-cog"></i> 丰富的插件 <i>Hexo 拥有强大的插件系统, 安装插件可以让 Hexo 支持 Jade, CoffeeScript. </i> `<i class="fab fa-github"></i>` `<i class="fab fa-github fa-lg"></i>` `<i class="fab fa-github fa-2x"></i>` 使用颜文字 颜文字算是中文圈特有的文化符号了 (。◕‿◕。)ノ♥ 击掌/打招呼 ╭(●`∀´●)╯╰(●’◡’●)╮ (●’◡’●)ノ ヾ(*´▽‘*)ノ 手拉手 ╭(′▽`)╭(′▽`)╯ 好困呀(揉眼睛 ( ‘-ωก̀ ) 已阅留爪  (ฅ´ω`ฅ) 勾手指可萌啦 ( 。ớ ₃ờ)ھ 开心  ♪(^∀^●)ノシ (●´∀`)♪ 爱你么么哒 ( ˘ ³˘)♥ ( ˘ ³˘) •́ε•̀)ฅ (๑•́ ₃•̀๑٥) (๑ºั ³ ˘๑)♥ (๑ơ ₃ ơ)ﻌﻌﻌ♥ (ㆀ˘・з・˘) ε٩(๑> ₃ <)۶з 爱心眼 ( •́ .̫ •̀ ) (´・ω・`) (●′ω`●) (´,,•ω•,,‘) (´;ω;‘) (´・н・‘) (›´ω`‹ ) (๑•ั็ω•็ั๑)( ˘•ω•˘ ) (●´ϖ`●) ( •̀∀•́ ) 疑问  ◔ ‸◔? (⊙.⊙) 逃跑 ε=ε=ε=ε=ε=ε=┌(; ̄◇ ̄)┘ 撒花 。:.゚ヽ(。◕‿◕。)ノ゚.:。+゚ 瞥眼  (¬、¬) (¬_¬) 盯  ≖‿≖✧  o‿≖✧ (๑•̀ㅂ•́)و✧ 中老年人/脸红系列  ( ˙灬˙ ) (´•灬•‘) ε٩ (๑> 灬 <)۶з ( ˘•灬•˘ )(´-灬-‘) (๑´灬`๑) ٩(๑`灬´๑)۶ (•̅灬•̅ ) (๑ơ 灬 ơ) (ง •̀灬•́)ง 加油! (ง •̀_•́)ง (*•̀ㅂ•́)و 无奈  ╮(๑•́ ₃•̀๑)╭ 猫爪 ฅ’ω’ฅ ฅ(๑˙o˙๑)ฅ ٩(๛˘³˘)۶♥ ฅ(๑*д*๑)ฅ ฅ(๑˙o˙๑)ฅ ʕ•̀ω•́ʔ✧ (๑•̀ㅁ•́ฅ)ฅʕ•̫͡•ʔฅ ʕ•͡-•ʔ 伸懒腰  ٩(๑´0`๑)۶ 害羞  (//▽//) 委屈 (,,•́ . •̀,,) (๑•́ ₃•̀๑) (๑•́ ₃ •̀),,Ծ‸Ծ,, 着急/救命系列   ヘ(;´Д`ヘ) (/゚Д゚)/ (*゜ロ゜)ノ Σ(  ̄д ̄;) !!! Σ(っ °Д °;)っ ( •̀д•́) Σ( ° △ °|||)︴ =´Å‘= 各种哭法 π__π  T.T  ε(┬┬_┬┬)3  ╥﹏╥  ┬_┬  (╥╯^╰╥) 冒汗皱眉系列 (;¬_¬) ( ´◔ ‸◔`) (눈_눈) ( ∙̆ .̯ ∙̆ ) (;¬д¬) (“▔□▔) 呆子  (•ิ_•ิ) 认真脸  (..•˘_˘•..) 喂喂 ((٩(//̀Д/́/)۶)) 盖被子  (:3[▓▓] (:3[▓▓▓▓▓▓▓▓▓] (¦3[▓▓] 爬地 _(:з」∠)_  _(:qゝ∠)_  _(・ω・」 ∠)_ 嘿嘿嘿  ๑乛◡乛๑ (●´∀`●) 闭眼满足  (。→‿←。) (๑→‿ฺ←๑)(=ˇωˇ=)(⺻▽⺻ )<( ̄︶ ̄)>(•‾̑⌣‾̑•)✧˖° (๑˘ ˘๑)  ♥(。→v←。)♥ 哇呀 >ㅂ<  (๑>m<๑)  o(>ω<)o  ≥▽≤ 噜啦啦   (づ ̄ 3 ̄)づ ( ˙ε ˙ ) 乛 з乛 ( ̄ε ̄) (。◕ฺˇε ˇ◕ฺ。)(๑¯ิε ¯ิ๑) ( ´´ิ∀´ ) 流口水  ԅ(¯﹃¯ԅ) (¯﹃¯) 好呲  (๑´ڡ`๑) (๑>ڡ<)☆ 生气  (`д′) ( ̄^ ̄) 哼! <(`^′)> 瞪眼  ٩͡[๏̯͡๏] 掀桌系列 无表情掀桌 ( ╯-_-)╯┴—┴ (ノ—_—)ノ~┴————┴ (╯-_-)╯╧╧ (ノ*-_-*)ノ┴—┴  娇蛮掀桌 (/= _ =)/~┴┴ 无语掀 (╯#-_-)╯╧═╧ ( ╯#-_-)╯┴—┴ 大力掀 (╯#-_-)╯~~~~~~~~~~~~~~~~~╧═╧  抓狂掀桌 (╯ ̄Д ̄)╯╘═╛ (ノ=Д=)ノ┻━┻ (╯#-皿-)╯~~╧═╧ (╯’ – ‘)╯︵ ┻━┻ 再他妈的掀一次 (╯°Д°)╯︵ ┻━┻ (`□′)╯┴┴ ┴—┴ ╰(`□′╰) 泪奔掀桌 ((ノ*T_T*)ノ┴—┴ (┙>∧<)┙へ┻┻ 摆好 (\#-_-)\┯━┯ 桌放好 ┬─┬ ノ( ‘ – ‘ノ) 摆好摆好 其它 ╭( ̄▽ ̄)╯╧═╧ 单手掀 ╧═╧(-_-)╧═╧ 桌子飞人 卖萌 (•‾̑⌣‾̑•)✧˖°(๑¯ิε ¯ิ๑) (๑•́ ₃ •̀๑) ( ∙̆ .̯ ∙̆ ) (๑˘ ˘๑) (●′ω`●) ︶ε╰✿ ✿◡‿◡ (●・̆⍛・̆●) ♫ ♫♬♪♫ ヾ(。◕ฺ∀◕ฺ)ノ♫♬ 。゚+.゚ヽ(●´ω`●)ノ。 (●´3`)~♪ (●>∀<●)ィェ━ィ★彡 ♥♥(o→ܫ←o)♫ (〃^∇^)ぇ∧∧∧っ *゜✲ฺ(✿◕ฺ ∀◕ฺ)ฺノ†゜* (●´д`).。o ヽ(.◕ฺˇд ˇ◕ฺ;)ノ ((٩(//̀Д/́/)۶)) (´;ω;`) ( `)3′)  v(゚ー゚) =≡Σ((( つ•̀ω•́)つ (;′⌒`) ╰(*´︶`*)╯ ( ´´ิ∀´ิ` ) (´∩`。) ( ื▿ ื) (。ŏ_ŏ) ( •ิ _ •ิ ) ヽ(*΄◞ิ౪◟ิ‵ *)ノ ( ˘ ³˘) (๑>m<๑) (; ´_ゝ`) (*ˉ﹃ˉ) (◍’౪`◍)ノ゙ (。◝‿◜。) (ಠ .̫.̫ ಠ) (´◞⊖◟`) (。≖ˇェˇ≖。) ℰ⋆‿⋆ℰ (ಠ .̫.̫ ಠ) p(´⌒`。q) ┗(´D`* (´D`*(´D`*)┛ <(▰˘◡˘▰)> (・ω< )★ (*゚ェ゚*) ✧ (≖ ‿ ≖)✧ (◕ܫ◕) (`◕‸◕´+) (▼ _ ▼) ( ◉ืൠ◉ื) ㄟ(◑‿◐ )ㄏ (●’◡’●)ノ♥ (。◕ˇ∀ˇ◕) ~Ⴚ(●ტ●)Ⴢ~ ⊙.⊙ ( ◔ ڼ ◔ ) ( ´◔ ‸◔`) (☍﹏⁰) (♥◠‿◠)ノ ✪ω✪ ʅ(‾◡◝)ʃ (๑°3°๑) ლ(╹◡╹ლ ) இwஇ (๑꒪◞౪◟꒪๑) (๑◕ܫ←๑)b (*☉౪⊙*) ヾ(o゜_,゜o)ノ ლↀѡↀლ (。▰´◞◟`▰。) ( ͡° ͜ʖ ͡°)  ( ͡° ͜ʖ ͡°)✧ (*゜ロ゜)ノ   ( ´・∀・`) °(°ˊДˋ°) ° (つ﹏⊂) –\(˙<>˙)/- 心情好 萌 满足 ლ(´ڡ`ლ) (*≧m≦*) (*・ω・) ヾ(。・ω・。) (=゚ω゚)ノ (○’ω’○) (´・ω・`) (。-`ω´-) (。⌒∇⌒)。(ノ≧∀≦)ノ ( ̄ω ̄;) (◡‿◡✿) (◕‿◕✿) ♪(^∇^*) o(^▽^)o (●´▽`●) (= ̄ω ̄=) o(* ̄▽ ̄*)ブ ( ̄ε ̄*) ( o`ω′) o((>ω< ))o o(〃’▽’〃)o (@゜▽゜) (*^-゜)v \( ^▽^ )/ (。・`ω´・) o(*////▽////*)q (・ω< )★ (*〞艸〝) (◍’౪`◍)ノ゙(●’◡’●)ノ♥ヾ(o゜_,゜o)ノ (๑>ڡ<)☆ (・∀・(・∀・(・∀・*) ლ(・ิω・ิლ) (๑°3°๑) (˘❥˘) ︶ε╰✿ ƪ(•̃͡ε•̃͡)∫ʃ (*^︹^*)♡ ヽ(o゚∀゚o)ノ •́ε•̀~ ˇ▽ˇ (´◔౪◔)٩(๛ ˘ ³˘)۶ (๑•́ ₃ •̀๑) (*¯︶¯*) (●′ω`●) (U◕‿‿◕U)(*/ω\*)(´இωஇ`)゜(´∀`)♡ (ღ˘⌣˘ღ) ヽ(○´∀`)ノ♪ (*´∀`*) (⁎⚈᷀᷁ᴗ⚈᷀᷁⁎) ( ´・◡・` ) 心情不好 (→_←) (︶︹︺) (ノ´д`)(・_-。 ) ˋ(′~‵”)ˊ( TロT)σ ( T﹏T ) (; ´_ゝ`) (,,Ծ‸Ծ,,) (ಥ_ಥ) ( ꈨຶ ˙̫̮ ꈨຶ ) (;´༎ຶД༎ຶ`) (⌇ຶД⌇ຶ) (>人<) (°̥̥̥̥̥̥̥̥-°̥̥̥̥̥̥̥̥ ) థ౪థ இдஇ p(´⌒`。q) ( ´•︵•` ) º·(˚ ˃̣̣̥᷄⌓˂̣̣̥᷅ )‧º·˚ (´-ι_-`) (┳◇┳) ( >﹏<。)~ ( ̤இॕ⌓இॕ ̤) °(ಗдಗ。)° (´இ皿இ`)゜(´;ω;`) 。:゚(。ノω\。)゚・。(;*△*;) ( ཀ͝ ∧ ཀ͝ ) 呆呆的 无奈和汗颜 〜( ̄△ ̄〜) (〜 ̄△ ̄)〜 (*。_。) (; ̄Д ̄)(´Д`) (* ̄m ̄) ( ̄~ ̄;) ( ̄ェ ̄;) ( ̄◇ ̄;) ┐(─__─)┌ (*´Д`) (=_=)( ̄ー ̄*||| (-_-メ) ( ̄ ‘i  ̄;) ( ̄ε(# ̄) ( ¯▽¯;) (*゚ェ゚*) (。≖ˇェˇ≖。) (◒。◒) ( ᖛ ̫ ᖛ )ʃ) ヽ(´o`;(; ̄ェ ̄)( ´Д`)y━・~~ 搞怪颜文字 ヘ( ̄ω ̄ヘ) ♪(┌・。・)┌ (-o⌒) ☆~(ゝ。∂)╮(╯▽╰)╭ ( ̄︶ ̄)ψ (ˉ﹃ˉ) ೭(˵¯̴͒ꇴ¯̴͒˵)౨ _(:з」∠)_ ( ◉ืൠ◉ื) 罒ω罒 (☝ ՞ਊ ՞)☝⃔⌄ ⃔ ─=≡Σ((( つ•̀ω•́)つ ٩꒰⍢ ꒱۶⁼³₌₃ Σ( ̄。 ̄ノ)ノ ฅ(*ơ ₃ơ)ฅ” (「・ω・)「 (。・o・。)ノ ~ (o´〰`o) ( • ̀ω ⁃᷄)✧ (ФwФ) ( ื▿ ื) ◐/v/◐ (ゝω・)(੭ु ‾̑ω‾̑)੭ु⁾⁾ (ू ͒•‧̫•ू⑅ ͒) ᕦ(ò_óˇ)ᕤ ( ͡° ͜ʖ ͡°) 斜眼 鄙视状 (ਛ_≻ਛ) ( ﹁ ﹁ ) (¬д¬。) ( ¬、¬) (;¬_¬) (;¬д¬) (′д`σ)σ .╮(﹀_﹀”)╭ 认真的样子 (`・ω・´)ゞ(๑•̀.̫•́๑) (̿▀̿̿Ĺ̯̿̿▀̿ ̿)̄ ( ‾ʖ̫‾) ( •̀ .̫ •́ )✧ (๑•̀_•́๑) (ง •̀_•́)ง (`◕‸◕´+) ( ∙̆ .̯ ∙̆ ) (•ิ_•ิ) 惊恐 担心 (,,#゚Д゚) (」゜ロ゜)」 (;° ロ°) ヽ(゜ロ゜;)ノ ( ̄口 ̄)!! ┌(。Д。)┐(⊙ˍ⊙) Σ( ° △ °|||)︴ (⊙_⊙;)… (っ °Д °;)っ щ(゜ロ゜щ) 不满 傲娇状 ( ̄^ ̄) o(´^`)o ( ̄へ ̄)φ( ̄ー ̄ ) ╮(~▽~)╭ b( ̄▽ ̄)d ( ̄ c ̄)y▂ξ (ˉ▽ ̄~) o(一︿一+)o ε=(>ε<)ˋ﹏ˊノ(≖ A ≖))ノ =3=3=3 (‵▽′)/ 气愤 (╬ ̄皿 ̄) ヽ(o`皿′o)ノ ヽ(≧Д≦)ノ (>д<) (;≧皿≦) ヽ(#`Д´)ノ [○・`Д´・○] ヽ( `0´)ノ Σ(-`Д´-ノ;)ノ o(-`д´- 。) ヽ(●-`Д´-)ノ (`^´)ノ (╯‵□′)╯︵ ┴─┴ (╯-_-)╯╧╧ ┗|`O′|┛ (o#゜ 曲゜)o (╯‵□′)╯···*~● 凸(艹皿艹 ) (ʘдʘ╬) ╰(‵□′)╯ s(・`ヘ´・;)ゞ 山(≧皿≦)山 (ノ`Д´)ノ (┙>∧<)┙へ┻┻ 双人 (●ゝω)ノヽ(∀<●) o(╬ ̄皿 ̄)=○# ( ̄#)3 ̄) ╭(′▽`)╭(′▽`)╯( ̄ε(# ̄)☆╰╮o( ̄皿 ̄///) ( * ̄▽ ̄)((≧︶≦*) (~ ̄▽ ̄)→))* ̄▽ ̄*)o (┘ ̄︶ ̄)┘└( ̄︶ ̄└) (〃 ̄︶ ̄)人( ̄︶ ̄〃) <( ‵□′)───C<─___-)|| └( ̄  ̄└)(┘ ̄  ̄)┘ ( * ̄▽ ̄)((≧︶≦*) └│∵│┐┌│∵│┘ヽ(*´∀`)八(´∀`*)ノ \(“▔□▔)/\(“▔□▔)/ (*^ω^)人(^ω^*)(((*°▽°*)八(*°▽°*)))♪ヽ(^▽^)人(^▽^)人(^▽^)ノ 。*:★(´・ω・人・ω・`)。:゜★。ヽ(∀゜ )人( ゜∀)ノ 得意 <( ̄︶ ̄)> 乾杯 []~( ̄▽ ̄)~* 滿足 ( ̄ˇ ̄) 沒睡醒 ( ̄﹏ ̄) 狡猾(‵﹏′) 被打一巴掌 ( ̄ε(# ̄) 無言 ( ̄. ̄) 無奈 ╮( ̄▽ ̄)╭ 裝傻 ( ̄▽ ̄)~* 驚訝 (⊙ˍ⊙) 發現( ̄. ̄)+ 驚嚇 Σ( ° △ °|||)︴ 冷 ( ̄▽ ̄)” 沒辦法 ╮(╯▽╰)╭ 貓咪臉 (= ̄ω ̄=) 疑惑 ( ̄3 ̄)a 阿達 ( ̄0  ̄)y 重創 (。_。) 不 (>﹏<) 懷疑 (→_→) 睏 ( ̄o ̄) . z Z 崇拜 m( _ _ )m 我想想 (ˇˍˇ) 生氣 <( ̄ ﹌  ̄)> 就是你 <( ̄ ﹌  ̄)@m 小眼睛 ( ・ˍ・) (・ˍ・*) (p・_q) (〃・o・〃) (*^・_・) (。・ˍ・。) (*・0・) (・ε・●) (。・ω・) (。・д・。) (・∀・) (/ˍ・、) (・□・、*) (・-・。) (・▽・。) (・_・。) (・O・。) (ノ△・。) (@・ˍ・) (*・・*) 人(・ε・;) (・ o ・) (・ェ・o) (′・∀・『) 瞇瞇眼 (*  ̄ー ̄) ( ̄ー ̄〃) (@ ̄ー ̄@) (*  ̄︿ ̄) (* ̄∇ ̄*) <(ˍ ˍ*)> ( ̄(●●) ̄) ( ̄・・ ̄) (ー∀ー) ( ̄o ̄) ( ̄、 ̄) (* ̄△ ̄*) ( ̄へ ̄) ( ̄□ ̄) ( ̄~ ̄;) (。-ˍ-。 ) ( ̄ε ̄;) ( ̄┬ ̄;) ( ̄∀ ̄) (ノへ ̄、) (* ̄ro ̄) (ー人ー) (* ̄m ̄) 日系小眼睛 (′▽`〃) ( ′o`) (′ェ`) (′ε` ) (=′ー`) ( ′θ`) (′○` ) ( ′-`) (′∀`=) (*′▽`) (*′ノ0`) ( ′ロ` ) (′~`;) (′ ︿ `) (*′∇`*) (′m`) (′0ノ`*) (@。ε。@) (=′∇`=) (●′ω`●) (′~`●) (′へ`、 ) (〃′o`) ( ;′⌒`) 日系大眼睛 (ΘΘ) (Θ~Θ〃) (ΘoΘ) (ΘェΘ) (Θ∀Θ#) (ΘдΘ;) (Θ皿Θメ) (ΘーΘ*) (Θ0Θ●) (Θ▽Θ) (ΘεΘ◎) (Θ◇Θ。) (ΘへΘ) (ΘˍΘ=) (Θ、Θ) (Θ△Θ@) (Θ3Θ) 圆珠眼 (°ー°〃) (#°Д°) (。□。) (*。∀。) (*。∇^*) (* ^ー。) (@。ー。 @) (。∇^☆) (o。◇。) ( 。 ▽ 。) (#。ε。#) (。∇^d) (。・。;) (。皿。メ) (* 。 3 ^) (〃。 o 。〃) ( °◇ °) ( 。⊿。) (°□°;) ( ロ)。 。 (。Д。 ;) (*。ノO。) (; 。。) 紧闭眼 (><) (;><) (>_<) (>.<) (>o<) (>▽<) (>O<) (o>▽<) (>◇< ) (>▽<) (;>△<) (>з<) (o>ェ<) (>д<) (>皿<) (>_<、) (/_<。) (>。;) (>。ヘ) (ノ_<) (>。☆) (>y<;) 小狗嘴 (-ω- ) (+ω+) (*ω* ) ( ^ω^) (;ω;) (。ω。) (『ω′) (・ω・=) ( ̄ω ̄) (〃ω〃) (≧ω≦) (。・ω・) (=・ω・=) ( >ω<) (′・ω・`) (/ω\) (/ω・\) (/・ω・\) (ΘωΘ) (ΦωΦ) 悲伤眼 (UU*) (uu〃) (uou〃) (U3U*) (●U_U●) (u~u=) (@U▽U@) (UAU*) (U△U●) (uДu〃) (U◇U◎) (○uAu○) (u▽u#) (@U~U@) (u△u*) (u◇u〃) (UДU◎) (=u3u=) (u_u#) (UoU*) <( ̄︶ ̄)> 满足且得意 <( ̄︶ ̄)/ 满足并且伸出手表示赞同 <(@ ̄︶ ̄@)> 满足地脸红 (# ̄▽ ̄#) 害羞 \( ̄︶ ̄)/ 抱抱 b( ̄▽ ̄)d 竖起双手拇指说好 ╰( ̄▽ ̄)╭ 眉飞色舞 ( ̄︶ ̄)↗ 出发吧 ○(* ̄︶ ̄*)○ 吃饱睡好 ♀( ̄▽ ̄)/ 优质女孩 ♂( ̄▽ ̄)/ 优质男孩 ╮(╯◇╰)╭ 啾~啾~亲一个 ╭(′▽‵)╭(′▽‵)╭(′▽‵)╯ GO! ( ̄▽ ̄)~■□~( ̄▽ ̄) 干杯 <( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)> 当我们同在一起 伤心 (┬_┬) 流泪 (>﹏<) 痛苦 (┬_┬)↘ 跌倒 〒▽〒 真命苦 生气 …(⊙_⊙;)… 嘎? ( ̄∞ ̄) 猪! (︶︿︶) 不满 ╰(‵□′)╯ 暴怒 ((‵□′)) 暴怒 (︶︿︶)=凸 比中指 (╯-_-)╯╧╧ 翻桌A (╯‵□′)╯︵┴─┴ 翻桌B ┴─┴︵╰(‵□′╰) 翻桌C ╭∩╮( ̄▽ ̄)╭∩╮ 哼,去你的 ┴┴︵╰(‵□′)╯︵┴┴ 拆房子 (╬ ̄皿 ̄)=○#( ̄#)3 ̄) 看拳 <(‵□′)>───Cε(┬_┬)3 生气扭耳朵 <(  ̄︿ ̄)︵θ︵θ︵θ︵θ︵☆(>口<-) 无影脚攻击 道歉 〈(_ _)〉 道歉、鞠躬 无奈、尴尬 ╮( ̄▽ ̄)╭ ╮(╯_╰)╭ ╮(﹀_﹀)╭ ╮( ̄﹏ ̄)╭ ˋ(′~‵)ˊ ┐(─__─)┌ ( ̄口 ̄) (#-.-) (─.─||) ≡ ̄﹏ ̄≡ 其他 (~ ̄▽ ̄~) 装傻 \(“▔□▔)/\(“▔□▔)/\(“▔□▔)/ 大冷场 <( ̄3 ̄)> -(>口<-) <( ̄ c ̄)y▂ξ 抽烟 ( ̄Q ̄)╯ 滚一边去 使用emoji ⭕✅☑✔✖❌❎🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜☀🌝🌞⭐🌟💉💊 😀😁😂😃😎😍😘😗😙😚☺😇😐😑😶😏😣😥😮😯😪😫😴😭 更多 emoji 参考 ( 👁️︠ ‿‿ ︡👁️)✊ emoji表情符号 full-emoji-list fsymbols 插入html 跳转位置演示(跳转位置设置点) 我们可以在 Markdown 中插入一些简单的 HTML 代码或 CSS 片段来获得更多扩展,使得文章内容更具有多样性。以下演示几个简单功能。 文字颜色 #519D9E颜色演示 <p><span style="color: #519D9E; ">#519D9E颜色演示</span></p> 文字大小 0.7em 文字大小演示 <p><span style="font-size:0.7em;">0.7em 文字大小演示</span></p> 文字位置 内容居中演示 <p style="text-align:center">内容居中演示</p> # 可以修改 text-align 参数来设置文字位置。 页内跳转 点击到达跳转位置演示 <a ignore-external-link href="#demo">点击到达跳转位置演示</a> # 在需要跳转的地方添加此代码。 <a ignore-external-link id="demo">跳转位置演示(跳转位置设置点)</a> # 在跳转位置添加次代码。 综合演示 <p style="text-align:center;color:#8EC0E4;font-size:1.5em;font-weight: bold;"> 综合演示 <br> 优雅使用 Hexo 写文章 </p> iframe 页面镶套 iframe 页面镶套可以帮助我们更好的展示一个页面。比如以下演示页面。 iframe自动加载 <iframe src="/galleries/" width="100%" height="500" loading="lazy" name="topFrame" scrolling="yes" noresize="noresize" frameborder="0" id="topFrame" loading="lazy"></iframe> iframe鼠标点击加载 点击加载主页 点击加载相册 <ul> <li> <a id="download" onclick="frameA.src='/'" aria-label="iframe测试">点击加载主页</a> </li> <li> <a id="download" onclick="frameB.location='/galleries/'" >点击加载相册</a> </li> </ul> <iframe id="frameA" src="" loading="lazy" style="width:100%;height:500px;background-image:url(/medias_webp/loading.webp);background-size: 100% 100%;" frameborder="0"></iframe> <iframe name="frameB" src="" loading="lazy" style="width:100%;height:500px;background-image:url(/medias_webp/loading.webp);background-size: 100% 100%;" frameborder="2"></iframe> object标签 <object width="100%" height="400" data="/galleries/"></object> details 标签 用于展示代码较多需要折叠或折叠相关内容,以下为演示。summary 填写显示名称。 Demo 夜法之书 欢迎光临 <details> <summary>Demo</summary> <p><a href="/" target="_blank"><b>夜法之书</b></a></p> <p><b>欢迎光临</b></p> <img width="200" src="/favicon.webp" alt="wechat"> </details> 配图 众所周知,博客好不好看,配图占一半。这里给大家推荐几个我常用找配图的地方。另外,请遵循相关网站的版权协议。 Google Image是你的好搭档 Wallpaper Hub 点击跳转到 Wallpaper Hub Wallhaven 点击跳转到 Wallhaven Unsplash 点击跳转到 Unsplash 插入Mermaid 直接在我网页前端生成SVG图像,能够实现非常复杂,美观的流程图! Mermaid 简明教程 pluntuml 简明教程 graph LR 1[Sonarr] == request Jackett / Prowlarr Torznab api ==> 2(JProxy) == proxy Sonarr request ==> 3(Jackett / Prowlarr) 3(Jackett / Prowlarr) == return ==> 2(JProxy) == return result after format ==> 1(Sonarr) 2(JProxy) == replace search key ==> 2(JProxy) 2(JProxy) == format result title ==> 2(JProxy) 插入音乐和视频 教程: 插入音乐和视频 插入优美的音乐可以愉悦阅读过程 插入视频教程或者视频Live可以极大提高知识传播速度! 内容为王 前面提到了那么多的方法和工具,但是内容才是最重要的! 内容好,前面提到的写作技巧和工具都可以忽略;内容不好,再多的方法和工具都是白费!谨记! 尺度控制 不同平台,能够容忍的尺度是不同的! 面对不同的人群,不同地域,不同背景的读者,写作尺度需要区分!也就是需要主动自我阉割! 能说的比能写的至少严格一个等级,私密场合口耳相传的可以更接近真相! 能写出来,广泛传播的大众平台言论,都是被阉割删减过的。顶多给你一个入门的方向指引,甚至很多时候故意给你一个错误的方向误导你! 很多假话,套话,写一写,喊一喊,自己真信就是傻逼了 文学技巧 对于技术文章,是不需要什么文学技巧的,有足够的行业积累,才能够写的深入浅出! 如果你写的是头条账号,瓜田李下,下里巴人才能够吸引眼球,一些写作技巧,如适当的疑问,引用,递进,顶珠,等方法可以大大提高流量。但是,不要做标题党,广大读者包括笔者都痛恨标题党! 关于谣言 造谣一张嘴,辟谣跑断腿! 社交平台通过故意制造谣言,引起社会对立,可以极大提高平台活跃度与曝光量! Facebook 内部员工就爆料 Facebook 故意挑起种族仇恨言论(具体详情请自行搜索新闻来源)。 微博为什么是女权发源地,这与微博的故意放纵,背后资本都是相关的。 另外,有不少收钱发帖的账号! 国家应该对接受资本资助的平台账号备案,并严令禁止社交平台账号接受国外资本资助! 这种账号日常就发一些没有时间,地点,人物等详细细节的文章,引导舆论,或者文化打压,渗透! 关键这种你很难举报,博主举报了很多次,平台都说举报不成立,不算谣言!即使举报成功了,谣言也已经传播开了,对于造谣者来说也没多大损失!顶多删除一条就是,这种应该严惩的行为目前没看到什么法律法规的约束! 但是,国家早晚会对这一块整治,法律会严惩这些造谣者的!别看这些造谣者一时收黑钱一时爽,总会有清算的一天的。各位读者遇到这类文章也多点击一下举报吧,举报间谍成功奖励50W哦! 私有笔记云 平时不积累,用时方嫌少! 建立自己的知识库,就显得那么重要了 完美笔记进化论 经历了很长时间,使用了各种各样的方案,最终选择了一种相对完美的方式。docker私有部署运行的joplin,使用markdown语法,github作为图床,picgo作为图像自动上传后端,pypora作为MD编辑器,Snipaste作为截图工具。后备gitlab ee selfhost备份,自建图床VPS多线负载均衡。cloudflare partner cdn加速,jsdelivr加速。 pigo图床搭建与配置 Joplin教程 Snipaste截图工具 Typora 作为Markdown编辑器最强 完美笔记进化论 wiznote docker版作为笔记管理搜索工具,typora作为markdown编辑器,只使用markdown格式笔记,Picgo作为图上上传工具,github作为图像图床,Snippaste作为截屏工具。一起组成笔记工具链。整体免费,满足selfhost, 富文本,多平台,版本管理,目录管理,可搜索,对图像友好的苛刻要求,超越市面所有产品,wiznote 还可以对外网提供服务。 Joplin入门指南&实践方案 Joplin和使用 Joplin同步与备份 Joplin导入与导出 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin安装使用,调用外部编辑器,网盘同步等等 Joplin 插件以及其Markdown语法。All in One! Joplin简明教程 markdown语法简明教程 Joplin 插件使用推荐 教你用各种插件打造一个强大的笔记工具。 为知笔记私有化Docker部署 如何部署自己私有的为知笔记。 其实博主更推荐私有部署joplin 私有Nas 丰富自己的知识图谱! 数据最值钱,自己的数据真正属于自己的,所以你需要一个私有Nas 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 jackett 作为种子源,sonarr剧集管理,bt下载,qbittorrent主力下载,使用iyuu转移辅种,emby,jellyfin做海报墙,sunfinder自动下载字幕。基本算是完美打通全流程自动追剧。bt种子文件命名规则SxxExx的自动识别下载,国内的资源手动查找下载,自动推送到emby刮削好 结构化自己的图书,音乐,和视频! 丰富自己的见识,知识储备 如何建立自己的私人电子图书馆 图书管理员似乎是个非常有前途的职业,远的有孔子,游学之前当图书管理员,近的有本朝开国毛教员,也当了很长时间图书管理员。我们也可以自己做个私人电子图书馆,当个图书管理员,说不定很有前途? 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 音乐文件则是将歌名、歌手、专辑、发行时间、歌词、封面图等信息写入文件标签,称为ID3 Tag 。它能够在MP3中附加曲子的演出者、作者以及其它类别资讯,方便众多乐曲的管理。 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 tinyMediaManager是最好用的视频刮削工具,可以刮削电影,动画,电视剧。使用TinyMediaManager生成nfo元数据文件,多媒体软件解析生成海报墙展示丰富的影片信息,配合Emby,Plex使用体验绝佳 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 RSS订阅 一直输出知识怎么能行?身体被掏空,急需补充能量! 那么,你就需要一个好用的RSS订阅工具,TTRSS是一个好选择 RSS的使用与Tiny Tiny RSS Selfhost自建 RSS是一种消息来源的格式规范,网站可以按照这种格式规范提供文章的标题、摘要、全文等信息给订阅用户,用户可以通过订阅不同网站 RSS 链接的方式将不同的信息源进行聚合,在一个工具里阅读这些内容 博客搭建 私有博客,你值得拥有! [三万字教程]基于Hexo的matery主题搭建博客并深度优化 [三万字教程]基于Hexo的matery主题搭建博客并深度优化 一文介绍了Hexo利用github page搭建博客全过程,还附带一个博主自己定制过的`hexo Docker`,使用docker 配合博文将引导你搭建一个功能完善的blog,并指导全程免费seo优化,性能极致优化过程和工具。并附带几个常见问题的解决方案在文章最后。 hexo博客博文撰写篇之完美笔记大攻略终极完全版 hexo博客博文撰写篇之完美笔记大攻略终极完全版 hexo博客文章卷写技巧,包括MarkDown,hexo技巧,html插入,美化方法,写作方法,知识储备方法,开发工具,等一系列全介绍!终极攻略篇 系列文章 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 Gitbook使用 长篇专业电子书制作工具 当你的文章写的长了,就可以考虑用Gitbook来制作电子书了 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) 开发工具 上面都是说的写作工具,该说说开发工具了。私有建立一个完善的DevOps将极大的提高你的开发效率和能力! 自建全套开源Devops开发系统 目标:单节点,以最低成本,最低消耗,使用开源软件实现一个可用的DevOps!满足中小企业的研发、测试、运维需求。 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Docker使用 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 博客美观性 博客美观性增强方法 使用标准Markdown语法 使用hexo tag 使用 hexo 主题 tag 使用hexo 插件 特殊符号 CSS自定义 博文可迁移性 博客文章可迁移性评价 使用标准Markdown语法 少用hexo tag 少用 hexo 主题 tag 少用hexo 插件 可以说,美观和可迁移性是不可兼得的。 写作工具 工欲善其事,必先利其器 Markdown编辑器 Typora,早期beta版本免费 截图 snippaste 动图 ScreentoGIF 图床 Picgo 脑图 Draw.IO 密码同步+随机生成+保存 BitWarden Docker 图片处理 Photoshop? 笔记工具 git + gitlab docker 或者 Joplin Docker PDF 转换 Markdown , json 工具 MinerU AI 助手 熟练使用各种AI 工具可以极大的提升工作与写作体验!下面简单介绍几种 ChatGPT https://claude.ai/ ollama/ollama: 本地搭建各种大模型 Stability-AI/stablediffusion pinokiocomputer/pinokio: AI Browser 编辑器 确实,有些基于JavaScript的Markdown编辑器在处理大型文档时可能会表现出性能问题。以下是一些高性能的Markdown编辑器推荐,这些编辑器大多是桌面应用程序,通常能提供更流畅的使用体验: 1. Typora 特点: 实时预览 支持自定义主题 集成表格、图表、代码块和数学公式 无干扰的写作模式 优点:界面简洁,性能优异,支持多种导出格式。 下载:Typora 2. Mark Text 特点: 实时预览 支持CommonMark和GFM 多标签页支持 主题自定义 优点:开源,轻量且功能丰富。 下载:Mark Text 3. Obsidian 特点: 强大的链接和笔记组织功能 支持插件扩展 离线使用 实时预览和多面板支持 优点:适合笔记和知识管理,性能良好。 下载:Obsidian 4. Zettlr 特点: 专为学术写作设计 支持文献管理 实时预览 多种导出格式(如LaTeX、PDF) 优点:开源,适合长篇文档和学术写作。 下载:Zettlr 5. HedgeDoc 特点: 实时协作 支持嵌入媒体和LaTeX公式 可自托管 优点:适合团队协作,开源。 下载:HedgeDoc 6. VNote 特点: 多标签页 支持Markdown、Vim/Emacs模式 集成文件管理 实时预览和分屏模式 优点:性能稳定,适合技术写作和管理。 下载:VNote 这些Markdown编辑器大多是本地应用程序,具有更高的性能和稳定性,适合处理大型文档和复杂的写作需求。你可以根据自己的需求选择合适的编辑器。 图片上传 Picgo 截图 snipaste FastStone Capture ScreenToGif 笔记管理 Joplin 疑难杂陈 问答 1:hexo g出错怎么办? npm包升级到最新试试? npm modules 模流删除,重新安装 先移除所有文章,编译看看是否文章中出现了语法错误! 可以用二分法定位语法错误 特别注意插件tag语法是否有误 hexo或者npm包先删除编译试试 hexo,theme主题功能先零时关闭试试 问答2:笔记丢失怎么办? 使用 Git 保存 + Gitlab 服务器 使用 Joplin,没有任何限制的批量导入导出 Markdown! 不要使用任何私有格式的笔记工具,例如X知笔记 问答3:修改不生效怎么办? 本地 Docker 或者直接本地测试时,重启 hexo docker,hexo 一些修改需要下一次启动才能生效 重启电脑 如果插件问题,试着删除插件,重新安装插件测试 如果使用了 CDN 服务,在线测试时,修改不生效怎么办?清除 CDN 缓存,暂时停用 CDN(如Cloudflare),CTRL + F5 来刷新网页试试!或者检查CDN版本是否正确,如 Jsdelivr 后记 写到这篇文章,基本把博客很大部分文章都串起来了,串成了一个圆环,一颗颗珍珠终于连成一串美丽的珍珠项链。一篇篇博文不再是孤岛,而是开始连成一片大陆了。 参考 Hexo Doc 搭配 Fluid 如何优雅的写一篇文章 Hexo 搭建个人博客系列:写作技巧篇 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署

2022/8/17
articleCard.readMore

使用nodeppt给hexo博客嵌入PPT演示

给网页添加PPT演示功能,一定会炫酷到你的小伙伴,这里介绍nodeppt给hexo博客添加PPT演示功能,当然PPT演示也可以独立域名访问 插入PPT Github demo 安装nodeppt $ npm install -g nodeppt 使用nodeppt # new:使用线上模板创建一个新的 md 文件 # create a new slide with an official template $ nodeppt new slide.md # 使用模板 $ nodeppt new username/repo xxx.md # create a new slide straight from a github template $ nodeppt new slide.md -t username/repo # serve:启动一个 md 文件的 webpack dev server # start local sever show slide $ nodeppt serve slide.md # start local sever show slide with port $ nodeppt serve slide.md -p port # build:编译产出一个 md 文件 # to build a slide $ nodeppt build slide.md 生成的网页可以使用键盘操作(类似PPT操作) Page: ↑/↓/←/→ Space Home End Fullscreen: F Overview: -/+ Speaker Note: N Grid Background: Enter nodeppt 有演讲者模式,在页面 url 后面增加?mode=speaker 既可以打开演讲者模式,双屏同步 端口port的好处是可以照着官网的demo文件学习和修改,保证多个slide.md在浏览器查看时不会冲突,默认的链接是http://192.168.0.105:8080/。 官网的demo文件在Github其中的index.md。 产生pdf:直接在浏览器上command+P/ctrl+P 产生html: 之前版本通过nodeppt generate ./ppts/demo.md -a,见Github nodePPT v1.2.0 当前版本产生html利用built指令 ,例如nodeppt build slide.md,产生的html在默认文件夹dist中,包含CSS、IMG、JS三个文件夹和demo.html。 在nodeppt仓库的Issue上找到一个小哥做的爬虫程序,亲测有效。会生成一个html文件,虽然文件会大一点。不过用index.md文件实验,发现(某些)图片响应时间过长导致失败,不过自己写的markdown基本无压力转html,给小哥点大大的赞👍而且小哥表示: 之前试过直接用build,效果没问题,但build出来会有几个文件,如果通过手机或email分享出去直接播放的话稍显麻烦。 nodeppt入门 配置与hexo的post文件头一样,用yaml 语法设定基本配置 title: nodeppt markdown 演示 speaker: 三水清 url: https://github.com/ksky521/nodeppt js: - https://www.echartsjs.com/asset/theme/shine.js prismTheme: solarizedlight plugins: - echarts - mermaid - katex 正文使用<slide>对整个 markdown 文件进行拆分,拆成单页的幻灯片内容。 图片、样式、布局、icon、动画等设置可以看看仓库的文档和demo文件学习。 演讲者模式的批注通过来:::语法添加,然后再页面的链接添加?mode=speaker,按N开启演讲中模式。 :::note ## Note here ::: 踩坑 CSS样式导入失败 生成的html数学公式的格式全部错误,即使在nodeppt的配置部分引入katex的JS和CSS,导出的文档仍然会出错。 通过nodeppt build的html页面 打开生成的html文件可以看到2 <link rel="stylesheet" href="//cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="//cdn.staticfile.org/prism/1.15.0/themes/prism.min.css" /> <link rel="stylesheet" href="//cdn.staticfile.org/KaTeX/0.10.0-rc.1/katex.min.css" /> <link rel="stylesheet" href="//cdn.staticfile.org/KaTeX/0.5.1/katex.min.css" /> 只要把文件中所有//开头的都替换成http://,如 <link rel=stylesheet href=https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css> <link rel=stylesheet href=https://cdn.staticfile.org/prism/1.15.0/themes/prism.min.css> <link rel=stylesheet href=https://cdn.staticfile.org/KaTeX/0.10.0-rc.1/katex.min.css> <link rel=stylesheet href=https://cdn.staticfile.org/KaTeX/0.5.1/katex.min.css> 这样控制台就不会报错了,数学公式和fa-icon能正常显示了。 通过py程序爬的html页面 配合katex官网的使用文档,在生成的html文件<head>引用katex的JS和CSS。 <!DOCTYPE html> <!-- KaTeX requires the use of the HTML5 doctype. Without it, KaTeX may not render properly --> <html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous"> <!-- The loading of KaTeX is deferred to speed up page rendering --> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script> <!-- To automatically render math in text elements, include the auto-render extension: --> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script> </head> ... </html> 添加后公式都能正确显示了。 在博客添加nodeppt 通过py程序爬的html页面 在Hexo博客里想调用或者链接nodeppt生成的html,需要hexo设置skip_render, 指定不进行渲染的文件或文件夹,例如在source目录下新建nodeppt来存放nodeppt生成的html,则需要在根目录下的_config.yml文件添加 skip_render: - nodeppt/*.html 通过nodeppt build的html页面 skip_render: - nodeppt/** 文件匹配是基于正则匹配的,如果需要忽略全部文件(/*)、指定类型type文件(/*.type)、全部文件以及子目录(/**)以及多个文件需要用(- file/**)。 对应的文件访问格式是../../nodeppt/file.html或../../nodeppt/file/demo.html,本页演示的加载是通过iframe实现的。 <iframe src="../../nodeppt/file.html" width="100%" height="500" name="topFrame" scrolling="yes" noresize="noresize" frameborder="0" id="topFrame"></iframe> 注意:如果这一步不执行的话,debug会发现nodeppt生成的html会被hexo处理,产生错误 FATAL Something's wrong. Maybe you can find the solution here: https://hexo.io/docs/troubleshooting.html Nunjucks Error: [Line 9418, Column 3465] expected variable end 至于使用cdn来使用html似乎不行,出来的是html的源码,而不是网页。如果使用cdn的方式能成功就不用这么麻烦的skip_render。 有一种简单的方法就是用github或者coding等部署nodeppt的html,再iframe的src填对应的网址。如果hexo的skip_render设置正确,也可通过网址主页下的nodeppt下找到。 https://pxxyyz.com/nodeppt/%E5%A4%9A%E5%A4%8D%E5%8F%98%E8%BF%91%E6%9C%9F%E8%BF%9B%E5%B1%95/demo.html http://uwrfy5.coding-pages.com/ 相关项目 slidev 又一个 Web 演示PPT,基于 VUE slidev 开发相当活跃!在线试用 sli.dev/new presenterm 又一个 Web 演示PPT,基于 rust, 终端风格 presenterm A markdown terminal slideshow tool 参考 编辑整理 https://pxxyyz.com/posts/44941/ 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2022/8/11
articleCard.readMore

在 Hexo 博客中插入 ECharts 动态图表

ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的 Canvas 类库 ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。 插入 ECharts 动态图表 在 12 Best Charting Libraries for Web Developers - Christopher Watkins 一文中,博主 Christopher Watkins 向我们介绍了 12 款为网页开发者推荐的绘图库。其中不乏大名鼎鼎的 Google Charts,D3.js 和 HighCharts 这样的富图表库,还有不少其他的特型图表库,它们在展示某些特定的图表时,非常出色。百度开发维护的 ECharts 当然也在其中。 ECharts 作为国产工具,在语言上对中文开发者有着天然的优势,官方文档对每一个细节、参数、配置都有详尽的说明,对于新手非常的友好。另外一个重要的方面,就是 ECharts 的图表颜值很高,默认的主题和配色可以呈现出优雅漂亮的图表。所以,我也一直选择 ECharts 作为我的网页图表绘图工具。 Hexo 中的 ECharts npm install hexo-tag-echarts --save 注意:ECharts官网教程-[5 分钟上手 ECharts]([https://echarts.apache.org/zh/tutorial.html#5 分钟上手 ECharts](https://echarts.apache.org/zh/tutorial.html#5 分钟上手 ECharts))里的npm install echarts --save并不适合hexo博客,这种安装方式无效,请安装hexo-tag-echarts插件。 添加如下js文件 // 通过jsDelivr的CDN引入echarts <script src="https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js"></script> // 使用GL里的各种组件时需要添加,否则可不需要 <script src="https://cdn.jsdelivr.net/npm/echarts-gl@1.1.1/dist/echarts-gl.min.js"></script> 在markdown文件下添加echarts,格式如下 <script> ... </script> {% echarts 400 '85%' %} ... {% endecharts %} <script>中添加定义的变量和函数,若无设定则可删掉<script></script> {% echarts 400 '85%' %}和{% endecharts %}之间添加echarts的option 。 参数400指定图表展示的高度为400px,85%则指定图表展示的宽度为85%,如不写明这两项参数则默认值为高度400px,宽度81%。 title:标题组件,包含主标题和副标题。 legend:图例组件。 tooltip:提示框组件。 toolbox:工具栏。内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具。 xAxis、yAxis:直角坐标系 grid 中的 x 轴、y轴。 series:系列列表。每个系列通过type决定自己的图表类型。 series-line:折线/面积图 series-bar:柱状/条形图 series-pie:饼图 series-scatter:散点图 series-radar:雷达图 series-tree:树图 series-boxplot:箱形图 series-candlestick:K线图 series-heatmap:热力图 series-graph:关系图 多个图表的数据和函数可能会冲突,请注意! 直接在html中直接绘制,然后用<iframe></iframe>展示效果更佳。关于hexo的html文件渲染问题,可以参考Fluid+自定义html,主要是去掉head部分的说明。 在html绘图ECharts的格式如下: <script src="https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"></script> <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --> <div id="main" style="width: 600px;height:400px;"></div> <script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 指定图表的配置项和数据 var option = { ... }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); // 刷新调整 window.onresize = function () { myChart.resize(); } </script>Copy 部分echart需要引入其他js,如bmap、jquery等,请自行添加。 使用百度地图的api需要申请密钥(ak),使用格式如下,注意替换FAKE_AK。 <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=FAKE_AK"></script> <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=2.0&ak=FAKE_AK"></script>Copy 实例 下面给出一些echarts官方实例,大多数都可以交互。 折线图Line Stacked area chart // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts8715')); // 指定图表的配置项和数据 var option = option = { title: { text: '堆叠区域图' }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } } }, legend: { data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'] }, toolbox: { feature: { saveAsImage: {} } }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: [ { type: 'category', boundaryGap: false, data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] } ], yAxis: [ { type: 'value' } ], series: [ { name: '邮件营销', type: 'line', stack: '总量', areaStyle: {}, data: [120, 132, 101, 134, 90, 230, 210] }, { name: '联盟广告', type: 'line', stack: '总量', areaStyle: {}, data: [220, 182, 191, 234, 290, 330, 310] }, { name: '视频广告', type: 'line', stack: '总量', areaStyle: {}, data: [150, 232, 201, 154, 190, 330, 410] }, { name: '直接访问', type: 'line', stack: '总量', areaStyle: {}, data: [320, 332, 301, 334, 390, 330, 320] }, { name: '搜索引擎', type: 'line', stack: '总量', label: { normal: { show: true, position: 'top' } }, areaStyle: {}, data: [820, 932, 901, 934, 1290, 1330, 1320] } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); Area Pieces // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts5401')); // 指定图表的配置项和数据 var option = option = { xAxis: { type: 'category', boundaryGap: false }, yAxis: { type: 'value', boundaryGap: [0, '30%'] }, visualMap: { type: 'piecewise', show: false, dimension: 0, seriesIndex: 0, pieces: [{ gt: 1, lt: 3, color: 'rgba(0, 180, 0, 0.5)' }, { gt: 5, lt: 7, color: 'rgba(0, 180, 0, 0.5)' }] }, series: [ { type: 'line', smooth: 0.6, symbol: 'none', lineStyle: { color: 'green', width: 5 }, markLine: { symbol: ['none', 'none'], label: {show: false}, data: [ {xAxis: 1}, {xAxis: 3}, {xAxis: 5}, {xAxis: 7} ] }, areaStyle: {}, data: [ ['2019-10-10', 200], ['2019-10-11', 400], ['2019-10-12', 650], ['2019-10-13', 500], ['2019-10-14', 250], ['2019-10-15', 300], ['2019-10-16', 450], ['2019-10-17', 300], ['2019-10-18', 100] ] } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); Rainfall // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts2017')); // 指定图表的配置项和数据 var option = option = { title: { text: '雨量流量关系图', subtext: '数据来自西安兰特水电测控技术有限公司', left: 'center', align: 'right' }, grid: { bottom: 80 }, toolbox: { feature: { dataZoom: { yAxisIndex: 'none' }, restore: {}, saveAsImage: {} } }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', animation: false, label: { backgroundColor: '#505765' } } }, legend: { data: ['流量', '降雨量'], left: 10 }, dataZoom: [ { show: true, realtime: true, start: 65, end: 85 }, { type: 'inside', realtime: true, start: 65, end: 85 } ], xAxis: [ { type: 'category', boundaryGap: false, axisLine: {onZero: false}, data: [ '2009/6/12 2:00', '2009/6/12 3:00', '2009/6/12 4:00', '2009/6/12 5:00', '2009/6/12 6:00', '2009/6/12 7:00', '2009/6/12 8:00', '2009/6/12 9:00', '2009/6/12 10:00', '2009/6/12 11:00', '2009/6/12 12:00', '2009/6/12 13:00', '2009/6/12 14:00', '2009/6/12 15:00', '2009/6/12 16:00', '2009/6/12 17:00', '2009/6/12 18:00', '2009/6/12 19:00', '2009/6/12 20:00', '2009/6/12 21:00', '2009/6/12 22:00', '2009/6/12 23:00', '2009/6/13 0:00', '2009/6/13 1:00', '2009/6/13 2:00', '2009/6/13 3:00', '2009/6/13 4:00', '2009/6/13 5:00', '2009/6/13 6:00', '2009/6/13 7:00', '2009/6/13 8:00', '2009/6/13 9:00', '2009/6/13 10:00', '2009/6/13 11:00', '2009/6/13 12:00', '2009/6/13 13:00', '2009/6/13 14:00', '2009/6/13 15:00', '2009/6/13 16:00', '2009/6/13 17:00', '2009/6/13 18:00', '2009/6/13 19:00', '2009/6/13 20:00', '2009/6/13 21:00', '2009/6/13 22:00', '2009/6/13 23:00', '2009/6/14 0:00', '2009/6/14 1:00', '2009/6/14 2:00', '2009/6/14 3:00', '2009/6/14 4:00', '2009/6/14 5:00', '2009/6/14 6:00', '2009/6/14 7:00', '2009/6/14 8:00', '2009/6/14 9:00', '2009/6/14 10:00', '2009/6/14 11:00', '2009/6/14 12:00', '2009/6/14 13:00', '2009/6/14 14:00', '2009/6/14 15:00', '2009/6/14 16:00', '2009/6/14 17:00', '2009/6/14 18:00', '2009/6/14 19:00', '2009/6/14 20:00', '2009/6/14 21:00', '2009/6/14 22:00', '2009/6/14 23:00', '2009/6/15 0:00', '2009/6/15 1:00', '2009/6/15 2:00', '2009/6/15 3:00', '2009/6/15 4:00', '2009/6/15 5:00', '2009/6/15 6:00', '2009/6/15 7:00', '2009/6/15 8:00', '2009/6/15 9:00', '2009/6/15 10:00', '2009/6/15 11:00', '2009/6/15 12:00', '2009/6/15 13:00', '2009/6/15 14:00', '2009/6/15 15:00', '2009/6/15 16:00', '2009/6/15 17:00', '2009/6/15 18:00', '2009/6/15 19:00', '2009/6/15 20:00', '2009/6/15 21:00', '2009/6/15 22:00', '2009/6/15 23:00', '2009/6/15 0:00', '2009/6/16 1:00', '2009/6/16 2:00', '2009/6/16 3:00', '2009/6/16 4:00', '2009/6/16 5:00', '2009/6/16 6:00', '2009/6/16 7:00', '2009/6/16 8:00', '2009/6/16 9:00', '2009/6/16 10:00', '2009/6/16 11:00', '2009/6/16 12:00', '2009/6/16 13:00', '2009/6/16 14:00', '2009/6/16 15:00', '2009/6/16 16:00', '2009/6/16 17:00', '2009/6/16 18:00', '2009/6/16 19:00', '2009/6/16 20:00', '2009/6/16 21:00', '2009/6/16 22:00', '2009/6/16 23:00', '2009/6/15 0:00', '2009/6/17 1:00', '2009/6/17 2:00', '2009/6/17 3:00', '2009/6/17 4:00', '2009/6/17 5:00', '2009/6/17 6:00', '2009/6/17 7:00', '2009/6/17 8:00', '2009/6/17 9:00', '2009/6/17 10:00', '2009/6/17 11:00', '2009/6/17 12:00', '2009/6/17 13:00', '2009/6/17 14:00', '2009/6/17 15:00', '2009/6/17 16:00', '2009/6/17 17:00', '2009/6/17 18:00', '2009/6/17 19:00', '2009/6/17 20:00', '2009/6/17 21:00', '2009/6/17 22:00', '2009/6/17 23:00', '2009/6/18 0:00', '2009/6/18 1:00', '2009/6/18 2:00', '2009/6/18 3:00', '2009/6/18 4:00', '2009/6/18 5:00', '2009/6/18 6:00', '2009/6/18 7:00', '2009/6/18 8:00', '2009/6/18 9:00', '2009/6/18 10:00', '2009/6/18 11:00', '2009/6/18 12:00', '2009/6/18 13:00', '2009/6/18 14:00', '2009/6/18 15:00', '2009/6/18 16:00', '2009/6/18 17:00', '2009/6/18 18:00', '2009/6/18 19:00', '2009/6/18 20:00', '2009/6/18 21:00', '2009/6/18 22:00', '2009/6/18 23:00', '2009/6/15 0:00', '2009/6/19 1:00', '2009/6/19 2:00', '2009/6/19 3:00', '2009/6/19 4:00', '2009/6/19 5:00', '2009/6/19 6:00', '2009/6/19 7:00', '2009/6/19 8:00', '2009/6/19 9:00', '2009/6/19 10:00', '2009/6/19 11:00', '2009/6/19 12:00', '2009/6/19 13:00', '2009/6/19 14:00', '2009/6/19 15:00', '2009/6/19 16:00', '2009/6/19 17:00', '2009/6/19 18:00', '2009/6/19 19:00', '2009/6/19 20:00', '2009/6/19 21:00', '2009/6/19 22:00', '2009/6/19 23:00', '2009/6/20 0:00', '2009/6/20 1:00', '2009/6/20 2:00', '2009/6/20 3:00', '2009/6/20 4:00', '2009/6/20 5:00', '2009/6/20 6:00', '2009/6/20 7:00', '2009/6/20 8:00', '2009/6/20 9:00', '2009/6/20 10:00', '2009/6/20 11:00', '2009/6/20 12:00', '2009/6/20 13:00', '2009/6/20 14:00', '2009/6/20 15:00', '2009/6/20 16:00', '2009/6/20 17:00', '2009/6/20 18:00', '2009/6/20 19:00', '2009/6/20 20:00', '2009/6/20 21:00', '2009/6/20 22:00', '2009/6/20 23:00', '2009/6/21 0:00', '2009/6/21 1:00', '2009/6/21 2:00', '2009/6/21 3:00', '2009/6/21 4:00', '2009/6/21 5:00', '2009/6/21 6:00', '2009/6/21 7:00', '2009/6/21 8:00', '2009/6/21 9:00', '2009/6/21 10:00', '2009/6/21 11:00', '2009/6/21 12:00', '2009/6/21 13:00', '2009/6/21 14:00', '2009/6/21 15:00', '2009/6/21 16:00', '2009/6/21 17:00', '2009/6/21 18:00', '2009/6/21 19:00', '2009/6/21 20:00', '2009/6/21 21:00', '2009/6/21 22:00', '2009/6/21 23:00', '2009/6/22 0:00', '2009/6/22 1:00', '2009/6/22 2:00', '2009/6/22 3:00', '2009/6/22 4:00', '2009/6/22 5:00', '2009/6/22 6:00', '2009/6/22 7:00', '2009/6/22 8:00', '2009/6/22 9:00', '2009/6/22 10:00', '2009/6/22 11:00', '2009/6/22 12:00', '2009/6/22 13:00', '2009/6/22 14:00', '2009/6/22 15:00', '2009/6/22 16:00', '2009/6/22 17:00', '2009/6/22 18:00', '2009/6/22 19:00', '2009/6/22 20:00', '2009/6/22 21:00', '2009/6/22 22:00', '2009/6/22 23:00', '2009/6/23 0:00', '2009/6/23 1:00', '2009/6/23 2:00', '2009/6/23 3:00', '2009/6/23 4:00', '2009/6/23 5:00', '2009/6/23 6:00', '2009/6/23 7:00', '2009/6/23 8:00', '2009/6/23 9:00', '2009/6/23 10:00', '2009/6/23 11:00', '2009/6/23 12:00', '2009/6/23 13:00', '2009/6/23 14:00', '2009/6/23 15:00', '2009/6/23 16:00', '2009/6/23 17:00', '2009/6/23 18:00', '2009/6/23 19:00', '2009/6/23 20:00', '2009/6/23 21:00', '2009/6/23 22:00', '2009/6/23 23:00', '2009/6/24 0:00', '2009/6/24 1:00', '2009/6/24 2:00', '2009/6/24 3:00', '2009/6/24 4:00', '2009/6/24 5:00', '2009/6/24 6:00', '2009/6/24 7:00', '2009/6/24 8:00', '2009/6/24 9:00', '2009/6/24 10:00', '2009/6/24 11:00', '2009/6/24 12:00', '2009/6/24 13:00', '2009/6/24 14:00', '2009/6/24 15:00', '2009/6/24 16:00', '2009/6/24 17:00', '2009/6/24 18:00', '2009/6/24 19:00', '2009/6/24 20:00', '2009/6/24 21:00', '2009/6/24 22:00', '2009/6/24 23:00', '2009/6/25 0:00', '2009/6/25 1:00', '2009/6/25 2:00', '2009/6/25 3:00', '2009/6/25 4:00', '2009/6/25 5:00', '2009/6/25 6:00', '2009/6/25 7:00', '2009/6/25 8:00', '2009/6/25 9:00', '2009/6/25 10:00', '2009/6/25 11:00', '2009/6/25 12:00', '2009/6/25 13:00', '2009/6/25 14:00', '2009/6/25 15:00', '2009/6/25 16:00', '2009/6/25 17:00', '2009/6/25 18:00', '2009/6/25 19:00', '2009/6/25 20:00', '2009/6/25 21:00', '2009/6/25 22:00', '2009/6/25 23:00', '2009/6/26 0:00', '2009/6/26 1:00', '2009/6/26 2:00', '2009/6/26 3:00', '2009/6/26 4:00', '2009/6/26 5:00', '2009/6/26 6:00', '2009/6/26 7:00', '2009/6/26 8:00', '2009/6/26 9:00', '2009/6/26 10:00', '2009/6/26 11:00', '2009/6/26 12:00', '2009/6/26 13:00', '2009/6/26 14:00', '2009/6/26 15:00', '2009/6/26 16:00', '2009/6/26 17:00', '2009/6/26 18:00', '2009/6/26 19:00', '2009/6/26 20:00', '2009/6/26 21:00', '2009/6/26 22:00', '2009/6/26 23:00', '2009/6/27 0:00', '2009/6/27 1:00', '2009/6/27 2:00', '2009/6/27 3:00', '2009/6/27 4:00', '2009/6/27 5:00', '2009/6/27 6:00', '2009/6/27 7:00', '2009/6/27 8:00', '2009/6/27 9:00', '2009/6/27 10:00', '2009/6/27 11:00', '2009/6/27 12:00', '2009/6/27 13:00', '2009/6/27 14:00', '2009/6/27 15:00', '2009/6/27 16:00', '2009/6/27 17:00', '2009/6/27 18:00', '2009/6/27 19:00', '2009/6/27 20:00', '2009/6/27 21:00', '2009/6/27 22:00', '2009/6/27 23:00', '2009/6/28 0:00', '2009/6/28 1:00', '2009/6/28 2:00', '2009/6/28 3:00', '2009/6/28 4:00', '2009/6/28 5:00', '2009/6/28 6:00', '2009/6/28 7:00', '2009/6/28 8:00', '2009/6/28 9:00', '2009/6/28 10:00', '2009/6/28 11:00', '2009/6/28 12:00', '2009/6/28 13:00', '2009/6/28 14:00', '2009/6/28 15:00', '2009/6/28 16:00', '2009/6/28 17:00', '2009/6/28 18:00', '2009/6/28 19:00', '2009/6/28 20:00', '2009/6/28 21:00', '2009/6/28 22:00', '2009/6/28 23:00', '2009/6/29 0:00', '2009/6/29 1:00', '2009/6/29 2:00', '2009/6/29 3:00', '2009/6/29 4:00', '2009/6/29 5:00', '2009/6/29 6:00', '2009/6/29 7:00', '2009/6/29 8:00', '2009/6/29 9:00', '2009/6/29 10:00', '2009/6/29 11:00', '2009/6/29 12:00', '2009/6/29 13:00', '2009/6/29 14:00', '2009/6/29 15:00', '2009/6/29 16:00', '2009/6/29 17:00', '2009/6/29 18:00', '2009/6/29 19:00', '2009/6/29 20:00', '2009/6/29 21:00', '2009/6/29 22:00', '2009/6/29 23:00', '2009/6/30 0:00', '2009/6/30 1:00', '2009/6/30 2:00', '2009/6/30 3:00', '2009/6/30 4:00', '2009/6/30 5:00', '2009/6/30 6:00', '2009/6/30 7:00', '2009/6/30 8:00', '2009/6/30 9:00', '2009/6/30 10:00', '2009/6/30 11:00', '2009/6/30 12:00', '2009/6/30 13:00', '2009/6/30 14:00', '2009/6/30 15:00', '2009/6/30 16:00', '2009/6/30 17:00', '2009/6/30 18:00', '2009/6/30 19:00', '2009/6/30 20:00', '2009/6/30 21:00', '2009/6/30 22:00', '2009/6/30 23:00', '2009/7/1 0:00', '2009/7/1 1:00', '2009/7/1 2:00', '2009/7/1 3:00', '2009/7/1 4:00', '2009/7/1 5:00', '2009/7/1 6:00', '2009/7/1 7:00', '2009/7/1 8:00', '2009/7/1 9:00', '2009/7/1 10:00', '2009/7/1 11:00', '2009/7/1 12:00', '2009/7/1 13:00', '2009/7/1 14:00', '2009/7/1 15:00', '2009/7/1 16:00', '2009/7/1 17:00', '2009/7/1 18:00', '2009/7/1 19:00', '2009/7/1 20:00', '2009/7/1 21:00', '2009/7/1 22:00', '2009/7/1 23:00', '2009/7/2 0:00', '2009/7/2 1:00', '2009/7/2 2:00', '2009/7/2 3:00', '2009/7/2 4:00', '2009/7/2 5:00', '2009/7/2 6:00', '2009/7/2 7:00', '2009/7/2 8:00', '2009/7/2 9:00', '2009/7/2 10:00', '2009/7/2 11:00', '2009/7/2 12:00', '2009/7/2 13:00', '2009/7/2 14:00', '2009/7/2 15:00', '2009/7/2 16:00', '2009/7/2 17:00', '2009/7/2 18:00', '2009/7/2 19:00', '2009/7/2 20:00', '2009/7/2 21:00', '2009/7/2 22:00', '2009/7/2 23:00', '2009/7/3 0:00', '2009/7/3 1:00', '2009/7/3 2:00', '2009/7/3 3:00', '2009/7/3 4:00', '2009/7/3 5:00', '2009/7/3 6:00', '2009/7/3 7:00', '2009/7/3 8:00', '2009/7/3 9:00', '2009/7/3 10:00', '2009/7/3 11:00', '2009/7/3 12:00', '2009/7/3 13:00', '2009/7/3 14:00', '2009/7/3 15:00', '2009/7/3 16:00', '2009/7/3 17:00', '2009/7/3 18:00', '2009/7/3 19:00', '2009/7/3 20:00', '2009/7/3 21:00', '2009/7/3 22:00', '2009/7/3 23:00', '2009/7/4 0:00', '2009/7/4 1:00', '2009/7/4 2:00', '2009/7/4 3:00', '2009/7/4 4:00', '2009/7/4 5:00', '2009/7/4 6:00', '2009/7/4 7:00', '2009/7/4 8:00', '2009/7/4 9:00', '2009/7/4 10:00', '2009/7/4 11:00', '2009/7/4 12:00', '2009/7/4 13:00', '2009/7/4 14:00', '2009/7/4 15:00', '2009/7/4 16:00', '2009/7/4 17:00', '2009/7/4 18:00', '2009/7/4 19:00', '2009/7/4 20:00', '2009/7/4 21:00', '2009/7/4 22:00', '2009/7/4 23:00', '2009/7/5 0:00', '2009/7/5 1:00', '2009/7/5 2:00', '2009/7/5 3:00', '2009/7/5 4:00', '2009/7/5 5:00', '2009/7/5 6:00', '2009/7/5 7:00', '2009/7/5 8:00', '2009/7/5 9:00', '2009/7/5 10:00', '2009/7/5 11:00', '2009/7/5 12:00', '2009/7/5 13:00', '2009/7/5 14:00', '2009/7/5 15:00', '2009/7/5 16:00', '2009/7/5 17:00', '2009/7/5 18:00', '2009/7/5 19:00', '2009/7/5 20:00', '2009/7/5 21:00', '2009/7/5 22:00', '2009/7/5 23:00', '2009/7/6 0:00', '2009/7/6 1:00', '2009/7/6 2:00', '2009/7/6 3:00', '2009/7/6 4:00', '2009/7/6 5:00', '2009/7/6 6:00', '2009/7/6 7:00', '2009/7/6 8:00', '2009/7/6 9:00', '2009/7/6 10:00', '2009/7/6 11:00', '2009/7/6 12:00', '2009/7/6 13:00', '2009/7/6 14:00', '2009/7/6 15:00', '2009/7/6 16:00', '2009/7/6 17:00', '2009/7/6 18:00', '2009/7/6 19:00', '2009/7/6 20:00', '2009/7/6 21:00', '2009/7/6 22:00', '2009/7/6 23:00', '2009/7/7 0:00', '2009/7/7 1:00', '2009/7/7 2:00', '2009/7/7 3:00', '2009/7/7 4:00', '2009/7/7 5:00', '2009/7/7 6:00', '2009/7/7 7:00', '2009/7/7 8:00', '2009/7/7 9:00', '2009/7/7 10:00', '2009/7/7 11:00', '2009/7/7 12:00', '2009/7/7 13:00', '2009/7/7 14:00', '2009/7/7 15:00', '2009/7/7 16:00', '2009/7/7 17:00', '2009/7/7 18:00', '2009/7/7 19:00', '2009/7/7 20:00', '2009/7/7 21:00', '2009/7/7 22:00', '2009/7/7 23:00', '2009/7/8 0:00', '2009/7/8 1:00', '2009/7/8 2:00', '2009/7/8 3:00', '2009/7/8 4:00', '2009/7/8 5:00', '2009/7/8 6:00', '2009/7/8 7:00', '2009/7/8 8:00', '2009/7/8 9:00', '2009/7/8 10:00', '2009/7/8 11:00', '2009/7/8 12:00', '2009/7/8 13:00', '2009/7/8 14:00', '2009/7/8 15:00', '2009/7/8 16:00', '2009/7/8 17:00', '2009/7/8 18:00', '2009/7/8 19:00', '2009/7/8 20:00', '2009/7/8 21:00', '2009/7/8 22:00', '2009/7/8 23:00', '2009/7/9 0:00', '2009/7/9 1:00', '2009/7/9 2:00', '2009/7/9 3:00', '2009/7/9 4:00', '2009/7/9 5:00', '2009/7/9 6:00', '2009/7/9 7:00', '2009/7/9 8:00', '2009/7/9 9:00', '2009/7/9 10:00', '2009/7/9 11:00', '2009/7/9 12:00', '2009/7/9 13:00', '2009/7/9 14:00', '2009/7/9 15:00', '2009/7/9 16:00', '2009/7/9 17:00', '2009/7/9 18:00', '2009/7/9 19:00', '2009/7/9 20:00', '2009/7/9 21:00', '2009/7/9 22:00', '2009/7/9 23:00', '2009/7/10 0:00', '2009/7/10 1:00', '2009/7/10 2:00', '2009/7/10 3:00', '2009/7/10 4:00', '2009/7/10 5:00', '2009/7/10 6:00', '2009/7/10 7:00', '2009/7/10 8:00', '2009/7/10 9:00', '2009/7/10 10:00', '2009/7/10 11:00', '2009/7/10 12:00', '2009/7/10 13:00', '2009/7/10 14:00', '2009/7/10 15:00', '2009/7/10 16:00', '2009/7/10 17:00', '2009/7/10 18:00', '2009/7/10 19:00', '2009/7/10 20:00', '2009/7/10 21:00', '2009/7/10 22:00', '2009/7/10 23:00', '2009/7/11 0:00', '2009/7/11 1:00', '2009/7/11 2:00', '2009/7/11 3:00', '2009/7/11 4:00', '2009/7/11 5:00', '2009/7/11 6:00', '2009/7/11 7:00', '2009/7/11 8:00', '2009/7/11 9:00', '2009/7/11 10:00', '2009/7/11 11:00', '2009/7/11 12:00', '2009/7/11 13:00', '2009/7/11 14:00', '2009/7/11 15:00', '2009/7/11 16:00', '2009/7/11 17:00', '2009/7/11 18:00', '2009/7/11 19:00', '2009/7/11 20:00', '2009/7/11 21:00', '2009/7/11 22:00', '2009/7/11 23:00', '2009/7/12 0:00', '2009/7/12 1:00', '2009/7/12 2:00', '2009/7/12 3:00', '2009/7/12 4:00', '2009/7/12 5:00', '2009/7/12 6:00', '2009/7/12 7:00', '2009/7/12 8:00', '2009/7/12 9:00', '2009/7/12 10:00', '2009/7/12 11:00', '2009/7/12 12:00', '2009/7/12 13:00', '2009/7/12 14:00', '2009/7/12 15:00', '2009/7/12 16:00', '2009/7/12 17:00', '2009/7/12 18:00', '2009/7/12 19:00', '2009/7/12 20:00', '2009/7/12 21:00', '2009/7/12 22:00', '2009/7/12 23:00', '2009/7/13 0:00', '2009/7/13 1:00', '2009/7/13 2:00', '2009/7/13 3:00', '2009/7/13 4:00', '2009/7/13 5:00', '2009/7/13 6:00', '2009/7/13 7:00', '2009/7/13 8:00', '2009/7/13 9:00', '2009/7/13 10:00', '2009/7/13 11:00', '2009/7/13 12:00', '2009/7/13 13:00', '2009/7/13 14:00', '2009/7/13 15:00', '2009/7/13 16:00', '2009/7/13 17:00', '2009/7/13 18:00', '2009/7/13 19:00', '2009/7/13 20:00', '2009/7/13 21:00', '2009/7/13 22:00', '2009/7/13 23:00', '2009/7/14 0:00', '2009/7/14 1:00', '2009/7/14 2:00', '2009/7/14 3:00', '2009/7/14 4:00', '2009/7/14 5:00', '2009/7/14 6:00', '2009/7/14 7:00', '2009/7/14 8:00', '2009/7/14 9:00', '2009/7/14 10:00', '2009/7/14 11:00', '2009/7/14 12:00', '2009/7/14 13:00', '2009/7/14 14:00', '2009/7/14 15:00', '2009/7/14 16:00', '2009/7/14 17:00', '2009/7/14 18:00', '2009/7/14 19:00', '2009/7/14 20:00', '2009/7/14 21:00', '2009/7/14 22:00', '2009/7/14 23:00', '2009/7/15 0:00', '2009/7/15 1:00', '2009/7/15 2:00', '2009/7/15 3:00', '2009/7/15 4:00', '2009/7/15 5:00', '2009/7/15 6:00', '2009/7/15 7:00', '2009/7/15 8:00', '2009/7/15 9:00', '2009/7/15 10:00', '2009/7/15 11:00', '2009/7/15 12:00', '2009/7/15 13:00', '2009/7/15 14:00', '2009/7/15 15:00', '2009/7/15 16:00', '2009/7/15 17:00', '2009/7/15 18:00', '2009/7/15 19:00', '2009/7/15 20:00', '2009/7/15 21:00', '2009/7/15 22:00', '2009/7/15 23:00', '2009/7/16 0:00', '2009/7/16 1:00', '2009/7/16 2:00', '2009/7/16 3:00', '2009/7/16 4:00', '2009/7/16 5:00', '2009/7/16 6:00', '2009/7/16 7:00', '2009/7/16 8:00', '2009/7/16 9:00', '2009/7/16 10:00', '2009/7/16 11:00', '2009/7/16 12:00', '2009/7/16 13:00', '2009/7/16 14:00', '2009/7/16 15:00', '2009/7/16 16:00', '2009/7/16 17:00', '2009/7/16 18:00', '2009/7/16 19:00', '2009/7/16 20:00', '2009/7/16 21:00', '2009/7/16 22:00', '2009/7/16 23:00', '2009/7/17 0:00', '2009/7/17 1:00', '2009/7/17 2:00', '2009/7/17 3:00', '2009/7/17 4:00', '2009/7/17 5:00', '2009/7/17 6:00', '2009/7/17 7:00', '2009/7/17 8:00', '2009/7/17 9:00', '2009/7/17 10:00', '2009/7/17 11:00', '2009/7/17 12:00', '2009/7/17 13:00', '2009/7/17 14:00', '2009/7/17 15:00', '2009/7/17 16:00', '2009/7/17 17:00', '2009/7/17 18:00', '2009/7/17 19:00', '2009/7/17 20:00', '2009/7/17 21:00', '2009/7/17 22:00', '2009/7/17 23:00', '2009/7/18 0:00', '2009/7/18 1:00', '2009/7/18 2:00', '2009/7/18 3:00', '2009/7/18 4:00', '2009/7/18 5:00', '2009/7/18 6:00', '2009/7/18 7:00', '2009/7/18 8:00', '2009/7/18 9:00', '2009/7/18 10:00', '2009/7/18 11:00', '2009/7/18 12:00', '2009/7/18 13:00', '2009/7/18 14:00', '2009/7/18 15:00', '2009/7/18 16:00', '2009/7/18 17:00', '2009/7/18 18:00', '2009/7/18 19:00', '2009/7/18 20:00', '2009/7/18 21:00', '2009/7/18 22:00', '2009/7/18 23:00', '2009/7/19 0:00', '2009/7/19 1:00', '2009/7/19 2:00', '2009/7/19 3:00', '2009/7/19 4:00', '2009/7/19 5:00', '2009/7/19 6:00', '2009/7/19 7:00', '2009/7/19 8:00', '2009/7/19 9:00', '2009/7/19 10:00', '2009/7/19 11:00', '2009/7/19 12:00', '2009/7/19 13:00', '2009/7/19 14:00', '2009/7/19 15:00', '2009/7/19 16:00', '2009/7/19 17:00', '2009/7/19 18:00', '2009/7/19 19:00', '2009/7/19 20:00', '2009/7/19 21:00', '2009/7/19 22:00', '2009/7/19 23:00', '2009/7/20 0:00', '2009/7/20 1:00', '2009/7/20 2:00', '2009/7/20 3:00', '2009/7/20 4:00', '2009/7/20 5:00', '2009/7/20 6:00', '2009/7/20 7:00', '2009/7/20 8:00', '2009/7/20 9:00', '2009/7/20 10:00', '2009/7/20 11:00', '2009/7/20 12:00', '2009/7/20 13:00', '2009/7/20 14:00', '2009/7/20 15:00', '2009/7/20 16:00', '2009/7/20 17:00', '2009/7/20 18:00', '2009/7/20 19:00', '2009/7/20 20:00', '2009/7/20 21:00', '2009/7/20 22:00', '2009/7/20 23:00', '2009/7/21 0:00', '2009/7/21 1:00', '2009/7/21 2:00', '2009/7/21 3:00', '2009/7/21 4:00', '2009/7/21 5:00', '2009/7/21 6:00', '2009/7/21 7:00', '2009/7/21 8:00', '2009/7/21 9:00', '2009/7/21 10:00', '2009/7/21 11:00', '2009/7/21 12:00', '2009/7/21 13:00', '2009/7/21 14:00', '2009/7/21 15:00', '2009/7/21 16:00', '2009/7/21 17:00', '2009/7/21 18:00', '2009/7/21 19:00', '2009/7/21 20:00', '2009/7/21 21:00', '2009/7/21 22:00', '2009/7/21 23:00', '2009/7/22 0:00', '2009/7/22 1:00', '2009/7/22 2:00', '2009/7/22 3:00', '2009/7/22 4:00', '2009/7/22 5:00', '2009/7/22 6:00', '2009/7/22 7:00', '2009/7/22 8:00', '2009/7/22 9:00', '2009/7/22 10:00', '2009/7/22 11:00', '2009/7/22 12:00', '2009/7/22 13:00', '2009/7/22 14:00', '2009/7/22 15:00', '2009/7/22 16:00', '2009/7/22 17:00', '2009/7/22 18:00', '2009/7/22 19:00', '2009/7/22 20:00', '2009/7/22 21:00', '2009/7/22 22:00', '2009/7/22 23:00', '2009/7/23 0:00', '2009/7/23 1:00', '2009/7/23 2:00', '2009/7/23 3:00', '2009/7/23 4:00', '2009/7/23 5:00', '2009/7/23 6:00', '2009/7/23 7:00', '2009/7/23 8:00', '2009/7/23 9:00', '2009/7/23 10:00', '2009/7/23 11:00', '2009/7/23 12:00', '2009/7/23 13:00', '2009/7/23 14:00', '2009/7/23 15:00', '2009/7/23 16:00', '2009/7/23 17:00', '2009/7/23 18:00', '2009/7/23 19:00', '2009/7/23 20:00', '2009/7/23 21:00', '2009/7/23 22:00', '2009/7/23 23:00', '2009/7/24 0:00', '2009/7/24 1:00', '2009/7/24 2:00', '2009/7/24 3:00', '2009/7/24 4:00', '2009/7/24 5:00', '2009/7/24 6:00', '2009/7/24 7:00', '2009/7/24 8:00', '2009/7/24 9:00', '2009/7/24 10:00', '2009/7/24 11:00', '2009/7/24 12:00', '2009/7/24 13:00', '2009/7/24 14:00', '2009/7/24 15:00', '2009/7/24 16:00', '2009/7/24 17:00', '2009/7/24 18:00', '2009/7/24 19:00', '2009/7/24 20:00', '2009/7/24 21:00', '2009/7/24 22:00', '2009/7/24 23:00', '2009/7/25 0:00', '2009/7/25 1:00', '2009/7/25 2:00', '2009/7/25 3:00', '2009/7/25 4:00', '2009/7/25 5:00', '2009/7/25 6:00', '2009/7/25 7:00', '2009/7/25 8:00', '2009/7/25 9:00', '2009/7/25 10:00', '2009/7/25 11:00', '2009/7/25 12:00', '2009/7/25 13:00', '2009/7/25 14:00', '2009/7/25 15:00', '2009/7/25 16:00', '2009/7/25 17:00', '2009/7/25 18:00', '2009/7/25 19:00', '2009/7/25 20:00', '2009/7/25 21:00', '2009/7/25 22:00', '2009/7/25 23:00', '2009/7/26 0:00', '2009/7/26 1:00', '2009/7/26 2:00', '2009/7/26 3:00', '2009/7/26 4:00', '2009/7/26 5:00', '2009/7/26 6:00', '2009/7/26 7:00', '2009/7/26 8:00', '2009/7/26 9:00', '2009/7/26 10:00', '2009/7/26 11:00', '2009/7/26 12:00', '2009/7/26 13:00', '2009/7/26 14:00', '2009/7/26 15:00', '2009/7/26 16:00', '2009/7/26 17:00', '2009/7/26 18:00', '2009/7/26 19:00', '2009/7/26 20:00', '2009/7/26 21:00', '2009/7/26 22:00', '2009/7/26 23:00', '2009/7/27 0:00', '2009/7/27 1:00', '2009/7/27 2:00', '2009/7/27 3:00', '2009/7/27 4:00', '2009/7/27 5:00', '2009/7/27 6:00', '2009/7/27 7:00', '2009/7/27 8:00', '2009/7/27 9:00', '2009/7/27 10:00', '2009/7/27 11:00', '2009/7/27 12:00', '2009/7/27 13:00', '2009/7/27 14:00', '2009/7/27 15:00', '2009/7/27 16:00', '2009/7/27 17:00', '2009/7/27 18:00', '2009/7/27 19:00', '2009/7/27 20:00', '2009/7/27 21:00', '2009/7/27 22:00', '2009/7/27 23:00', '2009/7/28 0:00', '2009/7/28 1:00', '2009/7/28 2:00', '2009/7/28 3:00', '2009/7/28 4:00', '2009/7/28 5:00', '2009/7/28 6:00', '2009/7/28 7:00', '2009/7/28 8:00', '2009/7/28 9:00', '2009/7/28 10:00', '2009/7/28 11:00', '2009/7/28 12:00', '2009/7/28 13:00', '2009/7/28 14:00', '2009/7/28 15:00', '2009/7/28 16:00', '2009/7/28 17:00', '2009/7/28 18:00', '2009/7/28 19:00', '2009/7/28 20:00', '2009/7/28 21:00', '2009/7/28 22:00', '2009/7/28 23:00', '2009/7/29 0:00', '2009/7/29 1:00', '2009/7/29 2:00', '2009/7/29 3:00', '2009/7/29 4:00', '2009/7/29 5:00', '2009/7/29 6:00', '2009/7/29 7:00', '2009/7/29 8:00', '2009/7/29 9:00', '2009/7/29 10:00', '2009/7/29 11:00', '2009/7/29 12:00', '2009/7/29 13:00', '2009/7/29 14:00', '2009/7/29 15:00', '2009/7/29 16:00', '2009/7/29 17:00', '2009/7/29 18:00', '2009/7/29 19:00', '2009/7/29 20:00', '2009/7/29 21:00', '2009/7/29 22:00', '2009/7/29 23:00', '2009/7/30 0:00', '2009/7/30 1:00', '2009/7/30 2:00', '2009/7/30 3:00', '2009/7/30 4:00', '2009/7/30 5:00', '2009/7/30 6:00', '2009/7/30 7:00', '2009/7/30 8:00', '2009/7/30 9:00', '2009/7/30 10:00', '2009/7/30 11:00', '2009/7/30 12:00', '2009/7/30 13:00', '2009/7/30 14:00', '2009/7/30 15:00', '2009/7/30 16:00', '2009/7/30 17:00', '2009/7/30 18:00', '2009/7/30 19:00', '2009/7/30 20:00', '2009/7/30 21:00', '2009/7/30 22:00', '2009/7/30 23:00', '2009/7/31 0:00', '2009/7/31 1:00', '2009/7/31 2:00', '2009/7/31 3:00', '2009/7/31 4:00', '2009/7/31 5:00', '2009/7/31 6:00', '2009/7/31 7:00', '2009/7/31 8:00', '2009/7/31 9:00', '2009/7/31 10:00', '2009/7/31 11:00', '2009/7/31 12:00', '2009/7/31 13:00', '2009/7/31 14:00', '2009/7/31 15:00', '2009/7/31 16:00', '2009/7/31 17:00', '2009/7/31 18:00', '2009/7/31 19:00', '2009/7/31 20:00', '2009/7/31 21:00', '2009/7/31 22:00', '2009/7/31 23:00', '2009/8/1 0:00', '2009/8/1 1:00', '2009/8/1 2:00', '2009/8/1 3:00', '2009/8/1 4:00', '2009/8/1 5:00', '2009/8/1 6:00', '2009/8/1 7:00', '2009/8/1 8:00', '2009/8/1 9:00', '2009/8/1 10:00', '2009/8/1 11:00', '2009/8/1 12:00', '2009/8/1 13:00', '2009/8/1 14:00', '2009/8/1 15:00', '2009/8/1 16:00', '2009/8/1 17:00', '2009/8/1 18:00', '2009/8/1 19:00', '2009/8/1 20:00', '2009/8/1 21:00', '2009/8/1 22:00', '2009/8/1 23:00', '2009/8/2 0:00', '2009/8/2 1:00', '2009/8/2 2:00', '2009/8/2 3:00', '2009/8/2 4:00', '2009/8/2 5:00', '2009/8/2 6:00', '2009/8/2 7:00', '2009/8/2 8:00', '2009/8/2 9:00', '2009/8/2 10:00', '2009/8/2 11:00', '2009/8/2 12:00', '2009/8/2 13:00', '2009/8/2 14:00', '2009/8/2 15:00', '2009/8/2 16:00', '2009/8/2 17:00', '2009/8/2 18:00', '2009/8/2 19:00', '2009/8/2 20:00', '2009/8/2 21:00', '2009/8/2 22:00', '2009/8/2 23:00', '2009/8/3 0:00', '2009/8/3 1:00', '2009/8/3 2:00', '2009/8/3 3:00', '2009/8/3 4:00', '2009/8/3 5:00', '2009/8/3 6:00', '2009/8/3 7:00', '2009/8/3 8:00', '2009/8/3 9:00', '2009/8/3 10:00', '2009/8/3 11:00', '2009/8/3 12:00', '2009/8/3 13:00', '2009/8/3 14:00', '2009/8/3 15:00', '2009/8/3 16:00', '2009/8/3 17:00', '2009/8/3 18:00', '2009/8/3 19:00', '2009/8/3 20:00', '2009/8/3 21:00', '2009/8/3 22:00', '2009/8/3 23:00', '2009/8/4 0:00', '2009/8/4 1:00', '2009/8/4 2:00', '2009/8/4 3:00', '2009/8/4 4:00', '2009/8/4 5:00', '2009/8/4 6:00', '2009/8/4 7:00', '2009/8/4 8:00', '2009/8/4 9:00', '2009/8/4 10:00', '2009/8/4 11:00', '2009/8/4 12:00', '2009/8/4 13:00', '2009/8/4 14:00', '2009/8/4 15:00', '2009/8/4 16:00', '2009/8/4 17:00', '2009/8/4 18:00', '2009/8/4 19:00', '2009/8/4 20:00', '2009/8/4 21:00', '2009/8/4 22:00', '2009/8/4 23:00', '2009/8/5 0:00', '2009/8/5 1:00', '2009/8/5 2:00', '2009/8/5 3:00', '2009/8/5 4:00', '2009/8/5 5:00', '2009/8/5 6:00', '2009/8/5 7:00', '2009/8/5 8:00', '2009/8/5 9:00', '2009/8/5 10:00', '2009/8/5 11:00', '2009/8/5 12:00', '2009/8/5 13:00', '2009/8/5 14:00', '2009/8/5 15:00', '2009/8/5 16:00', '2009/8/5 17:00', '2009/8/5 18:00', '2009/8/5 19:00', '2009/8/5 20:00', '2009/8/5 21:00', '2009/8/5 22:00', '2009/8/5 23:00', '2009/8/6 0:00', '2009/8/6 1:00', '2009/8/6 2:00', '2009/8/6 3:00', '2009/8/6 4:00', '2009/8/6 5:00', '2009/8/6 6:00', '2009/8/6 7:00', '2009/8/6 8:00', '2009/8/6 9:00', '2009/8/6 10:00', '2009/8/6 11:00', '2009/8/6 12:00', '2009/8/6 13:00', '2009/8/6 14:00', '2009/8/6 15:00', '2009/8/6 16:00', '2009/8/6 17:00', '2009/8/6 18:00', '2009/8/6 19:00', '2009/8/6 20:00', '2009/8/6 21:00', '2009/8/6 22:00', '2009/8/6 23:00', '2009/8/7 0:00', '2009/8/7 1:00', '2009/8/7 2:00', '2009/8/7 3:00', '2009/8/7 4:00', '2009/8/7 5:00', '2009/8/7 6:00', '2009/8/7 7:00', '2009/8/7 8:00', '2009/8/7 9:00', '2009/8/7 10:00', '2009/8/7 11:00', '2009/8/7 12:00', '2009/8/7 13:00', '2009/8/7 14:00', '2009/8/7 15:00', '2009/8/7 16:00', '2009/8/7 17:00', '2009/8/7 18:00', '2009/8/7 19:00', '2009/8/7 20:00', '2009/8/7 21:00', '2009/8/7 22:00', '2009/8/7 23:00', '2009/8/8 0:00', '2009/8/8 1:00', '2009/8/8 2:00', '2009/8/8 3:00', '2009/8/8 4:00', '2009/8/8 5:00', '2009/8/8 6:00', '2009/8/8 7:00', '2009/8/8 8:00', '2009/8/8 9:00', '2009/8/8 10:00', '2009/8/8 11:00', '2009/8/8 12:00', '2009/8/8 13:00', '2009/8/8 14:00', '2009/8/8 15:00', '2009/8/8 16:00', '2009/8/8 17:00', '2009/8/8 18:00', '2009/8/8 19:00', '2009/8/8 20:00', '2009/8/8 21:00', '2009/8/8 22:00', '2009/8/8 23:00', '2009/8/9 0:00', '2009/8/9 1:00', '2009/8/9 2:00', '2009/8/9 3:00', '2009/8/9 4:00', '2009/8/9 5:00', '2009/8/9 6:00', '2009/8/9 7:00', '2009/8/9 8:00', '2009/8/9 9:00', '2009/8/9 10:00', '2009/8/9 11:00', '2009/8/9 12:00', '2009/8/9 13:00', '2009/8/9 14:00', '2009/8/9 15:00', '2009/8/9 16:00', '2009/8/9 17:00', '2009/8/9 18:00', '2009/8/9 19:00', '2009/8/9 20:00', '2009/8/9 21:00', '2009/8/9 22:00', '2009/8/9 23:00', '2009/8/10 0:00', '2009/8/10 1:00', '2009/8/10 2:00', '2009/8/10 3:00', '2009/8/10 4:00', '2009/8/10 5:00', '2009/8/10 6:00', '2009/8/10 7:00', '2009/8/10 8:00', '2009/8/10 9:00', '2009/8/10 10:00', '2009/8/10 11:00', '2009/8/10 12:00', '2009/8/10 13:00', '2009/8/10 14:00', '2009/8/10 15:00', '2009/8/10 16:00', '2009/8/10 17:00', '2009/8/10 18:00', '2009/8/10 19:00', '2009/8/10 20:00', '2009/8/10 21:00', '2009/8/10 22:00', '2009/8/10 23:00', '2009/8/11 0:00', '2009/8/11 1:00', '2009/8/11 2:00', '2009/8/11 3:00', '2009/8/11 4:00', '2009/8/11 5:00', '2009/8/11 6:00', '2009/8/11 7:00', '2009/8/11 8:00', '2009/8/11 9:00', '2009/8/11 10:00', '2009/8/11 11:00', '2009/8/11 12:00', '2009/8/11 13:00', '2009/8/11 14:00', '2009/8/11 15:00', '2009/8/11 16:00', '2009/8/11 17:00', '2009/8/11 18:00', '2009/8/11 19:00', '2009/8/11 20:00', '2009/8/11 21:00', '2009/8/11 22:00', '2009/8/11 23:00', '2009/8/12 0:00', '2009/8/12 1:00', '2009/8/12 2:00', '2009/8/12 3:00', '2009/8/12 4:00', '2009/8/12 5:00', '2009/8/12 6:00', '2009/8/12 7:00', '2009/8/12 8:00', '2009/8/12 9:00', '2009/8/12 10:00', '2009/8/12 11:00', '2009/8/12 12:00', '2009/8/12 13:00', '2009/8/12 14:00', '2009/8/12 15:00', '2009/8/12 16:00', '2009/8/12 17:00', '2009/8/12 18:00', '2009/8/12 19:00', '2009/8/12 20:00', '2009/8/12 21:00', '2009/8/12 22:00', '2009/8/12 23:00', '2009/8/13 0:00', '2009/8/13 1:00', '2009/8/13 2:00', '2009/8/13 3:00', '2009/8/13 4:00', '2009/8/13 5:00', '2009/8/13 6:00', '2009/8/13 7:00', '2009/8/13 8:00', '2009/8/13 9:00', '2009/8/13 10:00', '2009/8/13 11:00', '2009/8/13 12:00', '2009/8/13 13:00', '2009/8/13 14:00', '2009/8/13 15:00', '2009/8/13 16:00', '2009/8/13 17:00', '2009/8/13 18:00', '2009/8/13 19:00', '2009/8/13 20:00', '2009/8/13 21:00', '2009/8/13 22:00', '2009/8/13 23:00', '2009/8/14 0:00', '2009/8/14 1:00', '2009/8/14 2:00', '2009/8/14 3:00', '2009/8/14 4:00', '2009/8/14 5:00', '2009/8/14 6:00', '2009/8/14 7:00', '2009/8/14 8:00', '2009/8/14 9:00', '2009/8/14 10:00', '2009/8/14 11:00', '2009/8/14 12:00', '2009/8/14 13:00', '2009/8/14 14:00', '2009/8/14 15:00', '2009/8/14 16:00', '2009/8/14 17:00', '2009/8/14 18:00', '2009/8/14 19:00', '2009/8/14 20:00', '2009/8/14 21:00', '2009/8/14 22:00', '2009/8/14 23:00', '2009/8/15 0:00', '2009/8/15 1:00', '2009/8/15 2:00', '2009/8/15 3:00', '2009/8/15 4:00', '2009/8/15 5:00', '2009/8/15 6:00', '2009/8/15 7:00', '2009/8/15 8:00', '2009/8/15 9:00', '2009/8/15 10:00', '2009/8/15 11:00', '2009/8/15 12:00', '2009/8/15 13:00', '2009/8/15 14:00', '2009/8/15 15:00', '2009/8/15 16:00', '2009/8/15 17:00', '2009/8/15 18:00', '2009/8/15 19:00', '2009/8/15 20:00', '2009/8/15 21:00', '2009/8/15 22:00', '2009/8/15 23:00', '2009/8/16 0:00', '2009/8/16 1:00', '2009/8/16 2:00', '2009/8/16 3:00', '2009/8/16 4:00', '2009/8/16 5:00', '2009/8/16 6:00', '2009/8/16 7:00', '2009/8/16 8:00', '2009/8/16 9:00', '2009/8/16 10:00', '2009/8/16 11:00', '2009/8/16 12:00', '2009/8/16 13:00', '2009/8/16 14:00', '2009/8/16 15:00', '2009/8/16 16:00', '2009/8/16 17:00', '2009/8/16 18:00', '2009/8/16 19:00', '2009/8/16 20:00', '2009/8/16 21:00', '2009/8/16 22:00', '2009/8/16 23:00', '2009/8/17 0:00', '2009/8/17 1:00', '2009/8/17 2:00', '2009/8/17 3:00', '2009/8/17 4:00', '2009/8/17 5:00', '2009/8/17 6:00', '2009/8/17 7:00', '2009/8/17 8:00', '2009/8/17 9:00', '2009/8/17 10:00', '2009/8/17 11:00', '2009/8/17 12:00', '2009/8/17 13:00', '2009/8/17 14:00', '2009/8/17 15:00', '2009/8/17 16:00', '2009/8/17 17:00', '2009/8/17 18:00', '2009/8/17 19:00', '2009/8/17 20:00', '2009/8/17 21:00', '2009/8/17 22:00', '2009/8/17 23:00', '2009/8/18 0:00', '2009/8/18 1:00', '2009/8/18 2:00', '2009/8/18 3:00', '2009/8/18 4:00', '2009/8/18 5:00', '2009/8/18 6:00', '2009/8/18 7:00', '2009/8/18 8:00', '2009/8/18 9:00', '2009/8/18 10:00', '2009/8/18 11:00', '2009/8/18 12:00', '2009/8/18 13:00', '2009/8/18 14:00', '2009/8/18 15:00', '2009/8/18 16:00', '2009/8/18 17:00', '2009/8/18 18:00', '2009/8/18 19:00', '2009/8/18 20:00', '2009/8/18 21:00', '2009/8/18 22:00', '2009/8/18 23:00', '2009/8/19 0:00', '2009/8/19 1:00', '2009/8/19 2:00', '2009/8/19 3:00', '2009/8/19 4:00', '2009/8/19 5:00', '2009/8/19 6:00', '2009/8/19 7:00', '2009/8/19 8:00', '2009/8/19 9:00', '2009/8/19 10:00', '2009/8/19 11:00', '2009/8/19 12:00', '2009/8/19 13:00', '2009/8/19 14:00', '2009/8/19 15:00', '2009/8/19 16:00', '2009/8/19 17:00', '2009/8/19 18:00', '2009/8/19 19:00', '2009/8/19 20:00', '2009/8/19 21:00', '2009/8/19 22:00', '2009/8/19 23:00', '2009/8/20 0:00', '2009/8/20 1:00', '2009/8/20 2:00', '2009/8/20 3:00', '2009/8/20 4:00', '2009/8/20 5:00', '2009/8/20 6:00', '2009/8/20 7:00', '2009/8/20 8:00', '2009/8/20 9:00', '2009/8/20 10:00', '2009/8/20 11:00', '2009/8/20 12:00', '2009/8/20 13:00', '2009/8/20 14:00', '2009/8/20 15:00', '2009/8/20 16:00', '2009/8/20 17:00', '2009/8/20 18:00', '2009/8/20 19:00', '2009/8/20 20:00', '2009/8/20 21:00', '2009/8/20 22:00', '2009/8/20 23:00', '2009/8/21 0:00', '2009/8/21 1:00', '2009/8/21 2:00', '2009/8/21 3:00', '2009/8/21 4:00', '2009/8/21 5:00', '2009/8/21 6:00', '2009/8/21 7:00', '2009/8/21 8:00', '2009/8/21 9:00', '2009/8/21 10:00', '2009/8/21 11:00', '2009/8/21 12:00', '2009/8/21 13:00', '2009/8/21 14:00', '2009/8/21 15:00', '2009/8/21 16:00', '2009/8/21 17:00', '2009/8/21 18:00', '2009/8/21 19:00', '2009/8/21 20:00', '2009/8/21 21:00', '2009/8/21 22:00', '2009/8/21 23:00', '2009/8/22 0:00', '2009/8/22 1:00', '2009/8/22 2:00', '2009/8/22 3:00', '2009/8/22 4:00', '2009/8/22 5:00', '2009/8/22 6:00', '2009/8/22 7:00', '2009/8/22 8:00', '2009/8/22 9:00', '2009/8/22 10:00', '2009/8/22 11:00', '2009/8/22 12:00', '2009/8/22 13:00', '2009/8/22 14:00', '2009/8/22 15:00', '2009/8/22 16:00', '2009/8/22 17:00', '2009/8/22 18:00', '2009/8/22 19:00', '2009/8/22 20:00', '2009/8/22 21:00', '2009/8/22 22:00', '2009/8/22 23:00', '2009/8/23 0:00', '2009/8/23 1:00', '2009/8/23 2:00', '2009/8/23 3:00', '2009/8/23 4:00', '2009/8/23 5:00', '2009/8/23 6:00', '2009/8/23 7:00', '2009/8/23 8:00', '2009/8/23 9:00', '2009/8/23 10:00', '2009/8/23 11:00', '2009/8/23 12:00', '2009/8/23 13:00', '2009/8/23 14:00', '2009/8/23 15:00', '2009/8/23 16:00', '2009/8/23 17:00', '2009/8/23 18:00', '2009/8/23 19:00', '2009/8/23 20:00', '2009/8/23 21:00', '2009/8/23 22:00', '2009/8/23 23:00', '2009/8/24 0:00', '2009/8/24 1:00', '2009/8/24 2:00', '2009/8/24 3:00', '2009/8/24 4:00', '2009/8/24 5:00', '2009/8/24 6:00', '2009/8/24 7:00', '2009/8/24 8:00', '2009/8/24 9:00', '2009/8/24 10:00', '2009/8/24 11:00', '2009/8/24 12:00', '2009/8/24 13:00', '2009/8/24 14:00', '2009/8/24 15:00', '2009/8/24 16:00', '2009/8/24 17:00', '2009/8/24 18:00', '2009/8/24 19:00', '2009/8/24 20:00', '2009/8/24 21:00', '2009/8/24 22:00', '2009/8/24 23:00', '2009/8/25 0:00', '2009/8/25 1:00', '2009/8/25 2:00', '2009/8/25 3:00', '2009/8/25 4:00', '2009/8/25 5:00', '2009/8/25 6:00', '2009/8/25 7:00', '2009/8/25 8:00', '2009/8/25 9:00', '2009/8/25 10:00', '2009/8/25 11:00', '2009/8/25 12:00', '2009/8/25 13:00', '2009/8/25 14:00', '2009/8/25 15:00', '2009/8/25 16:00', '2009/8/25 17:00', '2009/8/25 18:00', '2009/8/25 19:00', '2009/8/25 20:00', '2009/8/25 21:00', '2009/8/25 22:00', '2009/8/25 23:00', '2009/8/26 0:00', '2009/8/26 1:00', '2009/8/26 2:00', '2009/8/26 3:00', '2009/8/26 4:00', '2009/8/26 5:00', '2009/8/26 6:00', '2009/8/26 7:00', '2009/8/26 8:00', '2009/8/26 9:00', '2009/8/26 10:00', '2009/8/26 11:00', '2009/8/26 12:00', '2009/8/26 13:00', '2009/8/26 14:00', '2009/8/26 15:00', '2009/8/26 16:00', '2009/8/26 17:00', '2009/8/26 18:00', '2009/8/26 19:00', '2009/8/26 20:00', '2009/8/26 21:00', '2009/8/26 22:00', '2009/8/26 23:00', '2009/8/27 0:00', '2009/8/27 1:00', '2009/8/27 2:00', '2009/8/27 3:00', '2009/8/27 4:00', '2009/8/27 5:00', '2009/8/27 6:00', '2009/8/27 7:00', '2009/8/27 8:00', '2009/8/27 9:00', '2009/8/27 10:00', '2009/8/27 11:00', '2009/8/27 12:00', '2009/8/27 13:00', '2009/8/27 14:00', '2009/8/27 15:00', '2009/8/27 16:00', '2009/8/27 17:00', '2009/8/27 18:00', '2009/8/27 19:00', '2009/8/27 20:00', '2009/8/27 21:00', '2009/8/27 22:00', '2009/8/27 23:00', '2009/8/28 0:00', '2009/8/28 1:00', '2009/8/28 2:00', '2009/8/28 3:00', '2009/8/28 4:00', '2009/8/28 5:00', '2009/8/28 6:00', '2009/8/28 7:00', '2009/8/28 8:00', '2009/8/28 9:00', '2009/8/28 10:00', '2009/8/28 11:00', '2009/8/28 12:00', '2009/8/28 13:00', '2009/8/28 14:00', '2009/8/28 15:00', '2009/8/28 16:00', '2009/8/28 17:00', '2009/8/28 18:00', '2009/8/28 19:00', '2009/8/28 20:00', '2009/8/28 21:00', '2009/8/28 22:00', '2009/8/28 23:00', '2009/8/29 0:00', '2009/8/29 1:00', '2009/8/29 2:00', '2009/8/29 3:00', '2009/8/29 4:00', '2009/8/29 5:00', '2009/8/29 6:00', '2009/8/29 7:00', '2009/8/29 8:00', '2009/8/29 9:00', '2009/8/29 10:00', '2009/8/29 11:00', '2009/8/29 12:00', '2009/8/29 13:00', '2009/8/29 14:00', '2009/8/29 15:00', '2009/8/29 16:00', '2009/8/29 17:00', '2009/8/29 18:00', '2009/8/29 19:00', '2009/8/29 20:00', '2009/8/29 21:00', '2009/8/29 22:00', '2009/8/29 23:00', '2009/8/30 0:00', '2009/8/30 1:00', '2009/8/30 2:00', '2009/8/30 3:00', '2009/8/30 4:00', '2009/8/30 5:00', '2009/8/30 6:00', '2009/8/30 7:00', '2009/8/30 8:00', '2009/8/30 9:00', '2009/8/30 10:00', '2009/8/30 11:00', '2009/8/30 12:00', '2009/8/30 13:00', '2009/8/30 14:00', '2009/8/30 15:00', '2009/8/30 16:00', '2009/8/30 17:00', '2009/8/30 18:00', '2009/8/30 19:00', '2009/8/30 20:00', '2009/8/30 21:00', '2009/8/30 22:00', '2009/8/30 23:00', '2009/8/31 0:00', '2009/8/31 1:00', '2009/8/31 2:00', '2009/8/31 3:00', '2009/8/31 4:00', '2009/8/31 5:00', '2009/8/31 6:00', '2009/8/31 7:00', '2009/8/31 8:00', '2009/8/31 9:00', '2009/8/31 10:00', '2009/8/31 11:00', '2009/8/31 12:00', '2009/8/31 13:00', '2009/8/31 14:00', '2009/8/31 15:00', '2009/8/31 16:00', '2009/8/31 17:00', '2009/8/31 18:00', '2009/8/31 19:00', '2009/8/31 20:00', '2009/8/31 21:00', '2009/8/31 22:00', '2009/8/31 23:00', '2009/9/1 0:00', '2009/9/1 1:00', '2009/9/1 2:00', '2009/9/1 3:00', '2009/9/1 4:00', '2009/9/1 5:00', '2009/9/1 6:00', '2009/9/1 7:00', '2009/9/1 8:00', '2009/9/1 9:00', '2009/9/1 10:00', '2009/9/1 11:00', '2009/9/1 12:00', '2009/9/1 13:00', '2009/9/1 14:00', '2009/9/1 15:00', '2009/9/1 16:00', '2009/9/1 17:00', '2009/9/1 18:00', '2009/9/1 19:00', '2009/9/1 20:00', '2009/9/1 21:00', '2009/9/1 22:00', '2009/9/1 23:00', '2009/9/2 0:00', '2009/9/2 1:00', '2009/9/2 2:00', '2009/9/2 3:00', '2009/9/2 4:00', '2009/9/2 5:00', '2009/9/2 6:00', '2009/9/2 7:00', '2009/9/2 8:00', '2009/9/2 9:00', '2009/9/2 10:00', '2009/9/2 11:00', '2009/9/2 12:00', '2009/9/2 13:00', '2009/9/2 14:00', '2009/9/2 15:00', '2009/9/2 16:00', '2009/9/2 17:00', '2009/9/2 18:00', '2009/9/2 19:00', '2009/9/2 20:00', '2009/9/2 21:00', '2009/9/2 22:00', '2009/9/2 23:00', '2009/9/3 0:00', '2009/9/3 1:00', '2009/9/3 2:00', '2009/9/3 3:00', '2009/9/3 4:00', '2009/9/3 5:00', '2009/9/3 6:00', '2009/9/3 7:00', '2009/9/3 8:00', '2009/9/3 9:00', '2009/9/3 10:00', '2009/9/3 11:00', '2009/9/3 12:00', '2009/9/3 13:00', '2009/9/3 14:00', '2009/9/3 15:00', '2009/9/3 16:00', '2009/9/3 17:00', '2009/9/3 18:00', '2009/9/3 19:00', '2009/9/3 20:00', '2009/9/3 21:00', '2009/9/3 22:00', '2009/9/3 23:00', '2009/9/4 0:00', '2009/9/4 1:00', '2009/9/4 2:00', '2009/9/4 3:00', '2009/9/4 4:00', '2009/9/4 5:00', '2009/9/4 6:00', '2009/9/4 7:00', '2009/9/4 8:00', '2009/9/4 9:00', '2009/9/4 10:00', '2009/9/4 11:00', '2009/9/4 12:00', '2009/9/4 13:00', '2009/9/4 14:00', '2009/9/4 15:00', '2009/9/4 16:00', '2009/9/4 17:00', '2009/9/4 18:00', '2009/9/4 19:00', '2009/9/4 20:00', '2009/9/4 21:00', '2009/9/4 22:00', '2009/9/4 23:00', '2009/9/5 0:00', '2009/9/5 1:00', '2009/9/5 2:00', '2009/9/5 3:00', '2009/9/5 4:00', '2009/9/5 5:00', '2009/9/5 6:00', '2009/9/5 7:00', '2009/9/5 8:00', '2009/9/5 9:00', '2009/9/5 10:00', '2009/9/5 11:00', '2009/9/5 12:00', '2009/9/5 13:00', '2009/9/5 14:00', '2009/9/5 15:00', '2009/9/5 16:00', '2009/9/5 17:00', '2009/9/5 18:00', '2009/9/5 19:00', '2009/9/5 20:00', '2009/9/5 21:00', '2009/9/5 22:00', '2009/9/5 23:00', '2009/9/6 0:00', '2009/9/6 1:00', '2009/9/6 2:00', '2009/9/6 3:00', '2009/9/6 4:00', '2009/9/6 5:00', '2009/9/6 6:00', '2009/9/6 7:00', '2009/9/6 8:00', '2009/9/6 9:00', '2009/9/6 10:00', '2009/9/6 11:00', '2009/9/6 12:00', '2009/9/6 13:00', '2009/9/6 14:00', '2009/9/6 15:00', '2009/9/6 16:00', '2009/9/6 17:00', '2009/9/6 18:00', '2009/9/6 19:00', '2009/9/6 20:00', '2009/9/6 21:00', '2009/9/6 22:00', '2009/9/6 23:00', '2009/9/7 0:00', '2009/9/7 1:00', '2009/9/7 2:00', '2009/9/7 3:00', '2009/9/7 4:00', '2009/9/7 5:00', '2009/9/7 6:00', '2009/9/7 7:00', '2009/9/7 8:00', '2009/9/7 9:00', '2009/9/7 10:00', '2009/9/7 11:00', '2009/9/7 12:00', '2009/9/7 13:00', '2009/9/7 14:00', '2009/9/7 15:00', '2009/9/7 16:00', '2009/9/7 17:00', '2009/9/7 18:00', '2009/9/7 19:00', '2009/9/7 20:00', '2009/9/7 21:00', '2009/9/7 22:00', '2009/9/7 23:00', '2009/9/8 0:00', '2009/9/8 1:00', '2009/9/8 2:00', '2009/9/8 3:00', '2009/9/8 4:00', '2009/9/8 5:00', '2009/9/8 6:00', '2009/9/8 7:00', '2009/9/8 8:00', '2009/9/8 9:00', '2009/9/8 10:00', '2009/9/8 11:00', '2009/9/8 12:00', '2009/9/8 13:00', '2009/9/8 14:00', '2009/9/8 15:00', '2009/9/8 16:00', '2009/9/8 17:00', '2009/9/8 18:00', '2009/9/8 19:00', '2009/9/8 20:00', '2009/9/8 21:00', '2009/9/8 22:00', '2009/9/8 23:00', '2009/9/9 0:00', '2009/9/9 1:00', '2009/9/9 2:00', '2009/9/9 3:00', '2009/9/9 4:00', '2009/9/9 5:00', '2009/9/9 6:00', '2009/9/9 7:00', '2009/9/9 8:00', '2009/9/9 9:00', '2009/9/9 10:00', '2009/9/9 11:00', '2009/9/9 12:00', '2009/9/9 13:00', '2009/9/9 14:00', '2009/9/9 15:00', '2009/9/9 16:00', '2009/9/9 17:00', '2009/9/9 18:00', '2009/9/9 19:00', '2009/9/9 20:00', '2009/9/9 21:00', '2009/9/9 22:00', '2009/9/9 23:00', '2009/9/10 0:00', '2009/9/10 1:00', '2009/9/10 2:00', '2009/9/10 3:00', '2009/9/10 4:00', '2009/9/10 5:00', '2009/9/10 6:00', '2009/9/10 7:00', '2009/9/10 8:00', '2009/9/10 9:00', '2009/9/10 10:00', '2009/9/10 11:00', '2009/9/10 12:00', '2009/9/10 13:00', '2009/9/10 14:00', '2009/9/10 15:00', '2009/9/10 16:00', '2009/9/10 17:00', '2009/9/10 18:00', '2009/9/10 19:00', '2009/9/10 20:00', '2009/9/10 21:00', '2009/9/10 22:00', '2009/9/10 23:00', '2009/9/11 0:00', '2009/9/11 1:00', '2009/9/11 2:00', '2009/9/11 3:00', '2009/9/11 4:00', '2009/9/11 5:00', '2009/9/11 6:00', '2009/9/11 7:00', '2009/9/11 8:00', '2009/9/11 9:00', '2009/9/11 10:00', '2009/9/11 11:00', '2009/9/11 12:00', '2009/9/11 13:00', '2009/9/11 14:00', '2009/9/11 15:00', '2009/9/11 16:00', '2009/9/11 17:00', '2009/9/11 18:00', '2009/9/11 19:00', '2009/9/11 20:00', '2009/9/11 21:00', '2009/9/11 22:00', '2009/9/11 23:00', '2009/9/12 0:00', '2009/9/12 1:00', '2009/9/12 2:00', '2009/9/12 3:00', '2009/9/12 4:00', '2009/9/12 5:00', '2009/9/12 6:00', '2009/9/12 7:00', '2009/9/12 8:00', '2009/9/12 9:00', '2009/9/12 10:00', '2009/9/12 11:00', '2009/9/12 12:00', '2009/9/12 13:00', '2009/9/12 14:00', '2009/9/12 15:00', '2009/9/12 16:00', '2009/9/12 17:00', '2009/9/12 18:00', '2009/9/12 19:00', '2009/9/12 20:00', '2009/9/12 21:00', '2009/9/12 22:00', '2009/9/12 23:00', '2009/9/13 0:00', '2009/9/13 1:00', '2009/9/13 2:00', '2009/9/13 3:00', '2009/9/13 4:00', '2009/9/13 5:00', '2009/9/13 6:00', '2009/9/13 7:00', '2009/9/13 8:00', '2009/9/13 9:00', '2009/9/13 10:00', '2009/9/13 11:00', '2009/9/13 12:00', '2009/9/13 13:00', '2009/9/13 14:00', '2009/9/13 15:00', '2009/9/13 16:00', '2009/9/13 17:00', '2009/9/13 18:00', '2009/9/13 19:00', '2009/9/13 20:00', '2009/9/13 21:00', '2009/9/13 22:00', '2009/9/13 23:00', '2009/9/14 0:00', '2009/9/14 1:00', '2009/9/14 2:00', '2009/9/14 3:00', '2009/9/14 4:00', '2009/9/14 5:00', '2009/9/14 6:00', '2009/9/14 7:00', '2009/9/14 8:00', '2009/9/14 9:00', '2009/9/14 10:00', '2009/9/14 11:00', '2009/9/14 12:00', '2009/9/14 13:00', '2009/9/14 14:00', '2009/9/14 15:00', '2009/9/14 16:00', '2009/9/14 17:00', '2009/9/14 18:00', '2009/9/14 19:00', '2009/9/14 20:00', '2009/9/14 21:00', '2009/9/14 22:00', '2009/9/14 23:00', '2009/9/15 0:00', '2009/9/15 1:00', '2009/9/15 2:00', '2009/9/15 3:00', '2009/9/15 4:00', '2009/9/15 5:00', '2009/9/15 6:00', '2009/9/15 7:00', '2009/9/15 8:00', '2009/9/15 9:00', '2009/9/15 10:00', '2009/9/15 11:00', '2009/9/15 12:00', '2009/9/15 13:00', '2009/9/15 14:00', '2009/9/15 15:00', '2009/9/15 16:00', '2009/9/15 17:00', '2009/9/15 18:00', '2009/9/15 19:00', '2009/9/15 20:00', '2009/9/15 21:00', '2009/9/15 22:00', '2009/9/15 23:00', '2009/9/16 0:00', '2009/9/16 1:00', '2009/9/16 2:00', '2009/9/16 3:00', '2009/9/16 4:00', '2009/9/16 5:00', '2009/9/16 6:00', '2009/9/16 7:00', '2009/9/16 8:00', '2009/9/16 9:00', '2009/9/16 10:00', '2009/9/16 11:00', '2009/9/16 12:00', '2009/9/16 13:00', '2009/9/16 14:00', '2009/9/16 15:00', '2009/9/16 16:00', '2009/9/16 17:00', '2009/9/16 18:00', '2009/9/16 19:00', '2009/9/16 20:00', '2009/9/16 21:00', '2009/9/16 22:00', '2009/9/16 23:00', '2009/9/17 0:00', '2009/9/17 1:00', '2009/9/17 2:00', '2009/9/17 3:00', '2009/9/17 4:00', '2009/9/17 5:00', '2009/9/17 6:00', '2009/9/17 7:00', '2009/9/17 8:00', '2009/9/17 9:00', '2009/9/17 10:00', '2009/9/17 11:00', '2009/9/17 12:00', '2009/9/17 13:00', '2009/9/17 14:00', '2009/9/17 15:00', '2009/9/17 16:00', '2009/9/17 17:00', '2009/9/17 18:00', '2009/9/17 19:00', '2009/9/17 20:00', '2009/9/17 21:00', '2009/9/17 22:00', '2009/9/17 23:00', '2009/9/18 0:00', '2009/9/18 1:00', '2009/9/18 2:00', '2009/9/18 3:00', '2009/9/18 4:00', '2009/9/18 5:00', '2009/9/18 6:00', '2009/9/18 7:00', '2009/9/18 8:00', '2009/9/18 9:00', '2009/9/18 10:00', '2009/9/18 11:00', '2009/9/18 12:00', '2009/9/18 13:00', '2009/9/18 14:00', '2009/9/18 15:00', '2009/9/18 16:00', '2009/9/18 17:00', '2009/9/18 18:00', '2009/9/18 19:00', '2009/9/18 20:00', '2009/9/18 21:00', '2009/9/18 22:00', '2009/9/18 23:00', '2009/9/19 0:00', '2009/9/19 1:00', '2009/9/19 2:00', '2009/9/19 3:00', '2009/9/19 4:00', '2009/9/19 5:00', '2009/9/19 6:00', '2009/9/19 7:00', '2009/9/19 8:00', '2009/9/19 9:00', '2009/9/19 10:00', '2009/9/19 11:00', '2009/9/19 12:00', '2009/9/19 13:00', '2009/9/19 14:00', '2009/9/19 15:00', '2009/9/19 16:00', '2009/9/19 17:00', '2009/9/19 18:00', '2009/9/19 19:00', '2009/9/19 20:00', '2009/9/19 21:00', '2009/9/19 22:00', '2009/9/19 23:00', '2009/9/20 0:00', '2009/9/20 1:00', '2009/9/20 2:00', '2009/9/20 3:00', '2009/9/20 4:00', '2009/9/20 5:00', '2009/9/20 6:00', '2009/9/20 7:00', '2009/9/20 8:00', '2009/9/20 9:00', '2009/9/20 10:00', '2009/9/20 11:00', '2009/9/20 12:00', '2009/9/20 13:00', '2009/9/20 14:00', '2009/9/20 15:00', '2009/9/20 16:00', '2009/9/20 17:00', '2009/9/20 18:00', '2009/9/20 19:00', '2009/9/20 20:00', '2009/9/20 21:00', '2009/9/20 22:00', '2009/9/20 23:00', '2009/9/21 0:00', '2009/9/21 1:00', '2009/9/21 2:00', '2009/9/21 3:00', '2009/9/21 4:00', '2009/9/21 5:00', '2009/9/21 6:00', '2009/9/21 7:00', '2009/9/21 8:00', '2009/9/21 9:00', '2009/9/21 10:00', '2009/9/21 11:00', '2009/9/21 12:00', '2009/9/21 13:00', '2009/9/21 14:00', '2009/9/21 15:00', '2009/9/21 16:00', '2009/9/21 17:00', '2009/9/21 18:00', '2009/9/21 19:00', '2009/9/21 20:00', '2009/9/21 21:00', '2009/9/21 22:00', '2009/9/21 23:00', '2009/9/22 0:00', '2009/9/22 1:00', '2009/9/22 2:00', '2009/9/22 3:00', '2009/9/22 4:00', '2009/9/22 5:00', '2009/9/22 6:00', '2009/9/22 7:00', '2009/9/22 8:00', '2009/9/22 9:00', '2009/9/22 10:00', '2009/9/22 11:00', '2009/9/22 12:00', '2009/9/22 13:00', '2009/9/22 14:00', '2009/9/22 15:00', '2009/9/22 16:00', '2009/9/22 17:00', '2009/9/22 18:00', '2009/9/22 19:00', '2009/9/22 20:00', '2009/9/22 21:00', '2009/9/22 22:00', '2009/9/22 23:00', '2009/9/23 0:00', '2009/9/23 1:00', '2009/9/23 2:00', '2009/9/23 3:00', '2009/9/23 4:00', '2009/9/23 5:00', '2009/9/23 6:00', '2009/9/23 7:00', '2009/9/23 8:00', '2009/9/23 9:00', '2009/9/23 10:00', '2009/9/23 11:00', '2009/9/23 12:00', '2009/9/23 13:00', '2009/9/23 14:00', '2009/9/23 15:00', '2009/9/23 16:00', '2009/9/23 17:00', '2009/9/23 18:00', '2009/9/23 19:00', '2009/9/23 20:00', '2009/9/23 21:00', '2009/9/23 22:00', '2009/9/23 23:00', '2009/9/24 0:00', '2009/9/24 1:00', '2009/9/24 2:00', '2009/9/24 3:00', '2009/9/24 4:00', '2009/9/24 5:00', '2009/9/24 6:00', '2009/9/24 7:00', '2009/9/24 8:00', '2009/9/24 9:00', '2009/9/24 10:00', '2009/9/24 11:00', '2009/9/24 12:00', '2009/9/24 13:00', '2009/9/24 14:00', '2009/9/24 15:00', '2009/9/24 16:00', '2009/9/24 17:00', '2009/9/24 18:00', '2009/9/24 19:00', '2009/9/24 20:00', '2009/9/24 21:00', '2009/9/24 22:00', '2009/9/24 23:00', '2009/9/25 0:00', '2009/9/25 1:00', '2009/9/25 2:00', '2009/9/25 3:00', '2009/9/25 4:00', '2009/9/25 5:00', '2009/9/25 6:00', '2009/9/25 7:00', '2009/9/25 8:00', '2009/9/25 9:00', '2009/9/25 10:00', '2009/9/25 11:00', '2009/9/25 12:00', '2009/9/25 13:00', '2009/9/25 14:00', '2009/9/25 15:00', '2009/9/25 16:00', '2009/9/25 17:00', '2009/9/25 18:00', '2009/9/25 19:00', '2009/9/25 20:00', '2009/9/25 21:00', '2009/9/25 22:00', '2009/9/25 23:00', '2009/9/26 0:00', '2009/9/26 1:00', '2009/9/26 2:00', '2009/9/26 3:00', '2009/9/26 4:00', '2009/9/26 5:00', '2009/9/26 6:00', '2009/9/26 7:00', '2009/9/26 8:00', '2009/9/26 9:00', '2009/9/26 10:00', '2009/9/26 11:00', '2009/9/26 12:00', '2009/9/26 13:00', '2009/9/26 14:00', '2009/9/26 15:00', '2009/9/26 16:00', '2009/9/26 17:00', '2009/9/26 18:00', '2009/9/26 19:00', '2009/9/26 20:00', '2009/9/26 21:00', '2009/9/26 22:00', '2009/9/26 23:00', '2009/9/27 0:00', '2009/9/27 1:00', '2009/9/27 2:00', '2009/9/27 3:00', '2009/9/27 4:00', '2009/9/27 5:00', '2009/9/27 6:00', '2009/9/27 7:00', '2009/9/27 8:00', '2009/9/27 9:00', '2009/9/27 10:00', '2009/9/27 11:00', '2009/9/27 12:00', '2009/9/27 13:00', '2009/9/27 14:00', '2009/9/27 15:00', '2009/9/27 16:00', '2009/9/27 17:00', '2009/9/27 18:00', '2009/9/27 19:00', '2009/9/27 20:00', '2009/9/27 21:00', '2009/9/27 22:00', '2009/9/27 23:00', '2009/9/28 0:00', '2009/9/28 1:00', '2009/9/28 2:00', '2009/9/28 3:00', '2009/9/28 4:00', '2009/9/28 5:00', '2009/9/28 6:00', '2009/9/28 7:00', '2009/9/28 8:00', '2009/9/28 9:00', '2009/9/28 10:00', '2009/9/28 11:00', '2009/9/28 12:00', '2009/9/28 13:00', '2009/9/28 14:00', '2009/9/28 15:00', '2009/9/28 16:00', '2009/9/28 17:00', '2009/9/28 18:00', '2009/9/28 19:00', '2009/9/28 20:00', '2009/9/28 21:00', '2009/9/28 22:00', '2009/9/28 23:00', '2009/9/29 0:00', '2009/9/29 1:00', '2009/9/29 2:00', '2009/9/29 3:00', '2009/9/29 4:00', '2009/9/29 5:00', '2009/9/29 6:00', '2009/9/29 7:00', '2009/9/29 8:00', '2009/9/29 9:00', '2009/9/29 10:00', '2009/9/29 11:00', '2009/9/29 12:00', '2009/9/29 13:00', '2009/9/29 14:00', '2009/9/29 15:00', '2009/9/29 16:00', '2009/9/29 17:00', '2009/9/29 18:00', '2009/9/29 19:00', '2009/9/29 20:00', '2009/9/29 21:00', '2009/9/29 22:00', '2009/9/29 23:00', '2009/9/30 0:00', '2009/9/30 1:00', '2009/9/30 2:00', '2009/9/30 3:00', '2009/9/30 4:00', '2009/9/30 5:00', '2009/9/30 6:00', '2009/9/30 7:00', '2009/9/30 8:00', '2009/9/30 9:00', '2009/9/30 10:00', '2009/9/30 11:00', '2009/9/30 12:00', '2009/9/30 13:00', '2009/9/30 14:00', '2009/9/30 15:00', '2009/9/30 16:00', '2009/9/30 17:00', '2009/9/30 18:00', '2009/9/30 19:00', '2009/9/30 20:00', '2009/9/30 21:00', '2009/9/30 22:00', '2009/9/30 23:00', '2009/10/1 0:00', '2009/10/1 1:00', '2009/10/1 2:00', '2009/10/1 3:00', '2009/10/1 4:00', '2009/10/1 5:00', '2009/10/1 6:00', '2009/10/1 7:00', '2009/10/1 8:00', '2009/10/1 9:00', '2009/10/1 10:00', '2009/10/1 11:00', '2009/10/1 12:00', '2009/10/1 13:00', '2009/10/1 14:00', '2009/10/1 15:00', '2009/10/1 16:00', '2009/10/1 17:00', '2009/10/1 18:00', '2009/10/1 19:00', '2009/10/1 20:00', '2009/10/1 21:00', '2009/10/1 22:00', '2009/10/1 23:00', '2009/10/2 0:00', '2009/10/2 1:00', '2009/10/2 2:00', '2009/10/2 3:00', '2009/10/2 4:00', '2009/10/2 5:00', '2009/10/2 6:00', '2009/10/2 7:00', '2009/10/2 8:00', '2009/10/2 9:00', '2009/10/2 10:00', '2009/10/2 11:00', '2009/10/2 12:00', '2009/10/2 13:00', '2009/10/2 14:00', '2009/10/2 15:00', '2009/10/2 16:00', '2009/10/2 17:00', '2009/10/2 18:00', '2009/10/2 19:00', '2009/10/2 20:00', '2009/10/2 21:00', '2009/10/2 22:00', '2009/10/2 23:00', '2009/10/3 0:00', '2009/10/3 1:00', '2009/10/3 2:00', '2009/10/3 3:00', '2009/10/3 4:00', '2009/10/3 5:00', '2009/10/3 6:00', '2009/10/3 7:00', '2009/10/3 8:00', '2009/10/3 9:00', '2009/10/3 10:00', '2009/10/3 11:00', '2009/10/3 12:00', '2009/10/3 13:00', '2009/10/3 14:00', '2009/10/3 15:00', '2009/10/3 16:00', '2009/10/3 17:00', '2009/10/3 18:00', '2009/10/3 19:00', '2009/10/3 20:00', '2009/10/3 21:00', '2009/10/3 22:00', '2009/10/3 23:00', '2009/10/4 0:00', '2009/10/4 1:00', '2009/10/4 2:00', '2009/10/4 3:00', '2009/10/4 4:00', '2009/10/4 5:00', '2009/10/4 6:00', '2009/10/4 7:00', '2009/10/4 8:00', '2009/10/4 9:00', '2009/10/4 10:00', '2009/10/4 11:00', '2009/10/4 12:00', '2009/10/4 13:00', '2009/10/4 14:00', '2009/10/4 15:00', '2009/10/4 16:00', '2009/10/4 17:00', '2009/10/4 18:00', '2009/10/4 19:00', '2009/10/4 20:00', '2009/10/4 21:00', '2009/10/4 22:00', '2009/10/4 23:00', '2009/10/5 0:00', '2009/10/5 1:00', '2009/10/5 2:00', '2009/10/5 3:00', '2009/10/5 4:00', '2009/10/5 5:00', '2009/10/5 6:00', '2009/10/5 7:00', '2009/10/5 8:00', '2009/10/5 9:00', '2009/10/5 10:00', '2009/10/5 11:00', '2009/10/5 12:00', '2009/10/5 13:00', '2009/10/5 14:00', '2009/10/5 15:00', '2009/10/5 16:00', '2009/10/5 17:00', '2009/10/5 18:00', '2009/10/5 19:00', '2009/10/5 20:00', '2009/10/5 21:00', '2009/10/5 22:00', '2009/10/5 23:00', '2009/10/6 0:00', '2009/10/6 1:00', '2009/10/6 2:00', '2009/10/6 3:00', '2009/10/6 4:00', '2009/10/6 5:00', '2009/10/6 6:00', '2009/10/6 7:00', '2009/10/6 8:00', '2009/10/6 9:00', '2009/10/6 10:00', '2009/10/6 11:00', '2009/10/6 12:00', '2009/10/6 13:00', '2009/10/6 14:00', '2009/10/6 15:00', '2009/10/6 16:00', '2009/10/6 17:00', '2009/10/6 18:00', '2009/10/6 19:00', '2009/10/6 20:00', '2009/10/6 21:00', '2009/10/6 22:00', '2009/10/6 23:00', '2009/10/7 0:00', '2009/10/7 1:00', '2009/10/7 2:00', '2009/10/7 3:00', '2009/10/7 4:00', '2009/10/7 5:00', '2009/10/7 6:00', '2009/10/7 7:00', '2009/10/7 8:00', '2009/10/7 9:00', '2009/10/7 10:00', '2009/10/7 11:00', '2009/10/7 12:00', '2009/10/7 13:00', '2009/10/7 14:00', '2009/10/7 15:00', '2009/10/7 16:00', '2009/10/7 17:00', '2009/10/7 18:00', '2009/10/7 19:00', '2009/10/7 20:00', '2009/10/7 21:00', '2009/10/7 22:00', '2009/10/7 23:00', '2009/10/8 0:00', '2009/10/8 1:00', '2009/10/8 2:00', '2009/10/8 3:00', '2009/10/8 4:00', '2009/10/8 5:00', '2009/10/8 6:00', '2009/10/8 7:00', '2009/10/8 8:00', '2009/10/8 9:00', '2009/10/8 10:00', '2009/10/8 11:00', '2009/10/8 12:00', '2009/10/8 13:00', '2009/10/8 14:00', '2009/10/8 15:00', '2009/10/8 16:00', '2009/10/8 17:00', '2009/10/8 18:00', '2009/10/8 19:00', '2009/10/8 20:00', '2009/10/8 21:00', '2009/10/8 22:00', '2009/10/8 23:00', '2009/10/9 0:00', '2009/10/9 1:00', '2009/10/9 2:00', '2009/10/9 3:00', '2009/10/9 4:00', '2009/10/9 5:00', '2009/10/9 6:00', '2009/10/9 7:00', '2009/10/9 8:00', '2009/10/9 9:00', '2009/10/9 10:00', '2009/10/9 11:00', '2009/10/9 12:00', '2009/10/9 13:00', '2009/10/9 14:00', '2009/10/9 15:00', '2009/10/9 16:00', '2009/10/9 17:00', '2009/10/9 18:00', '2009/10/9 19:00', '2009/10/9 20:00', '2009/10/9 21:00', '2009/10/9 22:00', '2009/10/9 23:00', '2009/10/10 0:00', '2009/10/10 1:00', '2009/10/10 2:00', '2009/10/10 3:00', '2009/10/10 4:00', '2009/10/10 5:00', '2009/10/10 6:00', '2009/10/10 7:00', '2009/10/10 8:00', '2009/10/10 9:00', '2009/10/10 10:00', '2009/10/10 11:00', '2009/10/10 12:00', '2009/10/10 13:00', '2009/10/10 14:00', '2009/10/10 15:00', '2009/10/10 16:00', '2009/10/10 17:00', '2009/10/10 18:00', '2009/10/10 19:00', '2009/10/10 20:00', '2009/10/10 21:00', '2009/10/10 22:00', '2009/10/10 23:00', '2009/10/11 0:00', '2009/10/11 1:00', '2009/10/11 2:00', '2009/10/11 3:00', '2009/10/11 4:00', '2009/10/11 5:00', '2009/10/11 6:00', '2009/10/11 7:00', '2009/10/11 8:00', '2009/10/11 9:00', '2009/10/11 10:00', '2009/10/11 11:00', '2009/10/11 12:00', '2009/10/11 13:00', '2009/10/11 14:00', '2009/10/11 15:00', '2009/10/11 16:00', '2009/10/11 17:00', '2009/10/11 18:00', '2009/10/11 19:00', '2009/10/11 20:00', '2009/10/11 21:00', '2009/10/11 22:00', '2009/10/11 23:00', '2009/10/12 0:00', '2009/10/12 1:00', '2009/10/12 2:00', '2009/10/12 3:00', '2009/10/12 4:00', '2009/10/12 5:00', '2009/10/12 6:00', '2009/10/12 7:00', '2009/10/12 8:00', '2009/10/12 9:00', '2009/10/12 10:00', '2009/10/12 11:00', '2009/10/12 12:00', '2009/10/12 13:00', '2009/10/12 14:00', '2009/10/12 15:00', '2009/10/12 16:00', '2009/10/12 17:00', '2009/10/12 18:00', '2009/10/12 19:00', '2009/10/12 20:00', '2009/10/12 21:00', '2009/10/12 22:00', '2009/10/12 23:00', '2009/10/13 0:00', '2009/10/13 1:00', '2009/10/13 2:00', '2009/10/13 3:00', '2009/10/13 4:00', '2009/10/13 5:00', '2009/10/13 6:00', '2009/10/13 7:00', '2009/10/13 8:00', '2009/10/13 9:00', '2009/10/13 10:00', '2009/10/13 11:00', '2009/10/13 12:00', '2009/10/13 13:00', '2009/10/13 14:00', '2009/10/13 15:00', '2009/10/13 16:00', '2009/10/13 17:00', '2009/10/13 18:00', '2009/10/13 19:00', '2009/10/13 20:00', '2009/10/13 21:00', '2009/10/13 22:00', '2009/10/13 23:00', '2009/10/14 0:00', '2009/10/14 1:00', '2009/10/14 2:00', '2009/10/14 3:00', '2009/10/14 4:00', '2009/10/14 5:00', '2009/10/14 6:00', '2009/10/14 7:00', '2009/10/14 8:00', '2009/10/14 9:00', '2009/10/14 10:00', '2009/10/14 11:00', '2009/10/14 12:00', '2009/10/14 13:00', '2009/10/14 14:00', '2009/10/14 15:00', '2009/10/14 16:00', '2009/10/14 17:00', '2009/10/14 18:00', '2009/10/14 19:00', '2009/10/14 20:00', '2009/10/14 21:00', '2009/10/14 22:00', '2009/10/14 23:00', '2009/10/15 0:00', '2009/10/15 1:00', '2009/10/15 2:00', '2009/10/15 3:00', '2009/10/15 4:00', '2009/10/15 5:00', '2009/10/15 6:00', '2009/10/15 7:00', '2009/10/15 8:00', '2009/10/15 9:00', '2009/10/15 10:00', '2009/10/15 11:00', '2009/10/15 12:00', '2009/10/15 13:00', '2009/10/15 14:00', '2009/10/15 15:00', '2009/10/15 16:00', '2009/10/15 17:00', '2009/10/15 18:00', '2009/10/15 19:00', '2009/10/15 20:00', '2009/10/15 21:00', '2009/10/15 22:00', '2009/10/15 23:00', '2009/10/16 0:00', '2009/10/16 1:00', '2009/10/16 2:00', '2009/10/16 3:00', '2009/10/16 4:00', '2009/10/16 5:00', '2009/10/16 6:00', '2009/10/16 7:00', '2009/10/16 8:00', '2009/10/16 9:00', '2009/10/16 10:00', '2009/10/16 11:00', '2009/10/16 12:00', '2009/10/16 13:00', '2009/10/16 14:00', '2009/10/16 15:00', '2009/10/16 16:00', '2009/10/16 17:00', '2009/10/16 18:00', '2009/10/16 19:00', '2009/10/16 20:00', '2009/10/16 21:00', '2009/10/16 22:00', '2009/10/16 23:00', '2009/10/17 0:00', '2009/10/17 1:00', '2009/10/17 2:00', '2009/10/17 3:00', '2009/10/17 4:00', '2009/10/17 5:00', '2009/10/17 6:00', '2009/10/17 7:00', '2009/10/17 8:00', '2009/10/17 9:00', '2009/10/17 10:00', '2009/10/17 11:00', '2009/10/17 12:00', '2009/10/17 13:00', '2009/10/17 14:00', '2009/10/17 15:00', '2009/10/17 16:00', '2009/10/17 17:00', '2009/10/17 18:00', '2009/10/17 19:00', '2009/10/17 20:00', '2009/10/17 21:00', '2009/10/17 22:00', '2009/10/17 23:00', '2009/10/18 0:00', '2009/10/18 1:00', '2009/10/18 2:00', '2009/10/18 3:00', '2009/10/18 4:00', '2009/10/18 5:00', '2009/10/18 6:00', '2009/10/18 7:00', '2009/10/18 8:00' ].map(function (str) { return str.replace(' ', '\n'); }) } ], yAxis: [ { name: '流量(m^3/s)', type: 'value', max: 500 }, { name: '降雨量(mm)', nameLocation: 'start', max: 5, type: 'value', inverse: true } ], series: [ { name: '流量', type: 'line', animation: false, areaStyle: {}, lineStyle: { width: 1 }, markArea: { silent: true, data: [[{ xAxis: '2009/9/12\n7:00' }, { xAxis: '2009/9/22\n7:00' }]] }, data: [ 0.97,0.96,0.96,0.95,0.95,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.93,0.92,0.91,0.9,0.89,0.88,0.87,0.87,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.87,0.88,0.9,0.93,0.96,0.99,1.03,1.06,1.1,1.14,1.17,1.2,1.23,1.26,1.29,1.33,1.36,1.4,1.43,1.45,1.48,1.49,1.51,1.51,1.5,1.49,1.47,1.44,1.41,1.37,1.34,1.3,1.27,1.24,1.22,1.2,1.19,1.18,1.16,1.15,1.14,1.13,1.12,1.11,1.11,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.09,1.09,1.08,1.07,1.06,1.05,1.04,1.03,1.03,1.02,1.01,1.01,1,0.99,0.98,0.97,0.96,0.96,0.95,0.95,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.93,0.92,0.91,0.9,0.89,0.88,0.87,0.87,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.85,0.84,0.83,0.82,0.81,0.8,0.8,0.79,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.77,0.75,0.73,0.71,0.68,0.65,0.63,0.61,0.59,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.57,0.57,0.57,0.56,0.55,0.55,0.54,0.54,0.53,0.52,0.52,0.51,0.51,0.5,0.5,0.49,0.48,0.48,0.47,0.47,0.47,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.52,0.67,0.9,1.19,1.52,1.87,2.22,2.55,2.84,3.07,3.22,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.28,3.24,3.13,2.97,2.77,2.54,2.3,2.05,1.82,1.62,1.46,1.35,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.31,1.3,1.26,1.21,1.14,1.06,0.97,0.89,0.81,0.74,0.69,0.65,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.63,0.63,0.62,0.62,0.61,0.6,0.59,0.59,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.59,0.61,0.63,0.65,0.68,0.71,0.73,0.75,0.77,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.77,0.75,0.73,0.71,0.68,0.65,0.63,0.61,0.59,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.58,0.59,0.59,0.6,0.61,0.62,0.62,0.63,0.63,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.65,0.66,0.68,0.69,0.71,0.73,0.74,0.76,0.77,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.79,0.81,0.82,0.84,0.86,0.88,0.9,0.92,0.93,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.94,0.93,0.92,0.91,0.9,0.89,0.88,0.87,0.87,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.86,0.85,0.84,0.82,0.8,0.78,0.76,0.75,0.73,0.72,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.72,0.73,0.74,0.76,0.78,0.79,0.82,0.84,0.86,0.89,0.91,0.94,0.97,1,1.02,1.05,1.08,1.11,1.14,1.17,1.19,1.22,1.25,1.27,1.29,1.31,1.33,1.35,1.36,1.38,1.39,1.39,1.4,1.4,1.4,1.39,1.37,1.35,1.32,1.29,1.26,1.22,1.18,1.14,1.1,1.05,1.01,0.97,0.93,0.89,0.85,0.82,0.78,0.76,0.74,0.72,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.72,0.73,0.74,0.75,0.77,0.78,0.8,0.82,0.84,0.87,0.89,0.92,0.94,0.97,0.99,1.02,1.05,1.08,1.1,1.13,1.16,1.18,1.21,1.23,1.26,1.28,1.3,1.32,1.34,1.35,1.37,1.38,1.39,1.4,1.41,1.41,1.42,1.42,1.43,1.43,1.43,1.44,1.44,1.44,1.44,1.45,1.45,1.45,1.46,1.46,1.46,1.47,1.47,1.48,1.48,1.49,1.5,1.51,1.54,1.62,1.73,1.88,2.05,2.24,2.45,2.67,2.89,3.11,3.31,3.51,3.69,3.86,4.03,4.18,4.33,4.48,4.62,4.76,4.89,5.02,5.16,5.29,5.43,5.57,5.71,5.86,6.02,6.18,6.36,6.54,6.73,6.93,7.15,7.38,7.62,7.88,8.16,8.46,8.77,9.11,9.46,9.84,10.24,10.67,11.12,11.6,12.3,13.66,16,38.43,82.21,146.6,218.7,226,225.23,223.08,219.78,212,199.82,184.6,168,151.65,137.21,126.31,119.94,115.52,112.06,108.92,105.44,101,94.56,86.36,77.67,69.76,63.9,60.38,57.41,54.84,52.57,50.56,48.71,46.97,45.25,43.48,41.6,39.5,37.19,34.81,32.46,30.27,28.36,26.85,25.86,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.5,25.27,24.65,23.7,22.52,21.17,19.75,18.33,16.98,15.8,14.85,14.23,14,14.02,14.08,14.17,14.29,14.44,14.61,14.8,15.01,15.23,15.47,15.71,15.95,16.19,16.43,16.67,16.89,17.1,17.29,17.46,17.61,17.73,17.82,17.88,17.9,17.63,16.88,15.75,14.33,12.71,10.98,9.23,7.56,6.05,4.81,3.92,3.47,3.28,3.1,2.93,2.76,2.61,2.46,2.32,2.19,2.07,1.96,1.85,1.75,1.66,1.58,1.51,1.44,1.39,1.34,1.29,1.26,1.23,1.22,1.2,1.2,1.2,1.2,1.2,1.2,1.21,1.21,1.21,1.21,1.22,1.22,1.22,1.23,1.23,1.23,1.24,1.24,1.25,1.25,1.25,1.26,1.26,1.27,1.27,1.27,1.28,1.28,1.28,1.29,1.29,1.29,1.29,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.29,1.29,1.29,1.29,1.28,1.28,1.28,1.27,1.27,1.26,1.25,1.25,1.24,1.23,1.23,1.22,1.21,1.2,1.16,1.06,0.95,0.83,0.74,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.71,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.69,0.69,0.69,0.69,0.69,0.69,0.69,0.69,0.68,0.68,0.68,0.68,0.68,0.68,0.67,0.67,0.67,0.67,0.67,0.67,0.67,0.66,0.66,0.66,0.66,0.66,0.66,0.66,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.65,0.66,0.68,0.69,0.71,0.73,0.74,0.76,0.77,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.78,0.8,0.86,0.95,1.08,1.25,1.46,1.7,1.97,2.28,2.63,3.01,3.42,3.87,4.35,4.86,5.4,5.98,6.59,7.92,10.49,14.04,18.31,23.04,27.98,32.87,37.45,41.46,44.64,46.74,47.5,46.86,45.16,42.77,40.04,37.33,35,32.74,30.21,27.7,25.5,23.9,23.2,23.06,22.94,22.84,22.77,22.72,22.7,22.8,23.23,23.95,24.91,26.04,27.3,28.76,30.7,33.39,37.12,42.15,48.77,65.22,252.1,257,237.32,221.19,212,208.67,206.89,205.2,202.15,189.82,172,165.3,160.49,156.8,153.44,149.62,144.6,138.27,131,123.11,114.9,106.69,98.79,91.5,85.13,80,75.53,71.03,66.65,62.54,58.85,55.73,53.31,51.75,51.2,56.53,68.25,80,91.01,102.03,109,112.37,115.29,117.68,119.48,120.61,121,119.45,115.57,110.52,105.47,101.58,100,99.97,99.94,99.92,99.9,99.88,99.86,99.85,99.84,99.83,99.82,99.81,99.81,99.8,99.8,99.8,122.15,163.65,186,182.96,175.15,164.56,153.18,143,136,131.37,126.98,122.81,118.85,115.09,111.52,108.13,104.9,101.83,98.9,96.11,93.44,90.87,88.41,86.04,83.74,81.51,79.33,77.2,75.1,73.02,70.95,68.88,66.8,64.87,63.14,61.4,59.53,57.67,56,54.6,53.36,52.2,51.05,49.85,48.5,46.87,44.92,42.74,40.42,38.04,35.69,33.46,31.44,29.72,28.38,27.51,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.2,27.14,26.97,26.7,26.35,25.95,25.49,25.02,24.53,24.04,23.58,23.16,22.8,22.46,22.11,21.75,21.39,21.03,20.69,20.36,20.05,19.78,19.54,19.35,19.2,19.09,19,18.92,18.85,18.79,18.74,18.68,18.62,18.56,18.49,18.4,18.3,18.17,18.02,17.83,17.63,17.41,17.18,16.93,16.68,16.43,16.18,15.93,15.7,15.47,15.22,14.97,14.71,14.45,14.18,13.93,13.68,13.44,13.21,13,12.8,12.62,12.46,12.31,12.16,12.03,11.89,11.76,11.62,11.48,11.33,11.17,11,10.81,10.59,10.36,10.12,9.86,9.61,9.36,9.12,8.89,8.68,8.5,8.35,8.21,8.08,7.94,7.81,7.68,7.56,7.46,7.36,7.29,7.23,7.19,7.18,7.51,8.42,9.81,11.58,13.63,15.86,18.16,20.44,22.58,24.49,26.06,27.2,28.08,28.95,29.81,30.65,31.48,32.28,33.07,33.82,34.55,35.25,35.92,36.56,37.15,37.71,38.23,38.7,39.13,39.5,39.83,40.1,40.31,40.47,40.57,40.6,40.49,40.16,39.64,38.94,38.09,37.1,36,34.79,33.51,32.17,30.79,29.39,27.99,26.6,25.25,23.96,22.75,21.63,20.63,19.76,19.04,18.49,18.14,18,17.97,17.95,17.94,17.92,17.91,17.9,17.89,17.88,17.87,17.85,17.83,17.8,17.7,17.46,17.13,16.7,16.21,15.68,15.13,14.57,14.04,13.56,13.14,12.8,12.52,12.27,12.02,11.79,11.57,11.37,11.16,10.97,10.78,10.59,10.39,10.2,10.01,9.81,9.63,9.44,9.26,9.08,8.9,8.73,8.56,8.39,8.22,8.06,7.9,7.73,7.57,7.41,7.25,7.09,6.94,6.79,6.65,6.52,6.4,6.28,6.17,6.08,5.98,5.9,5.81,5.73,5.65,5.57,5.49,5.41,5.32,5.23,5.14,5.04,4.94,4.84,4.74,4.63,4.53,4.43,4.33,4.23,4.13,4.03,3.93,3.81,3.69,3.57,3.45,3.33,3.22,3.12,3.04,2.98,2.93,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.92,2.9,2.86,2.8,2.71,2.62,2.52,2.42,2.33,2.24,2.18,2.14,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.12,2.1,2.06,2,1.91,1.82,1.71,1.61,1.5,1.4,1.32,1.25,1.2,1.16,1.13,1.1,1.06,1.03,1,0.97,0.93,0.9,0.87,0.85,0.82,0.79,0.77,0.74,0.72,0.69,0.67,0.65,0.63,0.61,0.59,0.58,0.56,0.54,0.53,0.52,0.51,0.5,0.49,0.48,0.48,0.47,0.47,0.46,0.46,0.47,0.48,0.5,0.53,0.56,0.59,0.62,0.64,0.67,0.69,0.7,0.71,0.71,0.71,0.71,0.7,0.7,0.7,0.69,0.69,0.69,0.68,0.68,0.67,0.67,0.67,0.66,0.66,0.65,0.65,0.65,0.65,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.64,0.65,0.65,0.65,0.66,0.66,0.67,0.68,0.69,0.69,0.7,0.71,0.73,0.74,0.75,0.76,0.78,0.8,0.81,0.83,0.85,0.87,0.89,0.92,0.94,0.97,0.99,1.02,1.05,1.08,1.11,1.15,1.18,1.32,1.66,2.21,2.97,3.94,5.11,6.5,8.1,9.9,11.92,14.15,16.6,22.3,22.8,24.48,30.38,35.74,42.4,57.14,94.04,112.9,123.4,130.4,130,119.4,120.7,116.8,118.1,119.4,124.8,143.5,204,294,319.2,328.4,365,350.8,347.6,347.6,325,331.6,319.2,308,308,308,308,296.8,300,281,278.4,270.6,271,253.6,233.5,219.2,207.8,205.9,204,189.6,178.8,173.4,160,154.4,146,145,140.5,130.4,126.2,116.8,112.9,106.5,101.6,98.51,82.67,67.3,80.05,76.12,72.3,71.02,69.78,67.3,67.3,68.54,57.6,71.02,66.06,59.12,57.14,55.16,55.16,52.19,52.19,51.2,48.56,44.16,43,45.92,49.44,44.16,36.48,35.74,35,32.36,37.22,32.36,32.36,32.36,33.68,32.36,31.7,35.74,29.72,32.36,30.38,29.72,28.4,28.4,28.4,27.28,25.6,25.04,23.92,22.3,21.8,21.8,21.8,22.8,21.8,25.6,22.8,22.8,17.8,16.04,16.04,16.04,16.04,16.04,16.04,16.04,16.04,16.04,16.04,15.02,14,14.03,14.11,14.25,14.45,14.72,15.06,15.46,15.95,16.51,17.15,17.87,18.69,19.59,20.59,21.69,22.88,24.18,25.59,27.1,28.73,30.48,32.34,34.33,36.44,38.69,41.06,43.57,46.22,49.01,51.95,55.04,58.27,61.66,65.21,68.92,72.8,88.09,104.9,105.7,110.3,111.6,110.3,106.5,105.7,103.3,100,97.02,98.8,91.07,83.98,88.09,81.36,78.74,77.43,77.43,73.5,74.81,72.63,68.58,66.4,68.54,69.78,67.3,64.82,61.1,59.12,56.15,53.18,50.32,49.44,44.16,36.5,42.4,37.96,37.22,33.68,36.48,35.74,35,35,37.22,37.22,39.44,32.6,34.54,36.48,35.74,34.34,33.68,33.02,31.04,29.72,29.72,29.72,26.16,25.6,29.72,18.3,22.3,21.3,21.8,21.8,20.3,20.8,25.04,25.04,25.6,25.6,25.04,25.6,25.04,25.6,23.92,25.04,21.3,21.8,22.3,21.8,20.8,16.1,20.3,18.3,13.22,19.3,19.3,18.3,14.4,13.86,13.36,12.9,12.48,12.1,11.75,11.43,11.15,10.9,10.67,10.48,10.31,10.16,10.04,9.93,9.85,9.78,9.73,9.69,9.67,9.65,9.65,12.08,8.67,11.7,11.38,10.65,9.84,9.32,9.07,8.85,8.66,8.49,8.35,8.22,8.1,7.98,7.86,7.74,7.61,7.47,7.31,7.14,6.96,6.78,6.58,6.39,6.19,5.99,5.78,5.58,5.39,5.2,5.01,4.83,4.67,4.51,4.37,4.24,4.12,4.02,3.95,3.89,3.85,3.84,4.41,5.77,7.39,8.75,9.32,9.18,9,8.94,8.88,8.83,8.78,8.73,8.68,8.64,8.6,8.56,8.53,8.5,8.47,8.45,8.42,8.4,8.39,8.37,8.36,8.35,8.35,8.34,8.34,8.67,9.65,9.62,9.53,9.4,9.21,8.98,8.7,8.4,8.06,7.69,7.3,6.89,6.47,6.03,5.59,5.14,4.7,4.26,3.83,3.42,3.02,2.65,2.3,1.98,1.7,1.45,1.25,1.09,0.99,0.94,0.92,0.91,0.89,0.87,0.85,0.84,0.82,0.81,0.79,0.78,0.77,0.75,0.74,0.73,0.72,0.71,0.7,0.69,0.68,0.67,0.66,0.65,0.64,0.64,0.63,0.63,0.62,0.62,0.61,0.61,0.61,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.61,0.61,0.61,0.61,0.61,0.61,0.62,0.62,0.62,0.62,0.63,0.63,0.63,0.63,0.63,0.64,0.64,0.64,0.64,0.64,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.64,0.63,0.62,0.6,0.59,0.57,0.55,0.54,0.53,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.51,0.51,0.51,0.5,0.5,0.49,0.48,0.47,0.47,0.46,0.45,0.45,0.44,0.43,0.42,0.42,0.41,0.41,0.41,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.41,0.42,0.43,0.44,0.46,0.48,0.5,0.53,0.55,0.58,0.61,0.64,0.67,0.7,0.73,0.77,0.8,0.83,0.87,0.9,0.93,0.96,0.99,1.02,1.05,1.08,1.1,1.12,1.14,1.16,1.17,1.18,1.19,1.2,1.2,1.2,1.19,1.17,1.15,1.12,1.09,1.06,1.02,0.98,0.94,0.9,0.86,0.82,0.78,0.74,0.7,0.66,0.63,0.6,0.57,0.55,0.53,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.52,0.51,0.51,0.5,0.5,0.49,0.49,0.48,0.47,0.47,0.47,0.46,0.46,0.45,0.45,0.45,0.44,0.44,0.44,0.43,0.43,0.43,0.42,0.42,0.42,0.41,0.41,0.41,0.41,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.41,0.42,0.42,0.42,0.42,0.42,0.42,0.42,0.42,0.42,0.43,0.43,0.43,0.43,0.43,0.43,0.44,0.44,0.44,0.44,0.44,0.44,0.45,0.45,0.45 ] }, { name: '降雨量', type: 'line', yAxisIndex: 1, animation: false, areaStyle: {}, lineStyle: { width: 1 }, markArea: { silent: true, data: [ [{ xAxis: '2009/9/10\n7:00' }, { xAxis: '2009/9/20\n7:00' }] ] }, data: [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.005,0.017,0.017,0.017,0.017,0.011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.021,0.026,0.03,0.036,0.036,0.195,0.221,0.019,0.013,0.017,0.03,0.03,0.03,0.046,0.045,0.038,0.084,0.045,0.045,0.037,0.034,0.035,0.036,0.044,0.052,0.048,0.109,0.033,0.029,0.04,0.042,0.042,0.042,0.073,0.076,0.062,0.066,0.066,0.075,0.096,0.128,0.121,0.128,0.14,0.226,0.143,0.097,0.018,0,0,0,0,0,0.018,0.047,0.054,0.054,0.054,0.036,0.185,0.009,0.038,0.061,0.077,0.091,0.126,0.69,0.182,0.349,0.231,0.146,0.128,0.167,0.1,0.075,0.071,0.071,0.117,0.01,0.002,0.002,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.005,0.026,0.038,0.038,0.038,0.076,0.086,0.109,0.213,0.276,0.288,0.297,0.642,1.799,1.236,2.138,0.921,0.497,0.685,0.828,0.41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.018,0.024,0.024,0.024,0.024,0.006,0.003,0.046,0.046,0.046,0.046,0.043,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.204,0.303,1.028,1.328,1.524,1.41,1.362,1.292,1.191,0.529,0.501,0.944,1.81,2.899,0.859,0.126,0.087,0.047,0,0,0,0,0.011,0.028,0.028,0.028,0.028,0.017,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.099,0.159,0.297,0.309,0.309,0.614,0.818,1.436,1.195,0.553,0.542,0.955,0.898,0.466,0.386,0.556,0.388,0.221,0.192,0.192,0.187,0.166,0.18,0.302,0.158,0.009,0.009,0.009,0.009,0.009,0.007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.004,0.032,0.032,0.032,0.032,0.082,0.149,0.204,0.247,0.262,0.49,0.51,0.533,0.746,0.847,2.393,1.188,1.114,0.475,0.043,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.017,0.017,0.021,0.042,0.079,0.111,0.126,0.122,0.133,0.846,0.102,0.077,0.067,0.056,0.005,0,0,0,0,0,0,0,0,0,0,0,0,0,0.011,0.017,0.017,0.017,0.017,0.006,0,0,0,0,0,0.01,0.03,0.054,0.067,0.07,0.25,0.251,0.494,0.065,0.054,0.054,0.064,0.084,0.077,0.101,0.132,0.248,0.069,0.117,0.115,0.087,0.326,0.036,0.009,0.009,0.009,0.009,0.009,0.004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.02,0.039,0.04,0.04,0.04,0.229,0.079,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.023,0.069,0.082,0.082,0.082,0.503,0.774,0.038,0.012,0.012,0.012,0.016,0.02,0.028,0.051,0.06,0.064,0.19,0.15,0.164,0.139,0.13,0.085,0.031,0.023,0.022,0.007,0.005,0.005,0.001,0,0.02,0.048,0.048,0.053,0.056,0.036,0.008,0.008,0.004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.013,0.017,0.036,0.068,0.095,0.233,0.272,0.377,0.722,1.494,3.756,0.954,0.439,0.442,0.462,0.373,0.249,0.214,0.1,0.044,0.037,0.023,0.002,0,0,0,0,0,0,0.02,0.024,0.024,0.024,0.024,0.004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.008,0.017,0.017,0.045,0.186,0.308,0.241,0.241,0.893,4.067,4.494,5.015,3.494,2.057,1.411,0.718,0.407,0.313,0.339,1.537,1.105,0.218,0.136,0.03,0.005,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.037,0.448,1.2,1.309,1.309,1.425,1.223,0.471,0.767,0.423,0.273,0.412,0.646,0.481,0.239,0.131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.044,0.15,0.223,0.388,0.513,0.883,2.828,4.786,5.959,4.95,6.434,6.319,3.35,2.806,4.204,1.395,1.015,1.015,0.836,0.74,0.72,0.615,0.477,0.192,0.046,0.007,0.007,0.007,0.007,0.007,0.007,0.007,0.008,0.005,0.005,0.005,0.005,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001,0.012,0.012,0.012,0.012,0.011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.002,0.012,0.028,0.028,0.028,0.138,0.092,0.082,0.082,0.096,0.719,0.155,0.042,0.047,0.129,0.021,0.021,0.014,0.009,0.029,0.067,0.088,0.095,0.095,0.138,0.091,0.032,0.025,0.025,0.003,0,0,0,0,0,0,0,0,0,0,0,0,0.002,0.045,0.228,0.297,0.325,0.339,0.581,1.244,0.796,0.517,0.227,0.053,0.006,0,0,0,0,0,0,0,0,0,0.003,0.005,0.005,0.005,0.005,0.081,0.129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.014,0.041,0.041,0.041,0.041,0.027,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.009,0.017,0.017,0.017,0.017,0.355,0.174,0.009,0.009,0.012,0.136,0.208,0.208,0.208,0.215,7.359,1.858,0.458,0.053,0.053,0.047,0.045,0.045,0.059,0.136,0.188,0.206,0.21,0.588,1.517,6.02,4.688,4.42,0.624,0.326,0.359,0.553,0.899,0.94,2.95,9.415,5.752,1.092,0.096,0.035,0.026,0.018,0.015,0.011,0.011,0.011,0,0,0,0,0,0,0,0,0,0,0,0.056,0.27,0.314,0.351,0.354,0.609,0.796,1.857,0.848,0.538,0.214,0.178,0.178,0.201,0.231,0.227,0.272,0.397,0.45,1.014,2.917,1.675,0.081,0.059,0.059,0.148,0.075,0.075,0.078,0.236,0.784,0.784,0.784,0.784,0.741,0.115,0.058,0.058,0.058,0.029,0.015,0.015,0.015,0.015,0.012,0.008,0.604,0.985,1.305,2.273,2.528,2.336,2.496,2.281,1.397,1.713,3.259,1.167,0.745,0.548,1.058,0.684,0.728,0.392,0.179,0.283,0.283,0.46,0.08,0.099,0.099,0.099,0.1,0.143,0.137,0.238,0.317,0.262,0.225,0.792,0.426,0.332,0.261,0.11,0.093,0.102,0.171,0.292,0.504,0.605,1.745,2.485,1.964,0.33,0.171,0.259,0.242,0.215,0.366,0.354,0.205,0.203,0.262,0.153,0.13,0.137,0.362,0.691,0.295,0.433,0.154,0.056,0.053,0.053,0.053,0.051,0.047,0.065,0.078,0.091,0.206,0.813,0.102,0.151,0.05,0.024,0.004,0.001,0,0,0,0.021,0.021,0.021,0.021,0.021,0.013,0.013,0.013,0.013,0.013,0.013,0.013,0.013,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.008,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.018,0.021,0.021,0.021,0.021,0.003,0,0,0,0,0,0,0,0,0,0.024,0.173,0.261,0.267,0.267,0.534,1.354,1.772,0.72,0.218,0.018,0.018,0.028,0.036,0.032,0.194,0.082,0.035,0.286,0.027,0.038,0.038,0.027,0.021,0.014,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.016,0.017,0.017,0.031,0.047,0.043,0.056,0.104,0.149,0.179,0.205,0.328,0.998,0.522,1.851,3.727,3.273,2.204,1.169,1.006,1.179,0.74,0.741,1.065,0.925,0.671,0.497,0.431,0.327,0.277,0.126,0.581,0.207,0.359,2.485,0.038,0.036,0.003,0.003,0.003,0.003,0.004,0.098,0.023,0.021,0.021,0.022,0.041,0.041,0.043,0.045,0.043,0.014,0.014,0.014,0.014,0.014,0.014,0.014,0.031,0.046,0.063,0.119,0.107,0.092,0.085,0.065,0.06,0.054,0.042,0.039,0.046,0.044,0.028,0.028,0.02,0.013,0.013,0.013,0.013,0.016,0.032,0.031,0.031,0.031,0.028,0.011,0.011,0.011,0.011,0.011,0.023,0.024,0.024,0.024,0.019,0.015,0.015,0.015,0.015,0.015,0.015,0.013,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.001,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.011,0.017,0.024,0.026,0.061,0.172,0.206,0.213,0.267,0.511,0.668,0.157,0.017,0.017,0.017,0.046,0.054,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001,0.017,0.017,0.017,0.017,0.016,0,0,0,0,0,0,0,0,0,0.01,0.017,0.017,0.017,0.017,0.012,0.017,0.017,0.017,0.017,0.012,0,0,0,0,0,0.003,0.031,0.066,0.093,0.112,0.122,0.202,0.068,0.041,0.022,0.011,0,0,0,0,0,0,0,0,0,0,0,0.002,0.005,0.012,0.021,0.021,0.019,0.033,0.03,0.026,0.026,0.034,0.095,0.024,0.024,0.024,0.023,0.019,0.018,0.018,0.018,0.011,0.03,0.045,0.044,0.044,0.044,0.022,0.009,0.024,0.033,0.033,0.033,0.024,0.009,0,0,0,0,0,0,0.003,0.017,0.017,0.017,0.017,0.014,0,0,0,0,0,0.032,0.032,0.032,0.032,0.032,0.005,0.008,0.009,0.014,0.014,0.009,0.005,0.004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.007,0.009,0.009,0.009,0.009,0.043,0.063,0.084,0.098,0.101,0.213,0.334,0.383,0.43,0.448,0.511,0.801,0.835,1.642,1.614,1.496,1.496,1.476,1.068,0.481,0.22,0.119,0.099,0.07,0.072,0.063,0.076,0.14,0.205,0.28,0.297,0.3,0.479,0.877,1.098,1.611,1.629,1.686,1.686,1.631,1.528,1.862,1.703,1.531,2.196,0.395,0.416,0.453,0.728,0.917,0.986,1.17,2.171,3.011,2.909,3.301,1.377,0.778,0.799,0.947,1.039,0.879,0.76,1.372,1.674,1.674,1.68,1.823,1.793,1.162,0.783,0.216,0.152,0.152,0.152,0.049,0,0,0,0.117,0.127,0.127,0.127,0.127,0.127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.003,0.005,0.005,0.005,0.005,0.003,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.309,0.364,0.364,0.364,0.364,0.063,0.01,0.01,0.01,0.012,0.015,0.015,0.11,0.55,0.824,0.825,0.829,1.39,1.429,1.342,1.43,1.636,1.717,2.135,2.203,3.191,3.022,1.589,0.86,0.807,0.645,0.595,0.588,0.557,0.552,1.271,0.708,0.677,0.629,0.714,0.203,0.133,0.061,0.062,0.018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001,0.072,0.29,0.438,0.53,0.557,0.873,1.039,1.04,0.208,0.049,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.03,0.039,0.039,0.039,0.039,0.098,0.008,0.007,0.007,0.007,0.007,0.007,0.007,0.007,0.007,0.007,0.056,0.062,0.065,0.065,0.065,0.047,0.216,0.256,0.315,0.4,0.502,0.449,0.47,0.571,0.814,1.153,0.774,0.202,0.086,0.075,0.071,0.032,0.019,0.003,0.004,0.004,0.004,0.004,0.004,0.004,0.007,0.072,0.153,0.256,0.306,0.404,0.698,0.733,0.823,0.715,0.563,0.404,0.293,0.217,0.213,0.202,0.202,0.294,0.704,0.797,1.359,1.101,0.72,0.514,0.539,0.434,0.389,0.387,0.386,0.375,0.369,0.319,0.239,0.183,0.136,0.062,0.052,0.096,0.119,0.119,0.114,0.127,0.132,0.139,0.169,0.191,0.278,0.254,0.214,0.237,0.221,0.143,0.129,0.125,0.109,0.1,0.087,0.06,0.038,0.029,0.029,0.028,0.048,0.053,0.053,0.111,0.125,0.102,0.097,0.097,0.039,0.02,0.02,0.02,0.014,0.004,0.031,0.043,0.047,0.052,0.08,0.144,0.182,0.176,0.171,0.149,0.112,0.025,0,0,0,0,0,0,0,0.016,0.031,0.031,0.031,0.031,0.015,0,0,0,0,0,0.005,0.005,0.005,0.005,0.005,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.005,0.005,0.005,0.005,0.005,0.001,0,0,0 ] } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); Line Easing Visualizing // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts1092')); // 指定图表的配置项和数据 var option = option = { title: titles.concat([{ text: 'Different Easing Functions', top: 'bottom', left: 'center' }]), grid: grids, xAxis: xAxes, yAxis: yAxes, series: series }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 柱状图Bar 柱状图动画延迟 // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts262')); // 指定图表的配置项和数据 var option = option = { title: { text: '柱状图动画延迟' }, legend: { data: ['bar01', 'bar02'] }, toolbox: { // y: 'bottom', feature: { magicType: { type: ['stack', 'tiled'] }, dataView: {}, saveAsImage: { pixelRatio: 2 } } }, tooltip: {}, xAxis: { data: xAxisData, splitLine: { show: false } }, yAxis: { }, series: [{ name: 'bar01', type: 'bar', data: data01, animationDelay: function (idx) { return idx * 10 + 50; } }, { name: 'bar02', type: 'bar', data: data02, animationDelay: function (idx) { return idx * 10 + 100; } }], animationEasing: 'elasticOut', animationDelayUpdate: function (idx) { return idx * 5; } }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 柱状图框选 // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts3297')); // 指定图表的配置项和数据 var option = option = { backgroundColor: '#eee', legend: { data: ['bar', 'bar2', 'bar3', 'bar4'], left: 10 }, brush: { toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'], xAxisIndex: 0 }, toolbox: { feature: { magicType: { type: ['stack', 'tiled'] }, dataView: {} } }, tooltip: {}, xAxis: { data: xAxisData, name: 'X Axis', axisLine: {onZero: true}, splitLine: {show: false}, splitArea: {show: false} }, yAxis: { inverse: true, splitArea: {show: false} }, grid: { left: 100 }, visualMap: { type: 'continuous', dimension: 1, text: ['High', 'Low'], inverse: true, itemHeight: 200, calculable: true, min: -2, max: 6, top: 60, left: 10, inRange: { colorLightness: [0.4, 0.8] }, outOfRange: { color: '#bbb' }, controller: { inRange: { color: '#2f4554' } } }, series: [ { name: 'bar', type: 'bar', stack: 'one', emphasis: emphasisStyle, data: data1 }, { name: 'bar2', type: 'bar', stack: 'one', emphasis: emphasisStyle, data: data2 }, { name: 'bar3', type: 'bar', stack: 'two', emphasis: emphasisStyle, data: data3 }, { name: 'bar4', type: 'bar', stack: 'two', emphasis: emphasisStyle, data: data4 } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 极坐标系下的堆叠柱状图 // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts8847')); // 指定图表的配置项和数据 var option = option = { angleAxis: { type: 'category', data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] }, radiusAxis: { }, polar: { }, series: [{ type: 'bar', data: [1, 2, 3, 4, 3, 5, 1], coordinateSystem: 'polar', name: 'A', stack: 'a' }, { type: 'bar', data: [2, 4, 6, 1, 3, 2, 1], coordinateSystem: 'polar', name: 'B', stack: 'a' }, { type: 'bar', data: [1, 2, 3, 4, 1, 2, 5], coordinateSystem: 'polar', name: 'C', stack: 'a' }], legend: { show: true, data: ['A', 'B', 'C'] } }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 饼图Pie Texture on Pie Chart // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts5180')); // 指定图表的配置项和数据 var option = option = { backgroundColor: { image: bgPatternImg, repeat: 'repeat' }, title: { text: '饼图纹理', textStyle: { color: '#235894' } }, tooltip: {}, series: [{ name: 'pie', type: 'pie', selectedMode: 'single', selectedOffset: 30, clockwise: true, label: { fontSize: 18, color: '#235894' }, labelLine: { lineStyle: { color: '#235894' } }, data: [ {value: 335, name: '直接访问'}, {value: 310, name: '邮件营销'}, {value: 234, name: '联盟广告'}, {value: 135, name: '视频广告'}, {value: 1548, name: '搜索引擎'} ], itemStyle: itemStyle }] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 地理坐标/地图GEO/Map Air Quality - Baidu Map 可进入页面查看 K 线图Candlestick Candlestick Brush 可进入页面查看 雷达图Radar Proportion of Browsers // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts1495')); // 指定图表的配置项和数据 var option = option = { title: { text: '浏览器占比变化', subtext: '纯属虚构', top: 10, left: 10 }, tooltip: { trigger: 'item', backgroundColor: 'rgba(0,0,250,0.2)' }, legend: { type: 'scroll', bottom: 10, data: (function (){ var list = []; for (var i = 1; i 关系图Graph Graph Webkit Dep 可进入页面查看 树图Tree Multiple Trees // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts6774')); // 指定图表的配置项和数据 var option = option = { tooltip: { trigger: 'item', triggerOn: 'mousemove' }, legend: { top: '2%', left: '3%', orient: 'vertical', data: [{ name: 'tree1', icon: 'rectangle' }, { name: 'tree2', icon: 'rectangle' }], borderColor: '#c23531' }, series:[ { type: 'tree', name: 'tree1', data: [data], top: '5%', left: '7%', bottom: '2%', right: '60%', symbolSize: 7, label: { position: 'left', verticalAlign: 'middle', align: 'right' }, leaves: { label: { position: 'right', verticalAlign: 'middle', align: 'left' } }, expandAndCollapse: true, animationDuration: 550, animationDurationUpdate: 750 }, { type: 'tree', name: 'tree2', data: [data2], top: '20%', left: '60%', bottom: '22%', right: '18%', symbolSize: 7, label: { position: 'left', verticalAlign: 'middle', align: 'right' }, leaves: { label: { position: 'right', verticalAlign: 'middle', align: 'left' } }, expandAndCollapse: true, animationDuration: 550, animationDurationUpdate: 750 } ] } // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 日历坐标系Calendar Calendar Heatmap Horizontal // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts9940')); // 指定图表的配置项和数据 var option = option = { tooltip: { position: 'top' }, visualMap: { min: 0, max: 1000, calculable: true, orient: 'horizontal', left: 'center', top: 'top' }, calendar: [{ range: '2020', cellSize: ['auto', 15] }, { top: 260, range: '2019', cellSize: ['auto', 15] }], series: [{ type: 'heatmap', coordinateSystem: 'calendar', calendarIndex: 0, data: getVirtulData(2020) }, { type: 'heatmap', coordinateSystem: 'calendar', calendarIndex: 1, data: getVirtulData(2019) }] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); 3D Bar3D - Simplex Noise 可进入页面查看 Surface Wave // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts3713')); // 指定图表的配置项和数据 var option = option = { tooltip: {}, backgroundColor: '#fff', visualMap: { show: false, dimension: 2, min: -1, max: 1, inRange: { color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'] } }, xAxis3D: { type: 'value' }, yAxis3D: { type: 'value' }, zAxis3D: { type: 'value', max: 1, splitNumber: 2 }, grid3D: { viewControl: { // projection: 'orthographic' }, boxHeight: 40 }, series: [{ type: 'surface', wireframe: { show: false }, shading: 'color', equation: { x: { step: 0.05, min: -3, max: 3, }, y: { step: 0.05, min: -3, max: 3, }, z: function (x, y) { return Math.sin(x * x + y * y) * x / 3.14 } } }] } // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); pyecharts py+echarts=pyecharts 是什么 Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。 怎么用–py或jupyter pip 安装 $ pip install pyecharts -U 生成 HTML from pyecharts.charts import Bar from pyecharts import options as opts # V1 版本开始支持链式调用 bar = ( Bar() .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"]) .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105]) .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49]) .set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况")) ) bar.render() # 不习惯链式调用的开发者依旧可以单独调用方法 bar = Bar() bar.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"]) bar.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105]) bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49]) bar.set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况")) bar.render() Demo:pyecharts 画廊 pyecharts仓库 参考 在 Hexo 中插入 ECharts 动态图表 echarts examples echarts 官网 Fluid+ECharts 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2022/8/11
articleCard.readMore

一大堆寓意深刻的管理故事锦集

一些寓意深刻的小故事合集! 几十个关于管理,经营的故事。寓教于乐,寓意深刻,在自己遗忘之前,记录保存下来。包括 扁鹊三兄弟,曲突徒薪,猎人与狗等等 法不轻传,道不外卖,师不顺路,医不抠门! 每一个小故事都从国家治理,企业管理,家庭维护等多个角度去多维度分析,多读几遍,多思考一会儿,必有大收获! 八个管理故事 分 工 【故 事】 一位年轻的炮兵军官上任后,到下属部队视察操练情况,发现有几个部队操练时有一个共同的情况:在操练中,总有一个士兵自始至终站在大炮的炮筒下,纹丝不动。经过询问,得到的答案是:操练条例就是这样规定的。原来,条例因循的是用马拉大炮时代的规则,当时站在炮筒下的士兵的任务是拉住马的缰绳,防止大炮发射后因后座力产生的距离偏差,减少再次瞄准的时间。现在大炮不再需要这一角色了。但条例没有及时调整,出现了不拉马的士兵。这位军官的发现使他受到了国防部的表彰。 【分 析】 **管理的首要工作就是科学分工。**只有每个员工都明确自己的岗位职责,才不会产生推委、扯皮等不良现象。如果公司象一个庞大的机器,那么每个员工就是一个个零件,只有他们爱岗敬业,公司的机器才能得以良性运转。**公司是发展的,管理者应当根据实际动态情况对人员数量和分工及时做出相应调整。否则,队伍中就会出现“不拉马的士兵”。**如果队伍中有人滥竽充数,给企业带来的不仅仅是工资的损失,而且会导致其他人员的心理不平衡,最终导致公司工作效率整体下降。 标 准 【故 事】 有一个小和尚担任撞钟一职,半年下来,觉得无聊之极,“做一天和尚撞一天钟”而已。有一天,主持宣布调他到后院劈柴挑水,原因是他不能胜任撞钟一职。小和尚很不服气地问:“我撞的钟难道不准时、不响亮?”老主持耐心地告诉他:“你撞的钟虽然很准时、也很响亮,但钟声空泛、疲软,没有感召力。钟声是要唤醒沉迷的众生,因此,撞出的钟声不仅要洪亮,而且要圆润、浑厚、深沉、悠远。” 【分 析】 本故事中的主持犯了一个常识性管理错误,“做一天和尚撞一天钟”是由于主持没有提前公布工作标准造成的。如果小和尚进入寺院的当天就明白撞钟的标准和重要性,我想他也不会因怠工而被撤职。**工作标准是员工的行为指南和考核依据。缺乏工作标准,往往导致员工的努力方向与公司整体发展方向不统一,造成大量的人力和物力资源浪费。**因为缺乏参照物,时间久了员工容易形成自满情绪,导致工作懈怠。制定工作标准尽量做到数字化,要与考核联系起来,注意可操作性。 体 制 【故 事】 有七个人住在一起,每天共喝一桶粥,但粥每天都不够。一开始,他们抓阄决定谁来分粥,每天轮一个。于是乎每周下来,他们只有一天是饱的,就是自己分粥的那一天。后来他们开始推选出一个道德高尚的人出来分粥。强权就会产生腐败,大家开始挖空心思去讨好他,贿赂他,搞得整个小团体乌烟瘴气。然后大家开始组成三人的分粥委员会及四人的评选委员会,互相攻击扯皮下来,粥吃到嘴里全是凉的。最后想出来一个方法:轮流分粥,但分粥的人要等其它人都挑完后拿剩下的最后一碗。为了不让自己吃到最少的,每人都尽量分得平均,就算不平,也只能认了。大家快快乐乐,和和气气,日子越过越好。 【分 析】 **管理的真谛在“理”不在“管”。**管理者的主要职责就是建立一个象“轮流分粥,分者后取”那样合理的游戏规则,让每个员工按照游戏规则自我管理。游戏规则要兼顾公司利益和个人利益,并且要让个人利益与公司整体利益统一起来。**责任、权利和利益是管理平台的三根支柱,缺一不可。缺乏责任,公司就会产生腐败,进而衰退;缺乏权利,管理者的执行就变成废纸;缺乏利益,员工就会积极性下降,消极怠工。**只有管理者把“责、权、利”的平台搭建好,员工才能“八仙过海,各显其能”。 表 率 【故 事】 春秋晋国有一名叫李离的狱官,他在审理一件案子时,由于听从了下属的一面之辞,致使一个人冤死。真相大白后,李离准备以死赎罪,晋文公说:官有贵贱,罚有轻重,况且这件案子主要错在下面的办事人员,又不是你的罪过。李离说:“我平常没有跟下面的人说我们一起来当这个官,拿的俸禄也没有与下面的人一起分享。现在犯了错误,如果将责任推到下面的办事人员身上,我又怎么做得出来。”他拒绝听从晋文公的劝说,伏剑而死。 【分 析】 正人先正己,做事先做人。**管理者要想管好下属必须以身作则,示范的力量是惊人的。**不但要象先人李离那样勇于替下属承担责任,而且要事事为先、严格要求自己,做到“己所不欲,勿施于人”。**一旦通过表率树立起在员工中的威望,将会上下同心,大大提高团队的整体战斗力。**得人心者得天下,做下属敬佩的领导将使管理事半功倍。 竞 争 【故 事】 国外一家森林公园曾养殖几百只梅花鹿,尽管环境幽静,水草丰美,又没有天敌,而几年以后,鹿群非但没有发展,反而病的病,死的死,竟然出现了负增长。后来他们买回几只狼放置在公园里,在狼的追赶捕食下,鹿群只得紧张地奔跑以逃命。这样一来,除了那些老弱病残者被狼捕食外,其它鹿的体质日益增强,数量也迅速地增长着。 【分 析】 **流水不腐,户枢不蠹。人天生有种惰性,没有竞争就会固步自封,躺在功劳簿上睡大觉。**竞争对手就是追赶梅花鹿的狼,时刻让梅花鹿清楚狼的位置和同伴的位置。跑在前面的梅花鹿可以得到更好的食物,跑在最后的梅花鹿就成了狼的食物。按照市场规则,给予“头鹿”奖励,让“末鹿”被市场淘汰。 沟 通 【故 事】 美国知名主持人“林克莱特”一天访问一名小朋友,问他说:“你长大后想要当什么呀?”小朋友天真的回答:“我要当飞机的驾驶员!”林克莱特接着问:“如果有一天,你的飞机飞到太平洋上空所有引擎都熄火了,你会怎么办?”小朋友想了说:“我会先告诉坐在飞机上的人绑好安全带,然后我挂上我的降落伞跳出去。”当在现场的观众笑的东倒西歪时,林克莱特继续注视这孩子,想看他是不是自作聪明的家伙。没想到,接著孩子的两行热泪夺眶而出,这才使得林克莱特发觉这孩子的悲悯之情远非笔墨所能形容。于是林克莱特问他说:“为甚么要这么做?”小孩的答案透露出一个孩子真挚的想法:“我要去拿燃料,我还要回来!!”。 【分 析】 你真的听懂了手下的话了吗?你是不是也习惯性地用自己的权威打断手下的语言?我们经常犯这样的错误:在手下还没有来得及讲完自己的事情前,就按照我们的经验大加评论和指挥。反过头来想一下,如果你不是领导,你还会这么做吗?**打断手下的语言,一方面容易做出片面的决策,另一方面使员工缺乏被尊重的感觉。时间久了,手下将再也没有兴趣向上级反馈真实的信息。反馈信息系统被切断,领导就成了“孤家寡人”,在决策上就成了“睁眼瞎”。**与手下保持畅通的信息交流,将会使你的管理如鱼得水,以便及时纠正管理中的错误,制定更加切实可行的方案和制度。 指 导 【故 事】 有一回,日本歌舞伎大师勘弥扮演古代一位徒步旅行的百姓,他要上场之前故意解开自己的鞋带,试图表现这个百姓长途旅行的疲态。正巧那天有位记者到后台采访,看见了这一幕。等演完戏后,记者问勘弥:“你为什么不当时指教学生呢,他们并没有松散自己的鞋带呀。”勘弥回答说:“要教导学生演戏的技能,机会多的是,在今天的场合,最重要的是不要让他们保持热情。” 【分 析】 **提高员工素质和能力是提高管理水准的有效方式。**学习有利于提高团队执行力,便于增强团队凝聚力。手把手的现场指导可以及时纠正员工的错误,是提高员工素质的重要形式之一。但是指导必须注重技巧,就像勘弥大师那样要保护员工的热情。管理者必须避免教训式指导,应当语重心长的激励员工提高自身业务素质。除了现场指导外,还可以综合运用培训、交流会、内部刊物、业务竞赛等多种形式,激发员工不断提高自身素质和业务水平,形成一个积极向上的学习型团队。 锻 炼 【故 事】 一个人在高山之巅的鹰巢里,抓到了一只幼鹰,他把幼鹰带回家,养在鸡笼里。这只幼鹰和鸡一起啄食、嬉闹和休息。它以为自己是一只鸡。这只鹰渐渐长大,羽翼丰满了,主人想把它训练成猎鹰,可是由于终日和鸡混在一起,它已经变得和鸡完全一样,根本没有飞的愿望了。主人试了各种办法,都毫无效果,最后把它带到山顶上,一把将它扔了出去。这只鹰像块石头似的,直掉下去,慌乱之中它拼命地扑打翅膀,就这样,它终于飞了起来! 【分 析】 **每个人都希望用自己的能力来证明自身价值,手下也不例外。给他们更大的空间去施展自己的才华,是对他们最大的尊重和支持。**不要害怕他们失败,给予适当的扶持和指点,放开你手中的“雄鹰”,让他们翱翔于更宽阔的天空。是个猴子就给他们座山折腾折腾,是条龙就给他们条大江大河扑腾。他们的成长,将为你的工作带来更大的贡献。他们的成长,将促使你更进一步。 猎人与猎狗的故事 猎人与猎狗,看似永恒的主仆,但事事无绝对。一个小故事献给大家,故事虽小,含义颇丰,请各位看官慢慢看,细细读,用心品,绝对不会浪费大家的时间。既可以看好看的故事又可以在故事中受到启发,想必这也是内刊创建的宗旨之一吧。好啦,不多说啦,正文开始。 CHAPTER Ⅰ 一条猎狗将兔子赶出了窝,一直追赶它,但是追了很久仍没有捉到。羊看到此情景讥笑猎狗说:“你们两个之间,个子小的反而跑的快的多。”猎狗回答说:“你知道什么?我们两个的跑是完全不同的!我仅仅为了一顿饭在跑而它却是为了它的命!” CHAPTER Ⅱ 猎人又买来几条猎狗,凡是能够捉到兔子的,就可以得到骨头,捉不到的就没有饭吃。这一招果然有用,猎狗们纷纷去努力追兔子。过了一段时间,问题又出现了。大兔子难捉,小兔子好捉。但捉到大兔子和小兔子得到的骨头差不多,猎狗们专门去捉小兔子。猎狗们说:反正没有什么大的区别,为什么费那么大的劲去捉那些大的呢? CHAPTER Ⅲ 猎人经过思考后,按照捉到兔子的总重量决定猎狗的待遇。于是猎狗们捉到兔子的数量和重量都增加了。但是过了一段时间,猎狗们捉兔子的数量又少了,猎狗说“我们把最好的时间都奉献给了您,主人,但是当我们老了,捉不到兔子的时候,您还会给我们骨头吃吗?” CHAPTER Ⅳ 猎人做了论功行赏的决定。规定如果捉到的兔子超过了一定的数量后,即使捉不到兔子,每顿饭也可以得到一定数量的骨头。猎狗们都努力去达到猎人规定的数量。一段时间过后,终于有一些猎狗达到了猎人规定的数量。这时,其中有一只猎狗说:“我们这么努力,只得到几根骨头,而我们捉的猎物远远超过了这几根骨头。我们为什么不能给自己捉兔子呢?”于是,有些猎狗离开了猎人,自己捉兔子去了 CHAPTER Ⅴ 猎人意识到猎狗正在流失,并且那些流失的猎狗像野狗一般和自己的猎狗抢兔子。情况变得越来越糟,猎人咨询了野狗以后进行了改革,使得每条猎狗除基本骨头外,可获得其所猎兔肉总量的n%,而且随着服务时间加长,贡献变大,该比例还可递增,并有权分享猎人总兔肉的m%。就这样,猎狗们与猎人一起努力,将野狗们逼得叫苦连天,纷纷强烈要求重归猎狗队伍。 CHAPTER Ⅵ 冬天到了,兔子越来越少,猎人们的收成也一天不如一天。而那些服务时间长的老猎狗们老得不能捉到兔子,但仍然在无忧无虑地享受着那些他们自以为是应得的大份食物。终于有一天猎人再也不能忍受,把他们扫地出门,因为猎人更需要身强力壮的猎狗…… CHAPTER Ⅶ 被扫地出门的老猎狗们得了一笔不菲的赔偿金,成立了Micro Bone公司。采用连锁加盟的方式招募野狗,向野狗们传授猎兔的技巧,他们从猎得的兔子中抽取一部分作为管理费。当赔偿金几乎全部用于广告后,他们终于有了足够多的野狗加盟。公司开始赢利。一年后,他们收购了猎人的家当…… CHAPTER Ⅷ Micro Bone公司许诺给加盟的野狗能得到公司n%的股份。这实在是太有诱惑力了。于是野狗们拖家带口地加入了Micro Bone,一些在猎人门下的年轻猎狗也开始蠢蠢欲动,甚至很多猎人也想加入。好多同类型的公司象雨后春笋般地成立了,Bone Ease,Bone.com,China Bone…… CHAPTER Ⅸ 猎人凭借出售公司的钱走上了老猎狗走过的路,最后千辛万苦要与Micro Bone公司谈判的时候,老猎狗出人意料,把Micro Bone公司卖给了猎人。老猎狗们从此不再经营公司,转而开始写自转《老猎狗的一生》,又写:《如何成为出色的猎狗》,《如何从一只普通猎狗成为一只管理层的猎狗》,《猎狗成功秘诀》《成功猎狗500条》《穷猎狗,富猎狗》,并且将老猎狗的故事搬上屏幕,取名《猎狗花园》,四只老猎狗成为了家喻户晓的明星F4。收版权费,没有风险,利润更高。 也许有人会问到这里故事是不是就完结了,我想还没有,故事还会继续,要知道流星花园也有续集的哦,呵呵。老猎狗成名之后机会更多了,他们会怎么做?猎人难道就被打败了吗?想必每个人都有自己的想法和看法。 14个「经营管理小故事」 1、割草的男孩 一个替人割草打工的男孩打电话给一位陈太太说:“您需不需要割草?”陈太太回答说:“不需要了,我已有了割草工。”,男孩又说:“我会帮您拔掉花丛中的杂草。”,陈太太回答:“我的割草工也做了。”,男孩又说:“我会帮您把草与走道的四周割齐。”,陈太太说:“我请的那人也已做了,谢谢你,我不需要新的割草工人。”,男孩便挂了电话,此时男孩的室友问他说:“你不是就在陈太太那割草打工吗?为什么还要打这电话?”男孩说:“我只是想知道我做得有多好!”。 【启示】 这个故事反映的ISO的第一个思想,即以顾客为关注焦点,不断地探询顾客的评价,我们才有可能知道自己的长处与不足,然后扬长避短,改进自己的工作质量,牢牢的抓住顾客。 这也是质量管理八项原则第6条:“持续改进”思想的实际运用的一个例子。我们每个员工是否也可结合自己的岗位工作,做一些持续改进呢? 所有的员工都可以做到让顾客满意。对于营销人员来说,这样是可以得到忠诚度极高的顾客。对于我们每个员工来说,只有时刻关注我们的“顾客(服务对象)”我们的工作质量才可以不断改进。 这也是沟通的问题,一个人想得到公正、客观的评价真的好难。这个故事是否为我们提供了一个好的方法呢? 做质量的大多数时候都是被动的,只是延续出现问题然后再去解决问题的模式,如果能主动查找问题并解决问题那才是完美的质量管理模式。这也就显示出了一个质量管理者的精髓所在。 一切都属于那些天天做好准备的人。不要光想着天上能下钞票雨,那是不可能的,凡事靠脑子去想,用双手去做,把不应该发生的事情,提前预防,把不良的缺憾扼杀在萌芽状态。我们要始终坚信“风险是可以防范的,缺陷是可以预防的”! 2、降落伞的真实故事 这是一个发生在第二次世界大战中期,美国空军和降落伞制造商之间的真实故事。在当时,降落伞的安全度不够完美,即使经过厂商努力的改善,使得降落伞制造商生产的降落伞的良品率已经达到了99.9%,应该说这个良品率即使现在许多企业也很难达到。但是美国空军却对此公司说No,他们要求所交降落伞的合格率必须达到100%。于是降落伞制造商的总经理便专程去飞行大队商讨此事,看是否能够降低这个水准?因为厂商认为,能够达到这个程度已接近完美了,没有什么必要再改。当然美国空军一口回绝,因为品质没有折扣。后来,军方要求改变了检查品质的方法。那就是从厂商前一周交货的降落伞中,随机挑出一个,让厂商负责人装备上身后亲自从飞行中的机身跳下。这个方法实施后,不良率立刻变成零。 【启示】 日本经营之神松下幸之助有句名言:“对产品来说,不是100分就是0分。”任何产品,只要存在一丝一毫的质量问题,都意味着失败。许多人做事时常有“差不多”的心态,对于领导或是客户所提出的要求,即使是合理的,也会觉得对方吹毛求疵而心生不满! 对待产品质量应该保持精益求精的态度和严谨细致的工作作风。换位成消费者,如果买回的酵母做的馒头里吃出一根头发,什么滋味?也许我们会认为10万(或10亿)袋酵母里才有一袋里有一根头发无需大惊小怪。但是对我们来说是十万分之一,对于吃到头发的消费者来说就是100%。试想,如果什么事情只有99.9%的成功率,那么每年有20,000次配错药事件;每年15,000个婴儿出生时会被抱错;每星期有500宗做错手术事件;每小时有2000封信邮寄错误。看了这些数据,我们肯定都希望全世界所有的人都能在工作中作到100%。因为我们是生产者,同时我们也是消费者。 3、老木匠造房子的故事 有个老木匠准备退休,他告诉老板,说要离开建筑行业,回家与妻子儿女享受天伦之乐。老板舍不得他的好工人走,问他是否能帮忙再建一座房子,老木匠说可以。但是大家后来都看得出来,他的心已不在工作上,他用的是软料、次料,出的是粗活,所以手工非常粗糙,工艺做得更是马虎。房子建好的时候,老板把大门的钥匙递给他。“这是我送给你的退休礼物。”,他震惊得目瞪口呆,羞愧得无地自容。如果他早知道是在给自己建房子,他怎么会这样呢?现在他得住在一幢粗制滥造的房子里! 【启示】 不可否认,老木匠曾经是一个优秀的人才,给公司创造过很多财富,但最后时刻没有做好自己的本职工作,忘了职责,后果自负。 作为一名员工,责任在先,时时刻刻都应该认认真真地对待自己的工作,并做到善始善终。这才能给公司带来更多的利润,当然自己也将得到丰厚的回报。 提高质量,总是有方法。 品质没有折扣。 我们的生活也像建房子,如果是漫不经心地“建造”自己的生活,不是积极行动,而是消极应付,凡事不肯精益求精,在关键时刻不能尽最大努力。等我们惊觉自己的处境,早已深困在自己建造的劣质“房子”里了。 把你当成那个木匠吧,想想你的房子,每天你敲进去一颗钉,加上去一块板,或者竖起一面墙,用你的智慧好好建造吧! 4、电话亭的故事 中国的留德大学生见德国人做事刻板,不知变通,就存心捉弄他们一番。大学生们在相邻的两个电话亭上分别标上了“男”“女”的字样,然后躲到暗处,看“死心眼”的德国人到底会怎么样做。结果他们发现,所有到电话亭打电话的人,都像是看到厕所标志那样,毫无怨言地进入自己该进的那个亭子。有一段时间,“女亭”闲置,“男亭“那边宁可排队也不往“女亭”这边移动。我们的大学生惊讶极了,不晓得德国人何以“呆”到这份上。面对大学生的疑问,德国人平静地耸耸肩说:“规则嘛,还不就是让人来遵守的吗?” 【启示】 德国人的刻板可以让我们开心地一连笑上3天,而他们看似有理的解释,也足以让某些一贯无视规则的“国产大能人”笑掉大牙。但是在开心之余,嘲笑之余,我们漠视规则已经多久了?我们总是聪明地认为,那些甘愿被规则约束的人不仅是“死心眼”,简直是“缺心眼”。规则是死的可人是活的,活人为什么要被死规则套住呢?正是因为这样,我们才会落后人家好多年。 5、小和尚撞钟的故事 有一个小和尚在寺院担任撞钟之职。按照寺院的规定,他每天必须在早上和黄昏各撞钟一次。如此半年下来,小和尚感觉撞钟的工作极其简单,倍感无聊。后来,干脆“做一天和尚撞一天钟”了。一天寺院住持忽然宣布要将他调到后院劈柴挑水,原因是他不能胜任撞钟之职。小和尚觉得奇怪,就问住持:“难道我撞的钟不准时、不响亮?”住持告诉他:“你的钟撞得很响,但钟声空泛、疲软,因为你心中没有理解撞钟的意义。钟声不仅仅是寺里作息的准绳,更为重要的是唤醒沉迷众生。因此,钟声不仅要宏亮,还要圆润、浑厚、深沉、悠远。一个人心中无钟,既是无佛;如果不虔诚,怎能担当撞钟之职?”小和尚听后,面有愧色,此后潜心修炼,终成一代名僧。 【启示】 本故事中的主持犯了一个常识性管理错误,“做一天和尚撞一天钟”的结果,是由于主持没有提前公布工作标准造成的。如果小和尚进入寺院的当天就明白撞钟的标准和重要性,他也不会因怠工而被撤职。 工作标准是员工的行为指南和考核依据。缺乏工作标准,往往导致员工的努力方向与公司整体发展方向不统一,造成大量的人力和物力资源浪费。因为缺乏参照物,时间久了员工容易形成自满情绪,导致工作懈怠。制定工作标准尽量做到数字化,要与考核联系起来,注意可操作性。 既然有了工作标准就应该很好的去执行它,不要打折扣,不要等到领导认为你不能胜任工作才后悔! 公司、各部门、各岗位的培训都是很重要的,为了让员工知道该怎么做,就必须定好标准,作好培训! 领导------请重视制度和培训,这样才能培养员工,您才不需要这么忙。 员工------请遵守制度,这样才能胜任工作,你才不会因怠工而被撤职。 6、扁鹊论医 魏文王问名医扁鹊说∶“你们家兄弟三人,都精于医术,到底哪一位医术最好呢?”扁鹊答说∶“长兄最好,中兄次之,我最差。”文王吃惊地问∶“你的名气最大,为何长兄医术最高呢?”扁鹊惭愧地说∶“我扁鹊治病,是治病于病情严重之时。一般人都看到我在经脉上穿针管来放血、在皮肤上敷药等大手术,所以以为我的医术高明,名气因此响遍全国。我中兄治病,是治病于病情初起之时。一般人以为他只能治轻微的小病,所以他的名气只及于本乡里。而我长兄治病,是治病于病情发作之前。由于一般人不知道他事先能铲除病因,所以觉得他水平一般,但在医学专家看来他水平最高。 【启示】 以上的“病”可以理解为“质量事故”。能将质量事故在“病”情发作之前就进行消除,才是“善之善者也”。 预防质量事故,要从“小病”做起。也就是要防患于未然。事后控制不如事中控制,事中控制不如事前控制。 对于成功处理已发质量事故的人要进行奖励,同时,更要对预防质量事故的人和行为进行奖励。 质量管理如同医生看病,治标不能忘固本。许多企业悬挂着“质量是企业的生命”的标语,而现实中存在“头疼医头、脚疼医脚”的质量管理误区。 造成“重结果轻过程”现象是因为:结果控制者因为改正了管理错误,得到员工和领导的认可;而默默无闻的过程控制者不容易引起员工和领导的重视。最终导致管理者对表面文章乐此不疲,而对预防式的事前控制和事中控制敬而远之。 如何提高事前控制和事中控制的执行力呢?首先,从上到下应当有很强的全过程质量管理意识。其次,每个环节都制定详细的质量管理标准。再次,用业绩考核改变公司不利局面。第四,客户和员工是最好的质量改善者。 7、袋鼠与笼子 一天,动物园管理员发现袋鼠从笼子里跑出来了,于是开会讨论,一致认为是笼子的高度过低。所以决定将笼子的高度由原来的10米加高到20米。结果第二天又发现袋鼠还是跑到外面来了,所以再次决定再将高度加高到30米。没想到隔天居然又看到袋鼠全跑到外面,于是管理员大为紧张,决定一不做二不休,将笼子的高度加高到100米。一天长颈鹿和几只袋鼠们在闲聊,“你们看,这个人会不会再继续加高你们的笼子?”长颈鹿问。“很难说。”袋鼠说∶“如果他再继续忘记关门的话!” 【启示】 这是一个典型的本末倒置的例子。他们不是去消除根源——“关门”,而是去加高“笼子。” 在作质量问题调查的时候,如果不找到问题的根源,那么,永远无法消除这些质量问题。同时,还将造成企业成本的升高——“加高笼子”。 所以,作为质量人,我们要经常问自己,“我们的袋鼠笼子关好了吗?” 8、提醒自我 有个老太太坐在马路边望着不远处的一堵高墙,总觉得它马上就会倒塌,见有人向墙边走过去,她就善意地提醒道:“那堵墙要倒了,远着点走吧。”被提醒的人不解地看着她,大模大样地顺着墙根走过去了,那堵墙没有倒。老太太很生气:“怎么不听我的话呢?!”又有人走来,老太太又予以劝告。三天过去了,许多人在墙过走过去,并没有遇上危险。第四天,老太太感到有些奇怪,又有些失望,不由自主便走到墙根下仔细观看,然而就在此时墙倒了,老太太被掩埋在灰尘砖石中,气绝身亡。 【启示】 提醒别人容易,提醒自己有时更难。 快要倒的墙,它始终是要倒的,不要存任何侥幸的心理。 做质量工作也是一样。要时时警惕质量管理中风险,不仅时时提醒别人,也要时时警示自己。同时,对风险最好的方法是进行改善并消除,而且要有危机感,尽快解决。不然,一旦风险爆发了,伤及的不仅是公司,也会伤及自己。 9、天堂 一位行善的基督徒,临终后想见天堂与地狱究竟有何差异,于是天使就带他到地狱参观。在他们面前出现摆满了佳肴的餐桌。“地狱的生活还不错嘛”。“不用急,你再继续看下去。”一会,只见一群骨瘦如柴的饿鬼鱼贯入座。每个人手上拿着一双长十几尺的筷子。可是由于筷子实在是太长了,最后每个人都夹得到,吃不到……来到天堂,同样的情景,同样的满桌佳肴,每个人同样用一双长十几尺的筷子。不同的是,围着吃饭的人们,他们互相喂对面的人吃菜,因此每个人都吃得很愉快。 【启示】 这则故事体现了质量管理八项原则上与供方互利的关系,在经济全球化不断深化的今天,与供应商之间建立起牢固的合作关系,加强对供应商的质量控制,建立互利共赢的合作关系已经成为企业必须认真面对的问题。 10、1000只羊 在9.11事件之前,美国总统克林顿曾悬赏1000万美元捉拿恐怖组织头目本·拉登。9.11事件以后,总统将赏金提高到2500万美元。然而,阿富汗人民却对此无动于衷。后来,美国情报局经过调查发现,并非阿富汗人嫌2500万美元太少,而是在极端贫穷的阿富汗人的心目中,2500万美元是一个空洞无际的天文数字。对于他们来说,解决每天的柴米油盐和生计才是头等大事,至于那些数以千万计的巨额财富,实在是太遥远了——于是赏金变成了1000只羊。一时间,阿富汗人轰动了,他们纷纷钻进山林寻找拉登的下落。一个当地人兴奋地说:“1000只羊!天啊,那是多么大的一群羊啊!我们村子里最富有的人家也只有八只羊。如果能有1000只羊,我们全家几辈子都有着落了。” 【启示】 把握顾客需要是能否成功的关键。我们不能把产品毫无选择地卖给任何一个客户。例如:我们很难把梳子、洗发水和护发素推销给和尚;把保险柜卖给乞丐;把照相机卖给瞎子;把高级音响卖给聋子。对于他们来说,这些产品都毫无用处。 必须时刻关注顾客的需求变化,努力适应并符合其需求。海尔在这一方面是成功的典范。为了适应每一个地区不同的消费群体的不同需要,海尔为北京市场提供技术最高、价格最贵的高档精品;为上海家庭提供小型瘦长、小巧玲珑的“小小王子”;为广西家庭提供有单列装水果用的保鲜室的“果蔬王”。 11、曲突徙薪 客人到主人家做客,看见主人家的灶上烟囱是直的,旁边又有很多木材。客人告诉主人说,烟囱要改曲,木材须移去,否则将来可能会有火灾,主人听了没有作任何表示。不久主人家里果然失火,四周邻居赶紧跑来救火,最后火被扑灭了。于是主人烹羊宰牛,宴请四邻,以酬谢他们救火的功劳,但没有请当初建议他将木材移走、烟囱改曲的人。有人对主人说:“如果当初听了那位先生的话,今天也不用准备筵席,而且没有火灾的损失,现在论功行赏,原先给你建议的人没有被感恩,而救火的人却是座上客,真是很奇怪的事呢!”主人顿时省悟,赶紧去邀请当初给予建议的那个客人。 【启示】 预防重于救火。客人告诉主人需要“曲突”和“徙薪”,其实就是告诉主人需要预防火灾的出现,因为“直突”和“薪”是产生火灾的重大隐患。只有去除火灾的根源,才能预防火灾的出现。不仅需要提出预防措施,而且要更进一步地跟踪改善措施的有效完成。 12、猴子与香蕉 西点实验室有一个很经典的故事:有6只猴子关在一个实验室里,头顶上挂着一些香蕉,但香蕉都连着一个水龙头,猴子看到香蕉,很开心去拉香蕉,结果被水淋的一塌糊涂,然后6只猴子知道香蕉不能碰了。然后换一只新猴子进去,就有5只老猴子1只新猴子,新来的猴子看到香蕉自然很想吃,但5只老猴子知道碰香蕉会被水淋,都制止它,过了一些时间,新来的猴子也不再问,也不去碰香蕉。然后再换一只新猴子,就这样,最开始的6只猴子被全部换出来,新进去的6只猴子也不会去碰香蕉。 【启示】 这个故事反映的是培训的重要性和无条件的执行制度。 培训的重要性:把好的经验做好培训,让大家共享,培训好了,可以少犯错误,少走弯路,大家都会向同一个方向,也是正确的方向使力,这样的团队或公司会战无不胜的。 制度就是要无条件执行的。因为制度是经验的总结。不遵守制度是要犯错误或受惩罚的。 作为一个企业能不能在市场竞争当中生存、发展、取胜,质量将成为企业生死存亡的决定力量,但什么又决定质量呢?如何提高质量呢?执行!——还是执行!这个“质量文化”中最重要的一环,是质量最有力的发动机,它发动着质量的改进,发动着企业发展。 13、汽车“秀逗”的故事 有一天美国通用汽车公司收到一封客户抱怨信:我们家有一个传统的习惯,就是每天在吃完晚餐后,都会以冰淇淋来当饭后甜点。由于冰淇淋的口味很多,所以我们家每天在饭后投票决定要吃哪一种口味,等大家决定后我就会开车去买。但自从最近我买了一部新的庞帝雅克后,在我去买冰淇淋的这段路程问题就发生了。每当我买的是香草口味时,我从店里出来车子就发不动。但如果我买的是其它的口味,车子发动就顺得很。问题听起来很猪头。庞帝雅克的总经理对这封信虽心存怀疑,但还是派了一位工程师去查看究竟。当工程师去找这位仁兄时,很惊讶的发现这封信是出之于一位事业成功、乐观、且受了高等教育的人。工程师安排与这位仁兄的见面时间刚好是在用完晚餐的时间,两人于是上车往冰淇淋店开去。那个晚上投票结果是香草口味,当买好香草冰淇淋回到车上后,车子又熄火了。这位工程师之后又依约来了三个晚上。第一晚,巧克力冰淇淋,车子没事。第二晚,草莓冰淇淋,车子也没事。第三晚,香草冰淇淋,车子“秀逗”。这位思考有逻辑的工程师,还是死不相信这位仁兄的车子对香草过敏。 因此,他仍然不放弃继续安排相同的行程,希望能够将这个问题解决。工程师开始记下从头到现在所发生的种种详细资料,如时间、车子使用油的种类、车子开出及开回的时间…,根据资料显示他有了一个结论,这位仁兄买香草冰淇淋所花的时间比其它口味的要少。为什么呢?原因是出在这家冰淇淋店的内部设置的问题。因为,香草冰淇淋是所有口味中最畅销的口味,店家为了让顾客每次都能很快的取拿,将香草口味特别分开陈列在单独的冰柜,并将冰柜放置在店的前端;至于其它口味则放置在距离收银台较远的后端。现在,工程师所要知道的疑问是,为什么这部车会因为从熄火到重新激活的时间较短时就会“秀逗”?原因很清楚,绝对不是因为香草冰淇淋的关系,工程师很快地由心中浮现出,答案应该是“蒸气锁”。因为当这位仁兄买其它口味时,由于时间较久,引擎有足够的时间散热,重新发动时就没有太大的问题。但是买香草口味时,由于花的时间较短,引擎太热以至于还无法让“蒸气锁”有足够的散热时间。 【启示】 即使有些问题看起来真的是疯狂,但是有时候它还是真的存在;如果我们每次在看待任何问题并秉持着冷静的思考去找寻解决的方法,这些问题将看起来会比较简单不那么复杂。所以碰到问题时不要直接就反应说那是不可能的,而没有投入一些真诚的努力。 做质量的首先要相信顾客的投诉,没有谁闲的无聊,找人投诉玩儿! 会投诉的客户才是真的回头客户或者是真诚的客户处事态度,莫若于此!若人人皆有此处事态度,何愁公司经营不好! 质量改进工具之一的“头脑风暴法”在分析问题时“知无不言、言无不尽、言者无责”的方法和质量管理原则“基于事实为依据的决策方法”思想在此例中也有所体现。 14、三个老汉想象皇帝的笑话 话说有三个老汉有一天碰到一起了,于是就聊天,聊着聊着就聊到了皇帝身上。第一个是个拾粪的老汉说:“如果我当了皇帝,我就下令这条街东面的粪全部归我,谁去拾就有公差来抓”。第二个是个砍柴的老汉,瞪了第一个老汉一眼说:“你就知道拾粪,皇帝拾粪干啥?如果我当了皇帝,我就打一把金斧头,天天用金斧头去砍柴”。第三个是个讨饭的老汉,听完后哈哈大笑,眼泪都笑出来了,他说:“你们两个真有意思,都当了皇帝了,还用得着干活吗?要是我当了皇帝,我就天天坐在火炉边吃烤红薯”。 【启示】 这些老汉们就是想坏了脑子,也不知道皇帝是如何生活的。 这个故事对我们从事质量管理和学习质量管理的人能引起深思。由于质量管理象雾霭的朦胧一样,既浩瀚又神秘;但同时质量管理又象空气,经常不经意的出现在每个人的身边;结果如同这三个老汉一样对质量管理并不真的知道却敢遐想的人还真不少。 这种遐想如果是聊天还可以,可怕的是有些遐想质量管理的人却有机会发挥他的遐想;结果用对质量管理的这些遐想来代替实际的质量管理,从而引发了质量管理的危机。 质量管理第一是人文科学;因为之所以叫质量管理,其主体对象应该是对“人”的行为才称之为质量管理。 质量管理是按质量目标设计并实施的行为,因而质量管理又与目标形成对应关系。 行为与实施的环境紧密相连的,因而质量管理还与实现目标时的环境呈依赖关系。 质量管理既是科学,还是艺术;质量管理靠想当然是不行的。成功的质量管理不能复制,质量管理的成功永远来自于创新;而创新则需要知识和艺术的结合。 对香草冰淇淋过敏的汽车 这是一个发生在美国通用汽车的客户与该公司客服部间的真实故事。 有一天美国通用汽车公司的庞帝雅克(Pontiac)部门收到一封客户抱怨信,上面是这样写的: 这是我为了同一件事第二次写信给你,我不会怪你们为什么没有回信给我,因为我也觉得这样别人会认为我疯了,但这的确是一个事实。 我们家有一个传统的习惯,就是我们每天在吃完晚餐后,都会以冰淇淋来当我们的饭后甜点。由于冰淇淋的口味很多,所以我们家每天在饭后才投票决定要吃哪一种口味,等大家决定后我就会开车去买。但自从最近我买了一部新的庞帝雅克后,在我去买冰淇淋的这段路程问题就发生了。 你知道吗?每当我买的冰淇淋是香草口味时,我从店里出来后车子就发不动。但如果我买的是其它的口味,车子发动就顺得很。我要让你知道,我对这件事情是非常认真的,尽管这个问题听起来很猪头。但为什么这部庞帝雅克当我买了香草冰淇淋它就秀逗,而我不管什么时候买其它口味的冰淇淋,它就是一尾活龙?为什么?为什么? 这封不可思议的投诉信立即引来了庞帝雅克车技术服务人员的调侃:“汽车对香草冰淇淋过敏?那我的游艇对可口可乐也要过敏了。”“找错了对象,他应该去看看心理医生。”“查查地址,这封投诉信可能是从疯人院里寄来的。”……虽然对这封信的真实性心存怀疑,但庞帝雅克的总经理没有马虎对待这近乎天方夜谭的投诉,他派了一位办事严谨的工程师前去处理这件不可思议的投诉案。 当工程师去找这位仁兄时,很惊讶的发现这封信是出之于一位事业成功、乐观且受了高等教育的人。工程师安排与这位仁兄的见面时间刚好是在用完晚餐的时间,两人于是上了汽车,往冰淇淋店开去。那个晚上投票结果是香草口味,当买好香草冰淇淋回到车上后,车子又秀逗了。这位工程师之后又连续来了三个晚上。第一晚,巧克力冰淇淋,车子没事。第二晚,草莓冰淇淋,车子也没事。第三晚,香草冰淇淋,车子“秀逗”。看来,投诉者反映的“荒唐”问题一点儿也不荒唐,庞帝雅克汽车确实时香草冰淇淋“过敏”。 这位思考有逻辑的工程师,到这时还是死不相信这位仁兄的车子对香草“过敏”。因此,他仍然不放弃继续安排相同的行程,希望能够将这个神秘的问题解决。工程师开始记下从开始到现在所发生的种种详细资料,如汽车经过的路线、使用汽油的种类、开出和开回以及停车所用的时间……根据记录的资料,他得出了一个结论:这位仁兄买香草冰淇淋所花的时间比其它口味的要少。 为什么呢?一丝不苟的工程师仔细研究了其中的一些细节问题后,终于发现了汽车对香草冰淇淋“过敏”的奥秘:这家冰淇淋店的内部设置是整个问题的关键。因为,香草冰淇淋是所有冰淇淋口味中最畅销的口味,店家为了让顾客每次都能很快的取拿,将香草口味特别分开陈列在单独的冰柜,并将冰柜放置在店的前端;至于其它口味则放置在距离收银台较远的后端。 现在,工程师所要知道的疑问是,为什么这部车会因为从熄火到重新激活的时间较短时就会“秀逗”?具有深厚专业知识的工程师很快找出了答案:问题出在汽车发动机那个小小的散热装置上。原来,当买其他口味的冰淇淋时,由于所花的时间较长,发动机有足够的时间散热,重新发动时就没有太大的问题;但是当买香草冰淇淋时,由于所花的时间较短发动机太热以至于还无法让散热装置有足够的时间散热,在密闭管路中油跟油之间会出现一段气体,阻塞了油路,人们通常把它叫做“气阻”,引擎所吸收的燃料就会断断续续,从而引起发动机不能正常发动,汽车当然就时香草冰淇淋“过敏”了。原来这都是发动机散热不畅惹的祸。 这位工程师向公司反映了汽车对香草冰淇淋“过敏”的原因,设计部门迅速进行了技术改进,弥补了散热装置的缺陷,解决了气阻现象。不久,随时能重新发动引擎的散热装置应运而生。从此,庞帝雅克车对香草冰淇淋再也不“过敏”了,这个看似荒唐的投诉案得到了圆满的解决。 解决问题的第一步是了解事情的来龙去脉,每一个细节都不能放过 扁鹊三兄弟 (魏文侯问扁鹊)曰:“子昆弟三人,其孰最善为医?”扁鹊曰:“长兄最善,中兄次之,扁鹊最为下。”魏文侯曰:“可得闻邪?”扁鹊曰:“长兄于病视神,未有形而除之,故名不出于家。中兄治病,其在毫毛,故名不出于闾(lǘ)。若扁鹊者,镵(chán)血脉,投毒药,副(pì)肌肤间,而名出闻于诸侯。”(节选自《鹖(hé)冠子·卷下·世贤第十六》) 春秋战国时期,有位神医被尊为“医祖”,他就是“扁鹊”。一次,魏文王问扁鹊说:“你们家兄弟三人,都精于医术,到底哪一位最好呢?”扁鹊答:“长兄最好,中兄次之,我最差。”文王又问:“那么为什么你最出名呢?”扁鹊答:“长兄治病,是治病于病情发作之前,由于一般人不知道他事先能铲除病因,所以他的名气无法传出去;中兄治病,是治病于病情初起时,一般人以为他只能治轻微的小病,所以他的名气只及本乡里;而我是治病于病情严重之时,一般人都看到我在经脉上穿针管放血,在皮肤上敷药等大手术,所以以为我的医术高明,名气因此响遍全国。” 从故事中,可以了解到:扁鹊大哥擅长的是“事前控制”,具有敏锐的洞察力和战略眼光,能够帮助人们防患于未然。因此,如果在现代社会,扁鹊大哥应该比较适合去卖保险或者保健品——赶快保险,重视保健,一句“君有疾在腠理,不治将恐深”已足以让现代人提心吊胆。而且,这年头,如果保险或者保健品卖得好,更容易出名。当然,如果扁鹊大哥不想去卖保险或者保健品,也可以到企业去做战略规划、项目投资的特聘专家。总之,一句话,在这个一切成功的要素都已经存在的今天,战略眼光已经显得比能力更加重要。所以,若干年前,扁鹊先生的谦虚,也具有很强的预见性,看来还真是兄弟一家亲。 扁鹊二哥擅长的是“事中控制”,具有出手迅速、果断、干练的特点,能够帮助人们免受重大疾病或灾难的折磨。拿感冒来说,相信大部分人都有过感冒的经历。感冒虽是小病,但如果不及时根治,很容易引起鼻炎、肺炎、病毒性心肌炎等很难治疗的慢性疾病,给病人带来巨大的身体痛苦和金钱损失。所以,扁鹊二哥的迅速、果断与干练能及时地扼杀病毒,断病根于初起之时。如果在现代社会,扁鹊二哥一定会大受企业老板的欢迎。一方面,能够及时清除企业发展过程中遇到的问题,同时又节约成本,不至于让企业损失巨大的经济利益和商业机会。 扁鹊先生擅长“事后控制”,能够扶大厦之将倾,挽狂澜于即倒,是临危受命型的关键人物——企业的救命草。当发生重大危机时,扁鹊先生往往能够将企业盘活,把企业从奄奄一息或者休克的状态中抢救过来,从而延续生命。所以,扁鹊先生不轻易出手,而是该出手时就出手;也不会受雇于一家企业,因为有太多的企业等着他去救死扶伤。因而,扁鹊先生类似于现代的咨询专家,在从一家企业走向另一家企业,一次手术到另一次手术的过程中,成就了自己的名声。因为人们天生对痛苦的经历记忆深刻,而且对冲在第一线的救命人员心存好感,所以,扁鹊先生的“医祖”之称自然当之无愧。 事后控制不如事中控制,事中控制不如事前控制,可惜大多数的事业经营者均未能体会到这一点,等到错误的决策造成了重大的损失才寻求弥补,有时是亡羊补牢,为时已晚。 需要我们建立完善的绩效考核体系,清除隐患的奖励必须大于时候解决这个问题的奖励! 曲突徒薪 有位客人到某人家里作客,看见主人家的灶上烟囱是直的,旁边又有很多木材。客人告诉主人说,烟囱要改曲,木材须移去,否则将来可能会有火灾,主人听了没有做任何表示。 不久主人家里果然失火,四周的邻居赶紧跑来救火,最后火被扑灭了,于是主人烹羊宰牛,宴请四邻,以酬谢他们救火的功劳,但是并没有请当初建议他将木材移走,烟囱改曲的人。 有人对主人说∶「如果当初听了那位先生的话,今天也不用准备筵席,而且没有火灾的损失,现在论功行赏,原先给你建议的人没有被感恩,而救火的人却是座上客,真是很奇怪的事呢!」 主人顿时省悟,赶紧去邀请当初给予建议的那个客人来吃酒。 一般人认为,足以摆平或解决企业经营过程中的各种棘手问题的人,就是优秀的管理者,其实这是有待商榷的,俗话说∶「预防重于治疗」,能防患于未然之前,更胜于治乱于已成之后,由此观之,企业问题的预防者,其实是优于企业问题的解决者。 医生和鬼 原故事找不到了,这里自己按照原来故事脉络现编一个 一书生母亲病重,遂求医。镇上有两位医生,不知道该请哪一位。如是去问村里一位开了天眼的巫师,此巫师说:镇东大夫背后跟着5个小鬼,镇西大夫背后跟着100个小鬼。书生说:善,吾去请镇东大夫!巫师又说:镇东大夫每年看10病人,镇西大夫每年看1000个病人。书生拜谢:差点误了老母性命,吾速去请镇西大夫! 不做不错,多做多错,多错多罚,管理大忌! 猫捉老鼠 一个越国人为了捕鼠,特地弄回一只善于捕老鼠的猫。这只猫善于捕鼠,也喜欢吃鸡,结果越国人家中的老鼠被捕光了,但鸡也所剩无几。他的儿子想把吃鸡的猫赶走,父亲却说:“祸害我们家的是老鼠不是猫,老鼠偷我们的食物,咬坏我们的衣物,挖穿我们的墙壁,损害我们的家具,不除掉它们我们必将挨饿受冻,所以必须除掉它们!没有鸡大不了不吃罢了,离挨饿受冻还远着哩!” 金无足赤,领导者对人才不可苛求完美,任何人都难免有些小毛病,只要无伤大雅,何必过分计较呢?最重要的是发现他最大的优点,能够为企业带来怎样的利益。 现代化管理学主张对人实行功能分析:“能”,是指一个人能力的强弱,长处短处的综合;“功”,是指这些能力是否可转化为工作成果。结果表明:宁可使用有缺点的能人,也不用没有缺点的平庸的“完人”。 掩耳盗铃 掩耳盗铃出自《吕氏春秋·自知》:“范氏之亡也,百姓有得钟者,欲负而走,则钟大不可负。以锤毁之,钟况然有声。恐人闻之而夺己也,遽掩其耳。”恶人闻之,可也;恶己自闻之,悖也! 在春秋时期,晋国的范家大宅遭遇了挫折。有一天一名小偷闯入范家,发现院子中悬挂着一口宝贵的青铜钟,工艺精湛,价值连城。小偷渴望将其偷走,但钟太大太重,难以搬运。 为了解决这个问题,小偷决定将钟敲碎,再一块一块运回家。他拿来一把大锤,用力敲击钟,发出巨大的响声。小偷吓坏了,意识到这个声音将引来麻烦。他迅速爬到钟上,试图用双手捂住钟声,但钟声依然传播。 小偷越来越害怕,不知所措。突然,他想到一个聪明的主意,用布料塞住耳朵,认为这样就听不到钟声了。于是,他紧紧捂住耳朵,心想自己已经安全了。然而,他没有注意到,虽然自己听不到钟声,但钟声依然清晰地传向远方。 村里的人们听到钟声,纷纷涌向范家大院,把小偷抓到了。 很多管理者不解决问题,缺去解决提出问题的人,掩盖问题,欺上瞒下,这样早晚被揭破,害己害人! 跑的比你快 两个朋友去露营。夜里,熊来了,甲吓得衣不蔽体就想逃跑,却见乙好整以暇地在穿鞋。甲问: 跑都来不及了,穿鞋就能跑得比熊快吗?乙答: 我不必跑得比熊快,只要跑得比你快就行了。 智猪博弈 “智猪博弈"是一个著名的纳什均衡的例子,由约翰·纳什(JohnFNash),1950年提出。 理论简介 如果两只猪同时踩踏板,同时跑向食槽,大猪吃进7份,得益5份,小猪吃进3份,实得1份;如果大猪踩踏板后跑向食槽,这时小猪抢先,吃进4份,实得4份,大猪吃进6份,付出2份,得益4份;如果大猪等待,小猪踩踏板,大猪先吃,吃进9份,得益9份,小猪吃进1份,但是付出了2份,实得-1份;如果双方都懒得动,所得都是0。 小猪 行动 等待 大猪 行动 5,1 4,4 等待 9,-1 0,0 利益分配格局决定两头猪的理性选择:小猪踩踏板只能吃到一份,不踩踏板反而能吃上4份。对小猪而言,无论大猪是否踩动踏板,小猪将选择“搭便车”策略,也就是舒舒服服地等在食槽边,这是最好的选择。 而从大猪角度思考,由于小猪有“等待”这个优势策略,大猪只剩下了两个选择:等待,一份也得不到;踩踏板得到4份。所以“等待”就变成了大猪的劣势策略,当大猪知道小猪是不会去踩动踏板的,自己亲自去踩踏板总比不踩强吧,只好为一点残羹不知疲倦地奔忙于踏板和食槽之间。 大船和小船的故事 有这样的两只船,一只大船,一只小船,大船的速度和续航都比小船快,两只船都在海上比赛看谁先到岸上,海上没有什么方向标,问小船如何能够先到岸上? 解决方案就是,小船不要和大船走同一条道路,如果大船走A路线,那么小船不要选择A路线,反正都是在大海中盲行,如果小船和大船走同一个方向,绝对是没有任何胜算的,而不相同的或者相反的道路,这个时候比拼的就不仅仅只有速度和续航了,还有判断力和运气,在错误的道路下,走得越快反而离目的地越走越远,优势变成了劣势,小船就算走得慢,就算续航不行,也不一定会失败,只要路径正确,小船还是能比大船更先上岸的。 南橘北枳 出自《晏子春秋·杂下之六 》:“婴闻之:橘生淮南则为橘,生于淮北则为枳,叶徒相似,其实味不同。所以然者何?水土异也。” 根据《晏子春秋》记载,齐国的晏婴出使楚国,楚灵王想要羞辱晏婴,便在宴会上故意让人带着一个盗窃犯来到面前,说这是齐国人。楚王问晏婴,是否齐国人生来喜欢偷盗。晏婴回答说:“橘生淮南则为橘,生于淮北则为枳,叶徒相似,其实味不同。所以然者何?水土异也。今民生于齐不盗,入楚则盗,得无楚之水土使民善盗耶?”即齐国人到了楚国就成为了盗窃犯,以“楚国的水土导致齐国人成为了盗窃犯”反驳楚王。 比喻环境变了,事物的性质也变了。人和事物是会随着环境变化而变化的! 寒号鸟 在古老的原始森林,阳光明媚,鸟儿欢快地歌唱,辛勤的劳动。其中有一支寒号鸟,有着一身漂亮的羽毛和嘹亮的歌喉。他到处卖弄自己的羽毛和嗓子,看到别人辛勤劳动,反而嘲笑不已,好心的鸟儿提醒它说;“快垒个窝吧!不然冬天来了怎么过呢”。 就这让,日复一日,冬天眨眼就到了。鸟儿们晚上躲在自己暖和的窝里安乐的休息,而寒号鸟却在寒风里,冻得发抖,用美丽的歌喉悔恨过去,哀叫未来:“抖落落,寒风冻死我,明天就垒窝。” 第二天,太阳出来了,万物苏醒了。沐浴在阳光中,寒号鸟好不得意,完全忘记了昨天的痛苦,又快乐的歌唱起来。 鸟儿劝他,“快垒个窝吧,不然晚上又要发抖了。” 寒号鸟嘲笑地说:“不会享受的家伙。” 晚上又来临了,寒号鸟又重复着昨天晚上一样的故事。就这样重复了几个晚上,大雪突然降临,鸟儿们奇怪寒号鸟怎么不发出叫声了呢, 太阳一出来,大家寻找一看,寒号鸟早已被冻死了。 点评:在人的一生中,今天是多么重要,是你最有权力发挥的。寄希望于明天的人,是一事无成的人,到了明天,后天也就成了明天。今天的事情推到明天,明天事情推到后天,一而再,再而三。事情永远没完。只有那些懂得如何利用“今天”的人,才会在“今天”创造明天的希望。 启示:需要区分重要,非重要,紧急,非紧急四个象限!重要紧急的事情需要提前准备做好!重要的事情做不好,就一直有做不完紧急的事情! 狼来了 狼来了是一则民间流传很久了的寓言小故事。讲的是一个放羊的小孩,有一天在山上放羊的时候觉得自己一个人很无聊,就想靠捉弄大家来寻个开心。下面是小编收集整理的童话故事:狼来了,供大家参考借鉴,希望可以帮助到有需要的朋友。 童话故事:狼来了 篇1 从前,有个放羊娃,每天都去山上放羊。一天,他觉得十分无聊,就想了个捉弄大家寻开心的主意。他向着山下正在种田的农夫们大声喊:“狼来了!狼来了!救命啊!” 农夫们听到喊声急忙拿着锄头和镰刀往山上跑,他们边跑边喊:“不要怕,孩子,我们来帮你打恶狼!” 农夫们气喘吁吁地赶到山上一看,连狼的影子也没有!放羊娃哈哈大笑:“真有意思,你们上当了!”农夫们生气地走了。 第二天,放羊娃故伎重演,善良的农夫们又冲上来帮他打狼,可还是没有见到狼的影子。 放羊娃笑得直不起腰:“哈哈!你们又上当了!哈哈!”大伙儿对放羊娃一而再再而三地说谎十分生气,从此再也不相信他的话了。过了几天,狼真的来了,一下子闯进了羊群。 放羊娃害怕极了,拼命地向农夫们喊:“狼来了!狼来了!快救命呀!狼真的来了!”农夫们听到他的喊声,以为他又在说谎,大家都不理睬他,没有人去帮他,结果放羊娃的许多羊都被狼咬死了。 寓言的寓意: 1、说谎是一种不好的行为,它既不尊重别人,也会失去别人对自己的信任。我们应该培养诚恳待人的良好品质。 2、寓言告诉大家做人应诚实,不以通过说谎来达到自己的目的。更不能以说谎去愚弄他人。生存希望,身处逆境临危不惧,心中就会充满阳光。 ​ 3、管理人员胡乱指挥,朝令夕改,底下人员不知所措。会使你很快就失去管理权威,手下听令不行动,想着,反正做了也没有意义,到下午又要换其它方向做。整个团队看着很忙,但是就是不出成绩。无能的管理者看不得别人闲下来,只会从时间上考核手下,对什么能产生真正有效的绩效一无所知! 童话故事:狼来了 篇2 一个小男孩在山坡上快乐地玩耍。他扑蝴蝶、捉蚂蚱,无忧无虑,十分开心。 忽然,小男孩看到远远的地方有一只大灰狼在向这边偷看。他害怕地大声呼救:“狼来了,救命啊!”狼吓跑了。大人们听到呼救声,丢下手中的工作,拿着棍棒赶来。他们没有看到狼的影子,不相信小男孩的解释,认为小男孩在撒谎,生气地各自忙自己的工作去了。 小男孩很难过,他不知道大人们为什么不相信狼真的来过,他感到很沮丧。蝴蝶飞过来了,蚂蚱蹦过来了,他都失去了兴趣,只是呆呆地的坐着,想着…… 这时,大灰狼又出现了,小男孩又看到了它,但他没敢喊,他怕大人们又会责怪他不诚实。 大灰狼感觉到周围没有危险,就悄悄向这边靠近。小男孩一直在心惊胆战地观察大灰狼的行踪,见大灰狼已经在不远处向自己伸出长长的红舌头,他忍不住恐惧地大声呼救:“狼来了,救命啊!”“狼来了,救命啊!”大灰狼狡猾地躲了起来。 大人们听到呼救声,再次纷纷赶来,没有看见狼的影子,他们不听小男孩的诉说,很生气地斥责他:“你为什么要再三地欺骗我们呢?你真是一个爱撒谎地坏孩子!” 大人们气恼地走了,小男孩更难过更孤独,他不知道自己做错了什么,为什么自己说出的实话,在大人眼里就是撒谎。他伤心地躲在山坡上流眼泪。这时,他分明感觉到危险离他越来越近。一抬头,小男孩看到大灰狼已经近在咫尺,就要向自己扑过来了。 小男孩吓得动也动不了,他只会没命地大呼:“狼来了,狼来了……” 小男孩喊了一遍又一遍,没有一个大人赶来,倒是那只面目狰狞的大灰狼在向他一步步逼近,那粗重的、可怕的喘息声几经贴到了他的耳边。 小男孩绝望中喊了最后一声:“狼来了……” 丧身在狼口下的孩子,永远也不会明白:被欺诈、虚伪的世风所熏染的成年人,只会相信他们自己亲眼看到的东西,他们早已忘记了什么叫天真、什么叫真诚。 童话故事:狼来了 篇3 从前,在一个小村庄里,住着一个放羊娃。放羊娃总是喜欢说谎,放羊娃放牧的时候,经常大声向村里人大叫:“快来人啊,有狼来吃我的羊了!救命啊!”开始的时候,村里人听到放羊娃的叫声,就会马上跑过来救他,关心地问他:“怎么啦?狼在哪里呀?”这个时候,放羊娃哈哈大笑:“哈哈哈,你们太笨了,根本就没有狼,我是骗你们的。”大家一听非常生气,可是村民们都很善良,每次听见放羊娃的叫声,都会赶过来看看,可是每次放羊娃都是骗人的,大家只好又走回去。 后来,有一天,放羊娃赶着他的羊群又去外面放牧,他走啊走,走到很远很远的地方了。这时候,狼真的来了,一下子窜入羊群,大口大口地咬着这些小羊。牧羊娃很害怕,他向着村里拼命地跑,边跑还边大声叫:“快来人啊,狼来啦!它在吃我的小羊!救命啊!”村里人听见了都说:“看唉说谎的放羊娃又在骗我们啦!”结果,没有人理他。最后,放羊娃的羊群都被狼吃掉了,放羊娃再也不敢撒谎了。 童话故事:狼来了 篇4 从前,有个小孩儿每天赶着一群羊到山里去吃草,有一天,这个小孩儿突然大叫起来:“狼来了!狼来了!”在山里种地、打柴的人听说狼来了,都赶紧放下手里的活儿,带来柴刀、锄头、扁担飞快地跑过来打狼,救孩子,大伙儿跑到跟前一看,羊在那儿乖乖的吃草呢,狼在哪儿呢?大伙儿就问这小孩儿,小孩儿听了,哈哈大笑起来了,原来呀,根本就没有狼,是这小孩儿闹着玩儿呢,大伙儿可生气了,就说了这小孩儿一顿,叫他以后不要再说谎了。 过了几天,大伙儿正忙着呢,又听见那个放羊的孩子在喊:“狼来了!狼来了!”大伙儿跟上回一样,赶紧放下手里的活儿,带来柴刀、锄头、扁担赶过来打狼,救孩子,谁知道,又上当了,根本就没有狼,还是那个孩子在闹着玩儿呢。“你这孩子,上回跟你说了,叫你不要说谎,你怎么又说谎了?”那个孩子呢,一边儿哈哈大笑,一边儿心里在想:“哈!那么多大人上当,瞧我多有本事。” 又过了几天,这个孩子又喊起来了:“狼来了!狼来了!快来打狼呀!”大伙儿听见了,谁也不理他,“这孩子说了两次谎了,这次准又说谎了。”“咱们上了两次当,再也不能上他的当了。”哎呀!这回真的是狼来了,张着血红的嘴巴,露出尖尖的牙齿,见了羊就咬,咬了羊,又来咬这小孩子了,“狼来了!狼来了!快来打狼啊!”这小孩儿一边儿跑一边儿叫,可是谁也不来救他,还好,这小孩从山坡上滚下来,没让狼咬着,可是,他的羊呢?全给狼咬死了。打那以后啊,这小孩儿再也不敢说谎了。 童话故事:狼来了 篇5 从前,有个小孩子每天赶了一群羊,到山里去吃草。 有一天,这个小孩子忽然大叫起来: “狼来了,狼来了!” 在山里种地打柴的人听说狼来了,都赶紧放下手里的活儿,带了镰刀、锄头、扁担,飞快跑来打狼救孩子。大伙儿跑到跟前一看,羊在乖乖地吃草,狼在哪里呀?大伙儿问小孩子,小孩子哈哈大笑起来。 原来根本没有狼,是这小孩子闹着玩儿呢。大伙儿很生气,说了小孩子一顿,叫他以后不要再说谎了,就回去干活了。 过了几天,大伙儿正在忙着,又听见那个放羊的小孩子在喊: “狼来了,狼来了!” 大伙儿跟上回一样,放下活儿,带了镰刀、锄头、扁担,赶来打狼救孩子,谁知道又上当了。根本没有狼,还是这小孩子在闹着玩儿。 “上回跟你说了,叫你不要说谎,你为什么又说谎了?” 这小孩子呢?一边哈哈大笑,一边心里在想:瞧我,一个小孩子能叫那么多大人上当,多有本事。 又过了几天,这小孩子又喊起来: “狼来了,狼来了,快来打狼呀!” 大伙儿听见了,谁也不去理他,这个说:“这小孩子说了两次谎,这回准又说谎了。”那个说:“咱们上了两次当,这回再也不上他的当了。” 哎呀,这回真的是狼来了,张着血红的嘴巴,露出尖尖的牙齿,见了羊就咬,咬了羊,又来咬这小孩子了。 “狼来了,狼来了!快来打狼呀!”这小孩子一边跑,一边叫,可是谁也不来救他了。 还好,这小孩子从山坡上滚下来,没让狼咬着,可是他的羊全给狼咬死了。打这以后,这小孩子再也不敢说谎了。 童话故事:狼来了 篇6 有一天,一个孩子在山顶上放羊,太阳在天上挂着,山顶上很安静。那些羊们都在吃着草,这个孩子觉得挺无聊,就想:“嗯!我玩儿点什么呢?” 他站在山顶上往村里看,大人们都在忙着干农活。有的在村里干活,有的在地里干活。 小孩忽然灵机一动,他想:“让我来逗逗他们吧!” 于是,他站在山顶上,向山下喊起来:“狼来了!狼来了!” 山下的`大人们听到小孩喊“狼来了”都很担心,大家纷纷扛着锄头扁担跑上山来了,他们跑得气喘吁吁的。 孩子站在山顶上看大家都往这儿跑,乐得哈哈大笑起来。 这时候,大人们都跑过来了,着急地问:“狼在哪?狼在哪?” 孩子笑了,说:“嗯……没有狼,没有狼,是我觉得太无聊啦!” 大人们都很生气说:没有狼,你怎么说有狼啊!下次可别这么说了啊! 过了几天,这个孩子又到山顶上放羊。他坐在草地上,看着羊在慢腾腾地吃草,又觉得没意思了,他想上次我一说狼来了,大家都往这儿跑,真好玩儿,今天让我再逗一逗他们。 于是,他又站在山顶上大声喊起来:“狼来了!狼来了!” 山下的大人们,听到小孩一声比一声高的呼救,心里想:“可能真是狼来了。” 于是又拿着扁担锄头赶上山来,大人们跑到他身边问:“狼在哪 ?狼在哪呢?” 孩子又笑了说:“没有狼,我是在逗你们玩呢!” 大人们气坏了说:“这个孩子你怎么老说谎啊!” 可是没办法,大家只好扛着扁担锄头下山去了。 又过了几天,孩子又到山上放羊。 这一次啊!狼真的来了,他正在草地上看着羊吃草呢!就看见一只大灰狼从那边跑过来,抓起一只羊就往嘴里送。 放羊娃急了,在山顶上拼命地大喊起来:“救命啊!狼来了,狼来了!” 可是这回呀,任凭他喊破嗓子,再也没有一个大人赶上山来了,因为大家想,他肯定又在撒谎呢! 大灰狼把那只小羊吃完了以后,又跑过来,抓住小孩,把这个孩子也咬死了。 童话故事:狼来了 篇7 小时候,妈妈给我讲过一个名叫《狼来了》的故事,对我印象深刻。 这个故事主要讲了一个小朋友家里养了一群羊,他一直帮家里去放羊,有一次,他在放学的时候感觉到很无聊,就突然想了一个馊主意,骗大家狼来了,边上的人听见了纷纷扔下手里的活赶过来,结果发现羊好好地在吃草;第二次,他又觉得无聊,又开始耍小聪明,大家都很气愤;第三次的时候,狼真的来了,可是村民都不相信了,他们继续忙自己手里的活,结果羊全被狼吃了。 在我的身边也发生过这种事情,比如我同班的一个女同学,她问我借了一块橡皮,说:“张钱瑜,你能借我用一下吗?我放学就还给你。”我高兴地说:“好的,你拿去用吧。”可到了放学的时候,她还没有还给我,我有点生气了,不过,我想可能她忘记了。过了几天,她又问我借尺子,可又到了放学,她也没有提起这件事情,我心情很难过,觉得她怎么说话不算话。又过了几天,她又想来问我借东西,可是我再也不相信她了,我对她说:“你把我上次借你的东西还给我,我再借给你。” 我觉得每个小朋友都应该做个诚实守信用的人。 童话故事:狼来了 篇8 我读了一个故事说:从前有一个小孩喜欢搞恶作剧。 有一天他来到了山上放羊,闲着没事就冲着山下大叫:狼来了,狼来了,山下的农民放下手里的活,急忙跑到山上去说:小朋友》哪里有狼?狼在哪里? 小孩说:哪里有狼?是我骗你们的,你们真傻,哈哈哈…! 农民们听了生气的下山了!过了几天小孩又搞了同样的恶作剧。她同样冲着山下面喊:狼来了,狼来了,农民们又从山下跑到山上。 小孩看了又说:你们真是傻透了,哈哈哈哈哈,你们又上当了! 农民们说:你为什么要撒谎欺骗别人? 太好玩了,太好玩了,哈哈哈…,小孩高兴的说。 农民们又生气地下山了,其中有人还骂了那小孩一句。 第三天,狼真的来了,小孩冲着山下喊了很久,就算喊破了嗓子都不会有人再来救他了。因为他的恶作剧搞得太多了,所以他把别人惹生气了,别人就都不救他,也没人会再相信他了! 这个故事告诉我们:如果你欺骗别人,骗了一次,别人可以原谅你,如果你再三再四的欺骗别人,人家就不愿意原谅你了,不会再相信你了,所以不要和放羊的小孩一样爱欺骗别人!要做一个守信用,诚实的人! 童话故事:狼来了 篇9 作为一名教师、一个人,言而有信这个道理大家都明白,但我们通常在一些小事上忽略这一点。我在幼儿园带大班时就发生过这样一件事。我是数学组的,我们班的数学课由我来带,孩子们刚升入大班,集中注意力学习的时间不是很长,而且数学对孩子来说又是乏味无趣的。我也想过很多办法,比如说准备好多教具来吸引孩子的注意力,但效果不是很好。 今天有我的数学课,我就开始想怎样才能把所有孩子的注意力都吸引到我这来呢?我准备了教具,但光靠教具还是不够的。我灵机一动,对呀,孩子们喜欢表演,那我不如就好好利用一下孩子爱表演的心理特点。在上课之前我就对孩子们讲:“今天要是小朋友们在这节活动课上能够认真听、积极参与活动、上好这节数学活动课,那下课之前我就请一些小朋友带着头饰到前面来表演,没有到前面表演的小朋友也都有机会,我们可以利用吃完晚饭的时间来进行表演。”其实我在课前并没有准备好头饰。小朋友们都很积极的参与到了活动中,活动课结束了,孩子们坐的整整齐齐用渴望的眼神望着我,等着我叫他们的名字请他们来表演,到户外活动的时间了,而且我今天也没准备头饰,我只好许诺说明天老师带头饰来请小朋友表演,晚上回到家里,因为今天配班老师有事我带了一天的班实在是很累,我想也许到了明天孩子们会把带头饰表演的事忘记,抱着侥幸的心理我就没有做。第二天到了,早操活动后回到教室里“萱萱”直着嗓子对我说:“周老师你怎么没带头饰来呀!”哎呀,我以为孩子们会忘记这件事,我就偷了一下懒没有做,没想到孩子们这么重视这件事。顷刻间孩子们议论到:“是呀,老师怎么忘了?老师真没记性。老师是不是骗人呀。”这话声音很小,但还是钻进了我的耳朵里,望着孩子们,我红着脸说:“对不起,老师马上去做。” 有的时候为了达到某种目的,不少教师经常会向孩子许诺。例如:“组织集体活动,为了使孩子注意力集中,就会说谁的表现好,我就奖励给谁礼物,诸如此类的话。”而大多结果是孩子们都做到了,活动顺利完成了,教师的诺言却没有兑现。作为教师我们还经常给孩子们讲“狼来了”的故事,让孩子们从中学到到不说谎话,可是我们教师从来没有想到自己为了达到教学中的目的也在过程中扮演着放羊孩子的角色,在这过程中给孩子们带来了无形中的错误教育,有的教师可能没有意识到,但学前儿童的模仿力极强,后果不堪想象。长此以来,孩子们会认为教师言而无信,而孩子也会受此影响。所以言而有信是教师以身作则,教育孩子诚信的第一步。 童话故事:狼来了 篇10 从前,村里来了一个行乞的男孩,村民们颇为同情和可怜,便收留了他,让他给村里放羊。 一天,放羊娃向着山下正在种田的农夫们大声喊:“狼来了!狼来了!救命啊!”农夫们听到喊声急忙拿着锄头和镰刀往山上跑,他们边跑边喊:“不要怕,孩子,我们来帮你打恶狼!” 农夫们气喘吁吁地赶到山上一看,虽然少了一只羊,地上还有一些血迹,可是没有发现狼的踪迹!农夫们懊丧的走了。 隔了几天,放羊娃故伎重演,善良的农夫们又冲上去帮他打狼,同样,又少了一只羊,地上也有一些新的血迹,可是仍旧没有见到狼的影子。 农夫们觉得有点蹊跷,村子里从未发生过羊被狼吃的事情,怎么这孩子来了不几天,狼就来了两次。于是,商定派人去观察。那人回来后,惊慌失措的给大伙讲,他看见放羊娃变成一条狼,把埋在洞里的羊刨出来啃吃。 农夫们半信半疑,便悄悄的一起到山上去看个究竟。此时正值炎热的中午,放羊娃脱关了衣服正躺在树阴下睡觉,可是屁股上长着一根粗大的长尾巴。农夫们当机立断,决定将它处死,于是众人一拥而上,几锄头打下去就结果了它的性命。 这家伙气绝之前,在不停的抽搐中,渐渐的现出了原形,一条獠牙锋利的恶狼,原来这是一条会变成人样的狼精。 农夫与蛇 农夫和蛇的故事 篇1 一个农夫干完农活,看见一条蛇冻僵了,就把它拾起来,小心翼翼地揣进怀里,用暖热的身体温暖着它。那蛇渐渐复苏了,它彻底苏醒过来后,便以迅雷不及掩耳的速度用尖利的毒牙狠狠地咬了恩人一口,使他受了致命的创伤。农夫临死的时候痛悔地说:“我可怜恶人,不辨好坏,结果害了自己,遭到这样的恶报,我真是活该!” 这个故事是说,做人一定要分清善恶,只能把援助之手伸向善良的人。对那些恶人即使仁至义尽,他们的本性也是不会改变。 渔夫和蛇,讽刺了那些恩将仇报的恶人和帮助恶人的伪善的人。 告诫我们要学会辨认是非,不要被美好的事物蒙蔽了双眼,因为狐狸也会哭泣、蛇也有落难的时候。 农夫和蛇的故事 篇2 话说农夫被蛇咬伤之后,千方百计的治疗,花光了家里的所有,最后,连自己仅有的两间草房也卖掉了,终于排除了体内的毒液,把病治好了。 为了生计,农夫和老婆搬到了县城去打工,他们租了间简陋的破房子,白天,农夫夫妇都出去给人做钟点工,晚上他们就在破房子里安身。一晃两年过去了,农夫攒了一部分钱,准备再赚两年钱,就可以回乡下盖房子了。 一天傍晚,天气闷热,一丝风也没有。农夫刚给人刮完大白往家走,在路边碰见一条被车碾得血肉模糊的蛇,已经奄奄一息了,一条小蛇在旁边不停的哭喊着妈妈。农夫见状,连忙蹲下身子,把受伤的蛇和小蛇一起装进工具袋里,拎回了家。 回到家中,农夫的老婆见状,气不打一处来,骂农夫是好了伤疤忘了疼,而农夫还是默默的给受伤的蛇上药,包扎伤口,喂它们食物。 时间一天天的过去了,蛇的伤口还不见好转,小蛇就骂骂咧咧的埋怨农夫,怎么不早点救它妈妈?农夫也不跟小蛇计较,依然每天下班就给受伤的蛇换药,清洗伤口。为给伤蛇治疗,农夫花了不少钱,每天还要听老婆的埋怨和唠叨。 就这样,憨厚的农夫终于把受伤的蛇治疗痊愈了,而伤蛇一直耿耿于怀农夫给它换药时的粗鲁动作,让它疼痛难忍。小蛇非常讨厌农夫的老婆讲它们的坏话。 这一天,农夫下班回家,看见老婆躺在地上,脸色铁青。原来是那两条蛇为了让农夫的老婆给他们做好吃的’,农夫的老婆动作慢了些,就被小蛇给咬伤了。 农夫急忙上前搀扶起老婆,狠狠的瞪着两条蛇,什么也没说,匆匆忙忙的带老婆去了医院,此后,再也没有回来。 农夫和蛇的故事 篇3 冬天已经来临了,河里结了一层厚厚的冰。 这天早晨,农夫外出办事,冒着寒风出发了。从天朦朦亮一直走到中午,他没吃一口饭,没喝一口水,肚子咕噜咕噜直叫,他想我得找个地方歇一会儿。他在路边坐了下来,从怀里掏出干粮大口大口地吃了起来。突然他在身边的地上发现一条冻僵了的蛇。 这条蛇耷拉着脑袋,就像死了一般。农夫心里想,这条蛇只是冻僵了,看样子还能救活,他想着便把这条蛇拾起来放进自己的怀里。这时候他又想到蛇是会咬人的,如果他醒来之后咬我一口,我这条老命可就完了。 想到这儿,农夫一把将那冻僵的蛇丢在地上,站起身继续赶路。走着走着,农夫的脚步又放慢了下来,他想蛇是会咬人,可是我如果把它救了,我就是他的救命恩人,对待救命恩人他难道会恩将仇报,再咬我一口吗? 不可能!绝对不可能!想到这儿农夫转回身,又向那冻僵的蛇走过去。 这个好心的农夫,弯下腰将蛇拾起来贴着肉放进怀里,继续赶路走了一阵子,农夫觉得那条蛇在怀里动了一动,他想,好啊!看来这蛇是能救活的。 农夫又走了好一阵子,那蛇猛的动了起来,接着就向农夫温暖的胸膛狠狠地咬了一大口。 哎呀!农夫疼得捂住胸膛叫了起来,他将那该死的蛇一把摔在地上,掐住喉咙把它弄死了。但是蛇毒已经进入了农夫的血液,很快就蔓延到了他的心脏。农夫只觉得眼前的一切都变得模糊不清了,最后他倒在地上死了。 农夫和蛇的故事是告诉我们,对恶人可不能发善心,他们邪恶的本性是不会改变的,怜惜了恶人,后患无穷啊! 农夫和蛇的故事 篇4 从前,有一位十分善良的农夫。 在一个大雪纷飞的晚上,农夫干完活走在回家的路上,听到了一阵微弱的求救声,他四下环顾,只见空无一人,只有高耸的山岭、片片雪花儿和呼呼的北风。 无意间,他发现脚下有一条盘着的即将冻死的蛇。农夫一边看着即将冻死的蛇,一边想:如果我救它,说不定它会把我自己咬死,但如果不救它,又对不起自己的良心,我该怎么办呢?正在这时,蛇又发出了一阵求救声,一声比一声微弱。农夫听着于心不忍,他想来又想去,终于想到一个两全其美的好办法。农夫把他的手套脱了下来,把蛇轻轻地放入手套里,还不忘扣上扣子。这样,既可以把蛇护好,自己也不会被蛇咬伤,农夫就这样把这条蛇带回了家里。 回到家后,农夫见蛇醒了,便把它从手套里慢慢地放出来,可蛇还是没有动。农夫仔细看了看蛇,发现蛇的脖子有部分受了伤。于是他就把自己摘的药草给蛇涂了上去。这时候,蛇的尾巴动了动,一阵烟雾腾起,蛇一下子变成了一位美丽的女人。 原来,这一条蛇叫小青,是被玉帝派下来巡查人间的。小青故意装作冻僵的蛇让人来救她,如果他是一个好心人,便可以给他带来幸福。 从此,小青和农夫幸福快乐地生活在一起了。 最后,我们别忘了还有另一个书生与蛇的故事——白娘子传奇 我真的有一头牛 记者采访一位农民 记者:假设国家有难而你有一百亩地,你愿意捐给国家吗? 农民:我愿意! 记者:假设你有一百万,你愿意捐给国家吗? 农民:我愿意! 记者:假设你有一头牛,你愿意捐给国家吗? 农民:不愿意! 记者:为什么? 农民:因为我真的有一头牛。 在某个假设的前提下,一些人总是愿意许各种承诺。因为我们知道假设不会成立,或者假设成立的概率非常小。可真的等到假设成立的那一天,哪些当初许下承诺的人在哪里了! 推销修行故事十则 【销售心理】 某富豪征婚,海选后剩三个美女,富翁给她们各一千元,请她们把房间装满,展示自己的能力。女孩甲买了很多棉花,装满房间的1/2,女孩乙买了很多气球,装满房间3/4,最后一个女孩丙买了蜡烛,让光充满房间。最终,富翁选了胸部最大的那个。 启示:推销商品,要抓住主要矛盾了解客户的真实需求非常重要。 【习惯】 乞丐到小王家乞讨,他给5块,第二天乞丐又去,又给5块,持续1年。一天只给2块,乞丐:以前给5块,怎么现在给2块?小王:我结婚了。乞丐一巴掌放了过去:妈蛋,你竟然拿我的钱去养你老婆? 启示:当提供免费服务让客户成为一种习惯,这种服务就不再是优势,而是劣势,客户会觉得那是他应得的。 【夫妇】 夫妇逛商场,女的看中一套高档餐具,坚持要买,丈夫觉得没必要买这么贵的,坚决不肯掏钱,两人僵持不下。这时,导购悄悄对丈夫说了句话,他一听马上掏钱。他们走后,另一个导购问:是什么让他立马转变?这个导购员说:很简单,我对他说,这么贵的餐具,你太太是不会舍得让你洗碗的。 启示:人的观念没有什么不可以改变的,关键是角度,要善于揣摩客户心理。 【买卖】 一少妇到楼下买牛奶。小贩说:1瓶3块,3瓶10块。她很无语,掏出3块买了1瓶,随即重复,一共买了三次,回去她就对老公一个劲吐槽小贩智商有问题,夸耀自己聪明,只花9块就买了3瓶。殊不知楼下的小贩心底一直在偷笑:哈哈,自从我这么干,每次都能一下卖掉3瓶。 启示:做买卖不仅要保证自己获利,也要让消费者买得愉快,互惠共赢。 【小圈子】 一条水沟水越来越少,住在那的一只小青蛙每天不停地蹦,想要逃离这个地方。有一天,小青蛙终于纵身一跃,跳进旁边的一个大河塘,他呼唤水沟的同伴,但同伴说:“我在这里已经习惯了,我从小就生活在这里,懒得动了!”不久,水沟里的水干了,同伴活活饿死。 启示:只有敢于打破自己固有的圈子,才可能拥有更加广阔的发展空间。那些墨守成规、满足于小天地的人是不会得到突破的。 【杯子】 一只玻璃杯中装满牛奶时,人们说:“这是牛奶”;改装可乐时,人们说:“这是可乐”。只有当杯子空置时,人们才看到杯子,说:“这是一只杯子”。同样,当我们心中被金钱、权势充满时,就已经不是自己了。 启示:人往往热衷拥有很多,却难以真正拥有自己。而且,当人拥有太多的时候,别人通常只看得到他所拥有的东西。 【目标】 一小钟刚刚被制作出来,老钟对它说:“你一年里要摆525600下。”小钟吓坏了,说“这么多,怎么可能?我完不成!”老钟笑着说:“不用怕,你只需一秒钟摆一下,每一秒坚持下来就可以了。”小钟半信半疑,但还是照做了。一年下来,小钟已经摆了525600下! 启示:面对大目标,我们往往望而怯步,不相信自己。其实只要根据实际,分期制定小目标,一一完成就行了。 【琐事】 一只鼬鼠提出跟一只狮子决斗,狮子果断地拒绝了。鼬鼠轻蔑地说:“你害怕了吗?”狮子说:“如果答应你,你就可以得到曾与狮子比武的殊荣;而我呢,以后所有的动物都会耻笑我竟和鼬鼠打架。” 启示:不要把时间和精力浪费在无谓的琐事上,那样只会得不偿失。 【环境和专长】 有个鲁国人擅长编草鞋,他妻子擅长织白绢。他想迁到越国去。友人对他说:你到越国去,一定会贫穷的。鲁国人不明白。友人说:草鞋,是穿着走路的,但越国人习惯赤足走;白绢,是做帽子的,但越国人习惯披头散发。你把你的专长用到不需要的环境,这样当然会贫穷。 启示:有专长,也要到适合专长发挥的环境中去,否则就会英雄无用武之地。 【损失】 一个卖瓷碗的人挑着扁担在路上走,突然一个瓷碗掉到地上摔碎了,但那人头也不回继续向前走。路人觉得奇怪,问他:“为什么你的碗摔碎了,你却不看一下?”那人说:“我回头看,那个碗就不会碎了吗?” 启示:如果做不到弥补,就不要做多余的事,那样只会浪费时间,将损失扩大。 后话 大家还有什么好故事推荐没? 参考&感谢 语文迷 名言赏析 老鼠偷大米,人们说他狡猾;人们偷蜂蜜,却说蜜蜂勤劳。 系列教程 全部文章RSS订阅 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2022/8/7
articleCard.readMore

如何编写Linux驱动?

本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标! 驱动学习 •整个内核70%以上是各种驱动代码 •每一个你日常使用的小功能背后都有复杂的实现! •Linux 驱动程序设计模式(40%) char,block,net,input,pci,usb,Platform(bus,device,driver),kset,kobject,proc,sysfs,ioctl,mmap,miscdevice, softirq,tasklet,workqueue, console, •内核相关知识(30%):内核目录结构,内存访问,ipc,锁,内核数据结构,不通内核版本api,热拔插netlink,内核线程,中断处理(注册,共享),设备树, •硬件相关知识(30%): 总线,协议(I2C,I2S,SPI,USB,PCI,sensor,bt1120,bt656,LCD),各种CPU、传感器(ADC,sensor,temperature etc)工作原理 前置基础知识 模拟电路,数字电路 硬件总线协议,各种RFC文档; 了解硬件电路设计,能看懂电路图。示波器等工具的使用 对C语言了如指掌,各种特殊宏的用法,对内核基本数据结构了解。 熟悉C系统编程,应用层编程 内核软件子系统,各种软件框架 上述知识你都有了一定了解之后,你才能开始尝试去开发驱动了! 学习曲线非常陡峭,必须一次性踏上台阶,否则后续又得重新攀爬。 这么多基础知识要求,基本就限定了只有科班计算机相关专业才能在这一行深入钻研了。 编写驱动困难之处 打怪升级困难。要有硬件项目才能给你升级涨经验!一个公司硬件项目周期极长,可能几年都做不了几个新硬件项目 新手与熟手完成同样任务时间差异极大!强者越强,你有经验,有难度的活都给你,你没经验,练手的机会都不会给你 一切都是以懵懂中开始的。内核代码量太大,没有任何人熟悉所有模块,你不可能都熟悉之后再开始动手修改。内核版本之间接口一直变动,没有稳定的软件方法。接口总线RFC文档太长,一般至少几千页的英文文档,你不可能都看完才开始动手。硬件设计可能有漏洞,不是官方设计出错,而是现实情况是当初设计RFC标准的人就没有考虑到这种异常情况 不同总线接口调试方法和工具差异极大,和医院不同科室使用不同工具差不多,你会不会使用某种工具,可能使你的工作效率差异几十倍 软件开发,你有一台电脑就足够了。硬件驱动开发,必须有对应的硬件开发板,调试工具Jtag,PC端调试工具,示波器,电源等一整套设备才能开始工作 所有书本的知识,都是过时的,落后的。任何一个实际硬件项目,基本都是独一无二的,驱动程序也是独一无二,全世界都没有第二个人做同样的东西!几乎没有任何参考。 网络上面所有相关教程,实际使用一般至少有一半以上是不切和实际的,错误的,没法使用。需要以你的基础知识从头推导,纠正相关部分的错误! 写驱动好比挖隧道 不知道隧道下面什么地质情况,什么岩层结构,是否好施工 是否有地下水,多大的地下水没法确定 是否能完工没法确定 完工时间多久没法确定 在你完工之前,你不知道还需要多长时间才能完工,是否能完工都不清楚 等等 写驱动,就是给你一个垃圾场,要你组装出来一个能走动的钟表! 不知道是否缺少零件,你要对整个软硬件构架了如指掌,比硬件更熟悉硬件 零件是否损坏,有可能多个零件,这个损坏,哪个没有损坏,你换一个同样的零件,说不定可行,也可能不可行 零件是否符合设计规范性能,有可能这个设计错误,根本就是不可能成功的 这个零件的说明书和零件是否匹配,给错了没有?外行连给到手的资料判断是否正确资料的能力都没有 由于你的上游一开始拿到的也是错误的资料,所以给你的也是错误资料 由于商业,保密等各种原因,一开始就给你错误的资料,故意不给你正确资料的情况也有 上游厂商的性能指标数据可能造假,或者批次性能瑕疵!没有实际验证之前,任何承诺都不能算数! 零件是否完好,是否工作正常 在你组装好,能走动之前,你不知道能否组装好手表 组成的钟表走时快慢是否正常,能够走动起来,说明零件大抵不差了,是驱动开发决定性进展 钟表能走动了,后续就是走时准确的调整。性能优化,续航优化,软件框架优化,内存优化,稳定性优化,电磁兼容等等 从一堆垃圾零件,组装出来一个能走的钟表!从上图到下图的过程! 实现出来 组装好,把驱动跑起来是第一步 性能优化 对于访问外设emmc,不同时序参数访问性能差距很大。对跑分影响很大! 续航优化 不用外设时,可以关闭对应外设电源,或者根据负载动态调节 内存优化 内存占用,Zero Copy,指针传递 稳定性优化 稳定性,眼图,高速性能 电磁兼容 电磁兼容测试,各种标准 等等其它方面 驱动开发深入下去,是一座又一座高山需要攀爬,但基本的驱动开发还是不难的。 驱动案例 每一个外设都有复杂的物理,材料,结构,光学,工艺,版本等等各种复杂因素需要研究,考虑。当然不是每个外设都这么复杂,复杂的摄像头子系统涉及的知识技术几年就研究不完! 每一款芯片构架差异都很大,会有不同的内核软件构架,德州仪器TI一份完整的芯片手册就有3000多页,至少看完前四章(几百页英文文档)才能说对芯片有基本了解。 简单的按键 按键硬件设计方法常用的就有3、4种。每种硬件设计,内核就要好几种软件框架可以实现它。 学习驱动可以从它开始。万里长征第一步,后面慢慢学习I2C,SPI, NAND等外设驱动。 摄像头驱动介绍 可以说是整个手机最复杂的外设驱动!研究两年只能说刚入门。 3A算法是核心: AWB 启动白平衡,AE自动曝光,AF自动对焦 理论上就没有完善的解决方案,只有近似解决方案。技术理论发展很快,经常有新技术和方法出来。 感觉这个很复杂?很正常,整套软件系统自己搞定就需要几十人的团队,一般也就是需要修改整套系统种的某一部分。Sensor驱动,ISP tunning等。 下面简单图解ISP驱动相关知识 涉及到Sensor专有知识点有 黑电平与线性化 Green Imbalance 坏点消除 Vignetting 与 Color shading SNR 与 Raw Denoise Dynamic Range 与 Tone Mapping MTF 与 Demosaic 色彩空间与色彩重建 Color Correction Matrix 与 3D LUT Gamma与对比度增强 Sharpening Color Space Conversion 空域降噪 时域降噪 Color Aberrance Corrention and Depurple 闪光灯 HDR Exif 与 DNG 图像防抖 编解码知识 H264 H265等 Sensor子系统涉及到的知识大概有如上,个人做过的最复杂的子系统就这个了。 会写简单驱动,到会写sensor驱动,到会写ISP系统,中间都隔了几年时间差距。 驱动的技术级别 要做好驱动,要熟悉硬件,总线协议,要会怀疑每一处地方,其它每个人给的信息都可能是错误的,如何定位这个错误就是驱动的工作。成功的路径只有一个,而失败的路径千千万万,驱动的的工作就是找到这条成功的路。 必备:入门水平 必备:入门水平,能在别人指导下完成一些简单驱动开发。在一些深入,系统学习后进入下一阶段。 基本的数电模电基础。 熟悉一些常用开发工具。 熟悉linux 内核基本驱动框架。懂得基本内核原理。 独立实现过char字符设备。 调试过一些常见总线接口设备。比如常见的I2C,SPI设备。 中等水平 中等水平:能够按照指示完成任务,需要大量的时间和大量产品开发慢慢积累经验,完成本阶段进阶。 熟练使用各种开发工具。 对linux驱动绝大部分常用框架都有研究。 能够进行ip core外围器件级别的移植。 熟悉内核锁的使用,了解中断上下文。 能够分析定位解决时序问题。 用gpio模拟实现过I2C,SPI等总线驱动。 对oops定位分析,驱动调试熟悉。 对proc,sys,debugfs熟悉或者做过。 能够在现有驱动基础上修改,阅读datasheet对接新硬件。 在一些行业应用领域能够在fae帮助下完成外围设备驱动。 了解arm硬件构架,懂得基本arm汇编指令。基本c程序优化。 懂得基本pcb升级,打板贴片流程。 能够解决大部分硬件异常问题。 高手进阶 高手进阶:能够独当一面,带领团队。 工具什么的无所谓,有自己一套最高效的配置工具。 能够进行ip core级别的移植。 熟悉并懂得使用各种内核锁,能用内核线程实现一些复杂需求,中断上下文实现都有做过。 对应用层构架各种技术方法也都非常熟悉。 知道单核、多核同构、异构构架的内核、驱动、应用层设计差异及处理方法,优化方法。 熟悉arm构架,arm指令集。懂得怎么根据硬件构架,芯片指令集优化程序。 知道怎么使用汇编,cache优化。知道cache一致性原理及其实现。 深入研究过linux内核实现机制。 熟悉编译,汇编,链接原理。能够定位一些复杂问题,知道怎么通过编译器,链接器实现一些非标准的功能。 独立实现过绝大部分外围驱动。 能够独立从头开始实现一些复杂框架驱动。例如网络设备,视频设备等。 在一些具体应用业务上研究的非常深入,达到行业一流水平。 深入研究过绝大部分总线接口。比如音视频接口,编解码,usb,网络等业务。 画过pcb,或者至少了解pcb设计,绘制,打板过程中的各种问题。 能够熟练协助硬件定位解决各种问题。 超一流高手进阶 超一流高手进阶:技术方面基本没有什么可以难倒你的了。 自己去实现基本的uboot,内核。 能够自己设计实现全新的内核框架。 开始一些具体应用的结构,物理,数学,光学等方面深入研究。 一些问题能否解决,怎么解决,更多的从数学角度分析。 参与主线linux kernel开发。 对hdl,Verilog深入了解,自己设计芯片ip core。 以上都是个人见解,仅供参考! 硬件设计 下面是硬件工程师的能力需要掌握的能力,驱动对这些不一定要精通,但一定要懂!作为驱动工程师要比硬件工程师更懂硬件,才能发现并解决硬件问题 基础学科和电路相关学科的理论能力,主要涉及高等数学、复变函数、大学电路、大学物理、模拟电路、数字电路、高速电路设计、信号完整性、电磁仿真、EMS/EMI设计等; 器件选型、电路设计能力;PCB设计与绘制,PCB生产工艺与流程,各种硬件设计标准,环保标准,各国的电路、工艺、环保等标准 电路板焊接、手工工具使用能力; 万用表、示波器、频谱仪、时序分析仪、矢量网络分析仪等仪器仪表的使用能力; 常见数字信号的总线和接口的理解和测试能力; 文档阅读、撰写能力; 新方案和平台的学习能力; 代码debug能力; 问题描述和沟通能力。 信号完整性 信号完整性是指在电路中从发射端到接收端,信号在传输和处理过程中能够保持其原始质量和数据完整性的能力。当信号受到任何形式的损失或变形时,就会损害其完整性,并导致数据错误、跳闸和其他问题。 为了维持信号完整性,需要考虑主要的因素: 反射:信号反射是由于信号传输线路不匹配、连接器品质差、排布方式不当造成的现象,反射会导致信号幅度降低、延迟和失真。 接入损耗:当信号通过多个组件(例如 PCB迹道、基板穿孔、插头、接口和连接器等)时,信号的路径会产生接触阻抗变化,这种变化会产生不同级别的功率损失。 串扰:由于超近距离物理链接和电场交互作用,两条相邻线路之间会产生频域与时间域上的干扰。 时钟偏移和抖动:由于温度波动、震动、噪声及晶体管本身等影响,时钟频率的稳定性可能会出现相对误差,从而引起抖动或者不同频段的交叉干扰。 非线性效应:过度开启、过度关断和电流饱和等导致非线性的行为会引起因求得对谐波失真、交调失真、截止失真和互交调制等影响。 地面反弹和回归损耗: 相邻板层之间产生了地较差,这样传输线路上天线肯定设计在一端上,然而模式(典型的是 TEM、vs TE/TM)会影响抑制和放射。通过地掩盖和 返工方式优化此项效果。 维持信号完整性的主要方法包括:使用高品质的线路和连接器、选择适当的电缆阻抗匹配、考虑噪声源问题和EMC防护、按要求使用功率地面、使用屏蔽技术、使用合适的静电保护、并使用冗余机制和误码纠正机制等等。 维护信号完整性是现代电子设计中至关重要的一个方面,很多电气、无线、测试和计算机网络领域中需要保证信号完整性。 Linux Performance Linux Performance Linux observability tools, Linux static performance analysis tools, Linux benchmarking tools, Linux tuning tools, and Linux sar 参考 相关书籍 Linux内核完全注释 见字如晤 书名: Linux内核完全注释 作者: 赵炯 出版年份: 2005-8 评分: 8.5 Linux设备驱动程序 我读过这本书 书名: Linux设备驱动程序 作者: 科波特 出版年份: 2006-1-1 评分: 8.7 Linux设备驱动开发详解 见字如晤 书名: Linux设备驱动开发详解 作者: 宋宝华 出版年份: 2008-2 评分: 8.2 上面两本是介绍Linux kernel软件驱动框架的 Link and loader 见字如晤 书名: LinkersandLoaders 作者: JohnR.Levine 出版年份: October1999 评分: 8.9 Linux内核源代码情景分析(上册) 见字如晤 书名: Linux内核源代码情景分析(上册) 作者: 毛德操 出版年份: 2001-9 评分: 8.7 相关文章 如何编写Linux驱动 本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标! 3G,4G,Wifi选型需求分析及技术简介 详细介绍了3G,4G,wifi技术类型,选型,移植,性能介绍全过程。写了好多年了,禁止转载,第一次公开发表。 海思MPP&UNF构架源代码级分析 行业中分析海思MPP内核构架,源码分析,多年经验总结积累结果。写了好多年了,禁止转载,第一次公开发表。 如何实现自己的操作系统 作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库! 手把手教你构建 C 语言编译器 “手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。 系列教程 全部文章RSS订阅 系统编程系列 如何实现自己的操作系统 手把手教你构建 C 语言编译器 如何编写Linux驱动? 海思MPP&UNF构架源代码级分析 使用 Shell 脚本实现一个简单 Docker Github build-your-own-x 系列 百善孝为先,论心不论迹,论迹贫家无孝子;万恶淫为首,论迹不论心,论心世上少完人。 ​ ——名言赏析 《唾玉集》 烂柯真诀妙通神, 一局曾经几度春。 自出洞来无敌手, 得饶人处且饶人。

2022/7/28
articleCard.readMore

如何实现自己的操作系统

作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库! OS的层级模型 层级 涉及知识 材料,工艺 电路设计 EDA, VHDL, Verilog 硬件 CPU,内存,硬盘,显示器等 串口,网口,bt1120等协议,电磁兼容。总线协议 CPU X86, ARM, RISC, DSP, 指令集,体系结构。专用加速核心 H264等 汇编 intel, AT&T 不同的体系结构和语法 链接器 ld uboot,kernel链接过程 编译器 gcc, golang ld,编译器,makefile, gdb OS 进程,内存,文件,IO等 标准库 open,close,read,fork等 posix接口,glibc, QT,MFC,TF, Caffe等 实用程序 shell,编辑器,浏览器 软件协议,OSI网络模型 用户 交互设计 LFS Linux From Scratch 从源码开始构建一个可用的 Linux 操作系统。 可以从 LFS BLFS CLFS 这几个项目入手! 学习 Linux From Scratch(LFS)是一个深入了解 Linux 内部工作原理的有趣而丰富的过程。以下是一份简单的学习 LFS 的资源链接列表: LFS 官方网站 Linux From Scratch Official Site LFS 项目手册 LFS Project Manual Beyond Linux From Scratch (BLFS) Beyond Linux From Scratch LFS 论坛 LFS Forum LFS 下载页面 LFS Downloads LFS 指南 LFS 指南 Hints 文档 LFS Hints 在线交流 Reddit - /r/linuxfromscratch LFS Git 仓库 LFS Git Repository 视频教程 Linux from Scratch (LFS) Tutorial by TheUrbanPenguin on YouTube. 其他资源 LFS Wikipedia 学习步骤: 阅读 LFS 指南,了解整个 LFS 构建过程。 下载 LFS 项目手册,并按照其中的步骤逐步构建自己的 Linux 系统。 深入学习 Beyond Linux From Scratch (BLFS),这是一个提供额外软件安装的扩展。 在 LFS 论坛或 Reddit 上寻求帮助,与其他学习者和有经验的用户交流经验。 记住,LFS 是一项深入的任务,需要花费一些时间和耐心。确保在学习过程中理解每个步骤,这将有助于提高对 Linux 系统的整体理解。 相关书籍 30天自制操作系统 我最近在读这本书 书名: 30天自制操作系统 作者: [日]川合秀实 出版年份: 2012-8 评分: 8.3 自制编译器 见字如晤 书名: 自制编译器 作者: [日]青木峰郎 出版年份: 2016-6 评分: 7.9 自制搜索引擎 见字如晤 书名: 自制搜索引擎 作者: [日]山田浩之 出版年份: 2016-1 评分: 7.6 自己动手实现Lua 见字如晤 书名: 自己动手实现Lua 作者: 张秀宏 出版年份: 2018-1-1 评分: 9.1 两周自制脚本语言 见字如晤 书名: 两周自制脚本语言 作者: [日]千叶滋 出版年份: 2014-6 评分: 8.4 自制编程语言 见字如晤 书名: 自制编程语言 作者: [日]前桥和弥 出版年份: 2013-11 评分: 8.1 CPU自制入门 见字如晤 书名: CPU自制入门 作者: [日]水头一寿 出版年份: 2014-1 评分: 7.8 link and loader 见字如晤 书名: LinkersandLoaders 作者: JohnR.Levine 出版年份: October1999 评分: 8.9 Orange’S:一个操作系统的实现 我最近在读这本书 书名: Orange'S:一个操作系统的实现 作者: 于渊 出版年份: 2009-6 评分: 8.8 Linux内核完全注释 见字如晤 书名: Linux内核完全注释 作者: 赵炯 出版年份: 2005-8 评分: 8.5 没看过这本书,可以说内核没入门。 作为一个合格的计算机专业学生,半年搞懂OS并实现一个,就是个大作业水平! 相关仓库 https://rcore-os.github.io/rCore-Tutorial-Book-v3/ 相关文章 如何编写Linux驱动 本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标! 3G,4G,Wifi选型需求分析及技术简介 详细介绍了3G,4G,wifi技术类型,选型,移植,性能介绍全过程。写了好多年了,禁止转载,第一次公开发表。 海思MPP&UNF构架源代码级分析 行业中分析海思MPP内核构架,源码分析,多年经验总结积累结果。写了好多年了,禁止转载,第一次公开发表。 如何实现自己的操作系统 作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库! 手把手教你构建 C 语言编译器 “手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。 相关书籍和源代码仓库收集中! 有什么好的仓库可以留言建议! 参考 全方位剖析 Linux 操作系统 程序员必知的 89 个操作系统核心概念 Wiki 操作系统 Linux Lab 公开课 Linux kernel 系列教程 全部文章RSS订阅 系统编程系列 如何实现自己的操作系统 手把手教你构建 C 语言编译器 如何编写Linux驱动? 海思MPP&UNF构架源代码级分析 使用 Shell 脚本实现一个简单 Docker Github build-your-own-x 系列

2022/7/27
articleCard.readMore

手把手教你构建 C 语言编译器

“手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。 手把手教你构建 C 语言编译器系列共有10个部分: 前言 在开始进入正题之前,本篇是一些闲聊,谈谈这个系列的初衷。如果你急切地想进入正篇,请跳过本章。 为什么要学编译原理 如果要我说计算机专业最重要的三门课,我会说是《数据结构》、《算法》和《编译原理》。在我看来,能不能理解“递归”像是程序员的第一道门槛,而会不会写编译器则是第二道。 (当然,并不是说是没写过编译器就不是好程序员,只能说它是一个相当大的挑战吧) 以前人们会说,学习了编译原理,你就能写出更加高效的代码,但随着计算机性能的提升,代码是否高效显得就不那么重要了。那么为什么要学习编译原理呢? 原因只有一个:装B。 好吧,也许现在还想学习编译原理的人只可能是因为兴趣了。一方面想了解它的工作原理;另一方面希望挑战一下自己,看看自己能走多远。 理论很复杂,实现也很复杂? 我对编译器一直心存敬佩。所以当学校开《编译原理》的课程后,我是抱着满腔热情去上课的,但是两节课后我就放弃了。原因是太复杂了,听不懂。 一般编译原理的课程会说一些: 如何表示语法(BNF什么的) 词法分析,用什么有穷自动机和无穷自动机 语法分析,递归下降法,什么 LL(k),LALR 分析。 中间代码的表示 代码的生成 代码优化 我相信绝大多数(98%)的学生顶多学到语法分析就结束了。并且最重要的是,学了这么多也没用!依旧帮助不了我们学习编译器!这其中最主要的原因是《编译原理》试图教会我们的是如何构造“编译器生成器”,即构造一个工具,根据文法来生成编译器(如 lex/yacc)等等。 这些理论试图教会我们如何用通用的方法来自动解决问题,它们有很强的实际意义,只是对于一般的学生或程序员来说,它们过于强大,内容过于复杂。如果你尝试阅读 lex/yacc (或 flex/bison)的代码,就会发现太可怕了。 然而如果你能跟我一样,真正来实现一个简单的编译器,那么你会发现,比起可怕的《编译原理》,这点复杂度还是不算什么的(因为好多理论根本用不上)。 项目的初衷 有一次在 Github 上看到了一个项目(当时很火的),名叫 c4,号称用 4 个函数来实现了一个小的 C 语言编译器。它最让我震惊的是能够自举,即能自己编译自己。并且它用很少的代码就完成了一个功能相当完善的 C 语言编译器。 一般的编译器相关的教程要么就十分简单(如实现四则运算),要么就是借助了自动生成的工具(如 flex/bison)。而 c4 的代码完全是手工实现的,不用外部工具。可惜的是它的代码初衷是代码最小化,所以写得很乱,很难懂。所以本项目的主要目的: 实现一个功能完善的 C 语言编译器 通过教程来说明这个过程。 c4 大致500+行。重写的代码历时一周,总共代码加注释1400行。项目地址: Write a C Interpreter。 声明:本项目中的代码逻辑绝大多数取自 c4 ,但确为自己重写。 做好心理准备 在写编译器的时候会遇到两个主要问题: 繁琐,会有许多相似的代码,写起来很无聊。 难以调试,一方面没有很好的测试用例,另一方面需要对照生成的代码来调试(遇到的时候就知道了)。 所以我希望你有足够的耐心和时间来学习,相信当你真正完成的时候会像我一样,十分有成就感。 PS. 第一篇完全没有正题相关的内容也是希望你能有所心理准备再开始学习。 参考资料 最后想介绍几个资料: Let’s Build a Compiler 很好的初学者教程,英文的。 Lemon Parser Generator,一个语法分析器生成器,对照《编译原理》观看效果更佳。 设计 从整体上讲解如何设计我们的 C 语言编译器。 首先要说明的是,虽然标题是编译器,但实际上我们构建的是 C 语言的解释器,这意味着我们可以像运行脚本一样去运行 C 语言的源代码文件。这么做的理由有两点: 解释器与编译器仅在代码生成阶段有区别,而其它方面如词法分析、语法分析是一样的。 解释器需要我们实现自己的虚拟机与指令集,而这部分能帮助我们了解计算机的工作原理。 编译器的构建流程 一般而言,编译器的编写分为 3 个步骤: 词法分析器,用于将字符串转化成内部的表示结构。 语法分析器,将词法分析得到的标记流(token)生成一棵语法树。 目标代码的生成,将语法树转化成目标代码。 已经有许多工具能帮助我们处理阶段1和2,如 flex 用于词法分析,bison 用于语法分析。只是它们的功能都过于强大,屏蔽了许多实现上的细节,对于学习构建编译器帮助不大。所以我们要完全手写这些功能。 所以我们会依照以下步骤来构建我们的编译器: 构建我们自己的虚拟机以及指令集。这后生成的目标代码便是我们的指令集。 构建我们的词法分析器 构建语法分析器 编译器框架 我们的编译器主要包括 4 个函数: next() 用于词法分析,获取下一个标记,它将自动忽略空白字符。 program() 语法分析的入口,分析整个 C 语言程序。 expression(level) 用于解析一个表达式。 eval() 虚拟机的入口,用于解释目标代码。 这里有一个单独用于解析“表达式”的函数 expression 是因为表达式在语法分析中相对独立并且比较复杂,所以我们将它单独作为一个模块(函数)。下面是相应的源代码: #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <string.h> int token; // current token char *src, *old_src; // pointer to source code string; int poolsize; // default size of text/data/stack int line; // line number void next() { token = *src++; return; } void expression(int level) { // do nothing } void program() { next(); // get next token while (token > 0) { printf("token is: %c\n", token); next(); } } int eval() { // do nothing yet return 0; } int main(int argc, char **argv) { int i, fd; argc--; argv++; poolsize = 256 * 1024; // arbitrary size line = 1; if ((fd = open(*argv, 0)) < 0) { printf("could not open(%s)\n", *argv); return -1; } if (!(src = old_src = malloc(poolsize))) { printf("could not malloc(%d) for source area\n", poolsize); return -1; } // read the source file if ((i = read(fd, src, poolsize-1)) <= 0) { printf("read() returned %d\n", i); return -1; } src[i] = 0; // add EOF character close(fd); program(); return eval(); } 上面的代码看上去挺复杂,但其实内容不多。它的流程为:读取一个文件(内容为 C 语言代码),逐个读取文件中的字符,并输出。这里需要的是注意每个函数的作用,后面的文章中,我们将逐个填充每个函数的功能,最终构建起我们的编译器。 本节的代码可以在 Github 上下载,也可以直接 clone git clone -b step-0 https://github.com/lotabout/write-a-C-interpreter 这样我们就有了一个最简单的编译器:什么都不干的编译器,下一章中,我们将实现其中的eval函数,即我们自己的虚拟机。 虚拟机 本章我们要构建一台虚拟的电脑,设计我们自己的指令集,运行我们的指令集,说得通俗一点就是自己实现一套汇编语言。它们将作为我们的编译器最终输出的目标代码。 计算机的内部工作原理 计算机中有三个基本部件需要我们关注:CPU、寄存器及内存。代码(汇编指令)以二进制的形式保存在内存中;CPU 从中一条条地加载指令执行;程序运行的状态保存在寄存器中。 内存 内存用于存储数据,这里的数据可以是代码,也可以是其它的数据。现代操作系统在操作内存时,并不是直接处理”物理内存“,而是操作”虚拟内存“。虚拟内存可以理解为一种映射,它的作用是屏蔽了物理的细节。例如 32 位的机器中,我们可以使用的内存地址为 2^32 = 4G,而电脑上的实际内存可能只有 256 M。操作系统将我们使用的虚拟地址映射到了到实际的内存上。 当然,我们这里并不需要了解太多,但需要了解的是:进程的内存会被分成几个段: 代码段(text)用于存放代码(指令)。 数据段(data)用于存放初始化了的数据,如int i = 10;,就需要存放到数据段中。 未初始化数据段(bss)用于存放未初始化的数据,如 int i[1000];,因为不关心其中的真正数值,所以单独存放可以节省空间,减少程序的体积。 栈(stack)用于处理函数调用相关的数据,如调用帧(calling frame)或是函数的局部变量等。 堆(heap)用于为程序动态分配内存。 它们在内存中的位置类似于下图: +------------------+ | stack | | high address | ... v | | | | | | | | | | ... ^ | | heap | | +------------------+ | bss segment | +------------------+ | data segment | +------------------+ | text segment | low address +------------------+ 我们的虚拟机并不打算模拟完整的计算机,因此简单起见,我们只关心三个内容:代码段、数据段以及栈。其中的数据段我们只用来存放字符串,因为我们的编译器并不支持初始化变量,因此我们也不需要未初始化数据段。 当用户的程序需要分配内存时,理论上我们的虚拟机需要维护一个堆用于内存分配,但实际实现上较为复杂且与编译无关,故我们引入一个指令MSET,使我们能直接使用编译器(解释器)中的内存。 综上,我们需要首先在全局添加如下代码: int *text, // text segment *old_text, // for dump text segment *stack; // stack char *data; // data segment 注意这里的类型,虽然是int型,但理解起来应该作为无符号的整型,因为我们会在代码段(text)中存放如指针/内存地址的数据,它们就是无符号的。其中数据段(data)由于只存放字符串,所以是 char * 型的。 接着,在main函数中加入初始化代码,真正为其分配内存: int main() { close(fd); ... // allocate memory for virtual machine if (!(text = old_text = malloc(poolsize))) { printf("could not malloc(%d) for text area\n", poolsize); return -1; } if (!(data = malloc(poolsize))) { printf("could not malloc(%d) for data area\n", poolsize); return -1; } if (!(stack = malloc(poolsize))) { printf("could not malloc(%d) for stack area\n", poolsize); return -1; } memset(text, 0, poolsize); memset(data, 0, poolsize); memset(stack, 0, poolsize); ... program(); } 寄存器 计算机中的寄存器用于存放计算机的运行状态,真正的计算机中有许多不同种类的寄存器,但我们的虚拟机中只使用 4 个寄存器,分别如下: PC 程序计数器,它存放的是一个内存地址,该地址中存放着 下一条 要执行的计算机指令。 SP 指针寄存器,永远指向当前的栈顶。注意的是由于栈是位于高地址并向低地址增长的,所以入栈时 SP 的值减小。 BP 基址指针。也是用于指向栈的某些位置,在调用函数时会使用到它。 AX 通用寄存器,我们的虚拟机中,它用于存放一条指令执行后的结果。 要理解这些寄存器的作用,需要去理解程序运行中会有哪些状态。而这些寄存器只是用于保存这些状态的。 在全局中加入如下定义: int *pc, *bp, *sp, ax, cycle; // virtual machine registers 在 main 函数中加入初始化代码,注意的是PC在初始应指向目标代码中的main函数,但我们还没有写任何编译相关的代码,因此先不处理。代码如下: memset(stack, 0, poolsize); ... bp = sp = (int *)((int)stack + poolsize); ax = 0; ... program(); 与 CPU 相关的是指令集,我们将专门作为一个小节。 指令集 指令集是 CPU 能识别的命令的集合,也可以说是 CPU 能理解的语言。这里我们要为我们的虚拟机构建自己的指令集。它们基于 x86 的指令集,但更为简单。 首先在全局变量中加入一个枚举类型,这是我们要支持的全部指令: // instructions enum { LEA ,IMM ,JMP ,CALL,JZ ,JNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PUSH, OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD , OPEN,READ,CLOS,PRTF,MALC,MSET,MCMP,EXIT }; 这些指令的顺序安排是有意的,稍后你会看到,带有参数的指令在前,没有参数的指令在后。这种顺序的唯一作用就是在打印调试信息时更加方便。但我们讲解的顺序并不依据它。 MOV MOV 是所有指令中最基础的一个,它用于将数据放进寄存器或内存地址,有点类似于 C 语言中的赋值语句。x86 的 MOV 指令有两个参数,分别是源地址和目标地址:MOV dest, source (Intel 风格),表示将 source 的内容放在 dest 中,它们可以是一个数、寄存器或是一个内存地址。 一方面,我们的虚拟机只有一个寄存器,另一方面,识别这些参数的类型(是数据还是地址)是比较困难的,因此我们将 MOV 指令拆分成 5 个指令,这些指令只接受一个参数,如下: IMM <num> 将 <num> 放入寄存器 ax 中。 LC 将对应地址中的字符载入 ax 中,要求 ax 中存放地址。 LI 将对应地址中的整数载入 ax 中,要求 ax 中存放地址。 SC 将 ax 中的数据作为字符存放入地址中,要求栈顶存放地址。 SI 将 ax 中的数据作为整数存放入地址中,要求栈顶存放地址。 你可能会觉得将一个指令变成了许多指令,整个系统就变得复杂了,但实际情况并非如此。首先是 x86 的 MOV 指令其实有许多变种,根据类型的不同有 MOVB, MOVW 等指令,我们这里的 LC/SC 和 LI/SI 就是对应字符型和整型的存取操作。 但最为重要的是,通过将 MOV 指令拆分成这些指令,只有 IMM 需要有参数,且不需要判断类型,所以大大简化了实现的难度。 在 eval() 函数中加入下列代码: void eval() { int op, *tmp; while (1) { if (op == IMM) {ax = *pc++;} // load immediate value to ax else if (op == LC) {ax = *(char *)ax;} // load character to ax, address in ax else if (op == LI) {ax = *(int *)ax;} // load integer to ax, address in ax else if (op == SC) {ax = *(char *)*sp++ = ax;} // save character to address, value in ax, address on stack else if (op == SI) {*(int *)*sp++ = ax;} // save integer to address, value in ax, address on stack } ... return 0; } 其中的 *sp++ 的作用是退栈,相当于 POP 操作。 这里要解释的一点是,为什么 SI/SC 指令中,地址存放在栈中,而 LI/LC 中,地址存放在 ax 中?原因是默认计算的结果是存放在 ax 中的,而地址通常是需要通过计算获得,所以执行 LI/LC 时直接从 ax 取值会更高效。另一点是我们的 PUSH 指令只能将 ax 的值放到栈上,而不能以值作为参数,详细见下文。 PUSH 在 x86 中,PUSH 的作用是将值或寄存器,而在我们的虚拟机中,它的作用是将 ax 的值放入栈中。这样做的主要原因是为了简化虚拟机的实现,并且我们也只有一个寄存器 ax 。代码如下: else if (op == PUSH) {*--sp = ax;} // push the value of ax onto the stack JMP JMP <addr> 是跳转指令,无条件地将当前的 PC 寄存器设置为指定的 <addr>,实现如下: else if (op == JMP) {pc = (int *)*pc;} // jump to the address 需要注意的是,pc 寄存器指向的是 下一条 指令。所以此时它存放的是 JMP 指令的参数,即 <addr> 的值。 JZ/JNZ 为了实现 if 语句,我们需要条件判断相关的指令。这里我们只实现两个最简单的条件判断,即结果(ax)为零或不为零情况下的跳转。 实现如下: else if (op == JZ) {pc = ax ? pc + 1 : (int *)*pc;} // jump if ax is zero else if (op == JNZ) {pc = ax ? (int *)*pc : pc + 1;} // jump if ax is not zero 子函数调用 这是汇编中最难理解的部分,所以合在一起说,要引入的命令有 CALL, ENT, ADJ 及 LEV。 首先我们介绍 CALL <addr> 与 RET 指令,CALL 的作用是跳转到地址为 <addr> 的子函数,RET 则用于从子函数中返回。 为什么不能直接使用 JMP 指令呢?原因是当我们从子函数中返回时,程序需要回到跳转之前的地方继续运行,这就需要事先将这个位置信息存储起来。反过来,子函数要返回时,就需要获取并恢复这个信息。因此实际中我们将 PC 保存在栈中。如下: else if (op == CALL) {*--sp = (int)(pc+1); pc = (int *)*pc;} // call subroutine //else if (op == RET) {pc = (int *)*sp++;} // return from subroutine; 这里我们把 RET 相关的内容注释了,是因为之后我们将用 LEV 指令来代替它。 在实际调用函数时,不仅要考虑函数的地址,还要考虑如何传递参数和如何返回结果。这里我们约定,如果子函数有返回结果,那么就在返回时保存在 ax 中,它可以是一个值,也可以是一个地址。那么参数的传递呢? 各种编程语言关于如何调用子函数有不同的约定,例如 C 语言的调用标准是: 由调用者将参数入栈。 调用结束时,由调用者将参数出栈。 参数逆序入栈。 事先声明一下,我们的编译器参数是顺序入栈的,下面的例子(C 语言调用标准)取自 维基百科: int callee(int, int, int); int caller(void) { int i, ret; ret = callee(1, 2, 3); ret += 5; return ret; } 会生成如下的 x86 汇编代码: caller: ; make new call frame push ebp mov ebp, esp sub 1, esp ; save stack for variable: i ; push call arguments push 3 push 2 push 1 ; call subroutine 'callee' call callee ; remove arguments from frame add esp, 12 ; use subroutine result add eax, 5 ; restore old call frame mov esp, ebp pop ebp ; return ret 上面这段代码在我们自己的虚拟机里会有几个问题: push ebp,但我们的 PUSH 指令并无法指定寄存器。 mov ebp, esp,我们的 MOV 指令同样功能不足。 add esp, 12,也是一样的问题(尽管我们还没定义)。 也就是说由于我们的指令过于简单(如只能操作ax寄存器),所以用上面提到的指令,我们连函数调用都无法实现。而我们又不希望扩充现有指令的功能,因为这样实现起来就会变得复杂,因此我们采用的方法是增加指令集。毕竟我们不是真正的计算机,增加指令会消耗许多资源(钱)。 ENT ENT <size> 指的是 enter,用于实现 ‘make new call frame’ 的功能,即保存当前的栈指针,同时在栈上保留一定的空间,用以存放局部变量。对应的汇编代码为: ; make new call frame push ebp mov ebp, esp sub 1, esp ; save stack for variable: i 实现如下: else if (op == ENT) {*--sp = (int)bp; bp = sp; sp = sp - *pc++;} // make new stack frame ADJ ADJ <size> 用于实现 ‘remove arguments from frame’。在将调用子函数时压入栈中的数据清除,本质上是因为我们的 ADD 指令功能有限。对应的汇编代码为: ; remove arguments from frame add esp, 12 实现如下: else if (op == ADJ) {sp = sp + *pc++;} // add esp, <size> LEV 本质上这个指令并不是必需的,只是我们的指令集中并没有 POP 指令。并且三条指令写来比较麻烦且浪费空间,所以用一个指令代替。对应的汇编指令为: ; restore old call frame mov esp, ebp pop ebp ; return ret 具体的实现如下: else if (op == LEV) {sp = bp; bp = (int *)*sp++; pc = (int *)*sp++;} // restore call frame and PC 注意的是,LEV 已经把 RET 的功能包含了,所以我们不再需要 RET 指令。 LEA 上面的一些指令解决了调用帧的问题,但还有一个问题是如何在子函数中获得传入的参数。这里我们首先要了解的是当参数调用时,栈中的调用帧是什么样的。我们依旧用上面的例子(只是现在用“顺序”调用参数): sub_function(arg1, arg2, arg3); | .... | high address +---------------+ | arg: 1 | new_bp + 4 +---------------+ | arg: 2 | new_bp + 3 +---------------+ | arg: 3 | new_bp + 2 +---------------+ |return address | new_bp + 1 +---------------+ | old BP | <- new BP +---------------+ | local var 1 | new_bp - 1 +---------------+ | local var 2 | new_bp - 2 +---------------+ | .... | low address 所以为了获取第一个参数,我们需要得到 new_bp + 4,但就如上面的说,我们的 ADD 指令无法操作除 ax 外的寄存器,所以我们提供了一个新的指令:LEA <offset> 实现如下: else if (op == LEA) {ax = (int)(bp + *pc++);} // load address for arguments. 以上就是我们为了实现函数调用需要的指令了。 运算符指令 我们为 C 语言中支持的运算符都提供对应汇编指令。每个运算符都是二元的,即有两个参数,第一个参数放在栈顶,第二个参数放在 ax 中。这个顺序要特别注意。因为像 -,/ 之类的运算符是与参数顺序有关的。计算后会将栈顶的参数退栈,结果存放在寄存器 ax 中。因此计算结束后,两个参数都无法取得了(汇编的意义上,存在内存地址上就另当别论)。 实现如下: else if (op == OR) ax = *sp++ | ax; else if (op == XOR) ax = *sp++ ^ ax; else if (op == AND) ax = *sp++ & ax; else if (op == EQ) ax = *sp++ == ax; else if (op == NE) ax = *sp++ != ax; else if (op == LT) ax = *sp++ < ax; else if (op == LE) ax = *sp++ <= ax; else if (op == GT) ax = *sp++ > ax; else if (op == GE) ax = *sp++ >= ax; else if (op == SHL) ax = *sp++ << ax; else if (op == SHR) ax = *sp++ >> ax; else if (op == ADD) ax = *sp++ + ax; else if (op == SUB) ax = *sp++ - ax; else if (op == MUL) ax = *sp++ * ax; else if (op == DIV) ax = *sp++ / ax; else if (op == MOD) ax = *sp++ % ax; 内置函数 写的程序要”有用“,除了核心的逻辑外还需要输入输出,例如 C 语言中我们经常使用的 printf 函数就是用于输出。但是 printf 函数的实现本身就十分复杂,如果我们的编译器要达到自举,就势必要实现 printf 之类的函数,但它又与编译器没有太大的联系,因此我们继续实现新的指令,从虚拟机的角度予以支持。 编译器中我们需要用到的函数有:exit, open, close, read, printf, malloc, memset 及 memcmp。代码如下: else if (op == EXIT) { printf("exit(%d)", *sp); return *sp;} else if (op == OPEN) { ax = open((char *)sp[1], sp[0]); } else if (op == CLOS) { ax = close(*sp);} else if (op == READ) { ax = read(sp[2], (char *)sp[1], *sp); } else if (op == PRTF) { tmp = sp + pc[1]; ax = printf((char *)tmp[-1], tmp[-2], tmp[-3], tmp[-4], tmp[-5], tmp[-6]); } else if (op == MALC) { ax = (int)malloc(*sp);} else if (op == MSET) { ax = (int)memset((char *)sp[2], sp[1], *sp);} else if (op == MCMP) { ax = memcmp((char *)sp[2], (char *)sp[1], *sp);} 这里的原理是,我们的电脑上已经有了这些函数的实现,因此编译编译器时,这些函数的二进制代码就被编译进了我们的编译器,因此在我们的编译器/虚拟机上运行我们提供的这些指令时,这些函数就是可用的。换句话说就是不需要我们自己去实现了。 最后再加上一个错误判断: else { printf("unknown instruction:%d\n", op); return -1; } 测试 下面我们用我们的汇编写一小段程序,来计算 10+20,在 main 函数中加入下列代码: int main(int argc, char *argv[]) { ax = 0; ... i = 0; text[i++] = IMM; text[i++] = 10; text[i++] = PUSH; text[i++] = IMM; text[i++] = 20; text[i++] = ADD; text[i++] = PUSH; text[i++] = EXIT; pc = text; ... program(); } 编译程序 gcc xc-tutor.c,运行程序:./a.out hello.c。输出 exit(30) 另外,我们的代码里有一些指针的强制转换,默认是 32 位的,因此在 64 位机器下,会出现 segmentation fault,解决方法(二选一): 编译时加上 -m32 参数:gcc -m32 xc-tutor.c 在代码的开头,增加 #define int long long,long long 是 64 位的,不会出现强制转换后的问题。 注意我们的之前的程序需要指令一个源文件,只是现在还用不着,但从结果可以看出,我们的虚拟机还是工作良好的。 小结 本章中我们回顾了计算机的内部运行原理,并仿照 x86 汇编指令设计并实现了我们自己的指令集。希望通过本章的学习,你能对计算机程序的原理有一定的了解,同时能对汇编语言有一定的概念,因为汇编语言就是 C 编译器的输出。 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-1 https://github.com/lotabout/write-a-C-interpreter 实际计算机中,添加一个新的指令需要设计许多新的电路,会增加许多的成本,但我们的虚拟机中,新的指令几乎不消耗资源,因此我们可以利用这一点,用更多的指令来完成更多的功能,从而简化具体的实现。 词法分析器 本章我们要讲解如何构建词法分析器。 什么是词法分析器 简而言之,词法分析器用于对源码字符串做预处理,以减少语法分析器的复杂程度。 词法分析器以源码字符串为输入,输出为标记流(token stream),即一连串的标记,每个标记通常包括: (token, token value) 即标记本身和标记的值。例如,源码中若包含一个数字 '998' ,词法分析器将输出 (Number, 998),即(数字,998)。再例如: 2 + 3 * (4 - 5) => (Number, 2) Add (Number, 3) Multiply Left-Bracket (Number, 4) Subtract (Number, 5) Right-Bracket 通过词法分析器的预处理,语法分析器的复杂度会大大降低,这点在后面的语法分析器我们就能体会。 词法分析器与编译器 要是深入词法分析器,你就会发现,它的本质上也是编译器。我们的编译器是以标记流为输入,输出汇编代码,而词法分析器则是以源码字符串为输入,输出标记流。 +-------+ +--------+ -- source code --> | lexer | --> token stream --> | parser | --> assembly +-------+ +--------+ 在这个前提下,我们可以这样认为:直接从源代码编译成汇编代码是很困难的,因为输入的字符串比较难处理。所以我们先编写一个较为简单的编译器(词法分析器)来将字符串转换成标记流,而标记流对于语法分析器而言就容易处理得多了。 词法分析器的实现 由于词法分析的工作很常见,但又枯燥且容易出错,所以人们已经开发出了许多工具来生成词法分析器,如 lex, flex。这些工具允许我们通过正则表达式来识别标记。 这里注意的是,我们并不会一次性地将所有源码全部转换成标记流,原因有二: 字符串转换成标记流有时是有状态的,即与代码的上下文是有关系的。 保存所有的标记流没有意义且浪费空间。 所以实际的处理方法是提供一个函数(即前几篇中提到的 next()),每次调用该函数则返回下一个标记。 支持的标记 在全局中添加如下定义: // tokens and classes (operators last and in precedence order) enum { Num = 128, Fun, Sys, Glo, Loc, Id, Char, Else, Enum, If, Int, Return, Sizeof, While, Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak }; 这些就是我们要支持的标记符。例如,我们会将 = 解析为 Assign;将 == 解析为 Eq;将 != 解析为 Ne 等等。 所以这里我们会有这样的印象,一个标记(token)可能包含多个字符,且多数情况下如此。而词法分析器能减小语法分析复杂度的原因,正是因为它相当于通过一定的编码(更多的标记)来压缩了源码字符串。 当然,上面这些标记是有顺序的,跟它们在 C 语言中的优先级有关,如 *(Mul) 的优先级就要高于 +(Add)。它们的具体使用在后面的语法分析中会提到。 最后要注意的是还有一些字符,它们自己就构成了标记,如右方括号 ] 或波浪号 ~ 等。我们不另外处理它们的原因是: 它们是单字符的,即并不是多个字符共同构成标记(如 == 需要两个字符); 它们不涉及优先级关系。 词法分析器的框架 即 next() 函数的主体: void next() { char *last_pos; int hash; while (token = *src) { ++src; // parse token here } return; } 这里的一个问题是,为什么要用 while 循环呢?这就涉及到编译器(记得我们说过词法分析器也是某种意义上的编译器)的一个问题:如何处理错误? 对词法分析器而言,若碰到了一个我们不认识的字符该怎么处理?一般处理的方法有两种: 指出错误发生的位置,并退出整个程序 指出错误发生的位置,跳过当前错误并继续编译 这个 while 循环的作用就是跳过这些我们不识别的字符,我们同时还用它来处理空白字符。我们知道,C 语言中空格是用来作为分隔用的,并不作为语法的一部分。因此在实现中我们将它作为“不识别”的字符,这个 while 循环可以用来跳过它。 换行符 换行符和空格类似,但有一点不同,每次遇到换行符,我们需要将当前的行号加一: // parse token here ... if (token == '\n') { ++line; } ... 宏定义 C 语言的宏定义以字符 # 开头,如 # include <stdio.h>。我们的编译器并不支持宏定义,所以直接跳过它们。 else if (token == '#') { // skip macro, because we will not support it while (*src != 0 && *src != '\n') { src++; } } 标识符与符号表 标识符(identifier)可以理解为变量名。对于语法分析而言,我们并不关心一个变量具体叫什么名字,而只关心这个变量名代表的唯一标识。例如 int a; 定义了变量 a,而之后的语句 a = 10,我们需要知道这两个 a 指向的是同一个变量。 基于这个理由,词法分析器会把扫描到的标识符全都保存到一张表中,遇到新的标识符就去查这张表,如果标识符已经存在,就返回它的唯一标识。 那么我们怎么表示标识符呢?如下: struct identifier { int token; int hash; char * name; int class; int type; int value; int Bclass; int Btype; int Bvalue; } 这里解释一下具体的含义: token:该标识符返回的标记,理论上所有的变量返回的标记都应该是 Id,但实际上由于我们还将在符号表中加入关键字如 if, while 等,它们都有对应的标记。 hash:顾名思义,就是这个标识符的哈希值,用于标识符的快速比较。 name:存放标识符本身的字符串。 class:该标识符的类别,如数字,全局变量或局部变量等。 type:标识符的类型,即如果它是个变量,变量是 int 型、char 型还是指针型。 value:存放这个标识符的值,如标识符是函数,刚存放函数的地址。 BXXXX:C 语言中标识符可以是全局的也可以是局部的,当局部标识符的名字与全局标识符相同时,用作保存全局标识符的信息。 由上可以看出,我们实现的词法分析器与传统意义上的词法分析器不太相同。传统意义上的符号表只需要知道标识符的唯一标识即可,而我们还存放了一些只有语法分析器才会得到的信息,如 type 。 由于我们的目标是能自举,而我们定义的语法不支持 struct,故而使用下列方式。 Symbol table: ----+-----+----+----+----+-----+-----+-----+------+------+---- .. |token|hash|name|type|class|value|btype|bclass|bvalue| .. ----+-----+----+----+----+-----+-----+-----+------+------+---- |<--- one single identifier --->| 即用一个整型数组来保存相关的ID信息。每个ID占用数组中的9个空间,分析标识符的相关代码如下: int token_val; // value of current token (mainly for number) int *current_id, // current parsed ID *symbols; // symbol table // fields of identifier enum {Token, Hash, Name, Type, Class, Value, BType, BClass, BValue, IdSize}; void next() { ... else if ((token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z') || (token == '_')) { // parse identifier last_pos = src - 1; hash = token; while ((*src >= 'a' && *src <= 'z') || (*src >= 'A' && *src <= 'Z') || (*src >= '0' && *src <= '9') || (*src == '_')) { hash = hash * 147 + *src; src++; } // look for existing identifier, linear search current_id = symbols; while (current_id[Token]) { if (current_id[Hash] == hash && !memcmp((char *)current_id[Name], last_pos, src - last_pos)) { //found one, return token = current_id[Token]; return; } current_id = current_id + IdSize; } // store new ID current_id[Name] = (int)last_pos; current_id[Hash] = hash; token = current_id[Token] = Id; return; } ... } 查找已有标识符的方法是线性查找 symbols 表。 数字 数字中较为复杂的一点是需要支持十进制、十六进制及八进制。逻辑也较为直接,可能唯一不好理解的是获取十六进制的值相关的代码。 token_val = token_val * 16 + (token & 15) + (token >= 'A' ? 9 : 0); 这里要注意的是在ASCII码中,字符a对应的十六进制值是 61, A是41,故通过 (token & 15) 可以得到个位数的值。其它就不多说了,这里这样写的目的是装B(其实是抄 c4 的源代码的)。 void next() { ... else if (token >= '0' && token <= '9') { // parse number, three kinds: dec(123) hex(0x123) oct(017) token_val = token - '0'; if (token_val > 0) { // dec, starts with [1-9] while (*src >= '0' && *src <= '9') { token_val = token_val*10 + *src++ - '0'; } } else { // starts with number 0 if (*src == 'x' || *src == 'X') { //hex token = *++src; while ((token >= '0' && token <= '9') || (token >= 'a' && token <= 'f') || (token >= 'A' && token <= 'F')) { token_val = token_val * 16 + (token & 15) + (token >= 'A' ? 9 : 0); token = *++src; } } else { // oct while (*src >= '0' && *src <= '7') { token_val = token_val*8 + *src++ - '0'; } } } token = Num; return; } ... } 字符串 在分析时,如果分析到字符串,我们需要将它存放到前一篇文章中说的 data 段中。然后返回它在 data 段中的地址。另一个特殊的地方是我们需要支持转义符。例如用 \n 表示换行符。由于本编译器的目的是达到自己编译自己,所以代码中并没有支持除 \n 的转义符,如 \t, \r 等,但仍支持 \a 表示字符 a 的语法,如 \" 表示 "。 在分析时,我们将同时分析单个字符如 'a' 和字符串如 "a string"。若得到的是单个字符,我们以 Num 的形式返回。相关代码如下: void next() { ... else if (token == '"' || token == '\'') { // parse string literal, currently, the only supported escape // character is '\n', store the string literal into data. last_pos = data; while (*src != 0 && *src != token) { token_val = *src++; if (token_val == '\\') { // escape character token_val = *src++; if (token_val == 'n') { token_val = '\n'; } } if (token == '"') { *data++ = token_val; } } src++; // if it is a single character, return Num token if (token == '"') { token_val = (int)last_pos; } else { token = Num; } return; } } 注释 在我们的 C 语言中,只支持 // 类型的注释,不支持 /* comments */ 的注释。 void next() { ... else if (token == '/') { if (*src == '/') { // skip comments while (*src != 0 && *src != '\n') { ++src; } } else { // divide operator token = Div; return; } } ... } 这里我们要额外介绍 lookahead 的概念,即提前看多个字符。上述代码中我们看到,除了跳过注释,我们还可能返回除号 /(Div) 标记。 提前看字符的原理是:有一个或多个标记是以同样的字符开头的(如本小节中的注释与除号),因此只凭当前的字符我们并无法确定具体应该解释成哪一个标记,所以只能再向前查看字符,如本例需向前查看一个字符,若是 / 则说明是注释,反之则是除号。 我们之前说过,词法分析器本质上也是编译器,其实提前看字符的概念也存在于编译器,只是这时就是提前看k个“标记”而不是“字符”了。平时听到的 LL(k) 中的 k 就是需要向前看的标记的个数了。 另外,我们用词法分析器将源码转换成标记流,能减小语法分析复杂度,原因之一就是减少了语法分析器需要“向前看”的字符个数。 其它 其它的标记的解析就相对容易一些了,我们直接贴上代码: void next() { ... else if (token == '=') { // parse '==' and '=' if (*src == '=') { src ++; token = Eq; } else { token = Assign; } return; } else if (token == '+') { // parse '+' and '++' if (*src == '+') { src ++; token = Inc; } else { token = Add; } return; } else if (token == '-') { // parse '-' and '--' if (*src == '-') { src ++; token = Dec; } else { token = Sub; } return; } else if (token == '!') { // parse '!=' if (*src == '=') { src++; token = Ne; } return; } else if (token == '<') { // parse '<=', '<<' or '<' if (*src == '=') { src ++; token = Le; } else if (*src == '<') { src ++; token = Shl; } else { token = Lt; } return; } else if (token == '>') { // parse '>=', '>>' or '>' if (*src == '=') { src ++; token = Ge; } else if (*src == '>') { src ++; token = Shr; } else { token = Gt; } return; } else if (token == '|') { // parse '|' or '||' if (*src == '|') { src ++; token = Lor; } else { token = Or; } return; } else if (token == '&') { // parse '&' and '&&' if (*src == '&') { src ++; token = Lan; } else { token = And; } return; } else if (token == '^') { token = Xor; return; } else if (token == '%') { token = Mod; return; } else if (token == '*') { token = Mul; return; } else if (token == '[') { token = Brak; return; } else if (token == '?') { token = Cond; return; } else if (token == '~' || token == ';' || token == '{' || token == '}' || token == '(' || token == ')' || token == ']' || token == ',' || token == ':') { // directly return the character as token; return; } ... } 代码较多,但主要逻辑就是向前看一个字符来确定真正的标记。 关键字与内置函数 虽然上面写完了词法分析器,但还有一个问题需要考虑,那就是“关键字”,例如 if, while, return 等。它们不能被作为普通的标识符,因为有特殊的含义。 一般有两种处理方法: 词法分析器中直接解析这些关键字。 在语法分析前将关键字提前加入符号表。 这里我们就采用第二种方法,将它们加入符号表,并提前为它们赋予必要的信息(还记得前面说的标识符 Token 字段吗?)。这样当源代码中出现关键字时,它们会被解析成标识符,但由于符号表中已经有了相关的信息,我们就能知道它们是特殊的关键字。 内置函数的行为也和关键字类似,不同的只是赋值的信息,在main函数中进行初始化如下: // types of variable/function enum { CHAR, INT, PTR }; int *idmain; // the `main` function void main() { ... src = "char else enum if int return sizeof while " "open read close printf malloc memset memcmp exit void main"; // add keywords to symbol table i = Char; while (i <= While) { next(); current_id[Token] = i++; } // add library to symbol table i = OPEN; while (i <= EXIT) { next(); current_id[Class] = Sys; current_id[Type] = INT; current_id[Value] = i++; } next(); current_id[Token] = Char; // handle void type next(); idmain = current_id; // keep track of main ... program(); } 代码 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-2 https://github.com/lotabout/write-a-C-interpreter 上面的代码运行后会出现 ‘Segmentation Falt’,这是正常的,因为它会尝试运行我们上一章创建的虚拟机,但其中并没有任何汇编代码。 小结 本章我们为我们的编译器构建了词法分析器,通过本章的学习,我认为有几个要点需要强调: 词法分析器的作用是对源码字符串进行预处理,作用是减小语法分析器的复杂程度。 词法分析器本身可以认为是一个编译器,输入是源码,输出是标记流。 lookahead(k) 的概念,即向前看 k 个字符或标记。 词法分析中如何处理标识符与符号表。 下一章中,我们将介绍递归下降的语法分析器。我们下一章见。 递归下降 本章我们将讲解递归下降的方法,并用它完成一个基本的四则运算的语法分析器。 什么是递归下降 传统上,编写语法分析器有两种方法,一种是自顶向下,一种是自底向上。自顶向下是从起始非终结符开始,不断地对非终结符进行分解,直到匹配输入的终结符;自底向上是不断地将终结符进行合并,直到合并成起始的非终结符。 其中的自顶向下方法就是我们所说的递归下降。 终结符与非终结符 没有学过编译原理的话可能并不知道什么是“终结符”,“非终结符”。这里我简单介绍一下。首先是 BNF 范式,就是一种用来描述语法的语言,例如,四则运算的规则可以表示如下: <expr> ::= <expr> + <term> | <expr> - <term> | <term> <term> ::= <term> * <factor> | <term> / <factor> | <factor> <factor> ::= ( <expr> ) | Num 用尖括号 <> 括起来的就称作 非终结符 ,因为它们可以用 ::= 右侧的式子代替。| 表示选择,如 <expr> 可以是 <expr> + <term>、<expr> - <term>或 <term> 中的一种。而没有出现在::=左边的就称作 终结符 ,一般终结符对应于词法分析器输出的标记。 四则运算的递归下降 例如,我们对 3 * (4 + 2) 进行语法分析。我们假设词法分析器已经正确地将其中的数字识别成了标记 Num。 递归下降是从起始的非终结符开始(顶),本例中是 <expr>,实际中可以自己指定,不指定的话一般认为是第一个出现的非终结符。 1. <expr> => <expr> 2. => <term> * <factor> 3. => <factor> | 4. => Num (3) | 5. => ( <expr> ) 6. => <expr> + <term> 7. => <term> | 8. => <factor> | 9. => Num (4) | 10. => <factor> 11. => Num (2) 可以看到,整个解析的过程是在不断对非终结符进行替换(向下),直到遇见了终结符(底)。而我们可以从解析的过程中看出,一些非终结符如<expr>被递归地使用了。 为什么选择递归下降 从上小节对四则运算的递归下降解析可以看出,整个解析的过程和语法的 BNF 表示是十分接近的,更为重要的是,我们可以很容易地直接将 BNF 表示转换成实际的代码。方法是为每个产生式(即 非终结符 ::= ...)生成一个同名的函数。 这里会有一个疑问,就是上例中,当一个终结符有多个选择时,如何确定具体选择哪一个?如为什么用 <expr> ::= <term> * <factor> 而不是 <expr> ::= <term> / <factor> ?这就用到了上一章中提到的“向前看 k 个标记”的概念了。我们向前看一个标记,发现是 *,而这个标记足够让我们确定用哪个表达式了。 另外,递归下下降方法对 BNF 方法本身有一定的要求,否则会有一些问题,如经典的“左递归”问题。 左递归 原则上我们是不讲这么深入,但我们上面的四则运算的文法就是左递归的,而左递归的语法是没法直接使用递归下降的方法实现的。因此我们要消除左递归,消除后的文法如下: <expr> ::= <term> <expr_tail> <expr_tail> ::= + <term> <expr_tail> | - <term> <expr_tail> | <empty> <term> ::= <factor> <term_tail> <term_tail> ::= * <factor> <term_tail> | / <factor> <term_tail> | <empty> <factor> ::= ( <expr> ) | Num 消除左递归的相关方法,这里不再多说,请自行查阅相关的资料。 四则运算的实现 本节中我们专注语法分析器部分的实现,具体实现很容易,我们直接贴上代码,就是上述的消除左递归后的文法直接转换而来的: int expr(); int factor() { int value = 0; if (token == '(') { match('('); value = expr(); match(')'); } else { value = token_val; match(Num); } return value; } int term_tail(int lvalue) { if (token == '*') { match('*'); int value = lvalue * factor(); return term_tail(value); } else if (token == '/') { match('/'); int value = lvalue / factor(); return term_tail(value); } else { return lvalue; } } int term() { int lvalue = factor(); return term_tail(lvalue); } int expr_tail(int lvalue) { if (token == '+') { match('+'); int value = lvalue + term(); return expr_tail(value); } else if (token == '-') { match('-'); int value = lvalue - term(); return expr_tail(value); } else { return lvalue; } } int expr() { int lvalue = term(); return expr_tail(lvalue); } 可以看到,有了BNF方法后,采用递归向下的方法来实现编译器是很直观的。 我们把词法分析器的代码一并贴上: ##include <stdio.h> ##include <stdlib.h> enum {Num}; int token; int token_val; char *line = NULL; char *src = NULL; void next() { // skip white space while (*src == ' ' || *src == '\t') { src ++; } token = *src++; if (token >= '0' && token <= '9' ) { token_val = token - '0'; token = Num; while (*src >= '0' && *src <= '9') { token_val = token_val*10 + *src - '0'; src ++; } return; } } void match(int tk) { if (token != tk) { printf("expected token: %d(%c), got: %d(%c)\n", tk, tk, token, token); exit(-1); } next(); } 最后是main函数: int main(int argc, char *argv[]) { size_t linecap = 0; ssize_t linelen; while ((linelen = getline(&line, &linecap, stdin)) > 0) { src = line; next(); printf("%d\n", expr()); } return 0; } 小结 本章中我们介绍了递归下降的方法,并用它来实现了四则运算的语法分析器。 花这么大精力讲解递归下降方法,是因为几乎所有手工编写的语法分析器都或多或少地有它的影子。换句话说,掌握了递归下降的方法,就可以应付大多数的语法分析器编写。 同时我们也用实例看到了理论(BNF 语法,左递归的消除)是如何帮助我们的工程实现的。尽管理论不是必需的,但如果能掌握它,对于提高我们的水平还是很有帮助的。 变量定义 本章中我们用 EBNF 来大致描述我们实现的 C 语言的文法,并实现其中解析变量定义部分。 由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定义、函数定义、表达式。 EBNF 表示 EBNF 是对前一章提到的 BNF 的扩展,它的语法更容易理解,实现起来也更直观。但真正看起来还是很烦,如果不想看可以跳过。 program ::= {global_declaration}+ global_declaration ::= enum_decl | variable_decl | function_decl enum_decl ::= 'enum' [id] '{' id ['=' 'num'] {',' id ['=' 'num'] '}' variable_decl ::= type {'*'} id { ',' {'*'} id } ';' function_decl ::= type {'*'} id '(' parameter_decl ')' '{' body_decl '}' parameter_decl ::= type {'*'} id {',' type {'*'} id} body_decl ::= {variable_decl}, {statement} statement ::= non_empty_statement | empty_statement non_empty_statement ::= if_statement | while_statement | '{' statement '}' | 'return' expression | expression ';' if_statement ::= 'if' '(' expression ')' statement ['else' non_empty_statement] while_statement ::= 'while' '(' expression ')' non_empty_statement 其中 expression 相关的内容我们放到后面解释,主要原因是我们的语言不支持跨函数递归,而为了实现自举,实际上我们也不能使用递归(亏我们说了一章的递归下降)。 P.S. 我是先写程序再总结上面的文法,所以实际上它们间的对应关系并不是特别明显。 解析变量的定义 本章要讲解的就是上节文法中的 enum_decl 和 variable_decl 部分。 program() 首先是之前定义过的 program 函数,将它改成: void program() { // get next token next(); while (token > 0) { global_declaration(); } } 我知道 global_declaration 函数还没有出现过,但没有关系,采用自顶向下的编写方法就是要不断地实现我们需要的内容。下面是 global_declaration 函数的内容: global_declaration() 即全局的定义语句,包括变量定义,类型定义(只支持枚举)及函数定义。代码如下: int basetype; // the type of a declaration, make it global for convenience int expr_type; // the type of an expression void global_declaration() { // global_declaration ::= enum_decl | variable_decl | function_decl // // enum_decl ::= 'enum' [id] '{' id ['=' 'num'] {',' id ['=' 'num'} '}' // // variable_decl ::= type {'*'} id { ',' {'*'} id } ';' // // function_decl ::= type {'*'} id '(' parameter_decl ')' '{' body_decl '}' int type; // tmp, actual type for variable int i; // tmp basetype = INT; // parse enum, this should be treated alone. if (token == Enum) { // enum [id] { a = 10, b = 20, ... } match(Enum); if (token != '{') { match(Id); // skip the [id] part } if (token == '{') { // parse the assign part match('{'); enum_declaration(); match('}'); } match(';'); return; } // parse type information if (token == Int) { match(Int); } else if (token == Char) { match(Char); basetype = CHAR; } // parse the comma seperated variable declaration. while (token != ';' && token != '}') { type = basetype; // parse pointer type, note that there may exist `int ****x;` while (token == Mul) { match(Mul); type = type + PTR; } if (token != Id) { // invalid declaration printf("%d: bad global declaration\n", line); exit(-1); } if (current_id[Class]) { // identifier exists printf("%d: duplicate global declaration\n", line); exit(-1); } match(Id); current_id[Type] = type; if (token == '(') { current_id[Class] = Fun; current_id[Value] = (int)(text + 1); // the memory address of function function_declaration(); } else { // variable declaration current_id[Class] = Glo; // global variable current_id[Value] = (int)data; // assign memory address data = data + sizeof(int); } if (token == ',') { match(','); } } next(); } 看了上面的代码,能大概理解吗?这里我们讲解其中的一些细节。 向前看标记 :其中的 if (token == xxx) 语句就是用来向前查看标记以确定使用哪一个产生式,例如只要遇到 enum 我们就知道是需要解析枚举类型。而如果只解析到类型,如 int identifier 时我们并不能确定 identifier 是一个普通的变量还是一个函数,所以还需要继续查看后续的标记,如果遇到 ( 则可以断定是函数了,反之则是变量。 变量类型的表示 :我们的编译器支持指针类型,那意味着也支持指针的指针,如 int **data;。那么我们如何表示指针类型呢?前文中我们定义了支持的类型: // types of variable/function enum { CHAR, INT, PTR }; 所以一个类型首先有基本类型,如 CHAR 或 INT,当它是一个指向基本类型的指针时,如 int *data,我们就将它的类型加上 PTR 即代码中的:type = type + PTR;。同理,如果是指针的指针,则再加上 PTR。 enum_declaration() 用于解析枚举类型的定义。主要的逻辑用于解析用逗号(,)分隔的变量,值得注意的是在编译器中如何保存枚举变量的信息。 即我们将该变量的类别设置成了 Num,这样它就成了全局的常量了,而注意到上节中,正常的全局变量的类别则是 Glo,类别信息在后面章节中解析 expression 会使用到。 void enum_declaration() { // parse enum [id] { a = 1, b = 3, ...} int i; i = 0; while (token != '}') { if (token != Id) { printf("%d: bad enum identifier %d\n", line, token); exit(-1); } next(); if (token == Assign) { // like {a=10} next(); if (token != Num) { printf("%d: bad enum initializer\n", line); exit(-1); } i = token_val; next(); } current_id[Class] = Num; current_id[Type] = INT; current_id[Value] = i++; if (token == ',') { next(); } } } 其它 其中的 function_declaration 函数我们将放到下一章中讲解。match 函数是一个辅助函数: void match(int tk) { if (token == tk) { next(); } else { printf("%d: expected token: %d\n", line, tk); exit(-1); } } 它将 next 函数包装起来,如果不是预期的标记则报错并退出。 代码 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-3 https://github.com/lotabout/write-a-C-interpreter 本章的代码还无法正常运行,因为还有许多功能没有实现,但如果有兴趣的话,可以自己先试着去实现它。 小结 本章的内容应该不难,除了开头的 EBNF 表达式可能相对不好理解一些,但如果你查看了 EBNF 的具体表示方法后就不难理解了。 剩下的内容就是按部就班地将 EBNF 的产生式转换成函数的过程,如果你理解了上一章中的内容,相信这部分也不难理解。 下一章中我们将介绍如何解析函数的定义,敬请期待。 函数定义 由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定义、函数定义、表达式。本章讲解函数定义相关的内容。 EBNF 表示 这是上一章的 EBNF 方法中与函数定义相关的内容。 variable_decl ::= type {'*'} id { ',' {'*'} id } ';' function_decl ::= type {'*'} id '(' parameter_decl ')' '{' body_decl '}' parameter_decl ::= type {'*'} id {',' type {'*'} id} body_decl ::= {variable_decl}, {statement} statement ::= non_empty_statement | empty_statement non_empty_statement ::= if_statement | while_statement | '{' statement '}' | 'return' expression | expression ';' if_statement ::= 'if' '(' expression ')' statement ['else' non_empty_statement] while_statement ::= 'while' '(' expression ')' non_empty_statement 解析函数的定义 上一章的代码中,我们已经知道了什么时候开始解析函数的定义,相关的代码如下: ... if (token == '(') { current_id[Class] = Fun; current_id[Value] = (int)(text + 1); // the memory address of function function_declaration(); } else { ... 即在这断代码之前,我们已经为当前的标识符(identifier)设置了正确的类型,上面这断代码为当前的标识符设置了正确的类别(Fun),以及该函数在代码段(text segment)中的位置。接下来开始解析函数定义相关的内容:parameter_decl 及 body_decl。 函数参数与汇编代码 现在我们要回忆如何将“函数”转换成对应的汇编代码,因为这决定了在解析时我们需要哪些相关的信息。考虑下列函数: int demo(int param_a, int *param_b) { int local_1; char local_2; ... } 那么它应该被转换成什么样的汇编代码呢?在思考这个问题之前,我们需要了解当 demo函数被调用时,计算机的栈的状态,如下(参照第三章讲解的虚拟机): | .... | high address +---------------+ | arg: param_a | new_bp + 3 +---------------+ | arg: param_b | new_bp + 2 +---------------+ |return address | new_bp + 1 +---------------+ | old BP | <- new BP +---------------+ | local_1 | new_bp - 1 +---------------+ | local_2 | new_bp - 2 +---------------+ | .... | low address 这里最为重要的一点是,无论是函数的参数(如 param_a)还是函数的局部变量(如 local_1)都是存放在计算机的 栈 上的。因此,与存放在 数据段 中的全局变量不同,在函数内访问它们是通过 new_bp 指针和对应的位移量进行的。因此,在解析的过程中,我们需要知道参数的个数,各个参数的位移量。 函数定义的解析 这相当于是整个函数定义的语法解析的框架,代码如下: void function_declaration() { // type func_name (...) {...} // | this part match('('); function_parameter(); match(')'); match('{'); function_body(); //match('}'); // ① // ② // unwind local variable declarations for all local variables. current_id = symbols; while (current_id[Token]) { if (current_id[Class] == Loc) { current_id[Class] = current_id[BClass]; current_id[Type] = current_id[BType]; current_id[Value] = current_id[BValue]; } current_id = current_id + IdSize; } } 其中①中我们没有消耗最后的}字符。这么做的原因是:variable_decl 与 function_decl 是放在一起解析的,而 variable_decl 是以字符 ; 结束的。而 function_decl 是以字符 } 结束的,若在此通过 match 消耗了 ‘;’ 字符,那么外层的 while 循环就没法准确地知道函数定义已经结束。所以我们将结束符的解析放在了外层的 while 循环中。 而②中的代码是用于将符号表中的信息恢复成全局的信息。这是因为,局部变量是可以和全局变量同名的,一旦同名,在函数体内局部变量就会覆盖全局变量,出了函数体,全局变量就恢复了原先的作用。这段代码线性地遍历所有标识符,并将保存在 BXXX 中的信息还原。 解析参数 parameter_decl ::= type {'*'} id {',' type {'*'} id} 解析函数的参数就是解析以逗号分隔的一个个标识符,同时记录它们的位置与类型。 int index_of_bp; // index of bp pointer on stack void function_parameter() { int type; int params; params = 0; while (token != ')') { // ① // int name, ... type = INT; if (token == Int) { match(Int); } else if (token == Char) { type = CHAR; match(Char); } // pointer type while (token == Mul) { match(Mul); type = type + PTR; } // parameter name if (token != Id) { printf("%d: bad parameter declaration\n", line); exit(-1); } if (current_id[Class] == Loc) { printf("%d: duplicate parameter declaration\n", line); exit(-1); } match(Id); //② // store the local variable current_id[BClass] = current_id[Class]; current_id[Class] = Loc; current_id[BType] = current_id[Type]; current_id[Type] = type; current_id[BValue] = current_id[Value]; current_id[Value] = params++; // index of current parameter if (token == ',') { match(','); } } // ③ index_of_bp = params+1; } 其中①与全局变量定义的解析十分一样,用于解析该参数的类型。 而②则与上节中提到的“局部变量覆盖全局变量”相关,先将全局变量的信息保存(无论是是否真的在全局中用到了这个变量)在 BXXX 中,再赋上局部变量相关的信息,如 Value 中存放的是参数的位置(是第几个参数)。 ③则与汇编代码的生成有关,index_of_bp 就是前文提到的 new_bp 的位置。 函数体的解析 我们实现的 C 语言与现代的 C 语言不太一致,我们需要所有的变量定义出现在所有的语句之前。函数体的代码如下: void function_body() { // type func_name (...) {...} // -->| |<-- // ... { // 1. local declarations // 2. statements // } int pos_local; // position of local variables on the stack. int type; pos_local = index_of_bp; // ① while (token == Int || token == Char) { // local variable declaration, just like global ones. basetype = (token == Int) ? INT : CHAR; match(token); while (token != ';') { type = basetype; while (token == Mul) { match(Mul); type = type + PTR; } if (token != Id) { // invalid declaration printf("%d: bad local declaration\n", line); exit(-1); } if (current_id[Class] == Loc) { // identifier exists printf("%d: duplicate local declaration\n", line); exit(-1); } match(Id); // store the local variable current_id[BClass] = current_id[Class]; current_id[Class] = Loc; current_id[BType] = current_id[Type]; current_id[Type] = type; current_id[BValue] = current_id[Value]; current_id[Value] = ++pos_local; // index of current parameter if (token == ',') { match(','); } } match(';'); } // ② // save the stack size for local variables *++text = ENT; *++text = pos_local - index_of_bp; // statements while (token != '}') { statement(); } // emit code for leaving the sub function *++text = LEV; } 其中①用于解析函数体内的局部变量的定义,代码与全局的变量定义几乎一样。 而②则用于生成汇编代码,我们在第三章的虚拟机中提到过,我们需要在栈上为局部变量预留空间,这两行代码起的就是这个作用。 代码 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-4 https://github.com/lotabout/write-a-C-interpreter 本章的代码依旧无法运行,还有两个重要函数没有完成:statement 及 expression,感兴趣的话可以尝试自己实现它们。 小结 本章中我们用了不多的代码完成了函数定义的解析。大部分的代码依旧是用于解析变量:参数和局部变量,而它们的逻辑和全局变量的解析几乎一致,最大的区别就是保存的信息不同。 当然,要理解函数定义的解析过程,最重要的是理解我们会为函数生成怎样的汇编代码,因为这决定了我们需要从解析中获取什么样的信息(例如参数的位置,个数等),而这些可能需要你重新回顾一下“虚拟机”这一章,或是重新学习学习汇编相关的知识。 下一章中我们将讲解语句的解析,敬请期待。 语句 整个编译器还剩下最后两个部分:语句和表达式的解析。它们的内容比较多,主要涉及如何将语句和表达式编译成汇编代码。这章讲解语句的解析,相对于表达式来说它还是较为容易的。 语句 C 语言区分“语句”(statement)和“表达式”(expression)两个概念。简单地说,可以认为语句就是表达式加上末尾的分号。 在我们的编译器中共识别 6 种语句: if (...) <statement> [else <statement>] while (...) <statement> { <statement> } return xxx; <empty statement>; expression; (expression end with semicolon) 它们的语法分析都相对容易,重要的是去理解如何将这些语句编译成汇编代码,下面我们逐一解释。 IF 语句 IF 语句的作用是跳转,跟据条件表达式决定跳转的位置。我们看看下面的伪代码: if (...) <statement> [else <statement>] if (<cond>) <cond> JZ a <true_statement> ===> <true_statement> else: JMP b a: a: <false_statement> <false_statement> b: b: 对应的汇编代码流程为: 执行条件表达式 <cond>。 如果条件失败,则跳转到 a 的位置,执行 else 语句。这里 else 语句是可以省略的,此时 a 和 b 都指向 IF 语句后方的代码。 因为汇编代码是顺序排列的,所以如果执行了 true_statement,为了防止因为顺序排列而执行了 false_statement,所以需要无条件跳转 JMP b。 对应的 C 代码如下: if (token == If) { match(If); match('('); expression(Assign); // parse condition match(')'); *++text = JZ; b = ++text; statement(); // parse statement if (token == Else) { // parse else match(Else); // emit code for JMP B *b = (int)(text + 3); *++text = JMP; b = ++text; statement(); } *b = (int)(text + 1); } While 语句 While 语句比 If 语句简单,它对应的汇编代码如下: a: a: while (<cond>) <cond> JZ b <statement> <statement> JMP a b: b: 没有什么值得说明的内容,它的 C 代码如下: else if (token == While) { match(While); a = text + 1; match('('); expression(Assign); match(')'); *++text = JZ; b = ++text; statement(); *++text = JMP; *++text = (int)a; *b = (int)(text + 1); } Return 语句 Return 唯一特殊的地方是:一旦遇到了 Return 语句,则意味着函数要退出了,所以需要生成汇编代码 LEV 来表示退出。 else if (token == Return) { // return [expression]; match(Return); if (token != ';') { expression(Assign); } match(';'); // emit code for return *++text = LEV; } 其它语句 其它语句并不直接生成汇编代码,所以不多做说明,代码如下: else if (token == '{') { // { <statement> ... } match('{'); while (token != '}') { statement(); } match('}'); } else if (token == ';') { // empty statement match(';'); } else { // a = b; or function_call(); expression(Assign); match(';'); } 代码 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-5 https://github.com/lotabout/write-a-C-interpreter 本章的代码依旧无法运行,还剩最后一部分没有完成:expression。 小结 本章讲解了如何将语句编译成汇编代码,内容相对容易一些,关键就是去理解汇编代码的执行原理。 同时值得一提的是,编译器的语法分析部分其实是很简单的,而真正的难点是如何在语法分析时收集足够多的信息,最终把源代码转换成目标代码(汇编)。我认为这也是初学者实现编译器的一大难点,往往比词法分析/语法分析更困难。 所以建议如果没有学过汇编,可以学习学习,它本身不难,但对理解计算机的原理有很大帮助。 表达式 这是整个编译器的最后一部分,解析表达式。什么是表达式?表达式是将各种语言要素的一个组合,用来求值。例如:函数调用、变量赋值、运算符运算等等。 表达式的解析难点有二:一是运算符的优先级问题,二是如何将表达式编译成目标代码。我们就来逐一说明。 运算符的优先级 运算符的优先级决定了表达式的运算顺序,如在普通的四则运算中,乘法 * 优先级高于加法 +,这就意味着表达式 2 + 3 * 4 的实际运行顺序是 2 + (3 * 4) 而不是 (2 + 3) * 4。 C 语言定义了各种表达式的优先级,可以参考 C 语言运算符优先级。 传统的编程书籍会用“逆波兰式”实现四则运算来讲解优先级问题。实际上,优先级关心的就是哪个运算符先计算,哪个运算符后计算(毕竟叫做“优先级”嘛)。而这就意味着我们需要决定先为哪个运算符生成目标代码(汇编),因为汇编代码是顺序排列的,我们必须先计算优先级高的运算符。 那么如何确定运算符的优先级呢?答曰:栈(递归调用的实质也是栈的处理)。 举一个例子:2 + 3 - 4 * 5,它的运算顺序是这样的: 将 2 入栈 遇到运算符 +,入栈,此时我们期待的是+的另一个参数 遇到数字 3,原则上我们需要立即计算 2+3的值,但我们不确定数字 3 是否属于优先级更高的运算符,所以先将它入栈。 遇到运算符 -,它的优先级和 + 相同,此时判断参数 3 属于这前的 +。将运算符 + 出栈,并将之前的 2 和 3 出栈,计算 2+3 的结果,得到 5 入栈。同时将运算符 - 入栈。 遇到数字4,同样不能确定是否能立即计算,入栈 遇到运算符 * 优先级大于 -,入栈 遇到数字5,依旧不能确定是否立即计算,入栈 表达式结束,运算符出栈,为 *,将参数出栈,计算 4*5 得到结果 20 入栈。 运算符出栈,为 -,将参数出栈,计算 5-20,得到 -15 入栈。 此时运算符栈为空,因此得到结果 -15。 // after step 1, 2 | | +------+ | 3 | | | +------+ +------+ | 2 | | + | +------+ +------+ // after step 4 | | | | +------+ +------+ | 5 | | - | +------+ +------+ // after step 7 | | +------+ | 5 | +------+ +------+ | 4 | | * | +------+ +------+ | 5 | | - | +------+ +------+ 综上,在计算一个运算符‘x’之前,必须先查看它的右方,找出并计算所有优先级大于‘x’的运算符,之后再计算运算符‘x’。 最后注意的是优先通常只与多元运算符相关,单元运算符往往没有这个问题(因为只有一个参数)。也可以认为“优先级”的实质就是两个运算符在抢参数。 一元运算符 上节中说到了运算符的优先级,也提到了优先级一般只与多元运算符有关,这也意味着一元运算符的优先级总是高于多元运算符。因为我们需要先对它们进行解析。 当然,这部分也将同时解析参数本身(如变量、数字、字符串等等)。 关于表达式的解析,与语法分析相关的部分就是上文所说的优先级问题了,而剩下的较难较烦的部分是与目标代码的生成有关的。因此对于需要讲解的运算符,我们主要从它的目标代码入手。 常量 首先是数字,用 IMM 指令将它加载到 AX 中即可: if (token == Num) { match(Num); // emit code *++text = IMM; *++text = token_val; expr_type = INT; } 接着是字符串常量。它比较特殊的一点是 C 语言的字符串常量支持如下风格: char *p; p = "first line" "second line"; 即跨行的字符串拼接,它相当于: char *p; p = "first linesecond line"; 所以解析的时候要注意这一点: else if (token == '"') { // emit code *++text = IMM; *++text = token_val; match('"'); // store the rest strings while (token == '"') { match('"'); } // append the end of string character '\0', all the data are default // to 0, so just move data one position forward. data = (char *)(((int)data + sizeof(int)) & (-sizeof(int))); expr_type = PTR; } sizeof sizeof 是一个一元运算符,我们需要知道后面参数的类型,类型的解析在前面的文章中我们已经很熟悉了。 else if (token == Sizeof) { // sizeof is actually an unary operator // now only `sizeof(int)`, `sizeof(char)` and `sizeof(*...)` are // supported. match(Sizeof); match('('); expr_type = INT; if (token == Int) { match(Int); } else if (token == Char) { match(Char); expr_type = CHAR; } while (token == Mul) { match(Mul); expr_type = expr_type + PTR; } match(')'); // emit code *++text = IMM; *++text = (expr_type == CHAR) ? sizeof(char) : sizeof(int); expr_type = INT; } 注意的是只支持 sizeof(int),sizeof(char) 及 sizeof(pointer type...)。并且它的结果是 int 型。 变量与函数调用 由于取变量的值与函数的调用都是以 Id 标记开头的,因此将它们放在一起处理。 else if (token == Id) { // there are several type when occurs to Id // but this is unit, so it can only be // 1. function call // 2. Enum variable // 3. global/local variable match(Id); id = current_id; if (token == '(') { // function call match('('); // ① // pass in arguments tmp = 0; // number of arguments while (token != ')') { expression(Assign); *++text = PUSH; tmp ++; if (token == ',') { match(','); } } match(')'); // ② // emit code if (id[Class] == Sys) { // system functions *++text = id[Value]; } else if (id[Class] == Fun) { // function call *++text = CALL; *++text = id[Value]; } else { printf("%d: bad function call\n", line); exit(-1); } // ③ // clean the stack for arguments if (tmp > 0) { *++text = ADJ; *++text = tmp; } expr_type = id[Type]; } else if (id[Class] == Num) { // ④ // enum variable *++text = IMM; *++text = id[Value]; expr_type = INT; } else { // ⑤ // variable if (id[Class] == Loc) { *++text = LEA; *++text = index_of_bp - id[Value]; } else if (id[Class] == Glo) { *++text = IMM; *++text = id[Value]; } else { printf("%d: undefined variable\n", line); exit(-1); } //⑥ // emit code, default behaviour is to load the value of the // address which is stored in `ax` expr_type = id[Type]; *++text = (expr_type == Char) ? LC : LI; } } ①中注意我们是顺序将参数入栈,这和第三章:虚拟机中讲解的指令是对应的。与之不同,标准 C 是逆序将参数入栈的。 ②中判断函数的类型,同样在第三章:“虚拟机”中我们介绍过内置函数的支持,如 printf, read, malloc 等等。内置函数有对应的汇编指令,而普通的函数则编译成 CALL <addr> 的形式。 ③用于清除入栈的参数。因为我们不在乎出栈的值,所以直接修改栈指针的大小即可。 ④:当该标识符是全局定义的枚举类型时,直接将对应的值用 IMM 指令存入 AX 即可。 ⑤则是用于加载变量的值,如果是局部变量则采用与 bp 指针相对位置的形式(参见第 7章函数定义)。而如果是全局变量则用 IMM 加载变量的地址。 ⑥:无论是全局还是局部变量,最终都根据它们的类型用 LC 或 LI 指令加载对应的值。 关于变量,你可能有疑问,如果遇到标识符就用 LC/LI 载入相应的值,那诸如 a[10] 之类的表达式要如何实现呢?后面我们会看到,根据标识符后的运算符,我们可能会修改或删除现有的 LC/LI 指令。 强制转换 虽然我们前面没有提到,但我们一直用 expr_type 来保存一个表达式的类型,强制转换的作用是获取转换的类型,并直接修改 expr_type 的值。 else if (token == '(') { // cast or parenthesis match('('); if (token == Int || token == Char) { tmp = (token == Char) ? CHAR : INT; // cast type match(token); while (token == Mul) { match(Mul); tmp = tmp + PTR; } match(')'); expression(Inc); // cast has precedence as Inc(++) expr_type = tmp; } else { // normal parenthesis expression(Assign); match(')'); } } 指针取值 诸如 *a 的指针取值,关键是判断 a 的类型,而就像上节中提到的,当一个表达式解析结束时,它的类型保存在变量 expr_type 中。 else if (token == Mul) { // dereference *<addr> match(Mul); expression(Inc); // dereference has the same precedence as Inc(++) if (expr_type >= PTR) { expr_type = expr_type - PTR; } else { printf("%d: bad dereference\n", line); exit(-1); } *++text = (expr_type == CHAR) ? LC : LI; } 取址操作 这里我们就能看到“变量与函数调用”一节中所说的修改或删除 LC/LI 指令了。前文中我们说到,对于变量,我们会先加载它的地址,并根据它们类型使用 LC/LI 指令加载实际内容,例如对变量 a: IMM <addr> LI 那么对变量 a 取址,其实只要不执行 LC/LI 即可。因此我们删除相应的指令。 else if (token == And) { // get the address of match(And); expression(Inc); // get the address of if (*text == LC || *text == LI) { text --; } else { printf("%d: bad address of\n", line); exit(-1); } expr_type = expr_type + PTR; } 逻辑取反 我们没有直接的逻辑取反指令,因此我们判断它是否与数字 0 相等。而数字 0 代表了逻辑 “False”。 else if (token == '!') { // not match('!'); expression(Inc); // emit code, use <expr> == 0 *++text = PUSH; *++text = IMM; *++text = 0; *++text = EQ; expr_type = INT; } 按位取反 同样我们没有相应的指令,所以我们用异或来实现,即 ~a = a ^ 0xFFFF。 else if (token == '~') { // bitwise not match('~'); expression(Inc); // emit code, use <expr> XOR -1 *++text = PUSH; *++text = IMM; *++text = -1; *++text = XOR; expr_type = INT; } 正负号 注意这里并不是四则运算中的加减法,而是单个数字的取正取负操作。同样,我们没有取负的操作,用 0 - x 来实现 -x。 else if (token == Add) { // +var, do nothing match(Add); expression(Inc); expr_type = INT; } else if (token == Sub) { // -var match(Sub); if (token == Num) { *++text = IMM; *++text = -token_val; match(Num); } else { *++text = IMM; *++text = -1; *++text = PUSH; expression(Inc); *++text = MUL; } expr_type = INT; } 自增自减 注意的是自增自减操作的优先级是和它的位置有关的。如 ++p 的优先级高于 p++,这里我们解析的就是类似 ++p 的操作。 else if (token == Inc || token == Dec) { tmp = token; match(token); expression(Inc); // ① if (*text == LC) { *text = PUSH; // to duplicate the address *++text = LC; } else if (*text == LI) { *text = PUSH; *++text = LI; } else { printf("%d: bad lvalue of pre-increment\n", line); exit(-1); } *++text = PUSH; *++text = IMM; // ② *++text = (expr_type > PTR) ? sizeof(int) : sizeof(char); *++text = (tmp == Inc) ? ADD : SUB; *++text = (expr_type == CHAR) ? SC : SI; } 对应的汇编代码也比较直观,只是在实现 ++p时,我们要使用变量 p 的地址两次,所以我们需要先 PUSH (①)。 ②则是因为自增自减操作还需要处理是指针的情形。 二元运算符 这里,我们需要处理多运算符的优先级问题,就如前文的“优先级”一节提到的,我们需要不断地向右扫描,直到遇到优先级 小于 当前优先级的运算符。 回想起我们之前定义过的各个标记,它们是以优先级从低到高排列的,即 Assign 的优先级最低,而 Brak([) 的优先级最高。 enum { Num = 128, Fun, Sys, Glo, Loc, Id, Char, Else, Enum, If, Int, Return, Sizeof, While, Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak }; 所以,当我们调用 expression(level) 进行解析的时候,我们其实通过了参数 level 指定了当前的优先级。在前文的一元运算符处理中也用到了这一点。 所以,此时的二元运算符的解析的框架为: while (token >= level) { // parse token for binary operator and postfix operator } 解决了优先级的问题,让我们继续讲解如何把运算符编译成汇编代码吧。 赋值操作 赋值操作是优先级最低的运算符。考虑诸如 a = (expession) 的表达式,在解析 = 之前,我们已经为变量 a 生成了如下的汇编代码: IMM <addr> LC/LI 当解析完=右边的表达式后,相应的值会存放在 ax 中,此时,为了实际将这个值保存起来,我们需要类似下面的汇编代码: IMM <addr> PUSH SC/SI 明白了这点,也就能理解下面的源代码了: tmp = expr_type; if (token == Assign) { // var = expr; match(Assign); if (*text == LC || *text == LI) { *text = PUSH; // save the lvalue's pointer } else { printf("%d: bad lvalue in assignment\n", line); exit(-1); } expression(Assign); expr_type = tmp; *++text = (expr_type == CHAR) ? SC : SI; } 三目运算符 这是 C 语言中唯一的一个三元运算符: ? :,它相当于一个小型的 If 语句,所以生成的代码也类似于 If 语句,这里就不多作解释。 else if (token == Cond) { // expr ? a : b; match(Cond); *++text = JZ; addr = ++text; expression(Assign); if (token == ':') { match(':'); } else { printf("%d: missing colon in conditional\n", line); exit(-1); } *addr = (int)(text + 3); *++text = JMP; addr = ++text; expression(Cond); *addr = (int)(text + 1); } 逻辑运算符 这包括 || 和 &&。它们对应的汇编代码如下: <expr1> || <expr2> <expr1> && <expr2> ...<expr1>... ...<expr1>... JNZ b JZ b ...<expr2>... ...<expr2>... b: b: 所以源码如下: else if (token == Lor) { // logic or match(Lor); *++text = JNZ; addr = ++text; expression(Lan); *addr = (int)(text + 1); expr_type = INT; } else if (token == Lan) { // logic and match(Lan); *++text = JZ; addr = ++text; expression(Or); *addr = (int)(text + 1); expr_type = INT; } 数学运算符 它们包括 |, ^, &, ==, != <=, >=, <, >, <<, >>, +, -, *, /, %。它们的实现都很类似,我们以异或 ^ 为例: <expr1> ^ <expr2> ...<expr1>... <- now the result is on ax PUSH ...<expr2>... <- now the value of <expr2> is on ax XOR 所以它对应的代码为: else if (token == Xor) { // bitwise xor match(Xor); *++text = PUSH; expression(And); *++text = XOR; expr_type = INT; } 其它的我们便不再详述。但这当中还有一个问题,就是指针的加减。在 C 语言中,指针加上数值等于将指针移位,且根据不同的类型移动的位移不同。如 a + 1,如果 a 是 char * 型,则移动一字节,而如果 a 是 int * 型,则移动 4 个字节(32位系统)。 另外,在作指针减法时,如果是两个指针相减(相同类型),则结果是两个指针间隔的元素个数。因此要有特殊的处理。 下面以加法为例,对应的汇编代码为: <expr1> + <expr2> normal pointer <expr1> <expr1> PUSH PUSH <expr2> <expr2> | ADD PUSH | <expr2> * <unit> IMM <unit> | MUL | ADD 即当 <expr1> 是指针时,要根据它的类型放大 <expr2> 的值,因此对应的源码如下: else if (token == Add) { // add match(Add); *++text = PUSH; expression(Mul); expr_type = tmp; if (expr_type > PTR) { // pointer type, and not `char *` *++text = PUSH; *++text = IMM; *++text = sizeof(int); *++text = MUL; } *++text = ADD; } 相应的减法的代码就不贴了,可以自己实现看看,也可以看文末给出的链接。 自增自减 这次是后缀形式的,即 p++ 或 p--。与前缀形式不同的是,在执行自增自减后, ax上需要保留原来的值。所以我们首先执行类似前缀自增自减的操作,再将 ax 中的值执行减/增的操作。 // 前缀形式 生成汇编代码 *++text = PUSH; *++text = IMM; *++text = (expr_type > PTR) ? sizeof(int) : sizeof(char); *++text = (tmp == Inc) ? ADD : SUB; *++text = (expr_type == CHAR) ? SC : SI; // 后缀形式 生成汇编代码 *++text = PUSH; *++text = IMM; *++text = (expr_type > PTR) ? sizeof(int) : sizeof(char); *++text = (token == Inc) ? ADD : SUB; *++text = (expr_type == CHAR) ? SC : SI; *++text = PUSH; // *++text = IMM; // 执行相反的增/减操作 *++text = (expr_type > PTR) ? sizeof(int) : sizeof(char); // *++text = (token == Inc) ? SUB : ADD; // 数组取值操作 在学习 C 语言的时候你可能已经知道了,诸如 a[10] 的操作等价于 *(a + 10)。因此我们要做的就是生成类似的汇编代码: else if (token == Brak) { // array access var[xx] match(Brak); *++text = PUSH; expression(Assign); match(']'); if (tmp > PTR) { // pointer, `not char *` *++text = PUSH; *++text = IMM; *++text = sizeof(int); *++text = MUL; } else if (tmp < PTR) { printf("%d: pointer type expected\n", line); exit(-1); } expr_type = tmp - PTR; *++text = ADD; *++text = (expr_type == CHAR) ? LC : LI; } 代码 除了上述对表达式的解析外,我们还需要初始化虚拟机的栈,我们可以正确调用 main 函数,且当 main 函数结束时退出进程。 int *tmp; // setup stack sp = (int *)((int)stack + poolsize); *--sp = EXIT; // call exit if main returns *--sp = PUSH; tmp = sp; *--sp = argc; *--sp = (int)argv; *--sp = (int)tmp; 当然,最后要注意的一点是:所有的变量定义必须放在语句之前。 本章的代码可以在 Github 上下载,也可以直接 clone git clone -b step-6 https://github.com/lotabout/write-a-C-interpreter 通过 gcc -o xc-tutor xc-tutor.c 进行编译。并执行 ./xc-tutor hello.c 查看结果。 正如我们保证的那样,我们的代码是自举的,能自己编译自己,所以你可以执行 ./xc-tutor xc-tutor.c hello.c。可以看到和之前有同样的输出。 小结 本章我们进行了最后的解析,解析表达式。本章有两个难点: 如何通过递归调用 expression 来实现运算符的优先级。 如何为每个运算符生成对应的汇编代码。 尽管代码看起来比较简单(虽然多),但其中用到的原理还是需要仔细推敲的。 最后,恭喜你!通过一步步的学习,自己实现了一个C语言的编译器(好吧,是解释器)。 总结 恭喜你完成了自己的 C 语言编译器,本章中我们发一发牢骚,说一说编写编译器值得注意的一些问题;编写编译器时遇到的一些难题。 虚拟机与目标代码 整个系列的一开始,我们就着手虚拟机的实现。不知道你是否有同感,这部分对于整个编译器的编写其实是十分重要的。我认为至少占了重要程度的50%。 这里要说明这样一个观点,学习编译原理时常常着眼于词法分析和语法分析,而忽略了同样重要的代码生成。对于学习或考试而言或许可以,但实际编译项目时,最为重要的是能“跑起来”,所以我们需要给予代码生成高度的重视。 同时我们也看到,在后期解析语句和表达式时,难点已经不再是语法分析了,而是如何为运算符生成相应的汇编代码。 词法分析 我们用了很暴力的手段编写了我们的词法分析器,我认为这并无不可。 但你依旧可以学习相关的知识,了解自动生成词法分析器的原理,它涉及到了“正则表达式”,“状态机”等等知识。相信这部分的知识能够很大程度上提高你的编程水平。 同时,如果今后你仍然想编写编译器,不妨试试这些自动生成工具。 语法分析 长期以来,语法分析对我而言一直是迷一样的存在,直到真正用递归下降的方式实现了一个。 我们用了专门的一章讲解了“递归下降”与 BNF 文法的关系。希望能减少你对理论的厌恶。至少,实现起来并不是太难。 如果有兴趣,可以学习学习这些文法,因为已经有许多自动生成的工具支持它们。这样你就不需要重复造轮子。可以看看 yacc 等工具,更先进的版本是 bsion。同时其它语言也有许多类似的支持。 题外话,最近知道了一个叫“PEG 文法”的表示方法,无论是读起来,还是实现起来,都比 BNF 要容易,你也可以学习看看。 关于编代码 这也是我自己的感慨吧。无论多好的教程,想要完全理解它,最好的方式恐怕还是要自己实现它。 只是在编写代码的过程中,我们会遇到许多的挫折,例如需要考虑许多细节,或是调试起来十分困难。但也只有真正静下心来去克服它,我们才能有所成长吧。 例如在编写表达式的解析时,大量重复的代码特别让人崩溃。还有就是调试编译器,简直痛苦地无话可说。 P.S. 如果你按这个系列自己编写代码,记得事先写一些用于输出汇编代码的函数,很有帮助的。 还有就是写这个系列的文章,开始的冲动过了之后,每写一篇都特别心烦,希望文章本身没有受我的这种情绪影响吧。 结语 编程有趣又无趣,只有身在其中的我们才能体会吧。 参考 Github write-a-C-interpreter 编辑整理 手把手教你构建 C 语言编译器 相关书籍 30天自制操作系统 我最近在读这本书 书名: 30天自制操作系统 作者: [日]川合秀实 出版年份: 2012-8 评分: 8.3 自制编译器 见字如晤 书名: 自制编译器 作者: [日]青木峰郎 出版年份: 2016-6 评分: 7.9 自制搜索引擎 见字如晤 书名: 自制搜索引擎 作者: [日]山田浩之 出版年份: 2016-1 评分: 7.6 自己动手实现Lua 见字如晤 书名: 自己动手实现Lua 作者: 张秀宏 出版年份: 2018-1-1 评分: 9.1 两周自制脚本语言 见字如晤 书名: 两周自制脚本语言 作者: [日]千叶滋 出版年份: 2014-6 评分: 8.4 自制编程语言 见字如晤 书名: 自制编程语言 作者: [日]前桥和弥 出版年份: 2013-11 评分: 8.1 CPU自制入门 见字如晤 书名: CPU自制入门 作者: [日]水头一寿 出版年份: 2014-1 评分: 7.8 Orange’S:一个操作系统的实现 我最近在读这本书 书名: Orange'S:一个操作系统的实现 作者: 于渊 出版年份: 2009-6 评分: 8.8 Linux内核完全注释 见字如晤 书名: Linux内核完全注释 作者: 赵炯 出版年份: 2005-8 评分: 8.5 相关仓库 相关文章 如何编写Linux驱动 本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标! 3G,4G,Wifi选型需求分析及技术简介 详细介绍了3G,4G,wifi技术类型,选型,移植,性能介绍全过程。写了好多年了,禁止转载,第一次公开发表。 海思MPP&UNF构架源代码级分析 行业中分析海思MPP内核构架,源码分析,多年经验总结积累结果。写了好多年了,禁止转载,第一次公开发表。 如何实现自己的操作系统 作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库! 手把手教你构建 C 语言编译器 “手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。 系列教程 全部文章RSS订阅 系统编程系列 如何实现自己的操作系统 手把手教你构建 C 语言编译器 如何编写Linux驱动? 海思MPP&UNF构架源代码级分析 使用 Shell 脚本实现一个简单 Docker Github build-your-own-x 系列

2022/7/27
articleCard.readMore

什么才是真正的知识与智慧?

现代人都可以说是学富五车,阅读量远超孔子,那么是否现代人就比孔子聪明了?没那个傻缺敢这么吹吧!那么,什么才是真正的知识与智慧了? 什么才是聪明? 不好理解什么是聪明,那么,我们先来找个聪明人,看看聪明人有什么特点! 老子,孔子可以说是聪明吧! 他们有什么成果流传于世了? 没错,就是《论语》《道德经》,能写出这种作品的人,没有那个大骗子敢说这两老爷子不聪明吧。 知识与聪明 很多人把技能,知识储量当作聪明,这其实是不对的。 读书读到博士,只能说明知识储量高,但是智慧不一定高。 一个受过基本教育的现代人,就阅读量,知识储备来说,知识量远不止学富五车,学富五十车,五百车都不止。 但是,有谁能写出《论语》《道德经》这样的集智慧之大成做? 学不出来这种作品,你能说比孔子,老子聪明? 没那个骗子敢这么大言不惭吧! 那么,什么才是真正的智慧了?到底什么才是聪明真正的评价标准? 机器学习与聪明 为了更好的理解和解释智慧,这里用机器学习三要素来类比聪明程度。 机器学习评价 聪明评价 算力(cpu频率,某个特定算法专用硬件加速器,cache,内存大小等的综合评价。在某个算法算力高,在另一种算法算力低是很常见的。) 个人精力,专注力,在某一特定学科领域处理速度的综合表现。一种综合概念,经过长时间学习,训练形成的在某一特定领域解决问题的能力,包括速度,准确性等。 算法(解决问题的逻辑思路,不同算法自建性能,速度可以差距几个,甚至几十个数量级) 智慧,处理各种知识,技能的能力。偏向哲学概念,天才真正是在这里突出。可以说是天分,后天很难增加。 数据(被标注的数据) 知识储量,技能数量。剋有后天学习积累,只要肯花时间,可以积累巨量的知识。知识量足够多,但是处理知识的智慧不够时,我们称呼这种人为书呆子! 科学与聪明 经过前一个章节的对比,我们可以知道,智慧更多的是一个哲学方面的概念。而科学更多的是一个对现实世界认识的知识量储备! 科技发达,不代表智慧高! 智慧高,也不代表科技发达! 中国过去几千年,智慧成果有《道德经》《论语》《孙子兵法》等等,都是远超时代的智慧结晶,领先世界几千年! 近代西方几百年,科学成果超越才超越中国,但论社会智慧成果,连两千多年前的中国都比不上。 盎克鲁撒克逊国家只是海盗穿上了西服,但本质上还是海盗,几千年一直没变。 教育的目的是培养技能工人,而不是教你赚钱! 知识在哪里 最前沿的知识都在行业顶尖大佬的老子里面,只通过口耳相传 书本的知识一般至少落后行业10年以上 论文的知识一般落后行业一年以上 入门一门知识最好的方式还是章节全面的书本,碎片化的学习没法掌握一门新技能 知识也分三六九等 第一等叫天机,只在对顶尖一小嘬人中流传,比如某些帝王术 第二等叫真传,传内不传外,你还需要深度学习才能掌握 第三等叫技术,某门手艺活,大学普及教育的都只能算技术 第四等叫常识,基础教育教你的东西 第五等叫鸡汤,奶头乐麻木你的东西,成功学,抖音教你的都是这类鸡汤 总结 聪明,智慧,知识是三个不同角度的评判标准。 知识储量 + 处理知识的技巧和方法 + 特定领域的专注钻研 才是真正的聪明!

2022/7/2
articleCard.readMore

RSS的使用与Tiny Tiny RSS Selfhost自建

RSS 是对你信任的网站的订阅,微博是对你信任的人的订阅,即刻是对你感兴趣的话题的订阅。 RSS 的介绍 维基百科zh.wikipedia.org/wiki/RSS RSS(简易信息聚合)是一种消息来源格式规范,用以聚合经常发布更新数据的网站,例如博客文章、新闻、音频或视频的网摘。RSS文件(或称做摘要、网络摘要、或频更新,提供到频道)包含全文或是节录的文字,再加上发布者所订阅之网摘数据和授权的元数据。 社交媒体混乱的时间线、聚合阅读工具烦人的算法推荐,都让我们无法高效地获取需要的信息。RSS 将信息的选择权交还给了用户,但 RSS 并不是什么新玩意,20多年前就有了。RSS可以让我们高效的获取感兴趣的信息。 互联网的信息是庞杂的,甚至可以说是无限的,随着我们关注量的上升,我们关注的内容会越来越多,可能每天要去打开几十几百个网站或APP。手机里的有些 APP,收藏夹里的某些网站,也许就是为了看一小部分的内容,但是我们不得不装上它。通过 RSS 我们就可以将它们聚合在一起,还免受广告和追踪的困扰。也许对于一些内容还有即时推送的要求,有些网站和APP可能并没有推送,但是我们又需要即时收到推送(比如停水通知),这时如果通过 RSS 联动 IFTTT 便可以做到即时推送。可见 RSS 可以有提高信息获取效率、时效性高、便于管理、无广告等优点。 RSS工具 RSSHub RSSHub docs 万物皆可 RSS RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇怪怪的内容生成 RSS 订阅源 移动端可以使用 App RSSBud (iOS) 与 RSSAid (Android) 制作 在使用一段时间后你可能会发现有很多网站和想订阅的内容没有提供 RSS,因为 RSS 不利于投放广告、收集数据等商业行为,越来越多的网站不再提供 RSS,甚至还反爬虫。幸好,我们还有 RSSHub 项目(反爬严格的网站也需要自建,RSSHub 文档有自建教程)。RSSHub 项目由 DIYgod 发起,经过许多开发者一年多的活跃开发,现在已经支持很多网站的 RSS 输出。具体支持那些网站可以查阅文档。 RSSHub Radar RSSHub 项目,作者开发了相应的浏览器插件 – RSSHub Radar。浏览器插件可以帮助你快速发现和订阅当前网站 RSS ,RSSHub 项目网站上也提供了很多可以直接拿来用的方式,例如订阅 B 站某 UP 主的投稿等,具体的请参看 https://docs.rsshub.app/social-media.html 后食用。 Tiny Tiny RSS 可以Selfhost部署的RSS聚合客户端,支持多用户注册。 FEEDX FEEDX 是一个个人站,主打一些网站的全文 RSS,但质量上乘,没有 RSS 的话留言站长也会考虑做 RSS。 与其他 APP 联动 IFTTT IFTTT,是一个新生的网络服务平台,通过其他不同平台的条件来决定是否执行下一条命令。即对网络服务通过其他网络服务作出反应。IFTTT得名为其口号“if this then that”。 维基百科zh.wikipedia.org/wiki/IFTTT IFTTT 是一款可玩性很高的软件,其中便包含着 RSS Feed(有简单的关键词过滤功能),可以做到停水通知(×××有更新…)发送邮件或通知等功能。 Telegram bot Telegram 是一款国外的即时通讯聊天工具,除了加密、简洁流畅、跨平台、消息记录永久保存等优点外,我最喜欢的还是 Telegram bot 的功能。Telegram 里有各种各样的 bot,可以满足许多的需求,比如 十分钟邮箱、油管下载、听歌等 bot,RSS 订阅 bot 也十分多(IFTTT 同样有 Telegram bot)。这里就推荐一款最近才出现在眼前的 RSS bot:flowerss bot。优点是可以将 RSS 内容转换成 telegraph 来支持 Telegram 的应用内 instant view(即时预览用过的都说好!),还可以为 Group 和 Channel 订阅 RSS 消息。支持 Docker 部署。 RSS 也许还有更多有趣好玩的方式,期待更多的骚操作被广大网友发现 Tiny Tiny RSS Selfhost 搭建 搭建要求 一台服务器(我是 Debian 10,以它为例),能连上外网最好 知道 Linux 基本命令 安装方式 传统方式安装,通过 git clone 的方式安装 TTRSS,这种方式安装比较慢,而且难度比较大,这里不介绍这种方式,如果有兴趣的话可以去官方 wiki 瞅瞅。 Docker 安装,可以将 Docker 看作 虚拟机,但是又有占用小、启动快等优点,这里采用的是 @HenryQW 的通过 docker-compose 部署。戳这里查看文档。 开始安装 安装 Docker 首先升级系统到最新 apt update && apt upgrade 可以选择使用一键脚本安装 Docker,优点是方便快速,缺点是有可能不稳定,如果使用此方法运行下面的命令后跳过后面的步骤直接到下一步。想一步步安装的请无视。 curl https://get.docker.com/ | sh 然后安装一些软件包使 apt 支持 https apt install \ apt-transport-https \ ca-certificates \ curl \ gnupg2 \ software-properties-common 添加 Docker 官方的 GPG 密钥 curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - 添加 Docker CE 稳定版的库(nightly、test 版本可通过替换 stable 实现),这里是 amd64 架构的,其他架构自行替换。 sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/debian \ $(lsb_release -cs) \ stable" 接下来更新 apt 包索引 apt update 安装最新的 Docker CE 和 containerd(非必选) apt install docker-ce docker-ce-cli containerd.io 测试 docker 是否安装成功 docker run hello-world 将 Docker 加入开机自启 systemctl enable docker 安装 docker-compose 安装 docker-compose 最新版的命令可以在这里查看:https://github.com/docker/compose/releases 通过 docker-compose 部署 下载 docker-compose.yml 至任意目录或者新建 docker-compose.yml 拷贝我的内容进去。 注意事项: 包含了:TTRSS、PostgreSQL、Mercury Parser API、OpenCC API 四个镜像,后面两个为可选项,可以安装也可以不安装。 请务必更改 postgres 用户密码。 默认通过 181 端口访问 TTRSS, 默认账户:admin 密码:password,请第一时间更改。 docker-compose.yml version: '3' services: database.postgres: image: postgres:alpine container_name: postgres restart: always environment: - PG_PASSWORD=password # 务必修改密码! - DB_EXTENSION=pg_trgm volumes: - ./postgres/data/:/var/lib/postgresql/ # 将数据库数据保存到当前目录的 postgres/data/ 文件夹中 service.rss: image: wangqiru/ttrss:latest container_name: ttrss restart: always ports: - 181:80 environment: - SELF_URL_PATH=http://localhost:181/ # 更改为你自己的域名或者 IP! - DB_HOST=database.postgres # 数据库地址 - DB_PORT=5432 # 数据库端口 - DB_NAME=ttrss # 数据库名称 - DB_USER=postgres # 数据库用户名 - DB_PASS=password # 务必修改密码(应与上面修改的密码相同) - ENABLE_PLUGINS=auth_internal,fever # 在系统层面启用的插件名称(为所有用户启用),auth_internal 为必选 stdin_open: true tty: true command: sh -c 'sh /wait-for.sh database.postgres:5432 -- php /configure-db.php && exec s6-svscan /etc/s6/' service.mercury: # 在插件页 API 地址填写 `service.mercury:3000` 启用插件 image: wangqiru/mercury-parser-api:latest container_name: mercury restart: always expose: - 3000 service.opencc: # 在插件页 API 地址填写 `service.opencc:3000` 启用插件 image: wangqiru/opencc-api-server:latest container_name: opencc restart: always environment: - NODE_ENV=production expose: - 3000 支持的环境变量列表: SELF_URL_PATH: TTRSS 实例地址 DB_HOST: 数据库地址 DB_PORT: 数据库端口 DB_NAME: 数据库名字 DB_USER: 数据库用户名 DB_PASS: 数据库密码 ENABLE_PLUGINS: 在系统层面启用的插件名称,其中 auth_internal 为必须启用的登录插件 SESSION_COOKIE_LIFETIME: 使用网页版登陆时 cookie 过期时间,单位为小时,默认为 24 小时 修改完成后在同目录下运行 docker-compose up -d 等待部署完成即可。此时通过域名(域名需解析到这个 VPS)或 ip 加刚刚设置的端口已经可以开始使用 TTRSS 了,出来登录的界面后先去改个密码,然后来开启 HTTPS 访问。 Tips: TTRSS是每日构建,有时候构建出来的镜像没法使用,还不如固定一个Docker版本 配置 HTTPS 首先安装 nginx 并将其加入开机自启: apt install nginx systemctl enable nginx 然后编写 ttrss 反向代理配置文件 新建 /etc/nginx/conf.d/ttrss.conf 并将一下内容写入,注意替换域名。 nano /etc/nginx/conf.d/ttrss.conf /etc/nginx/conf.d/ttrss.conf upstream ttrssdev { server 127.0.0.1:181; } server { listen 80; server_name youdomain.com; #return 301 https://youdomain.com$request_uri; #rewrite ^(.*)$ https://$host$1 permanent; } server { listen 443 ssl; gzip on; server_name youdomain.com; access_log /var/log/nginx/ttrssdev_access.log combined; error_log /var/log/nginx/ttrssdev_error.log; location / { proxy_redirect off; proxy_pass http://ttrssdev; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Frame-Options SAMEORIGIN; client_max_body_size 100m; client_body_buffer_size 128k; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } } 然后使用 nginx -t 查看有无错误,没有错误后使用 nginx -s reload 重启 Nginx 服务。此时使用域名或 ip 应该可以直接访问了,不过这时还是 http。 然后使用 Let’s Encrypt 官方推荐的 Certbot 获取免费的 SSL 证书。 打开 Certbot 说明 后选择 Nginx 和运行的系统后就可以查看官方详细地说明,跟着做一遍就好了。 有证书之后再再访问我们的 TTRSS 服务器令人喜爱的小绿锁是不是就出来呢(可能需要重启 Nginx 服务)。 到这个界面就算是告一段落了,撒花! TTRSS 插件 Mercury 全文获取 Mercury 全文获取插件需要配合单独的 Mercury Parser API 服务器使用,docker-compose 部署方式已经包含 HenryQW/mercury-parser-api 服务器。 设置步骤: 首先去 TTRSS 的偏好设置中开启 Mercury。 再在设置中填写 mercury 容器的地址。 再右键点击源选择编辑信息源,在插件中对这个源开启插件。 OpenCC 繁简转换 OpenCC 是一个开源的简繁转换项目,需要配合单独的 Mercury Parser API 服务器使用,docker-compose 部署方式已经包含 HenryQW/OpenCC.henry.wang 服务器。 再在设置中填写刚刚查看的 Opencc 容器的地址。 备注:t2s为繁体转简体,其他的转换方式如下: s2t: Simplified Chinese to Traditional Chinese 简体到繁体 t2s: Traditional Chinese to Simplified Chinese 繁体到简体 s2tw: Simplified Chinese to Traditional Chinese (Taiwan Standard) 简体到台湾正体 tw2s: Traditional Chinese (Taiwan Standard) to Simplified Chinese 台湾正体到简体 s2hk: Simplified Chinese to Traditional Chinese (Hong Kong Standard) 简体到香港繁体(香港小学学习字词表标准) hk2s: Traditional Chinese (Hong Kong Standard) to Simplified Chinese 香港繁体(香港小学学习字词表标准)到简体 s2twp: Simplified Chinese to Traditional Chinese (Taiwan Standard) with Taiwanese idiom 简体到繁体(台湾正体标准)并转换为台湾常用词汇 tw2sp: Traditional Chinese (Taiwan Standard) to Simplified Chinese with Mainland Chinese idiom 繁体(台湾正体标准)到简体并转换为中国大陆常用词汇 t2tw: Traditional Chinese (OpenCC Standard) to Taiwan Standard 繁体(OpenCC 标准)到台湾正体 t2hk: Traditional Chinese (OpenCC Standard) to Hong Kong Standard 繁体(OpenCC 标准)到香港繁体(香港小学学习字词表标准) 这个插件同样需要去订阅源的编辑源信息中开启。 Fever API 提供 Fever API 支持,对于使用 Reeder 的用户十分有用。该插件默认作为系统插件启用。 首先在设置中启用 API 然后在插件中设置 Fever API 密码 在支持 Fever 的阅读器使用 https://youdomain.com/plugins/fever/ 作为服务器地址,使用刚刚设置的密码登录。由于该插件使用未加盐的 MD5 加密密码进行通信,强烈建议使用应用专用密码并开启 HTTPS。 最终效果 把你感兴趣的RSS订阅了,甚至可以作为一个更加高效的私有搜索引擎来使用! 个人独立博客是博文质量最高的搜索文章来源! Docker compose 安装 添加支持了中文搜索 Github postgres-chinese-textsearch DockerHub postgres-chinese-textsearch version: "3" services: service.rss: image: bloodstar/ttrss:latest container_name: ttrss ports: - 181:80 environment: - SELF_URL_PATH=http://localhost:181/ # please change to your own domain - DB_HOST=database.postgres - DB_PORT=5432 - DB_NAME=ttrss - DB_USER=postgres - DB_PASS=ttrss # please change the password - PUID=1000 - PGID=1000 - TEXTSEARCH_EXTENSION=pg_jieba # add support for chinese fulltext search (pg_jieba, zhparser, or both two) volumes: - feed-icons:/var/www/feed-icons/ networks: - public_access - service_only - database_only stdin_open: true tty: true restart: always service.mercury: # set Mercury Parser API endpoint to `service.mercury:3000` on TTRSS plugin setting page image: wangqiru/mercury-parser-api:latest container_name: mercury networks: - public_access - service_only restart: always service.opencc: # set OpenCC API endpoint to `service.opencc:3000` on TTRSS plugin setting page image: wangqiru/opencc-api-server:latest container_name: opencc environment: - NODE_ENV=production networks: - service_only restart: always # database.postgres: # image: postgres:13-alpine # container_name: postgres # environment: # - POSTGRES_PASSWORD=ttrss # feel free to change the password # volumes: # - ~/postgres/data/:/var/lib/postgresql/data # persist postgres data to ~/postgres/data/ on the host # networks: # - database_only # restart: always database.postgres: image: bloodstar/postgres-chinese-textsearch:latest container_name: postgres environment: - POSTGRES_PASSWORD=ttrss # please change the password volumes: - ~/postgres/data/:/var/lib/postgresql/data # persist postgres data to ~/postgres/data/ on the host restart: always # utility.watchtower: # container_name: watchtower # image: containrrr/watchtower:latest # volumes: # - /var/run/docker.sock:/var/run/docker.sock # environment: # - WATCHTOWER_CLEANUP=true # - WATCHTOWER_POLL_INTERVAL=86400 # restart: always volumes: feed-icons: networks: public_access: # Provide the access for ttrss UI service_only: # Provide the communication network between services only internal: true database_only: # Provide the communication between ttrss and database only internal: true 网络订阅平台 各种原因没法自己搭建私有订阅,那么还有一些免费平台可以选择。只是都有各种限制! 在聚合搜索平台查找感兴趣的订阅源,使用私有订阅工具订阅,是最佳体验! QQ 邮箱 很多人可能没怎么用过,但 QQ 邮箱订阅 rss 做的还不错 wordpress https://wordpress.com/read feedly http://feedly.com/ 一些订阅源推荐 最优质的文章来源应该是一些独立站点的博客了,其它还有微信公众号,Telegram频道,Bilibili,Youtube,少数派、知乎、V2EX等平台 中文博客列表导航项目 中文独立博客列表 中文独立博客文章聚合搜索 RSS Source | RSS订阅源推荐 RSSHub RSS Feed 收录 weekend-project-space/top-rss-list Feed 免费 RSS 订阅源 · Feed 提供免费的 RSS 订阅源,支持微信公众号,通过 Hamibot 可扩展支持任意 APP。 RSS 订阅源整理 一些法律相关信息的 RSS 订阅地址 播客 RSS Feed ?RSS 源共享 | Trello Rss-IT: 这个项目记录了个人订阅的一些科技人的Blog地址,欢迎大家推荐,一起来完善! 中文Newsletter导航 (notion.so) alaskasquirrel/Email-newsletter-RSS: 邮箱 ? newsletter RSS 荟萃 News (github.com) chasays/newsletter-list: 有趣,免费的 newsletter,欢迎推荐 (github.com) 中文Newsletter导航 (notion.so) AlleyRead - 重塑你的信息源 参考 RSS使用心得 TTRSS搭建教程 Installing on a host machine Installation Guide 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2022/5/31
articleCard.readMore

如何做好竞品分析

竞品分析可以帮助我们更好地找准自身产品定位,发现自己产品的优劣所在,进而推动产品的优化迭代。 Tips:友情提示,部分内容RSS输出获取不到,请跳转到源网页地址浏览全文! 如何做好竞品分析?竞品分析的六大维度 一、为什么做竞品分析? 1.知己知彼百战百胜 2.为自身的产品设计提供功能、可用性、关键技术等方面的参考 3.提高自身产品的差异化程度 4.降低风险 二、如何选择竞品? 1.寻找行业内领先的榜样产品(取其精华) 2.类似于自己的产品(竞争关系最大) 3.有潜力的竞品(存活原因) 三、如何做竞品调研? 1.市场分析:了解产业和行业的运作模式、所处环境和市场数据,便于筛选目标市场 2.用户分析:了解目标市场中全部用户的分层及画像,便于筛选目标用户 3.产品分析:了解开发生命周期中的差异 4.产品调研:了解产品生命周期中的差异 5.用户运营:了解产品中存量用户的细分,便于精细化运营 6.用户调研:了解用户的体验和评价 7.竞品分析:从产品背后看企业,了解竞争者的资源配置情况 四、竞品分析的基本思路 1.分析目的有哪些? 2.分析对象有哪些? 3.分析角度有哪些? 4.竞品信息的来源有哪些? 5.竞品信息的处理流程有哪些? 6.分析方法有哪些? 7.结论如何呈现? 五、竞品分析的模型方法 1.PEST分析模型 2.STP理论 3.波特五力模型 4.波士顿矩阵分析 5.用户体验五要素 6.APPEALS模型 7.SWOT分析法 六、竞品分析报告模板 1.分析目的:为什么做分析报告 2.确定竞品:分析了哪些、产品形态、产品版本、体验环境 3.竞品分析:战略定位、目标用户、商业模式、运营策略、产品功能及设计、市场推广、盈利模式 4.复盘总结:优缺点总结、结论、趋势预测 参考 如何做好竞品分析 附赠 钱学森《论系统工程》 钱学森诞辰110周年:重读经典,钱学森《论系统工程》笔记摘要 钱老从中国传统哲学角度出发,把工业企业运行分为人、物、事三类要素。“人”就是组织、岗位和人员;“物”就是产品、设备等;“事”就是事物运转的流程。与国外的TOGAF建模方法不同,钱老说的模型太接地气了,中国人一听就懂。 以下是钱老的原文,大家可以一起学习下: 就一个工厂甚至任何一个环节而言,都由下列人、物、事三类要素组成。其中“人”当然是第一要素;物包括三个要素即:物资(能源、原料、半成品、成品等),设备(土木建筑、机电设备、工具仪表等)和财(工资、流动资金等);事包括两个要素:任务的推进(上级所下达的任务或与其他单位所订的合约)与信息的传递(数据、图纸、报表、规章、决策等等)。从历史上一个个体劳动者泥瓦匠的工作开始,就包含这六个要素。 人、物资、设备、财、任务和信息这六个要素,都要满足一定的制约,一是经济规律的制约,一是技术条件的制约。进行经营管理首先要认识这种制约,并从而能动地求得在制约下的系统的最优运转。通过六个要素,把一个复杂的生产体系组织管理好,需要科学,即所谓经营科学。从历史上一个个体劳动者泥瓦匠的工作开始,就包含这六个要素。那时人当然是有的,不过是个体;砖瓦木料便是物资;斧锯瓦刀是设备;钱当然是个因素,任务指标是明确的;至于信息可能全部都存放在泥瓦匠这个人的头脑中。在现代的大工厂中,还是这六种要素,只不过规模空前地扩大。在工厂这个整系统中,各分系统之间的相互作用和相互依赖的关系,就凭这六个要素的流通而得以体现。 中国为什么没有自己的编程语言?哲学、数学和语言学基础是关键 钱老的物、事、人的理论是生根于中国历史文化中,有着具有中国特色的世界观和价值观,这也是中国哲学的基础研究问题。所以非常容易被东方文化人群所接受,每一个中国人都很容易理解物、事和人的划分,这就为理论应用奠定了基础。 系列教程 全部文章RSS订阅 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2022/5/30
articleCard.readMore

中西医的优缺点

中医西医谁更科学,总是争论不休,这里说说个人的一些看法,中西医都是非科学,都只是经验科学,各有各自的优缺点 中医治疗调理费用低,见效慢,但是把人体作为整体调理,治疗疾病的根本原因。西医通过药物提取,化学合成,见效快,但是有耐药性,常常头痛医头,脚痛医脚,哪里有问题,就切除哪里。 中医西医都是非科学 按照现代科学定义,中医西医都非1+1=2这样类似数学的严格意义上面的科学。都只是经验科学! 西医和中医分歧某种程度上可以看成是还原论和整体论之争: 西医把人体看做一个一个器官组成,什么地方出问题,就解决什么地方的问题,头疼医头,脚痛医脚。F{a+b} = f{a} +f{(b) 中医把人体看做一个整体,讲究阴阳平衡,脉络的畅通,你头痛,不光是头的问题,,而是整体出现的失衡,中医调理平衡,头疼就医好了。 还原论(Reductionism)是一种哲学和科学方法论,主张复杂系统和现象可以通过分解为更简单、更基本的组成部分来理解。具体到医学领域,还原论认为生物学和医学的复杂问题可以通过研究其分子、细胞或生物化学基础来解释和解决。 整体论(Holism)是一种哲学和科学方法论,与还原论相对立。整体论强调整体系统的整体性质和特征,并认为这些整体性质不能简单地通过分解系统为其组成部分来理解。相反,整体论强调整体与部分之间的相互作用和相互依赖,以及整体系统所具有的新的、综合的特性。整体论认为人体是一个复杂的生物系统,不仅仅是其分子、细胞或器官的简单堆积。人体的健康和疾病状态受到多种因素的影响,包括生物学、心理学、社会学、环境等各个方面。因此,治疗和健康管理不应只关注疾病的局部表现或特定的生物化学过程,而是需要综合考虑整体的个体情况及其生活环境。 人体是非科学的 现代科学远远不能解释人体运行机制,在系统性人体解释方面西医还不如中医。 张三心率60,身体健康。李四心率80,身体也是健康的。人体几乎所有的指标都是没法科学量化的,现代仪器检测的指标几乎都是盲人摸象,用现代的科学的手段去研究非科学的人体本身就是反科学的。 中医治病于未然 防患于未然,机体稍有功能上的变化,中医即认为是阴阳失衡,就要适当的调整。治病求本,发现问题就要找到发病的根本,从根本上去除疾病,从而使机体恢复正常状态。 而西医,你的身体不出问题就认为没有问题。而不知道疾病隐患已经在身体慢慢积累,就等某一天爆发 中药没有耐药性 你找不到两株一模一样的药材,吃中医永远不会有抗药性问题。而西医通过提纯,化学合成看似疗效快,但会有抗药性问题,长期来看,几乎所有的西药都可能失去作用!而中药,几千年后,如果还有人类,还是会吃和今天一样的中药。 中药虽然没有抗药性,但现代中药种植导致药效远不如以前,通过加大剂量可以解决。 有个有趣的例子,白糖吃多了会上火,而红糖,也就是提纯前的白糖不会让人上火,杂质是有益的,几乎所有纯净的东西都对人有毒 中医是生命学,西医是死物学 中医整体观念,中医认为人与自然是统一的整体,自然界的变化对人体的影响是不容忽视的;人体本身是不可分割的统一整体,一个位置有病,其根本不一定在这里,多数是两三个脏器或经络功能失衡的结果。而西医几百年了,还是在研究分子化学,下药手术都只是作用与复杂人体的一部分区域。 西医分析分子结构,但没搞明白同样是水,味道也是不同的。 同样的纯净水,热水冷水混合的,开水,冰水,恒温静置一晚的水,经过祝福或者咒骂的水,味道都是不同的。对人的作用也是差异极大。 有兴趣的可以去了解一下酸性食物,碱性食物;寒性食物,热性食物的差异与区分方法。 同样是水,可以是寒性的,也可以是热性的。同样的茶叶,不同生长环境价值相差上万倍。同一种草药,必须是特定地域生长的才能治病!西医对这一块几乎没啥研究。 双盲实验是非科学的 双盲根本就不存在,理论上的双盲需要基因完全一样,生活习惯饮食完全一样的人来做实验,等条件,这种苛刻的条件根本就实现不了。人体本身是复杂的,多样的,没法量化的。用一批各种年龄,性别,身体条件的人去做双盲实验是初中生生物化学知识都可以判断是不科学的。 现代的双盲实验非常容易操控结果。人为控制各种变量,筛选实验数据,不合适的数据就不采用。几乎所有通过双盲实验的西药药物在不到50年就被禁用了!这都是公开的数据。 通过选择特定年龄,性别,胖瘦等身体条件,可以很容易的控制实验结果!这也是西方制药公司经常干的事,历史上比比皆是! 西医也有很多荒诞无知的历史 早期西医是理发师兼任的,现在理发店外面红白相间旋转的是纪念以前理发师给病人放血治疗的染血绷带。老美创建者乔治.华盛顿就是放血过多死亡的! 扁桃体,十二指肠西医以前都是建议切除。现在发现了其重要生理功能,建议保留了。 镭元素发现后,被制作为各种保健品,饮料发售,很长时间都是"科学"背书。 骇人听闻的脑前额切除术,得了诺贝尔奖,把无数正常人变成痴呆,都是以西医科学的名义造成的! 等等。 请不要对这些历史视而不见! 现代医学过度治疗,很多反而不如带病生活的时间长。没见到很多医生自己得了癌症不治疗么? 医生一罢工,全国死亡率下降50%!(援引) 这听起来是个笑话,但确是真实的历史事实。各种解释很多,但这个现象足够引人深思! 中医费用低导致被黑 中医不赚钱是最大的原罪,望闻问切就搞定了几乎所有病症,西医背后各种财团不黑你黑谁?对于医药公司来说,中医费用低是缺点。它们恨不得你的疾病需要天天服药,一辈子服药。 费用低,怎么拿回扣? 费用低,怎么上市圈钱? 费用低,怎么养写手去黑对手? 国内各大交流平台,基本都被国外势力操控,连说一点中医中立的观点都会被删帖,封号。其中一部分人拿钱办事,是坏,还有一部分人是智商低,蠢,要注意分辨。 请警醒,中医国宝一边在被国外势力有计划的抹黑,打压,一边又在偷窃中医的成果。 鬼才倪海厦 中医鬼才,是因其一人身兼医, 命,星,山,卜五术,是海外中医界的风云人物。 最近发现的一个中医大师!有全套中医教程!是目前中医讲解的最好的中医教程! tree -F -L 2 ./自学倪海厦人纪 ./自学倪海厦人纪/ ├── 10自学第十课-文章与医案汇总/ │   ├── 【02】倪海厦专题/ │   ├── 【03】倪海厦事实评论/ │   ├── 1倪海厦汉唐中医经典文章医案集.pdf │   ├── 2人纪班学生的诊疗案例.pdf │   ├── 倪海厦人纪班学生医桉1.pdf │   ├── 倪海厦传统中医跟诊过程.pdf │   ├── 倪海厦内部案例100篇.pdf │   ├── 倪海厦文集及医桉最新版.pdf │   ├── 倪海廈汉唐中医文章全集1.pdf │   ├── 医案/ │   ├── 学员医案.pdf │   ├── 【文】倪海厦医案1(文集和日志)文集(2005年07月25日).pdf │   ├── 【文】倪海厦医案2(诊疗日志)日志(2006年09月01日).pdf │   ├── 【文】倪海厦文集(2006年06月06日).pdf │   ├── 汉唐中医倪海厦医师对猪流感的分析及其处方[1].pdf │   ├── 【汉唐中医内容】倪海厦传统中医跟诊过程.pdf │   └── 汉唐方剂/ ├── 1自学第一课-梁冬对话倪海厦/ │   ├── 《梁冬对话倪海厦》01(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》02(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》03(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》04(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》05(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》06(字幕版)_标清.flv │   ├── 《梁冬对话倪海厦》07(字幕版)_标清.flv │   └── 梁冬对话倪海厦字幕稿.pdf ├── 2自学第二课-倪海厦斯坦福演讲/ │   ├── 倪海厦斯坦福大学演讲:从感冒一路治到癌症.mp4 │   └── 倪海厦斯坦福大学演讲字幕稿.docx ├── 3自学第三课-倪海厦原版《针灸教程》全集11DVD(含字幕版视频)/ │   ├── ​​人纪针灸DVD​​01/ │   ├── ​​人纪针灸DVD​​02/ │   ├── ​​人纪针灸DVD​​03/ │   ├── ​​人纪针灸DVD​​04/ │   ├── ​​人纪针灸DVD​​05/ │   ├── ​​人纪针灸DVD​​06/ │   ├── ​​人纪针灸DVD​​07/ │   ├── ​​人纪针灸DVD​​08/ │   ├── ​​人纪针灸DVD​​09/ │   ├── ​​人纪针灸DVD​​10/ │   ├── ​​人纪针灸DVD​​11/ │   └── 倪海厦针灸大成字幕版视频/ ├── 4自学第四课-倪海厦:原版《黄帝内经》全集11DVD(新增字幕版视频)/ │   ├── 02.倪海厦《黄帝内经》(79集全)无风制作【公众号:汉唐倪师传承】/ │   ├── ​​人纪内经DVD​01​/ │   ├── ​​人纪内经DVD​02​/ │   ├── ​​人纪内经DVD​03​/ │   ├── ​​人纪内经DVD​04​/ │   ├── ​​人纪内经DVD​05​/ │   ├── ​​人纪内经DVD​06​/ │   ├── ​​人纪内经DVD​07​/ │   ├── ​​人纪内经DVD​08​/ │   ├── ​​人纪内经DVD​09​/ │   ├── ​​人纪内经DVD​10​/ │   ├── ​​人纪内经DVD​11​/ │   ├── 倪海夏-人纪-黄帝内经讲义.pdf │   ├── 【视频同步文稿】倪海厦人纪系列书籍之《黄帝内经上册》 .pdf │   └── 【视频同步文稿】倪海厦人纪系列书籍之《黄帝内经下册》.pdf ├── 5自学第五课-倪海厦:原版《神农本草经》全集8DVD(含字幕版视频)/ │   ├── ​​​人纪本草DVD01​/ │   ├── ​​​人纪本草DVD02​/ │   ├── ​​​人纪本草DVD03​/ │   ├── ​​​人纪本草DVD04​/ │   ├── ​​​人纪本草DVD05​/ │   ├── ​​​人纪本草DVD06​/ │   ├── ​​​人纪本草DVD07​/ │   ├── ​​​人纪本草DVD08​/ │   ├── 倪海厦神农本草字幕稿.pdf │   ├── 倪海厦神农本草经视频字幕版/ │   └── 倪海厦神农本草经讲义.pdf ├── 6自学第六课-倪海厦:原版《伤寒论》全集8DVD/ │   ├── ​人纪伤寒DVD​01​/ │   ├── ​人纪伤寒DVD​02​/ │   ├── ​人纪伤寒DVD​03​/ │   ├── ​人纪伤寒DVD​04​/ │   ├── ​人纪伤寒DVD​05​/ │   ├── ​人纪伤寒DVD​06​/ │   ├── ​人纪伤寒DVD​07​/ │   ├── ​人纪伤寒DVD​08​/ │   ├── 倪海厦伤寒论视频字幕.pdf │   └── 倪海厦伤寒论讲义.pdf ├── 7自学第七课-倪海厦:原版《金匮要略》全集11DVD/ │   ├── ​​人纪金匮DVD​01​/ │   ├── ​​人纪金匮DVD​02​/ │   ├── ​​人纪金匮DVD​03​/ │   ├── ​​人纪金匮DVD​04​/ │   ├── ​​人纪金匮DVD​05​/ │   ├── ​​人纪金匮DVD​06​/ │   ├── ​​人纪金匮DVD​07​/ │   ├── ​​人纪金匮DVD​08​/ │   ├── ​​人纪金匮DVD​09​/ │   ├── ​​人纪金匮DVD​10​/ │   ├── ​​人纪金匮DVD​11​/ │   ├── 倪海厦金匮要略视频字幕PDF.pdf │   └── 倪海厦金匮要略讲义.pdf ├── 8自学第八课-倪海厦扶阳论坛演讲/ │   ├── 倪海厦扶阳论坛演讲文字稿.doc │   ├── 第三届扶阳论坛-倪海厦-上.mp4 │   └── 第三届扶阳论坛-倪海厦-下.mp4 ├── 9自学第九课-倪海厦仲景心法传讲/ │   ├── 仲景心法傳講01.mp4 │   ├── 仲景心法傳講02.mp4 │   ├── 仲景心法傳講03.mp4 │   ├── 仲景心法傳講04.mp4 │   ├── 仲景心法傳講05.mp4 │   └── 倪海厦仲景心法传讲 同步文稿85页_1.pdf ├── 其他2-《天纪》《人纪》正版影印版文档/ │   ├── 倪海厦《天纪》.pdf │   ├── 倪海夏伤寒论.pdf │   ├── 倪海夏金匮.pdf │   ├── 倪海夏针炙.pdf │   ├── 天纪 人间道.pdf │   ├── 天纪 地脉道.pdf │   ├── 天纪 天机道(终稿).pdf │   ├── 神农本草经.PDF │   └── 黄帝内经.pdf └── 捕获.PNG 以上资源网络上有下载,版权原因,这里就不提供链接了!Bilibili 上面就有大部分相关资源了。 供中医相关人士及爱好者学习! 自学中医方法 自学的话,从学校的教材入手比较好,先学《中基》,至少看三遍,然后学《中药》,《方剂学》,方剂学可以看邓中甲的视频,多看几遍,边看边记,并背一下《汤头歌诀》,这样打下中医基础。再学《中诊》,后面研究伤寒金贵,李东恒等等。基本就入门了。 总结 生老病死都是生命旅途中的一部分,我们要学会接受它。 中医是几千年的经验总结,其中虽然有一些荒诞的部分,但也有非常多的宝藏等待我们去挖掘。 西医几百年发展虽然有不少见效快的治疗手段,但是由于现代科学本身科学性就有局限性,所以现代西医的科学性也要批判的接受。 个人见解,也请理性接收! 名言赏析 谁控制了石油,谁就控制了所有国家;谁控制了粮食,谁就控制了人类;谁掌握了货币发行权,谁就掌握了世界。 ​ ——亨利·基辛格 系列教程 全部文章RSS订阅 健康系列 健康分类RSS订阅 如何将身体恢复到完美状态 健身从基础常识到实践指导! 中西医的优缺点 文化历史系列 文化历史 分类 RSS 订阅 易学入门 阴历、阳历、阴阳和历的来龙去脉 中西医的优缺点

2022/5/30
articleCard.readMore

常用Linux Bash命令教程

常用linux命令介绍。入门Linux必学的命令行,熟练掌握后,效率远超Windows GUI操作。重要的是,可以方便的做自动化处理! 更多命令在线查询 linux-command.17lai.site Bash 基础 说明 记录在Linux中经常会用到的命令,持续更新。更多命令详解可参考: Linux Tools Quick Tutorial Linux 命令大全 Bash 脚本教程 SSH 教程 Shell选择与切换 在现代的 Linux 上,sh 已经被 bash 代替,/bin/sh往往是指向/bin/bash的符号链接。早期macos系统默认使用bash解释器,在macos10.15系统中官方推荐使用zsh解释器。bash和zsh均是shell的一种,由于bash或zsh本质上都是解释器,他们所共同服务的是shell语言,因此在命令语法上基本相同,zsh能基本完美兼容bash的命令,并且使用起来更加优雅。 $ echo $SHELL # 查看当前默认shell $ cat /etc/shells # 查看系统安装了哪些shell $ chsh -s /bin/bash # 切换bash,读取的配置文件:~/.bash_profile $ chsh -s /bin/zsh # 切换,读取的配置文件:~/.zshrc 当从bash切换为zsh时,如果不想重新配置一遍.zshrc文件,可以在.zshrc文件中加上source ~/.bash_profile,从而直接从.bash_profile文件读取配置。 如果选择zsh,会获得如下好用的功能: $ cd ..... # 输入n+1个点,可以往上跳转n层 $ kill process_name # 自动补全进程ID $ d # 列出最近访问过的目录,然后选择目录前面的数字进行快速跳转 $ r # 重复执行上一条命令 $ commond + tab # 常用命令参数补全提醒 扩展阅读:程序员内功系列–iTerm与Zsh篇 特殊命令符号 符号 格式 作用 ; 命令1;命令2 多个命令顺序执行,命令之间无任何逻辑关系 && 命令1&&命令2 逻辑与:当命令1正确执行后,命令2才会正确执行,否则命令2不会执行 || 命令1||命令2 逻辑或:当命令1不正确执行后,命令2才会正确执行,否则命令2不会执行 | 命令1命令2 管道符:命令1的正确输出作为命令2的操作对象 & 命令 & 后台执行:把命令放在后台执行 > 命令1 > file 输出重定向:将命令1的结果输出到文件中,该文件原有内容会被删除 >> 命令1 >> file 输出重定向:将命令1的结果附加到文件中,原文件内容不会被删除 < 命令1 < file 输入重定向:将file作为命令1的输入 一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件: 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null,以下是常用重定向命令示例: 将 stderr 重定向到 file:command 2>file 将 stderr 追加到 file 文件末尾:command 2>>file。 将 stdout 和 stderr 合并后重定向到 file:$ command > file 2>&1 对 stdin 和 stdout 都重定向:command < file1 > file2 屏蔽 stdout 和 stderr:command > /dev/null 2>&1 **注意:**0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。 Bash中的特殊符号 通配符 作用 ? 匹配一个任意字符 * 匹配0个或多个任意字符,也就是可以匹配任何内容 [] 匹配括号中任意一个字符 [-] 匹配括号中任意一个字符,“-”代表范围 [^] 逻辑非,表示匹配不是括号内的一个字符 ‘’ 单引号,在单引号中所有的特殊符号,如“$”和“`”(反引号)都无特殊含义 “” 双引号,在双引号中特殊符号都无特殊含义, 但“$”、“`”(反引号)和“\”是例外,拥有“调用变量值”,“引用命令”和“转义符”的特殊含义 “ 反引号:反引号括起来的内容是系统命令,在Bash中先会执行它和() $() 和反引号作用相同,用来引用系统命令 # 在shell脚本中,#开头的行代表注释 $ 用于调用变量的值,如需要调用变量name的值时,需要用的 $name 方式得到 \ 转义符,跟在\之后的特殊字符将失去特殊含义,变为普通字符 基础命令 查看系统基础信息 $ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.22 # 免密登录 $ cat /etc/redhat-release # 查看CentOS版本 $ lshw # 查看硬件详细信息 $ cat /proc/cpuinfo| grep "cpu cores"| uniq   # 查看cpu核心数 $ cat /proc/cpuinfo| grep "physical id"|uniq| wc -l # 查看物理cpu个数 $ cat /proc/cpuinfo | grep "processor[[:space:]]:"| wc -l # 查看逻辑cpu的个数 $ free -h   #查看内存大小 添加用户 # 添加用户 lxl80 $ useradd lxl80 && echo "Lixl.cn" | passwd --stdin lxl80 $ vi /etc/sudoers ## Allow root to run any commands anywhere root ALL=(ALL) ALL # 添加以下内容 weixin ALL=(ALL) NOPASSWD: ALL $ vim /etc/ssh/sshd_config # 禁止root用户远程登录 PermitRootLogin no # 生效要重启sshd进程。 $ systemctl restart sshd 基础设置 $ yum install -y wget # 安装wget # 修改yum源 $ cd /etc/yum.repos.d $ mv CentOS-Base.repo CentOS-Base.repo.bak $ wget -O ./CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo $ yum clean all $ yum makecache $ yum update # 升级系统及相关软件 # 安装必备软件 $ yum install net-tools -y # 安装常用网络工具 $ yum install bash-completion -y # 命令自动补全 $ echo -e 'set completion-ignore-case on' >> ~/.inputrc && bind -f ~/.inputrc # 命令补全忽略大小写 $ yum install ntp # 与NTP服务器进行的同步 $ systemctl start ntpd $ systemctl enable ntpd $ ntpdate -u cn.ntp.org.cn # 同步时间 $ date # 检查时间 $ yum -y install crontab # 安装crontab $ crontab -e # 创建crontab任务 # 每天2点同步一次,先通过 which ntpdate 查找命令所在路径 $ * 2 * * * /sbin/ntpdate cn.ntp.org.cn > /dev/null 2>&1 $ service crond reload # 重启crontab 磁盘管理 # 以易读的方式查看磁盘占用情况 $ df -Th $ lsblk    # 查看分区和磁盘,列出所有可用块设备的信息 $ fdisk -l # 分区工具查看分区信息,查看所有被系统识别的磁盘 $ fdisk /dev/sdb    # 分区操作,n,p, , ,w # 格式化sdb1分区,挂载到/home/weixin,并开机启动自动挂载 $ mkfs -t ext4 /dev/sdb1 && mkdir /weixin && mount /dev/sdb1 /weixin && echo /dev/sdb1 /weixin ext4 defaults 0 0 >> /etc/fstab $ chmod 700 /weixin && chown weixin:weixin /weixin # 更改目录权限及归属 $ resize2fs /dev/sdb # 扩展ext*磁盘分区文件系统的大小 $ xfs_growfs /dev/sdb # 扩展xfs磁盘分区文件系统的大小 $ du -sh * # 以易读的方式查看当前目录空间占用总计 $ du -h --max-depth=1 # 查看哪个文件夹或文件占用磁盘最多 $ du -ch *.tar.gz # 查看当前文件夹下所有后缀是 tar.gz 的文件的磁盘使用量总和 -c 查看网络情况 $ semanage port -l|grep ssh # 查看 SELinux 开放给 ssh 使用的端口 $ semanage port -a -t ssh_port_t -p tcp 12022 # 为 ssh 添加允许使用的端口12022 $ vi /etc/ssh/sshd_config # 查看/修改 ssh 使用的端口 $ vi /etc/hosts.allow # 如果ssh无法链接 sshd: ALL ##允许所有ip主机均能连接本机 # 查看当前网络连接情况 $ netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}' $ netstat -anlp | grep 1230 # 查看端口监听 $ systemctl status firewalld # 查看防火墙状态 $ systemctl stop firewalld.service # 停止防火墙 $ systemctl disable firewalld.service # 禁止防火墙开机启动 $ firewall-cmd --zone=public --permanent --add-port=端口号/tcp # 新增开放端口 $ firewall-cmd --zone=public --permanent --remove-port=端口号/tcp # 移除开放端口 $ firewall-cmd --zone=public --list-ports # 查看开放端口 $ firewall-cmd --reload # 刷新防火墙 $ nc -lv 19301 # 监听本机19301端口 $ nc 192.168.0.18 19301 # 连接特定端口 $ telnet 192.168.0.18 19301 # 尝试连接19302端口,ctrl+],q退出 上传下载文件 # 通过 sftp 上传下载文件 $ sftp -i ~/Downloads/newszxl.pem root@106.15.89.34 # 连接服务器 $ get /data/chainmaker/log/* . # 把log下所有日志下载到本地当前目录 $ put crypto-config.zip /data/app/chainmaker/ # 把节点证书上传版到服务器 # 通过 scp 远程传输文件 $ scp -rp /data/ root@192.168.1.3:/data/ $ scp -rp root@192.168.1.3:/data/ /data/ # 通过 rsync 传输/同步文件,排除/data/dir1/目录下的所有文件,不排除dir1目录 $ sudo yum install -y rsync $ rsync -av --exclude={'.*','dir1/*'} /data/ root@192.168.1.3:/data/ 清除history $ history -c # 清除所有历史记录 $ vim ~/.bash_history # 按需修改 $ history -r # 重置文件里的内容到内存中,缓存修改 窗口管理 tmux 是一个终端复用器,可以激活多个终端或窗口,每一个终端都可以访问、运行和控制各自的程序。tmux类似于screen,可以关闭窗口将程序放在后台运行,需要的时候再重新连接。常用快捷键如下: Ctrl+b %:划分左右两个窗格。 Ctrl+b ":划分上下两个窗格。 Ctrl+b <方向键>:光标切换到其他窗格。 Ctrl+b x:关闭当前窗格。 Ctrl+b z:当前窗格全屏显示,再使用一次会变回原来大小。 Ctrl+b Ctrl+<方向键>:按箭头方向调整窗格大小。 后台执行 $ command & # 命令末尾添加&符号在后台运行 $ command > /dev/null 2>&1 & # 将stdout重定向到/dev/null,将stderr重定向到stdout ctrl + z # 将一个正在前台执行的命令放到后台,并且处于暂停状态。 $ bg # 将一个在后台暂停的命令继续执行。用bg %jobnumber 恢复运行 $ fg # 将后台任务切换到前台执行 $ jobs -l # 显示当前shell会话中所有已停止和后台进程的状态 性能测试 磁盘测试 # 使用dd磁盘IO简易性能测试 $ dd if=/dev/zero of=iotestr bs=1024k count=8k conv=fsync # 测试写性能 $ dd if=/dev/sda of=/dev/null bs=8k count=1024k # 测试读性能 # 使用fio进行磁盘专业性能测试 $ yum install fio -y # 测试随机写IOPS: $ fio -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=8G -numjobs=1 -runtime=60 -group_reporting -filename=iotest -name=Rand_Write_IOPS_Test # 测试随机读IOPS: $ fio -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=8G -numjobs=1 -runtime=60 -group_reporting -filename=iotest -name=Rand_Read_IOPS_Test # 测试写吞吐量: $ fio -direct=1 -iodepth=32 -rw=write -ioengine=libaio -bs=1024k -size=8G -numjobs=1 -runtime=60 -group_reporting -filename=iotest -name=Write_BandWidth_Test # 测试读吞吐量: $ fio -direct=1 -iodepth=32 -rw=read -ioengine=libaio -bs=1024k -size=8G -numjobs=1 -runtime=60 -group_reporting -filename=iotest -name=Read_BandWidth_Test 延伸阅读:磁盘性能压测—FIO 网络测试 # 网络测试(需要在需要测试的服务器上分别安装iperf) $ wget https://iperf.fr/download/source/iperf-3.1.3-source.tar.gz $ tar zxvf iperf-3.1.3-source.tar.gz $ cd iperf-3.1.3 $ ./configure $ make $ make install # 服务器端测试命令,后台运行 $ iperf3 -s -D -i 10 -p 19302 --logfile /data/iperf.log # 客户端测试命令,运行60秒,加参数R代表ServerToClient模式 $ iperf3 -c 192.168.0.18 -t 60 -f M -P 1 -p 19302 --get-server-output $ iperf3 -c 192.168.0.18 -t 60 -f M -P 1 -R -p 19302 --get-server-output 延伸阅读:使用 iPerf 进行网络带宽测试,使用 MTR 诊断网络问题 系统监 dstat dstat 是一个可以取代vmstat,iostat,netstat和ifstat这些命令的多功能产品。使用dstat命令可以查看当前cpu,磁盘,网络,内存页和系统的一些当前状态指标。 $ yum install -y dstat $ dstat 5 # 5秒统计一次 1、 –total-cpu-usage—- CPU使用率 usr:用户空间的程序所占百分比; sys:系统空间程序所占百分比; idel:空闲百分比; wai:等待磁盘I/O所消耗的百分比; hiq:硬中断次数; siq:软中断次数; 2、-dsk/total-磁盘统计 read:读总数 writ:写总数 3、-net/total- 网络统计 recv:网络收包总数 send:网络发包总数 4、—paging– 内存分页统计 in: pagein(换入) out:page out(换出) 注:系统的分页活动。分页指的是一种内存管理技术用于查找系统场景,一个较大的分页表明系统正在使用大量的交换空间,通常情况下当系统已经开始用交换空间的时候,就说明你的内存已经不够用了,或者说内存非常分散,理想情况下page in(换入)和page out(换出)的值是0 0。 5、–system–系统信息 int:中断次数 csw:上下文切换 注:中断(int)和上下文切换(csw)。这项统计仅在有比较基线时才有意义。这一栏中较高的统计值通常表示大量的进程造成拥塞,需要对CPU进行关注。你的服务器一般情况下都会运行运行一些程序,所以这项总是显示一些数值。 vmstat vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可实时动态监视操作系统的虚拟内存、进程、CPU活动。 $ vmstat -S m -t 3 # 3秒刷新一次,以M为单位 r 表示运行队列,当这个值超过了CPU数目,就会出现CPU瓶颈了。 b 正在等待资源的阻塞内核线程数,大于3表示io性能不好 bi: 每秒读取的块数 bo: 每秒写入的块数 us: 用户进程执行时间(user time) sy: 系统进程执行时间(system time) id: 空闲时间(包括IO等待时间) wa: IO等待所占用的CPU时间的百分比,高过30%时IO压力高。 top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况。提供了实时的对系统处理器的状态监视。它将显示系统中CPU最“敏感”的任务列表。该命令可以按CPU使用、内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。 $ top -s # 在安全模式运行top Cpu(s) %id:空闲CPU时间百分比 Cpu(s) %wa:等待I/O的CPU时间百分比 VIRT:进程占用的虚拟内存,详情可参考: 观察进程的内存占用情况 RES:进程占用的物理内存 SHR:进程使用的共享内存 i 只显示正在运行的进程 e 切换内存单位,切换顺序为: k,m,g,t,p k 杀掉某进程 o: COMMAND=chain 过滤进程,只显示启动命令带chain的进程 sysstat 一个非常方便的工具,它带有众多的系统资源监控工具,用于监控系统的性能和使用情况。我们在日常使用的工具中有相当一部分是来自sysstat工具包的。同时,它还提供了一种使用cron表达式来制定性能和活动数据的收集计划。以下是包含在sysstat包中的工具: iostat: 输出CPU的统计信息和所有I/O设备的输入输出(I/O)统计信息。 mpstat: 关于CPU的详细信息(单独输出或者分组输出)。 pidstat: 关于运行中的进程/任务、CPU、内存等的统计信息。 sar: 保存并输出不同系统资源(CPU、内存、IO、网络、内核等)的详细信息。 sadc: 系统活动数据收集器,用于收集sar工具的后端数据。 sa1: 系统收集并存储sadc数据文件的二进制数据,与sadc工具配合使用 sa2: 配合sar工具使用,产生每日的摘要报告。 sadf: 用于以不同的数据格式(CVS或者XML)来格式化sar工具的输出。 Sysstat: sysstat工具的man帮助页面。 nfsiostat: NFS(Network File System)的I/O统计信息。 cifsiostat: CIFS(Common Internet File System)的统计信息。 $ yum install sysstat -y # 安装 $ iostat 2 -mxt # 监测IO,2秒刷新一次,以M为单位 $ pidstat -u 1 10 # 监测进程,1秒刷新一次 %user:CPU处在用户模式下的时间百分比。 %nice:CPU处在带NICE值的用户模式下的时间百分比。 %system:CPU处在系统模式下的时间百分比。 %iowait:CPU等待输入输出完成时间的百分比。 %steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。 %idle:CPU空闲时间百分比。 r/s: 每秒完成的读 I/O 设备次数。即 rio/s w/s: 每秒完成的写 I/O 设备次数。即 wio/s rMB/s: 每秒读M字节数。 wMB/s: 每秒写K字节数。 rrqm/s: 每秒进行 merge 的读操作数目。即 rmerge/s wrqm/s: 每秒进行 merge 的写操作数目。即 wmerge/s avgrq-sz:平均每次设备I/O操作的数据大小,类似于平均每人所买的东西多少 avgqu-sz:平均I/O队列长度,类似于单位时间里平均排队人数,如果值比较大,表示有大量io在等待。 await: 平均每次设备I/O操作的等待时间 (毫秒),类似于平均每人的等待时间,如果远大于svctm说明IO响应太慢。 r_await:平均每次读请求的等待时间(毫秒)。这包括请求在队列中和执行它们所花费的时间。 w_await:平均每次写请求的等待时间(毫秒)。这包括请求在队列中和执行它们所花费的时间。 aqu-sz:发送到设备的请求的平均队列长度。 如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈,同时可以结合vmstat 查看b参数和wa参数。 另外 await 的参数也要和 svctm 参考比较。差的过高就一定有 IO 的问题。svctm 一般要小于 await (因为同时等待的请求的等待时间被重复计算了),svctm 的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致 svctm 的增加。await 的大小一般取决于服务时间(svctm) 以及 I/O 队列的长度和 I/O 请求的发出模式。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明 I/O 队列太长,应用得到的响应时间变慢。 队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 洪水。 更详细的信息,可参考:深入理解iostat iotop iotop 是一个类似 top 的工具,用来显示实时的磁盘活动。监控 Linux 内核输出的 I/O 使用信息,并且显示一个系统中进程或线程的当前 I/O 使用情况。它显示每个进程/线程读写 I/O 带宽。它同样显示当等待换入和等待 I/O 的线程/进程花费的时间的百分比。 $ yum install iotop $ iotop -o # 仅显示正在占用I/O的进程或者线程,可以随时按o切换 $ iotop -oP # 按进程显示 IO:它显示每个进程的 I/O 利用率,包含磁盘和交换。 SWAPIN: 它只显示每个进程的交换使用率。 更多信息可参考:https://cleanli.github.io/cleanhome/posts/2021-01-05/Iotop_usage.html 性能调优 分析进程调用 pstack用来跟踪进程栈,如果发现一个服务一直处于work状态(如假死),可以多执行几次pstack,若发现代码栈总是停在同一个位置,很可能就是出问题的地方: $ yum install gdb -y $ pstack pid # 获取进程栈 strace能够动态的跟踪进程执行时的系统调用和所接收的信号: $ yum install -y strace $ strace -ttTv o ~/straceout.txt -p 21120 # 查看进程20020的系统调用情况 内核参数优化 对于服务器来说,file-max和ulimit都需要设置,否则会出现文件描述符耗尽的问题。否则会碰到”Too many open files”或者Socket/File: Can’t open so many files等错误。 # 查看用户进程级的能够打开文件句柄的数量,Centos7默认是1024。 $ ulimit -a # 查看系统级别的能够打开的文件句柄的数量,Centos7默认是794168 $ cat /proc/sys/fs/file-max # 永久生效的修改方法,文件末尾加入配置内容: $ vim /etc/sysctl.conf fs.file-max = 2000000 # 然后执行命令,使修改配置立即生效: $ sysctl -p # 查看当前shell的当前用户的打开的最大限制 $ ulimit -n # 修改一个用户的所有shell能打开的最大数,文件末尾加入配置内容: $ vim /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 # 修改以后,需要重新登录才能生效。如果需要设置当前用户session立即生效,还需要执行: $ ulimit -n 65535 文本处理 Vim常用命令 $ vi +/pattern filename # 打幵文件,并将光标置于第一个与pattern匹配的位置 # u 撤销刚才执行的命令 # I 在光标所在行的行首插入随后输入的文本,相当于光标移动到行首执行 i 命令 # o/O 在光标所在行的下面/上面插入新的一行。光标停在空行首,等待输入文本 # /abc ?abc 从光标所在位置向前/向后查找字符串 abc,如搜索空格加转义符\ # ?abc 从光标所在为主向后查找字符串 abc # /^abc /abc$ 查找以 abc 为行首/为行尾的行 # n N 向同一/相反方向重复上次的查找指令 # gg 跳转到第一行,G 跳转到最后一行 # :s/a1/a2/g 将当前光标所在行中的所有 a1 用 a2 替换 # :n1,n2 s/a1/a2/g 将文件中 n1 到 n2 行中所有 a1 都用 a2 替换 # :%s/a1/a2/g 将文件中所有的 a1 都用 a2 替换 # x 删除光标所在位置的字符(放入剪贴板) # ndd 删除当前行(包括此行)后 n 行文本(放入剪贴板) # dG 删除光标所在行一直到文件末尾的所有内容(放入剪贴板) # D 删除光标位置到行尾的内容(放入剪贴板) # p(P) 将剪贴板中的内容粘贴到光标后(光标后) # 列编辑模式 $ ctrl + v # 进入列编辑模式,然后通过光标移动选择要编辑的块 $ shift + i/a # 在光标前/后插入,ESC自动补全 $ shift + c # 修改内容,ESC自动补全 文本处理 $ grep "put block" logs -R -n # 在多级目录中对文本递归搜索 $ grep -e "ERROR" -e "put block" file # 匹配多个模式 $ cat LOG.* | tr a-z A-Z | grep "FROM " | grep "WHERE" > b # 将日志中的所有带where条件的sql查找查找出来 $ sort unsort.txt | uniq # 消除重复行 $ sort unsort.txt | uniq -c # 统计各行在文件中出现的次数 $ sort unsort.txt | uniq -d # 找出重复行 $ echo 12345 | tr '0-9' '9876543210' # 加解密转换,替换对应字符 $ cat text| tr '\t' ' ' # 制表符转空格 $ cat file | tr -d '0-9' # 删除所有数字 $ cat file | tr -c '0-9' # 获取文件中所有数字 $ cat file | tr -d -c '0-9 \n' # 删除非数字数据 $ cut -f2,4 filename # 截取文件的第2列和第4列 $ paste file1 file2 -d "," # 将两个文本按列拼接到一起,用,分割 $ wc -l file # 统计行数 $ wc -w file # 统计单词数 $ wc -c file # 统计字符数 $ sed 's/text/replace_text/' file # 替换每一行的第一处匹配的text $ sed 's/text/replace_text/g' file # 全局替换,输出替换后的内容 $ sed -i 's/text/replace_text/g' file # 全局替换,直接替换源文件 $ sed '/^$/d' file # 移除空白行 awk 数据流处理 awk是文本处理程序,它依次处理文件的每一行,并读取里面的每一个字段。适用于处理日志、CSV 这种每行格式相同的文本文件。参考:Awk入门 及 30个Awk文本处理示例 脚本结构: awk 'BEGIN{statements} statements2 END{statements}',工作方式: 执行begin中语句块; 从文件或stdin中读入一行,然后执行statements2,重复这个过程,直到文件全部被读取完毕; 执行end语句块; # 使用不带参数的print时,会打印当前行,输入内容如下: $ echo -e "line1\nline2" | awk 'BEGIN{print "start"} {print} END{print "End"}' start line1 line2 End $ awk '{print $0}' demo.txt # 把demo.txt文件中每一行原样打印出来 # 用空格分割,输出字段数>30且第四列为特定字符的行中1,4及倒数第二列,第4列转成大写。','代表用空格分割 $ awk -F ' ' 'NF>3 {if ($4 = "CONSENSUS") print $1,toupper($4),$(NF-1)}' panic.log 数字证书 // 查看证书信息 $ openssl x509 -noout -text -in user/admin1/admin1.tls.crt $ openssl x509 -in cert.pem -noout -text 系统相关 hostname - 查看主机名 hostname命令用于查看系统的主机名,或是修改系统的主机名。 hostname的常用命令如下: # 显示系统的当前主机名 hostname # 修改你系统的主机名 hostname blinkfox-system # 使用 -F 选项,从指定的文件中读取主机名 hostname -F /root/hostname.txt uptime - 查看系统运行时间 uptime命令用于打印系统的运行时间等信息。使用如下: uptime w、who - 列出登录的用户 w命令用于显示登录用户及他们当前运行的进程。输入的内容格式如下: w # 打印如下 22:42 up 18 days, 1 hr, 2 users, load averages: 1.23 1.79 1.75 USER TTY FROM LOGIN@ IDLE WHAT blinkfox console - 日19 6days - blinkfox s000 - 五23 - w who命令有与w命令类似的用途,但它的功能比w命令更强大一些。语法格式如下: who [OPTION]... [FILE | ARG1 ARG2] who常用命令如下: # 显示当前登录的所有用户信息 who # 显示系统的启动时间 who -b # 显示系统登录进程 who -l # 显示与当前标准输入关联的用户信息 who -m # 显示系统的运行级别 who -r # 显示所有登录用户的用户名和登录用户数 who -q uname - 查看系统信息 uname命令用于打印内核名称和版本、主机名等系统信息。命令的语法如下所示: uname [OPTION]... 常用使用方式如下: # 只打印内核的名称 uname # 使用 -n 选项,只打印系统的主机名 uname -n # 使用 -r 选项,打印内核版本信息 uname -r # 使用 -m 选项,打印系统的硬件名称 uname -m # 使用 -p 选项,打印系统的处理器类型信息 uname -p # 使用 -i 选项,打印系统的硬件平台信息 uname -i # 使用 -a 选项,打印上述所有示例中的信息 uname -a date - 显示和设置系统日期和时间 date命令用于以多种格式显示日期和时间,或设置系统的日期和时间。date命令的语法如下所示: date [OPTION]... [+FORMAT] date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] 常用使用命令如下: # 以默认格式显示系统的当前日期时间 date # 格式化当前日期 date +"%Y-%m-%d" # 格式化输出昨天的日期 date -d "1 day ago" +"%Y-%m-%d" # 2秒后格式化输出 date -d "2 second" +"%Y-%m-%d %H:%M.%S" # 普通格式化转出 date -d "2009-12-12" +"%Y/%m/%d %H:%M.%S" # apache格式转换 date -d "Dec 5, 2009 12:00:37 AM" +"%Y-%m-%d %H:%M.%S" # 日期加减操作 date +%Y%m%d #显示前天年月日 date -d "+1 day" +%Y%m%d #显示前一天的日期 date -d "-1 day" +%Y%m%d #显示后一天的日期 date -d "-1 month" +%Y%m%d #显示上一月的日期 date -d "+1 month" +%Y%m%d #显示下一月的日期 date -d "-1 year" +%Y%m%d #显示前一年的日期 date -d "+1 year" +%Y%m%d #显示下一年的日期 # 设定时间 date -s # 设置当前时间,只有root权限才能设置,其他只能查看 date -s 20160816 # 设置成20160816,这样会把具体时间设置成空00:00:00 date -s 01:01:01 # 设置具体时间,不会对日期做更改 date -s "01:01:01 2012-05-23" # 这样可以设置全部时间 date -s "01:01:01 20120523" # 这样可以设置全部时间 date -s "2012-05-23 01:01:01" # 这样可以设置全部时间 date -s "20120523 01:01:01" # 这样可以设置全部时间 id - 显示用户属性 id命令用于打印输出用户uid、gid、用户名和组名等用户身份信息。id命令的语法如下所示: id [OPTION]... [USERNAME] 常见使用命令如下: # 输出当前用户的uid、用户名、gid、组名及用户属于的群组信息 id # 使用 -u 选项,输出用户的 uid id -u #-u 选项和 -n 选项结合使用,输出账户的用户名 id -un # 使用 -g 选项,输出帐号当前起作用的gid id -g # -g 与 -n 选项结合使用,输出帐号当前起作用的用户组名 id -gn # 使用 -G 选项,输出帐号所属的所有群组id id -G root # -G 与 -n 选项结合使用,输出账号所属的所有群组的名称 id -Gn root 文件和目录操作 touch - 创建文件 touch命令就可用于创建、变更和修改文件的时间戳。它是 Linux 操作系统的标准程序。touch命令又如下选项: -a: 只改变访问时间 -c: 不创建任何文件 -m: 只改变修改时间 -r: 使用指定文件的时间替代当前时间 -t: 使用 [[CC]YY]MMDDhhmm[.ss] 替代当前时间 touch 命令的常见用法如下: # 创建一个名为 effyl 的新空文件 touch effyl # 同时创建名称分别为 effyl myeffyl lueffyl 的三个文件 touch effyl myeffyl lueffyl # 使用 -a 选项,可以改变或更新文件的最新访问时间,如果文件 effyl 不存在,则新创建一个 touch -a effyl # 使用 -c 选项,可以避免创建一个新文件,并用当前时间更新文件的时间戳 touch -c effyl # 使用 -m 选项,可以只改变文件的修改时间,而访问时间不变 touch -m effyl # 使用 -c 和 -t 选项,来明确设置文件的时间 touch -c -t YYMMDDHHMM filename # 如果想使用文件 myeffyl 的时间戳更新文件 effyl 的时间戳,可以使用 -r 选项 touch -r myeffyl effyl mkdir - 创建目录 mkdir命令用于创建一个新目录。最基本的mkdir命令的使用方法如下所示: # 在当前目录下创建一个给定的目录名 mkdir <dirname> # 在 backup 中的相对路径创建一个名为 old 的目录 mkdir backup/old # 在 backup 中的绝对路径中创建一个名为 old 的目录 mkdir /home/blinkfox/backup/old # 使用 -p 选项,会自动创建所有还不存在的父目录 mkdir -p backup/old # 使用 -m 选项,可以设置将要创建目录的权限 # 如:创建一个任何人都有读写访问权限的目录 mkdir -p -m 777 backup/old cp - 复制文件或目录 cp命令用于将文件从一个地方复制到另一个地方。原来的文件保持不变,新文件可能保持原名或用一个不同的名字。 使用 cp 命令复制文件和目录的语法有以下几种: # 复制源文件到目标文件 cp [OPTION] SOURCE DEST # 复制一个或多个源文件到一个目录 cp [OPTION] SOURCE... DIRECTORY # 同上 cp [OPTION] -t DIRECTORY SOURCE... 常用使用示例如下: # 在当前目录下,创建一个文件 file.txt 的副本,取名为 newfile.txt cp file.txt newfile.txt # 复制当前目录下的 file.txt 文件到 /tmp 目录下 cp file.txt /tmp # 复制当前目录下的所有文件到 /tmp 目录下 cp * /tmp # 使用 -p 选项,可以使复制一个文件到新文件时,保留源文件的所有者、权限等信息 cp -p filename /path/to/new/location/myfile # 使用 -R 或 -r 选项,恶意递归地复制一个目录 # 即将一个目录及其下的所有文件和子目录都复制到另一个目录 cp -R * /home/blinkfox/backup ln - 链接文件或目录 ln命令用于创建软链接或硬链接。使用 -s 选项,可以创建一个软链接: # 在目录 lib 下创建一个软链接 library.so,链接到 /home/blinkfox/src/library.so ln -s /home/blinkfox/src/library.so /home/blinkfox/lib # 创建目录的软链接 ln -s /home/blinkfox/src source mv - 移动文件或目录 mv命令用于将文件和目录从一个位置移到另外一个位置。除了移动文件,mv命令还可用于修改文件或目录的名字。 mv 命令的基本语法如下所示: mv SOURCE... DIRECTORY 常用命令如下: # 将当前目录下的文件 source.txt 移到目录 /tmp 下 mv source.txt /tmp # 将目录 dir1、dir2 移到目录 dir_dist 下 mv dir1 dir2 dir_dist # 将当前目录下的 old.txt 文件更名为 new.txt mv old.txt new.txt # 使用 -i 选项,在重写覆盖目标文件或目录之前给出提示信息 mv -i old.txt new.txt # 将当前目录下的所有文件移动到目录 /tmp 下 mv * /tmp/ # 使用 -i 选项,从 dir1 中移动那些在目标目录中不存在的文件到目标目录 mv -u dir1/* dir2/ rm - 删除文件或目录 rm命令用于删除指定的文件和目录。其语法如下所示: rm [OPTIONS]... FILE... rm的常用命令如下: # 删除当前目录下的文件 file1.txt、file2.txt、file3.txt rm file1.txt file2.txt file3.txt # 删除当前目录下的所有文件 rm * # 删除你当前帐号主目录下的 temp 目录中的所有文件 rm ~/temp/* # 使用 -i 选项,可以在删除每个文件或目录前提示用户确认 rm -i * # 删除当前目录下所有以".doc"结尾的文件 rm *.doc # 删除当前目录下所有文件名中包含"movie"字符串的文件 rm *movie* # 删除当前目录下所有以"a"开头的文件 rm a* # 删除当前目录下整个文件名(包括扩展名)只有 3 个字符的所有文件 rm ??? # 删除当前目录下文件扩展名有两个字符的所有文件 rm *.?? # 删除当前目录下文件名中含有字母 a 或 b 或 c 的所有文件 rm *[abc]* # 删除当前目录下文件名中包含 0~9 的所有文件 rm *[0-9]* # 删除当前目录下文件扩展名是字母 c 或 h 的所有文件 rm *.[ch] # 删除 /tmp 目录下的所有文件及其子目录 rm -rf /tmp/* -f 删除前不提示用户确认,并忽略不存在的文件 -r 递归地删除目录及其下的内容 ls - 列出文件名和目录 ls命令是Linux中最常用的命令之一,其作用就是列出文件名和目录。在命令行提示符下,直接输入ls命令,不带任何选项,将列出当前目录下所有文件和目录,但不会显示详细的信息,比如,文件类型、大小、修改日期和时间、权限等。 以下便是ls命令及其选项的作用说明: # 仅列出当前目录下所有文件和目录 ls # 每行显示一条记录,每条记录包括文件类型、大小、修改日期和时间、权限等 ls -l # 将文件大小显示符合人类阅读习惯的格式 ls -lh # 将使用不同的特殊字符归类不同的文件类型 ls -F # 以长列表格式列出某个目录的信息 ls -ld /var/log # 将递归地列出子目录的内容 ls -R /etc/sysconfig/ # 以长列表格式按文件或目录的修改时间倒序地列出文件和目录 ls -ltr # 以长列表格式按文件大小顺序列出文件和目录 ls -ls # 列出包括隐藏文件或目录在内的所有文件和目录,包括“.”(当前目录)和“..”(父目录) ls -a # 列出包括隐藏文件或目录在内的所有文件和目录,不包括“.”(当前目录)和“..”(父目录) ls -A 输出的内容类似于-l选项,指示显示uid和gid,替代显示所有者和用户组 ls -n cat - 连接显示文件内容 cat 命令也是 Linux 系统中最常用的命令之一。cat命令让我们可以看看文件的内容、连接文件、创建一个或多个文件和重定向输出到终端或文件。 cat命令的语法如下所示: cat [OPTION] [FILE]... cat常用命令如下: # 使用 cat 命令查看文件 /etc/group 的内容 cat /etc/group # 显示多个文件的内容 cat /etc/redhat-release /etc/issue # -n 选项,可以显示文件内容的行号 cat -n /etc/fstab # -b 选项和 -n 选项类似,但只标识非空白行的行号 cat -b /etc/fstab # -e 选项,将在每一行的结尾显示“$”字符 cat -e /etc/fstab 当你只输入 cat 命令,而没有任何参数时,它只是接收标准输入的内容并在标准输出中显示。所以你在输入一行内容并回车后,会在接下来的一行显示相同的内容。你也可以重定向标准输出到一个新文件。 dd less、more - 分屏显示文件 more命令在你使用小的 xterm 窗口时,或是想不使用文本编辑器而只是简单地阅读一个文件时是很有用的。more 命令是一个用于一次翻阅一整屏文件的过滤器。 # 查看一个文件,自动清空屏幕并显示文件开头部分 more /etc/inittab # 指定一次显示num行 more -num /etc/inittab 与more命令相比,我个人更喜欢less命令来查看文件。less命令与more命令类似,但less命令向前和向后翻页都支持,而且less命令不需要在查看前加载整个文件,即less命令查看文件更快速。 less常用命令参数如下: -b <缓冲区大小> 设置缓冲区的大小 -e 当文件显示结束后,自动离开 -f 强迫打开特殊文件,例如外围设备代号、目录和二进制文件 -g 只标志最后搜索的关键词 -i 忽略搜索时的大小写 -m 显示类似more命令的百分比 -N 显示每行的行号 -o <文件名> 将less 输出的内容在指定文件中保存起来 -Q 不使用警告音 -s 显示连续空行为一行 -S 行过长时间将超出部分舍弃 -x <数字> 将“tab”键显示为规定的数字空格 /字符串:向下搜索“字符串”的功能 ?字符串:向上搜索“字符串”的功能 n: 重复前一个搜索(与 / 或 ? 有关) N: 反向重复前一个搜索(与 / 或 ? 有关) b 向后翻一页 d 向后翻半页 h 显示帮助界面 Q 退出less 命令 u 向前滚动半页 y 向前滚动一行 空格键 滚动一行 回车键 滚动一页 [pagedown]: 向下翻动一页 [pageup]: 向上翻动一页 head - 显示文件头部 head命令用于打印指定输入的开头部分内容。默认情况下,打印每个指定输入的前 10 行内容。 使用-n选项可以指定打印文件的前 N 行: # 指定打印文件的前5行 head -n 5 /etc/inittab (或)head -5 /etc/inittab # 打印文件的前N个字节的数据 head -c 10 /etc/inittab tail - 显示文件尾部 tail命令和head命令相反,它打印指定输入的结尾部分的内容。默认情况下,它打印指定输入的最后 10 行内容。 使用-n选项可以指定打印文件的最后 N 行: # 指定打印文件的后10行 tail -n 10 /etc/inittab tail -10 /etc/inittab # 即时打印文件中新写入的行 tail -f /var/log/messages # --retry选项表示持续尝试打开某个文件,当你想打开一个稍后才会创建或即使不可用的文件 tail -f /tmp/debug.log --retry file - 查看文件类型 file命令用于接收一个文件作为参数并执行某些测试,已确定正确的文件类型。 # 查看文件类型 file /etc/inittab # 可以MIME类型的格式显示文件类型的信息 file -i /etc/inittab # 使用-N 选项,输出的队列可以以在文件名之后无空白填充的形式显示 file -N * wc - 查看文件统计信息 wc命令用于查看文件的行数、单词数和字符数等信息。语法类似如下所示: wc filename X Y Z /etc/inittab 其中 X 表示行数,Y 表示单词数,Z 表示字节数,filename 表示文件名。 # -l选项,可以只统计文件的行数信息 wc -l /etc/inittab # -w选项,可以只统计文件的单词数信息 wc -w /etc/inittab # -c选项,可以只统计文件的字节数信息 wc -c /etc/inittab # -L选项,可以只统计文件中最长的行的长度 wc -L /etc/inittab find - 查找文件或目录 find命令用于根据你指定的参数搜索和定位文件和目录的列表。find命令可以在多种情况下使用,比如你可以通过权限、用户、用户组、文件类型、日期、大小和其他可能的条件来查找文件。 find命令常用使用和说明如下: # 查找指定目录下的某个文件 find /etc/ -name inittab # 在当前目录下查找名称为 inittab 的文件 find . -name inittab # 在当前目录下,文件不区分大小写是example的所有文件 find . -iname example # 找出当前目录下所有以 sh 结尾的文件 find . -type f -name "*.sh" # 找出当前目录下,文件权限是 777 的所有文件 find . -type f -perm 777 # 找出当前目录下,文件权限不是 777 的所有文件 find . -type f ! -perm 777 # 找出当前目录下所有只读文件 find . -type f ! -perm /a+w # 找出你帐号主目录下的所有可执行文件 find ~ -type f -perm /a+w # 找出 /tmp 目录下的.log文件并将其删除: find /tmp/ -type f -name "*.log" -exec rm -f {} \; # 找出当前目录下的所有空文件 find . -type f -empty # 找出当前目录下的所有空目录 find . -type d -empty # 找出 /tmp 目录下的所有隐藏文件 find /tmp/ -type f -name ".*" # 找出 /tmp 目录下,所有者是 root 的文件和目录 find /tmp/ -user root # 找出 /tmp 目录下,用户组是 developer 的文件和目录 find /tmp/ -group root # 找出你账号的主目录下,3 天前修改的文件 find ~ -type f -mtime 3 # 找出你账号的主目录下,30 天以前修改的所有文件 find ~ -type f -mtime +30 # 找出你账号的主目录下,3 天以内修改的所有文件 find ~ -type f -mtime -3 # 找出你账号的主目录下,30 天以前,60 天以内修改的所有文件 find ~ -type f -mtime +30 -mtime -60 # 找出 /etc 目录下,一小时以内变更过的文件 find /etc -type f -cmin -60 # 找出 /etc 目录下,一小时以内访问过的文件 find /etc -type f -amin -60 # 找出你账号主目录下,大小是50MB的所有文件 find ~ -type f -size 50MB # 找出你账号主目录下,大于50MB小于100MB的所有文件 find ~ -type f -size +50MB -size -100MB # 找出你账号主目录下,大于100MB的文件并将其删除 find ~ -type f -size +100MB -exec rm -rf {} \; 文本处理 sort - 文本排序 sort命令用于将文本文件的行排序。默认情况下,sort命令是按照字符串的字母顺序排序。 sort 的常用命令如下: # 将文本内容按字母顺序排序 sort example.txt # 使用 -u 选项,移除所有重复行后排序 sort -u example.txt # 使用 -n 选项,将令数字按数值的大小排序 sort -n example.txt # 使用 -r 选项,以倒序方式排序 sort -n -r example.txt # 同时将 file1、file2 的内容排序 sort file1 file2 uniq - 文本去重 uniq命令用于移除或发现文件中重复的条目。 # 它将移除文件中重复的行并显示单一行 uniq example.txt # 可以统计重复行出现的次数 uniq -c example.txt # 使用 -d 选项,只显示文件中有重复的行并只显示一次 uniq -d example.txt # 使用 -D 选项,显示文件中所有重复的行 uniq -D example.txt # 使用 -u 选项,只显示文件中不重复的行 uniq -u example.txt # 使用 -w 选项,限制 uniq 命令只比较每行的前 3 个字符是否重复 uniq -w 3 example.txt # 使用 -s 选项,避免 uniq 命令比较每行的前 3 个字符,只比较后面的字符是否重复 uniq -s 3 example.txt # 使用 -f 选项,避免 uniq 命令比较第一列的内容,只比较后面的字符是否重复 uniq -f 1 example.txt tr - 替换或删除字符 tr命令主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串 1 用于查询,字符串 2 用于处理各种转换。tr刚执行时,字符串 1 中的字符被映射到字符串 2 中的字符,然后转换操作开始。 tr命令的语法如下所示: tr [OPTION]... SET1 [SET2] 常用命令示例: # 若要将大括号转换为小括号 tr '{}' '()' < textfile > newfile # 若要将大括号转换成方括号 tr '{}' '\[]' < textfile > newfile # 若要将小写字符转换成大写,请输入: tr 'a-z' 'A-Z' < textfile > newfile # 若要创建一个文件中的单词列表 tr -cs '[:lower:][:upper:]' '[\n*]' < textfile > newfile # 若要从某个文件中删除所有空字符 tr -d '\0' < textfile > newfile # 若要用单独的换行替换每一序列的一个或多个换行,请输入: tr -s '\n' < textfile > newfile # 要以单个“#”字符替换 <space> 字符类中的每个字符序列 tr -s '[:space:]' '[#*]' grep - 查找字符串 grep命令用于搜索文本或指定的文件中与指定的字符串或模式相匹配的行。默认情况下,grep命令只显示匹配的行。 grep命令的语法如下所示: grep [OPTION]... PATTERN [FILE]... grep [OPTION]... [-e PATTERN | -f FILE] [FILE]... # `grep`命令查找文件/etc/passwd 中帐号 blinkfox 的信息 grep blinkfox /etc/passwd # 使用 -i 选项,强制 grep 命令忽略搜索关键字的大小写 grep -i blinkfox /etc/passwd # 使用 -r 选项,可以递归搜索指定目录下的所有文件 grep -r blinkfox /etc/ # 使用 -w 选项,只匹配包含指定单词的行 grep -w blinkfox /etc/ # 使用 -c 选项,报告文件或文本中模式被匹配的次数 grep -c blinkfox /etc/passwd # 使用 -n 选项,显示每一个匹配的行的行号 grep -n blinkfox /etc/passwd # 使用 -v 选项,可以输出除匹配指定模式的行以外的其他所有行 grep -v blinkfox /etc/passwd # 使用 --color 选项,在输出中将匹配的字符串以彩色的形式标出 grep --color blinkfox /etc/passwd diff - 比较两个文件 diff命令用于比较两个文件,并找出它们之间的不同。diff命令的语法如下所示: diff [OPTION]... from-file to-file 常用使用方式如下: # 比较两个文件 diff nsswitch.conf nsswitch.conf.org # 使用 -w 选项,比较时忽略空格 diff -w nsswitch.conf nsswitch.conf.org # 使用 -y 选项,以并排的格式输出两个文件的比较结果 diff -y nsswitch.conf nsswitch.conf.org 使用 -c 选项,以上下对比的格式输出两个文件的比较结果 diff -c nsswitch.conf nsswitch.conf.org Linux 和UNIX 的新手培训教程 免费的新手Linux教程 Introduction to Linux – 这是来自IBM的教程,用于给那些想学习Linux的人。 Linux Desktop 101 – 这是一个 14周 课时的教程,主要用于学校里教学生如何在一个PC上运行一个Linux操作系统。 Hands-On Introduction to Linux – Machtelt Garrels 的一个格式相当不错的教程。 Real Time Linux Introduction – 一系列的介绍Linux的教程,来自National Institute of Standards and Technology. Getting Started with Linux – 来自Linux Online 的20课时的用于新手的教程。 Linux Fundamentals Course – 一个相当不错的基础教程,大约使用18个小时,让你知道Linux操作系统的最基础的知识。 The 35-Command Tutorial – 来自BeginLinux.org 的一个最简单的教程,教你使用 35 个Linux用户必需了解的命令。 Getting Started with Linux Desktop – Novell的自学教程。 免费的UNIX 新手教程 UNIX Tutorial for Beginners – 来自The University of Surrey的新手指南,告诉你Unix系统最基本的特性。 A Basic UNIX Tutorial – 这是来自 Idaho State University 教程,主要用于Unix计算的基础,其中有一些很不错的示例和练习。 UNIX Training Manual – 这是一个 88页 的培训手册,主要用一些示例来教一个Unix文件系统的相关的命令。严格说来,这并不是一个教程,但也很有用。 UNIX Command Tutorial – 来自University of Mississippi 的教学生如果使用Unix命令和操作系统交互的课程。 Learn UNIX Tutorial – Soft Lookup 的一个全面的 UNIX 教程,完全可以让你从一个新手变成一个高手。 UNIX – The Bare Minimum – 来自 UC Davis 教授,提供了一个简单的UNIX介绍。 Learning About UNIX – 来自University of Toronto,提供了一些UNIX 和Linux 课程笔记。这个课程关注于UNIX 和Linux 工具。 What is UNIX? – 这个教程提供了一个简单的Unix介绍,以及一个初学者的论坛。 Linux 和 UNIX 专家培训教程 免费的Linux高手教程 Linux Online’s Course for Advanced Users – 这是一个来自Linux Online的高级教程,提供了一系Linux最流行的How-To文档。主要是给那些想了解更多关于Linux安装,配置和维护的人。 Linux System Administration Course – 通过28个课程为Linux系统管理员提供了一个全面的教程。 Kernel Tutorials – 这是在HowToForge上的一个内核级的教程,这个教程相当不错,如果你要了解Linux的内核,你不能错过这个教程。 Advanced Routing and Traffic Control Tutorial – 一个关于Linux网络路由,过滤和传输的教程。 Linux Enterprise Server Courses – Novell Training Services 提供给高级用户的培训教程。 Linux Network Administration Course – 来自Shuttleworth Foundation的 Linux 网络管理员的基础课程。 Advanced Linux Programming – 这是一本电子书可以免费下载。这本书主要教程序员们怎么在Linux下做软件和编程序。 IBM’s Technical Library – IBM’s Technical Library 提供的一组给高级Linux用户的教程。 免费的UNIX高手教程 UNIX for Advanced Users – Indiana University的 UNIX Workstation Support Group 提供的一个相当不错的面对UNIX 高级用户的教程。 Kevin Heard’s UNIX Tutorial – Kevin Heard (UC Berkeley) 的一个相当相当不错的三部教程,从Unix的基础开始,以高级话题结束。 Advanced UNIX Commands – 虽然这是一个命令例表,但他是一个相当不错的索引的速查手册。 Parallel Programming Tutorial – 这个UNIX 教程面对的是Unix下的并行编程 Parallel Programming。 Advanced Bash Scripting Guide – 来自于Linux Document Project 的教程,一个shell编程由浅入深的教程。 UNIX Shell Scripting Advanced – VTC 有一组视频的 UNIX 的教程。而这一个是指导高级用户如何进行脚本编程。 Advanced C Shell Programming – 这是UC Davis 的教程,主要教使用如何使用C shell 和tcsh 进行脚本编程。 参考&感谢 常用Bash命令整理之查看文件和目录 常用Bash命令整理之其他常用命令 常用Bash命令整理之文本处理 常用Bash命令整理之查看文件和目录 Linux常用命令 Useful Tutorials on Linux and UNIX for Beginners and Experts Alike

2022/5/28
articleCard.readMore

Doxygen入门教程

Doxygen是API文档生成工具,可以根据代码注释生成文档的工具。支持HTML、CHM、PDF等格式。主要支持C语言、Python语言,其它C语系语言也支持(如C++、Java、C#等)。 本教程的测试环境 Ubuntu 18.04 LTS Doxygen 1.8.13 C++ Gitlab CI/CD windows 什么是 Doxygen? Doxygen 是一个将文件的特定注释转化为文档的工具 如何安装 Doxygen? $ sudo apt install graphviz $ sudo apt install doxygen 如何使用 Doxygen? 1. 查看你使用的语言 Doxygen 是否默认支持? Doxygen 默认支持的语言有:C,C++,C#,Objective-C,IDL,Java,VHDL,PHP,Python,Tcl,Fortran 和 D 2. 生成配置文件 $ ## 生成配置文件,默认配置文件名为:Doxyfile $ doxygen -g <config-file> $ $ ## 生成配置文件(不含注释) $ doxygen -s -g <config-file> $ 3. 修改配置文件 ## 常见配置选项 ## 设置项目编码,默认为 UTF-8 DOXYFILE_ENCODING = UTF-8 ## 设置项目名称 PROJECT_NAME = "project-name" ## 设置项目版本号 PROJECT_NUMBER = "1.0.0" ## 设置项目的描述 PROJECT_BRIEF = "这是项目描述" ## 设置项目的 logo PROJECT_LOGO = "" ## 设置输入目录,如果未设置,则在当前目录查找 INPUT = src ## 设置要匹配的输入文件 FILE_PATTERNS = *.cc *.h ## 设置不需要处理的输入目录 EXCLUDE = ## 设置不需要匹配的输入文件 EXCLUDE_PATTERNS = ## 设置输入编码,默认为 UTF-8 INPUT_ENCODING = UTF-8 ## 设置是否递归搜索输入目录,默认为 NO RECURSIVE = NO ## 设置是否提取所有类,函数等(不包括类的私有成员和静态成员),默认为 NO EXTRACT_ALL = NO ## 设置是否提取类的私有成员,默认为 NO EXTRACT_PRIVATE = NO ## 设置是否提取类的静态成员,默认为 NO EXTRACT_STATIC = NO ## 设置文档是否包含源文件,默认为 NO SOURCE_BROWSER = NO ## 设置是否对每个类都链接到其所在的头文件中,默认值为 YES VERBATIM_HEADERS = YES ## 设置文档的输出目录 OUTPUT_DIRECTORY = doc ## 设置是否支持 Markdown,默认值为 YES MARKDOWN_SUPPORT = YES ## 设置文档的主界面 USE_MDFILE_AS_MAINPAGE = ## 设置文档的语言,默认为 English OUTPUT_LANGUAGE = Chinese 4. 给代码添加注释 /** 注释的内容 */ /*! 注释的内容 */ ## 在变量后 注释文件,类,结构体,共同体,枚举成员 或 函数参数 int a; /**< 注释的内容 */ int a; /*!< 注释的内容 */ 注意: 这里并不是所有的注释风格,更多注释风格见 官网 Doxygen 常用的注释标记(标记以 / 或 @ 开头表示): ## 添加作者 @author 作者1 作者2 ## 添加日期 @date 日期 ## 添加文件名 @file 文件名 ## 添加简单描述 @brief 简要描述 ## 添加详细描述 @details 详细描述 ## 添加类信息 @class 类名 类所在的文件 类所在的文件(可包括路径) ## 添加结构体信息 @class 结构体名 结构体所在的文件 结构体所在的文件(可包括路径) ## 添加宏信息 @enum 宏名 ## 添加函数信息 @fn 函数信息 ## 添加参数说明 @param [in] 输入参数名 说明 @param [out] 输出参数名 说明 ## 添加返回说明 @return 返回说明 ## 添加返回特定值说明 @retval 特定值 特定返回值说明 ## 添加异常说明 @exception 异常类型 异常说明 ## 添加代码 @code ...代码... @encode ## 添加文件名说明 @headfile 文件名 文件名(可包括路径) ## 添加版本号 @version 版本号 ## 添加计划做的事儿 @todo 计划做的事 ## 添加参考 @see 参加其它 ## 添加过时说明 @deprecated 过时说明 ## 添加 bug 说明 @bug "bug 说明" ## 添加例子 @example 例子文件名 ## 添加警告信息 @warning 警告信息 ## 添加开始使用的版本 @since 版本 ## 添加测试信息 @test 测试 ## 添加主界面信息 @mainpage 标题 ## 添加注意事项 @note 注意事项 ## 添加协议信息 @copyright 协议信息 为C/C++添加注释 首先为函数添加注释信息,这是必须要做的。这里有个选择性问题,添加到哪里呢?.c文件?.h文件? 一般来说: .h文件代表模块对外的接口最小信息,面向模块使用者 .c文件代表模块的实现代码,面向的是开发者 在实际编程中,事先约定各个模块间的接口,然后将不同的模块分配给不同的开发者,与此同时,测试人员根据接口要求,编写测试代码,这就完全保证了并发编程和白盒测试要求。 这里我们可以看到,文档主要是用来描述接口信息的,所以,我对代码的注释规定如下: 模块对外接口,仅在.h中提供注释信息 模块内部辅助函数,全部用static设为私有函数,同时仅在.c中保留注释信息 当然,您也可以同时为.c .h的接口函数编写两份完全一样的注释信息,但这么做,您会同时维护两份信息,出错的概率会更大些。 确定了注释位置,下一步考虑一个函数需要哪些信息 一般来说,需要函数功能,入口参数,返回值,注意事项,某些时候还需要说明上下文环境,从而保证函数能正确执行 比如这个函数 extern int Dev_PrintInt(int number); 它的功能就是打印一个整形数据,传入参数为整数,返回的是成功打印的数据长度(字节为单位),同时呢,我们在调用这个函数之前,必须要先初始化Dev设备 ok,这就是所有接口信息,稍微规范一下,就变成了下面的样子 // 函数功能:打印整数 // 入口参数:number为一个整数类型 // 返回结构:返回的是成功打印的数据长度(字节为单位) // 注意事项: // 1:在调用本函数前,请确保已经调用Dev_Init初始化设备 // 2:请注意函数返回值,如果该值为0,则说明函数执行失败 extern int Dev_PrintInt(int number); 用英文来书写呢,则变成下面的样子 //*************************************************************************************** // // brief : Print Int number to terimal device. // // param : number is the data you want to print. // retval : the number of print information, in bytes. return zero indicate print error ! // // Note: // * Be sure you have called \ref Dev_Init function before call this fuction. // * Remember to check return value. // //*************************************************************************************** extern int Dev_PrintInt(int number); 注释信息写完了,一般来说,函数能达到这种信息程度就ok了,但既然要生成文档,就不得不考虑一个问题 如果你是Doxygen作者,怎么从上面的注释里面提取信息呢,信息那么多,有*号,有各种文字信息。 你可以将所有的注释信息都输出出来,但这么做,等于没有分类整理,同时也包含了杂乱信息,比如一排* 另外一个解决方法是:设置某些特殊字符,比如function表示,一旦检测到这个特殊标记,则认为是接下来 也许你会说了,可以采用 FUNCTION这种形式啊,恩,这么做是可行的,可以确保识别出来特殊标记 接下来,还有一个问题,我们上面的注释中,有很多*号,仅仅起到美观和格式化的作用,当然不希望在 *,ok,假设用户同意这么做。那接下来呢,如果我希望在代码中写某些话 正向思考遇到问题时,不妨反向考虑,这是谁的问题:是我设计思路的问题还是用户用法的问题? 困难重重,肯定是设计思路的问题 如果设计一个标记符,将普通注释和要生成的文档注释区分开来,就能解决问题了。 Doxygen的用法,说白了,就是为了解决上面提到的两个问题: 怎么区分普通注释和输出注释 怎么在输出注释里面,识别特殊标记和普通文本 ok,讲到这里,基本把Doxygen的机制给解释清楚了,如果您还不理解,最简单的方法就是把你假设为Doxygen 下面咱们看看Doxygen怎么解决这两个问题的 区分普通注释和特殊注释 对于C/C++语言来说,注释形式有两种 // /* */ Doxygen通过在这里增加*,/,!来作为特殊标记,比如 对于/* */这种注释来说,正常注释为 /* * 正常注释 */ Doxygen在注释第一个*后,设置*或!作为标志,如果检测到有这些, /** * 要输出成文档的注释 */ 或者 /*! * 要输出成文档的注释 */ 同时,中间的*号可以省略,像这样 /** 要输出成文档的注释 */ 或者 /*! 要输出成文档的注释 */ 对于//这种类型的注释,Doxygen在第二个/后,增加!或/作为区分标志,如果检测到有这些, /// 要输出成文档的注释 或者 //! 要输出成文档的注释 对于这种呢,有一个潜在的问题,很多时候,我们需要在把注释放到后面,比如下面这种 #define DEV_ON ((int)(1)) //! Simple device is power on. #define DEV_OFF ((int)(0)) //! Simple device is power off. 如果真要这么写的话,Doxygen会把//! Simple device is power on.当做DEV_OFF的注释,这 !后 <标志符,如果检测到这个,则认为这个注释是为前面代码准备的,所以,上面的注释应该 #define DEV_ON ((int)(1)) //!< Simple device is power on. #define DEV_OFF ((int)(0)) //!< Simple device is power off. 做到这里,Doxygen就可以正确区分普通注释和特殊注释了。 **注:**提到特殊标记,其实吧,编程语言非常常用,比如HTML就是典型的markup语言,一堆一堆的括号,看着就头疼 Doxygen采用\和@作为特殊标记符,当在特殊注释里面检测到了特殊标记符,则接下来检测紧跟单词是不是Doxygen \和@解释为普通文本,聪明吧 可能有点拗口,下面给你个例子 //*************************************************************************************** // //! \brief Print Int number to terimal device. //! //! \param [in] number is the data you want to print. //! \retval the number of print information, in bytes. return zero indicate print error !. //! //! \note //! * Be sure you have called \ref Dev_Init function before call this fuction. //! * Remember to check return value. // //*************************************************************************************** extern int Dev_PrintInt(int number); 看到了吧,这里的\brief和\param都是特殊符号,表示简要描述和参数。万一你小手一抖,把\param \parame,那就悲剧了,因为Doxygen不认识parame,所以它会把这句话当做是普通文本来处理 其实,上面的\换成@也是ok的,如下所示 //*************************************************************************************** // //! @brief Print Int number to terimal device. //! //! @param [in] number is the data you want to print. //! @retval the number of print information, in bytes. return zero indicate print error !. //! //! @note //! * Be sure you have called \ref Dev_Init function before call this fuction. //! * Remember to check return value. // //*************************************************************************************** extern int Dev_PrintInt(int number); 相信某些玩过ARM芯片的,对这类注释非常熟悉,官方库都是采用Doxygen语法规则注释的 示例 采用Doxygen语法为main.c dev.c dev.h添加注释信息,完成后的效果如下所示: main.c //*************************************************************************************** // //! \file main.c //! This is an simple example show developer how to use dev api to print int number. //! //! \author Cedar //! \version V1.0 //! \date 2014-03-23 //! \copyright GNU Public License V3.0 // //*************************************************************************************** #include "dev.h" #define CNT_MAX 10 //!< The maxium number of print //! Simple device example. void DEV_Example(void) { int i = 0; Dev_Init(); for (i = 0; i < CNT_MAX; ++i) { Dev_PrintInt(i); } Dev_Close(); } //! Application Entry int main(void) { DEV_Example(); return 0; } dev.c //*************************************************************************************** // //! \file dev.c //! the implement of simple device. //! //! \author Cedar //! \version V1.0 //! \date 2014-03-23 //! \copyright GNU Public License V3.0 // //*************************************************************************************** //! Simple device status. //! //! \warning This variable is designed for internal, user \b MUST \b NOT call it. static int __DevStatus = 0 void Dev_Init(void) { // Print debug information printf("Dev Initialize OK!\r\n"); } int Dev_PrintInt(int number) { printf("Print IntType number: %d\r\n", number); } int Dev_StatusCheck(void) { return (__DevStatus); } void Dev_Close(void) { printf("Dev Close OK!\r\n"); } dev.h //*************************************************************************************** // //! \file dev.h //! Simple device user API. //! //! \author Cedar //! \version V1.0 //! \date 2014-03-23 //! \copyright GNU Public License V3.0 // //*************************************************************************************** #include <stdio.h> //*************************************************************************************** // //! \addtogroup Dev_Status Simple device status information. //! @{ // //*************************************************************************************** #define DEV_ON ((int)(1)) //!< Simple device is power on. #define DEV_OFF ((int)(0)) //!< Simple device is power off. //*************************************************************************************** // //! @} // //*************************************************************************************** //*************************************************************************************** // //! \addtogroup Dev_API Simple device APIs list. //! @{ // //*************************************************************************************** //*************************************************************************************** // //! \brief Initialize simple device. //! //! \param none. //! \retval none. //! //! \note This function \b MUST be called first before others function. // //*************************************************************************************** extern void Dev_Init(void); //*************************************************************************************** // //! \brief Print Int number to terimal device. //! //! \param [in] number is the data you want to print. //! \retval the number of print information, in bytes. return zero indicate print error !. //! //! \note //! * Be sure you have called \ref Dev_Init function before call this fuction. //! * Remember to check return value. // //*************************************************************************************** extern int Dev_PrintInt(int number); //*************************************************************************************** // //! \brief Check simple device status information. //! //! \param none. //! \retval status information of simple device, which can be one of the following value:\n //! - \ref DEV_ON //! - \ref DEV_OFF //! \n More information, please reference \ref Dev_Status. // //*************************************************************************************** extern int Dev_StatusCheck(void); //*************************************************************************************** // //! \brief Close simple device. //! //! \param none. //! \retval none. // //*************************************************************************************** extern void Dev_Close(void); //*************************************************************************************** // //! @} // //*************************************************************************************** //*************************************************************************************** // //! \example main.c //! Show how to use simple device to print int number. // //*************************************************************************************** 4. 生成文档 $ doxygen <config-file> Win 图形界面使用 第1章 安装 在Linux下可以通过apt install doxygen安装命令行工具,然后用apt install doxygen-gui安装图形界面。对Linux用户来说,命令行工具可以通过doxygen命令运行,而图形界面可以通过doxywizard命令运行。 而Windows用户可以在这里下载,安装完毕后,直接双击就能运行图形界面。 1.1 基本使用 图形工具的基本使用如下图所示,有非常多的配置选项,这里我们只填入必要的配置,其它配置都用默认值。 我们的工作目录如下: . ├── out └── src └── math.h 其中math.h代码如下: /*! \file math.h */ /*! 用于求一个角度的sin值,输入是字符串以便同时支持弧度制和角度制表示 \li 弧度制用pi表示,例如:2pi表示一圈、0.5pi表示直角 \li 角度制用d结尾,例如:360d表示一圈、90d表示直角 \li 输入也可以是数值,例如:输入3.14159大约表示180度 \param a 用弧度制或角度制表示都行,字符串必须用'\0'表示结束 \param[out] res 是输出参数,用于保存sin运算的结果 \return 错误码,0表示成功,其它表示失败 \todo 在xxx的情况下存在BUG,预计下一版本修复 */ int sin(char *a, double *res); Doxygen生成的HTML会放到out目录下,生成的HTML如图1-3所示。 1.2 保存配置 在1.1节中我们配置了一些选项,也成功生成了HTML文档。我们希望下次代码改动后能够继续沿用上次配置,那么我们可以把这些配置保存成Doxyfile文件,见图1-4。 1.3 命令行运行Doxygen 有了配置文件后我们完全可以通过命令行来生成API文档,假设配置文件名为Doxyfile,那么我们只需要执行doxygen /path/to/Doxyfile即可生成API文档。 通过命令行生成文档有许多好处,其中最主要的好处就是:能够集成到持续集成之类的自动化系统中。 第2章 为代码编写注释 2.1 什么样的注释会被Doxygen识别? Doxygen能识别这几种风格的注释: /** * ... text ... */ /*! * ... text ... */ /// /// ... text ... /// //! //!... text ... //! 文件的开头必须有文件注释,否则该文件不会被识别: /*! \file math.h */ 2.2 注释怎么写 这个自己看官网例子体会吧。 第3章 为其它编程语言生成注释 Doxygen主要支持C语言,其它语法跟C差不多的语言(如:C++/C#/PHP/Java)也能够支持,我们称这类语言为「C语系语言」。而哪些跟C语法差异较大的语言叫做「非C语系语言」。 对于大多非C语系语言,Doxygen都是支持的,Doxygen原生支持这些语言:IDL、Java、Javascript、C#、C、C++、D、PHP、Objective-C、Python、Fortran、VHDL。 万一项目需要的语言(例如:Lua)Doxygen官方并不支持,那么只能自行编写「第三方语言扩展」来支持了。 3.1 Doxygen官方支持的语言 见图3-1,文件名符合FILE_PATTERNS都会被处理。其中包括了.c、.h、.py等等。 如果我们的扩展名并不在FILE_PATTERNS内,那么可以加上去。例如我们项目下的所有.ccc文件,其实是C语言代码(这很奇葩,举个例子而已)。那我们可以编辑Doxyfile配置文件满足这一需求,需要2个步骤。 (1) 在FILE_PATTERNS中添加*.ccc,如图3-2 (2) 在EXTENSION_MAPPING中添加映射规则ccc=C,如图3-3。语法是ext=language,其中language可以取的值有:IDL、Java、Javascript、C#、C、C++、D、PHP、Objective-C、Python、Fortran、VHDL。 3.2 Doxygen官方不支持的语言 以Lua语言为例,它的代码是长这样的: -- \file lmath.h --[[ 用于求一个角度的sin值,输入是字符串以便同时支持弧度制和角度制表示 \li 弧度制用pi表示,例如:2pi表示一圈、0.5pi表示直角 \li 角度制用d结尾,例如:360d表示一圈、90d表示直角 \li 输入也可以是数值,例如:输入3.14159大约表示180度 \param a 字符串类型,表示角度,用弧度制或角度制表示都行 \return 返回sin运算的结果 \todo 在xxx的情况下存在BUG,预计下一版本修复 --]] function sin(a) return 1.123 end 可以看到Lua的语法既不像C也不像Python。本节以Lua为例,介绍如何为Doxygen编写Lua语言扩展。 第4章 定制Doxygen的输出 4.1 定制页面样式 Doxygen输出的默认HTML比较难看,如图4-1。 如果嫌生成的HTML不好看,可以自定义HTML页面头部、尾部以及页面整体CSS样式表。 doxygen -w html header.html footer.html customdoxygen.css,可以生成header.html、footer.html、customdoxygen.css。 HTML_HEADER、HTML_FOOTER、HTML_STYLESHEET指向修改后的文件,如图4-2。 Doxygen默认的页面主色调大约是天蓝色的,可以通过HTML_COLORSTYLE_HUE、HTML_COLORSTYLE_SAT、HTML_COLORSTYLE_GAMMA修改主色调,这3个配置分别对应色相、饱和度、Gamma校正,见图4-3。如果不太懂色相、饱和度是啥意思,请自行百度「色彩模式」或参考Photoshop相关教程。 经过图4-3的修改,页面的主色调变为图4-4的样子。 4.2 导航栏 Doxygen中「导航栏」有两种展示方式:Treeview和Index,分别是竖向和横向的,如图4-5。 可以配置DISABLE_INDEX和GENERATE_TREEVIEW来控制是否显示它们,如图4-6。 4.3 自定义「导航栏」的目录结构 我们已经知道Doxygen中「导航栏」有Treeview和Index两种了。这节介绍如何定制导航栏的目录结构。这需要三个步骤。 doxygen -l,生成DoxygenLayout.xml文件 DoxygenLayout.xml文件,修改其中的布局 LAYOUT_FILE配置,使其指向DoxygenLayout.xml文件,如图4-7 那么如何修改XML文件呢?默认的DoxygenLayout.xml代码如下: <doxygenlayout version="1.0"> <navindex> <tab type="mainpage" visible="yes" title=""/> <tab type="pages" visible="yes" title="" intro=""/> <tab type="modules" visible="yes" title="" intro=""/> <tab type="namespaces" visible="yes" title=""> <tab type="namespacelist" visible="yes" title="" intro=""/> <tab type="namespacemembers" visible="yes" title="" intro=""/> </tab> <tab type="classes" visible="yes" title=""> <tab type="classlist" visible="yes" title="" intro=""/> <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> <tab type="hierarchy" visible="yes" title="" intro=""/> <tab type="classmembers" visible="yes" title="" intro=""/> </tab> <tab type="files" visible="yes" title=""> <tab type="filelist" visible="yes" title="" intro=""/> <tab type="globals" visible="yes" title="" intro=""/> </tab> <tab type="examples" visible="yes" title="" intro=""/> </navindex> </doxygenlayout> XML对应了导航栏的目录树结构,我们通过该文件改变布局。标签的type属性取值除了上面列出的这些预定义值以外,还可以是type="user"或type="usergroup",我们只能通过这两个type自定义布局,例如下面这段代码,生成的效果如图4-8: <doxygenlayout version="1.0"> <navindex> <tab type="usergroup" visible="yes" title="友情链接(演示如何外链)"> <tab type="user" visible="yes" title="百度" url="http://www.baidu.com" /> <tab type="user" visible="yes" title="163" url="http://www.163.com" /> </tab> <tab type="usergroup" visible="yes" title="数学库(演示如何链接文件)"> <tab type="user" visible="yes" url="@ref math.h" title="math" /> <tab type="user" visible="yes" url="@ref math2.h" title="math2" /> </tab> <tab type="usergroup" visible="yes" title="三角函数(演示链接函数、结构体)"> <tab type="user" visible="yes" url="@ref sin" title="sin" /> <tab type="user" visible="yes" url="@ref sin2" title="sin2" /> </tab> </navindex> </doxygenlayout> 4.4 完全自定义 如果Doxygen输出的界面实在不入你的法眼,4.1~4.3介绍的定制化功能也不能彻底满足你的需求。那么你需要根据Doxygen输出的XML数据自行生成界面了。 GENERATE_XML配置为YES 第5章 Markdown支持 待补充完善 Markdown在工业界是非常流行的文档格式,文件名以.md结尾,其简洁直观的语法深受广大程序员喜爱。对Markdown本身的介绍超出了本文范围,本章介绍Doxygen对Markdown的支持。 5.1 为.md文件生成文档 5.2 在代码注释中使用Markdown语法 第6章 搜索功能 Gitlab CI/CD使用 https://gitlab.com/pages/doxygen 结合Docker和Gitlab CI/CD使用案例 参考资源 Doxygen 官网 官网注释例子 Doxygen文档生成工具教程 Doxygen 10 分钟入门教程 Gitlab CI/CD doxygen 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2022/5/28
articleCard.readMore

自建全套开源Devops开发系统

国内的Devops云平台动辄封号,删库,屏蔽,还多次发生数据泄密,项目被云平台克隆事件,国内云平台devops已死!数据安全没法保证,自建私有Devops平台才靠谱。这里采用开源项目建立一个完善的低成本Devops系统,基本运行良好! 目标:单节点,以最低成本,最低消耗,使用开源软件实现一个可用的DevOps!满足中小企业的研发、测试、运维需求。并对后续如何扩展本套DevOps系统做了项目,成本,路线升级规划,可以一直扩展到业界最前沿最大系统。 整套系统已经跑起来很长时间了!单节点Nas服务器,32G内存,共运行了约80个Docker,优化到平均负载10以下。 Devops框架图解 下面系统大多可以做负载平衡,多节点备份,可以扩展为一个高可用,大中央平台。 珍爱生命,使用Docker! 开源云平台生死连问 珍爱生命,不建议使用国内云平台。 什么是大教堂? 什么是集市? 什么是信任链? 什么是开源生态? 为什么要做开源生态? 怎么做开源生态? 开源生态的土壤肥力维护如何做? 这些问题没想明白,没想到如何做的是没法做开源的。 国内平台连种子嫩芽都要收割,到处收费,动辄删库,屏蔽,封号,注定做不了开源生态。 Consul自动负载均衡 基于服务自动发现和注册的负载均衡,负载均衡的方式没有变,只是多了一些外围组件,当然这些组件对 Client 是不可见的,client 依然只能看到 Nginx 入口,访问方式也没变化。 Github仓库备份 最优秀的资源,大多只在短时间内出现! 平时多备份你重要的仓库,以及你使用的仓库的重要上下游仓库! github-backup Githb github-backup Dockerhub githubback: image: lnxd/github-backup container_name: "githubback" hostname: githubback # ports: # - "80:80" volumes: - "${USERDIR}/githubback/data:/home/docker/backups:rw" env_file: - .env environment: - HTTP_PROXY=http://[ip]:[port] - HTTPS_PROXY=http://[ip]:[port] restart: always 配置要求 个人Nas配置 cpu j4125 4 核 14nm 2.00 GHz ~2.70 GHz SSD sata 接口的 读写 500MB/S 32G DDR4. 2x16G 双通道 上图中介绍的系统都是上面配置的单服务器中可以运行的。 如何以最低的配置,最少的内存运行起来最多的功能才是本文的追求,花费更多金钱去满足极少数情况的高压力是钱多的没处花。 8G内存的nas 就可以运行 gitea + drone ,zentao 想用就用 gitlab 要跑起来至少要2核 8G 内存,jenkins 也是内存 cpu 占用大户。大于 16G 内存时考虑上这个 4核 32G 内存的nas,图片中介绍的可以全都跑起来! 可靠性 ELK集群监控对于单服务器来说完全多余,netdata监控也不错,portainer就够用了,以后为了节约资源,portainer说不定也会被干掉,大多数时候命令行监控就够了。少于200节点K8S就是多余的。 数据安全 云平台把数据交给别人,赌别人的道德不会私自偷拿你的数据?真是想多了。 某垄断社交平台内部有专门的团队分析客户的数据,看有什么有价值的没有,是很多年前就爆出来的消息。 自建DevOps成本其实相当的低! 整套系统可以从少到多,从小到大,慢慢优化,扩展的。硬件成本也是随着需求变化而变化的,随着业务扩展而增加成本,一开始单节点单服务器就可以满足要求了,后面业务增加慢慢扩展为集群,k8s 等。 数据,代码是公司核心资产与竞争力的公司,上云赌别人的人品就是找死。你注册账户的时候,就同意了,无论别人随意删除你的数据,或者窃取你的数据都是不用付任何责任的,再说,整个系统数据都在别人手上,你要维权也没有证据。 备份 UPS电源,防止意外断电 rsync 备份,对于大多数人,已经够用了 文件系统快照 离线每日,或者每周冷备份 大系统,多台服务器的时候可以用多节点集群备灾。nginx,harbor,gitlab,elasticsearch等都可以使用集群 扩展性 上面说的都可以单服务器搞定。多台服务器的时候可以用多节点集群备灾。nginx,harbor,gitlab,elasticsearch等都可以使用集群。 多于200节点,大于3台服务器以后考虑上K8S。ELK监控之类的这时候可以上了。蓝鲸智云标准运维这时候也可以考虑了。 再次扩大的时候可以考虑Proxmox VE(PVE) + ceph 更大的系统,或者对外提供云平台服务的时候可以考虑上OpenStack 项目介绍 ELK 消耗资源很多,至少上百节点以上再考虑上这个 portainer -> netdata -> ELK,zabbix cacti zabbix ansible CMDB PVE Proxmox VE(PVE) CEPH OpenStack 其它项目 大家还有啥好项目建议? onedev onedev 是替代Gitlab的极佳候补,看文档介绍,潜力无限! smartdns 一个本地DNS服务器,获取最快的网站IP,获得最佳上网体验。 awesome-selfhosted 这里你能找到各种各样的自建 Docker 服务 私有Git服务器整理 ruby系:GitLab。这个没什么好说的,说到私有git服务器第一反应必然是这个,似乎也是目前已知的开源git服务器中体量最大的,功能齐全,界面美观。 golang系:Gogs、gitea、forgejo。这仨一脉相传,简单概括来说,就是先有的gogs,然后一群贡献者嫌gogs更新慢、不加新功能,然后fork出了gitea;然后gitea搞了几年之后开公司了,codeberg担心gitea搞收费,就又从gitea代码fork出了一个forgejo自己开发。 Java系:gitbucket、GitBlit、OneDev。这三家都是个搞个的,其中OneDev比较新,界面做的也比较现代化。 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 相关文档 Devops

2022/5/9
articleCard.readMore

视频图书和音乐完全自动化管理框架图解

音视频,音乐和图书管理全过程自动化解决方案框架图解!结构化你的音视频、音乐和图书资源。所有过程一张图搞定! 框架自动化构架图解 相关资源 更多相关资源可以到下面网址查看 DockerHub Github nas-tools nas-tools Github nas-tools DockerHub 推荐一下这个,作者相当勤奋,更新速度非常快!最重要的是它是国人开发,对中文支持很好!有问题提Issue,作者回复也很快! 功能: 1、资源检索 PT站聚合RSS订阅,实现资源自动追新。 通过微信、Telegram或者WEB界面聚合检索资源并择优,最新热门一键搜索或者订阅。 在豆瓣中标记,后台自动检索,未出全的自动加入RSS追更。 2、媒体识别和重命名 监控下载软件,下载完成后自动识别真实名称,硬链接到媒体库并重命名。 对目录进行监控,文件变化时自动识别媒体信息硬链接到媒体库并重命名。 支持国产剧集,支持动漫,改名后Emby/Jellyfin/Plex 100%搜刮。 3、消息服务 支持ServerChan、微信、Telegram、Bark等图文消息通知,直接在手机上控制。 4、其它 自动签到、Emby/Jellyfin/Plex播放状态通知等等。 安装 version: "3.4" services: nastools: image: jxxghp/nas-tools:latest container_name: nastools hostname: nastools # ports: # - 3000:3000 # 默认的webui控制端口 volumes: - ${USERDIR}/nastools/config:/config # 冒号左边请修改为你想保存配置的路径 - ${USERDIR}/[path]/Download:/share/Download #- /你的媒体目录:/你想设置的容器内能见到的目录 # 媒体目录,多个目录需要分别映射进来 environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} - UMASK=022 # 掩码权限,默认000,可以考虑设置为022 #- REPO_URL=https://ghproxy.com/https://github.com/jxxghp/nas-tools.git restart: always 参数配置 新版参数基本都可以在web界面配置。 也可以直接修改配置文件,配置文件中有非常详细的注释!请认真查看配置文件中的文本注释! 配置文件位置,基于docker路径/config/config.yaml 配置文件模板,可以仓库下面链接文件 https://github.com/jxxghp/nas-tools/blob/master/config/config.yaml 硬链接工具 Github appotry/PTtool nginx docker Github appotry/nginx-purge-docker nginx DockerHub prowlarr 最早是玩sonarr、radarr,然后找到i相关的全家桶,见下图 发现各种资源,结构化,Github上面都有很完善的解决方案,但大都对中文支持不好。而且各种上下游资源也是越来越丰富,看看prowlarr支持的app,基本覆盖你的所有所需!Whisparr项目的介绍惊呆了我😄 国人也有一些好项目, IYUU,nas-tools等。 FlareSolverr docker run -d \ --name=flaresolverr \ -p 8191:8191 \ -e LOG_LEVEL=info \ --restart unless-stopped \ ghcr.io/flaresolverr/flaresolverr:latest 如果成功启动,访问ip:8191将看到如下信息 { "msg": "FlareSolverr is ready!", "version": "v2.2.4", "userAgent": "Mozilla/5.0 (X11; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0" } 图书、音乐、视频三剑客! 结构化自己的图书,音乐,和视频! 视频图书和音乐完全自动化管理框架图解 音视频,音乐和图书管理全过程自动化解决方案框架图解!结构化你的音视频、音乐和图书资源。所有过程一张图搞定! 如何建立自己的私人电子图书馆--出版书籍,网络小说,漫画一网打尽! 图书管理员似乎是个非常有前途的职业,远的有孔子,游学之前当图书管理员,近的有本朝开国毛教员,也当了很长时间图书管理员。我们也可以自己做个私人电子图书馆,当个图书管理员,说不定很有前途? 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 音乐文件则是将歌名、歌手、专辑、发行时间、歌词、封面图等信息写入文件标签,称为ID3 Tag 。它能够在MP3中附加曲子的演出者、作者以及其它类别资讯,方便众多乐曲的管理。 私人在线音乐服务器搭建与使用介绍 私人在线音乐服务器搭建与使用介绍!Mstream Docker 部署, rclone 挂载 webdav 网盘。 cloudflare parterner加速 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 tinyMediaManager是最好用的视频刮削工具,可以刮削电影,动画,电视剧。使用TinyMediaManager生成nfo元数据文件,多媒体软件解析生成海报墙展示丰富的影片信息,配合Emby,Plex使用体验绝佳 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程。jackett 作为种子源,sonarr剧集管理,bt下载,qbittorrent主力下载,使用iyuu转移辅种,emby,jellyfin做海报墙,sunfinder自动下载字幕。结合本地DNS管理,DNS去广告,Nginx反向代理去端口访问,形成一个完整解决方案。 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2022/5/9
articleCard.readMore

QNAP添加man pages

默认QNAP是不带man命令的,但是,作为一个Linux重度用户怎么能忍?得想办法安装man啊!经过一番努力,最终成功安装man pages! 需求 默认QNAP是不带man命令的,但是,作为一个Linux重度用户怎么能忍? 得想办法安装man啊! 验证 先试一下 # man -sh: man: command not found 基本可以死心了。 看看busybox版本 # /bin/busybox BusyBox v1.24.1 (2022-03-24 03:13:07 CST) multi-call binary. BusyBox is copyrighted by many authors between 1998-2015. Licensed under GPLv2. See source distribution for detailed copyright notices. Usage: busybox [function [arguments]...] or: busybox --list or: function [arguments]... BusyBox is a multi-call binary that combines many common Unix utilities into a single executable. Most people will create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as. Currently defined functions: [, [[, addgroup, adduser, arping, ash, awk, base64, basename, bunzip2, bzcat, bzip2, cat, chattr, chgrp, chmod, chown, chroot, chvt, cksum, clear, cmp, cp, cpio, crond, crontab, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, df, diff, dirname, dmesg, dnsdomainname, dos2unix, du, echo, egrep, env, expr, false, fdisk, fgrep, find, free, fsync, getty, grep, groups, gunzip, gzip, halt, hd, head, hexdump, hostname, hwclock, id, ifconfig, init, insmod, install, ip, ipaddr, iplink, iproute, iprule, iptunnel, kill, killall, killall5, klogd, less, linuxrc, ln, logger, login, logread, ls, lsattr, lsmod, lspci, md5sum, mkdir, mknod, mktemp, modprobe, more, mount, mv, nameif, netstat, nslookup, openvt, passwd, pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, rdate, readlink, realpath, reboot, renice, reset, resize, rm, rmdir, rmmod, route, sed, seq, sh, sha1sum, sleep, sort, split, start-stop-daemon, stat, strings, swapoff, swapon, switch_root, sync, sysctl, syslogd, tail, tar, taskset, tee, telnet, test, tftp, time, top, touch, tr, traceroute, traceroute6, true, tty, umount, uname, uniq, unix2dos, unzip, uptime, usleep, vi, watch, wc, wget, which, whoami, xargs, yes, zcat 可以看到内置busybox不支持man的。 寻找解决方案 去看看官方Busybox是否支持 Busybox : https://busybox.net/downloads/BusyBox.html 发现是支持man的,只是QNAP没有编译进去。 解决思路 给QNAP提需求单? 是一个选择,但是太慢了,想官方内置,不知道等到猴年马月了。 QNAP似乎开发了底层SDK,记得有下载过,还没有仔细研究怎么使用。不过记得有附带编译工具链,自己动手编译一个busybox版本替代系统内置的,应该也是可行的。 去看看别人有啥解决方案? Optware has man but only for the optware installed packages (if supplied) and or manually added files in the man folder. https://forum.qnap.com/viewtopic.php?t=49961 柳暗花明又一村, entware 支持man pages,可以直接安装了。 插入entware安装方法: 打开App Center,源选择刚添加的Qnapclub,点击搜索框输入entware,选Entware-std 1.03 一条命令解决: opkg install man-db man-pages 安装完之后验证: # man fopen FOPEN(3) Linux Programmer's Manual FOPEN(3) NAME fopen, fdopen, freopen - stream open functions SYNOPSIS #include <stdio.h> FILE *fopen(const char *restrict pathname, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): fdopen(): _POSIX_C_SOURCE DESCRIPTION The fopen() function opens the file whose name is the string pointed to by pathname and associates a stream with it. The argument mode points to a string beginning with one of the following sequences (possibly followed by additional char‐ acters, as described below): r Open text file for reading. The stream is positioned at the beginning of the file. r+ Open for reading and writing. The stream is positioned at the beginning of the file. w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. 问题就这么解决了。 一个问题,我有很多其它手册,想要安装,怎么办? 安装其它man手册 已经有了man命令,只要把手册安装到entware man命令目录中就行了。 找到enteware man手册目录。 cd /share/CACHEDEV3_DATA/.qpkg/Entware find . -name "*man*" TIPS:CACHEDEV3_DATA/.qpkg这个是安装qpkg软件的磁盘。CACHEDEV3似乎是表示第三块插入机器的磁盘。 结果输出: ./bin/catman ./bin/go/misc/chrome/gophertool/manifest.json ./bin/go/pkg/linux_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a ./bin/go/src/cmd/compile/internal/types2/testdata/manual.go2 ./bin/go/src/cmd/go/internal/modconv/testdata/dockerman.glide ./bin/go/src/cmd/go/internal/modconv/testdata/dockerman.out ./bin/go/src/cmd/go/internal/modconv/testdata/govmomi.vmanifest ./bin/go/src/cmd/go/internal/modconv/vmanifest.go ./bin/go/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt ./bin/go/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt ./bin/go/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt ./bin/go/src/cmd/go/testdata/script/gccgo_mangle.txt ./bin/go/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go ./bin/go/src/cmd/vendor/github.com/ianlancetaylor/demangle ./bin/go/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go ./bin/go/src/compress/bzip2/huffman.go ./bin/go/src/compress/flate/huffman_bit_writer.go ./bin/go/src/compress/flate/huffman_bit_writer_test.go ./bin/go/src/compress/flate/huffman_code.go ./bin/go/src/compress/flate/testdata/huffman-null-max.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-null-max.golden ./bin/go/src/compress/flate/testdata/huffman-null-max.in ./bin/go/src/compress/flate/testdata/huffman-null-max.wb.expect ./bin/go/src/compress/flate/testdata/huffman-null-max.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-pi.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-pi.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-pi.golden ./bin/go/src/compress/flate/testdata/huffman-pi.in ./bin/go/src/compress/flate/testdata/huffman-pi.wb.expect ./bin/go/src/compress/flate/testdata/huffman-pi.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-rand-1k.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-rand-1k.golden ./bin/go/src/compress/flate/testdata/huffman-rand-1k.in ./bin/go/src/compress/flate/testdata/huffman-rand-1k.wb.expect ./bin/go/src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-rand-limit.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-rand-limit.golden ./bin/go/src/compress/flate/testdata/huffman-rand-limit.in ./bin/go/src/compress/flate/testdata/huffman-rand-limit.wb.expect ./bin/go/src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-rand-max.golden ./bin/go/src/compress/flate/testdata/huffman-rand-max.in ./bin/go/src/compress/flate/testdata/huffman-shifts.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-shifts.golden ./bin/go/src/compress/flate/testdata/huffman-shifts.in ./bin/go/src/compress/flate/testdata/huffman-shifts.wb.expect ./bin/go/src/compress/flate/testdata/huffman-shifts.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-text-shift.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-text-shift.golden ./bin/go/src/compress/flate/testdata/huffman-text-shift.in ./bin/go/src/compress/flate/testdata/huffman-text-shift.wb.expect ./bin/go/src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-text.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-text.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-text.golden ./bin/go/src/compress/flate/testdata/huffman-text.in ./bin/go/src/compress/flate/testdata/huffman-text.wb.expect ./bin/go/src/compress/flate/testdata/huffman-text.wb.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-zero.dyn.expect ./bin/go/src/compress/flate/testdata/huffman-zero.dyn.expect-noinput ./bin/go/src/compress/flate/testdata/huffman-zero.golden ./bin/go/src/compress/flate/testdata/huffman-zero.in ./bin/go/src/compress/flate/testdata/huffman-zero.wb.expect ./bin/go/src/compress/flate/testdata/huffman-zero.wb.expect-noinput ./bin/go/src/go/parser/performance_test.go ./bin/go/src/go/printer/performance_test.go ./bin/go/src/go/types/testdata/manual.go2 ./bin/go/src/image/jpeg/huffman.go ./bin/go/src/vendor/golang.org/x/net/http2/hpack/huffman.go ./bin/go/test/bench/go1/mandel_test.go ./bin/go/test/abi/many_int_input.go ./bin/go/test/abi/many_int_input.out ./bin/go/test/abi/many_intstar_input.go ./bin/go/test/abi/many_intstar_input.out ./bin/man ./bin/mandb ./bin/manpath ./etc/man_db.conf ./lib/opkg/info/man-db.conffiles ./lib/opkg/info/man-db.control ./lib/opkg/info/man-pages.list ./lib/opkg/info/man-db.list ./lib/opkg/info/man-pages.control ./lib/opkg/info/man-pages.postinst ./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.opt-1.pyc ./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.opt-2.pyc ./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.opt-2.pyc ./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.pyc ./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.pyc ./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.pyc ./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.opt-1.pyc ./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.opt-1.pyc ./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.opt-2.pyc ./lib/python3.10/encodings/hp_roman8.pyc ./lib/python3.10/encodings/mac_roman.pyc ./lib/python3.10/encodings/mac_romanian.pyc ./lib/tcl8.5/encoding/macRoman.enc ./lib/tcl8.5/encoding/macRomania.enc ./lib/groff/groffer/man.pl ./lib/man-db ./lib/man-db/libman-2.10.2.so ./lib/man-db/libman.so ./lib/man-db/libmandb-2.10.2.so ./lib/man-db/libmandb.so ./lib/man-db/manconv ./share/zoneinfo/Asia/Amman ./share/zoneinfo/Asia/Kathmandu ./share/zoneinfo/Asia/Katmandu ./share/doc/man-db ./share/doc/man-db/man-db-manual.ps ./share/doc/man-db/man-db-manual.txt ./share/groff/1.22.4/tmac/man.tmac ./share/groff/1.22.4/tmac/mandoc.tmac ./share/groff/site-tmac/man.local ./share/man ./share/man/man1 ./share/man/man1/man-recode.1 ./share/man/man1/man.1 ./share/man/man1/manconv.1 ./share/man/man1/manpath.1 ./share/man/man5 ./share/man/man5/manpath.5 ./share/man/man8 ./share/man/man8/catman.8 ./share/man/man8/mandb.8 ./share/man/man2 ./share/man/man3 ./share/man/man4 ./share/man/man6 ./share/man/man7 ./share/man/man7/man-pages.7 ./share/man/man7/man.7 ./var/cache/man 很显然,路径就在/share/CACHEDEV3_DATA/.qpkg/Entware/share//man/中了。 那么,安装完entware之后,其它的man 手册放到 /share/CACHEDEV3_DATA/.qpkg/Entware/share/man这个目录中就行了。 把gh git等手册放进去。再次验证 man gh GH(1) GitHub CLI manual GH(1) NAME gh - GitHub CLI SYNOPSIS gh <command> <subcommand> [flags] DESCRIPTION Work seamlessly with GitHub from the command line. CORE COMMANDS gh-auth(1) Authenticate gh and git with GitHub gh-browse(1) Open the repository in the browser gh-codespace(1) Connect to and manage your codespaces gh-gist(1) Manage gists gh-issue(1) Manage issues gh-pr(1) Manage pull requests gh-release(1) Manage releases gh-repo(1) Manage repositories ACTIONS COMMANDS 完美收工! 可能需要注意的地方,注意man手册的权限644,如果手册copy进去了,发现使用不了。运行下面命令。 chmod 644 -R /share/CACHEDEV3_DATA/.qpkg/Entware/share/man 安装更多的man pages Git手册下载地址: https://mirrors.edge.kernel.org/pub/software/scm/git/ 中文man手册: https://github.com/man-pages-zh/manpages-zh PS: 中文man手册有不少依赖需要解决,在Docker中已经可以查询中文man了,qnap中试了下,解决依赖搞得头大,暂时就docker中用中文man好了 真正收工了! 附录 man介绍 man命令并非仅仅能查看命令或者函数的介绍,在linux中,有丰富的帮助手册信息,并且每一个手册都有一个编号。编号和对应内容如下: 编号 代表内容 1 可执行程序或shell命令,如ls 2 系统调用,如chdir 3 库函数,如printf 4 设备或特殊文件,如tty 5 配置文件格式或约定 6 游戏 7 杂项 8 管理命令,通常只有root用户可以使用 9 内核例程 n 内置命令,如cd 常用快捷键 手册内容 多数手册包含以下几部分内容: NAME 功能的简单描述 SYNOPSIS 语法格式 DESCRIPTION 描述 OPTIONS 选项 ERRORS 描述出错场景,这在排查错误时很有帮助 NOTES 注意事项 FILES 相关文件,例如对于man命令的FILES部分内容显示了它的配置文件位置等信息 EXAMPLES 使用示例,会提供一些简单的示例 BUGS 存在的bug,当遇到奇怪的问题时,不妨看看当前命令是否有已知的bug 基本查看 手册的查看和less查看文本类似,可以参考《文本查看篇》或查看less命令的使用,这里介绍基本操作: 空格 向下翻页 Home 回到第一页 End 跳到最后一页 /string 向前搜索string字符串 ?string 向后搜索string字符串 n 下一个匹配字符 N 上一个匹配字符 q 退出

2022/4/21
articleCard.readMore

Git介绍以及分支模型图解

不废话,直接上图。 由 Drawio 绘制 GIT架构 GIT的架构,可以分为几个部分: 本地工作区(working directory) 暂存区(stage area, 又称为索引区, index)、 本地仓库(local repository)、 远程仓库副本 远程仓库(remote repository)。 工作区(working directory) 简言之就是你工作的区域。对于git而言,就是的本地工作目录。工作区的内容会包含提交到暂存区和版本库(当前提交点)的内容,同时也包含自己的修改内容。 暂存区(stage area, 又称为索引区index) 是git中一个非常重要的概念。是我们把修改提交版本库前的一个过渡阶段。查看GIT自带帮助手册的时候,通常以index来表示暂存区。在工作目录下有一个.git的目录,里面有个index文件,存储着关于暂存区的内容。git add命令将工作区内容添加到暂存区。 本地仓库(local repository) 版本控制系统的仓库,存在于本地。当执行git commit命令后,会将暂存区内容提交到仓库之中。在工作区下面有.git的目录,这个目录下的内容不属于工作区,里面便是仓库的数据信息,暂存区相关内容也在其中。 远程版本库(remote repository) 与本地仓库概念基本一致,不同之处在于一个存在远程,可用于远程协作,一个却是存在于本地。通过push/pull可实现本地与远程的交互; 远程仓库副本 可以理解为存在于本地的远程仓库缓存。如需更新,可通过git fetch/pull命令获取远程仓库内容。使用fech获取时,并未合并到本地仓库,此时可使用git merge实现远程仓库副本与本地仓库的合并。 .git介绍 .git目录下各个文件中所存放的内容信息: HEAD 当前所在位置,其实就是工作区的在版本库中的那个提交点,最终会指向一个40位的HASH值; config 当前版本库的专有配置文件,如使用命令git config user.name poloxue便会记录在此文件; description 被gitweb (Github的原型)用来显示对repo的描述。 hooks git有可自动运行在 git 任有意义阶段的脚本hooks, 如commit/release/pull/push等状态之前或者之后。个人思考的一个用处,如pre-push可以用来强制进行代码检查。 index 存放暂存区(stage area)的相关信息; info/exclue 可以做到和.gitignore相同的事情,用于排除不要包含进版本库的文件。区别就是,此文件不会被共享。 refs/heads 目录下有关于本地仓库的所有分支; refs/remote 目录下有关于远程仓库的所有分支; object 目录下存放的就是实际的数据文件 Commitizen Commitizen——标准化的Git commit工具 Commitizen 分为两部分,脚手架(cz-cli) 和 规范(Adapters) 脚手架可以帮助我们初始化和构建 Commitizen,而规范是开发者可以自定义的内容 官方默认提供的规范是 cz-conventional-changelog 同时,官方也提供了一些优秀的第三方规范,例如你肯定想要的表情包commit规范:cz-emoji-conventional 本文也将提供这两种规范的安装和使用方式 安装 一条命令搞定 npm install -g commitizen 这就安装成功了,而且是全局安装,以后再用就不用重复安装了 当然,安装成功的只是一个脚手架,现在还不能使用 创建 package.json Commitizen 基于 nodejs,想要使用的话,在你的项目中自然需要一个 package.json 如果已经存在了那最好,没有的话,例如是一个 java 项目,那么你可以在项目根目录执行以下命令 npm init 当然,如果不是 nodejs 的项目,你肯定不需要将这些文件也上传到 git 你可以在 .gitignore 文件中加入下面几句来忽略这些文件 package-lock.json package.json node_modules/ 初始化 这一步就可以选择我们需要的规范了 windows commitizen init 规范名称 --save-dev --save-exact linux commitizen init 规范名称 --yarn --dev --exact commitizen 脚手架会自动帮我们导入规范的依赖并进行下载,所以你只要注意不要写错规范名称就好了 关于这些名称,可以参考 这里推荐的规范 例如你想使用默认的规范 那么可以这样写: commitizen init cz-conventional-changelog --save-dev --save-exact 而如果你想使用带表情包的,就这样写: commitizen init cz-emoji-conventional --save-dev --save-exact 使用 使用的方式很简单,将你原本要输入的 git commit 命令替换为 git cz 即可 当你的控制台出现这样的界面,你可以使用方向键的 ↑ 和 ↓ 来移动光标选择这次 commit 的 type 按回车 enter 进行选择 常用的 type 有: 英文 含义 feat 新特性,新功能 fix 修bug docs 更新文档 style 修改代码风格、代码格式(不影响代码运行的变动) refactor 重构代码(既不是新增功能,也不是修改bug,可以理解为觉得原本写太烂了,重新写了一遍) perf 优化性能、优化体验 test 测试 chore 构建过程或者辅助工具的变动 revert 回滚版本 merge 代码合并 sync 同步主线或分支 随后,根据提示输入相关信息即可 例如 scope 作用域,也就是这次变动影响的范围,例如数据层,控制层,或者单单某个类 subject / description 描述,cz 将描述分为简短描述和详细描述,使用几下就清楚了 除此以外,cz 还会提示你这次变动是否与某个 issue 有关等等 变更规范 上面是在初始化时选择的规范,如果在后期我们想要变更该怎么做? 首先,脚手架只有在初始化才能帮我们自动管理依赖 后期想要变动,就得手动下载依赖了 例如初始化时用的是官方默认的规范 那么这时候你的package.json里面会有这样一段代码 "config": { "commitizen": { "path": "node_modules/cz-conventional-changelog" } } 我们如果想要换成有表情包的规范形式 cz-emoji-conventional 首先需要下载依赖,当然是要在项目根目录执行: npm i cz-emoji-conventional 然后修改上面 package.json 中的配置 "config": { "commitizen": { "path": "node_modules/cz-emoji-conventional" } } 到这里,规范就修改完成了 全局安装 上面所讲的安装方式仅适用于项目内,也就是每一个项目都会创建node_modules并安装依赖。 如果需要在电脑上任意地方都能用 git cz 命令,需要进行全局安装: 脚手架 npm install -g commitizen 选择一个规范,参考上文:npm install -g cz-emoji-conventional 在用户目录下创建文件 .czrc Windows:C:\user\用户名 Linux: /home 编辑 .czrc 文件,写入规范名称: { "path": "cz-emoji-conventional" } 参考 Git 教程 Git book 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等

2022/4/19
articleCard.readMore

PMBOK指南(第6版)

PMBOK 只是一套悬在空中的方法论,要想具体落地还需要具体的行业知识。两条腿,缺一不可!瘸腿项目管理有还不如没有,由部门管理或者研发兼任也行。PMBOK 是基础中的基础知识,了解总是没有坏处的。是常识,不懂就没法做,但要做项目管理,光PMBOK远远不够。 [ 管理收益 - 管理成本 >= 0 ] [ 管理收益 - 管理成本 <= 0 ] 可以看到项目管理其实只是企业管理中很小的一部分 1 引论 1.2 基本要素 1.2.1 项目 项目是为创造独特的产品、服务或成果而进行的临时性工作。 独特的产品、服务或成果 开展项目是为了通过可交付成果达成目标。 可交付成果指的是在某一个过程、阶段或项目完成时,必须产出的任何独特性并可核实的产品、成果或服务能力,可以是有形的,也可以是无形的。 一个独特的产品,可能是其他产品的组成部分、某个产品的升级版或修正版,也可能其本身就是新的最终产品; 一种独特的服务或提供某种服务的能力; 一项独特的成果,例如某个结果或文件; 一个或多个产品、服务或成果的独特组合。 某些项目可交付成果和活动中可能存在重复的元素,但这种重复并不会改变项目本质上的独特性。 临时性工作 项目的“临时性”是指项目有明确的起点和终点。 “临时性”并不意味着项目的持续时间短。 虽然项目是临时的,但是项目产生的可交付成果可能会在项目的终止后依然存在。 项目驱动变革 从商业角度来看,项目旨在推动组织从一个状态转到另一个状态,从而达成特定目标。 在项目开始之前,通常将此时的组织描述为“当前状态”,项目驱动变革是为了获得期望的结果,即“将来状态”。 项目创造商业价值 项目的商业价值指特定项目的成果能够为相关方带来的效益。 项目带来的效益可以是有形的(货币资产、市场份额等)、无形的(品牌认知度、荣誉等)或两者兼有之。 项目启动背景 符合法规、法律或社会要求; 满足相关方的要求或需求; 执行、变更业务或技术战略; 创造、改进或修复产品、过程或服务。 如何将示例因素归入一个或多个基本因素类别 1.2.2 项目管理的重要性 项目管理就是将知识、技能、工具与技术应用于项目活动,以满足项目的要求。项目管理通过合理运用与整合特定项目所需的项目管理过程得以实现。项目管理使组织能够有效且高效地开展项目。 达成业务目标; 满足相关方的期望; 提高可预测性; 提高成功的概率; 在适当的时间交付正确的产品; 解决问题和争议; 及时应对风险; 优化组织资源的使用; 识别、挽救或终止失败项目; 管理制约因素(例如范围、质量、进度、成本、资源); 平衡制约因素对项目的影响(例如范围扩大可能会增加成本或延长进度); 以更好的方式管理变更。 1.2.3 项目、项目集、项目组合以及运营管理之间的关系 1.2.3.1 概述 项目集:项目集是一组相互关联且被协调管理的项目、子项目集和项目集活动,以便获得分别管理所无法获得的利益。项目集不是大项目,大项目指规模特别大的项目。 项目组合:项目组合是指为实现战略目标而组合在一起的项目、项目集、子项目组合和运营工作。 项目集、项目、共享资源和相关方之间的关系 从组织的角度看项目、项目集和项目组合管理: 项目集和项目管理的重点在于以“正确”的方式开展项目集和项目; 项目组合管理则注重于开展“正确”的项目集和项目。 项目组合、项目集与项目组合管理的比较 1.2.3.2 项目集管理 项目集管理指在项目集中应用知识、技能与原则来实现项目集的目标,获得分别管理项目集组成部分所无法实现的利益和控制。 项目集管理注重项目与项目以及项目与项目集之间的依赖关系。 1.2.3.3 项目组合管理 项目组合管理是指为了实现战略目标而对一个或多个项目组合进行的集中管理。 项目组合中的项目集或项目不一定彼此依赖或直接相关。 项目组合管理的目的: 指导组织的投资决策; 选择项目集与项目的最佳组合方式,以达成战略目标; 提供决策透明度; 确定团队和实物资源分配的优先顺序; 提高实现预期投资回报的可能性; 实现对所有组成部分的综合风险的集中式管理; 确定项目组合符合组织战略。 1.2.3.5 运营与项目管理 项目与运营会在产品生命周期的不同时点交叉,例如: 在新产品开发、产品升级或提高产量时; 在改进运营或产品开发流程时; 在产品生命周期结束阶段; 在每个收尾阶段。 1.2.4 指南的组成部分 PMBOK指南关键组成部分的描述 PMBOK指南关键组成部分在项目中的相互关系 1.2.4.1项目和开发生命周期 项目生命周期指项目从启动到完成开始到结束所经历的一系列阶段。 项目生命周期内通常有一个或多个阶段与产品、服务或成果的开发相关,这些阶段成为开发生命周期。开发生命周期可以是预测型、迭代型、增量型、适应型或混合型的模式。 预测型:在生命周期早期阶段确定项目范围、时间和成本。 迭代型:范围通常于项目生命周期的早期确定,但时间及成本估算将随着项目团队对产品理解的不断深入而定期修改。迭代方法是通过一系列重复的循环活动来开发产品,而增量方法是渐进地增加产品的功能。 增量型:通过在预定的时间区间内渐进增加产品功能的一系列迭代来产出可交付成果。 适应型:也称为敏捷或变更驱动型,详细范围在迭代开始之前就得到了定义和批准。 混合型:预测型和适应型的组合。 1.2.4.2 项目阶段 项目阶段是一组具有逻辑关系的项目活动的集合,通常以一个或多个可交付成果的完成为结束。 生命周期的各个阶段可以通过各种不同的属性来描述。 属性可能包括(但不限于):名称、数量、持续时间、资源需求、项目进入某一阶段的准入标准、项目完成某一阶段的退出标准。 项目分为多个阶段的方式有助于更好地掌控项目管理,同时还提供了评估项目绩效并在后续阶段采取必要的纠正或预防措施的机会。 1.2.4.3 阶段关口 阶段关口设立在阶段结束点,在该时点,把项目及进展与各种项目文件及业务文件(项目商业论证、项目章程、项目管理计划、效益管理计划)进行比较,并根据比较结果做出决定,以便: 进入下个阶段; 整改后进入下个阶段; 结束项目; 停留在当前阶段; 重复阶段或某个要素。 1.2.4.4 项目管理过程 项目生命周期是通过一系列项目管理活动进行的,即项目管理过程。每个项目管理过程通过合适的项目管理工具和技术将一个或多个输入转化成一个或多个输出。一个过程的输出通常成为以下二者之一:另一个过程的输入;项目或项目阶段的可交付成果。 过程通常分三类: 仅开展一次或仅在项目预定义点开展的过程,如制定章程; 根据需要定期开展的过程,如需要采购时开展采购过程; 在整个项目期间持续开展的过程,如开展监控过程。 1.2.4.5 项目管理过程组 启动过程组:定义一个新项目或现有项目的一个新阶段,授权开始该项目/阶段的一组过程; 规划过程组:明确项目范围,优化目标,为实现目标制定行动方案的一组过程; 执行过程组:完成项目管理计划中确定的工作,以满足项目要求的一组过程; 监控过程组:跟踪、审查和调整项目进展与绩效,识别必要的计划变更并启动相应变更的一组过程; 收尾过程组:正式完成或结束项目、阶段或合同所执行的过程。 1.2.4.6 项目管理知识领域 项目整合管理:为识别、定义、组合、统一和协调各项目管理过程组的各个过程和活动而开展的过程与活动。 项目范围管理:确保项目做且只做所需的全部工作以成功完成项目的各个过程。 项目进度管理:管理项目按时完成所需的各个过程。 项目成本管理:为使项目在批准的预算内完成而对成本进行规划、估算、预算、融资、筹资、管理和控制的各个过程。 项目质量管理:把组织的质量政策应用于规划、管理、控制项目和产品质量要求,以满足相关方的期望的各个过程。 项目资源管理:识别、获取和管理所需资源以完成项目的各个过程。 项目沟通管理:为确保项目信息及时且恰当地规划、收集、生成、发布、存储、检索、管理、控制、监督和最终处置所需的各个过程。 项目风险管理:包含规划风险管理、识别风险、开展风险分析、规划风险应对、实施风险应对和监督风险的各个过程。 项目采购管理:从项目团队外部采购或获取所需产品、服务或成果的各个过程。 项目干系人管理:识别影响或受项目影响的人员、团队或组织,分析相关方对项目的期望和影响,制定合适的管理策略来有效调动相关方参与项目决策和执行。 1.2.4.7 项目管理数据和信息 工作绩效数据:在执行项目工作的过程中,从每个正在执行的活动中收集到的原始观察结果和测量值。例如工作完成百分比、质量和技术绩效测量结果、进度计划活动的开始和结束日期、变更请求的数量、缺陷的数量、实际成本和实际持续时间等。 工作绩效信息:从各控制过程收集,并结合相关背景和跨领域关系进行整合分析而得到的绩效数据。绩效信息的例子包括可交付成果的状态、变更请求的落实情况及预测的完工尚需估算。 工作绩效报告:为制定决策、提出问题、采取行动或引起关注,而汇编工作绩效信息所形成的实物或电子项目文件。例如状况报告、备忘录、论证报告、信息札记、电子仪表盘、推荐意见和情况更新。 1.2.5 裁剪 由于每个项目都是独特的,所以在实际应用时,应把项目管理裁剪成适合于特定项目,应选择恰当的项目管理过程、输入、工具、技术、输出和生命周期阶段以管理项目。 1.2.6 项目管理商业文件 需求评估与关键业务/项目文件的相互关系 1.2.6.1 项目商业论证 项目商业论证指文档化的经济可行性研究报告,用来对尚缺乏充分定义的所选方案的收益进行有效性论证,是启动后续项目管理活动的依据。商业论证列出了项目启动的目标和理由。在商业论证之前,通常需要进行需求评估,包含了解业务目的和目标、问题及机会,并提出处理建议。 商业论证可能包括(但不限于)记录一下内容: 业务需要 确定促进采取行动的动机; 情况说明,记录了待处理的业务问题或机会,包含能够为组织创造的价值; 确定受影响的相关方; 确定范围。 形势分析 确定组织战略、目的和目标; 确保问题的根本原因或机会的触发因素; 分析项目所需能力与组织现有能力之间的差距; 识别已知风险; 识别成功的关键因素; 确定可能用于评估各种行动方案的决策准则; 建立一些可选方案,用以处理业务问题或机会。可选方案指组织可能采取的备选行动方案。 推荐 对所推荐方案的说明; 说明书的内容可能包含(但不限于): 对潜在方案的分析结果; 潜在方案的制约因素、假设、风险和依赖关系; 成功标准。 一种实施方法,可能包括(但不限于): 里程碑; 依赖关系; 角色与职责。 评估 对如何测量项目所交付的效益的说明。 1.2.6.2 项目效益管理计划 项目效益管理计划描述了项目实现效益的方式和时间,以及应制定的效益衡量机制。项目效益指为发起组织和项目预期收益方创造价值的行动、行为、产品、服务或成果的结果。 项目效益管理计划可能包括(但不限于)记录一下内容: 目标效益(例如预计通过项目实施可以创造的有形价值和无形价值;财物价值体现为净现值); 战略一致性(例如项目效益与组织业务战略的一致程度); 实现效益的时限(例如阶段效益、短期效益、长期效益和持续效益); 效益责任人(例如在计划确定的整个时限内负责监督、记录和报告已实现效益的负责人); 测量指标(例如用于显示已实现效益的直接测量值和间接测量值); 假设(例如预计存在或显而易见的因素); 风险(例如实现效益的风险)。 1.2.6.3 项目章程和项目管理计划 项目章程是由项目发起人发布的,正式批准项目成立,并授权项目经理动用组织资源开展活动的文件。 项目管理计划是描述如何执行、监督和控制项目的一份文件。 1.2.6.4 项目成功标准 确定项目是否成功是项目管理中最常见的挑战之一。 时间、成本、范围和质量等项目管理测量指标历来被视为确定项目是否成功的最重要的因素。 最近,从业者和学者提出,确定项目是否成功还应考虑项目目标的实现情况。 关于项目成功的定义和最重要的因素,项目相关方可能有不同的看法。明确记录项目目标并选择可测量的目标是项目成功的关键。主要相关方和项目经理应思考以下三个问题: 怎样才是项目成功? 主要相关方和项目经理应就这些问题达成共识并予以记录。 项目成功可能涉及与组织战略和业务成果交付有关的其他标准。这些项目目标可能包括(但不限于): 完成项目效益管理计划; 达到商业论证中记录的已商定的财务测量指标。这些财务测量指标可能包括(但不限于): 净现值 (NPV); 投资回报率 (ROI); 内部报酬率 (IRR); 回收期 (PBP); 效益成本比率 (BCR)。 达到商业论证的非财务目标; 完成组织从“当前状态”转到“将来状态”; 履行合同条款和条件; 达到组织战略、目的和目标; 使相关方满意; 可接受的客户/最终用户的采纳度; 将可交付成果整合到组织的运营环境中; 满足商定的交付质量; 遵循治理规则; 满足商定的其他成功标准或准则(例如过程产出率)。 为了取得项目成功,项目团队必须能够正确评估项目状况,平衡项目要求,并与相关方保持积极主动的沟通。 但在业务环境中,如果项目能够与组织的战略方向持续保持一致,那么项目成功的概率就会显著提高。 有可能一个项目从范围/进度/预算来看是成功的,但从商业角度来看并不成功。这是因为业务需要和市场环境在项目完成之前发生了变化。 2.项目运行环境 2.1 概述 项目所处的环境可能对项目的开展产生有利或不利的影响。这些影响的两大主要来源为事业环境因素 (EEF) 和组织过程资产 (OPA)。 事业环境因素源于项目外部(往往是企业外部)的环境,事业环境因素可能对整个企业、项目组合、项目集或项目产生影响。 组织过程资产源于组织内部,可能来自组织自身、项目组合、项目集、其他项目或这些的组合。 项目影响 2.2 事业环境因素 事业环境因素(EEFs)是指项目团队不能控制的,将对项目产生影响、限制或指令作用的各种条件。这些条件可能来自于组织的内部和外部。 2.2.1 组织内部的事业环境因素 组织文化、结构和治理,例如:愿景、使命、价值观、制度等; 设施和资源的地理分布; 基础设施; 信息技术软件; 资源可用性,例如合同和采购制约因素; 员工能力。 2.2.2 组织外部的事业环境因素 市场条件,例如:竞争对手、市场份额等; 社会和文化影响与问题,例如:政治氛围; 法律限制; 商业数据库,例如风险数据库等; 学术研究; 政府或行业标准; 财务考虑因素,例如:关税、利率等; 物理环境要素,例如工作环境等。 2.3 组织过程资产 组织过程资产是执行组织所持有并使用的计划、过程、政策、程序和知识库,会影响对具体项目的管理。组织过程资产包含来自任何项目执行组织的,可用于执行或治理项目的任何工件、实践或知识,还包括来自组织以往项目的经验教育和历史信息,可能还包括完成的进度计划、风险数据和挣值数据。 组织过程资产主要分两类: 过程、政策和程序; 组织知识库。 2.3.1 过程、政策和程序 组织用于执行项目工作的流程与程序,包括(但不限于): 启动和规划 指南和标准,用于裁剪组织标准流程和程序以满足项目的特定要求; 特定的组织标准,例如人力资源政策; 产品和项目生命周期,以及方法和程序; 模板,例如项目管理计划、项目文件、报告格式等; 预先批准的供应商清单和各种合同协议类型。 执行和监控 变更控制程序,包括修改组织标准、政策、计划和程序等所须遵循的步骤,以及如何批准和确认变更; 跟踪矩阵; 财务控制程序,例如定期报告、支付审查等; 问题与缺陷管理程序,例如定义问题和缺陷控制等; 资源的可用性控制和分配管理; 组织对沟通的要求,例如可用的沟通技术、许可的沟通媒介等; 确定工作优先顺序、批准工作与签发工作授权的程序; 模板,例如问题日志,变更日志; 标准化的指南、工作提示、建议书评价准则和绩效测量准则; 产品、服务或成果的核实和确认程序。 收尾 项目收尾指南或要求,例如项目评价、项目审计、成果验收等。 2.3.2 组织知识库 组织用来存取信息的知识库,包含(但不限于): 配置管理知识库,包括软件和硬件组件版本以及所有执行组织的标准、政策、程序和任何项目文件的基准; 财务数据库,包括人工时、实际成本、预算等方面的信息; 历史信息与经验教训知识库,例如从以往风险管理活动中获取的信息等; 问题与缺陷管理数据库,包括问题与缺陷的状态、控制信息、解决方案以及相关行动的结果; 测量指标数据库,用来收集与提供过程和产品的测量数据; 以往项目的项目档案。 2.4 组织系统 单个组织内多种因素的交互影响创造出一个独特的系统,会对在该系统内运行的项目造成影 响。组织系统是动态的、能优化的。 系统因素包括(但不限于): 管理要素 管理要素是组织中的关键职能或一般管理原则。 治理框架 项目集和项目管理的常见治理框架,涉及四个治理领域:一致性、风险、绩效和沟通。各个领域都具备以下职能部门:监督、控制、整合与决策。 组织结构类型 组织需要权衡两个关键变量之后才可确定合适的组织结构类型。这两个变量指可以采用的组织结构类型以及针对特定组织如何优化组织结构类型的方式。 组织对项目的影响 2.4.4.3 项目管理办公室 项目管理办公室 (PMO) 是对与项目相关的治理过程进行标准化,并促进资源、方法论、工具和技术共享的一个组织结构。PMO 的职责范围可大可小,从提供项目管理支持服务,到直接管理一个或多个项目。 PMO 有几种不同类型,它们对项目的控制和影响程度各不相同,例如: 支持型。支持型 PMO 担当顾问的角色,向项目提供模板、最佳实践、培训,以及来自其他项目的信息和经验教训。这种类型的 PMO 其实就是一个项目资源库,对项目的控制程度很低。 控制型。控制型 PMO 不仅给项目提供支持,而且通过各种手段要求项目服从,这种类型的 PMO对项目的控制程度属于中等。服从可能包括: 采用项目管理框架或方法论; 使用特定的模板、格式和工具; 服从治理。 指令型。指令型 PMO 直接管理和控制项目。项目经理由 PMO 指定并向其报告。这种类型的 PMO对项目的控制程度很高。 除了被集中管理以外,PMO 所支持和管理的项目不一定彼此关联。PMO 的具体形式、职能和结构取决于所在组织的需要。 为了保证项目符合组织的业务目标,PMO 可能有权在每个项目的生命周期中充当重要相关方和关键决策者。PMO 可以: 提出建议; 领导知识传递; 终止项目; 根据需要采取其他行动。 对 PMO 所辖的全部项目的共享资源进行管理; 识别和制定项目管理方法、最佳实践和标准; 指导、辅导、培训和监督; 通过项目审计,监督对项目管理标准、政策、程序和模板的遵守程度; 制定和管理项目政策、程序、模板和其他共享的文件(组织过程资产); 对跨项目的沟通进行协调。 3.项目经理的角色 3.2 项目经理的定义 项目经理的角色不同于职能经理或运营经理,项目经理是由执行组织委派,领导团队实现项目目标的个人。 3.3 项目经理的影响力范围 3.3.1 概述 项目经理的影响力范围示例 3.3.2 项目 项目经理需要领导项目团队实现项目目标和相关方的期望。 项目经理需要利用可用资源,以平衡相互竞争的项目制约因素。 项目经理还充当项目发起人、团队成员与其他相关方之间的沟通者,包括提供指导和展示项目成功的愿景。 项目经理需要使用软技能(例如人际关系技能和人员管理技能)来平衡项目相关方之间相互冲突和竞争的目标,以达成共识。 与团队和发起人等相关方沟通的能力适用于项目的各个方面,包括(但不限于)以下各个方面: 通过多种方法(例如口头、书面和非口头)培养完善的技能; 创建、维护和遵循沟通计划和进度计划; 以可预见且一致的方式进行沟通; 寻求了解项目相关方的沟通需求; 以简练、清晰、完整、简单、相关和经过裁剪的方式进行沟通; 包含重要的正面和负面消息; 合并反馈渠道; 人际关系技能,即通过项目经理的影响力范围拓展广泛的人际网络。 3.3.3 组织 项目经理需要积极地与其他项目经理互动。其他独立项目或同一项目集的其他项目可能会对项目 造成影响,原因包括(但不限于): 对相同资源的需求; 资金分配的优先顺序; 可交付成果的接受或发布; 项目与组织的目的和目标的一致性。 3.3.4 行业 项目经理应时刻关注行业的最新发展趋势,获得并思考这一信息对当前项目是否有影响或可用。这些趋势包括(但不限于): 产品和技术开发; 新兴且正在变化的市场空间; 标准(例如项目管理标准、质量管理标准等); 技术支持工具; 影响当前项目的经济力量; 影响项目管理学科的各种力量; 过程改进和可持续发展战略。 3.4 项目经理的胜任力 3.4.1 概述 PMI人才三角: 技术项目管理 领导力 战略和商务管理 3.4.2 技术项目管理技能 技术项目管理技能指有效运用管理知识实现项目集或项目的预期成果的能力。包括(但不限于): 重点关注所管理的各个项目的关键技术项目管理要素。简单来说,就是随时准备好合适的资料。最主要的是: 项目成功的关键因素; 进度计划; 指定的财务报告; 问题日志。 针对每个项目裁剪传统和敏捷工具、技术和方法。 花时间制定完整的计划并谨慎排定优先顺序。 管理项目要素,包括(但不限于)进度、成本、资源和风险。 3.4.3 战略和商务管理技能 战略和商务管理技能包括纵览组织概况并有效协商和执行有利于战略调整和创新的决策和行动的能力。战略和商务管理技能可能还包括发展和运用相关的产品和行业专业知识,这些业务知识也称为领域知识。 项目经理应掌握足够的业务知识,以便能够: 向其他人解释关于项目的必要商业信息; 与项目发起人、团队和主题专家合作制定合适的项目交付策略; 以实现项目商业价值最大化的方式执行策略。 战略 使命 目的和目标 产品和服务 运营(例如位置、类型、技术) 市场和市场条件,例如客户、市场状况 竞争(例如竞争什么、竞争地位) 为确保一致性,项目经理应将以下关于组织的知识和信息运用到项目中: 战略 使命 目的和目标 优先级 策略 产品或服务(例如可交付成果) 战略和商业技能有助于项目经理确定应为其项目考虑哪些商业因素。这些因素包括(但不限于): 风险和问题; 财务影响; 成本效益分析,包括各种可选方案; 商业价值; 效益预期实现情况和战略; 范围、预算、进度和质量。 3.4.4 领导力技能 3.4.4.1 人际交往 项目经理应研究人的行为和动机,应尽力成为一个好的领导者,因为领导力对组织项目是否成功至关重要。项目经理需要运用领导力技能和品质与所有项目相关方合作,包括项目团队、团队指导和项目发起人。 3.4.4.2 领导者的品质和技能 领导者的品质和技能包含(但不限于): 有远见(例如帮助描述项目的产品、目的和目标); 积极乐观; 乐于合作; 通过以下方式管理关系和冲突: 建立信任; 解决顾虑; 寻求共识; 平衡相互竞争和对立的目标; 运用说服、协商、妥协和解决冲突的技能; 发展和培养个人及专业网络; 以长远的眼光把人际关系看成与项目本身同样重要; 持续发展和运用政治敏锐性。 通过以下方式进行沟通: 花大量的时间沟通; 管理期望; 诚恳地接受反馈; 提出建议性的反馈; 询问和倾述。 尊重他人(帮助他人保持独立自主)、谦恭有礼、友善待人、诚实可信、忠诚可靠、遵守职业道德; 展现出诚信正直和文化敏感性,果断、勇敢,能够解决问题; 适时称赞他人; 终身学习,以结果和行动为导向; 关注重要的事情,包括: 通过必要的审查和调整,不断调整工作优先级; 寻求并采用适用于团队和项目的优先级排序方法; 区分高层级战略优先级,尤其是与项目成功的关键因素相关的事项; 对项目的主要制约因素保持警惕; 在战术优先级上保持灵活; 能够从大量信息中筛选出最重要的信息。 以整体和系统的角度来看待项目,同等对待内部和外部因素; 能够运用批判性思维并将自己视为变革推动者; 能够创建高效的团队、以服务为导向、展现出幽默的一面,与团队成员有效地分享乐趣。 3.4.4.3 政治、权力和办好事情 领导和管理的最终目的是办好事情。这些技能和品质有助于项目经理实现项目目的和目标。很多 技能和品质归根究底就是处理政治的能力。政治涉及影响、谈判、自主和权力。政治及其相关要素不局限于“好”与“不好”以及“正面”与“负面”之分。项目经理对组织运行方式的了解越多,就越有可能获得成功。 权力的种类包括(但不限于): 地位(有时称为正式的、权威的、合法权力的,例如组织或团队授予的正式职位); 信息(例如对信息收集或分发的控制); 参考(例如因为他人的尊重和赞赏,获得的信任); 情境(例如在特别危机等特殊情况下获得的权力); 个性或魅力(例如魅力、吸引力); 关系(例如参与人际交往、联系和结盟); 专家(例如拥有的技能和信息、经验、培训、教育、证书); 奖励相关的(例如能够给予表扬、金钱或其他奖励); 处罚或强制力(例如给予纪律处分或施加负面后果的能力); 迎合(例如运用奉承或其他常用手段赢得青睐或合作); 施加压力(例如限制选择或活动自由,以符合预期的行动); 愧疚(例如强加的义务或责任感); 说服力(例如能够提供论据,使他人执行预期的行动方案); 回避(例如拒绝参与)。 3.4.5 领导力与管理之比较 3.5 执行整合 执行项目整合时,项目经理承担双重角色: 项目经理扮演重要角色,与项目发起人携手合作,来理解战略目标,并确保项目目标和成果与项目组合、项目集以及业务领域保持一致。项目经理以这种方式帮助实现战略层面的整合与执行。 在项目层面上,项目经理负责指导团队关注真正重要的事务并协同工作。为此,项目经理需要整合过程、知识和人员。 4.项目整合管理 项目整合管理包括对隶属于项目管理过程组的各个过程和项目管理活动进行识别、定义、组合、统一和协调的各个过程。项目整合管理包括进行以下选择: 资源分配; 平衡竞争性需求; 研究各种备选方法; 为实现项目目标而裁剪过程; 管理各个项目管理知识领域之间的依赖关系。 4.1 制定项目章程 — 编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程。 4.2 制定项目管理计划 — 定义、准备和协调项目计划的所有组成部分,并把它们整合为一份综合项目管理计划的过程。 4.3 指导与管理项目工作 — 为实现项目目标而领导和执行项目管理计划中所确定的工作,并实施已批准变更的过程。 4.4 管理项目知识 — 使用现有知识并生成新知识,以实现项目目标,并且帮助组织学习的过程。 4.5 监控项目工作 — 跟踪、审查和报告整体项目进展,以实现项目管理计划中确定的绩效目标的过程。 4.6 实施整体变更控制 — 审查所有变更请求,批准变更,管理对可交付成果、组织过程资产、项目文件和项目管理计划的变更,并对变更处理结果进行沟通的过程。 4.7 结束项目或阶段 — 终结项目、阶段或合同的所有活动的过程。 项目整合管理概述 项目整合管理的核心概念 项目整合管理指的是: 确保产品、服务或成果的交付日期,项目生命周期以及效益管理计划这些方面保持一致; 编制项目管理计划以实现项目目标; 确保创造合适的只是并运用到项目中,并从项目中获取必要的知识; 管理项目管理计划中活动的绩效和变更; 做出针对影响项目的关键变更的综合决策; 测量和监督项目进展,并采取适当措施以实现项目目标; 收集关于已实现的成果的数据,分析数据以获取信息,并与相关方分享信息; 完成全部项目工作,正式关闭各个阶段、合同以及整个项目; 管理可能需要的阶段过渡。 项目整合管理的发展趋势和新兴实践 项目整合管理知识领域要求整合所有其他知识领域的成果。与整合管理过程相关的发展趋势包括(但不限于): 使用自动化工具; 使用可视化工具; 项目知识管理,项目人员的流动性和不稳定性越来越高,就要求采用更严格的过程,在整个项目生命周期中积累知识和其他相关方识别和解决问题的能力。 增加项目经理的职责,比如被要求接入启动和结束项目,如开展项目商业论证和效益管理。 混合型方法,比如采用敏捷或其他迭代做法,为开展需求管理而采用商业分析技术等。 裁剪时需要考虑的因素 裁剪时应考虑的因素包括(但不限于): 项目生命周期 开发生命周期 管理方法 知识管理 变更 治理 经验教训 效益 在敏捷或适应型环境中需要考虑的因素 迭代和敏捷方法能够促进团队成员以相关领域专家的身份参与整合管理。团队成员自行决定计划及其组件的整合方式。 在适应型环境下,《整合管理的核心概念》中所述的对项目经理的期望保持不变,但把对具体产品的规划和交付授权给团队来控制。项目经理的关注点在于营造一个合作型的决策氛围,并确保团队有能力应对变更。 4.1 制定项目章程 制定项目章程是编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程。本过程的主要作用是,明确项目与组织战略目标之间的直接联系,确立项目的正式地位,并展示组织对项目的承诺。 项目章程一旦被批准,就标志着项目的正式启动。 制定项目章程:输入、工具与技术和输出 制定项目章程:数据流向图 4.1.1 制定项目章程:输入 制定项目章程的输入包括: 商业文件 商业论证。经批准的商业论证或类似文件是最常用于制定项目章程的商业文件。商业论证从商业视角描述必要的信息。 市场需求 组织需要 客户要求 技术进步 法律要求 生态影响 社会需要 效益管理计划 协议 协议用于定义启动项目的初衷。协议有多种形式,包含合同、谅解备忘录、服务水平协议、协议书、意向书、口头协议、电子邮件或其他书面协议。 事业环境因素 政府或行业标准; 法律法规要求和(或)制约因素; 市场条件; 组织文化和政治氛围; 组织治理框架; 相关方的期望和风险临界值。 组织过程资产 组织的标准政策、流程和程序; 项目组合、项目集和项目的治理框架; 监督和报告方法; 模板(项目章程模板); 历史信息和经验教训知识库。 4.1.2 制定项目章程:工具与技术 制定项目章程的工具和技术包含: 专家判断:专家判断是基于某应用领域、知识领域、学科和行业等的专业知识而做出的,关于当前活动的合理判断,这些专业知识可来自具有专业学历、知识、技能、经验或培训经理的任何小组或个人。 组织战略; 效益管理; 关于项目所在的行业以及项目关注的领域的技术知识; 持续时间和成本估算; 风险识别。 数据收集 头脑风暴 焦点小组 访谈 人际关系与团队技能 冲突管理 引导 会议管理 会议 4.1.3 制定项目章程:输出 制定项目章程的输出包括: 项目章程:项目章程是由项目启动者或发起人发布的,正式批准项目成立,并授权项目经理使用组织资源开展项目活动的文件。它记录了关于项目和项目预期要交付的产品、服务或成果的高层级信息,例如: 项目目的; 可测量的项目目标和相关的成功标准; 高层级需求; 高层级项目描述、边界定义以及主要可交付成果; 整体项目风险; 总体里程碑进度计划; 预先批准的财务资源; 关键相关方名单; 项目审批要求; 项目退出标准; 委派的项目经理及其职责和职权; 发起人或其他批准项目章程的人员的姓名和职权。 假设日志 通常,在项目启动之前编制商业论证时,识别高层级的战略和运营假设条件与制约因素。这些假设条件与制约因素应纳入项目章程。较低层级的活动和任务假设条件在项目期间随着诸如定义技术规范、估算、进度和风险等活动的开展而生成。假设日志用于记录整个项目生命周期中的所有假设条件和制约因素。 4.2 制定项目管理计划 制定项目管理计划是定义、准备和协调项目计划的所有组成部分,并把它们整合为一份综合项目 管理计划的过程。 制定项目管理计划:输入、工具与技术和输出 制定项目管理计划:数据流向图 *注意点 项目管理计划应基准化,即,至少应规定项目的范围、时间和成本方面的基准,以便据此考核项目执行情况和管理项目绩效。在确定基准之前,可能要对项目管理计划进行多次更新,且这些更新无需遵循正式流程。但是,一旦确定了基准,就只能通过实施整体变更控制过程进行更新。在这种情况下,如果需要进行变更,应提出变更请求以待决定。 4.2.1 制定项目管理计划:输入 制定项目管理计划的输入包含: 项目章程 项目团队把项目章程作为初始项目规划的起始点。项目章程所包含的信息种类和数量因项目的复杂程度和已知的信息而异。在项目章程中至少应该定义项目的高层级信息,供将来在项目管理计划的各个组成部分中进一步细化。 其他过程的输出 其他规划过程所输出的子计划和基准都是本过程的输入。此外,对这些子计划和基准的变更都可能导致对项目管理计划的相应更新。 事业环境因素 政府或行业标准; 法律法规要求和制约因素; 垂直市场和专门领域的项目管理知识体系; 组织的结构、文化、管理实践和可持续性; 组织治理框架; 基础设施。 组织过程资产 组织的标准政策、流程和程序; 项目管理计划模板 根据项目的特定要求而裁剪组织的标准流程的指南和标准; 项目收尾指南或要求,如产品确认及验收标准。 变更控制程序; 监督和报告方法、风险控制程序以及沟通要求; 以往类似项目的相关信息; 历史信息和经验教训知识库。 4.2.2 制定项目管理计划:工具与技术 制定项目管理计划的工具与技术包含: 专家判断 根据项目需要裁剪项目管理过程,包括这些过程间的依赖关系和相互影响,以及这些过程的主要输入和输出; 根据需要制定项目管理计划的附加组成部分; 确定这些过程所需的工具与技术; 编制应包括在项目管理计划中的技术与管理细节; 确定项目所需的资源与技能水平; 定义项目的配置管理级别; 确定哪些项目文件受制于正式的变更控制过程; 确定项目工作的优先级,确保把项目资源在合适的时间分配到合适的工作。 数据收集 头脑风暴 核对单 焦点小组 访谈 人际关系与团队技能 冲突管理 引导 会议管理 会议 4.2.3 制定项目管理计划:输出 制定项目管理计划的输出包括: 项目管理计划 子管理计划 范围管理计划:确定如何定义、制定、监督、控制和确认项目范围。 需求管理计划:确定如何分析、记录和管理需求。 进度管理计划:为编制、监督和控制项目进度建立准则并确定活动。 成本管理计划:确定如何规划、安排和控制成本。 质量管理计划:确定在项目中如何实施组织的质量政策、方法和标准。 资源管理计划:指导如何对项目资源进行分类、分配、管理和释放。 沟通管理计划:确定项目信息将如何、何时、由谁来进行管理和传播。 风险管理计划:确定如何安排与实施风险管理活动。 采购管理计划:确定项目团队将如何从执行组织外部获取货物和服务。 相关方参与计划:确定如何根据相关方的需求、利益和影响让他们参与项目决策和执行。 基准 范围基准:经过批准的范围说明书、工作分解结构(WBS)和相应的WBS词典,用作比较依据。 进度基准:经过批准的进度模型,用作与实际结果进行比较的依据。 成本基准:经过批准的、按时间段分配的项目预算,用作与实际结果进行比较的依据。 其他组件 变更管理计划:描述在整个项目期间如何正式审批和采纳变更请求。 配置管理计划:描述如何记录和更新项目的特定信息,以及该记录和更新哪些信息,以保持产品、服务或成果的一致性和(或)有效性。 绩效测量基准:经过整合的项目范围、进度和成本计划,用作项目执行的比较依据,以测量和管理项目绩效。 项目生命周期 开发方法:描述产品、服务或成果的开发方法,例如预测、迭代、敏捷或混合型模式。 管理审查:确定项目经理和有关相关方审查项目进展的时间点,以考核绩效是否符合预期,或者确定是否有必要采取预防或纠正措施。 项目管理计划和项目文件 4.3 指导与管理项目工作 指导和管理项目工作是为实现项目目标而领导和执行项目管理计划中所确定的工作,并实施已批准变更的过程。本过程的主要作用是对项目工作和可交付成果开展综合管理,以提高项目成功的可能性。 指导与管理项目工作:输入、工具与技术和输出 指导与管理项目工作:数据流向图 4.3.1 指导与管理项目文件:输入 指导与管理项目文件的输入包括: 项目管理计划 项目文件 变更日志 经验教训登记册 里程碑清单 项目沟通记录 项目进度计划 需求跟踪矩阵 风险登记册 风险报告 批准的变更请求 批准的变更请求是实施整体变更控制过程的输出,包括经项目经理或变更控制委员会(CCB)(必要时)审查和批准的变更请求。批准的变更请求可能是纠正措施、预防措施或缺陷补救,并由项目团队纳入项目进度计划付诸实施。 事业环境因素 组织的结构、文化、管理实践和可持续性; 基础设施(如现有的设施和固定资产); 相关方的风险临界值(如允许的成本超支百分比)。 组织过程资产 组织的标准政策、流程和程序; 问题与缺陷管理程序,用于定义问题与缺陷控制、问题与缺陷识别及其解决,以及行动事项跟踪; 问题与缺陷管理数据库,包括历史问题与缺陷状态、问题和缺陷解决情况,以及行动事项的结果; 绩效测量数据库,用来收集与提供过程和产品的测量数据; 变更控制和风险控制程序; 以往项目的项目信息(如范围、成本、进度与绩效测量基准,项目日历,项目进度网络图,风险登记册,风险报告以及经验教训知识库)。 4.3.2 指导与管理项目工作:工具与技术 指导与管理项目工作的工具与技术包括: 专辑判断 项目管理信息系统 会议 4.3.3 指导与管理项目工作:输出 指导与管理项目工作的输出包括: 可交付成果 工作绩效数据 问题日志 问题类型 问题提出者和提出时间 问题描述 问题优先级 由谁负责解决问题 目标解决日期 问题状态 最终解决情况 变更请求 纠正措施 预防措施 缺陷补救 更新 项目管理计划更新 项目文件更新 活动清单 假设日志 经验教训登记册 需求文件 风险登记册 相关方登记册 组织过程资产更新 4.4 管理项目知识 管理项目知识是使用现有知识并生成新知识,以实现项目目标,并且帮助组织学习的过程。本过程的主要作用是,利用已有的组织知识来创造或改进项目成果,并且使当前项目创造的知识可用于支持组织运营和未来的项目或阶段。 管理项目知识:输入、工具与技术和输出 管理项目知识:数据流向图 知识通常分为“显性知识”(易使用文字、图片和数字进行编撰的知识)和“隐性知识”(个体知识以及难以明确表达的知识,如信念、洞察力、经验和“诀窍”)两种。知识管理指管理显性和隐性知识,旨在重复使用现有知识并生成新知识。有助于达成这两个目的的关键活动是知识分享和知识集成(不同领域的知识、情境知识和项目管理知识)。 从组织的角度来看,知识管理指的是确保项目团队和其他相关方的技能、经验和专业知识在项目开始之前、开展期间和结束之后得到运用。因为知识存在于人们的思想中,且无法强迫人们分享自己的知识或关注他人的知识,所以,知识管理最重要的环节就是营造一种相互信任的氛围,激励人们分享知识或关注他人的知识。如果不激励人们分享知识或关注他人的知识,即便最好的知识管理工具和技术也无法发挥作用。在实践中,联合使用知识管理工具和技术(用于人际互动)以及信息管理工具和技术(用于编撰显性知识)来分享知识。 4.4.1 管理项目知识:输入 管理项目知识的输入包括: 项目管理计划 项目文件 经验教训登记册 项目团队派工单 资源分解结构 相关方登记册 可交付成果 事业环境因素 组织文化、相关方文化和客户文化 设施和资源的地理分布 组织中的知识专家 法律法规要求或制约因素 组织过程资产 组织的标准政策、流程和程序 人事管理制度 组织对沟通的要求 正式的知识分享和信息分享程序 4.4.2 管理项目知识:工具与技术 管理项目知识需要的工具与技术包括: 专家判断 知识管理; 信息管理; 组织学习; 知识和信息管理工具; 来自其他项目的相关信息。 知识管理 人际交往,包括非正式的社交和在线社交。可以进行开放式提问(如“谁知道……?”)的在线论坛有助于与专家进行知识分享对话; 实践社区(有时称为“兴趣社区”或“社区”)和特别兴趣小组; 会议,包括使用通信技术进行互动的虚拟会议; 工作跟随和跟随指导; 讨论论坛,如焦点小组; 知识分享活动,如专题讲座和会议; 研讨会,包括问题解决会议和经验教训总结会议; 讲故事; 创造力和创意管理技术; 知识展会和茶座; 交互式培训。 信息管理 编撰显性知识的方法,例如,如何确定经验教训登记册的条目; 经验教训登记册; 图书馆服务; 信息收集,例如搜索网络和阅读已发表的文章; 项目管理信息系统 (PMIS)。 人际关系与团队技能 积极倾听 引导 领导力 人际交往 政治意识 4.4.3 管理项目知识:输出 管理项目知识的输出包括: 经验教训登记册 经验教训登记册可以包含情况的类别和描述,经验教训登记册还可包括与情况相关的影响、建议和行动方案。经验教训登记册可以记录遇到的挑战、问题、意识到的风险和机会,或其他适用的内容。 项目管理计划更新 组织过程资产更新 4.5 监控项目工作 监控项目工作是跟踪、审查和报告整体项目进展,以实现项目管理计划中确定的绩效目标的过程。本过程的主要作用是,让相关方了解项目的当前状态并认可为处理绩效问题而采取的行动,以及通过成本和进度预测,让相关方了解未来项目状态。 监控项目工作:输入、工具与技术和输出 监控项目工作:数据流向图 监督是贯穿于整个项目的项目管理活动之一,包括收集、测量和分析测量结果,以及预测趋势, 以便推动过程改进。持续的监督使项目管理团队能洞察项目的健康状况,并识别须特别关注的任何方面。控制包括制定纠正或预防措施或重新规划,并跟踪行动计划的实施过程,以确定它们能否有效解决问题。监控项目工作过程关注: 把项目的实际绩效与项目管理计划进行比较; 定期评估项目绩效,决定是否需要采取纠正或预防措施,并推荐必要的措施; 检查单个项目风险的状态; 在整个项目期间,维护一个准确且及时更新的信息库,以反映项目产品及相关文件的情况; 为状态报告、进展测量和预测提供信息; 做出预测,以更新当前的成本与进度信息; 监督已批准变更的实施情况; 如果项目是项目集的一部分,还应向项目集管理层报告项目进展和状态; 确保项目与商业需求保持一致。 4.5.1 监控项目工作:输入 监控项目工作的输入包括: 项目管理计划 项目文件 假设日志。假设日志包含会影响项目的假设条件和制约因素的信息。 估算依据。估算依据说明不同估算是如何得出的,用于决定如何应对偏差。 成本预测。成本预测基于项目以往的绩效,用于确定项目是否仍处于预算的公差区间内,并识别任何必要的变更。 问题日志。问题日志用于记录和监督由谁负责在目标日期内解决特定问题。 经验教训登记册。经验教训登记册可能包含应对偏差的有效方式以及纠正措施和预防措施。 里程碑清单。里程碑清单列出特定里程碑的实现日期,用于检查是否达到计划的里程碑。 质量报告。质量报告包含质量管理问题,针对过程、项目和产品的改善建议,纠正措施建议(包括返工、缺陷或漏洞补救、100% 检查等),以及在控制质量过程中发现的情况的概述。 风险登记册。风险登记册提供在项目执行过程中发生的各种威胁和机会的相关信息。 风险报告。风险报告提供关于整体项目风险和单个风险的信息。 进度预测。进度预测基于项目以往的绩效,用于确定项目是否仍处于进度的公差区间内,并识别任何必要的变更。 工作绩效信息 在工作执行过程中收集工作绩效数据,再交由控制过程做进一步分析。将工作绩效数据与项目管理计划组件、项目文件和其他项目变量比较之后生成工作绩效信息。通过这种比较可以了解项目的执行情况。 协议 事业环境因素 项目管理信息系统,例如进度、成本、资源工具、绩效指标、数据库、项目记录和财务数据; 基础设施(如现有设施、设备、组织通讯渠道); 相关方的期望和风险临界值; 政府或行业标准(如监管机构条例、产品标准、质量标准和工艺标准)。 组织过程资产 组织的标准政策、流程和程序; 财务控制程序(如必需的费用与支付审查、会计编码及标准合同条款等); 监督和报告方法; 问题管理程序,用于定义问题控制、问题识别及其解决,以及行动事项跟踪; 缺陷管理程序,用于定义缺陷控制、缺陷识别及其解决,以及行动事项跟踪; 组织知识库,尤其是过程测量和经验教训知识库。 4.5.2 监控项目工作:工具与技术 监控项目工作所需要的工具和技术包括: 专家判断 挣值分析; 数据的解释和情境化; 持续时间和成本的估算技术; 趋势分析; 关于项目所在的行业以及项目关注的领域的技术知识; 风险管理; 合同管理。 数据分析 备选方案分析。备选方案分析用于在出现偏差时选择要执行的纠正措施或纠正措施和预防措施的组合。 成本效益分析。成本效益分析有助于在项目出现偏差时确定最节约成本的纠正措施。 挣值分析。挣值分析对范围、进度和成本绩效进行了综合分析。 根本原因分析。根本原因分析关注识别问题的主要原因,它可用于识别出现偏差的原因以及项目经理为达成项目目标应重点关注的领域。 趋势分析。趋势分析根据以往结果预测未来绩效,它可以预测项目的进度延误,提前让项目经理意识到,按照既定趋势发展,后期进度可能出现的问题。应该在足够早的项目时间进行趋势分析,使项目团队有时间分析和纠正任何异常。可以根据趋势分析的结果,提出必要的预防措施建议。 偏差分析。偏差分析审查目标绩效与实际绩效之间的差异(或偏差),可涉及持续时间估算、成本估算、资源使用、资源费率、技术绩效和其他测量指标。 决策 会议 4.5.3 监控项目工作:输出 监控项目工作的输出包括: 工作绩效报告 变更请求 纠正措施 预防措施 缺陷补救 项目管理计划更新 项目文件更新 成本预测 问题日志 经验教训登记册 风险登记册 进度预测 4.6 实施整体变更控制 实施整体变更控制是审查所有变更请求、批准变更,管理对可交付成果、项目文件和项目管理计划的变更,并对变更处理结果进行沟通的过程。本过程审查对项目文件、可交付成果或项目管理计划的所有变更请求,并决定对变更请求的处置方案。本过程的主要作用是确保对项目中已记录在案的变更做综合评审。如果不考虑变更对整体项目目标或计划的影响就开展变更,往往会加剧整体项目风险。 实施整体变更控制:输入、工具与技术和输出 实施整体变更控制:数据流向图 在基准确定之前,变更无需正式受控于实施整体变更控制过程。一旦确定了项目基准,就必须通过本过程来处理变更请求。依照常规,每个项目的配置管理计划应规定哪些项目工件受控于配置控制程序。对配置要素的任何变更都应该提出变更请求,并经过正式控制。 尽管也可以口头提出,但所有变更请求都必须以书面形式记录,并纳入变更管理和(或)配置管 理系统中。在批准变更之前,可能需要了解变更对进度的影响和对成本的影响。在变更请求可能影响任一项目基准的情况下,都需要开展正式的整体变更控制过程。每项记录在案的变更请求都必须由一位责任人批准、推迟或否决,这个责任人通常是项目发起人或项目经理。应该在项目管理计划或组织程序中指定这位责任人,必要时,应该由变更控制委员会(CCB)来开展实施整体变更控制过程。CCB是一个正式组成的团体,负责审查、评价、批准、推迟或否决项目变更,以及记录和传达变更处理决定。 变更请求得到批准后,可能需要新编(或修订)成本估算、活动排序、进度日期、资源需求和(或)风险应对方案分析,这些变更可能要求调整项目管理计划和其他项目文件。某些特定的变更请求,在 CCB 批准之后,可能还需要得到客户或发起人的批准,除非他们本身就是 CCB 的成员。 4.6.1 实施整体变更控制:输入 实施整体变更控制的输入包括: 项目管理计划 配置管理计划 范围基准 进度基准 成本基准 项目文件 估算依据 需求跟踪矩阵 风险报告 工作绩效报告 变更请求 事业环境因素 法律限制,例如国家或地区法规; 政府或行业标准(如产品标准、质量标准、安全标准和工艺标准); 法律法规要求和(或)制约因素; 组织治理框架(通过安排人员、制定政策和确定过程,以结构化的方式实施控制、指导和协调,以实现组织的战略和运营目标); 合同和采购制约因素。 组织过程资产 变更控制程序,包括修改组织标准、政策、计划和程序或任一项目文件所须遵循的步骤,以及如何批准和确认变更; 批准与签发变更的程序; 配置管理知识库,包括组织标准、政策、程序和项目文件的各种版本及基准。 4.6.2 实施整体变更控制:工具与技术 实施整体变更控制所需要的工具与技术包括: 专家判断 变更控制工具 识别配置项。识别与选择配置项,从而为定义与核实产品配置、标记产品和文件、管理变更和明确责任提供基础。 记录并报告配置项状态。关于各个配置项的信息记录和报告。 进行配置项核实与审计。通过配置核实与审计,确保项目的配置项组成的正确性,以及相应的变更都被登记、评估、批准、跟踪和正确实施,从而确保配置文件所规定的功能要求都已实现。 识别变更。识别并选择过程或项目文件的变更项。 记录变更。将变更记录为合适的变更请求。 做出变更决定。审查变更,批准、否决、推迟对项目文件、可交付成果或基准的变更或做出其他决定。 跟踪变更。确认变更被登记、评估、批准、跟踪并向相关方传达最终结果。 数据分析 备选方案分析。该技术用于评估变更请求,并决定哪些请求可接受、应否决或需修改。 成本效益分析。该分析有助于确定变更请求是否值得投入相关成本。 决策 投票 独裁型决策制定 多标准决策分析 会议 4.6.3 实施整体变更控制:输出 实施整体变更控制的输出包括: 批准的变更请求 项目管理计划更新 项目文件更新 4.7 结束项目或阶段 结束项目或阶段是终结项目、阶段或合同的所有活动的过程。本过程的主要作用是,存档项目或阶段信息,完成计划的工作,释放组织团队资源以展开新的工作。它仅开展一次或仅在项目的预定义点开展。 结束项目或阶段:输入、工具与技术和输出 结束项目或阶段:数据流向图 在结束项目时,项目经理需要回顾项目管理计划,确保所有项目工作都已完成以及项目目标均已实现。项目或阶段行政收尾所需的必要活动包括(但不限于): 为达到阶段或项目的完工或退出标准所必须的行动和活动,例如: 确保所有文件和可交付成果都已是最新版本,且所有问题都已得到解决; 确认可交付成果已交付给客户并已获得客户的正式验收; 确保所有成本都已记入项目成本账; 关闭项目账户; 重新分配人员; 处理多余的项目材料; 重新分配项目设施、设备和其他资源; 根据组织政策编制详尽的最终项目报告。 为关闭项目合同协议或项目阶段合同协议所必须开展的活动,例如 确认卖方的工作已通过正式验收; 最终处置未决索赔; 更新记录以反映最后的结果; 存档相关信息供未来使用。 为完成下列工作所必须开展的活动: 收集项目或阶段记录; 审计项目成败; 管理知识分享和传递; 总结经验教训; 存档项目信息以供组织未来使用。 为向下一个阶段,或者向生产和(或)运营部门移交项目的产品、服务或成果所必须开展的行动和活动。 收集关于改进或更新组织政策和程序的建议,并将它们发送给相应的组织部门。 测量相关方的满意程度。 原因。为了实现上述目的,项目经理应该引导所有合适的相关方参与本过程。 4.7.1 结束项目或阶段:输入 结束项目或阶段的输入包括: 项目章程 项目管理计划 项目文件 假设日志 估算依据 变更日志 问题日志 经验教训登记册 里程碑清单 项目沟通记录 质量控制测量结果 质量报告 需求文件 风险登记册 风险报告 验收的可交付成果 商业文件 协议 采购文档 组织过程资产 项目或阶段收尾指南或要求(如经验教训、项目终期审计、项目评价、产品确认、验收标准、合同收尾、资源重新分配、团队绩效评估,以及知识传递); 配置管理知识库,包括组织标准、政策、程序和项目文件的各种版本及基准。 4.7.2 结束项目或阶段:工具与技术 结束项目或阶段所需要的工具与技术包含: 专家判断 管理控制; 审计; 法规与采购; 法律法规。 数据分析 文件分析,评估现有文件有助于总结经验教训和分享知识,以改进未来项目和组织资产。 回归分析,该技术分析作用于项目结果的不同项目变量之间的相互关系,以提高未来项目的绩效。 趋势分析,趋势分析可用于确认组织所用模式的有效性,并且为了未来项目而进行相应的模式调整。 偏差分析,偏差分析可通过比较最初计划目标与最终结果来改进组织的测量指标。 会议 4.7.3 结束项目或阶段:输出 结束项目或阶段的输出包含: 项目文件更新 最终产品、服务或成果移交 最终报告 项目或阶段的概述; 范围目标、范围的评估标准,以及证明达到完工标准的证据; 质量目标、项目和产品质量的评估标准、相关核实信息和实际里程碑交付日期以及偏差原因; 成本目标,包括可接受的成本区间、实际成本,以及产生任何偏差的原因; 最终产品、服务或成果的确认信息的总结。 进度计划目标包括成果是否实现项目所预期的效益。如果在项目结束时未能实现效益,则指出效益实现程度并预计未来实现情况。 关于最终产品、服务或成果如何满足商业计划所述业务需求的概述。如果在项目结束时未能满足业务需求,则指出需求满足程度并预计业务需求何时能够得到满足。 关于项目过程中发生的风险或问题及其解决情况的概述。 组织过程资产更新 项目文件 运营和支持文件 项目或阶段收尾文件 经验教训知识库 5.项目范围管理 项目范围管理包括确保项目做且只做所需的全部工作,以成功完成项目的各个过程。管理项目范围主要在于定义和控制哪些工作应该包括在项目内,哪些不应该包括在项目内。 项目范围管理过程包括: 5.1 规划范围管理 — 为记录如何定义、确认和控制项目范围及产品范围,而创建范围管理计划的过程。 5.2 收集需求 — 为实现项目目标而确定、记录并管理相关方的需要和需求的过程。 5.3 定义范围 — 制定项目和产品详细描述的过程。 5.4 创建 WBS — 将项目可交付成果和项目工作分解为较小的、更易于管理的组件的过程。 5.5 确认范围 — 正式验收已完成的项目可交付成果的过程。 5.6 控制范围 — 监督项目和产品的范围状态,管理范围基准变更的过程。 范围的含义: 产品范围:某项产品、服务或成果所具有的特征和功能。 项目范围:为交付具有规定特性与功能的产品、服务或成果而必须完成的工作。项目范围有时也包括产品范围。 在项目范围管理过程中,收集、记录和管理相关方需求。项目范围管理的发展趋势和新兴实践包括(但不限于)注重与商业分析专业人士的合作,以便: 确定问题并识别商业需要; 识别并推荐能够满足这些需要的可行解决方案; 收集、记录并管理相关方需求,以满足商业和项目目标; 推动项目集或项目的产品、服务或最终成果的成功应用 。 需求管理过程结束于需求关闭,即把产品、服务或成果移交给接收方,以便长期测量、监控、实现和维持效益。 裁剪时需要考虑的因素 因为每个项目都是独特的,所以项目经理需要裁剪项目范围管理过程。裁剪时应考虑的因素包括(但不限于): 知识和需求管理。组织是否拥有正式或非正式的知识和需求管理体系?为了在未来项目中重复使用需求,项目经理应建立哪些指南? 确认和控制。组织是否拥有正式或非正式的与确认和控制相关的政策、程序和指南? 开发方法。组织是否采用敏捷方法管理项目?开发方法属于迭代型还是增量型?是否采用预测型方法?混合型方法是否有效? 需求的稳定性。项目中是否存在需求不稳定的领域?是否有必要采用精益、敏捷或其他适应型技术来处理不稳定的需求,直至需求稳定且定义明确? 治理。组织是否拥有正式或非正式的审计和治理政策、程序和指南 在敏捷或适应型环境中需要考虑的因素 对于需求不断变化、风险大或不确定性高的项目,在项目开始时通常无法明确项目的范围,而需要在项目期间逐渐明确。敏捷方法特意在项目早期缩短定义和协商范围的时间,并为持续探索和明确范围而延长创建相应过程的时间。在许多情况下,不断涌现的需求往往导致真实的业务需求与最初所述的业务需求之间存在差异。因此,敏捷方法有目的地构建和审查原型,并通过发布多个版本来明确需求。这样一来,范围会在在整个项目期间被定义和再定义。在敏捷方法中,把需求列入未完项。 5.1 规划范围管理 规划范围管理是为记录如何定义、确认和控制项目范围及产品范围,而创建范围管理计划的过程。本过程的主要作用是,在整个项目期间对如何管理范围提供指南和方向。本过程仅开展一次或仅在项目的预定义点开展。 规划范围管理:输入、工具与技术和输出 规划范围管理:数据流向图 5.1.1 规划范围管理:输入 规划范围管理的输入包括: 项目章程 项目管理计划 质量管理计划 项目生命周期描述 开发方法 事业环境因素 组织文化 基础设施 人事管理制度 市场条件 组织过程资产 政策和程序 历史信息和经验教训知识库 5.1.2 规划范围管理:工具与技术 规划范围管理需要的工具与技术包括: 专家判断 以往类似项目 特定行业、学科和应用领域的信息 数据分析 会议 5.1.3 规划范围管理:输出 规划范围管理的输出包括: 范围管理计划 制定项目范围说明书 根据详细项目范围说明书创建WBS 确定如何审批和维护范围基准 正式验收已完成的项目可交付成果 需求管理计划 如何规划、跟踪和报告各种需求活动; 配置管理活动,例如如何启动变更,如何分析其影响,如何进行追溯、跟踪和报告,以及如何变更审批权限; 需求优先级排序过程; 测量指标及使用这些指标的理由; 反映哪些需求属性将被列入跟踪矩阵的跟踪结构。 5.2 收集需求 收集需求是为实现目标而确定、记录并管理相关方的需要和需求的过程。本过程的主要作用是,为定义产品范围和项目范围奠定基础,且仅开展一次或仅在项目的预定义点开展。 收集需求:输入、工具与技术和输出 收集需求:数据流向图 5.2.1 收集需求:输入 收集需求的需求包括: 项目章程 项目管理计划 范围管理计划 需求管理计划 相关方参与计划 项目文件 假设日志 经验教训登记册 相关方登记册 商业文件 协议 事业环境因素 组织文化 基础设施 人事管理制度 市场条件 组织过程资产 政策和程序 包含以往项目信息的历史信息和经验教训知识库 5.2.2 收集需求:工具与技术 收集需求需要的工具与技术包括: 专家判断 商业分析 需求获取 需求分析 需求文件 以往类似项目的项目需求 图解技术 引导 冲突管理 数据收集 头脑风暴 访谈 焦点小组 问卷调查 标杆对照 数据分析 协议 商业计划 业务流程或接口文档 业务规则库 现行流程 市场文献 问题日志 政策和程序 法规文件 建议邀请书 用例 决策 投票 独裁型决策执行 多标准决策分析 数据表现 亲和图:用来对大量创意进行分组的技术,以便进一步审查和分析 思维导图:把从头脑风暴中获得的创意整合成一张图,用以反映创意之间的共性和差异,激发新创意 人际关系与团队技能 名义小组技术,名义小组技术是用于促进头脑风暴的一种技术,通过投票排列最有用的创意,以便进一步开展头脑风暴或优先排序。名义小组技术是一种结构化的头脑风暴形式,由四个步骤组成: 向小组提出一个问题或难题。每个人在沉思后写出自己的想法。 主持人在活动挂图上记录所有人的想法。 集体讨论各个想法,直到全体成员清晰理解。 个人私下投票决出各种想法的优先排序,通常采用 5 分制,1 分最低,5 分最高。为减少想法数量、集中关注想法,可进行数轮投票。每轮投票后,都将清点选票,选出得分靠前的那些想法。 观察和交谈 引导,引导与主题研讨会结合使用,把主要相关方召集在一起定义产品需求。研讨会可用于快速定义跨职能需求并协调相关方的需求差异。因为具有群体互动的特点,有效引导的研讨会有助于参与者之间建立信任、改进关系、改善沟通,从而有利于相关方达成一致意见。此外,与分别召开会议相比,研讨会能够更早发现并更快解决问题。适合采用引导技能的情境包括(但不限于): 联合应用设计或开发 (JAD)。JAD 会议适用于软件开发行业。这种研讨会注重把业务主题专家和开发团队集中在一起,以收集需求和改进软件开发过程。 质量功能展开 (QFD)。制造行业则采用 QFD 这种引导技能来帮助确定新产品的关键特征。QFD从收集客户需要(又称“客户声音”)开始,然后客观地对这些需要进行分类和排序,并为实现这些需要而设定目标。 用户故事。用户故事是对所需功能的简短文字描述,经常产生于需求研讨会。用户故事描述哪个相关方将从功能中受益(角色),他需要实现什么(目标),以及他期望获得什么利益(动机)。 系统交互图,系统交互图是范围模型的一个例子,它是对产品范围的可视化描绘,显示业务系统(过程、设备、计算机系统等)及其与人和其他系统(行动者)之间的交互方式。 原型法,原型法是指在实际制造预期产品之前,先造出该产品的模型,并据此征求对需求的早期反馈。原型包括微缩产品、计算机生成的二维和三维模型、实体模型或模拟。因为原型是有形的实物,它使得相关方可以体验最终产品的模型,而不是仅限于讨论抽象的需求描述。原型法支持渐进明细的理念,需要经历从模型创建、用户体验、反馈收集到原型修改的反复循环过程。在经过足够的反馈循环之后,就可以通过原型获得足够的需求信息,从而进入设计或制造阶段。故事板是一种原型技术,通过一系列的图像或图示来展示顺序或导航路径。故事板用于各种行业的各种项目中,如电影、广告、教学设计,以及敏捷和其他软件开发项目。在软件开发中,故事板使用实体模型来展示网页、屏幕或其他用户界面的导航路径。 5.2.3 收集需求:输出 收集需求的输出包括: 需求文件 业务需求 相关方需求 解决方案需求 功能需求 非功能需求 过渡和就绪需求 项目需求 质量需求 需求跟踪矩阵:需求跟踪矩阵是把产品需求从其来源连接到能满足需求的可交付成果的一种表格。使用需求跟踪矩阵,把每个需求与业务目标或项目目标联系起来,有助于确保每个需求都具有商业价值。 业务需要、机会、目的和目标; 项目目标; 项目范围和 WBS 可交付成果; 产品设计; 产品开发; 测试策略和测试场景; 高层级需求到详细需求。 需求跟踪矩阵示例 5.3 定义范围 定义范围是制定项目和产品详细描述的过程。本过程的主要作用是,描述产品、服务或成果的边界和验收标准。 定义范围:输入、工具与技术和输出 定义范围:数据流向图 5.3.1 定义范围:输入 定义范围的输入包括: 项目章程 项目管理计划 项目文件 假设日志 需求文件 风险登记册 事业环境因素 组织文化 基础设施 人事管理制度 市场条件 组织过程资产 用于制定项目范围说明书的政策、程序和模板 以往项目的项目档案 以往阶段或项目的经验教训 5.3.2 定义范围:工具与技术 定义范围需要的工具与技术包括: 专家判断 数据分析 决策 人际关系与团队技能 产品分析 产品分解 需求分析 系统分析 系统工程 价值分析 价值工程 5.3.3 定义范围:输出 定义范围的输出包括: 项目范围说明书:项目范围说明书是对项目范围、主要可交付成果、假设条件和制约因素的描述。它记录了整个范围,包括项目和产品范围;详细描述了项目的可交付成果;还代表项目相关方之间就项目范围所达成的共识。为便于管理相关方的期望,项目范围说明书可明确指出哪些工作不属于本项目范围。 产品范围描述 可交付成果 验收标准 项目的除外责任:识别排除在项目之外的内容 项目文件更新 假设日志 需求文件 需求跟踪矩阵 相关方登记册 5.4 创建WBS 创建工作分解结构(WBS)是把项目可交付成果和项目工作分解成较小、更易于管理的组件的过程。本过程的主要作用是,为所要交付的内容提供架构,它仅开展一次或仅在项目的预定义点开展。 WBS 是对项目团队为实现项目目标、创建所需可交付成果而需要实施的全部工作范围的层级分解。WBS 组织并定义了项目的总范围,代表着经批准的当前项目范围说明书中所规定的工作。 创建 WBS:输入、工具与技术和输出 创建 WBS:数据流向图 5.4.1 创建WBS:输入 创建WBS的输入包括: 项目管理计划 项目文件 项目范围说明书 需求文件 事业环境因素 组织过程资产 用于创建WBS的政策、程序和模板 以往项目的项目档案 以往项目的经验教训 5.4.2 创建WBS:工具与技术 创建WBS需要的工具和技术包括: 专家判断 分解:分解是一种把项目范围和项目可交付成果逐步划分为更小、更便于管理的组成部分的技术;工作包是 WBS 最低层的工作,可对其成本和持续时间进行估算和管理。分解的程度取决于所需的控制程度,以实现对项目的高效管理;工作包的详细程度则因项目规模和复杂程度而异。 识别和分析可交付成果及相关工作; 确定 WBS 的结构和编排方法; 自上而下逐层细化分解; 为 WBS 组成部分制定和分配标识编码; 核实可交付成果分解的程度是否恰当。 WBS示例 5.4.3 创建WBS:输出 创建WBS的输出包括: 范围基准 项目范围说明书 WBS 工作包:WBS 的最低层级是带有独特标识号的工作包。这些标识号为进行成本、进度和资源信息的逐层汇总提供了层级结构,构成账户编码。每个工作包都是控制账户的一部分,而控制账户则是一个管理控制点。在该控制点上,把范围、预算和进度加以整合,并与挣值相比较,以测量绩效。控制账户拥有两个或更多工作包,但每个工作包只与一个控制账户关联。 规划包:一个控制账户可以包含一个或多个规划包,其是一种低于控制账户而高于工作包的工作分解结构组件,工作内容已知,但详细的进度活动未知。 WBS词典 项目文件更新 假设日志 需求文件 5.5 确认范围 确认范围是正式验收已完成的项目可交付成果的过程。本过程的主要作用是,使验收过程具有客观性;同时通过确认每个可交付成果,来提高最终产品、服务或成果获得验收的可能性。 确认范围:输入、工具与技术和输出 确认范围:数据流向图 5.5.1 确认范围:输入 确认范围的输入包括: 项目管理计划 范围管理计划 需求管理计划 范围基准 项目文件 经验教训登记册 质量报告 需求文件 需求跟踪矩阵 核实的可交付成果 工作绩效数据 5.5.2 确认范围:工具与技术 确认范围需要的工具与技术包括: 检查 决策 5.5.3 确认范围:输出 确认范围的输出包括: 验收的可交付成果 工作绩效信息 变更请求 项目文件更新 5.6 控制范围 控制范围是监督项目和产品的范围状态,管理范围基准变更的过程。本过程的主要作用是,在整个项目期间保持对项目基准的维护,且需要在整个项目期间开展。 控制范围:输入、工具与技术和输出 控制范围:数据流向图 5.6.1 控制范围:输入 控制范围的输入包括: 项目管理计划 范围管理计划 需求管理计划 变更管理计划 配置管理计划 范围基准 绩效测量基准 项目文件 经验教训登记册 需求文件 需求跟踪矩阵 工作绩效数据 组织过程资产 现有的、正式和非正式的,与范围控制相关的政策、程序和指南 可用的监督和报告的方法和模板 5.6.2 控制范围:工具与技术 控制范围需要的工具与技术包括: 数据分析 偏差分析 趋势分析 5.6.3 控制范围:输出 控制范围的输出包括: 工作绩效信息 变更请求 项目管理计划更新 范围管理计划 范围基准 进度基准 成本基准 绩效测量基准 项目文件更新 经验教训登记册 需求文件 需求跟踪矩阵 6.项目进度管理 项目进度管理包括为管理项目按时完成所需的各个过程。其过程包括: 6.1 规划进度管理 — 为规划、编制、管理、执行和控制项目进度而制定政策、程序和文档的过程。 6.2 定义活动 — 识别和记录为完成项目可交付成果而需采取的具体行动的过程。 6.3 排列活动顺序 — 识别和记录项目活动之间的关系的过程。 6.4 估算活动持续时间 — 根据资源估算的结果,估算完成单项活动所需工作时段数的过程。 6.5 制定进度计划 — 分析活动顺序、持续时间、资源需求和进度制约因素,创建项目进度模型,从而落实项目执行和监控的过程。 6.6 控制进度 — 监督项目状态,以更新项目进度和管理进度基准变更的过程。 项目进度管理概述 项目进度管理的核心概念 通过项目进度规划制定详尽的计划,说明项目如何以及何时交付项目范围中定义的产品、服务和成果,并作为一种用于沟通和管理相关方期望的工具,以及报告绩效的基础。 项目管理团队选择进度计划方法,例如关键路径法或敏捷方法。之后,项目管理团队将项目特定数据,如活动、计划日期、持续时间、资源、依赖关系和制约因素等输入进度计划编制工具,以创建项目进度模型。这件工作的成果就是项目进度计划。 进度规划工作概述 具有未完项的迭代型进度计划 这是一种基于适应型生命周期的滚动式规划,例如敏捷的产品开发方法。这种方法将需求记录在用户故事中,然后在建造之前按优先级排序并优化用户故事,最后在规定的时间盒内开发产品功能。这一方法通常用于向客户交付增量价值,或多个团队并行开发大量内部关联较小的功能。适应型生命周期在产品开发中的应用越来越普遍,很多项目都采用这种进度计划方法。这种方法的好处在于,它允许在整个开发生命周期期间进行变更。 按需进度计划 这种方法通常用于看板体系,基于制约理论和来自精益生产的拉动式进度计划概念,根据团队的交付能力来限制团队正在开展的工作。按需进度计划方法不依赖于以前为产品开发或产品增量制定的进度计划,而是在资源可用时立即从未完项和工作序列中提取出来开展。按需进度计划方法经常用于此类项目:在运营或持续环境中以增量方式研发产品,且任务的规模或范围相对类似,或者,可以按照规模或范围对任务进行组合的项目。 裁剪考虑因素 由于每个项目都是独特的,因此项目经理可能需要裁剪项目进度管理过程。裁剪时应考虑的因素包括(但不限于): 生命周期方法。哪种生命周期方法最适合制定详细的进度计划 资源可用性。影响资源可持续时间的因素是什么(如可用资源与其生产效率之间的相关性) 项目维度。项目复杂性、技术不确定性、产品新颖度、速度或进度跟踪要求(如挣值、完成百分比、“红黄绿”停止信号灯指示)如何影响预期的控制水平 技术支持。是否采用技术来制定、记录、传递、接收和存储项目进度模型的信息以及该技术是否易于获取 6.1 规划进度管理 规划进度管理是为控制、编制、管理、执行和控制项目进度而制定政策、程序和文档的过程。本过程的主要作用是,为如何在整个项目期间管理项目进度提供指南和方向。 6.1.1 规划进度管理:输入 规划进度管理的输入包括: 项目章程 项目管理计划 范围管理计划 开发方法监督和报告 事业环境因素 组织文化和结构 团队资源可用性、技能以及物流资源可用性 进度计划软件 指南和标准,用于裁剪组织标准过程和程序以满足项目的特定要求 商业数据库 组织过程资产 历史信息和经验教训知识库 现有与制定进度计划以及管理和控制进度相关的正式和非正式的程序、程序和时间 模板和表格 监督和报告工具 6.1.2 规划进度管理:工具与技术 规划进度管理需要的工具与技术包括: 专家判断 进度计划的编制、管理和控制 进度计划方法 进度项目软件 进度计划软件项目所在特定行业 数据分析 会议 6.1.3 规划进度管理:输出 规划进度管理的输出包括: 进度管理计划:进度管理计划是项目管理计划的组成部分,为编制、监督和控制项目进度建立准则和明确活动。根据项目需要,进度管理计划可以是正式或非正式的,非常详细或高度概括的,其中应包括合适的控制临界值。 项目进度模型制定。需要规定用于制定项目进度模型的进度规划方法论和工具。 进度计划的发布和迭代长度。使用适应型生命周期时,应指定固定时间的发布时段、阶段和迭代。固定时间段指项目团队稳定地朝着目标前进的持续时间,它可以推动团队先处理基本功能,然后在时间允许的情况下再处理其他功能,从而尽可能减少范围蔓延。 准确度。准确度定义了需要规定活动持续时间估算的可接受区间,以及允许的应急储备数量。 计量单位。需要规定每种资源的计量单位,例如,用于测量时间的人时数、人天数或周数,用于计量数量的米、升、吨、千米或立方码。 组织程序链接。工作分解结构为进度管理计划提供了框架,保证了与估算及相应进度计划的协调性。 项目进度模型维护。需要规定在项目执行期间,将如何在进度模型中更新项目状态,记录项目进展。 控制临界值。可能需要规定偏差临界值,用于监督进度绩效。它是在需要采取某种措施前,允许出现的最大差异。临界值通常用偏离基准计划中的参数的某个百分数来表示。 绩效测量规则。需要规定用于绩效测量的挣值管理(EVM)规则或其他测量规则。例如,进度管理计划可能规定: 确定完成百分比的规则; EVM 技术,如基准法、固定公式法、完成百分比法等; 进度绩效测量指标,如进度偏差(SV)和进度绩效指数(SPI),用来评价偏离原始进度基准的程度。 报告格式。需要规定各种进度报告的格式和编制频率。 6.2 定义活动 定义活动是识别和记录为完成项目可交付成果而须必须采取的具体行动的过程。本过程的主要作用是,将工作包分解为进度活动,作为对项目工作进行进度估算、规划、执行、监督和控制的基础。本过程需要在整个项目期间开展。 6.2.1 定义活动:输入 定义活动的输入包括: 项目管理计划 进度管理计划 范围基准 事业环境因素 组织文化和结构 商业数据库中发布的商业信息 项目管理信息系统 组织过程资产 经验教训知识库,其中包含以往类似项目的活动清单等历史信息 标准化的流程 以往项目中包含标准活动清单或部分活动清单的模板 现有与活动规划相关的正式和非正式的政策、程序和指南,如进度规划方法论,在编制活动定义时应考虑这些因素 6.2.2 定义活动:工具与技术 定义活动需要的工具和技术包括: 专家判断 分解 滚动式规划:滚动式规划是一种迭代式的规划技术,即详细规划近期要完成的工作,同时在较高层级上粗略规划远期工作。它是一种渐进明细的规划方式,适用于工作包、规划包以及采用敏捷或瀑布式方法的发布规划。 会议 6.2.3 定义活动:输出 定义活动的输出包括: 活动清单:活动清单包含项目所需的进度活动 活动属性:活动属性是指每项活动所具有的多重属性,用来扩充对活动的描述 里程碑清单 变更请求 项目管理计划更新 进度基准 成本基准 6.3 排列活动顺序 排列活动顺序是识别和记录项目活动之间的关系的过程,本过程的主要作用是定义工作之间的逻辑顺序,以便在既定的所有项目制约因素下获得最高的效率。 6.3.1 排列活动顺序:输入 排列活动顺序的输入包括: 项目管理计划 进度管理计划 范围基准 项目文件 活动属性 活动清单 假设日志 里程碑清单 事业环境因素 政府或行业标准 项目管理信息系统 进度规划工具 组织的工作授权系统 组织过程资产 项目组织和项目集规划,以及项目之间的依赖关系与关联 现有与活动规划相关的正式和非正式的政策、程序和指南,如进度计划方法论,在确定逻辑关系时应考虑这些因素; 有助于加快项目活动网络图编制的各种模板;模板中也会包括有助于排列活动顺序的,与活动属性有关的信息; 经验教训知识库,其中包含有助于优化排序过程的历史信息。 6.3.2 排列活动顺序:工具与技术 排列活动顺序需要的工具和技术包括: 紧前关系绘图法:紧前关系绘图法(PDM)是创建进度模型的一种技术,用节点表示活动,用一种或多种逻辑关系连接活动,以显示活动的实施顺序。PDM 包括四种依赖关系或逻辑关系。紧前活动是在进度计划的逻辑路径中,排在某个活动前面的活动。紧后活动是在进度计划的逻辑路径中,排在某个活动后面的活动。 完成到开始(FS)。只有紧前活动完成,紧后活动才能开始的逻辑关系。例如,只有完成装配PC 硬件(紧前活动),才能开始在 PC 上安装操作系统(紧后活动)。 完成到完成(FF)。只有紧前活动完成,紧后活动才能完成的逻辑关系。例如,只有完成文件的编写(紧前活动),才能完成文件的编辑(紧后活动)。 开始到开始(SS)。只有紧前活动开始,紧后活动才能开始的逻辑关系。例如,开始地基浇灌(紧前活动)之后,才能开始混凝土的找平(紧后活动)。 开始到完成(SF)。只有紧前活动开始,紧后活动才能完成的逻辑关系。例如,只有启动新的应付账款系统(紧前活动),才能关闭旧的应付账款系统(紧后活动)。 确定和整合依赖关系 强制性依赖关系。强制性依赖关系是法律或合同要求的或工作的内在性质决定的依赖关系,强制性依赖关系往往与客观限制有关。例如,在建筑项目中,只有在地基建成后,才能建立地面结构;在电子项目中,必须先把原型制造出来,然后才能对其进行测试。强制性依赖关系又称硬逻辑关系或硬依赖关系。技术性依赖关系并非都是强制性的。在活动排序过程中,项目团队应明确哪些关系是强制性依赖关系,不应把强制性依赖关系和进度计划编制工具中的进度制约因素相混淆。 选择性依赖关系。选择性依赖关系有时又称首选逻辑关系、优先逻辑关系或软逻辑关系。便还有其他依赖关系可用,选择性依赖关系应基于具体应用领域的最佳实践或项目的某些特殊性质对活动顺序的要求来创建。例如,根据普遍公认的最佳实践,在建筑施工期间,应该先完成给排水施工,再开始电气施工。 这个顺序并不是强制性的。虽然两项工作可以同时(并行)开展,但是按先后顺序开展可以降低整体项目风险。应该对选择性依赖关系进行全面记录,因为它们会影响总浮动时间,并限制后续的进度安排。如果打算进行快速跟进,则应当审查相应的选择性依赖关系,并考虑是否需要调整或去除。在排列活动顺序过程中,项目团队应明确哪些依赖关系属于选择性依赖关系。 外部依赖关系。外部依赖关系是项目活动与非项目活动之间的依赖关系,这些依赖关系往往不在项目团队的控制范围内。例如,软件项目的测试活动取决于外部硬件的到货;建筑项目的现场准备,可能要在政府的环境听证会之后才能开始。在排列活动顺序过程中,项目管理团队应明确哪些依赖关系属于外部依赖关系。 内部依赖关系。内部依赖关系是项目活动之间的紧前关系,通常在项目团队的控制之中。例如,只有机器组装完毕,团队才能对其测试,这是一个内部的强制性依赖关系。在排列活动顺序过程中,项目管理团队应明确哪些依赖关系属于内部依赖关系。 提前量和滞后量 提前量是相对于紧前活动,紧后活动可以提前的时间量。例如,在新办公大楼建设项目中,绿化施工可以在尾工清单编制完成前 2 周开始,这就是带 2 周提前量的完成到开始的关系,如图 6-10 所示。在进度计划软件中,提前量往往表示为负滞后量。 滞后量是相对于紧前活动,紧后活动需要推迟的时间量。例如,对于一个大型技术文档,编写小组可以在编写工作开始后 15 天,开始编辑文档草案,这就是带 15 天滞后量的开始到开始关系,如图 6-10 所示。在图 6-11 的项目进度网络图中,活动 H 和活动 I 之间就有滞后量,表示为SS+10(带10 天滞后量的开始到开始关系),虽然图中并没有用精确的时间刻度来表示滞后的量值。 项目管理信息系统 6.3.3 排列活动顺序:输出 排列活动顺序的输出包括: 项目进度网络图:项目进度网络图是表示项目进度活动之间的逻辑关系(也叫依赖关系)的图形。项目进度网络图可手工或借助项目管理软件来绘制,可包括项目的全部细节,也可只列出一项或多项概括性活动。项目进度网络图应附有简要文字描述,说明活动排序所使用的基本方法。在文字描述中,还应该对任何异常的活动序列做详细说明。 项目文件更新 活动属性 活动清单 假设日志 里程碑清单 6.4 估算活动持续时间 估算活动持续时间是根据资源估算的结果,估算完成单项活动所需工作时段数的过程。本过程的主要作用是,确定完成每个活动所需花费的时间量。本过程需要在整个项目期间开展。 估算活动持续时间依据的信息包括:工作范围、所需资源类型与技能水平、估算的资源数量和资源日历,而可能影响持续时间估算的其他因素包括对持续时间受到的约束、相关人力投入、资源类型(如固定持续时间、固定人力投入或工作、固定资源数量)以及所采用的进度网络分析技术。应该由项目团队中最熟悉具体活动的个人或小组提供持续时间估算所需的各种输入,对持续时间的估算也应该渐进明细,取决于输入数据的数量和质量。 在本过程中,应该首先估算出完成活动所需的工作量和计划投入该活动的资源数量,然后结合项目日历和资源日历,据此估算出完成活动所需的工作时段数(活动持续时间)。在许多情况下,预计可用的资源数量以及这些资源的技能熟练程度可能会决定活动的持续时间,更改分配到活动的主导性资源通常会影响持续时间,但这不是简单的“直线”或线性关系。有时候,因为工作的特性(即受到持续时间的约束、相关人力投入或资源数量),无论资源分配如何(如 24 小时应力测试),都需要花预定的时间才能完成工作。估算持续时间时需要考虑的其他因素包括: 收益递减规律。在保持其他因素不变的情况下,增加一个用于确定单位产出所需投入的因素(如资源)会最终达到一个临界点,在该点之后的产出或输出会随着增加这个因素而递减。 资源数量。增加资源数量,使其达到初始数量的两倍不一定能缩短一半的时间,因为这样做可能会因风险而造成持续时间增加;在某些情况下,如果增加太多活动资源,可能会因知识传递、学习曲线、额外合作和其他相关因素而造成持续时间增加。 技术进步。在确定持续时间估算时,这个因素也可能发挥重要作用。例如,通过采购最新技术,制造工厂可以提高产量,而这可能会影响持续时间和资源需求。 员工激励。项目经理还需要了解“学生综合征”(即拖延症)和帕金森定律,前者指出,人们只有在最后一刻,即快到期限时才会全力以赴;后者指出,只要还有时间,工作就会不断扩展,直到用完所有的时间。 6.4.1 估算活动持续时间:输入 估算活动持续时间的输入包括:项目管理计划 进度管理计划 范围基准 项目文件 活动属性 活动清单 假设日志 经验教训登记册 里程碑清单 项目团队派工单 资源分解结构 资源日历 资源需求 风险登记册 事业环境因素 持续时间估算数据库和其他参考数据 生产率测量指标 发布的商业信息 团队成员的所在地 组织过程资产 关于持续时间的历史信息 项目日历 估算政策 进度规划方法论 经验教训知识库 6.4.2 估算活动持续时间:工具与技术 估算活动持续时间需要的工具与技术包括: 专家判断 进度计划的编制、管理和控制 有关估算的专业知识 学科或应用知识 类比估算:类比估算是一种使用相似活动或项目的历史数据,来估算当前活动或项目的持续时间或成本的技术。类比估算以过去类似项目的参数值(如持续时间、预算、规模、重量和复杂性等)为基础,来估算未来项目的同类参数或指标。 参数估算:参数估算是一种基于历史数据和项目参数,使用某种算法来计算成本或持续时间的估算技术。它是指利用历史数据之间的统计关系和其他变量(如建筑施工中的平方英尺),来估算诸如成本、预算和持续时间等活动参数。 三点估算:通过考虑估算中的不确定性和风险,可以提高持续时间估算的准确性。使用三点估算有助于界定活动持续时间的近似区间: 最可能时间 ( tM)。基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现实预计、资源对其他参与者的可能依赖关系及可能发生的各种干扰等,所估算的活动持续时间。 最乐观时间 (tO)。基于活动的最好情况所估算的活动持续时间。 最悲观时间 (tP)。基于活动的最差情况所估算的持续时间。 基于持续时间在三种估算值区间内的假定分布情况,可计算期望持续时间 tE。一个常用公式为三角分布:tE = (tO + tM + tP) / 3。 自下而上估算:自下而上估算是一种估算项目持续时间或成本的方法,通过从下到上逐层汇总 WBS 组成部分的估算而得到项目估算。如果无法以合理的可信度对活动持续时间进行估算,则应将活动中的工作进一步细化,然后估算具体的持续时间,接着再汇总这些持续时间估算,得到每个活动的持续时间。活动之间可能存在或不存在会影响资源利用的依赖关系;如果存在,就应该对相应的资源使用方式加以说明,并记录在活动资源需求中。 数据分析 备选方案分析:备选方案分析用于比较不同的资源能力或技能水平、进度压缩技术、不同工具(手动和自动),以及关于资源的创建、租赁或购买决策。这有助于团队权衡资源、成本和持续时间变量,以确定完成项目工作的最佳方式。 储备分析:储备分析用于确定项目所需的应急储备量和管理储备。在进行持续时间估算时,需考虑应急储备(有时称为“进度储备”),以应对进度方面的不确定性。应急储备是包含在进度基准中的一段持续时间,用来应对已经接受的已识别风险。应急储备与“已知 — 未知”风险相关,需要加以合理估算,用于完成未知的工作量。应急储备可取活动持续时间估算值的某一百分比或某一固定的时间段,亦可把应急储备从各个活动中剥离出来并汇总。随着项目信息越来越明确,可以动用、减少或取消应急储备,应该在项目进度文件中清楚地列出应急储备。也可以估算项目进度管理所需要的管理储备量。管理储备是为管理控制的目的而特别留出的项目预算,用来应对项目范围中不可预见的工作。管理储备用来应对会影响项目的“未知-未知”风险,它不包括在进度基准中,但属于项目总持续时间的一部分。依据合同条款,使用管理储备可能需要变更进度基准。 决策 会议 6.4.3 估算活动持续时间:输出 估算活动持续时间的输出包括: 持续时间估算:持续时间估算是对完成某项活动、阶段或项目所需的工作时段数的定量评估,其中并不包括任何滞后量,但可指出一定的变动区间。 估算依据:持续时间估算所需的支持信息的数量和种类,因应用领域而异。不论其详细程度如何,支持性文件都应该清晰、完整地说明持续时间估算是如何得出的。 关于估算依据的文件 关于全部假设条件的文件 关于各种已知制约因素的文件 对估算区间的说明,以指出预期持续时间的所在区间 对最终估算的置信水平的说明 有关影响估算的单个项目风险的文件 项目文件更新 活动属性 假设日志 经验教训登记册 6.5 制定进度计划 制定进度计划是分析活动顺序、持续时间、资源需求和进度制约因素,创建进度模型,从而落实项目执行和监控的过程。本过程的主要作用是,为完成项目活动而制定具有计划日期的进度模型。本过程需要在整个项目活动期间开展。 制定可行的项目进度计划是一个反复进行的过程。基于获取的最佳信息,使用进度模型来确定各项目活动和里程碑的计划开始日期和计划完成日期。编制进度计划时,需要审查和修正持续时间估算、资源估算和进度储备,以制定项目进度计划,并在经批准后作为基准用于跟踪项目进度。关键步骤包括定义项目里程碑、识别活动并排列活动顺序,以及估算持续时间。一旦活动的开始和完成日期得到确定,通常就需要由分配至各个活动的项目人员审查其被分配的活动。之后,项目人员确认开始和完成日期与资源日历没有冲突,也与其他项目或任务没有冲突,从而确认计划日期的有效性。然后要分析进度计划,确定是否存在逻辑关系冲突,以及在批准进度计划并将其作为基准之前是否需要资源平衡。还需要在整个项目期间不断修订和维护项目进度模型,确保进度计划一直切实可行。 6.5.1 制定进度计划:输入 制定进度计划的输入包括: 项目管理计划 进度管理计划 范围基准 项目文件 活动属性 活动清单 假设日志 估算依据 持续时间估算 经验教训 里程碑清单 项目进度网络图 项目团队派工单 资源日历 资源需求 风险登记册 协议 事业环境因素 政府或行业标准 沟通渠道 组织过程资产 进度计划方法论 项目日历 6.5.2 制定进度计划:工具与技术 制定进度计划需要的工具与技术包括: 进度网络分析:进度网络分析是创建项目进度模型的一种综合技术。 关键路径法:关键路径法用于在进度模型中估算项目最短工期,确定逻辑网络路径的进度灵活性大小。这种进度网络分析技术在不考虑任何资源限制的情况下,沿进度网络路径使用顺推与逆推法,计算出所有活动的最早开始、最早结束、最晚开始和最晚法完成日期 资源优化:资源优化用于调整活动的开始和完成日期,以调整计划使用的资源,使其等于或少于可用的资源。资源优化技术是根据资源供需情况,来调整进度模型的技术。 资源平衡:为了在资源需求与资源供给之间取得平衡,根据资源制约因素对开始日期和完成日期进行调整的一种技术。 资源平滑:对进度模型中的活动进行调整,从而使项目资源需求不超过预定的资源限制的一种技术。相对于资源平衡而言,资源平滑不会改变项目关键路径,完工日期也不会延迟。 数据分析 假设情景分析 模拟:模拟是把单个项目风险和不确定性的其他来源模型化,以评估它们对项目目标的潜在影响。最常见的模拟技术是蒙特卡罗分析,它利用风险和其他不确定性来源计算整个项目可能的进度结果。 提前量和滞后量 进度压缩 赶工 快速跟进 项目管理信息系统 敏捷发布规划:敏捷发布规划基于项目路线图和产品发展愿景,提供了高度概括的发布进度时间轴(通常是 3 到 6个月)。同时,敏捷发布规划还确定了发布的迭代或冲刺次数,使产品负责人和团队能够决定需要开发的内容,并基于业务目标、依赖关系和障碍因素确定达到产品放行所需的时间。 6.5.3 制定进度计划:输出 制定进度计划的输出包括: 进度基准:进度基准是经过批准的进度模型,只有通过正式的变更控制程序才能进行变更,用作与实际结果进行比较的依据。经相关方接受和批准,进度基准包含基准开始日期和基准结束日期。在监控过程中,将用实际开始和完成日期与批准的基准日期进行比较,以确定是否存在偏差。进度基准是项目管理计划的组成部分。 项目进度计划 横道图(甘特图) 里程碑图 项目进度网络图 进度数据:项目进度模型中的进度数据是用以描述和控制进度计划的信息集合。进度数据至少包括进度里程碑、进度活动、活动属性,以及已知的全部假设条件与制约因素,而所需的其他数据因应用领域而异。 项目日历 变更请求 项目管理计划更新 进度管理计划 成本基准 项目文件更新 活动属性 假设日志 持续时间估算 经验教训登记册 资源需求 风险登记册 6.6 控制进度 控制进度是监督项目状态,以更新项目进度和管理进度基准变更的过程。本过程的主要作用是在整个项目期间保持对进度基准的维护,且需要在整个项目期间开展。 控制进度作为实施整体变更控制过程的一部分,关注如下内容: 判断项目进度的当前状态; 对引起进度变更的因素施加影响; 重新考虑必要的进度储备; 判断项目进度是否已经发生变更; 在变更实际发生时对其进行管理。 如果采用敏捷方法,控制进度要关注如下内容: 通过比较上一个时间周期中已交付并验收的工作总量与已完成的工作估算值,来判断项目进度的当前状态; 实施回顾性审查(定期审查,记录经验教训),以便纠正与改进过程(如果需要的话); 对剩余工作计划(未完项)重新进行优先级排序; 确定在每段既定的迭代时间(约定的工作周期持续时间,通常是两周或一个月)内可交付成果的生成、核实和验收的速度; 确定项目进度已经发生变更; 在变更实际发生时对其进行管理。 6.6.1 控制进度:输入 控制进度的输入包括: 项目管理计划 进度管理计划 进度基准 范围基准 绩效测量基准 项目文件 经验教训登记册 项目日历 项目进度计划 资源日历 进度数据 工作绩效数据 组织过程资产 现有与进度控制有关的正式和非正式的政策、程序和指南 进度控制工具 可用的监督和报告方法 6.6.2 控制进度:工具与技术 控制进度需要的工具与技术包括: 数据分析 挣值分析 迭代燃尽图:这类图用于追踪迭代未完项中尚待完成的工作。它基于迭代规划中确定的工作,分析与理想燃尽图的偏差。可使用预测趋势线来预测迭代结束时可能出现的偏差,并据此在迭代期间采取合理行动。在燃尽图中,先用对角线表示理想的燃尽情况,再每天画出实际剩余工作,最后基于剩余工作计算出趋势线以预测完成情况。 绩效审查 趋势分析 偏差分析 假设情景分析 关键路径法 项目管理信息系统 资源优化 提前量和滞后量 进度压缩 6.6.3 控制进度:输出 控制进度的输出包括: 工作绩效信息 进度预测:进度更新即进度预测,指根据已有的信息和知识,对项目未来的情况和事件进行的估算或预计。随着项目执行,应该基于工作绩效信息,更新和重新发布预测。 变更请求 项目管理计划更新 进度管理计划 进度基准 成本基准 绩效测量基准 项目文件更新 假设日志 估算依据 经验教训登记册 项目进度计划 资源日历 风险登记册 进度数据 7.项目成本管理 项目成本管理包括为使项目在批准的预算内完成而对成本进行规划、估算、预算、融资、筹资、管理和控制的各个过程,从而确保项目在批准的预算内完工。项目成本管理过程包括: 7.1 规划成本管理 — 确定如何估算、预算、管理、监督和控制项目成本的过程。 7.2 估算成本 — 对完成项目活动所需货币资源进行近似估算的过程。 7.3 制定预算 — 汇总所有单个活动或工作包的估算成本,建立一个经批准的成本基准的过程。 7.4 控制成本 — 监督项目状态,以更新项目成本和管理成本基准变更的过程。 项目成本管理的核心概念 项目成本管理重点关注完成项目活动所需资源的成本,但同时也应考虑项目决策对项目产品、服务或成果的使用成本、维护成本和支持成本的影响。例如,限制设计审查的次数可降低项目成本,但可能增加由此带来的产品运营成本。 成本管理的另一个方面是认识到不同的相关方会在不同的时间,用不同的方法测算项目成本。例如,对于某采购品,可在做出采购决策、下达订单、实际交货、实际成本发生或进行项目会计记账时,测算其成本。在很多组织中,预测和分析项目产品的财务效益是在项目之外进行的,但对于有些项目,如固定资产投资项目,可在项目成本管理中进行这项预测和分析工作。在这种情况下,项目成本管理还需使用其他过程和许多通用财务管理技术,如投资回报率分析、现金流贴现分析和投资回收期分析等。 裁剪考虑因素 由于每个项目都是独特的,项目经理因此可能需要裁剪项目成本管理过程。裁剪时应考虑的因素包括(但不限于): 知识管理。组织是否拥有易于使用的、正式的知识管理体系和财务数据库,并要求项目经理使用 估算和预算。组织是否拥有正式或非正式的,与成本估算和预算相关的政策、程序和指南 挣值管理。组织是否采用挣值管理来管理项目 敏捷方法的使用。组织是否采用敏捷方法管理项目?这对成本估算有什么影响 治理。组织是否拥有正式或非正式的审计和治理政策、程序和指南 关于敏捷/适应型环境的考虑因素 对易变性高、范围并未完全明确、经常发生变更的项目,详细的成本计算可能没有多大帮助。在这种情况下,可以采用轻量级估算方法快速生成对项目人力成本的高层级预测,在出现变更时容易调整预测;而详细的估算适用于采用准时制的短期规划。 如果易变的项目也遵循严格的预算,通常需要更频繁地更改范围和进度计划,以始终保持在成本制约因素之内。 7.1 规划成本管理 规划成本管理是确定如何估算、预算、管理、监督和控制项目的过程。本过程的主要作用是,在整个项目期间为如何管理项目成本提供指南和方向。本过程仅开展一次或仅在项目的预定义点开展。 应该在项目规划阶段的早期就对成本管理工作进行规划,建立各成本管理过程的基本框架,以确保各过程的有效性和协调性。 7.1.1 规划成本管理:输入 规划成本管理的输入包括: 项目章程 项目管理计划 进度管理计划 风险管理计划 事业环境因素 能够影响成本管理的组织文化和组织结构 市场条件,决定着在当地及全球市场上可获取哪些产品、服务和成果 货币汇率,用于换算发生在多个国家的项目成本 发布的商业信息 项目管理信息系统 不同地区的生产率差异 组织过程资产 财务控制程序 历史信息和经验教训知识库 财务数据库 现有的正式和非正式的与成本估算和预算有关的政策、程序和指南 7.1.2 规划成本管理:工具与技术 规划成本管理需要的工具与技术包括: 专家判断 以往类似项目 来自行业、学科和应用领域的信息 成本估算和预算 挣值管理 数据分析 会议 7.1.3 规划成本管理:输出 规划成本管理的输出包括: 成本管理计划:成本管理计划是项目管理计划的组成部分,描述将如何规划、安排和控制项目成本。成本管理过程及其工具与技术应记录在成本管理计划中。例如,在成本管理计划中规定: 计量单位。需要规定每种资源的计量单位,例如用于测量时间的人时数、人天数或周数,用于计量数量的米、升、吨、千米或立方码,或者用货币表示的总价。 精确度。根据活动范围和项目规模,设定成本估算向上或向下取整的程度(例如 995.59 美元取整为 1,000 美元)。 准确度。为活动成本估算规定一个可接受的区间(如 ±10%),其中可能包括一定数量的应急储备。 组织程序链接。工作分解结构(见 5.4 节)为成本管理计划提供了框架,以便据此规范地开展 成本估算、预算和控制。在项目成本核算中使用的 WBS 组成部分,称为控制账户(CA),每个控制账户都有唯一的编码或账号,直接与执行组织的会计制度相联系。 控制临界值。可能需要规定偏差临界值,用于监督成本绩效。它是在需要采取某种措施前,允许出现的最大差异,通常用偏离基准计划的百分数来表示。 绩效测量规则。需要规定用于绩效测量的挣值管理(EVM)规则。例如,成本管理计划应该: 定义 WBS 中用于绩效测量的控制账户; 确定拟用的 EVM 技术(如加权里程碑法、固定公式法、完成百分比法等); 规定跟踪方法,以及用于计算项目完工估算(EAC)的 EVM 公式,该公式计算出的结果可用于验证通过自下而上方法得出的完工估算。 报告格式。需要规定各种成本报告的格式和编制频率。 其他细节。关于成本管理活动的其他细节包括(但不限于): 对战略筹资方案的说明; 处理汇率波动的程序; 记录项目成本的程序。 7.2 估算成本 估算成本是对完成项目工作所需资源成本进行近似估算的过程。本过程的主要作用是,确定项目所需的资金。本过程应根据需要在整个项目期间定期开展。 成本估算是对完成活动所需资源的可能成本的量化评估,是在某特定时点,根据已知信息所做出的成本预测。在估算成本时,需要识别和分析可用于启动与完成项目的备选成本方案;需要权衡备选成本方案并考虑风险,如比较自制成本与外购成本、购买成本与租赁成本及多种资源共享方案,以优化项目成本。 通常用某种货币单位(如美元、欧元、日元等)进行成本估算,但有时也可采用其他计量单位,如人时数或人天数,以消除通货膨胀的影响,便于成本比较。 7.2.1 估算成本:输入 估算成本的输入包括: 项目管理计划 成本管理计划 质量管理计划 范围基准 项目范围说明书 工作分解结构 WBS词典 项目文件 经验教训登记册 项目进度计划 资源需求 风险登记册 事业环境因素 市场条件 发布的商业信息 汇率和通货膨胀率 组织过程资产 成本估算政策 成本估算模板 历史信息和经验教训知识库 7.2.2 估算成本:工具与技术 估算成本需要的工具与技术包括: 专家判断 以往类似项目 来自行业、学科和应用领域的信息 成本估算方法 类比估算 参数估算 自下而上估算 三点估算 最可能成本(cM)。对所需进行的工作和相关费用进行比较现实的估算,所得到的活动成本。 最乐观成本(cO)。基于活动的最好情况所得到的成本。 最悲观成本(cP)。基于活动的最差情况所得到的成本。 三角分布。cE = (cO + cM + cP) / 3 贝塔分布。cE = (cO + 4cM + cP) / 6 数据分析 备选方案分析 储备分析:为应对成本的不确定性,成本估算中可以包括应急储备(有时称为“应急费用”)。应急储备是包含在成本基准内的一部分预算,用来应对已识别的风险;应急储备往往被看作预算中用来应对会影响项目的“已 知 — 未知”风险的那一部分。 质量成本 项目管理信息系统 决策 7.2.3 估算成本:输出 估算成本的输出包括: 成本估算:成本估算包括对完成项目工作可能需要的成本、应对已识别风险的应急储备,以及应对计划外工作的管理储备的量化估算。 估算依据 关于估算依据的文件(如估算是如何编制的); 关于全部假设条件的文件; 关于各种已知制约因素的文件; 有关已识别的、在估算成本时应考虑的风险的文件; 对估算区间的说明(如“10,000美元 ±10%”就说明了预期成本的所在区间); 对最终估算的置信水平的说明。 项目文件更新 假设日志 经验教训登记册 风险登记册 7.3 制定预算 制定预算是汇总所有单个活动或工作包的估算成本,建立一个经批准的成本基准的过程。本过程的主要作用是,确定可据以监督和控制项目绩效的成本基准。本过程仅开展一次或仅在项目的预定义点开展。 项目预算包括经批准用于执行项目的全部资金,而成本基准是经过批准且按时间段分配的项目语速那,包括应急储备,但不包括管理储备。 7.3.1 制定预算:输入 制定预算的输入包括: 项目管理计划 成本管理计划 资源管理计划 范围基准 项目文件 估算依据 成本估算 项目进度计划 风险登记册 商业文件 商业论证 效益管理计划 协议 事业环境因素 组织过程资产 现有的正式和非正式的与成本预算有关的政策、程序和指南 历史信息和经验教训知识库 成本预算工具 报告方法 7.3.2 制定预算:工具与技术 制定预算需要的工具与技术包括: 专家判断 以往类似项目 来自行业、学科和应用领域的信息 财务原则 黄金需求和来源 成本汇总 数据分析 历史信息审核:审核历史信息有助于进行参数估算或类比估算。历史信息可包括各种项目特征(参数),它们用于建立数学模型预测项目总成本。 资金限制平衡 融资 7.3.3 制定预算:输出 制定预算的输出包括: 成本基准 项目资金需求 项目文件更新 成本估算 项目进度计划 风险登记册 7.4 控制成本 控制成本是监督项目状态,以更新项目成本和管理成本基准变更的过程。本过程的主要作用是,在整个项目期间保持对成本基准的维护。本过程需要在整个项目期间开展。 项目成本控制包括: 对造成成本基准变更的因素施加影响; 确保所有变更请求都得到及时处理; 更实际发生时,管理这些变更; 确保成本支出不超过批准的资金限额,既不超出按时段、按 WBS 组件、按活动分配的限额,也不超出项目总限额; 监督成本绩效,找出并分析与成本基准间的偏差; 对照资金支出,监督工作绩效; 防止在成本或资源使用报告中出现未经批准的变更; 向相关方报告所有经批准的变更及其相关成本; 设法把预期的成本超支控制在可接受的范围内。 7.4.1 控制成本:输入 控制成本的输入包括: 项目管理计划 成本管理计划 成本基准 绩效测量基准 项目文件 项目资金需求 工作绩效数据 组织过程资产 现有的正式的和非正式的与成本控制相关的政策、程序和指南 成本控制工具 可用的监督和报告方法 7.4.2 控制成本:工具与技术 控制成本需要的工具与技术包括: 专家判断 偏差分析 挣值分析 预测 财务分析 数据分析 挣值分析 计划价值。计划价值(PV)是为计划工作分配的经批准的预算,它是为完成某活动或工作分解结构 (WBS) 组成部分而准备的一份经批准的预算,不包括管理储备。应该把该预算分配至项目生命周期的各个阶段;在某个给定的时间点,计划价值代表着应该已经完成的工作。PV的总和有时被称为绩效测量基准(PMB),项目的总计划价值又被称为完工预算(BAC)。 挣值。挣值(EV)是对已完成工作的测量值,用该工作的批准预算来表示,是已完成工作的经批准的预算。EV 的计算应该与 PMB 相对应,且所得的 EV 值不得大于相应组件的 PV 总预算。EV 常用于计算项目的完成百分比,应该为每个 WBS 组件规定进展测量准则,用于考核正在实施的工作。项目经理既要监测 EV 的增量,以判断当前的状态,又要监测 EV 的累计值,以判断长期的绩效趋势。 实际成本。实际成本(AC)是在给定时段内,执行某活动而实际发生的成本,是为完成与 EV相对应的工作而发生的总成本。AC 的计算方法必须与 PV 和 EV 的计算方法保持一致(例如,都只计算直接小时数,都只计算直接成本,或都计算包含间接成本在内的全部成本)。AC 没有上限,为实现 EV 所花费的任何成本都要计算进去。 偏差分析:在 EVM 中,偏差分析用以解释成本偏差(CV = EV – AC)、进度偏差(SV = EV – PV)和完工偏差(VAC = BAC – EAC)的原因、影响和纠正措施。成本和进度偏差是最需要分析的两种偏差。对于不使用正规挣值分析的项目,可开展类似的偏差分析,通过比较计划成本和实际成本,来识别成本基准与实际项目绩效之间的差异;然后可以实施进一步的分析,以判定偏离进度基准的原因和程度,并决定是否需要采取纠正或预防措施。可通过成本绩效测量来评价偏离原始成本基准的程度。 进度偏差。进度偏差(SV)是测量进度绩效的一种指标,表示为挣值与计划价值之差。它是指在某个给定的时点,项目提前或落后的进度,它是测量项目进度绩效的一种指标,等于挣值(EV)减去计划价值(PV)。EVA 进度偏差是一种有用的指标,可表明项目进度是落后还是提前于进度基准。当项目完工时,全部的计划价值都将实现(即成为挣值),所以 EVA 进度偏差最终将等于零。最好把进度偏差与关键路径法 (CPM) 和风险管理一起使用。公式:SV = EV – PV。 成本偏差。成本偏差(CV)是在某个给定时点的预算亏空或盈余量,表示为挣值与实际成本之差。它是测量项目成本绩效的一种指标,等于挣值(EV)减去实际成本(AC)。项目结束时的成本偏差,就是完工预算(BAC)与实际成本之间的差值。由于成本偏差指明了实际绩效与成本支出之间的关系,所以非常重要。负的 CV 一般都是难以挽回的。公式:CV = EV – AC。 进度绩效指数。进度绩效指数(SPI)是测量进度效率的一种指标,表示为挣值与计划价值之比,反映了项目团队完成工作的效率。有时与成本绩效指数(CPI)一起使用,以预测项目的最终完工估算。当 SPI 小于 1.0 时,说明已完成的工作量未达到计划要求;当 SPI 大于1.0 时,则说明已完成的工作量超过计划。由于 SPI 测量的是项目的总工作量,所以还需要对关键路径上的绩效进行单独分析,以确认项目是否将比计划完成日期提前或推迟完工。SPI等于 EV 与 PV 的比值。公式:SPI = EV/PV。 成本绩效指数。成本绩效指数(CPI)是测量预算资源的成本效率的一种指标,表示为挣值与实际成本之比。它是最关键的 EVA 指标,用来测量已完成工作的成本效率。当 CPI 小于 1.0时,说明已完成工作的成本超支;当 CPI 大于 1.0 时,则说明到目前为止成本有结余。CPI 等于 EV 与 AC 的比值。公式:CPI = EV/AC。 趋势分析:趋势分析旨在审查项目绩效随时间的变化情况,以判断绩效是正在改善还是正在恶化。图形分析技术有助于了解截至目前的绩效情况,并把发展趋势与未来的绩效目标进行比较,如 BAC 与EAC、预测完工日期与计划完工日期的比较。 图表。在挣值分析中,对计划价值、挣值和实际成本这三个参数,既可以分阶段(通常以周或月为单位)进行监督和报告,也可以针对累计值进行监督和报告。 预测。随着项目进展,项目团队可根据项目绩效,对完工估算(EAC)进行预测,预测的结果可能与完工预算(BAC)存在差异。如果 BAC 已明显不再可行,则项目经理应考虑对EAC进行预测。预测EAC是根据当前掌握的绩效信息和其他知识,预计项目未来的情况和事件。预测要根据项目执行过程中所提供的工作绩效数据(见 4.3.3.2 节)来产生、更新和重新发布。工作绩效信息包含项目过去的绩效,以及可能在未来对项目产生影响的任何信息。在计算 EAC 时,通常用已完成工作的实际成本,加上剩余工作的完工尚需估算(ETC)。项目团队要根据已有的经验,考虑实施 ETC 工作可能遇到的各种情况。把挣值分析与手工预测 EAC 方法联合起来使用,效果会更佳。由项目经理和项目团队手工进行的自下而上汇总方法,就是一种最普通的 EAC 预测方法。项目经理所进行的自下而上的 EAC 估算,就是以已完成工作的实际成本为基础,并根据已积累的经验来为剩余项目工作编制一个新估算。公式:EAC = AC + 自下而上的 ETC。 假设将按预算单价完成 ETC 工作。这种方法承认以实际成本表示的累计实际项目绩效(不论好坏),并预计未来的全部 ETC 工作都将按预算单价完成。如果目前的实际绩效不好,则只有在进行项目风险分析并取得有力证据后,才能做出“未来绩效将会改进”的假设。公式:EAC = AC +(BAC – EV)。 假设以当前 CPI 完成 ETC 工作。这种方法假设项目将按截至目前的情况继续进行,即 ETC工作将按项目截至目前的累计成本绩效指数(CPI)实施。公式:EAC = BAC/CPI。 假设 SPI 与 CPI 将同时影响 ETC 工作。在这种预测中,需要计算一个由成本绩效指数与进度绩效指数综合决定的效率指标,并假设 ETC 工作将按该效率指标完成。如果项目进度对 ETC 有重要影响,这种方法最有效。使用这种方法时,还可以根据项目经理的判断,分别给 CPI 和 SPI 赋予不同的权重,如 80/20、50/50 或其他比率。公式:EAC =AC +[(BAC – EV)/(CPI x SPI)]。 储备分析:在控制成本过程中,可以采用储备分析来监督项目中应急储备和管理储备的使用情况,从而判断是否还需要这些储备,或者是否需要增加额外的储备。随着项目工作的进展,这些储备可能已按计划用于支付风险或其他应急情况的成本;反之,如果抓住机会节约了成本,节约下来的资金可能会增加到应急储备中,或作为盈利(利润)从项目中剥离。 项目管理信息系统 完工尚需绩效指数 完工尚需绩效指数(TCPI) 是一种为了实现特定的管理目标,剩余资源的使用必须达到的成本绩效指标,是完成剩余工作所需的成本与剩余预算之比。TCPI 是指为了实现具体的管理目标(如BAC 或 EAC),剩余工作的实施必须达到的成本绩效指标。如果 BAC 已明显不再可行,则项目经理应考虑使用预测的 EAC。经过批准后,就用 EAC 取代 BAC。基于 BAC 的 TCPI 公式:TCPI =(BAC –EV)/(BAC – AC)。 TCPI 的概念可用图 7-13 表示。其计算公式在图的左下角,用剩余工作(BAC 减去 EV)除以剩余资金(可以是 BAC 减去 AC,或 EAC 减去 AC)。 如果累计 CPI 低于基准(如图 7-13 所示),那么项目的全部剩余工作都应立即按TCPI(BAC)(图7-13 中最高的那条线)执行,才能确保实际总成本不超过批准的 BAC。至于所要求的这种绩效水平是否可行,就需要综合考虑多种因素(包括风险、项目剩余时间和技术绩效)后才能判断;如果不可行,就需要把项目未来所需的绩效水平调整为如 TCPI(EAC)线所示。基于 EAC 的 TCPI 公式:TCPI =(BAC – EV)/(EAC – AC)。表 7-1 列出了 EVM 的计算公式。 7.4.3 控制成本:输出 控制成本的输出包括: 工作绩效信息 成本预测 变更请求 项目管理计划更新 成本管理计划 成本基准 绩效测量基准 项目文件更新 假设日志 估算依据 成本估算 经验教训登记册 风险登记册 8.项目质量管理 项目质量管理包括把组织的质量政策应用于规划、管理、控制项目和产品质量要求,以满足相关方目标的各个过程。此外,项目质量管理以执行组织的名义支持过程的持续改进。 项目质量管理过程包括: 8.1 规划质量管理 — 识别项目及其可交付成果的质量要求和/或标准,并书面描述项目将如何证明符合质量要求和/或标准的过程。 8.2 管理质量 — 把组织的质量政策应用于项目,并将质量管理计划转化为可执行的质量活动的过程。 8.3 控制质量 — 为了评估绩效,确保项目输出完整、正确,并满足客户期望,而监督和记录质量管理活动执行结果的过程。 项目质量管理的核心概念 项目质量管理需要兼顾项目管理和项目可交付成果两个方面,它适用于所有项目,无论项目的可交付成果具有何种特性。质量的测量方法和技术则需专门针对项目所产生的可交付成果类型而定。 “质量”和“等级”不是相同的概念。质量作为实现的性能或成果,是“一系列内在特性满足要求的程度”。等级作为设计意图,是对用途相同但技术特性不同的交付成果的级别分类。质量水平未达到质量要求肯定是个问题,而低等级产品不一定是个问题。 预防胜于检查。最好将质量设计到可交付成果中,而不是在检查时发现质量问题。预防错误的成本通常远低于在检查或使用中发现并纠正错误的成本。 按有效性递增排列的五种质量管理水平如下: 通常,代价最大的方法是让客户发现缺陷。这种方法可能会导致担保问题、召回、商誉受损和返工成本。 控制质量过程包括先检测和纠正缺陷,再将可交付成果发送给客户。该过程会带来相关成本,主要是评估成本和内部失败成本。 通过质量保证检查并纠正过程本身,而不仅仅是特殊缺陷。 将质量融入项目和产品的规划和设计中。 在整个组织内创建一种关注并致力于实现过程和产品质量的文化。 项目质量管理的趋势和新兴实践 现代质量管理方法力求缩小偏差,交付满足既定相关方要求的成果。项目质量管理的趋势包括(但不限于): 客户满意。了解、评估、定义和管理要求,以便满足客户的期望。这就需要把“符合要求”(确保项目产出预定的成果)和“适合使用”(产品或服务必须满足实际需求)结合起来。在敏捷环境中,应该让相关方参与团队工作,确保在整个项目期间始终做到客户满意。 持续改进。由休哈特提出并经戴明完善的“计划 — 实施 — 检查 — 行动 (PDCA)”循环是质量改进的基础。另外,诸如全面质量管理(TQM)、六西格玛和精益六西格玛等质量改进举措也可以提高项目管理的质量以及最终产品、服务或成果的质量。 管理层的责任。项目的成功需要项目团队全体成员的参与。管理层在其质量职责内,肩负着为项目提供具有足够能力的资源的相应责任。 与供应商的互利合作关系。组织与其供应商相互依赖。相对传统的供应商管理而言,与供应商建立合作伙伴关系对组织和供应商都更加有益。组织应着眼于长期关系而不是短期利益。互利合作关系增强了组织和供应商互相为对方创造价值的能力,推动他们共同实现客户的需求和期望,并优化成本和资源。 裁剪考虑因素 政策合规与审计 标准与法规合规性 持续改进 相关方参与 在敏捷或适应性环境中需要考虑的因素 为引导变更,敏捷方法要求在整个项目期间频繁开展质量与审核步骤,而不是在面临项目结束时才执行。 循环回顾,定期检查质量过程的效果;寻找问题的根本原因,然后建议实施新的质量改进方法;后续回顾会议评估试验过程,确定新方法是否可行,是否应继续使用,是否应该调整,或者直接弃用。 为促进频繁的増量交付,敏捷方法关注于小批量工作,纳入尽可能多的项目可交付成果的要素。小批量系统的目的是在项目生命周期早期(整体变更成本较低)发现不一致和质量问题。 8.1 规划质量管理 规划质量管理是识别项目及其可交付成果的质量要求和(或)标准,并书面描述项目将如何证明符合质量要求或标准的过程。本过程的主要作用是,为在整个项目期间如何管理和核实质量提供指南和方向。本过程仅开展一次或仅在项目的预定义点开展。 质量规划应与其他规划过程并行开展。例如,为满足既定的质量标准而对可交付成果提出变更,可能需要调整成本或进度计划,并就该变更对相关计划的影响进行详细风险分析。 8.1.1 规划质量管理:输入 规划质量管理的输入包括: 项目章程 项目管理计划 需求管理计划 风险管理计划 相关方参与计划 范围基准 项目文件 假设日志 需求文件 需求跟踪矩阵 风险登记册 相关方登记册 事业环境因素 政府法规 特定应用领域的相关规则、标准和指南 地理分布 组织结构 市场条件 项目或可交付成果的工作条件或运行条件 文化观念 组织过程资产 组织的质量管理体系,包括政策、程序及指南 质量模板,例如核查表、跟踪矩阵及其他 历史数据库和经验教训知识库 8.1.2 规划质量管理:工具与技术 规划质量管理需要的工具与技术包括: 专家判断 质量保证 质量控制 质量测量结果 质量改进 质量体系 数据收集 标杆对照:标杆对照是将实际或计划的项目实践或项目的质量标准与可比项目的实践或标准进行比较,以便识别最佳实践,形成改进意见,并为绩效考核提供依据。作为标杆的项目可以来自执行组织内部或外部,或者来自同一应用领域或其他应用领域。标杆对照也允许用不同应用领域或行业的项目做类比。 头脑风暴 访谈 数据分析 成本效益分析:成本效益分析是用来估算备选方案优势和劣势的财务分析工具,以确定可以创造最佳效益的备选方案。成本效益分析可帮助项目经理确定规划的质量活动是否具有成本有效性。达到质量要求的主要效益包括减少返工、提高生产率、降低成本、提升相关方满意度及提升赢利能力。对每个质量活动进行成本效益分析,就是要比较其可能成本与预期效益。 质量成本 预防成本:预防特定项目的产品、可交付成果或服务质量低劣所带来的相关成本; 评估成本:评估、测量、审计和测试特定项目的产品、可交付成果和服务所带来的相关成本; 失败成本(内部/外部):因产品、可交付成果或服务与相关方需求或期望不一致而导致的相关成本。 决策 数据表现 流程图 逻辑数据模型 矩阵图 思维导图 测试与检查规划 会议 8.1.3 规划质量管理:输出 规划质量管理的输出包括:质量管理计划:质量管理计划是项目管理计划的组成部分,描述如何实施适用的政策、程序和指南以实现质量目标。它描述了项目管理团队为实现一系列项目质量管理目标所需的活动和资源。质量管理计划可以是正式或非正式的,非常详细或高度概括的,其风格与详细程度取决于项目的具体需要。应该在项目早期就对质量管理计划进行评审,以确保决策是基于准确信息的。这样做的好处是,更加关注项目的价值定位,降低因返工而造成的成本超支金额和进度延误次数。 项目将采用的质量标准 项目的质量目标 质量角色与职责 需要质量审查的项目可交付成果和过程 为项目规划的质量控制和质量管理活动 项目将使用的质量工具 与项目有关的主要程序,例如处理不合符要求的情况、纠正措施程序,以及持续改进程序。 质量测量指标:质量测量指标专用于描述项目或产品属性,以及控制质量过程将如何验证质量符合测量指标程度。质量测量指标的例子包括按时完成的任务的百分比、以 CPI 测量的成本绩效、故障率、天发现的缺陷数量、每月总停机时间、每个代码行的错误、客户满意度分数,以及测试计划所涵盖的需求的百分比(即测试覆盖度)。 项目管理计划更新 风险管理计划 范围基准 项目文件更新 经验教训登记册 需求跟踪矩阵 风险登记册 相关方登记册 8.2 管理质量 管理质量是把组织的质量政策用于项目,并将质量管理计划转化为可执行的质量活动的过程。本过程的主要作用是,提高实现质量目标的可能性,以及识别无效过程和导致质量低劣的原因。管理质量使用控制质量过程的数据和结果向相关方展示项目的总体质量状态。本过程需要在整个项目期间开展。 管理质量过程执行在项目质量管理计划中所定义的一系列有计划、有系统的行动和过程,有助于: 通过执行有关产品特定方面的设计准则,设计出最优的成熟产品; 建立信心,相信通过质量保证工具和技术(如质量审计和故障分析)可以使未来输出在完工时满足特定的需求和期望; 确保使用质量过程并确保其使用能够满足项目的质量目标; 提高过程和活动的效率与效果,以获得更好的成果和绩效并提高相关方的满意程度。 项目经理和项目团队可以通过组织的质量保证部门或其他组织职能执行某些管理质量活动,例如故障分析、实验设计和质量改进。质量保证部门在质量工具和技术的使用方面通常拥有跨组织经验,是良好的项目资源。管理质量被认为是所有人的共同职责,包括项目经理、项目团队、项目发起人、执行组织的管理层,甚至是客户。 8.2.1 管理质量:输入 管理质量的输入包括: 项目管理计划 项目文件 经验教训登记册 质量控制测量结果 质量测量指标 风险报告 组织过程资产 包括政策、程序及指南的组织质量管理体系 质量模板,例如核查表、跟踪矩阵、测试计划、测试文件及其他模板 以往审计的结果 包含类似项目信息的经验教训知识库 8.2.2 管理质量:工具与技术 管理质量需要的工具与技术包括: 数据收集 核对单 数据分析 备选方案分析 文件分析 过程分析 根本原因分析(RCA) 决策 数据表现 亲和图 因果图 流程图 直方图 矩阵图 散点图 审计:审计是用于确定项目活动是否遵循了组织和项目的政策、过程与程序的一种结构化且独立的过程。质量审计通常由项目外部的团队开展,如组织内部审计部门、项目管理办公室 (PMO) 或组织外部的审计师。质量审计目标可能包括(但不限于): 识别全部正在实施的良好及最佳实践; 识别所有违规做法、差距及不足; 分享所在组织和/或行业中类似项目的良好实践; 积极、主动地提供协助,以改进过程的执行,从而帮助团队提高生产效率; 强调每次审计都应对组织经验教训知识库的积累做出贡献。 面向X的设计:面向 X 的设计 (DfX) 是产品设计期间可采用的一系列技术指南,旨在优化设计的特定方面,可以控制或提高产品最终特性。DfX 中的“X”可以是产品开发的不同方面,例如可靠性、调配、装配、制造、成本、服务、可用性、安全性和质量。使用 DfX 可以降低成本、改进质量、提高绩效和客户满意度。 问题解决:问题解决是指找到解决问题或应对挑战的解决方案。它包括收集其他信息、具有批判性思维的、创造性的、量化的和/或逻辑性的解决方法。 质量改进方法:质量改进的开展,可基于质量控制过程的发现和建议、质量审计的发现,或管理质量过程的问题解决。计划 — 实施 — 检查 — 行动和六西格玛是最常用于分析和评估改进机会的两种质量改进工具。 8.2.3 管理质量:输出 管理质量的输出包括: 质量报告:质量报告可能是图形、数据或定性文件,其中包含的信息可帮助其他过程和部门采取纠正措施,以实现项目质量期望。质量报告的信息可以包含团队上报的全部质量管理问题,针对过程、项目和产品的改善建议,纠正措施建议(包括返工、缺陷/漏洞补救、100% 检查等),以及在控制质量过程中发现的情况的概述。 测试与评估文件 变更请求 项目管理计划更新 质量管理计划 范围基准 进度基准 成本基准 项目文件更新 问题日志 经验教训登记册 风险登记册 8.3 控制质量 控制质量是为了评估绩效,确保项目输出完整、正确且满足客户期望,而监督和记录质量管理活动执行结果的过程。本过程的主要作用是,核实项目可交付成果和工作已经达到主要相关方的质量要求,可供最终验收。控制质量过程确定项目输出是否达到预期目的,这些输出需要满足所有适用标准、要求、法规和规范。本过程需要在整个项目期间开展。 控制质量过程的目的是在用户验收和最终交付之前测量产品或服务的完整性、合规性和适用性。本过程通过测量所有步骤、属性和变量,来核实与规划阶段所描述规范的一致性和合规性。 8.3.1 控制质量:输入 控制质量的输出包括: 项目管理计划 项目文件 经验教训登记册 质量测量指标 测试与评估文件 批准的变更请求 可交付成果 工作绩效数据 事业环境因素 项目管理信息系统 政府法规 特定应用领域的相关规则、标准和指南 组织过程资产 质量标准和政策 质量模板,例如核查表和核对单等 问题与缺陷报告程序及沟通政策 8.3.2 控制质量:工具与技术 控制质量需要的工具与技术包括: 数据收集 核对单 核查表:核查表,又称计数表,用于合理排列各种事项,以便有效地收集关于潜在质量问题的有用数据。在开展检查以识别缺陷时,用核查表收集属性数据就特别方便,例如关于缺陷数量或后果的数据。 统计抽样 问卷调查 数据分析 绩效审查 根本原因分析(RCA) 检查 测试/产品评估:测试是一种有组织的、结构化的调查,旨在根据项目需求提供有关被测产品或服务质量的客观信息。测试的目的是找出产品或服务中存在的错误、缺陷、漏洞或其他不合规问题。用于评估各项需求的测试的类型、数量和程度是项目质量计划的一部分,具体取决于项目的性质、时间、预算或其他制约因素。测试可以贯穿于整个项目,可以随着项目的不同组成部分变得可用时进行,也可以在项目结束(即交付最终可交付成果)时进行。早期测试有助于识别不合规问题,帮助减少修补不合规组件的成本。 数据表现 因果图 控制图 直方图 散点图 会议 审查已批准的变更请求 回顾/经验教训 8.3.3 控制质量:输出 控制质量的输出包括: 质量控制测量结果 核实的可交付成果 工作绩效信息 变更请求 项目管理计划更新 项目文件更新 问题日志 经验教训登记册 风险登记册 测试与评估文件 9.项目资源管理 项目资源管理包括识别、获取和管理所需资源以成功完成项目的各个过程,这些过程有助于确保项目经理和项目团队在正确的时间和地点使用正确的资源。 项目资源管理过程包括: 9.1 规划资源管理 — 定义如何估算、获取、管理和利用实物以及团队项目资源的过程。 9.2 估算活动资源 — 估算执行项目所需的团队资源,以及材料、设备和用品的类型和数量的过程。 9.3 获取资源 — 获取项目所需的团队成员、设施、设备、材料、用品和其他资源的过程。 9.4 建设团队 — 提高工作能力,促进团队成员互动,改善团队整体氛围,以提高项目绩效的过程。 9.5 管理团队 — 跟踪团队成员工作表现,提供反馈,解决问题并管理团队变更,以优化项目绩效的过程。 9.6 控制资源 — 确保按计划为项目分配实物资源,以及根据资源使用计划监督资源实际使用情况,并采取必要纠正措施的过程。 项目资源管理的核心概念 团队资源管理相对于实物资源管理,对项目经理提出了不同的技能和能力要求。实物资源包括设备、材料、设施和基础设施,而团队资源或人员指的是人力资源。项目团队成员可能具备不同的技能,可能是全职或兼职的,可能随项目进展而增加或减少。 项目团队由承担特定角色和职责的个人组成,他们为实现项目目标而共同努力。项目经理因此应在获取、管理、激励和增强项目团队方面投入适当的努力。尽管项目团队成员被分派了特定的角色和职责,但让他们全员参与项目规划和决策仍是有益的。团队成员参与规划阶段,既可使他们对项目规划工作贡献专业技能,又可以增强他们对项目的责任感。 作为领导者,项目经理还负责积极培养团队技能和能力,同时提高并保持团队的满意度和积极性,项目经理还应了解并支持符合职业与道德要求的行为,确保所有团队成员都按这些要求行动。 实物资源管理着眼于以有效和高效的方式,分配和使用成功完成项目所需的实物资源,如材料、设备和用品。为此,组织应当拥有如下数据:(当前和合理的未来的)资源需求、(可以满足这些需求的)资源配置,以及资源供应。 项目资源管理的趋势和新兴实践 项目管理风格正在从管理项目的命令和控制结构,转向更加协作和支持性的管理方法,通过将决策权分配给团队成员来提高团队能力。 资源管理方法(精益管理、准时制(JIT生产)、Kaizen(持续改善)、全面生产维护(TPM)、约束理论等) 情商EI 自组织团队 虚拟团队/分布式团队 裁剪需要考虑的因素 多元化 物理位置 行业特定资源 团队成员的获得 团队管理 生命周期方法 在敏捷或适应型环境中需要考虑的因素 易变性高的项目得益于最大限度地集中和协作的团队结构,例如拥有通才的自组织团队。 协作旨在提高生产率和促进创新的问题解决方式。协作型团队可以促进不同工作活动的加速整合、改善沟通、增加知识分享,以及提供工作分配的灵活性和其他优势。 9.1 规划资源管理 规划资源管理是定义如何估算、获取、管理和利用团队以及实物资源的过程。本过程的主要作用是,根据项目类型和复杂程度确定适用于项目资源的管理方法和管理程度。本过程仅开展一次或仅在项目的预定义点开展。 资源规划用于确定和识别一种方法,以确保项目的成功完成有足够的可用资源。项目资源可能 包括团队成员、用品、材料、设备、服务和设施。有效的资源规划需要考虑稀缺资源的可用性和竞争,并编制相应的计划。 9.1.1 规划资源管理:输入 规划资源管理的输入包括: 项目章程 项目管理计划 质量管理计划 范围基准 项目文件 项目进度计划 需求文件 风险登记册 相关方登记册 事业环境因素 组织文化和结构 设施和资源的地理分布 现有资源的能力和可用性 市场条件 组织过程资产 人力资源政策和程序; 实物资源管理政策和程序; 安全政策; 安保政策; 资源管理计划模板; 类似项目的历史信息。 9.1.2 规划资源管理:工具与技术 规划资源管理需要的工具与技术包括: 专家判断 协调组织内部的最佳资源; 人才管理和员工发展; 确定为实现项目目标所需的初步投入水平; 根据组织文化确定报告要求; 根据经验教训和市场条件,评估获取资源所需的提前量; 识别与资源获取、留用和遣散计划有关的风险; 遵循适用的政府和工会法规; 管理卖方和物流工作,确保在需要时能够提供材料和用品。 数据表现 层级型 工作分解结构WBS 组织分解结构DBS 资源分解结构 责任分配矩阵 文本型 组织理论 会议 9.1.3 规划资源管理:输出 规划资源管理的输出包括: 资源管理计划 识别资源 获取资源 角色与职责 角色 职权 职责 能力 项目组织图 项目团队资源管理 培训 团队建设 资源控制 认可计划 团队章程 团队价值观; 沟通指南; 决策标准和过程; 冲突处理过程; 会议指南; 团队共识。 项目文件更新 假设日志 风险登记册 9.2 估算活动资源 估算活动资源是估算执行项目所需的团队资源,以及材料、设备和用品的类型和数量的过程。本过程的主要作用是,明确完成项目所需的资源种类、数量和特性。本过程应根据需要在整个项目期间定期开展。 9.2.1 估算活动资源:输入 估算活动资源的输入包括: 项目管理计划 资源管理计划 范围基准 项目文件 活动属性 活动清单 假设日志 成本估算 资源日历 风险登记册 事业环境因素 资源的位置; 资源可用性; 团队资源的技能; 组织文化; 发布的估算数据; 市场条件。 组织过程资产 关于人员配备的政策和程序; 关于用品和设备的政策与程序; 关于以往项目中类似工作所使用的资源类型的历史信息。 9.2.2 估算活动资源:工具与技术 估算活动资源需要的工具与技术包括: 专家判断 自下而上估算 类比估算 参数估算 数据分析 项目管理信息系统 会议 9.2.3 估算活动资源:输出 估算活动资源的输出包括: 资源需求 估算依据 估算方法; 用于估算的资源,如以往类似项目的信息; 与估算有关的假设条件; 已知的制约因素; 估算范围; 估算的置信水平; 有关影响估算的已识别风险的文件。 资源分解结构 项目文件更新 活动属性 假设日志 经验教训登记册 9.3 获取资源 获取资源是获取项目所需的团队成员、设施、设备、材料、用品和其他资源的过程。本过程的主要作用是,概述和指导资源的选择,并将其分配给相应的活动。本过程应根据需要在整个项目期间定期开展。 9.3.1 获取资源:输入 获取资源的输入包括: 项目管理计划 资源管理计划 采购管理计划 成本基准 项目文件 项目进度计划 资源日历 资源需求 相关方登记册 事业环境因素 现有组织资源信息,包括可用性、能力水平、以及有关团队资源和资源成本的以往经验 市场条件 组织结构 地理位置 组织过程资产 有关项目资源的获取、配给和分配的政策和程序 历史信息和经验教训知识库 9.3.2 获取资源:工具与技术 获取资源需要的工具与技术包括: 决策 可用性 成本 能力 经验 知识 技能 态度 国际因素 人际关系与团队技能 职能经理 执行组织中的其他项目管理团队 外部组织和供应商 预分派 虚拟团队:具有共同目标、在完成角色任务的过程中很少或没有时间面对面工作的一群人 9.3.3 获取资源:输出 获取资源的输出包括: 实物资源分配单 项目团队派工单 资源日历 变更请求 项目管理计划更新 资源管理计划 成本基准 项目文件更新 经验教训登记册 项目进度计划 资源分解结构 资源需求 风险登记册 相关方登记册 事业环境因素 组织内资源的可用性 组织已使用的消耗资源的数量 组织过程资产 9.4 建设团队 建设团队是提高工作能力,促进团队成员互动,改善团队整体氛围,以提高项目绩效的过程。本过程的主要作用是,改进团队协作、增强人际关系技能和胜任力、激励员工、减少摩擦以及提升整体项目绩效。本过程需要在整个项目期间开展。 通过以下行为可以实现团队的高效运行: 使用开放与有效的沟通; 创造团队建设机遇; 建立团队成员间的信任; 以建设性方式管理冲突; 鼓励合作型的问题解决方法; 鼓励合作型的决策方法。 建设项目团队的目标包括(但不限于): 提高团队成员的知识和技能,以提高他们完成项目可交付成果的能力,并降低成本、缩短工期和提高质量; 提高团队成员之间的信任和认同感,以提高士气、减少冲突和增进团队协作; 创建富有生气、凝聚力和协作性的团队文化,从而:(1)提高个人和团队生产率,振奋团队精神,促进团队合作;(2)促进团队成员之间的交叉培训和辅导,以分享知识和经验; 提高团队参与决策的能力,使他们承担起对解决方案的责任,从而提高团队的生产效率,获得更有效和高效的成果。 塔克曼阶梯理论: 形成阶段。在本阶段,团队成员相互认识,并了解项目情况及他们在项目中的正式角色与职责。在这一阶段,团队成员倾向于相互独立,不会开诚布公。 震荡阶段。在本阶段,团队开始从事项目工作、制定技术决策和讨论项目管理方法。如果团队成员不能用合作和开放的态度对待不同观点和意见,团队环境可能变得事与愿违。 规范阶段。在规范阶段,团队成员开始协同工作,并调整各自的工作习惯和行为来支持团队,团队成员会学习相互信任。 成熟阶段。进入这一阶段后,团队就像一个组织有序的单位那样工作,团队成员之间相互依靠,平稳高效地解决问题。 解散阶段。在解散阶段,团队完成所有工作,团队成员离开项目。通常在项目可交付成果完成之后,或者,在结束项目或阶段过程中,释放人员,解散团队。 9.4.1 建设团队:输入 建设团队的输入包括: 项目管理计划 项目文件 经验教训登记册 项目进度计划 项目团队派工单 资源日历 团队章程 事业环境因素 有关雇用和解雇、员工绩效审查、员工发展与培训记录,以及认可与奖励的人力资源管理政策; 团队成员的技能、能力和专业知识; 团队成员的地理分布。 组织过程资产 9.4.2 建设团队:工具与技术 建设团队需要的工具与技术包括: 集中办公 虚拟团队 沟通技术 人际关系与团队技能 冲突管理 影响力 激励 谈判 团队建设 认可与奖励 培训 个人和团队评估 会议 9.4.3 建设团队:输出 建设团队的输出包括: 团队绩效评价 变更请求 项目管理计划更新 项目文件更新 经验教训登记册 项目进度计划 项目团队派工单 资源日历 团队章程 事业环境因素 员工发展计划的记录 技能评估 组织过程资产更新 培训需求 人事评测 9.5 管理团队 管理团队是跟踪团队成员工作表现,提供反馈,解决问题并管理团队变更,以优化项目绩效的过程。本过程的主要作用是,影响团队行为、管理冲突以解决问题。本过程需要在整个项目期间开展。 9.5.1 管理团队:输入 管理团队的输入包括: 项目管理计划 项目文件 问题日志 经验教训登记册 项目团队派工单 团队章程 工作绩效报告 团队绩效报告 事业环境因素 组织过程资产 嘉奖证书 公司制服 组织中其他的额外待遇 9.5.2 管理团队:工具与技术 管理团队需要的工具与技术包括: 人际关系与团队技能 冲突管理 撤退/回避。从实际或潜在冲突中退出,将问题推迟到准备充分的时候,或者将问题推给其他人员解决。 缓和/包容。强调一致而非差异;为维持和谐与关系而退让一步,考虑其他方的需要。 妥协/调解。为了暂时或部分解决冲突,寻找能让各方都在一定程度上满意的方案,但这种方法有时会导致“双输”局面。 强迫/命令。以牺牲其他方为代价,推行某一方的观点;只提供赢 — 输方案。通常是利用权力来强行解决紧急问题,这种方法通常会导致“赢输”局面。 合作/解决问题。综合考虑不同的观点和意见,采用合作的态度和开放式对话引导各方达成共识和承诺,这种方法可以带来双赢局面。 制定决策 着眼于所要达到的目标; 遵循决策流程; 研究环境因素; 分析可用信息; 激发团队创造力; 考虑风险。 情商 影响力 领导力 项目管理信息系统 9.5.3 管理团队:输出 管理团队的输出包括: 变更请求 项目管理计划更新 资源管理计划 进度基准 成本基准 项目文件更新 问题日志 经验教训登记册 项目团队派工单 事业环境因素 对组织绩效评价的输入 个人技能 9.6 控制资源 控制资源是确保按计划为项目分配实物资源,以及根据资源使用计划监督资源实际使用情况,并采取必要纠正措施的过程。本过程的主要作用是,确保所分配的资源适时适地可用于项目,且在不再需要时被释放。本过程需要在整个项目期间开展。 控制资源过程关注: 监督资源支出; 及时识别和处理资源缺乏/剩余情况; 确保根据计划和项目需求使用和释放资源; 在出现资源相关问题时通知相应的相关方; 影响会导致资源使用变更的因素; 在变更实际发生时对其进行管理。 9.6.1 控制资源:输入 控制资源的输入包括: 项目管理计划 项目文件 问题日志 经验教训登记册 实物资源分配单 项目进度计划 资源分解结构 资源需求 风险登记册 工作绩效数据 协议 组织过程资产 有关资源控制和分配的政策; 执行组织内用于解决问题的上报程序; 经验教训知识库,其中包含以往类似项目的信息。 9.6.2 控制资源:工具与技术 控制资源需要的工具与技术包括: 数据分析 备选方案分析 成本效益分析 绩效审查 趋势分析 问题解决 识别问题。明确问题。 定义问题。将问题分解为可管理的小问题。 调查。收集数据。 分析。找出问题的根本原因。 解决。从众多解决方案中选择最合适的一个。 检查解决方案。确认是否已解决问题。 人际关系与团队技能 谈判 影响力 项目管理信息系统 9.6.3 控制资源:输出 控制资源的输出包括: 工作绩效信息 变更请求 项目管理计划更新 资源管理计划 进度基准 成本基准 项目文件更新 假设日志 问题日志 经验教训登记册 实物资源分配单 资源分解结构 风险登记册 10.项目沟通管理 项目沟通管理包括通过开发工件,以及执行用于有效交换信息的各种活动,来确保项目及其相关方的信息需求得以满足的各个过程。项目沟通管理由两个部分组成:第一部分是制定策略,确保沟通对相关方行之有效;第二部分是执行必要活动,以落实沟通策略。 项目沟通管理的过程包括: 10.1 规划沟通管理 — 基于每个相关方或相关方群体的信息需求、可用的组织资产,以及具体项目的需求,为项目沟通活动制定恰当的方法和计划的过程。 10.2 管理沟通 — 确保项目信息及时且恰当地收集、生成、发布、存储、检索、管理、监督和最终处置的过程。 10.3 监督沟通 — 确保满足项目及其相关方的信息需求的过程。 图 10-1 概括了项目沟通管理的各个过程。虽然在本《PMBOK® 指南》中,各项目沟通管理过程 以界限分明和相互独立的形式出现,但在实践中它们会以本指南无法全面详述的方式相互交叠和相互作用。 图 10-1项目沟通管理概述 项目沟通管理的核心概念沟通是指有意或无意的信息交换。交换的信息可以是想法、指示或情绪。信息交换的方法包括: 书面形式。实物或电子形式。 口头形式。面对面或远程形式。 正式或非正式形式(用正式纸质或社交媒体)。 手势动作。语调和面部表情。 媒体形式。图片、行动,甚至只是遣词造句。 遣词造句。表达一种想法的词语往往不止一个,且各词语的含义会存在细微差异。 沟通是指用各种可能的方式来发送或接收信息,或者通过沟通活动(如会议和演讲),或者以工件的方式(如电子邮件、社交媒体、项目报告或项目文档)。 项目经理的大多数时间用于与团队成员和其他项目相关方沟通,包括来自组织内部(组织的各个层级)和组织外部的人员。不同相关方可能有不同的文化和组织背景,以及不同的专业水平、观点和兴趣,而有效的沟通能够在他们之间架起一座桥梁。 沟通活动可按多种维度进行分类,包括(但不限于): 内部。针对项目内部或组织内部的相关方。 外部。针对外部相关方,如客户、供应商、其他项目、组织、政府,公众和环保倡导者。 正式。报告、正式会议(定期及临时)、会议议程和记录、相关方简报和演示。 非正式。采用电子邮件、社交媒体、网站,以及非正式临时讨论的一般沟通活动。 层级沟通。相关方或相关方群体相对于项目团队的位置将会以如下方式影响信息传递的形式和内容: 向上沟通。针对高层相关方。 向下沟通。针对承担项目工作的团队和其他人员。 横向沟通。针对项目经理或团队的同级人员。 官方沟通。年报,呈交监管机构或政府部门的报告。 非官方沟通。采用灵活(往往为非正式)的手段,来建立和维护项目团队及其相关方对项目情况的了解和认可,并在他们之间建立强有力的关系。 书面与口头沟通。口头(用词和音调变化)及非口头(肢体语言和行为),社交媒体和网站、媒体发布。 沟通可以为成功完成项目与项目集建立必要的关系。用于开展沟通的活动和工件多种多样,从电子邮件和非正式对话,到正式会议和定期项目报告。通过言语、面部表情、手势动作和其他行动有意或无意地发送和接收信息。为了成功管理与相关方的项目关系,沟通既包括制定策略和计划,以便创建合适的沟通工件和开展合适的沟通活动,也包括运用相关技能来提升计划和即兴的沟通的效果。 成功的沟通包括两个部分。第一部分是根据项目及其相关方的需求而制定适当的沟通策略。从该策略出发,制定沟通管理计划,来确保用各种形式和手段把恰当的信息传递给相关方。这些信息构成项目沟通-成功沟通的第二部分。项目沟通是规划过程的产物,在沟通管理计划中有相关规定。 沟通管理计划定义了信息的收集、生成、发布、储存、检索、管理、追踪和处置。最终,沟通策略和沟通管理计划将成为监督沟通效果的依据。 在项目沟通中,需要尽力预防理解错误和沟通错误,并从规划过程所规定的各种方法、发送方、接收方和信息中作出谨慎选择。 在编制传统(非社交媒体)的书面或口头信息的时候,应用书面沟通的 5C 原则,可以减轻但无法消除理解错误: 正确的语法和拼写。语法不当或拼写错误会分散注意力,还有可能扭曲信息含义,降低可信度。 简洁的表述和无多余字。简洁且精心组织的信息能降低误解信息意图的可能性。 清晰的目的和表述(适合读者的需要)。确保在信息中包含能满足受众需求与激发其兴趣的内容。 连贯的思维逻辑。写作思路连贯,以及在整个书面文件中使用诸如“引言”和“小结”的小标题。 受控的语句和想法承接。可能需要使用图表或小结来控制语句和想法的承接。 书面沟通的 5C原则需要用下列沟通技巧来配合: 积极倾听。与说话人保持互动,并总结对话内容,以确保有效的信息交换。 理解文化和个人差异。提升团队对文化及个人差异的认知,以减少误解并提升沟通能力。 识别、设定并管理相关方期望。与相关方磋商,减少相关方社区中的自相矛盾的期望。 强化技能。强化所有团队成员开展以下活动的技能: 说服个人、团队或组织采取行动; 激励和鼓励人们,或帮助人们重塑自信; 指导人们改进绩效和取得期望结果; 通过磋商达成共识以及减轻审批或决策延误; 解决冲突,防止破坏性影响。 有效的沟通活动和工件创建具有如下基本属性: 沟通目的明确; 尽量了解沟通接收方,满足其需求及偏好; 监督并衡量沟通的效果。 项目沟通管理的发展趋势和新兴实践在关注相关方,以及认可相关方的有效参与对项目及组织的价值的同时,也要认识到制定和落实适当的沟通策略,对维系与相关方的有效关系是至关重要的。项目沟通管理的发展趋势和新兴实践包括(但不限于): 将相关方纳入项目评审范围。每个项目的相关方社区中都包括被项目团队确定为对成功达成项目目标和组织成果不可或缺的个人、群体和组织。有效的沟通策略要求定期且及时地评审相关方社区,以管理成员及其态度的变化。 让相关方参加项目会议。项目会议应邀请项目外部甚至组织外部(若适当)的相关方参与。敏捷方法中的一些做法适用于任何类型的项目,例如,简短的每日站会。在每日站会上,项目团队和主要相关方就前一天的成绩和问题以及当天的工作计划展开讨论。 社交工具的使用日益增多。以硬件平台、社交媒体服务和个人便携设备为代表的社交工具已经改变组织及其人员的沟通和业务方式。在公共 IT 基础设施的支持下,社交工具将不同的协作方式融合在一起。网络社交是指用户建立关系网络,与他人共同拓展兴趣和活动。社交媒体工具不仅能支持信息交换,而且也有助于建立更深层次的信任和社群关系。 多面性沟通方法。制定项目相关方沟通策略时,通常应考虑所有可用技术,并从中作出选择; 同时也应尊重因文化、实践和个人背景而产生的对沟通语言、媒介、内容和方式的偏好。可以根据需要采用社交媒体和其他先进的电脑技术。多面性方法能够提高与不同年代和文化背景的相关方沟通的效果。 裁剪时需要考虑的因素因为每个项目都是独特的,所以项目团队需要裁剪项目沟通管理过程。裁剪时应考虑的因素包括(但不限于): 相关方。相关方是属于组织内部或外部,或者二者都是? 物理地点。团队成员身处何地?团队是否集中办公?团队是否位于相同地理区域?团队是否分散于多个时区? 沟通技术。哪项技术可用于创建、记录、传输、检索、追踪和储存沟通工件?哪些技术最适用于与相关方沟通且成本效益最高? 语言。语言是沟通活动中要考虑的主要因素。使用的是一种语言,还是多种语言?是否已为适应多语种团队的复杂情况安排了资金? 知识管理。组织是否有正式的知识管理库?是否采用管理库? 在敏捷或适应型环境中需要考虑的因素在模糊不定的项目环境中,必然需要对不断演变和出现的细节情况,进行更频繁和快速的沟通。 因此,应该尽量简化团队成员获取信息的通道,频繁进行团队检查,并让团队成员集中办公。 此外,为了促进与高级管理层和相关方的沟通,还需要以透明的方式发布项目工件,并定期邀请相关方评审项目工件。 10.1 规划沟通管理 规划沟通管理是基于每个相关方或相关方群体的信息需求、可用的组织资产,以及具体项目的需求,为项目沟通活动制定恰当的方法和计划的过程。本过程的主要作用是,为及时向相关方提供相关信息,引导相关方有效参与项目,而编制书面沟通计划。本过程应根据需要在整个项目期间定期开展。 10.1.1 规划沟通管理:输入 规划沟通管理的输入包括: 项目章程‘’ 项目管理计划 资源管理计划 相关方参与计划 项目文件 需求文件 相关方登记册 事业环境因素 组织文化、政治氛围和治理框架; 人事管理政策; 相关方风险临界值; 已确立的沟通渠道、工具和系统; 全球、区域或当地的趋势、实践或习俗; 设施和资源的地理分布。 组织过程资产 组织的社交媒体、道德和安全政策及程序; 组织的问题、风险、变更和数据管理政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 历史信息和经验教训知识库; 以往项目的相关方及沟通数据和信息。 10.1.2 规划沟通管理:工具与技术 规划沟通管理需要的工具与技术包括: 专家判断 组织内的政治和权力结构; 组织及其他客户组织的环境和文化; 组织变革管理方法和实践; 项目可交付成果所属的行业或类型; 组织沟通技术; 关于遵守与企业沟通有关的法律要求的组织政策与程序; 与安全有关的组织政策与程序; 相关方,包括客户或发起人。 沟通需求分析 相关方登记册及相关方参与计划中的相关信息和沟通需求; 潜在沟通渠道或途径数量,包括一对一、一对多和多对多沟通; 组织结构图; 项目组织与相关方的职责、关系及相互依赖; 开发方法; 项目所涉及的学科、部门和专业; 有多少人在什么地点参与项目; 内部信息需要(如何时在组织内部沟通); 外部信息需要(如何时与媒体、公众或承包商沟通); 法律要求。 沟通技术(信息交换和协作的常见方法包括对话、会议、书面文件、数据库、社交媒体和网站。) 沟通模型。沟通模型可以是最基本的线性(发送方和接收方)沟通过程,也可以是增加了反馈元素(发送方、接收方和反馈)、更具互动性的沟通形式,甚至可以是融合了发送方或接收方的人性因素、试图考虑沟通复杂性的更加复杂的沟通模型。 基本的发送方和接收方沟通模型示例。此模型将沟通描述为一个过程,并由发送方和接收方两方参与;其关注的是确保信息送达,而非信息理解。基本沟通模型中的步骤顺序为: 编码。把信息编码为各种符号,如文本、声音或其他可供传递(发送)的形式。 传递信息。通过沟通渠道发送信息。信息传递可能受各种物理因素的不利影响,如不熟悉的技术,或不完备的基础设施。可能存在噪音和其他因素,导致信息传递和(或)接收过程中的信息损耗。 解码。接收方将收到的数据还原为对自己有用的形式。 互动沟通模型示例。此模型也将沟通描述为由发送方与接收方参与的沟通过程,但它还强调确保信息理解的必要性。此模型包括任何可能干扰或阻碍信息理解的噪音,如接收方注意力分散、接收方的认知差异,或缺少适当的知识或兴趣。互动沟通模型中的新增步骤有: 确认已收到。收到信息时,接收方需告知对方已收到信息(确认已收到)。这并不一定意味着同意或理解信息的内容,仅表示已收到信息。 反馈/响应。对收到的信息进行解码并理解之后,接收方把还原出来的思想或观点编码成信息,再传递给最初的发送方。如果发送方认为反馈与原来的信息相符,代表沟通已成功完成。 沟通方法 互动沟通。在两方或多方之间进行的实时多向信息交换。它使用诸如会议、电话、即时信息、社交媒体和视频会议等沟通工件。 推式沟通。向需要接收信息的特定接收方发送或发布信息。这种方法可以确保信息的发送,但不能确保信息送达目标受众或被目标受众理解。在推式沟通中,可以采用的沟通工件包括信件、备忘录、报告、电子邮件、传真、语音邮件、博客、新闻稿。 拉式沟通。适用于大量复杂信息或大量信息受众的情况。它要求接收方在遵守有关安全规定的前提之下自行访问相关内容。这种方法包括门户网站、企业内网、电子在线课程、经验教训数据库或知识库。 人际关系与团队技能 数据表现 会议 10.1.3 规划沟通管理:输出 规划沟通管理的输出包括: 沟通管理计划 相关方的沟通需求; 需沟通的信息,包括语言、形式、内容和详细程度; 上报步骤; 发布信息的原因; 发布所需信息、确认已收到,或作出回应(若适用)的时限和频率; 负责沟通相关信息的人员; 负责授权保密信息发布的人员; 接收信息的人员或群体,包括他们的需要、需求和期望; 用于传递信息的方法或技术,如备忘录、电子邮件、新闻稿,或社交媒体; 为沟通活动分配的资源,包括时间和预算; 随着项目进展,如项目不同阶段相关方社区的变化,而更新与优化沟通管理计划的方法; 通用术语表; 项目信息流向图、工作流程(可能包含审批程序)、报告清单和会议计划等; 来自法律法规、技术、组织政策等的制约因素。 项目管理计划更新 项目文件更新 项目进度计划 相关方登记册 10.2 管理沟通 管理沟通是确保项目信息及时且恰当地收集、生成、发布、存储、检索、管理、监督和最终处置的过程。本过程的主要作用是,促成项目团队与相关方之间的有效信息流动。本过程需要在整个项目期间开展。 本过程不局限于发布相关信息,它还设法确保信息以适当的格式正确生成和送达目标受众。本过程也为相关方提供机会,允许他们请求更多信息、澄清和讨论。有效的沟通管理需要借助相关技术并考虑相关事宜,包括(但不限于): 发送方 - 接收方模型。运用反馈循环,为互动和参与提供机会,并清除妨碍有效沟通的障碍。 媒介选择。为满足特定的项目需求而使用合理的沟通工件,例如,何时进行书面沟通或口头沟通、何时准备非正式备忘录或正式报告、何时使用推式或拉式沟通,以及该选择何种沟通技术。 写作风格。合理使用主动或被动语态、句子结构,以及合理选择词汇。 会议管理。准备议程,邀请重要参会者并确保他们出席;处理会议现场发生的冲突,或因对会议纪要和后续行动跟进不力而导致的冲突,或因不当人员与会而导致的冲突。 演示。了解肢体语言和视觉辅助设计的作用。 引导。达成共识、克服障碍(如小组缺乏活力),以及维持小组成员的兴趣和热情。 积极倾听。积极倾听包括告知已收到、澄清与确认信息、理解,以及消除妨碍理解的障碍。 10.2.1 管理沟通:输入 管理沟通的输入包括: 项目管理计划 资源管理计划 沟通管理计划 相关方参与计划 项目文件 变更日志 问题日志 经验教训登记册 质量报告 风险报告 相关方登记册 工作绩效报告 事业环境因素 组织文化、政治氛围和治理框架; 人事管理政策; 相关方风险临界值; 已确立的沟通渠道、工具和系统; 全球、区域或当地的趋势、实践或习俗; 设施和资源的地理分布。 组织过程资产 企业的社交媒体、道德和安全政策及程序; 企业的问题、风险、变更和数据管理政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 以往项目的历史信息,包括经验教训知识库。 10.2.2 管理沟通:工具与技术 管理沟通需要的工具与技术包括: 沟通技术 沟通方法 沟通技能 沟通胜任力。经过裁剪的沟通技能的组合,有助于明确关键信息的目的、建立有效关系、实现信息共享和采取领导行为。 反馈。反馈是关于沟通、可交付成果或情况的反应信息。反馈支持项目经理和团队及所有其他项目相关方之间的互动沟通。例如,指导、辅导和磋商。 非口头技能。例如,通过示意、语调和面部表情等适当的肢体语言来表达意思。镜像模仿和眼神交流也是重要的技能。团队成员应该知道如何通过说什么和不说什么来表达自己的想法。 演示。演示是信息和/或文档的正式交付。向项目相关方明确有效地演示项目信息可包括(但不限于): 向相关方报告项目进度和信息更新; 提供背景信息以支持决策制定; 提供关于项目及其目标的通用信息,以提升项目工作和项目团队的形象; 提供具体信息,以提升对项目工作和目标的理解和支持力度。 为获得演示成功,应该从内容和形式上考虑以下因素: 受众及其期望和需求; 项目和项目团队的需求及目标。 项目管理信息系统 电子项目管理工具 电子沟通管理 社交媒体管理 项目报告发布 项目报告发布是收集和发布项目信息的行为。项目信息应发布给众多相关方群体。应针对每种相关方来调整项目信息发布的适当层次、形式和细节。从简单的沟通到详尽的定制报告和演示,报告的形式各不相同。可以定期准备信息或基于例外情况准备。 人际关系与团队技能 积极倾听 冲突管理 文化意识 会议管理 人际交往 政治意识 会议 10.2.3 管理沟通:输出 管理沟通的输出包括: 项目沟通记录 项目沟通工件可包括(但不限于):绩效报告、可交付成果的状态、进度进展、产生的成本、演示,以及相关方需要的其他信息。 项目管理计划更新 沟通管理计划 相关方参与计划 项目文件更新 问题日志 经验教训登记册 项目进度计划 风险登记册 相关方登记册 组织过程资产更新 项目记录,例如往来函件、备忘录、会议记录及项目中使用的其他文档; 计划内的和临时的项目报告和演示。 10.3 监督沟通 监督沟通是确保满足项目及其相关方的信息需求的过程。本过程的主要作用是,按沟通管理计划和相关方参与计划的要求优化信息传递流程。本过程需要在整个项目期间开展。 10.3.1 监督沟通:输入 监督沟通的输入包括: 项目管理计划 资源管理计划 沟通管理计划 相关方参与计划 项目文件 问题日志 经验教训登记册 项目沟通记录 工作绩效数据 事业环境因素 组织文化、政治氛围和治理框架; 已确立的沟通渠道、工具和系统; 全球、区域或当地的趋势、实践或习俗; 设施和资源的地理分布。 组织过程资产 企业的社交媒体、道德和安全政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 以往项目的历史信息和经验教训知识库; 以往项目的相关方及沟通数据和信息。 10.3.2 监督沟通:工具与技术 监督沟通需要的工具与技术包括: 专家判断 项目管理信息系统 数据表现 人际关系与团队技能 会议 10.3.3 监督沟通:输出 监督沟通的输出包括: 工作绩效信息 变更请求 项目管理计划更新 沟通管理计划 相关方参与计划 项目文件更新 问题日志 经验教训登记册 相关方登记册 11.项目风险管理 项目风险管理包括规划风险管理、识别风险、开展风险分析、规划风险应对、实施风险应对和监督风险的各个过程。项目风险管理的目标在于提高正面风险的概率或影响,降低负面风险的概率或影响,从而提高项目成功的可能性。 项目风险管理的过程是: 11.1 规划风险管理 — 定义如何实施项目风险管理活动的过程。 11.2 识别风险 — 识别单个项目风险,以及整体项目风险的来源,并记录风险特征的过程。 11.3 实施定性风险分析 — 通过评估单个项目风险发生的概率和影响以及其他特征,对风险进行优先级排序,从而为后续分析或行动提供基础的过程。 11.4 实施定量风险分析 — 就已识别的单个项目风险和其他不确定性的来源对整体项目目标的综合影响进行定量分析的过程。 11.5 规划风险应对 — 为处理整体项目风险敞口,以及应对单个项目风险,而制定可选方案、选择应对策略并商定应对行动的过程。 11.6 实施风险应对 — 执行商定的风险应对计划的过程。 11.7 监督风险 — 在整个项目期间,监督商定的风险应对计划的实施、跟踪已识别风险、识别和分析新风险,以及评估风险管理有效性的过程。 项目风险管理的核心概念 项目风险管理旨在识别和管理未被其他项目管理过程所管理的风险。如果不妥善管理,这些风险有可能导致项目偏离计划,无法达成既定的项目目标。因此,项目风险管理的有效性直接关乎项目成功与否。 每个项目都在两个层面上存在风险。每个项目都有会影响项目达成目标的单个风险,以及由单个项目风险和不确定性的其他来源联合导致的整体项目风险。考虑整体项目风险,也非常重要。项目风险管理过程同时兼顾这两个层面的风险。它们的定义如下: 单个项目风险是一旦发生,会对一个或多个项目目标产生正面或负面影响的不确定事件或条件。 整体项目风险是不确定性对项目整体的影响,是相关方面临的项目结果正面和负面变异区间。它源于包括单个风险在内的所有不确定性。 项目风险管理的发展趋势和新兴实践 非事件类风险。大多数项目只关注作为可能发生或不发生的不确定性未来事件的风险。 变异性风险。已规划事件、活动或决策的某些关键方面存在不确定性,就导致变异性风险。 模糊性风险。对未来可能发生什么,存在不确定性。 项目韧性。随着对所谓“未知-未知”因素的意识的增强,人们也越来越明确地知道确实存在突发性风险。这种风险只有在发生后才能被发现。可以通过加强项目韧性来应对突发性风险。这就要求每个项目: 除了为已知风险列出具体风险预算,还要为突发性风险预留合理的应急预算和时间; 采用灵活的项目过程,包括强有力的变更管理,以便在保持朝项目目标推进的正确方向的同时,应对突发性风险; 授权目标明确且值得信赖的项目团队在商定限制范围内完成工作; 经常留意早期预警信号,以尽早识别突发性风险; 明确征求相关方的意见,以明确为应对突发性风险而可以调整项目范围或策略的领域。 整合式风险管理。项目存在于组织背景中,可能是项目集或项目组合的一部分。在项目、项目集、项目组合和组织这些层面上,都存在风险。 裁剪时需要考虑的因素 项目规模 项目复杂性 项目重要性 开发方法 11.1 规划风险管理 规划风险管理是定义如何实施项目风险管理活动的过程。本过程的主要作用是,确保风险管理的水平、方法和可见度与项目风险程度,以及项目对组织和其他相关方的重要程度相匹配。本过程仅开展一次或仅在项目的预定义点开展。 11.1.1 规划风险管理:输入 规划风险管理的输入包括: 项目章程 项目管理计划 项目文件 事业环境因素 组织过程资产 组织的风险政策; 风险类别,可能用风险分解结构来表示; 风险概念和术语的通用定义; 风险描述的格式; 风险管理计划、风险登记册和风险报告的模板; 角色与职责; 决策所需的职权级别; 经验教训知识库,其中包含以往类似项目的信息。 11.1.2 规划风险管理:工具与技术 规划风险管理需要的工具与技术包括: 专家判断 数据分析 会议 11.1.3 规划风险管理:输出 规划风险管理的输出包括: 风险管理计划 风险管理战略 方法论 角色与职责 资金 时间安排 风险类别 相关方风险偏好 风险概率和影响定义 概率和影响矩阵 报告格式 跟踪 11.2 识别风险 识别风险是识别单个项目风险以及整体项目风险的来源,并记录风险特征的过程。本过程的主要作用是,记录现有的单个项目风险,以及整体项目风险的来源;同时,汇集相关信息,以便项目团队能够恰当应对已识别的风险。本过程需要在整个项目期间开展。 11.2.1 识别风险:输入 识别风险的输入包括: 项目管理计划 需求管理计划 进度管理计划 成本管理计划 质量管理计划 资源管理计划 风险管理计划 范围基准 进度基准 成本基准 项目文件 假设日志 成本估算 持续时间估算 问题日志 经验教训登记册 需求文件 资源需求 相关方登记册 协议 采购文档 事业环境因素 已发布的材料,包括商业风险数据库或核对单; 学术研究资料; 标杆对照成果; 类似项目的行业研究资料。 组织过程资产 项目文档,包括实际数据; 组织和项目的过程控制资料; 风险描述的格式; 以往类似项目的核对单。 11.2.2 识别风险:工具与技术 识别风险的工具与技术包括: 专家判断 数据收集 头脑风暴 核对单 访谈 数据分析 根本原因分析 假设条件和制约因素分析 SWOT 分析 文件分析 人际关系与团队技能 提示清单 会议 11.2.3 识别风险:输出 识别风险的输出包括: 风险登记册 已识别风险的清单。在风险登记册中,每项单个项目风险都被赋予一个独特的标识号。要以所需的详细程度对已识别风险进行描述,确保明确理解。可以使用结构化的风险描述,来把风险本身与风险原因及风险影响区分开来。 潜在风险责任人。如果已在识别风险过程中识别出潜在的风险责任人,就要把该责任人记录到风险登记册中。随后将由实施定性风险分析过程进行确认。 潜在风险应对措施清单。如果已在识别风险过程中识别出某种潜在的风险应对措施,就要把它记录到风险登记册中。随后将由规划风险应对过程进行确认。 风险报告 整体项目风险的来源。说明哪些是整体项目风险敞口的最重要驱动因素。 关于已识别单个项目风险的概述信息。例如,已识别的威胁与机会的数量、风险在风险类别中的分布情况、测量指标和发展趋势。 项目文件更新 假设日志 问题日志 经验教训登记册 11.3 实施定性风险分析 实施定性风险分析是通过评估单个项目风险发生的概率和影响以及其他特征,对风险进行优先级排序,从而为后续分析或行动提供基础的过程。本过程的主要作用是重点关注高优先级的风险。本过程需要在整个项目期间开展。 11.3.1 实施定性风险分析:输入 实施定性风险分析的输入包括: 项目管理计划 项目文件 假设日志 风险登记册 相关方登记册 事业环境因素 类似项目的行业研究资料 已发布的材料,包括商业风险数据库或核对单 组织过程资产 11.3.2 实施定性风险分析:工具与技术 实施定性风险分析需要的工具与技术包括: 专家判断 数据收集 数据分析 风险数据质量评估。风险数据是开展定性风险分析的基础。风险数据质量评估旨在评价关于单个项目风险的数据的准确性和可靠性。使用低质量的风险数据,可能导致定性风险分析对项目来说基本没用。如果数据质量不可接受,就可能需要收集更好的数据。可以开展问卷调查,了解项目相关方对数据质量各方面的评价,包括数据的完整性、客观性、相关性和及时性,进而对风险数据的质量进行综合评估。可以计算这些方面的加权平均数,将其作为数据质量的总体分数。 风险概率和影响评估。风险概率评估考虑的是特定风险发生的可能性,而风险影响评估考虑的是风险对一项或多项项目目标的潜在影响,如进度、成本、质量或绩效。威胁将产生负面的影响,机会将产生正面的影响。要对每个已识别的单个项目风险进行概率和影响评估。风险评估可以采用访谈或会议的形式,参加者将依照他们对风险登记册中所记录的风险类型的熟悉程度而定。项目团队成员和项目外部资深人员应该参加访谈或会议。在访谈或会议期间,评估每个风险的概率水平及其对每项目标的影响级别。如果相关方对概率水平和影响级别的感知存在差异,则应对差异进行探讨。此外,还应记录相应的说明性细节。 其他风险参数评估。 紧迫性。为有效应对风险而必须采取应对措施的时间段。时间短就说明紧迫性高。 邻近性。风险在多长时间后会影响一项或多项项目目标。时间短就说明邻近性高。 潜伏期。从风险发生到影响显现之间可能的时间段。时间短就说明潜伏期短。 可管理性。风险责任人(或责任组织)管理风险发生或影响的容易程度。如果容易管理,可管理性就高。 可控性。风险责任人(或责任组织)能够控制风险后果的程度。如果后果很容易控制,可控性就高。 可监测性。对风险发生或即将发生进行监测的容易程度。如果风险发生很容易监测,可监测性就高。 连通性。风险与其他单个项目风险存在关联的程度大小。如果风险与多个其他风险存在关联,连通性就高。 战略影响力。风险对组织战略目标潜在的正面或负面影响。如果风险对战略目标有重大影响,战略影响力就大。 密切度。风险被一名或多名相关方认为要紧的程度。被认为很要紧的风险,密切度就高。 人际关系与团队技能 风险分类 数据表现 概率和影响矩阵:概率和影响矩阵是把每个风险发生的概率和一旦发生对项目目标的影响映射起来的表格。此矩阵对概率和影响进行组合,以便于把单个项目风险划分成不同的优先级组别 层级图 会议 11.3.3 实施定性风险分析:输出 实施定性风险分析的输出包括: 项目文件更新 假设日志 问题日志 风险登记册 风险报告 11.4 实施定量风险分析 实施定量风险分析是就已识别的单个项目风险和不确定性的其他来源对整体项目目标的影响进行定量分析的过程。本过程的主要作用是,量化整体项目风险敞口,并提供额外的定量风险信息,以支持风险应对规划。本过程并非每个项目必需,但如果采用,它会在整个项目期间开展。 项目风险管理计划会规定是否需要使用定量风险分析,定量分析最可能适用于大型或复杂的项目、具有战略重要性的项目、合同要求进行定量分析的项目,或主要相关方要求进行定量分析的项目。通过评估所有单个项目风险和其他不确定性来源对项目结果的综合影响,定量风险分析就成为评估整体项目风险的唯一可靠的方法。 11.4.1 实施定量风险分析:输入 实施定量风险分析的输入包括: 项目管理计划 风险管理计划 范围基准 进度基准 成本基准 项目文件 假设日志 估算依据 成本估算 成本预测 持续时间估算 里程碑清单 资源需求 风险登记册 风险报告 进度预测 事业环境因素 组织过程资产 11.4.2 实施定量风险分析:工具与技术 实施定量风险分析需要的工具与技术包括: 专家判断 将单个项目风险和其他不确定性来源的信息转化成用于定量风险分析模型的数值输入; 选择最适当的方式表示不确定性,以便为特定风险或其他不确定性来源建立模型; 用适合项目环境的技术建立模型; 识别最适用于所选建模技术的工具; 解释定量风险分析的输出。 数据收集 人际关系与团队技能 不确定性表现方式 数据分析 模拟 敏感性分析 决策树分析 影响图 11.4.3 实施定量风险分析:输出 实施定量风险分析的输出包括: 项目文件更新 对整体项目风险敞口的评估结果 项目成功的可能性。基于已识别的单个项目风险和其他不确定性来源,项目实现其主要目标(例如,既定的结束日期或中间里程碑、既定的成本目标)的概率。 项目固有的变异性。在开展定量分析之时,可能的项目结果的分布区间。 项目详细概率分析的结果。列出定量风险分析的重要输出,如 S 曲线、龙卷风图和关键性指标,以及对它们的叙述性解释。定量风险分析的详细结果可能包括: 所需的应急储备,以达到实现目标的特定置信水平; 对项目关键路径有最大影响的单个项目风险或其他不确定性来源的清单; 整体项目风险的主要驱动因素,即:对项目结果的不确定性有最大影响的因素。 单个项目风险优先级清单。根据敏感性分析的结果,列出对项目造成最大威胁或产生最大机会的单个项目风险。 定量风险分析结果的趋势。随着在项目生命周期的不同时间重复开展定量风险分析,风险的发展趋势可能逐渐清晰。发展趋势会影响对风险应对措施的规划。 风险应对建议。风险报告可能根据定量风险分析的结果,针对整体项目风险敞口或关键单个项目风险提出应对建议。这些建议将成为规划风险应对过程的输入。 11.5 规划风险应对 规划风险应对是为处理整体项目风险敞口,以及应对单个项目风险,而制定可选方案、选择应对策略并商定应对行动的过程。本过程的主要作用是,制定应对整体项目风险和单个项目风险的适当方法;本过程还将分配资源,并根据需要将相关活动添加进项目文件和项目管理计划。本过程需要在整个项目期间开展。 11.5.1 规划风险应对:输入 规划风险应对的输入包括: 项目管理计划 资源管理计划 风险管理计划 成本基准 项目文件 经验教训登记册 项目进度计划 项目团队派工单 资源日历 风险登记册 风险报告 相关方登记册 事业环境因素 组织过程资产 风险管理计划、风险登记册和风险报告的模板; 历史数据库; 类似项目的经验教训知识库。 11.5.2 规划风险应对:工具与技术 规划风险应对需要的工具与技术包括: 专家判断 威胁应对策略; 机会应对策略; 应急应对策略; 整体项目风险应对策略。 数据收集 人际关系与团队技能 威胁应对策略 上报 规避 转移 减轻 接受 机会应对策略 上报 开拓 分享 提高 接受 应急应对策略 整体项目风险应对策略 规避 开拓 转移或分享 减轻或提高 接受 数据分析 备选方案分析 成本收益分析 决策 11.5.3 规划风险应对:输出 规划风险应对的输出包括: 变更请求 项目管理计划更新 进度管理计划 成本管理计划 质量管理计划 资源管理计划 采购管理计划 范围基准 进度基准 成本基准 项目文件更新 假设日志 成本预测 经验教训登记册 项目进度计划 项目团队派工单 风险登记册 商定的应对策略; 实施所选应对策略所需要的具体行动; 风险发生的触发条件、征兆和预警信号; 实施所选应对策略所需要的预算和进度活动; 应急计划,以及启动该计划所需的风险触发条件; 弹回计划,供风险发生且主要应对措施不足以应对时使用; 在采取预定应对措施之后仍然存在的残余风险,以及被有意接受的风险; 由实施风险应对措施而直接导致的次生风险。 风险报告 11.6 实施风险应对 实施风险应对是执行商定的风险应对计划的过程。本过程的主要作用是,确保按计划执行商定的风险应对措施,来管理整体项目风险敞口、最小化单个项目威胁,以及最大化单个项目机会。本过程需要在整个项目期间开展。 11.6.1 实施风险应对:输入 实施风险应对的输入包括: 项目管理计划 项目文件 经验教训登记册 风险登记册 风险报告 组织过程资产 11.6.2 实施风险应对:工具与技术 实施风险应对需要的工具与技术包括: 专家判断 人际关系与团队技能 项目管理信息系统 11.6.3 实施风险应对:输出 实施风险应对的输出包括: 变更请求 项目文件更新 问题日志 经验教训登记册 项目团队派工单 风险登记册 风险报告 11.7 监督风险 监督风险是在整个项目期间,监督商定的风险应对计划的实施、跟踪已识别风险、识别和分析新风险,以及评估风险管理有效性的过程。本过程的主要作用是,使项目决策都基于关于整体项目风险敞口和单个项目风险的当前信息。本过程需要在整个项目期间开展。 为了确保项目团队和关键相关方了解当前的风险敞口级别,应该通过监督风险过程对项目工作进行持续监督,来发现新出现、正变化和已过时的单个项目风险。监督风险过程采用项目执行期间生成的绩效信息,以确定: 实施的风险应对是否有效; 整体项目风险级别是否已改变; 已识别单个项目风险的状态是否已改变; 是否出现新的单个项目风险; 风险管理方法是否依然适用; 项目假设条件是否仍然成立; 风险管理政策和程序是否已得到遵守; 成本或进度应急储备是否需要修改; 项目策略是否仍然有效。 11.7.1 监督风险:输入 监督风险的输入包括: 项目管理计划 项目文件 问题日志 经验教训登记册 风险登记册 风险报告 工作绩效数据 工作绩效报告 11.7.2 监督风险:工具与技术 监督风险需要的工具与技术包括: 数据分析 技术绩效分析 储备分析 审计 会议 11.7.3 监督风险:输出 监督风险的输出包括: 工作绩效信息 变更请求 项目管理计划更新 项目文件更新 假设日志 问题日志 经验教训登记册 风险登记册 风险报告 组织过程资产更新 风险管理计划、风险登记册和风险报告的模板 风险分解结构 12.项目采购管理 项目采购管理包括从项目团队外部采购或获取所需产品、服务或成果的各个过程。项目采购管理包括编制和管理协议所需的管理和控制过程,例如:合同、订购单、协议备忘录(MOA),或服务水平协议(SLA)。被授权采购项目所需货物和(或)服务的人员可以是项目团队、管理层或组织采购部的成员。 项目采购管理过程包括: 12.1 规划采购管理 — 记录项目采购决策、明确采购方法,及识别潜在卖方的过程。 12.2 实施采购 — 获取卖方应答、选择卖方并授予合同的过程。 12.3 控制采购 — 管理采购关系、监督合同绩效、实施必要的变更和纠偏,以及关闭合同的过程。 项目采购管理的核心概念 项目采购管理过程涉及到用协议来描述买卖双方之间的关系。协议可以很简单,如以特定人工单价购买所需的工时,也可以很复杂,如多年的国际施工合同。合同签署的方法和合同本身应体现可交付成果或所需人力投入的简单性或复杂性,其书写形式也应符合当地、所在国或国际法中关于合同签署的规定。 合同应明确说明预期的可交付成果和结果,包括从卖方到买方的任何知识转移。合同中未规定的任何事项则不具法律强制力。开展国际合作的项目经理应牢记,无论合同规定如何详尽,文化和当地法律对合同及其可执行性均有影响。采购合同中包括条款和条件,也可包括买方就卖方应实施工作或应交付产品的其他规定。 中标人可将所承揽的工作当作一个项目加以管理。在这种情况下: 买方就变成了承包商、供应商及服务提供商的客户,因此也就是卖方的关键项目相关方。 卖方的项目管理团队就需要关注工作执行或服务提供所涉及的所有过程。 对于卖方来说,合同条款和条件以及采购工作说明书 (SOW) 都是其许多管理过程的重要输入。在合同中,可实际列出各种输入(如,主要可交付成果、关键里程碑、成本目标),或者可限制项目团队的选择余地(如,在 IT 整合项目中,关于人员配备的决定往往要征得买方的批准)。另外,采购工作说明书可能使用其他名称,如技术工作说明书。 卖方本身也可能成为更低层级的产品、服务和材料分包商及供应商的买方。 采购管理的发展趋势和新兴实践 工具的改进 更先进的风险管理 变化中的合同签署实践 物流和供应链管理 技术和相关方关系 试用采购 裁剪时需要考虑的因素 采购的复杂性 物理地点 治理和法规环境 承包商的可用性 12.1 规划采购管理 规划采购管理是记录项目采购决策、明确采购方法,及识别潜在卖方的过程。本过程的主要作用是,确定是否从项目外部获取货物和服务,如果是,则还要确定将在什么时间、以什么方式获取什么货物和服务。货物和服务可从执行组织的其他部门采购,或者从外部渠道采购。本过程仅开展一次或在项目的预定义点开展。 典型的步骤可能有: 准备采购工作说明书 (SOW) 或工作大纲 (TOR); 准备高层级的成本估算,制定预算; 发布招标广告; 确定合格卖方的短名单; 准备并发布招标文件; 由卖方准备并提交建议书; 对建议书开展技术(包括质量)评估; 对建议书开展成本评估; 准备最终的综合评估报告(包括质量及成本),选出中标建议书; 结束谈判,买方和卖方签署合同。 12.1.1 规划采购管理:输入 规划采购管理的输入包括: 项目章程 商业文件 商业论证 收益管理计划 项目管理计划 范围管理计划 质量管理计划 资源管理计划 范围基准 项目文件 里程碑清单 项目团队派工单 需求文件 需求跟踪矩阵 资源需求 风险登记册 相关方登记册 事业环境因素 市场条件; 可从市场获得的产品、服务和成果; 卖方,包括其以往绩效或声誉; 关于产品、服务和成果的典型条款和条件,或适用于特定行业的典型条款和条件; 特殊的当地要求,例如关于雇用当地员工或卖方的法规要求; 关于采购的法律建议; 合同管理系统,包括合同变更控制程序; 已有的多层级供应商系统,其中列出了基于以往经验而预审合格的卖方; 财务会计和合同支付系统。 组织过程资产 预先批准的卖方清单 正式的采购政策、程序和指南 合同类型 总价合同:此类合同为既定产品、服务或成果的采购设定一个总价。这种合同应在已明确定义需求,且不会出现重大范围变更的情况下使用。 成本补偿合同:此类合同向卖方支付为完成工作而发生的全部合法实际成本(可报销成本),外加一笔费用作为卖方的利润。这种合同适用于:工作范围预计会在合同执行期间发生重大变更。 工料合同(T&M):工料合同(又称时间和手段合同),是兼具成本补偿合同和总价合同特点的混合型合同。这种合同往往适用于:在无法快速编制出准确的工作说明书的情况下扩充人员、聘用专家或寻求外部支持。 12.1.2 规划采购管理:工具与技术 规划采购管理需要的工具与技术包括: 专家判断 采购与购买; 合同类型和合同文件; 法规及合规性。 数据收集 数据分析 供方选择分析 最低成本 仅凭资质 基于质量或技术方案得分 基于质量和成本 独有来源 固定预算 会议 12.1.3 规划采购管理:输出 规划采购管理的输出包括: 采购管理计划 如何协调采购与项目的其他工作,例如,项目进度计划制定和控制; 开展重要采购活动的时间表; 用于管理合同的采购测量指标; 与采购有关的相关方角色和职责;如果执行组织有采购部,项目团队拥有的职权和受到的限制; 可能影响采购工作的制约因素和假设条件; 司法管辖权和付款货币; 是否需要编制独立估算,以及是否应将其作为评价标准; 风险管理事项,包括对履约保函或保险合同的要求,以减轻某些项目风险; 拟使用的预审合格的卖方(如果有)。 采购策略 交付方法。对专业服务项目和建筑施工项目,应该采用不同的交付方法。 专业服务项目的交付方法包括:买方或服务提供方不得分包、买方或服务提供方可以分包、买方和服务提供方设立合资企业、买方或服务提供方仅充当代表。 而工业或商业施工项目的交付方法包括(但不限于):交钥匙式、设计-建造 (DB)、设计-招标-建造 (DBB)、设计-建造-运营 (DBO)、建造-拥有-运营-转让 (BOOT),及其他。 合同支付类型。合同支付类型与项目交付方法无关,需要与采购组织的内部财务系统相协调。它们包括(但不限于)以下合同类型及其变种:总价、固定总价、成本加奖励费用、成本加激励费用、工料、目标成本及其他。 总价合同适用于工作类型可预知、需求能清晰定义且不太可能变更的情况; 成本补偿合同适用于工作不断演进、很可能变更或未明确定义的情况; 激励和奖励费用可用于协调买方和卖方的目标。 采购阶段。采购策略也可以包括与采购阶段有关的信息,这种信息可能包括: 采购工作的顺序安排或阶段划分,每个阶段的描述,以及每个阶段的具体目标; 用于监督的采购绩效指标和里程碑; 从一个阶段过渡到下一个阶段的标准; 用于追踪采购进展的监督和评估计划; 向后续阶段转移知识的过程。 招标文件 信息邀请书 (RFI)。如果需要卖方提供关于拟采购货物和服务的更多信息,就使用信息邀请书。随后一般还会使用报价邀请书或建议邀请书。 报价邀请书 (RFQ)。如果需要供应商提供关于将如何满足需求和(或)将需要多少成本的更多信息,就使用报价邀请书。 建议邀请书 (RFP)。如果项目中出现问题且解决办法难以确定,就使用建议邀请书。这是最正式的“邀请书”文件,需要遵守与内容、时间表,以及卖方应答有关的严格的采购规则。 采购工作说明书 承包商需要执行的任务,以及所需的协调工作; 承包商必须达到的适用标准; 需要提交批准的数据; 由买方提供给承包商的,将用于合同履行的全部数据和服务的详细清单(若适用); 关于初始成果提交和审查(或审批)的进度计划。 供方选择标准 能力和潜能; 产品成本和生命周期成本; 交付日期; 技术专长和方法; 具体的相关经验; 用于响应工作说明书的工作方法和工作计划; 关键员工的资质、可用性和胜任力; 公司的财务稳定性; 管理经验; 知识转移计划,包括培训计划。 自制或外购决策 独立成本估算 变更请求 项目文件更新 经验教训登记册 里程碑清单 需求文件 需求跟踪矩阵 风险登记册 相关方登记册 组织过程资产更新 12.2 实施采购 实施采购是获取卖方应答、选择卖方并授予合同的过程。本过程的主要作用是,选定合格卖方并签署关于货物或服务交付的法律协议。本过程的最后成果是签订的协议,包括正式合同。本过程应根据需要在整个项目期间定期开展。 12.2.1 实施采购:输入 实施采购的输入包括: 项目管理计划 范围管理计划 需求管理计划 沟通管理计划 风险管理计划 采购管理计划 配置管理计划 成本基准 项目文件 经验教训登记册 项目进度计划 需求文件 风险登记册 相关方登记册 采购文档 招标文件 采购工作说明书 独立成本估算 供方选择标准 卖方建议书 事业环境因素 关于采购的当地法律和法规; 确保主要采购涉及当地卖方的当地法律和法规; 制约采购过程的外部经济环境; 市场条件; 以往与卖方合作的相关经验,包括正反两方面; 之前使用的协议; 合同管理系统。 组织过程资产 预审合格的优先卖方清单; 会影响卖方选择的组织政策; 组织中关于协议起草及签订的具体模板或指南; 关于付款申请和支付过程的财务政策和程序。 12.2.2 实施采购:工具与技术 实施采购需要的工具与技术包括: 专家判断 建议书评估; 技术或相关主题事宜; 相关的职能领域,如财务、工程、设计、开发、供应链管理等; 行业监管环境; 法律法规和合规性要求; 谈判。 广告 投标人会议 数据分析 人际关系与团队技能 12.2.3 实施采购:输出 实施采购的输出包括: 选定的卖方 协议 采购工作说明书或主要的可交付成果; 进度计划、里程碑,或进度计划中规定的日期; 绩效报告; 定价和支付条款; 检查、质量和验收标准; 担保和后续产品支持; 激励和惩罚; 保险和履约保函; 下属分包商批准; 一般条款和条件; 变更请求处理; 终止条款和替代争议解决方法。 变更请求 项目管理计划更新 需求管理计划 质量管理计划 沟通管理计划 风险管理计划 采购管理计划 范围基准 进度基准 成本基准 项目文件更新 经验教训登记册 需求文件 需求跟踪矩阵 资源日历 风险登记册 相关方登记册 组织过程资产更新 潜在和预审合格的卖方清单; 与卖方合作的相关经验,包括正反两方面。 12.3 控制采购 控制采购是管理采购关系,监督合同绩效,实施必要的变更和纠偏,以及关闭合同的过程。本过程的主要作用是,确保买卖双方履行法律协议,满足项目需求。本过程应根据需要在整个项目期间开展。 合同管理活动可能包括: 收集数据和管理项目记录,包括维护对实体和财务绩效的详细记录,以及建立可测量的采购绩效指标; 完善采购计划和进度计划; 建立与采购相关的项目数据的收集、分析和报告机制,并为组织编制定期报告; 监督采购环境,以便引导或调整实施; 向卖方付款。 12.3.1 控制采购:输入 控制采购的输入包括: 项目管理计划 需求管理计划 风险管理计划 采购管理计划 变更管理计划 进度基准 项目文件 假设日志 经验教训登记册 里程碑清单 质量报告 需求文件 需求跟踪矩阵 风险登记册 相关方登记册 协议 采购文档 批准的变更请求 工作绩效数据 事业环境因素 合同变更控制系统; 市场条件; 财务管理和应付账款系统; 采购组织的道德规范。 组织过程资产 12.3.2 控制采购:工具与技术 控制采购需要的工具与技术包括: 专家判断 相关的职能领域,如财务、工程、设计、开发、供应链管理等; 法律法规和合规性要求; 索赔管理。 索赔管理 数据分析 绩效审查 挣值分析(EVA) 趋势分析 检查 审计 12.3.3 控制采购:输出 控制采购的输出包括: 采购关闭 工作绩效信息 采购文档更新 变更请求 项目管理计划更新 风险管理计划 采购管理计划 进度基准 成本基准 项目文件更新 经验教训登记册 资源需求 需求跟踪矩阵 风险登记册 相关方登记册 组织过程资产更新 支付计划和请求 卖方绩效评估文件 预审合格卖方清单更新 经验教训登记册 采购档案 13.项目相关方管理 项目相关方管理包括用于开展下列工作的各个过程:识别能够影响项目或会受项目影响的人员、团体或组织,分析相关方对项目的期望和影响,制定合适的管理策略来有效调动相关方参与项目决策和执行。用这些过程分析相关方期望,评估他们对项目或受项目影响的程度,以及制定策略来有效引导相关方支持项目决策、规划和执行。 项目相关方管理的过程是: 13.1 识别相关方 — 识别相关方是定期识别项目相关方,分析和记录他们的利益、参与度、相互依赖性、影响力和对项目成功的潜在影响的过程。 13.2 规划相关方参与 — 规划相关方参与是根据相关方的需求、期望、利益和对项目的潜在影响,制定项目相关方参与项目的方法的过程。 13.3 管理相关方参与 — 管理相关方参与是与相关方进行沟通和协作,以满足其需求与期望,处理问题,并促进相关方合理参与的过程。 13.4 监督相关方参与 — 监督项目相关方关系,并通过修订参与策略和计划来引导相关方合理参与项目的过程。 项目相关方管理的核心概念 相关方满意度应作为项目目标加以识别和管理。有效引导相关方参与的关键是重视与所有相关方保持持续沟通(包括团队成员),以理解他们的需求和期望、处理所发生的问题、管理利益冲突,并促进相关方参与项目决策和活动。 至少要在以下时点开展这些活动: 项目进入其生命周期的不同阶段; 当前相关方不再与项目工作有关,或者在项目的相关方社区中出现了新的相关方成员; 组织内部或更大区域的相关方社区发生重大变化。 项目相关方管理的发展趋势和新兴实践 识别所有相关方,而非在限定范围内; 确保所有团队成员都涉及引导相关方参与的活动; 定期审查相关方社区,往往与单个项目风险的审查并行开展; 应用“共创”概念,咨询最受项目工作或成果影响的相关方。该概念的重点是,将团队内受影响的相关方视为合作伙伴。 关注与相关方有效参与程度有关的正面及负面价值。正面价值是相关方(尤其是强大相关方)对项目的更积极支持所带来的效益;负面价值是因相关方未有效参与而造成的真实成本,包括产品召回、组织信誉损失或项目信誉损失。 裁剪时需要考虑的因素 相关方多样性 相关方关系的复杂性 沟通技术 13.1 识别相关方 识别相关方是定期识别项目相关方,分析和记录他们的利益、参与度、相互依赖性、影响力和对项目成功的潜在影响的过程。本过程的主要作用是,使项目团队能够建立对每个相关方或相关方群体的适度关注。本过程应根据需要在整个项目期间定期开展。 本过程通常在编制和批准项目章程之前或同时首次开展。本过程需在必要时重复开展,至少应在每个阶段开始时,以及项目或组织出现重大变化时重复开展。每次重复开展本过程,都应通过查阅项目管理计划组件及项目文件,来识别有关的项目相关方。 13.1.1 识别相关方:输入 识别相关方的输入包括: 项目章程 商业文件 商业论证 收益管理计划 项目管理计划 沟通管理计划 相关方参与计划 项目文件 变更日志 问题日志 需求文件 协议 事业环境因素 组织文化、政治氛围,以及治理框架; 政府或行业标准(法规、产品标准和行为规范); 全球、区域或当地的趋势、实践或习惯; 设施和资源的地理分布。 组织过程资产 相关方登记册模板和说明; 以往项目的相关方登记册; 经验教训知识库,包括与相关方偏好、行动和参与有关的信息。 13.1.2 识别相关方:工具与技术 识别相关方需要的工具与技术包括: 专家判断 理解组织内的政治和权力结构; 了解所在组织和其他受影响组织(包括客户及其他组织)的环境和文化; 了解项目所在行业或项目可交付成果类型; 了解个体团队成员的贡献和专长。 数据收集 问卷和调查 头脑风暴 数据分析数据表现 相关方分析 兴趣 权利 所有权 知识 贡献 文件分析 数据表现 权力利益方格、权力影响方格,或作用影响方格 相关方立方体 凸显模型 影响方向 优先级排序 会议 13.1.3 识别相关方:输出 识别相关方的输出包括: 相关方登记册 身份信息 评估信息 相关方分类 变更请求 项目管理计划更新 需求管理计划 沟通管理计划 风险管理计划 相关方参与计划 项目文件更新 假设日志 问题日志 风险登记册 13.2 规划相关方参与 规划相关方参与是根据相关方的需求、期望、利益和对项目的潜在影响,制定项目相关方参与项目的方法的过程。本过程的主要作用是,提供与相关方进行有效互动的可行计划。本过程应根据需要在整个项目期间定期开展。 会触发该计划更新的典型情况包括(但不限于): 项目新阶段开始; 组织结构或行业内部发生变化; 新的个人或群体成为相关方,现有相关方不再是相关方社区的成员,或特定相关方对项目成功的重要性发生变化; 当其他项目过程(如变更管理、风险管理或问题管理)的输出导致需要重新审查相关方参与策略。 13.2.1 规划相关方参与:输入 规划相关方参与的输入包括: 项目章程 项目管理计划 资源管理计划 沟通管理计划 风险管理计划 项目文件 假设日志 变更日志 问题日志 项目进度计划 风险登记册 相关方登记册 协议 事业环境因素 组织文化、政治氛围,以及治理框架; 人事管理政策; 相关方风险偏好; 已确立的沟通渠道; 全球、区域或当地的趋势、实践或习惯; 设施和资源的地理分布。 组织过程资产 企业的社交媒体、道德和安全政策及程序; 企业的问题、风险、变更和数据管理政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 经验教训知识库,包括与相关方偏好、行动和参与有关的信息; 支持有效相关方参与所需的软件工具。 13.2.2 规划相关方参与:工具与技术 规划相关方参与需要的工具与技术包括: 专家判断 组织内部及外部的政治和权力结构; 组织及组织外部的环境和文化; 相关方参与过程使用的分析和评估技术; 沟通手段和策略; 来自以往项目的关于相关方、相关方群体及相关方组织(他们可能参与过以往的类似项目)的特征的知识。 数据收集 数据分析 假设条件和制约因素分析 根本原因分析 决策 数据表现 思维导图 相关方参与度评估矩阵 不了解型 抵制型 中立型 支持型 领导型 会议 13.2.3 规划相关方参与:输出 规划相关方参与的输出包括: 项目管理计划 相关方参与计划 13.3 管理相关方参与 管理相关方参与是与相关方进行沟通和协作以满足其需求与期望、处理问题,并促进相关方合理参与的过程。本过程的主要作用是,让项目经理能够提高相关方的支持,并尽可能降低相关方的抵制。本过程需要在整个项目期间开展。 在管理相关方参与过程中,需要开展多项活动,例如: 在适当的项目阶段引导相关方参与,以便获取、确认或维持他们对项目成功的持续承诺; 通过谈判和沟通管理相关方期望; 处理与相关方管理有关的任何风险或潜在关注点,预测相关方可能在未来引发的问题; 澄清和解决已识别的问题。 13.3.1 管理相关方参与:输入 管理相关方参与的输入包括: 项目管理计划 沟通管理计划 风险管理计划 相关方参与计划 变更管理计划 项目文件 变更日志 问题日志 经验教训登记册 相关方登记册 事业环境因素 组织文化、政治氛围,以及组织的治理结构; 人事管理政策; 相关方风险临界值; 已确立的沟通渠道; 全球、区域或当地的趋势、实践或习惯; 设施和资源的地理分布。 组织过程资产 企业的社交媒体、道德和安全政策及程序; 企业的问题、风险、变更和数据管理政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 以往类似项目的历史信息。 13.3.2 管理相关方参与:工具与技术 管理相关方参与需要的工具与技术包括: 专家判断 组织内部及外部的政治和权力结构; 组织及组织外部的环境和文化; 相关方参与过程使用的分析和评估技术; 沟通方法和策略; 可能参与过以往类似项目的相关方、相关方群体及相关方组织的特征。 需求管理、供应商管理和变更管理。 沟通技能 正式与非正式对话; 问题识别和讨论; 会议; 进展报告; 调查。 人际关系与团队技能 冲突管理 文化意识 谈判 观察和交谈 政治意识 基本规则 会议 决策; 问题解决; 经验教训和回顾总结; 项目开工; 迭代规划; 状态更新。 13.3.3 管理相关方参与:输出 管理相关方参与的输出包括: 变更请求 项目管理计划更新 沟通管理计划 相关方参与计划 项目文件更新 变更日志 问题日志 经验教训登记册 相关方登记册 13.4 监督相关方参与 监督相关方参与是监督项目项目相关方关系,并通过修订参与策略和计划来引导相关方合理参与项目的过程。本过程的主要作用是,随着项目进展和环境变化,维持或提升相关方参与活动的效率和效果。本过程需要在整个项目期间开展。 13.4.1 监督相关方参与:输入 监督相关方参与的输入包括: 项目管理计划 资源管理计划 沟通管理计划 相关方参与计划 项目文件 问题日志 经验教训登记册 项目沟通记录 风险登记册 相关方登记册 工作绩效数据 事业环境因素 组织文化、政治氛围,以及治理框架; 人事管理政策; 相关方风险临界值; 已确立的沟通渠道; 全球、区域或当地的趋势、实践或习惯; 设施和资源的地理分布。 组织过程资产 企业的社交媒体、道德和安全政策及程序; 企业的问题、风险、变更和数据管理政策及程序; 组织对沟通的要求; 制作、交换、储存和检索信息的标准化指南; 以往项目的历史信息。 13.4.2 监督相关方参与:工具与技术 监督相关方参与需要的工具与技术包括: 数据分析 备选方案分析 根本原因分析 相关方分析 决策 多标准决策分析 投票 数据表现 沟通技能 反馈 演示 人际关系与团队技能 积极倾听 文化意识 领导力 人际交往 政治意识 会议 13.4.3 监督相关方参与:输出 监督相关方参与的输出包括: 工作绩效数据 变更请求 项目管理计划更新 资源管理计划 沟通管理计划 相关方参与计划 项目文件更新 问题日志 经验教训登记册 风险登记册 相关方登记册 项目管理过程组与知识领域总表 知识领域 启动过程组 规划过程组 执行过程组 监控过程组 收尾过程组 项目整合管理 4.1 制定项目章程 4.2 制定项目管理计划 4.4 管理项目知识 4.3 指导与管理项目工作 4.5 监控项目工作4.6实施整体变更控制 4.7 结束项目或阶段 项目范围管理 5.1规划范围管理5.2 手机需求5.3 定义范围5.4 创建WBS 5.5 确认范围5.6 控制范围 项目进度管理 6.1 规划进度管理6.2 定义活动6.3 排序活动顺序6.4 估算活动持续时间6.5 制定进度计划 6.6 控制进度 项目成本管理 7.1 规划成本管理7.2 估算成本7.3 制定预算 7.4 控制成本 项目质量管理 8.1 规划质量管理 8.2 管理质量 8.3 控制质量 项目资源管理 9.1 规划资源管理9.2 估算活动资源 9.3 获取资源9.4 建设团队9.5 管理团队 9.6 控制资源 项目沟通管理 10.1 规划沟通管理 10.2 管理沟通 10.3 监督沟通 项目风险管理 11.1 规划风险管理11.2 识别风险11.3 实施定性风险分析11.4 实施定量风险分析11.5 规划风险应对 11.6 实施风险应对 11.7 监督风险 项目采购管理 12.1 规划采购管理 12.2 实施采购 12.3 控制采购 项目相关方管理 13.1 识别相关方 13.2 规划相关方参与 13.3 管理相关方参与 13.4 监督相关方参与 编辑整理 zabbx 系列教程 全部文章RSS订阅 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2022/4/17
articleCard.readMore

三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境

最近在 K8S 1.18.2 版本的集群上搭建DevOps环境,期间遇到了各种坑。目前,搭建环境的过程中出现的各种坑均已被填平,特此记录,并分享给大家! 文章和搭建环境所需要的yml文件已收录到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe 。如果文件对你有点帮助,别忘记给个Star哦! 服务器规划 IP 主机名 节点 操作系统 192.168.175.101 binghe101 K8S Master CentOS 8.0.1905 192.168.175.102 binghe102 K8S Worker CentOS 8.0.1905 192.168.175.103 binghe103 K8S Worker CentOS 8.0.1905 安装环境版本 软件名称 软件版本 说明 Docker 19.03.8 提供容器环境 docker-compose 1.25.5 定义和运行由多个容器组成的应用 K8S 1.8.12 是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。 GitLab 12.1.6 代码仓库(与SVN安装一个即可) Harbor 1.10.2 私有镜像仓库 Jenkins 2.89.3 持续集成交付 SVN 1.10.2 代码仓库(与GitLab安装一个即可) JDK 1.8.0_202 Java运行基础环境 maven 3.6.3 构建项目的基础插件 服务器免密码登录 在各服务器执行如下命令。 ssh-keygen -t rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys 将binghe102和binghe103服务器上的id_rsa.pub文件复制到binghe101服务器。 [root@binghe102 ~]# scp .ssh/id_rsa.pub binghe101:/root/.ssh/102 [root@binghe103 ~]# scp .ssh/id_rsa.pub binghe101:/root/.ssh/103 在binghe101服务器上执行如下命令。 cat ~/.ssh/102 >> ~/.ssh/authorized_keys cat ~/.ssh/103 >> ~/.ssh/authorized_keys 然后将authorized_keys文件分别复制到binghe102、binghe103服务器。 [root@binghe101 ~]# scp .ssh/authorized_keys binghe102:/root/.ssh/authorized_keys [root@binghe101 ~]# scp .ssh/authorized_keys binghe103:/root/.ssh/authorized_keys 删除binghe101节点上~/.ssh下的102和103文件。 rm ~/.ssh/102 rm ~/.ssh/103 安装JDK 需要在每台服务器上安装JDK环境。到Oracle官方下载JDK,我这里下的JDK版本为1.8.0_202,下载后解压并配置系统环境变量。 tar -zxvf jdk1.8.0_212.tar.gz mv jdk1.8.0_212 /usr/local 接下来,配置系统环境变量。 配置项内容如下所示。 JAVA_HOME=/usr/local/jdk1.8.0_212 CLASS_PATH=.:$JAVA_HOME/lib PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASS_PATH PATH 接下来执行如下命令使系统环境变量生效。 安装Maven 到Apache官方下载Maven,我这里下载的Maven版本为3.6.3。下载后直接解压并配置系统环境变量。 tar -zxvf apache-maven-3.6.3-bin.tar.gz mv apache-maven-3.6.3-bin /usr/local 接下来,就是配置系统环境变量。 配置项内容如下所示。 JAVA_HOME=/usr/local/jdk1.8.0_212 MAVEN_HOME=/usr/local/apache-maven-3.6.3-bin CLASS_PATH=.:$JAVA_HOME/lib PATH=$MAVEN_HOME/bin:$JAVA_HOME/bin:$PATH export JAVA_HOME CLASS_PATH MAVEN_HOME PATH 接下来执行如下命令使系统环境变量生效。 接下来,修改Maven的配置文件,如下所示。 <localRepository>/home/repository</localRepository> 将Maven下载的Jar包存储到/home/repository目录下。 安装Docker环境 本文档基于Docker 19.03.8 版本搭建Docker环境。 在所有服务器上创建install_docker.sh脚本,脚本内容如下所示。 export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com dnf install yum* yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo dnf install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 systemctl enable docker.service systemctl start docker.service docker version 在每台服务器上为install_docker.sh脚本赋予可执行权限,并执行脚本即可。 安装docker-compose 注意:在每台服务器上安装docker-compose 1.下载docker-compose文件 curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 2.为docker-compose文件赋予可执行权限 chmod a+x /usr/local/bin/docker-compose 3.查看docker-compose版本 [root@binghe ~]# docker-compose version docker-compose version 1.25.5, build 8a1c60f6 docker-py version: 4.1.0 CPython version: 3.7.5 OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019 安装K8S集群环境 本文档基于K8S 1.8.12版本来搭建K8S集群 安装K8S基础环境 在所有服务器上创建install_k8s.sh脚本文件,脚本文件的内容如下所示。 #配置阿里云镜像加速器 mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker #安装nfs-utils yum install -y nfs-utils yum install -y wget #启动nfs-server systemctl start nfs-server systemctl enable nfs-server #关闭防火墙 systemctl stop firewalld systemctl disable firewalld #关闭SeLinux setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 关闭 swap swapoff -a yes | cp /etc/fstab /etc/fstab_bak cat /etc/fstab_bak |grep -v swap > /etc/fstab #修改 /etc/sysctl.conf # 如果有配置,则修改 sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf # 可能没有,追加 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf # 执行命令以应用 sysctl -p # 配置K8S的yum源 cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF # 卸载旧版本K8S yum remove -y kubelet kubeadm kubectl # 安装kubelet、kubeadm、kubectl,这里我安装的是1.18.2版本,你也可以安装1.17.2版本 yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2 # 修改docker Cgroup Driver为systemd # # 将/usr/lib/systemd/system/docker.service文件中的这一行 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # # 修改为 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd # 如果不修改,在添加 worker 节点时可能会碰到如下错误 # [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". # Please follow the guide at https://kubernetes.io/docs/setup/cri/ sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service # 设置 docker 镜像,提高 docker 镜像下载速度和稳定性 # 如果访问 https://hub.docker.io 速度非常稳定,亦可以跳过这个步骤 # curl -sSL https://kuboard.cn/install-script/set_mirror.sh | sh -s ${REGISTRY_MIRROR} # 重启 docker,并启动 kubelet systemctl daemon-reload systemctl restart docker systemctl enable kubelet && systemctl start kubelet docker version 在每台服务器上为install_k8s.sh脚本赋予可执行权限,并执行脚本即可。 初始化Master节点 只在binghe101服务器上执行的操作。 1.初始化Master节点的网络环境 注意:下面的命令需要在命令行手动执行。 # 只在 master 节点执行 # export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令 export MASTER_IP=192.168.175.101 # 替换 k8s.master 为 您想要的 dnsName export APISERVER_NAME=k8s.master # Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于物理网络中 export POD_SUBNET=172.18.0.1/16 echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts 2.初始化Master节点 在binghe101服务器上创建init_master.sh脚本文件,文件内容如下所示。 #!/bin/bash # 脚本出错时终止执行 set -e if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m" echo 当前POD_SUBNET=$POD_SUBNET echo 当前APISERVER_NAME=$APISERVER_NAME exit 1 fi # 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2 rm -f ./kubeadm-config.yaml cat <<EOF > ./kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.18.2 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers controlPlaneEndpoint: "${APISERVER_NAME}:6443" networking: serviceSubnet: "10.96.0.0/16" podSubnet: "${POD_SUBNET}" dnsDomain: "cluster.local" EOF # kubeadm init # 根据服务器网速的情况,您需要等候 3 - 10 分钟 kubeadm init --config=kubeadm-config.yaml --upload-certs # 配置 kubectl rm -rf /root/.kube/ mkdir /root/.kube/ cp -i /etc/kubernetes/admin.conf /root/.kube/config # 安装 calico 网络插件 # 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises echo "安装calico-3.13.1" rm -f calico-3.13.1.yaml wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml kubectl apply -f calico-3.13.1.yaml 赋予init_master.sh脚本文件可执行权限并执行脚本。 3.查看Master节点的初始化结果 (1)确保所有容器组处于Running状态 # 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态 watch kubectl get pod -n kube-system -o wide 具体执行如下所示。 [root@binghe101 ~]# watch kubectl get pod -n kube-system -o wide Every 2.0s: kubectl get pod -n kube-system -o wide binghe101: Sun May 10 11:01:32 2020 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES calico-kube-controllers-5b8b769fcd-5dtlp 1/1 Running 0 118s 172.18.203.66 binghe101 <none> <none> calico-node-fnv8g 1/1 Running 0 118s 192.168.175.101 binghe101 <none> <none> coredns-546565776c-27t7h 1/1 Running 0 2m1s 172.18.203.67 binghe101 <none> <none> coredns-546565776c-hjb8z 1/1 Running 0 2m1s 172.18.203.65 binghe101 <none> <none> etcd-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101 <none> <none> kube-apiserver-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101 <none> <none> kube-controller-manager-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101 <none> <none> kube-proxy-dvgsr 1/1 Running 0 2m1s 192.168.175.101 binghe101 <none> <none> kube-scheduler-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101 <none> <none> (2) 查看 Master 节点初始化结果 kubectl get nodes -o wide 具体执行如下所示。 [root@binghe101 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME binghe101 Ready master 3m28s v1.18.2 192.168.175.101 <none> CentOS Linux 8 (Core) 4.18.0-80.el8.x86_64 docker://19.3.8 初始化Worker节点 1.获取join命令参数 在Master节点(binghe101服务器)上执行如下命令获取join命令参数。 kubeadm token create --print-join-command 具体执行如下所示。 [root@binghe101 ~]# kubeadm token create --print-join-command W0510 11:04:34.828126 56132 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io] kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 其中,有如下一行输出。 kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 这行代码就是获取到的join命令。 注意:join命令中的token的有效时间为 2 个小时,2小时内,可以使用此 token 初始化任意数量的 worker 节点。 2.初始化Worker节点 针对所有的 worker 节点执行,在这里,就是在binghe102服务器和binghe103服务器上执行。 在命令分别手动执行如下命令。 # 只在 worker 节点执行 # 192.168.175.101 为 master 节点的内网 IP export MASTER_IP=192.168.175.101 # 替换 k8s.master 为初始化 master 节点时所使用的 APISERVER_NAME export APISERVER_NAME=k8s.master echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts # 替换为 master 节点上 kubeadm token create 命令输出的join kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 具体执行如下所示。 [root@binghe102 ~]# export MASTER_IP=192.168.175.101 [root@binghe102 ~]# export APISERVER_NAME=k8s.master [root@binghe102 ~]# echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts [root@binghe102 ~]# kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d W0510 11:08:27.709263 42795 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set. [preflight] Running pre-flight checks [WARNING FileExisting-tc]: tc not found in system path [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. 根据输出结果可以看出,Worker节点加入了K8S集群。 注意:kubeadm join…就是master 节点上 kubeadm token create 命令输出的join。 3.查看初始化结果 在Master节点(binghe101服务器)执行如下命令查看初始化结果。 kubectl get nodes -o wide 具体执行如下所示。 [root@binghe101 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION binghe101 Ready master 20m v1.18.2 binghe102 Ready <none> 2m46s v1.18.2 binghe103 Ready <none> 2m46s v1.18.2 注意:kubectl get nodes命令后面加上-o wide参数可以输出更多的信息。 重启K8S集群引起的问题 1.Worker节点故障不能启动 Master 节点的 IP 地址发生变化,导致 worker 节点不能启动。需要重新安装K8S集群,并确保所有节点都有固定的内网 IP 地址。 2.Pod崩溃或不能正常访问 重启服务器后使用如下命令查看Pod的运行状态。 kubectl get pods --all-namespaces 发现很多 Pod 不在 Running 状态,此时,需要使用如下命令删除运行不正常的Pod。 kubectl delete pod <pod-name> -n <pod-namespece> 注意:如果Pod 是使用 Deployment、StatefulSet 等控制器创建的,K8S 将创建新的 Pod 作为替代,重新启动的 Pod 通常能够正常工作。 K8S安装ingress-nginx 注意:在Master节点(binghe101服务器上执行) 1.创建ingress-nginx命名空间 创建ingress-nginx-namespace.yaml文件,文件内容如下所示。 apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: name: ingress-nginx 执行如下命令创建ingress-nginx命名空间。 kubectl apply -f ingress-nginx-namespace.yaml 2.安装ingress controller 创建ingress-nginx-mandatory.yaml文件,文件内容如下所示。 apiVersion: v1 kind: Namespace metadata: name: ingress-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: default-http-backend labels: app.kubernetes.io/name: default-http-backend app.kubernetes.io/part-of: ingress-nginx namespace: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: default-http-backend app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: default-http-backend app.kubernetes.io/part-of: ingress-nginx spec: terminationGracePeriodSeconds: 60 containers: - name: default-http-backend image: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5 livenessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 5 ports: - containerPort: 8080 resources: limits: cpu: 10m memory: 20Mi requests: cpu: 10m memory: 20Mi --- apiVersion: v1 kind: Service metadata: name: default-http-backend namespace: ingress-nginx labels: app.kubernetes.io/name: default-http-backend app.kubernetes.io/part-of: ingress-nginx spec: ports: - port: 80 targetPort: 8080 selector: app.kubernetes.io/name: default-http-backend app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: nginx-ingress-serviceaccount namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "extensions" resources: - ingresses verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" resources: - ingresses/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resources: - configmaps resourceNames: - "ingress-controller-leader-nginx" verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: serviceAccountName: nginx-ingress-serviceaccount containers: - name: nginx-ingress-controller image: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/nginx-ingress-controller:0.20.0 args: - /nginx-ingress-controller - --default-backend-service=$(POD_NAMESPACE)/default-http-backend - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE runAsUser: 33 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 443 livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 --- 执行如下命令安装ingress controller。 kubectl apply -f ingress-nginx-mandatory.yaml 3.安装K8S SVC:ingress-nginx 主要是用来用于暴露pod:nginx-ingress-controller。 创建service-nodeport.yaml文件,文件内容如下所示。 apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: type: NodePort ports: - name: http port: 80 targetPort: 80 protocol: TCP nodePort: 30080 - name: https port: 443 targetPort: 443 protocol: TCP nodePort: 30443 selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx 执行如下命令安装。 kubectl apply -f service-nodeport.yaml 4.访问K8S SVC:ingress-nginx 查看ingress-nginx命名空间的部署情况,如下所示。 [root@binghe101 k8s]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE default-http-backend-796ddcd9b-vfmgn 1/1 Running 1 10h nginx-ingress-controller-58985cc996-87754 1/1 Running 2 10h 在命令行服务器命令行输入如下命令查看ingress-nginx的端口映射情况。 kubectl get svc -n ingress-nginx 具体如下所示。 [root@binghe101 k8s]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default-http-backend ClusterIP 10.96.247.2 <none> 80/TCP 7m3s ingress-nginx NodePort 10.96.40.6 <none> 80:30080/TCP,443:30443/TCP 4m35s 所以,可以通过Master节点(binghe101服务器)的IP地址和30080端口号来访问ingress-nginx,如下所示。 [root@binghe101 k8s]# curl 192.168.175.101:30080 default backend - 404 也可以在浏览器打开http://192.168.175.101:30080 来访问ingress-nginx,如下所示。 K8S安装gitlab代码仓库 注意:在Master节点(binghe101服务器上执行) 1.创建k8s-ops命名空间 创建k8s-ops-namespace.yaml文件,文件内容如下所示。 apiVersion: v1 kind: Namespace metadata: name: k8s-ops labels: name: k8s-ops 执行如下命令创建命名空间。 kubectl apply -f k8s-ops-namespace.yaml 2.安装gitlab-redis 创建gitlab-redis.yaml文件,文件的内容如下所示。 apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: k8s-ops labels: name: redis spec: selector: matchLabels: name: redis template: metadata: name: redis labels: name: redis spec: containers: - name: redis image: sameersbn/redis imagePullPolicy: IfNotPresent ports: - name: redis containerPort: 6379 volumeMounts: - mountPath: /var/lib/redis name: data livenessProbe: exec: command: - redis-cli - ping initialDelaySeconds: 30 timeoutSeconds: 5 readinessProbe: exec: command: - redis-cli - ping initialDelaySeconds: 10 timeoutSeconds: 5 volumes: - name: data hostPath: path: /data1/docker/xinsrv/redis --- apiVersion: v1 kind: Service metadata: name: redis namespace: k8s-ops labels: name: redis spec: ports: - name: redis port: 6379 targetPort: redis selector: name: redis 首先,在命令行执行如下命令创建/data1/docker/xinsrv/redis目录。 mkdir -p /data1/docker/xinsrv/redis 执行如下命令安装gitlab-redis。 kubectl apply -f gitlab-redis.yaml 3.安装gitlab-postgresql 创建gitlab-postgresql.yaml,文件内容如下所示。 apiVersion: apps/v1 kind: Deployment metadata: name: postgresql namespace: k8s-ops labels: name: postgresql spec: selector: matchLabels: name: postgresql template: metadata: name: postgresql labels: name: postgresql spec: containers: - name: postgresql image: sameersbn/postgresql imagePullPolicy: IfNotPresent env: - name: DB_USER value: gitlab - name: DB_PASS value: passw0rd - name: DB_NAME value: gitlab_production - name: DB_EXTENSION value: pg_trgm ports: - name: postgres containerPort: 5432 volumeMounts: - mountPath: /var/lib/postgresql name: data livenessProbe: exec: command: - pg_isready - -h - localhost - -U - postgres initialDelaySeconds: 30 timeoutSeconds: 5 readinessProbe: exec: command: - pg_isready - -h - localhost - -U - postgres initialDelaySeconds: 5 timeoutSeconds: 1 volumes: - name: data hostPath: path: /data1/docker/xinsrv/postgresql --- apiVersion: v1 kind: Service metadata: name: postgresql namespace: k8s-ops labels: name: postgresql spec: ports: - name: postgres port: 5432 targetPort: postgres selector: name: postgresql 首先,执行如下命令创建/data1/docker/xinsrv/postgresql目录。 mkdir -p /data1/docker/xinsrv/postgresql 接下来,安装gitlab-postgresql,如下所示。 kubectl apply -f gitlab-postgresql.yaml 4.安装gitlab (1)配置用户名和密码 首先,在命令行使用base64编码为用户名和密码进行转码,本示例中,使用的用户名为admin,密码为admin.1231 转码情况如下所示。 [root@binghe101 k8s]# echo -n 'admin' | base64 YWRtaW4= [root@binghe101 k8s]# echo -n 'admin.1231' | base64 YWRtaW4uMTIzMQ== 转码后的用户名为:YWRtaW4= 密码为:YWRtaW4uMTIzMQ== 也可以对base64编码后的字符串解码,例如,对密码字符串解码,如下所示。 [root@binghe101 k8s]# echo 'YWRtaW4uMTIzMQ==' | base64 --decode admin.1231 接下来,创建secret-gitlab.yaml文件,主要是用户来配置GitLab的用户名和密码,文件内容如下所示。 apiVersion: v1 kind: Secret metadata: namespace: k8s-ops name: git-user-pass type: Opaque data: username: YWRtaW4= password: YWRtaW4uMTIzMQ== 执行配置文件的内容,如下所示。 kubectl create -f ./secret-gitlab.yaml (2)安装GitLab 创建gitlab.yaml文件,文件的内容如下所示。 apiVersion: apps/v1 kind: Deployment metadata: name: gitlab namespace: k8s-ops labels: name: gitlab spec: selector: matchLabels: name: gitlab template: metadata: name: gitlab labels: name: gitlab spec: containers: - name: gitlab image: sameersbn/gitlab:12.1.6 imagePullPolicy: IfNotPresent env: - name: TZ value: Asia/Shanghai - name: GITLAB_TIMEZONE value: Beijing - name: GITLAB_SECRETS_DB_KEY_BASE value: long-and-random-alpha-numeric-string - name: GITLAB_SECRETS_SECRET_KEY_BASE value: long-and-random-alpha-numeric-string - name: GITLAB_SECRETS_OTP_KEY_BASE value: long-and-random-alpha-numeric-string - name: GITLAB_ROOT_PASSWORD valueFrom: secretKeyRef: name: git-user-pass key: password - name: GITLAB_ROOT_EMAIL value: 12345678@qq.com - name: GITLAB_HOST value: gitlab.binghe.com - name: GITLAB_PORT value: "80" - name: GITLAB_SSH_PORT value: "30022" - name: GITLAB_NOTIFY_ON_BROKEN_BUILDS value: "true" - name: GITLAB_NOTIFY_PUSHER value: "false" - name: GITLAB_BACKUP_SCHEDULE value: daily - name: GITLAB_BACKUP_TIME value: 01:00 - name: DB_TYPE value: postgres - name: DB_HOST value: postgresql - name: DB_PORT value: "5432" - name: DB_USER value: gitlab - name: DB_PASS value: passw0rd - name: DB_NAME value: gitlab_production - name: REDIS_HOST value: redis - name: REDIS_PORT value: "6379" ports: - name: http containerPort: 80 - name: ssh containerPort: 22 volumeMounts: - mountPath: /home/git/data name: data livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 180 timeoutSeconds: 5 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 timeoutSeconds: 1 volumes: - name: data hostPath: path: /data1/docker/xinsrv/gitlab --- apiVersion: v1 kind: Service metadata: name: gitlab namespace: k8s-ops labels: name: gitlab spec: ports: - name: http port: 80 nodePort: 30088 - name: ssh port: 22 targetPort: ssh nodePort: 30022 type: NodePort selector: name: gitlab --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: gitlab namespace: k8s-ops annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: gitlab.binghe.com http: paths: - backend: serviceName: gitlab servicePort: http 注意:在配置GitLab时,监听主机时,不能使用IP地址,需要使用主机名或者域名,上述配置中,我使用的是gitlab.binghe.com主机名。 在命令行执行如下命令创建/data1/docker/xinsrv/gitlab目录。 mkdir -p /data1/docker/xinsrv/gitlab 安装GitLab,如下所示。 kubectl apply -f gitlab.yaml 5.安装完成 查看k8s-ops命名空间部署情况,如下所示。 [root@binghe101 k8s]# kubectl get pod -n k8s-ops NAME READY STATUS RESTARTS AGE gitlab-7b459db47c-5vk6t 0/1 Running 0 11s postgresql-79567459d7-x52vx 1/1 Running 0 30m redis-67f4cdc96c-h5ckz 1/1 Running 1 10h 也可以使用如下命令查看。 [root@binghe101 k8s]# kubectl get pod --namespace=k8s-ops NAME READY STATUS RESTARTS AGE gitlab-7b459db47c-5vk6t 0/1 Running 0 36s postgresql-79567459d7-x52vx 1/1 Running 0 30m redis-67f4cdc96c-h5ckz 1/1 Running 1 10h 二者效果一样。 接下来,查看GitLab的端口映射,如下所示。 [root@binghe101 k8s]# kubectl get svc -n k8s-ops NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gitlab NodePort 10.96.153.100 <none> 80:30088/TCP,22:30022/TCP 2m42s postgresql ClusterIP 10.96.203.119 <none> 5432/TCP 32m redis ClusterIP 10.96.107.150 <none> 6379/TCP 10h 此时,可以看到,可以通过Master节点(binghe101)的主机名gitlab.binghe.com和端口30088就能够访问GitLab。由于我这里使用的是虚拟机来搭建相关的环境,在本机访问虚拟机映射的gitlab.binghe.com时,需要配置本机的hosts文件,在本机的hosts文件中加入如下配置项。 192.168.175.101 gitlab.binghe.com 注意:在Windows操作系统中,hosts文件所在的目录如下。 C:\Windows\System32\drivers\etc 接下来,就可以在浏览器中通过链接:http://gitlab.binghe.com:30088 来访问GitLab了,如下所示。 此时,可以通过用户名root和密码admin.1231来登录GitLab了。 注意:这里的用户名是root而不是admin,因为root是GitLab默认的超级用户。 登录后的界面如下所示。 到此,K8S安装gitlab完成。 安装Harbor私有仓库 注意:这里将Harbor私有仓库安装在Master节点(binghe101服务器)上,实际生产环境中建议安装在其他服务器。 1.下载Harbor的离线安装版本 wget https://github.com/goharbor/harbor/releases/download/v1.10.2/harbor-offline-installer-v1.10.2.tgz 2.解压Harbor的安装包 tar -zxvf harbor-offline-installer-v1.10.2.tgz 解压成功后,会在服务器当前目录生成一个harbor目录。 3.配置Harbor 注意:这里,我将Harbor的端口修改成了1180,如果不修改Harbor的端口,默认的端口是80。 (1)修改harbor.yml文件 修改的配置项如下所示。 hostname: 192.168.175.101 http: port: 1180 harbor_admin_password: binghe123 ###并把https注释掉,不然在安装的时候会报错:ERROR:root:Error: The protocol is https but attribute ssl_cert is not set #https: #port: 443 #certificate: /your/certificate/path #private_key: /your/private/key/path (2)修改daemon.json文件 修改/etc/docker/daemon.json文件,没有的话就创建,在/etc/docker/daemon.json文件中添加如下内容。 [root@binghe~]# cat /etc/docker/daemon.json { "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"], "insecure-registries":["192.168.175.101:1180"] } 也可以在服务器上使用 ip addr 命令查看本机所有的IP地址段,将其配置到/etc/docker/daemon.json文件中。这里,我配置后的文件内容如下所示。 { "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"], "insecure-registries":["192.168.175.0/16","172.17.0.0/16", "172.18.0.0/16", "172.16.29.0/16", "192.168.175.101:1180"] } 4.安装并启动harbor 配置完成后,输入如下命令即可安装并启动Harbor [root@binghe harbor]# ./install.sh 5.登录Harbor并添加账户 安装成功后,在浏览器地址栏输入http://192.168.175.101:1180打开链接,如下图所示。 输入用户名admin和密码binghe123,登录系统,如下图所示 接下来,我们选择用户管理,添加一个管理员账户,为后续打包Docker镜像和上传Docker镜像做准备。添加账户的步骤如下所示。 此处填写的密码为Binghe123。 点击确定后,如下所示。 此时,账户binghe还不是管理员,此时选中binghe账户,点击“设置为管理员”。 此时,binghe账户就被设置为管理员了。到此,Harbor的安装就完成了。 6.修改Harbor端口 如果安装Harbor后,大家需要修改Harbor的端口,可以按照如下步骤修改Harbor的端口,这里,我以将80端口修改为1180端口为例 (1)修改harbor.yml文件 修改的配置项如下所示。 hostname: 192.168.175.101 http: port: 1180 harbor_admin_password: binghe123 ###并把https注释掉,不然在安装的时候会报错:ERROR:root:Error: The protocol is https but attribute ssl_cert is not set #https: #port: 443 #certificate: /your/certificate/path #private_key: /your/private/key/path (2)修改docker-compose.yml文件 修改的配置项如下所示。 (3)修改config.yml文件 cd common/config/registry vim config.yml 修改的配置项如下所示。 realm: http://192.168.175.101:1180/service/token (4)重启Docker systemctl daemon-reload systemctl restart docker.service (5)重启Harbor [root@binghe harbor]# docker-compose down Stopping harbor-log ... done Removing nginx ... done Removing harbor-portal ... done Removing harbor-jobservice ... done Removing harbor-core ... done Removing redis ... done Removing registry ... done Removing registryctl ... done Removing harbor-db ... done Removing harbor-log ... done Removing network harbor_harbor [root@binghe harbor]# ./prepare prepare base dir is set to /mnt/harbor Clearing the configuration file: /config/log/logrotate.conf Clearing the configuration file: /config/nginx/nginx.conf Clearing the configuration file: /config/core/env Clearing the configuration file: /config/core/app.conf Clearing the configuration file: /config/registry/root.crt Clearing the configuration file: /config/registry/config.yml Clearing the configuration file: /config/registryctl/env Clearing the configuration file: /config/registryctl/config.yml Clearing the configuration file: /config/db/env Clearing the configuration file: /config/jobservice/env Clearing the configuration file: /config/jobservice/config.yml Generated configuration file: /config/log/logrotate.conf Generated configuration file: /config/nginx/nginx.conf Generated configuration file: /config/core/env Generated configuration file: /config/core/app.conf Generated configuration file: /config/registry/config.yml Generated configuration file: /config/registryctl/env Generated configuration file: /config/db/env Generated configuration file: /config/jobservice/env Generated configuration file: /config/jobservice/config.yml loaded secret from file: /secret/keys/secretkey Generated configuration file: /compose_location/docker-compose.yml Clean up the input dir [root@binghe harbor]# docker-compose up -d Creating network "harbor_harbor" with the default driver Creating harbor-log ... done Creating harbor-db ... done Creating redis ... done Creating registry ... done Creating registryctl ... done Creating harbor-core ... done Creating harbor-jobservice ... done Creating harbor-portal ... done Creating nginx ... done [root@binghe harbor]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 安装Jenkins(一般的做法) 1.安装nfs(之前安装过的话,可以省略此步) 使用 nfs 最大的问题就是写权限,可以使用 kubernetes 的 securityContext/runAsUser 指定 jenkins 容器中运行 jenkins 的用户 uid,以此来指定 nfs 目录的权限,让 jenkins 容器可写;也可以不限制,让所有用户都可以写。这里为了简单,就让所有用户可写了。 如果之前已经安装过nfs,则这一步可以省略。找一台主机,安装 nfs,这里,我以在Master节点(binghe101服务器)上安装nfs为例。 在命令行输入如下命令安装并启动nfs。 yum install nfs-utils -y systemctl start nfs-server systemctl enable nfs-server 2.创建nfs共享目录 在Master节点(binghe101服务器)上创建 /opt/nfs/jenkins-data目录作为nfs的共享目录,如下所示。 mkdir -p /opt/nfs/jenkins-data 接下来,编辑/etc/exports文件,如下所示。 在/etc/exports文件文件中添加如下一行配置。 /opt/nfs/jenkins-data 192.168.175.0/24(rw,all_squash) 这里的 ip 使用 kubernetes node 节点的 ip 范围,后面的 all_squash 选项会将所有访问的用户都映射成 nfsnobody 用户,不管你是什么用户访问,最终都会压缩成 nfsnobody,所以只要将 /opt/nfs/jenkins-data 的属主改为 nfsnobody,那么无论什么用户来访问都具有写权限。 这个选项在很多机器上由于用户 uid 不规范导致启动进程的用户不同,但是同时要对一个共享目录具有写权限时很有效。 接下来,为 /opt/nfs/jenkins-data目录授权,并重新加载nfs,如下所示。 chown -R 1000 /opt/nfs/jenkins-data/ systemctl reload nfs-server 在K8S集群中任意一个节点上使用如下命令进行验证: 如果能够看到 /opt/nfs/jenkins-data 就表示 ok 了。 具体如下所示。 [root@binghe101 ~]# showmount -e 192.168.175.101 Export list for 192.168.175.101: /opt/nfs/jenkins-data 192.168.175.0/24 [root@binghe102 ~]# showmount -e 192.168.175.101 Export list for 192.168.175.101: /opt/nfs/jenkins-data 192.168.175.0/24 3.创建PV Jenkins 其实只要加载对应的目录就可以读取之前的数据,但是由于 deployment 无法定义存储卷,因此我们只能使用 StatefulSet。 首先创建 pv,pv 是给 StatefulSet 使用的,每次 StatefulSet 启动都会通过 volumeClaimTemplates 这个模板去创建 pvc,因此必须得有 pv,才能供 pvc 绑定。 创建jenkins-pv.yaml文件,文件内容如下所示。 apiVersion: v1 kind: PersistentVolume metadata: name: jenkins spec: nfs: path: /opt/nfs/jenkins-data server: 192.168.175.101 accessModes: ["ReadWriteOnce"] capacity: storage: 1Ti 我这里给了 1T存储空间,可以根据实际配置。 执行如下命令创建pv。 kubectl apply -f jenkins-pv.yaml 4.创建serviceAccount 创建service account,因为 jenkins 后面需要能够动态创建 slave,因此它必须具备一些权限。 创建jenkins-service-account.yaml文件,文件内容如下所示。 apiVersion: v1 kind: ServiceAccount metadata: name: jenkins --- kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: jenkins rules: - apiGroups: [""] resources: ["pods"] verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["secrets"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: jenkins roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: jenkins subjects: - kind: ServiceAccount name: jenkins 上述配置中,创建了一个 RoleBinding 和一个 ServiceAccount,并且将 RoleBinding 的权限绑定到这个用户上。所以,jenkins 容器必须使用这个 ServiceAccount 运行才行,不然 RoleBinding 的权限它将不具备。 RoleBinding 的权限很容易就看懂了,因为 jenkins 需要创建和删除 slave,所以才需要上面这些权限。至于 secrets 权限,则是 https 证书。 执行如下命令创建serviceAccount。 kubectl apply -f jenkins-service-account.yaml 5.安装Jenkins 创建jenkins-statefulset.yaml文件,文件内容如下所示。 apiVersion: apps/v1 kind: StatefulSet metadata: name: jenkins labels: name: jenkins spec: selector: matchLabels: name: jenkins serviceName: jenkins replicas: 1 updateStrategy: type: RollingUpdate template: metadata: name: jenkins labels: name: jenkins spec: terminationGracePeriodSeconds: 10 serviceAccountName: jenkins containers: - name: jenkins image: docker.io/jenkins/jenkins:lts imagePullPolicy: IfNotPresent ports: - containerPort: 8080 - containerPort: 32100 resources: limits: cpu: 4 memory: 4Gi requests: cpu: 4 memory: 4Gi env: - name: LIMITS_MEMORY valueFrom: resourceFieldRef: resource: limits.memory divisor: 1Mi - name: JAVA_OPTS value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 volumeMounts: - name: jenkins-home mountPath: /var/jenkins_home livenessProbe: httpGet: path: /login port: 8080 initialDelaySeconds: 60 timeoutSeconds: 5 failureThreshold: 12 readinessProbe: httpGet: path: /login port: 8080 initialDelaySeconds: 60 timeoutSeconds: 5 failureThreshold: 12 volumeClaimTemplates: - metadata: name: jenkins-home spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Ti jenkins 部署时需要注意它的副本数,你的副本数有多少就要有多少个 pv,同样,存储会有多倍消耗。这里我只使用了一个副本,因此前面也只创建了一个 pv。 使用如下命令安装Jenkins。 kubectl apply -f jenkins-statefulset.yaml 6.创建Service 创建jenkins-service.yaml文件,文件内容如下所示。 apiVersion: v1 kind: Service metadata: name: jenkins spec: selector: name: jenkins ports: - name: http port: 80 nodePort: 31888 targetPort: 8080 protocol: TCP - name: jenkins-agent port: 32100 nodePort: 32100 targetPort: 32100 protocol: TCP type: NodePort 使用如下命令安装Service。 kubectl apply -f jenkins-service.yaml 7.安装 ingress jenkins 的 web 界面需要从集群外访问,这里我们选择的是使用 ingress。创建jenkins-ingress.yaml文件,文件内容如下所示。 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: jenkins spec: rules: - http: paths: - path: / backend: serviceName: jenkins servicePort: 31888 host: jekins.binghe.com 这里,需要注意的是host必须配置为域名或者主机名,否则会报错,如下所示。 The Ingress "jenkins" is invalid: spec.rules[0].host: Invalid value: "192.168.175.101": must be a DNS name, not an IP address 使用如下命令安装ingress。 kubectl apply -f jenkins-ingress.yaml 最后,由于我这里使用的是虚拟机来搭建相关的环境,在本机访问虚拟机映射的jekins.binghe.com时,需要配置本机的hosts文件,在本机的hosts文件中加入如下配置项。 192.168.175.101 jekins.binghe.com 注意:在Windows操作系统中,hosts文件所在的目录如下。 C:\Windows\System32\drivers\etc 接下来,就可以在浏览器中通过链接:http://jekins.binghe.com:31888 来访问Jekins了。 物理机安装SVN 这里,以在Master节点(binghe101服务器)上安装SVN为例。 1.使用yum安装SVN 在命令行执行如下命令安装SVN。 yum -y install subversion 2.创建SVN库 依次执行如下命令。 #创建/data/svn mkdir -p /data/svn #初始化svn svnserve -d -r /data/svn #创建代码仓库 svnadmin create /data/svn/test 3.配置SVN mkdir /data/svn/conf cp /data/svn/test/conf/* /data/svn/conf/ cd /data/svn/conf/ [root@binghe101 conf]# ll 总用量 20 -rw-r--r-- 1 root root 1080 5月 12 02:17 authz -rw-r--r-- 1 root root 885 5月 12 02:17 hooks-env.tmpl -rw-r--r-- 1 root root 309 5月 12 02:17 passwd -rw-r--r-- 1 root root 4375 5月 12 02:17 svnserve.conf 配置authz文件, 配置后的内容如下所示。 [aliases] # joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average [groups] # harry_and_sally = harry,sally # harry_sally_and_joe = harry,sally,&joe SuperAdmin = admin binghe = admin,binghe # [/foo/bar] # harry = rw # &joe = r # * = # [repository:/baz/fuz] # @harry_and_sally = rw # * = r [test:/] @SuperAdmin=rw @binghe=rw 配置passwd文件 配置后的内容如下所示。 [users] # harry = harryssecret # sally = sallyssecret admin = admin123 binghe = binghe123 配置 svnserve.conf 配置后的文件如下所示。 ### This file controls the configuration of the svnserve daemon, if you ### use it to allow access to this repository. (If you only allow ### access through http: and/or file: URLs, then this file is ### irrelevant.) ### Visit http://subversion.apache.org/ for more information. [general] ### The anon-access and auth-access options control access to the ### repository for unauthenticated (a.k.a. anonymous) users and ### authenticated users, respectively. ### Valid values are "write", "read", and "none". ### Setting the value to "none" prohibits both reading and writing; ### "read" allows read-only access, and "write" allows complete ### read/write access to the repository. ### The sample settings below are the defaults and specify that anonymous ### users have read-only access to the repository, while authenticated ### users have read and write access to the repository. anon-access = none auth-access = write ### The password-db option controls the location of the password ### database file. Unless you specify a path starting with a /, ### the file's location is relative to the directory containing ### this configuration file. ### If SASL is enabled (see below), this file will NOT be used. ### Uncomment the line below to use the default password file. password-db = /data/svn/conf/passwd ### The authz-db option controls the location of the authorization ### rules for path-based access control. Unless you specify a path ### starting with a /, the file's location is relative to the ### directory containing this file. The specified path may be a ### repository relative URL (^/) or an absolute file:// URL to a text ### file in a Subversion repository. If you don't specify an authz-db, ### no path-based access control is done. ### Uncomment the line below to use the default authorization file. authz-db = /data/svn/conf/authz ### The groups-db option controls the location of the file with the ### group definitions and allows maintaining groups separately from the ### authorization rules. The groups-db file is of the same format as the ### authz-db file and should contain a single [groups] section with the ### group definitions. If the option is enabled, the authz-db file cannot ### contain a [groups] section. Unless you specify a path starting with ### a /, the file's location is relative to the directory containing this ### file. The specified path may be a repository relative URL (^/) or an ### absolute file:// URL to a text file in a Subversion repository. ### This option is not being used by default. # groups-db = groups ### This option specifies the authentication realm of the repository. ### If two repositories have the same authentication realm, they should ### have the same password database, and vice versa. The default realm ### is repository's uuid. realm = svn ### The force-username-case option causes svnserve to case-normalize ### usernames before comparing them against the authorization rules in the ### authz-db file configured above. Valid values are "upper" (to upper- ### case the usernames), "lower" (to lowercase the usernames), and ### "none" (to compare usernames as-is without case conversion, which ### is the default behavior). # force-username-case = none ### The hooks-env options specifies a path to the hook script environment ### configuration file. This option overrides the per-repository default ### and can be used to configure the hook script environment for multiple ### repositories in a single file, if an absolute path is specified. ### Unless you specify an absolute path, the file's location is relative ### to the directory containing this file. # hooks-env = hooks-env [sasl] ### This option specifies whether you want to use the Cyrus SASL ### library for authentication. Default is false. ### Enabling this option requires svnserve to have been built with Cyrus ### SASL support; to check, run 'svnserve --version' and look for a line ### reading 'Cyrus SASL authentication is available.' # use-sasl = true ### These options specify the desired strength of the security layer ### that you want SASL to provide. 0 means no encryption, 1 means ### integrity-checking only, values larger than 1 are correlated ### to the effective key length for encryption (e.g. 128 means 128-bit ### encryption). The values below are the defaults. # min-encryption = 0 # max-encryption = 256 接下来,将/data/svn/conf目录下的svnserve.conf文件复制到/data/svn/test/conf/目录下。如下所示。 [root@binghe101 conf]# cp /data/svn/conf/svnserve.conf /data/svn/test/conf/ cp:是否覆盖'/data/svn/test/conf/svnserve.conf'? y 4.启动SVN服务 (1)创建svnserve.service服务 创建svnserve.service文件 vim /usr/lib/systemd/system/svnserve.service 文件的内容如下所示。 [Unit] Description=Subversion protocol daemon After=syslog.target network.target Documentation=man:svnserve(8) [Service] Type=forking EnvironmentFile=/etc/sysconfig/svnserve #ExecStart=/usr/bin/svnserve --daemon --pid-file=/run/svnserve/svnserve.pid $OPTIONS ExecStart=/usr/bin/svnserve --daemon $OPTIONS PrivateTmp=yes [Install] WantedBy=multi-user.target 接下来执行如下命令使配置生效。 命令执行成功后,修改 /etc/sysconfig/svnserve 文件。 vim /etc/sysconfig/svnserve 修改后的文件内容如下所示。 # OPTIONS is used to pass command-line arguments to svnserve. # # Specify the repository location in -r parameter: OPTIONS="-r /data/svn" (2)启动SVN 首先查看SVN状态,如下所示。 [root@itence10 conf]# systemctl status svnserve.service ● svnserve.service - Subversion protocol daemon Loaded: loaded (/usr/lib/systemd/system/svnserve.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:svnserve(8) 可以看到,此时SVN并没有启动,接下来,需要启动SVN。 systemctl start svnserve.service 设置SVN服务开机自启动。 systemctl enable svnserve.service 接下来,就可以下载安装TortoiseSVN,输入链接svn://192.168.0.10/test 并输入用户名binghe,密码binghe123来连接SVN了。 物理机安装Jenkins 注意:安装Jenkins之前需要安装JDK和Maven,我这里同样将Jenkins安装在Master节点(binghe101服务器)。 1.启用Jenkins库 运行以下命令以下载repo文件并导入GPG密钥: wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key 2.安装Jenkins 执行如下命令安装Jenkis。 接下来,修改Jenkins默认端口,如下所示。 vim /etc/sysconfig/jenkins 修改后的两项配置如下所示。 JENKINS_JAVA_CMD="/usr/local/jdk1.8.0_212/bin/java" JENKINS_PORT="18080" 此时,已经将Jenkins的端口由8080修改为18080 3.启动Jenkins 在命令行输入如下命令启动Jenkins。 配置Jenkins开机自启动。 查看Jenkins的运行状态。 [root@itence10 ~]# systemctl status jenkins ● jenkins.service - LSB: Jenkins Automation Server Loaded: loaded (/etc/rc.d/init.d/jenkins; generated) Active: active (running) since Tue 2020-05-12 04:33:40 EDT; 28s ago Docs: man:systemd-sysv-generator(8) Tasks: 71 (limit: 26213) Memory: 550.8M 说明,Jenkins启动成功。 配置Jenkins运行环境 1.登录Jenkins 首次安装后,需要配置Jenkins的运行环境。首先,在浏览器地址栏访问链接http://192.168.0.10:18080,打开Jenkins界面。 根据提示使用如下命令到服务器上找密码值,如下所示。 [root@binghe101 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword 71af861c2ab948a1b6efc9f7dde90776 将密码71af861c2ab948a1b6efc9f7dde90776复制到文本框,点击继续。会跳转到自定义Jenkins页面,如下所示。 这里,可以直接选择“安装推荐的插件”。之后会跳转到一个安装插件的页面,如下所示。 此步骤可能有下载失败的情况,可直接忽略。 2.安装插件 需要安装的插件 Kubernetes Cli Plugin:该插件可直接在Jenkins中使用kubernetes命令行进行操作。 Kubernetes plugin: 使用kubernetes则需要安装该插件 Kubernetes Continuous Deploy Plugin:kubernetes部署插件,可根据需要使用 还有更多的插件可供选择,可点击 系统管理->管理插件进行管理和添加,安装相应的Docker插件、SSH插件、Maven插件。其他的插件可以根据需要进行安装。如下图所示。 3.配置Jenkins (1)配置JDK和Maven 在Global Tool Configuration中配置JDK和Maven,如下所示,打开Global Tool Configuration界面。 接下来就开始配置JDK和Maven了。 由于我在服务器上将Maven安装在/usr/local/maven-3.6.3目录下,所以,需要在“Maven 配置”中进行配置,如下图所示。 接下来,配置JDK,如下所示。 注意:不要勾选“Install automatically” 接下来,配置Maven,如下所示。 注意:不要勾选“Install automatically” (2)配置SSH 进入Jenkins的Configure System界面配置SSH,如下所示。 找到 SSH remote hosts 进行配置。 配置完成后,点击Check connection按钮,会显示 Successfull connection。如下所示。 至此,Jenkins的基本配置就完成了。 Jenkins发布Docker项目到K8s集群 1.调整SpringBoot项目的配置 实现,SpringBoot项目中启动类所在的模块的pom.xml需要引入打包成Docker镜像的配置,如下所示。 <properties> <docker.repostory>192.168.0.10:1180</docker.repostory> <docker.registry.name>test</docker.registry.name> <docker.image.tag>1.0.0</docker.image.tag> <docker.maven.plugin.version>1.4.10</docker.maven.plugin.version> </properties> <build> <finalName>test-starter</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>${docker.maven.plugin.version}</version> <executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <contextDirectory>${project.basedir}</contextDirectory> <useMavenSettingsForAuth>useMavenSettingsForAuth>true</useMavenSettingsForAuth> <repository>${docker.repostory}/${docker.registry.name}/${project.artifactId}</repository> <tag>${docker.image.tag}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <targetPath>${project.build.directory}/classes</targetPath> <includes> <include>**/*</include> </includes> <filtering>true</filtering> </resource> </resources> </build> 接下来,在SpringBoot启动类所在模块的根目录创建Dockerfile,内容示例如下所示。 #添加依赖环境,前提是将Java8的Docker镜像从官方镜像仓库pull下来,然后上传到自己的Harbor私有仓库中 FROM 192.168.0.10:1180/library/java:8 #指定镜像制作作者 MAINTAINER binghe #运行目录 VOLUME /tmp #将本地的文件拷贝到容器 ADD target/*jar app.jar #启动容器后自动执行的命令 ENTRYPOINT [ "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar" ] 根据实际情况,自行修改。 注意:FROM 192.168.0.10:1180/library/java:8的前提是执行如下命令。 docker pull java:8 docker tag java:8 192.168.0.10:1180/library/java:8 docker login 192.168.0.10:1180 docker push 192.168.0.10:1180/library/java:8 在SpringBoot启动类所在模块的根目录创建yaml文件,录入叫做test.yaml文件,内容如下所示。 apiVersion: apps/v1 kind: Deployment metadata: name: test-starter labels: app: test-starter spec: replicas: 1 selector: matchLabels: app: test-starter template: metadata: labels: app: test-starter spec: containers: - name: test-starter image: 192.168.0.10:1180/test/test-starter:1.0.0 ports: - containerPort: 8088 nodeSelector: clustertype: node12 --- apiVersion: v1 kind: Service metadata: name: test-starter labels: app: test-starter spec: ports: - name: http port: 8088 nodePort: 30001 type: NodePort selector: app: test-starter 2.Jenkins配置发布项目 将项目上传到SVN代码库,例如地址为svn://192.168.0.10/test 接下来,在Jenkins中配置自动发布。步骤如下所示。 点击新建Item。 在描述文本框中输入描述信息,如下所示。 接下来,配置SVN信息。 注意:配置GitLab的步骤与SVN相同,不再赘述。 定位到Jenkins的“构建模块”,使用Execute Shell来构建发布项目到K8S集群。 执行的命令依次如下所示。 #删除本地原有的镜像,不会影响Harbor仓库中的镜像 docker rmi 192.168.0.10:1180/test/test-starter:1.0.0 #使用Maven编译、构建Docker镜像,执行完成后本地Docker容器中会重新构建镜像文件 /usr/local/maven-3.6.3/bin/mvn -f ./pom.xml clean install -Dmaven.test.skip=true #登录 Harbor仓库 docker login 192.168.0.10:1180 -u binghe -p Binghe123 #上传镜像到Harbor仓库 docker push 192.168.0.10:1180/test/test-starter:1.0.0 #停止并删除K8S集群中运行的 /usr/bin/kubectl delete -f test.yaml #将Docker镜像重新发布到K8S集群 /usr/bin/kubectl apply -f test.yaml 编辑整理 冰河团队 From 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等

2022/4/16
articleCard.readMore

DevOps系列---【Jenkinsfile+Dockerfile+nginx+vue】

1.前提:一台装好的jenkins 参考:https://www.cnblogs.com/hujunwei/p/13176994.html 2.编写Dockerfile,放在项目根目录下 FROM nginx #修改名字、版本、作者 LABEL name="home-finance-web-dev" version="1.0.0" author="hjw" COPY dist/ /usr/share/nginx/html/ COPY nginx/nginx-dev.conf /etc/nginx/nginx.conf EXPOSE 80 3.编写Jenkinsfile,放在项目根目录下 //流水线脚本 pipeline { agent any environment { WS = "${WORKSPACE}" TOPIC = "测试" TITLE = "标题" CONTENT = "具体内容" } //定义流水线的加工流程 stages { stage('环境检查') { steps{ sh 'printenv' echo "正在检测基本信息" sh 'git --version' sh 'docker version' } } stage('编译') { //jenkins不配置任何环境的情况下可以兼容任何场景 agent { docker { image 'node:14.17.6-alpine3.13' } } steps{ sh 'node -v' sh 'npm -v' sh 'pwd && ls -alh' sh 'echo "默认的项目目录:${WS}"' //注意:cd ${WS} && npm不能分开写,也不能直接用${WORKSPACE} sh 'cd ${WS}/fast-ui && npm config set registry=https://registry.npm.taobao.org && npm install -g cnpm --registry=https://registry.npm.taobao.org && cnpm install && cnpm run build' } } stage('生成镜像') { steps{ sh 'pwd && ls -alh' echo '生成镜像' sh 'docker version' sh "echo 默认的项目目录:${WS}" sh 'cd ${WS}/fast-ui && docker build -t home-finance-web .' } } stage('部署') { steps{ echo '部署....' sh 'pwd && ls -alh' sh 'pwd && ls -alh' sh 'docker rm -f home-finance-web' sh 'docker run -d -p 8081:80 --restart=always --name home-finance-web home-finance-web' } } } } 4.编写nginx-dev.conf,放在项目根目录下的nginx目录下 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; # include /etc/nginx/conf.d/*.conf; server { listen 80; server_name 101.43.159.8; # 服务器地址或绑定域名 #charset koi8-r; #access_log /var/log/nginx/host.access.log main; # ========================================================= # ================== ↓↓↓↓↓↓ start ↓↓↓↓↓↓ ================== # ========================================================= location / { root /usr/share/nginx/html; #try_files $uri $uri/ @router; index index.html index.htm; try_files $uri $uri/ /index.html; # 解决页面刷新 404 问题 #proxy_pass http://zhengqingya.gitee.io; # 代理的ip地址和端口号 #proxy_connect_timeout 600; #代理的连接超时时间(单位:毫秒) #proxy_read_timeout 600; #代理的读取资源超时时间(单位:毫秒) } # ========================================================= # ================== ↑↑↑↑↑↑ end ↑↑↑↑↑↑ ================== # ========================================================= #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } 编辑整理 hujunwei 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等

2022/4/15
articleCard.readMore

项目开发管理工具推荐

软件开发是复杂的创造性的劳动,需要依赖大量工具才能完成,因此想要提高软件开发的效率和质量,离不开强大、高效、易用、维护成本低的工具,下面我根据自己的经验,推荐一些好用的工具。 即时通讯 更推荐自建开源替代。 即时通讯和会议系统是项目开发过程中必不可少的,尤其是远程办公时,会议系统更是不可或缺。企业微信拥有和微信一致的沟通体验,简单易用。企业微信可随时随地发起和参与音视频会议,支持300人同时参会,并为主持人提供了管理功能。发言时还可演示文档或电脑屏幕,支持实时标注演示内容。 官方网站:https://work.weixin.qq.com/ 项目管理 目前主流的项目管理通常采用敏捷开发的模式,因此项目管理工具也要选择支持敏捷开发模式的工具,不建议使用禅道这样的重流程的工具,不适合敏捷团队,这里我推荐Taiga,它设计简洁,操作简单,充分体现了敏捷开发的理念。 官方网站:https://taiga.io 在线体验:https://tree.taiga.io 体验版服务器在国外,访问可能会有点慢。 代码托管 前几年使用的比较多是SVN,近几年基本都使用GIT了,开源项目大都使用Github,虽然免费,但国内访问不稳定,速度慢,因此国内的公司基本都会自己搭建,我先后为公司搭建过两个托管平台,一个是Gitlab,一个是Gitea,Gitlab功能比较全面,但对硬件资源要求比较高,而且性能一般。所以推荐使用另一个开源的git托管平台——Gitea。 官方网站:https://gitea.io 在线体验:https://gitea.com 持续交付 最知名、使用最广泛的开源的持续集成、交付平台当属Jenkins,主要的优势在于有大量免费的插件可以使用,但实际使用发现,很多插件质量很差,配置项很多,真正想要落地,其实需要自己编写shell脚本。这里我推荐基于docker技术的一款现代化的持续交付平台DroneCI,它使用简单,可以和主流的Git代码托管平台无缝对接,并且不需要编写代码就可以满足大多数持续构建、交付的需求。 官方网站:https://drone.io 在线体验:https://cloud.drone.io 体验版服务器在国外,访问可能会有点慢。 制品库(本地仓库) Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。 后来,除了Maven仓库,还有npm、nuget、pypi、docker等仓库也需要本地仓库。 市面上可选的通用的本地仓库有:nexus、ARTIFACTORY,ARTIFACTORY是收费的,nexus是免费的,同时nexus以其易用性和可靠性,成为目前市场上最主流的本地仓库。 官方网站:https://www.sonatype.com/product-nexus-repository 文件存储 在公司中,文件分享是一个很常用的功能,不同于云盘,他对性能和安全性没有那么高的要求,简单易用才是大家最关心的,这里推荐chfs,chfs是一个免费的、HTTP协议的文件共享服务器,使用浏览器可以快速访问。与其他常用文件共享方式(如FTP,飞秋,网盘,自己建站)相比,具有使用简单,适用场景更多的优点,在个人使用以及共享给他人的场景中非常方便快捷。 官方网站:http://iscute.cn/chfs 绘图(流程图、UML、思维导图) draw.io 是一个强大简洁的在线的绘图网站,支持流程图,UML图,架构图,原型图等。支持Github,Google Drive, One drive等网盘同步,并且永久免费。如果觉得使用Web版不方便,draw.io 也提供了多平台的离线桌面版可供下载。 在线版:https://www.draw.io 本地部署版:https://github.com/jgraph/drawio/releases/latest PC 安装版:https://github.com/jgraph/drawio-desktop/releases/latest 接口管理 维护不同工具之间数据一致性非常困难、低效。并且这里不仅仅是工作量的问题,更大的问题是多个系统之间数据不一致,导致协作低效、频繁出问题,开发测试人员痛苦不堪。 Apifox 是接口管理、开发、测试全流程集成工具,定位 Postman + Swagger + Mock + JMeter。通过一套系统、一份数据,解决多个系统之间的数据同步问题。只要定义好接口文档,接口调试、数据 Mock、接口测试就可以直接使用,无需再次定义;接口文档和接口开发调试使用同一个工具,接口调试完成后即可保证和接口文档定义完全一致。高效、及时、准确! 官方网站:https://www.apifox.cn 安全测试 在今天,网站的安全是容易被忽视的,黑客具备广泛的攻击手段,例如SQL注入,XSS,文件包含,目录遍历,参数篡改,认证攻击等,虽然你配置了正确的防火墙和WAF,但是这些安全防御软件仍然存在策略性的绕过。因此,需要您定期的扫描你的web应用,但是手动检测你所有的web应用是否存在安全漏洞比较复杂和费时,所以您需要一款自动化的web漏洞扫描工具来检测您的web应用是否存在安全漏洞。 Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的Web网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞。 官方网站:https://www.acunetix.com 性能测试 Locust是一个用于可扩展的,分布式的,性能测试的,开源的,用Python编写框架/工具,它非常容易使用,也非常好学。 它的主要思想就是模拟一群用户将访问你的网站。每个用户的行为由你编写的python代码定义,同时可以从Web界面中实时观察到用户的行为。 Locust完全是事件驱动的,因此在单台机器上能够支持几千并发用户访问。 与其它许多基于事件的应用相比,Locust并不使用回调,而是使用gevent,而gevent是基于协程的,可以用同步的方式来编写异步执行的代码。 官方网站:https://www.locust.io 代码静态分析平台 SonarQube 是一款用于代码质量管理的开源工具,它主要用于管理源代码的质量。 通过插件形式,可以支持众多计算机语言,比如 java, C#, go,C/C++, PL/SQL, Cobol, JavaScrip, Groovy 等。sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具来检测你的代码,帮助你发现代码的漏洞,Bug,异味等信息。 Sonar 不仅提供了对 IDE 的支持,可以在 Eclipse和 IntelliJ IDEA 这些工具里联机查看结果;同时 Sonar 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用 Sonar 官方网站:https://www.sonarqube.org 系列教程 全部文章RSS订阅 Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等

2022/4/15
articleCard.readMore

健身从基础常识到实践指导!

有哪些相见恨晚的运动常识?接下来将从分别从基础概念、减肥、腹肌,训练,实操几个方面去分享。 本文修订增补中! 健康是需要维护的,健身至少需要三个月才能从外表看到明显的区别!但是如果不继续锻炼,三个月就会恢复原本的外表,只是下次锻炼,会更快的出效果。 健身,需要花费大量的时间、金钱,持续的高蛋白饮食,充足的睡眠,科学的持续的三个月以上的锻炼,才能看到效果! 健身是一项没钱没闲别进来的运动! 基本概念 01. RM RM是英文"repetition maximum"的缩写,中文意义是"最大重复值"。以8RM为例,意思是,某个重量你最多完成8次。一般而言1~6RM侧重锻炼力量,8~12RM侧重锻炼肌肉围度,15RM以上侧重锻炼肌肉耐力。 02 升糖指数 升糖指数全称为“血糖生成指数”,简称,它反映了某种食物与葡萄糖相比升高血糖的速度和能力。是反映通过进食引起人体血糖升高程度的指标,高gi为70以上,中gi为55~70,低gi为55以下。 03 马甲线、人鱼线和腹肌 图一是人鱼线,是在髋关节上侧,图二是马甲线,通常是腹直肌两侧两到往下的线,图三是常说的腹肌,其实只是腹直肌,是肚脐眼两侧的腹部肌肉。 04 BMI 身体质量指数 (Body Mass Index, 简称BMI), 亦叫做克托莱指数, 是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。计算公式为:BMI=体重(千克)除以身高(米)的平方。 05 心率 心率是指正常人安静状态下每分钟心跳的次数,也叫安静心率,一般为60~100次/分,最大心率通常用220-年龄来计算率。运动时心率达到90%~95%的最大心率,此时供能物质主要为糖原,而心率大致在45%~60%的最大心率,此时供能物质主要是脂肪和糖原。而我们常说的减脂心率为65%~80%的最大心率。 06 有氧运动和无氧运动的区别 一张图给你解释清楚 07 减肥 减肥字面上的意思是减去肥肉,也就是脂肪,看的是体脂率,而不是体重,体重包括了肌肉、肥肉、水。因此体重下降不等于减肥成功。 08 蛋白粉 蛋白粉不是药,不是谁吃了都能变成施瓦辛格,蛋白粉也没什么神奇配方,基本上可以理解为瘦肉粉加水面粉,而且普通人不需要蛋白粉,蛋白粉是用于日常营养摄入不足才补充的。 09 减肥原理 减肥的原理是实现热量差,摄入的要低于消耗的,不管你是什么方式减肥,脱离了这个原则,都不要相信,因此在别人给你介绍减肥方法的时候,先想清楚,这个方法是怎样增加热量消耗或者减少热量摄入的。 10 增肌 增肌需要三个方面,首先是需要不断给肌肉新的刺激,也就是“渐进超负荷原则”,在训练完后则需要高蛋白高碳水的饮食和48~72小时的恢复时间让肌肉实现超量恢复。训练、饮食、休息,三者缺一不可。 11 三大供能系统 第一个是磷酸原系统,主要在运动开始后6秒内进行供能,在短时间高强度运动中,磷酸原系统是主要的供能系统。 第二是糖酵解系统,主要在运动开始后6秒~2分钟内为身体供能,在中高强度的运动中主要由糖酵解系统参与。而糖酵解系统分为快速糖酵解和慢速糖酵解。 第三是有氧氧化系统,主要在运动开始后2分钟内由糖、碳水化合物、脂肪和蛋白质氧化为身体进行供能,它需要大量的氧气参与。有氧系统的强度最低。 当然需要注意的是,这三者运动开始都会工作,区别是供能比例不同。 12 基础代谢 减脂的人都会经常听到基础代谢这个词,基础代谢是指人体维持生命的所有器官所需要的最低能量需要,也就是你啥也不干,都得消耗的热量。测定方法是在人体在清醒而又极端安静的状态下,不受肌肉活动、环境温度、食物及精神紧张等影响时的能量代谢率。 代谢指数和年龄相关,要健身,需要增加代谢指数。 13 超级组 超级组训练是指练完一组训练动作后尽可能没有休息地做另外一组主动肌与前一组训练的主动肌相反方向用力的训练。这种训练方式可以在最短时间内刺激更多肌肉群,强度非常大。 14 金字塔训练 做某一个动作时,逐渐增加或减少每组的重量,相应减少或增加每组的重复次数,直到重量加到预先安排训练目标,比如15 RM、12 RM、10 RM、 8RM。 再比如徒手耐力训练,以做俯卧撑最高次数组为10,那么第1组1个,第2组2个,直到第10组10个,11组9个,12组8个,倒回去做到第19组1个完成训练,总计100个。 15 HIIT 高强度间歇性训练(HIIT),是一种让你在短时间内进行全力、快速、爆发式锻炼的一种训练方式。这种技术让你在短期内心率提高并且燃烧更多热量。运动时,心率要控制在最大心率的84%以上,中间间歇时心率不要低于70%。这就使得HIIT不适合没训练经验的人,毕竟强度太大,跟不上。 16 开窗理论 开窗理论指的是大强度运动时,淋巴细胞浓度降低,增值分化及活动降低,免疫球蛋白含量及功能也受到影响,出现免疫低下期。据研究,受一次性急性运动的影响,免疫地下其可持续3~7小时不等。在这一免疫低下期,各种细菌、病毒等病原体极易入侵人体,最常见的就是高强度训练后出现感冒。 17 核心力量 目前主流的观点认为,核心指的是腰椎到骨盆这个整体,核心也分为内核心和外核心。而核心力量最重要的作用就是稳定,我们的日常活动都需要核心力量。 心率控制 作为一个专业健身锻炼者,需要知道并有意识的控制自己健身时的心率! 一、心率与运动强度的核心关系 心率是运动强度的“晴雨表” 最大心率估算公式:HRmax = 220 - 年龄(通用公式,实际个体差异可达±15次/分)。 更精准的HRmax测定:通过热身后全力运动20分钟的平均心率×0.95计算。 不同心率区间对应不同供能系统 50%-70% HRmax:以脂肪供能为主,适合减脂和初学者。 70%-85% HRmax:糖原和脂肪混合供能,提升心肺耐力。 85%以上 HRmax:无氧代谢主导,增强爆发力但易疲劳。 二、如何科学控制运动心率? (一)监测方法 设备监测 使用心率带或智能手表(如医疗级臂带传感器,误差更小)。 团体课程可借助实时心率监测系统,同步显示多人数据。 手动测量 暂停运动,按压颈动脉或桡动脉15秒,乘以4得实时心率。 (二)强度调整策略 循序渐进 初学者从60% HRmax开始,每周强度增幅不超过10%。 例如:40岁学员,HRmax=180次/分,初始目标心率设为108-126次/分(60%-70%)。 结合主观感受(RPE量表) 中等强度:呼吸急促但能说话,无法唱歌(RPE 12-14分)。 高强度:仅能说短句,明显出汗(RPE 15-17分)。 特殊人群注意事项 三高或心脏病患者需采用更保守公式:目标心率 = 晨脉×1.4~1.8。 服用降压药者需咨询医生,因药物可能降低最大心率。 三、不同健身目标的心率区间建议 目标 心率区间(%HRmax) 持续时间 适用运动类型 注意事项 减脂 60%-75% 30分钟以上 快走、慢跑、游泳 需配合饮食,心率过低无效 提升心肺耐力 70%-85% 20-45分钟 骑行、有氧操 每周3-5次,避免过度疲劳 增强无氧能力 85%-95% 30秒-2分钟/组 冲刺跑、HIIT 组间充分休息,每周≤2次 康复/初学者 50%-60% 15-30分钟 散步、瑜伽 监测晨脉,避免晨脉升高时训练 四、常见误区与教练建议 误区纠正 “减脂心率必须140次/分”:实际因人而异,30岁人群可能需150次/分才有效。 “出汗多=效果好”:高强度出汗可能源于脱水,而非脂肪消耗。 个性化设计 使用储备心率法更精准: 目标心率 = (HRmax - 静息心率) × 强度% + 静息心率 例如:静息心率60次/分,目标强度70% → (180-60)×0.7+60=144次/分。 科技辅助 推荐使用自学习式健身系统,根据实时心率自动调整训练计划。 小结 控制心率的关键是**“量体裁衣”**: 减脂人群:坚持60%-75% HRmax的中低强度有氧,每周累计150分钟以上。 增肌/耐力训练者:穿插中高强度间歇,刺激心肺阈值。 安全第一:运动中出现头晕、胸痛需立即停止,并就医排查。 科学的健身计划,需要根据年龄、静息心率和健身目标,进一步优化方案! 运动类型 常见锻炼形式可以发分为三类 ——GPT3.5 生成 特征 有氧运动 无氧运动 HIIT 定义 通过有氧代谢产生能量的运动,如跑步、游泳、骑自行车等 依靠无氧代谢产生能量的高强度运动,如重量训练、举重等 结合高强度爆发性运动和休息间隔的训练模式 能量系统 主要使用有氧代谢产生能量 主要使用无氧代谢产生能量 结合有氧和无氧能量系统 时间 通常持续较长,如30分钟以上 较短,如高强度训练一组通常在1分钟以内 短暂且高强度,如20-30分钟 强度 中等到低强度 高强度 高强度 举例 慢跑、游泳、骑自行车 重量训练、举重 跳绳、冲刺、体操 心血管效益 提高心肺健康,降低心脏病和中风风险 有限,但可增强肌肉力量和耐力 提高心血管健康,类似有氧运动但时间更短 脂肪燃烧效果 有助于脂肪燃烧,但需要持续时间较长 较少,但在训练后会产生后续的燃烧效果 高强度间歇性运动被认为可以提高脂肪燃烧效果 肌肉效益 有限,但有助于提高耐力和心肺功能 提高肌肉力量和耐力,有助于肌肉增长 有限,但通过提高耐力和爆发力间接增强肌肉 适用人群 适用于想要增强心肺健康和耐力的人群 适用于想要增强肌肉力量和体型的人群 适用于想要在短时间内获得全面锻炼的人群 心率百分比 60-80% 70-90% 80-95% 年龄 适用于各个年龄段 适用于各个年龄段 适用于各个年龄段 生长激素 增加代谢速度、有助于燃烧脂肪 促进肌肉生长、恢复和修复 有助于提高脂肪燃烧和肌肉增长 皮质醇 帮助应对压力,但过量可能对健康有害 通过提高皮质醇水平帮助应对训练中的压力 有助于应对训练中的高压力情况 减肥篇 01 流汗多不等于减肥 运动时你流汗多和减肥没有直接关系,减肥减的是脂肪,流汗虽然有助于排除废物,但终归是水,只要你正常饮水,体重就会回去的。 因此,所谓的爆汗服或者在身上裹上保鲜膜减肥,都是在骗自己。 02 青汁不是用来减肥的 从青汁的配料来看,它其实就是一堆草叶子,或者蔬菜叶子,磨成粉,再泡水喝。而且青汁本身是给日本人喝的,毕竟他们那里蔬菜水果缺乏还特别贵,日常生活缺乏维生素和膳食纤维,说白了青汁就是给日常蔬菜摄入不足的日本人补充膳食纤维平衡一下营养。 至于那些所谓的减肥功效什么的,或者其他类似的产品,基本都是商家的过度营销宣传。 03 新手尽量不要空腹做有氧运动 虽然说空腹有氧对于脂肪消耗的有利的,尤其是空腹晨跑,但是,在空腹状态下身体中的血糖水平会比较低,就有可能出现低血糖,这可是很危险的。新手的话建议在训练前半小时左右适当吃一些全麦面包等低GI碳水,防止训练中的低血糖。 04 变肥不是因为吃肉 就我们中国人的饮食习惯来说,其实大部分是主食吃多的,比如米饭,馒头,面条这些,热量高,饱腹感低。而肉类,只要不是肥肉,减脂期间吃了不仅能帮助身体维持基础代谢,而且肉类的饱腹感比主食还高。 05 低gi饮食更减顽固脂肪 常见的顽固脂肪有肚子,大腿,臀部,这些部位的肥肉受胰岛素影响大,而血糖升高又会导致胰岛素分泌增加,而碳水化合物的升糖指数通常比较高。因此想减少顽固脂肪,主食还需要多吃低升糖指数(gi)的五谷杂粮。 06 只要你运动就在消耗脂肪 不要认为只有有氧运动才能减肥,只要你在运动,脂肪和糖都在消耗,区别只是比例不同,因此你即使是力量训练,脂肪也在燃烧。 07 先力量训练后有氧减肥效率更高 力量训练主要消耗糖,而有氧系统包括糖,脂肪,蛋白质,先用力量训练消耗掉糖,再用有氧消耗脂肪,这样有氧效率就会得到提高。 08 没有局部减脂 运动时全身的脂肪是同步分解的,不存在局部脂肪分解给局部肌肉供能的情况。这就好比,你能只抽空泳池一个角的水吗?因此如果你见到网上教你某个动作瘦小腿,某个动作瘦肚子,你可以直接不理他。 09 没有负热量食物 食物吃进去都有食物热效应,也就是进去的时候,消化食物你需要消耗的能量,那如果你摄入的热量还没有消化食物用得多,那人岂不是越吃越瘦,吃到最后身体都没能量日常活动了。而吃东西最起码的需要满足活下去这个要求,既然热量都负了,那人咋活下来的? 腹肌篇 01 胖子的胸肌和瘦子的腹肌一样毫无意义 虽然说体脂率是腹肌的关键因素,但是如果你从来没练过腹肌,即使你再瘦,腹肌也不可能变得饱满,结实。而胖子的胸都是脂肪,并不是肌肉,光是好吃懒做就能有的。 02 光练腹肌也是不行的 结合上一条,腹肌要明显的两大因素,体脂率和腹肌围度,也就是说减脂和训练都需要,你光练也不行,就拿健美选手来说,腹肌围度够大了吧,非赛季一样看不到腹肌。 03 仰卧起坐练不出腹肌 虽然体育老师都说,仰卧起坐是练腹肌的,但实际上这是错误的,标准仰卧起坐腰背部是挺直的,腹肌长度没有变化,仰卧起坐主要在做屈髋,而不是卷曲腰部,因此仰卧起坐是练核心和屈髋肌肉的。 04 腹肌不代表核心力量强 前面提到了,腹肌明不明显主要和腹肌训练以及体脂率有关,比如大力士选手的核心力量,足够强悍了吧,但是他们也看不到腹肌,核心力量包括腰腹部、髋关节这一个整体的,腹肌只是属于核心肌肉的一部分。 05 腹肌是天生的 腹肌是否对称是肌划决定的,而肌划是由基因决定的,也就是你出生是几块就是几块,出生不对称,那么这辈子都不对称。任何说帮你矫正不对称腹肌的都是骗子。 腹肌是否显现,最重要的是体脂率,体脂率低于一定数值,就可以看到一些腹肌。腹肌不需要专门锻炼,在其它锻炼过程中掺杂锻炼就够了! 训练篇 01 健身不需要天天练 许多人认为多练就一定是好的,不能休息,但实际上,不管是肌肉力量,还是肌肉围度,都是需要休息的,正常来说,我们运动后身体的力量水平会下降,然后在休息的时候慢慢恢复,如果休息和营养补充得好,就会超量恢复,超过之前的水平,短期恢复需要24~72小时。 正常来说,一周起码给自己休息一天。 02 热身不限于跑步 虽然说跑步是最简单的热身方式,但跑跑步,压压腿是远远不够的,正常来说,热身需要分为三部分,首先是关节热身,然后是动态热身体(开合跳,跑步这类),然后则是针对训练内容的热身,比如要练卧推,可以先做做空杠卧推,俯卧撑之类的。 03 不要盲目追求大重量 虽然说重量越大,训练的刺激越大,但是对于身体来说,受伤风险也越大,新手最好还是把训练的重点放在学会动作,把动作做标准。 06 跑步不会腿粗 一些女生在跑完步后,感觉腿部比之前更粗了,那是因为你本身训练少,而且此时肌肉充血,只需要多拉伸放松即可,慢跑是不会让腿变粗的,反而你看马拉松运动员,腿个个都很细。 05 训练不要追求酸痛 训练过后的酸痛越明显说明练得越到位,这是典型的误区,如果你只是第二天的酸痛还是正常的,如果是训练后隔天才开始酸痛,那很可能就是延迟性酸痛,这会导致身体抵抗力的下降,容易生病。而且正常的力量训练只要强度不是非常高也可以不酸痛。 06 女生练肌肉不会变成金刚芭比 如果有关注一些健身女网红你就会发现,其实好多人练了5年,6年,其实也没有多少围度,体重也是100来斤,而且长肌肉需要雄性激素,而女性的雄性激素很低,即使是正常男性,练个三四年也不一定能练成健美选手。 对于女生而言,肌肉训练更多的是塑形。 很多人怕练畸形了,但事实是,没有大重量锻炼几年,休想练畸形!一些无量教练以此威胁不买课的! 07 脂肪不能转化成肌肉 肌肉和脂肪是不会相互转化的,它们原本就是两种不同的组织,肌肉是人生下来就有的,有些小伙伴摸着自己肉肉的,觉得全身肥肉,事实上是那是因为你脂肪太多,遮住肌肉了。肌肉长期不锻炼,是会退化松弛的,而不是直接转化为脂肪。 也就是说,一些认为的瘦子想长肉,就得先吃胖,再练,其实是错误的,健身并不能把肥肉变成肌肉。 08 深蹲膝盖可以超脚尖 深蹲膝盖不是绝对不能超过脚尖的,这和每个人的身体结构相关,练臀基本都会刺激到腿的,绝对不粗腿的臀部训练是基本做不到。 09 健身不会吸引女孩子 当你练 得越久,你会发现,你身边的肌肉男越来越多,女的越来越少。 但是,有人把男人健身和女性美甲类比,这就过分了。健身要看到效果,至少不要3个月集中锻炼,每周3次以上,每次至少一个小时,科学的吃,锻炼,休息,健身房投入几百个小时,几个W的金钱才能看到效果。而美甲,2个小时,几百块就够了! 实操篇 健身是需要持续投入,长期坚持,自我折磨的。没有坚强的意志力根本坚持不下来,说白了,就是自虐!还要,长期的、有计划的,持续性的自虐,才能有效果!这是意志,与体力,与耐力的抗争。 有不少健身App,可以跟着学,比大多数私教专业。 1 逆呼吸法 所谓顺腹式呼吸法是指吸气时让腹部凸起,吐气时压缩腹部使之凹入的呼吸法。 而逆腹式呼吸方法则相反:吸气时腹部凹进,而呼气时腹部突出。 健身大多采用逆呼吸法。 2 发力技巧 健身大多采用逆呼吸法。配合发力技巧,一般肢体远离躯干时,吐气,发力,肢体靠近驱赶时,吸气,不主动发力(被动发力)。 3 肌肉充血 健身要想有效果,要集中锻炼某一个部位,达到感觉肌肉明显充血,发烫的感觉! 一般来说,一个部位至少锻炼4组,每组12个,增肌是大重量rm递减。减肥是小重量,rm 15以上。 4 锻炼,营养,和休息 三分练,七分吃。健身营养一定要补充好。 6:2:2 碳水,蛋白质,脂肪。 两分锻炼,三分营养,五分休息!要想看到锻炼效果,营养和休息非常重要! 没有三个月集中锻炼,你几乎看不到效果,但有三个月大强度锻炼之后,旁边人能明显感觉你的不同!健身没法速成! 补剂: 谷氨酸:可以帮助恢复肌肉酸痛。 蛋白粉:补充蛋白质,大多数人日常饮食蛋白质摄入量不足以满足健身要求! 5 穷文富武 没钱没闲没法健身!真的! 每周三次2小时空闲锻炼时间,大量补充蛋白质,充足的睡眠时间。普通人真的很难负担得起。 6 日常锻炼 专门锻炼难以抽取时间,但是日常办公的椅子上,就可以做不少锻炼动作的。工作空闲时间,可以稍加锻炼,比完全不做锻炼,素质要强上百倍! 7 简单训练计划 一个简单的每周5次健身计划,如下: 肱二头肌,背 胸,腿 背,肱二头肌 腿,肩 胸,肱三头肌 每个部位至少4组,增肌每组12个,减少到8个,力竭为止。减肥15个以上,小重量。 每次健身力量锻炼越45分钟到一小时,前后5到10分钟跑步,热身和放松。 锻炼完,肌肉拉伸放松,帮助恢复疲劳! 锻炼中可以补充水分和蛋白质,带上蛋白粉饮品。少量,多次,不要一次大量喝水! 练腿非常重要,特别是对于增肌来说。可以促睾,提高体内睾酮激素水平。对于想增肌来说,是必不可少的。 8 心率 控制 健康且体质较好的,心跳可以控制在120~180次/每分钟。 中老年或慢性病人群,心跳可以控制在(170 - 年龄)~(180 - 年龄)之间。 最大心率 = 220 - 实际年龄。 燃脂区: 慢跑时,控制心率在最大心率的60%~ 70%。 健身要有效果,需要三个基本指标: 持续20分钟以上 心率120次/分钟以上(青年) 频率一周3~4次 9 代谢指数控制 代谢指数和体重和肌肉含量高相关,还和年龄有关,减肥就是要增加代谢指数,有氧运动最有效。 10 理论指导 不管实际锻炼,丰富你的理论知识,同样非常重要!可以达到事半功倍的效果,没有理论指导,就事倍功半了! 大量健身教练非常不专业,都是业余的。可能还没你看几篇文章理论知识丰富。 11 健身装备 运动手套,健身服,吸汗毛巾,水杯等等。一些必要的投入是必须的。 12 关于做C 这是个专业用语,指打激素等药物,打了药物之后还要加强锻炼,才能看到明显效果。 这个效果非常显著!正常锻炼几年的效果,药物几个月半年就可以达到。但是对身体伤害非常大!每年你都能在新闻上看到好几个用药的突然死亡的新闻! 普通人不要做! 徒手健身 胸肌————俯卧撑 胸厚————臂屈伸 背阔肌————普通引体向上 倒三角————宽距引体向上 二头肌————窄距俯卧撑 腹肌————卷腹 核心力量————举腿 肩宽————折刀俯卧撑 腿部爆发力————蹲跳 腿瘦————拉伸 腹部脂肪 提膝击掌 单侧提膝 抬腿击膝 开合跳 另一种 胯下击掌 单侧提膝 提膝下压 深蹲 图解健身 一、热身准备(5-8分钟) 动态拉伸 - 肩部绕环:前后各15次,活动肩袖肌群。 - 猫牛式:脊柱逐节屈伸,10次,激活核心。 - 弹力带高位下拉:模拟背肌发力,15次×2组。 二、正式训练(30-40分钟) 引体向上(或辅助引体) 目标肌群:背阔肌、肱二头肌 动作要领:双手握距略宽于肩,核心收紧,肘部后拉带动身体上提,下巴过杠后缓慢下放。 组数:新手辅助器械或弹力带辅助,4组×8-12次;进阶者负重(如挂哑铃),4组×6-10次。 杠铃划船 目标肌群:斜方肌中下束、菱形肌 动作要领:双脚与肩同宽,俯身至躯干与地面约45°,杠铃贴近小腿拉起至腹部,肘部向后上发力,下放时保持背部紧张。 组数:4组×10-12次,重量选择能控制动作的负荷。 单臂哑铃划船 目标肌群:单侧背部深层肌群 动作要领:单膝跪于长凳,对侧手扶凳面,另一只手握住哑铃,垂直上拉至肘部高于躯干,下放时缓慢控制。 组数:左右各4组×10-12次。 高位下拉 目标肌群:背阔肌、大圆肌 动作要领:调整座椅高度,双手宽握杆,下拉至锁骨位置,肘部向两侧打开,避免耸肩借力。 组数:4组×12-15次。 坐姿绳索面拉 目标肌群:肩袖肌群、斜方肌后束 动作要领:掌心朝前握住绳索把手,向两侧打开手臂至与肩平,收缩肩胛骨,重点感受背部外侧发力。组数:3组×15-20次。 三、放松与拉伸(5-8分钟) 泡沫轴放松:滚动背部肌肉,重点放松竖脊肌、背阔肌,每侧30秒。 静态拉伸: - 坐姿体前屈:拉伸背部整体,保持30秒。 - 蝴蝶式拉伸:双手抱头,手肘向后展开,感受背部扩张,30秒。 注意事项 动作质量优先:宁可降低重量,也要确保发力集中在背部,避免手臂或腰部代偿。 呼吸节奏:发力时呼气(如引体向上拉起时),还原时吸气。 循序渐进:新手从低组数、轻重量开始,逐渐增加强度。 训练频率:背肌训练建议每周1-2次,留出48-72小时恢复时间。 根据自身能力灵活调整动作和组数,长期坚持,配合合理饮食和休息,背部线条与力量会逐步提升! 常用健身肌肉解剖 文章参考人体解剖学(修订版) 黄慧贞编着 这部分会比较冗长,但对于健身来说,有时可能会需要一些知识来提升相关讯息比较好,我从网路上整理常用的肌肉解剖让大家概略知道自己练了哪些肌肉。欢迎有兴趣的健身朋友们看看。 三大类槓桿 註:F=支点,R=重量(阻力),E=作用力 左边第一张为第一类槓桿往右为第二类槓桿,以此类推。举例如下 第一类槓桿 抬头动作 支点:枕寰关节 阻力:头颅之颜面被移动的重力 作用力:背部肌肉的收缩 第二类槓桿 垫脚尖 支点:脚趾基部的肉 阻力:身体的重量 作用力:小腿肌肉的收缩 第三类槓桿 前臂举重物 支点:肘关节 阻力:前臂加手中物体的重量 作用力:肱二头肌的收缩 正面肌肉 胸大肌 描述:为一大扇形覆盖上胸的肌肉 作用:负责上臂内收、内旋、屈伸 神经支配:胸内、外神经 起端:锁骨、胸骨、第1~6节肋软骨 止端:肱骨之大结节 胸小肌 描述:为一薄平位于胸大肌下方的肌肉 作用:下压肩胛骨;当肩胛骨稳定时可将肋骨往上提 神经支配:胸内神经 起端:第3~5肋骨的前面 止端:肩胛骨之喙突 前鉅肌 描述:位于胸肌之下,胸廓之外侧且形成腋窝之内侧壁,因像锯齿而命名 作用:固定及旋转肩胛骨、上提肋骨 神经支配:胸长神经 起端:第1~8肋骨 止端:肩胛骨之内侧缘 腹直肌 描述:为表层内侧之成对肌肉,被外侧肌肉之腱膜披覆,且其之间经由腱划予以分开 作用:屈伸及旋转腰椎、固定及往下压肋骨、提供走路时稳定骨盆及增加腹内压等 神经支配:肋间神经(T7~T12) 起端:耻骨嵴及耻骨联合 止端:剑突及第5~7肋软骨 腹外斜肌 描述:为腹外侧三层肌肉中最薄的表层肌肉,其肌纤维的走向为往下内侧,其腱膜往下形成腹股沟韧带 作用:当其成对收缩时,协助腹直肌屈伸腰椎及增肌腹压,若单侧肌肉收缩则协助背部躯干之肌肉旋转及嵴柱向外侧弯曲。 神经支配:肋间神经(T7~T12) 起端:第5~12肋骨 止端:髂嵴及白线 三角肌 描述:为一厚、多重羽状围绕肩膀的主要肌肉,亦为肌肉注射的位置之一 作用:锁骨端之部分主要屈伸及内旋上臂,肩峰端为外展上臂,而肩胛棘端则为伸展及外旋上臂 神经支配:腋神经 起端:锁骨的外侧1/3肩胛骨之肩峰及肩胛棘 止端:肱骨之三角粗隆 肱三头肌 描述:为上臂后方唯一肌肉,其有三个起始点分别称长头、内侧头、外侧头 作用:内侧头为前臂强而有力之原动肌,长头侧为协助稳定肩关节及上臂之内收 神经支配:桡神经 起端:《长头》肩胛骨之盂下结节,《外侧头》肱骨后侧桡神经沟之上,《内侧头》肱骨后侧桡神经沟以下 止端:尺骨之鹰嘴突 肘肌 描述:唯一短的三角形肌肉,紧接肱骨后侧肱三头肌之末端 作用:当前臂进行旋前动作时,其负责尺骨之外展;与肱三头肌相互协同于肘关节伸展 神经支配:桡神经 起端:肱骨之外上髁 止端:尺骨鹰嘴突外侧 肱二头肌 描述:有长头、短头,其中长头协助肩关节稳定 作用:屈曲上臂(肘关节)及旋后前臂 神经支配:肌皮神经 始端:《长头》肩胛骨之盂上结节,《短头》肩胛骨之喙突 止端:桡骨粗隆,与肱二头肌腱膜 肱肌 描述:为深入肱二头肌内之肌肉 作用:为前臂主要屈曲之肌肉 神经支配:肌皮神经 起端:肱骨前面下半部 止端:尺骨冠状突与粗隆 肱桡肌 描述:为前臂外侧之浅层肌,形成肘窝外侧缘 作用:屈曲前臂 神经支配:桡神经 起端:肱骨外侧髁上嵴 止端:桡骨之茎突 缝匠肌 描述:为身体最长的肌肉,亦为一斜走之肌肉越过大腿前侧至膝部,故其跨过髋关节及膝关节 作用:大腿屈曲、外旋、小腿屈曲,如同翘二郎腿的姿势 神经支配:股神经 起端:髁前上棘 止端:近端胫骨内侧 内收大肌 描述:由内收肌之一部分与大腿后侧肌肉所组成的三角形肌肉 作用:前侧负责大腿内收,外侧负责大腿屈曲及外旋,后侧则与大腿后侧肌肉相互协同大腿伸展之动作 神经支配:闭孔神经与坐骨神经 起端:坐骨与耻骨枝、坐骨粗隆 止端:股骨之粗线 内收长肌 描述:覆盖内收大肌中间部分 作用:大腿之内收、屈曲、外旋 支配神经:闭孔神经 起端:近耻骨联合处 止端:股骨之粗线 内收短肌 描述:与闭孔外肌相邻且绝大部分为内收长肌及耻骨肌所覆盖 作用:大腿的内收 神经支配:闭孔神经 起端:耻骨体及下枝 止端:股骨之粗线 股直肌 描述:大腿前侧浅层肌肉,其肌纤维为一直往膝部之走向,且为股四头肌中唯一越过髋关节的肌肉 作用:屈曲大腿(髋关节)及伸展小腿(膝关节) 神经支配:股神经 起端:髂前下棘及髁臼之上缘 止端:附着于髌骨上而后经由膝韧带终止于胫骨粗隆 胫前肌 描述:为小腿前方浅层肌肉,其外与胫骨之尖锐边缘平行 作用:足背之屈曲及内翻 神经支配:腓深神经 起端:胫骨外髁、胫骨上2/3及骨间膜 止端:第1楔状骨内侧及第1跖骨底 背面肌肉 斜方肌 描述:为后胸部最表层的三角形肌肉,其上方之肌纤维走向往下,中间肌纤维走向为水平,下方肌纤维走向往上 作用:稳定、上提、缩回、及旋转肩胛骨,其上方肌纤维主要负责上提肩胛骨或伸展头部;中间肌纤维为缩回肩胛骨;下方肌纤维为下压肩胛骨 神经支配:嵴副神经及第3~4颈嵴神经 起端:枕骨、顶韧带及第7颈椎至第12胸椎(C7~T12)之棘突 止端:肩胛骨之肩峰、肩胛棘及锁骨之外侧2/3 肩胛提肌 描述:为一厚且似带状的肌肉,其位于后颈部且深入斜方肌之下 作用:上提肩胛骨 神经支配:肩胛背神经 起端:第14颈锥(C1C4)之横突 止端:肩胛骨内侧缘上部 菱形肌 描述:为2块四边形的肌肉,深入于斜方肌且位于肩胛提肌的下方,其肌纤维自嵴椎往肩胛骨方向延伸,小菱形肌位于上方,大菱形肌位于下方 作用:内收及稳定肩胛骨 神经支配:肩胛背神经 起端:《小菱形肌》第7颈椎至第1胸椎(C7T1)之棘突;《大菱形肌》第25胸椎(T2~T5)之棘突 止端:肩胛骨之内侧缘 背阔肌 描述:为下背部一宽、平且呈三角形之肌肉 作用:伸展、内收、内旋上臂、将肩胛骨向下、后拉 神经支配:胸背神经 起端:第612胸椎(T6T12)、腰椎、髂嵴 止端:肱骨之结节间沟 肩胛下肌 描述:形成腋窝之后壁 作用:稳定肩关节、内收及内旋上臂 神经支配:肩胛下神经 起端:肩胛下窝 止端:肱骨之小结节 小圆肌 描述:位于棘下肌之下的一小长条形的肌肉 作用:外旋上臂、稳定肩胛骨 神经支配:腋神经 起端:肩胛骨背侧之外缘 止端:肱骨之大结节 大圆肌 描述:为一厚圆且位于小圆肌之下的肌肉 作用:伸展、内收、内旋上臂,背阔肌为其协同肌 神经支配:肩胛下神经 起端:肩胛骨之下角 止端:肱骨之小结节 臀大肌 描述:为臀部最大且深层的肌肉 作用:大腿之伸展及外旋 神经支配:臀下神经 起端:背侧髂骨、荐骨及尾骨 止端:股骨之臀肌粗隆及髂胫束 臀中肌 描述:大部分为臀大肌所覆盖 作用:大腿外展、内旋、稳定骨盆且其为走路时相当重要的一条肌肉 神经支配:臀上神经 起端:髂骨外侧之前臀及后臀中线之间 止端:股骨大转子之外侧 臀小肌 描述:为臀部最小且最内侧的肌肉 作用:与臀中肌相同 神经支配:臀上神经 起端:髂骨表面之前臀线与下臀线之间 止端:股骨大转子之前缘 股方肌 描述:为一短、厚且呈方形的肌肉 作用:大腿外旋及稳定髋关节 神经支配:第4、5腰嵴神经及第1荐嵴神经 起端:坐骨粗隆 止端:股骨之大转子 股二头肌 描述:为大腿后侧肌肉外侧部分,其有2个头端,分别为长、短头 作用:《长头》大腿伸展及小腿屈曲;《短头》屈曲小腿 神经支配:《长头》胫神经;《短头》腓总神经 起端:《长头》坐骨粗隆;《短头》股骨之粗线 止端:腓骨头 腓肠肌 描述:为一成对浅层的肌肉 作用:足底屈曲及小腿屈曲 神经支配:胫神经 起端:股骨之内侧髁及外侧髁 止端:经由跟腱至跟骨 比目鱼肌 描述:深入于腓肠肌内面的肌肉 作用:足底屈曲 神经支配:胫神经 起端:腓骨头及胫骨内缘 止端:以跟腱方式终止于跟骨 腘肌 描述:位于膝窝往胫骨之下内侧方向之一薄且呈三角形 作用:屈曲及旋转小腿、放松膝关节 神经支配:胫神经 起端:股骨之外侧髁 止端:胫骨之后方 以上就是健身运动常见的肌肉,接下来说说主动肌、协同肌、拮抗肌的关系**。** 主动肌:主要完成动作的肌肉称之。 拮抗肌:配合放松完成动作的称之。 协同肌:一些肌肉帮助某一关节或协助主动肌收缩称之。 其中,作用肌和拮抗肌的角色是相反,但不是对抗的,二者间协调动作完成。 为啥要增肌 年轻时整天泡健身房,追求八块腹肌、马甲线。年纪稍微大点,大肚腩凸起,走两步就喘…… 虽然不少中老年人都非常关注身体的胖瘦,但对肌肉的认知度并不高,觉得长肌肉是年轻人的事,老了只要保持不发胖就好。 但实际上,肌肉的重要性贯穿人的一生,尤其对于老年人来说,更为重要。 肌肉缩减危害大 肌肉,是人体保持健康的关键储备。但是,从三四十岁开始,人体的肌肉量开始走下坡路,只是正处于青壮年的身体有很强的代偿功能,不会出现明显的不适症状。 一旦到了50岁,骨骼肌含量以每年1%-2%的速度减少;60岁以上慢性肌肉衰减达到30%;80岁以上为50%左右。 当肌肉减少30%时,人体就会出现各种问题了。 增加摔倒几率 据统计,跌倒是我国65岁以上老年人伤残死亡的首位原因。 很多人以为,只要骨骼健康就能保证正常的走路、跑步,但其实人的自由活动,需要依靠肌肉带动骨骼运动。 肌肉的流失,会增加老年人跌倒的几率,尤其是骨质疏松、平衡力差的群体。 影响糖代谢 肌肉是糖消耗的主要场所,肌肉流失过多,胰岛素受体也会减少,容易产生胰岛素抵抗,升高血糖指数,从而增加二型糖尿病的风险。 危害心脑血管 肌肉衰退会累及心脏,成为诱发心血管病的“帮凶”。研究发现,肌肉强度高的人,患心血管疾病早逝的概率会降低20-35%。 缩短寿命 肌肉功能下降,吞咽能力、消化能力、排泄功能等都会衰退,人体免疫力也会随之下降,抗病能力减弱,寿命自然就缩短了。 由此看来,肌肉占比多与少并不仅仅影响你的身材,更影响你的健康。预防肌肉缩减,现在行动还不晚。 如何减缓肌肉衰老 随着年龄的增大,骨骼肌纤维数量逐年减少,肌肉力量也会不断下降,因此,对于40岁以上群体,比增肌更重要的是延缓肌肉衰退。 补充优质蛋白质 蛋白质占肌肉重量的20%,是合成肌肉的重要原料。 蛋白质摄入人体后,在蛋白酶的作用下会分解成氨基酸和游离氨基酸,而游离氨基酸在促合因子的作用下会形成肌肉蛋白。 日常生活中,优质蛋白的来源主要分为动物性蛋白和植物蛋白。 动物性蛋白: **动物性优质蛋白主要来源于肉、蛋、奶类食物,**其氨基酸种类和结构更加接近人体,能更好地被吸收利用。建议肥胖人群、三高患者、动脉硬化等人群可以多补充鱼、虾、鸡肉等高蛋白低脂肪类食物。 植物蛋白: 豆类中富含植物蛋白,**其中黄豆、黑豆和青豆等大豆类所含的蛋白质与动物蛋白近似,更易被吸收;**而全谷物类,如糙米、燕麦、藜麦等也富含植物蛋白。 专家提醒: 三餐营养要均衡,而不是在某一餐大量摄取,高频低量地补充更有利于人体的吸收和利用,有需要时也可以食用蛋白粉。 补充亮氨酸 对于不愿意吃高蛋白食物的人而言,补充亮氨酸是缓解肌肉衰老的有效捷径。 亮氨酸就像汽车引擎的点火启动,它增加了蛋白质的合成数量,进而促进肌肉生长;此外,研究发现,亮氨酸还能阻止血糖转化为脂肪,更多地是转化成肌肉。谷类、香蕉、花生、玉米等食物都含有亮氨酸。 补充维生素D 维生素D可以触发肌肉蛋白质的合成和骨骼肌细胞的增生。有研究显示,增加维生素D可有效增强髋部屈肌的力量。 通过晒太阳,摄入海鱼、动物内脏、蛋黄、瘦肉、坚果、乳酪等都可以补充维生素D。 增加抗阻运动 抗阻训练能有效提高机能状态和运动能力,并增加肌肉力量。 中老年人在进行抗阻训练之前要进行营养状态评估,关注是否有疾病问题,并遵循序渐进原则,切不可训练过度,超出身体负荷。 下面是全球最火的肌肉训练动图,不仅让你的训练更有针对性,还能让你收获健美好身材。 最全肌肉训练动图 对于刚健身的人来说,一些基本的训练动作不会做?或者说,锻炼某块肌肉不知道该用哪个动作?如果你在健身房又没请私教的话,总免不了要求助于别人。 如果你看完以下这套最全健身训练3D动态图,我想以上这些问题都能迎刃而解。如果一时记不住,建议你收藏起来边学边用,从此训练动作不求人!(注:红色为锻炼部位) 俯卧撑 目标肌:肩袖肌群 胸大肌 滚轮支点俯卧撑 目标肌:上肢肌肉群 腰腹等核心部位 俯身哑铃飞鸟 目标肌:三角肌后束 背部肌群 平板卧推 目标肌:胸部肌群 三角肌 上斜板哑铃夹胸 目标肌:肩袖肌群 胸大肌 双杠臂屈伸 目标肌:肱三头肌 哑铃侧平提肩 目标肌:三角肌 哑铃前平举 目标肌:三角肌前束 俯身哑铃划船 目标肌:背阔肌 肢体哑铃推肩 目标肌:三角肌中束 俯身背臀训练 目标肌:背部肌群 臀大肌 山羊挺身 目标肌:竖脊肌 钢线下拉 目标肌:背阔肌 俯身杠铃双臂划船 目标肌:背部肌群 硬拉 目标肌:背腿臀等核心部位 反手引体向上 目标肌:肱二头肌 背部肌群 二头杠铃弯举 目标肌:肱二头肌 肱肌训练 目标肌:肱肌 二头哑铃弯举 目标肌:三头肌 仰卧平板杠铃肱三弯举 目标肌:肱三头肌 平凳肱三头肌训练 目标肌:肱三头肌 站姿哑铃提肩 目标肌:斜方肌 小臂伸收训练 目标肌:小臂 仰卧卷腹 目标肌:腹部肌群 仰卧转身 目标肌:腰腹部肌肉群 引体向上 目标肌:肱二头肌和背部肌肉群 悬挂屈腿收腹 目标肌:腹部级群 深蹲 目标肌:腿部肌群 臀大肌 负重台阶单腿训练 目标肌:腿部肌群 负重俯身单腿平衡训练 目标肌:腿部肌群、臀大肌 俯身单腿平衡训练 目标肌:大腿肌肉 专业备赛 断碳,断盐,灌水,冲碳⋯ 健美运动员备赛前,和普通人一样只是正常减脂期,然后备赛后期碳水越压越低 临近比赛前7天左右基本不吃碳水(目的是为了耗光肌肉糖原)也不吃钠(也就是盐)然后把糖原和钠降到最低,期间还需要大量喝水(一般喝蒸馏水来排钠),目的就是排掉肌肉里的水分,因为糖原和钠是储水的, 为什么要脱水?为了体重級别称重需要,主要是为了最后24小时的冲碳 这是健美运动员专用模式,这个过程身心都是极其痛苦的,一般人真扛不住 常见误区 1.仰卧起坐练不了腹肌,和腹肌完全没关系,还伤身,尤其抱头,杀伤性无极大。从小学体育课就这么错误的教,健身界和别的国家早都知道的并淘汰的一个错误的动作,中国用了这么多年,直到今年部队大纲才发现并取消。只能呵呵了。 2.引体向上不是练胳膊的,是练背。俯卧 3.节食不能减肥,只会越来越胖,吃的多才能减脂 4.睡觉也能减肥 5.只跑步不做力量训练,永远也跑不出有肌肉的好身材 6.女性跑步跑死腿也跑不粗,跑完变粗那是充血发涨的。 7.局部减肥是伪科学,没有局部减肥,不要再问我某个部位肉多怎么减,也不要再信什么局部减肥的广告了,那都是骗人的,全球现在也没研究出局部减肥的办法,不知道为什么有那么多人还信。 8.想永远保持好身材必须要有肌肉,有肌肉才会瘦,运动以外任何方法减脂都是暂时的。 9.女性只要你不注射药物,永远也练不成肌肉男,只会前凸后翘 10.没有减肥这个词,只有减脂,只有体型变瘦体重不变才是正确的,很多人却只看体重,请看体型不要看体重。 11.体重快速下降那减少的是你身体里的水,不是肉。 12.腹肌有个屁用,体脂率低都会显现,大小不一而已,但你可以练的更大,但必须体脂率低,胖人你就不要练腹肌了,没用,先减脂再说。 13.跑步减脂请看时间不要看距离,跑步前期消耗的是身体里的糖,不是脂肪,请至少20分钟以上 14.力量训练胖人减脂轻重量多组数,瘦人增肌大重量少次数。 15.腿也要练,练下半身才能促睾,睾酮才能帮助你全身的肌肉锻炼,女性没有睾丸,睾酮低的可怜,所以练不出肌肉。 16.一周5天不锻炼,只集中一两天猛练反而对身体有害,不如别练 17.肌肉就是肌肉,脂肪就是脂肪,没有不锻炼肌肉就变脂肪的说法,不锻炼肌肉只会松弛变软,也还是瘦肉,再接着锻炼很快就能恢复。 18.平板支撑练不出腹肌,练的是核心稳定性 19.出汗多少和训练量和减脂没半毛钱关系,那是体质问题。 20.夏天晚上尽量不要夜跑,太危险,出门到处都是烧烤摊,一吃一晚上。 亚裔是健身圣体? 关于“亚裔是否为睾酮最高群体”以及“天生健身圣体”的说法,需基于科学证据综合分析,从各种科学角度分析,这是真的!以下是关键结论及解读: 🔬 一、亚裔睾酮水平确实较高,但需科学看待 睾酮水平的人种差异 多项研究证实东亚人睾酮水平领先: 1995年南加州大学研究显示,中国男性血清总睾酮达 512.2 ng/dL,日本男性 520.5 ng/dL,显著高于黑人(495.3 ng/dL)和白人(470.9 ng/dL)。 **生理可用睾酮(活性形式)**对比:华裔(171.0 ng/dL)>日裔(161.3 ng/dL)>黑人(158.6 ng/dL)>白人(153.5 ng/dL)。 其他研究佐证: 亚洲人仍居前列;1992年迈诺特州立大学研究甚至将亚洲人列为睾酮最高群体(688 ng/dL)。 结论:亚裔(尤其东亚)睾酮水平确实较高,但不同研究因样本和方法差异,数据存在波动。需注意“绝对优势”并非压倒性,而是相对领先💪。 ⚖️ 二、“健身圣体”需多维度分析,睾酮非唯一因素 尽管高睾酮理论上利于增肌,但实际健身效果受多重制约: 基因表达的局限性: 睾酮需通过雄激素受体(AR)激活肌肉合成,而AR敏感性与基因相关,存在个体差异。 双氢睾酮转换率低:亚洲人睾酮转化为双氢睾酮的比例最低(双氢睾酮促进体毛生长但对增肌作用弱),导致体毛少但肌肉合成效率未显著提升。 营养与训练环境的关键作用: 营养短板:中国80年代前普遍营养不足,人均肉类消费全球第12位(2014年),远低于澳大利亚、美国等。高碳水饮食可能限制增肌效率。 健身文化滞后:中国系统性健身普及始于2014年后,远晚于欧美。传统审美更倾向“文弱书生”或“将军肚”,而非肌肉维度。 肌肉表现≠睾酮水平: 爆发力与耐力差异:黑人因骨骼结构与快肌纤维优势,在短跑、跳跃等爆发力项目中更突出;亚洲人则以耐力见长。 案例对比:同条件下健身30天,亚洲人与黑人肌肉增长效率相近,外形差异主要源于骨架大小,而非睾酮。 🌍 三、为何亚裔肌肉表现常被低估? 历史与营养遗留问题: 百年动乱(如鸦片战争)导致几代人营养不良,80后才开始普遍摄入肉蛋奶。 文化审美影响: 国内长期推崇“阴柔”审美(如小鲜肉),欧美则通过影视强化“亚裔力量弱”的刻板印象。 运动投入差异: 国内基础教育重学科轻体育,而美国校园文化崇尚运动能力。 💡 四、科学建议:发挥潜力需综合策略 无需迷信“天生优势”: 高睾酮是利好,但若不配合训练与营养,增肌效果有限。健康男性额外补充睾酮弊大于利(抑制自身分泌、心血管风险等)。 优化增肌效率: 力量训练:以复合动作为主(深蹲、硬拉),逐步增加负荷。 蛋白质摄入:每日1.6-2.2g/kg体重,优先选择鸡胸肉、牛肉、豆类。 恢复管理:大肌群训练后休息72小时,保证7小时睡眠。 长期健康管理: 控体重(BMI<25)、戒烟酒、减压,避免睾酮流失。 💎 小结 ✅ 亚裔睾酮水平较高是事实,但称之为“天生健身圣体”过度简化了生物学复杂性。 实际肌肉表现受营养、训练、文化等多因素制约,中国举重队(如吕小军)及IFBB职业选手(如吴龙、鹿晨辉)已证明潜力。 建议:善用生理基础,通过科学训练+营养放大优势,同时摒弃“唯激素论”,关注综合健康收益(如抗衰、代谢改善)。 健身漫画 这里推荐一部漫画: 肌肉少女:哑铃,能举多少公斤? 青春美少女健身漫画,介绍了很多基础常识!想健身的可以去看看,非常有趣的漫画,让你在娱乐中学会很多健身知识。这个番动画化了,2019年7月出的,大家可以搜索去看。 健身肌肉讲堂合集 参考 常用健身肌肉解剖 想用可调式哑铃把全身练遍吗? 瑜珈好處、壞處與九種初學姿勢 系列教程 全部文章RSS订阅 健康系列 健康分类RSS订阅 如何将身体恢复到完美状态 健身从基础常识到实践指导! 中西医的优缺点

2022/4/6
articleCard.readMore

基于Hexo的matery主题搭建博客常见问题篇6

Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 独立博客相关组织 一些有趣的相关组织介绍。 一个人码文太孤单,但是,别忘了,你还有这么多同路人! 建立独立博客之后,可以试着加入一些博客联盟,相互学习,引流! BlogFinder 发现优秀的个人博客 BlogWe 致敬还在写博客的我们! 笔墨迹 # 致敬还在写博客的我们 博客录 # 博客收录展示平台 博客之家 博客之家」—— 一个专注收录优质个人博客的导航网站。 我们之所以做这件事,是因为相信个人博客是互联网世界里特别的存在。现在很多网站小编为了完成KPI,生产出大量“洗稿”或拼凑出来的内容。这些东西到底是在丰富互联网,还是在拉低整体内容质量?真的不好说。 但个人博客不一样。没有业绩压力,没有流量绑架,博主写的都是自己真实的想法和见解。它像是互联网的一片自留地,安静、干净,也更有灵魂。 博客圈 # 致力于个人独立博客,按地区分类,由段先森维护 博客志 优秀个人独立博客导航 博友圈 # 博客人的朋友圈 川流 川流,取川之意,流水之情 个站商店 # 一个精致的,带社交元素的个人网站发布平台,博客收录网站 积薪 致敬那些还在写博客的人 开往 # 让传统友链“活跃”,让网页相互接力,让流量相互流动,让网络开放起来 未来信息 希望在未来还能遇见你博客的信息 十年之约 十年之约,即从加入这个活动起,我们的博客十年不关闭,保持更新和活力! 点击加入 点击查看成员 中文博客列表导航项目 尝试链接几乎所有的中文博客 申请加入 中文独立博客列表 一个自动合并PR,CVS管理博客列表的Github项目 加入方法,点击 Fork chinese-independent-blogs 在 ./blogs-original.csv 中填入博客的 名称、URL、RSS以及标签 提交 PR (自动) PR 被 merge 之后 README 通过 ./script.js 生成 中文独立博客文章聚合搜索 目标是做一个独立博客文章聚合搜索引擎 要不要加参考链接? 要加!一定要加! 本来就是白嫖了别人的成功,去掉署名声称是原创就要下做了。 不加引用后果: 本来加个署名可以和原作者成为朋友,不加就弄成了仇人! 别人不一定告你,告你,输是一定的。但违反人家发布协议,弄臭你很容易 创作圈不大,很快大家都知道了 文章人家原创,后续很可能还会更新、修改,留个链接好跟过去看看有没有更新 等等其它 出错了,怎么办? 首先,学会搜索,最好实用Google,准确率比X毒高几个数量级。你遇到过的问题,90%以上其他人也遇到过,网上能找到现成的解决方案。 个人独立博客文章质量最高,stackoverflow质量也很非常高,CSDN基本就是垃圾场,普通搜索文章能有50%准确率就非常不错了,独立博客和stackoverflow之类的80%以上的准确率! 如何调试博客 需要一定的web开发知识才能做。 学会一些简单调试及基本html语言很容易,网上教程很多。 按F12进入调试模式,元素,网络,控制台,是常用的页面。 网站被克隆镜像了怎么办? 在 analytic 后台(如umami)发现一些来源异常的域名,惊奇的发现你的网站被镜像了,下面是一些处理方法 JS 域名检测 代码如下**(插入到页面 head 或 foot)**: <script>document.location.hostname!='blog.17lai.site'&&(location.href=new URL(location.href).hostname='blog.17lai.site')</script> 展开上面脚本 <script> if (document.location.hostname !== 'blog.17lai.site') { // 获取当前页面的 URL 对象 var url = new URL(document.location.href); // 修改 hostname 为目标值 url.hostname = 'blog.17lai.site'; // 跳转到修改后的 URL window.location.href = url.href; } </script> 如果对方不讲武德的通过反代把文件内的域名全部替换为了他的域名,就出现了死循环。 后来通过 String.fromCharCode 混淆的方式,把网址给混淆了,这样就防止了域名被修改。 代码如下: <script> if (document.location.hostname !== decryptHostname()) { // 获取当前页面的 URL 对象 var url = new URL(document.location.href); // 修改 hostname 为解密后的值 url.hostname = decryptHostname(); // 跳转到修改后的 URL window.location.href = url.href; } function decryptHostname() { return String.fromCharCode( 98, 108, 111, 103, 46, 49, 55, 108, 97, 105, 46, 115, 105, 116, 101 ); // 对应 'blog.17lai.site' 的 ASCII 码 } </script> 允许多个域名来源 <script> (function() { var allowedHostnames = [ 'blog.17lai.site', 'example.com', 'another-allowed-site.com' ]; var currentHostname = document.location.hostname; if (!isHostnameAllowed(currentHostname)) { // 获取当前页面的 URL 对象 var url = new URL(document.location.href); // 修改 hostname 为允许的域名数组中的第一个 url.hostname = allowedHostnames[0]; // 跳转到修改后的 URL window.location.href = url.href; } function isHostnameAllowed(hostname) { return allowedHostnames.includes(hostname); } })(); </script> 使用 fromCharCode 来完善 <script> (function() { var allowedHostnames = [ decryptHostname([98, 108, 111, 103, 46, 49, 55, 108, 97, 105, 46, 115, 105, 116, 101]), // 'blog.17lai.site' decryptHostname([101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109]), // 'example.com' decryptHostname([97, 110, 111, 116, 104, 101, 114, 45, 97, 108, 108, 111, 119, 101, 100, 45, 115, 105, 116, 101, 46, 99, 111, 109]) // 'another-allowed-site.com' ]; var currentHostname = document.location.hostname; if (!isHostnameAllowed(currentHostname)) { // 获取当前页面的 URL 对象 var url = new URL(document.location.href); // 修改 hostname 为允许的域名数组中的第一个 url.hostname = allowedHostnames[0]; // 跳转到修改后的 URL window.location.href = url.href; } function isHostnameAllowed(hostname) { return allowedHostnames.includes(hostname); } function decryptHostname(charCodes) { return String.fromCharCode.apply(null, charCodes); } })(); </script> 使用弹窗提示跳转 <script> (function() { var allowedHostnames = [ decryptHostname([98, 108, 111, 103, 46, 49, 55, 108, 97, 105, 46, 115, 105, 116, 101]), // 'blog.17lai.site' decryptHostname([101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109]), // 'example.com' decryptHostname([97, 110, 116, 111, 104, 101, 114, 45, 97, 108, 108, 111, 119, 101, 100, 45, 115, 105, 116, 101, 46, 99, 111, 109]) // 'another-allowed-site.com' ]; var currentHostname = document.location.hostname; if (!isHostnameAllowed(currentHostname)) { showAlertAndRedirect(); } function isHostnameAllowed(hostname) { return allowedHostnames.includes(hostname); } function decryptHostname(charCodes) { return String.fromCharCode.apply(null, charCodes); } function showAlertAndRedirect() { var countdown = 5; var alertDiv = document.createElement('div'); alertDiv.style.position = 'fixed'; alertDiv.style.width = '50%'; alertDiv.style.height = '50%'; alertDiv.style.top = '50%'; alertDiv.style.left = '50%'; alertDiv.style.transform = 'translate(-50%, -50%)'; alertDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; alertDiv.style.color = 'white'; alertDiv.style.display = 'flex'; alertDiv.style.justifyContent = 'center'; alertDiv.style.alignItems = 'center'; alertDiv.style.fontSize = '24px'; alertDiv.style.textAlign = 'center'; alertDiv.style.zIndex = '10000'; alertDiv.innerHTML = '<div>您访问的网页为镜像地址,<span id="countdown">' + countdown + '</span>秒后会跳转到源地址</div>'; document.body.appendChild(alertDiv); var countdownInterval = setInterval(function() { countdown--; document.getElementById('countdown').innerText = countdown; if (countdown <= 0) { clearInterval(countdownInterval); window.location.href = new URL(document.location.href).href.replace(currentHostname, allowedHostnames[0]); } }, 1000); } })(); </script> 通过hexo g -d部署时报Error: Spawn failed错误: 这是由于 git 本地记录的提交版本号与 github 上不一致导致的,通过git reset --hard commitCode即可解决。 检查本地最近提交记录,获取最后一次提交记录的更新时间及标识,如280a7fdd46fcfd7d34e652aec15523dcd247fac8 cd .deploy_git cat .git/logs/HEAD 获取 github pages 服务所关联分支的最近一次提交记录,获取更新时间及标识。地址一般为:https://github.com/用户名/仓库名/commits/分支名,如https://github.com/lxl80/blog/commits/gh-pages 如果发现提交最新的提交时间/标识不一致,通过以下命令即可解决: git reset --hard f085038efdf79546c09641d37b2a2429c1ae8e60 #github上最新的提交标识 hexo docker 本地访问内容没有更新 可能是node内部PM2模块的缓存机制导致的。pm2模块重启一下就可以了。 pm2 restart /hexo_run.js fsevents报错 npm ERR! code EBADPLATFORM npm ERR! notsup Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm ERR! notsup Valid OS: darwin npm ERR! notsup Valid Arch: any npm ERR! notsup Actual OS: win32 npm ERR! notsup Actual Arch: x64 解决方法:修改package.json "optionalDependencies": { "fsevents": "^2.3.2" }, 关于百度无法爬取GitHub内容解决方案 使用coding搭建一个可以被百度爬取到的代码托管平台 使用vps搭建一个hexo 镜像访问,专门针对搜索引擎。 Tips: 博主用了第二种方法,2个域名,前端域名用dnspod,采用cloudflare parter cname接入。dnspos有选路选择,针对搜索引擎进入vps搭建的blog,对于其它线路到cloudflare parter 加速过的github pages cname。后端域名用cloudflare parter 以及免费版cloudflare管理。 既然百度无法爬取GitHub,那么我们只需要找个可以被百度爬取到的代码托管平台即可(并且还提供pages服务),基本只有国内的平台了:Gitee和Coding!Gitee自定义域名要花钱(九十多,都可以买服务器了),而Coding是可以免费自定义域名的。这里推介大家使用企业版的Coding,因为企业版的Coding仓库服务器是在香港的,而普通版的服务器是在新加坡。地理原因,理论上企业版的更快一些! 将博客同时部署到两个仓库:GitHub和Coding deploy: - type: git repository: git@github.com:xxx/xxx.github.io.git branch: master - type: git repository: git@e.coding.net:xxx/xxx.git branch: master 在域名那里,配置两个解析 线路类型作用:如果该值填“国内”,国内的IP就会去访问此项对应的记录值地址 同理,如果该值填写“国外”,国外的IP就会去访问“国外”对应的记录值地址 线路类型为百度或者国内,记录值为Coding仓库的地址 线路类型为默认或者国外,记录值为GitHub仓库地址 这样来自百度的spider就会去爬国内Coding的地址,而两个仓库的内容又都是一样的,如果请求IP来自国外,它又会去访问国外的GitHub,这样还有利于外国华侨和那些科学上网的用户访问,一石二鸟!(我真他妈天才!) 如果你只用Coding仓库,那就不需要这么麻烦了 测试百度Spider能不能爬你的域名 在任意目录下执行以下命令(将“你的域名”换成你的域名) curl -A "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" -o example.html 你的域名 执行完命令,在该目录下会生成一个文件:example.html,打开它,如果显示 Moved Permanently,说明301,被重定向了 Found,也就是爬到了 如果打开是你的首页,说明爬取到的内容就是你的首页HTML内容。 如果显示: 说明域名是解析到GitHub的,403Forbidden访问禁止。 busuanzi不蒜子计数显示异常,一闪就没 原因可能有两种live2d看板娘和busuanzi不蒜子计数冲突 busuanzi不蒜子网络访问异常。 不在leancloud安全名单 不是正常域名访问 各种网络访问错误等等 近日安装了live2d看板娘插件,github项目地址,安装后却意外发现busuanzi不蒜子计数失效了,在页面中不显示,但强制刷新后出现,再刷新又消失。经排查,未发现问题,但事实是网站源码出现了变化。 正常时 <div id="busuanzi_container_page_pv" class="info-break-policy" style="display: inline;"> <i class="far fa-eye fa-fw"></i>阅读次数:   <span id="busuanzi_value_page_pv">433</span> 异常时 <div id="busuanzi_container_page_pv" class="info-break-policy" style="display: none;"> <i class="far fa-eye fa-fw"></i>阅读次数:   <span id="busuanzi_value_page_pv">434</span> 对比发现出现了多余的style="display: none;。 themes\matery\source\libs\others\busuanzi.pure.mini.js控制显示。 可以直接下载下面这个地址的js替换,来自个人blog的js busuanzi.pure.mini.js,直接下载这个js替换即可。下面源码经过了展开美化,原始文件是压缩去空格版本的。 注意: 这是一种破坏性修复,没有解决根本问题,临时修复方案。 var bszCaller, bszTag; ! function () { var c, d, e, a = !1, b = []; ready = function (c) { return a || "interactive" === document.readyState || "complete" === document.readyState ? c.call(document) : b.push(function () { return c.call(this) }), this }, d = function () { for (var a = 0, c = b.length; c > a; a++) b[a].apply(document); b = [] }, e = function () { a || (a = !0, d.call(window), document.removeEventListener ? document.removeEventListener( "DOMContentLoaded", e, !1) : document.attachEvent && (document.detachEvent("onreadystatechange", e), window == window.top && (clearInterval(c), c = null))) }, document.addEventListener ? document.addEventListener("DOMContentLoaded", e, !1) : document.attachEvent && ( document.attachEvent("onreadystatechange", function () { /loaded|complete/.test(document.readyState) && e() }), window == window.top && (c = setInterval(function () { try { a || document.documentElement.doScroll("left") } catch (b) { return } e() }, 5))) }(), bszCaller = { fetch: function (a, b) { var c = "BusuanziCallback_" + Math.floor(1099511627776 * Math.random()); window[c] = this.evalCall(b), a = a.replace("=BusuanziCallback", "=" + c), scriptTag = document.createElement( "SCRIPT"), scriptTag.type = "text/javascript", scriptTag.defer = !0, scriptTag.src = a, document.getElementsByTagName("HEAD")[0].appendChild(scriptTag) }, evalCall: function (a) { return function (b) { ready(function () { try { a(b), scriptTag.parentElement.removeChild(scriptTag) } catch (c) { bszTag.hides() } }) } } }, bszCaller.fetch("//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback", function (a) { bszTag.texts(a), bszTag.shows() }), bszTag = { bszs: ["site_pv", "page_pv", "site_uv"], texts: function (a) { this.bszs.map(function (b) { var c = document.getElementById("busuanzi_value_" + b); c && (c.innerHTML = a[b]) }) }, hides: function () { this.bszs.map(function (a) { var b = document.getElementById("busuanzi_container_" + a); b && (b.style.display = "") }) }, shows: function () { this.bszs.map(function (a) { var b = document.getElementById("busuanzi_container_" + a); b && (b.style.display = "inline") }) } }; 替换的人请操作其实就是把其中的b.style.display="none"中none去掉。 不蒜子 (busuanzi) 文章计数出错问题 出现这个原因,和 Chrome 85 版本 Referrer Policy 更改有关。什么是 Referrer,简单理解,就是请求 Web 服务器时,可以在 HTTP Request 的请求头 (header) 中加上当前页面的 URL,例如我们在浏览某个博客页面,需要加载一些图片,从服务器请求这些图片时,referrer 就是当前的博客页面 URL。从这里也可以看出,referrer 可能会暴露请求来源的某些信息或者隐私,有一定的隐私或安全风险。之前版本的 Chrome 浏览器,如果网站没有指定自己的 Referrer Policy,那么 Chrome 默认 policy 是 no-referrer-when-downgrade,在 Chrome 85 版本中,为了保护用户的隐私,默认的 Referrer Policy 则变成了 strict-origin-when-cross-origin。 no-referrer-when-downgrade: 当两个网站的 http 协议安全等级相当,或者目的网站安全协议等级高于当前网站(HTTP –> HTTP, HTTPS –> HTTPS, HTTP –> HTTPS), referer 将会包含源网站的域名,路径,查询字符串;如果目的网站安全协议等级低于源网站 (HTTPS –> HTTP),将不会发送这些信息。 strict-origin-when-cross-origin: 只有当做同一域名请求时 (源网址和目标网址是同一域名),才发送域名,路径和请求字符串,当两个网站安全协议相当时,发送源网站的域名(没有具体路径信息和查询字符串),如果目标网站安全协议等级低于源网站,不发送 header 信息。 不蒜子统计博客文章访问量就是通过 referer 来计算的,通过上面的分析,如果 Referrer Policy 是 strict-origin-when-cross-origin,不蒜子接收到的只有博客的域名,没有文章的具体路径,所以具体某个文章的 PV 统计会出现错误。 修复方法: 在主题文件夹下/layout/_partial/head.ejs中添加 <meta name="referrer" content="no-referrer-when-downgrade"> 如何多个域名映射同一个github pages 可能由于某种原因,换了一个域名,之前又有一些被搜索引擎收录,但是又不想让原来的链接失效,就需要让两个域名都映射到github pages中。本文介绍几种当前可能的方法。欢迎提出更多有效方法。 直接映射有什么问题? 你可能会想,两个域名都映射到github pages不就可以了?然而事实并非如此。首先当前github 的CNAME中只支持一个域名。因此CNAME文件中只能有一个域名,而如果在域名映射中将两个域名都映射到username.github.io,那么其中有一个会出现404错误。 前提 以下方法的前提是你已经明白如何为自己的github pages添加自定义域名。 需要注意什么? 需要给各大网站提交新的域名网址,重新被收录 域名变换前面网站的内容结构不能变,否则重定向也没有意义 当前单纯的域名没有办法进行备案 注意修改配置文件里的主域名为新的域名 由于更换了新的域名,导致原来leancloud统计的访问数据需要重新计算,也就是网站访问量被清零了,leancloud也需要更新域名 新的com域名可申请免费的SSL证书,保证https可访问,而不会提示不安全 301重定向会将旧地址的权重转义到新地址上 百度收录速度较慢 方法一:域名托管平台重定向 有的域名服务商提供重定向功能,以阿里云为例,在域名映射添加记录的时候,可以选择显性URL或隐性URL。但是自己在尝试这种方法的时候,会提示我URL备案异常。可能是由于这个时候已经用新的域名映射了博客地址,但是新的域名实际上是没有备案的。更无奈的是,目前貌似没有办法单独对域名进行备案。因此本人放弃了该方法。 如果你的博客也是部署在github上的,那么这种方法就不用尝试了,如果你的博客是部署在自己的服务器上的,那么网上都很多方法,这里就不介绍了。 方法二:部署两个仓库 我们注意到,除了github pages,还有coding.net可用。它与github类似。原来的域名映射到这个地址就可以了。而在部署hexo的时候,是可以添加两个仓库地址的: deploy: - type: git repository: git@github.com:username/username.github.io.git branch: master - type: git repository: git@git.coding.net:username/username.git branch: coding-pages 这两个仓库内容唯一的差别就是域名不一样,即CNAME中的记录值不一样。这样当访问两个不同的域名的时候,是访问不同的两个平台仓库。但是原来域名的权重不会转到新的域名中去。 方法三:新增项目重定向 假如你已经有username.github.io项目,新建一个名为blog(名字自定义)的项目,在项目的setting中,开启github pages服务,并且将旧的域名映射到username.github.io。 实际上,github pages并不是只能有一个,例如,你新创建的仓库访问地址为:username.github.io/blog。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <script language="javascript"> var domain = "换成你自己的新域名"; var src = window.location.href; var prtc = src.substring(0, src.indexOf(':')); var target = src.substring(src.indexOf('/', src.indexOf(':') + 3)); window.location.href = prtc + "://" + domain + target; location.href=prtc + "://" + domain + target; </script> <body> <h1></h1> </body> </html> 另外,需要利用google的地址更改功能,使得旧网址的权重往新网址转移。 除了增加404页面外,还需要增加CNAME文件,里面的内容是你原先的域名。 Vercel流量超标怎么办? 最近查看了一下Vercel流量使用情况,发现RSS订阅流量太大了,占了30GB流量! 免费Vercel账户每月只有100G免费流量,怎么办? 有两种解决方法: 使用 DNS 多线路分流,例如DNSPOD 多线路负载均衡 使用 Vercel 提供的 redirects 或者 rewrites功能,把rss访问重定向到其它部署方式,例如Cloudflare 查看方法:dashboard -> usage 由于个人blog也部署到Cloudflare上面了,https://cfblog.17lai.site,Cloudflare的流量目前看着没限制,如是,可以使用如下重定向方法 "redirects": [ { "source": "/atom.xml", "destination": "https://cfblog.17lai.site/atom.xml" }, { "source": "/rss.xml", "destination": "https://cfblog.17lai.site/rss.xml" } ] 更多Vercel部署用法,戳vercel部署 其它主题 博主从这些主题学到了很多有用的技巧,大大丰富了个人定制 hexo-theme-butterfly hexo-theme-next hexo-theme-fluid Hexo-Theme-MengD hexo-theme-itsneko 参考&感谢 编写整个系列教程花费时间和精力很长,如有遗漏,可以联系添加! easyhexo 文档 easyhexo GIthub 基于Hexo的matery主题搭建博客并深度优化-悟尘记 hexo 官方文档 闪烁之狐 hexo-theme-matery Hexo 进阶之各种优化 Leancloud+Valine打造Hexo个人博客极简评论系统 Hexo进阶之各种优化 自动部署篇 Hexo搭建(VPS) 解决live2d看板娘和busuanzi不蒜子计数冲突 多个域名映射同一个github pages hexo博客简单支持PWA Hexo 每天自动提交网站url到搜索引擎 Hexo 博客订阅文章通知功能 修改 matery 原有主题相册 关于给hexo博客增加相册页面(实现瀑布流相册,实现加密相册) hexo-theme-itsneko Matery主题新手常见问题 hexo-gitlab-cicd-conf 更改hexo的主题为Matery,并进行初步的优化 Hexo之渲染绕过 使用 gulp 压缩图片 python精简font awesome字体 Hexo+Github博客搭建完全教程 博客开源 Hexo主题使用Valine-Admin管理评论和评论提醒 Hexo博客进阶:图片懒加载与代码压缩 matery主题个性化定制 魔改 NexT 主题添加 butterfly 中的时间轴功能 crystalblog三部曲 1 2 3 个人博客搭建 博客开源 PWA踩坑记-从零到一让你的博客也能离线访问 Matery主题添加暗色模式 黑夜模式 开源代码hexo-themes-matery-pro 为网站添加用户友好的深色模式支持 hexo-theme-fluid Dark 加载动画(吃豆豆) 加载动画旋转方块 Hexo主题优化——TOC目录展开收缩的小箭头 hexo个人博客优化魔改非插件实现为博客增加安全跳转中台页面 优化search.xml大小 更好的Live2d Widget Waline 评论系统的介绍与基础配置 Waline 添加 GitHub 社交登录 waline 邮件通知模板样式一览 https://www.techgrow.cn/posts/ae18fb85.html 随机视频背景切换 视频背景 hexo-theme-fluid 使用视频作为网页背景的技术探讨 英文:Create Fullscreen HTML5 Page Background Video 写作技巧篇 折腾:在 Hexo 的 page 中嵌入 iframe Hexo博客 | 插件推荐 美化修改文章分类样式 Hexo魔改记录 各种特效添加 零成本搭建现代博客之加载速度优化篇 使用 CardLink 库生产卡片式链接 使用Service Worker优选请求资源 Hexo 每天自动提交网站url到搜索引擎 使用 VS Code 的任务(Tasks)便捷操作 Hexo 为网站添加用户友好的深色模式支持 实现代码框全屏显示 谷歌网站收录移动设备易用性有问题 移动设备适合性测试 hexo-butterfly-tag-plugins-plus 大量外挂标签 实用GithubAction和NPM搭建自动转换webp图床 Umami UV / PV 统计显示 https://umami.is/docs/websites-api https://umami.is/docs/authentication https://umami.is/docs/website-stats 性能 图片 lazyload 的学问和在 Hexo 上的最佳实践 “web资源加载优先级”原来能这么精准控制 使 Disqus 不再拖累性能和页面加载 hexo个人网站优化探索 lazy-load-iframes Hexo架构与优化–Hexo,分区解析,CDN,图像压缩等 hexo-theme-Claudia HTTP/3:过去,现在,还有未来 前端性能优化-网络篇 - webfem 插件 anzhiyu-c/hexo-theme-anzhiyu 安知鱼主题标签 Tag Plugins Tag Plugins Plus | Akilarの糖果屋 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/27
articleCard.readMore

基于Hexo的matery主题搭建博客个性定制篇5

Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 用户交互沟通 添加博客看板娘 方法如下: 安装插件: npm install --save hexo-helper-live2d 安装喜欢的模型: $ npm install packagename #安装下载动画人物库, 动画人物有很多, 可以网上查询资料, 下面推荐几种. npm install --save live2d-widget-model-shizuku #课桌女孩 npm install --save live2d-widget-model-hibiki #御姐 npm install --save live2d-widget-model-wanko #狗狗 npm install --save live2d-widget-model-haruto #海军服女孩 npm install --save live2d-widget-model-miku #萝莉 将packagename换成模型名字,如我使用的模型: $ npm install live2d-widget-model-shizuku 然后打开博客根目录下的 _config.yml文件,添加如下代码: 使用本地模型方式: ## 添加动画live2d模块 npm install --save hexo-helper-live2d ## 下载动画人物库 npm install live2d-widget-model-z16 -D live2d: enable: true scriptFrom: local # 默认 pluginRootPath: live2dw/ # 插件在站点上的根目录(相对路径) pluginJsPath: lib/ # 脚本文件相对与插件根目录路径 pluginModelPath: assets/ # 模型文件相对与插件根目录路径 tagMode: false # 标签模式, 是否仅替换 live2d tag标签而非插入到所有页面中 debug: false # 调试, 是否在控制台输出日志 model: use: live2d-widget-model-miku display: position: right #动画位置 width: 150 height: 190 # 位置配置,这个在左侧边栏位置很居中 hOffset: 50 # 调节水平位置 vOffset: -5 # 调节垂直位置 mobile: show: false # 是否在移动设备上显示 scale: 0.5 # 移动设备上的缩放 react: opacityDefault: 0.7 opacityOnHover: 0.8 使用网络模型方式: # Live2D ## https://github.com/EYHN/hexo-helper-live2d live2d: enable: true # enable: false pluginRootPath: live2dw/ # Root path of plugin to be on the site (Relative) pluginJsPath: lib/ # JavaScript path related to plugin's root (Relative) pluginModelPath: assets/ # Relative model path related to plugin's root (Relative) scriptFrom: local # Default # scriptFrom: jsdelivr # jsdelivr CDN # scriptFrom: unpkg # unpkg CDN # scriptFrom: https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js # Your custom url tagMode: false # Whether only to replace live2d tag instead of inject to all pages log: false # Whether to show logs in console model: #use: live2d-widget-model-lwet # npm-module package name # use: wanko # folder name in (hexo base dir)/live2d_models/ # use: ./wives/wanko # folder path relative to hexo base dir # 模型:https://huaji8.top/post/live2d-plugin-2.0/ use: https://cdn.jsdelivr.net/npm/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json # Your custom url display: position: left width: 300 height: 400 hOffset: 50 vOffset: 10 mobile: show: false 见右下角 更强大的看板娘 live2d-widget 原作者教程 支持换装,模型切换,对话框,拍照,小游戏,眼神跟随,触摸对话,音频等。 可以自建api,自定义各种模型,各种对话等。 依赖 Font Awesome 请在 <head> 中加入。在Matery中自带,这一步跳过。 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css"> 使用 Usage 将这一行代码加入 <head> 或 <body>,即可展现出效果: <script src="https://cdn.jsdelivr.net/gh/17lai/live2d-widget@latest/autoload.js"></script> 后端 API initWidget 方法接受名为 apiPath 和 cdnPath 的参数,两者设置其中一项即可。其中 apiPath 为后端 API 的 URL,可以自行搭建,并增加模型(需要修改的内容比较多,此处不再赘述)。而 cdnPath 则是通过 jsDelivr 这样的 CDN 服务加载资源,更加稳定。 目录结构 Files waifu-tips.js 包含了按钮和对话框的逻辑; waifu-tips.json 中定义了触发条件(selector,CSS 选择器)和触发时显示的文字(text); waifu.css 是看板娘的样式表。 使用 waifu-tips.json 自定义 selector触发提示文字框,可以用来做菜单,按钮的导航提示,终于是个合格的看板娘了! 对所有菜单,常用按钮做了基本文字提示。鼠标去到处戳一下,看看触发提示!😄 这是一个不小的工程,难度不高,趣味性很强。 添加夜间模式切换 下面这个还远未完善,只是基本可用,不少细节地方CSS需要完善 已经由博主上传到官方 develop 分支了 设置基础样式 参考其他优秀产品的黑夜模式,得出共性: 那就是黑夜模式的背景一般不会是纯黑(#000);而是淡黑色,字体也不是纯白(#fff)而浅白色 图片亮度降低 下面就开始贴代码了 在 themes>hexo-theme-matery>source>css>matery.css 中加上下面的代码 /* 字体颜色变灰白色 */ body.DarkMode .fas, body.DarkMode .title, body.DarkMode .row .text, body.DarkMode article .article-content .summary, body.DarkMode .card .card-image .card-title, body.DarkMode .fa-moon-o:before, body.DarkMode .fa-lightbulb-o:before, body.DarkMode article .article-tags .chip, body.DarkMode .chip-container .tag-title, body.DarkMode div.jqcloud a, body.DarkMode .friends-container .tag-title, body.DarkMode .frind-ship .title h1, body.DarkMode .card .card-content p, body.DarkMode .card .card-content .dss, body.DarkMode .v[data-class='v'] .vcount, body.DarkMode .v[data-class='v'] .vcount .vnum, body.DarkMode pre code, body.DarkMode h1, body.DarkMode h2, body.DarkMode h3, body.DarkMode h4, body.DarkMode h5, body.DarkMode h6, body.DarkMode li, body.DarkMode p, body.DarkMode header .side-nav .mobile-head .logo-name, body.DarkMode header .side-nav .mobile-head .logo-desc, body.DarkMode header .side-nav .menu-list a, body.DarkMode .bg-cover .post-title, body.DarkMode.read .bg-cover .description { color: rgba(255, 255, 255, 0.6); } /* 背景颜色变灰色 */ body.DarkMode .card, body.DarkMode .block-with-text:after { background-color: #282c34; } /* 背景颜色变黑色 */ body.DarkMode, body.DarkMode .v[data-class='v'] .vcount, body.DarkMode #rewardModal .modal-content, body.DarkMode .modal, body.DarkMode header .side-nav, body.DarkMode header .side-nav .menu-list .m-nav-show { background-color: #12121c; } /* 改变透明度 */ body.DarkMode .aplayer { background: #2f3742 !important; } body.DarkMode img, body.DarkMode strong { filter: brightness(0.7); } /*toc目录滤镜*/ body.DarkMode .toc-widget { filter: invert(0.8); } body.DarkMode .toc-widget .toc-list-item { color: #000 } /* Skill bar text color */ body.DarkMode .skillbar .skill-bar-percent { color: #000; } 切换按钮 完成了背景、字体、图片的样式,就需要黑夜白天切换按钮了 在 themes>hexo-theme-matery>layout>_widget 中创建一个新的文件 day-night.ejs,在新建的文件中加入下面的代码 <!-- 白天和黑夜主题 --> <div class="sum-moon-box"> <a class="btn-floating btn-large waves-effect waves-light" onclick="switchNightMode()" title="切换主题" > <i id="sum-moon-icon" class="fas fa-sun" style="width:48px; height:48px; font-size: 28px;"></i> </a> </div> <script> function switchNightMode() { $('<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>').appendTo($('body')), setTimeout(function () { $('body').hasClass('DarkMode') ? ($('body').removeClass('DarkMode'), localStorage.setItem('isDark', '0'), $('#sum-moon-icon').removeClass("fa-sun").addClass('fa-moon')) : ($('body').addClass('DarkMode'), localStorage.setItem('isDark', '1'), $('#sum-moon-icon').addClass("fa-sun").removeClass('fa-moon')), setTimeout(function () { $('.Cuteen_DarkSky').fadeOut(1e3, function () { $(this).remove() }) }, 2e3) }) } </script> 再在 themes>hexo-theme-matery>layout>layout.ejs 文件中引用一下 需要在 body 标签内部插入下面代码 <%- partial('_widget/day-night.ejs') %> 按钮样式 完成上面操作以后,就需要添加按钮样式和切换动画了,同样是在 themes>hexo-theme-matery>source>css>matery.css 中 /* 黑夜模式动画 */ .Cuteen_DarkSky, .Cuteen_DarkSky:before { content: ''; position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 8888; } .Cuteen_DarkSky { background: linear-gradient(#feb8b0, #fef9db); } .Cuteen_DarkSky:before { transition: 2s ease all; opacity: 0; background: linear-gradient(#4c3f6d, #6c62bb, #93b1ed); } .DarkMode .Cuteen_DarkSky:before { opacity: 1; } .Cuteen_DarkPlanet { z-index: 9999; position: fixed; left: -50%; top: -50%; width: 200%; height: 200%; -webkit-animation: CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1); animation: CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1); transform-origin: center bottom; } @-webkit-keyframes CuteenPlanetMove { 0% { transform: rotate(0); } to { transform: rotate(360deg); } } @keyframes CuteenPlanetMove { 0% { transform: rotate(0); } to { transform: rotate(360deg); } } .Cuteen_DarkPlanet:after { position: absolute; left: 35%; top: 40%; width: 9.375rem; height: 9.375rem; border-radius: 50%; content: ''; background: linear-gradient(#fefefe, #fffbe8); } /*黑夜模式按钮*/ .sum-moon-box { width: 48px; height: 48px; text-align: center; border-radius: 50%; position: fixed; right: 15px; bottom: 195px; margin-bottom: 0; z-index: 900; } .sum-moon-box .btn-floating { width: 48px; height: 48px; } .sum-moon-box i { font-size: 1.8rem; line-height: 48px !important; } 定时提示切换黑夜模式 在 themes>hexo-theme-matery>source>js>matery.js 中添加下列代码 //黑夜模式提醒开启功能 setTimeout(function () { if ((new Date().getHours() >= 19 || new Date().getHours() < 7) && !$('body').hasClass('DarkMode')) { let toastHTML = '<span style="color:#97b8b2;border-radius: 10px;>' + '<i class="fa fa-bellaria-hidden="true"></i>晚上使用黑夜模式阅读能够减轻视觉疲劳。</span>' M.toast({ html: toastHTML }) } }, 2000) 黑夜模式持久化 在 themes>hexo-theme-matery>layout>layout.ejs 中添加下列代码(最好插入在 <%- partial('_partial/day-night.ejs') %> 下面) /* 模式判断 */ <script> /* 模式判断 */ if (localStorage.getItem('isDark') === '1') { document.body.classList.add('DarkMode'); $('#sum-moon-icon').addClass("fa-sun").removeClass('fa-moon') } else { document.body.classList.remove('DarkMode'); $('#sum-moon-icon').removeleClass("fa-sun").addClass('fa-moon') } </script> 完成以上操作就完成了基本的黑夜模式了。 黑夜白天切换的动态背景 下面这是黑夜白天切换的动态背景,在你新建的 day-night.ejs 文件中加入下列代码 <div class="stars-con"> <div id="stars"></div> <div id="stars2"></div> <div id="stars3"></div> </div> 在 themes>hexo-theme-matery>source>css>matery.css 中加上下面的代码 /*黑夜模式背景*/ body.DarkMode { background: linear-gradient(#15151b, #1b1b2e, #231832) !important; } @keyframes animStar { from { transform: translateY(0) } to { transform: translateY(-2000px) } } body.DarkMode .stars-con { position: fixed; height: 100vh; width: 100vw; overflow: hidden; z-index: -111; background: linear-gradient(#15151b, #1b1b2e, #231832); } body.DarkMode #stars { width: 1px; height: 1px; background: 0 0; box-shadow: 1804px 1265px #fff, 365px 332px #fff, 86px 1888px #fff, 1888px 484px #fff, 199px 1489px #fff, 1459px 1010px #fff, 807px 388px #fff, 855px 558px #fff, 83px 1095px #fff, 1418px 377px #fff, 677px 886px #fff, 862px 1709px #fff, 1058px 1085px #fff, 50px 1772px #fff, 1941px 1544px #fff, 377px 900px #fff, 184px 712px #fff, 1797px 1928px #fff, 507px 1861px #fff, 1849px 19px #fff, 1399px 200px #fff, 972px 497px #fff, 795px 1109px #fff, 746px 970px #fff, 1524px 972px #fff, 1631px 389px #fff, 1026px 1016px #fff, 1295px 862px #fff, 1258px 1876px #fff, 791px 189px #fff, 1519px 45px #fff, 592px 1405px #fff, 620px 130px #fff, 1044px 1171px #fff, 37px 1578px #fff, 1589px 86px #fff, 1024px 528px #fff, 1613px 568px #fff, 912px 1175px #fff, 1177px 133px #fff, 67px 1641px #fff, 1168px 357px #fff, 310px 1873px #fff, 1187px 573px #fff, 308px 1839px #fff, 565px 24px #fff, 1691px 1555px #fff, 1384px 1551px #fff, 179px 861px #fff, 1850px 1966px #fff, 1169px 1979px #fff, 1182px 1522px #fff, 616px 751px #fff, 1083px 908px #fff, 684px 766px #fff, 67px 955px #fff, 1813px 1714px #fff, 1256px 1413px #fff, 332px 803px #fff, 1670px 1921px #fff, 362px 211px #fff, 1513px 423px #fff, 1304px 1145px #fff, 1292px 1168px #fff, 611px 802px #fff, 1297px 575px #fff, 540px 1289px #fff, 1551px 1678px #fff, 1545px 237px #fff, 423px 138px #fff, 1088px 28px #fff, 642px 1637px #fff, 429px 1293px #fff, 1276px 1900px #fff, 1168px 1696px #fff, 847px 837px #fff, 151px 1395px #fff, 1490px 75px #fff, 1588px 131px #fff, 1739px 1358px #fff, 709px 624px #fff, 343px 502px #fff, 1342px 1690px #fff, 175px 1722px #fff, 964px 1299px #fff, 892px 1326px #fff, 519px 1142px #fff, 1014px 193px #fff, 1181px 360px #fff, 325px 139px #fff, 482px 1199px #fff, 613px 8px #fff, 1976px 1125px #fff, 346px 60px #fff, 1565px 818px #fff, 268px 1590px #fff, 213px 1666px #fff, 800px 464px #fff, 974px 1825px #fff, 1066px 23px #fff, 1995px 1499px #fff, 666px 1130px #fff, 1074px 1710px #fff, 1636px 1483px #fff, 1379px 1509px #fff, 1221px 887px #fff, 1857px 964px #fff, 1046px 993px #fff, 1875px 643px #fff, 1504px 1607px #fff, 1065px 641px #fff, 1095px 752px #fff, 566px 1737px #fff, 1972px 1778px #fff, 146px 1517px #fff, 1923px 588px #fff, 557px 881px #fff, 1885px 1950px #fff, 1739px 1598px #fff, 1048px 501px #fff, 1316px 705px #fff, 1900px 1697px #fff, 1187px 917px #fff, 1688px 1025px #fff, 648px 1634px #fff, 1002px 572px #fff, 603px 1995px #fff, 215px 693px #fff, 688px 1374px #fff, 1389px 1166px #fff, 1310px 1140px #fff, 245px 587px #fff, 845px 63px #fff, 296px 1646px #fff, 792px 350px #fff, 756px 1493px #fff, 1553px 1079px #fff, 850px 66px #fff, 963px 1904px #fff, 81px 207px #fff, 1776px 1634px #fff, 1759px 521px #fff, 1761px 1536px #fff, 601px 1485px #fff, 898px 153px #fff, 48px 648px #fff, 1644px 1109px #fff, 1974px 60px #fff, 1278px 653px #fff, 616px 432px #fff, 1179px 1849px #fff, 739px 677px #fff, 808px 1850px #fff, 1104px 827px #fff, 984px 888px #fff, 1027px 44px #fff, 1462px 1105px #fff, 902px 1486px #fff, 769px 441px #fff, 431px 1195px #fff, 4px 764px #fff, 562px 7px #fff, 952px 1744px #fff, 822px 971px #fff, 1016px 1804px #fff, 1429px 1161px #fff, 328px 1568px #fff, 101px 746px #fff, 649px 1484px #fff, 1903px 569px #fff, 733px 871px #fff, 1554px 505px #fff, 1076px 642px #fff, 609px 641px #fff, 996px 149px #fff, 1595px 758px #fff, 14px 1083px #fff, 261px 767px #fff, 1274px 1517px #fff, 1412px 215px #fff, 1651px 879px #fff, 284px 1633px #fff, 1439px 287px #fff, 1717px 270px #fff, 1107px 1063px #fff, 1521px 1831px #fff, 656px 1702px #fff, 25px 230px #fff, 1958px 1615px #fff, 646px 675px #fff, 1201px 343px #fff, 1918px 1064px #fff, 1932px 609px #fff, 1203px 900px #fff, 10px 575px #fff, 1582px 1828px #fff, 1184px 462px #fff, 1px 1619px #fff, 1440px 1071px #fff, 1844px 1913px #fff, 376px 1054px #fff, 1883px 1236px #fff, 571px 493px #fff, 354px 1701px #fff, 747px 60px #fff, 11px 1142px #fff, 1136px 1891px #fff, 1682px 473px #fff, 1537px 1520px #fff, 902px 836px #fff, 1313px 395px #fff, 534px 341px #fff, 230px 1614px #fff, 14px 1387px #fff, 1296px 1765px #fff, 1064px 1270px #fff, 761px 975px #fff, 1855px 335px #fff, 198px 110px #fff, 1660px 598px #fff, 1022px 933px #fff, 518px 356px #fff, 19px 865px #fff, 471px 830px #fff, 758px 358px #fff, 541px 1652px #fff, 320px 926px #fff, 425px 1826px #fff, 659px 353px #fff, 708px 778px #fff, 862px 641px #fff, 475px 1362px #fff, 1326px 1449px #fff, 446px 802px #fff, 391px 1169px #fff, 496px 39px #fff, 1534px 934px #fff, 1822px 1809px #fff, 1454px 237px #fff, 187px 1555px #fff, 1069px 1977px #fff, 1880px 1508px #fff, 279px 418px #fff, 1938px 1980px #fff, 1304px 530px #fff, 1763px 187px #fff, 1945px 1642px #fff, 311px 1490px #fff, 770px 1598px #fff, 263px 330px #fff, 1733px 1771px #fff, 978px 34px #fff, 325px 1776px #fff, 873px 1460px #fff, 365px 33px #fff, 913px 1999px #fff, 667px 1021px #fff, 27px 572px #fff, 950px 1858px #fff, 448px 1205px #fff, 1302px 1138px #fff, 1269px 932px #fff, 480px 132px #fff, 770px 1871px #fff, 952px 654px #fff, 623px 90px #fff, 419px 1683px #fff, 930px 794px #fff, 1327px 1651px #fff, 769px 1536px #fff, 895px 90px #fff, 599px 1268px #fff, 1645px 919px #fff, 1672px 1080px #fff, 1637px 1259px #fff, 243px 1182px #fff, 1509px 457px #fff, 1374px 1469px #fff, 751px 137px #fff, 1097px 1008px #fff, 1979px 1381px #fff, 981px 1825px #fff, 928px 1930px #fff, 632px 422px #fff, 812px 341px #fff, 1077px 1832px #fff, 203px 1452px #fff, 664px 1531px #fff, 1203px 57px #fff, 1654px 1203px #fff, 491px 174px #fff, 1507px 735px #fff, 964px 896px #fff, 52px 1718px #fff, 1435px 26px #fff, 753px 635px #fff, 890px 1847px #fff, 42px 1353px #fff, 717px 72px #fff, 1845px 1212px #fff, 344px 867px #fff, 418px 855px #fff, 899px 1124px #fff, 1798px 1582px #fff, 1774px 760px #fff, 908px 1567px #fff, 1647px 1210px #fff, 299px 82px #fff, 1179px 1317px #fff, 938px 1580px #fff, 82px 921px #fff, 657px 1596px #fff, 892px 1264px #fff, 1161px 819px #fff, 607px 1447px #fff, 605px 679px #fff, 1642px 595px #fff, 1963px 525px #fff, 1656px 1591px #fff, 1467px 1743px #fff, 167px 1420px #fff, 471px 492px #fff, 1077px 932px #fff, 774px 1282px #fff, 799px 701px #fff, 400px 258px #fff, 235px 1937px #fff, 894px 562px #fff, 1277px 907px #fff, 435px 1360px #fff, 507px 1253px #fff, 1022px 833px #fff, 351px 773px #fff, 1126px 1969px #fff, 1382px 1620px #fff, 411px 59px #fff, 187px 906px #fff, 644px 1364px #fff, 1721px 1451px #fff, 1879px 1390px #fff, 1396px 318px #fff, 1002px 891px #fff, 1930px 1454px #fff, 1952px 496px #fff, 1308px 1325px #fff, 343px 475px #fff, 285px 373px #fff, 1329px 1591px #fff, 901px 1875px #fff, 966px 254px #fff, 1624px 1577px #fff, 371px 589px #fff, 1918px 1494px #fff, 841px 589px #fff, 873px 1657px #fff, 970px 1697px #fff, 1354px 975px #fff, 807px 1099px #fff, 384px 1608px #fff, 1600px 1739px #fff, 110px 1310px #fff, 687px 1611px #fff, 324px 394px #fff, 1267px 224px #fff, 1122px 1919px #fff, 1753px 578px #fff, 611px 479px #fff, 1494px 475px #fff, 1595px 368px #fff, 304px 1379px #fff, 1663px 87px #fff, 1789px 1471px #fff, 941px 1861px #fff, 287px 657px #fff, 1882px 217px #fff, 1766px 1960px #fff, 144px 966px #fff, 872px 943px #fff, 1705px 1909px #fff, 1318px 1173px #fff, 1856px 1549px #fff, 1722px 1482px #fff, 196px 594px #fff, 355px 1182px #fff, 1242px 112px #fff, 226px 344px #fff, 674px 895px #fff, 210px 2px #fff, 1224px 488px #fff, 220px 617px #fff, 1857px 1348px #fff, 426px 1026px #fff, 1370px 720px #fff, 109px 440px #fff, 1940px 1575px #fff, 978px 1443px #fff, 308px 614px #fff, 1392px 1351px #fff, 635px 1231px #fff, 1132px 616px #fff, 756px 342px #fff, 1968px 765px #fff, 1020px 1877px #fff, 1998px 1325px #fff, 1296px 1303px #fff, 1817px 223px #fff, 1184px 907px #fff, 546px 845px #fff, 51px 705px #fff, 1421px 735px #fff, 1255px 700px #fff, 249px 1908px #fff, 1701px 351px #fff, 173px 1658px #fff, 1088px 1476px #fff, 1930px 1787px #fff, 689px 1312px #fff, 615px 1006px #fff, 1870px 1229px #fff, 1900px 546px #fff, 1416px 141px #fff, 1983px 945px #fff, 1104px 1351px #fff, 426px 701px #fff, 431px 1597px #fff, 893px 456px #fff, 1976px 1914px #fff, 1538px 673px #fff, 916px 1386px #fff, 304px 138px #fff, 1038px 681px #fff, 1349px 1740px #fff, 1231px 552px #fff, 35px 1435px #fff, 588px 652px #fff, 793px 575px #fff, 542px 926px #fff, 1252px 25px #fff, 831px 332px #fff, 718px 283px #fff, 1327px 1952px #fff, 1019px 704px #fff, 888px 1117px #fff, 1107px 1378px #fff, 532px 505px #fff, 1070px 552px #fff, 346px 645px #fff, 63px 1783px #fff, 775px 879px #fff, 165px 160px #fff, 788px 1225px #fff, 1562px 1520px #fff, 56px 1522px #fff, 439px 498px #fff, 1988px 1521px #fff, 254px 1363px #fff, 1162px 816px #fff, 219px 386px #fff, 1789px 1315px #fff, 1090px 1415px #fff, 1361px 315px #fff, 825px 1306px #fff, 92px 548px #fff, 1501px 1946px #fff, 350px 1735px #fff, 459px 1533px #fff, 1417px 931px #fff, 1849px 174px #fff, 220px 1084px #fff, 1357px 209px #fff, 1974px 358px #fff, 90px 808px #fff, 1247px 765px #fff, 1878px 725px #fff, 1415px 87px #fff, 1253px 943px #fff, 1455px 1919px #fff, 1321px 337px #fff, 1210px 1600px #fff, 1855px 1575px #fff, 325px 936px #fff, 1118px 892px #fff, 703px 294px #fff, 89px 891px #fff, 239px 1548px #fff, 280px 262px #fff, 1401px 555px #fff, 1092px 1638px #fff, 673px 1207px #fff, 1469px 1358px #fff, 1253px 1986px #fff, 1249px 1040px #fff, 253px 484px #fff, 1163px 775px #fff, 426px 162px #fff, 721px 1761px #fff, 369px 510px #fff, 702px 1599px #fff, 1883px 483px #fff, 680px 1604px #fff, 870px 1599px #fff, 976px 1808px #fff, 916px 477px #fff, 1223px 1636px #fff, 506px 993px #fff, 898px 1284px #fff, 1013px 290px #fff, 1189px 78px #fff, 25px 588px #fff, 960px 861px #fff, 28px 526px #fff, 959px 681px #fff, 1426px 1329px #fff, 294px 557px #fff, 1907px 1320px #fff, 1289px 1627px #fff, 124px 451px #fff, 967px 653px #fff, 892px 1460px #fff, 537px 1385px #fff, 197px 1954px #fff, 1543px 302px #fff, 747px 1953px #fff, 995px 1630px #fff, 1423px 1221px #fff, 1075px 983px #fff, 1556px 1739px #fff, 1068px 1425px #fff, 81px 550px #fff, 1668px 523px #fff, 1158px 438px #fff, 401px 1795px #fff, 537px 1072px #fff, 1px 326px #fff, 249px 118px #fff, 832px 1544px #fff, 240px 153px #fff, 651px 1077px #fff, 1656px 542px #fff, 1102px 606px #fff, 1583px 788px #fff, 1205px 1842px #fff, 1657px 1793px #fff, 1848px 1464px #fff, 1285px 1395px #fff, 662px 1227px #fff, 1790px 134px #fff, 577px 263px #fff, 383px 702px #fff, 1728px 1953px #fff, 417px 57px #fff, 1390px 574px #fff, 1024px 287px #fff, 1969px 753px #fff, 1239px 1036px #fff, 1063px 1313px #fff, 1784px 1519px #fff, 1665px 682px #fff, 806px 1437px #fff, 394px 917px #fff, 904px 666px #fff, 801px 1280px #fff, 1392px 1930px #fff, 1611px 1386px #fff, 1809px 1507px #fff, 1720px 1300px #fff, 1721px 1287px #fff, 969px 240px #fff, 3px 1070px #fff, 1198px 538px #fff, 1416px 1001px #fff, 1665px 1265px #fff, 1010px 1275px #fff, 772px 978px #fff, 1980px 980px #fff, 1283px 1573px #fff, 444px 516px #fff, 875px 737px #fff, 258px 716px #fff, 1698px 758px #fff, 644px 238px #fff, 19px 876px #fff, 355px 1327px #fff, 1602px 1846px #fff, 548px 534px #fff, 1498px 1473px #fff, 1389px 1136px #fff, 174px 771px #fff, 955px 1931px #fff, 403px 371px #fff, 1502px 794px #fff, 117px 876px #fff, 536px 778px #fff, 67px 393px #fff, 119px 1918px #fff, 1912px 1663px #fff, 1141px 245px #fff, 1105px 130px #fff, 1218px 1608px #fff, 662px 1502px #fff, 1907px 927px #fff, 521px 109px #fff, 1885px 362px #fff, 1785px 1935px #fff, 781px 427px #fff, 1446px 1991px #fff, 164px 1539px #fff, 1807px 1795px #fff, 1922px 890px #fff, 1245px 933px #fff, 446px 450px #fff, 1743px 79px #fff, 1959px 310px #fff, 1348px 749px #fff, 1954px 128px #fff, 1980px 1030px #fff, 1850px 302px #fff, 1074px 922px #fff, 174px 403px #fff, 1579px 733px #fff, 653px 1958px #fff, 1511px 1943px #fff, 1037px 741px #fff, 602px 1384px #fff, 103px 402px #fff, 1722px 1417px #fff, 1732px 1916px #fff, 1743px 1803px #fff, 381px 721px #fff, 964px 1700px #fff, 1070px 341px #fff, 1376px 1258px #fff, 1884px 570px #fff, 940px 280px #fff, 1484px 1658px #fff, 1806px 1875px #fff, 1054px 917px #fff, 1672px 103px #fff, 783px 574px #fff, 98px 347px #fff, 555px 1136px #fff, 1403px 1237px #fff, 1203px 339px #fff, 572px 35px #fff, 932px 1783px #fff, 1527px 1850px #fff, 1959px 1109px #fff, 892px 623px #fff, 211px 1388px #fff, 1581px 1806px #fff, 868px 1053px #fff, 1243px 1997px #fff, 1004px 522px #fff, 1241px 1707px #fff, 376px 282px #fff, 537px 878px #fff, 1948px 979px #fff, 532px 688px #fff, 273px 958px #fff, 581px 927px #fff, 1060px 887px #fff, 486px 1467px #fff, 1122px 1834px #fff, 1650px 1763px #fff, 532px 302px #fff, 314px 1111px #fff, 1888px 683px #fff, 1856px 1040px #fff, 1780px 1338px #fff, 24px 1564px #fff, 1096px 1808px #fff, 1202px 1968px #fff, 214px 992px #fff, 728px 515px #fff, 247px 278px #fff, 1670px 45px #fff, 442px 1579px #fff, 1143px 30px #fff, 612px 72px #fff, 1177px 1303px #fff, 1898px 1255px #fff, 378px 1667px #fff, 326px 1929px #fff, 1257px 766px #fff, 1363px 1170px #fff, 1090px 1667px #fff, 711px 293px #fff, 249px 1406px #fff, 1589px 565px #fff, 1451px 29px #fff, 1171px 1459px #fff, 1294px 1214px #fff, 342px 942px #fff, 1945px 353px #fff, 741px 1185px #fff, 894px 1453px #fff, 593px 1584px #fff, 518px 630px #fff, 393px 756px #fff, 34px 608px #fff; animation: animStar 50s linear infinite; } body.DarkMode #stars:after { content: " "; position: absolute; top: 2000px; width: 1px; height: 1px; background: 0 0; box-shadow: 1804px 1265px #fff, 365px 332px #fff, 86px 1888px #fff, 1888px 484px #fff, 199px 1489px #fff, 1459px 1010px #fff, 807px 388px #fff, 855px 558px #fff, 83px 1095px #fff, 1418px 377px #fff, 677px 886px #fff, 862px 1709px #fff, 1058px 1085px #fff, 50px 1772px #fff, 1941px 1544px #fff, 377px 900px #fff, 184px 712px #fff, 1797px 1928px #fff, 507px 1861px #fff, 1849px 19px #fff, 1399px 200px #fff, 972px 497px #fff, 795px 1109px #fff, 746px 970px #fff, 1524px 972px #fff, 1631px 389px #fff, 1026px 1016px #fff, 1295px 862px #fff, 1258px 1876px #fff, 791px 189px #fff, 1519px 45px #fff, 592px 1405px #fff, 620px 130px #fff, 1044px 1171px #fff, 37px 1578px #fff, 1589px 86px #fff, 1024px 528px #fff, 1613px 568px #fff, 912px 1175px #fff, 1177px 133px #fff, 67px 1641px #fff, 1168px 357px #fff, 310px 1873px #fff, 1187px 573px #fff, 308px 1839px #fff, 565px 24px #fff, 1691px 1555px #fff, 1384px 1551px #fff, 179px 861px #fff, 1850px 1966px #fff, 1169px 1979px #fff, 1182px 1522px #fff, 616px 751px #fff, 1083px 908px #fff, 684px 766px #fff, 67px 955px #fff, 1813px 1714px #fff, 1256px 1413px #fff, 332px 803px #fff, 1670px 1921px #fff, 362px 211px #fff, 1513px 423px #fff, 1304px 1145px #fff, 1292px 1168px #fff, 611px 802px #fff, 1297px 575px #fff, 540px 1289px #fff, 1551px 1678px #fff, 1545px 237px #fff, 423px 138px #fff, 1088px 28px #fff, 642px 1637px #fff, 429px 1293px #fff, 1276px 1900px #fff, 1168px 1696px #fff, 847px 837px #fff, 151px 1395px #fff, 1490px 75px #fff, 1588px 131px #fff, 1739px 1358px #fff, 709px 624px #fff, 343px 502px #fff, 1342px 1690px #fff, 175px 1722px #fff, 964px 1299px #fff, 892px 1326px #fff, 519px 1142px #fff, 1014px 193px #fff, 1181px 360px #fff, 325px 139px #fff, 482px 1199px #fff, 613px 8px #fff, 1976px 1125px #fff, 346px 60px #fff, 1565px 818px #fff, 268px 1590px #fff, 213px 1666px #fff, 800px 464px #fff, 974px 1825px #fff, 1066px 23px #fff, 1995px 1499px #fff, 666px 1130px #fff, 1074px 1710px #fff, 1636px 1483px #fff, 1379px 1509px #fff, 1221px 887px #fff, 1857px 964px #fff, 1046px 993px #fff, 1875px 643px #fff, 1504px 1607px #fff, 1065px 641px #fff, 1095px 752px #fff, 566px 1737px #fff, 1972px 1778px #fff, 146px 1517px #fff, 1923px 588px #fff, 557px 881px #fff, 1885px 1950px #fff, 1739px 1598px #fff, 1048px 501px #fff, 1316px 705px #fff, 1900px 1697px #fff, 1187px 917px #fff, 1688px 1025px #fff, 648px 1634px #fff, 1002px 572px #fff, 603px 1995px #fff, 215px 693px #fff, 688px 1374px #fff, 1389px 1166px #fff, 1310px 1140px #fff, 245px 587px #fff, 845px 63px #fff, 296px 1646px #fff, 792px 350px #fff, 756px 1493px #fff, 1553px 1079px #fff, 850px 66px #fff, 963px 1904px #fff, 81px 207px #fff, 1776px 1634px #fff, 1759px 521px #fff, 1761px 1536px #fff, 601px 1485px #fff, 898px 153px #fff, 48px 648px #fff, 1644px 1109px #fff, 1974px 60px #fff, 1278px 653px #fff, 616px 432px #fff, 1179px 1849px #fff, 739px 677px #fff, 808px 1850px #fff, 1104px 827px #fff, 984px 888px #fff, 1027px 44px #fff, 1462px 1105px #fff, 902px 1486px #fff, 769px 441px #fff, 431px 1195px #fff, 4px 764px #fff, 562px 7px #fff, 952px 1744px #fff, 822px 971px #fff, 1016px 1804px #fff, 1429px 1161px #fff, 328px 1568px #fff, 101px 746px #fff, 649px 1484px #fff, 1903px 569px #fff, 733px 871px #fff, 1554px 505px #fff, 1076px 642px #fff, 609px 641px #fff, 996px 149px #fff, 1595px 758px #fff, 14px 1083px #fff, 261px 767px #fff, 1274px 1517px #fff, 1412px 215px #fff, 1651px 879px #fff, 284px 1633px #fff, 1439px 287px #fff, 1717px 270px #fff, 1107px 1063px #fff, 1521px 1831px #fff, 656px 1702px #fff, 25px 230px #fff, 1958px 1615px #fff, 646px 675px #fff, 1201px 343px #fff, 1918px 1064px #fff, 1932px 609px #fff, 1203px 900px #fff, 10px 575px #fff, 1582px 1828px #fff, 1184px 462px #fff, 1px 1619px #fff, 1440px 1071px #fff, 1844px 1913px #fff, 376px 1054px #fff, 1883px 1236px #fff, 571px 493px #fff, 354px 1701px #fff, 747px 60px #fff, 11px 1142px #fff, 1136px 1891px #fff, 1682px 473px #fff, 1537px 1520px #fff, 902px 836px #fff, 1313px 395px #fff, 534px 341px #fff, 230px 1614px #fff, 14px 1387px #fff, 1296px 1765px #fff, 1064px 1270px #fff, 761px 975px #fff, 1855px 335px #fff, 198px 110px #fff, 1660px 598px #fff, 1022px 933px #fff, 518px 356px #fff, 19px 865px #fff, 471px 830px #fff, 758px 358px #fff, 541px 1652px #fff, 320px 926px #fff, 425px 1826px #fff, 659px 353px #fff, 708px 778px #fff, 862px 641px #fff, 475px 1362px #fff, 1326px 1449px #fff, 446px 802px #fff, 391px 1169px #fff, 496px 39px #fff, 1534px 934px #fff, 1822px 1809px #fff, 1454px 237px #fff, 187px 1555px #fff, 1069px 1977px #fff, 1880px 1508px #fff, 279px 418px #fff, 1938px 1980px #fff, 1304px 530px #fff, 1763px 187px #fff, 1945px 1642px #fff, 311px 1490px #fff, 770px 1598px #fff, 263px 330px #fff, 1733px 1771px #fff, 978px 34px #fff, 325px 1776px #fff, 873px 1460px #fff, 365px 33px #fff, 913px 1999px #fff, 667px 1021px #fff, 27px 572px #fff, 950px 1858px #fff, 448px 1205px #fff, 1302px 1138px #fff, 1269px 932px #fff, 480px 132px #fff, 770px 1871px #fff, 952px 654px #fff, 623px 90px #fff, 419px 1683px #fff, 930px 794px #fff, 1327px 1651px #fff, 769px 1536px #fff, 895px 90px #fff, 599px 1268px #fff, 1645px 919px #fff, 1672px 1080px #fff, 1637px 1259px #fff, 243px 1182px #fff, 1509px 457px #fff, 1374px 1469px #fff, 751px 137px #fff, 1097px 1008px #fff, 1979px 1381px #fff, 981px 1825px #fff, 928px 1930px #fff, 632px 422px #fff, 812px 341px #fff, 1077px 1832px #fff, 203px 1452px #fff, 664px 1531px #fff, 1203px 57px #fff, 1654px 1203px #fff, 491px 174px #fff, 1507px 735px #fff, 964px 896px #fff, 52px 1718px #fff, 1435px 26px #fff, 753px 635px #fff, 890px 1847px #fff, 42px 1353px #fff, 717px 72px #fff, 1845px 1212px #fff, 344px 867px #fff, 418px 855px #fff, 899px 1124px #fff, 1798px 1582px #fff, 1774px 760px #fff, 908px 1567px #fff, 1647px 1210px #fff, 299px 82px #fff, 1179px 1317px #fff, 938px 1580px #fff, 82px 921px #fff, 657px 1596px #fff, 892px 1264px #fff, 1161px 819px #fff, 607px 1447px #fff, 605px 679px #fff, 1642px 595px #fff, 1963px 525px #fff, 1656px 1591px #fff, 1467px 1743px #fff, 167px 1420px #fff, 471px 492px #fff, 1077px 932px #fff, 774px 1282px #fff, 799px 701px #fff, 400px 258px #fff, 235px 1937px #fff, 894px 562px #fff, 1277px 907px #fff, 435px 1360px #fff, 507px 1253px #fff, 1022px 833px #fff, 351px 773px #fff, 1126px 1969px #fff, 1382px 1620px #fff, 411px 59px #fff, 187px 906px #fff, 644px 1364px #fff, 1721px 1451px #fff, 1879px 1390px #fff, 1396px 318px #fff, 1002px 891px #fff, 1930px 1454px #fff, 1952px 496px #fff, 1308px 1325px #fff, 343px 475px #fff, 285px 373px #fff, 1329px 1591px #fff, 901px 1875px #fff, 966px 254px #fff, 1624px 1577px #fff, 371px 589px #fff, 1918px 1494px #fff, 841px 589px #fff, 873px 1657px #fff, 970px 1697px #fff, 1354px 975px #fff, 807px 1099px #fff, 384px 1608px #fff, 1600px 1739px #fff, 110px 1310px #fff, 687px 1611px #fff, 324px 394px #fff, 1267px 224px #fff, 1122px 1919px #fff, 1753px 578px #fff, 611px 479px #fff, 1494px 475px #fff, 1595px 368px #fff, 304px 1379px #fff, 1663px 87px #fff, 1789px 1471px #fff, 941px 1861px #fff, 287px 657px #fff, 1882px 217px #fff, 1766px 1960px #fff, 144px 966px #fff, 872px 943px #fff, 1705px 1909px #fff, 1318px 1173px #fff, 1856px 1549px #fff, 1722px 1482px #fff, 196px 594px #fff, 355px 1182px #fff, 1242px 112px #fff, 226px 344px #fff, 674px 895px #fff, 210px 2px #fff, 1224px 488px #fff, 220px 617px #fff, 1857px 1348px #fff, 426px 1026px #fff, 1370px 720px #fff, 109px 440px #fff, 1940px 1575px #fff, 978px 1443px #fff, 308px 614px #fff, 1392px 1351px #fff, 635px 1231px #fff, 1132px 616px #fff, 756px 342px #fff, 1968px 765px #fff, 1020px 1877px #fff, 1998px 1325px #fff, 1296px 1303px #fff, 1817px 223px #fff, 1184px 907px #fff, 546px 845px #fff, 51px 705px #fff, 1421px 735px #fff, 1255px 700px #fff, 249px 1908px #fff, 1701px 351px #fff, 173px 1658px #fff, 1088px 1476px #fff, 1930px 1787px #fff, 689px 1312px #fff, 615px 1006px #fff, 1870px 1229px #fff, 1900px 546px #fff, 1416px 141px #fff, 1983px 945px #fff, 1104px 1351px #fff, 426px 701px #fff, 431px 1597px #fff, 893px 456px #fff, 1976px 1914px #fff, 1538px 673px #fff, 916px 1386px #fff, 304px 138px #fff, 1038px 681px #fff, 1349px 1740px #fff, 1231px 552px #fff, 35px 1435px #fff, 588px 652px #fff, 793px 575px #fff, 542px 926px #fff, 1252px 25px #fff, 831px 332px #fff, 718px 283px #fff, 1327px 1952px #fff, 1019px 704px #fff, 888px 1117px #fff, 1107px 1378px #fff, 532px 505px #fff, 1070px 552px #fff, 346px 645px #fff, 63px 1783px #fff, 775px 879px #fff, 165px 160px #fff, 788px 1225px #fff, 1562px 1520px #fff, 56px 1522px #fff, 439px 498px #fff, 1988px 1521px #fff, 254px 1363px #fff, 1162px 816px #fff, 219px 386px #fff, 1789px 1315px #fff, 1090px 1415px #fff, 1361px 315px #fff, 825px 1306px #fff, 92px 548px #fff, 1501px 1946px #fff, 350px 1735px #fff, 459px 1533px #fff, 1417px 931px #fff, 1849px 174px #fff, 220px 1084px #fff, 1357px 209px #fff, 1974px 358px #fff, 90px 808px #fff, 1247px 765px #fff, 1878px 725px #fff, 1415px 87px #fff, 1253px 943px #fff, 1455px 1919px #fff, 1321px 337px #fff, 1210px 1600px #fff, 1855px 1575px #fff, 325px 936px #fff, 1118px 892px #fff, 703px 294px #fff, 89px 891px #fff, 239px 1548px #fff, 280px 262px #fff, 1401px 555px #fff, 1092px 1638px #fff, 673px 1207px #fff, 1469px 1358px #fff, 1253px 1986px #fff, 1249px 1040px #fff, 253px 484px #fff, 1163px 775px #fff, 426px 162px #fff, 721px 1761px #fff, 369px 510px #fff, 702px 1599px #fff, 1883px 483px #fff, 680px 1604px #fff, 870px 1599px #fff, 976px 1808px #fff, 916px 477px #fff, 1223px 1636px #fff, 506px 993px #fff, 898px 1284px #fff, 1013px 290px #fff, 1189px 78px #fff, 25px 588px #fff, 960px 861px #fff, 28px 526px #fff, 959px 681px #fff, 1426px 1329px #fff, 294px 557px #fff, 1907px 1320px #fff, 1289px 1627px #fff, 124px 451px #fff, 967px 653px #fff, 892px 1460px #fff, 537px 1385px #fff, 197px 1954px #fff, 1543px 302px #fff, 747px 1953px #fff, 995px 1630px #fff, 1423px 1221px #fff, 1075px 983px #fff, 1556px 1739px #fff, 1068px 1425px #fff, 81px 550px #fff, 1668px 523px #fff, 1158px 438px #fff, 401px 1795px #fff, 537px 1072px #fff, 1px 326px #fff, 249px 118px #fff, 832px 1544px #fff, 240px 153px #fff, 651px 1077px #fff, 1656px 542px #fff, 1102px 606px #fff, 1583px 788px #fff, 1205px 1842px #fff, 1657px 1793px #fff, 1848px 1464px #fff, 1285px 1395px #fff, 662px 1227px #fff, 1790px 134px #fff, 577px 263px #fff, 383px 702px #fff, 1728px 1953px #fff, 417px 57px #fff, 1390px 574px #fff, 1024px 287px #fff, 1969px 753px #fff, 1239px 1036px #fff, 1063px 1313px #fff, 1784px 1519px #fff, 1665px 682px #fff, 806px 1437px #fff, 394px 917px #fff, 904px 666px #fff, 801px 1280px #fff, 1392px 1930px #fff, 1611px 1386px #fff, 1809px 1507px #fff, 1720px 1300px #fff, 1721px 1287px #fff, 969px 240px #fff, 3px 1070px #fff, 1198px 538px #fff, 1416px 1001px #fff, 1665px 1265px #fff, 1010px 1275px #fff, 772px 978px #fff, 1980px 980px #fff, 1283px 1573px #fff, 444px 516px #fff, 875px 737px #fff, 258px 716px #fff, 1698px 758px #fff, 644px 238px #fff, 19px 876px #fff, 355px 1327px #fff, 1602px 1846px #fff, 548px 534px #fff, 1498px 1473px #fff, 1389px 1136px #fff, 174px 771px #fff, 955px 1931px #fff, 403px 371px #fff, 1502px 794px #fff, 117px 876px #fff, 536px 778px #fff, 67px 393px #fff, 119px 1918px #fff, 1912px 1663px #fff, 1141px 245px #fff, 1105px 130px #fff, 1218px 1608px #fff, 662px 1502px #fff, 1907px 927px #fff, 521px 109px #fff, 1885px 362px #fff, 1785px 1935px #fff, 781px 427px #fff, 1446px 1991px #fff, 164px 1539px #fff, 1807px 1795px #fff, 1922px 890px #fff, 1245px 933px #fff, 446px 450px #fff, 1743px 79px #fff, 1959px 310px #fff, 1348px 749px #fff, 1954px 128px #fff, 1980px 1030px #fff, 1850px 302px #fff, 1074px 922px #fff, 174px 403px #fff, 1579px 733px #fff, 653px 1958px #fff, 1511px 1943px #fff, 1037px 741px #fff, 602px 1384px #fff, 103px 402px #fff, 1722px 1417px #fff, 1732px 1916px #fff, 1743px 1803px #fff, 381px 721px #fff, 964px 1700px #fff, 1070px 341px #fff, 1376px 1258px #fff, 1884px 570px #fff, 940px 280px #fff, 1484px 1658px #fff, 1806px 1875px #fff, 1054px 917px #fff, 1672px 103px #fff, 783px 574px #fff, 98px 347px #fff, 555px 1136px #fff, 1403px 1237px #fff, 1203px 339px #fff, 572px 35px #fff, 932px 1783px #fff, 1527px 1850px #fff, 1959px 1109px #fff, 892px 623px #fff, 211px 1388px #fff, 1581px 1806px #fff, 868px 1053px #fff, 1243px 1997px #fff, 1004px 522px #fff, 1241px 1707px #fff, 376px 282px #fff, 537px 878px #fff, 1948px 979px #fff, 532px 688px #fff, 273px 958px #fff, 581px 927px #fff, 1060px 887px #fff, 486px 1467px #fff, 1122px 1834px #fff, 1650px 1763px #fff, 532px 302px #fff, 314px 1111px #fff, 1888px 683px #fff, 1856px 1040px #fff, 1780px 1338px #fff, 24px 1564px #fff, 1096px 1808px #fff, 1202px 1968px #fff, 214px 992px #fff, 728px 515px #fff, 247px 278px #fff, 1670px 45px #fff, 442px 1579px #fff, 1143px 30px #fff, 612px 72px #fff, 1177px 1303px #fff, 1898px 1255px #fff, 378px 1667px #fff, 326px 1929px #fff, 1257px 766px #fff, 1363px 1170px #fff, 1090px 1667px #fff, 711px 293px #fff, 249px 1406px #fff, 1589px 565px #fff, 1451px 29px #fff, 1171px 1459px #fff, 1294px 1214px #fff, 342px 942px #fff, 1945px 353px #fff, 741px 1185px #fff, 894px 1453px #fff, 593px 1584px #fff, 518px 630px #fff, 393px 756px #fff, 34px 608px #fff; } body.DarkMode #stars2 { width: 2px; height: 2px; background: 0 0; box-shadow: 114px 658px #fff, 236px 768px #fff, 1130px 1503px #fff, 486px 592px #fff, 1353px 1407px #fff, 1583px 1741px #fff, 450px 1479px #fff, 1845px 327px #fff, 1520px 361px #fff, 580px 1699px #fff, 1277px 1233px #fff, 1697px 943px #fff, 568px 1135px #fff, 1273px 263px #fff, 788px 126px #fff, 1834px 1911px #fff, 1147px 1652px #fff, 651px 567px #fff, 79px 1897px #fff, 1590px 666px #fff, 1362px 566px #fff, 275px 367px #fff, 556px 479px #fff, 1063px 476px #fff, 1337px 1119px #fff, 1780px 1109px #fff, 1323px 1655px #fff, 1740px 1165px #fff, 525px 60px #fff, 1513px 1484px #fff, 708px 280px #fff, 429px 475px #fff, 563px 1360px #fff, 1580px 697px #fff, 1702px 1164px #fff, 1649px 1952px #fff, 1580px 1812px #fff, 70px 1190px #fff, 1100px 98px #fff, 1232px 1896px #fff, 851px 1047px #fff, 851px 30px #fff, 596px 1486px #fff, 666px 526px #fff, 1855px 1342px #fff, 80px 531px #fff, 248px 1804px #fff, 1990px 263px #fff, 1796px 1640px #fff, 1502px 862px #fff, 1780px 488px #fff, 1881px 1191px #fff, 1063px 876px #fff, 1614px 1073px #fff, 1414px 666px #fff, 1865px 289px #fff, 687px 352px #fff, 1329px 1312px #fff, 279px 136px #fff, 475px 756px #fff, 1177px 435px #fff, 1264px 921px #fff, 467px 1496px #fff, 391px 1359px #fff, 666px 1083px #fff, 1526px 1251px #fff, 594px 564px #fff, 991px 525px #fff, 1511px 875px #fff, 1935px 1049px #fff, 1471px 1430px #fff, 959px 604px #fff, 1685px 72px #fff, 1505px 1876px #fff, 509px 1627px #fff, 1065px 978px #fff, 1860px 884px #fff, 1038px 464px #fff, 1051px 106px #fff, 1056px 728px #fff, 1953px 45px #fff, 1483px 638px #fff, 559px 845px #fff, 1184px 922px #fff, 1320px 1117px #fff, 1572px 747px #fff, 1971px 43px #fff, 665px 13px #fff, 1457px 1153px #fff, 848px 154px #fff, 1039px 1837px #fff, 878px 795px #fff, 1286px 1705px #fff, 1946px 1143px #fff, 1114px 1166px #fff, 1747px 874px #fff, 1894px 636px #fff, 1316px 541px #fff, 1953px 1620px #fff, 1446px 1773px #fff, 974px 833px #fff, 1814px 1211px #fff, 102px 335px #fff, 327px 1868px #fff, 348px 548px #fff, 353px 1540px #fff, 1212px 1872px #fff, 1968px 129px #fff, 1531px 644px #fff, 1939px 559px #fff, 1397px 1876px #fff, 1446px 1446px #fff, 1721px 603px #fff, 924px 1171px #fff, 1086px 1954px #fff, 1798px 310px #fff, 21px 1595px #fff, 1462px 1948px #fff, 149px 1752px #fff, 804px 318px #fff, 1262px 636px #fff, 1051px 100px #fff, 392px 560px #fff, 654px 1236px #fff, 1889px 1159px #fff, 498px 394px #fff, 522px 1889px #fff, 1198px 579px #fff, 1437px 1866px #fff, 1049px 1064px #fff, 286px 921px #fff, 993px 1790px #fff, 1557px 1997px #fff, 1525px 532px #fff, 481px 1561px #fff, 790px 683px #fff, 141px 17px #fff, 1202px 28px #fff, 518px 1927px #fff, 90px 1677px #fff, 1258px 370px #fff, 1379px 1536px #fff, 607px 474px #fff, 163px 139px #fff, 1025px 1359px #fff, 815px 845px #fff, 231px 1212px #fff, 192px 806px #fff, 313px 1946px #fff, 1132px 1808px #fff, 624px 767px #fff, 379px 722px #fff, 733px 1847px #fff, 628px 1517px #fff, 1559px 929px #fff, 234px 397px #fff, 1230px 1231px #fff, 849px 726px #fff, 1148px 786px #fff, 546px 1533px #fff, 477px 822px #fff, 1325px 480px #fff, 972px 383px #fff, 334px 958px #fff, 1032px 664px #fff, 1781px 40px #fff, 38px 1335px #fff, 1634px 1691px #fff, 1061px 680px #fff, 1319px 304px #fff, 82px 1776px #fff, 1302px 509px #fff, 1231px 746px #fff, 1264px 1509px #fff, 980px 495px #fff, 1153px 1381px #fff, 1981px 1918px #fff, 70px 113px #fff, 390px 736px #fff, 1882px 1925px #fff, 1380px 1326px #fff, 257px 1681px #fff, 860px 998px #fff, 518px 1136px #fff, 168px 905px #fff, 500px 1882px #fff, 1012px 1572px #fff, 349px 1916px #fff, 905px 1339px #fff, 1940px 1803px #fff, 23px 1159px #fff, 9px 1559px #fff, 1658px 776px #fff, 820px 1361px #fff, 171px 983px #fff, 580px 1902px #fff, 1268px 263px #fff, 1734px 994px #fff, 1872px 29px #fff, 1475px 435px #fff; animation: animStar 100s linear infinite; } body.DarkMode #stars2:after { content: " "; position: absolute; top: 2000px; width: 2px; height: 2px; background: 0 0; box-shadow: 114px 658px #fff, 236px 768px #fff, 1130px 1503px #fff, 486px 592px #fff, 1353px 1407px #fff, 1583px 1741px #fff, 450px 1479px #fff, 1845px 327px #fff, 1520px 361px #fff, 580px 1699px #fff, 1277px 1233px #fff, 1697px 943px #fff, 568px 1135px #fff, 1273px 263px #fff, 788px 126px #fff, 1834px 1911px #fff, 1147px 1652px #fff, 651px 567px #fff, 79px 1897px #fff, 1590px 666px #fff, 1362px 566px #fff, 275px 367px #fff, 556px 479px #fff, 1063px 476px #fff, 1337px 1119px #fff, 1780px 1109px #fff, 1323px 1655px #fff, 1740px 1165px #fff, 525px 60px #fff, 1513px 1484px #fff, 708px 280px #fff, 429px 475px #fff, 563px 1360px #fff, 1580px 697px #fff, 1702px 1164px #fff, 1649px 1952px #fff, 1580px 1812px #fff, 70px 1190px #fff, 1100px 98px #fff, 1232px 1896px #fff, 851px 1047px #fff, 851px 30px #fff, 596px 1486px #fff, 666px 526px #fff, 1855px 1342px #fff, 80px 531px #fff, 248px 1804px #fff, 1990px 263px #fff, 1796px 1640px #fff, 1502px 862px #fff, 1780px 488px #fff, 1881px 1191px #fff, 1063px 876px #fff, 1614px 1073px #fff, 1414px 666px #fff, 1865px 289px #fff, 687px 352px #fff, 1329px 1312px #fff, 279px 136px #fff, 475px 756px #fff, 1177px 435px #fff, 1264px 921px #fff, 467px 1496px #fff, 391px 1359px #fff, 666px 1083px #fff, 1526px 1251px #fff, 594px 564px #fff, 991px 525px #fff, 1511px 875px #fff, 1935px 1049px #fff, 1471px 1430px #fff, 959px 604px #fff, 1685px 72px #fff, 1505px 1876px #fff, 509px 1627px #fff, 1065px 978px #fff, 1860px 884px #fff, 1038px 464px #fff, 1051px 106px #fff, 1056px 728px #fff, 1953px 45px #fff, 1483px 638px #fff, 559px 845px #fff, 1184px 922px #fff, 1320px 1117px #fff, 1572px 747px #fff, 1971px 43px #fff, 665px 13px #fff, 1457px 1153px #fff, 848px 154px #fff, 1039px 1837px #fff, 878px 795px #fff, 1286px 1705px #fff, 1946px 1143px #fff, 1114px 1166px #fff, 1747px 874px #fff, 1894px 636px #fff, 1316px 541px #fff, 1953px 1620px #fff, 1446px 1773px #fff, 974px 833px #fff, 1814px 1211px #fff, 102px 335px #fff, 327px 1868px #fff, 348px 548px #fff, 353px 1540px #fff, 1212px 1872px #fff, 1968px 129px #fff, 1531px 644px #fff, 1939px 559px #fff, 1397px 1876px #fff, 1446px 1446px #fff, 1721px 603px #fff, 924px 1171px #fff, 1086px 1954px #fff, 1798px 310px #fff, 21px 1595px #fff, 1462px 1948px #fff, 149px 1752px #fff, 804px 318px #fff, 1262px 636px #fff, 1051px 100px #fff, 392px 560px #fff, 654px 1236px #fff, 1889px 1159px #fff, 498px 394px #fff, 522px 1889px #fff, 1198px 579px #fff, 1437px 1866px #fff, 1049px 1064px #fff, 286px 921px #fff, 993px 1790px #fff, 1557px 1997px #fff, 1525px 532px #fff, 481px 1561px #fff, 790px 683px #fff, 141px 17px #fff, 1202px 28px #fff, 518px 1927px #fff, 90px 1677px #fff, 1258px 370px #fff, 1379px 1536px #fff, 607px 474px #fff, 163px 139px #fff, 1025px 1359px #fff, 815px 845px #fff, 231px 1212px #fff, 192px 806px #fff, 313px 1946px #fff, 1132px 1808px #fff, 624px 767px #fff, 379px 722px #fff, 733px 1847px #fff, 628px 1517px #fff, 1559px 929px #fff, 234px 397px #fff, 1230px 1231px #fff, 849px 726px #fff, 1148px 786px #fff, 546px 1533px #fff, 477px 822px #fff, 1325px 480px #fff, 972px 383px #fff, 334px 958px #fff, 1032px 664px #fff, 1781px 40px #fff, 38px 1335px #fff, 1634px 1691px #fff, 1061px 680px #fff, 1319px 304px #fff, 82px 1776px #fff, 1302px 509px #fff, 1231px 746px #fff, 1264px 1509px #fff, 980px 495px #fff, 1153px 1381px #fff, 1981px 1918px #fff, 70px 113px #fff, 390px 736px #fff, 1882px 1925px #fff, 1380px 1326px #fff, 257px 1681px #fff, 860px 998px #fff, 518px 1136px #fff, 168px 905px #fff, 500px 1882px #fff, 1012px 1572px #fff, 349px 1916px #fff, 905px 1339px #fff, 1940px 1803px #fff, 23px 1159px #fff, 9px 1559px #fff, 1658px 776px #fff, 820px 1361px #fff, 171px 983px #fff, 580px 1902px #fff, 1268px 263px #fff, 1734px 994px #fff, 1872px 29px #fff, 1475px 435px #fff; } body.DarkMode #stars3 { width: 3px; height: 3px; background: 0 0; box-shadow: 519px 875px #fff, 1497px 751px #fff, 1256px 88px #fff, 1168px 1791px #fff, 1884px 109px #fff, 1465px 451px #fff, 450px 370px #fff, 1560px 703px #fff, 1788px 1997px #fff, 1047px 963px #fff, 1281px 119px #fff, 439px 96px #fff, 164px 1956px #fff, 1360px 930px #fff, 1387px 347px #fff, 1073px 1970px #fff, 1296px 284px #fff, 25px 1602px #fff, 455px 944px #fff, 1177px 738px #fff, 633px 1142px #fff, 1730px 1079px #fff, 1283px 1606px #fff, 674px 1186px #fff, 513px 166px #fff, 1077px 636px #fff, 1811px 580px #fff, 971px 1789px #fff, 694px 1756px #fff, 703px 1138px #fff, 1290px 942px #fff, 351px 1509px #fff, 1904px 790px #fff, 68px 819px #fff, 1097px 362px #fff, 1035px 331px #fff, 180px 940px #fff, 1776px 1229px #fff, 1487px 781px #fff, 1131px 1765px #fff, 1684px 536px #fff, 939px 367px #fff, 1102px 1481px #fff, 741px 887px #fff, 167px 1132px #fff, 1756px 529px #fff, 608px 758px #fff, 541px 1025px #fff, 1976px 505px #fff, 1349px 1257px #fff, 815px 1388px #fff, 505px 1351px #fff, 33px 1945px #fff, 861px 1695px #fff, 678px 1360px #fff, 1615px 727px #fff, 1138px 726px #fff, 30px 293px #fff, 1624px 1044px #fff, 683px 1242px #fff, 1781px 1758px #fff, 906px 1328px #fff, 1066px 1764px #fff, 1568px 664px #fff, 1027px 1876px #fff, 775px 1099px #fff, 1605px 208px #fff, 730px 837px #fff, 1475px 1482px #fff, 871px 1759px #fff, 1240px 15px #fff, 1987px 705px #fff, 302px 1049px #fff, 475px 1015px #fff, 1843px 1296px #fff, 493px 631px #fff, 1613px 164px #fff, 1863px 156px #fff, 1479px 423px #fff, 202px 1499px #fff, 886px 969px #fff, 904px 930px #fff, 1853px 535px #fff, 726px 914px #fff, 435px 1205px #fff, 1732px 1824px #fff, 1212px 667px #fff, 499px 31px #fff, 552px 594px #fff, 1715px 1814px #fff, 775px 908px #fff, 1949px 921px #fff, 1267px 718px #fff, 1830px 1960px #fff, 338px 1325px #fff, 466px 1120px #fff, 140px 1675px #fff, 1919px 664px #fff, 1136px 771px #fff, 1888px 1302px #fff; animation: animStar 150s linear infinite; } body.DarkMode #stars3:after { content: " "; position: absolute; top: 2000px; width: 3px; height: 3px; background: 0 0; box-shadow: 519px 875px #fff, 1497px 751px #fff, 1256px 88px #fff, 1168px 1791px #fff, 1884px 109px #fff, 1465px 451px #fff, 450px 370px #fff, 1560px 703px #fff, 1788px 1997px #fff, 1047px 963px #fff, 1281px 119px #fff, 439px 96px #fff, 164px 1956px #fff, 1360px 930px #fff, 1387px 347px #fff, 1073px 1970px #fff, 1296px 284px #fff, 25px 1602px #fff, 455px 944px #fff, 1177px 738px #fff, 633px 1142px #fff, 1730px 1079px #fff, 1283px 1606px #fff, 674px 1186px #fff, 513px 166px #fff, 1077px 636px #fff, 1811px 580px #fff, 971px 1789px #fff, 694px 1756px #fff, 703px 1138px #fff, 1290px 942px #fff, 351px 1509px #fff, 1904px 790px #fff, 68px 819px #fff, 1097px 362px #fff, 1035px 331px #fff, 180px 940px #fff, 1776px 1229px #fff, 1487px 781px #fff, 1131px 1765px #fff, 1684px 536px #fff, 939px 367px #fff, 1102px 1481px #fff, 741px 887px #fff, 167px 1132px #fff, 1756px 529px #fff, 608px 758px #fff, 541px 1025px #fff, 1976px 505px #fff, 1349px 1257px #fff, 815px 1388px #fff, 505px 1351px #fff, 33px 1945px #fff, 861px 1695px #fff, 678px 1360px #fff, 1615px 727px #fff, 1138px 726px #fff, 30px 293px #fff, 1624px 1044px #fff, 683px 1242px #fff, 1781px 1758px #fff, 906px 1328px #fff, 1066px 1764px #fff, 1568px 664px #fff, 1027px 1876px #fff, 775px 1099px #fff, 1605px 208px #fff, 730px 837px #fff, 1475px 1482px #fff, 871px 1759px #fff, 1240px 15px #fff, 1987px 705px #fff, 302px 1049px #fff, 475px 1015px #fff, 1843px 1296px #fff, 493px 631px #fff, 1613px 164px #fff, 1863px 156px #fff, 1479px 423px #fff, 202px 1499px #fff, 886px 969px #fff, 904px 930px #fff, 1853px 535px #fff, 726px 914px #fff, 435px 1205px #fff, 1732px 1824px #fff, 1212px 667px #fff, 499px 31px #fff, 552px 594px #fff, 1715px 1814px #fff, 775px 908px #fff, 1949px 921px #fff, 1267px 718px #fff, 1830px 1960px #fff, 338px 1325px #fff, 466px 1120px #fff, 140px 1675px #fff, 1919px 664px #fff, 1136px 771px #fff, 1888px 1302px #fff; } 这样黑夜模式算是真正完成了 Tag标签外挂使用方法 Tag标签外挂使用方法 {%r%} 紅色 {%endr%} {%g%} 綠色 {%endg%} {%y%} 黃色 {%endy%} 屏蔽网页源码(单纯的屏蔽鼠标右键和键盘事件) 在 themes/matery/layout/layout.ejs 添加如下代码 <script type="text/javascript"> window.onload = function(){ //屏蔽键盘事件 document.onkeydown = function (){ var e = window.event || arguments[0]; //F12 if(e.keyCode == 123){ return false; //Ctrl+Shift+I }else if((e.ctrlKey) && (e.shiftKey) && (e.keyCode == 73)){ return false; //Shift+F10 }else if((e.shiftKey) && (e.keyCode == 121)){ return false; //Ctrl+U }else if((e.ctrlKey) && (e.keyCode == 85)){ return false; } }; //屏蔽鼠标右键 document.oncontextmenu = function (){ return false; } } </script> 添加天气小插件 首先去中国天气官网:,配置自己的插件,选择自定义插件—>自定义样式——>生成代码,然后会生成一段代码,复制粘贴到 themes/matery/layout/layout.ejs 即可。 新增个人相册 这个功能,已经由博主上传到官方develop分支了 看下面配置使用方法就好,代码不用修改直接使用! 新建相册目录 执行下面的命令: hexo new page galleries 然后到站点根目录的 source 目录下找名称为 galleries 的目录,打开目录下的 **index.md ** 文档,在原有基础上添加一下配置: type: "galleries" layout: "galleries" 紧接着,在主题配置文件的 menu 属性添加关于相册的菜单 相册: url: /galleries icon: fas fa-image 如果需要添加到二级菜单,添加格式为: - name: 相册 url: /galleries icon: fas fa-image 添加 ejs 文件和 css 文件 首先新建 gallery.css,填写的代码内容如下: .gallery-wrapper{ padding-top: 30px; } .gallery-wrapper .gallery-box{ padding: 5px !important; } .gallery-wrapper .gallery-item { display: block; overflow: hidden; background-color: #fff; padding: 5px; padding-bottom: 0; position: relative; -moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); } .gallery-cover-box{ width: 100%; padding-top: 60%; text-align: center; overflow: hidden; position: relative; background: center center no-repeat; -webkit-background-size: cover; background-size: cover; } .gallery-cover-box .gallery-cover-img { display: inline-block; width: 100%; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); } .gallery-item .gallery-name{ font-size: 14px; line-height: 24px; text-align: center; color: #666; margin: 0; } .waterfall { column-count: 3; column-gap: 1em; } .photo-wrapper{ padding-top: 20px; } .photo-item { display: block; padding: 10px; padding-bottom: 0; margin-bottom: 14px; font-size: 0; -moz-page-break-inside: avoid; -webkit-column-break-inside: avoid; break-inside: avoid; background: white; -moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22); } .photo-item img { width: 100%; } .photo-item .photo-name{ font-size: 14px; line-height: 30px; text-align: center; margin-top: 10px; margin-bottom: 10px; border-top: 1px solid #dddddd; } /*适配移动端布局*/ @media only screen and (max-width: 601px) { .waterfall { column-count: 2; column-gap: 1em; } } 然后保存,将此文件放在主题目录下,路径为 matery/source/css。 紧接着,新建 galleries.ejs 文件,添加以下代码: <link rel="stylesheet" href="/css/gallery.css"> <%- partial('_partial/bg-cover') %> <main class="content"> <div class="container"> <% if (site.data && site.data.galleries) { %> <% var galleries = site.data.galleries; %> <div class="gallery-wrapper row"> <% for (var i = 0, len = galleries.length; i < len; i++) { %> <% var gallery = galleries[i]; %> <div class="col s6 m4 l4 xl3 gallery-box"> <a href="./<%- gallery.name %>" class="gallery-item" data-aos="zoom-in-up"> <div class="gallery-cover-box" style="background-image: url(<%- theme.jsDelivr.url %><%- gallery.cover%>);"> </div> <p class="gallery-name"> <%- gallery.name %> </p> </a> </div> <% } %> </div> <% } %> </div> </main> 将此文件放在 matery/layout 目录下,同时再此目录下接着新建 gallery.ejs 文件,添加以下代码: <link rel="stylesheet" href="/css/gallery.css"> <link type="text/css" href="/libs/fancybox/jquery.fancybox.css" rel="stylesheet"> <link type="text/css" href="/libs/justifiedGallery/justifiedGallery.min.css" rel="stylesheet"> <%- partial('_partial/post-cover') %> <% let galleries = []; if (site.data && site.data.galleries) { galleries = site.data.galleries; } var pageTitle = page.title; function getCurrentGallery(galleries, pageTitle) { for (let i = 0; i < galleries.length; i++) { if (galleries[i]['name'] == pageTitle) { return galleries[i]; } } } var currentGallery = getCurrentGallery(galleries, pageTitle) var photos = currentGallery.photos; var galleryImageStr = theme.jsDelivr.url ? theme.jsDelivr.url : ''; let imageStr = '' for (var i = 0, len = photos.length; i < len; i++) { var photo = photos[i]; imageStr += "<a href=\"" + galleryImageStr + photo + "\"" + " class=\"photo-item\" rel=\"example_group\"" + " data-fancybox=\"images\">" + " <img src=\"" + galleryImageStr + photo + "\"" + " alt=" + photo + ">\n" + " </a>" } %> <div class="container"> <div class="photo-wrapper"> <% if (page.password ) { %> <script src="/js/crypto-js.js"></script> <script src="/js/gallery-encrypt.js"></script> <div id="hbe-security"> <div class="hbe-input-container"> <input type="password" class="hbe-form-control" id="pass" placeholder="请输入密码查看内容"/> <a href="javascript:;" class="btn-decrypt" id="btn_decrypt">解密</a> </div> </div> <div id="mygallery"> <div class="waterfall" id="encrypt-blog" style="display:none"> <%- aes(imageStr, page.password) %> </div> </div> <% } else { %> <div class="waterfall" id="encrypt-blog"> <%- imageStr %> </div> <% } %> </div> </div> <script src="/libs/fancybox/fancybox.js"></script> <script src="/libs/justifiedGallery/justifiedGallery.min.js"></script> <script> $("a[rel=example_group]").fancybox(); $("#encrypt-blog").justifiedGallery({margins: 5, rowHeight: 150}); </script> 注意: 需要几个文件,我把文件地址放在下面,用浏览器打开链接,就会显示出代码,然后复制粘贴到文加中去就行。开头的是文件路径,如果没有的话,就新建一个就 OK 了。 libs/fancybox/jquery.fancybox.css: </libs/fancybox/jquery.fancybox.css> libs/justifiedGallery/justifiedGallery.min.css: </libs/justifiedGallery/justifiedGallery.min.css> matery/source/js/crypto-js.js: </js/crypto-js.js> matery/source/js/gallery-encrypt.js: </js/gallery-encrypt.js> libs/fancybox/fancybox.js: </libs/fancybox/fancybox.js> libs/justifiedGallery/justifiedGallery.min.js: </libs/justifiedGallery/justifiedGallery.min.js> 添加相册 json 配置文件 在站点目录 source/_data/ 下新建一个 galleries.json 的文件,json 代码如下: [ { "name": "2020", "cover": "/medias_webp/images/01.webp", "description": "我的图床", "photos": [ "/medias_webp/images/01.webp", "/medias_webp/images/02.webp", "/medias_webp/images/03.webp" ] }, { "name": "2021", "cover": "/medias_webp/featureimages/1.webp", "description": "featureimages 图片展示", "photos": [ "/medias_webp/featureimages/1.webp", "/medias_webp/featureimages/2.webp", "/medias_webp/featureimages/3.webp", "/medias_webp/featureimages/4.webp", ] }, { "name": "2022", "cover": "/medias_webp/banner/0.webp", "description": "banner 图片展示", "photos": [ "/medias_webp/banner/0.webp", "/medias_webp/banner/1.webp", "/medias_webp/banner/2.webp", ] } ] 字段含义: name 是相册标题 cover 是封面图片 description 是相册介绍 photos 是图片列表 配置文件建好了之后还没完,只剩最后一个步骤了,在 galleries 目录下建立对应的相册名称目录和文件,比如我这个相册需要新建名称为 2020 目录,然后下面再分别新建 index.md 文件,2020/index.md文件内容为: --- title: 2020 date: 2021-10-13 10:51:50 type: "gallery" layout: "gallery" --- 2021/index.md,2022/index.md文件内容和上面一样,只是title修改不同而已 galleries 目录结构 galleries ├── 2020 │   └── index.md ├── 2021 │   └── index.md ├── 2022 │   └── index.md ├── index.md 查看效果 完成以上步骤,执行命令,在本地查看效果: hexo clean && hexo g && hexo s 我的效果 支持RSS分类订阅 这个功能个人使用很久了,但是原作者插件不支持hexo6, Hexo 6 强制使用的时候,会影响很多基础功能。 这次测试Npm包发布,就拿这个插件练手了! Github 地址 hexo-feed-new NPM 地址 hexo-feed-new 或者直接访问我的博客查看效果! 重要注意.需要安装 hexo-generator-tag 和 hexo-generator-category 插件用来生成 tag/category feeds. 安装 npm install hexo-feed-new --save-dev 配置 feed: limit: 20 order_by: "-date" tag_dir: "tag" category_dir: "category" rss: enable: true template: "themes/theme/layout/_alternate/rss.ejs" output: "rss.xml" atom: enable: true template: "themes/theme/layout/_alternate/atom.ejs" output: "atom.xml" jsonFeed: enable: true template: "themes/theme/layout/_alternate/json.ejs" output: "feed.json" Key Required Default value Description limit false 0 Post count that will be presented in the feed. Use 0 to publish all posts to the feed. order_by false -date Sorting order for the posts. tag_dir false tag Directory name to publish all tag-related feeds. Set false to avoid generating feeds by tag. For more information see below. category_dir false category Directory name to publish all category-related feeds. Set false to avoid generating feeds by category. For more information see below. rss.enable false true Enable/disable RSS feed generating. rss.template false Path to custom template for the RSS feed. rss.output false rss.xml Output filename for RSS feed. atom.enable false true Enable/disable ATOM feed generating. atom.template false Path to custom template for the ATOM feed. atom.output false atom.xml Output filename for ATOM feed. jsonFeed.enable false true Enable/disable JSON feed generating. jsonFeed.template false Path to custom template for the JSON feed. jsonFeed.output false feed.json Output filename for JSON feed. 添加feed <html> <head> <!-- ... --> <link rel="alternate" type="application/rss+xml" title="<%= config.title %>" href="<%= full_url_for(`/rss.xml}`) %>" /> <link rel="alternate" type="application/atom+xml" title="<%= config.title %>" href="<%= full_url_for(`/atom.xml`) %>" /> <link rel="alternate" type="application/json" title="<%= config.title %>" href="<%= full_url_for(`/feed.json`) %>" /> </head> <body> <!-- ... --> </body> </html> 豆瓣书单电影页面 1.首先在博客站点目录执行下面的命令安装豆瓣插件: npm install hexo-douban --save 2.紧接着在博客站点目录的配置文件_config.yml下,添加如下配置: douban: user: 123456789 #这个需要修改为你个人的id builtin: true book: title: '我的书单' quote: '你必须要看的书籍' movie: title: '我的影单' quote: '那些年我们一起看过的电影' timeout: 10000 user::你的豆瓣ID。打开豆瓣,登入账户,然后在右上角点击 ”个人主页“,这时候地址栏的URL大概是这样:https://www.douban.com/people/xxxxxx/ ,其中的”xxxxxx”就是你的个人ID了。 builtin:是否将生成页面的功能嵌入 hexo s 和 hexo g 中,默认是 false ,另一可选项为 true 。 title: 该页面的标题。 quote: 写在页面开头的一段话,支持html语法。 timeout: 爬取数据的超时时间,默认是 10000ms,如果在使用时发现报了超时的错(ETIMEOUT)可以把这个数据设置的大一点。 如果只想显示某一个页面(比如movie),那就把其他的配置项注释掉即可。 3.然后再主题配置文件_config.yml中添加关于此页面的菜单:(下面是我的配置) 媒体: icon: fas fa-list children: - name: 电影 url: /movies icon: fas fa-film - name: 书单 url: /books icon: fas fa-book 4.适配Matery主题:在 /themes/hexo-theme-matery/layout 文件夹下面创建一个名为 douban.ejs 的文件,并将下面的内容复制进去: <%- partial('_partial/post-cover') %> <style> .hexo-douban-picture img { width: 100%; } </style> <main class="content"> <div id="contact" class="container chip-container"> <div class="card"> <div class="card-content" style="padding: 30px"> <h1 style="margin: 10px 0 10px 0px;"><%= page.title %></h1> <%- page.content %> </div> </div> <div class="card"> <div class="card-content" style="text-align: center"> <h3 style="margin: 5px 0 5px 5px;">如果你有好的内容推荐,欢迎在下面留言!</h3> </div> </div> <div class="card"> <% if (theme.gitalk && theme.gitalk.enable) { %> <%- partial('_partial/gitalk') %> <% } %> <% if (theme.gitment.enable) { %> <%- partial('_partial/gitment') %> <% } %> <% if (theme.disqus.enable) { %> <%- partial('_partial/disqus') %> <% } %> <% if (theme.livere && theme.livere.enable) { %> <%- partial('_partialvere') %> <% } %> <% if (theme.valine && theme.valine.enable) { %> <%- partial('_partialaline') %> <% } %> </div> </div> </main> 5.然后在博客站点目录下的node_modules文件夹下找到hexo-douban/lib,文件夹下有三个js文件,分别为:books-generator.js 、games-generator.js 、movies-generator.js,用文本编辑器打开这三个文件,并将其文件内容末尾的代码修改为一下内容: /* 原文件内容为 layout: [`page`, `post`] ,将其修改为下面的内容*/ layout: [`page`, `douban`] 6.最后就是使用并生成相应的页面,执行命令如下: hexo douban 需要注意的是,通常大家都喜欢用 hexo d 来作为 hexo deploy 命令的简化,但是当安装了 hexo douban 之后,就不能用 hexo d 了,因为 hexo douban 跟 hexo deploy 的前缀都是 hexo d ,你以后执行的 hexo d 将不再是 Hexo 页面的生成,而是豆瓣页面的生成。 以下是可选的命令参数: -h, --help # 帮助页面 -b, --books # 只生成书单页面 -g, --games # 只生成游戏页面 -m, --movies # 只生成电影页面 当站点配置文件的builtin的值为true时,生成页面的功能会嵌入到hexo g和hexo s中,在进行部署生成操作,会自动生成相应的页面。 新增折叠功能 这里利用hexo-sliding-spoiler插件间接实现折叠功能,在matery主题中零修改源代码实现折叠功能。 另一种修改代码实现折叠效果,参考Hexo next博客添加折叠块功能添加折叠代码块。 安装插件 npm install hexo-sliding-spoiler --save 配置插件 根目录配置文件_config.yml中添加 plugin: - hexo-sliding-spoiler 到这里已经实现折叠功能了。 进一步完善美化 修改node_modules_hexo-sliding-spoiler@1.2.1@hexo-sliding-spoiler\assets\spoiler.css .spoiler { margin: 20px 0; padding: 15px; border: 1px solid #E5E5E5; background: #E5E5E5; position: relative; clear: both; border-radius: 3px; transition:all .6s } .spoiler .spoiler-title { margin: 0 -15px; padding: 5px 15px; color: #353535; font-weight: bold; font-size: 18px; display: block; cursor: pointer; } .spoiler.collapsed .spoiler-title:before { content: "▶ "; } .spoiler.expanded .spoiler-title:before { content: "▼ "; } 使用方法 {% spoiler title %} content {% endspoiler %} 实例 {% spoiler 点击显/隐内容 %} 内容测试 {% endspoiler %} {% spoiler 点击显/隐内容 %} 内容测试 {% endspoiler %} 代码块全屏显示 最新发现引用的博客文章消失了,如实找到原来的git修改记录,提取出代码块全屏显示的方法给大家 原理简单,通过 JS 添加删除属性,使用 CSS 控制显示和动画效果 .code-area.code-block-fullscreen pre { overflow: auto; max-height: unset; overflow: auto; width: 100%; height: 100%; min-width: 100%; } /* code-block-fullscreen */ .code-block-fullscreen { position:fixed; top:-0.4em; left:0; width:100%; height:100%; min-width:100%; z-index: 999999; margin:0; animation: elastic 1s; } .code-block-fullscreen code { --widthA:100%; --widthB:calc(var(--widthA) - 30px); height:var(--widthB); min-height:99%; overflow-y:hidden; overflow-x:auto; height:auto; } .code-block-fullscreen-html-scroll { overflow: hidden; } .code-area.code-block-fullscreen i.code-expand, .code-area.code-block-fullscreen .scroll-down-bar { display: none; } .code-show-expand { position: absolute; top: 4px; right: 53px; z-index: 1; filter: invert(50%); cursor: pointer; padding: 7px; } if (enableShowexpand) { var $code_show_expand = $('<i class="fas fa-expand code-show-expand" title="全屏显示" aria-hidden="true"></i>'); $pre.before($code_show_expand); $('.code-area .code-show-expand').on('click', function (e) { if (e.target !== this) return if ($(this).parent().hasClass('code-closed')) { $(this).siblings('pre').find('code').show(); $(this).parent().removeClass('code-closed'); } $(this).parent().toggleClass('code-block-fullscreen') $('html').toggleClass('code-block-fullscreen-html-scroll') }); } TOC目录展开收缩的小箭头 效果展示 代码 $(function(){ // 切换TOC目录展开收缩的相关操作. const expandedClass = 'expanded'; let $tocAside = $('#toc-aside'); let $mainContent = $('#main-content'); $('#floating-toc-btn .btn-floating').click(function () { if ($tocAside.hasClass(expandedClass)) { $tocAside.removeClass(expandedClass).hide(); $mainContent.removeClass('l9'); } else { $tocAside.addClass(expandedClass).show(); $mainContent.addClass('l9'); } fixPostCardWidth('artDetail', 'prenext-posts'); }); let $itemHasChild = $(".toc-list-item:has(> .toc-list)"); $itemHasChild.prepend("<i class='fa fa-caret-down'></i><i class='fa fa-caret-right'></i><span> </span>"); let $iconToFold = $(".toc-list-item > .fa-caret-down"); let $iconToExpand = $(".toc-list-item > .fa-caret-right"); $iconToFold.addClass("hide"); const targetNodes = document.getElementsByClassName("toc-list-item"); const config = { attributes: true, childList: false, subtree: false }; const callback = function(mutationsList, observer) { for(let mutation of mutationsList) { if (mutation.type === "attributes") { let target = $(mutation.target) if (target.hasClass("is-active-li")) { let $toFold = $(".toc-list-item > .fa-caret-down"); let $toExpand = $(".toc-list-item > .fa-caret-right"); $toFold.addClass("hide"); $toExpand.removeClass("hide"); target.children(".fa-caret-right").first().addClass("hide") target.children(".fa-caret-down").first().removeClass("hide") let parents = target.parents(".toc-list-item") for (p of parents) { $(p).children(".fa-caret-right").first().addClass("hide") $(p).children(".fa-caret-down").first().removeClass("hide") } } } } }; const observer = new MutationObserver(callback); for (node of targetNodes) { observer.observe(node, config) } }); 如何使用 我先简单介绍一下上面的代码。代码使用了 Jquery,以及font awesome,不过hexo的主题应该都有这些 代码的逻辑是,在网页加载完毕后,给TOC目录的分级菜单加入小箭头,并创建MutationObserver来监听属性变化,因为属性变化不是事件,所以并不能以事件监听的形式处理 那么这段代码该放到哪里呢? 代码是在网页加载完毕后执行的,那么和网页本身的代码无关,只和网页展示内容有关。你想要加在文章的TOC目录,总不能把这段代码放到分类页面去吧。 而hexo主题用的都是模板引擎,例如 ejs、swig。通常一个页面都会被拆分为 header,footer 等 所以只要加在任意一个,文章包含的模板即可,但是最好还是加在文章独属的模板 模板位于\layout\_partial 目录,下面讲解的是 ejs 怎么放,swig 可能也差不多 如果你不知道怎么找文章独属的模板 那就在目录下面一个一个添加呗,哪个有效了就行 方法很简单,直接把文件拉到底下,写一个新的 script 标签,把代码复制进去即可 <script> 复制代码过来 </script> 如果你能找到TOC或者文章独属的模板 操作方法和上面一样,区别是你的网站性能会提高。因为这段代码仅在需要加载的地方加载 更加推荐的是,加上模板引擎的判断逻辑 <% if (theme.toc.enable && theme.toc.showToggleBtn) { %> 代码 <% } %> theme 对象是主题的配置文件_config.yml,toc 是其中的属性,enable 控制 toc 是否显示 让Hexo博客支持通知功能 更新文章后,自动发消息给订阅用户的浏览器! 国外非常火的低成本客户召回方式,增加用户粘性。 Tips: 如果访问不了订阅服务器,就不可用这个通知功能了! 安装插件 插件的 GitHub 仓库 hexo-web-push-notification 在你的博客站点目录执行下面的命令: npm i hexo-web-push-notification --save 如果你安装了 cnpm 或者 yarn 等可执行下面的命令,安装依赖包的速度更快: cnpm i hexo-web-push-notification --save #安装cnpm的执行这个命令 yarn add hexo-web-push-notification #安装yarn的执行这个命令 紧接着再你的博客站点目录下的配置文件,而不是主题配置文件,添加以下配置: webPushNotification: webpushrKey: "your webpushr rest api key" webpushrAuthToken: "your webpushr authorize token" trackingCode: "AEGlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLVbjpCw8x2GmFmi1ZcLTz0ni6OnX5MAwoM88" 其中 webpushrKey,webpushrAuthToken 和 trackingCode 的值在官网注册得到。 官网注册 点击右边的图标即可进入👉 : 传送门 注册完之后,然后会让你重新登录,登录之后,然后填写相关的信息即可。 填写图中所显示的相关网站信息,填写完之后,点击下一步 Web push notications 仅支持 HTTPS 的网站,不支持 HTTP 的网站 根据网站类型,并根据网站指引进行操作,以 Hexo 为例 info, 其中将第二步中所指的代码复制粘贴到你的 footer.ejs 或者 layout.ejs,对于 hexo 用户,建议将其加入 index.ejs 即可。因为主题的不同,所以代码添加的位置不同,简单的说,就是放在网站的 </body> 标签之前,根据你的主题而言,自己添加。 接着将以下代码插入到网页中就可以了。确保每一个你想要询问用户接受通知的页面都要包含以下代码。 其中,上图步骤二中的代码有 trackingCode 的值,如下图中所标明的一长串字母。 验证安装 部署之后可能会遇到无法正常发送通知的情况. 进入目录 node_modules/hexo-web-push-notification/index.js文件中第22行'summary': util.stripHTML(newPost.excerpt),这里取值取的是excerpt,改成summary即可。 修改前 var JSONFeed = { 'title': newPost.title, 'id': newPost.path, 'date_published': newPost.date.format('L'), 'summary': util.stripHTML(newPost.excerpt), 'url': newPost.permalink, 'tags': newPost.tags.data.map(function (v) { return v.name }), 'categories': newPost.categories.data.map(function (v) { return v.name }) } var JSONFeed = { 'title': newPost.title, 'id': newPost.path, 'date_published': newPost.date.format('L'), 'summary': util.stripHTML(newPost.summary), 'url': newPost.permalink, 'tags': newPost.tags.data.map(function (v) { return v.name }), 'categories': newPost.categories.data.map(function (v) { return v.name }) } 客服聊天窗口 1、在官网注册账号 官网地址:点我去crisp官网注册 2、注册完成后设置 登录刚才注册的账户——设置——网站设置——添加网站。 添加完成之后就多了一行网站信息。点网站整合,就有不同的站的整合方式。 比如:html方式 就是复制JS代码片段到你的到head标签里。 <script type="text/javascript">window.$crisp=[];window.CRISP_WEBSITE_ID="xxxxxxx-097e-402f-bb6b-xxxxxxx";(function(){d=document;s=d.createElement("script");s.src="https://client.crisp.chat/l.js";s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})();</script> 3、其他的设置也 整个使用非常简单的。 使用Valine-Admin管理评论和评论提醒 使用 首先其他的不错说了,在阅读本篇文章之前你最好已经整合了Valine留言。 由于我已经整合过了所以前面几个步骤的图片来源自@Valine-Admin 首先登陆账号,找到云引擎在点击设置。 推荐使用这个 HCLonely/Valine-Admin 复制仓库地址:DesertsP/Valine-Admin 把git仓库地址房子代码库输入框中。 切换到部署标签页,分支使用 master,点击部署。 接下来输入分支为master 部署完成之后就是设置环境变量 环境变量 点击设置,找到自定义环境变量点击新增变量 SITE_NAME : 网站名称。 SITE_URL : 网站地址, 最后不要加 / 。 SMTP_USER : SMTP 服务用户名,一般为邮箱地址。 SMTP_PASS : SMTP 密码,一般为授权码,而不是邮箱的登陆密码,请自行查询对应邮件服务商的获取方式 SMTP_SERVICE : 邮件服务提供商,支持 QQ、163、126、Gmail、"Yahoo"、...... ,全部支持请参考 : Nodemailer Supported services。 — 如这里没有你使用的邮件提供商,请查看自定义邮件服务器 SENDER_NAME : 寄件人名称。 TO_EMAIL:这个是填收邮件提醒的邮箱地址,若没有这个字段,则将邮件发到SMTP_USER。 TEMPLATE_NAME:设置提醒邮件的主题,目前内置了两款主题,分别为 default 与 rainbow。默认为 default 设置好以上变量之后 点击实例 然后重启项目,注意任何变动都要重启项目 然后看一下效果 还不错 自定义后台 首先需要设置管理员信息。访问管理员注册页面https://云引擎域名/sign-up,注册管理员登录信息,如:https://deserts-io.avosapps.us/sign-up 点击设置然后点击Web主机域名找到自己的后台地址 然后在Usee表中增加账号, 只需要填写 email、password、username 其中邮箱必须设置为你的上面环境变量的邮箱 设置完之后登录就能在你的后台管理评论 更多设置 邮件通知模板 HCLonely/Valine-Admin 时使用这个 评论通知模板 <div style=" border-radius: 10px 10px 10px 10px; font-size: 13px; color: #555555; width: 666px; font-family: 'Century Gothic', 'Trebuchet MS', 'Hiragino Sans GB', 微软雅黑, 'Microsoft Yahei', Tahoma, Helvetica, Arial, 'SimSun', sans-serif; margin: 50px auto; border: 1px solid #eee; max-width: 100%; background: #ffffff repeating-linear-gradient(-45deg, #fff, #fff 1.125rem, transparent 1.125rem, transparent 2.25rem); box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15); " > <div style=" width: 100%; background: #49bdad; color: #ffffff; border-radius: 10px 10px 0 0; background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244)); background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244)); height: 66px; " > <p style=" font-size: 15px; word-break: break-all; padding: 23px 32px; margin: 0; background-color: hsla(0, 0%, 100%, 0.4); border-radius: 10px 10px 0 0; " > 您在<a style="text-decoration: none; color: #ffffff" href="<%=siteUrl%>"> <%=siteName%> </a>上的留言有新回复啦! </p> </div> <div style="margin: 40px auto; width: 90%"> <p><%=pname%> 同学,您曾在文章上发表评论:</p> <div style=" background: #fafafa repeating-linear-gradient(-45deg, #fff, #fff 1.125rem, transparent 1.125rem, transparent 2.25rem); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); margin: 20px 0px; padding: 15px; border-radius: 5px; font-size: 14px; color: #555555; " > <%-ptext%> </div> <p><%=name%> 给您的回复如下:</p> <div style=" background: #fafafa repeating-linear-gradient(-45deg, #fff, #fff 1.125rem, transparent 1.125rem, transparent 2.25rem); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); margin: 20px 0px; padding: 15px; border-radius: 5px; font-size: 14px; color: #555555; " > <%-text%> </div> <p> 您可以点击 <a style="text-decoration: none; color: #12addb" href="<%=url%>">查看回复的完整內容 </a>,欢迎再次光临 <a style="text-decoration: none; color: #12addb" href="<%=siteUrl%>"> <%=siteName%> </a>。 </p> <style type="text/css"> a:link { text-decoration: none; } a:visited { text-decoration: none; } a:hover { text-decoration: none; } a:active { text-decoration: none; } </style> </div> </div> 博主回复通知模板 <div style=" border-radius: 10px 10px 10px 10px; font-size: 13px; color: #555555; width: 666px; font-family: 'Century Gothic', 'Trebuchet MS', 'Hiragino Sans GB', 微软雅黑, 'Microsoft Yahei', Tahoma, Helvetica, Arial, 'SimSun', sans-serif; margin: 50px auto; border: 1px solid #eee; max-width: 100%; background: #ffffff repeating-linear-gradient(-45deg, #fff, #fff 1.125rem, transparent 1.125rem, transparent 2.25rem); box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15); " > <div style=" width: 100%; background: #49bdad; color: #ffffff; border-radius: 10px 10px 0 0; background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244)); background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244)); height: 66px; " > <p style=" font-size: 15px; word-break: break-all; padding: 23px 32px; margin: 0; background-color: hsla(0, 0%, 100%, 0.4); border-radius: 10px 10px 0 0; " > 您的<a style="text-decoration: none; color: #ffffff" href="<%=siteUrl%>"> <%=siteName%> </a>上有新的评论啦! </p> </div> <div style="margin: 40px auto; width: 90%"> <p><%=name%> 发表评论:</p> <div style=" background: #fafafa repeating-linear-gradient(-45deg, #fff, #fff 1.125rem, transparent 1.125rem, transparent 2.25rem); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); margin: 20px 0px; padding: 15px; border-radius: 5px; font-size: 14px; color: #555555; " > <%-text%> </div> <p><a style="text-decoration: none; color: #12addb" href="<%=url%>" target="_blank">[查看评论]</a></p> <style type="text/css"> a:link { text-decoration: none; } a:visited { text-decoration: none; } a:hover { text-decoration: none; } a:active { text-decoration: none; } </style> </div> </div> 使用 DesertsP/Valine-Admin 时使用下面配置 邮件通知模板在云引擎环境变量中设定,可自定义通知邮件标题及内容模板。 环境变量 示例 说明 MAIL_SUBJECT ${PARENT_NICK},您在${SITE_NAME}上的评论收到了回复 [可选]@通知邮件主题(标题)模板 MAIL_TEMPLATE 见下文 [可选]@通知邮件内容模板 MAIL_SUBJECT_ADMIN ${SITE_NAME}上有新评论了 [可选]博主邮件通知主题模板 MAIL_TEMPLATE_ADMIN 见下文 [可选]博主邮件通知内容模板 邮件通知包含两种,分别是被@通知和博主通知,这两种模板都可以完全自定义。默认使用经典的蓝色风格模板(样式来源未知)。 默认被@通知邮件内容模板如下: <div style="border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;"><h2 style="border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;">您在<a style="text-decoration:none;color: #12ADDB;" href="${SITE_URL}" target="_blank"> ${SITE_NAME}</a>上的评论有了新的回复</h2> ${PARENT_NICK} 同学,您曾发表评论:<div style="padding:0 12px 0 12px;margin-top:18px"><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;"> ${PARENT_COMMENT}</div><p><strong>${NICK}</strong>回复说:</p><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;"> ${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}" target="_blank">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="${SITE_URL}" target="_blank">${SITE_NAME}</a>。<br></p></div></div> 效果如下图: mail-blue-template @通知模板中的可用变量如下(注,这是邮件模板变量,是指嵌入到HTML邮件模板中的变量,请勿与云引擎环境变量混淆): 模板变量 说明 SITE_NAME 博客名称 SITE_URL 博客首页地址 POST_URL 文章地址(完整路径) PARENT_NICK 收件人昵称(被@者,父级评论人) PARENT_COMMENT 父级评论内容 NICK 新评论者昵称 COMMENT 新评论内容 默认博主通知邮件内容模板如下: <div style="border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;"><h2 style="border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;">您在<a style="text-decoration:none;color: #12ADDB;" href="${SITE_URL}" target="_blank">${SITE_NAME}</a>上的文章有了新的评论</h2><p><strong>${NICK}</strong>回复说:</p><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;"> ${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}" target="_blank">查看回复的完整內容</a><br></p></div></div> 博主通知邮件模板中的可用变量与@通知中的基本一致,PARENT_NICK 和 PARENT_COMMENT 变量不再可用。 这里还提供一个彩虹风格的@通知邮件模板代码: <div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的留言有新回复啦!</p></div><div style="margin:40px auto;width:90%"><p>${PARENT_NICK} 同学,您曾在文章上发表评论:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${PARENT_COMMENT}</div><p>${NICK} 给您的回复如下:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="${SITE_URL}"> ${SITE_NAME}</a>。</p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div></div> 效果如图: 彩虹模板 垃圾评论检测 Akismet (Automattic Kismet)是应用广泛的一个垃圾留言过滤系统,其作者是大名鼎鼎的WordPress 创始人 Matt Mullenweg,Akismet也是WordPress默认安装的插件,其使用非常广泛,设计目标便是帮助博客网站来过滤留言Spam。有了Akismet之后,基本上不用担心垃圾留言的烦恼了。 启用Akismet后,当博客再收到留言会自动将其提交到Akismet并与Akismet上的黑名单进行比对,如果名列该黑名单中,则该条留言会被标记为垃圾评论且不会发布。 如果还没有Akismet Key,你可以去 AKISMET FOR DEVELOPERS 免费申请一个; 当AKISMET_KEY设为MANUAL_REVIEW时,开启人工审核模式; 如果你不需要反垃圾评论,Akismet Key 环境变量可以忽略。 为了实现较为精准的垃圾评论识别,采集的判据除了评论内容、邮件地址和网站地址外,还包括评论者的IP地址、浏览器信息等,但仅在云引擎后台使用这些数据,确保隐私和安全。 如果使用了本站最新的Valine和Valine Admin,并设置了Akismet Key,可以有效地拦截垃圾评论。被标为垃圾的评论可以在管理页面取消标注。 环境变量 示例 说明 AKISMET_KEY xxxxxxxxxxxx [可选]Akismet Key 用于垃圾评论检测 手动配置邮件服务器 自定义邮件服务器地址和端口信息,删除SMTP_SERVICE环境变量,新增以下变量: 变量 示例 说明 SMTP_HOST smtp.qq.com [可选]SMTP_SERVICE留空时,自定义SMTP服务器地址 SMTP_PORT 465 [可选]SMTP_SERVICE留空时,自定义SMTP端口 SMTP_SECURE true [可选]使用TLS Troubleshooting 部署失败,请在评论中附图,或去Github发起Issue 邮件发送失败,确保环境变量都没问题后,重启云引擎 重启云引擎 博主通知模板中不要出现PARENT*相关参数(请勿混用模板) 点击邮件中的链接跳转至相应评论,这一细节实现需要在Web前端添加一点额外的代码: <script> if(window.location.hash){ var checkExist = setInterval(function() { if ($(window.location.hash).length) { $('html, body').animate({scrollTop: $(window.location.hash).offset().top-90}, 1000); clearInterval(checkExist); } }, 100); } </script> @邮件通知效果: 您在[ ${SITE_NAME}](/posts/40300608/${SITE_URL})上的留言有新回复啦! ${PARENT_NICK} 同学,您曾在文章上发表评论: ${PARENT_COMMENT} ${NICK} 给您的回复如下: ${COMMENT} 您可以点击查看回复的完整內容${POST_URL}#comments,欢迎再次光临 ${SITE_NAME}${SITE_URL}。 @邮件通知模板代码: <div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的留言有新回复啦!</p></div><div style="margin:40px auto;width:90%"><p>${PARENT_NICK} 同学,您曾在文章上发表评论:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${PARENT_COMMENT}</div><p>${NICK} 给您的回复如下:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="${SITE_URL}"> ${SITE_NAME}</a>。</p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 0 0 10px 10px;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg,rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"></div></div> 博主通知效果: 您在[${SITE_NAME}${SITE_URL}上的文章有了新的评论! **${NICK}** 同学,发表评论说: ${COMMENT} 您可以点击查看回复的完整內容${POST_URL}#comments)。 <div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的文章有了新的评论!</p></div><div style="margin:40px auto;width:90%"><p><strong>${NICK}</strong> 同学,发表评论说:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a>。</p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 0 0 10px 10px ;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg,rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"></div></div> 解决休眠 免费版的 LeanCloud 容器,是有强制性休眠策略的,不能 24 小时运行: 每天必须休眠 6 个小时 30 分钟内没有外部请求,则休眠。 休眠后如果有新的外部请求实例则马上启动(但激活时此次发送邮件会失败)。 也就是如果服务器休眠了的话用户第一次评论是提醒不了的。 参考了Valine-Admin官网找到了解决办法。 首先在环境变量增加服务器地址,就是你的后台服务器地址 下面是你的服务器地址,可以自定义 同样登录后台 找到定时任务 然后点击创建任务,上面是我创建好的 选择self_wake函数,然后运行时间使用cron表达式 0 0/30 7-23 ? 表示每天6点到11点 每30分钟叫醒服务器一次 这样就完美的解决了服务器休眠的问题 那如果用户不在时间范围内发留言了怎么办?我们也可以创建一个捡漏的定时任务 创建捡漏定时任务 然后运行函数选择resend_mails,同样使用cron表达式 0 0 8 ? 表示每八个小时进行捡漏一次,这样如果有留言遗漏的话就能即使的提醒。 WakeLeanCloud 这个项目主要是用来解决LeanCloud通过定时任务唤醒机器时被流控的问题。 如何使用 Fork此项目 添加一个名为GITHUB_TOKEN的Token,并为赋予repo,admin:repo_hook , workflow的权限 添加名为SITE的Secrets,内容为自己管理后台地址。多个请用英文逗号分隔 详细教程请参考优雅解决LeanCloud流控问题 让hexo支持pwa pwa中文叫渐进式网页应用,pwa网站可以直接添加网址站到桌面,就相当于在系统中直接安装了一个app,打开的效果也和app差不多,加载速度也很快,部分功能可以直接离线使用。Google的Workbox标准,目前来看需要Chrome支持 hexo-pwa 很久没更新,看到资料都是支持4.x版本hexo。 hexo-offline 亲自验证,支持最新5.x的hexo。 安装hexo-offline npm install hexo-offline --save 关于这个插件的详细使用方法可以看下面这里 https://github.com/JLHwung/hexo-offline 配置hexo-offline 之后我们在站点根目录_config.yml如下配置 # offline config passed to sw-precache. service_worker: maximumFileSizeToCacheInBytes: 5242880 staticFileGlobs: - /**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,woff2} - /lib/**/*.js - /lib/**/*.css - /images/* - /js/src/**/*.js stripPrefix: public verbose: true runtimeCaching: - urlPattern: /* handler: cacheFirst options: origin: cdn.bootcss.com 注意哦不是主题的_config.yml文件 之后生成manifest.json文件,可以在这个网站在线生成。 填入相关的参数,如下 Tips: 一定需要一个512x512的icon! 之后点击generate.zip 把配置都下载过来 把manifest.json和images文件夹直接复制到hexo下source文件夹中,最后我们编辑主题,在head里添加 <link rel="manifest" href="/manifest.json"> 如果使用的是hexo next主题,在 themes/next/layout/_partials/head/head.swig 如果使用的是hexo matery主题,在 themes/matery/layout/_partial/head.ejs 这个文件中添加上面这句话即可,最后直接重新生成站点,部署即可 验证和使用 需要https访问,看到这个齿轮 然后在浏览器地址栏可以看到应用标志 Tips: offline 需要https才能正常使用 点击打开,会看到如下结果,试一下? valine 的使用与升级到1.4 一、valine启用 1、主要流程 valine和miniValine使用基本类似。 (1)去 Leancloud注册。 注意事项: 节点选择:华东节点、华北节点、国际版。 如果你的域名没有备案,建议选择国际版。 因为华东或华北节点在安装评论系统之后访问要求域名备案。 (2)在“设置“,”应用 Keys”,找到你的appid和appkey,配置到主题中valine配置的地方,启用valine。 (3)在“设置“,”安全中心”,”Web 安全域名”,添加自己的域名。 (4)在“设置“,”安全中心”,”服务开关”,数据存储要打开。 (5)在“存储“,”用量统计”,”HTTP状态码”,启用,方便后续报错查错误码。 (6)重新编译部署hexo clean & hexo g & hexo d 2、遇到问题 搞这个东西采坑不少,有些坑都是自己不小心造成的。我在网上查了,交流群里也咨询请教了,没有人能解决这个问题,毕竟这个坑是自己造成的。 常见Code 403问题: Code 403: 访问被api域名白名单拒绝,请检查你的安全域名设置. 网上多数的说法是在web安全域名中添加自己的域名。可是如果添加之后还是这个问题呢? 其实一般不会有这个问题,我有这个问题是我改了权限造成了。 官方给的解释: 应用在控制台中的相关服务选项未打开,如 Class 关闭了权限,或是 User 缺失了 session 信息等情况下,云端会统一地返回 403 错误码及不同的错误信息,代表当前请求因权限不够而被拒。例如: 信息 - Forbidden to read/write by class permissions 信息 - The user cannot be altered by a client without the session. 解决: (1)首次使用,添加一条评论,一般添加之后就会好了。 (2)后续使用,403,请检查comment表的add_fields/create/find权限开放。 (3)如果还是不行将_use表的add_fields/create/find权限开放。 (4)如果还是不行,到“存储“,”用量统计”,”HTTP状态码”处,检查你的错误码,然后去LeanCloud的错误找应用的错误码,排查原因吧。 二、valine升级 1、引入1.4版的js文件 (1)修改主题配置文件 js: valine: https://unpkg.com/valine/dist/Valine.min.js #/libs/valine/Valine.min.js (2)将文件放你自己的仓库 下载我的 Valine.min.js 文件,直接替换你主题目录 /source/libs/valine/ 下的 Valine.min.js 文件。 注意,如果你担心替换有问题,可以先备份一下你自己的 Valine.min.js 文件。 2、增加valine的配置: 1.4的版本有些属性调整了,主题下的_config.ymlvaline属性如下: valine: enable: true appId: iTxfqh5e9IaRfiiVOTbIWoKa-XXXXXX appKey: C5s5xGFErD1EtXXXXXXXX verify: true # 是否启用防垃圾验证 notify: true # 是否开启邮件提醒(https://valine.js.org/notify.html) visitor: true avatar: monsterid # 头像样式(https://valine.js.org/avatar.html) pageSize: 10 placeholder: 'ヾノ≧∀≦)o来啊,快活啊!' # Comment Box placeholder background: /medias/comment_bg.png #背景图 count: true enableQQ: 970175021 recordIP: true requiredFields: - nick - mail guest_info: - nick - mail - link master: - 123abc508165c8eba9a77f872xxxx046 # md5加密后的博主邮箱 metaPlaceholder: # 输入框的背景文字 nick: 昵称/QQ号(必填) mail: 邮箱(必填) link: 网址(https://) lang: zh-CN tagMeta: # The String Array of Words to show Flag.[Just Only xCss Style mode] - 博主 - 小伙伴 - 访客 friends: # The MD5 String Array of friends Email to show friends Flag.[Just Only xCss Style mode] - c08508165c8eba9a77f8c2853xxxx09e - 901345d4c91ddfd8db0f175bbcfff0c8 - 1512958e18378c98b498d5effe3e76ff 复制代码注意缩进对齐,不对齐可能会报错,请自行检查对齐。 3、修改valine.ejs: Matery 主题使用的ejs模板预编译,如果你使用了pug或者swig等其他的模板语言,请修改成对应语言语法即可。 原始的valine.ejs new Valine({ el: '#vcomments', appId: '<%- theme.valine.appId %>', appKey: '<%- theme.valine.appKey %>', notify: '<%- theme.valine.notify %>' === 'true', verify: '<%- theme.valine.verify %>' === 'true', visitor: '<%- theme.valine.visitor %>' === 'true', avatar: '<%- theme.valine.avatar %>', pageSize: '<%- theme.valine.pageSize %>', lang: '<% if (config.language == "zh-CN") { %>zh-cn<% } else { %>en<% } %>', placeholder: '<%= theme.valine.placeholder %>' }); 升级后的valine.ejs let metaPlaceholder = <%- JSON.stringify(theme.valine.metaPlaceholder) %> ; //这里要换行 new Valine({ el: '#vcomments', appId: '<%- theme.valine.appId %>', appKey: '<%- theme.valine.appKey %>', notify: '<%- theme.valine.notify %>' === 'true', verify: '<%- theme.valine.verify %>' === 'true', visitor: '<%- theme.valine.visitor %>' === 'true', avatar: '<%- theme.valine.avatar %>', pageSize: '<%- theme.valine.pageSize %>', lang: '<%- theme.valine.lang %>', placeholder: '<%= theme.valine.placeholder %>', meta: <%- '["' + theme.valine.guest_info.join('", "') + '"]' %>, recordIP: '<%- theme.valine.recordIP %>' === 'true', enableQQ: '<%- theme.valine.avatar %>', requiredFields: <%- '["' + theme.valine.master.join('", "') + '"]' %>, master: <%- '["' + theme.valine.master.join('", "') + '"]' %>, friends: <%- '["' + theme.valine.friends.join('", "') + '"]' %>, tagMeta: <%- '["' + theme.valine.tagMeta.join('", "') + '"]' %>, metaPlaceholder: metaPlaceholder, }); 如果需要验证昵称和邮箱可以加上以下代码: document.body.addEventListener('click', function(e) { if (e.target.classList.contains('vsubmit')) { const email = document.querySelector('input[type=email]'); const nick = document.querySelector('input[name=nick]'); const reg = /^[A-Za-z0-9_-\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; if (!email.value || !nick.value || !reg.test(email.value)) { const str = `<div class="valert txt-center"><div class="vtext">请填写正确的昵称和邮箱!</div></div>`; const vmark = document.querySelector('.vmark'); vmark.innerHTML = str; vmark.style.display = 'block'; e.stopPropagation(); setTimeout(function() { vmark.style.display = 'none'; vmark.innerHTML = ''; }, 2500); } } }, true); 说明:代码非原创,JS正则验证本身也不难。 好了可以部署之后自己测试一下。 顺便说一下,填写昵称邮箱和网址的地方如果折行了就按我的样式改一下就好: 在 valine.ejs 是上面对着改一下就好了: .v[data-class="v"] .vwrap .vheader .vinput { width: 32%; border-bottom: 1px dashed #dedede; } 新建文章自动打开本地Markdown编辑器 写新文章时,需要控制台执行hexo new “文章名字”生成一篇新文章,但需要手动打开,挺麻烦,我们可以设置在生成之后自动打开 在站点根目录下新建scripts目录,然后在新建auto_open.js,在文件填入一下内容 var spawn = require('child_process').exec; // Hexo 2.x 用户复制这段 //hexo.on('new', function(path){ //spawn('start "markdown编辑器绝对路径.exe" ' + path); //}); // Hexo 3 用户复制这段 hexo.on('new', function(data){ spawn('start "D:\Program Files\Typora\Typora.exe" ' + data.path); }); 其中”D:\Program Files\Typora\Typora.exe”是我本地编辑器的路径,只需要改为你本地编辑器的路径即可,然后在执行hexo cl && hexo g -d,部署到GitHub即可,以后在新建文章就会自动打开编辑器. 新建文章自动打开本地Vim编辑器 Linux , MacOS 等类UNIX系统用户,vim $hexo/scripts/openNewFile.js var spawn = require('child_process').spawn; // Hexo 3 hexo.on('new', function(data){ spawn('vim', [data.path], { stdio: 'inherit' }); }); 使用 VS Code 的任务(Tasks)便捷操作 Hexo 本文章要实现目标是通过配置任务,可以使用 Ctrl+Shift+B(“运行生成任务”的快捷键)自动完成 Hexo 的清理、生成、开启本地预览,并且可以使用 VS Code 的“终端”菜单下的“运行命令”完成上述的单个命令。 配置 Tasks 工作区的特定任务是从 Workspace 的 .vscode 文件夹中的 tasks.json 文件配置。 新建 tasks.json 在 Hexo 工作区的 .vscode 文件夹下新建 tasks.json 文件。 配置单个 Hexo 命令 以 hexo generate 命令为例,在 tasks.json 粘贴下面的代码。 { "version": "2.0.0", "tasks": [ { // 任务类型。 "type": "shell", // 任务的用户界面中使用的标签;相当于变量名。 "label": "local generate", // 实际执行的命令。 "command": "hexo generate", // 定义如何在用户界面中处理任务输出,自行定义。 "presentation": { // 命令面板。dedicated -> 如果任务已在命令面板中则重用此面板,否则新建面板。 "panel": "dedicated", // 任务执行前是否清理命令面板。 "clear": true }, // 问题匹配器,为空则不匹配任何问题。 "problemMatcher": [] } ] } 代码中的参数根据注释和名称自行理解,想要查看更多的参数信息或关于 Tasks 的信息可以访问官方文档 。 备注:上述任务中的 presentation 和 problemMatcher 是非必要的,但是实际使用时可以减少 VS Code 可能出现的询问次数。 配置多个 Hexo 命令 我们还需要按照上述增加其他命令,添加后的代码如下: { "version": "2.0.0", "tasks": [ { "type": "shell", "label": "生成", "command": "hexo generate", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, // ---------- // 新增代码 { "type": "shell", "label": "清理", "command": "hexo clean", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "预览", "command": "hexo server", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] } // ---------- ] } 备注:tasks 内的任务书写无顺序之分。 配置多个命令的顺序执行 代码如下: { "version": "2.0.0", "tasks": [ // ---------- // 新增代码。 { "label": "清理、生成并预览", // 执行顺序。sequence -> 顺序依次执行。 "dependsOrder": "sequence", // 执行本任务前要执行的任务。在此处依次写入其他任务的标签(label)。 "dependsOn": ["清理", "生成", "预览"], "problemMatcher": [], // 组。 "group": { // 任务类型。 "kind": "build", // 是否为默认任务。 "isDefault": true } }, // ---------- { "type": "shell", "label": "清理", "command": "hexo clean", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "生成", "command": "hexo generate", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "预览", "command": "hexo server", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] } ] } 其中本例内 group 的设置是为了将任务 local clear & server 设置为 VS Code “运行生成任务…”功能的默认任务,这样我们才能通过快捷键 Ctrl+Shift+B 执行此任务。 备注:新增的这个任务是一个自身不执行任何命令的任务。 执行 Tasks 完成上面的设置后,我们在编辑了 Hexo 的文章或其他内容后使用 Ctrl+Shift+B 快捷键就可以自动完成 Hexo 的清理、生成、开启本地预览。 如果想要执行上面配置的 3 个任务中的某一个,可以点击菜单栏“终端”下的“运行任务”来执行其中的任务。 如果最近任务里没有自己定义的任务,可以点击最下方的“显示所有任务…”来查看所有定义的任务。 疑问与解答 为什么要创建 4 个任务,而不是将最后任务的依赖设为前两个,这样就只会有 3 个任务(比如如下代码),这难道不是更简洁吗? { "version": "2.0.0", "tasks": [ { "type": "shell", "label": "清理", "command": "hexo clean", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "生成", "command": "hexo generate", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, // 最后一个任务执行前先执行其他两个 { "type": "shell", "label": "预览", "command": "hexo server", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [], "dependsOrder": "sequence", "dependsOn": ["清理", "生成"], "group": { "kind": "build", "isDefault": true } } ] } 解答:这样设置会导致无法使用单一的命令 hexo server,因为调用 local server 这个任务总会调用其他两个。当然如果你不需要有单独执行命令 hexo server 的任务,那你这样写也可以。 只能通过 shell 类型的任务来完成本次的目标吗? 答:当然不是,你也可以使用 npm 等类型的任务来完成目标。 附录 你也可以参考上面的任务,自己添加 Hexo 的任务,比如一键部署等。 使用案例 { "version": "2.0.0", "tasks": [ { "label": "清理、生成并预览", "dependsOrder": "sequence", "dependsOn": ["清理", "生成", "预览"], "problemMatcher": [], "group": { "kind": "build", "isDefault": true } }, { "type": "shell", "label": "清理", "command": "hexo clean", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "生成", "command": "hexo generate", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "预览", "command": "hexo server", "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "新建文章", "command": "hexo", "args": ["new", "post", "${input:postName}"], "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] }, { "type": "shell", "label": "新建草稿", "command": "hexo", "args": ["new", "draft", "${input:postName}"], "presentation": { "panel": "dedicated", "clear": true }, "problemMatcher": [] } ], "inputs": [ { "type": "promptString", "id": "postName", "description": "文章名称" } ] } TODO List 准备做,但时间不确定的需求 自建 不蒜子 API https://busuanzi.icodeq.com/ https://github.com/zkeq/Busuanzi_backend_self 访问速度优化 进行中 Search JS 优化 hexo-generator-searchdb 目标实例 CSS整理 进行中 插件内置修改 性能优化,外部插件内置修改 进行中 字体优化 字体体积比较大,是拖慢网页加载速度的重要因素。减少它的体积是重要的加速手段 Done! font forge hexo-fontawesome Customize-Font-Awesome 在线精简 Fontello: http://fontello.com/ IcoMoon: https://icomoon.io/app/#/select (How To) Fontastic: http://fontastic.me/ 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/27
articleCard.readMore

基于Hexo的matery主题搭建博客增强部署篇4

免费域名 不想花钱,就能获得的免费域名: 🌍 EU.org 详细介绍:EU.org提供免费的二级域名,适合有技术需求的用户。 🌈 Gay域名 详细介绍:Dynadot提供免费的.Gay顶级域名,适合LGBTQ+相关网站。 🌐 Freenom 详细介绍:Freenom提供免费的域名注册,支持.TK、.ML、.GA、.CF和.GQ域名。 🌍 Porkbun 详细介绍:Porkbun提供免费的顶级域名,使用优惠码即可免费获取。 🌐 Dot.tk 详细介绍:Dot.tk提供免费的.TK域名,适合个人项目和短期使用。 🌍 js.org 详细介绍:https://github.com/js-org/js.org 适合技术网站 免费的稳定性堪忧,可能随时被收回域名,所以想长期稳定使用的用户,强烈建议花钱购买一个域名。然后可以上 cloudflare CDN,免费域名不能使用cloudflare CDN! 博客部署方式 静态博客的部署方式多种多样,免费部署资源非常多。 如果DNS支持多线路,还可以设置多路负载均衡! 注意:这些免费的部署都没法做ICP备案,或者国内CDN套着备案。不过,都免费了,你还要求那么多? 部署方式 费用 限制 难易度 多域名 Github 0 $ 100G/M 简单 单域名 VPS 约2~5$/M 看购买套餐 复杂 支持 Vercel 0 $ 100G/M 简单 支持 Netlify 0 $ 100G/M 简单 支持 Cloudflare pages 0 $ 无 简单 支持 Gitlab 0 $ 无 简单 支持(?) 更详细对比 特性 GitHub GitLab Netlify Vercel CloudFlare Firebase Render Build Limit 10/hour None 3/Minute 32/hour 500/month Not Applicable Unlisted Build Time to Error 10 minutes 3 Hours 15 minutes 30 minutes Unlisted Not Applicable 120 minutes Build Time per Month NA 400 Minutes 300 Minutes 6000 Minutes Unlisted Not Applicable Unlisted Concurrent Builds 🤷‍♂️ Yes One One One Not Applicable Unlisted Deploy Limits NA No Not Applicable 100/Day Unlisted Not Applicable Unlisted Deploy Previews No No Yes Yes Yes Yes Yes Serverless Functions No No Yes Yes Yes Yes Not for free Invocations/Month 125k/per site/mo 100GB hours/mo 100k/day 125k/mo Duration Allowed 10s 10s 10ms 540s DNS Management No No Yes Yes Yes No No HTTPS Available Yes Yes Yes Yes Yes Yes Yes Bandwidth/Month 100GB/Mo No limit 100GB/Mo 100GB/Mo No Limit 10GB/Mo 100GB/Mo Site Limit 1GB 10GB 100GB 12.5K Files 20K Files 10GB None listed Default URL github.io gitlab.io netlify.app vercel.app pages.dev web.app and firebaseapp.com onrender.com # of Team Members Unlimited Unlimited One One Unlimited Unlimited Team SSO Available Yes Yes Yes Not for Free Unlisted Yes No # of Users Yes Yes 1000/site/month No No Yes Planned User SSO Available [Yes] Yes Not for free No No Yes Form Submissions/Month No No 100 No Yes and No No Yes - via Formspree integration Analytics No Not Yet Not for free Free is only good for 1 day Yes Yes No Split A/B Testing No No Yes No No Yes No Allowed for Business Use No Yes Yes No for hobby Yes Yes Yes Github可以通过同样代码仓库,多个仓库同时部署,不同仓库设置不同的域名来支持多域名! Tips: Github有每个账户1000个仓库限制,每个仓库大小超过1G,就会被人工审查!所以撸羊毛可以,注意仓库个数和大小限制! GitHub Pages 速度:尚可,并不很慢,但有时候会抽风。 自定义域名:一个。 限制: 单个文件大于50MB将受到警告。 单个文件大于100MB无法上传。 仓库大小「强烈建议」少于1GB。 每小时可构建10次。https://help.github.com/articles/what-is-my-disk-quota/#file-and-repository-size-limitations 每月流量100GB 或者 100,000 次请求。 https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#guidelines-for-using-github-pages 优点:简单方便 缺点:国内速度慢,直连CNAME会泄露GitHub用户名,免费版私有仓库无法使用 Netlify 控制台无法访问。 部署方式:GitHub、GitLab、BitBucket仓库自动拉取以及本地CLI直接推送。 速度:较GitHub Pages要快,但是稳定性差上不少,部分时候可能直接出现无法访问。 自定义域名:多个。 限制: 同时只能构建一个站点。 每月流量100GB。 每月构建时间300分钟。 https://www.netlify.com/pricing 优点:pr单独部署,速度还可以,有免费的serverless 缺点:直连CNAME会泄露分配域名 对比Vercel,Netlify在国内的速度确实要比Vercel慢很多,但前者有许多后者没有的服务或插件,比如Algolia、表单等等 Cloudflare Pages 部署方式:GitHub仓库。 速度:与GitHub Pages相似。 自定义域名:最多10个; 限制: 每月构可构建500次。 每日所有Functions 和 Workers 总计限制 100,000 次请求。 文件数量最多2w个。 单个文件大小不得超过25MB。 https://developers.cloudflare.com/pages/platform/limits Vercel 部署方式:与Netlify相同,支持GitHub、GitLab、BitBucket仓库自动拉取以及本地CLI直接推送。 速度:在所有方案中最快且最稳定。 自定义域名:多个。 限制: 每日可构建100次,但每小时不超过32次。 单个Git仓库支持连接3个Vercel项目。 每次构建时长最多45min。每月总计不超过100h。 每月带宽100G。 https://vercel.com/docs/platform/limits 优点:pr单独部署,速度快,CNAME无隐私问题,有免费的serverless 缺点:嗯,免费的能做到这样还指望啥? Cloudflare CDN Cloudflare CDN本身并非博客托管服务,但是可以与上文任意一个服务进行搭配。 使用CF CDN时访问速度大多数时候较快,遇高峰期将减速。总体来说速度不如Vercel。稳定性尚可,但曾出现过无法访问的情况。 最主要的是将获得非常多的扩展功能,如HSTS、访问限制,以及HTTP/3等前沿网络技术。他们对IETF的跟进是很快的。同时还会获得DDoS清洗、网站分析等服务。 注意,套上CF CDN之后,可能访问速度会下降,例如Vercel,CF pages 最佳方法是使用Vercel+CF Partner?不过现在能用的CF Partner几乎没有了 gcore CDN gcore 每月 1000G 免费流量! jsDelivr CDN 官网 支持 HTTPS,支持 HTTP2,提供 SRI 网宿、Fastly、Stackpath、Cloudflare Business Plan 非常丰富的国内节点 非常丰富的海外节点 全球的速度都非常优秀 cdn.jsdelivr.net,NS1 和 Rage4 主从 DNS 便捷性:★★★★★ jsDelivr 支持从 NPM、GitHub Tag 和 WordPress SVN 上抓取文件并分发,大大降低了开发者使用的难度——直接发个 Release 就可以用了。jsDelivr 每个月会被调用上百亿次,服务 620+ TB 的流量,意味着如果你不是通过 jsDelivr 加载较为热门的库,那么缓存命中率是不会太理想的。 公用库采用jsDelivr加速,自定义修改的js,css使用自己的部署服务 其它CDN测评 VPS 一句话,VPS的超能力就是有钱。配置更好的服务器速度更快,对国内外来说,地理位置最理想的是香港VPS。当然,价格也是相当感人! 优点:钱越多,速度越快。自定义性最高,想做什么服务都可以 缺点:很花钱,网站较大时考虑这个。不够稳定,要稳定性就要多点部署,需要自己维护服务器 RackNerd VPS 推荐 目前个人能找到的最便宜的 VPS 服务商: racknerd VPS 双11,或者6.18 活动价更优惠!几年前买的一个 1核1G 的,一年不到10刀!现在已经绝版了,并且后续每年循环账单续费没有涨价! 如果你发现了更便宜的服务商,务必留言告诉我! 本站的镜像! > > vercel, netlify, cloudflare pages 有100G流量或者访问次数限制,如果访问不了请更换其它部署方式! > - 主站: [blog.17lai.site](https://blog.17lai.site) > - Vercel: [17lai.vercel.app](https://17lai.vercel.app) > - netlify: [17lai.netlify.app](https://17lai.netlify.app) > - Cloudflare Pages: [17lai.pages.dev](https://17lai.pages.dev/) > - VPS: [v20blog.17lai.site](https://v20blog.17lai.site) > --> Hexo Docker 本地部署 在最前面的篇章介绍了Hexo Docker 环境的使用方法。具体使用方法见本文系列Hexo Docker 环境篇。 优点:本地使用可定制化成都更高 缺点:必须要有Docker 环境。异地使用麻烦,除非ssh,vpn等远程链接方法。 Hexo Docker VPS 部署 和 Hexo Docker 本地部署基本一样,最后反向代理设置域名。 具体参考 Hexo Docker 环境篇 个人购买的经验是最好2核起步,空间最好30GB以上。空间少了后期维护极其痛苦! racknerd racknerd发布端午节VPS促销套餐,$12.88/年起,可选纽约/圣何塞/西雅图/阿什本机房,这个西雅图机房好久不见商家促销了。商家特色:默认KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,solusvm管理面板,colocrossing机房。rn 的低价VPS还算不错,机器稳定,客服响应快。关注便宜VPS的小伙伴,可以围观。 1、官网 官方网站:https://www.racknerd.com 2、端午VPS套餐详情 KVM虚拟,solusvm管理,1Gbps带宽,默认1个IPv4,可选纽约/圣何塞/西雅图/阿什本机房 CPU 内存 SSD 带宽/月流量 年付 购买 1核 1.25G 20G 1Gbps/2T $12.88 链接 2核 2G 30G 1Gbps/4T $19.88 链接 2核 3G 45G 1Gbps/5T $26.88 链接 商家往期促销,可以看看 2、2024新春促销VPS套餐 KVM虚拟、1Gbps带宽、SSD raid10阵列、solusvm控制面板,可选数据中心包括:洛杉矶DC-02, 圣何塞, 达拉斯, 芝加哥, 亚特兰大, 纽约, 阿什本。 CPU 内存 SSD 带宽/月流量 年付 购买 1核 1G 15G 1Gbps/2T $10.99 链接 1核 1.5G 25G 1Gbps/4T $16.88 链接 2核 2.5G 38G 1Gbps/6T $23.88 链接 3、24年元旦促销 可选机房:洛杉矶DC-02, 圣何塞, 西雅图, 达拉斯, 芝加哥, 亚特兰大, 纽约, 阿什本 CPU 内存 硬盘 宽带 月流量 年付 购买 1核 1G 21G SSD 1Gbps 1000G $11.49 链接 1核 2G 35G SSD 1Gbps 2500G $17.38 链接 2核 3G 45G SSD 1Gbps 5000G $27.98 链接 2核 4G 60G SSD 1Gbps 8000G $37.38 链接 4、23年黑五促销套餐 可选机房: 洛杉矶DC-02, 圣何塞, 西雅图, 达拉斯, 芝加哥, 亚特兰大, 纽约, 阿什本 CPU 内存 硬盘 宽带 月流量 年付 购买 1核 768M 15G SSD 1Gbps 1000G $10.18 链接 1核 2G 30G SSD 1Gbps 2500G $16.98 链接 2核 2.5G 50G SSD 1Gbps 5000G $25.49 链接 3核 4G 80G SSD 1Gbps 8000G $38.88 链接 5、23年黑五Ryzen NVMe VPS 基于 AMD Ryzen 7950X CPU、DDR5 RAM 和 Gen4 NVMe 存储! 可选机房: 纽约 CPU 内存 硬盘 宽带 月流量 年付 购买 1核 1.5G 30G SSD 1Gbps 2500G $19 链接 2核 2G 40G SSD 1Gbps 4000G $29 链接 2核 3G 55G SSD 1Gbps 6000G $45 链接 3、法国-斯特拉斯堡机房VPS VPS特征:KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,支持rdns,solusvm面板管理。 Test IPv4: 45.95.173.2 下载:http://lg-fr.racknerd.com/1000MB.test LGS:http://lg-fr.racknerd.com/ CPU 内存 SSD 带宽流量 年付 购买 1核 1G 20G 1Gbps@3T $17.98 链接 1核 2G 30G 1Gbps@4T $24.89 链接 2核 4G 50G 1Gbps@6T $44.59 链接 3、2023年元旦+中国春节促销 VPS特征:KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,支持rdns,solusvm面板管理。 可选节点为洛杉矶DC-02, 芝加哥, 达拉斯, 新泽西, 亚特兰大, 圣何塞, 西雅图, 纽约。 CPU 内存 SSD 流量 年付 购买 1核 512M 10G 1.5T/月 $10.18 链接 1核 1G 25G 4T/月 $12.98 链接 2核 2.5G 45G 6T/月 $24.88 链接 4核 4G 70G 10T/月 $46.68 链接 3、其他年付10美元左右VPS 数据中心可选:洛杉矶、圣何塞、达拉斯、芝加哥、新泽西、亚特兰大、纽约、荷兰(阿姆斯特丹) VPS特征:KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,支持rdns,solusvm面板管理。 CPU 内存 SSD 流量 年付 购买 1核 768M 10G 1T/月 $10.28 链接 1核 768M 10G 2T/月 $11.88 链接 1核 1G 16G 3T/月 $14.98 链接 1核 1.2G 18G 2T/月 $14.88 链接 1核 1.5G 30G 3T/月 $16.88 链接 6、年付60刀 - 5个ipv4 默认配置5个ipv4。 CPU 内存 SSD 流量 年付 购买 1核 1.5G 20G 3T/月 $60 链接 7、内存1.5G-2.5G套餐 数据中心可选:洛杉矶、圣何塞、达拉斯、芝加哥、新泽西、亚特兰大、纽约、荷兰(阿姆斯特丹) VPS特征:KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,支持rdns,solusvm面板管理。 CPU 内存 SSD 流量 年付 购买 1核 1.5G 30G 3T/月 $25.95 链接 2核 2G 25G 4T/月 $20.98 链接 2核 2G 35G 4T/月 $38.78 链接 2核 2.5G 40G 3T/月 $25.88 链接 2核 2.5G 60G 7T/月 $28.55 链接 2核 2.5G 40G 5T/月 $29.50 链接 2核 2.5G 50G 5T/月 $39.95 链接 8、内存3G-8G套餐 数据中心可选:洛杉矶、圣何塞、达拉斯、芝加哥、新泽西、亚特兰大、纽约、荷兰(阿姆斯特丹) VPS特征:KVM虚拟,纯SSD raid10阵列,1Gbps带宽,自带一个IPv4,支持rdns,solusvm面板管理。 CPU 内存 SSD 流量 年付 购买 2核 3G 35G 5T/月 $29.99 链接 3核 3.5G 36G 5T/月 $30.19 链接 2核 3.5G 60G 6T/月 $35.88 链接 2核 3.5G 80G 10T/月 $38.88 链接 3核 4G 50G 10T/月 $45.89 链接 3核 4.5G 100G 12T/月 $48.77 链接 4核 8G 100G 5T/月 $89.00 链接 9、AMD+NVMe系列便宜VPS套餐 可选纽约,圣何塞,达拉斯,亚特兰大。特征,kvm虚拟,AMD Ryzen 9 3900X、DDR4、NVMe SSD、1Gbps口带宽,默认一个IPv4,不支持Windows。 CPU 内存 NVMe 流量 年付 购买 1核 512M 6G 400G/月 $15 链接 1核 1G 20G 2T/月 $32 链接 1核 1.5G 22G 3T/月 $35 链接 2核 2.5G 40G 6T/月 $69 链接 10、AMD+NVME系列windows vps套餐 可选机房洛杉矶,达拉斯,纽约,亚特兰大。 VPS特征:KVM虚拟,AMD Ryzen 9 3900x+ddr4+NVMe SSD阵列+1Gbps带宽,默认一个IPv4,solusvm管理,windows中英文授权版系统(版本为2012和2016系统)。 内存 CPU NVMe 流量 年付 购买 2G 1核 35G 2T/月 $60 链接 2.5G 1核 40G 3.5T/月 $69 链接 3G 2核 35G 3T/月 $78.88 链接 3.5G 2核 60G 3.5T/月 $99 链接 4G 3核 60G 6T/月 $115 链接 8G 3核 150G 10T/月 $219 链接 12G 4核 160G 12T/月 $289 链接 11、大硬盘VPS套餐 可选机房:圣何塞/达拉斯/芝加哥/新泽西/亚特兰大/纽约/荷兰 特征:1Gbps带宽,自带一个IPv4,solusvm管理,硬盘SSD cached,洛杉矶MC机房! CPU 内存 硬盘 流量 年付 购买 2核 2G 50G 4T/月 $36 链接 3核 4G 80G 5T/月 $59 链接 4核 6G 140G 6T/月 $95 链接 4核 8G 100G 5T/月 $89 链接 4核 8G 200G 8T/月 $135 链接 12、 便宜VPS - AMD Ryzen KVM虚拟,洛杉矶multacom机房,KVM虚拟,AMD Ryzen 9 3900X、DDR4、NVMe SSD、1Gbps带宽,自带一个IPv4,不支持Windows。 CPU 内存 NVMe 月流量 年付 购买 1核 512M 6G 400G $15 链接 1核 512M 10G 500G $23 链接 1核 1G 24G 2.5T $18.18 链接 1核 1G 20G 2T $32 链接 1核 1.5G 22G 3T $35 链接 2核 2G 38G 4T $31.88 链接 2核 2.5G 40G 6T $69 链接 2核 3G 55G 5T $48.79 链接 13、最后 网络测试: **洛杉矶DC02:**204.13.154.3,http://lg-lax02.racknerd.com/1000MB.test **洛杉矶DC05:**5.181.135.8,http://lg-lax05.racknerd.com/1000MB.test **圣何塞:**192.210.207.88,http://lg-sj.racknerd.com/1000MB.test **西雅图:**192.3.253.2,http://lg-sea.racknerd.com/1000MB.test 新泽西: 192.3.165.30,http://lg-nj.racknerd.com/1000MB.test 达拉斯:198.23.249.100,http://lg-dal.racknerd.com/1000MB.test **芝加哥:**198.23.228.15,http://lg-chi.racknerd.com/1000MB.test 阿什本:107.173.166.10,http://lg-ash.racknerd.com/1000MB.test **亚特兰大:**107.173.164.160,http://lg-atl.racknerd.com/1000MB.test **荷兰.阿姆斯特丹:**23.94.101.88,http://lg-ams.racknerd.com/1000MB.test **水牛城:**192.3.81.8,http://lg-ny.racknerd.com/1000MB.test Hexo IPFS 部署 全面拥抱 web 3.0。静态部署 hexo blog! 本节待完善! 4everland https://4everland.org/ 私有部署 IPFS hexo 插件 hexo-deployer-ipfs Docker 配置 IPFS Hexo+IPFS搭建个人免服务器独立博客 Docker linuxserver/ipfs Docker private-network-ipfs 利用 Docker 搭建 IPFS 私有网络 IPFS在windows平台下的安装与简单使用 Win10 配置IPFS IPFS是点对点协议InterPlanetary File System的简称,它是一个面向全球的、点对点的分布式版本文件系统,试图将所有具有相同文件系统的计算设备连接在一起。 2.1 安装IPFS 至官网下载对应版本,一路安装即可,win10系统,下载对应zip解压后,将ipfs.exe添加到%PATH%。 2.2 启动本地IPFS节点 第一步:先初始化IPFS http://localhost:5001/webui,打开自己的操作台。 2.3 将Hexo博客部署到IPFS节点上 Hexo是一个静态博客生成器,执行hexo generate后,会在博客目录生成/Public目录,该目录即为全部博客内容 http://localhost:8080/ipfs/$SITE_HASH,也可以通过官方运行的节点访问:http://gateway.ipfs.io/ipfs/$SITE_HASH。 2.4 绑定独立域名 刚才,我们通过ipfs add,将博客发布到了IPFS运行的区块链节点上,但复杂的site_hash并不友好,我们可以使用IPNS技术,通过绑定独立域名来实现与现有的网站访问并无任何不一样的体现。我们假设你已经有一个可以正常使用的域名,如aa.com,没有域名的可以到任意域名服务商初购买。 如gateway.ipfs.io。 现在访问aa.com,你是不是发现已经可以正常访问你刚才生成的博客了。当然,在没有优化之前,访问会很慢,但可以打开。 http://ipfs.io/ipfs/QmeaNWtacNyWZxEphYCdVmF6bcMg7Bjn6e5sGdK6fr1nMx 查看本页面。 将Hexo部署到VPS实现自动发布 搭建流程 服务器环境配置,安装Git、Nginx配置、创建git用户 本地hexo初始化 使用Git自动部署并发布博客 服务器环境搭建 安装Git和NodeJS(Centos环境) yum install git # 安装NodeJS curl --silent --location https://rpm.nodesource.com/setup_5.x | bash - 创建git账号 adduser git chmod 740 /etc/sudoers vim /etc/sudoers 添加内容 ## Allow root to run any commands anywhere root ALL=(ALL) ALL 添加以下内容 git ALL=(ALL) ALL 保存退出并改回权限 chmod 400 /etc/sudoers 设置git账号密码 sudo passwd git 使用su git切换到git用户,再执行下列操作: # 切换到git用户目录 cd /home/git # 创建.ssh文件夹 mkdir ~/.ssh # 创建authorized_keys文件并编辑 vim ~/.ssh/authorized_keys # 如果你还没有生成公钥,那么首先在本地电脑中执行 cat ~/.ssh/id_rsa.pub | pbcopy生成公钥 # 再将公钥复制粘贴到authorized_keys # 保存关闭authorized_keys后,修改相应权限 chmod 600 ~/.ssh/authorized_keys chmod 700 ~/.ssh 然后可以通过本地Git Bash执行ssh命令测试是否可以免密登录 ssh -v git@服务器ip地址 这样git用户就添加好了。 Tips: 将公钥拷贝到服务器的~/.ssh/authorized_keys文件中方法有如下几种: 将公钥通过scp拷贝到服务器上,然后追加到~/.ssh/authorized_keys文件中,这种方式比较麻烦。scp -P 22 ~/.ssh/id_rsa.pub user@host:~/。 通过ssh-copy-id程序,就是我演示的方法,ssh-copyid user@host即可 可以通过cat ~/.ssh/id_rsa.pub | ssh username@host "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys",这个也是比较常用的方法,因为可以更改端口号。 安装Nginx 准备工作 yum install gcc-c++ yum install pcre pcre-devel yum install zlib zlib-devel yum install openssl openssl--devel Ubuntu系统安装命令如下: sudo apt-get install libpcre3 libpcre3-dev sudo apt-get install zlib1g-dev sudo apt-get install openssl libssl-dev 安装Nginx find -name nginx 如果系统已经安装了nginx,那么就先卸载 yum remove nginx 然后开始安装 /usr/local目录 cd /usr/local 从官网下载最新版的nginx wget -c https://nginx.org/download/nginx-1.14.2.tar.gz (注:版本号可更改,去官网查看最新版本号修改即可) 解压nginx压缩包 tar -zxvf nginx-1.14.2.tar.gz 会产生一个nginx-1.14.2 目录,这时进入nginx-1.14.2 目录 cd nginx-1.14.2 接下来安装,使用–prefix参数指定nginx安装的目录,make、make install安装 ./configure (默认安装在/usr/local/nginx,推荐使用默认设置) make make install 如果没有报错,顺利完成后,最好看一下nginx的安装目录 whereis nginx (where和is要连这些,中间没有空格) 启动和停止nginx cd /usr/local/nginx/sbin/ ./nginx ./nginx -s stop ./nginx -s quit ./nginx -s reload ./nginx -s quit: 此方式停止步骤是待nginx进程处理任务完毕进行停止。 ./nginx -s stop: 此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。 查询nginx进程: ps aux | grep nginx 重启 nginx 先停止再启动(推荐): ./nginx -s quit ./nginx 重新加载配置文件: ./nginx -s reload 启动成功后,在浏览器可以看到如下页面: 开机自启动 即在rc.local增加启动代码就可以了。 vim /etc/rc.local 增加一行 /usr/local/nginx/sbin/nginx 到这里,nginx安装完毕,启动、停止、重启操作也都完成。 建立git裸库 # 回到git目录 cd /home/git # 使用git用户创建git裸仓库,以blog.git为例 git init --bare blog.git 检查用户组权限 我们的git裸仓库已经建立好了,离成功又近了一步。为了以防万一,我们要检查一下之前的blog.git、.ssh、blog目录的用户组权限是否都为git:git # 还记得/var/www/吗?这是之前配置nginx时,我们自己选定的网站根目录,请依据你自己的设置更改,如果没有的话自己 ll -a /www/wwwroot/hexo ll -a /home/git/ 如果有哪个不是,执行下面相应的命令后再查看 sudo chown -R git:git /www/wwwroot/hexo sudo chmod -R 755 /www/wwwroot/hexo sudo chown git:git -R /home/git/blog.git 使用git-hooks同步网站根目录 简单来说,我们使用一个钩子文件:post-receive,每当git仓库接收到内容的时候,就会自动调用这个钩子,把内容同步到网站根目录。 # 新建一个post-receive文件并编辑 vim ~/blog.git/hooks/post-receive 在里面输入以下内容,注意修改为自己的设置: #!/bin/bash set -e GIT_REPO=/home/git/blog.git TMP_GIT_CLONE=/tmp/blog PUBLIC_WWW=/www/wwwroot/hexo rm -rf ${TMP_GIT_CLONE} git clone -b main $GIT_REPO $TMP_GIT_CLONE cd $TMP_GIT_CLONE #for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done #git checkout main rm -rf ${PUBLIC_WWW}/* cp -rf ${TMP_GIT_CLONE}/* ${PUBLIC_WWW} echo "update web done!" #ls -al ${PUBLIC_WWW} rm -rf ${TMP_GIT_CLONE} 保存退出后,执行以下赋予这个文件可执行权限。 chown -R git:git ~/blog.git/hooks/post-receive chmod +x ~/blog.git/hooks/post-receive 好了,以上就是服务器端需要配置的内容。我们还差最后一步就可以完成整个部署了! 修改配置文件nginx.conf 修改上面的配置文件: vim /usr/local/nginx/conf/nginx_config 然后修改其中两个部分,如下所示: 然后重启nginx,方法见nginx安装部分。 配置本地Hexo的_config.yml 非常简单,只需要找到本地Hexo博客的站点配置文件_config.yml,找到以下内容并修改: deploy: type: git repo: git@你的服务器IP:/home/git/blog.git branch: master 保存后,剩下的就是Hexo的日常操作了,这里就不赘述了,写完文章后,在你的本地博客根目录执行以下命令: hexo c && hexo g -d 就可以实现线上博客的自动更新了!一切搞定! webhook部署 adnanh/webhook 上面这个仓库支持在你的VPS 快速建立一个webhook 接口。然后利用 github webhook 通知你的 VPS 来拉取最新的代码部署 对于 webhook 来说,可以自己写一个脚本来接受信息,思路很简单,运行一个 HTTP Server,监听服务器的某个端口,如果有消息传递过来,那么就运行事先写好的脚本,来完成 webhook 的功能即可。 安装 webhook 这里推荐三种安装方法,使用其中一种方法即可,github 下载速度可能很慢,推荐使用系统源安装的方式 法一:使用系统源的安装方式 如果是 Ubuntu 系统,可以直接使用下面的命令进行安装: $ sudo apt-get update $ sudo apt-get install webhook 法二:使用 github 下载 webhook 的 release 链接,找到对应的选项 webhook-linux-amd64.tar.gz 右键复制链接 ,当前最新版本链接为 // 下载对应的软件 $ wget https://github.com/adnanh/webhook/releases/download/2.8.1/webhook-linux-amd64.tar.gz // 解压进入 $ tar -zxf tar -zxf webhook-linux-amd64.tar.gz && cd webhook-linux-amd64/ $ ./webhook 法三:Golang 环境下安装 首先安装 Golang 环境(这里略过),然后安装 webhook,这里注意需要已经设置了 GOPATH // 安装对应的工具 $ go get github.com/adnanh/webhook // 安装完成之后可以在 $GOPATH/bin 下找到对应的执行文件 $ echo $GOPATH /root/go $ ls /root/go/bin webhook // 将路径写入到 shell 可以直接执行 $ vi ~/.bash_profile // 在文件最后一行加入对应内容 export PATH="/root/go/bin:$PATH" // 更新文件使其生效 $ source ~/.bash_profile // 测试命令是否已经成功安装,得到输出说明安装完成 $ webhook 配置 webhook 我们的 hooks.json 文件现在看起来是这样的: [ { "id": "redeploy-webhook", "execute-command": "/var/scripts/redeploy.sh", "command-working-directory": "/var/webhook" } ] 注意:如果您更喜欢 YAML 格式,等价的 hooks.yaml 文件如下: - id: redeploy-webhook execute-command: "/var/scripts/redeploy.sh" command-working-directory: "/var/webhook" 您现在可以使用以下命令运行 webhook: $ /path/to/webhook -hooks hooks.json -verbose 它将在默认端口 9000 上启动,并为您提供一个 HTTP 终端: http://yourserver:9000/hooks/redeploy-webhook 更多配置参数 webhook/docs/Webhook-Parameters.md at master · adnanh/webhook (github.com) Usage of webhook: -cert string path to the HTTPS certificate pem file (default "cert.pem") -cipher-suites string comma-separated list of supported TLS cipher suites -debug show debug output -header value response header to return, specified in format name=value, use multiple times to set multiple headers -hooks value path to the json file containing defined hooks the webhook should serve, use multiple times to load from different files -hotreload watch hooks file for changes and reload them automatically -http-methods string globally restrict allowed HTTP methods; separate methods with comma -ip string ip the webhook should serve hooks on (default "0.0.0.0") -key string path to the HTTPS certificate private key pem file (default "key.pem") -list-cipher-suites list available TLS cipher suites -logfile string send log output to a file; implicitly enables verbose logging -nopanic do not panic if hooks cannot be loaded when webhook is not running in verbose mode -pidfile string create PID file at the given path -port int port the webhook should serve hooks on (default 9000) -secure use HTTPS instead of HTTP -setgid int set group ID after opening listening port; must be used with setuid -setuid int set user ID after opening listening port; must be used with setgid -template parse hooks file as a Go template -tls-min-version string minimum TLS version (1.0, 1.1, 1.2, 1.3) (default "1.2") -urlprefix string url prefix to use for served hooks (protocol://yourserver:port/PREFIX/:hook-id) (default "hooks") -verbose show verbose output -version display webhook version and quit -x-request-id use X-Request-Id header, if present, as request ID -x-request-id-limit int truncate X-Request-Id header to limit; default no limit 实战 # pwd /www/docker/webhook # tree . . ├── bin │ └── webhook ├── xxx └── webhook-linux-amd64.tar.gz 2 directories, 2 files 利用 uuidgen 生成随机 ID # uuidgen ecbfc10e-6b2d-4d32-98da-bdd2c3c29fc7 hooks.yaml - id: redeploy-hblog-xxxxx-7e86-4f24-8667-23xxxxxxx1 execute-command: "/www/docker/webhook/github-webhooks/depHblog.sh" command-working-directory: "/www/wwwroot/blog.17lai.site" depHblog.sh #!/bin/sh # 创建临时目录 temp_dir='/www/docker/webhook/tmp/hexoblog' dst_dir='/www/wwwroot/blog.17lai.site' repo_url='https://github.com/appotry/hexo.git' data_dir='' # 在这里进行你的操作,例如复制文件、下载内容等 # 检查目标目录是否存在 .git 目录 if [ -d "$temp_dir/.git" ]; then # 如果存在 .git 目录,则执行 git pull 命令进行更新 echo "Repository already cloned. Performing git pull..." cd "$temp_dir" git pull origin main # 如果使用了默认的主分支名字为 main git reset --hard origin/main else # 如果不存在 .git 目录,则执行 git clone 命令进行克隆 rm $temp_dir -rf echo "Cloning repository into $temp_dir..." git clone --progress -v --depth 1 "$repo_url" "$temp_dir" fi echo "rsync 目录同步" # -a:表示以归档模式同步,保留文件的所有属性,包括权限、时间戳等。 # -v:表示详细模式,显示同步过程中的详细信息。 # --delete:表示删除目标目录中源目录没有的文件。 rsync --delete -r --exclude='.git' --link-dest="$dst_dir" ${temp_dir}/${data_dir} ${dst_dir} echo "设置文件权限" chown www:www ${dst_dir}/${data_dir} -R vim depHblog.sh chmod +x depHblog.sh curl -X POST https://xxxx.17lai.site/hooks/redeploy-hblog-xxxx8fa-7e86-4f24-8667-23axxxx # 运行测试 su root /www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.json -verbose -port <通信端口> /www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.yaml -verbose -port 18xxx 后台运行 nohup webhook -hooks /usr/local/bin/github-webhooks/hooks.json -verbose -port <通信端口> & 反向代理 宝塔面板 go 项目 调用 curl -X POST https://xxx.17lai.site/hooks/redeploy-hblog-xxxa-7e86-4f24-8667-2xxxx3xx 上面命令测试成功之后就可以正式和 github 仓库关联起来了 Rsync同步部署静态文件方法 使用rsync同步 本地生成静态文件后rsync同步到vps网页目录,lnap使用宝塔配置,这里只需要一个nginx。 # rsync [options] from_dir to_dir # 替换这里的ip为你的服务器ip rsync -avzP /home/17lai.blog root@8.8.8.8:/www/wwwroot/hexo Hexo Github Action 自动部署 准备 Hexo 博客源码的仓库,在 GitHub 上。 ssh 密钥,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub 步骤 为需要部署的平台添加密钥 修改 _config.yml 中的 deploy 配置 在 GitHub 上设置 Secrets 创建 GitHub Action 为需要部署的平台添加密钥 按照之前的教程,只要你之前成功将 Hexo 的博客部署到 GitHub 上,那你电脑在 ~/.ssh 目录下一定有以下三个文件: id_rsa:私钥 id_rsa.pub:公钥 known_hosts:记录对所有用户都可信赖的远程主机的公钥 将 id_rsa.pub(公钥)添加到不同平台中即可,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub 下面是不同平台添加的地址: GitHub GitLab Coding Gitee 修改 _config.yml 中的 deploy 配置 请使用 ssh (即以 git@ 开头的 clone 链接) 的连接方式,根据直接的实际地址填写。 deploy: - type: git repo: github: git@github.com:Sitoi/Sitoi.github.io.git coding: git@e.coding.net:Sitoi/Sitoi.git gitee: git@gitee.com:sitoi/sitoi.git gitlab: git@gitlab.com:Sitoi/sitoi.gitlab.io.git branch: master 在 GitHub 上设置 Secrets 进入到你在 GitHub 上面的源码仓库 点击右上角的 Settings Settings 点击左侧的 Secrets 点击右上角的 New secret New secret 在 Name 中输入 HEXO_DEPLOY_PRI,在 Value 中填入 id_rsa(私钥)的全部内容 Add secret 创建 GitHub Action 点击项目上方的 Action 按钮 Action 点击 set up a workflow yourself 创建 Workflow Workflow 修改 main.yaml 的内容 Create Workflow 根据实际情况修改成你自己的内容 Git 推送使用的用户名:git config –global user.name ‘your name’: Git 推送使用的邮箱:git config –global user.email name@email.com Hexo 的版本:npm i hexo@4.1.1 -g name: Hexo CI on: push: branches: - butterfly jobs: butterfly-build: runs-on: ubuntu-latest strategy: matrix: node-version: [10.x] steps: - uses: actions/checkout@v1 - name: Use Node.js 10.x uses: actions/setup-node@v1 with: node-version: '10.x' - name: env prepare env: HEXO_DEPLOY_PRI: ${{ secrets.HEXO_DEPLOY_PRI }} run: | mkdir -p ~/.ssh/ echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan github.com >> ~/.ssh/known_hosts ssh-keyscan gitlab.com >> ~/.ssh/known_hosts ssh-keyscan e.coding.net >> ~/.ssh/known_hosts ssh-keyscan gitee.com >> ~/.ssh/known_hosts git config --global user.name 'sito' git config --global user.email '133397418@qq.com' npm i npm i hexo@4.1.1 -g - name: gen run: | hexo clean hexo generate hexo deploy 下面这个部署脚本功能更加完善,解决了文章更新时间问题 .github/workflows/deploy.yml name: Hexo Deploy on: push: branches: - master workflow_dispatch: jobs: build: permissions: contents: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Use Node.js 18 uses: actions/setup-node@v2 with: node-version: 18 cache: yarn - name: Install Dependencies run: yarn install - name: Fix File Modify Date run: | git ls-files | while read filepath; do touch -d "$(git log -1 --format='@%ct' $filepath)" "$filepath" && echo "Fixed: $filepath"; done - name: Build Site run: | export TZ='Asia/Shanghai' yarn build - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: public cname: 17lai.site - name: Setup Deploy Private Key env: HEXO_DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY_KEY }} run: | mkdir -p ~/.ssh/ echo "$HEXO_DEPLOY_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan blog.17lai.site >> ~/.ssh/known_hosts - name: Deploy to VPS run: yarn deploy 将你的源码推送到 GitHub 上,你的博客一会就会自动更新了。 Hexo Gitlab CI/CD自动部署 啥都不说,直接上代码,请参考 Gitlab 官方项目 Gitlab hexo 更多关于 Gitlab CICD 介绍,请看下面文章 CI/CD与Git Flow与GitLab vercel 部署 jsdelivr被封了,怎么办?vercel 部署可以加速访问 为什么使用 vercel 国内 Github Pages 速度较慢。 vercel 速度快且能够自定义域名,能实现和 Github Pages 一样的效果 vercel 官方地址:vercel.com/ 如何部署 首先注册一个账号 注册成功后进入页面,点击 News Project 然后通过绑定的 github 或者 gitlab 导入需要部署的项目 如果导入的项目是打包好的静态页,在 Build and Output Settings 的 override 都勾上,表示不执行它的默认命令。 点击 deployed 进行部署,如果部署失败可以查看报错信息是不是上一步的某些选项没有覆盖。部署成功后会进入如图所示的界面 如何自定义域名 腾讯云域名地址:console.cloud.tencent.com/domain vercel 静态页挂载地址: 进入到 setting 中可对项目进行一些设置,如项目名称 下面演示如何自定义域名,默认情况下部署成功后 vercel 会给你生成一个默认的域名,如果想要修改成自己的域名可将域名名称修改成自己的。 当选择修改成自己的域名名称后,vercel 会检查域名指向的 DNS 对不对,如果不对的话会提示你域名的 DNS 应该如何配置,按照 vercel 提示的 DNS 信息 在自己的域名的 DNS 配置中进行配置,如图 配置多个域名 对其他新增的域名选择重定向到自己的主域名即可 自定义Header缓存时间 vercel.com/docs 使用Vercel必备配置,本地缓存加速访问! vercel.json { "headers": [ { "source": "/sw.js", "headers": [ { "key": "Cache-Control", "value": "public, max-age=0, must-revalidate" } ] }, { "source": "(.*)", "headers": [ { "key": "Cache-Control", "value": "public, s-maxage=86400, max-age=86400" } ] } ] } Vercel自定义404 learn how to customize the 404 page. cloudflare Pages 部署 jsdelivr被封了,怎么办?cloudflare Pages 部署可以加速访问 强烈推荐! 全球CDN,静态加速,可以说是最佳部署方案!就是有每日100000次请求限制!可以使用dnspod多线路负载均衡来帮助分流。 官网 cloudflare 首先注册一个账号 错过了CloudFlare Partner的时代,官方的CloudFlare for SaaS也提供了一种更灵活的CNAME接入方式 https://blog.cloudflare.com/zh-cn/waf-for-saas-zh-cn/ Cloudflare访问速率限制 我们一直不怕网站内容被爬走,但怕服务器被疯狂的爬虫爬垮,所以希望能限制恶意爬虫速度,而又不影响用户访问和搜索引擎爬虫抓取,这是个两难的事情。不过 Cloudflare 提供了 DNS 级别控制的速率限制! Rate limiting rules 各计划的速率限制额度 计划 规则数 操作 操作持续时间 请求期间 免费 1 阻止 1 分钟或 1 小时 10 秒钟或 1 分钟 Pro 10 阻止、旧版 CAPTCHA、JS 质询、托管质询或记录 1 分钟或 1 小时 10 秒钟或 1 分钟 Business 15 阻止、旧版 CAPTCHA、JS 质询、托管质询或记录 1 分钟、1 小时或 24 小时 10 秒钟、1 分钟或 10 分钟 企业 100 阻止、旧版 CAPTCHA、JS 质询、托管质询或记录 可以输入 10 秒到 86400 秒(24 小时)范围内的任何时间长度 可以输入 10 秒到 3600 秒(1 小时)范围内的任何值。 设置方法 该功能是防御 CC 强有效的功能,可以从【安全性】-【WAF-】【速率限制规则】进入配置页面。 针对免费用户来说可以配置的参数比较少,主要实现的是同个 IP(10 秒内请求数>n)时对其返回 429 阻止访问。如图填写 / 可对 zone 下所有域名进行保护,正常情况下 n 建议设置为 50-100,资源更多的站点可以考虑适当放大(以不影响正常访问为准)。 在“安全性” - “WAF” - “防火墙规则”中添加排除跳过速率限制只能老版本的速率限制有效,但新版本的速率限制无效,可以采取在“安全性” - “WAF” - “工具”中添加IP 访问规则,将常见的AS15169(Google)、AS8075(Microsoft)等IP段设置为“允许”,这些IP就不会受到速率限制的影响; 所有版本都在过滤条件中增加了Verified Bot,可以让通过验证的好爬虫跳过速率限制,设置截图如下: CORS跨域问题 CloudFlare 解决 CORS 跨域问题 nginx 解决 CORS nginx配置文件中添加: #跨域 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type'; 以 token 方式部署到 Github deploy: type: git repo: github: url: <repository url> branch: [branch] token: '' message: [message] name: [git user] email: [git email] extend_dirs: [extend directory] ignore_hidden: false # default is true ignore_pattern: regexp # whatever file that matches the travis 自动部署配置 travis是第三方CICD服务,比action更加强大,下面只是参考,请查阅travis 文档,并结合自己的环境修改! sudo: false language: node_js node_js: - 10.16.3 cache: npm branches: only: - master # build master branch only env: global: - GIT_USER: appotry - HEXO_BACKUP_REPO: github.com/appotry/hexo-backup.git - HEXO_THEME_REPO: github.com/appotry/hexo-theme-matery.git - GITHUB_PAGES_REPO: github.com/appotry/hexo.github.io.git - APPOTRY_REPO: github.com/appotry/hexo.git before_install: - export TZ='Asia/Shanghai' - npm install hexo -g - npm install gulp-cli -g install: - npm install script: - git clone https://${HEXO_THEME_REPO} themes/next - git clone https://${GIT_USER}:${GITHUB_TOKEN}@${HEXO_BACKUP_REPO} hexo-backup - mv hexo-backup/source . - rm -rf source/private - npm run build after_success: - git config --global user.name "appotry" - git config --global user.email "email@qq.com" - git clone https://${GIT_USER}:${GITHUB_TOKEN}@${GITHUB_PAGES_REPO} voidking - unalias cp - cp -rf public/. 17lai.blog - cd 17lai.blog - git add . - git commit -m "Travis CI Auto Builder" - git push --force --quiet "https://${GIT_USER}:${GITHUB_TOKEN}@${GITHUB_PAGES_REPO}" master:master 利用 GitLab 实现 Hexo 博客的 CI/CD Portainer 提供了对服务在线更新的 WebHook,所以基于 GitLab 自带的 CI/CD 功能实现 Hexo 博客的持续部署,就非常轻松了。 CI/CD 其实本质上是一套流程,流程规则可以自行定义。在本文研究的主题下,流程分为三步:第一步是编译 Hexo 博客并生成静态文件;第二步是将静态文件打包成可提供 Web 服务的镜像;第三步则是通过 Portainer 的钩子触发服务更新。 .gitlab-ci.yml stages: - compile - build - deploy # CONTAINER_RELEASE_IMAGE 根据自己的仓库名修改 variables: DOCKER_HOST: tcp://docker:2375 DOCKER_DRIVER: overlay2 CONTAINER_RELEASE_IMAGE: registry.gitlab.com/xxx/xxx:latest compile: stage: compile image: node:lts-alpine script: - npm install - ./node_modules/hexo/bin/hexo generate artifacts: paths: - public/ expire_in: 20 minutes build: stage: build image: docker:stable services: - docker:dind script: - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com - docker info - docker build -f ./Dockerfile -t $CONTAINER_RELEASE_IMAGE public - docker push $CONTAINER_RELEASE_IMAGE # 根据自己的钩子修改下方的 URL deploy: stage: deploy script: - curl https://xxx.xxx.xxx/api/webhooks/xxx -X POST 为了保证服务更新的成功率,可以在 deploy 环节加个错误判断和重试次数,具体的看 GitLab 官方文档即可。 下面给出我的 Dockerfile 文件,供参考。 FROM nginx:alpine COPY . /usr/share/nginx/html RUN chmod 777 /usr/share/nginx/html -R \ && sed -i 's/#error_page 404/error_page 404/' /etc/nginx/conf.d/default.conf 部署图床 有很多上传图片的方法,如果使用第三方服务,不知道什么时候就跑路了。所以还是自己部署图床比较稳妥 github pages 使用git 管理图片仓库。picgo + github 上传,保存图片,github pages 或者 vercel,netlify,cloudflare pages来作为网络访问。 vercel 托管github上面的图片仓库。 每月免费100G流量。 还有netlify托管,github托管,都有每月免费100G流量使用dns分流,采用DNS 权重自动分流每月就有300G免费流量了。 300G流量,足够每天几千PV访问量了 npm托管 还有一个完全不要钱的方案。图片使用npm包管理,上传到npm仓库,各个npm镜像仓库就都是你的图床了。没有流量限制,就怕什么时候npm封闭你的账号 O(∩_∩)O哈哈~ 本文假设您已有 NPM 账号、GitHub 账号。 下面是一个使用GithubAction和NPM搭建自动转换webp图床的完整教程 准备工作 新建仓库 新建一个 GitHub 仓库,公开或是私人都可以,此处不再赘述。 在 Git 仓库中新建 rawimg/.gitkeep 与 webpimg/.gitkeep 两个文件。 获取令牌 登录 https://npmjs.com ,点击右上角的头像,进入 Access Token。 点击页面中的 Generate New Token 获取新的令牌。 选择 Automation,点击 Generate Token 生成令牌。 将生成的令牌复制下来。 进入 GitHub 仓库,点击 Settings。 点击菜单栏中的 Secrets。 点击 New repository secret 新建一个 Secret。 Secret Name 为 NPM_TOKEN,Value 是你的 NPM 令牌,点击 Add secret 添加。 在仓库中新建 package.json 文件,参考如下: { "name": "ocoke-osg", "version": "0.0.0", "description": "Somewhere to save the file from @oCoke", "author": "YFun(@oCoke)" } 图片转换与发布 为了方便多端写作,我使用 GitHub 临时存储所需的图片,GitHub Action 发布 NPM 包。 WebP 可以大大缩减图片的尺寸,我们还可以借助 GitHub Action 在发布前自动转换。 name: NPM & WebP # 在 Release 发布时 或手动执行 on: release: types: - published workflow_dispatch: jobs: publish-npm: runs-on: ubuntu-latest # Clone 仓库 steps: - name: Checkout uses: actions/checkout@v2 with: ref: master # 安装 Node.js - name: Setup Node uses: actions/setup-node@v1 with: node-version: "12.x" registry-url: https://registry.npmjs.org/ # rawimg/ 作为原始图片存储,webpimg/ 作为压缩图片存储处,最后合并。 # 安装相关插件,转换图片。 - name: Install & Convert run: | npm install -g webp-batch-convert cwebp-batch --in rawimg --out webpimg -q 75 -quiet mv webpimg/*.webp rawimg/ # 发布 NPM 包 - name: Publish Package run: | git config --global user.email "icolabot@e.yfun.top" git config --global user.name "iColaBot" npm version patch npm publish env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} # 删除 rawimg/ 和 webpimg/ 下的所有文件 - name: Delete Files run: | rm -rf webpimg/* rm -rf rawimg/* touch webpimg/.gitkeep touch rawimg/.gitkeep - name: Push run: | git add -A git commit -m "Publish" git push origin master 使用 上传 将图片文件上传至仓库的 rawimg/ 文件夹下即可。 当然也可以使用 PicGo / UPic / HexoPlusPlus 等工具上传。 发布 在 GitHub 中新建 Release,将自动修改版本号并发布 NPM 包,无需手动修改 package.json。 访问 推荐的镜像 https://cdn.jsdelivr.net/npm/ # jsDelivr https://unpkg.zhimg.com/ # 知乎 https://code.bdstatic.com/npm/ # 百度 (不推荐) https://shadow.elemecdn.com/npm/ # 饿了么 https://unpkg.com/ # Unpkg 镜像推荐选择访问速度快的,比较稳定的,拉取速度快的。 我选择的是 jsDelivr,国内外速度都很优秀。 链接 以 jsDelivr 为例,原图链接为: https://cdn.jsdelivr.net/npm/[package-name]@[version]/rawimg/[filename].[suffix] WebP 图片链接为: https://cdn.jsdelivr.net/npm/[package-name]@[version]/rawimg/[filename].webp [值] 说明 package-name NPM 包的名称 (package.json 文件中 name 的值) version 当前版本 (package.json 文件中 version 的值,通常需要在发布 Release 1 分钟后更新) filename 文件名 suffix 文件后缀名 vps自建图床 lychee , chevereto 等免费图床工具有很多。就是需要自己配置vps https://hub.docker.com/r/nmtan/chevereto https://hub.docker.com/r/linuxserver/lychee 下面是一个 docker compose 创建Lychee图床的示例 version: "3" services: mariadb: image: lscr.io/linuxserver/mariadb:latest container_name: lychee_mariadb restart: always volumes: - /path/to/mariadb/data:/config environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=lychee - MYSQL_USER=lychee - MYSQL_PASSWORD=dbpassword - PGID=1000 - PUID=1000 - TZ=Europe/London lychee: image: lscr.io/linuxserver/lychee:latest container_name: lychee restart: always depends_on: - mariadb volumes: - /path/to/config:/config - /path/to/pictures:/pictures environment: - DB_CONNECTION=mysql - DB_HOST=mariadb - DB_PORT=3306 - DB_USERNAME=lychee - DB_PASSWORD=dbpassword - DB_DATABASE=lychee - PGID=1000 - PUID=1000 - TZ=Europe/London ports: - 80:80 DNS 优化 DNSPOD 多线路负载均衡 DNSPOD官网 console.dnspod.cn dnspod对cname数目有限制。 这里使用权重来分配各条线路访问比例! DNSPOD api 使用教程 使用 dns api 来自动化设置 dns ,可以实现很多 dns 收费功能! 例如定时自动修改 dns 的指向 ip 或者cname 值,来实现资源,负载的动态平衡! 登录DNSPod DNSPod:https://console.dnspod.cn/ 创建API密钥 注意保存密码,只显示一次 配置请求 获取RecordList、RecordId Domain填写一级域名 Subdomain填写二级域名 https://console.cloud.tencent.com/api/explorer?Product=dnspod&Version=2021-03-23&Action=DescribeRecordList 修改解析值 https://console.cloud.tencent.com/api/explorer?Product=dnspod&Version=2021-03-23&Action=ModifyRecord Domain填写一级域名 Subdomain填写二级域名 RecordId填写要修改的记录ID RecordType记录类型(例如修改的IPV6,所以填AAAA;可以在https://console.cloud.tencent.com/cns/detail/xumeng03.com/records查阅记录类型) RecordLine填写“默认”即可 Value填写要换的IP地址 确认在此页面可以修改正确后就进行下一步 修改域名工具(go) 编写过程中多有参考ddns-go:https://github.com/jeessy2/ddns-go,本工具链接:https://github.com/xumeng03/ddns 乒乓部署 也可以叫旋转门部署。 解决调试博客插件,修改半成品文章时部署到云端会影响正在查阅博客的用户的问题! 使用Docker版本本地预览是很不错,但是 jsdelivr 版本发布需要在 Github 生成新 release 这时本地就不行了。乒乓部署可以解决这个问题! 具体方法就是同时部署到两个地方A和B,博客域名在两个服务器之间切换。这里以 Vercel 为例 准备工作: 创建2个Github仓库,对应服务器A和B的部署 建立两个服务器A和B,分别关联两个 Github 仓库 把调试完毕的代码上传到两个仓库 这时通过服务器A和B都是可以正常浏览的 要调试的时候: 发布到A之前,把博客域名转移到服务器B 在服务A做一些调试,在线 debug 工作 特别是在线 pageseed 测试调优,这种事必备方法。简单不需要新的 jsdelivr 版本调试本地 docker-hexo 调试即可! 调试完毕后: 把域名切换到服务器A 同时部署到服务器B,服务器B同步A的部署内容,以便下次备用 总结就是服务器A现行,服务器B做后备,调试发布使用A,调试A的时候B就顶上前台! 这样,调试和正常部署网络服务两不误。是不是感觉自己是个大聪明! 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/27
articleCard.readMore

基于Hexo的matery主题搭建博客网络优化篇3

经过一系列优化修改后,网站测速评分总算是过得去了。😄使用技术大概有如下: 各种CDN webp lazyload preload gulp 压缩 cloudflare parter service worker, PWA 部分资源异步加载 优化无止境,每当以为只能上钞能力的时候,又发现了新的优化方法! 看来,钞能力还得保留一整子了~ 加载速度优化概要 性能优化 浏览器渲染网页的过程可以参考这篇文章 在浏览器输入 URL 回车之后发生了什么 前端性能优化作为前端开发中的一项系统化工程,不仅仅是提升页面加载速度或减少资源大小,它涵盖了从网络请求、资源加载、代码执行到页面渲染等多个环节的优化策略,是一个复杂且系统化的工程。然而,在实际开发过程中,许多开发者往往只关注某些局部的优化点,如压缩图片、减少HTTP请求等,而缺乏对性能优化全局的把握。这种碎片化的优化方式虽然能在一定程度上提升性能,但往往难以达到最佳效果,甚至可能引入新的性能瓶颈。 因此,掌握前端性能优化的全局视角,理解各个环节的优化原理与实践方法,是每一位前端开发者必须面对的重要课题。本文将从性能优化的核心目标出发,探索性能优化的整个流程的核心关键节点以及其优化手段,帮助开发者建立起系统化的性能优化思维。 整体流程 前端性能优化的核心目标是提升用户从输入 URL 到最终看到完整页面并与之交互的体验。这一过程可以概括为三个主要环节:从用户输入 URL 到资源加载完成、浏览器解析与渲染网页、JavaScript 脚本执行。每个环节都涉及不同的性能瓶颈和优化机会,只有系统性地分析并优化这些环节,才能真正提升前端性能。 输入URl到请求结束的流程 输入URL URL解析 DNS查询 建立TCP连接 发送HTTP请求 服务器处理请求 服务器返回响应 关闭连接 通过思维导图,再看看其中的详细过程 网络请求优化 当用户在浏览器地址栏输入 URL 并按下回车键后,浏览器会经历一系列步骤,包括 DNS 解析、建立 TCP 连接、发送 HTTP 请求、等待服务器响应,以及最终将资源(如 HTML、CSS、JavaScript 等)下载到本地。 这一过程的核心是从用户发起请求到浏览器接收到完整的资源数据,其效率直接影响页面的首次加载时间(First Contentful Paint, FCP)。 优化这一环节的关键在于减少网络延迟、压缩资源体积、利用缓存机制以及优化服务器响应时间。把这些点总结一下可以分两个思路:网络链路加速和网络负载体积减少 渲染优化 当浏览器接收到 HTML、CSS、JavaScript 等资源后,会开始解析和渲染页面。这个过程包括构建 DOM 树、CSSOM 树、合并生成渲染树(Render Tree),以及进行布局(Layout)和绘制(Paint)。浏览器解析和渲染的效率直接影响页面的交互性和流畅度。 优化这一环节的关键在于减少渲染阻塞资源、优化 CSS 和 HTML 结构、避免不必要的重排(Reflow)和重绘(Repaint)以及GPU加速等。 JS 执行优化 JavaScript 是前端交互的核心,但它的执行效率直接影响页面的响应速度和用户体验。JavaScript 的解析、编译和执行可能会阻塞主线程,导致页面卡顿或无响应。 优化这一环节的关键在于 减少 JavaScript 文件大小、避免长任务(Long Tasks)、优化代码执行效率,以及合理使用 Web Workers 等技术来分担主线程的压力。以下是几种常见的优化方法: 使用 async 和 defer 加载脚本 JavaScript 默认是 同步加载并执行 的,会阻塞 HTML 解析,因此对于外部脚本文件,推荐使用 async 或 defer 来优化加载策略。 属性 执行顺序 是否阻塞 HTML 解析 适用场景 async 下载完立即执行,多个 async 脚本执行顺序不固定 否 独立脚本,不依赖其他脚本(如广告、统计代码) defer HTML 解析完后按顺序执行 否 依赖 HTML 结构或其他脚本(如主逻辑 JS 文件) ✅ 示例 <!-- async:适用于无依赖的独立脚本 --> <script async src="analytics.js"></script> <!-- defer:适用于依赖 HTML 结构的脚本(推荐)--> <script defer src="main.js"></script> 代码拆分 & 按需加载 加载过多的 JavaScript 会拖慢页面速度,因此可以使用 代码拆分(Code Splitting)和 按需加载(Lazy Loading)减少主线程压力。 ✅ 示例:使用 import() 进行动态加载 document.getElementById('loadFeature').addEventListener('click', async () => { const { featureFunction } = await import('./featureModule.js'); featureFunction(); }); 只有用户点击按钮时才会加载 featureModule.js,减少初始加载时间。 避免长任务(Long Tasks) 长任务(执行时间超过 50ms 的任务)会导致页面卡顿,影响交互流畅性。可以使用 requestIdleCallback 或 setTimeout 将任务拆分成多个小块执行。 ✅ 示例:使用 requestIdleCallback 让低优先级任务在空闲时间执行 requestIdleCallback(() => { heavyTask(); // 仅在浏览器空闲时执行 }); ✅ 示例:使用 setTimeout 让任务拆分执行 function processLargeArray(arr) { let i = 0; function nextChunk() { const start = performance.now(); while (i < arr.length && performance.now() - start < 50) { processItem(arr[i]); i++; } if (i < arr.length) { setTimeout(nextChunk, 0); } } nextChunk(); } 每次执行 50ms,避免长时间阻塞主线程,提高页面流畅度。 使用 Web Workers 进行多线程计算 JavaScript 运行在 单线程环境 下,繁重的计算任务会导致页面卡顿。可以使用 Web Workers 将计算任务放到后台线程运行。 ✅ 示例:使用 Web Worker worker.js self.onmessage = function (event) { const result = heavyComputation(event.data); self.postMessage(result); }; 主线程 const worker = new Worker('worker.js'); worker.postMessage(largeData); worker.onmessage = function (event) { console.log('计算结果:', event.data); }; 计算任务在后台线程执行,主线程不会被阻塞,提高页面响应速度。 其他优化技巧 ✅ 减少 JavaScript 体积 使用 Tree Shaking 移除无用代码(适用于 ES6 import/export) 启用 gzip、Brotli 压缩(Content-Encoding: gzip) 使用 CDN 加速 静态资源加载 ✅ 优化 DOM 操作 减少回流(Reflow)和重绘(Repaint) 使用 documentFragment 进行批量 DOM 插入: const fragment = document.createDocumentFragment(); for (let i = 0; i < 1000; i++) { const div = document.createElement('div'); div.textContent = `Item ${i}`; fragment.appendChild(div); } document.body.appendChild(fragment); ✅ 使用 requestAnimationFrame() 提高动画流畅度 function smoothScroll() { requestAnimationFrame(smoothScroll); } smoothScroll(); 总结 优化方法 关键点 async & defer async 适用于无依赖脚本,defer 适用于依赖 HTML 的脚本 代码拆分 & 按需加载 仅在需要时加载 JavaScript 避免长任务 使用 requestIdleCallback 或 setTimeout 拆分任务 Web Workers 将 CPU 密集型任务放到后台线程 压缩 JavaScript 使用 Tree Shaking、Gzip/Brotli 压缩 优化 DOM 操作 减少回流 & 使用 documentFragment 合理使用这些技术,可以有效提升 JavaScript 执行效率,提高页面流畅度 🚀 网络链路优化 DNS 预解析 – dns-prefetch 通过在页面加载初期就解析可能需要的域名,当实际需要加载这些域名的资源时,DNS 解析已经完成,从而加快资源的加载速度。这个标签对于 CDN 域名等非主域名提前解析 CDN ,有很大的帮助,强烈建议添加。 dns-prefetch 可以通过 <link> 标签在 HTML 中声明,或者通过 HTTP 头部进行配置。 <head> <link rel="dns-prefetch" href="https://blog.17lai.site"> </head> HTTP 预连接 – preconnect preconnect 用于提前建立与目标域名的连接,包括 DNS 解析、TCP 握手和 TLS 协商。这比 dns-prefetch 更全面,适用于需要更早建立连接的场景。 使用方法和 dns-prefetch 类似 <head> <link rel="preconnect" href="https://blog.17lai.site" crossorigin> <head> 内容预加载 – prefetch prefetch 是一种资源提示,它告诉浏览器在空闲时间提前下载并缓存将来可能需要的资源。这可以显著减少用户请求这些资源时的等待时间,从而提高用户体验。 使用场景: 当您预测用户可能会导航到另一个页面或执行某个操作时,可以提前预加载该页面或操作所需的资源。 对于单页应用(SPA),预加载用户可能访问的下一个视图或组件可以显著提高性能。 使用方法: <head> <!-- 预加载整个页面 --> <link rel="prefetch" href="next-page.html"> <!-- 预加载特定资源,如图片、脚本或样式表 --> <link rel="prefetch" href="image.png" as="image"> <link rel="prefetch" href="script.js" as="script"> <link rel="prefetch" href="styles.css" as="style"> </head> 注意事项: 不要过度使用 prefetch,因为它可能会浪费带宽和资源,特别是当预加载的资源最终未被使用时。 优先加载 – preload preload 是一种更强大的资源提示,它告诉浏览器立即请求并缓存特定资源,以便在需要时立即使用。与 prefetch 不同,preload 更侧重于当前页面渲染所需的资源,而不是将来可能需要的资源。 使用场景: 当您知道某个资源对当前页面的渲染至关重要,并且希望确保它在需要时立即可用时,可以使用 preload。 对于关键路径上的资源,如关键的 CSS、JavaScript 或字体文件,preload 可以显著提高页面加载性能。 使用方法: <head> <!-- 立即加载 CSS --> <link rel="preload" href="styles.css" as="style"> <link rel="stylesheet" href="styles.css"> <!-- 立即加载 JavaScript --> <link rel="preload" href="main.js" as="script"> <script src="main.js"></script> <!-- 立即加载 --> <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin> </head> 注意事项: preload 的资源会被浏览器优先加载,这可能会影响其他资源的加载顺序和性能。 以上四种优化方式我们同程为 resource hints 资源缓存 通过http的缓存能力,将资源缓存到浏览器端,可以直接从浏览器拿取内容,不经过服务器,或者经过浏览器,浏览器返回 304,告诉浏览器直接使用缓存,不用下载。 缓存常用的 http header 包括,cach-control 和 expire 。这里内容较多,暂不展开,之后详细介绍 升级 HTTP 协议 HTTP 协议,主要包括HTTP/1.1、HTTP/2和HTTP/3。高版本在性能、安全性和功能上进行了优化和改进。能使用高版本,尽量使用高版本,同时做好兼容性配置。下面是几个版本的核心能力 HTTP 版本号 核心功能 HTTP/1.1 引入持久连接和管道化,提升了连接复用和传输效率,但存在队头阻塞问题 HTTP/2 采用二进制协议和多路复用,消除了队头阻塞,引入头部压缩和服务器推送,显著提升了性能和效率。 HTTP/3 基于QUIC协议,进一步优化了连接建立速度、传输效率和安全性,解决了TCP的一些固有问题,提供了更好的用户体验。 减少网络负载 网络传输协议压缩 开启 gzip 和 Brotli 压缩 在服务端放置 gzip 压缩后的文件,开启 gzip 之后,可以直接发送 gzip 文件,浏览器端会自动解析 gzip。 Brotli 和 gzip 一样的压缩策略,只不过压缩比更高,后来居上,但是兼容性不好,使用 brotli 需要考虑兼容性 资源内容压缩 JS 和 CSS 压缩 通过打包工具,去掉注释,空格,各种名称精简等方式,将 js 和 CSS 压缩到更小的体积, 图片压缩 图片大小优化有两个方向: 通过压缩算法,将图片压缩到更小的体积,常用的网站如:https://tinify.cn/ 转换图片格式,获得更小的体积。比如 jpg 转 png,png 转 webp等,webp 有更小的体积,但要考虑兼容性问题。 利用 tree shaking 使用第三方库时,经常会将所有代码引入进来,但是只用到其中的很少的功能。因此,通过打包工具,开启tree shaking,可以有效减少生成代码的体积。 开始tree shaking 的优化 代码拆分 不同页面有不同的功能,代码逻辑不同。因此,在加载首页时,非必要的内容就不要加载,减少首次加载的资源的体积。 网站测速工具 网站打开速度已经成为 SEO 重要的排名依据,除了上面说到的人肉测试,就面向国内用户 + 加载速度测试场景而言,推荐以下三款工具: 站长工具 IPIP.NET TraceRoute 查询 Pingdom Website Speed Test 站长工具 网站速度测试 针对国内资源加载、网站速度测试。包括 Ping 检测、国内外多监测点网速测试、网站速度对比、DNS 查询和路由跟踪等工具。 点击打开 IPIP.NET TraceRoute 查询 IPIP.NET 是一家专注 IP 地理位置以及 IP 画像数据的研究、整理与发行的数据公司,提供 TraceRoute 等一系列 IP 相关的在线工具。 IPIP.NET 是因为其 TraceRoute 提供了可视化的效果,一眼看清问题所在。 点击打开 Pingdom Website Speed Test 知名的网站测速工具,相比 Google PageSpeed Insights 不能指定测速节点,它可以指定从全球数个节点发起测试请求,更贴近你的用户群体。 亚洲这边只有东京区域,四舍五入一下我选择东京区域来测试好了。 点击打开 其它还有 https://www.itdog.cn/http/ https://tool.chinaz.com/speedtest/ 网络测速 https://www.speedtest.net/ 加载速度评估 要想优化加载速度,我们首先要通过一些方法量化分析网站加载速度,这样才能更好的对加载速度进行优化。以下是常用的一些分析网站加载速度的工具。 Google PageSpeed Insights https://pagespeed.web.dev/ PageSpeed是检测网站加载速度很重要的工具,它可以给予我们非常详细的优化点,从中可以发现拖慢网站的元凶。 移动设备适合性测试 https://search.google.com/test/mobile-friendly?hl=zh_CN experte pagespeed https://www.experte.com/pagespeed 一次自动化测试多个网页评分 Chrome Audits(Lighthouse) 现代浏览器都自带性能测试工具,例如 Chrome, firefox,打开网页, 按 F12 键即可调出测试工具! Chrome浏览器自带的Audits除了能让我们查看网站的加载速度,还可以查看网站最佳实践、可用性、SEO及PWA方面的评分及改进点。如果你的网站在这几方面评分都超过90分,那一定是Google在这几方面很喜欢的网站了。 webpagetest webpagetest是非常强大的测试网站加载速度并深入分析网站资源加载速度的工具,还可以测试网站在不加载(屏蔽)某些资源的情况下网站加载速度与正常加载的对比,这样可以发现让网站加载速度变慢的资源或库。 用户反馈 有时候不同地区的加载速度是不同的,更麻烦的是你很难知道当地的网络情况,这时候就需要用户的反馈了。 加载速度优化概要 图片优化 图片大小优化 优化图片大小非常重要,网站资源大头一般都是图片,图片太大会导致加载速度很慢,在手机端也很耗费用户的流量。一般可以通过对图片大小进行裁剪,对图片格式进行转换这些方式来降低图片大小。 有多种实现方法 <img src="original.jpg" srcset="thumbnail.jpg" data-srcset="original.jpg"> 虽然 <img>标签定义了 src 属性,但是由于有 srcset 属性,所以现代浏览器会优先使用 srcset 的属性加载缩略图 thumbnail.jpg (如果愿意,你也可以使用空白小图 blank.gif)。同时负责 lazyload 的 JS 会在页面滚动的时候将 data-srcset 属性赋值给 srcset 展示原图。而在不支持 srcset 的老旧浏览器或者 RSS 阅读器上srcset 属性都会被忽略、直接读取 src 加载图片。 使用 srcset 属性的好处还有更多,比如对响应式设计友好、支持 WebP 图片及其 Fallback、对那些 curl 爬虫也很友好。 srcset 这个属性的关键之处在于它的优先级比 src 属性要高,这就是为什么我们可以在不对 src 属性动刀的前提下还可以做到不立刻加载原图。 另一个实现方法 hexo-filter-lqip 图片懒加载 例如这个插件,hexo-lazyload-image,可以极大提高首次显示时间 前端资源优化 网站的前端资源越来越大了,尤其是当你使用了很多第三方库的时候。 用库一时爽,优化火葬场! 如果想极大的提高网站加载速度,尽可能使用少的第三方库。 JS和CSS优化 通过压缩,去除不需要的代码减小前端资源文件大小。 第三方库优化 在这篇《Loading Third-Party JavaScript》中提到了如何正确加载第三方包,通过分析第三方包的加载时序图来判断对加载速度影响最大的几个因素,从而帮助你优化第三方包的加载。 内容结构优化 加载更多 一般对于瀑布流布局的网站,通过加载更多来降低每页返回的页面大小。不过这种方式对爬虫并不算友好,只有第一个页面可以被爬取到。 分页 常规网站一般通过分页来控制每页返回的页面大小。分页页面通过设置唯一的 canonical url 可以让爬虫更好的爬取到分页页面。 CDN 本站使用了免费的 netlify 作为CDN来提高网站在不同地区的加载速度,CDN通过边缘服务器缓存来提高用户请求网页的速度,一般的CDN都会设置某个失效时间后自动去源站拉取最新的内容缓存到边缘服务器。 你也可以选择诸如 Amazon CloudFront 与 cloudflare 这类CDN。还有一些特殊的比如具备反爬虫的CDN,如imperva收购的 distilnetworks 就是很厉害的反爬虫CDN。 静态化技术 动态网站一般需要做一些查询数据库和页面渲染的额外工作,为了提高网站响应速度,一些框架可以自动生成静态化页面部署到CDN中来提高网站响应速度。比如本站使用了基于 Hugo 的静态化技术框架,类似的还有 Hexo,这类技术都属于 JAMSTACK,还有新型的 gatsbyjs 技术让我们更容易开发出更快的网站。 AMP AMP是Google推出的Web组件框架,可以加速移动端的访问速度,比如你可以看看本篇文章的AMP版本页面,在移动端访问速度是非常快的。 广告优化 使用webpagetest研究本站前端资源的加载速度,最终发现让网站变慢的是Google Adsense广告资源。 通过将广告延迟5秒展示加载的方式来提高页面访问速度,具体代码见 seo improve by delay google ads load,此举将网站加载速度评分提升至90+了。但是测试后发现这种延迟广告展示的方式会降低广告收入😂。 总结 在SEO技术性优化中,提升加载速度是很重要的一个方面,我们需要使用多种手段去降低页面返回的大小来提升网站的加载速度。而且在设计、开发与运营网站的全流程中,加载速度始终是各个环节都需要考虑的问题。 加速NPM安装下载 安装淘宝镜像 npm config set registry https://registry.npm.taobao.org 安装CNPM npm install -g cnpm --registry=https://registry.npm.taobao.org 测试您的网络状况 Network Test DNS优化 多节点部署,多线路DNS配置 少用cname 双上联负载均衡 CDN 加速 为什么强烈建议启用CDN? 研究表明,用户最满意的打开网页时间,是在 2 秒以下。用户能够忍受的最长等待时间在 6~8 秒之间。就是说,8 秒是一个临界值,如果你的网站打开速度在 8 秒以上,那么你将失去大部分用户。研究显示,如果等待 12 秒以后,网页还是没有载入,那么 99% 以上的用户会选择关闭网页。 Google 做过一个试验,10 条搜索结果的页面载入时间需要 0.4 秒,显示 30 条搜索结果的页面载入时间需要 0.9 秒,结果后者使得 Google 总的流量和收入减少了 20%。Google 地图上线的时候,首页大小有 100KB,后来下降到 70~80KB。结果,流量在第一个星期上升了 10%,接下来的 3 个星期又再上升了 25%。Amazon 的统计也显示了相近的结果,首页打开时间每增加 100 毫秒,网站销售量会减少 1%。 以上数据说明了一个非常重要的问题,如果你的网站速度如果超过 2s 以上,那么你的客户可能在流失和离你而去了。这一点对于电商网站尤其重要,打开速度慢,那么将造成转化率降低,损失将会大量增加。 放在 Github 的资源在国内加载速度比较慢,因此需要使用 CDN 加速来优化网站打开速度,jsDelivr + Github 便是免费且好用的 CDN,非常适合博客网站使用。也可以选择主流云服务商提供的对象存储+CDN 来获得更快速及稳定的访问效果,费用低到几乎可忽略。 用法: https://cdn.jsdelivr.net/gh/{你的用户名}/{你的仓库名}@{发布的版本号}/{文件路径} 例如: https://cdn.jsdelivr.net/gh/appotry/cloudimg@latest/data/2022/03/1120220311110247.webp 注意:版本号不是必需的,是为了区分新旧资源,如果不使用版本号,将会直接引用最新资源。 还可以配合 PicGo图床上传工具的自定义域名前缀来上传图片,使用极其方便。具体使用方法可参见这篇文章: 使用 Typora+iPic/PicGo 图床+CDN 实现高效 Markdown 创作 jsdelivr jsdelivr 是还在目前还在国内运营的可以通过特殊方法免费使用的CDN。 Github开源仓库发布版本才能使用jsdelivr,懂了怎么做了吧。 https://cdn.jsdelivr.net/gh/[name]/[repo]@latest/data/2022/03/1120220311110247.webp Cloudflare CDN 配置最简单的CDN方式了。在github raw链接地址前面加https://images.weserv.nl/?url=, 就会自动使用cloudflare cdn来加速图片访问。使用发现无法加速gif。 本blog主要使用这个方法,如下所示。 未加速图片地址 https://raw.githubusercontent.com/appotry/cloudimg/main/data/2021/09/1020210910231815.png Cloudflare加速图片地址 # 使用了cloudflare partner 加速 https://cimg1.17lai.site/data/2021/09/1020210910231815.png 配置Service worker 后篇文章基于Hexo的matery主题搭建博客个性定制篇5中提到的 让hexo支持pwa 就是使用的Service worker ,参考个性定制篇,把常用的大体积文件加入Service worker 缓存列表,可以极大的提高访问速度! 原理:在访问时,后台异步加载 SW 缓存文件列表,后面渲染网页,直接使用缓存中的文件,不再从网络中获取。你可以提前把所有常用的大体积资源放到缓存列表中,后面访问其它页面时,很多资源已经提前加载好了,可以极大的提高访问速度! SEO 优化 google search console"}]},{"t":"list_item","d":4,"p":{"lines":[16,17]},"v":"竞品研究"},{"t":"list_item","d":4,"p":{"lines":[17,18]},"v":"内容研究"},{"t":"list_item","d":4,"p":{"lines":[18,19]},"v":"反向链接研究","c":[{"t":"list_item","d":6,"p":{"lines":[19,20]},"v":"SEOquake"},{"t":"list_item","d":6,"p":{"lines":[20,21]},"v":"google search console"}]}]},{"t":"list_item","d":2,"p":{"lines":[21,22]},"v":"优化","c":[{"t":"list_item","d":4,"p":{"lines":[22,23]},"v":"博客搭建框架优化对比"},{"t":"list_item","d":4,"p":{"lines":[23,24]},"v":"站内优化","c":[{"t":"list_item","d":6,"p":{"lines":[24,25]},"v":"meta"},{"t":"list_item","d":6,"p":{"lines":[25,26]},"v":"meta seo inspector"},{"t":"list_item","d":6,"p":{"lines":[26,27]},"v":"SEO Minion"},{"t":"list_item","d":6,"p":{"lines":[27,28]},"v":"关键字"},{"t":"list_item","d":6,"p":{"lines":[28,29]},"v":"关键字挖掘","c":[{"t":"list_item","d":8,"p":{"lines":[29,30]},"v":"google 搜索排名"},{"t":"list_item","d":8,"p":{"lines":[30,31]},"v":"google搜索建议"},{"t":"list_item","d":8,"p":{"lines":[31,32]},"v":"data.chinaz.com"}]}]},{"t":"list_item","d":4,"p":{"lines":[32,33]},"v":"技术性优化","c":[{"t":"list_item","d":6,"p":{"lines":[33,34]},"v":"加载速度"},{"t":"list_item","d":6,"p":{"lines":[34,35]},"v":"图片优化"},{"t":"list_item","d":6,"p":{"lines":[35,36]},"v":"rebot.txt"},{"t":"list_item","d":6,"p":{"lines":[36,37]},"v":"sitemap.xml"}]},{"t":"list_item","d":4,"p":{"lines":[37,38]},"v":"内容优化","c":[{"t":"list_item","d":6,"p":{"lines":[38,39]},"v":"网站定位"},{"t":"list_item","d":6,"p":{"lines":[39,40]},"v":"关键伙伴 代理平台,广告平台"},{"t":"list_item","d":6,"p":{"lines":[40,41]},"v":"搭建网站"},{"t":"list_item","d":6,"p":{"lines":[41,42]},"v":"写手招聘与管理"},{"t":"list_item","d":6,"p":{"lines":[42,43]},"v":"读者关系维护 聚会 群 留言 email"},{"t":"list_item","d":6,"p":{"lines":[43,44]},"v":"支出与收入"}]},{"t":"list_item","d":4,"p":{"lines":[44,45]},"v":"站外优化","c":[{"t":"list_item","d":6,"p":{"lines":[45,46]},"v":"其他平台导流","c":[{"t":"list_item","d":8,"p":{"lines":[46,47]},"v":"各大社区同步发送"},{"t":"list_item","d":8,"p":{"lines":[47,48]},"v":"国外社区论坛"}]},{"t":"list_item","d":6,"p":{"lines":[48,49]},"v":"友情链接"},{"t":"list_item","d":6,"p":{"lines":[49,50]},"v":"社交分享"}]},{"t":"list_item","d":4,"p":{"lines":[50,51]},"v":"内链优化"}]}],"p":{}}"> 搜索引擎优化,又称为 SEO,即 Search Engine Optimization,它是一种通过分析搜索引擎的排名规律,了解各种搜索引擎怎样进行搜索、怎样抓取互联网页面、怎样确定特定关键词的搜索结果排名的技术。Google 自动收录效果还不错,百度就差得远了(GitHub不允许百度的Spider爬取GitHub上的内容)。 如果没有备案,百度seo是不会收录的!所以如果你有国内vps,并且备案了,可以做百度seo,如果没有,百度seo内容都不需要看了。 网域提交方式 自动提交 (分三种) 主动推送 自动推送 sitemap(站点地图) 手动提交 即手动地将链接一次性提交给百度 一般自动提交比手动提交效果好一点,自动提交又从效率上来说: 主动推送>自动推送>sitemap 自动提交的三种方式: 主动推送:最为快速的提交方式。将站点当天新产出链接通过此方式推送给百度,以保证新链接可以及时被百度收录。 自动推送:最为便捷的提交方式。将自动推送的JS代码部署在站点的每一个页面源代码中,当部署代码的页面在每次被浏览时,链接就会被自动推送给百度。可以与主动推送配合使用。 sitemap:您可以定期将网站链接放到sitemap文件中,然后将sitemap文件提交给百度。百度会周期性的抓取检查您提交的sitemap,对其中的链接进行处理,但收录速度慢于主动推送。 使用sitemap方式推送 安装 sitemap 插件生成站点地图文件: npm install hexo-generator-sitemap --save npm install hexo-generator-baidu-sitemap --save #百度专用 安装后直接执行 hexo cl&&hexo g -d 命令,就会在网站根目录生成 sitemap.xml 及 baidusitemap.xml 文件。 在博客目录的_config.yml中添加如下代码 # 通用站点地图 sitemap: path: sitemap.xml # 百度站点地图 baidusitemap: path: baidusitemap.xml 百度优化 登录百度搜索资源平台, 登录成功之后在 用户中心 –> 站点管理 页面中点击添加网站,按提示操作。 添加网站 提示:由于百度的 spider 是爬取不到 GitHub 的内容的,所以在第三步验证网站的时候,建议选择CNAME验证的方式。 经过以上步骤,百度已经知道有我们网站的存在了,但是百度还不知道我们的网站上有什么内容,所以要向百度推送我们的内容。点击 网站支持 –> 数据引入 –> 链接提交菜单,提交站点地图: 提交站点地图 另外,hexo-theme-matery主题已经内置了 自动推送 的功能, 检查 themes/hexo-theme-matery/_config.yml 文件中如下配置: # 百度搜索资源平台提交链接 baiduPush: true 自动推送的 JS 代码部署在站点的每一个页面源代码中,当页面在每次被浏览时,链接就会被自动推送给百度。 谷歌优化 登录 Google Search Console,点击添加资源,输入自己的域名,按提示操作。 添加资源 提示:需要进行 DNS 验证,进入 DNS 域名解析设置页面,按提示增加 TXT 记录,如下图: DNS验证内容填写示例 验证成功后,需要提交站点地图。参照下图提交,然后等待收录。 提交站点地图 注意:hexo 配置文件中的 url 一定要输入正确的域名,插件是根据 url 生成站点地图的。 其它搜索引擎 Bing提交 神马站长 百度自动推送方式 只要每个需要被百度爬取的HTML页面中加入一段JS代码即可: <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> 我所使用的matery主题可以自动给每个页面加上这段代码,只需在主题配置文件中配置: # 百度搜索资源平台提交链接 baiduPush: true 即可! 其他主题一般都有这个功能的实现,如果没有的话,想办法在每个页面加入以上JS代码即可,原理是一样。 百度主动推送SEO方式 配置文章自动推送到百度蜘蛛 获取百度推送密钥 在 百度资源 注册你的网址,验证完后可在站点管理->资源提交->链接提交->主动推送(实时) 中找到你的推送密钥,下面说明中的 token= 后的内容即为推送密钥。 推送接口 接口调用地址:http://data.zz.baidu.com/urls?site=https://ifibe.com&token=xxxxxxxxxx 安装主动推送插件:hexo-baidu-url-submit $ npm install hexo-baidu-url-submit --save 然后打开hexo配置文件,在末尾加入以下配置: # hexo-baidu-url-submit 百度主动推送 baidu_url_submit: count: 80 # 提交最新的一个链接 host: https://blog.17lai.site # 在百度站长平台中注册的域名 token: xxxxxxx # 请注意这是您的秘钥, 所以请不要把博客源代码发布在公众仓库里! path: baidu_urls.txt # 文本文档的地址, 新链接会保存在此文本文档里 密匙的获取是在百度的自动提交的主动推送那里。 再加入新的deploy: deploy: - type: baidu_url_submitter 如图: 这样每次执行 hexo d 的时候,新的链接就会被推送了。 $ hexo clean $ hexo g $ hexo d 推送成功时,会有如下终端提示! 各种不同的推送反馈字段说明点我查看,一般来说,推送失败基本都是地址不相符造成的,我们只需对比baidu_url_submit在public中生成的baidu_urls.txt的地址,与自己填写在host字段中的地址对比看是否一样即可。 Github Action 自动提交SEO方式 强烈推荐使用!Hexo-SEO-AutoPush 安装插件 npm i hexo-seo-autopush --save 配置 在hexo 的config.yml里添加 hexo-seo-autopush配置 # enable: 开启/关闭 推送 # count: 每次提交最新的10篇文章 # https://github.com/lete114/hexo-seo-autopush hexo_seo_autopush: baidu: enable: true count: 100 bing: enable: true count: 10 google: enable: true count: 10 google_file: google_service_account.json # 谷歌服务账户 添加Google Push配置和解决push后没有GitHub Actions .github\workflows\AutoPush.yml文件的问题 # Deployment ## Docs: https://hexo.io/docs/one-command-deployment deploy: - type: git repo: https://github.com/lete114/Test.git branch: main ignore_hidden: false # 忽略隐藏文件及文件夹(目录) - type: GooglePush # 谷歌提交 获取站长平台密钥 Baidu Key 打开百度站长平台,点击左侧的普通收录https://ziyuan.baidu.com/ Bing Key 打开Bing站长平台,https://www.bing.com/webmasters/home 点击右上角头像 旁边的齿轮,跟着下图操作 Google Key Google Wiki, 使用参考。 打开Google indexing API官网 选择创建项目,点击继续 点击转到凭据页面 跟着如下图片步骤 json文件内的内容 { "type": "service_account", "project_id": "elated-guild-298003", "private_key_id": "cf58d669c0e8c8e082b2c403ade5e2548078e384", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEAJw89yeylRrA\nB+bzOAfQQNgOCABIwEKCy5mMxWSaiXy2RktyCJWjMR2Pgz770NJgClQHPJjsFn0c\nukHufpnuiX3VPlimLANPCRFdU/qp+yiaw4quIhYF1UZJkhmhL30anghUcvi+r9hQ\nw+RwcKrgA4EUzqUJaPdvjtzSoo315PPGfR91ASD5S8gE02yVI8igtYMX7v2x1JYR\n7PwHJwOVemiM9lot8ilvoUbV4BU0vSlwFoxKMJAbEXTmJjEKQi9992rcMW0GzXO8\ncHldUUtURXkt3VFjYTH27KhHiTkTXw+uZRBu1rkubDJkS8lGIWN7Fc/r4HMMCVTu\nXPS6HbJ/AgMBAAECggEANSS7OBaFd3jRL3cVCiZLjA5A5pEJzq/+eKtOn2oYDISx\nwVRO+YTVWdGj47kg1zM4D11NikbGaeDxHFxuKwW9o/04lpyYebneTcw2Hpl6EiOs\nz0WssOlCEmPQ8nrAI0GWiKSHuqoPwtg37TIoGsqZsjKRCby759DDokZYnm3/0sc+\niEllT0ZyBZhGDzyguVLEdCIR2P02q/hQzLyd6ejWGGwZebImbGoILhmuOjVrco0p\nV0JbrrNskjM5Epe7w+CpGftEASJ7Dxa8oj0qIT6cyAipra2AZAGnG9jrLcWpJuhu\nvNeDIFnTfpNEac+khXZZE2++MIQfTX9wGJc8tox2vQKBgQD6yiNvAL7sxExiy6ER\ntLtFQ3bvmMpKRFGvFOyPOtMbmjZ3D1GEtNNKGH4v1TI+tncEy7Q5Dm7nWwpi8yvL\nbh8xKghelAc/CU1nw0xDEDCkMbAwpFg5A5ZDImy3LZsQh0kNXniIMy1vMSt5yLKS\n80gXQKGCxG8t3rP8Qd/2a55g1QKBgQDIExP1nG9sHJaigmitEUwr0Ow6Shqr56Me\nd7995gaV1oLWWCQzrXt/viWkb1W5ZGIxzcWNWz99m4CbvqfewRr598Eenald0csN\nVcIEk+0C+6KqA+jU9Tfs2zow/C7JuKULP2N++o0EoSz/ngokP7f1yLOYbr507v/R\n0cLElQBQAwKBgAbxDWYHKUG4dTzO0hiBXiWepm4fVooTtgcYlyunvywmapeFDwaT\nUr3cS7HbPtbJiiXR1Z02rw8sT+9JN88brzVXKoAjrMer5D6ZA0Vf71i8H1pZUi/R\nz5jwHP48/uvIMtdx4/gxInLPc5qdWYQDw90Q5ueNtF4aqfSzhhV2CR45AoGBAJN9\nPOF6iMjx6jmyWOf8MGK8iOgPaMoA4Ea9j/SHdaNPlvPb1hQid0AcNDObv14Dmj+M\nqW0jLxKxZ4VobufPAsvyz/J51zjKRx11cqldQwNH7QnYB/O1MZzxn1wtC3C5JTG9\ncONSYFJhXoKxRliigEI3ye089jnNVdifAS1ZiflxAoGBANTX1fEMEeNuYU0v3rtd\n5CkPZg4TNZ+y2MGl5xR1LdIgrJ8c9xKoW4rpp7SsOIvHpWX494f90D7o9uFEGSQ4\nyQK53jVzJ0ekGV5BdPF3n3/2j2VEqFLHi7LL4CJSxr6ci7OfBoHOGE8odhevQCCK\njnFzEin0QsBEgIC73fBh6XcH\n-----END PRIVATE KEY-----\n", "client_email": "googleindexing@elated-guild-298003.iam.gserviceaccount.com", "client_id": "103034240916368863393", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/googleindexing%40elated-guild-298003.iam.gserviceaccount.com" } 打开谷歌站长平台 配置博客仓库 Name必须是baidu_token和bing_apikey(不区分大小写) 添加完成后 谷歌的一些问题 触发谷歌提交的命令是hexo d 由于谷歌需要配合Google indexing API平台提供的json进行提交,而这个json格式不能泄露 如果你的使用Github Actions自动部署的话请把仓库设置为私有 提交成功返回状态码 以上步骤完成后即可hexo d部署了 看看Github仓库是否上传成功 点击Actions查看是否执行 点击 Auto Push—->build—–>点击第2步 自动提交 如图43行 // baidu返回的结果 { "remain": 2060, // 表示当天剩余的可推送url条数 "success": 47 // 成功推送的url条数 } // bing返回结果(错误) { "ErrorCode": 2, // 错误 "Message": "ERROR!!! Quota remaining for today: 2, Submitted: 47" // Message:表示 你目前只剩2个url推送,而你现在推送的是47条url // bing新用户开始每日只有10个推送额,据我了解连续推送10天(这我也不确定) // 如果出现这个错误的话,你就只能先手动添加等系统给你分配额了(分配9999) } // bing返回结果(成功) {"d":null} Google 返回状态码 成功返回 Google response: { urlNotificationMetadata: { url: 'https://blog.lete114.top/article/hexo-seo-autopush.html', latestUpdate: { url: 'https://blog.lete114.top/article/hexo-seo-autopush.html', type: 'URL_UPDATED', notifyTime: '2020-12-08T02:31:32.871417693Z' } } } 出现此错误需要: 翻墙 FetchError: request to https://www.googleapis.com/oauth2/v4/token failed, reason: connect ETIMEDOUT 172.217.27.138:443 at ClientRequest.<anonymous> (D:\Lete\GitHub\Hexo-Butterfly\node_modules\node-fetch\lib\index.js:1461:11) at ClientRequest.emit (events.js:321:20) at TLSSocket.socketErrorListener (_http_client.js:426:9) at TLSSocket.emit (events.js:321:20) at emitErrorNT (internal/streams/destroy.js:92:8) at emitErrorAndCloseNT (internal/streams/destroy.js:60:3) at processTicksAndRejections (internal/process/task_queues.js:84:21) { message: 'request to https://www.googleapis.com/oauth2/v4/token failed, reason: connect ETIMEDOUT 172.217.27.138:443', type: 'system', errno: 'ETIMEDOUT', code: 'ETIMEDOUT', config: { method: 'POST', url: 'https://www.googleapis.com/oauth2/v4/token', data: { grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJnb29nbGVpbmRleGluZ0BzdGF0ZWx5LXRyYW5zaXQtMjk3NzE1LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczovL3d3d 本地主动提交SEO hexo-url-submission Wiki 安装方法 在终端中输入: npm i hexo-url-submission 在 blog/_config.yml 文件中添加配置: url_submission: enable: true type: 'latest' # latest or all( latest: modified pages; all: posts & pages) channel: ['baidu', 'bing', 'google', 'shenma'] # Included channels are `baidu`, `google`, `bing`, `shenma` prefix: ['/post', '/wiki'] # URL prefix count: 10 # Submit limit proxy: '' # Set the proxy used to submit urls to Google urls_path: 'submit_url.txt' # URL list file path baidu_token: '' # Baidu private key bing_token: '' # Bing private key google_key: '' # Google key path (e.g. `google_key.json` or `data/google_key.json`) shenma_token: '' # ShenMa private key shenma_user: '' # Username used when registering sitemap: '' # Sitemap path(e.g. the url is like this https://abnerwei.com/baidusitemap.xml, you can fill in `baidusitemap.xml`) 更新方法 在站点根目录执行: npm update hexo-url-submission deploy deploy: - type: us_baidu_deployer - type: us_bing_deployer - type: us_google_deployer - type: us_shenma_deployer good job Run: hexo clean && hexo g && hexo d enjoy it! 提交 robots.txt robots.txt是干嘛的? robots.txt 是一种存放于网站根目录下的 ASCII 编码的文本文件,它的作用是告诉搜索引擎此网站中哪些内容是可以被爬取的,哪些是禁止爬取的。 robots.txt 要放在 Hexo根目录 下的 source 文件夹中。 每个人站点目录可能不太一样,可以参考下我的 robots.txt 文件,内容如下: User-agent: * Allow: / Allow: /posts/ Disallow: /about/ Disallow: /archives/ Disallow: /js/ Disallow: /css/ Disallow: /contact/ Disallow: /fonts/ Disallow: /friends/ Disallow: /libs/ Disallow: /medias/ Disallow: /page/ Disallow: /tags/ Disallow: /categories/ 更多关于 robots.txt 的写法参见 https://blog.csdn.net/fanghua_vip/article/details/79535639 编写完以上内容再重新部署一下,然后到百度资源平台的数据监控->Robots点击检测并更新 看能不能检测到。 配置 Nofollow nofollow 是HTML页面中 a标签 的 属性值。 这个属性的作用是:告诉搜索引擎的爬虫不要追踪该链接,为了对抗博客垃圾留言信息 URL优化 一般来说,SEO搜索引擎优化认为,网站的最佳结构是 用户从首页点击三次就可以到达任何一个页面,但是我们使用Hexo编译的站点结构的URL是:域名/年/月/日/文章标题四层的结构,这样的URL结构很不利于SEO,爬虫就会经常爬不到我们的文章,于是,我们需要优化一下网站文章的URL 方案一: 直接改成域名/文章标题的形式,在Hexo配置文件中修改permalink如下: # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: https://blog.sky03.cn root: / permalink: :title.html permalink_defaults: 这个方式有个不好的地方: 直接以文章的标题作为URL,而我们所写的文章的标题一般都是中文,但是URL只能用字母数字和标点符号表示,所以中文的URL只能被转义成一堆符号,而且还特别长。 方案二: 安装固定链接插件:hexo-abbrlink 插件作用:自动为每篇文章生成一串数字作每篇文章的URI地址。每篇文章的Front-matter中会自动增加一个配置项:abbrlink: xxxxx,该项的值就是当前文章的URI地址。 Hexo根目录执行: npm install hexo-abbrlink --save Hexo配置文件末尾加入以下配置: # hexo-abbrlink config 、固定文章地址插件 abbrlink: alg: crc16 #算法选项:crc16、crc32,区别见之前的文章,这里默认为crc16丨crc32比crc16复杂一点,长一点 rep: dec #输出进制:十进制和十六进制,默认为10进制。丨dec为十进制,hex为十六进制 Hexo配置文件中修改permalink如下: # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: https://blog.17lai.site root: / permalink: posts/:abbrlink.html permalink_defaults: 这样站点结构就变成了:域名/posts/xxx.html Analytics 优化 强烈推荐自建 Umami 统计服务,所有公用的访问统计服务都被浏览器插件拦截工具拦截! Google Google Analytics 是一个 gzip 以后都还有 45KB 大小的 analytics.js、Cache-Control 还只有 7200 秒;Google 国内的数据中心会被抽风不说,www.google-analytics.com 域名早就上了各个广告屏蔽软件的黑名单!所以要么自建其它私有统计,要么想办法优化加载了。 Google Analytics 加载优化 使用 Cloudflare Workers 加速 Google Analytics Google Analytics 优化 @ WordPress umami Running on Vercel Umami官方文档 version: '3' services: umami: image: ghcr.io/umami-software/umami:postgresql-latest ports: - "3000:3000" environment: DATABASE_URL: postgresql://umami:umami@db:5432/umami DATABASE_TYPE: postgresql APP_SECRET: replace-me-with-a-random-string depends_on: db: condition: service_healthy restart: always db: image: postgres:15-alpine environment: POSTGRES_DB: umami POSTGRES_USER: umami POSTGRES_PASSWORD: umami volumes: - umami-db-data:/var/lib/postgresql/data restart: always healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 5 volumes: umami-db-data: https://github.com/umami-software/umami/blob/master/docker-compose.yml umami支持MySQL和Postgres,并可以在 Vercel Netlify 上面部署。 Umami UV / PV 统计显示 Umami 统计了 UV PV 等各种访问数据,比不蒜子详细得多,自建服务也比不蒜子稳定。那么怎么用 Umami 代替不蒜子了? 下文将介绍详细方法 新建 View only 权限的用户 Settings` -> `Users` -> `Create user` -> 填写账号密码,`Role` 选择 `View only` -> `Save Q: 为什么不直接调用 Umami 的 API 获取数据,而是要额外创建一个账户? A: 博客是 静态开源无服务器 的,所有代码都展示在前端,包括 API 调用。而 Umami 的 admin API 权限太大了,如果使用 admin 权限的 API Token,那么这个 token 可以获取、修改、删除所有网站的数据,会有严重的安全隐患。 所以我们需要创建一个 View only 权限的用户,使用这个 低权限的用户的 API Token 来访问我们的浏览量等数据。 新建 Team 并添加用户和网站 Settings -> Teams -> Create team -> 填写名称 -> Save -> 找到刚刚创建的 Team -> Edit -> 复制 Access code,点击 Websites 中点击 Add website 选中你想共享的网站 换一个浏览器登录 Umami(使用View only 权限的用户) -> Settings -> Teams -> Join team -> 输入 Access code -> Join -> 如果没有出错的话,点击 Dashboard 就可以看到你刚刚添加的网站了 获取 View only 用户的 API Token 根据 Umami 的文档,我们可以通过以下方式获取 API Token: POST /api/auth/login 例如 你的网站地址为 example.com,那么你需要使用 View only 的账户密码向 https://example.com/api/auth/login 发送一个 POST 请求,请求体为: { "username": "your-username", "password": "your-password" } 如果成功,你应该会得到以下的结果: { "token": "eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A", "user": { "id": "cd33a605-d785-42a1-9365-d6cad3b7befd", "username": "your-username", "createdAt": "2020-04-20 01:00:00" } } 保存 token 值,并在所有请求中发送带 Bearer <token> 值的 Authorization 标头。请求标头应该如下所示: Authorization: Bearer eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A 发送请求获取数据 这里要用到类似于 postman 的 API 测试工具,可以使用的是开源的 hoppscotch,你也可以使用 curl 或者其他工具。 先分析一下官方文档的 API 接口: GET /api/websites/{websiteId}/stats 有两个必填的 查询参数:startAt 和 endAt,都是 Unix 毫秒时间戳,表示开始时间和结束时间 websiteId 和 startAt 需要我们自己获取 websiteId 可以在 Dashboard -> View details -> 看浏览器栏的地址 https://example.com/websites/{websiteId} 中找到 startAt 可发送 GET 请求到 https://example.com/api/websites/{websiteId},请求头为 Authorization: Bearer eyTMjU2IiwiY...4Q0JDLUhWxnIjoiUE_A 在返回结果中找到 createdAt 字段,这个字段就是 startAt 的值,也就是你的网站创建时间,数据的开始时间 编写页面 代码如下,修改你对应的参数即可运行: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div style="text-align:center;"> <h1>Umami 网站统计</h1> <span>总访问量 <span id="umami-site-pv"></span> 次</span> <span>总访客数 <span id="umami-site-uv"></span> 人</span> </div> <script> // 从配置文件中获取 umami 的配置 const website_id = 'xxx'; // 拼接请求地址 const request_url = 'https://xxx.com' + '/api/websites/' + website_id + '/stats'; const start_time = new Date('2024-01-01').getTime(); const end_time = new Date().getTime(); const token = 'xxxxxx'; // 检查配置是否为空 if (!website_id) { throw new Error("Umami website_id is empty"); } if (!request_url) { throw new Error("Umami request_url is empty"); } if (!start_time) { throw new Error("Umami start_time is empty"); } if (!token) { throw new Error("Umami token is empty"); } const params = new URLSearchParams({ startAt: start_time, endAt: end_time, }); const request_header = { method: "GET", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token, }, }; async function allStats() { try { const response = await fetch(`${request_url}?${params}`, request_header); const data = await response.json(); const uniqueVisitors = data.pageviews.value; // 获取独立访客数 const pageViews = data.pageviews.value; // 获取页面浏览量 let ele1 = document.querySelector("#umami-site-pv") if (ele1) { ele1.textContent = pageViews; // 设置页面浏览量 } let ele2 = document.querySelector("#umami-site-uv") if (ele2) { ele2.textContent = uniqueVisitors; } console.log(uniqueVisitors, pageViews); console.log(data); } catch (error) { console.error(error); return "-1"; } } allStats(); </script> </body> </html> 异步加载JS 方法:将JS文件的引入,放到HTML的body结束标签的上方 例: <html> <head> <title>Hello World!</title> </head> <body> xxxxx.... <script src="xx/xx.js"></script> </body> </html> 原理:首先要明白,HTML的加载是从上往下一行一行解释执行的,把js文件的引入放到下面,这样就会先把HTML页面展示出来,然后再加载js。这样看起来的效果就是,大体的页面先出来,而js让它慢慢加载执行,如果你把js放到网页的上方,效果就是必须要加载完js才能继续展示网页,体验极差。 注意:原主题的js文件尽量不要动,我们只需将自己增加的一些js按照异步加载的方式做即可,比如一些音乐js插件、实时在线聊天js插件等放到最后即可!因为这些文件要加载的东西很多。 字蛛压缩字体 在上面我们介绍了如何在网站上引用自己喜欢的字体,但是这样会出现一个问题:字体文件太大!(尤其是中文,有时候为了几个字引入一个数十兆的字体文件,得不偿失),所有需要字体压缩! 官网 GitHub 使用场景 你的网站中需要自定义字体(额外添加一些普通电脑中没有的字体),但是一般字体是包含很多字符的,这就导致字体文件的体积很大 字蛛作用 字蛛就是自动检测网站的 CSS 与 HTML 文件中的自定义字体(额外加的字体),并将网站中用到的文字重新打包成一个新的字体文件,并自动引入; 而没用到的文字就会删除,从而达到压缩字体文件体积的作用。 安装 npm install font-spider -g 在 CSS 中使用 WebFont: /*声明 WebFont*/ @font-face { font-family: 'pinghei'; src: url('../font/pinghei.eot'); src: url('../font/pinghei.eot?#font-spider') format('embedded-opentype'), url('../font/pinghei.woff') format('woff'), url('../font/pinghei.ttf') format('truetype'), url('../font/pinghei.svg') format('svg'); font-weight: normal; font-style: normal; } /*使用选择器指定字体*/ .home h1, .demo > .test { font-family: 'pinghei'; } @font-face 中的 src 定义的 .ttf 文件必须存在,其余的格式将由工具自动生成 开发阶段请使用相对路径的 CSS 与 WebFont 运行 font-spider 命令: font-spider ./demo/*.html 页面依赖的字体将会自动压缩好,原 .ttf 字体会备份 使用 FontForge 压缩 Font awesome 曾经尝试过各种方案来压缩字体,最后还是这种方法最适合 下载安装 FontForge Windows, Mac and GNU+Linux. 准备python 环境 minify.py 文件 import glob import re import fontforge extensions = [".html", ".js"] pattern = re.compile("(fa-[-\w]+)") # 获取使用到的图标 def get_used_icons(path): icon_dict = {} for filename in glob.glob(path, recursive=True): for extension in extensions: if extension in filename: for line in open(filename, encoding='utf-8'): for match in re.finditer(pattern, line): icon_dict[match.group()[3:]] = True return icon_dict # 去除除了传入的字典的图标 def minify(path, used_dict): font = fontforge.open(path) assert isinstance(font, fontforge.font) selection = font.selection assert isinstance(selection, fontforge.selection) selection.all() for i in selection.byGlyphs: assert isinstance(i, fontforge.glyph) if i.glyphname not in used_dict: font.removeGlyph(i) font.generate(path) if __name__ == '__main__': web_path = "V:/hexo/blog/public/**" font_path = "V:/hexo/blog/themes/matery/source/libs/awesome/webfonts/" font_list = ["fa-brands-400.woff2", "fa-regular-400.woff2", "fa-solid-900.woff2"] used_icon_dict = get_used_icons(web_path) for font_name in font_list: minify(font_path + font_name, used_icon_dict) import glob import re import fontforge import os extensions = [".html", ".js"] pattern = re.compile(r"(fa-[-\w]+)") user_defined_icons = ["fa-github", "fa-pencil", "fa-cog", "fa-cloud-upload", "fa-compress-arrows-alt"] # 获取使用到的图标 def get_used_icons(path): icon_dict = {} for filename in glob.glob(path, recursive=True): for extension in extensions: if extension in filename: with open(filename, encoding="utf-8") as file: for line in file: for match in re.finditer(pattern, line): icon_dict[match.group()[3:]] = True return icon_dict # 去除除了传入的字典的图标 def minify(source_path, target_path, used_dict): font = fontforge.open(source_path) assert isinstance(font, fontforge.font) selection = font.selection assert isinstance(selection, fontforge.selection) selection.all() for i in selection.byGlyphs: assert isinstance(i, fontforge.glyph) if i.glyphname not in used_dict: font.removeGlyph(i) font.generate(target_path) font.close() if __name__ == '__main__': web_path = "V:/hexo/blog/public/**/*" font_source_dir = "V:/hexo/blog/themes/matery/source/libs/awesome5/webfonts/" font_target_dir = "V:/hexo/blog/themes/matery/source/libs/awesome/webfonts/" font_list = ["fa-brands-400.woff2", "fa-regular-400.woff2", "fa-solid-900.woff2"] used_icon_dict = get_used_icons(web_path) # Add user-defined icons to the used icons dictionary for icon in user_defined_icons: used_icon_dict[icon] = True print("Used Icons:") for icon in used_icon_dict.keys(): print(icon) for font_name in font_list: source_path = os.path.join(font_source_dir, font_name) target_path = os.path.join(font_target_dir, font_name) minify(source_path, target_path, used_icon_dict) 下面是一个增强版本 import glob import re import fontforge import os extensions = [".html", ".js"] pattern = re.compile(r"(fa-[-\w]+)") user_defined_icons = ["fa-github", "fa-pencil", "fa-cog", "fa-cloud-upload"] # 获取使用到的图标 def get_used_icons(path): icon_dict = {} for filename in glob.glob(path, recursive=True): for extension in extensions: if extension in filename: with open(filename, encoding="utf-8") as file: for line in file: for match in re.finditer(pattern, line): icon_dict[match.group()[3:]] = True return icon_dict # 去除除了传入的字典的图标 def minify(source_path, target_path, used_dict): font = fontforge.open(source_path) assert isinstance(font, fontforge.font) selection = font.selection assert isinstance(selection, fontforge.selection) selection.all() for i in selection.byGlyphs: assert isinstance(i, fontforge.glyph) if i.glyphname not in used_dict: font.removeGlyph(i) font.generate(target_path) font.close() if __name__ == '__main__': web_path = "V:/hexo/blog/public/**/*" font_source_dir = "V:/hexo/blog/themes/matery/source/libs/awesome5/webfonts/" font_target_dir = "V:/hexo/blog/themes/matery/source/libs/awesome/webfonts/" font_list = ["fa-brands-400.woff2", "fa-regular-400.woff2", "fa-solid-900.woff2"] used_icon_dict = get_used_icons(web_path) # Add user-defined icons to the used icons dictionary for icon in user_defined_icons: used_icon_dict[icon] = True print("Used Icons:") for icon in used_icon_dict.keys(): print(icon) for font_name in font_list: source_path = os.path.join(font_source_dir, font_name) target_path = os.path.join(font_target_dir, font_name) minify(source_path, target_path, used_icon_dict) 运行压缩 Windows下只能通过font forge自带的解释器了,打开这个FontForge interactive console。 D:\Program Files (x86)\FontForgeBuilds>bin\ffpython.exe d:\Work\Dev\minifyFont\minify.py 只在 font awesome v5 上面测试成功! V6 运行失败 使用webp图像格式来优化大小 把所有图像都转换为webp格式,可以极大减小图片体积,加快加载速度。 图片懒加载 图片懒加载是提升网站性能和用户体验的一个非常很好方式,并且几乎所有的大型网站都使用到了,比如微博,仅把用户可见的部分显示图片,其余的都暂时不加载,做法就是:让所有图片元素src指向一个小的站位图片比如loading,并新增一个属性(如data-original)存放真实图片地址。每当页面加载(或者滚动条滚动),使用JS脚本将可视区域内的图片src替换回真实地址,并做请求重新加载。 Don’t worry about lazyload SEO problem, because Google supports it already. 那么,赶快用起来吧! 在站点根目录执行下面的命令: npm install hexo-lazyload-image --save #或者使用yarn yarn add hexo-lazyload-image 之后在站点配置文件下添加下面的代码 lazyload: enable: true # 是否开启图片懒加载 onlypost: false # 是否只对文章的图片做懒加载 loadingImg: # eg ./images/loading.gif isSPA: false # optional. For performance considering, isSPA is added. If your theme is a SPA page, please set it as true preloadRatio: 3 # optional, default is 1 最后执行 hexo clean && hexo g && hexo s 就可以看到效果了。 存在问题: 查看大图,发现全部为 loading 加载图,原因是因为懒加载插件与 lightgallery 插件冲突,解决办法如下: 修改主题文件下的 matery.js,在 108 行左右添加以下代码: $(document).find('img[data-original]').each(function(){ $(this).parent().attr("href", $(this).attr("data-original")); }); specify no-lazy for specify image we can also disable the lazy process if specify a attribute on img tag in both markdown or html <img no-lazy src="abc.png" /> Hexo-lazy-image 实现原理 因为文章都是使用markdown来编写的,所以不可能要求我们在markdown里将所有图片路径都指向站位图片,并附加另一个属性,所以,这个工作必须留给hexo的generate部分来做。 最终可分为两步: 在hexo after_post_render事件或者after_render:html事件里将生产出来的文章html代码中所有img元素都加上 data-original 属性,并把src值付给他, 然后在将src值致为loading图片 注入simple-lazyload脚本在每个页面最后面,当页面加载过后负责判定当前需要重新加载的图片。 这里重点提提正则表达式,在对第一步替换的时候,只是使用了简单的正则表达式去匹配查找所有的img节点,后来发现不仅如此,正则表达式结合string.replace更是如此强大。 return htmlContent.replace(/<img(\s*?)src="(.*?)"(.*?)>/gi, function (str, p1, p2) { return str.replace(p2, loadingImage + '" data-original="' + p2); }) 另一种懒加载,需要自定义修改的比较多 vanilla-lazyload 博客写作工具 FFMpeg 将小视频转换成GIF动图 那么,如何能够将一个完整小视频,或一个长视频的某一部分转化成GIF动图呢?这里要使用一种多媒体工具:ffmpeg. 想将整个视频转换成GIF,你可以使用下面的命令: ffmpeg -i small.mp4 small.gif 想将一个视频里的指定的时间段转换成GIF,你可以使用下面的命令: ffmpeg -t 3 -ss 00:00:02 -i small.webm small-clip.gif 上面的命令是利用ffmpeg将从视频第二秒开始、时长为3秒的片段提取出、并转化成GIF动图。 如果各种参数保持缺省值,则转换后的图像的清晰度、分辨率并不是特别高,但这些参数你可以任意设置: ffmpeg -i small.mp4 -b 2048k small.gif 将GIF动图转换成视频 命令行的写法非常相似而简单: ffmpeg -f gif -i animation.gif animation.mp4 这个命令还可以让你选择性的将GIF图转换成各种视频格式: ffmpeg -f gif -i animation.gif animation.mpeg ffmpeg -f gif -i animation.gif animation.webm 将MP4、MPEG、MOV等格式的视频转换成WEBM格式的方法 ffmpeg -i trailer.mov -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis trailer.webm 让Apache Servers支持WEBM格式 因为WEBM是一种新的文件格式,你需要让Apache服务器认识这种后缀。下面就是通过修改.htaccess来让Apache支持它: AddType video/webm webm 用gifsicle优化GIF动图 大部分的GIF动图都是要放在网页上,最终下载到用户的浏览器里,所以,优化这些GIF图片的体积是十分必要的,这里我们就需要用到另外一个非常有用的GIF图片修改工具:gifsicle,它有一个内置的方法能够优化GIF动图的体积。 在开始介绍对GIF图片的优化方法前,你需要知道的一点是,gifsicle不仅仅是GIF图片优化工具。gifsicle还可以调整GIF图片的大小,合并多个GIF动图等等任何你能想到的对GIF图片的操作。 gifsicle 对GIF图片有三种优化选项: -O1 只保存每张图像上变化的部分。这是缺省模式。 -O2 进一步用透明度压缩图片。 -O3 尝试各种优化方法(通常速度会慢一些,有时会产生更好的效果)。 优化GIF动图的命令行写法是这样的: gifsicle -O3 animation.gif -o animation-optimized.gif 如果你有耐心和时间,推荐你尝试一下-O3,它有可能会给你输出体积更小的GIF动图。 hexo插件hexo-minify Hexo-minify Hexo-minify 是一款 Hexo 压缩插件,它可以压缩 HTML、CSS、JS 安装 npm install hexo-minify --save 说明 如需修改,可在Hexo配置文件内编辑覆盖 如果仅安装插件,并未填写相关配置,则使用默认配置信息 默认配置信息 ## Hexo-minify Default Config Options minify: js: enable: true ## 详细配置: https://github.com/mishoo/UglifyJS options: css: enable: true ## 详细配置: https://github.com/clean-css/clean-css#compatibility-modes options: html: enable: true ## 详细配置: https://github.com/kangax/html-minifier#options-quick-reference options: minifyJS: true # Compressed JavaScript minifyCSS: true # CSS Compressed removeComments: true # Remove the comments collapseWhitespace: true # Delete any extra space removeAttributeQuotes: true # Delete attribute quotes # + 1.2.0 版本新增 postcss: enable: true ## 详细配置: https://github.com/postcss/autoprefixer#options ## 注意Hexo-minify仅内置了autoprefixer插件 ## 受Hexo限制,目前无法实现自定义postcss插件 options: # JavaScript 数组写法 # overrideBrowserslist: ['> 1%', 'last 2 versions', 'not dead'] # YAML 数组写法 overrideBrowserslist: - '> 1%' # 特殊符号需要使用'或" - last 2 versions - not dead hexo插件hexo-filter-lqip hexo-filter-lqip A Hexo plugins which helps to introduce low quality image placeholders to the theme 不支持hexo5.x以上版本,可以强制安装 -f,实现方法可以借鉴 Installation npm i hexo-filter-lqip --save Usage Install this plugin for the theme and use the view helper to render a placeholder. lqipFor view helper lqipFor(path_to_asset, options) String *path_to_asset - a path to the image Object options String [type] - a type of placeholder, see the list of available types, defaults to the default_type as configured Returns a CSS value for background-image property, which is a simplified version of the original image. Example for EJS <div style="background-image: <%- lqip_for('/content/my-photo.jpg') %>" ></div> iframe Lazy Loading 现代浏览器 支持 loading 参数,让浏览器滚动到 iframe 附近再价值啊 iframe <iframe src="https://blog.17lai.site" loading="lazy" /> loading 参数: lazy: good candidate for lazy-loading eager: not a good candidate for lazy-loading, loads right away auto: the browser determines whether or not to lazily load 老旧浏览器兼容 检查 HTMLIFrameElement 是否有 loading 属性 if ('loading' in HTMLIFrameElement.prototype) { // Native image lazy-loading is available } else { // Use polyfill or a 3rd-party library } 完整代码 <iframe class="lazyload" data-src="https://blog.17lai.site"> </iframe> if ('loading' in HTMLIFrameElement.prototype) { const iframes = document.querySelectorAll('iframe[loading="lazy"]'); iframes.forEach(iframe => { iframe.src = iframe.dataset.src; }); } else { // Dynamically import the LazySizes library const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.2/lazysizes.min.js'; document.body.appendChild(script); } jquery lazyloading Jquery 实现的按键加载 iframe var iframes = $('iframe'); $('button').click(function() { iframes.attr('src', function() { return $(this).data('src'); }); }); iframes.attr('data-src', function() { var src = $(this).attr('src'); $(this).removeAttr('src'); return src; }); gulp 体积压缩 减小体积,加快加载速度 因为 hexo 生成的 html、css、js 等都有很多的空格或者换行,而空格和换行也是占用字节的,所以需要将空格换行去掉也就是我要进行的 “压缩”。 npm install gulp -g # 安装各种小功能模块 执行这步的时候,可能会提示权限的问题,最好以管理员模式执行 npm install gulp gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save # 额外的功能模块 npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del @babel/core --save 或者使用yarn yarn global add gulp yarn add gulp gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin yarn add gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del @babel/core npm下载太慢怎么办? 修改国内淘宝源加速,戳 然后,在根目录新增 gulpfile.js : var gulp = require("gulp"); var debug = require("gulp-debug"); var cleancss = require("gulp-clean-css"); //css压缩组件 var uglify = require("gulp-uglify"); //js压缩组件 var htmlmin = require("gulp-htmlmin"); //html压缩组件 var htmlclean = require("gulp-htmlclean"); //html清理组件 var imagemin = require("gulp-imagemin"); //图片压缩组件 var changed = require("gulp-changed"); //文件更改校验组件 var gulpif = require("gulp-if"); //任务 帮助调用组件 var plumber = require("gulp-plumber"); //容错组件(发生错误不跳出任务,并报出错误内容) var isScriptAll = true; //是否处理所有文件,(true|处理所有文件)(false|只处理有更改的文件) var isDebug = true; //是否调试显示 编译通过的文件 var gulpBabel = require("gulp-babel"); var es2015Preset = require("babel-preset-es2015"); var del = require("del"); var Hexo = require("hexo"); var hexo = new Hexo(process.cwd(), {}); // 初始化一个hexo对象 // 清除public文件夹 gulp.task("clean", function () { return del(["public/**/*"]); }); // 下面几个跟hexo有关的操作,主要通过hexo.call()去执行,注意return // 创建静态页面 (等同 hexo generate) gulp.task("generate", function () { return hexo.init().then(function () { return hexo .call("generate", { watch: false }) .then(function () { return hexo.exit(); }) .catch(function (err) { return hexo.exit(err); }); }); }); // 启动Hexo服务器 gulp.task("server", function () { return hexo .init() .then(function () { return hexo.call("server", {}); }) .catch(function (err) { console.log(err); }); }); // 部署到服务器 gulp.task("deploy", function () { return hexo.init().then(function () { return hexo .call("deploy", { watch: false }) .then(function () { return hexo.exit(); }) .catch(function (err) { return hexo.exit(err); }); }); }); // 压缩public目录下的js文件 gulp.task("compressJs", function () { return gulp .src(["./public/**/*.js", "!./public/libs/**"]) //排除的js .pipe(gulpif(!isScriptAll, changed("./public"))) .pipe(gulpif(isDebug, debug({ title: "Compress JS:" }))) .pipe(plumber()) .pipe( gulpBabel({ presets: [es2015Preset] // es5检查机制 }) ) .pipe(uglify()) //调用压缩组件方法uglify(),对合并的文件进行压缩 .pipe(gulp.dest("./public")); //输出到目标目录 }); // 压缩public目录下的css文件 gulp.task("compressCss", function () { var option = { rebase: false, //advanced: true, //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)] compatibility: "ie7" //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式] //keepBreaks: true, //类型:Boolean 默认:false [是否保留换行] //keepSpecialComments: '*' //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀 }; return gulp .src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css .pipe(gulpif(!isScriptAll, changed("./public"))) .pipe(gulpif(isDebug, debug({ title: "Compress CSS:" }))) .pipe(plumber()) .pipe(cleancss(option)) .pipe(gulp.dest("./public")); }); // 压缩public目录下的html文件 gulp.task("compressHtml", function () { var cleanOptions = { protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理 unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊处理 }; var minOption = { collapseWhitespace: true, //压缩HTML collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input /> removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: true, //删除<script>的type="text/javascript" removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css" removeComments: true, //清除HTML注释 minifyJS: true, //压缩页面JS minifyCSS: true, //压缩页面CSS minifyURLs: true //替换页面URL }; return gulp .src("./public/**/*.html") .pipe(gulpif(isDebug, debug({ title: "Compress HTML:" }))) .pipe(plumber()) .pipe(htmlclean(cleanOptions)) .pipe(htmlmin(minOption)) .pipe(gulp.dest("./public")); }); // 压缩 public/medias 目录内图片 gulp.task("compressImage", function () { var option = { optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级) progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片 interlaced: false, //类型:Boolean 默认:false 隔行扫描gif进行渲染 multipass: false //类型:Boolean 默认:false 多次优化svg直到完全优化 }; return gulp .src("./public/medias/**/*.*") .pipe(gulpif(!isScriptAll, changed("./public/medias"))) .pipe(gulpif(isDebug, debug({ title: "Compress Images:" }))) .pipe(plumber()) .pipe(imagemin(option)) .pipe(gulp.dest("./public")); }); // 执行顺序: 清除public目录 -> 产生原始博客内容 -> 执行压缩混淆 -> 部署到服务器 gulp.task( "cicd", gulp.series( "clean", "generate", "compressHtml", "compressCss", "compressJs", "compressImage", gulp.parallel("deploy") ) ); gulp.task( "ci", gulp.series( "clean", "generate", gulp.parallel("compressHtml", "compressCss", "compressJs","compressImage") ) ); // 默认任务 gulp.task( "default", gulp.series( gulp.parallel("compressHtml", "compressCss", "compressJs","compressImage") ) ); //Gulp4最大的一个改变就是gulp.task函数现在只支持两个参数,分别是任务名和运行任务的函数 运行: hexo clean && hexo g && gulp && hexo g 直接在 Hexo 根目录执行 gulp ci,这个命令相当于 hexo cl&&hexo g 并且再把代码和图片压缩。 在 Hexo 根目录执行 gulp cicd ,这个命令与 gulp ci相比是:在最后又加了个 hexo d ,等于说生成、压缩文件后又帮你自动部署了 如果不想用图片压缩可以把"compressImage" 去掉即可 Docker版Imagin 使用Docker版本的imagemin来压缩图片!一行命令搞定! gulp-imagemin相关的依赖,以及配置太TMD复杂了,博主新的Docker里面配置很久没搞定,虽然以前搞定过,囧rz! 如是去找了一下Docker镜像,立马搞定! docker run -v `pwd`:/work mitakeck/imagemin 源代码 mitakeck/docker-imagemin Python图片无损压缩 xinlin-z/smally jpg,png.webp图片无损压缩工具!说明去项目主页看。有中文说明。 最近作者更新了新版本,以前bug都解决了,使用完美! 使用教程O(∩_∩)O git clone https://github.com/xinlin-z/smally.git cd smally git checkout newstart sudo bash install_tools.sh # Run Test bash test.sh # Usage find <path/to/image_folder> -type f -exec bash smally.sh {} \; 本地搜索优化 html、css和js都压缩了,很开心。但是,还有一个大文件没有压缩,就是本地搜索的DB文件search.xml。这个search.xml文件的大小为7.5M,很大。 修改hexo/_config.yml的localsearch配置为: # local search search: path: search.xml field: post format: striptags limit: 10000 重新生成search.xml文件 还可以给search.xml添加上jsdelivr cdn 加速! 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/27
articleCard.readMore

基于Hexo的matery主题搭建博客自定义修改篇2

Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 如果本主题中的诸多功能和主题色彩你不满意,可以在主题中自定义修改,很多更自由的功能和细节点的修改难以在主题的 _config.yml 中完成,需要修改源代码才来完成。以下列出了可能有用的地方: 自定义Logo 免费生成 logo 的网站很多,这里给一个个人使用的网站。 找一个喜欢的图片 https://www.logosc.cn/logo/ 图片上传到这里,然后安装提示生成图片 下载生成的图标文件,替换主题中对应的文件! 还有其它的服务推荐 Iconifier: 网址:https://iconifier.net/ Iconifier 是一个简单易用的在线图标生成器,支持导入 PNG、JPG 和 GIF 格式的图片,并生成相应的 SVG 图标。你可以通过上传图片或者提供图片的 URL 来生成图标。 SVGOMG: 网址:https://jakearchibald.github.io/svgomg/ SVGOMG 是一个由 Google 开发的 SVG 优化工具,它可以帮助你压缩和优化现有的 SVG 文件,并提供一些额外的编辑功能,比如调整路径和属性。你可以在这个工具中导入已有的 SVG 文件并进行编辑和优化。 Flaticon: 网址:https://www.flaticon.com/ Flaticon 是一个图标搜索引擎,提供了大量的免费图标资源供用户选择。你可以在 Flaticon 上搜索你需要的图标,然后下载为 SVG 格式。虽然 Flaticon 提供了大量的免费图标资源,但一些高质量的图标可能需要付费下载。 logoly 网址:https://www.logoly.pro/ 源码:https://github.com/bestony/logoly A Pornhub Flavour Logo Generator。开源 Logo 生成 修改主题颜色 配色包括导航栏,底部栏,a标签等,主题配色是绿色。 修改themes\Matery\source\css\matery.css样式 /* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */ .bg-color { background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%); } /*如果想去掉banner图的颜色渐变效果,请将以下的css属性注释掉或者删除掉即可*/ @-webkit-keyframes rainbow { /* 动态切换背景颜色. */ } @keyframes rainbow { /* 动态切换背景颜色. */ } 背景樱花飘落效果 在themes/matery/source/js目录下新建sakura.js文件,打开这个网址传送门,将内容复制粘贴到sakura.js即可。 然后在themes/matery/layout/layout.ejs文件内添加下面的内容: <script type="text/javascript"> //只在桌面版网页启用特效 var windowWidth = $(window).width(); if (windowWidth > 768) { document.write('<script type="text/javascript" src="/js/sakura.js"><\/script>'); } </script> 修改花瓣的数量 因为普遍在使用的樱花背景效果花瓣数太多了,一些人不太喜欢。 于是按不同花瓣数量做了几个新的 js ,并提供如下 cdn 形式的引用: https://cdn.jsdelivr.net/gh/fz6m/Private-web@1.2/js/sakura/sakura-small.js 以上为少量樱花效果,另提供几个不同数量的文件引用名: 文件名 说明 sakura-small.js 少量樱花 sakura-half.js 樱花相对原效果数量减半 sakura-reduce.js 樱花相对原效果减少1/4 sakura-original.js 樱花数量不变(原效果) 自定义鼠标样式 首先将鼠标样式下载到本地,推荐大家一个网站:https://zhutix.com/ico/ori-cursors/ 以我的为例,我将鼠标指针样式放在了主题文件夹下的medias目录下,然后打开themes\matery\source\css下的my.css文件,添加内容如下: *{ cursor: url("/medias/imgs/zhengchang.ico"),auto!important; } :active{ cursor: url("/medias/imgs/dianji.ico"),auto!important; } 取消首页渐变颜色动画 在themes\Matery\source\css\matery.css,ctrl+F快捷键查找.bg-cover:after,注释掉即可。 /* .bg-cover:after { -webkit-animation: rainbow 60s infinite; animation: rainbow 60s infinite; } */ 首页随机图片轮播 themes\matery\layout\_partial\bg-cover-content.ejs 修改随机获取一张图片: $('.bg-cover').css('background-image', 'url(<%- theme.featureImages[Math.floor(Math.random() * theme.featureImages.length + 1)-1] %>)'); 优化目录栏,透明化 目录样式竟然在:themes\Matery\layout\_partial\post-detail-toc.ejs .toc-widget { width: 345px; padding-left: 20px; background-color: rgb(255, 255, 255,0.7); border-radius: 10px; box-shadow: 0 10px 35px 2px rgba(0, 0, 0, .15), 0 5px 15px rgba(0, 0, 0, .07), 0 2px 5px -5px rgba(0, 0, 0, .1) !important; } 增加点击跳转评论按钮 新建文件themes\Matery\layout\_partial\back-comment.ejs,粘贴如下代码 我这里评论是valine,直接填写的valine的id——href="#vcomments",如果是其他评论,对应修改即可。 <!-- 直达评论 --> <div id="to_comment" class="comment-scroll"> <a class="btn-floating btn-large waves-effect waves-light" href="#vcomments" title="直达评论"> <i class="fas fa-comments"></i> </a> </div> 在themes\Matery\layout\_partial\valine.ejs文末添加一条,引用第一步的内容; <%- partial('_partial/back-comment.ejs') %> 则只在valine存在的页面才显示直达评论,防止首页其他地方也出现按钮。其实还可以优化为浮动出现,有一点麻烦,我这里没有设置。 增加样式在themes\Matery\source\css\matery.css添加内容如下: /*直达评论按钮样式*/ .comment-scroll { position: fixed; right: 15px; bottom: 135px; padding-top: 15px; margin-bottom: 0; z-index: 998; } .comment-scroll .btn-floating { background: linear-gradient(to bottom right, #FF9999 0%, #ff6666 100%); width: 48px; height: 48px; } .comment-scroll .btn-floating i { line-height: 48px; font-size: 1.8rem; } bottom: 135px;是距离底部的高度,看看你是否需要修改。 添加简体繁体一键切换 首先,我们可以在这里右键另存下载简繁字体切换所需的 tw_cn.js 文件,我们把这个文件放到 ~/themes/(你的主题名)/source/js/ 文件夹下。 修改模板,在我们想要显示简繁转换按钮的地方添加如下代码。例如,我在 NexT 主题的布局文件 ~/themes/(你的主题名)/layout/_partials/footer.ejs 里添加了如下代码: <div class="translate-style"> 繁/简:<a id="translateLink" href="javascript:translatePage();">繁体 </a> </div> <script type="text/javascript" src="/js/tw_cn.js"></script> <script type="text/javascript"> var defaultEncoding = 2; //网站编写字体是否繁体,1-繁体,2-简体 var translateDelay = 0; //延迟时间,若不在前, 要设定延迟翻译时间, 如100表示100ms,默认为0 var cookieDomain = "https://1han.wiki/"; //Cookie地址, 一定要设定, 通常为你的网址 var msgToTraditionalChinese = "繁体"; //此处可以更改为你想要显示的文字 var msgToSimplifiedChinese = "简体"; //同上,但两处均不建议更改 var translateButtonId = "translateLink"; //默认互换id translateInitilization(); </script> 读者可以在博客底部点击简体 / 繁体来看具体的切换字体效果。 修改滑动条 /* 滚动条 */ ::-webkit-scrollbar-thumb { background-color: #FF2A68; background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent); border-radius: 3em; } ::-webkit-scrollbar-track { background-color: #ffcacaff; border-radius: 3em; } ::-webkit-scrollbar { width: 8px; height: 15px; } 文章标题添加打字机效果 定位到文章标题代码 layout/_partial/post-cover.ejs <h1 class="description center-align post-title"><%= page.title %></h1> 文章标题代码替换成下面的代码 <script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.typed) %>"></script> <% if (theme.post.enable) { %> <script> var typedObj = new Typed("#post-title", { strings: [ '<%= page.title %>' ], startDelay: <%= theme.post.startDelay %>, typeSpeed: <%= theme.post.typeSpeed %>, loop: <%= theme.post.loop %>, backSpeed: <%= theme.post.backSpeed %>, showCursor: <%= theme.post.showCursor %> }); </script> <% } %> 最后在主题配置文件中进行配置 _config.yml # 文章标题 post: enable: true loop: false # 是否循环 showCursor: true # 是否显示光标 startDelay: 500 # 开始延迟 typeSpeed: 100 # 打字速度 backSpeed: 50 # 删除速度 现在就完成了为一言和文章标题添加打字机效果 更换字体 一般网站的web字体都可以直接从Google-Font获取资源,这样不用担心字体商业带来的法律问题。 常见的开源字体有: 思源黑体 、 文泉驿 、 文鼎开放字体 、 柳体 、 cwTeX中文字体 、 濑户字体、江西拙楷体等。 1)创建web字体引用 @font-face{ font-family: '引用的字体名称'; src: url('谷歌字体路径(或者其他什么字体引用)'); } 2)在网页合适的位置进行字体引用 ①利用浏览器检查元素,获取需要定义字体的部分 ②在主体的配置文件中(hexo-theme-matery/layout/…)找到对应的渲染(.ejs)文件,查找需要修改的部分 ①演示一下利用浏览器获取定义字体的部分 对获取到的id选择器:#artDetail进行css渲染 #artDetail { font-family: '引用的web字体'; } ②利用主体的ejs渲染文件找出需要修饰的部分(加入自定义类) /*使用我在文章内容详情定义的diyFnot类**/ .diyfont { font-family: '引用的web字体'; } /*也可以使用自带的id*/ #artDetail { font-family: '引用的web字体'; } 网站全局化字体定义 @font-face{ font-family: '引用的字体名称'; src: url('谷歌字体路径(或者其他什么字体引用)'); } body { font-family: '引用的web字体名称'; } 引用本地的字体文件 当然有时候那个谷歌字体的网站可能登录不上去,需要科学上网,很烦人!我们也可以直接下载下字体文件,将他放在本地,进行直接引用!看下面操作👇 ①在本地的hexo根目录的source文件下创立diy-font文件夹:/source/diy-font 在该文件下存放你的字体文件,比如:/source/diy-font/IBMPlexMono-Italic.ttf ②引用本地字体(仍然是在my.css文件中书写代码) @font-face{ font-family: 'hl'; src: url('../diy-font/IBMPlexMono-Italic.ttf'); } /** 表示全局使用,如果不想全局使用不要添加该段 */ body{ font-family: 'hl'; } /* 可以局部使用,建议添加 */ .diyFont{ font-family: 'hl'; } 这样我们就可以实现引用本地的字体了,并且在web有效! 在你想要使用的元素的 class 里面加上 diyFont 即可。 直接使用 F12,找到对应的代码片段即可: <span class="logo-span diyFont">测试字体</span> 模板使用 找到对应的模板 header.ejs中的代码片段使用即可: <span class="logo-span diyFont"><%= config.title %></span> 修改主题颜色 在主题文件的 /source/css/matery.css 文件中,搜索 .bg-color 来修改背景颜色: /* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */ .bg-color { background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%); } @-webkit-keyframes rainbow { /* 动态切换背景颜色. */ } @keyframes rainbow { /* 动态切换背景颜色. */ } 修改 banner 图和文章特色图 可以直接在 /source/medias/banner 文件夹中更换喜欢的 banner 图片,主题代码中是每天动态切换一张,只需 7 张即可。如果会 JavaScript 代码,可以修改成自己喜欢切换逻辑,如:随机切换等,banner 切换的代码位置在 /layout/_partial/bg-cover-content.ejs 文件的 <script></script> 代码中: $(".bg-cover").css("background-image", "url(/medias/banner/" + new Date().getDay() + ".jpg)"); 在 /source/medias/featureimages 文件夹中默认有 24 张特色图片,你可以再增加或者减少,并需要在 _config.yml 做同步修改。 Hexo 跳过渲染 在Hexo部署时会默认渲染source下的所有html页面,但有时候想在Hexo博客上单独自定义html页面或README.md时,却不希望被Hexo渲染。因此对某个文件或者目录进行排除渲染是非常必要的。 方法一:font matter Hexo新建网站页面,然后将你的代码直接写入 index.md 中 在 Front matter 中添加 layout: false,此方法适用于单一的纯HTML CSS 页面。 --- title: tools date: 2020-04-28 00:00:00 type: "tools" layout: false --- 方法二:skip rende 在博客根目录下的 _config.yml,找到 skip_render,大概在32行左右,写入你想要的跳过渲染的路径,注意缩进和空格。 # 指定目录跳过hexo渲染 skip_render: - 'tools/*' - 'tools/**' 注释:tools/* 表示在目录 source/fireworks 下的文件全部跳过渲染,tools/** 表示在博客根目录 source/tools/ 文件夹下的文件全部跳过渲染(例如页面的 js、css 在另一个文件夹中)。 博客中插入音乐 hexo-tag-aplayer hexo-tag-aplayerAPlayer 播放器的 Hexo 标签插件(现已支持 MetingJS)。 安装 npm install --save hexo-tag-aplayer 使用方法——aplayer {% aplayer title author url [picture_url, narrow, autoplay, width:xxx, lrc:xxx] %} title : 曲目标题 author: 曲目作者 url: 音乐文件 URL 地址 picture_url: (可选) 音乐对应的图片地址 narrow: (可选)播放器袖珍风格 autoplay: (可选) 自动播放,移动端浏览器暂时不支持此功能 width:xxx: (可选) 播放器宽度 (默认: 100%) lrc:xxx: (可选)歌词文件 URL 地址 例如: {% aplayer "她的睫毛" "周杰伦" "http://home.ustc.edu.cn/~mmmwhy/%d6%dc%bd%dc%c2%d7%20-%20%cb%fd%b5%c4%bd%de%c3%ab.mp3" "http://home.ustc.edu.cn/~mmmwhy/jay.jpg" %} 如果你觉得前面的方法不太好用,可以用下面的方法,使用MetingJS。 使用方法——MetingJS MetingJS 是基于Meting API 的 APlayer 衍生播放器,支持对于 QQ音乐、网易云音乐、虾米、酷狗、百度等平台的音乐播放。 第一步:修改_config.yml配置 aplayer: meting: true 第二步:使用MetingJS 播放器 <!-- 简单示例 (id, server, type) --> {% meting "571184509" "xiami" "playlist" %} 有关的选项列表如下: 选项 默认值 描述 id 必须值 歌曲 id / 播放列表 id / 相册 id / 搜索关键字 server 必须值 音乐平台: netease, tencent, kugou, xiami, baidu type 必须值 song, playlist, album, search, artist fixed false 开启固定模式 mini false 开启迷你模式 loop all 列表循环模式:all, one,none order list 列表播放模式: list, random volume 0.7 播放器音量 lrctype 0 歌词格式类型 listfolded false 指定音乐播放列表是否折叠 storagename metingjs LocalStorage 中存储播放器设定的键名 autoplay true 自动播放,移动端浏览器暂时不支持此功能 mutex true 该选项开启时,如果同页面有其他 aplayer 播放,该播放器会暂停 listmaxheight 340px 播放列表的最大长度 preload auto 音乐文件预载入模式,可选项: none, metadata, auto theme #ad7a86 播放器风格色彩设置 博客中插入视频 hexo-tag-dplayer hexo-tag-dplayer 是 DPlayer 播放器的 Hexo 标签插件 安装 npm install --save hexo-tag-dplayer 使用 {% dplayer key=value ... %} 例: {% dplayer "url=http://www.nenu.edu.cn/_upload/article/videos/03/5f/7c999eed42e3aadc413d7f851f0e/0f50b3eb-9285-41d2-ac4d-6cc363651aad_B.mp4" "autoplay=true" "preload=metadata" "hotkey=true" %} 有关的选项列表如下: 选项 默认值 描述 url 必须值 视频地址 loop false 视频循环播放 volume 0.7 播放器音量 hotkey true 开启热键 autoplay true 自动播放,移动端浏览器暂时不支持此功能 logo - 在左上角展示一个 logo,你可以通过 CSS 调整它的大小和位置 mutex true 该选项开启时,如果同页面有其他播放,该播放器会暂停 highlight [] 自定义进度条提示点 preload auto 视频文件预载入模式,可选项: none, metadata, auto theme #ad7a86 播放器风格色彩设置 注:如果使用腾讯视频、优酷视频等在线视频网站的资源,需要先进行视频地址解析,如点量视频解析,获取到实际的视频地址。 其他使用方法 在使用优酷或者腾讯视频时可以直接复制分享代码到文章中,如: <iframe height=498 width=510 src='https://player.youku.com/embed/XMjk4ODAyMzIyOA==' frameborder=0 'allowfullscreen'></iframe> 参考文献 hexo-tag-aplayer hexo-tag-dplayer hexo-tag-videojs 录屏:OBS OBS Studio录屏教程 视频切片:FFmpeg 托管:任何一个支持静态资源访问的都可以,比如跑个 Nginx Hexo 插件:hexo-tag-videojs Video标签需要加载完整个视频文件(如mp4)才能开始播放,拖动不便。 使用bilibili服务,审查手段未知,可能看你白嫖就封号了 自托管ts切片综合考虑是最佳方案! FFmpeg m3u8 切片 要使用FFmpeg将一个MP4文件制作为M3U8文件并使用TS分片,您可以按照以下步骤进行操作: 安装FFmpeg 首先,您需要安装FFmpeg。可以在FFmpeg的官方网站(https://ffmpeg.org/)上下载适用于您的操作系统的二进制文件。 制作M3U8文件和TS分片 使用以下命令,将您的MP4文件制作为M3U8文件和TS分片: ffmpeg -i input.mp4 -codec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_list output.m3u8 -segment_time 10 output%03d.ts -i input.mp4:指定输入文件为input.mp4。 -codec copy:使用与输入文件相同的编解码器。 -vbsf h264_mp4toannexb:将MP4的H.264视频流转换为MPEG-TS格式,以便进行分片。 -map 0:将所有输入流映射到输出中。 -f segment:指定输出格式为segment,表示进行分段。 -segment_list output.m3u8:指定输出的M3U8文件名为output.m3u8。 -segment_time 10:指定每个TS分片的时长为10秒。 output%03d.ts:指定输出的TS分片文件名为output001.ts、output002.ts等。 执行命令后,FFmpeg将开始处理您的视频,并将其制作为M3U8文件和多个TS分片。 检查输出 完成后,您可以在当前目录下找到一个名为output.m3u8的文件,以及一系列以output001.ts、output002.ts等命名的TS分片文件。您可以使用任何支持M3U8格式的播放器来播放此视频。 外链跳转插件 使用 npm 或者 yarn 安装 ## npm 安装 npm install hexo-external-link --save ## yarn 安装 yarn add hexo-external-link 之后在博客站点根目录下添加如下配置: hexo_external_link: enable: true enable_base64_encode: true url_param_name: 'u' html_file_name: 'go.html' target_blank: true link_rel: 'external nofollow noopener noreferrer' domain: 'your_domain' # 如果开启了防盗链,填写你的域名 safety_chain: true 文章生成永久链接 主题默认的文章链接配置是 premalink: :year/:month/:day/:title 这种生成的链接地址很长,文章版权的链接地址会出现一大串字符编码,一点也不好看。因此需要修改文章生成链接的格式。 首先再根目录下执行下面的命令: hexo-abbrlinkGitHub地址 npm install hexo-abbrlink --save 然后再站点配置文件下添加如下配置: abbrlink: alg: crc16 #算法: crc16(default) and crc32 rep: hex #进制: dec(default) and hex: dec #输出进制:十进制和十六进制,默认为10进制。丨dec为十进制,hex为十六进制 再将站点配置文件的permalink的值修改为: permalink: posts/:abbrlink.html # 此处可以自己设置,也可以直接使用 :/abbrlink 生成完后,原md文件的Front-matter 内会增加abbrlink 字段,值为生成的ID 。这个字段确保了在我们修改了Front-matter 内的博客标题title或创建日期date字段之后而不会改变链接地址. Hexo 插件推荐 hexo 的强大之处在于,拥有非常多的免费开源插件给你使用! 插件 功能 文档链接 hexo-generator-index-pin-top 文章置顶 https://github.com/netcan/hexo-generator-index-pin-top hexo-wordcount 文章字数统计和阅读时长统计 https://github.com/willin/hexo-wordcount hexo-abbrlink 生成URL短链接 https://github.com/rozbo/hexo-abbrlink hexo-lazyload-image 图片懒加载 https://github.com/Troy-Yang/hexo-lazyload-image hexo-generator-baidu-sitemap 生成baidusitemap.xml https://github.com/coneycode/hexo-generator-baidu-sitemap hexo-generator-sitemap 生成sitemap.xml https://github.com/hexojs/hexo-generator-sitemap hexo-generator-feed 生成RSS文件 https://github.com/hexojs/hexo-generator-feed hexo-external-link 外链跳转 https://github.com/hvnobug/hexo-external-link hexo-autonofollow 自动对外部链接增加nofollow属性 https://github.com/liuzc/hexo-autonofollow hexo-filter-nofollow 为外链添加 rel="noopener external nofollow noreferrer" https://github.com/hexojs/hexo-filter-nofollow hexo-prism-plugin 代码高亮 https://github.com/ele828/hexo-prism-plugin hexo-neat 博客压缩 https://github.com/rozbo/hexo-neat hexo-allminifier https://developer.aliyun.com/mirror/npm/package/hexo-all-minifier hexo-tag-aplayer aplayer音乐播放器 https://github.com/MoePlayer/hexo-tag-aplayer hexo-tag-dplayer dplayer视频播放器 https://github.com/MoePlayer/hexo-tag-dplayer hexo-douban 添加豆瓣读书,电影,游戏页面 https://github.com/mythsman/hexo-douban hexo-generator-searchdb 本地搜索,生成search.xml https://github.com/theme-next/hexo-generator-searchdb hexo-algoliasearch 搜索系统 https://github.com/LouisBarranqueiro/hexo-algoliasearch hexo-algolia https://github.com/oncletom/hexo-algolia hexo-generator-search 本地搜索系统 https://github.com/wzpan/hexo-generator-search hexo-baidu-url-submit 百度站长主动推送 https://github.com/huiwang/hexo-baidu-url-submit hexo-offline 开启PWA https://github.com/JLHwung/hexo-offline hexo-pwa https://github.com/lavas-project/hexo-pwa hexo-helper-live2d 看板娘 https://github.com/EYHN/hexo-helper-live2d hexo-addlink 文末添加当前文章链接和版权声明 https://github.com/acwong00/hexo-addlink hexo-blog-encrypt 博客文章加密 https://github.com/MikeCoder/hexo-blog-encrypt hexo-simple-mindmap 博客添加脑图 https://github.com/HunterXuan/hexo-simple-mindmap hexo-pdf 博客展示pdf https://github.com/superalsrk/hexo-pdf hexo-tag-echarts 博客添加图表 https://github.com/zhoulvjun/hexo-tag-echarts hexo-steam-games 添加Steam游戏界面 https://github.com/HCLonely/hexo-steam-games hexo-bilibili-bangumi 添加bilibili番剧页面 https://github.com/HCLonely/hexo-bilibili-bangumi hexo-generator-random 生成随机文章页面 https://github.com/Drew233/hexo-generator-random hexo-web-push-notification web推送插件 https://github.com/glazec/hexo-web-push-notification 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/27
articleCard.readMore

ISP 数字图像处理 算法概述、工作原理、架构、处理流程

584d73a89d03fffb9e2dcb66cd3c11419bb7dc7ef1a51297c142b0f8c3c01b2d15f087ec1dc3c726740abbaf245c05002b9b64627007f9abc74bcf7d6d4ae220cd964fb0b4b1628104f57b8cf2aed83e7116ab6e8e3d7935521b90cc317e891043c146f9bc15777259e12c642559f07630b6b0f54efe29afb440c1221d4a71a90c0fbbbc116e1a4558b5806f157d4ca5155e365e35a1aa48169f6446308509ec6d09f121d446b4acb52760d12b053ff4d838f0b0e2b1949053eb81b575869729ce2114334fb984a048d9dbb85cc075b6666e86a9f499b59a1083ecc3b434ce2aa567b0639eaf1d5ae59fcfb5cad38ab90951bc5a85faf1909bb1c3afd30f1c86358bd9d2471a740ef6cd4216cca3e68f5a4d5d126a525f4ab0185eef20274af7b406e527978665d27f4bf13d8b0f8aca533537bad1e73f542f092d5f1e2bac186ed8dabb7107df4df00b611ba84bd0971c6d608b4d7b218a905aa9adf17a00c649955b76bc3ffe9df4bf885249b50f8583276ee3e8c43f3fe3a6a628128d3385990e30c346d43398a55db3aca44ef93de8341728a9193470b9f6669b2fda46f0585d5d994fde2fac12d92d6b226281602a4ec5cd5e325c0b26a000f01971cb4adc442dc8e73c16dbb10cde4683cb5c6e3611a8304fa60133eb24db81b30f032c7bda8be30683c4ba5e46b5ef4ae8751374374cf985c25cf74986fd319da0543d025d40a2ec3b16e63389fa477cfaef54c838811e11f6071d0af16a98cf06234cc8f2ef7b2f4a0fcd561f83932e56f34f6051701ef1ccef87b76620472c0664b51251433b7cc4aabc2a36ed1e163ff6dc85effc90cf2624f01d78f99317084830e444e52c2686ba2428f0f959a923438ff4173b050ddef026634619a7f0a5a8aa36cdaae5977ecaf4921bc729825eb8dd20fc4a1183a962d5f00e872b8ec1f589af19f081eecbb537ab4a3a34c8c2e112beeb37af3935c3dc28b85111b6840d7cac2c1d944c9c41ce82b87d006e4cb17b67db8c21f56feaa6fdaacdb0d5d2b783f006240d2cfd3d24224dbc563314bf68f0d72aea8bb80ca0d99e81e32649c7f5ee3e654edf193999e70be087b9d2d1800e72611138bbcf7d89e67b6130d62d5a1ec41e4b2a59f29eb7f5d0f9e9465d2cdd04a45c513231c73d2d0146c9f3403be4c653d2b02592080757cc8c9950cee7c958d4ae8fec016aef7b7c7a48825604f77d286b206e46f25f8a0ffa0a93d3c65f91dcb3be53a054f00e4aad3cca7e25d279ed14b76ebd1f6771f6009afa81039a82611f60a0dfe63aa0545c453402acd26cd0ba951c73c8d006ef1325a3a5f4104470ed376954ce61c3072287bb13170afe688bbe13641761c7cba8440c18d56b8d4e19bc43781d6a1af42d19e0a190d6432177bef416b73ccece090daebf884825056bc761c150ac8e0c04739d78d733e867b1e4ee31f5b72ad6c7144c068b214f205beb40b6fe003edcba59f0f4a49b59f75d6f8bc5a7e73c28876de4b0c1af7ed958cbc1fb1dbf8ee34e132ea7ab2b340b3c9d57a8d4908d855a5e9fdc6383149b5e4b47f593ed55b0fdac473bd19eea07af9b167b3132e06ce1154b51909d717806c2e5ffb0df5f831aed51c21f636b7c8ce854f0b5a03aeea6a0fdf3e80c87ccb6aa9a2d287308d04278127f1f905b4122fe00eb657512642b289f171003dacef294d845e1d336c5702b4ea510a8273a7bdee0e7ad8a44c42cb14675686fc6181bcda2f41649ddf56e9369bd32c0b3738f4ff718700893174c3422172874c86ae876cfe2b8582cf53cf5e1745692ff87624d99b124757c414541f8d06d820334b4c32bb753798abf4715d435faa1b93ee17e07add3769eaaa1b6c82f2b3d5c94c5b3c9ca625fd5c04b625c950761591d9162a5404a82614acc05ed3b1d6c34e85049f4a922968b5bafd6cd4d25c01c75fb02f6b6da3e03c6ff0013ad7d8cfe7e88b36ce7d2adcce306552e51e666ad3ce3c292fddea1424d2f7f8a8db987e064a3e17cb95cb620807fdd318739813a2dfff82863fcab550d1185f57dcd78135015714e2739a800304d2a1169be813c0da27683018ee50348cba9c0f00f023d310b8868ad59539a68c85481900a460e6790ad77e5bea0bbf9d92fd3c6351748cdb6d327962c7112903f76586117f7a6cd0ac24b4c97be22761a441fcb1dea0ce1c8f46c3c787da8d7a1a9625c5f352be40f7a9418d9018c4d39f5bfab01b0bcb592cef6cf25e1a8de7c06f2ab9f1b8a4032d3e21267f2d49bb473b8e1c5b3f8b7383a001292bd4ff020ecf271288ef6fb35a89e8eb006d6a657db49502410d7635319eb599f2fb512d791e19b49f147bd7e515a204eb98ae30c48ac990617155b91ca35ac748aa7ac0d11970cff9ef1b710a137ee4b51688b449682c942ec65e5b58f83ad3ea3f520b56d0ac43f69c2614ccc80238d8fa2ae888dc42a7324f00d69a38b99e5875d6efc636a471d1601aae660ba4595fec00432a6ed521bbaae4c086ea6d24630ae681a5a9708c3bb62d56ad0e1f15ef997107034ecbc6911c2a2e9d1f6a94aec4f92241d46e6b4579af958eed56bad50d99dbfddb7d8a1f1727c4f1f79f8fb3d43a554d6ef06fe41e0e4a089523e320fe11178f8a3f0b802e96df94135c7ca4aa104974704110b085dc02bd1b0dafdbd8a8efaefb789fd2fde3ba007dd0c4abba51366d2e9b644a4cfa2658a8f36208912fb0088dc7246e8954ec48310381be2a72cba5f25accdbd9ae6f544db62d82868086122b1c9a70ee9462448556d251272223e7d67f685418f41fc4bccd548b5957074bf72176650eac5fb5039ef0f6abab5eb357079021436351ebbd979fc90d0afefd388d29147a130b65234350f3c61a747cc51c8a8aab4b0274d2923bce98c4c3c0eb5b78aef282c089914865c11e5204b65d7ebce0b75c054d743c835712ad39777504b327718eccc3f151a94328b4db6fc69401a7efb3ea492bdba8606b0a7a761c353ab24a616e9e5f126741f05d9096c1b6a0f835dc1489b0541292175b11daecdd37f25c3c9f856157258888f1719c50ee31d6552176e0afc8629dc70d9677188d11563deb70f42be1de2c45cfa124f9e107eb8cf476c8b70b96a90b0fc3f77e876e52cfa62ce130962e6101391f91b7638edc1458bee8da150aca7b6b9eab220177cf8bbde38ae20304bb7bdaf09091534cd24167f26a426b57750fbd22c5d5d877327390eed0dce3cc5729d3b5e3c0d86c3e06860cc76ddd211211b0c15428efa5ab24d3440bdaa5c4e5cb92a2934db13a2aad38334d5bc111fab822da479820b266181f111fb401acf0b4e208246798dc58b0d9d32307b0512bd2370dd6a69ad499b2262f7e24408c5a8e1ba338fb0cf4ca836480cc2f28c46513e3dbc7bbd85540ff222742903215a573f1c506fdb9e2cc1169f452e1fcfa49749228a7c8450eb41fadb143fa10c90f84548f8f9fa82cb4baa26080588daab96724372692a3b78a65815591a3bd3014a9d3658bf61b66a4f611ba8e001d7f79f61eb20e106c9f6bcc2bd2f27a3f59d060fc077d2611335cc916c82b23983556caf28ddc6e1d9e2b81022fc2f6e5cf2622c8c6630a15455c1a1f450f1207ea64afe7972c5bdc83bcda0325babea938f776f68c00a2496445797fe28ff903983a7dd992bf07b68442633ecad37a306690c990bb8a7ea48d37de2d0dabd2cb7ef03321e1764412cc059daa2df8a764d1e257ef06ba5053b62980f0dfc5cb46a142ad963e16d7f431a37b649581c6886dde06c6f1ccb25968322df419466ac25781cf35d7c5b834b82d30d72cd18ed81c519f90b2b950fea81f5b70e058b2356a55d035c34fbff23a134d14b37c2f559b360c7e7cfaba844956024b4d4718df728e51772d40e2c31e5a794088e416d6c1e63afae6a6e2385931a8ab5fc423f6b9a96f97ab8a8d21154b95b99e84afc1cf0946360b42d59873e25121bf18d3e33acb3a5fe742af2631fa0b18c45e2302fdfc01c0d6ca52df8371eedd704258af5ceafbddf1127601b433f893e787fc3044eaf631fe220f715d64c0ab1a29bb11667223778b754db474371ddd80f1d24ddaefc639b5cc1ced23d3719db3676d69a4001fbb65b0e02ae948c5c3f1286d19de9a1b5b92a0a73eccf2490b01150de0e44acc6f2137d413ebc2cf9a5a219418a6e59af0dc8ee762cf4f4d368007f466647e1a92a050f458b587187c1e9aafdb2f0a0f5f031f9544cbd0799f6bc341eada8dde661b635852bec8ec983b720986b8c9a0f94b15d0ba0aa0455a7a5979d1280d9998dadc2b23e58f88d1e55ada21526806a91b8d72b05b408d70c15e064ebd5f59db3ea553d8c26b38be5fc5ec6eea7afd9eef042dc4eb6cc8fe956810bfebf3745162636f87cc5433676eddefc1db053267a4baceac089301703455f23c5db29f7516356e956bf6f710b24386aace5f0241dbea6f1cffbf75151cee00af9d06c81bb916d6dd3dea1acf1d5f309eca1d81975c435012b44b7df49e029f164e63b811bdd8bb5cb2c20c72720b53f156f069cc258c82834e680a1466da3faf6bec9b0f5bd64bc7d1210f854e7dcacfd0d4a99818a4f7893dbb35d5604f7b8ebc393a1ef288f748f75954687d8b057346e0e82ccb989a32cc24c330513e978a0e44b5565f9d33cebe4727b2208784499c1b4871a7ba69f4723010ab4a24d92d0e76fa9ea5a56cdf0d0abf08128229a8d5e8bd4220732db2390a69efc1513b1b89398387b0bbd97bc8641af787f1549745e7cab91fb8074862093498e1531922c1dbb6944c4d733963acc61733769129d03c879a0ac1f9686e0ba9f9158ce5970b388401147b640aec3b8c10aa7311f45497d6352971e15ab83777c5f2f976a479f5bf10d3fa6fa63d7c1be365ba20c438089525eeeaa96c0bb5906368df20773cbd84b8dddfe3fc04acb8ceacb2d3e834df14c1788509548808a1488bc3f834c7bda45412154c5aea934eb7119f2b493a87da056ad264c2ae241257a655d4353212e5a22159e706cf57c0b096433bc2d54a69156078b4373449c027cb4fada9c0c651c7b18dabec0e6744e40f566f3d876f68c3d1ec0e01cea2255f066bc5c47c869ee29c521ed96491c2328af60f1cbd04c2176067d15495430f2c1e6df2dddc67048f7457115e505183aa53078ec2fc9e83e664f98d8486fb746c4285ea1bc73055862b5bb3ade9a31f93de1f250ceccda9f357ef65084b54d00442f49365b2f618a12ed83d7497ae30c360cdf9b8075d172a7f83794957b6ad4bc4aea2e2296efef8595acb710a594b5ab37a768d84b7703bcddb1821228e1d7c7dcfa30859a2e81e6e8e4baa8c1224354a2e8525ec274a919bcbd9f95ad213d2c6e90205f4af0a8bf9b1e4cd77ece7c659d1690fb5eaae061a887d18fc7c4e6c76a73a339b75c6990c1713f7c1a0940434908ebc23a278e18957b7bf578dadf58a15cdb83788e8d255f118a1c869317d2461d49b3740099915112ad6389bbbf304d7890bdd4b9ddf7d31d5feebad2911010ac5de79e163ae93ad91403b3774eaa11cb9738bb417a947d50b5c426949679b9f27e93cb58bc235b11a7f37c754fd98029aebd612ba3191ceab61f340b580bec0b17452bd88e56063a51e39045f043540d1b45bd2b142b785f741a4e3c87ecb137a4787d7ee6498792636ae9ebf3bc731f9c18dd4533c6abcfaa216c9ae3357e947991cea60407cc38e5dc404f9b929c638bfc6f9361eb99ed8899a37708712b83782aa8c1514b5cf7345917b0696670e56df542349272857785303b5dccc2bfca7093fac4feffa0f57fd9a704e2b4b9cf70f8d656b5519dcf06e7c74e46c721a9f9c48efa42fc82ff522dfafad6593c4ce1d2484a5494098e0425c029ca97612330da5fa6bd4df34e2c1038d097fa18905b943e8fee2da75f2249c8407d6285d87019a577948a7ecbfe62fada38220544714b2ef9394e66d9fc0f096f3ed5346c9a36c143872819776bf2edf7cf71b5f7f822e19500894f51cebad04dae61bd183ce7105a166ed041ba93242fecd5947fc527d654b2b8e18ca7a58a94e1cf00c5c2426eb17245699fca5d9ddc0d7a476cc1a0e4191ec25fc6c409b26266a216cbc1cf84c497626b59e446aba23ce632fd917e2198f19a26fd7db8563a085a73d5112b29334ff7ac82f085f423cc9dc6978cc818a7224e450a353e443340e9d275e602e2c7b7a52f316fa41112a499136fc1c9e276e6b9f02b137fc554d759e8e7fb04b820de64944534f3a9dca9c299c3fcde67a2ec36e1157a471972a38491d84891915d53dfd2ba1d66c63b08e88c864683009dc2a2bad9e20e44ea58495da41c0ce61624eb9fe19b8f7b4efa75f9a4f652361adfec9817a4736ac71264f8fcbf6d23d75d3fc52f93af661d46c945aabb8382d40e38994c759aa2243499432bcc7b913c17187595346fcd3be1286f7c440abb31bf08ab3795bed5ea0915372029c1d1a38ef34251132490c34335e47ade9786396ae2ce178469bf8b0e67320e79f3d10a0a221bc26f8e66328abf8b72cb3d84363ab2cb0a52355515f810ac1ecc07754e954f3d5b726b203bf4cab4501b1e79168267ff3d118fd91c6159b3f9d2eab6098405c34af307dc7d822edb9e41d2a430eaf17299e43f24b436340d8107993eb50e1256c0d33769ccb43ecfef63abd5f88e10304befdbdd0f80271cef75a14919e203d4da2c2110e0f36a96314d3bf419c65552b63e7ee2a89f4b8c318f86f7e106da0209c022082f06883a7aab0d3598cf84318ae8efe4ac8a4230d77660b38286f48070ffa05c31636ce84758d24fcc3eb185414dd0ad603615e171441e9064aa5027a59fb8ed62c92adfe2750f89ee2a866359b1639da2598ca2b39aaec7eeec5c8af3248dbe6f65706f878be762ceb9b0a71d5d34cd75a138cd382afda7bfdc8b345a362654f9582de7798a518e0941e363672ee732117d58e48242644aba375e0762ff8a1307efcbed006c673adaf32a34a4fc181e44a0af1045a36134a9108c934f3708c772d0184c8e7a35061e7b7224d32d41160aeb73a3fcf877f12eba557bb5a97a05bd531379bcb31bdc5617f3366907d422091bd06910198d8292b11dc64e871b6aeb4ea6a89d36b01dcc391fc6e842234688d0c55506d4026d7a78447fa43e3e1861b76edbf979ceb70ca5bffaf74069ed69ad17968a2bae11653e277bdeca9d1778a941241ed6013efae739a25072c4710b3eda7ab749d696d9dbc06adcf0120b46fd6bde2ccf4b645aeb03167f6bf78efc0643bebe29e3bd668d74ba4d2a869b015b90720be1a490d81ba8f5bc8b1310de0926f6e562bc0f3321eeb20ca81738779eaca766caefc26f8b64602808dc36cd6b8b7ee214a1b12d9de2cc3989715e3fce4717b6934b903dbe3d9491d2b11282296c60276a945f390f80a035ce91b672a9b2b89fea92175ee9d650c22ea79806d4c600783bca75c8e1ec11bccf6ccc99be25b980fc40d4039eea1fea8cc9449e61d6bb5ef2880c7b9671da8e97db21f375bd5018db10f2f8169751f06f9e2540f85768cf46fadf7a04b5f569752a52165c816fbd90fdefa50044d6266d019005ef493cac75ef9949f0380cacf123d172564480f15276f8e738fa605cf2f412e7d910a3ba6fef481f9eb074b4f7aaed60dea018edbab798738a2a2a0277ae888b11bec85d1ee786ef2c41c701774d64a93176646fa115036832d534c5b0f6c1e006747672878317018d93db571a77b78f97d16e9e23576641d8c0c288b31bfbf8775fe53a9fbd64b1488315269ab5a337e65f362eaba3f840db87c06df562771d93df0a4fab748c633892d0baf934c4c5cc8a7ee9a31a27f8f7cd6ccecdffa78a605fade56751d490a1968a4975e424d24408d64637555f67b11fb570400533882b6de4d99820e4fbb44a5766b4c562c789a0735a0e52ea7e7f326e6a4bcf6ef73730ee8f56c214d82ec9165257ea4a00694a1f82eecb491060faf4dde7e3d0d6e501ee44f420cb14ab076d21a78f0fc9863f1b971b2fa072dce71ca2c60096a682e53f693aaeda5279e7eb318777c2ab6e791e8b238ea0b59f594610c67cb6a93dcd223024f819835550f431e771db20da01f8286d55df2827d1cc2e406567c66bfe141e46373d9caf472123f08c21785f55ef553c4392197e44e59ca111cd289210b49efca420e6e9b6bd7d13edffa353f539907c8fa2f08f8602bbf238c18d48b968641fd260ddd9164afdbcc8ea5b88ec11de57fdeb32ba1c6d4347a5337717e1751243aa9f319e7756dd040baa6cc73ba9dfe1ced6a4496690f4224419e07da3a1af584b0a3f77b722a26711910cac38aa6206807aedb110de54887d96e524a124cef7236e9f0338e2d1530ce7a4fd21fb67c9154975af4618aaa27357aae01dc584ec87d983cbd032d7e1025c38328725160bda494869d49e04721bf4cc7b7ab051fcb4168ebf0a857ca56da681bff09263de46d57edbd75fa9511377d5ade698df4b5c8ac52d873d29f556174ab9f4054e0b8c6a3f4cb49d0f142627ed49e4aab6054bbb2c71a75d506c6788e1ab09c601317ca431da5485b9ab23477dc43575feba36e89303f78c11949f735bbf054fcace3c3dcadffa82070e7bf7e837eaee213b0e29470bfd8ac2c4229f565c69fc1b1f25faa881ce43af0e8d4327b8e532ebbf5f7360c861a5b149ae0273e255de9cb1222fff22423ce27a092b862844993b1fcbc59062cb65a10d30470b82fae4d337a19a405b0ac2bfb17707f0ff9d2dabba99e02f4350618aa9525a0a3d88481d5ebb34ce03844d005706272f9623bcd824a6da757739331e1a6b44044049d74eb560c26f46ade91ee2d5a9ead8c33ad4293e694175bc99bb846c4b2a1ea6fafe0b8d8672a2dac975d84dc3ae852f373a384e990313806a78c9c2bb2d12217643013b8c0b6d9ab8ff9da4e92513e02a39ec794d7c31b7c1c327669a78deaa6dd2ea4f61174b80adf64cfa94650db73c02e9e9bc0fc29a24ac36f5cb2efee914b331640aa4013fed6ec7eb1dd169911d8dd70c2e1dd5e8949102539acf087b59c285741c9733d858dd995dde4148404c82a8fa213c4a7f41f57c27a159a2544aa7aaa69a81da11ecf66549c028cdcc277d18ea9208cbd5ff734daceeb553b21059de9470aa00a69360a2438e022c2165e1284c4d507d2275e6acb237defdb81b8c52d806779d3f666e6f55899ce023dfce7e4b916626171f403ae7ecb12b676fe69036b5c5dec4ed0988a0000c4d2a736caf3c196a0ea22a7254d3db790097660da49263a33ba4ec1f6af55aab9c2189bdeecfa53077d5d3bdea81111aeadcb95ce0ab6dd248ef35b16efa21f1bea7d6064bc433a12b70b99124714d94bd03fa9b0bb9561a3ac6346dee0cec1f2c482dc9d425962d3acbb9697b11d86696b00ee3f81ccbf404dcb229b51ad7ca5f28c9974030ced43dfc6ba77b146e44b71b29cd705423f2f96f233288ae7bc49e0a3fd9c1e3956ede4bdb11326d7ba0c7e1a0646582cd608f999befa33604007ecbe2f06bb76af79021e5cd9d76e8c5b7454c8844cbcfb2427351075c7808965debbde0d42fef9a6266092223d8a43593278888311cca26728e96ad45324cffbf2258f63b635a677553e40267cdf1dc383e0ee9ec7c2cf22fa38eaa3e26c84a213945e618c27c01427d1b92f7757c64058dd7791edc4bfc7db3a140a7ef1ffca0f07c9b70d72bdcc2f3a45b19fe3407ac58faa67c4cea90c4e980a6ae64faa82fd44342530577a8a012f998b9e072911c216a80b17a732e089c20ca32c0acfb9ccbfaab09b78987cab6024b0e81a2ac35077c9d0ba55cd8459500d9b6db1fc32d809d4fe1b3d5f77f3e06e93c12f5c0e76b68a09c3a663b750da6a120f06e7bc3753c87e550eb85a1d6204f77678d10605c22c0cd9e9bbb37e62839316e5ed2361f01106f878d116affad29f72bf56320bd9b72c7acff1a9cf47e28c41d3a719b615411c7f72af4e6130be45a6922ce2ff0cdcc9fdc7a9058862c642638bd9602e194d64cf99bb901b80e15c7da3b0383abad3db9c2aa700f825bc26a0b431a5f60dd7d572214514b27d10ff81bf3b524b7c9a2782240601f4295a765f958185ef9e58002228b292219d1bccf11eedd11374403e0c1c1ad7e46e30583e563ee0aa0ddc5c0e0e1bb2770b047aa5937e0289ab2b164e13bcd5cdbc2868d24333178d74a603aacbe569c3272bdef61cb92cccae36a6ccbcb3a04847c425aed51514f34c81011af2b7dac17088ff35974824c1812d3267b08aa7e673d3740e33c14ff3284245081a6ace0e181ada80b112bb1121cd3b29037135cf762444e8cb7e2d1a81f10e350e8836268ce98f2b888b5f06f3d365582cc1251d78e93602ec51360eccfa59dda5882fc86063e6d90189da532274e2562fb07a99aa88abf47ae2e277008557eb1e164e758f7bd4c251424d2e020c8ed15356e6143f60de03108dca1c14bd4e90de013e6f8ede48a76b005ad436eba34ce9ced3a34caa8ac3ea9772abeb459089e13f90c34e3c28d63ba4b416e4552595550645437063443cfd40ccc126bc0022c2228ed1cec815902581177a478b4144b13e039c0de7d576afde5fca04c9568634e1f5e8e6f8774d4e9e388056af54782efcc0a3b2e54fb01240f709eda0fcb2c014e9f02fdfdc117189feccbbc6ba8060cff7d5890c0f960d596ed6390362e38fe4beb94586ef95c14c271a43b6c5c9b6fb3845950cdf25602a20484302b0f0749147567185ccec267afb30127552a09268eacc389d638c5b9e60129137c5d4d3177b6d1c17f2a545eb5d2ea3b123afdde3a9f727fc9cc2a49232be04a76e7ed92fe89619aec8a33f7a15a3db956728e0ca04d7a7e39ecf88429de198ecc84740374dd38eeac11efb0d135cef3f310d1e41daa3fcca257aa84994d8d5491f8cad5de25fbad5bf2f12c187c707d6f45117ca2e725af27ed075d2617ee564b48235785fda96c6db669c70ded8f539ff651aba10fc6f20215fb76210c4ad5179993b80dc6bb2afb29eb2dca363ef94df2d36ab0d3f88ab4111b3ee0cb9e635c5b8d0529ea6b2ed4bf7972faf5083d134d39af98827cbe426d1210692354901f1a91efc13b818936a044760f45cae57f5bec3df488aa4df0b538fd60815f2e0c4249d11dd92f8fb7a7f87aded5f813507fac68eadf0354e993cfceedeb460dc6a7e1cfb389214ebb40bc424328e5d3a028d316ed6e20075807c4103121178ee5f5af113389b68ec0b059daeeb9220fa3d8a037708ca6844d5d99a9f38240e842a347cb7b3652bb2f54b4e2f26a277a24271275add356395fa0b2917c87c4f6b529590c4f6aaecfd59c076189704c366f85ff033c2b96ee0454c25a2ccd4ca2f058278cd08135657280c7bb2fb069ad1e8415ab490aa702d6fc0e050cb0d24708acffb172c743aa37dadd6813810aa1eaf138a122fd0f07e892cf414442134272124cdacedb70766ad376f492cb9d21ebc03906bc473ce182abcb7dade86f41e8afbfc9efc72dedf38da483e0421a6d68b68e11f5566e5f588750223333e3f2795795e2252bd35d72c0e573f9184e3624b8cd2b2aa4df70908a881bb5b95a65a7e210c8882815b1ab94c96f52a31f62f744e32c7ae165cf56696e982ee82c1b4a0d7c9900a5e52a54a84b52f0bea6fdcc977526909db3a748a6c0a56f57e10254bd432ad7fe6ab6389c8c4fecb1fd505969a8c231328cb37133fcc78610e91a6c8607b1359f1cb559f3dbfc25d18b7196a0d2b67c99dae9ae3f514fbd8fa16bd72ae78234145d725b5f8ee84f158cba2e32e64e816814c12dfee7ef48a7a68ff104e6ee01b8dbaf8d58ab3d95227eb7885be71127cbb26d2362908cfc855d64e64f23b7a92ba7ff21cb2a46d0d712c25e64e3a04e82543d27c907526203ebf2996e575f2c95f88c2cf36714eaca9f2f8b79936dda7f4cef6950f2adebf6357bb9b1b419f20cb50979fa965090ff9466264bf68fcaafb5217407168010c81badf4ef91005eb002a8a03fa96c710eaf9180afa07d8838f3c0bfecad6d4d5872b49a90b5a9e104233fa657ade6de84bafb1d489ece19e96fc3d800277d38e2a1b067df840efd93a8bb7fb7edb2e4ef5a44ce723fb8048b24d69f5a2e39a2713fb578c73b26b1ac7ef5de255cc24859cdec4c456ea48d5af7d22376b853e183b8e7b5d67a45a0325372d56e1f48722b4b3614134822c053aa78d8710de73eba90e889bdd8a88882263f0f44a62a85227c2d7a2c0aaf493ca14eb4a80f95a640f73a45f851858134bb134c344ec236f8da07755159bd28ad9be4589d4b0cf05d07a028485539266fcb555bb7ec4304aedaf56ce435eae8659795f78008bfbe4167cbf92a79296ab1c5b7552e98a260d933f738aae7caf54aa7ca87675f1347174db77b061b0243baf693215d4f12f832f32c9318778c9f25c86ce3497bc608f9b0342a188399c00c6c3d45a1c7a463e4d49f97bff5f17620082b722b520bafeeeacb5ba9e1f0d032091e1c68dd4af7180cce4d61a14c6534cba2d5aea18090f6ef591161a24030da5a621a023f7e1af8949d5532ab5dbba580e77c07d290b2b555d4dc1cd9009b803c3e70812df19fff366c3a0de09f29dbfc6f52df5239c266ba3103b28ee48d608c87498a7b5df02b0808607d45e8b39844b3285c9ea7bf8f14a71b402a51104893c4b014c0a4dbf07b39cce4775697ced1b2ec267d417be8fdcb3d5fb756e6a913de77b285d476f3b6175873340304eb467e40efb93dcb75a48a8a1ec0ddcc9d665e16aa2edd47c63b70ba808cb87facd307e24c151e6e9af4e9b546eb8e18016615f1b1adca082ceb5f5b181519788b70fe8e53c3a14a4cc9d038681ecfe217ee4d776e48b2aef3f605d215f9afcce4a02606f0fba7f5c5d6170dc2ac0006b6afd710b4043c3941871e50c0db7a385afd052ca075ed990d07304de0723674cb0dd6d5b498650e480696a8e16dfe6b2caddd7db04751a2eda1901dd78acd36806c8d78ab7a5061ba868e124d058491e5536be44b36bb85eaabb6692e8debcf2a60ea71500a3ebf723320c17c9858968586e77902d1042b70de6ded10f7d6f3357312bda86d23fd05f60d15b473a51609f190b538a414bbad92a44657acd5c59d947fd1bed633668356ec7eef9c1fdd85e9555268f209a64eea3db5a382928aa830f7043db42f9a123757f21321eb1ad6dcc58c3a26cf97e47220ea455f2210266dbc01212115b6bb3b95c2695ba053abd38e9cc08bcb0c8d1276b5a56cfd718199e5967c829e6e78b1467480891b4bc0096c4d62e0449a97c8de97101e960c1d38139b1afa824d08d04746ae998542ac69a648e4ed27c5a153d3f9957d1c6409216497f27453c3609fbe364220e59f64e7f279c07458ab458a5c7afff8e007cfe190f49a04db49d09133483b477bb826bd0682c3469d093654ea496dda52316a3198c7d273d190f05d79e09e8489c88c8d00759291f0588dad646476f47626e24ea3fe97acf594f06b2bc4ed4c3a5c6fbe36a351dd99aefea4e2c394b5728cc36253ffe288cbf2d86ff04f9974ce08ff39134d2040555079cdd7ef259e0e70950c2c6b9d6009a766bb36066fe647fce3ccb442c39a7dd4baf3248408038d633a8e9cbf4abfc5a73ca21645a6a0dff7e24577f895bf1e6c5fad4c8f6f44a25f05f0c78936c96993c39b375be9a1a02014af5657a884f32a00afb914d430453149d97b97072e55abbee7a8466dede00b9ad45d554f43808ac32b0e0c6f3cb56d97ed1a4f33998eac043107a7b559e80a3a1137cb470dfa544a9f3354e83e693b85d807190f5e62b2963268450c25885823e69c9c0a27b34a2c3fd741859b8792c728a277286ee648d4fab2c1240e785d82d6f75d690b069062385262b2f94feab96b0de77a5c7bbbf9b9ecec2479308044716a427dba1d62c6d885f39fe7debf5372f1f7fb07f890ca0896bb26acc3d3e6776c2aebf24576dc21ceaf4d3d35fa038f597f9b4ccebf7005e9f10ff9ccd0c8dccdd78b0335c47d46d45c40dd53573db43c614fed7172c7b25e4f1b45ed651edec4b8335a0e8a009cafff3b514bd7a762961af70f76b2e07bdb9c133a2b4b5868e85e34b652b184e581f43bc9162972d1ec4a62a30bd0f12b46adf7aed074397f7559f131e429d8994b2b3663e0e336e6a9ee2b0e2f7b59d89d972170aecb64e87e232f064196b553820c6625ae2ababecbf1716fae0c08a59ee0ca02810bf9648def4eb64421d86b04ce2615c756a9ee88161ef63b1fb75aa7eabf1211bfb09085c3255a0dcf3ff688d5a489e4ebc620ceceeee8dd67d4d9c60501d8315d86afb1a82479824b06e617f17967a82419ebba169347fc11a42fd0a7218fbd62df1ef61d11528811a1809af9166416afa22f0494de7f4666f06fa3d8264480a32359ba985c7852164a477d692fb7172b6a06a309e9d1bf7c226c25ac5f181d34460c841804a472665ff5b971748659b4f80ec14eccd25dc871d0390e2dc37e0f437a6f0219129f34238dbc9b61c671976f235881afa3480c0a71de583d6df538a4e0c04bfaa8c57e8fc5b4f6f0589179fdf1eb190ab32bbe8999f5f8b6c005ed53656d3c4aad1a4ab5c0b9f3cb3043966118fb0b4e00bb3862b4c2eeffe544fff921b90670aa456f2803923e2ca8f4937e79b2276f9209432cc9082df94e6324937501806a6bd9045d98eb6ac0be6e8a37a1aa51c8fc89bcfec0d66392d76782dcd4e4fcfa6f2c53e0dfc24dcaa94e1e0b20c297e6d2e4c7a0718e92c74edf2f45ace1ee20673306ff15cbe3ebe66f1b3d102df0a7533da3b61a8a8b53f58005999f3a2f6b0113028f1b305238385ba064817c3c7d2e48588eacd1027c800c935ecd481ec42f2c61f912dbfaf6c83ddd87242a38125634e09e99e87602645a5aec01b03e139f7fa17b224b0c985e72ec1387b8ed90eb201a19249c66f9fe5dd67e88b885018479e89a17127507bc15537430e7e0f63d013c55520777da0b76c16421cd4b52dc997d95d9bd5ab56a2f9f5510a634e73ce45963aac57d5936ad4bf1bd57473b2481d4c53b3df43f9bce99dda671485d09c3ac53ec5e3c1bb7acb0b914e0f3cac4429ce409f20f4901b99b605c97f05110b8f80db236d2f89d2ec3a0e27accf59b555dd0db5d88b314ea8f469fc3470a0e6569fb2d2bc56bf8bf11cd2a9aa324b2cdbc8887278ab233fa2fcfc543b02e2a4056b61097b0023d829e9c09ba16c9f57a2595b2f2013e5a6db39985752c06787b46173f79dd69a78bcc121f485608bbb9feb29a9a1093d2208c201ab6ace5e856b1b6a1f10b941e39c1b4f6fe2f01f81313d4f078f0e12d84ebefea24f976e0d492293eb8e7c437f4375f190c7b129c8298fbf674c1a274ccf70043c30d61c5ff3f15d2e231b2129814c92309274c596f1a224eea36693658e0dd5ba074c1a810e87c663fc120c0def259cb647168d54f5ba79ebb7ead5466079f4c12035cddf3dca8688b5d7ff17fdc77ff77301745d79d98d2834659d2fb689d0599e0d587f1b950d6e364c23d5153d667d17cd2d9b7a2e71875cd5b33764d046466374b0e7d6fac25c7934e6d0a711972b60eba4cbad01e4ba29251664faff86527ce45f0ef7b5d49cf9b974c5f6b594c021e9ea143a14398f3755cf4868d89effec0a8d48e177a9b666307f47504a1d8d13c017199360af23aeb519a43290626902762a10b184bbaff2995b811b3c0b3e59c10ecce0846c2ce3634d78a0401f1713f2a8aed1caa81dc774da5db3c63a9932c2ba72ba65d885cd3a0c0f7ad3115747c83a1abeba1da8111f7667666a9c7d15d599c6c95c6b94276fe4d1a4fe47ef8c0737b749c85317288c616bc4f4f8a16d9994878d216ea6259f186eb89a8c0c8a97a9dd0caee0457cc78557b32ddfb2d835c801ba85a02031c5f6b330e51f65fc487e86cf47d5ee8b100244f0d124583174cfeb267e0cc11df9a19a5952bb95ebdfd1c56960a64ebdffe75b2f4497a030620bc1b4c1bc62feed2e80d93d370d8d8a877a599f8dd42aca58fa265d4d1e04619344e353979f20bfbf807291ff18b5d6fa853a5a08bf7b3f846c91459e6195c764f1e64e6cde46c30baa8e69c7a55fcec42e08cb1dd00bcb2b665bc0de15bd175608d4549b2389685f953864a03b9523e831265a55135b5fd3264c7695a9ea2a746597bd86c1bb600986b2cdc9659944d03fef33a326cfdcf1ebd0c02d0a5ac599e84a84ea0c4e3d3fdbea0bd190dc90f3f1aca9dcbc1cb1c02b472f87537d5d27ac85f87393f44644f75166144cb43b6883f8c92312dd4b0a2c0c9194d695d9270501ac654fa0cac82e5253c8e2b9bc4ce83065036451543cb65ddd143c31f94cfbd1f17b2b512f32b6a88d28822354af1cee51e3afb3b66c6c852c15a595776d87ea7354a4685d384c68bc956059d74875c5576f2e0886133d21506c151ce55d728c32ea75f894727cb7f33734f0e6dd36e2d3b3b355701094e3c45657f9360174bd966d49e9e130a2693f5993c2ded5ad17b942dfaa135d0086f7f7368e31ee7c193ea5ab9bd4929a38461c666d5e41a93ed31fc40f60097594b7968b57fd85e6ac845cd5617cfbd92a3d256561d384dc6f8c0a00a80a5b69fe67a953300078661745753987e1891f81adeed3a25438e9a2dacd4a6829abb8d14c88851d96f5138845a97aebdc8e5c28f0110c21193df73e634553ceb0148aced085361119e949637c47734e56cbe27109e9d14170dbd0e02deac47d9faf0262c1d874de22e0e54ce2606fea340c4b57f12a00e955cc466ea20db6b55ca674de8029fe823449ee6b551c4389dbed10862cd07900dbbf8c56de53425d504c7287cc4c3a9f56bd75118f7eb20f6b69cb0ba08c293d53f911fee78e299af0cf7243255fe54ea379c0cf512425f1d2b75ced2735f775a4b778fb2a6a7475448248073747dc49a5e9b87b1e2bdbc66ece3d45861bf14beec7b8a0289633915dfcddb1dd1369bf30636966679c670468339307a0941135b1b60a7dfd4ae10b63fbd24169ce62f2eceb022d00a801f52f37a9a44a89d9602f022cd49fcd6136c197f8ec8b659b9443cd3c01d8f37d04ac91469cfc8926a38badea74e12f680b863b06efac324220b65dc9666580aad154407cbf024f2657634b55b158ce42d8181a4bcb03b612d081dc25ed066b5371b12fb90366a6444f497c6eed31bf5cc75cbcc01e269edbf084b402735560aa3a56bb1334e5145fa9cf7a55deff69f55fa4a054ff9e3cee9b36e0786bf3f7341d274cfdace915ea2d4f8b2b95a28ec86aea73d06fe19d78eb6fbb17393232f4b63d85984f9b3a655387bce3a2f92a314ffd2c2c925177d9a0bb68313374ca27da99a813d2fa5d78a51ed46a8d6b471e313207de0c78582b3f9702dcc9072e1c3458c7ae707a8a062ffa2be1883ff1b6d44740cc824bc13a5847aac28cabb1e19ef961c615c37f5e3f734d5b255548ef04e15eba2468f68046f21b1112f1ee4a27c4592341ae7c31bf58fbf3d429faefeaa4f7d8f7d2d95418ba47ab39188a4da119e757036d2b24fba877f6eeb2b0eac14548dbaccdf622dd0c462330225c4234ab029dfa095312053581068a1d6ed908f96f6c0e1ea73f6fa8a318c994f2843df5bc493ef77782a64fcb5c46f4d17ad66656fd2638f3222bf83146dce90f658e5ddc6fad59e68d6837251d7ba3c303059dd1e996171067ea9b89bc21776d889e5da42f1e6e76ef66dfa51a14b9fab5b06b45338a24c43a92bc6608f4a0c322f87a9e6f891072db126c002c316d1df6104a653f78eb375b0ad1f461296a4c331a201c64330e39fa1eb7243391b17a2dcce28c377c08aff4076f37685543b41d0b4e61da4db2cd4140d2c20b47d2a19aa04f56c20c4a06696c295104fc9f97a10d1060603129e278b015ddc2c902c22075a2befee29269799feb132b9998038cd6f03167e51d389451ba07d8e3deaed365d75629e320eda88209c1577013a6e8f6f69b1fad29cbbb300119b014310fb340eaa858430ae770437ecb3ba3681f456ae7ed454c19099991fbc18364ad8b0fcc52d20b64acbd32bb85f5ccbc4780e1eaf52720bc30dafa9868c09f2aa6e50d0bf1762dcf581ee13e10e07b007d85369bb90ac46d46ef2377f2cfd9e0094a45663e951b587e545e3b377b3b5d81b1a0f4ef6364444937fef4bd153a7839e94090855b4066851dff73916718fd6c0b5686c73e207a3d6a719db8cf2dcfccf0a060b1daf0fa744157c485317bd42bd15305d24874e26b63be8947022cae90d837b9ede1538664e18ece2fc0616cc2a755fa6e09c6deb02388370c06236ae67cc05c497c25ee0d0e5d3208d65e6bf6c1e58ab16b8040fc1ee87f9748a3ce295c07658cb61062c800b2db900aed2b6ebe52422e3644bcf3d5af39fcff4dc33feccd2884227c60ab099e1f9004b5624a32d234fde68d78bafceb471133fc452676ce2685628a8ac41a85742c5ce169581274163d4497cf397d8bbf032cd4c1781d50c04f99371481cd3f96e451303348802d5af93cb1864b8c6a62f44adcd7eea49a6451183e9dec33b57c7df55ce30f971bb3a7725f74c8b0d47d00dc17e8da3287dec4868b5c96e6f5930b9f8ee880f3a4261c319747ef1f107e2f38d4eb56ec649d9cd3819ef333dd9cc60b8a6b2619c1ea9dcfbd8d025b8c8fb732b2d2534285eeb461bb869a7b7d8a07c1f21024a768349f6fc0aaae41f8a3b9bd7133eee8c783d6786c4a2752e8ca784a8f2b2bfa110b304f1c5795b5ab2ad11891a344008e2b5fd6015afdd21d642df80b407e65b100f2f0663655b28cc0a85cbb859f0e38001d1872d361ae073ddf4f46be3fc101916dfb52db0fd40d81306ff2d24846e99297aa85abebc9c4901e94b8a5c46422ec027e9dc04463e2dbc720170a6ee012f484813f76054b615deedd792359304bc910ed673c9bb84dac75ab0a4905a0ae816e04d441a8eac863a003fbcf765d692bb9f18854a44eb3b889242014212b0baa413c40ee7078716417896bbf744acf1b6f20b64159da092c9f383a387abe3320f67b928d62659836f6e36d35a331c7ec399fd515212d00b70faea37045db4501f1765dd5101da887dfee74a00dac8a2a192026baac313b585780380e0470ad2b41464aec7110df4cd023efe16167bce506ff9e85bd86ea592e056d1879cfbf9d0b6c97ebc3646cc5f3bad3eb3f3f37d8fe50a1e729a751d532ff22fe6e973b63bb891ef91bf4f0f37dbd6328234a8a8df3481fed624ac31e361e31b558d880d24a5bc6762f10e448e4697e080cd97e1a2c5376f5d15555a96fa370bef841ac83072a2fa5f5a4fb11eb00834c249dcffe5e90fc262ab7ef927e429f321c8e6f9e21e347ba92bced71a2cece943639be8563e599e1abf5c2041c4accbb11d2bc121a1962b03103e86382ca8771b4975f09c8958788f3cebf3d880410656de637799205569fcc33edf814fa8e8fa86eeff533118031d5b082fa342cdc08d60d10bfd108b896116ad7d42834eb744a329efa5e233ba4554214b75d5ad7b0dc97a6b6fea52423444c98983e3e46459f1db40e9eb2759c568657ce7a465f822884457aa54feef064de43afe2ea35fb2a113b60e15c9cb604a545863919ea9e8da1593a34efc74502141bbf5add02ab810126f8e10c0e1f46dfee15460c505e673fd124a46ea5f8d806ff73094d80e6af9037227baadd93f8b33bc19d441caf98f70b61dbf389d450e4fbbe0ada62d14f6208713b2ef0e6da08d9af413857eb2b31ea883c6239dce2604641e620743e99b72d6480669e868e06796655335cf4d29df43852326ff0fed0fb904221248ecb3a613ce57d7303c6ed7cf525b8d95add48126dcf8b4d629a13794ed9542ae38d9c8b0406dd599e6fbdec9e2e6a327c98ae7ded518010a2216121bc182ffd55b77fd869fcf91266b9253025317d902d07bc95e9456a48a766aabc2c2b1e3f29b18621ed3b69c51703906c260ae7d247fdd29573b70c291d273c124eef1b146ec960ada019db488e4f9a85cb9cccfadcdeb835d3687ca4a4260a206ad1c554792c2ce7cf905953e6e7b0b4872eef064079b0464fb73e48006a83c81f4583e786384bf516c3eab62f88540cb9207f1cbacae7dd9b997d3b244ea2b6e8bc572e74395fb65a0c64b8131a9bc8d8ec5c672141e9adb809e139068f2f7cf4adc1aa8cae6d862180468618b31dcbfc596b1ae2afa3ae0fdf926a52b135a094b3e6c18ca60a1aebc036fc482bbeb7d2e019a3e7ab12da7282753335def112848bb37db2f524a65be7b50bdb4fd0dc63ae49b0399ad3f096fa227db9da13273c7a45bf60f86f43761b1691f3a2c99561a6faf1b726257f0519d77ec1f20a996d42809ca6d5cf1ef44ebd5550693bc766db4e4b5b8a9128b8c159e43ba497b994c994186ad17444722f178d20c587a1a440819df420ebba2c00000e011756f7673843f3c4cffae39fdda57fb8da1ffc0263e318fc870f59021fd535add1bbe673fac01677072e9e02c1abd6ef127dee73abed83205fffb82e4c106de959dc8146b7de214ec5f595ca026f5717bd955814317c71542dd6d0eb3322f11e067b151e59987140723e5d8ca0c0e5fab2e77a785fbff8163a3d9b86f648b4354f6c853e34d8198b05b83ac2057712e00d5c408b430dafca8cdb11d43c2164b83deb04102cba679b9fb17db9e546848242af40074a2fa8bb77089ef65b2881fe546b84fe380256daa9878373eeb866d72fef331561d372fbee3829d9a0df1860cf266c7f4507b5db8dc2233e328ebdb21fb66fb5829a25bc0a4eab9bb2ac0bea9b36633298762e2308948ab67f2fe853e70992149d600c33e1cd04c0aaa80c95843f0c920e770b845097ecb2939e00f1a3af5665adfde01dbd3eef5faeaf565b41cc9152453f11b621896f8a95bbc672cbd100388989dcb5827b982245361563db36aff0e573459e96108d4921e091ab6a0e80b3726b2fafeebad485ab8e9e4f35e361157122e4abda9fbeb16f9c49d1a71905e0eded5e36553ba935f3d65a077788b8751251075826cd4b69dbb8014843e6b4a8eedf07c9f42ec050ffdb672cb5a0b708df4ba91bfae08fe38d111e4554ace337999c92eb9f163b0a72ea0f98d08cb7709442ca4a26029fbb9ab6a5c2b710c838d4ef257e762c58014cd8947f0617e6578bd7069c431f97b8533b8069749281992b50c156745adc19007bcc42c9b1d8944d39b383554ae5a2914d88f149aba6b8d067a75422a3c39610fae98d45d4eda50ae4483940df872360bc06947890dc24814d2ee4bf074e224e76b033f74aa8e19c779fa9874ab48c99673f5f7391f2fd965120608079c1426cac641f58544e5f673905b1d09c16083925971e9d244153df9d6987def3138bbcf564ea6cd4ce84557b7226ab708d920843325b6c17bea972af3e2cd48ba6a54092c7547109c2c5564b4adf15149d5f8afbd00537aeaf306cd7178929570f53f2444ec6cd217f981fdaaa51234666ff09d5eb211f09f57133ff12cd6d84a0865603a8fe1db40ae27728b274811b3cffbb0a84fafb07d1b97dcaa31503091200ce21ff524aa0f332e31109ee2e4e0d08a4bfb57e0215107b88de1a1cfd4512f4486535b04348baa7570d8bce3afbbd6c3cd70ce9bef1fe0e2f0ac348076643d8243cd2dbaaff26949c19e3771565accabbde4c2cc8620fe112d1c523c807e317ab3eb1172ae1ae6518bc407f2cb815ec75c937f1f539379219d371aa83c3aa13e2a6aef342187eb80010821c9c7ec40e152b01b25b16689b21be537c3405c83f811d9ac0c89fabe987485134c426dec79ce7f32c3b46c5a73b39d97cff5b256ce15092d5badb0eba7a14e60025b9e37a6d28cb135c0a846681b70d4631407de9e6da2fe6c12954f5b83f5e872bb6c43d676ee9493cb483c74a206822fa5871fddb5a07055bd558447b2a441f2f7b1eec0127bc9f649780c157c071baeff55b191959375ec5b970071ebb2661d54b4e9c277c4555b992ccb5d082c78d352d62a6091864ccde49656f0ad13e732501291fddf69f819ef940ad8e4012144b4b235bae7ad8649089efe0e4401863c833dcf5d5528898a99c2c1419e5b9634f4ed5e7abea76909ff55d1839ff97a06973a19fc7f0a291005a048607a33fe483c57d4c8bba79caf236033f8b02c605bd3b5b7ab99bba6da205063ec4536392699e9a6ead00fb3c722082079a566276ca25ac7a4cf6bc7b712c9280f90ccdecad35f05830ae34b29837b4c869f0a811841a3ef0c88e29c65ac6ed44284c7b3cd79af8cd7ad49a94098bb785e259e4c609c2b0399938d553f68b4294d7b95d1da8957815f00c17aaba2a015823b314b4b2d56aedb5cb5cbf258b7907f9cfe849961590138108ed76e873c2709da8fe015c03a8e0f993664ce3b40b56f20f963a02f93f6fa8472b1553ad509db9d9a0063e7441f4b129b4262f1a0e980f36d1e236cb10d99f96a375d8871ffdc02470f91ad6c9fd14e482bd5985c12dfaa0a69b16251c5ce91fe240b86cfc9129eca2c3df10ac35451293060b08a9fb2e396883b72317b36a811825b9582a1ba85d9eec37852cb14ff8c128f017a986bd952e2abfb2305a694430d98d75154fd77ef53495442c94f533a689da127f59041af31b2610de70a6947748a38f14586e3aae91a1fc2709e8e32ab0c721f616f049b2e3baa37fe7d411cf769adb2d20feef704ac5eb441efbc3232023c7ebdc4a5255ab57c26d3eba66a41e6fc426abee396a6c5fe40462128e170ff7f1b458502c42b2102d9b4bf5c19477cd2f9fa2bb790d21786602cf421b391d5ce7b3e40abc0c52cff45121dbca648c7ab30fc651d3632797359cb779739c4fb6dfef70e35c8055160dccf05e806ac3da23b47c37f38b5c348074d7c96bbb0c6eeb75d6632f4558bad4c8d891120c8fef4d56af8d4f5262c59bc6808144eea20475735f4ed842d6d17cba3c754dd0e6eaffc0d481582f467ef35ba8cf518d06ff0b90dbe38a90b1227966d25b52ed722250ff3a24b5468c8f431c580f19f15b42658c6d621501ae60cb561ce6d1e8c3e8a175b1cf6cfd32bef434498c6907b777d18fc9af3b2d738d7e63b428e27e1b2c63932d01bd5fb2157a6f5646fd5f417fd084871cbc7f64f4f4a74a58eda07ea37fcc0adacbb03ca03672b09224c7c71a23ab09495934738a889233a91a36240771de5a3248f2b014ea31cfb7fe9c6fef321de712ebf653d838eb38a9c947724d1841766a31b25ddb5a300aab487cb259cdb81061a16c444a502fe7cf3f7c8c868075efac7c53728f698da22937148474be8ea2041effbb618ff245eae8a0a9a0f72af59ddffb697b39489c5f97f6a609d3fc38b44fd1acc93cd5eafc52a2e01df63dc8edb961a1ac48a1fe391f0a67b309e5ba6e687f8882d91c78236b4f66e4e5d4c3a5e516b1b5af4c12410554043f237d46d044fd6148ea3a250ff405bf13b963eaf81962ee2d98c1f15ca226025d0696a8c64e7ca02d461cd24083060ad302217be8d63e539212e0820bf805a6ac6e6031b413a42ccc3675756dae02bddce05ba314ca78b8d36a296417de7ad080845727c062cd1f3c04aae2c634c6b9b1d6d2a2def90a863260cdc9a960933edde9a37fc5b028ad48ff1596f527476496b4479df2dfb48a07d86b41bf8de7b08a9f24685ec18d5bd00898c02c56205415fe04c62b35e705ab78bc75110f92cf06fd4f33d7eed1987c7e5a58c038cdcf2b74ce929a6fde8d1ff88f6182858dce8a067c9d3cb38f2a22079f52a8cad71929f0c1db74ada0a04441f7b20864a4060ae0cf1241ede0a245b841a61214cc4fdaf0b06520c9fec1fcdc0ab1ce7feb92ed148f37d1c0f89e057a64798985f18934aa831622ff045b6e287d06dc76dba766d5fc205a03ef13a0cfccc6058c88df39789616bf1e6d265c80673b40cf6dded355d3a732f42ab280771ef0d8a98cca20375e5cd78f81e30ad42dafdcde49cd42ee6f35a80f03bf5b794cd876447f3d34339d9228005bb5c1c080505a0a12b04c0d35b2e4b2770b6eb1823d885e65fa71feb470940e678316e9896571bfd0a38d49b02aaf4a5a7a27fa4d16744617c0b901aa95c6a2239657c2ab20407b4a00de4537371d3c6b599b4592d0d8f682c5f8a6d788c852f72e85c2e0790c987d7b2ac1f7044974032f64c99c2f460381849f5d33c24ce89e1b86deb670c73e64a62d718f0499f42624cbf340d691761a453027a8c83dd5614261651347e2f9e823a5ccbc78cb1fb5416b6f1bc12f64701193419f5f10e9a9ecd47a5d6f71a2a238222257bb6864bfb15b6c46df266a77cce6728557246113ecd2585c7358e31a0efc8c51f2fac7d7497d1a111e7560b41b73bd01750264d11af129bf342cb417962edd11e7b3e48f9329955129e0bda5329cc0a088b4ddc3d886568fddfa457e3a5837c069b79d9e8d05b12412f1e7f24f306f12d1f363dc9662cf43a03d732423888a5daa717ad6b03a869481906f5764b4a766c87ca9c9dcc4bbeae80df1d81fe95ec5fe1a1f3629071891190ae543d61d103629d0a9759348b8b931a74c202156b02cac04f1d173b4e6dc8bff2fdca2e896d1973e5bd69d268139098fccb8b921061d4726933b51269d7561dcff568f26364c74e059d46f336926c18bf7ee9a2b13ee367f6c0aded60104844b3d368ec4f73ce999b0e480fde14b33ab5a92bf3c295b0792294167f6fcdc24370fe7e2cf6a68bd1739de96dfdfe8aac959b5d5ae57407c5bb0d4563a2928673450322aa93c3205ae98dd4201fd6cb135a1262fb8b6b5d222e9bc1056694b917f1c3c9968df741d32643a45420b8348b691d8f1f0ce7f451734a96f375332d9115f941d056ea6d1549b96cac70a76e12c7bb9c6c1c0734736852edec2d7e191a6892ccacb1b79f15ce26d86fcbd0ff286cf6e14ab2bfeb7d2e2e1002ffcf40eaa3242abc5a7b00a7c74660eb1ead4201156b8ec8e0ae90fb314e92111975cd7d1c12a5d846bd0e87b754158f31f54ff5a3ab9a2c6a723b0cb5ef7df94cc93a3755ab6a5e57791f58d614f74115eebf9e6733efea57b5eb3834a5afe7a0fd4c543b74a1f8d4bb2662b1e9107eed5ba95b10fd6e16eb99281b01488ca796f18bcc1fb268b0fdcdbd3ef32ba332af03bacbbba45888f526313e66c06b282fcd737cfe1ddc880dec3c2bfed46e9fdc203418cb74c6dd7f7f9a52a202c9d45d06f2dd9d0ad20154fad04246fe54c45bbb7d3f492e5a405f495cf9061fe46320da96cb928f5cfce984286afbdf3a3e41a8a682c745988e6e9d0feed652ffe89e431980b4a47c086b4509a46da77d023995492ca61439960698dde171c10eca967703e4d221b86a0e57fd3a70d6c3551b034d44ae006715433a8e8c5553bfa8cea58290e05da5a45f8ef86f43e8546e2edd57d633a5493ea12d0869ca863110551744b53828a6c26074ddf75faa136a14e0b0f9dd3232e70be8f45a69ba80d532a4feac6b063910bd18d39e86a5183cd185e4abfe6b75eb439e155a335481926d2abe707cd96f21d61889839dada3715bef0ff7a0456efdfce75b9e1b38c5b21cc9255250b58f3d1e28381f33f45d24b3c6ca722734939f9f97cdc445888f7eb9e7fa158a25e14aeaef5c1e202a70665fcbcf10e6b796190432d7c1568aabc227569979e69f51dd348aa60b7ab429c53ce541bfd75091bbee42a121d0a808754e3a613274481be923743b5d8017291405231547cfc22dcaf902c6cd04bfe52ad098dacc6a63172ad76fdd38b7787630535203aec77a30c73271c0bb24099e1aa253cbd725286db173e1566f5b262f03b916e2f1b457f9aae3a30089b1d95ada85aaa0b1452ff67ca9caeb102f46cc41a7af8467ac9bd75177271890f7018ff4ef0b19976e0f6f9f5d37faa825ab7b13920b22a6723778fa4b38f4070d93fe9980a7f6c2660e5d76faf2e187900c729e4806b5651bd4190031705da10412914483dd4d2548e2387373bec545e5c37f41659ff298cefe4e55a6eab017b898c0b6b4dd9ad0a4028dfadfb73323dd880db1dac9bdf8d73f950b8be0ae6d3bd70691d18714d9231a82e7782ee0ea3e76de43980ee025235ff1d84860c6cd001cc172bdd6158cc8ec99f09dbf8ecb13fca6a808409eaab87bdf8e5cfcab34a05fd66fcb803bbae81adf39f303987634631929b24505dd08b234f9eb73c0aa1abb09030e31164f7327a66a55eec369464bf13cf81dee863535b239591bdbb910821c26733c9033b27d92229e6424cbbff4f8eda487b2997f373612b846ac4b1c3053fc074d049fd8247453c1392356bb1e58154e36ca55489de04b6b6b6a992dcdc67d8ce686445ad3afc5eae78b0b74c0de5933f37e37302a2a0d9205d0a05f79720c2e6ac20888155e86e56efc55bb0ed9a041feae3c9a92234d4eba662da76d2bb72f65c1c10d896cedf2b907b458bac29ad195a68b4fccbea9d7b248f380da6bf66f204e6ee12f42a634d7e067d846f50c684c3b3566072f7b2a39bd5ebf2181001b43c493b39fa0c963e693f4f90f2d5eb87233930efa558e8f888aed7439221ef8a78a9778e8b438351c3700692afeb1f1a40ba9db8cac0f3a94fe9b8d3314f0cbd277268807df5cc9fb4ac7faf4978a3b05eb43efb1ed09e33fc41e4efb8fa0b7bf4c31b683781c99156f3493babf2ca9ea0a2be262908aa33fb1888eace468b9eefd1a5b66b21fb3091fc0f8e41531e45343b8edd794fc868ee3a38855cbf16b8cfcbc3a20b64da31766145302b9488155fc18ab39d10fe796f9988913bc3e4959b53ff298f5d29c6e7aa9764184b220fb87d353f4db81ea03a108f8cd58b69db5a8b99d9ffc2f1ba15909a10b5e90d7558ad80aa404aec49e6f19adfd056494b215d948aa8cd1a983ac35fab466a4be4c23d976a788b6fc90ee9eab2ef374481dda94a879ed8662646bfd41132de4732779119de96ca435a767ca65b9137bfcea53c5b1ee6339533e797d71a02da19877e0c0db33a8e2fc45416d0b0cb8a201c479d53eb69437bb6a1672a53aa6170342df7c18038ac4ed9dd7a5e0e7d811813ea29226a96f0ecb1e9cef04c0ea559c19458e15e6df69a728a49066337a0de65ca20c686adb2c64420957ed18fba754f31809d423cc550b377f5082003210d6cec6bbbd35573983ddc6d75d75966da2c916721772c26bf411bf3ce52a0380707bef667b088782295991ae10045f3bc2b8d950a43b2916107c1194340828beabb43e8127b65f5e03c2d0e45754f5f4107cb5eb7713d8b378383d6f1100cf2dad8d425cb2f5ab5533c0ff67baf685407b57e9c1432e0e9682ab7232e66834d2b73ce2eba90171738105b8b96d33a9808d84ae6c20b405894f4caf72e0072201b6a64e2a4832bf3fc8c51ccf430e0315222423844a3b0ac8f5e84ecef0570b5b3c40609a5bd494f15b33fedd54a99c0294f0a77c9a94dc9660354209ec6d2a9cf6a22d1928cac64b6f464983b95db274546f65a6dcf99161128ed2476b4b1931f5e3cfab531e30dbce833e699352469d1675928e7e2918f2b2a35c867f38979f317614280be093aea938302bfffddf064eeafdd597950bc0b76b4dcd2e166ebee5804ff7191e4d7d5ddc20574f301715f3266f682ba9daa20fe8f3e50ef79a44a591df59aaf8d6f1e02b604db7ba53e75ebafe219d98fba3a0f38d21dc1f37a8ec1645501c3bbe3ef9ea9cfd033c068c3fee9be97018530294fc632974f7db4cae38b9e1f84e4149648211051810b12250858ee177a4449510e0d3220279b3d1fd378f0d772ef18634f331c0fa58a95bda37c4aae0ad722c5a103cf72d17c669b8c88a3db1d6dfab1cb0ddce968c69b3b37aabc63e4bfcf7ff08020367adb8da515c9ee481b4472a79312285b7932b75478d19c1cf665b99c13dfae1f2969740bdc69af02caa46ccb85cabb79b42afba0f14e5b1d52314b9a2582f09dc301864adb95e1d4f49d6b1098181b4a9e27384dc6fbbaeaa9e8b6047e27b9cc1e07972953c2ad2f2de5cd37ad38198315775c78b1ebd688b1fe46d9e4e7acc48b0aa6160cfe130dbd6128dcbacf40a0a516786f454dd1b57e9b76a8127850e12de9a300a00a27c267fbfa1960c50713bf47f9db3a5bf30f60d8872ca09094067881cfb350604837ae23a8d29142d43712ca63cdf891776668d8a119a33e7cfe2f815134a49de8abcef82eb704674579353a952958d9e85bb190bacbae1ad30ab5057d3e38af171f81a98321a3d8269d5d2c1f06227c9dbec1f52e526a599fca9dde85e64c4ab595077e35c1cedac57c43a8793b9d02a1c68d0b52538533c50cc95bd69206596bee5f5f479d6191b0ef194b9db9ddec310d2ad9292127694a0b306d6e0dbda9c1325fe946d55d9843e9f0f00babcb0d30c2d208adcd9b266d365e850929efd278639bfc1f36f11677e60e24a219bc17627e3acbc07d5999f704259c6e38b539ce44536a07c94c6fe1af56bec24d558230a3522441563eded6fd45b4cde5b052e96670e34d7ad8370862caa396f691be932461f1f4424c5bb35c0726d316ec0f808edbaffbeae1b1dabf04cafbf532db67ec1afeb1507cf075277c06e1df2397e837f2170bfde1eb7d1d7904b685165115819b6f33a6191f0872e380dcce8806e1004e33c46795481242b2e174a038433b21485eae1cf905c6aadf4a25a7f6e82b8ae44c2b4f63e80a35f4f532e5188399249763a830cebbe0f5d15d9d370830b9942c5191b9ccfd65a3e8e2fc93a624ec3be4cb3da36accf375afe1246fc908eed8344dcbd2e01427109a1170eea5b27ea4d9270568b869cdc327d4cca866d41566bf6ed37640d1ea003b679a1f0ccec97c4f49e175867504303ef89184aacf4a4774fd2f2791963b76c4bf030df38f2c17cc31693e09cbe0de1ce8c16ccf3d0dba7f4c6e4fb82ef29a1670d771bbaa8744f1f68bbf467b47eaa4c89f08b65324826712488cab864770b4cceb2adcc34a7d5ecf6f32e198aab542061e2f91918754e9c26bbd956fba8e14f0459d3008b593fa9590087973a6135ebfaa43dfc3216ae945841dfe57362b890e4d0d009c945479ec5bbb5288a493dad5d65feb22b8d2c7e3791520797ec07dbca1b99cea09f3ee4bbb806f8471994060cfaa2b4805d60800ab204667ff262874b9f8caa4d223b31cec20a602df4b87fb46fd361462b4e830e89d67b916d8df5041ab6e8707081311e4a1b4c9a9645811a72f39609b820c8c9c855383fc2b886966c89783fe738611a10b5a35ff817b5e42bdd23b68212ddd90c3aaad54d3518ed4c129c0fa65f6e3f186c92c669639b00df166d8c75abbf8b89a72775e0c2804e0a93bcb40194acb7102cabdd003b4797a088ffe793129c77d2113029dddfd0ccd4288e00e15a5cefeaf11d0e94d5817bb7cab03dea4f2ca7b1787fdd45c2853f5bb0e7801a46b91b302407b5143891ca81ef7b62f7a6b885af144c2f10c81676bcb6a8bbb9b72bd0ec2ebd87fe8a7f68b13145410ab2d6a8c3484ee33cf52017f2e8b7729cb3e6efc492f4410576c8256cf42bfc3b9fb632f35ecfd52bdcbf27a9b4d30b213d74324484c06ca413365e8a4a7677b779a40317a626ed0e8971abe2fc3d1509787d9c4d2ae568cbda0cd613c8179ca75b4d3ed22c92fbca774395d71a9c19be2ee2505a82c59214242279f2275318b87518d92a30b887d870b5b29dc8304f10bce3b912a096845002b994fdd5e70058246228ce292e56bdd73c8345490cc5ca5870a5ea029a4ccf474014cf98dd6a2f61b4067bdc434b516ba29d7200a1fe3bec1ae1b45a56f27002c866a9590ee46fa0d62ba3469c856cb84ae30df007872c81aab26ed7656079190df33aa5f741fe4472a68e50b76cb68dfbaf6b9ebfa0725f239916e3e94e62f3dbc9646aa0602771e3937666132c040184092fde6b0fe5dc1511e4f87c914021fa6accfbd3c899c5eafe7c8cfda2f56b5dbf212d684aa6866cdd90d5a75ccc882d47a35ddba2957735eef941095609224f6eca04852432b9219a0257141aefb8fa6adee7ea7a42d4c7d3e46f33825551fee935f609ba68fcc45f11086293167fd39df9e8ce90481f242cf8769308e942c4bccc0a98b0f84a0699c27af638068d117901fa1b6cea331048d1c43c836d99ea57cd2726eda83a41f283b082e6043487c834c234be666e3b37f3cf6d33c8b39974e414315546e7d7e15a7b49eee6049a232f180b3485d69d629356f8f6193339abe34b984e288b86a5644f0d6096a2e79d1bad01bfcf6ead323c5177a93bcc466fb260d3f3549edce8199c6f2e4ef9b5f11df562f84a42770d479397683ed14c46111ca8197a7ee998f6a18b56cb360d2a152a3ab68577e5ec1afbdc5de316f11b05faa896f3aa707290ad6c40b173edb8bb73a43a359ad63e434c846730f039e76eafca8a2366bfaa564aad603ea250992b123d641c9af9cd86f25ab843ee63470434c0b5b4196007362deb845ec9be5d967c5e7b48687399caefa146d6fe8a6406bc61d69575b645c94504ea5ea4f006030ee52534f51d94cbf17271ec3c1cb72b8141f23f54455911616632c6b4e9f0d1ffb811a33c52e825a9f5b6bbf62f8a01918eec488dfd1f9dec0cc08151667882cf765607768d647547c3d26dd528d65a8885872cd1d147a78342fdb19c4f8d8e438355f35f0775f579c67c4f6a39486dffb979d7be8ef86ad9d83c3fe7523da6e19cbb282ae3b90a37ba25148e8d7871ac8a4d65bf05600d0c496580ce09e4344943d2a4c0f2b714b22ea7cc30602f8f06865769f028ba8f405f50641b6970b3841e6c09ce2fc2ffd1265b71662dd85ef1d3718b9d57d5c8b827a4deba0dc77a6ab78b029a5db7df0b38b22c307acb70c49005eea1c65ec6d2390c3c0473edbcad02401cd86c220668cee401ebe97f49e5c37d9a91390d99e4bff82cd8637e9c221f4f50cca83616968600d5eb2fbddb41e077ecdb02646f2ea49755cf9c8812e1426811262894163db421c55dd71eb702928cb148e65b721c3019aa1e3b8345ac2aa5f30edddd44c4ff9087473a0399b38bb049b103ab8f048e9a9ef1fd0496deab61b18e56d1995d691b294ab8c91368d558a8bae29914fdb07e9c6f2fcbf193469a4c4860afec287a7531d581e2cd19d3fc4dad9760d95b7ea962d983f47478dcc68581944a4983fb85c0d7f0e2c2da9ba0534bbe7db16dd83ef96a854282c3c99ab548fc4f41fc1adaa6fa45d9d1f93af8ba57ff0ac71b9b2f28a9855f7b6f578e956ee7747a9db35eb062e3c439d2bea5a610cd4637dc4afa71c633ce9f4de8e72f5b17e5608e9f17c84178f34dcf3be8a0eee60f1c338806ab0853fc595b33f34a19fa93cb99a1e6ebfa189d3a60317194763fc95bfdace534a1685438dd0d42425e0d8777752df9b7e9be2c0aa9758bce90eef26b0e9ec5b6e47141ec3c322845fce3caaf0353a0d28849e05b4b7e542a577f0c16ee1671579599aa0942174a2b098c1a133f516394a2fabea08a1f1301f0614795556d001b22423676a6e493bcca06d1bf76fd52d39558a4e60fea5406b85800c898849b88f0f6ea0417c71ee76028d05e69994301c2ebb7c49fcc1fed18ff368d5588f7ac4c15dfabda158b6b3a29ac774c3da34115811d99b20297cfa8a04fc10f0ca81099b1f4594c34063d41ce6a46ae1adfd0a8fb8e5b015f0273c565cbf91bda224bbcbed5145a3cc8f60d7453f7bfc62f664f9d6c5860c6e798605c476370842c931ae2189dbeb479ef242bc5a6f509cbbfa286eb2fb8902cf82727d837d6c2b3db07e65003e4a7d28cdf447af1205da82db24f7ecb276bdcc31bbcf59f672a0231f7d236bfa8fdb5304a843fd6c15503e96c03c7ca0ef68653cbf049524e53ca33c9f350fb4ca3f15da6af166dedcda650cc997546b52d7bf7df8541f692c38bac1f2b1477d2e0bf7aaf96e2f34db199d3e90c3d3f03de2f97a5807f6f661c589b7c566f31116dae57494c8485799e43267344abddf711ef1eed113a7d3075a2122231c0bf9fca3b5cd1c474c4d306b3abaf9bdd523399f8a3f3c8b3b599e2fbf997638c32400b0c4a290be4d2b8aa01578fe4eed3e0e5a9b779dd2e29157d078229d7c4b3759b2ac930b344ac34079176ce214794be686637e961052725138bc5f67641f4eb4b0035eacba121d0095adf0dbcc30dc60245ce89ced691c80b997710e3fd4d0db1829c7eb01db4c8b16a200ac2985002a89252c123eb1096255e761595b8de4e09c6ea4896551b0c80dbcb8b6555b90ce118b09b9bd132dc2ac3d98d728541b2debd3ef38708841c31d0216a8670a33d0181804da679111b7c299c1c7ce1a29b34422b20bf1b158b42a3eb81b142f2990ac539e03d3ceba2d5b56483b556859e843ea1b14df003df9d8e69b1db534018964dbc3406b3cbc9c7bb82dc0e1e0ad3623cc181ce650cdda755b8bc0752cc7011cb6bbc8b5f6694ed71dcb87a726295e56db853b1e180f00430c05ff58950f85c44fc524620386b4b7cb7c065a2e26616771ee3b31d47c8799d20284b843b2d1f2e08d83b0bccec703c318133be06e328dee79751f650015b24fe286c18c5ba237f4057e5694ce2cbb6c8a477d1cb3c777d861128f83edfd819941c16700edc8d158a49036fb8c983b6c00158f3de95867c71572610be0f476e9425655a1abdf9930f006ee18c1b23a6efbe3d83f972e190b7bbe64ec682dcb0a3754579f703159d65b25f69bb49e64c1c64621a8ebdf6b8a2c863bbab2c14b540d42754e62fd50ac5cd340eaa33b399401b9b074ac929a86cffc3ce9c93c24a1d17cd151d136f4edfa27cb83edce43b649eee7a70031786e612316ca7b5a2dffbb4bf422d1958c8615f2652497795b24bafe97025ffd4d1aa6a6c31d451af45a53130835113b357868cbe910d872728e46927ad7aba333aba9413105a39f0d5b04f3a29c16085b25bafa35825b805233d531a42b035a83a0ee2c25eedf369d44a55e1404ecc5a71da1eb03589e35c6f9dd8bdb30f55cbd0a94eb671fcfad17e422b77db58a37fbbb1f10a50f59a206eb3009ab5cfe5eac0f0a15b9ed3e28f7ef7686867e88d65eb9115e1b1c0d886ff40c9f54962337fb54ba0ae9b2c2b8ec66b58d5e23e3147b4733bb2b3695c257785917e44de19e035eef29bae78553bb31f1356b93e528b1ab7cbf2cc99fc4a05a96b15fc02746f3d17e4cecf5c1c75cdea9fbed52f1978264b5215a281800d8f0e3146fef829fa54ffd1e9cfbe1695f9e8f31e6e8027bdc40416d804c15155ca012c1569e89adf77e148e732b83ecfdd3ef67b96fe8b6d666d32026a6b6cb086347d97a1f6fd14fe17d0aee5a46691135f77310b87eeafc4ce10cd7f0f28d5278cc13d51da06c0abf02ddc7144dc43f4c371cf7a4fcd5bc301e0aa350887fc122968f411adbc3b542b0d5ca999e38d8a3a5fe526de29f505c9b9de9eb8e205e91222f61178204015bb6fc707e09a38d10114b0caa308d42d21ea1234b2cd3f9b4bbf7780df0a9de4f79b2ec941d6771622d2acf452708b34ff7b50ce0aad2c0d42f6307fcbc1ed1d9252510b50fa72e38006d7e70b6c0bac907c3e9ec76c9805b4ee3d8bf896c4f7bb505b3b59f2e1fa4644fbd9f29cee51d95edccab4a0aad90053d2b3ce9252d54dfab1ad8ca1013fef9a7fabee7c6725152500fca5f97f53a18ca31725848f6557b1011176ddddfba01398ac8986a2f84c13741970018ad3065e5227f99a4860c64a3ecc4a167e04e4bdd0912e5ddebe325aa38d639697d8a5b1f846ed3c2c939224050b4cf50e7b14575264b2132579678c4a5db4fec5bd29ac58ff3657c3d941b68167199a56828b2845cf1bbabdff31ea10e2393690d131a49c8023adb27462281ca368447ad495123ce6a1de9fabcb4d6d26b3e6212fc3dd4385e4c1e6ffc4ece960c54184c290440603424e15de45d80b1fc8cd8a6417d3ce52a6422a81570103519e9c9d15fb8965af7f418c59c2c82ded67356d05d6806efbb994d051bb50542df493f655cf99b28c6b175f7ee40a1a2036f942f8dd1be7df6556d96ed626444fd5a8a2e1f2a3025fada58d6630b151d05f1d6d68af64cc5fc83183f00dd77b7738599f3e23fe4e0ffbaea0b762b85220d92c44fd155fb20384ea74e2a5017406212520bd5723bbe4e82223761a82f00ee7857bb384b65d934e391ab5a558838acef7d024f85c5789cb840676ee9c3eb95d87c6243f56b1b54d36080a4f7c8ff205a4b68ddbfd5eade96d2ea0ce7e895e0c5a733d6f97c4b956fdd02774697e59c67664c9884fcf54f5c47adbf19b83d6ac50c64bb3dcdaf5712e2fce253b3cd93b441946b77a748d77e523bb3cf8e8084a7a7dcd3ea8ae746d22276529290b3e4f3957f8d454258b685836dc90a335047ec0b9403aa567b8738b0edce38592ca3ba2314aa278b108c6daf4e4a3cda50b34b83e3993fc4426ad4a98c9d974f3aedd2ac614e77d482a72e36fd19b6766306074f99f4f9283d3624bfa6543b68b4418a66c4fa105ead01eee69fe437e70b07c85a834d2dfbfeffcb6a9ca3f1048bd8aab653ecaef6454836f0d9aa1472b166772190393ee1f11b5cd2e32b0a9aacf28df70a5932673e5e3838a42f946a125b0a9eb0ac21c8742ec6ae71f5a04866aa49e53ebc392c3624232811f8fe2a5a98fc536504697c5cd67c05fe289d5e190c92f3b58e1fb47d7c6a5ba1dfd558abc0684f99b3b27bfb3a3e7d2e1afdc739c4152da759557eaee599d0666c3b63893bfeda3a08a21d86036df42f79bb2a933547766c3c2367cb720fae321824aeb7d005fecb7112ad828fdf98a83a69b1422370dbbe6be7b22dc95d892981652d78bfacf45121f0ec621e19fb86da0c3b66543ff90504705e10b6bd74dab2fe80c39b165531b36b48ec705bc45606d324000d25bae29dda47726a6a78dc0d710c7d203b61463670bd7c0dcdd294f66444540114a0a29c8fb7c9e4208a6725973a817f1bdbfb148de7f53311b930f28caffcbde2cdb75cfd2a9710e26d67d96854caf73ae8e8380e9b90b2a322a20fc85865f07b0bee7d2b82fc996f32242c246b18e093e77662e8da6a895f82d093d095308b9e6e051e55eaa0588e8eeaf45ceb778bb277a8e11457c0db1893e18542b1d15f0ce23c9877907abe9ddde0a70e24b32e4552c83c7fff6f0b59e278be3a950d98085856f1006d6c23a38461d6590ccee05ff9b9b6f18d2df2c7c55722f55a641e16ee6ebf4871ea11a7c24ea7a134ef2cbd5557bdcdd63ea50715d0d68aa97a19c2b71f2a80fe05f3458ccb5369943ddd687fcfae04a763e4ed7b6d56c1e063836da23ad8173cf4ce574b39a7ca4751d7c901c38868ec26a262707a9d3242ffa4d9386c0bc6b09b558fa7b51d3bda5567f15260164ffa16dc050597ce598e9e140cb03d3f606e047375e0868ff8fb67eb2c665c9457f95c4934ab447c514350f4f44c96f42533120457add4ada3b97193934f69c47ac30a37fdf5ff3bf8a4eb3f0afe5e99638aef7a09f83619bed9875983eea7fa0da8625720ada1b9952c8b6b8f41fac39ba68d06f5747477395a52acade2c29dd301cc45808d6e3910174975453f35a36d680a1b0f10b791ec5a5d3ce04fa5b973b9ea5dbec3318b8448bcabadc6ccfac828c14567da2f0831858c91d48be36fea832eb5378048f061f7dc0f9048f49f76805764ac576fad886e77bb477fc1e549136c63be919cc2127d0e56d6b1a87f43e79091cc25c96ea2d433aef33dff5b28ac32352f17005ec0d9d6dc439865f128a640a1f5a04bed9bc6e20148cd5af47bd8424516678e024fcd44aa467db565bb28b492305240d1a918bc4b399f7442c609d011e4369629e35fc292b36b072da44cad58698f3364dcd0c9d23c09f379876b46d79fc1d3426cd4db8cb14184743f5f57d885faaa85adf50ff9b9938ace3d2416427bb9b5b8b6d6ee23829ccd047a157829a81123fc2417b963cbbc9ee29307803563dbf32692a99eba79b010d7f34b914f06d121b54ee73036f164b20e49c54415b2a35dcdeea63e5ec3203bbd9309371cfd252d071736be0ba3208efdd3b36418085ad3f0f99cbd42fd696e6e0e6ea68b6bcc3b4eebcebc4b9fcc059dc431e21f960026f3b8c89fd0573c515ed581a2e8c8d92b5f7562c17c915e1e642137b1b82f3398e98b169aa5a7f1e6e9199cde1b6b864428444bd8de7948abbcd22216068f7e73402aa63df8ef41fa4c8a6945520cc7601b2e5f985fc51328c017874b3128c43fa12a1ee48cbc3c9388f253daddf8fab650fb77a52b8ee10fa2fcbc2a24b2a4cead2a39c619f84c97f0a76a68edfe20f175a73d13db2c0e5a50a9c81a70b81c93bdf6550f342a0485ee8b93f23734f01c6ac123dcc6059bfeaba80c1ed545c9ae305c849db367d7578ed937182d74b15ede9e2dd8fe6fc09e21ddf5b80a87516fefe77d09c1287abffdc42a2dcba6988fc1edba72bcbd6dcc2f0a07f7b8d9b4cf915ab6840a131e707ac150ee8071c9a25d2ac8a7ba8a105816aca8a96ebabdb2316ac4dbe60d06761574a9feebc95ddb52f6b9ce961682cf17ed009f457b9653b91492d29aea0444c86594564171d1d092b06a673c88be64c2a950936c1979b8722e84b712178b10ee26822b0b98b10efb45598e68a5c96297d3e82dbf47169a80c7a30f06b546f3bbda2a7d486acf3be3c17b1e7fd8d3e6c4ee8d8dcafa2df329408261a3ff225e45219c4c5cbc904793d400263f20b7319560ad99bf0bd11a1bde15635f434990a4f0b49352a55cf3ec422d32d1d31631d53af95ab19e042d802b6f1b405733c780fef2307c1445ec100acdb3a0ebcb17814b27bd008f9c419baf160e97b8048920ae2b3d268ec5a45292dbae96f51bdd1e9d410242d6b21873db45b5863b947fd851ca3f3a80ef403582c4af40a69b6dc5bf92116ee66b6ec7ec777b753dbaf68a82a36ec82e638657881a45b12db5ff7ef8f12ef234b5ca04ca0a69a27f9d87c66dd8472cc84970666a0d3c6dd5de057bfd04c55dac25476299633fa7cd9c09d2e082d150d6d8831f0f563f62adb284472888cf9b5694b98f921f594eaa8bd0d0a6b0038460150f1d7c358ee1e338df2400f57cd4acd1f8410977e723df73387bffd25bca15366cf68ed6ed88b76a02984dd90adfe8ef07e5e1926d23a253679279e9e52762437112ce48954c0cf9f058d7f0149adda80be9e21661473969c9d7a161d4312dc693c22aca5a2d9dc7a90b14a36d5ea772cc401a7335a5ad08c103f99e0578d4eb5619148ed10bc55ef429e82bf224df1dbae5251bcc8fd7337427fc6338187cd90a74b0458d6f974cd1168e0bba6c7e426aa2338f56a5c05eb71d63e0f6f0428356241b8c066a131b0a51404f502bc31607b4e58b0f7b438e83ba7026c9ab9f4396465a476eaedb490dd55fa5e4180101623146a681683523af70fa7379be7a4046f7ff509b64caec504bc64f9a3d85584ad81f5ba4238f95874addb4d41491d6eda2df4ba9d1665f4935c3b5a79f5664116467530dc759d43772e2fc44091771190608e72934d7206dd8f58a7e00bb0e9186469ae6be88bc0d6fc5140c0ac594806b51b75ea6c4586740579a0d4b294f498e4aedd8852140dc7e7b745cf30d263ae2daeeb493489da259b5ce2e286c8d557ddb70179e826a19d2f7579eac562a4728a188f57d0e11a070e99b843c208dbec3e7f7f5d9d477a803982dc45d37a567548319afef6fec04211599b71d893502cd9a04aa35648baacb43caa3ca6b66de903d555509cd06e1fa28defe07445aeeb6dec5c64b016a7a9db2578b4100a24f2d7ad0175a9199c05d039686a26c7f7d7683fd487ab202d5c16c7d9262cfa39c1d5bd49485431dcdc9f26e058ff90a4319ea0a6b49420e9a3be5be5ec559d2b04ca4da1e1e4b7840a400c259973a7dabed675e5dfbd7eaaffb88ee0896a2122e2450612849d7d091e1ea6b98fade14d45707083c67599d0196912f14f 您好, 这里需要密码.

2022/3/24
articleCard.readMore

emoji表情符号

emoji表情符号是非常流行的表情符号,几乎没有地方都会支持。这里列举出常用的emoji表情不好,方便大家使用与查阅。 常用符号 ❤❥웃유♋☮✌☏☢☠✔☑♚▲♪✈✞÷↑↓◆◇⊙■□△▽¿─│♥❣♂♀☿Ⓐ✍✉☣☤✘☒♛▼♫⌘☪≈←→◈◎☉★☆⊿※¡━┃♡ღ ツ ☼☁❅♒✎©®™Σ✪✯☭➳ 卐 √↖↗●◐Θ◤◥︻〖〗┄┆℃℉°✿ϟ☃☂✄¢€£∞✫★½✡×↙↘○◑⊕◣◢︼【】┅┇☽☾✚〓 ▂▃▄▅▆▇█▉▊▋▌▍▎▏↔↕☽☾ の•▸◂▴▾┈┊①②③④⑤⑥⑦⑧⑨⑩ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ ㍿ ▓♨♛❖♓☪✙ ┉┋☹☺☻ت ヅツッシ Üϡﭢ™℠℗©®♥❤❥❣❦❧♡۵웃유ღ♋♂♀☿☼☀☁☂☄☾☽❄☃☈⊙☉℃℉❅✺ϟ☇♤♧♡♢♠♣ ♥♦☜☞☝✍☚☛☟✌✽✾✿❁❃❋❀⚘☑✓✔√☐☒✗✘ ㄨ ✕✖✖⋆✢✣✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴✵✶✷✸✹✺✻✼❄❅❆❇❈❉❊†☨✞✝☥☦☓☩☯☧☬ ☸✡♁✙♆。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ |‖"〃`@﹫¡¿﹏﹋﹌︴々﹟# ﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄ ¯―﹨ˆ˜﹍﹎+=<_*-\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽*﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼☩☨☦✞✛✜✝✙✠✚†‡◉○◌◍◎●◐◑◒◓◔◕◖◗❂☢⊗⊙◘◙◍⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌ ≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱㊣㊎㊍㊌㊋㊏㊐㊊㊚㊛㊤㊥ ㊦㊧㊨㊒㊞㊑㊒㊓㊔㊕㊖㊗㊘㊜㊝㊟㊠㊡㊢㊩㊪㊫㊬㊭㊮㊯㊰㊙ ㉿ 囍 ♔♕♖♗♘♙♚♛♜♝♞♟ℂℍℕℙℚℝℤℬℰℯℱℊℋℎℐℒℓℳℴ℘ℛℭ℮ℌℑℜℨ♪♫♩♬♭♮♯°øⒶ☮✌☪✡☭✯ 卐 ✐✎✏ ✑✒✍✉✁✂✃✄✆✉☎☏➟➡➢➣➤➥➦➧➨➚➘➙➛➜➝➞➸♐➲➳⏎➴➵➶➷➸➹➺➻➼➽←↑→↓↔↕↖↗↘↙↚↛↜↝ ↞↟↠↡↢↣↤↥↦↧↨➫➬➩➪➭➮➯➱↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕ ⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡ ⓢⓣⓤⓥⓦⓧⓨⓩ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⅠⅡⅢⅣⅤ ⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫ ┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽ ┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏ ═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬◤◥◄►▶◀◣◢▲ ▼◥▸◂▴▾△▽▷◁⊿▻◅▵▿▹◃❏❐❑❒▀▁▂▃▄▅▆▇▉▊▋█▌▍▎▏▐░▒▓▔▕■□▢▣▤▥▦▧ ▨▩▪▫▬▭▮▯ ㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲ ㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍘ ☰☲☱☴☵☶☳☷☯ 特殊符号 ♠♣♧♡♥❤❥❣♂♀✲☀☼☾☽◐◑☺☻☎☏✿❀№↑↓←→√×÷★℃℉°◆◇⊙■□△▽¿½☯✡ ㍿卍卐 ♂♀✚〓㎡♪♫♩♬ ㊚㊛囍㊒㊖ Φ♀♂‖KaTeX parse error: Expected ‘EOF’, got ‘&’ at position 3: @*&̲#※卍卐 Ψ♫♬♭♩♪♯♮⌒¶∮… 编号序号 ①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⓪ ❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴ ㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇ ⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛ ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ 数学符号 ﹢﹣×÷±/=≌∽≦≧≒ ﹤﹥ ≈≡≠=≤≥<>≮≯∷∶∫∮∝∞∧∨∑∏∪∩∈∵∴⊥∥∠⌒⊙√∟⊿㏒㏑% ‰⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟ ≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱øØπ 爱心符号 ♥❣ღ♠♡♤❤❥ 标点符号 。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ |‖"〃`@﹫¡¿﹏﹋﹌︴ 々﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄ ¯―﹨ˆ˜﹍﹎+=<_*-\ˇ~﹉﹊ ()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】 ︵︷︿︹︽*﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼❝❞ 单位符号 °′″$¥〒¢£%@℃℉ ﹩﹪‰﹫㎡㏕㎜㎝㎞㏎m³㎎㎏㏄º○¤%$º¹²³ 货币符号 €£Ұ₴$₰¢₤¥₳₲₪₵ 元 ₣₱฿¤₡₮₭₩ރ 円 ₢₥₫₦zł﷼₠₧₯₨Kčर₹ƒ₸ ¢ 箭头符号(含推导&转换符号) ↑↓←→↖↗↘↙↔↕➻➼➽➸➳➺➻➴➵➶➷➹▶►▷◁◀◄« »➩➪➫➬➭➮➯➱⏎➲➾➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨ ↚↛↜↝↞↟↠↠↡↢↣↤↤↥↦↧↨⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇖⇗⇘⇙ ⇜↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹☇☈↼↽↾↿⇀⇁⇂⇃⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪↺↻⇚⇛♐ 符号图案 ✐✎✏✑✒✍✉✁✂✃✄✆✉☎☏☑✓✔√☐☒✗✘ ㄨ ✕✖✖☢☠☣✈★☆✡ 囍㍿ ☯☰☲☱☴☵☶☳☷ ☜☞☝✍☚☛☟✌♤♧♡♢♠♣♥♦☀☁☂❄☃♨웃유❖☽☾☪✿♂♀✪✯☭➳ 卍卐 √×■◆●○◐◑✙☺☻ ❀⚘♔♕♖♗♘♙♚♛♜♝♞♟♧♡♂♀♠♣♥❤☜☞☎☏⊙◎☺☻☼▧▨♨◐◑↔↕▪▒◊◦▣▤▥▦▩◘◈◇ ♬♪♩♭♪ の ★☆→ あぃ£ Ю〓§♤♥▶¤✲❈✿✲❈➹☀☂☁【】┱┲❣✚✪✣✤✥✦❉❥❦❧❃❂❁❀✄☪☣☢☠☭ღ▶▷◀◁ ☀☁☂☃☄★☆☇☈⊙☊☋☌☍ⓛⓞⓥⓔ╬『』∴☀♫♬♩♭♪☆∷﹌の ★◎▶☺☻►◄▧▨♨◐◑↔↕↘▀▄█▌ ◦☼♪ の ☆→♧ ぃ£ ❤▒▬♦◊◦♠♣▣۰•❤•۰►◄▧▨♨◐◑↔↕▪▫☼♦⊙●○①⊕◎Θ⊙¤ ㊣ ★☆♀◆◇◣◢◥▲▼△▽⊿◤◥ ✐✌✍✡✓✔✕✖♂♀♥♡☜☞☎☏⊙◎☺☻►◄▧▨♨◐◑↔↕♥♡▪▫☼♦▀▄█▌▐░▒▬♦◊◘◙◦☼♠♣▣▤▥▦▩◘◙◈ ♫♬♪♩♭♪✄☪☣☢☠♯♩♪♫♬♭♮☎☏☪♈ºº₪¤큐«»™♂✿♥   ◕‿-。 。◕‿◕。 希腊字母 ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ αβγδεζνξοπρσηθικλμτυφχψω 俄语字母 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвг деёжзийклмнопрстуфхцчшщъыьэюя 汉语拼音 āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜüêɑńňɡ ㄅㄆㄇㄈㄉ ㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞ ㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ 中文字符 零壹贰叁肆伍陆柒捌玖拾佰仟万亿吉太拍艾分厘毫微 卍卐卄巜弍弎弐朤氺曱甴囍兀々〆のぁ〡〢〣〤〥〦〧〨〩 ㊎㊍㊌㊋㊏㊚㊛㊐㊊㊣㊤㊥㊦㊧㊨㊒㊫㊑㊓㊔㊕㊖㊗㊘㊜㊝㊞㊟㊠㊡㊢㊩㊪㊬㊭㊮㊯㊰ ㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉ 日文符号 ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてで とどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎ わゐゑをんゔゕゖァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタ ダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユ ョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ゠ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ 制表符号 ─ ━│┃╌╍╎╏┄ ┅┆┇┈ ┉┊┋┌┍┎┏┐┑┒┓└ ┕┖┗ ┘┙┚┛├┝┞┟┠┡┢┣ ┤┥┦┧┨┩┪┫┬ ┭ ┮ ┯ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻┼ ┽ ┾ ┿ ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╪ ╫ ╬═║╒╓╔ ╕╖╗╘╙╚ ╛╜╝╞╟╠ ╡╢╣ ╤ ╥ ╦ ╧ ╨ ╩ ╳╔ ╗╝╚ ╬ ═ ╓ ╩ ┠ ┨┯ ┷┏ ┓┗ ┛┳ ⊥ ﹃ ﹄┌ ╮ ╭ ╯╰ 皇冠符号 ♚   ♛   ♝   ♞   ♜   ♟   ♔   ♕   ♗   ♘   ♖   ♟ 彩色表情符号 🌹🍀🍎💰📱🌙🍁🍂🍃🌷💎🔪🔫🏀⚽⚡👄👍🔥 常用 emoji 符号 😀😁😂😃😄😅😆😉😊😋😎😍😘😗😙😚☺😇😐😑😶😏😣😥😮😯😪😫😴😌😛😜😝😒😓😔😕😲😷😖😞😟😤😢😭😦😧😨😬😰😱😳😵😡😠😈👿👹👺💀👻👽👦👧👨👩👴👵👶👱👮👲👳👷👸💂🎅👰👼💆💇🙍🙎🙅🙆💁🙋🙇🙌🙏👤👥🚶🏃👯💃👫👬👭💏💑👪💪👈👉☝👆👇✌✋👌👍👎✊👊👋👏👐✍👣👀👂👃👅👄💋👓👔👕👖👗👘👙👚👛👜👝🎒💼👞👟👠👡👢👑👒🎩🎓💄💅💍🌂🙈🙉🙊🐵🐒🐶🐕🐩🐺🐱😺😸😹😻😼😽🙀😿😾🐈🐯🐅🐆🐴🐎🐮🐂🐃🐄🐷🐖🐗🐽🐏🐑🐐🐪🐫🐘🐭🐁🐀🐹🐰🐇🐻🐨🐼🐾🐔🐓🐣🐤🐥🐦🐧🐸🐊🐢🐍🐲🐉🐳🐋🐬🐟🐠🐡🐙🐚🐌🐛🐜🐝🐞🦋💐🌸💮🌹🌺🌻🌼🌷🌱🌲🌳🌴🌵🌾🌿🍀🍁🍂🍃🌍🌎🌏🌐🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜☀🌝🌞⭐🌟🌠☁⛅☔⚡❄🔥💧🌊💩🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍅🍆🌽🍄🌰🍞🍖🍗🍔🍟🍕🍳🍲🍱🍘🍙🍚🍛🍜🍝🍠🍢🍣🍤🍥🍡🍦🍧🍨🍩🍪🎂🍰🍫🍬🍭🍮🍯🍼☕🍵🍶🍷🍸🍹🍺🍻🍴🎪🎭🎨🎰🚣🛀🎫🏆⚽⚾🏀🏈🏉🎾🎱🎳⛳🎣🎽🎿🏂🏄🏇🏊🚴🚵🎯🎮🎲🎷🎸🎺🎻🎬👾🌋🗻🏠🏡🏢🏣🏤🏥🏦🏨🏩🏪🏫🏬🏭🏯🏰💒🗼🗽⛪⛲🌁🌃🌆🌇🌉🌌🎠🎡🎢🚂🚃🚄🚅🚆🚇🚈🚉🚊🚝🚞🚋🚌🚍🚎🚏🚐🚑🚒🚓🚔🚕🚖🚗🚘🚚🚛🚜🚲⛽🚨🚥🚦🚧⚓⛵🚤🚢✈💺🚁🚟🚠🚡🚀🎑🗿🛂🛃🛄🛅💌💎🔪💈🚪🚽🚿🛁⌛⏳⌚⏰🎈🎉🎊🎎🎏🎐🎀🎁📯📻📱📲☎📞📟📠🔋🔌💻💽💾💿📀🎥📺📷📹📼🔍🔎🔬🔭📡💡🔦🏮📔📕📖📗📘📙📚📓📃📜📄📰📑🔖💰💴💵💶💷💸💳✉📧📨📩📤📥📦📫📪📬📭📮✏✒📝📁📂📅📆📇📈📉📊📋📌📍📎📏📐✂🔒🔓🔏🔐🔑🔨🔫🔧🔩🔗💉💊🚬🔮🚩🎌💦💨💣☠♠♥♦♣🀄🎴🔇🔈🔉🔊📢📣💤💢💬💭♨🌀🔔🔕✡✝🔯📛🔰🔱⭕✅☑✔✖❌❎➕➖➗➰➿〽✳✴❇‼⁉❓❔❕❗©®™🎦🔅🔆💯🔠🔡🔢🔣🔤🅰🆎🅱🆑🆒🆓ℹ🆔Ⓜ🆕🆖🅾🆗🅿🆘🆙🆚🈁🈂🈷🈶🈯 🉐 🈹🈚🈲 🉑 🈸🈴🈳 ㊗㊙ 🈺🈵▪▫◻◼◽◾⬛⬜🔶🔷🔸🔹🔺🔻💠🔲🔳⚪⚫🔴🔵♈♉♊♋♌♍♎♏♐♑♒♓⛎💘❤💓💔💕💖💗💙💚💛💜💝💞💟❣🌿🚧💒☎📟💽⬆↗➡↘⬇↙⬅↖↕↔↩↪⤴⤵🔃🔄🔙🔚🔛🔜🔝🔀🔁🔂▶⏩◀⏪🔼⏫🔽⏬📱📶📳📴♻🏧🚮🚰♿🚹🚺🚻🚼🚾⚠🚸⛔🚫🚳🚭🚯🚱🚷🔞

2022/3/23
articleCard.readMore

winrar去广告和破解

WinRAR 是一款不错的解压缩软件,但还是收费软件,广告不少,今天就总结了一下网上的各路教程。 crack winrar 首先通过特殊方式获取软件许可: 在这个文本文档里输入内容: RAR registration data``Federal Agency ``for` `Education``1000000 PC usage license``UID=b621cca9a84bc5deffbf``6412612250ffbf533df6db2dfe8ccc3aae5362c06d54762105357d``5e3b1489e751c76bf6e0640001014be50a52303fed29664b074145``7e567d04159ad8defc3fb6edf32831fd1966f72c21c0c53c02fbbb``2f91cfca671d9c482b11b8ac3281cb21378e85606494da349941fa``e9ee328f12dc73e90b6356b921fbfb8522d6562a6a4b97e8ef6c9f``fb866be1e3826b5aa126a4d2bfe9336ad63003fc0e71c307fc2c60``64416495d4c55a0cc82d402110498da970812063934815d81470829275 然后将文件名改为:rarreg.key 再将这个文件导入WinRAR的安装文件夹 去除广告 接下来使用Resource Hacker软件打开winrar.exe 进入字串表,找到“80”,删除“1267”和“1277”行 然后:文件→另存为,进行保存。 然后对源文件:winrar.exe进行替换,注意,要关闭winrar软件 至此,已经完成破解和去广告了。 参考来源 52pojie

2022/3/19
articleCard.readMore

使用 Shell 脚本实现一个简单 Docker

《使用 Shell 脚本实现 Docker》旨在通过一系列的实验使用户对docker的底层技术,如Namespace、CGroups、rootfs、联合加载等有一个感性的认识。在此过程中,我们还将通过Shell脚本一步一步地实现一个简易的docker,以期使读者在使用docker的过程中知其然知其所以然。 我们的实验环境为Ubuntu 18.04 64bit,简易docker工程的名字为 docker.sh,该工程仓库地址如下: https://github.com/pandengyang/docker.sh.git https://github.com/appotry/docker.sh 《使用 Shell 脚本实现 Docker》目录如下: 1. Namespace 1.1. Namespace简介 1.2. uts namespace 1.2.1. uts namespace简介 1.2.2. docker.sh 1.3. mount namespace 1.3.1. /etc/mtab、/proc/self/mounts 1.3.2. /proc/self/mountinfo 1.3.3. bind mount 1.3.4. mount namespace简介 1.3.5. docker.sh 1.4. pid namespace 1.4.1. unshare的--fork选项 1.4.2. pid namespace简介 1.4.3. pid嵌套 1.4.4. docker.sh 2. CGroups 2.1. CGroups简介 2.2. 限制内存 2.2.1. 用CGroups限制内存 2.2.2. docker.sh 3. 切换根文件系统 3.1. 根文件系统 3.2. pivot_root 3.3. docker.sh 4. 联合加载 4.1. 联合加载简介 4.2. AUFS 4.3. docker.sh 5. 卷 5.1. 卷简介 5.2. docker.sh 6. 后记 Namespace Namespace简介 传统上,在Linux中,许多资源是全局管理的。例如,系统中的所有进程按照惯例是通过PID标识的,这意味着内核必须管理一个全局的PID列表。而且,所有调用者通过uname系统调用返回的系统相关信息都是相同的。用户id的管理方式类似,即各个用户是通过一个全局唯一的UID标识。 Namespace是Linux用来隔离上述全局资源的一种方式。把一个或多个进程加入到同一个namespace中后,这些进程只会看到该namespace中的资源。namespace是后来加入到Linux中的,为了兼容之前的全局资源管理方式,Linux为每一种资源准备了一个全局的namespace。Linux中的每一个进程都默认加入了这些全局namespace。 Linux中的每个进程都有一个/proc/[pid]/ns/目录,里面包含了该进程所属的namespace信息。我们查看一下当前Shell的/proc/[pid]/ns目录,命令及结果如下: phl@kernelnewbies:~$ sudo ls -l /proc/$$/ns total 0 lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 cgroup -> cgroup:[4026531835] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 ipc -> ipc:[4026531839] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 mnt -> mnt:[4026531840] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 net -> net:[4026531993] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 pid -> pid:[4026531836] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 pid_for_children -> pid:[4026531836] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 user -> user:[4026531837] lrwxrwxrwx 1 phl phl 0 Jan 22 08:43 uts -> uts:[4026531838] 该目录下有很多符号链接,每个符号链接代表一个该进程所属的namespace。用readlink读取这些符号链接可以查看进程所属的namespace id。我们读一下当前Shell所属的uts namespace id,命令及结果如下: phl@kernelnewbies:~$ sudo readlink /proc/$$/ns/uts uts:[4026531838] 后文中我们将介绍uts namespace、mount namespace、pid namespace的用法。 uts namespace uts namespace简介 uts namespace用于隔离系统的主机名等信息,我们将通过实验学习其用法。在实验过程中,我们采用如下的步骤: 查看全局uts namespace信息 新建一个uts namespace,查看其信息并作出修改 查看全局uts namespace,查看其是否被新建的uts namespace影响到 对于其他namespace,我们也采取类似的步骤进行实验学习。 首先,我们查看一下全局的hostname及uts namespace id。命令及结果如下: phl@kernelnewbies:~$ hostname kernelnewbies phl@kernelnewbies:~$ sudo readlink /proc/$$/ns/uts uts:[4026531838] 然后,我们创建一个新的uts namespace,并查看其namespce id。 在继续之前,需要介绍一个namespace工具unshare。利用unshare我们可以新建一个的namespace,并在新namespace中执行一条命令。unshare执行时需要root权限。unshare的使用方法如下: unshare [options] [program [arguments]] 执行unshare时,我们可以指定要新建的namespace的类型以及要执行的命令。unshare提供了一系列选项,当指定某个选项时可新建指定的namespace。namespace类型选项如下: –uts创建新的uts namespace –mount创建新的mount namespace –pid创建新的pid namespace –user创建新的user namespace 介绍完unshare之后,我们继续之前的实验。我们用unshare创建一个新的uts namespace,并在新的uts namespace中执行/bin/bash命令,命令及结果如下: phl@kernelnewbies:~$ sudo unshare --uts /bin/bash root@kernelnewbies:~# 我们用unshare创建了一个新的uts namespace。在新的uts namespace中查看其hostname和namespace id,命令及结果如下: root@kernelnewbies:~$ hostname kernelnewbies root@kernelnewbies:~# readlink /proc/$$/ns/uts uts:[4026532177] 从结果我们可以看到,新uts namespace的id与全局uts namespace的id不一致。这说明/bin/bash已运行在一个新的uts namespace中了。 我们将新uts namespace的hostname改为dreamland,并强制更新Shell提示符。命令及结果如下: root@kernelnewbies:~# hostname dreamland root@kernelnewbies:~# hostname dreamland root@kernelnewbies:~# exec /bin/bash root@dreamland:~# 从结果我们可以看到,新uts namespace的hostname的确是被修改了,exec /bin/bash用于强制更新Shell的提示符。 我们重新打开一个Shell窗口,该Shell位于全局uts namespace中。在新的Shell窗口中查看全局uts namespace id及hostname,命令及结果如下: phl@kernelnewbies:~$ hostname kernelnewbies phl@kernelnewbies:~$ sudo readlink /proc/$$/ns/uts uts:[4026531838] 从结果我们可以看到,我们在新uts namespace中所作的修改并未影响到全局的uts namespace。 父进程创建子进程时只有提供创建新namespace的标志,才可创建新的namespace,并使子进程处于新的namespace中。默认情况下,子进程与父进程处于相同的namespace中。我们在新的uts namespace中创建一个子进程,然后查看该子进程的uts namespace id,命令及结果如下: phl@kernelnewbies:~$ sudo unshare --uts /bin/bash root@kernelnewbies:~# readlink /proc/$$/ns/uts uts:[4026532305] root@kernelnewbies:~# bash root@kernelnewbies:~# readlink /proc/$$/ns/uts uts:[4026532305] 从结果我们可以看到,子进程所属uts namespace的id与其父进程相同。其他namespae与uts namespace类似,子进程与父进程同属一个namespace。 docker.sh 有了以上关于uts namespace的介绍,我们就可以将uts namespace加入到docker.sh中了。docker.sh工程分为两个脚本:docker.sh和container.sh。 docker.sh用于收集用户输入、调用unshare创建namespace并执行container.sh脚本,docker.sh脚本如下: #!/bin/bash usage () { echo -e "\033[31mIMPORTANT: Run As Root\033[0m" echo "" echo "Usage: docker.sh [OPTIONS]" echo "" echo "A docker written by shell" echo "" echo "Options:" echo " -c string docker command" echo " (\"run\")" echo " -m memory" echo " (\"100M, 200M, 300M...\")" echo " -C string container name" echo " -I string image name" echo " -V string volume" echo " -P string program to run in container" return 0 } if test "$(whoami)" != root then usage exit -1 fi while getopts c:m:C:I:V:P: option do case "$option" in c) cmd=$OPTARG;; m) memory=$OPTARG;; C) container=$OPTARG;; I) image=$OPTARG;; V) volume=$OPTARG;; P) program=$OPTARG;; \?) usage exit -2;; esac done export cmd=$cmd export memory=$memory export container=$container export image=$image export volume=$volume export program=$program unshare --uts ./container.sh 脚本最开始为usage函数,该函数为docker.sh的使用说明。当用户以非预期的方式使用docker.sh时,该函数会被调用。该函数输出如下信息: IMPORTANT: Run As Root Usage: docker.sh [OPTIONS] A docker written by shell Options: -c string docker command ("run") -m memory ("100M, 200M, 300M...") -C string container name -I string image name -V string volume -P string program to run in container 从usage函数的输出我们可以看到,执行docker.sh时需要root权限且需要正确地传递参数。 docker.sh首先对当前用户进行检测,如果用户不为root,则打印使用说明并退出脚本;如果用户为root,则继续执行。检测用户的脚本如下: if test "$(whoami)" != root then usage exit -1 fi 然后,docker.sh使用getopts从命令行提取参数,然后赋值给合适的变量。从命令行提取参数的脚本如下: while getopts c:m:C:I:V:P: option do case "$option" in c) cmd=$OPTARG;; m) memory=$OPTARG;; C) container=$OPTARG;; I) image=$OPTARG;; V) volume=$OPTARG;; P) program=$OPTARG;; \?) usage exit -2;; esac done 如果用户的输入不正确,则打印使用说明并退出脚本;如果用户输入正确,则解析命令行参数并赋值给合适的变量。 为了简化,用户在运行docker.sh时需提供完整的参数列表,示例如下: sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash 当然,如果当前用户就是root,就不需要sudo了。下表列出了各个参数的含义及示例: docker.sh将命令行参数赋值给变量后,需要将这些变量导出,以传递给container.sh。导出变量的脚本如下: export cmd=$cmd export memory=$memory export container=$container export image=$image export volume=$volume export program=$program 这里说明一下为什么要将docker.sh工程拆分为docker.sh和container.sh两个脚本。因为调用unshare创建新的namespace时,会执行一个命令,该命令在新的namespace中运行。该命令一旦结束,unshare也就结束了,unshare创建的新namespace也就不存在了。 docker.sh不会并发地执行unshare命令与unshare之后的脚本,因此,只有unshare结束了,后续脚本才可继续运行。但是当unshare结束了,准备执行后续脚本时,新的namespae已经不存在了。因此一些加入cgroups、切换根文件系统等工作必须在unshare执行的命令中进行,所以我们采用在unshare中执行container.sh脚本的方式完成后续的工作。 最后,docker.sh调用unshare创建新的uts namespace,并执行container.sh脚本。调用unshare的脚本如下: unshare --uts ./container.sh container.sh将容器的hostname修改为通过-C传递的容器的名字,然后执行通过-P传递的程序。container.sh脚本如下: #!/bin/bash hostname $container exec $program 现在,我们运行docker.sh,并查看其hostname。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:~/docker.sh# hostname dreamland 从结果我们可以看到,容器的hostname已经改变为我们传递的容器名字dreamland了。 mount namespace /etc/mtab、/proc/self/mounts 早期的Linux使用/etc/mtab文件来记录当前的挂载点信息。每次mount/umount文件系统时会更新/etc/mtab文件中的信息。 后来,linux引入了mount namespace,每个进程都有一份自己的挂载点信息。当然,处于同一个mount namespace里面的进程,其挂载点信息是相同的。进程的挂载点信息通过/proc/[pid]/mounts文件导出给用户。 为了兼容以前的/etc/mtab,/etc/mtab变成了指向/proc/self/mounts的符号链接。通过readlink查看/etc/mtab指向的文件,命令及结果如下: phl@kernelnewbies:~$ readlink /etc/mtab ../proc/self/mounts 通过读取/proc/self/mounts文件,可以查看当前的挂载点信息,命令及结果如下: phl@kernelnewbies:~$ cat /proc/self/mounts sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 /dev/sda1 / ext4 rw,relatime,errors=remount-ro 0 0 securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 ... 由于该文件中内容太多,我们省略了一部分,只保留了一些比较重要的挂载点信息。每行的信息分为六个字段,各字段的含义及示例如下: 由于该文件有点过时,被后文介绍的/proc/self/mountinfo替换掉,所以不做过多介绍。 /proc/self/mountinfo /proc/self/mountinfo包含了进程mount namespace中的挂载点信息。 它提供了旧的/proc/[pid]/mounts文件中缺少的各种信息(传播状态,挂载点id,父挂载点id等),并解决了/proc/[pid]/mounts文件的一些其他缺陷。我们查看进程挂载点信息时应优先使用该文件。 该文件中每一行代表一个挂载点信息,每个挂载点信息分为11个字段。挂载点信息的示例如下: 各字段的含义及示例如下: 我们主要关注可选字段中的传播状态选项。首先,我们看一下关于mount namespace的问题。问题如下: 当创建mount namespace时,新mount namespace会拷贝一份老mount namespace里面的挂载点信息。例如,全局mount namespace中有一个/a挂载点,新建的mount namespace中也会有一个/a挂载点。那么我们在新mount namespace中的/a下创建或删除一个挂载点,全局mount namespace中的/a会同步创建或删除该挂载点吗?或者在全局mount namespace中的/a下创建或删除一个挂载点,新mount namespace中的/a会同步创建或删除该挂载点吗? mountinfo文件中可选字段的传播状态就是控制在一个挂载点下进行创建/删除挂载点操作时是否会传播到其他挂载点的选项。传播状态有四种可取值,常见的有如下两种: shared 表示创建/删除挂载点的操作会传播到其他挂载点 private 表示创建/删除挂载点的操作不会传播到其他挂载点 由于在容器技术中要保证主机与容器的挂载点信息互不影响,因此要求容器中的挂载点的传播状态为private。 1.3.3.bind mount bind mount可以将一个目录(源目录)挂载到另一个目录(目的目录),在目的目录里面的读写操作将直接作用于源目录。 下面我们通过实验了解一下bind mount的功能,首先,我们准备一下实验所需要的的目录及文件。命令及结果如下: phl@kernelnewbies:~$ mkdir bind phl@kernelnewbies:~$ cd bind/ phl@kernelnewbies:~/bind$ mkdir a phl@kernelnewbies:~/bind$ mkdir b phl@kernelnewbies:~/bind$ echo hello, a > a/a.txt phl@kernelnewbies:~/bind$ echo hello, b > b/b.txt 然后,我们将a目录bind mount到b目录并查看b目录下的内容。命令及结果如下: phl@kernelnewbies:~/bind$ sudo mount --bind a b phl@kernelnewbies:~/bind$ tree b b └── a.txt 0 directories, 1 file 从结果我们可以看到,b目录下原先的内容被隐藏,取而代之的是a目录下的内容。 然后,我们修改b目录下的内容,修改完毕后,从b目录上卸载掉a目录。命令及结果如下: phl@kernelnewbies:~/bind$ echo hello, a from b > b/a.txt phl@kernelnewbies:~/bind$ sudo umount b 我们读取一下a目录中a.txt,看看其内容是否被改变。命令及结果如下: phl@kernelnewbies:~/bind$ cat a/a.txt hello, a from b 从结果我们可以看到,a目录中的内容确实被当a被bind mount到b时对b目录的操作所修改了。 bind mount在容器技术中有很重要的用途,后文会有涉及。 mount namespace简介 mount namespace用来隔离文件系统的挂载点信息, 使得不同的mount namespace拥有自己独立的挂载点信息。不同的namespace之间不会相互影响,其在unshare中的选项为–mount。 当用unshare创建新的mount namespace时,新创建的namespace将拷贝一份老namespace里的挂载点信息,但从这之后,他们就没有关系了。这是unshare将新 namespace 里面的所有挂载点的传播状态设置为private实现的。通过mount和umount增加和删除各自mount namespace里面的挂载点都不会相互影响。 下面我们将演示mount namespace的用法。首先,我们准备需要的目录和文件,命令及结果如下: phl@kernelnewbies:~$ mkdir -p hds/hd1 hds/hd2 && cd hds phl@kernelnewbies:~/hds$ dd if=/dev/zero bs=1M count=1 of=hd1.img && mkfs.ext2 hd1.img phl@kernelnewbies:~/hds$ dd if=/dev/zero bs=1M count=1 of=hd2.img && mkfs.ext2 hd2.img phl@kernelnewbies:~$ tree . . ├── hd1 ├── hd1.img ├── hd2 └── hd2.img 2 directories, 2 files 然后,我们在全局的mount namespace中挂载hd1.img到hd1目录,然后查看该mount namespace中的挂载点信息与mount namespace id。命令及结果如下: phl@kernelnewbies:~/hds$ sudo mount hd1.img hd1 phl@kernelnewbies:~/hds$ cat /proc/self/mountinfo | grep hd 556 27 7:18 / /home/phl/hds/hd1 rw,relatime shared:372 - ext2 /dev/loop18 rw phl@kernelnewbies:~/hds$ sudo readlink /proc/$$/ns/mnt mnt:[4026531840] 然后,执行unshare命令创建一个新的mount namespace并查看该mount namespace id和挂载点信息。命令及结果如下: phl@kernelnewbies:~/hds$ sudo unshare --uts --mount /bin/bash root@kernelnewbies:~/hds# cat /proc/self/mountinfo | grep hd 739 570 7:18 / /home/phl/hds/hd1 rw,relatime - ext2 /dev/loop18 rw root@kernelnewbies:~/hds# readlink /proc/$$/ns/mnt mnt:[4026532180] 从结果我们可以看到,新mount namespace中的挂载点信息与全局mountnamespace中的挂载点信息基本一致,一些挂载选项(如传播状态)变化了。新的mount namespace id与全局mount namespace id是不一样的。 然后,我们在新的mount namespace中挂载hd2.img到hd2目录,并查看挂载点信息。命令及结果如下: root@kernelnewbies:~/hds# mount hd2.img hd2 root@kernelnewbies:~/hds# cat /proc/self/mountinfo | grep hd 739 570 7:18 / /home/phl/hds/hd1 rw,relatime - ext2 /dev/loop18 rw 740 570 7:19 / /home/phl/hds/hd2 rw,relatime - ext2 /dev/loop19 rw 从结果我们可以看到,新mount namespace中有hd1和hd2这两个挂载点。现在启动一个新的Shell窗口,查看全局mount namespace中的挂载点信息。命令及结果如下: phl@kernelnewbies:~/hds$ cat /proc/self/mountinfo | grep hd 556 27 7:18 / /home/phl/hds/hd1 rw,relatime shared:372 - ext2 /dev/loop18 rw 从结果我们可以看到,全局mount namespace中的挂载点信息只有hd1,而没有hd2。这说明在新mount namespace中进行挂载/卸载操作不会影响其他mount namespace中的挂载点信息。 mount namespace只隔离挂载点信息,并不隔离挂载点下面的文件信息。对于多个mount namespace都能看到的挂载点,如果在一个namespace中修改了挂载点下面的文件,其他namespace也能感知到。下面,我们在新建的mount namespace中创建一个文件,命令如下: root@kernelnewbies:~/hds# echo hello from new mount namespace > hd1/hello.txt 在新启动的Shell中,查看hd1目录并读取hd1/hello.txt文件。命令及结果如下: phl@kernelnewbies:~/hds$ tree hd1 hd1 ├── hello.txt └── lost+found [error opening dir] 1 directory, 1 file phl@kernelnewbies:~/hds$ cat hd1/hello.txt hello from new mount namespace 从结果我们可以看到,在全局mount namespace中,我们可以读取到在新建的mount namespace中创建的文件。 docker.sh 有了以上关于mount namespace的知识,我们就可以将mount namespace加入到docker.sh中了。mount namespace将放在docker.sh中,带下划线的行是我们为实现mount namespace而修改的代码。修改后的docker.sh脚本如下: ... unshare --uts --mount ./container.sh 从上述代码我们可以看到,我们仅仅是在调用unshare时加入–mount选项,就可为docker.sh引入了mount namespace功能。 pid namespace unshare的–fork选项 unshare有一个选项–fork,当执行unshare时,如果没有这个选项,unshare会直接exec新命令,也就是说unshare变成了新命令。如果带有–fork选项,unshare会fork一个子进程,该子进程exec新命令,unshare是该子进程的父进程。我们分别不带–fork和带–fork来执行unshare,然后查看进程之间的关系。 首先,我们不带–fork选项执行unshare,并查看当前Shell的进程id。命令及结果如下: phl@kernelnewbies:~$ sudo unshare --uts /bin/bash root@kernelnewbies:~/hds# echo $$ 11699 此时unshare会创建一个新的uts namespace,然后exec /bin/bash。我们启动一个新Shell,然后使用pstree查看进程间关系,命令及结果如下: phl@kernelnewbies:~/hds$ pstree -p | grep 11699 sudo(11698)---bash(11699) 从结果我们可以看到,sudo fork出一个子进程,该子进程执行unshare。unshare创建了新uts namespace后,exec了/bin/bash,也就是说unshare变成了/bin/bash。 然后,我们带–fork选项执行unshare,并查看当前Shell的进程id。命令及结果如下: phl@kernelnewbies:~/hds$ sudo unshare --uts --fork /bin/bash root@kernelnewbies:~/hds# echo $$ 11866 此时unshare会创建一个新的uts namespace,然后fork出一个子进程,该子进程exec /bin/bash。我们启动一个新Shell,然后使用pstree查看进程间关系,命令及结果如下: phl@kernelnewbies:~/hds$ pstree -p | grep 11866 sudo(11864)---unshare(11865)---bash(11866) 从结果我们可以看到,sudo fork出一个子进程,该子进程执行命令unshare。unshare创建了新uts namespace后,fork出一个子进程,该子进程exec /bin/bash,也就是说unshare变成了新的/bin/bash进程的父进程。 pid namespace简介 pid namespace用来隔离进程pid空间,使得不同pid namespace里的进程 pid可以重复且相互之间不影响。进程所属的pid namespace在创建的时候就确定了,无法更改,因此需要–fork选项来创建一个新进程,然后将该新进程加入新建的pid namespace中。pid namespace在unshare中的选项为–pid。 unshare在创建pid namespace时需同时提供–pid与–fork选项。unshare本身会加入全局的pid namespace,其fork出的子进程会加入新建的pid namespace。 首先,我们查看全局pid namespace id,命令及结果如下: phl@kernelnewbies:~$ sudo readlink /proc/$$/ns/pid pid:[4026531836] 然后,执行unshare命令创建一个新的pid namespace并查看该pid namespace id。命令及结果如下: phl@kernelnewbies:~$ sudo unshare --mount --pid --fork /bin/bash root@kernelnewbies:~# readlink /proc/$$/ns/pid pid:[4026531836] 从结果我们可以看到,新创建的进程也处于全局pid namespace中,而不是新的pid namespace。 出现这种情形是因为当前的/proc文件系统是老的。我们查看一下$$的值,命令及结果如下: root@kernelnewbies:~# echo $$ 1 从结果我们可以看到,$$的值为1,但是/proc文件系统却是老的,因此我们查看的实际是init进程所属的pid namespace,当然是全局pid namespace了。 重新挂载/proc文件系统,这也是unshare执行时带–mount选项的原因,只有这样,重新挂载/proc文件系统时,不会搞乱整个系统。再次查看新进程所属的pid namespace,命令及结果如下: root@kernelnewbies:~# mount -t proc proc /proc root@kernelnewbies:~# readlink /proc/$$/ns/pid pid:[4026532182] 从结果我们可以看到,新进程的pid namespace与全局pid namespace的id不同。 接下来,我们再来查看一下新pid namespace中的进程信息。命令及结果如下: root@kernelnewbies:~# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 19:03 pts/1 00:00:00 /bin/bash root 10 1 0 19:03 pts/1 00:00:00 ps -e 从结果我们可以看到,当前pid namespace中只有2个进程,看不到全局pid namespace里面的其他进程。我们通过unshare执行的进程pid为1,也就是说该进程成了新pid namespace中的init进程。 pid嵌套 pid namespace可以嵌套,也就是说有父子关系,在当前pid namespace里面创建的所有新的pid namespace都是当前pid namespace的子pid namespace。 首先,我们创建3个嵌套的pid namespace,并查看每个pid namespace id。–mount-proc选项用于自动挂载/proc文件系统,省去了手动挂载/proc文件系统的操作。命令及结果如下: phl@kernelnewbies:~$ sudo readlink /proc/$$/ns/pid pid:[4026531836] phl@kernelnewbies:~$ sudo unshare --uts --mount --pid --mount-proc --fork /bin/bash root@kernelnewbies:~# readlink /proc/$$/ns/pid pid:[4026532182] root@kernelnewbies:~# unshare --uts --mount --pid --mount-proc --fork /bin/bash root@kernelnewbies:~# readlink /proc/$$/ns/pid pid:[4026532185] root@kernelnewbies:~# unshare --uts --mount --pid --mount-proc --fork /bin/bash root@kernelnewbies:~# readlink /proc/$$/ns/pid pid:[4026532188] 然后,我们启动一个新Shell,然后使用pstree查看进程间关系。命令及结果如下: phl@kernelnewbies:~$ pstree -lp | grep unshare sudo(12547)---unshare(12548)---bash(12549)---unshare(12579)---bash(12580)---unshare(12593)---bash(12594) 使用cat /proc/[pid]/status | grep NSpid可查看某进程在当前pid namespace及子孙pid namespace中的pid。我们在全局pid namespace中查看上述各进程在各pid namespace中的pid,命令及结果如下: phl@kernelnewbies:~$ cat /proc/12594/status | grep NSpid NSpid: 12594 21 11 1 phl@kernelnewbies:~$ cat /proc/12593/status | grep NSpid NSpid: 12593 20 10 phl@kernelnewbies:~$ cat /proc/12580/status | grep NSpid NSpid: 12580 11 1 phl@kernelnewbies:~$ cat /proc/12579/status | grep NSpid NSpid: 12579 10 phl@kernelnewbies:~$ cat /proc/12549/status | grep NSpid NSpid: 12549 1 下面我们将以上进程在各pid namespace中的pid,整理成表格。表格信息如下: 我们以最后一行为例进行介绍,最后一行有4个pid,这4个pid其实是同一个进程。这个进程在4个pid namespace中都可以被看到,且其在4个pid namespace中的pid各不相同。 docker.sh 有了以上关于pid namespace的知识,我们就可以将pid namespae加入到docker.sh中了。pid namespace将放在docker.sh中,带下划线的行是我们为实现pid namespace而修改的代码。修改后的docker.sh脚本如下: ... unshare --uts --mount --pid --fork ./container.sh 从上述代码我们可以看到,我们仅仅是在调用unshare时加入–pid和–fork选项,就可为docker.sh引入了pid namespace功能。 然后,我们需要重新挂载/proc文件系统。重新挂载/proc文件系统的功能将放在container.sh中,带下划线的行是我们为重新挂载/proc文件系统而新添的代码。修改后的container.sh脚本如下如下所示: hostname $container mount -t proc proc /proc exec $program 现在,我们运行docker.sh,并查看当前的进程信息。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:~/docker.sh# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 17:31 pts/1 00:00:00 /bin/bash root 16 1 0 17:31 pts/1 00:00:00 ps -ef 从结果我们可看出,当前进程只有两个,不再有主机上的其他进程。 CGroups CGroups简介 CGroups是一种将进程分组,并以组为单位对进程实施资源限制的技术。每个组都包含以下几类信息: 进程列表 资源A限制 资源B限制 资源C限制 … 我们将以常见的CPU资源及内存资源为例进行介绍。以下的信息将使进程号为1001、1002、2008、3306的四个进程总共只能使用一个CPU核心;总共最多使用25%的CPU资源;总共最多使用100M内存,这样的一个分组被称为cgroup。 上面的介绍只是说明了要将何种资源限制施加于哪些进程,并未说明资源限制是如何施加到进程上。具体施加资源限制的过程需要subsystem来帮忙。subsystem读取cgroup中的资源限制和进程列表,然后将这些资源限制施加到这些进程上。常见的subsystem包括如下几种: cpu memory pids devices blkio net_cls 每个subsystem只读取与其相关的资源限制,然后施加到进程上。例如:memory子系统只读取内存限制,而cpu子系统只读取cpu限制。 cgroup被组织成树,如下图所示: 采用树状结构可以方便地实现资源限制继承,一个cgroup中的资源限制将作用于该cgroup及其子孙cgroup中的进程。例如:图中13001、10339、2999受到A、B、C、D四个cgroup中的资源限制。这样的一个树状结构被称为hierarchy。 hierarchy中包含了系统中所有的进程,它们分布于各个cgroup中。在hierarchy中,一个进程必须属于且只属于一个cgroup,这样才能保证对进程施加的资源限制不会遗漏也不会冲突。 要想让一个subsystem读取hierarchy中各cgroup的资源限制,并施加于其中的进程需要将subsystem和hierarchy关联起来。subsystem与hierarchy的关系如下: 系统中可以有多个hierarchy 一个hierarchy可以关联0个或多个subsystem,当关联0个subsystem时,该hierarchy只是对进程进行分类 一个subsystem最多关联到一个hierarchy,因为每个hierarchy都包含系统中所有的进程,若一个subsystem关联到了多个hierarchy,对同一进程将有多种资源限制,这是不对的 系统使用CGroups通常有两种形式:一种是创建一个hierarchy,将所有的subsystem关联到其上,在这个hierarchy上配置各种资源限制;另一种是为每一个subsystem创建一个hierarchy,并将该subsystem关联到其上,每个hierarchy只对一种资源进行限制。后一种比较清晰,得到了更普遍的采用。 CGroups不像大多数的技术那样提供API或命令之类的用户接口,而是提供给用户一个虚拟文件系统,该虚拟文件系统类型为cgroup。一个挂载后的cgroup文件系统就是一个hierarchy,文件系统中的一个目录就是一个cgroup,目录中的文件代表了进程列表或者资源限制信息。文件系统是树状结构,其各个目录之间的父子关系就代表了cgroup之间的继承关系。挂载cgroup虚拟文件系统后,通过在该文件系统上创建目录、写进程列表文件、写资源限制文件就可以操作CGroups。 下面,我们通过实验学习一下CGroups的用法。首先,我们挂载一个cgroup虚拟文件系统,该文件系统不与任何subsystem关联,仅仅是将进程进行分类。命令及结果如下: phl@kernelnewbies:~$ mkdir -p cg/test # -o none,name=test 表示该cgroup文件系统不与任何子系统关联 # 该文件系统用name=test来标识 phl@kernelnewbies:~$ sudo mount -t cgroup -o none,name=test test cg/test phl@kernelnewbies:~$ tree cg/test cg/test ├── cgroup.clone_children ├── cgroup.procs ├── cgroup.sane_behavior ├── notify_on_release ├── release_agent └── tasks 0 directories, 6 files 挂载cgroup文件系统后,该cgroup文件系统的根目录下会生成许多文件,该根目录被称为root cgroup。cgroup.procs里面存放的是当前cgroup中的所有进程id,由于该hierarchy中只有一个cgroup,所以这个文件包含了系统中所有的进程id。其他的文件与cgroups基本功能关系不大,暂时可以忽略。 在cgroup文件系统中,创建一个目录就会创建一个cgroup。下面我们将会演示如何创建下面这样的hierarchy: 命令及结果如下: phl@kernelnewbies:~$ sudo mkdir -p cg/test/test1/test11 phl@kernelnewbies:~$ sudo mkdir -p cg/test/test2/test22 phl@kernelnewbies:~$ tree cg/test cg/test ├── cgroup.clone_children ├── cgroup.procs ├── cgroup.sane_behavior ├── notify_on_release ├── release_agent ├── tasks ├── test1 │ ├── cgroup.clone_children │ ├── cgroup.procs │ ├── notify_on_release │ ├── tasks │ └── test11 │ ├── cgroup.clone_children │ ├── cgroup.procs │ ├── notify_on_release │ └── tasks └── test2 ├── cgroup.clone_children ├── cgroup.procs ├── notify_on_release ├── tasks └── test22 ├── cgroup.clone_children ├── cgroup.procs ├── notify_on_release └── tasks 4 directories, 22 files 从结果我们可以看到,我们创建了相应的目录后,这些目录下自动出现了包含cgroup信息的目录及文件。 删除cgroup时只需删除该cgroup所在的目录即可。下面我们将删除test11 cgroup,命令及结果如下: phl@kernelnewbies:~$ sudo rmdir cg/test/test1/test11 phl@kernelnewbies:~$ tree cg/test cg/test ├── cgroup.clone_children ├── cgroup.procs ├── cgroup.sane_behavior ├── notify_on_release ├── release_agent ├── tasks ├── test1 │ ├── cgroup.clone_children │ ├── cgroup.procs │ ├── notify_on_release │ └── tasks └── test2 ├── cgroup.clone_children ├── cgroup.procs ├── notify_on_release ├── tasks └── test22 ├── cgroup.clone_children ├── cgroup.procs ├── notify_on_release └── tasks 3 directories, 18 files 每个cgroup下面都有一个cgroup.procs文件,该文件里面包含当前cgroup里面的所有进程id。只要将某个进程的id写入该文件,即可将该进程加入到该cgroup中。下面,我们将当前的bash加入到test22 cgroup中,命令及结果如下: phl@kernelnewbies:~$ echo $$ 3894 phl@kernelnewbies:~$ sudo sh -c "echo 3894 > cg/test/test2/test22/cgroup.procs" /proc/[pid]/cgroup包含了某个进程所在的cgroup信息。下面,我们查看一下当前bash进程所在的cgroup信息,命令及结果如下: phl@kernelnewbies:~$ cat /proc/3894/cgroup 13:name=test:/test2/test22 12:freezer:/ 11:perf_event:/ 10:blkio:/user.slice 9:devices:/user.slice 8:hugetlb:/ 7:cpu,cpuacct:/user.slice 6:net_cls,net_prio:/ 5:memory:/user.slice 4:rdma:/ 3:pids:/user.slice/user-1001.slice/session-4.scope 2:cpuset:/ 1:name=systemd:/user.slice/user-1001.slice/session-4.scope 0::/user.slice/user-1001.slice/session-4.scope 从结果我们可以看到,当前bash进程加入了多个cgroup,其中带下划线的行为我们刚刚加入的cgroup。 要想将hierarchy与子系统关联起来,需要在-o选项中指定子系统名称。下面演示了如何将memory子系统与新挂载的cgroup文件系统关联起来。代码如下: phl@kernelnewbies:~$ sudo mkdir cg/memory phl@kernelnewbies:~$ sudo mount -t cgroup -o memory memcg cg/memory 由于很多发行版的操作系统已经为我们配置好了这些cgroup文件系统,我们应当直接使用这些已经挂在好的文件系统,不需要自己去挂载。 另外,当创建子进程时,子进程会自动加入父进程所在的cgroup。 限制内存 用CGroups限制内存 下面我们将介绍演示CGroups如何限制进程使用的内存资源,我们以内存为例进行讲解。 Ubuntu18.04已经为我们挂载了一个关联memory子系统的cgroup虚拟文件系统。我们用mount命令查看一下该系统挂载到了何处,命令及结果如下: phl@kernelnewbies:~$ mount | grep cgroup tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) cgroup on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate) cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) 该系统挂载到了/sys/fs/cgroup/memory目录下。我们在该hierarchy中创建一个test cgroup并查看该cgroup的目录结构,命令及结果如下: phl@kernelnewbies:~$ sudo mkdir /sys/fs/cgroup/memory/test phl@kernelnewbies:~$ tree /sys/fs/cgroup/memory/test /sys/fs/cgroup/memory/test ├── cgroup.clone_children ├── cgroup.event_control ├── cgroup.procs ├── memory.failcnt ├── memory.force_empty ├── memory.kmem.failcnt ├── memory.kmem.limit_in_bytes ├── memory.kmem.max_usage_in_bytes ├── memory.kmem.slabinfo ├── memory.kmem.tcp.failcnt ├── memory.kmem.tcp.limit_in_bytes ├── memory.kmem.tcp.max_usage_in_bytes ├── memory.kmem.tcp.usage_in_bytes ├── memory.kmem.usage_in_bytes ├── memory.limit_in_bytes ├── memory.max_usage_in_bytes ├── memory.move_charge_at_immigrate ├── memory.numa_stat ├── memory.oom_control ├── memory.pressure_level ├── memory.soft_limit_in_bytes ├── memory.stat ├── memory.swappiness ├── memory.usage_in_bytes ├── memory.use_hierarchy ├── notify_on_release └── tasks 0 directories, 27 files 从结果我们可以看到,新建的test cgroup中有许多文件,这些文件中存放着资源限制信息。其中memory.limit_in_bytes里面存放的是该cgroup中的进程能够使用的内存额度。 下面,我们将当前bash加入到test cgroup中并查看当前bash所属的cgroup信息。命令及结果如下: phl@kernelnewbies:~$ echo $$ 2984 phl@kernelnewbies:~$ sudo sh -c "echo 2984 > /sys/fs/cgroup/memory/test/cgroup.procs" phl@kernelnewbies:~$ cat /proc/2984/cgroup 12:devices:/user.slice 11:hugetlb:/ 10:memory:/test 9:rdma:/ 8:perf_event:/ 7:blkio:/user.slice 6:cpu,cpuacct:/user.slice 5:pids:/user.slice/user-1001.slice/session-4.scope 4:freezer:/ 3:cpuset:/ 2:net_cls,net_prio:/ 1:name=systemd:/user.slice/user-1001.slice/session-4.scope 0::/user.slice/user-1001.slice/session-4.scope 从结果我们可以看到,当前bash所属的memory cgroup变为了/test,该目录为一个相对于root cgroup的相对路径。 然后,将100M写入test cgroup中的memory.limit_in_bytes文件中,命令如下: phl@kernelnewbies:~$ sudo sh -c "echo 100M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes" 我们在当前bash中启动一个占用300M进程的stress进程,该stress进程是bash的子进程,其与bash进程都在test cgroup中。命令如下: phl@kernelnewbies:~$ stress --vm 1 --vm-bytes 300M --vm-keep 启动一个新的Shell窗口,执行top命令查看stress进程占用的内存。命令及结果如下: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14216 root 20 0 315440 101224 264 D 27.7 2.5 0:02.66 stress 从结果我们可以看到,stress进程占用了2.5%的内存。我的电脑的内存为4G,4G * 2.5% = 100M,stress进程确实受到了cgroup中设置的内存额度的限制。 docker.sh 下有了以上关于CGroups的知识,我们就可以将限制内存的功能加入到docker.sh中了。限制内存的功能将放在container.sh中,带下划线的行是我们为实现限制内存而新添的代码。修改后的container.sh脚本如下: hostname $container mkdir -p /sys/fs/cgroup/memory/$container echo $$ > /sys/fs/cgroup/memory/$container/cgroup.procs echo $memory > /sys/fs/cgroup/memory/$container/memory.limit_in_bytes mount -t proc proc /proc exec $program 首先,我们根据容器的名字创建cgroup,命令如下: mkdir -p /sys/fs/cgroup/memory/$container 然后,我们将当前bash加入到我们创建的cgroup中,命令如下: echo $$ > /sys/fs/cgroup/memory/$container/cgroup.procs 最后,我们将内存限制写入新cgroup的memory.limit_in_bytes文件中,命令如下: echo $memory > /sys/fs/cgroup/memory/$container/memory.limit_in_bytes 现在,我们运行docker.sh,并启动一个占用300M进程的stress进程。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:~/docker.sh# stress --vm 1 --vm-bytes 300M --vm-keep stress: info: [12] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd 启动一个新的Shell窗口,执行top命令查看stress进程占用的内存。命令及结果如下: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14216 root 20 0 315440 101224 264 D 27.7 2.5 0:02.66 stress 从结果我们可以看到,容器内的stress进程只使用了100M的内存。 切换根文件系统 根文件系统 在容器技术中,根文件系统可为容器进程提供一个与主机不一致的文件系统环境。举个例子,主机为Ubuntu 18.04,创建的容器采用Ubuntu 16.04的根文件系统,那么容器运行时所用的软件及其依赖库、配置文件等都是Ubuntu 16.04的。尽管该容器使用的内核是仍旧是Ubuntu 18.04的,但应用软件的表现却与Ubuntu 16.04一致,从虚拟化的角度来说该容器就是一个Ubuntu 16.04系统。 debootstrap是Ubuntu下的一个工具,用来构建根文件系统。生成的目录符合Linux文件系统标准,即包含了/boot、/etc、/bin、/usr等目录。debootstrap的安装命令如下: sudo apt install debootstrap 下面我们通过debootstrap构建Ubuntu 16.04的根文件系统。为了清晰,我们在images目录下生成根文件系统。命令及结果如下: phl@kernelnewbies:~/docker.sh$ mkdir images phl@kernelnewbies:~/docker.sh$ cd images phl@kernelnewbies:~/docker.sh/images$ sudo debootstrap --arch amd64 xenial ./ubuntu1604 制作根文件系统需要从服务器下载很多文件,很耗时,请耐心等待。当文件系统制作好后,可以使用tree命令查看生成的根文件系统。命令及结果如下: phl@kernelnewbies:~/docker.sh/images$ tree -L 1 ubuntu1604/ ubuntu1604/ ├── bin ├── boot ├── dev ├── etc ├── home ├── lib ├── lib64 ├── media ├── mnt ├── old_root ├── opt ├── proc ├── root ├── run ├── sbin ├── srv ├── sys ├── tmp ├── usr └── var 20 directories, 0 files 这个根文件系统与Linux系统目录很相近,我们后续的实验将使用该根文件系统。 pivot_root pivot_root命令用于切换根文件系统,其使用方式如下: pivot_root new_root put_old pivot_root将当前进程的根文件系统移至put_old目录并使new_root目录成为新的根文件系统。 下面我们将通过实验学习pivot_root的使用方法。为了简单,我们在一个新的mount namespace下进行实验。首先,我们创建一个新的mount namespace,命令及结果如下: phl@kernelnewbies:~/docker.sh/images$ sudo unshare --mount /bin/bash root@kernelnewbies:~/docker.sh/images# 在我们的实验中,我们的根文件系统将挂载在ubuntu1604目录,而老的根文件系统将被移动到ubuntu1604/old_root目录下。我们先创建old_root目录,命令如下: root@kernelnewbies:~/docker.sh/images# mkdir -p ubuntu1604/old_root/ 由于pivot_root命令要求老的根目录和新的根目录不能在同一个挂载点下,因此我们通过bind mount将ubuntu1604目录变成一个挂载点。命令及结果如下: root@kernelnewbies:~/docker.sh/images# mount --bind ubuntu1604 ubuntu1604 root@kernelnewbies:~/docker.sh/images# cat /proc/self/mountinfo | grep ubuntu1604 624 382 8:1 /home/phl/docker.sh/images/ubuntu1604 /home/phl/docker.sh/images/ubuntu1604 rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 准备好切换根文件系统所需要的条件后,我们调用pivot_root切换根文件系统。命令及结果如下: root@kernelnewbies:~/docker.sh/images# cd ubuntu1604/ root@kernelnewbies:~/docker.sh/images/ubuntu1604# pivot_root . old_root/ 此时,已完成根文件系统的切换,/proc文件系统也被挪到了 root@kernelnewbies:~/docker.sh/images/ubuntu1604# mount -t proc proc /proc 重新挂载/proc文件系统后,我们就可以查看当前的挂载点信息了。通过读取/proc/self/mountinfo文件来查看系统的挂载点信息。命令及结果如下: root@kernelnewbies:~/docker.sh/images/ubuntu1604# cat /proc/self/mountinfo 382 624 8:1 / /old_root rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro ... 624 381 8:1 /home/phl/docker.sh/images/ubuntu1604 / rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 625 624 0:5 / /proc rw,relatime - proc proc rw 此时的挂载点很多,为了方便查看,此处只保留了一些主要的挂载点信息。这些挂载点信息包括/、/proc、/old_root。/old_root为老的根文件系统,我们需要将其卸载。命令及结果如下: root@kernelnewbies:~/docker.sh/images/ubuntu1604# umount -l /old_root/ 卸载掉老的根文件系统后,我们再查看系统的挂载点信息。命令及结果如下: root@kernelnewbies:~/docker.sh/images/ubuntu1604# cat /proc/self/mountinfo 624 381 8:1 /home/phl/docker.sh/images/ubuntu1604 / rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 625 624 0:5 / /proc rw,relatime - proc proc rw 此时,挂载点信息中只有/、/proc,不再有主机的挂载点信息。 docker.sh 有了以上关于切换根文件系统的知识,我们就可以将切换根文件系统的功能加入到docker.sh中了。切换根文件系统的功能将放在container.sh中,带下划线的行是我们为实现切换根文件系统而新添的代码。修改后的container.sh脚本如下: #!/bin/bash hostname $container mkdir -p /sys/fs/cgroup/memory/$container echo $$ > /sys/fs/cgroup/memory/$container/cgroup.procs echo $memory > /sys/fs/cgroup/memory/$container/memory.limit_in_bytes mkdir -p images/$image/old_root mount --bind images/$image images/$image cd images/$image pivot_root . ./old_root mount -t proc proc /proc umount -l /old_root exec $program 首先,我们在新的根文件系统目录中创建挂载老的根文件系统的目录。命令如下: mkdir -p images/$image/old_root 然后,我们将新根文件系统目录bind mount成一个挂载点。命令如下: mount --bind images/$image images/$image 然后,我们切换根文件系统。命令如下: cd images/$image pivot_root . ./old_root 最后,我们重新挂载/proc文件系统,然后卸载掉老的根文件系统。命令如下: mount -t proc proc /proc umount -l /old_root 现在,我们运行docker.sh,并查看当前的发行版信息。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:/# cat /etc/issue Ubuntu 16.04 LTS \n \l 从结果我们可以看出,读出的发行版信息是Ubuntu 16.04 LTS \n \l,而非主机的Ubuntu 18.04.3 LTS \n \l。这说明当前使用的根文件系统确实是ubuntu16.04目录下的根文件系统,而非主机的根文件系统。 我们再查看一下当前的挂载点信息,看看是否只有/与/proc。命令及结果如下: root@dreamland:/# cat /proc/self/mountinfo 625 381 8:1 /home/phl/docker.sh/images/ubuntu1604 / rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 626 625 0:52 / /proc rw,relatime - proc proc rw 从结果我们可看出,当前挂载点信息中只有/、/proc,不再有主机的挂载点信息。 通过根文件系统,我们实现了在容器中虚拟出与主机不一样的操作系统的功能。 联合加载 联合加载简介 联合加载指的是一次同时加载多个文件系统,但是在外面看起来只能看到 一个文件系统。联合加载会将各层文件系统叠加到一起,这样最终的文件系统会 包含所有底层的文件和目录。 联合加载的多个文件系统中有一个是可读写文件系统,称为读写层,其他文件系统是只读的,称为只读层。当联合加载的文件系统发生变化时,这些变化都应用到这个读写层。比如,如果想修改一个文件,这个文件首先会从只读层复制到读写层。原只读层中的文件依然存在,但是被读写层中的该文件副本所隐藏。我们以后读写该文件时,都是读写的该文件在读写层中的副本。这种机制被称为 写时复制。 我们之前实现的docker.sh,有一个很大的缺陷。那就是,如果使用相同的根文件系统同时启动多个容器的实例,那么,这些容器实例使用的根文件系统位于同一个目录。我们在不同的容器实例对根文件系统所作的修改,这些容器彼此之间都可以看到,甚至一个容器可以覆覆盖另一个容器所作的修改。同时,容器实例退出时,对根文件系统所作的修改也直接作用于其所使用的根文件系统。当我们使用该根文件系统再次启动容器实例时,新启动的容器实例也可以看到以前的这些修改。例如,我们用ubuntu1604根文件系统启动两个容器实例,命令如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland2 -I ubuntu1604 -V data1 -P /bin/bash 这两个容器实例对根文件系统做的修改彼此都可以看到。容器实例退出时,这些修改也被保存了下来,当用ubuntu1604根文件系统启动新的容器实例时,新实例也可看到以前实例所做的修改。 如果容器使用的根文件系统是一个联合加载的文件系统,原先的根文件系统作为一个只读层,再添加一个读写层,那么,在容器内所作的修改都将只作用于读写层。为了区分,我们以后称ubuntu1604目录下的根文件系统为镜像。而我们可以为每一个容器实例指定一个唯一的读写层目录,这样的话,多个容器实例就可以使用同一个镜像,容器内所作的修改不会影响彼此,也不会影响到以后启动的容器实例。例如: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland2 -I ubuntu1604 -V data1 -P /bin/bash 我们使用ubuntu1604镜像启动了两个容器示例,并在容器实例里进行读写操作。这两个容器实例的读写层目录是不一样的,在容器实例中所作的修改只作用于各自的读写层,彼此之间不会影响,当然更不会影响到后续启动的容器实例。 AUFS AUFS是一个实现了联合加载功能的文件系统。我们将采用AUFS实现docker.sh中的联合加载功能。 下面,我们将通过实验演示一下AUFS文件系统的用法。首先,我们准备需要用到的目录及文件。命令及结果如下: phl@kernelnewbies:~$ mkdir aufs phl@kernelnewbies:~$ cd aufs/ phl@kernelnewbies:~/aufs$ mkdir rw r1 r2 union phl@kernelnewbies:~/aufs$ echo hello r1 > r1/hellor1.txt phl@kernelnewbies:~/aufs$ echo hello r2 > r2/hellor2.txt phl@kernelnewbies:~/aufs$ echo hello rw > rw/hellorw.txt 下表列出了各个目录的作用。列表如下: rw为aufs文件系统的读写层目录 r1为aufs文件系统的只读层目录 r2为aufs文件系统的只读层目录 union为挂载点,联合加载的aufs文件系统挂载于此目录 下面我们将rw、r1、r2联合加载到union目录。命令如下: phl@kernelnewbies:~/aufs$ sudo mount -t aufs -o dirs=rw:r1:r2 none union -t aufs表示要挂载的文件系统类型为AUFS -o dirs=rw:r1:r2表示要将哪些目录加载到afus文件系统中,多个目录之间以:分隔。目录列表中的第一个目录表示读写层目录 union表示aufs文件系统要挂载的目录 挂载好AUFS文件系统后,我们进入该文件系统,查看其内容。命令及结果如下: phl@kernelnewbies:~/aufs$ cd union/ phl@kernelnewbies:~/aufs/union$ ls hellor1.txt hellor2.txt hellorw.txt 从输出结果来看,rw、r1、r2目录下的内容全部出现在了AUFS文件系统中,该文件系统由rw、r1、r2目录叠加而成。 然后,我们修改这些文件,看看原始的rw、r1、r2目录下的文件是否更改。命令及结果如下: phl@kernelnewbies:~/aufs/union$ echo hello to r1 from union > hellor1.txt phl@kernelnewbies:~/aufs/union$ echo hello to r2 from union > hellor2.txt phl@kernelnewbies:~/aufs/union$ echo hello to rw from union > hellorw.txt 我们返回到aufs目录,直接查看aufs目录下的内容。命令及结果如下: phl@kernelnewbies:~/aufs$ tree . . ├── r1 │ └── hellor1.txt ├── r2 │ └── hellor2.txt ├── rw │ ├── hellor1.txt │ ├── hellor2.txt │ └── hellorw.txt └── union ├── hellor1.txt ├── hellor2.txt └── hellorw.txt 4 directories, 8 files 从输出结果我们可以看到,我们修改的hellor1.txt和hellor2.txt文件分别被拷贝了一份放在读写层目录rw中。我们查看一下这些文件的内容,命令及结果如下: phl@kernelnewbies:~/aufs$ cat r1/hellor1.txt hello r1 phl@kernelnewbies:~/aufs$ cat r2/hellor2.txt hello r2 phl@kernelnewbies:~/aufs$ cat rw/hellor1.txt hello to r1 from union phl@kernelnewbies:~/aufs$ cat rw/hellor2.txt hello to r2 from union phl@kernelnewbies:~/aufs$ cat rw/hellorw.txt hello to rw from union 从输出结果我们看到,用户修改只读层r1、r2中的文件时,这些文件被复制到了读写层,我们修改的是读写层的副本,原只读层中的文件没有变化。用户修改读写层rw中的文件时,修改直接作用于这些文件本身。 docker.sh 在继续之前,我们需要将上一章在ubuntu1604根文件系统中创建的old_root目录删除掉,以保证该根文件系统跟刚制作好时一样。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo rm -rf images/ubuntu1604/old_root 有了以上关于联合加载的介绍,我们就可以将联合加载功能加入到docker.sh中了。联合加载功能将放在container.sh脚本中,带下划线的行是我们为实现联合加载功能而新添的代码。修改后的container.sh如下: #!/bin/bash hostname $container mkdir -p /sys/fs/cgroup/memory/$container echo $$ > /sys/fs/cgroup/memory/$container/cgroup.procs echo $memory > /sys/fs/cgroup/memory/$container/memory.limit_in_bytes mkdir -p $container/rwlayer mount -t aufs -o dirs=$container/rwlayer:./images/$image none $container mkdir -p $container/old_root cd $container pivot_root . ./old_root mount -t proc proc /proc umount -l /old_root exec $program 首先,我们根据容器的名字创建联合加载需要的读写层目录及文件系统挂载目录。命令如下: mkdir -p $container/rwlayer 假如我们传递的容器的名字为dreamland,将创建以下目录: phl@kernelnewbies:~/docker.sh$ tree dreamland/ dreamland/ └── rwlayer 其中dreamland/rwlayer目录为创建的AUFS文件系统的读写层,dreamland目录为AUFS文件系统的挂载点。 然后我们将镜像目录、读写层目录联合加载到挂载点目录。命令如下: mount -t aufs -o dirs=$container/rwlayer:./images/$image none $container 假如容器名字为dreamland,使用的镜像为ubuntu1604根文件系统,dreamland/rwlayer、images/ubuntu1604将被联合加载的dreamland目录。其中,dreamland/rwlayer为AUFS文件系统的读写层,images/ubuntu1604为AUFS文件系统的只读层。 之前我们将老的根文件系统挪到了rootfs/old_root,rootfs代表一个具体的镜像目录。创建old_root目录时直接修改了该镜像。下面我们将老的根文件系统的挂载点目录放在AUFS文件系统中,并将老的根文件系统挪到此处。命令如下: mkdir -p $container/old_root cd $container pivot_root . ./old_root 此时,$container目录本身就是一个挂载点,挂载了AUFS文件系统。因此下面的代码就被移除了: mount --bind images/$image images/$image 现在,我们运行docker.sh,并在/root下创建一个文件。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:/# cd /root root@dreamland:/root# ls root@dreamland:/root# cat /etc/issue > hello.txt root@dreamland:/root# cat hello.txt Ubuntu 16.04 LTS \n \l 启动一个新的Shell窗口,查看一下该容器使用的AUFS文件系统。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo tree dreamland/ dreamland/ └── rwlayer ├── old_root └── root └── hello.txt 2 directories, 1 file 从结果我们可以看到,我们新建的文件及创建的老根文件系统的挂载点目录都出现在了读写层。我们再查看一下新创建的文件。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo cat dreamland/rwlayer/root/hello.txt Ubuntu 16.04 LTS \n \l 文件内容是Ubuntu 16.04的发行版信息。 通过联合加载,我们实现了在容器中的读写不会影响使用的镜像。这样使用ubuntu1604镜像创建多个容器时,彼此之间就不会相互影响了。 卷 卷简介 卷是容器内的一个目录,这个目录可以绕过联合文件系统,提供数据共享(容器所使用的的联合文件系统不应该被主机或其他容器访问)与数据持久化的功能。 举个例子,假如容器有个目录为/data的卷,我们向这个卷写入的内容不会出现在联合文件系统的读写层,而是直接出现在这个目录里。主机与其他容器也可以访问该目录,从而达到数据共享与数据持久化的目的。 卷位于联合文件系统中,通常来说写入该目录的内容会被写入容器的读写层中,那么怎样才能是写入卷的目录直接出现在该目录中,而不是容器读写层呢?其实方法很简单,只要我们将该目录变成一个挂载点就行,变成挂载点后,这个目录中的内容就不属于联合文件系统了,写入该目录的内容自然会保存在挂载到该挂载点的设备中。 docker.sh 有了以上关于卷的介绍,我们就可以将卷功能加入到docker.sh中了。卷功能将放在container.sh脚本中,带下划线的行是我们为实现卷功能而新添的代码。修改后的container.sh脚本如下: #!/bin/bash hostname $container mkdir -p /sys/fs/cgroup/memory/$container echo $$ > /sys/fs/cgroup/memory/$container/cgroup.procs echo $memory > /sys/fs/cgroup/memory/$container/memory.limit_in_bytes mkdir -p $container/rwlayer mount -t aufs -o dirs=$container/rwlayer:./images/$image none $container mkdir -p $volume mkdir -p $container/$volume mount --bind $volume $container/$volume mkdir -p $container/old_root cd $container pivot_root . ./old_root mount -t proc proc /proc umount -l /old_root exec $program 首先,我们根据卷的名字创建主机卷目录,我们在容器内部对卷的修改,都将作用于此目录。命令如下: mkdir -p $volume 然后,我们在容器内部创建同名卷目录,该目录本身会出现在容器的读写层中,因为该目录是在AUFS文件系统中创建的。因为 目录为容器的根目录,所以容器内部卷目录的路径为 container目录为容器的根目录,所以容器内部卷目录的路径为/volume。命令如下: mkdir -p $container/$volume 将主机上的卷目录bind mount到容器内部的卷目录上,这样容器内部对卷目录的修改,都将作用于主机卷目录。命令如下: mount --bind $volume $container/$volume 现在,我们运行docker.sh,并在卷目录(/data1)中创建一个文件。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo ./docker.sh -c run -m 100M -C dreamland -I ubuntu1604 -V data1 -P /bin/bash root@dreamland:/# cd /data1 root@dreamland:/data1# echo "hello to data1 volume from ubuntu16.04" >> hello.txt 启动一个新的Shell窗口,查看一下该容器使用的AUFS文件系统中的内容。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo tree dreamland/ dreamland/ └── rwlayer ├── data1 ├── old_root └── root └── hello.txt 4 directories, 1 file 从结果我们可以看到,我们使用的卷目录被创建在了容器的读写层,但是我们在卷目录中新建的文件却没有出现在读写层中。 我们再来查看一下主机卷目录的内容。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo tree data1/ data1/ └── hello.txt 0 directories, 1 file 从结果我们可以看到,在容器内部对卷目录的修改直接作用在了主机上的卷目录。我们再来查看一下主机卷目录下hello.txt中的内容。命令及结果如下: phl@kernelnewbies:~/docker.sh$ sudo cat data1/hello.txt hello to data1 volume from ubuntu16.04 从结果我们可以看到,该文件的内容与我们在容器内部写入hello.txt的内容一致。 通过卷目录,我们实现了容器之间数据共享与数据持久化的功能。 后记 至此,我们通过一系列的实验对docker的底层技术有了一个感性的认识。我们在使用docker时,也能够对其是如何运作的有了一个大致的了解。当然,这对于掌握docker技术来说还远远不够,有很多知识我们没有涉及,例如user namespace、容器安全、其他的CGroups、虚拟网络等。 编辑整理 ScratchLab 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2022/3/18
articleCard.readMore

node 项目从构建到使用 jenkins + docker + nginx + mysql + redis 自动化部署

概述 这都2019年末了,你还不会 docker吗? 你 low 爆了,我们作为一枚前端,不能说是要精通使用 docker 完成各种事情,但我觉得必须要学会使用 docker 干下面几件事: 部署前端应用 部署nginx 使用docker-compose部署 在容器之间建立联系 Docker 可理解为跑在宿主机上的非常精简、小巧、高度浓缩的虚拟机。 它可以将容器里的进程安稳的在宿主机上运行,之前我也有写过一些关于docker的文章,在这我就不做过多的介绍了,如有需要请自行查看我之前的文章即可,接下来我们通过项目来了解并使用 docker Egg.js ? 在这里我使用 egg.js 来为大家实操一下项目的部署流程。有人会问 egg.js 是什么? 我只能回答这是一款专业级的 node 框架。作为一个有梦想的前端,我们有必要去学习一种后端语言,而作为前端 node 的学习成本相对来说比较低的。 egg.js 这个框架在 node 现有框架中也是比较优秀的,如有需要,大家可以自行学习,我们今天的学习主要还是项目的部署流程,在这我就不给大家做过多的介绍。如有需要,请查阅 官方文档 开始前的准备 docker 与 docker-compose 的安装我就不给大家介绍了。在之前的文章中是有的,也比较详细,作为一位开发人员,我认为这点事情难不倒大家 初始化项目 $ mkdir egg-example && cd egg-example $ npm init egg --type=simple $ npm i 复制代码 创建需要的文件 我们需要在项目根目录创建我们所需要的文件 $ touch Dockerfile $ touch docker-compose.yml $ setup.sh 复制代码 目录结构 egg-project ├── package.json ├── setup.sh (新建) ├── Dockerfile (新建) ├── docker-compose.yml (新建) ├── app | ├── router.js │ ├── controller │ | └── home.js │ ├── service (可选) │ | └── user.js │ ├── middleware (可选) │ | └── response_time.js │ ├── schedule (可选) │ | └── my_task.js ... 复制代码 常用指令 在开始之前我们要学习下常用的一些指令,看下方: 了解流程 安装 jenkins 在安装jenkins我选择了使用docker-compose 首先我们需要在服务器上创建一个目录机构 (具体结构个人自行创建) /home/jenkins - docker-compose.yml - jenkins-home 复制代码 接下来我们来编写 docker-compose.yml 安装jenkins version: '3' # 指定 docker-compose.yml 文件的写法格式 services: # 多个容器集合 docker_jenkins: user: root # 为了避免一些权限问题 在这我使用了root restart: always # 重启方式 image: jenkins/jenkins:lts # 指定服务所使用的镜像 在这里我选择了 LTS (长期支持) container_name: jenkins # 容器名称 ports: # 对外暴露的端口定义 - '8080:8080' - '50000:50000' volumes: # 卷挂载路径 - /home/jenkins/jenkins_home/:/var/jenkins_home # 这是我们一开始创建的目录挂载到容器内的jenkins_home目录 - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker # 这是为了我们可以在容器内使用docker命令 - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose # 同样的这是为了使用docker-compose命令 复制代码 我们需要进入到 jenkins 目录下执行: $ docker-compose up -d 复制代码 配置 不出意外你现在可以打开你的服务器地址 http://xxxxxxx:端口号 就能看到这个界面: 打开你所创建的jenkins目录进入到jenkins-home 进入 secrets 目录 $ cat initialAdminPassword 复制代码 然后把里面的文本复制出来填到管理员密码中 接下来需要安装两个插件 NodeJS Plugin Publish Over SSH 复制代码 然后我们滑到最下方 开始我们的操作 Dockerfile 我们在开始阶段的时候学过一些常用指令,大家应该一眼就可以看得懂这些命令。 加油!! FROM node:10.0-alpine # 镜像版本 # 设置时区 RUN apk --update add tzdata \ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ && apk del tzdata # 创建app目录 RUN mkdir -p /usr/src/node-app/egg-santak # 设置工作目录 WORKDIR /usr/src/node-app/egg-santak # 拷贝package.json文件到工作目录 # !!重要:package.json需要单独添加。 # Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。 # 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。 # 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。 COPY package.json /usr/src/node-app/egg-santak/package.json # 安装npm依赖(使用淘宝的镜像源) # 如果使用的境外服务器,无需使用淘宝的镜像源,即改为`RUN npm i`。 RUN npm i --registry=https://registry.npm.taobao.org # 拷贝所有源代码到工作目录 COPY . /usr/src/node-app/egg-santak # 暴露容器端口 EXPOSE 7001 # 启动node应用 CMD npm start 复制代码 在服务器中创建我们所需要挂载的数据卷 # nginx $ mkdir -p nginx/conf.d nginx/logs # mysql $ mkdir mysql # redis $ mkdir redis 复制代码 然后进入 nginx/conf.d 文件夹中 创建一个后缀为 conf 的文件 $ cd nginx/conf.d $ touch default.conf $ vim default.conf 复制代码 写入以下内容: server { listen 80; listen [::]:80; server_tokens off; root /var/www/html; index index.html index.htm; # 修改为自己的域名 server_name api.lovelp.xin; # 访问 / 路径时执行反向代理 location / { # 这里 nodejs 是 node 容器名 proxy_pass http://nodejs:7001; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; # 后端的Web服务器可以通过 X-Forwarded-For 获取用户真实 IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 允许客户端请求的最大单文件字节数 client_max_body_size 15M; # 缓冲区代理缓冲用户端请求的最大字节数 client_body_buffer_size 128k; } } 复制代码 docker-compose.yml version: '3' services: santak_redis: image: redis:3 # 指定服务镜像 container_name: santak_redis # 容器名称 restart: always # 重启方式 hostname: redis command: redis-server /usr/local/etc/redis/redis.conf --requirepass 123456 --appendonly yes volumes: # 挂载数据卷 - /root/redis/redis.conf:/usr/local/etc/redis/redis.conf ports: # 映射端口 - "6379:6379" networks: # 加入指定网络 - app-network santak_nginx: image: nginx:stable-alpine # 指定服务镜像 container_name: santak_nginx # 容器名称 restart: always # 重启方式 ports: # 映射端口 - "80:80" volumes: # 挂载数据卷 - /etc/localtime:/etc/localtime - /root/nginx/conf.d:/etc/nginx/conf.d - /root/nginx/logs:/var/log/nginx depends_on: # 启动顺序 - nodejs networks: # 加入指定网络 - app-network santak_mysql: image: mysql:5.7 container_name: santak_mysql restart: always ports: # 映射端口 - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_USER=lovelp # 创建lovelp用户 - MYSQL_PASSWORD=mm123321 # 设置lovelp用户的密码 - MYSQL_DATABASE=santak # 创建初始数据库 - TZ=Asia/Shanghai # 设置时区 volumes: # 挂载数据卷 - /root/mysql:/var/lib/mysql # 为了数据持久化 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci networks: # 加入指定网络 - app-network nodejs: build: # 这里指的是我们刚刚撸的 Dockerfile 文件 context: . dockerfile: Dockerfile image: nodejs # 镜像名称 container_name: nodejs # 容器名称 restart: always # 重启方式 depends_on: # 启动顺序 - santak_redis - santak_mysql links: # 容器连接 - santak_redis:santak_redis - santak_mysql:santak_mysql networks: # 加入指定网络 - app-network volumes: certbot-etc: certbot-var: networks: # 实现通信 app-network: driver: bridge 复制代码 在项目中的使用 setup.sh #!/usr/bin/env bash #image_version=`date +%Y%m%d%H%M`; # 关闭容器 docker-compose stop || true; # 删除容器 docker-compose down || true; # 构建镜像 docker-compose build; # 启动并后台运行 docker-compose up -d; # 查看日志 docker logs nodejs; # 对空间进行自动清理 docker system prune -a -f 复制代码 jenkins 创建项目 最后我们就可以愉快的 Build Now 了 在这里我选择的是手动构建。其实jenkins有很多可配置项,比如自动化构建啥的,兴趣使然,大家自行摸索,谢谢大家 整理转载: 掘金

2022/3/16
articleCard.readMore

音乐推荐-曾经我也想过一了百了

现场MV .bbplayer{width: 100%; max-width: 850px; margin: auto} document.getElementById("mmedia-zBuiVHEaNhrSyPzn").style.height=document.getElementById("mmedia-zBuiVHEaNhrSyPzn").scrollWidth*0.76+"px"; window.onresize = function(){ document.getElementById("mmedia-zBuiVHEaNhrSyPzn").style.height=document.getElementById("mmedia-zBuiVHEaNhrSyPzn").scrollWidth*0.76+"px"; }; ## 背景介绍 《曾经我也想过一了百了》是日本歌手中岛美嘉演唱的歌曲,由秋田弘填词和谱曲、出羽良彰编曲,于2013年8月28日发行,收录在中岛美嘉个人专辑《TOUGH 为爱勇敢》中。该歌曲勾勒出向死而生、努力活着的人,让人感到温暖和希望,让因为压力迷茫无助而有轻生想法的人,开始积极拥抱生活。 《曾经我也想过一了百了》由日本摇滚乐队amazarashi的主唱秋田弘创作,创作理念为“为了描写浓烈的希望,必须先描写深层的黑暗”。2010年,迎来出道十周年的中岛美嘉宣布自己因耳咽管开放症暂停一切音乐活动。在疾病的影响下,歌唱对她而言变得无比艰难。2011年,她携单曲《Dear》复出,但复出后始终经历着状态的起伏和媒体的质疑。 中岛美嘉起先向amazarashi提出合作请求,希望乐队能为自己创作一首节奏明快的歌曲,但随后秋田弘向她播放了乐队一首未发行的样本歌曲,并认为该曲很适合由她来演唱。收到该曲时,中岛美嘉起先感到十分惊讶,但听到最后泪流不止,感到自己的心变得柔和,便立即要求演唱该曲。录制过程中,中岛美嘉将自己的心声融入到了该曲中,希望能将力量传达给低迷苦闷的听众。 ## 中文翻唱 var vZNSJKEjQZDJxExL_options = JSON.parse('{\"autoplay\":false,\"audio\":[{\"name\":\"曾经我也想过一了百了\",\"artist\":\"一么\",\"url\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/曾经我也想过一了百了-一么.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/僕が死のうと思ったのは.jpg\",\"lrc\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/曾经我也想过一了百了-一么.lrc\"},{\"name\":\"僕が死のうと思ったのは\",\"artist\":\"中岛美嘉\",\"url\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/01%20僕が死のうと思ったのは.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/僕が死のうと思ったのは.jpg\",\"lrc\":\"https://cdn.17lai.fun/media/music/僕が死のうと思ったのは/01%20僕が死のうと思ったのは.lrc\"}],\"volume\":0.8}'); vZNSJKEjQZDJxExL_options.container = document.getElementById("mmedia-vZNSJKEjQZDJxExL");HEXO_MMEDIA_DATA.css.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.css");HEXO_MMEDIA_DATA.js.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.js");HEXO_MMEDIA_DATA.aplayerData.push(vZNSJKEjQZDJxExL_options); LRC歌词 中文翻译 [00:02.09]作曲 : 秋田 ひろむ [00:02.64]曾经我也想过一了百了 [00:03.21]原唱:中岛美嘉 [00:04.46] [00:29.85]曾经我 也想过 一了百了 [00:34.79]因为看见蜷缩的猫 [00:37.40]在码头望着远方 [00:40.40]海浪拍打在岸上 [00:43.44]一阵又一阵侵踏 [00:46.22]希望那些过往都消失 [00:49.38]不再回望 [00:52.43]曾经我 也想过 [00:54.82]一了百了 [00:57.46]是因为生日的那天 [01:00.10]杏花 又开放 [01:03.75]阳光灿烂树荫下 [01:06.41]落花已沉睡安详 [01:09.84]是否我也 能化作尘土 [01:12.16]不再流浪 [01:15.76]仍放抽屉里过期的糖 [01:18.28]迷路的单车被留在回家路上 [01:21.27]还有海边抛弃的避风港 [01:23.88]全都提醒 我和他们一样 [01:26.75]昨天和今天的画面不断浮现 [01:29.74]明天 渴望能不能有 [01:31.54]新的改变 [01:32.90]不能沮丧 我知道啊 [01:35.55]可是啊 [01:40.88]曾经我 也想过 一了百了 [01:46.24]身边一切都像在问我 [01:49.19]过得好不好 [01:52.28]泪不能停止的流 [01:55.05]流进心底的荒漠 [01:58.28]这颗心中的模样 [02:00.17]早空如一具躯壳 [02:26.84]曾经我 也想过 一了百了 [02:32.71]因为我的存在 [02:34.23]总让别人失望 [02:37.98]不曾拥有就不怕 [02:40.80]关于人与人的伤 [02:44.18]这么简单的道理 [02:45.96]我也只会搞砸 [02:49.80]曾经我 也想过 一了百了 [02:55.49]是因为墙上 [02:56.52]那张骄傲的自画像 [03:00.96]无力反驳地跪下 [03:03.66]只说的出一句话 [03:06.99]生而为人的我 [03:08.61]真的对不起呀 [03:12.75]房间里闪烁着荧幕微光 [03:15.56]伴随着屋外夜色的声音嘈杂 [03:18.43]电话那头传来窒息的话 [03:21.28]刺痛在笼中 [03:22.44]备受折磨的时间啊 [03:24.25]黑暗中我装备 [03:25.58]唐吉轲德的毅力 [03:26.89]对抗看不见的敌人 [03:28.38]摧毁我的决心 [03:29.85]不要害怕我知道啊可是啊 [03:38.04]曾经我也想过一了百了 [03:44.29]为何人们都说我无可救药 [03:49.69]不强求能明白我 [03:52.60]不奢望时间倒流 [03:55.70]因为很久很久以前我曾爱过 [04:00.86]曾经我 也想过 一了百了 [04:06.89]是因为我该那样 [04:08.43]灿烂那样美好 [04:12.49]一味消极着过去 [04:14.95]离去的念头缠绕 [04:17.29]闭上眼能感受到 [04:20.04]更好的明天来到 [04:24.35]茫茫人海中的你 [04:27.01]泪光中微笑的你 [04:30.26]在我耳边温柔唱起这首歌曲 原版歌词 [00:00.10]僕が死のうと思ったのは (曾经我也想过一了百了) - 中島美嘉 (なかしま みか) [00:00.20]词:秋田ひろむ [00:00.30]曲:秋田ひろむ [00:00.40]编曲:出羽良彰 [00:27.95]僕が死のうと思ったのは [00:33.83]ウミネコが桟橋で鳴いたから [00:39.20]波の随意に浮かんで消える [00:45.33]過去も啄ばんで飛んでいけ [00:50.70]僕が死のうと思ったのは [00:56.52]誕生日に杏の花が咲いたから [01:02.22]その木漏れ日でうたた寝したら [01:08.09]虫の死骸と土になれるかな [01:14.09]薄荷飴 漁港の灯台 [01:17.05]錆びたアーチ橋 捨てた自転車 [01:19.74]木造の駅のストーブの前で [01:22.74]どこにも旅立てない心 [01:25.61]今日はまるで昨日みたいだ [01:28.30]明日を変えるなら今日を変えなきゃ [01:31.56]分かってる 分かってる けれど [01:39.71]僕が死のうと思ったのは [01:44.89]心が空っぽになったから [01:50.71]満たされないと泣いているのは [01:56.39]きっと満たされたいと願うから [02:25.49]僕が死のうと思ったのは [02:30.69]靴紐が解けたから [02:36.57]結びなおすのは苦手なんだよ [02:42.25]人との繋がりもまた然り [02:47.90]僕が死のうと思ったのは [02:53.65]少年が僕を見つめていたから [02:59.30]ベッドの上で土下座してるよ [03:05.12]あの日の僕にごめんなさいと [03:11.43]パソコンの薄明かり [03:14.05]上階の部屋の生活音 [03:16.80]インターフォンのチャイムの音 [03:19.80]耳を塞ぐ鳥かごの少年 [03:22.87]見えない敵と戦ってる [03:25.43]六畳一間のドンキホーテ [03:28.30]ゴールはどうせ醜いものさ [03:36.74]僕が死のうと思ったのは [03:42.05]冷たい人と言われたから [03:47.94]愛されたいと泣いているのは [03:53.63]人の温もりを知ってしまったから [04:22.79]僕が死のうと思ったのは [04:27.91]あなたが綺麗に笑うから [04:33.49]死ぬことばかり考えてしまうのは [04:39.62]きっと生きる事に真面目すぎるから [04:45.43]僕が死のうと思ったのは [04:50.70]まだあなたに出会ってなかったから [04:56.51]あなたのような人が生まれた [05:02.09]世界を少し好きになったよ [05:07.96]あなたのような人が生きてる [05:13.65]世界に少し期待するよ 系列教程 全部文章RSS订阅 音乐推荐 音乐推荐-爱是你我 音乐推荐-曾经我也想过一了百了 从文学的角度,分析韩红的《天亮了》 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版

2022/3/14
articleCard.readMore

私人在线音乐服务器搭建与使用介绍

多种音乐播放实现方式 页面内插入音乐列表。Aplayer实现 单独页面音乐列表。Aplayer实现 音乐Docker。在线云音乐 原作者DMCA原因不再维护,如果你想自己部署,需要修改原作者docker内部代码。 后面提供另一个Fork的版本,不过也被DMCA干掉了,不过功能比上面多一些,基本直接可用! 音乐Docker Mstream docker。 音乐Docker Logitech Media Server。Github 多用户音乐分享、播放,在线,分类等功能。 Aplayer 在线音乐 博文页面内插入音乐列表 var mWAGplXKJhNcsltB_options = JSON.parse('{\"volume\":0.66,\"audio\":[{\"name\":\"Hotel California\",\"artist\":\"Camille and Kennerly\",\"url\":\"https://cdn.17lai.fun/media/music/Hotel%20California/01%20Hotel%20California.mp3\",\"lrc\":\"https://cdn.17lai.fun/media/music/Hotel%20California/01%20Hotel%20California.lrc\",\"cover\":\"https://cdn.17lai.fun/media/music/Hotel%20California/Hotel%20California.webp\"}]}'); mWAGplXKJhNcsltB_options.container = document.getElementById("mmedia-mWAGplXKJhNcsltB");HEXO_MMEDIA_DATA.css.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.css");HEXO_MMEDIA_DATA.js.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.js");HEXO_MMEDIA_DATA.aplayerData.push(mWAGplXKJhNcsltB_options); var nUroTOJtKoppmbaC_options = JSON.parse('{\"autoplay\":false,\"audio\":[{\"name\":\"Hotel California\",\"artist\":\"Camille and Kennerly\",\"url\":\"https://cdn.17lai.fun/media/music/Hotel%20California/01%20Hotel%20California.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/Hotel%20California/Hotel%20California.webp\",\"lrc\":\"https://cdn.17lai.fun/media/music/Hotel%20California/01%20Hotel%20California.lrc\",\"theme\":\"#ebd0c2\"},{\"name\":\"Sold Out\",\"artist\":\"Diamonds\",\"url\":\"https://cdn.17lai.fun/media/music/Diamonds/05%20Sold%20Out.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/Diamonds/Diamonds.jpg\",\"theme\":\"#ebd0c2\"},{\"name\":\"The Final Bell\",\"artist\":\"Rocky_ Original Motion Picture Score\",\"url\":\"https://cdn.17lai.fun/media/music/Rocky_%20Original%20Motion%20Picture%20Score/12%20Bill%20Conti%20-%20The%20Final%20Bell.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/Rocky_%20Original%20Motion%20Picture%20Score/Rocky_%20Original%20Motion%20Picture%20Score.jpg\",\"theme\":\"#ebd0c2\"},{\"name\":\" Croatian Rhapsody\",\"artist\":\"The Piano Player\",\"url\":\"https://cdn.17lai.fun/media/music/The%20Piano%20Player/11%20Croatian%20Rhapsody.mp3\",\"cover\":\"https://cdn.17lai.fun/media/music/The%20Piano%20Player/The%20Piano%20Player.jpg\",\"theme\":\"#ebd0c2\"}],\"volume\":0.8}'); nUroTOJtKoppmbaC_options.container = document.getElementById("mmedia-nUroTOJtKoppmbaC");HEXO_MMEDIA_DATA.css.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.css");HEXO_MMEDIA_DATA.js.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.js");HEXO_MMEDIA_DATA.aplayerData.push(nUroTOJtKoppmbaC_options); 单独Aplayer音乐页面 直接戳这里 -> Musics 在线云音乐 私人云音乐 研究学习使用 不对外公开发布,研究学习用。 入口 公开在线云音乐服务网页版。 可以与网易云音乐UID同步! DockerHub 与网易云同步 网易云UID在登陆 https://music.163.com/ 后 点击右上角图标的我的主页 https://music.163.com/#/user/home?id=617xxxxx0 home?id= 后面的数字就是你的UID。登录后,可以同步个人列表! 在线播放可以配合IDM下载各个平台的音乐,在放入后面介绍的Docker播放器中,如此,可搭建自己的音乐播放器! 吐槽一下,QQ音乐在线版和这个神似,基本可以肯定就是抄袭这个的! 另一个 Fork 版本 研究学习用途! 不要公开访问链接!一切后果使用者自负!加上访问密码自用! 支持音乐搜索,音乐下载,歌词下载,封面下载 支持网易云歌单同步 支持自定义播放列表 version: '3' services: music: image: bloodstar/music-player container_name: music hostname: music restart: always environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai volumes: - /docker/music/cache/:/var/www/html/cache/ - /docker/music/temp/:/var/www/html/temp/ # 音乐下载功能需要设置 ports: - "264:264" 博主私人定制版本,推荐使用 私人音乐服务器 入口 所有音乐作者,专辑,演唱者元数据刮削。 rclone挂载webdav网盘存储音乐文件。 cloudflare parterner加速。 私人使用,不对外公开。 在线音乐播放 Mstream SelfHost 支持。Docker 部署! Github: Mstream docker。 浏览器界面支持。 支持DJ模式 在音乐库中随机选择音乐播放。 选择症患者救星。 Android支持 其它特性 转码支持 遥控器支持 播放列表 等等 在线音乐播放 navidrome 前面介绍的Docker中下载好音乐后,刮削好,使用Navidrome在线播放是最佳体验! Dockerhub navidrome Github navidrome Docker compose # This is just an example. Customize it to your needs. version: "3" services: navidrome: image: deluan/navidrome:latest ports: - "4533:4533" environment: # Optional: put your config options customization here. Examples: ND_SCANSCHEDULE: 1h ND_LOGLEVEL: info ND_BASEURL: "" volumes: - "./data:/data" - "/path/to/your/music/folder:/music:ro" 在线Demo 登录用户名和密码 User: demo Password: demo Mstream文件路径管理更完善,Navidrome界面更现代化,有封面,更美观! 目前博主使用中! Logitech Media Server Dockerhub LMS 另一个音乐播放器,Docker管理音乐文件,音乐上传到指定目录。 博主试用了一段时间后,感觉管理音乐文件不方便,就弃用了。 docker run -d \ --name lms \ -p 9000:9000 \ -p 9090:9090 \ -p 3483:3483 \ -p 3483:3483/udp \ -v /etc/localtime:/etc/localtime:ro \ -v <local-state-dir>:/srv/squeezebox \ -v <audio-dir>:/srv/music \ apnar/logitech-media-server 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/11/7
articleCard.readMore

自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式)

前言 对于经常阅读的人来说,制作本地电子书,算是刚需了。网上的很多教程都不太好用,所以我特地整理出一个详细的教程。亲测有效,一劳永逸。 当你意外发现某个宝藏公众号时,想要集中阅读上面的每一篇文章,恨不得一口气看完,你会怎么做呢?你可能会把它添加到“微信读书”App 的书架上: 但上面这种曲线救国的方式并非最佳,仍然不尽人意,存在不少问题。 我知道,现在有很多的第三方服务,可以将任意公众号的文章制作成电子书,我试过很多次,但都是付费的。一听说要钱,你又不干了: 再列举一种场景:当你在 GitHub 上发现一个很全面很丰富的项目文档时,仿佛发现了新大陆。可 GitHub 网站的服务器在国外,国内的访问速度实在感人,你想要把它下载到本地查看,会怎么做呢?你估计会选择git clone或者直接选择“Download ZIP”,然后用 Typora 或者 VS Code 软件打开这个项目文档,在本地查看: 总之,你能想到的方式,我都想到了,而且都尝试过。 现在的需求就是,如果你经常阅读网上的资料,肯定会有这样一个需求:怎么把这些几百页、甚至几千页的内容整理成 PDF、ePub、mobi等格式的电子书呢? 要么花钱请别人做,要么自己做。 今天这篇文章,就是来告诉你”自己动手制作 PDF、ePub、mobi 等格式电子书“的最佳方式。如果你是码农出身,下面讲的这些步骤,根本难不倒你。如果你不是码农出身,也没关系,只要你有一台电脑,跟着我讲的教程研究下去,肯定能搞定。 问题的关键不在于难不难、会不会,而是在于你是不是爱折腾。 工具篇 bloodstar/gitbook-builder Gitbook Docker 集成开发环境。支持CJK,附带常用工具。使用它,下面一些列环境配置都可以省略了。开箱即用。 Usage Read the official GitBook Toolchain Documentation documentation GitbookIO/gitbook first. # init docker run --rm -v "$PWD:/gitbook" -p 4000:4000 bloodstar/gitbook-builder gitbook init # serve docker run --rm -v "$PWD:/gitbook" -p 4000:4000 bloodstar/gitbook-builder gitbook serve # build docker run --rm -v "$PWD:/gitbook" -p 4000:4000 bloodstar/gitbook-builder gitbook build For short, you can use alias for the long command line text. Place the alias statement in your .bashrc or .zshrc. alias gitbook='docker run --rm -v "$PWD":/gitbook -p 4000:4000 bloodstar/gitbook-builder gitbook' # init gitbook init # serve gitbook serve # build gitbook build # pdf output gitbook pdf . Integrate with Gitlab CI This docker image is originally designed for generating ebook with Gitlab CI. You could configure your Gitlab CI as following: before_script: - env - export LC_ALL=zh_TW.UTF-8 stages: - build ebook: stage: build script: - gitbook pdf artifacts: paths: - book.pdf only: - master tags: - gitbook image: bloodstar/gitbook-builder:latest allow_failure: true 制作电子书的具体步骤 整体流程 先说一下整体步骤: (1)安装 gitbook 工具。 (2)安装 calibre 软件,配置 ebook-convert工具。 (3)将md格式的多个文件素材导出为电子书(支持 PDF、ePub、mobi 等格式)。 (4)高级进阶:配置电子书的目录、封面、页眉页脚等。 整理流程如下: 接下来我们看看详细的完整步骤。 步骤 1:通过 npm 安装 gitbook-cli 安装命令如下: npm install -g gitbook-cli 安装成功之后,再执行gitbook -V命令确认是否安装成功: gitbook -V CLI version: 2.3.2 GitBook version: 3.2.3 备注:如果你不知道 npm 是什么,可以自行查阅如何安装 Node.js 和 npm 环境。 步骤 2:安装 ebook-convert(针对 Windows 用户) ebook-convert 是能够自由转化格式的一个命令行工具,已经包含在 calibre 软件里面了。 (1)安装 calibre 软件。calibre 的官网如下:(我们可以去官网下载安装) https://calibre-ebook.com/ (2)在终端输入如下命令,验证 ebook-convert 是否能正常使用: 如果输入上面的命令后提示错误,说明你还需要将 calibre 的安装目录添加到系统的环境变量中。 步骤 2:安装 ebook-convert(针对 Mac 用户) ebook-convert 是能够自由转化格式的一个命令行工具,已经包含在 calibre 软件里面了。 (1)安装 calibre 软件。calibre 的官网如下:(我们可以去官网下载安装) https://calibre-ebook.com/ (2)配置 ebook-convert。针对 Mac 系统,需要执行如下命令,把 ebook-convert 软链接到 bin 目录: sudo ln -s /Applications/calibre.app/Contents/MacOS/ebook-convert /usr/bin 执行上面的命令后,如果出现Operation not permitted异常,说明系统权限限制,此时需要配置环境变量。 (3)环境变量配置: vim ~/.bash_profile # 将下面这两行配置,添加到 .bash_profile 文件中 export EBOOK_PATH=/Applications/calibre.app/Contents/MacOS export PATH=$PATH:$EBOOK_PATH 备注:可以自行研究下,在命令行环境,如何通过 vim 编辑文件。 然后刷新一下刚刚的配置: 验证ebook-convert是否能正常使用: 步骤 3:配置电子书的目录 本地新建一个空的文件夹,作为我们的电子书项目。文件夹的名字随便起,但建议用英文命名。 (1)项目初始化。 在当前项目下,执行如下命令,进行初始化: gitbook init 此时,项目下会自动生成如下两个文件:(非常重要,必不可少) README.md:书籍的简介放在这个文件里。 SUMMARY.md:书籍的目录结构在这里配置。 这两个文件创建后,内容为空白,可使用 Markdown 语言自定义内容。 (2)配置电子书的目录。 我们先把本地的 markdown 文件(也就是我们的电子书素材)放到项目中,然后在SUMMARY.md文件中配置电子书的目录。 比如说, 我的项目中有下面这些文件: 那么,我在SUMMARY.md文件中就要这样配置: # 目录 * [README](./README.md) * [00-前端工具](00-前端工具/0-README.md) * [01-VS Code的使用](00-前端工具/01-VS Code的使用.md) * [02-Git的使用](00-前端工具/02-Git的使用.md) * [01-HTML](01-HTML/0-README.md) * [01-认识Web和Web标准](01-HTML/01-认识Web和Web标准.md) * [02-浏览器的介绍](01-HTML/02-浏览器的介绍.md) * [03-初识HTML](01-HTML/03-初识HTML.md) * [02-CSS基础](02-CSS基础/0-README.md) * [01-CSS属性:字体属性和文本属性](02-CSS基础/01-CSS属性:字体属性和文本属性.md) * [02-CSS属性:背景属性](02-CSS基础/02-CSS属性:背景属性.md) * [03-CSS样式表和选择器](02-CSS基础/03-CSS样式表和选择器.md) * [03-JavaScript基础](03-JavaScript基础/0-README.md) * [00-编程语言](03-JavaScript基础/00-编程语言.md) * [01-JS简介](03-JavaScript基础/01-JS简介.md) * [02-变量](03-JavaScript基础/02-变量.md) * [03-变量的数据类型:基本数据类型和引用数据类型](03-JavaScript基础/03-变量的数据类型:基本数据类型和引用数据类型.md) 制作成的目录,将会是下面这种效果: 步骤 4:导出电子书 (1)本地预览电子书: 执行上方命令后,工具会对项目里的 Markdown 格式的文件进行转换,默认转换为 html 格式,最后提示 Serving book on http://localhost:4000。 我们打开浏览器输入http://localhost:4000,预览一下电子书的效果: (2)制作并导出电子书。接下来就是见证奇迹的时刻。 生成 PDF 格式的电子书:(PDF 是最常见的文档格式) gitbook pdf ./ ./mybook.pdf 生成 epub 格式的电子书:(epub 是最常见、最通用的电子书格式) gitbook epub ./ ./mybook.epub 生成 mobi 格式的电子书:(mobi 格式可以在 kindle 中打开) gitbook mobi ./ ./mybook.mobi 上面这三种格式的电子书生成之后,项目里会看到这三个新增的文件: 我们把电子书打开,验收一下成果。 打开 pdf 电子书看看效果: 打开 epub 电子书看看效果: 怎么样,自制电子书就这样做好了,是不是很有成就感? 更详细参考教程: GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 制作电子书的高级配置 电子书做好之后,我猜你肯定想进一步做个性化配置,比如:怎么加封面?怎么修改页眉页脚?还有其他的一些配置。 我们来看看亲手制作的电子书,有哪些常见的高级配置。 制作书籍封面 为了让书籍显示得更加优雅,我们可以指定一个自定义的封面。操作如下: 在项目的根目录下准备好 cover.jpg (大封面)和 cover_small.jpg (小封面)这两种封面图片。注意,图片的文件名和后缀名必须严格按照这句话来。 GitBook 的官方文档建议: cover.jpg (大封面)的尺寸为 1800x2360 像素,cover_small.jpg(小封面)的尺寸为 200x262 像素。图片的制作,建议遵循如下规范: 没有边框 清晰可见的书本标题 任何重要的文字在小封面中应该清晰可见 book.json :电子书的各种配置 我们可以在项目的根目录下新建一个文件book.json(注意,文件名是book,后缀名是json),这个book.json就是电子书的配置文件,可以在里面填一些常见的配置。 关于 book.json 的配置项有很多,我们可以在网上搜索“GitBook book.json”找到。这里大致列举一些。 1、常规配置如下: 配置 book.json 的示例如下: { "title": "前端入门和进阶图文教程", "description": "前端入门到进阶图文教程,超详细的Web前端学习笔记。从零开始学前端,做一名精致优雅的前端工程师。公众号「千古壹号」作者。", "author": "千古壹号", "language": "zh-hans", "gitbook": "3.2.3", "root": "." } 备注:上面的root根目录为当前目录,使用默认的就好,此项可以删掉,这里仅做演示。 2、pdf 的配置如下:(使用 book.json 中的一组选项来定制 PDF 输出) | 配置项 | 描述 | | ----------------- | ------------------------------------------------------------ | | pdf.pageNumbers | 将页码添加到每个页面的底部(默认为 true) | | pdf.fontSize | 基本字体大小(默认是 12) | | pdf.fontFamily | 基本字体样式(默认是 Arial) | | pdf.paperSize | 页面尺寸,选项有: a0、a1、 a2、 a3、a4、a5、a6、b0、b1、b2、b3、b4、b5、b6、legal、letter (默认值是 a4) | | pdf.margin.top | 上边距(默认值是 56) | | pdf.margin.bottom | 下边距(默认值是 56) | | pdf.margin.left | 左边距(默认值是 62) | | pdf.margin.right | 右边距(默认值是 62) | 定制 PDF 文档输出格式的示例代码如下: { "pdf": { "pageNumbers": false, "fontSize": 12, "paperSize": "a4", "margin": { "top": 36, "bottom": 36, "left": 62, "right": 62 } } } 备注:如果你不需要对输出的 pdf 做任何特定的配置,则不需要添加上面的内容,让 pdf 的输出格式保持默认就好。 3、plugins 插件: 插件及其配置在 book.json 中指定,让电子书的配置能力更加强大。 通过插件,我们可以做很多事情,比如:修改页眉页脚、自动生成并显示图片的标题等。 另外,针对在线版的GitBook电子书,也有很多插件,这里列举几个: 自带的search插件不支持中文搜索,使用起来非常不方便,还好search-pro插件横空出世,让搜索功能焕发出新的生机。插件地址:https://github.com/gitbook-plugins/gitbook-plugin-search-pro 默认侧边栏宽度是不能够调节的,如果想通过拖拽的方式自由调节侧边栏宽度,可以使用插件splitter。插件地址:https://github.com/yoshidax/gitbook-plugin-splitter donate插件支持定义和显示支付宝和微信打赏。插件地址:http://github.com/willin/gitbook-plugin-donate 关于插件的具体配置,感兴趣的同学可以自行研究下。 自动生成目录(重要) 如果你的电子书素材里有很多 markdown 文件,那么,如何将多个 markdown 文件的文件名,在SUMMARY.md里快速生成对应的目录? 难道要一个一个地手动 copy 吗?这不可能。 说白了,这个需求就是:如何自动生成电子书的目录?改变世界的程序员用「脚本」就能搞定,一键执行。 网上有很多好用的脚本,我给你推荐一个亲测好用的脚本: GitBook 自动生成目录的脚本:https://github.com/fushenghua/gitbook-plugin-summary 操作方法很简单,把上面这个链接中的项目下载下来,进入到这个项目的目录,执行 $ python gitbook-plugin-summary.py dirPath 即可自动生成电子书的目录,亲测有效。备注:这里的dirPath指的是你的电子书目录的绝对路径。 对了,在执行上面这个脚本之前,记得先安装 Python 环境。 电子书用什么软件打开 用什么软件打开 PDF Windows 平台:可以用「福昕阅读器」或者「Acrobat Reader DC」。「福昕阅读器」既有 Windows 平台,也有 Mac 平台。 Mac 平台:可以用自带的「预览」打开。 其实,不管你用的是 Windows 电脑还是 Mac 电脑,你都可以用 Chrome 浏览器打开 PDF。 iPhone 或 iPad平台:可以用自带的「iBooks」打开,或者用「WPS Office」打开。也可以用第三方软件「GoodReader」,不过需要 40 人民币。 Android 手机:可以用「WPS Office」等第三方办公软件打开。 用什么软件阅读 ePub 电子书 Windows 平台:可以用「calibre」软件阅读 epub 电子书。 Mac & iPhone & iPad 平台:用自带的「iBooks」阅读即可。iBooks 可以非常方便地对电子书进行标注和搜索,无疑是体验最好的 ePub 电子书阅读软件。 Android 手机:可以用「多看阅读」App 来阅读 epub 格式电子书。 用什么方式阅读 mobi 电子书 kindle 电子书有两种常见的电子书格式:「mobi」格式和「azw3」格式。 针对 mobi 格式的电子书,你既可以通过邮件的形式将其发送到 kindle 阅读器(可以自行网上查一下相关教程),也可以将其拷贝到 kindle 阅读器(是连接 usb 进行拷贝)。 针对 azw3 格式的电子书,就只能通过拷贝的形式(是连接 usb 拷贝)传输到 kindle 阅读器。 小结 我在 2017 年 1 月写过一篇电子书科普的文章,快三年过去了,如今回过头来看,那篇文章一点也不过时,不妨看看:《电子书有哪些常见格式?以及该怎样阅读它》 最后一段 如果你一时半会儿找不到可用的素材来制作电子书,可以拿我的项目练练手。项目地址: https://github.com/qianguyihao/web 不瞒你说,这篇文章,我在一年多以前就写好了初稿并放在了 GitHub 上,当时专门折腾过一次。 最近几天,我突然又有了制作电子书的需求。一年多过去了,我还以为有啥新的方法可以试试,然而我在网上找了一圈,好用的方法还是没变。所以,我今天整理一下发出来,希望让更多人看到。 其他的各种自制电子书的方法我都试过了,都不太好使,唯独 GitBook + calibre 是最佳选择,信我没错! https://github.com/honkit/honkit gitbook 已经不再维护了,honkit是社区维护版本,很容易迁移 参考链接 GITBOOK 使用:https://kuang.netlify.app/blog/gitbook.htmlbook.html GitBook 制作 Kindle 电子书详细教程:https://github.com/fushenghua/gitbook-plugin-summary/blob/master/gitbook-guide.md gitbook-plugin-summary 工具(自动生成目录):https://github.com/fushenghua/gitbook-plugin-summary gitbook-plugin-atoc(自动生成目录的插件):https://github.com/willin/gitbook-plugin-atoc 自动生成目录:https://github.com/mofhu/GitBook-auto-summary 使用 Gitbook 打造你的电子书:https://juejin.im/post/6844903793033740302 书籍《了不起的 Markdown》的第 8 章:自由地写作——GitBook gitbook 的 book.json 配置示例:https://blog.ujwd.cn/archives/349 关于更加详细的 book.json 文件配置:https://zhousiwei.gitee.io/mybook/notes/gitbook_config.html GitBook 简明使用教程:https://www.phpjieshuo.com/archives/153/ gitbook 入门教程之导出电子书:https://juejin.im/post/5caa0fb46fb9a05e5a2e53b3 GitBook 插件整理 - book.json 配置:https://www.cnblogs.com/mingyue5826/p/10307051.html 如何把 Markdown 文件批量转换为 PDF(不好用):https://sspai.com/post/47110 自己动手制作电子书的最佳方式 系列教程 全部文章RSS订阅 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2021/11/2
articleCard.readMore

CI/CD与Git Flow与GitLab

CI/CD + Git Flow + GitLab 的整体工作流程记录。主要介绍一下 GitLab CI 相关功能,并通过 GitLab CI 实现自动化构建项目。项目中所用的示例项目已经上传到了 GitHub 一、Git Flow 简介 Git Flow 定义了一个围绕项目开发发布的严格 git 分支模型,用于管理多人协作的大型项目中实现高效的协作开发;Git Flow 分支模型最早起源于 Vincent Driessen 的 A successful Git branching model 文章;随着时间发展,Git Flow 大致分为三种: Git Flow: 最原始的 Git Flow 分支模型 Github Flow: Git Flow 的简化版,专门配合持续发布 GitLab Flow: Git Flow 与 Github Flow 的结合版 关于三种 Git Flow 区别详情可参考 Git 工作流程 二、 Git Flow 流程 Github Flow 和 GitLab Flow 对于持续发布支持比较好,但是原始版本的 Git Flow 对于传统的按照版本发布更加友好一些,所以以下主要说明以下 Git Flow 的工作流程;Git Flow 主要分支模型如下 在整个分支模型中 存在两个长期分支: develop 和 master,其中 develop 分支为开发分支,master 为生产分支;master 代码始终保持随时可以部署到线上的状态;develop 分支用于合并最新提交的功能性代码;具体的分支定义如下 master: 生产代码,始终保持可以直接部署生产的状态 develop: 开发分支,每次合并最新功能代码到此分支 feature: 新功能分支,所有新开发的功能将采用 feature/xxxx 形式命名分支 hotfixes: 紧急修复补丁分支,当新功能部署到了线上出现了严重 bug 需要紧急修复时,则创建 hotfixes/xxxx 形式命名的分支 release: 稳定版分支,当完成大版本变动后,应该创建 release/xxxx 分支 在整个分支模型中,develop 分支为最上游分支,会不断有新的 feature 合并入 develop 分支,当功能开发达到完成所有版本需求时,则从 develop 分支创建 release 分支,release 后如没有发现其他问题,最终 release 会被合并到 master 分支以完成线上部署 三、Git Flow 工具 针对于 Git Flow,其手动操作 git 命令可能过于繁琐,所以后来有了 git-flow 工具;git-flow 是一个 git 扩展集,按 Vincent Driessen 的分支模型提供高层次的库操作;使用 git-flow 工具可以以更加简单的命令完成对 Vincent Driessen 分支模型的实践; git-flow 备忘清单,该文章详细描述了 git-flow 工具的使用方式 还有另一个工具是 git-extras,该工具没有 git-flow 那么简单化,不过其提供更加强大的命令支持 四、Git Commit Message 在整个 Git Flow 中,commit message 也是必不可少的一部分;一个良好且统一的 commit message 有助于代码审计以及 review 等;目前使用最广泛的写法是 Angular 社区规范,该规范大中 commit message 格式大致如下: <type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer>Copy 总体格式大致分为 3 部分,首行主要 3 个组成部分: type: 本次提交类型 scope: 本次提交影响范围,一般标明影响版本号或者具体的范围如 $browser, $compile, $rootScope, ngHref, ngClick, ngView, etc... subject: 本次提交简短说明 关于 type 提交类型,有如下几种值: feat:新功能(feature) fix:修补 bug docs:文档(documentation) style: 格式(不影响代码运行的变动) refactor:重构(即不是新增功能,也不是修改 bug 的代码变动) test:增加测试 chore:构建过程或辅助工具的变动 中间的 body 部分是对本次提交的详细描述信息,底部的 footer 部分一般分为两种情况: 不兼容变动: 如果出现不兼容变动,则以 BREAKING CHANGE: 开头,后面跟上不兼容变动的具体描述和解决办法 关闭 issue: 如果该 commit 针对某个 issue,并且可以将其关闭,则可以在其中指定关闭的 issue,如 Close #9527,#9528 不过 footer 部分也有特殊情况,如回滚某次提交,则以 revert: 开头,后面紧跟 commit 信息和具体描述;还有时某些 commit 只是解决了 某个 issue 的一部分问题,这是可以使用 refs ISSUE 的方式来引用该 issue 五、Git Commit Message 工具 针对 Git 的 commit message 目前已经有了成熟的生成工具,比较有名的为 commitizen-cli 工具,其采用 node.js 编写,执行 git cz 命令能够自动生成符合 Angular 社区规范的 commit message;不过由于其使用 node.js 编写,所以安装前需要安装 node.js,因此可能不适合其他非 node.js 的项目使用;这里推荐一个基于 shell 编写的 Git-toolkit,安装此工具后执行 git ci 命令进行提交将会产生交互式生成 Angular git commit message 格式的提交说明,截图如下: 六、GitLab 整合 以上 Git Flow 所有操作介绍的都是在本地操作,而正常我们在工作中都是基于 GitLab 搭建私有 Git 仓库来进行协同开发的,以下简述以下 Git Flow 配合 GitLab 的流程 6.1、开发 features 当开发一个新功能时流程如下: 本地 git flow feature start xxxx 开启一个 feature 新分支 git flow feature publish xxxx 将此分支推送到远端以便他人获取 完成开发后 GitLab 上向 develop 分支发起合并请求 CI sonar 等质量检测工具扫描,其他用户 review 代码 确认无误后 master 权限用户合并其到 develop 分支 部署到测试环境以便测试组测试 如果测试不通过,则继续基于此分支开发,直到该功能开发完成 6.2、创建 release 当一定量的 feature 开发完成并合并到 develop 后,如所有 feature 都测试通过并满足版本需求,则可以创建 release 版本分支;release 分支流程如下 本地 git flow release start xxxx 开启 release 分支 git flow release publish xxxx 将其推送到远端以便他人获取 继续进行完整性测试,出现问题继续修复,直到 release 完全稳定 从 release 分支向 master、develop 分支分别发起合并请求 master 合并后创建对应的 release 标签,并部署生产环境 develop 合并 release 的后期修改 6.3、紧急修复 当 master 某个 tag 部署到生产环境后,也可能出现不符合预期的问题出现;此时应该基于 master 创建 hotfix 分支进行修复,流程如下 本地 git flow hotfix start xxxx 创建紧急修复分支 修改代码后将其推送到远端,并像 master、develop 分支发起合并 develop 合并紧急修复补丁,如果必要最好再做一下测试 master 合并紧急修复补丁,创建紧急修复 tag,并部署生产环境 七、环境准备 首先需要有一台 GitLab 服务器,然后需要有个项目;这里示例项目以 Spring Boot 项目为例,然后最好有一台专门用来 Build 的机器,实际生产中如果 Build 任务不频繁可适当用一些业务机器进行 Build;本文示例所有组件将采用 Docker 启动, GitLab HA 等不在本文阐述范围内 Docker Version : 1.13.1 GitLab Version : 10.1.4-ce.0 GitLab Runner Version : 10.1.0 GitLab IP : 172.16.0.37 GitLab Runner IP : 172.16.0.36 八、GitLab CI 简介 GitLab CI 是 GitLab 默认集成的 CI 功能,GitLab CI 通过在项目内 .gitlab-ci.yaml 配置文件读取 CI 任务并进行相应处理;GitLab CI 通过其称为 GitLab Runner 的 Agent 端进行 build 操作;Runner 本身可以使用多种方式安装,比如使用 Docker 镜像启动等;Runner 在进行 build 操作时也可以选择多种 build 环境提供者;比如直接在 Runner 所在宿主机 build、通过新创建虚拟机(vmware、virtualbox)进行 build等;同时 Runner 支持 Docker 作为 build 提供者,即每次 build 新启动容器进行 build;GitLab CI 其大致架构如下 九、搭建 GitLab 服务器 9.1、GitLab 搭建 GitLab 搭建这里直接使用 docker compose 启动,compose 配置如下 version: '2' services: gitlab: image: 'gitlab/gitlab-ce:10.1.4-ce.0' restart: always container_name: gitlab hostname: 'git.mritd.me' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://git.mritd.me' # Add any other gitlab.rb configuration here, each on its own line ports: - '80:80' - '443:443' - '8022:22' volumes: - './data/gitlab/config:/etc/gitlab' - './data/gitlab/logs:/var/log/gitlab' - './data/gitlab/data:/var/opt/gitlab'Copy 直接启动后,首次登陆需要设置初始密码如下,默认用户为 root 登陆成功后创建一个用户(该用户最好给予 Admin 权限,以后操作以该用户为例),并且创建一个测试 Group 和 Project,如下所示 9.2、增加示例项目 这里示例项目采用 Java 的 SpringBoot 项目,并采用 Gradle 构建,其他语言原理一样;如果不熟悉 Java 的没必要死磕此步配置,任意语言(最好 Java)整一个能用的 Web 项目就行,并不强求一定 Java 并且使用 Gradle 构建,以下只是一个样例项目;SpringBoot 可以采用 Spring Initializr 直接生成(依赖要加入 WEB),如下所示 将项目导入 IDEA,然后创建一个 index 示例页面,主要修改如下 build.gradle buildscript { ext { springBootVersion = '1.5.8.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'org.springframework.boot' group = 'me.mritd' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter') compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-starter-thymeleaf') testCompile('org.springframework.boot:spring-boot-starter-test') }Copy 新建一个 HomeController package me.mritd.TestProject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /******************************************************************************* * Copyright (c) 2005-2017 Mritd, Inc. * TestProject * me.mritd.TestProject * Created by mritd on 2017/11/24 下午12:23. * Description: *******************************************************************************/ @Controller public class HomeController { @RequestMapping("/") public String home(){ return "index"; } }Copy templates 下新建 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> </head> <body> <h1>Test...</h1> </body> </html>Copy 最后项目整体结构如下 执行 assemble Task 打包出可执行 jar 包,并运行 java -jar TestProject-0.0.1-SNAPSHOT.jar 测试下能启动访问页面即可 最后将项目提交到 GitLab 后如下 十、GitLab CI 配置 针对这一章节创建基础镜像以及项目镜像,这里仅以 Java 项目为例;其他语言原理相通,按照其他语言对应的运行环境修改即可 10.1、增加 Runner GitLab CI 在进行构建时会将任务下发给 Runner,让 Runner 去执行;所以先要添加一个 Runner,Runner 这里采用 Docker Compose 启动,build 方式也使用 Docker 方式 Build;compose 文件如下 version: '2' services: gitlab-runner: container_name: gitlab-runner image: gitlab/gitlab-runner:alpine-v10.1.0 restart: always network_mode: "host" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./config.toml:/etc/gitlab-runner/config.toml extra_hosts: - "git.mritd.me:172.16.0.37"Copy 在启动前,我们需要先 touch 一下这个 config.toml 配置文件;该文件是 Runner 的运行配置,此后 Runner 所有配置都会写入这个文件(不 touch 出来 docker-compose 发现不存在会挂载一个目录进去,导致 Runner 启动失败);启动 docker-compose 后,需要进入容器执行注册,让 Runner 主动去连接 GitLab 服务器 # 生成 Runner 配置文件 touch config.toml # 启动 Runner docker-compose up -d # 激活 Runner docker exec -it gitlab-runner gitlab-runner registerCopy 在执行上一条激活命令后,会按照提示让你输入一些信息;首先输入 GitLab 地址,然后是 Runner Token,Runner Token 可以从 GitLab 设置中查看,如下所示 整体注册流程如下 注册完成后,在 GitLab Runner 设置中就可以看到刚刚注册的 Runner,如下所示 Runner 注册成功后会将配置写入到 config.toml 配置文件;由于两个测试宿主机都没有配置内网 DNS,所以为了保证 runner 在使用 docker build 时能正确的找到 GitLab 仓库地址,还需要增加一个 docker 的 host 映射( extra_hosts );同时为了能调用 宿主机 Docker 和持久化 build 的一些缓存还挂载了一些文件和目录;完整的 配置如下(配置文件可以做一些更高级的配置,具体参考 官方文档 ) config.toml concurrent = 1 check_interval = 0 [[runners]] name = "Test Runner" url = "http://git.mritd.me" token = "c279ec1ac08aec98c7141c7cf2d474" executor = "docker" builds_dir = "/gitlab/runner-builds" cache_dir = "/gitlab/runner-cache" [runners.docker] tls_verify = false image = "debian" privileged = false disable_cache = false shm_size = 0 volumes = ["/data/gitlab-runner:/gitlab","/var/run/docker.sock:/var/run/docker.sock","/data/maven_repo:/data/repo","/data/maven_repo:/data/maven","/data/gradle:/data/gradle","/data/sonar_cache:/root/.sonar","/data/androidsdk:/usr/local/android","/data/node_modules:/data/node_modules"] extra_hosts = ["git.mritd.me:172.16.0.37"] [runners.cache]Copy 注意,这里声明的 Volumes 会在每个运行的容器中都生效;也就是说 build 时新开启的每个容器都会被挂载这些目录;修改完成后重启 runner 容器即可,由于 runner 中没啥可保存的东西,所以可以直接 docker-compose down && docker-compose up -d 重启 10.2、创建基础镜像 由于示例项目是一个 Java 项目,而且是采用 Spring Boot 的,所以该项目想要运行起来只需要一个 java 环境即可,中间件已经被打包到了 jar 包中;以下是一个作为基础运行环境的 openjdk 镜像的 Dockerfile FROM alpine:edge LABEL maintainer="mritd <mritd1234@gmail.com>" ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk ENV PATH $PATH:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin RUN apk add --update bash curl tar wget ca-certificates unzip \ openjdk8 font-adobe-100dpi ttf-dejavu fontconfig \ && rm -rf /var/cache/apk/* \ CMD ["bash"]Copy 这个 openjdk Dockerfile 升级到了 8.151 版本,并且集成了一些字体相关的软件,以解决在 Java 中某些验证码库无法运行问题,详见 Alpine 3.6 OpenJDK 8 Bug;使用这个 Dockerfile,在当前目录执行 docker build -t mritd/openjdk:8 . build 一个 openjdk8 的基础镜像,然后将其推送到私服,或者 Docker Hub 即可 10.3、创建项目镜像 有了基本的 openjdk 的 docker 镜像后,针对于项目每次 build 都应该生成一个包含发布物的 docker 镜像,所以对于项目来说还需要一个项目本身的 Dockerfile;项目的 Dockerfile 有两种使用方式;一种是动态生成 Dockerfile,然后每次使用新生成的 Dockerfile 去 build;还有一种是写一个通用的 Dockerfile,build 时利用 ARG 参数传入变量;这里采用第二种方式,以下为一个可以反复使用的 Dockerfile FROM mritd/openjdk:8-144-01 MAINTAINER mritd <mritd1234@gmail.com> ARG PROJECT_BUILD_FINALNAME ENV TZ 'Asia/Shanghai' ENV PROJECT_BUILD_FINALNAME ${PROJECT_BUILD_FINALNAME} COPY build/libs/${PROJECT_BUILD_FINALNAME}.jar /${PROJECT_BUILD_FINALNAME}.jar CMD ["bash","-c","java -jar /${PROJECT_BUILD_FINALNAME}.jar"]Copy 该 Dockerfile 通过声明一个 PROJECT_BUILD_FINALNAME 变量来表示项目的发布物名称;然后将其复制到根目录下,最终利用 java 执行这个 jar 包;所以每次 build 之前只要能拿到项目发布物的名称即可 10.4、Gradle 修改 上面已经创建了一个标准的通用型 Dockerfile,每次 build 镜像只要传入 PROJECT_BUILD_FINALNAME 这个最终发布物名称即可;对于发布物名称来说,最好不要固定死;当然不论是 Java 还是其他语言的项目我们都能将最终发布物变成一个固定名字,最不济可以写脚本重命名一下;但是不建议那么干,最好保留版本号信息,以便于异常情况下进入容器能够分辨;对于当前 Java 项目来说,想要拿到 PROJECT_BUILD_FINALNAME 很简单,我们只需要略微修改一下 Gradle 的 build 脚本,让其每次打包 jar 包时将项目的名称及版本号导出到文件中即可;同时这里也加入了镜像版本号的处理,Gradle 脚本修改如下 build.gradle 最后面增加如下 bootRepackage { mainClass = 'me.mritd.TestProject.TestProjectApplication' executable = true doLast { File envFile = new File("build/tmp/PROJECT_ENV") println("Create ${archivesBaseName} ENV File ===> " + envFile.createNewFile()) println("Export ${archivesBaseName} Build Version ===> ${version}") envFile.write("export PROJECT_BUILD_FINALNAME=${archivesBaseName}-${version}\n") println("Generate Docker image tag...") envFile.append("export BUILD_DATE=`date +%Y%m%d%H%M%S`\n") envFile.append("export IMAGE_NAME=mritd/test:`echo \${CI_BUILD_REF_NAME} | tr '/' '-'`-`echo \${CI_COMMIT_SHA} | cut -c1-8`-\${BUILD_DATE}\n") envFile.append("export LATEST_IMAGE_NAME=mritd/test:latest\n") } }Copy 这一步操作实际上是修改了 bootRepackage 这个 Task(不了解 Gradle 或者不是 Java 项目的请忽略),在其结束后创建了一个叫 PROJECT_ENV 的文件,里面实际上就是写入了一些 bash 环境变量声明,以方便后面 source 一下这个文件拿到一些变量,然后用户 build 镜像使用,PROJECT_ENV 最终生成如下 export PROJECT_BUILD_FINALNAME=TestProject-0.0.1-SNAPSHOT export BUILD_DATE=`date +%Y%m%d%H%M%S` export IMAGE_NAME=mritd/test:`echo ${CI_BUILD_REF_NAME} | tr '/' '-'`-`echo ${CI_COMMIT_SHA} | cut -c1-8`-${BUILD_DATE} export LATEST_IMAGE_NAME=mritd/test:latestCopy 10.5、创建 CI 配置文件 一切准备就绪以后,就可以编写 CI 脚本了;GitLab 依靠读取项目根目录下的 .gitlab-ci.yml 文件来执行相应的 CI 操作;以下为测试项目的 .gitlab-ci.yml 配置 # 调试开启 #before_script: # - pwd # - env cache: key: $CI_PROJECT_NAME/$CI_COMMIT_REF_NAME-$CI_COMMIT_SHA paths: - build stages: - build - deploy auto-build: image: mritd/build:2.1.1 stage: build script: - gradle --no-daemon clean assemble tags: - test deploy: image: mritd/docker-kubectl:v1.7.4 stage: deploy script: - source build/tmp/PROJECT_ENV - echo "Build Docker Image ==> ${IMAGE_NAME}" - docker build -t ${IMAGE_NAME} --build-arg PROJECT_BUILD_FINALNAME=${PROJECT_BUILD_FINALNAME} . # - docker push ${IMAGE_NAME} - docker tag ${IMAGE_NAME} ${LATEST_IMAGE_NAME} # - docker push ${LATEST_IMAGE_NAME} # - docker rmi ${IMAGE_NAME} ${LATEST_IMAGE_NAME} # - kubectl --kubeconfig ${KUBE_CONFIG} set image deployment/test test=$IMAGE_NAME tags: - test only: - master - develop - /^chore.*$/Copy 关于 CI 配置的一些简要说明如下 stages stages 字段定义了整个 CI 一共有哪些阶段流程,以上的 CI 配置中,定义了该项目的 CI 总共分为 build、deploy 两个阶段;GitLab CI 会根据其顺序执行对应阶段下的所有任务;在正常生产环境流程可以定义很多个,比如可以有 test、publish,甚至可能有代码扫描的 sonar 阶段等;这些阶段没有任何限制,完全是自定义的,上面的阶段定义好后在 CI 中表现如下图 task task 隶属于 stages 之下;也就是说一个阶段可以有多个任务,任务执行顺序默认不指定会并发执行;对于上面的 CI 配置来说 auto-build 和 deploy 都是 task,他们通过 stage: xxxx 这个标签来指定他们隶属于哪个 stage;当 Runner 使用 Docker 作为 build 提供者时,我们可以在 task 的 image 标签下声明该 task 要使用哪个镜像运行,不指定则默认为 Runner 注册时的镜像(这里是 debian);同时 task 还有一个 tags 的标签,该标签指明了这个任务将可以在哪些 Runner 上运行;这个标签可以从 Runner 页面看到,实际上就是 Runner 注册时输入的哪个 tag;对于某些特殊的项目,比如 IOS 项目,则必须在特定机器上执行,所以此时指定 tags 标签很有用,当 task 运行后如下图所示 除此之外 task 还能指定 only 标签用于限定那些分支才能触发这个 task,如果分支名字不满足则不会触发;默认情况下,这些 task 都是自动执行的,如果感觉某些任务太过危险,则可以通过增加 when: manual 改为手动执行;注意: 手动执行被 GitLab 认为是高权限的写操作,所以只有项目管理员才能手动运行一个 task,直白的说就是管理员才能点击;手动执行如下图所示 cache cache 这个参数用于定义全局那些文件将被 cache;在 GitLab CI 中,跨 stage 是不能保存东西的;也就是说在第一步 build 的操作生成的 jar 包,到第二部打包 docker image 时就会被删除;GitLab 会保证每个 stage 中任务在执行时都将工作目录(Docker 容器 中)还原到跟 GitLab 代码仓库中一模一样,多余文件及变更都会被删除;正常情况下,第一步 build 生成 jar 包应当立即推送到 nexus 私服;但是这里测试没有搭建,所以只能放到本地;但是放到本地下一个 task 就会删除它,所以利用 cache 这个参数将 build 目录 cache 住,保证其跨 stage 也能存在 关于 .gitlab-ci.yml 具体配置更完整的请参考 官方文档 十一、其他相关 11.1、GitLab 内置环境变量 上面已经基本搞定了一个项目的 CI,但是有些变量可能并未说清楚;比如在创建的 PROJECT_ENV 文件中引用了 ${CI_COMMIT_SHA} 变量;这种变量其实是 GitLab CI 的内置隐藏变量,这些变量在每次 CI 调用 Runner 运行某个任务时都会传递到对应的 Runner 的执行环境中;也就是说这些变量在每次的任务容器 SHELL 环境中都会存在,可以直接引用,具体的完整环境变量列表可以从 官方文档 中获取;如果想知道环境变量具体的值,实际上可以通过在任务执行前用 env 指令打印出来,如下所示 11.2、GitLab 自定义环境变量 在某些情况下,我们希望 CI 能自动的发布或者修改一些东西;比如将 jar 包上传到 nexus、将 docker 镜像 push 到私服;这些动作往往需要一个高权限或者说有可写入对应仓库权限的账户来支持,但是这些账户又不想写到项目的 CI 配置里;因为这样很不安全,谁都能看到;此时我们可以将这些敏感变量写入到 GitLab 自定义环境变量中,GitLab 会像对待内置变量一样将其传送到 Runner 端,以供我们使用;GitLab 中自定义的环境变量可以有两种,一种是项目级别的,只能够在当前项目使用,如下 另一种是组级别的,可以在整个组内的所有项目中使用,如下 这两种变量添加后都可以在 CI 的脚本中直接引用 11.3、Kubernetes 集成 对于 Kubernetes 集成实际上有两种方案,一种是对接 Kubernetes 的 api,纯代码实现;另一种取巧的方案是调用 kubectl 工具,用 kubectl 工具来实现滚动升级;这里采用后一种取巧的方式,将 kubectl 二进制文件封装到镜像中,然后在 deploy 阶段使用这个镜像直接部署就可以 其中 mritd/docker-kubectl:v1.7.4 这个镜像的 Dockerfile 如下 FROM docker:dind LABEL maintainer="mritd <mritd1234@gmail.com>" ARG TZ="Asia/Shanghai" ENV TZ ${TZ} ENV KUBE_VERSION v1.8.0 RUN apk upgrade --update \ && apk add bash tzdata wget ca-certificates \ && wget https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \ && chmod +x /usr/local/bin/kubectl \ && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone \ && rm -rf /var/cache/apk/* CMD ["/bin/bash"]Copy 这里面的 ${KUBE_CONFIG} 是一个自定义的环境变量,对于测试环境我将配置文件直接挂载入了容器中,然后 ${KUBE_CONFIG} 只是指定了一个配置文件位置,实际生产环境中可以选择将配置文件变成自定义环境变量使用 11.4、GitLab CI 总结 关于 GitLab CI 上面已经讲了很多,但是并不全面,也不算太细致;因为这东西说起来实际太多了,现在目测已经 1W 多字了;以下总结一下 GitLab CI 的总体思想,当思路清晰了以后,我想后面的只是查查文档自己试一试就行了 CS 架构 GitLab 作为 Server 端,控制 Runner 端执行一系列的 CI 任务;代码 clone 等无需关心,GitLab 会自动处理好一切;Runner 每次都会启动新的容器执行 CI 任务 容器即环境 在 Runner 使用 Docker build 的前提下;所有依赖切换、环境切换应当由切换不同镜像实现,即 build 那就使用 build 的镜像,deploy 就用带有 deploy 功能的镜像;通过不同镜像容器实现完整的环境隔离 CI即脚本 不同的 CI 任务实际上就是在使用不同镜像的容器中执行 SHELL 命令,自动化 CI 就是执行预先写好的一些小脚本 敏感信息走环境变量 一切重要的敏感信息,如账户密码等,不要写到 CI 配置中,直接放到 GitLab 的环境变量中;GitLab 会保证将其推送到远端 Runner 的 SHELL 变量中 转载整理From: git-flow-note ci-cd-gitlab-ci 系列教程 全部文章RSS订阅 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2021/11/1
articleCard.readMore

Earthly 一个更加强大的镜像构建工具

一、Earthly 介绍 开局一张图,功能全靠吹。 Earthly 是一个更加高级的 Docker 镜像构建工具,Earthly 通过自己定义的 Earthfile 来代替传统的 Dockerfile 完成镜像构建;Earthfile 就如同 Earthly 官方所描述: **Makefile + Dockerfile = Earthfile** 在使用 Earthly 进行构建镜像时目前强依赖于 buildkit,Earthly 通过 buildkit 支持了一些 Dockerfile 的扩展语法,同时将 Dockerfile 与 Makefile 整合,使得多平台构建和代码化 Dockerfile 变得更加简单;使用 Earthly 可以更加方便的完成 Dockerfile 的代码复用以及更加友好的 CI 自动集成。 二、快速开始 2.1、安装依赖 Earthly 目前依赖于 Docker 和 Git,所以安装 Earthly 前请确保机器已经安装了 Docker 和 Git。 2.2、安装 Earthly Earthly 采用 Go 编写,所以主要就一个二进制文件,Linux 下安装可以直接参考官方的安装脚本: sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'Copy 安装完成后 Earthly 将会启动一个 buildkitd 容器: earthly-buildkitd。 2.3、语法高亮 目前 Earthly 官方支持 VS Code、VIM 以及 Sublime Text 三种编辑器的语法高亮,具体如何安装请参考 官方文档。 2.4、基本使用 本示例源于官方 Basic 教程,以下示例以编译 Go 项目为样例: 首先创建一个任意名称的目录,目录中存在项目源码文件以及一个 Earthfile 文件; main.go package main import "fmt" func main() { fmt.Println("hello world") }Copy Earthfile FROM golang:1.17-alpine WORKDIR /go-example build: COPY main.go . RUN go build -o build/go-example main.go SAVE ARTIFACT build/go-example /go-example AS LOCAL build/go-example docker: COPY +build/go-example . ENTRYPOINT ["/go-example/go-example"] SAVE IMAGE go-example:latestCopy 有了 Earthfile 以后我们就可以使用 Earthly 将其打包为镜像; # 目录结构 ~/t/earthlytest ❯❯❯ tree . ├── Earthfile └── main.go 0 directories, 2 files # 通过 earthly 进行构建 ~/t/earthlytest ❯❯❯ earthly +dockerCopy 构建完成后我们就可以直接从 docker 的 images 列表中查看刚刚构建的镜像,并运行: 三、进阶使用 3.1、多阶段构建 Earthfile 中包含类似 Makefile 一样的 target,不同的 target 之间还可以通过特定语法进行引用,每个 target 都可以被单独执行,执行过程中 earthly 会自动解析这些依赖关系。 这种多阶段构建时语法很弹性,我们可以在每个阶段运行独立的命令以及使用不同的基础镜像;从快速开始中可以看到,我们始终使用了一个基础镜像(golang:1.17-alpine),对于 Go 这种编译后自带运行时不依赖其语言 SDK 的应用,我们事实上可以将 “发布物” 仅放在简单的运行时系统镜像内,从而减少最终镜像体积: 由于使用了多个 target,所以我们可以单独的运行 build 这个 target 来验证我们的编译流程,这种多 target 的设计方便我们构建应用时对编译、打包步骤的细化拆分,同时也方便我们进行单独的验证。 例如我们单独执行 build 这个 target 来验证我们的编译流程是否正确: 在其他阶段验证完成后,我们可以直接运行最终的 target,earthly 会自动识别到这种依赖关系从而自动运行其依赖的 target: 3.2、扩展指令 3.2.1、SAVE SAVE 指令是 Earthly 自己的一个扩展指令,实际上分为 SAVE ARTIFACT 和 SAVE IMAGE;其中 SAVE ARTIFACT 指令格式如下: SAVE ARTIFACT [--keep-ts] [--keep-own] [--if-exists] [--force] <src> [<artifact-dest-path>] [AS LOCAL <local-path>]Copy SAVE ARTIFACT 指令用于将文件或目录从 build 运行时环境保存到 target 的 artifact 环境;当保存到 artifact 环境后,可以通过 COPY 等命令在其他位置进行引用,类似于 Dockerfile 的 COPY --from... 语法;不同的是 SAVE ARTIFACT 支持 AS LOCAL <local-path> 附加参数,一但指定此参数后,earthly 会同时将文件或目录在宿主机复制一份,一般用于调试等目的。SAVE ARTIFACT 命令在上面的样例中已经展示了,在运行完 earthly +build 命令后实际上会在本地看到被 SAVE 出来的 ARTIFACT: 而另一个 SAVE IMAGE 指令则主要用于将当前的 build 环境 SAVE 为一个 IMAGE,如果指定了 --push 选项,同时在执行 earthly +target 命令时也加入 --push 选项,该镜像将会自动被推送到目标 Registry 上。SAVE IMAGE 指令格式如下: SAVE IMAGE [--cache-from=<cache-image>] [--push] <image-name>...Copy 3.2.2、GIT CLONE GIT CLONE 指令用于将指定 git 仓库 clone 到 build 环境中;与 RUN git clone... 命令不同的是,GIT CLONE 通过宿主机的 git 命令运行,它不依赖于容器内的 git 命令,同时还可以直接为 earthly 配置 git 认证,从而避免将这些安全信息泄漏到 build 环境中; 关于如何配置 earthly 的 git 认证请参考 官方文档;下面是 GIT CLONE 指令的样例 3.2.3、COPY COPY 指令与标准的 Dockerfile COPY 指令类似,除了支持 Dockerfile 标准的 COPY 功能以外,earthly 中的 COPY 指令可以引用其他 target 环节产生的 artifact,在引用时会自动声明依赖关系;即当在 B target 中存在 COPY +A/xxxxx /path/to/copy 类似的指令时,如果只单纯的执行 earthly +B,那么 earthly 根据依赖分析会得出在 COPY 之前需要执行 target A。COPY 指令的语法格式如下: # 与 Dockerfile 相同的使用方式,从上下文复制 COPY [options...] <src>... <dest> # 扩展支持的从 target 复制方式 COPY [options...] <src-artifact>... <dest>Copy 3.2.4、RUN RUN 指令在标准使用上与 Dockerfile 里保持一致,除此之外增加了更多的扩展选项,其指令格式如下: # shell 方式运行(/bin/sh -c) RUN [--push] [--entrypoint] [--privileged] [--secret <env-var>=<secret-ref>] [--ssh] [--mount <mount-spec>] [--] <command> # exec 方式运行 RUN [[<flags>...], "<executable>", "<arg1>", "<arg2>", ...]Copy 其中 --privileged 选项允许运行的命令使用 privileged capabilities,但是需要 earthly 在运行 target 时增加 --allow-privileged 选项;--interactive / --interactive-keep 选项用于交互式执行一些命令,在完成交互后 build 继续进行,在交互过程中进行的操作都会被持久化到 镜像中: 限于篇幅原因,其他的具体指令请查阅官方文档 Earthfile reference。 3.3、UDCS UDCs 全称 “User-defined commands”,即用户定义指令;通过 UDCs 我们可以将 Earthfile 中特定的命令剥离出来,从而实现更加通用和统一的代码复用;下面是一个定义 UDCs 指令的样例: # 定义一个 Command # ⚠️ 注意: 语法必须满足以下规则 # 1、名称全大写 # 2、名称下划线分割 # 3、首个命令必须为 COMMAND(后面没有冒号) MY_COPY: COMMAND ARG src ARG dest=./ ARG recursive=false RUN cp $(if $recursive = "true"; then printf -- -r; fi) "$src" "$dest" # target 中引用 build: FROM alpine:3.13 WORKDIR /udc-example RUN echo "hello" >./foo # 通过 DO 关键字引用 UDCs DO +MY_COPY --src=./foo --dest=./bar RUN cat ./bar # prints "hello"Copy UDCs 不光可以定义在一个 Earthfile 中,UDCs 可以跨文件、跨目录引用: 有了 UDCs 以后,我们可以通过这种方式将对基础镜像的版本统一控制、对特殊镜像的通用处理等操作全部抽象出来,然后每个 Earthfile 根据需要进行引用;关于 UDCs 的使用样例可以参考我的 autobuild 项目,其中的 udcs 目录定义了大量的通用 UDCs,这些 UDCs 被其他目标镜的 Earthfile 批量引用。 3.4、多平台构建 在以前使用 Dockerfile 的时候,我们需要自己配置然后开启 buildkit 来实现多平台构建;在配置过程中可能会很繁琐,现在使用 earthly 可以默认帮我们实现多平台的交叉编译,我们需要做的仅仅是在 Earthfile 中声明需要支持哪些平台而已: 以上 Earthfile 在执行 earthly --push +all 构建时,将会自动构建四个平台的镜像,并保持单个 tag,同时由于使用了 --push 选项还会自动推送到 Docker Hub 上: 四、总结 Earthly 弥补了 Dockerfile 的很多不足,解决了很多痛点问题;但同样可能需要一些学习成本,但是如果已经熟悉了 Dockerfile 其实学习成本不高;所以目前还是比较推荐将 Dockerfile 切换为 Earthfile 进行统一和版本化管理的。本文由于篇幅所限(懒)很多地方没有讲,比如共享缓存等,所以关于 Earthly 更多的详细使用等最好还是仔细阅读一下官方文档。 整理转载:the-best-image-build-tool-earthly 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/11/1
articleCard.readMore

Hexo Markdown以及各种插件功能测试

Markdown 插件 markdown-it-abbr markdown-it-container markdown-it-deflist markdown-it-emoji markdown-it-footnote markdown-it-imsize markdown-it-ins markdown-it-mark markdown-it-regexp markdown-it-sub markdown-it-sup markdown-it-merge-cells markdown-it-multimd-table markdown-it-task-checkbox 常用标记 - 29^th^ => `29<sup>th</sup>` - H~2~0 => `H<sub>2</sub>O` - ==marked== => `<mark>inserted</mark>` - ++inserted++ => `<ins>inserted</ins>` 29th => 29<sup>th</sup> H20 => H<sub>2</sub>O marked => <mark>inserted</mark> inserted => <ins>inserted</ins> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>Document</title> <style> .lighter { font-weight: lighter; } .bold { font-weight: bold; } .bolder { font-weight: bolder; } </style> </head> <body> <P>这是分段</P> <b>这是粗体</b> <br/> <big>这是大号字</big> <br/> <em>这是着重字</em> <br/> <i>这是斜体字</i> <br/> <small>这是小号字</small> <br/> <strong>加重语气</strong> <br/> 这是<sup>上标字</sup> <br/> 这是<sub>下标字</sub> <br/> <ins>插入字</ins> <br/> <del>删除字</del> <br/> <p>This is a <span class="lighter">lighter text</span>.</p> <p>This is a <span class="bold">bold text</span>.</p> <p>This is a <span class="bolder">bolder text</span>.</p> <p> font-weight 属性以 lighter、bold 和 bolder 作为值,数字从 100 到 900。因此,使用它,你不仅可以将文本加粗,还可以使其比周围的文本更亮。 你通常应该避免使用 b,因为它已经是一种样式。当你使用 b 标记将文本设为粗体时,你明确地告诉浏览器将 HTML 中的文本设为粗体。 strong 也使文本显示粗体,但它是语义的。使用它,你就不是从 HTML 样式化(HTML 最初从未用于此目的),而是告诉浏览器使文本在外观上比周围的其他文本更为加粗。 CSS font-weight 属性让你可以更好地控制文本的粗细程度。lighter、bold 和 bolder的值是一个开始,但你可以通过应用数字/权重(例如 100、200、300、400、500、600、700、800 和 900)作为值,从而更进一步,这会产生不同的粗细。 </p> </body> </html> markdown-it-task-checkbox - [x] item 1 - [x] item 1-1 - [ ] item 1-2 - [ ] item 1-3 - [ ] item 1-4 - [ ] item 2 - [ ] item 2-1 - [ ] item 2-2 - [ ] item 2-3 - [ ] item 2-4 item 1 item 1-1 item 1-2 item 1-3 item 1-4 item 2 item 2-1 item 2-2 item 2-3 item 2-4 markdown-it-multimd-table 目前仅支持多列合并 | 标题1 | 标题2 | | ------------ | ------------ | | 合并第一行 || | 第二行第一列 | 第二行第二列 | 标题1 标题2 合并第一行 第二行第一列 第二行第二列 colspan > or empty cell: a b > 1 2 rowspan ‘^’ a b 1 2 ^^ 4 | Markdown | Rendered HTML | |--------------|---------------| | *Italic* | *Italic* | \ | | | | - Item 1 | - Item 1 | \ | - Item 2 | - Item 2 | | ```python | ```python \ | .1 + .2 | .1 + .2 \ | ``` | ``` | Markdown Rendered HTML Italic Italic \ - Item 1 - Item 1 \ - Item 2 - Item 2 ```python ```python \ .1 + .2 .1 + .2 \ ``` ``` | Task | Time required | Assigned to | Current Status | Finished | |----------------|---------------|---------------|----------------|-----------| | Calendar Cache | > 5 hours | @georgehrke | in progress | - [x] ok? | Object Cache | > 5 hours | @georgehrke | in progress | [x] item1<br/>[ ] item2 | Object Cache | > 5 hours | @georgehrke | in progress | <ul><li>- [x] item1</li><li>- [ ] item2</li></ul> | Object Cache | > 5 hours | @georgehrke | in progress | <ul><li>[x] item1</li><li>[ ] item2</li></ul> - [x] works - [x] works too Task Time required Assigned to Current Status Finished Calendar Cache > 5 hours @georgehrke in progress - [x] ok? Object Cache > 5 hours @georgehrke in progress [x] item1 [ ] item2 Object Cache > 5 hours @georgehrke in progress - [x] item1- [ ] item2 Object Cache > 5 hours @georgehrke in progress [x] item1[ ] item2 works works too Function | MySQL / MariaDB | PostgreSQL | SQLite :------------ | :-------------| :-------------| :------------- substr | :heavy_check_mark: | :white_check_mark: | :heavy_check_mark: Function MySQL / MariaDB PostgreSQL SQLite substr ✔️ ✅ ✔️ emoji :smile::smirk::sunny: 😄😏☀️ markdown-it-abbr *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium The HTML specification is maintained by the W3C. The HTML specification W3C. markdown-it-container ::: warning *here be dragons* ::: here be dragons footnote Here is a footnote reference,[^1] and another.[^longnote] [^1]: Here is the footnote. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous footnote. Here is a footnote reference,[1] and another.[2] belong to the previous footnote. markdown-it-imsize ![test](https://cimg1.17lai.site/data/2021/10/1220211012022352.png) ![test](https://cimg1.17lai.site/data/2021/10/1220211012022352.png =100x200) 综合测试 直接访问 markdown-it demo --- __Advertisement :)__ - __[pica](https://nodeca.github.io/pica/demo/)__ - high quality and fast image resize in browser. - __[babelfish](https://github.com/nodeca/babelfish/)__ - developer friendly i18n with plurals support and easy syntax. You will like those projects! --- ### h3 Heading 8-) #### h4 Heading ##### h5 Heading ###### h6 Heading ### Horizontal Rules ___ --- *** ### Typographic replacements Enable typographer option to see result. (c) (C) (r) (R) (tm) (TM) (p) (P) +- test.. test... test..... test?..... test!.... !!!!!! ???? ,, -- --- "Smartypants, double quotes" and 'single quotes' ### Emphasis **This is bold text** __This is bold text__ *This is italic text* _This is italic text_ ~~Strikethrough~~ ### Blockquotes > Blockquotes can also be nested... >> ...by using additional greater-than signs right next to each other... > > > ...or with spaces between arrows. ### Lists Unordered + Create a list by starting a line with `+`, `-`, or `*` + Sub-lists are made by indenting 2 spaces: - Marker character change forces new list start: * Ac tristique libero volutpat at + Facilisis in pretium nisl aliquet - Nulla volutpat aliquam velit + Very easy! Ordered 1. Lorem ipsum dolor sit amet 2. Consectetur adipiscing elit 3. Integer molestie lorem at massa 1. You can use sequential numbers... 1. ...or keep all the numbers as `1.` Start numbering with offset: 57. foo 1. bar ### Code Inline `code` Indented code // Some comments line 1 of code line 2 of code line 3 of code Block code "fences" ``` Sample text here... ``` Syntax highlighting ``` js var foo = function (bar) { return bar++; }; console.log(foo(5)); ``` ### Tables | Option | Description | | ------ | ----------- | | data | path to data files to supply the data that will be passed into templates. | | engine | engine to be used for processing templates. Handlebars is the default. | | ext | extension to be used for dest files. | Right aligned columns | Option | Description | | ------:| -----------:| | data | path to data files to supply the data that will be passed into templates. | | engine | engine to be used for processing templates. Handlebars is the default. | | ext | extension to be used for dest files. | ### Links [link text](http://dev.nodeca.com) [link with title](http://nodeca.github.io/pica/demo/ "title text!") Autoconverted link https://github.com/nodeca/pica (enable linkify to see) ### Images ![Minion](https://octodex.github.com/images/minion.png) ![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat") Like links, Images also have a footnote style syntax ![Alt text][id] With a reference later in the document defining the URL location: [id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat" ### Plugins The killer feature of `markdown-it` is very effective support of [syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin). #### [Emojies](https://github.com/markdown-it/markdown-it-emoji) > Classic markup: :wink: :crush: :cry: :tear: :laughing: :yum: > > Shortcuts (emoticons): :-) :-( 8-) ;) see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji. #### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup) - 19^th^ - H~2~O #### [\<ins>](https://github.com/markdown-it/markdown-it-ins) ++Inserted text++ #### [\<mark>](https://github.com/markdown-it/markdown-it-mark) ==Marked text== #### [Footnotes](https://github.com/markdown-it/markdown-it-footnote) Footnote 1 link[^first]. Footnote 2 link[^second]. Inline footnote^[Text of inline footnote] definition. Duplicated footnote reference[^second]. [^first]: Footnote **can have markup** and multiple paragraphs. [^second]: Footnote text. #### [Definition lists](https://github.com/markdown-it/markdown-it-deflist) Term 1 : Definition 1 with lazy continuation. Term 2 with *inline markup* : Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. _Compact style:_ Term 1 ~ Definition 1 Term 2 ~ Definition 2a ~ Definition 2b #### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr) This is HTML abbreviation example. It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on. *[HTML]: Hyper Text Markup Language Advertisement 😃 pica - high quality and fast image babelfish - developer friendly You will like those projects! h3 Heading 😎 h4 Heading h5 Heading h6 Heading Horizontal Rules Typographic replacements Enable typographer option to see result. © © ® ® ™ ™ (p) (P) ± test… test… test… test?.. test!.. !!! ??? , – — “Smartypants, double quotes” and ‘single quotes’ Emphasis This is bold text This is bold text This is italic text This is italic text Strikethrough Blockquotes Blockquotes can also be nested… …by using additional greater-than signs right next to each other… …or with spaces between arrows. Lists Unordered Create a list by starting a line with +, -, or * Sub-lists are made by indenting 2 spaces: Marker character change forces new list start: Ac tristique libero volutpat at Facilisis in pretium nisl aliquet Nulla volutpat aliquam velit Very easy! Ordered Lorem ipsum dolor sit amet Consectetur adipiscing elit Integer molestie lorem at massa You can use sequential numbers… …or keep all the numbers as 1. Start numbering with offset: foo bar Code Inline code Indented code // Some comments line 1 of code line 2 of code line 3 of code Block code “fences” Sample text here... Syntax highlighting var foo = function (bar) { return bar++; }; console.log(foo(5)); Tables Option Description data path to data files to supply the data that will be passed into templates. engine engine to be used for processing templates. Handlebars is the default. ext extension to be used for dest files. Right aligned columns Option Description data path to data files to supply the data that will be passed into templates. engine engine to be used for processing templates. Handlebars is the default. ext extension to be used for dest files. Links link text link with title Autoconverted link https://github.com/nodeca/pica (enable linkify to see) Images Like links, Images also have a footnote style syntax With a reference later in the document defining the URL location: Plugins The killer feature of markdown-it is very effective support of syntax plugins. Emojies Classic markup: 😉 :crush: 😢 :tear: 😆 😋 Shortcuts (emoticons): 😃 😦 😎 😉 see how to change output with twemoji. Subscript / Superscript 19th H2O <ins> Inserted text <mark> Marked text Footnotes Footnote 1 link[3]. Footnote 2 link[4]. Inline footnote[5] definition. Duplicated footnote reference[4:1]. Definition lists Term 1 Definition 1 Term 2 with inline markup Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. Compact style: Term 1 Definition 1 Term 2 Definition 2a Definition 2b Abbreviations This is HTML abbreviation example. It converts “HTML”, but keep intact partial entries like “xxxHTMLyyy” and so on. Markdown 语法 markdown 注释 #### 基于 HTML 标签的注释 <!-- 这是一段被注释掉的文字 --> 这是一段没有被注释的文字 <!-- 负责人:项目经理 补充内容:项目背景、实现目标、开发周期、责任人员分配。 计划用时:1周 --> #### 基于 HTML 样式 <div style="display:none"> 这是一段被注释掉的文字 </div> 这是一段没有被注释的文字 #### 通过 Markdown 解析达到注释效果 [//]: (这是一段被注释掉的文字) 这是一段没有被注释的文字 基于 HTML 标签的注释 这是一段没有被注释的文字 基于 HTML 样式 这是一段没有被注释的文字 通过 Markdown 解析达到注释效果 这是一段没有被注释的文字 tag button Usage {% button url, text, icon [class], [title] %} or {% btn url, text, icon [class], [title] %} url : Absolute or relative path to URL. text : Button text. Required if no icon specified. icon : Font Awesome icon name. Required if no text specified. [class] : Optional parameter. Font Awesome class(es): fa-fw | fa-lg | fa-2x | fa-3x | fa-4x | fa-5x [title] : Optional parameter. Tooltip at mouseover. Examples {% button #, Text %} Text Button with text & title {% btn #, Text %}{% btn #, Text & Title,, Title %} TextText & Title Button with icon {% btn #,, home fa-5x %} {% btn #,, home fa-4x %} {% btn #,, home fa-3x %} {% btn #,, home fa-2x %} {% btn #,, home fa-lg %} {% btn #,, home %} Button with text & icon {% btn #, Text & Icon (buggy), home %} {% btn #, Text & Icon (fixed width), home fa-fw %} Text & Icon (buggy) Text & Icon (fixed width) Button inside text Lorem {% btn #, Lorem, home fa-fw fa-lg %} ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolor Lorem Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolor Button inside other tag {% note info %} {% btn #, Text & Icon, home fa-fw %} {% btn #,, home, Title %}{% btn #, Text %} [Link](#) {% endnote %} Text & Icon Text Link Button margin <div class="center"><div>{% btn #,, heading %}{% btn #,, fab fa-edge %}{% btn #,, times %}{% btn #,, circle-notch %}</div> <div>{% btn #,, italic %}{% btn #,, fab fa-scribd %}</div> <div>{% btn #,, fab fa-google %}{% btn #,, fab fa-chrome %}{% btn #,, fab fa-opera %}{% btn #,, gem fa-rotate-270 %}</div></div> Button with relative URL <div class="center">{% btn #, Previous Chapter, arrow-left fa-fw fa-lg, Previous Chapter (Full Image) %} {% btn #, Next Chapter, arrow-right fa-fw fa-lg, Next Chapter (Label) %}</div> Previous Chapter Next Chapter Button with absolute URL <div class="center">{% btn https://github.com, GitHub, fab fa-github fa-fw fa-lg, GitHub %}</div> GitHub tag note 移植自Next 发现Next主题很完善,除了样式非常老旧,一些功能特性非常不错,故移植一些功能过来。 Usage {% note [class] [no-icon] [summary] %} Any content (support inline tags too). {% endnote %} [class] : Optional parameter. Supported values: default | primary | success | info | warning | danger. [no-icon] : Optional parameter. Disable icon in note. [summary] : Optional parameter. Optional summary of the note. All parameters are optional. Examples {% note %} #### Header (without define class style) {% endnote %} Header (without define class style) {% note default %} #### Default Header Welcome to [Hexo!](https://hexo.io) {% endnote %} Default Header Welcome to Hexo! {% note primary %} #### Primary Header **Welcome** to [Hexo!](https://hexo.io) {% endnote %} Primary Header Welcome to Hexo! {% note info %} #### Info Header **Welcome** to [Hexo!](https://hexo.io) {% endnote %} Info Header Welcome to Hexo! {% note success %} #### Success Header **Welcome** to [Hexo!](https://hexo.io) {% endnote %} Success Header Welcome to Hexo! {% note warning %} #### Warning Header **Welcome** to [Hexo!](https://hexo.io) {% endnote %} Warning Header Welcome to Hexo! {% note danger %} #### Danger Header **Welcome** to [Hexo!](https://hexo.io) {% endnote %} Danger Header Welcome to Hexo! {% note info no-icon %} #### No icon note Note **without** icon: `note info no-icon` {% endnote %} No icon note Note without icon: note info no-icon {% note info no-icon This is a summary %} #### Details and summary (No icon) Note with summary: `note info no-icon This is a summary` {% endnote %} This is a summary Details and summary (No icon) Note with summary: note info no-icon This is a summary {% note success %} #### Codeblock in note ``` code block in note tag code block in note tag code block in note tag ``` {% endnote %} Codeblock in note code block in note tag code block in note tag code block in note tag {% note default %} #### Lists in note * ul * ul * ul * ul * ul 1. ol 2. ol 1. ol 2. ol 3. ol {% endnote %} Lists in note ul ul ul ul ul ol ol ol ol ol #### Table in Note {% note default %} | 1 | 2 | | - | - | | 3 | 4 | | 5 | 6 | | 7 | 8 | {% endnote %} Table in Note 1 2 3 4 5 6 7 8 tag label 行内标签 移植自 Fluid 在 markdown 中加入如下的代码来使用 Label: {% label primary @text %} 行内标签 行内标签 行内标签 或者使用 HTML 形式: <span class="label label-primary">Label</span> 可选 Label: primary default info success warning danger warning 若使用 {% label primary @text %},text 不能以 @ 开头 tag group-image 组图 移植自 Fluid 如果想把多张图片按一定布局组合显示,你可以在 markdown 中按如下格式: {% gi total n1-n2-... %} ![](url) ![](url) ![](url) ![](url) ![](url) {% endgi %} total:图片总数量,对应中间包含的图片 url 数量 n1-n2-...:每行的图片数量,可以省略,默认单行最多 3 张图,求和必须相等于 total,否则按默认样式 如下图为示例,代表共 5 张图,第一行 3 张图,第二行 2 张图。 {% gi 5 3-2 %} ![](https://blog.17lai.site/medias_webp/cover/fitness.webp) ![](https://blog.17lai.site/medias_webp/cover/fitness.webp) ![](https://blog.17lai.site/medias_webp/cover/fitness.webp) ![](https://blog.17lai.site/medias_webp/cover/fitness.webp) ![](https://blog.17lai.site/medias_webp/cover/fitness.webp) {% endgi %} tag timeline 参考修改来源 butterfly color可选 default(留空) / blue / pink / red / purple / orange / green {% timeline 2024,pink %} <!-- timeline 01-01 --> 元旦快乐。 <!-- endtimeline --> <!-- timeline 01-02节后 --> 假期还有最后一天。 <!-- endtimeline --> <!-- timeline 上班快乐... --> 人生啊。 <!-- endtimeline --> {% endtimeline %} 2024 01-01 元旦快乐。 01-02节后 假期还有最后一天。 上班快乐… 人生啊。 hexo-tag-common 更多参考这里 Usage {% tabs Unique name, [index] %} <!-- tab [Tab caption] [@icon] --> Any content (support inline tags too). <!-- endtab --> {% endtabs %} Unique name : Unique name of tabs block tag without comma. [index] : Index number of active tab. [Tab caption] : Caption of current tab. [@icon] : Font Awesome icon name. Example First unique name 1 First unique name 2 First unique name 3 This is Tab 1. This is Tab 2. This is Tab 3. {% tabs First unique name %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Tabs with 3rd tab selected Second unique name 1 Second unique name 2 Second unique name 3 This is Tab 1. This is Tab 2. This is Tab 3. {% tabs Second unique name, 3 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Tabs with no tab selected Third unique name 1 Third unique name 2 Third unique name 3 This is Tab 1. This is Tab 2. This is Tab 3. {% tabs Third unique name, -1 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Tabs with custom labels Solution 1 Solution 2 Solution 3 This is Tab 1. This is Tab 2. This is Tab 3. {% tabs Fourth unique name %} <!-- tab Solution 1 --> **This is Tab 1.** <!-- endtab --> <!-- tab Solution 2 --> **This is Tab 2.** <!-- endtab --> <!-- tab Solution 3 --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Tabs with icons and labels Solution 1 Solution 2 Solution 3 品牌图标 生成: 生成: 生成: 生成: {% tabs Demo %} <!-- tab Solution 1@fas:question-circle --> 生成:<i class="fas fa-question-circle"></i> <!-- endtab --> <!-- tab Solution 2@fas:book --> 生成:<i class="fas fa-book"></i> <!-- endtab --> <!-- tab Solution 3@fas:tools --> 生成:<i class="fas fa-tools"></i> <!-- endtab --> <!-- tab 品牌图标@fab:github --> 生成:<i class="fab fa-github"></i> <!-- endtab --> {% endtabs %} Tabs permalinks test Permalink for > Tab one. Tab one 1. Tab one 2. Tab one 3. Permalink for > Tab two. Tab two 1. Tab two 2. Tab two 3. Tab one 1 Tab one 2 Tab one 3 This is Tab 1. This is Tab 2. This is Tab 3. Tab two 1 Tab two 2 Tab two 3 This is Tab 1. This is Tab 2. This is Tab 3. Permalink for > [Tab one](#tab-one). Permalink for > [Tab one 1](#tab-one-1). Permalink for > [Tab one 2](#tab-one-2). Permalink for > [Tab one 3](#tab-one-3). Permalink for > [Tab two](#tab-two). Permalink for > [Tab two 1](#tab-two-1). Permalink for > [Tab two 2](#tab-two-2). Permalink for > [Tab two 3](#tab-two-3). {% tabs Tab one %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} {% tabs Tab two %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Tabs with other tags Tags 1 Tags 2 Tags 3 This is Tab 1. One Two Three code tag code tag code tag Note default tag. This is Tab 2. Five Six Seven <div class="video-container"><iframe src="https://www.youtube.com/embed/Kt7u5kr_P5o" frameborder="0" loading="lazy" allowfullscreen></iframe></div> This is Tab 3. Sub Tabs 1 Sub Tabs 2 Sub Tabs 3 This is Sub Tab 1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. This is Sub Tab 2. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. This is Sub Tab 3. Sub-Sub Tabs 1 Sub-Sub Tabs 2 Sub-Sub Tabs 3 This is Sub-Sub Tab 1 of Sub Tab 3. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. This is Sub-Sub Tab 2 of Sub Tab 3. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. This is Sub-Sub Tab 3 of Sub Tab 3. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% tabs Tags %} <!-- tab --> **This is Tab 1.** 1. One 2. Two 3. Three {% code %} code tag code tag code tag {% endcode %} {% note default %} Note default tag. {% endnote %} <!-- endtab --> <!-- tab --> **This is Tab 2.** * Five * Six * Seven {% note primary %} {% code %} {% youtube Kt7u5kr_P5o %} {% endcode %} {% endnote %} <!-- endtab --> <!-- tab --> **This is Tab 3.** {% subtabs Sub Tabs %} <!-- tab --> **This is Sub Tab 1.** {% note success %} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. {% note warning %} Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. {% endnote %} Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% endnote %} <!-- endtab --> <!-- tab --> **This is Sub Tab 2.** {% note success %} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. {% note danger %} Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% endnote %} {% endnote %} <!-- endtab --> <!-- tab --> **This is Sub Tab 3.** {% subtabs Sub-Sub Tabs %} <!-- tab --> **This is Sub-Sub Tab 1 of Sub Tab 3.** {% note success %} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% endnote %} <!-- endtab --> <!-- tab --> **This is Sub-Sub Tab 2 of Sub Tab 3.** {% note success %} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. {% note warning %} Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% endnote %} {% endnote %} <!-- endtab --> <!-- tab --> **This is Sub-Sub Tab 3 of Sub Tab 3.** {% note success %} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti. Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc. {% note warning %} Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna. {% note danger %} Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl. {% endnote %} {% endnote %} {% endnote %} <!-- endtab --> {% endsubtabs %} <!-- endtab --> {% endsubtabs %} <!-- endtab --> {% endtabs %} hexo-admonition 作者ref hexo-admonition 注意: 需要把样式放入 hexo 主题的自定义样式文件中(如:my.css),并按自己喜好修改 安装插件 npm install hexo-admonition --save 使用的图标 content中 unicode 使用指南 支持的类型 提示类型 type 将用作 CSS 类名称,暂支持如下类型: note info, todo warning, attention, caution error, failure, missing, fail 语法说明 Hexo-admonition 遵循一种简单的语法:每个块都以 !!! 开头,然后是代表提示类型的关键字(type)及标题(title)。例如: !!! warning 这是一条采用默认标题的警告信息。 !!! Warning "" 这是一条不带标题的警告信息。 !!! note "嵌套链接及引用块" 欢迎访问我的博客链接:[夜法之书](https://www.blog.17lai.site) >这里嵌套一行引用信息。 !!! note Hexo-admonition 插件使用示例 这是基于 hexo-admonition 插件渲染的一条提示信息。类型为 note,并设置了自定义标题。 提示内容开头留 4 个空格,可以有多行,最后用空行结束此标记。 warning 这是一条采用默认标题的警告信息。 这是一条不带标题的警告信息。 嵌套链接及引用块 欢迎访问我的博客链接:夜法之书 这里嵌套一行引用信息。 Hexo-admonition 插件使用示例 这是基于 hexo-admonition 插件渲染的一条提示信息。类型为 note,并设置了自定义标题。 提示内容开头留 4 个空格,可以有多行,最后用空行结束此标记。 公式测试 采用**markdown-it-latex2img** Demo 数学公式 内联公式 开头的$必须在其右边紧跟一个非空格字符,而结尾的$必须在其左边紧接一个非空格字符,并且不能紧跟一个数字。 勾股定理: a2+b2=c2 等差数列求和公式: Sn=na1+n(n−1)2d,n∈N∗ 牛顿-莱布尼茨公式: ∫abf(x)dx=F(b)−F(a)=F(x)|ab 二项分布: Pn(k)=Cnkpkqn−kk=0,1,2……,n 块公式 正态分布 X∼N(μ,σ2): f(x)=12πσe−(x−μ)22σ2 斐波那契数列 An=An−1+An−2,前后两项的比值逐渐收敛到黄金分割比例 limn→∞An−1An=5−12. 因式分解 (x−1)(x−3)=x2−4x+3=x2−4x+4−1=(x−2)2−1 狄利克雷函数 D(x)={1,x∈Q0,x∉Q 高斯公式 ∭Ω(∂P∂x+∂Q∂y+∂R∂z)dv=∬ΣPdydz+Qdzdx+Rdxdy 范德蒙行列式 Dn−1=|11…1x2x3…xn⋮⋮⋮x2n−2x3n−2…xnn−2|=∏2≤j<i≤n(xi−xj) 线性方程组 {a11x1+a12x2+⋯+a1nxn=b1a21x1+a22x2+⋯+a2nxn=b2⋯⋯⋯am1x1+am2x2+⋯+amnxn=bm 物理公式 牛顿第一定律: ∑F→i=dv→dt=0 牛顿第二定律: F→=dmdtv→+mdv→dt=dmdtv→+ma→=dmdtv→+md2r→dt2 牛顿第三定律: F12→=−F21→ 质能守恒: E=mc2 万有引力定律: F=GMmr2 GmM(r+h)2=mν2(r+h) 基尔霍夫定律 [∂(ΔrHm)∂T]p=∑BvBCp,m(B) 热力学第二定律 dS≥δQT 化学公式 离子反应与沉淀: SOA4A2−+BaA2+⟶BaSOA4↓ 氮气氢气合成氨 高温、加压催化剂 NA2+3HA2↽−−⇀高温、加压催化剂2NHA3 化学平衡常数: Zn+2HCl(aq)=H2+ZnCl2(aq) Kθ=[p(H2)/pθ][c(ZnCl2)]c2(HC) 生物公式 光合作用  <!−−swig207−−> 语法参考 MathJax basic tutorial and quick reference 长公式 小括号测试 $\alpha\beta$ $\alpha_\beta$ $\alpha_\beta = \gamma_\delta$ (\alpha\beta) \(\alpha_\beta\) \\(\alpha_\beta = \gamma_\delta\\) αβ αβ αβ=γδ (\alpha\beta) (\alpha_\beta) \(\alpha_\beta = \gamma_\delta\) 下划线测试 w^{(l)}*{ij} = w^{(l)}*{ij} - \eta\frac{\partial E(W, b)}{\partial w^{(l)}_{ij}} w(l)∗ij=w(l)∗ij−η∂E(W,b)∂wij(l) CSS测试 文字增加背景色块 站点配置文件, 主题配置文件 <span id="inline-blue">站点配置文件</span>, <span id="inline-purple">主题配置文件</span> 引用边框变色 如果没有安装成功, 那可能就是墙的原因. 建议下载 `Node.js` 直接安装. 关于更多基本操作和基础知识, 请查阅 [Hexo](https://hexo.io/zh-cn/) 与 [NexT](http://theme-next.iissnan.com/) 官方文档. <p id="div-border-left-red">如果没有安装成功, 那可能就是墙的原因. 建议下载 `Node.js` 直接安装. </p> <p id="div-border-top-blue">关于更多基本操作和基础知识, 请查阅 [Hexo](https://hexo.io/zh-cn/) 与 [NexT](http://theme-next.iissnan.com/) 官方文档.</p> 图形边框效果 Download Now <a id="download" href="https://git-scm.com/download/win"><i class="fas fa-download"></i><span> Download Now</span> </a> 更多tips可参考 blog 在文档中增加图标 https://fontawesome.com/v6/search 支持Markdown Hexo 支持 GitHub Flavored Markdown 的所有功能, 甚至可以整合 Octopress 的大多数插件. 一键部署 只需一条指令即可部署到Github Pages, 或其他网站 丰富的插件 Hexo 拥有强大的插件系统, 安装插件可以让 Hexo 支持 Jade, CoffeeScript. - <i class="fas fa-pencil-alt"></i> 支持Markdown <i>Hexo 支持 GitHub Flavored Markdown 的所有功能, 甚至可以整合 Octopress 的大多数插件. </i> - <i class="fas fa-cloud-upload-alt"></i> 一键部署 <i>只需一条指令即可部署到Github Pages, 或其他网站</i> - <i class="fa fa-cog"></i>丰富的插件 <i>Hexo 拥有强大的插件系统, 安装插件可以让 Hexo 支持 Jade, CoffeeScript. </i> `<i class="fab fa-github"></i>` `<i class="fab fa-github fa-lg"></i>` `<i class="fab fa-github fa-2x"></i>` 图表绘制 hexo-tag-mermaid hexo-tag-plantuml hexo-tag-plantuml is a tag plugin for Hexo. It can work with plantuml to draw uml. 在Hexo中绘制uml图。 hexo-filter-flowchart Generate flowchart diagrams for Hexo. 插入PDF hexo-pdf 用法 Normal PDF {% pdf http://7xov2f.com1.z0.glb.clouddn.com/bash_freshman.pdf %} {% pdf ./bash_freshman.pdf %} Google drive {% pdf https://drive.google.com/file/d/0B6qSwdwPxPRdTEliX0dhQ2JfUEU/preview %} Slideshare {% pdf http://www.slideshare.net/slideshow/embed_code/key/8Jl0hUt2OKUOOE %} 预览 Normal PDF Tips: slideshare 和 Google drive 大陆是无法直接访问的! Mermaid Markdown mermaid教程 mermaid hexo-tag-mermaidhexo-tag-plantuml Mermaid Live editer 需要用下面块包裹 {% mermaid %} [内容] {% endmermaid %} 先来几个演示 graph LR source(*.java) --javac--> bytecode(*.class) bytecode --java--> result(程序输出) graph LR type(type) -.-> type type -.-> object(object) type -.-> A(A) type -.-> int(int) A -.-> a((a)) int -.-> i((i)) object --> type object --> A flowchart [docs - live editor] {% mermaid %} graph TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} C -->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[Car] {% endmermaid %} graph TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} C -->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[Car] {% mermaid %} flowchart LR A[Hard] -->|Text| B(Round) B --> C{Decision} C -->|One| D[Result 1] C -->|Two| E[Result 2] {% endmermaid %} flowchart LR A[Hard] -->|Text| B(Round) B --> C{Decision} C -->|One| D[Result 1] C -->|Two| E[Result 2] Sequence diagram [docs - live editor] {% mermaid %} sequenceDiagram loop every day Alice->>John: Hello John, how are you? John-->>Alice: Great! end {% endmermaid %} sequenceDiagram loop every day Alice->>John: Hello John, how are you? John-->>Alice: Great! end Gantt diagram [docs - live editor] {% mermaid %} gantt dateFormat YYYY-MM-DD title Adding GANTT diagram functionality to mermaid section A section Completed task :done, des1, 2014-01-06,2014-01-08 Active task :active, des2, 2014-01-09, 3d Future task : des3, after des2, 5d Future task2 : des4, after des3, 5d section Critical tasks Completed task in the critical line :crit, done, 2014-01-06,24h Implement parser and jison :crit, done, after des1, 2d Create tests for parser :crit, active, 3d Future task in critical line :crit, 5d Create tests for renderer :2d Add to mermaid :1d section Documentation Describe gantt syntax :active, a1, after des1, 3d Add gantt diagram to demo page :after a1 , 20h Add another diagram to demo page :doc1, after a1 , 48h section Last section Describe gantt syntax :after doc1, 3d Add gantt diagram to demo page : 20h Add another diagram to demo page : 48h {% endmermaid %} gantt dateFormat YYYY-MM-DD title Adding GANTT diagram functionality to mermaid section A section Completed task :done, des1, 2014-01-06,2014-01-08 Active task :active, des2, 2014-01-09, 3d Future task : des3, after des2, 5d Future task2 : des4, after des3, 5d section Critical tasks Completed task in the critical line :crit, done, 2014-01-06,24h Implement parser and jison :crit, done, after des1, 2d Create tests for parser :crit, active, 3d Future task in critical line :crit, 5d Create tests for renderer :2d Add to mermaid :1d section Documentation Describe gantt syntax :active, a1, after des1, 3d Add gantt diagram to demo page :after a1 , 20h Add another diagram to demo page :doc1, after a1 , 48h section Last section Describe gantt syntax :after doc1, 3d Add gantt diagram to demo page : 20h Add another diagram to demo page : 48h ER图 erDiagram CUSTOMER }|..|{ DELIVERY-ADDRESS : has CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ INVOICE : "liable for" DELIVERY-ADDRESS ||--o{ ORDER : receives INVOICE ||--|{ ORDER : covers ORDER ||--|{ ORDER-ITEM : includes PRODUCT-CATEGORY ||--|{ PRODUCT : contains PRODUCT ||--o{ ORDER-ITEM : "ordered in" erDiagram CUSTOMER }|..|{ DELIVERY-ADDRESS : has CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ INVOICE : "liable for" DELIVERY-ADDRESS ||--o{ ORDER : receives INVOICE ||--|{ ORDER : covers ORDER ||--|{ ORDER-ITEM : includes PRODUCT-CATEGORY ||--|{ PRODUCT : contains PRODUCT ||--o{ ORDER-ITEM : "ordered in" class [docs - live editor] {% mermaid %} classDiagram Animal <|-- Duck Animal <|-- Fish Animal <|-- Zebra Animal : +int age Animal : +String gender Animal: +isMammal() Animal: +mate() class Duck{ +String beakColor +swim() +quack() } class Fish{ -int sizeInFeet -canEat() } class Zebra{ +bool is_wild +run() } {% endmermaid %} classDiagram Animal <|-- Duck Animal <|-- Fish Animal <|-- Zebra Animal : +int age Animal : +String gender Animal: +isMammal() Animal: +mate() class Duck{ +String beakColor +swim() +quack() } class Fish{ -int sizeInFeet -canEat() } class Zebra{ +bool is_wild +run() } State [docs - live editor] {% mermaid %} stateDiagram-v2 [*] --> Still Still --> [*] Still --> Moving Moving --> Still Moving --> Crash Crash --> [*] {% endmermaid %} stateDiagram-v2 [*] --> Still Still --> [*] Still --> Moving Moving --> Still Moving --> Crash Crash --> [*] Pie [docs - live editor] {% mermaid %} pie title Pets adopted by volunteers "Dogs" : 386 "Cats" : 85 "Rats" : 15 {% endmermaid %} pie title Pets adopted by volunteers "Dogs" : 386 "Cats" : 85 "Rats" : 15 User Journey [docs - live editor] {% mermaid %} journey title My working day section Go to work Make tea: 5: Me Go upstairs: 3: Me Do work: 1: Me, Cat section Go home Go downstairs: 5: Me Sit down: 3: Me {% endmermaid %} journey title My working day section Go to work Make tea: 5: Me Go upstairs: 3: Me Do work: 1: Me, Cat section Go home Go downstairs: 5: Me Sit down: 3: Me Git Graph [docs - live editor] {% mermaid %} gitGraph commit commit branch develop checkout develop commit commit checkout main merge develop commit commit {% endmermaid %} gitGraph commit commit branch develop checkout develop commit commit checkout main merge develop commit commit C4 diagram [docs - live editor] C4Context title System Context diagram for Internet Banking System Enterprise_Boundary(b0, "BankBoundary0") { Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") Person(customerB, "Banking Customer B") Person_Ext(customerC, "Banking Customer C", "desc") Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.") System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") Enterprise_Boundary(b1, "BankBoundary") { SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") System_Boundary(b2, "BankBoundary2") { System(SystemA, "Banking System A") System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts. next line.") } System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") Boundary(b3, "BankBoundary3", "boundary") { SystemQueue(SystemF, "Banking System F Queue", "A system of the bank.") SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") } } } BiRel(customerA, SystemAA, "Uses") BiRel(SystemAA, SystemE, "Uses") Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") Rel(SystemC, customerA, "Sends e-mails to") UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red") UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5") UpdateRelStyle(SystemAA, SystemE, $textColor="blue", $lineColor="blue", $offsetY="-10") UpdateRelStyle(SystemAA, SystemC, $textColor="blue", $lineColor="blue", $offsetY="-40", $offsetX="-50") UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20") UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1") C4Context title System Context diagram for Internet Banking System Enterprise_Boundary(b0, "BankBoundary0") { Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") Person(customerB, "Banking Customer B") Person_Ext(customerC, "Banking Customer C", "desc") Person(customerD, "Banking Customer D", "A customer of the bank, with personal bank accounts.") System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") Enterprise_Boundary(b1, "BankBoundary") { SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") System_Boundary(b2, "BankBoundary2") { System(SystemA, "Banking System A") System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts. next line.") } System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") Boundary(b3, "BankBoundary3", "boundary") { SystemQueue(SystemF, "Banking System F Queue", "A system of the bank.") SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") } } } BiRel(customerA, SystemAA, "Uses") BiRel(SystemAA, SystemE, "Uses") Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") Rel(SystemC, customerA, "Sends e-mails to") UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red") UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5") UpdateRelStyle(SystemAA, SystemE, $textColor="blue", $lineColor="blue", $offsetY="-10") UpdateRelStyle(SystemAA, SystemC, $textColor="blue", $lineColor="blue", $offsetY="-40", $offsetX="-50") UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20") UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1") Katex Live editer {% mermaid %} graph LR A["$$f(\relax{x}) = \int_{-\infty}^\infty \hat{f}(\xi)\,e^{2 \pi i \xi x}\,d\xi$$"] -->|"$$\Bigg(\bigg(\Big(\big((\frac{-b\pm\sqrt{b^2-4ac}}{2a})\big)\Big)\bigg)\Bigg)$$"| B("$$1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots}}}}$$") A -->|"$$\overbrace{a+b+c}^{\text{note}}$$"| C("$$\phase{-78^\circ}$$") B --> D("$$x = \begin{cases} a &\text{if } b \\ c &\text{if } d \end{cases}$$") C --> E("$$x(t)=c_1\begin{bmatrix}-\cos{t}+\sin{t}\\ 2\cos{t} \end{bmatrix}e^{2t}$$") {% endmermaid %} graph LR A["$$f(\relax{x}) = \int_{-\infty}^\infty \hat{f}(\xi)\,e^{2 \pi i \xi x}\,d\xi$$"] -->|"$$\Bigg(\bigg(\Big(\big((\frac{-b\pm\sqrt{b^2-4ac}}{2a})\big)\Big)\bigg)\Bigg)$$"| B("$$1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots}}}}$$") A -->|"$$\overbrace{a+b+c}^{\text{note}}$$"| C("$$\phase{-78^\circ}$$") B --> D("$$x = \begin{cases} a &\text{if } b \\ c &\text{if } d \end{cases}$$") C --> E("$$x(t)=c_1\begin{bmatrix}-\cos{t}+\sin{t}\\ 2\cos{t} \end{bmatrix}e^{2t}$$") plant uml PlantUML 是一个允许你快速编写一下图表的组件 : Sequence diagram(时序图) Usecase diagram Class diagram(类图) Activity diagram (here is the legacy syntax) Component diagram State diagram Object diagram Deployment diagram(BETA) Timing diagram(BETA) Hexo安装hexo-tag-plantuml插件,便能使其绘制的图表在博客上展示,其原理其实使用的是 PlantUML 提供的在线服务, 只是简单地将标签包裹的代码传给服务器, 获取生成的链接, 生成 img标签替换原来的代码区域. plantUML在线编辑网站 可使用HTML标签将其嵌套 {% plantuml %} title Relationships - Class Diagram class Dwelling { +Int Windows +void LockTheDoor() } class Apartment class House class Commune class Window class Door Dwelling <|-down- Apartment: Inheritance Dwelling <|-down- Commune: Inheritance Dwelling <|-down- House: Inheritance Dwelling "1" *-up- "many" Window: Composition Dwelling "1" *-up- "many" Door: Composition {% endplantuml %} {% plantuml %} [内容] {% endplantuml %} 时序图 {% plantuml %} Bob->Alice : hello {% endplantuml %} Alice -> Bob: Authentication Request Bob --> Alice: Authentication Response Alice -> Bob: Another authentication Request Alice <-- Bob: Another authentication Response 用例图 {% plantuml %} User -> (Start) User --> (Use the application) : A small label :Main Admin: ---> (Use the application) : This is\nyet another\nlabel {% endplantuml %} 类图 {% plantuml %} class Object << general >> Object <|--- ArrayList note top of Object : In java, every class\nextends this one. note "This is a floating note" as N1 note "This note is connected\nto several objects." as N2 Object .. N2 N2 .. ArrayList class Foo note left: On last defined class {% endplantuml %} 活动图 {% plantuml %} @startuml start if (Graphviz 已安装?) then (yes) :处理所有\n绘制任务; else (no) :仅处理 __时序图__ 和 __活动__ 图; endif stop @enduml {% endplantuml %} 组件图 {% plantuml %} @startuml [First component] [Another component] as Comp2 component Comp3 component [Last\ncomponent] as Comp4 @enduml {% endplantuml %} 状态图 {% plantuml %} @startuml [*] --> State1 State1 --> [*] State1 : this is a string State1 : this is another string State1 -> State2 State2 --> [*] @enduml {% endplantuml %} 对象图 {% plantuml %} @startuml PERT left to right direction ' Horizontal lines: -->, <--, <--> ' Vertical lines: ->, <-, <-> title PERT: Project Name map Kick.Off { } map task.1 { Start => End } map task.2 { Start => End } map task.3 { Start => End } map task.4 { Start => End } map task.5 { Start => End } Kick.Off --> task.1 : Label 1 Kick.Off --> task.2 : Label 2 Kick.Off --> task.3 : Label 3 task.1 --> task.4 task.2 --> task.4 task.3 --> task.4 task.4 --> task.5 : Label 4 @enduml {% endplantuml %} 部署图 {% plantuml %} @startuml actor actor agent agent artifact artifact boundary boundary card card cloud cloud component component control control database database entity entity file file folder folder frame frame interface interface node node package package queue queue stack stack rectangle rectangle storage storage usecase usecase @enduml {% endplantuml %} 嵌入iframe code_dir code_dir的默认值为路径downloads/code [donwload file](/downloads/code/demo.html) Youtube视频 在浏览器中进入想分享的视频, 点击分享, 选择第一个“嵌入”按钮, 就可以得到嵌入博文中所需要的代码, 例如 <iframe width="560" height="315" src="https://www.youtube.com/embed/arj7oStGLkU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> bilibili视频 类似油管视频, 将鼠标移到B站视频下方分享按钮, 就会出来一段嵌入代码 <iframe src="//player.bilibili.com/player.html?aid=16091118&cid=26251892&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe> 统一尺寸控制 在Freemind主题下source/css/my.css中, 加入以下选择器 .auto-resizable-iframe { /*max-width: 540px;*/ max-width: 100%; margin: 0px auto; } .auto-resizable-iframe > div { position: relative; padding-bottom: 75%; height: 0px; } .auto-resizable-iframe iframe { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; } 然后将前面iframe放入两层div元素里, 最外层元素的类设为auto-resizable-iframe, 删除iframe中的宽度长度控制, 即 <div class="auto-resizable-iframe"> <div> <iframe src="https://www.youtube.com/embed/arj7oStGLkU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div> </div> 两层div使得画面尺寸是响应式的. 比起直接黏贴iframe稍微麻烦一些, 但是好看的多. 本地iframe <iframe width="100%" scrolling=no height="800" frameborder="0" src="/downloads/code/demo.html"></iframe> iframe 自适应高度的代码如下 <script type="text/javascript"> function SetCwinHeight(){ var iframeid = document.getElementById("iframeid"); //iframe id if (document.getElementById) { if (iframeid && !window.opera) { if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) { iframeid.height = iframeid.contentDocument.body.offsetHeight + 50; } else if (iframeid.Document && iframeid.Document.body.scrollHeight) { frameid.height = iframeid.Document.body.scrollHeight + 50; } } } } </script> <iframe width="100%" id="iframeid" onload="Javascript:SetCwinHeight()" scrolling=no height="1000" frameborder="0" src="https://www.17lai.site/iframe-html/"></iframe> URL 卡片 valkyr url card a simple url card display plugin for hexo {% valkyrurl [url=https://github.com/toastsgithub/hexo-valkyr-url] [title="valkyr url card"] [avatar=https://blog.17lai.site/medias_webp/cover/hexo.webp] [desc="a simple url card display plugin for hexo"] %} {% valkyrurl [url=http://example.com] [otherOpt=value] %} avatar image that describe your link (optional) title title desc description url destination when you click image url or title 空格要用引号包裹起来! 原作者失踪很久了,个人定制修改了一个自用版本,原版把 CSS 内嵌,引起不必要的体积增大,性能问题。修改版把 CSS 部分独立出来了,方便定制修改! hexo-matery-url BILIBILI 视频 hexo-bilibili-card {% bilicard BV1sr4y1K7Be %} 这个接口容易获取失败,网络超时错误 {% bilicard your_video_id %} hexo-bilibili-plus {%blil $VID} hexo-github-card {% githubCard user:your_user [repo:your_repo] [width:400] [height:200] [theme:default] [client_id:your_client_id] [client_secret:your_client_secret] [align:text-align_position] %} {% githubCard user:appotry %} {% githubCard user:appotry repo:hexo-github-card %} hexo-douban-card 强烈推荐这个,提的几个 issue 作者回复很快,问题修复也非常快。 支持爬取 douban 数据本地缓存,图片代理地址自定义,爬取 cookie 自定义! 插件配置 需要在 _config.yml 中配置 doubanCard,但这并不是必选项,如果你遇到了某些需要登录的豆瓣网址,那么请填写 cookie,如果你遇到图片代理失效的问题,请自行替换 imgProxy。未经验证的代理网址可以参考这个 issue:图像加速服务weserv地址被reset了,不能显示图片 doubanCard: cookie: ABCDEFGHIJKLMNOPQRSTUVWXYZ imgProxy: https://images.weserv.nl/?url= 灯影绰约 电影名: 绣春刀(2014) 导演: 路阳 主演: 张震/刘诗诗 上映时间: 2014-08-07(中国大陆) 评分: 7.6 见字如晤 书名: 一个人生活 作者: [日]谷川俊太郎 出版年份: 2019-3 评分: 7.0 余音绕梁 音乐名: María 表演者: 화사/华莎 发行时间: 2020-06-30 评分: 8.3 {% douban movie 24745500 %} {% douban book 30376420 %} {% douban music 35099703 %} Github Stats Card Github https://github.com/appotry/github-readme-stats 参考代码 Docker Hub https://hub.docker.com/r/bloodstar/github-readme-stats 更详细参数使用说明,请参考 Github 仓库 Readme 说明 由于 github 对 api 调用次数有限制,最好自建服务器使用! 自建 Docker 服务 docker-compose.yml version: "3" services: grs: image: bloodstar/github-readme-stats:latest container_name: grs environment: PAT_1: ghp_**** CACHE_SECONDS: 600 ports: - 9000:9000 docker run $ docker run \ --name grs \ --restart=unless-stopped \ -d \ -e PAT_1="ghp_****" \ bloodstar/github-readme-stats Vercel 和 docker 调用差异 和Vercel 部署调用不同,不需要 /api 这里vercel 和 docker 调用接口一致是比较容易实现的。为了方便和上游同步,这里就没有做修改。 # Vercel 部署调用 ![](https://ghstats.17lai.site/api?username=appotry) # Docker 部署调用 ![](https://ghstats.17lai.site/?username=appotry) [![Appotry's GitHub stats](https://ghstats.17lai.site/?username=appotry)](https://github.com/appotry/github-readme-stats) GitHub Stats Card [![Appotry's GitHub stats](https://ghstats.17lai.site/?username=appotry)](https://github.com/appotry/github-readme-stats) <picture> <source srcset="https://ghstats.17lai.site/?username=appotry&show_icons=true&theme=dark" media="(prefers-color-scheme: dark)" /> <source srcset="https://ghstats.17lai.site/?username=appotry&show_icons=true" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" /> <img src="https://ghstats.17lai.site/?username=appotry&show_icons=true" /> </picture> GitHub Repo Pins [![Readme Card](https://ghstats.17lai.site/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats) GitHub Gist Pins [![Gist Card](https://ghstats.17lai.site/gist?id=bbfce31e0217a3689c8d961a356cb10d)](https://gist.github.com/Yizack/bbfce31e0217a3689c8d961a356cb10d/) Top Languages Card [![Top Langs](https://ghstats.17lai.site/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) WakaTime Stats Card [![Harlok's WakaTime stats](https://ghstats.17lai.site/wakatime?username=ffflabs)](https://github.com/anuraghazra/github-readme-stats) hexo-feed-new 详细见 支持RSS分类订阅 hexo-lazyload-image 详细见 图片懒加载 插入音乐和视频 hexo-tag-aplayer hexo-tag-dplayer 最近做减法,去掉不必要的功能,只使用下面这个插件。 hexo-tag-mmedia 推荐使用 插入音乐 官方教程 {% aplayer title author url [picture_url, narrow, autoplay, width:xxx, lrc:xxx] %} title : 曲目标题 author: 曲目作者 url: 音乐文件 URL 地址 picture_url: (可选) 音乐对应的图片地址 narrow: (可选)播放器袖珍风格 autoplay: (可选) 自动播放,移动端浏览器暂时不支持此能 width:xxx: (可选) 播放器宽度 (默认: 100%) lrc:xxx: (可选)歌词文件 URL #### 单曲附带歌词显示 {% aplayer "Hotel California" "Camille and Kennerly" "https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.mp3" "https://cdn.17lai.site/media/music/Hotel%20California/Hotel%20California.webp" "lrc:https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.lrc" %} 音乐播放列表 {% aplayerlist %} { "narrow": false, // (可选)播放器袖珍风格 "autoplay": true, // (可选) 自动播放,移动端浏览器暂时不支持此功能 "mode": "random", // (可选)曲目循环类型,有 'random'(随机播放), 'single' (单曲播放), 'circulation' (循环播放), 'order' (列表播放), 默认:'circulation' "showlrc": 3, // (可选)歌词显示配置项,可选项有:1,2,3 "mutex": true, // (可选)该选项开启时,如果同页面有其他 aplayer 播放,该播放器会暂停 "theme": "#e6d0b2", // (可选)播放器风格色彩设置,默认:#b7daff "preload": "metadata", // (可选)音乐文件预载入模式,可选项: 'none' 'metadata' 'auto', 默认: 'auto' "listmaxheight": "513px", // (可选) 该播放列表的最大长度 "music": [ { "title": "CoCo", "author": "Jeff Williams", "url": "caffeine.mp3", "pic": "caffeine.jpeg", "lrc": "caffeine.txt" }, { "title": "アイロニ", "author": "鹿乃", "url": "irony.mp3", "pic": "irony.jpg" } ] } {% endaplayerlist %} {% aplayerlist %} { "narrow": false, "autoplay": true, "mode": "random", "showlrc": 3, "mutex": true, "theme": "#e6d0b2", "preload": "metadata", "listmaxheight": "513px", "music": [ { "title": "Hotel California", "author": "Camille and Kennerly", "url": "https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.mp3", "pic": "https://cdn.17lai.site/media/music/Hotel%20California/Hotel%20California.webp", "lrc": "https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.lrc" }, { "title": "Sold Out", "author": "Diamonds", "url": "https://cdn.17lai.site/media/music/Diamonds/05%20Sold%20Out.mp3", "pic": "https://cdn.17lai.site/media/music/Diamonds/Diamonds.jpg" } ] } {% endaplayerlist %} 插入视频 官方教程 {% dplayer key=value ... %} 例: {% dplayer "url=http://www.nenu.edu.cn/_upload/article/videos/03/5f/7c999eed42e3aadc413d7f851f0e/0f50b3eb-9285-41d2-ac4d-6cc363651aad_B.mp4" "autoplay=true" "preload=metadata" "hotkey=true" %} 有关的选项列表如下: 选项 默认值 描述 url 必须值 视频地址 loop false 视频循环播放 volume 0.7 播放器音量 hotkey true 开启热键 autoplay true 自动播放,移动端浏览器暂时不支持此功能 logo - 在左上角展示一个 logo,你可以通过 CSS 调整它的大小和位置 mutex true 该选项开启时,如果同页面有其他播放,该播放器会暂停 highlight [] 自定义进度条提示点 preload auto 视频文件预载入模式,可选项: none, metadata, auto theme #ad7a86 播放器风格色彩设置 注:如果使用腾讯视频、优酷视频等在线视频网站的资源,需要先进行视频地址解析,如点量视频解析,获取到实际的视频地址。 在使用优酷或者腾讯视频时可以直接复制分享代码到文章中,如: <iframe height=498 width=510 src='https://player.youku.com/embed/XMjk4ODAyMzIyOA==' frameborder=0 'allowfullscreen'></iframe> dplayer {% dplayer "url=http://www.nenu.edu.cn/_upload/article/videos/03/5f/7c999eed42e3aadc413d7f851f0e/0f50b3eb-9285-41d2-ac4d-6cc363651aad_B.mp4" "autoplay=false" "preload=metadata" "hotkey=true" %} iframe <iframe height=498 width=510 src='https://player.youku.com/embed/XMjk4ODAyMzIyOA==' frameborder=0 'allowfullscreen'></iframe> hexo-tag-mmedia使用 官方教程 audio 此部分请熟读 Audio 相关介绍 目前主题中不可用 使用 : 或 = 分割。 所有 <audio> 标签的原生参数均可添加,只要能写进去就可以。 具体能否实现相关标准,取决于客户端浏览器。 {% mmedia "audio" "src:a.mp3" %} {% mmedia "audio" "src:https://baidu.com/a.mp3" "autoplay:true" %} video 此部分请熟读 Video 相关介绍 目前主题中不可用 使用 : 或 = 分割。 所有 <video> 标签的原生参数均可添加,只要能写进去就可以。 具体能否实现相关标准,取决于客户端浏览器。 {% mmedia "video" "src:a.mp4" %} {% mmedia "video" "src:https://baidu.com/a.mp4" "autoplay:true" %} MetingJS 此部分请熟读 MetingJS 文档 option default description id require song id / playlist id / album id / search keyword server require music platform: netease, tencent, kugou, xiami, baidu type require song, playlist, album, search, artist auto options music link, support: netease, tencent, xiami fixed false enable fixed mode mini false enable mini mode autoplay false audio autoplay theme #2980b9 main color loop all player loop play, values: ‘all’, ‘one’, ‘none’ order list player play order, values: ‘list’, ‘random’ preload auto values: ‘none’, ‘metadata’, ‘auto’ volume 0.7 default volume, notice that player will remember user setting, default volume will not work after user set volume themselves mutex true prevent to play multiple player at the same time, pause other players when this player start play lrc-type 0 lyric type list-folded false indicate whether list should folded at first list-max-height 340px list max height storage-name metingjs localStorage key that store player setting Documentation for APlayer can be found at https://aplayer.js.org/#/home?id=options 单曲 {% mmedia "meting" "auto=https://y.qq.com/n/ryqq/songDetail/0005RQAO3FqG5K" %} {% mmedia "meting" "auto=https://y.qq.com/n/yqq/song/001RGrEX3ija5X.html" %} {% mmedia "meting" "server=netease" "type=playlist" "id=60198" %} Aplayer 详细参数表: 参数 默认 解释 name - audio name artist - audio artist url - audio url cover - audio cover lrc - audio lrc theme - audio theme type auto audio type 可选 ‘auto’, ‘hls’, ‘normal’ autoplay false autoplay loop ‘all’ player loop play, values: ‘all’, ‘one’, ‘none’ order ‘list’ player play order, values: ‘list’, ‘random’ volume 0.7 default volume, tlistMaxHeight - list max height 不在表格内的参数请使用下面 JSON 类型的参数。 mmedia 插件允许在 contents 部分使用 JSON 编写配置,由于允许使用 JSON5,此项配置几乎与 APlayer 完全一致。 单曲 {% mmedia "aplayer" "name:Hotel California" "artist:Camille and Kennerly" "url:https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.mp3" "lrc:https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.lrc" "cover:https://cdn.17lai.site/media/music/Hotel%20California/Hotel%20California.webp" "volume:0.66" %} 列表 var PsYqigNOUuvaGfdz_options = JSON.parse('{\"autoplay\":false,\"audio\":[{\"name\":\"Hotel California\",\"artist\":\"Camille and Kennerly\",\"url\":\"https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.mp3\",\"cover\":\"https://cdn.17lai.site/media/music/Hotel%20California/Hotel%20California.webp\",\"lrc\":\"https://cdn.17lai.site/media/music/Hotel%20California/01%20Hotel%20California.lrc\",\"theme\":\"#ebd0c2\"},{\"name\":\"Sold Out\",\"artist\":\"Diamonds\",\"url\":\"https://cdn.17lai.site/media/music/Diamonds/05%20Sold%20Out.mp3\",\"cover\":\"https://cdn.17lai.site/media/music/Diamonds/Diamonds.jpg\",\"theme\":\"#ebd0c2\"},{\"name\":\"The Final Bell\",\"artist\":\"Rocky_Original Motion Picture Score\",\"url\":\"https://cdn.17lai.site/media/music/Rocky_%20Original%20Motion%20Picture%20Score/12%20Bill%20Conti%20-%20The%20Final%20Bell.mp3\",\"cover\":\"https://cdn.17lai.site/media/music/Rocky_%20Original%20Motion%20Picture%20Score/Rocky_%20Original%20Motion%20Picture%20Score.jpg\",\"theme\":\"#ebd0c2\"},{\"name\":\" Croatian Rhapsody\",\"artist\":\"The Piano Player\",\"url\":\"https://cdn.17lai.site/media/music/The%20Piano%20Player/11%20Croatian%20Rhapsody.mp3\",\"cover\":\"https://cdn.17lai.site/media/music/The%20Piano%20Player/The%20Piano%20Player.jpg\",\"theme\":\"#ebd0c2\"}],\"volume\":0.8}'); PsYqigNOUuvaGfdz_options.container = document.getElementById("mmedia-PsYqigNOUuvaGfdz");HEXO_MMEDIA_DATA.css.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.css");HEXO_MMEDIA_DATA.js.push("https://cdn.jsdelivr.net/npm/aplayer@1/dist/APlayer.min.js");HEXO_MMEDIA_DATA.aplayerData.push(PsYqigNOUuvaGfdz_options); 例子 {% mmedias "aplayer" "autoplay:false" %} { "volume": 0.8, "audio": [ { "name": "name1", "artist": "artist1", "url": "url1.mp3", "cover": "cover1.jpg", "lrc": "lrc1.lrc", "theme": "#ebd0c2" }, { "name": "name2", "artist": "artist2", "url": "url2.mp3", "cover": "cover2.jpg", "lrc": "lrc2.lrc", "theme": "#46718b" } ] } {% endmmedias %} Dplayer 此部分请熟读 DPlayer 文档 {% mmedia "dplayer" "url:a.mp4" %} {% mmedias "dplayer" "flv:" "url:https://dandoc.u2sb.com/video/%E5%AE%89%E8%A3%85/1-%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85.mp4" %} { "contextmenu": [ { text: "custom1", link: "https://github.com/DIYgod/DPlayer" } ] } {% endmmedias %} {% mmedia "dplayer" "url:https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" %} {% mmedia "dplayer" "url:https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" %} {% mmedias "dplayer" %} { video: { url: "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" } } {% endmmedias %} 哔哩哔哩 详细参数表: 参数 默认 解释 aid - aid bvid - bvid,与 aid 同时出现时以 bvid 为准 page 1 page danmaku true 是否有弹幕 ture or false allowfullscreen allowfullscreen 允许全屏, allowfullscreen 或 true 允许,其他选项不允许 sandbox 见 配置 iframe sandbox width 100% css 属性 max_width 850px css 属性 margin auto css 属性 mmedia 插件允许在 contents 部分使用 JSON 编写配置,使用 JSON5 标准。 {% mmedia "bilibili" "bvid:BV1fs411S7u7" %} 西瓜视频 详细参数表: 参数 默认 解释 xid - 西瓜视频的 ID,就是那一串数字 id - 一般情况下不需要填写 autoplay false autoplay startTime 0 开始时间,秒 allowfullscreen allowfullscreen 允许全屏, allowfullscreen 或 true 允许,其他选项不允许 sandbox 见 配置 iframe sandbox width 100% css 属性 max_width 850px css 属性 margin auto css 属性 {% mmedia "xigua" "xid=6925997698269053453" %} {% mmedia "xigua" "xid:6925997698269053453" "autoplay:true" %} {% mmedia "xigua" "xid=6925997698269053453" %} ArtPlayer 此部分请熟读 ArtPlayer 文档 使用 : 或 = 分割。 详细参数表: 参数 默认 解释 url - url title - title poster - poster type - type autoplay false video autoplay loop false video loop volume 0.7 default volume style - style 上面有一个比较特殊的参数 flv,这里单独解释一下,这个参数是用于引入其他 js 文件的,目前支持的有: hls dash shaka_dash flv webtorrent ,上述参数可多个一起使用,如果后面带有 js 地址,将直接使用,否则将使用 _config.yml 配置或插件默认配置,如: {% mmedia "artplayer" "flv:" "url:a.flv" %} {% mmedias "artplayer" "flv:" "hls:https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js" %} { ... } {% endmmedias %} {% mmedia "artplayer" "url:https://dandoc.u2sb.com/video/%E5%AE%89%E8%A3%85/1-%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85.mp4" %} {% mmedias "artplayer" "flv:" %} { url: "https://dandoc.u2sb.com/video/%E5%AE%89%E8%A3%85/1-%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85.mp4" } {% endmmedias %} {% mmedia "artplayer" "url:https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_2mb.mp4" %} {% mmedias "artplayer" %} { url: "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_2mb.mp4" } {% endmmedias %} bilibili {% mmedia "bilibili" "bvid:BV1fs411S7u7" %} xigua {% mmedia "xigua" "xid=6925997698269053453" %} artplayer {% mmedias "artplayer" %} { url: "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_2mb.mp4" } {% endmmedias %} hexo-tag-videojs 录屏:OBS OBS Studio录屏教程 视频切片:FFmpeg 托管:任何一个支持静态资源访问的都可以,比如跑个 Nginx Hexo 插件:hexo-tag-videojs Video标签需要加载完整个视频文件(如mp4)才能开始播放,拖动不便。 使用bilibili服务,审查手段未知,可能看你白嫖就封号了 自托管ts切片综合考虑是最佳方案! FFmpeg m3u8 切片 要使用FFmpeg将一个MP4文件制作为M3U8文件并使用TS分片,您可以按照以下步骤进行操作: 安装FFmpeg 首先,您需要安装FFmpeg。可以在FFmpeg的官方网站上下载适用于您的操作系统的二进制文件。 制作M3U8文件和TS分片 使用以下命令,将您的MP4文件制作为M3U8文件和TS分片: ffmpeg -i input.mp4 -codec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_list output.m3u8 -segment_time 10 output%03d.ts -i input.mp4:指定输入文件为input.mp4。 -codec copy:使用与输入文件相同的编解码器。 -vbsf h264_mp4toannexb:将MP4的H.264视频流转换为MPEG-TS格式,以便进行分片。 -map 0:将所有输入流映射到输出中。 -f segment:指定输出格式为segment,表示进行分段。 -segment_list output.m3u8:指定输出的M3U8文件名为output.m3u8。 -segment_time 10:指定每个TS分片的时长为10秒。 output%03d.ts:指定输出的TS分片文件名为output001.ts、output002.ts等。 执行命令后,FFmpeg将开始处理您的视频,并将其制作为M3U8文件和多个TS分片。 检查输出 完成后,您可以在当前目录下找到一个名为output.m3u8的文件,以及一系列以output001.ts、output002.ts等命名的TS分片文件。您可以使用任何支持M3U8格式的播放器来播放此视频。 脑图 原作者记录 如果你的博客安装了 pjax 请开启此项配置 hexo_markmap: pjax: true 思维导图 links"},{"t":"list_item","d":4,"p":{"lines":[14,15]},"v":"inline text styles"},{"t":"list_item","d":4,"p":{"lines":[15,17]},"v":"multiline \ntext"},{"t":"list_item","d":4,"p":{"lines":[17,18]},"v":"inline code"},{"t":"list_item","d":4,"p":{"lines":[18,19]},"v":"Katex - x=−b±b2−4ac2ax = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}x=2a−b±b2−4ac ​​"}]}],"p":{}}"> 统计学习方法 kkk近邻法"},{"t":"list_item","d":6,"p":{"lines":[4,5]},"v":"决策树"},{"t":"list_item","d":6,"p":{"lines":[5,6]},"v":"逻辑斯蒂回归"},{"t":"list_item","d":6,"p":{"lines":[6,7]},"v":"最大熵模型"},{"t":"list_item","d":6,"p":{"lines":[7,8]},"v":"支持向量机"},{"t":"list_item","d":6,"p":{"lines":[8,9]},"v":"提升方法"},{"t":"list_item","d":6,"p":{"lines":[9,10]},"v":"条件随机场"}]},{"t":"list_item","d":4,"p":{"lines":[10,11]},"v":"生成方法","c":[{"t":"list_item","d":6,"p":{"lines":[11,12]},"v":"朴素贝叶斯方法"},{"t":"list_item","d":6,"p":{"lines":[12,13]},"v":"隐马尔可夫模型"}]}]},{"t":"list_item","d":2,"p":{"lines":[13,14]},"v":"无监督学习"}],"p":{}}"> 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Here is the footnote. ↩︎ Here’s one with multiple blocks. Subsequent paragraphs are indented to show that they ↩︎ Footnote can have markup and multiple paragraphs. ↩︎ Footnote text. ↩︎ ↩︎ Text of inline footnote ↩︎

2021/10/20
articleCard.readMore

第一次使用VS CODE时你应该指导的一切配置

前言 文章标题:《第一次使用 VS Code 时你应该知道的一切配置》。本文的最新内容,更新于 2021-10-09。大家完全不用担心这篇文章会过时,因为随着 VS Code 的版本更新和插件更新,本文也会随之更新。 本文的最新内容,也会在GitHub上同步更新,欢迎 star。 VS Code 软件实在是太酷、太好用了,越来越多的新生代互联网民工正在使用它。 前端男神尤雨溪大大这样评价 VS Code: 有一点你可能会感到惊讶:VS Code 这款软件本身,是用 JavaScript 语言编写的(具体请自行查阅基于 JS 的 PC 客户端开发框架 Electron)。Jeff Atwood 在 2007 年提出了著名的 Atwood 定律: 任何能够用 JavaScript 实现的应用系统,最终都必将用 JavaScript 实现。 Jeff Atwood 这个人是谁不重要(他是 Stack Overflow 网站的联合创始人),重要的是这条定律。 前端目前是处在春秋战国时代,各路英雄豪杰成为后浪,各种框架工具层出不穷,VS Code 软件无疑是大前端时代最骄傲的工具。 如果你是做前端开发(JavaScript 编程语言为主),则完全可以将 VS Code 作为「主力开发工具」。这款软件是为前端同学量身定制的,开箱即用。 如果你是做其他语言方向的开发,并且不需要太复杂的集成开发环境,那么,你可以把 VS Code 作为「代码编辑器」来使用,纵享丝滑。 甚至是一些写文档、写作的同学,也经常把 VS Code 作为 markdown 写作工具,毫无违和感。 退而求其次,即便你不属于以上任何范畴,你还可以把 VS Code 当作最简单的文本编辑器来使用,完胜 Windows 系统自带的记事本。 写下这篇文章,是顺势而为。 一、惊艳登场:VS Code 的介绍 VS Code 的全称是 Visual Studio Code,是一款开源的、免费的、跨平台的、高性能的、轻量级的代码编辑器。它在性能、语言支持、开源社区方面,都做得很不错。 微软有两种软件:一种是 VS Code,一种是其他软件。 在2015年4月29日的微软Build开发者大会上,微软宣布推出 VS Code之后,这个轻量级的编辑器成为全球无数开发者们最喜爱的开发工具。VS Code基于开源且跨平台的理念,每月都会进行迭代,并提供每天发布的 insider 版本(insider是微软的一种公测计划,类似于国内软件所说的内测版)。它拥有至少几万个插件,生态极为活跃和丰富。 IDE 与 编辑器的对比 IDE 和编辑器是有区别的: IDE(Integrated Development Environment,集成开发环境):对代码有较好的智能提示和相互跳转,同时侧重于工程项目,对项目的开发、调试工作有较好的图像化界面的支持,因此比较笨重。比如 Eclipse 的定位就是 IDE。 编辑器:要相对轻量许多,侧重于文本的编辑。比如 Sublime Text 的定位就是编辑器。再比如 Windows 系统自带的「记事本」就是最简单的编辑器。 需要注意的是,VS Code 的定位是编辑器,而非 IDE ,但 VS Code 又比一般的编辑器的功能要丰富许多。可以这样理解:VS Code 的体量是介于编辑器和 IDE 之间。VS Code 的使命,是让开发者在编辑器里拥有 IDE 那样的开发体验。 VS Code流行起来之后,使用 Sublime Text、Atom 这类编辑器软件的人,自然就越来越少了。 VS Code 的特点 跨平台:支持 MacOS、Windows 和 Linux 等多个平台。在这多种平台下,拥有一致的用户界面和开发体验。 开源:VS Code 的源代码以 MIT 协议开源。不仅代码开源,而且整个产品的开发计划和发布管理也都是开源的。VS Code团队每年都会在 GitHub 的Wiki上发布 Roadmap,列出一整年的规划图。VS Code 软件的官方文档也托管在了 GitHub 上。 自带终端、图形化的调试工具、Git 版本控制。 插件扩展:支持第三方插件,功能强大。既有中心化的插件市场,也可以直接在 VS Code里搜索你想要的插件。 生态:社区生态活跃且丰富,社区氛围浓厚。 自带 emmet:支持代码自动补全,快速生成简单的语法结构。要知道,这个功能在 Sublime Text中,得先安装插件才行。 语法支持:VS Code 自带了 JavaScript、TypeScript 和 Node.js 的语法支持,包括:语法高亮、代码智能提示和补全、括号匹配、颜色区分、代码片段提示等。也就是说,你在书写 JS 和 TS 时,这些语法支持都是自带的。其他的一些语言,你需要先安装相应的扩展包插件,就出现语法支持。 在修改配置方面,既有图形化的配置界面,也有 基于 JSON 文件的配置方式,满足不同人群的使用习惯。 前端利器之争: VS Code 与 WebStorm 前端小白最喜欢问的一个问题是:哪个编辑器/IDE 好用?是 VS Code 还是 WebStorm (WebStorm 其实是 IntelliJ IDEA 的定制版)?我来做个对比: 哪个更酷:显然 VS Code 更酷。 内存占用情况:根据我的观察,VS Code 是很占内存的(尤其是当你打开多个窗口的时候),但如果你的内存条够用,使用起来是不会有任何卡顿的感觉的。相比之下,IntelliJ IDEA 不仅非常占内存,而且还非常卡顿。如果你想换个既轻量级、又不占内存的编辑器,最好还是使用「Sublime Text」编辑器。 使用比例:当然是 VS Code 更胜一筹。先不说别的,我就拿数据说话,我目前所在的研发团队有 200 人左右(120个后台、80个前端),他们绝大部分人都在用 VS Code 编码,妥妥的。 所以,如果你以后还问这个问题,那就真有些掉底了。 VS Code 的技术栈、核心组件 了解 VS Code的技术栈和核心组件,可以让我们对 VS Code 有更深入的认识。此小段,了解即可。 开发框架:Electron。Electron可以使用 Node.js + JS这样的技术栈开发桌面GUI应用程序。 编辑器:Monaco Editor。Monaco Editor 是一款开源的在线代码编辑器,是 VS Code 浏览器版本的最核心组件。# 编程语言:TypeScript。TypeScript 是 JavaScript的严格超集。TS 在JS的基础上添加了许多功能,引入了声明文件,而且支持类型扩展。TS 适合长期的、多人开发的大型项目开发。 让编辑器支持语言功能:Language Server Protocol (LSP) 语言服务协议。LSP是编辑器/IDE 与语言服务器之间的一种协议,通过 JSON-PRC 传输消息,可以让编辑器嵌入并支持各种编程语言。开发者可以在编辑器中使用各种语言来编写程序。 让编辑器支持调试功能:Debug Adapter Protocol(DAP)。DAP 是基于 JSON的协议,它抽象了开发工具与调试工具质检的通信。 集成终端:Xterm.js。VS Code的集成终端是基于开源项目 Xterm.js 进行开发的。Xterm.js 是一个使用 TS 开发的终端组件。另外,Xterm.js 并不是直接下来下来就能用的终端应用,它只是一个前端组件,可以与 bash这样的进程进行连接,然后让用户通过 Xterm.js 进行交互。 VS Code 的安装 VS Code 官网:https://code.visualstudio.com VS Code 的安装很简单,直接去官网下载安装包,然后双击安装即可。 上图中,直接点击 download,一键下载安装即可。 VS Code支持以下平台: 安装完成后的界面如下: VS Code被分为以下五个区域: 编辑器 侧边栏 状态栏 活动栏 面板 VS Code在功能上非常克制,只包含了大多数开发流程中所需要的基础模块,包括:编辑器、文件管理、窗口管理、首选项设置、终端等。 你需要根据具体需要安装额外的组件或者插件。比如说,如果开发TS项目,则需要安装 TS编译器、ESLint、TSLint等编译工具。如果开发C语言项目,则需要安装gcc、Clang等编辑工具。 二、崭露锋芒:VS Code 快捷键 VS Code 用得熟不熟,首先就看你是否会用快捷键。以下列出的内容,都是常用快捷键,而加粗部分的快捷键,使用频率则非常高。 任何工具,掌握 20%的技能,足矣应对 80% 的工作。既然如此,你可能会问:那就只保留 20% 的特性,不久可以满足 80%的用户了吗? 但我想说的是:那从来都不是同样的 20%,每个人都会用到不同的功能。 掌握下面这些高频核心快捷键,你和你的工具,足矣露出锋芒。 1、工作区快捷键 Mac 快捷键 Win 快捷键 作用 备注 Cmd + Shift + P Ctrl + Shift + P,F1 显示命令面板 Cmd + B Ctrl + B 显示/隐藏侧边栏 很实用 Cmd + \ Ctrl + \ 拆分为多个编辑器 【重要】抄代码利器 Cmd + 1、2 Ctrl + 1、2 聚焦到第 1、第 2 个编辑器 同上重要 Cmd + +、Cmd + - ctrl + +、ctrl + - 将工作区放大/缩小(包括代码字体、左侧导航栏) 在投影仪场景经常用到 Cmd + J Ctrl + J 显示/隐藏控制台 Cmd + Shift + N Ctrl + Shift + N 重新开一个软件的窗口 很常用 Cmd + Shift + W Ctrl + Shift + W 关闭软件的当前窗口 Cmd + N Ctrl + N 新建文件 Cmd + W Ctrl + W 关闭当前文件 2、跳转操作 Mac 快捷键 Win 快捷键 作用 备注 Cmd + ` 没有 在同一个软件的多个工作区之间切换 使用很频繁 Cmd + Option + 左右方向键 Ctrl + Pagedown/Pageup 在已经打开的多个文件之间进行切换 非常实用 Ctrl + Tab Ctrl + Tab 在已经打开的多个文件之间进行跳转 不如上面的快捷键快 Cmd + Shift + O Ctrl + shift + O 在当前文件的各种方法之间(符号:Symbol)进行跳转 Cmd + T Ctrl + T 在当前工作区的各种方法之间(符号:Symbol)进行跳转 Ctrl + G Ctrl + G 跳转到指定行 Cmd+Shift+\ Ctrl+Shift+\ 跳转到匹配的括号 3、移动光标 Mac 快捷键 Win 快捷键 作用 备注 方向键 方向键 在单个字符之间移动光标 大家都知道 option + 左右方向键 Ctrl + 左右方向键 在单词之间移动光标 很常用 Cmd + 左右方向键 Fn + 左右方向键(或 Win + 左右方向键) 将光标定位到当前行的最左侧、最右侧(在整行之间移动光标) 很常用 Option + Alt + 左右方向键 Alt + Shift + 左右方向键 左右扩大/缩小选中的范围 很酷,极为高效 Cmd + ↑ Ctrl + Home 将光标定位到文件的第一行 Cmd + ↓ Ctrl + End 将光标定位到文件的最后一行 Cmd + Shift + \ 在代码块之间移动光标 4、编辑操作 Mac 快捷键 Win 快捷键 作用 备注 Cmd + C Ctrl + C 复制 Cmd + X Ctrl + X 剪切 Cmd + C Ctrl + V 粘贴 Cmd + Enter Ctrl + Enter 在当前行的下方新增一行,然后跳至该行 即使光标不在行尾,也能快速向下插入一行 Cmd+Shift+Enter Ctrl+Shift+Enter 在当前行的上方新增一行,然后跳至该行 即使光标不在行尾,也能快速向上插入一行 Option + ↑ Alt + ↑ 将代码向上移动 很常用 Option + ↓ Alt + ↓ 将代码向下移动 很常用 Option + Shift + ↑ Alt + Shift + ↑ 将代码向上复制一行 Option + Shift + ↓ Alt + Shift + ↓ 将代码向下复制一行 写重复代码的利器 另外再补充一点:将光标点击到某一行的任意位置时,默认就已经是选中全行了,此时可以直接复制或剪切,无需点击鼠标。这个非常实用,是所有的编辑操作中,使用得最频繁的。它可以有以下使用场景: 场景1:假设光标现在处于第5行的任意位置,那么,直接依次按下 Cmd + C 和 Cmd + V,就会把这行代码复制到第6行。继续按 Cmd + C 和 Cmd + V,就会把这行代码复制到第7行。copy代码so easy。 场景2:假设光标现在处于第5行,那么,先按下 Cmd + C,然后按两下↑ 方向键,此时光标处于第3行;紧接着,继续按下Cmd + V,就会把刚刚那行代码复制到第3行,原本处于第3行的代码会整体下移。 你看到了没?上面的两个场景,我全程没有使用鼠标,只通过简单的复制粘贴和方向键,就做到了如此迅速的copy代码。你说是不是很高效? 5、删除操作 Mac 快捷键 Win 快捷键 作用 备注 Cmd + shift + K Ctrl + Shift + K 删除整行 「Cmd + X」的作用是剪切,但也可以删除整行 option + Backspace Ctrl + Backspace 删除光标之前的一个单词 英文有效,很常用 option + delete Ctrl + delete 删除光标之后的一个单词 Cmd + Backspace 删除光标之前的整行内容 很常用 Cmd + delete 删除光标之后的整行内容 备注:上面所讲到的移动光标、编辑操作、删除操作的快捷键,在其他编辑器里,大部分都适用。 6、多光标选择/多光标编辑 多光标选择在编程的提效方面可谓立下了汗马功劳。因为比较难记住,所以你要时不时回来复习这一段。 Mac 快捷键 Win 快捷键 作用 备注 Option + 鼠标连续点击任意位置 Alt + 鼠标连续点击任意位置 在任意位置,同时出现多个光标 很容易记住 Cmd + D Ctrl + D 将光标放在某个单词的位置(或者先选中某个单词),然后反复按下「 Cmd + D 」键, 即可将下一个相同的词逐一加入选择。 较常用 Cmd + Shift + L Ctrl + Shift + L 将光标放在某个单词的位置(或者先选中某个单词),然后按下快捷键,则所有的相同内容处,都会出现光标。 很常用。比如变量重命名的时候,就经常用到 7、多列选择/多列编辑 多列选择是更高效的多光标选择,所以单独列成一小段。 Mac 快捷键 Win 快捷键 作用 备注 Cmd + Option + 上下键 Ctrl + Alt + 上下键 在连续的多列上,同时出现多个光标 较常用 Option + Shift + 鼠标拖动 Alt + Shift + 鼠标拖动 按住快捷键,然后把鼠标从区域的左上角拖至右下角,即可在选中区域的每一行末尾,出现光标。 很神奇的操作,较常用 Option + Shift + i Alt + Shift + I 选中一堆文本后,按下快捷键,既可在每一行的末尾都出现一个光标。 很常用 8、编程语言相关 Mac 快捷键 Win 快捷键 作用 备注 Cmd + / Ctrl + / 添加单行注释 很常用 Option + Shift + F Alt + shift + F 代码格式化 很常用 F2 F2 以重构的方式进行重命名 改代码备 Ctrl + J 将多行代码合并为一行 Win 用户可在命令面板搜索”合并行“ Cmd + Cmd + U Ctrl + U 将光标的移动回退到上一个位置 撤销光标的移动和选择 9、搜索相关 Mac 快捷键 Win 快捷键 作用 备注 Cmd + Shift + F Ctrl + Shift +F 全局搜索代码 很常用 Cmd + P Ctrl + P 在当前的项目工程里,全局搜索文件名 Cmd + F Ctrl + F 在当前文件中搜索代码,光标在搜索框里 Cmd + G F3 在当前文件中搜索代码,光标仍停留在编辑器里 很巧妙 10、自定义快捷键 按住快捷键「Cmd + Shift + P」,弹出命令面板,在命令面板中输入“快捷键”,可以进入快捷键的设置。 当然,你也可以选择菜单栏「偏好设置 --> 键盘快捷方式」,进入快捷键的设置: 11、快捷键列表 你可以点击 VS Code 左下角的齿轮按钮,效果如下: 上图中,在展开的菜单中选择「键盘快捷方式」,就可以查看和修改所有的快捷键列表了: 快捷键参考表(官方) VS Code官网提供了 PDF版本的键盘快捷键参考表,转需: Windows版本:https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf Mac 版本:https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf Linux版本:https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf 我们在 VS Code软件里通过菜单栏「帮助–>键盘快捷方式参考」也可以打开相应平台的快捷键大全(PDF版本)。 三、高端访问:命令面板的使用 Mac 用户按住快捷键 Cmd+Shift+P (Windows 用户按住快捷键Ctrl+Shift+P),可以打开快速命令面板。效果如下: 命令面板的作用是希望解放开发者的鼠标,让一些操作和配置可以直接通过键盘进行。如果让开发者记住所有的配置项在菜单的哪个位置是不现实的,而且有些命令并不在菜单中。 有了命令面板之后,如果你需要修改一些设置项,或者进行一些快捷操作,则可以通过「命令面板」来操作,效率会更高。接下来列举一些。 1、VS Code 设置为中文语言 Mac 用户按住快捷键 Cmd+Shift+P (Windows 用户按住快捷键Ctrl+Shift+P),打开命令面板。 在命令面板中,输入Configure Display Language,选择Install additional languages,然后安装插件Chinese (Simplified) Language Pack for Visual Studio Code即可。 或者,我们可以直接安装插件Chinese (Simplified) Language Pack for Visual Studio Code,是一样的。 安装完成后,重启 VS Code。 2、设置字体大小 在命令面板输入“字体”,可以进行字体的设置,效果如下: 当然,你也可以在菜单栏,选择「首选项-设置-常用设置」,在这个设置项里修改字体大小。 3、快捷键设置 在命令面板输入“快捷键”,就可以进入快捷键的设置。 4、大小写转换 选中文本后,在命令面板中输入transfrom,就可以修改文本的大小写了。 5、使用命令行启动 VS Code (1)输入快捷键「Cmd + Shift + P 」,选择install code command: (2)使用命令行: code命令:启动 VS Code 软件 code pathName/fileName命令:通过 VS Code 软件打开指定目录/指定文件。 备注:这种方法快捷简单,但是在电脑重启之后就失效了。稍后在第五段,我会介绍更常见的方法。 6、修改特定编程语言的设置项 输入快捷键「Cmd + Shift + P 」打开命令面板,然后输入并执行 Configure Language Specific Settings即可。 四、私人订制:VS Code 的常见配置 0、设置项介绍 在修改 VS Code配置之前,我们需要知道,在哪里可以找到设置项的入口。 方式1:Mac用户选择菜单栏「Code–> 首选项–>设置」,即可打开配置项: 方式2:点击软件右下角的设置图标: 如上图所示,VS Code提供两种不同范围的设置: 用户设置:全局生效。 工作区设置:只针对当前项目生效。工作区设置会覆盖用户设置。适用于团队协作场景。工作区的设置文件是保存在当前项目根目录的.vscode/settings.json中,可以被提交到Git仓库,方便共享给项目组的其他成员。 操作技巧: (1)我们可以在设置面板的顶部搜索框,输入关键词,就能迅速定位到你想要的设置项。 (2)上图中,点击右上角的icon,可以通过 json文件的形式修改设置项。 1、修改主题 1)修改颜色主题: 选择菜单栏「Code --> 首选项 --> 颜色主题」: 在弹出的对话框中,挑选你一个你喜欢的的颜色主题吧,或者安装其他颜色的主题: 或者在设置项里搜索Workbench: Color Theme,进行修改。 2)修改文件图标的主题: 选择菜单栏「Code --> 首选项 --> 文件图标主题」: 在弹出的对话框中,挑选你一个你喜欢的的主题吧,或者安装其他的主题: 或者在设置项里搜索Workbench: Icon Theme,进行修改。 2、面包屑(Breadcrumb)导航 打开 VS Code 的设置项,选择「用户设置 -> 工作台 -> 导航路径」,如下图所示: 上图中,将红框部分打钩即可。 设置成功后,我们就可以查看到当前文件的「层级结构」,非常方便。如下图所示: 有了这个面包屑导航,我们可以点击它,在任意目录、任意文件之间随意跳转。使用频繁非常高。 3、是否显示代码的行号 VS Code 默认显示代码的行号。你可以在设置项里搜索 editor.lineNumbers修改设置,配置项如下: 我建议保留这个设置项,无需修改。 4、右侧是否显示代码的缩略图 如果某个文件的代码量很大,缩略图就很有用了,可以预览全局,并在当前文件中快速跳转。 VS Code 会在代码的右侧,默认显示缩略图。你可以在设置项里搜索 editor.minimap 进行设置,配置项如下: 上面这张图,你仔细琢磨下会发现,中文翻译十分精准。 5、将当前行代码高亮显示(更改光标所在行的背景色) 当我们把光标放在某一行时,这一行的背景色并没有发生变化。如果想高亮显示当前行的代码,需要设置两步: (1)在设置项里搜索editor.renderLineHighlight,将选项值设置为all或者line。 (2)在设置项里增加如下内容: "workbench.colorCustomizations": { "editor.lineHighlightBackground": "#00000090", "editor.lineHighlightBorder": "#ffffff30" } 上方代码,第一行代码的意思是:修改光标所在行的背景色(背景色设置为全黑,不透明度 90%);第二行代码的意思是:修改光标所在行的边框色。 6、改完代码后立即自动保存 方式一: 改完代码后,默认不会自动保存。你可以在设置项里搜索files.autoSave,修改参数值为afterDelay ,即可自动保存。如下: files.autoSave的参数值有以下几种: off(默认值):不自动保存。 afterDelay(建议配置):文件修改超过一定时间(默认1秒)后,就自动保存。 onFocusChange:当前编辑器失去焦点时,则自动保存。如果我们将配置项修改为onFocusChange之后,那么,当光标离开该文件后,这个文件就会自动保存了。 onWindowChange:VS Code软件失去焦点时,则自动保存。 方式二: 当然,你也可以直接在菜单栏选择「文件-自动保存」。勾选后,当你写完代码后,文件会立即实时保存。 7、热退出 当VS Code退出后,它可以记住未保存的文件。如果你希望达到这种效果,那么,你需要先将设置项files.hotExit的值改为 onExitAndWindowClose。这个配置项要不要改,看你个人需要。比如我自己平时设置的值是onExit。 8、保存代码后,是否立即格式化 保存代码后,默认不会立即进行代码的格式化。你可以在设置项里搜索editor.formatOnSave查看该配置项: 我觉得这个配置项保持默认就好,不用打钩。 9、自动格式化粘贴的内容 在设置项里搜索 editor.formatOnPaste,将设置项改为true: 10、设置字体大小 在设置项里搜索fontSize,然后根据需要设置各种模块的字体大小: 11、空格 or 制表符 VS Code 会根据你所打开的文件来决定该使用空格还是制表。也就是说,如果你的项目中使用的都是制表符,那么,当你在写新的代码时,按下 tab 键后,编辑器就会识别成制表符。 (1)建议的设置项如下: editor.detectIndentation:自动检测(默认开启)。建议把这个配置项修改为 false,截图如下: 这样做,是为了取消系统的自动缩进,建议自己手动格式化比较好。 参考链接:https://www.yisu.com/zixun/327399.html editor.insertSpaces:按 Tab 键时插入空格(默认值为true)。截图如下: editor.tabSize:一个制表符默认等于四个空格。截图如下: (2)状态栏也会显示当前的缩进值。点击状态栏,可以直接修改 tabSize 缩进值: (3)另外,我们还可以安装 prettier 插件,设置代码在格式化时默认缩进值。prettier 是做代码格式化的最常见工具。 (4)去掉每一行末尾的空格。在设置项里搜索空格或者"files.trimTrailingWhitespace",将值设置为 true: 一般来说,每一行代码末尾的空格是多余的,所以建议去掉。 12、直观地显示代码里的空格和缩进 ✨ 代码里如果有缩进或者空格,肉眼是看不出来的,但是我们可以修改配置项,把它揪出来。 在配置项里搜索editor.renderWhitespace,修改为all: 修改之后,代码里的空格、缩进的展示效果如下: 看到了没?哪里有空格、哪里是缩进,全都一目了然。 13、新建文件后的默认文件类型 当我们按下快捷键「Cmd + N」新建文件时,VS Code 默认无法识别这个文件到底是什么类型的,因此也就无法识别相应的语法高亮。 如果你想修改默认的文件类型,可以在设置项里搜索files.defaultLanguage,设置项如下: 上图中的红框部分,填入你期望的默认文件类型。我填的是html类型,你也可以填写成 javascript 或者 markdown,或者其他的语言类型。 14、删除文件时,是否弹出确认框 当我们在 VS Code 中删除文件时,默认会弹出确认框。如果你想修改设置,可以在设置项里搜索xplorer.confirmDelete。截图如下: 我建议这个设置项保持默认的打钩就好,不用修改。删除文件前的弹窗提示,也是为了安全考虑,万一手贱不小心删了呢? 15、在新窗口打开文件/文件夹 通过 window.openFoldersInNewWindow(默认值为off)和window.openFilesInNewWindow(默认值为default),可以配置在打开文件夹、打开文件时,是否开启一个新的窗口。我个人建议,把这两个配置项都设置为 on,避免旧的窗口被覆盖: 补充知识—— window.restoreWindows可以用来配置 如何恢复之前的会话窗口。涉及到的场景是:你把 VS Code 关闭了,然后又打开了,是否要展示之前打开过的文件、文件夹?参数值有以下几种: one(默认配置):只会重新打开上一次回话中最后操作的那一个窗口。 none:打开一个空的窗口,不包含任何文件、文件夹。 all(建议配置):恢复上一次会话中的所有窗口。 folders:恢复上一次会话中包含文件夹的窗口。 接下来,我们来讲一些更高级的操作。 五、纵享丝滑:常见操作和使用技巧 1、快速生成HTML骨架 先新建一个空的html文件,然后通过以下方式,可以快速生成html骨架。 方式1:输入!,然后按下enter键,即可生成html骨架。如下图: 方式2:输入html:5,然后按住 Tab键,即可生成html骨架。 生成的骨架,内容如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> 有了上面的html骨架之后,我们就可以快乐地在里面插入CSS 代码和 JS 代码。 2、并排编辑:左右(上下)显示多个编辑器窗口(copy代码利器) 并排编辑是所有的编辑操作中最常用的一个技巧,十分有用。比如我们在开发一个项目时,可能需要同时打开 HTML 文件和 CSS 文件,很常见。 Mac 用户按住快捷键 Cmd + \, Windows 用户按住快捷键Ctrl + \,即可同时打开多个编辑器窗口,进行并排编辑。效果如下: 按快捷键「Cmd + 1 」切换到左边的窗口,按快捷键「Cmd + 2 」切换到右边的窗口,以此类推。随时随地,想切就切。 学会了这一招,以后 copy 代码的时候,leader 再也不用担心我抄得慢了,一天工资到手。 当然,使用快捷键Cmd + \只是其中一种方式,我们还有很多种方式打开并行编辑。我们来做一个汇总。 如果你已经打开了一个编辑器,那么可以通过以下几种方式在另一侧打开另一个编辑器:(按照使用频率,从高到低排序) 使用快捷键Cmd + \将编辑器一分为二。 使用快捷键Cmd + P调出文件列表,选择要打开的文件,然后按下 Cmd + Enter快捷键。【重要】 按住 Option 键的同时,单击资源管理器的文件(Windows 用户是按 Alt 键)。 点击编辑器右上角的 Split Editor按钮。 选择菜单栏「查看–> 编辑器布局」,然后选择你具体想要的布局,如下图所示: 通过拖拽,把当前文件移动到任意一侧。 补充知识:通过配置项worbench.editor.OpenSideBySideDirection可以控制编辑器在并排打开时出现的默认位置(默认值为right,你也可以根据需要改为 down)。如下图所示: 3、从终端 code 命令启动 VS Code(Mac电脑) 在终端输入code或者输入 code + 指定项目的目录,就可以启动 VS Code,十分便捷。即: code 命令:启动 VS Code 软件。 code pathName/fileName 命令:通过 VS Code 软件打开指定目录/指定文件。 为了达到目的,我们需要先将 VS Code的软件安装路径添加到环境变量,一劳永逸。具体操作如下: (1)打开 bash_profile文件: cd ~ vim ./bash_profile (2)在 bash_profile 中添加如下内容: # 从终端启动VS Code,并设置vscode启动的命令别名 alias code="/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code" 注意,由于Visual Studio Code.app这个路径里有空格,所以需要在空格前面加上反斜杠\。 (3)重启环境变量的配置: # 重启 source ~/.bash_profile 大功告成。 改完之后,如果没生效,那你把 bash_profile文件 换成 zshrc文件试试。 参考链接: mac通过终端code 命令打开vscode 3、从终端 code 命令启动 VS Code(Windows电脑) 在终端输入code或者输入 code + 指定项目的目录,就可以启动 VS Code,十分便捷。即: code 命令:启动 VS Code 软件。 code pathName/fileName 命令:通过 VS Code 软件打开指定目录/指定文件。 为了达到目的,我们需要先将 VS Code的软件安装路径添加到环境变量,一劳永逸。具体操作如下: (1)打开 VS Code 的安装位置,进入bin文件夹,复制路径。比如:D:\Microsoft VS Code\bin。 (2)回到桌面,右键我的电脑–>高级系统设置–>环境变量–>编辑path值,在原来的path后面,追加内容;D:\Microsoft VS Code\bin(即英文的分号+VS Code 的 bin 路径) (3)重启电脑,大功告成。 改完之后,如果没生效,那八成是因为你填的 path 值有问题。 参考链接: windows使用 code . 命令打开vscode 4、在当前文件中搜索 在上面的快捷键列表中,我们已经知道如下快捷键: Cmd + F(Win 用户是 Ctrl + F):在当前文件中搜索,光标在搜索框里 Cmd + G(Win 用户是 F3):在当前文件中搜索,光标仍停留在编辑器里 多个搜索结果出来之后,按下 Enter 键之后跳转到下一个搜索结果,按下 Shift + Enter 键之后跳转到上一个搜索结果。 另外,你可能会注意到,搜索框里有很多按钮,每个按钮都对应着不同的功能,如下图所示: 上图中,你可以通过「Tab」键和「Shift + Tab」键在输入框和替换框之间进行切换。 「在选定内容中查找」这个功能还是比较实用的。你也可以在设置项里搜索 editor.find.autoFindInSelection,勾选该设置项后,那么,当你选中指定内容后,然后按住「Cmd + F」,就可以自动只在这些内容里进行查找。该设置项如下图所示: 5、全局搜索 在上面的快捷键列表中,我们已经知道如下快捷键: Cmd + Shift + F(Win 用户是 Ctrl + Shift +F):在全局的文件夹中进行搜索。效果如下: 上图中,你可以点击红框部分,展开更多的配置项。然后点击红圈部分,进行过滤搜索。注意,第二个红圈那里会经常用到,它可以在搜索时过滤掉 .git、.node_modules等忽略文件。 上图中,我们还可以点击“在编辑器中打开”,在一个单独的文件中聚合展示搜索结果: 6、文件名/文件夹的搜索 前面的快捷键那一段我们讲过,通过 「Cmd + P」可以快速搜索并打开文件/文件夹。这种方式,一般用于快速打开最近编辑过的文件。 其实还有一种很巧妙的方式,可以在整个项目里,既能搜到文件,也能搜到文件夹。这种方式,常用于过滤项目的目录。操作方法很简单: 直接在文件资源管理器输入关键字就行。搜索结果会自动出现;使用方向键进行上下移动,可以在搜索的文件和文件夹之间进行跳转。 另外,右上角会看到一个过滤器,点击下图中的红圈部分,则只显示匹配的文件和文件夹。 当然,这招也有一点不足:不能搜中文。 7、大纲视图 如下图所示,大纲视图可以展示当前代码的方法结构、文件的目录结构: 8、文件对比 VS Code 默认支持对比两个文件的内容。选中两个文件,然后右键选择「将已选项进行比较」即可,效果如下: VS Code 自带的对比功能并不够强大,我们可以安装插件compareit,进行更丰富的对比。比如说,安装完插件compareit之后,我们可以将「当前文件」与「剪切板」里的内容进行对比: 如果你安装了 GitLens 插件,还可以将两个git分支的代码进行比对,非常完美。 9、查找某个函数在哪些地方被调用了 比如我已经在a.js文件里调用了 foo()函数。那么,如果我想知道foo()函数在其他文件中是否也被调用了,该怎么做呢? 做法如下:在 a.js 文件里,选中foo()函数(或者将光标放置在foo()函数上),然后按住快捷键「Shift + F12」,就能看到 foo()函数在哪些地方被调用了,比较实用。 10、鼠标操作 在当前行的位置,鼠标三击,可以选中当前行。 用鼠标单击文件的行号,可以选中当前行。 在某个行号的位置,上下移动鼠标,可以选中多行。 11、重构 重构分很多种,我们来举几个例子。 命名重构: 当我们尝试去修改某个函数(或者变量名)时,我们可以把光标放在上面,然后按下「F2」键,那么,这个函数(或者变量名)出现的地方都会被修改。 方法重构: 选中某一段代码,这个时候,代码的左侧会出现一个「灯泡图标」,点击这个图标,就可以把这段代码提取为一个单独的函数。 12:终端配置 VS Code软件自带了终端,但我个人认为不是很好用,而且VS Code 软件关了之后,终端也没了。建议大家使用其他的终端软件,专业的事情交给专业的人做。 Windows平台的终端:推荐 PowerShell 软件。远程终端推荐 xshell 软件。 Mac平台的终端:推荐 iTerm2 。 iTerm2 是Mac平台最好用的终端软件,没有之一。 右键行为: 在终端上,单击右键所产生的行为在不同的系统里是不同的。 Windows:如果有选定文本,则复制当前文本;如果没有选定文本,则粘贴。 macOS:选中光标所在位置的单词,并显示右键菜单。 Linux:显示右键菜单。 13、Git 版本管理 在 VS Code中使用Git之前,需要你先安装 Git 环境。 VS Code 自带了 Git 版本管理的功能,如下图所示: 上图中,我们可以在这里进行常见的 git 命令操作。如果你还不熟悉 Git 版本管理,可以先去补补课。 我自己用的最多的功能是diff 代码和合并冲突,自从用上了 VS Code 的这两个功能,简直离不开它。 我们先来看看 diff 代码的效果: 上图中,点击右上角的...,然后点击内联视图,则可以换一种视图 diff 代码: Git状态栏: 在VS Code的左下角会显示Git状态栏。如果当前代码仓库配置了远程仓库,那么“同步更改”会显示以下信息: 左边的数字:表示远程分支比本地分支多了XX个 Git commit。 右边的数字:表示本地分支比远程分支多了XX个 Git commit。 点击“同步更改”按钮,会拉取(pull)远程分支到本地分支,并推送(push)本地的Git commit到远程分支。 如果当前代码仓库没有配置远程仓库,则会显示“发布更改”的按钮。点击“发布更改”按钮,会把当前分支push到远程仓库。 另外,我建议安装插件GitLens搭配使用,它是 VS Code 中我最推荐的一个插件,简直是 Git 神器,码农必备。 我还要补充一句: 有人说,高手都是直接用命令行操作Git。然而,根据我多年的经验来看,如果你的代码仓库需要管理的分支特别多,与团队的其他成员需要经常协作,那么,我建议你优先使用 GUI 图形化工具来操作Git,避免出错。 我推荐的GUI版的Git工具有: Tower Sourcetree GitKraken 14、将工作区放大/缩小 我们在上面的设置项里修改字体大小后,仅仅只是修改了代码的字体大小。 如果你想要缩放整个工作区(包括代码的字体、左侧导航栏的字体等),可以按下快捷键「cmd +/-」。windows 用户是按下「ctrl +/-」 当我们在投影仪上给别人演示代码的时候,这一招十分管用。 如果你想恢复默认的工作区大小,可以在命令面板输入重置缩放(英文是reset zoom) f### 11、创建多层子文件夹 我们可以在新建文件夹的时候,如果直接输入aa/bb/cc,比如: 那么,就可以创建多层子文件夹,效果如下: 15、.vscode 文件夹的作用 为了统一团队的 vscode 配置,我们可以在项目的根目录下建立.vscode目录,在里面放置一些配置内容,比如: settings.json:工作空间设置、代码格式化配置、插件配置。 sftp.json:ftp 文件传输的配置。 .vscode目录里的配置只针对当前项目范围内生效。将.vscode提交到代码仓库,大家统一配置时,会非常方便。 16、自带终端 我们可以按下「Ctrl + `」打开 VS Code 自带的终端。我认为内置终端并没有那么好用,我更建议你使用第三方的终端 item2。 17、markdown 语法支持 VS Code 自带 markdown 语法高亮。也就是说,如果你是用 markdown 格式写文章,则完全可以用 VS Code 进行写作。 写完 md 文件之后,你可以点击右上角的按钮进行预览,如下图所示: 我一般是安装「Markdown Preview Github Styling」插件,以 GitHub 风格预览 Markdown 样式。样式十分简洁美观。 你也可以在控制面板输入Markdown: 打开预览,直接全屏预览 markdown 文件。 18、Emmet in VS Code Emmet可以极大的提高 html 和 css 的编写效率,它提供了一种非常简练的语法规则。 举个例子,我们在编辑器中输入缩写代码:ul>li*6 ,然后按下 Tab 键,即可得到如下代码片段: <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> VS Code 默认支持 Emmet。更多 Emmet 语法规则,可以自行查阅。 19、修改字体,使用「Fira Code」字体 这款字体很漂亮,很适合用来写代码: 安装步骤如下: (1)进入 https://github.com/tonsky/FiraCode 网站,下载并安装「Fira Code」字体。 (2)打开 VS Code 的「设置」,搜索font,修改相关配置为如下内容: "editor.fontFamily": "'Fira Code',Menlo, Monaco, 'Courier New', monospace", // 设置字体显示 "editor.fontLigatures": false,//控制是否启用字体连字,true启用,false不启用 上方的第二行配置,取决于个人习惯,我是直接设置为"editor.fontLigatures": null,因为我不太习惯连字。 20、代码格式化 VS Code 默认对 JavaScript、TypeScript、JSON、HTML 提供了开箱即用的代码格式化支持。其他语言则需要先安装相应的插件才能支持。 另外,我们还可以安装 Prettier 插件进行更精细的代码格式化。下一段将插件的时候,会讲解。 21、智能提示 IntelliSense VS Code 默认对 JavaScript、TypeScript、JSON、HTML、CSS、SCSS、Less这7种语言(文件)提供了智能提示的支持。其他编程语言则需要先安装相应的插件才能支持。 在 VS Code插件职场中,下图是最受欢迎的8种编程语言插件: 智能提示的功能很强大, 包括函数介绍、代码自动补全等等。 22、调试与运行 VS Code 内置了对 Node.js 运行时的调试支持,可以直接调试 JavaScript 和 TypeScript。其他编程语言的调试,则需要先安装相应的插件才能支持。 在 VS Code插件市场中,下图是最受欢迎的几种调试插件: 23、文件传输:sftp 如果你需要将本地文件通过 ftp 的形式上传到局域网的服务器(需要先把服务端的配置搭建好),可以安装sftp这个插件,很好用。在公司会经常用到。 步骤如下: (1)安装插件sftp。 (2)配置 sftp.json文件。 插件安装完成后,输入快捷键「cmd+shift+P」弹出命令面板,然后输入sftp:config,回车,当前工程的.vscode文件夹下就会自动生成一个sftp.json文件,我们需要在这个文件里配置的内容可以是: host:服务器的 IP 地址 username:用户名 privateKeyPath:存放在本地的已配置好的用于登录工作站的密钥文件(也可以是 ppk 文件) remotePath:工作站上与本地工程同步的文件夹路径,需要和本地工程文件根目录同名,且在使用 sftp 上传文件之前,要手动在工作站上 mkdir 生成这个根目录 ignore:指定在使用 sftp: sync to remote 的时候忽略的文件及文件夹,注意每一行后面有逗号,最后一行没有逗号 举例如下:(注意,其中的注释需要去掉) { "host": "192.168.xxx.xxx", //服务器ip "port": 22, //端口,sftp模式是22 "username": "", //用户名 "password": "", //密码 "protocol": "sftp", //模式 "agent": null, "privateKeyPath": null, "passphrase": null, "passive": false, "interactiveAuth": false, "remotePath": "/root/node/build/", //服务器上的文件地址 "context": "./server/build", //本地的文件地址 "uploadOnSave": true, //监听保存并上传 "syncMode": "update", "watcher": { //监听外部文件 "files": false, //外部文件的绝对路径 "autoUpload": false, "autoDelete": false }, "ignore": [ //忽略项 "**/.vscode/**", "**/.git/**", "**/.DS_Store" ] } (3)在 VS Code 的当前文件里,选择「右键 -> upload」,就可以将本地的代码上传到 指定的 ftp 服务器上(也就是在上方 host 中配置的服务器 ip)。 我们还可以选择「右键 -> Diff with Remote」,就可以将本地的代码和 ftp 服务器上的代码做对比,非常方便。 24、沉浸模式/禅模式 程序员写代码需要专注,有时需要进入一种心流。VS Code给我们提供了一种全屏下的沉浸模式,周围的面板都会被隐藏起来,只显示编辑器部分。 操作方法:菜单栏选择「查看-外观-禅模式」即可;或者按下快捷键Cmd + K,放手,再按Z也可以达到目的。 正则表达式批量删除字符串 需求:将文本中的字符串axxxxb,批量替换为ab。其中,开头字符 a 和 结尾字符 b 固定,中间xxx长度不确定。 解决:传统查找替换无法胜任。可以使用VScode正则表达式功能,查找a.*?b替换为ab即可。其中?是禁止贪婪匹配,否则会误删很多内容。 拓展需求:需求——将文本中的字符串axxxx,批量替换为a。其中,开头字符 a 固定,后面的xxx长度不确定。 解决:传统查找替换无法胜任。可以使用VScode正则表达式功能,查找a.*?\n替换为a\n即可。 六、三头六臂:VS Code 插件介绍 & 插件推荐 VS Code 有一个很强大的功能就是支持插件扩展,让你的编辑器仿佛拥有了三头六臂。 安装插件 上图中,点击红框部分,即可在顶部输入框里,查找你想要的插件名,然后进行安装。 插件安装完成后,记得重启软件(或者点击插件位置的“重新加载”),插件才会生效。 另外,我们还可以访问官网的插件市场来安装插件: VS Code插件市场(官方):https://marketplace.visualstudio.com/vscode 插件的安装目录: Windows::%USERPROFILE%\.vscode\extensions macOS:~/.vscode/extensions macOS:~/.vscode/extensions 插件的类型 插件市场的首页有四个模块,可以作为重要的信息来源: Featured:由 VS Code团队精心推荐的插件。 Trending:近期热门插件。 Most Popular:按总安装量排序的插件。 Recently Added:最新发布的插件。 插件市场至少有17种类型的插件:(按照数量排序) Themes:主题插件 Programming Languages:编程语言插件 Snippets:代码片段 Extension Packs:插件包,里面包括多个插件 Formatters:代码格式化 Linters:静态检查 Debuggers:调试器 Keymaps:快捷键映射 Visualization:可视化 Language Packs:各国的语言插件 Azure:Azure 云计算 Data Science:数据科学 SCM Providers:源代码控制管理器(source control manager) Notebooks Education:教育 Testing:测试相关 Machine Learning:机器学习 Others:其他 插件的过滤显示 在 VS Code中打开插件管理视图,可以针对已安装的插件,进行过滤展示。 1)点击插件视图右上角的...按钮,可以展示不同状态的插件: 2)在搜索框输入字符@,会展示出不同类型的过滤器: 常见的过滤器如下: 1)按大类搜: @builtin:显示 VS Code内置的插件 @disabled:显示被禁用的插件 @enabled:显示已启用的插件 @installed:显示已安装的插件 @outdated:显示待更新的插件 2)精准搜索: @id:按id显示插件 @tag:根据标签显示插件。 3)对插件进行排序: @sort:installs:根据插件的安装量排序 @sourt:rating:根据插件的评分排序 @sort:name:根据插件名字的字母顺序排序 4)组合搜索:(举例) @installed @category:themes:显示已安装的主题插件。 @sort:installs java:对 Java 相关的插件按照安装量排序。 下面的内容,我来列举一些常见的插件,这些插件都很实用,小伙伴们可以按需安装。注意:每一类插件里,顺序越靠前,越实用。 1、基本插件 Chinese (Simplified) Language Pack for Visual Studio Code 让软件显示为简体中文语言。 2、Git 相关插件 GitLens 【荐】 我强烈建议你安装插件GitLens,它是 VS Code 中我最推荐的一个插件,简直是 Git 神器,码农必备。如果你不知道,那真是 out 了。 GitLens 在 Git 管理上有很多强大的功能,比如: 将光标放置在代码的当前行,可以看到这样代码的提交者是谁,以及提交时间。这一点,是 GitLens 最便捷的功能。 查看某个 commit 的代码改动记录 查看不同的分支 可以将两个 commit 进行代码对比 甚至可以将两个 branch 分支进行整体的代码对比。这一点,简直是 GitLens 最强大的功能。当我们在不同分支 review 代码的时候,就可以用到这一招。 打开你的 Git仓库,未安装 GitLens 时是这样的: 安装了 GitLens 之后是这样的: 上图中,红框部分就是 GitLens 的功能,诸君可以自由发挥。 补充一个有意思的趣事:Python插件、Ruby插件、GitLens插件、Vetur插件,这四个插件的开发者先后加入了微软。 Git History 有些同学习惯使用编辑器中的 Git 管理工具,而不太喜欢要打开另外一个 Git UI 工具的同学,这一款插件满足你查询所有 Git 记录的需求。 Local History 【荐】 维护文件的本地历史记录。代码意外丢失时,有时可以救命。 3、代码智能提示插件 Vetur Vue 多功能集成插件,包括:语法高亮,智能提示,emmet,错误提示,格式化,自动补全,debugger。VS Code 官方钦定 Vue 插件,Vue 开发者必备。 ES7 React/Redux/GraphQL/React-Native snippets React/Redux/react-router 的语法智能提示。 JavaScript(ES6) code snippets ES6 语法智能提示,支持快速输入。 javascript console utils:快速打印 log 日志【荐】 安装这个插件后,当我们按住快捷键「Cmd + Shift + L」后,即可自动出现日志 console.log()。简直是日志党福音。 当我们选中某个变量 name,然后按住快捷键「Cmd + Shift + L」,即可自动出现这个变量的日志 console.log(name)。 其他的同类插件还有:Turbo Console Log。 不过,生产环境的代码,还是尽量少打日志比较好,避免出现一些异常。 编程有三等境界: 第三等境界是打日志,这是最简单、便捷的方式,略显低级,一般新手或资深程序员偷懒时会用。 第二等境界是断点调试,在前端、Java、PHP、iOS 开发时非常常用,通过断点调试可以很直观地跟踪代码执行逻辑、调用栈、变量等,是非常实用的技巧。 第一等境界是测试驱动开发,在写代码之前先写测试。与第二等的断点调试刚好相反,大部分人不是很习惯这种方式,但在国外开发者或者敏捷爱好者看来,这是最高效的开发方式,在保证代码质量、重构等方面非常有帮助,是现代编程开发必不可少的一部分。 Code Spell Checker:单词拼写错误检查 这个拼写检查程序的目标是帮助捕获常见的单词拼写错误,可以检测驼峰命名。从此告别 Chinglish. Auto Close Tag、Auto Rename Tag 自动闭合配对的标签、自动重命名配对的标签。 4、代码显示增强插件 Bracket Pair Colorizer 2:突出显示成对的括号【荐】 Bracket Pair Colorizer 2插件:以不同颜色显示成对的括号,并用连线标注括号范围。简称彩虹括号。 另外,还有个Rainbow Brackets插件,也可以突出显示成对的括号。 highlight-icemode:选中相同的代码时,让高亮显示更加明显【荐】 VSCode 自带的高亮显示,实在是不够显眼。用插件支持一下吧。 所用了这个插件之后,VS Code 自带的高亮就可以关掉了: 在用户设置里添加"editor.selectionHighlight": false即可。 参考链接:vscode 选中后相同内容高亮插件推荐 vscode-icons vscode-icons 会根据文件的后缀名来显示不同的图标,让你更直观地知道每种文件是什么类型的。 indent-rainbow:突出显示代码缩进 indent-rainbow插件:突出显示代码缩进。 安装完成后,效果如下图所示: TODO Highlight 写代码过程中,突然发现一个 Bug,但是又不想停下来手中的活,以免打断思路,怎么办?按照代码规范,我们一般是在代码中加个 TODO 注释。比如:(注意,一定要写成大写TODO,而不是小写的todo) //TODO:这里有个bug,我一会儿再收拾你 或者: //FIXME:我也不知道为啥, but it works only that way. 安装了插件 TODO Highlight之后,按住「Cmd + Shift + P」打开命令面板,输入「Todohighlist」,选择相关的命令,我们就可以看到一个 todoList 的清单。 Better Comments 为注释添加更醒目、带分类的色彩。 5、代码格式化插件 Prettier:代码格式化 Prettier 是一个代码格式化工具,只关注格式化,但不具备校验功能。在一个多人协同开发的团队中,统一的代码编写规范非常重要。一套规范可以让我们编写的代码达到一致的风格,提高代码的可读性和统一性。自然维护性也会有所提高,代码的展示也会更加美观。 步骤如下: (1)安装插件 Prettier。 (2)在项目的根路径下,新建文件.prettierrc,并在文件中添加如下内容: { "printWidth": 150, "tabWidth": 4, "semi": true, "singleQuote": true, "trailingComma": "es5", "tslintIntegration": true, "insertSpaceBeforeFunctionParenthesis": false } 上面的内容,是我自己的配置,你可以参考。更多配置,可见官方文档:https://prettier.io/docs/en/options.html (3)Mac用户按快捷键「Option + Shift + F」,Win 用户按快捷键「Alt + shift + F」,即可完成代码的格式化。如果你的VS Code 设置的是自动格式化代码,那么这一步可以忽略。 ESLint:代码格式的校验 日常开发中,建议用 Prettier 做代码格式化,然后用 eslint 做格式校验。很多人把这两个插件的功能弄混了。 一般做法是:格式化建议是由程序员手动触发,格式校验由系统强制校验。通过 Prettier 手动触发格式化,是为了让用户有感知;通过eslint 做强制校验之后,如果代码的格式不符合要求,系统就禁止你提交代码。 Beautify 代码格式化工具。 备注:相比之下,Prettier 是当前最流行的代码格式化工具,比 Beautify 用得更多。 Paste JSON as Code 此插件可以将剪贴板中的 JSON 字符串转换成工作代码。支持多种语言。 JS-CSS-HTML Formatter【荐】 保存文件时,自动格式化 HTML、CSS、JS代码。 6、图片相关插件 Polacode-2020:生成代码截图 【荐】 可以把代码片段保存成美观的图片,主题不同,代码的配色方案也不同,也也可以自定义设置图片的边框颜色、大小、阴影。 尤其是在我们做 PPT 分享时需要用到代码片段时,或者需要在网络上优雅地分享代码片段时,这一招很有用。 生成的效果如下: 其他同类插件:CodeSnap。我们也可以通过 https://carbon.now.sh/这个网站生成代码图片 有人可能会说:直接用 QQ 截图不行吗?可以是可以,但不够美观、不够干净。 Image Preview 【荐】 图片预览。鼠标移动到图片 url 上的时候,会自动显示图片的预览和图片尺寸。 7、CSS相关插件 CSS Peek 增强 HTML 和 CSS 之间的关联,快速查看该元素上的 CSS 样式。 Vue CSS Peek CSS Peek 对 Vue 没有支持,该插件提供了对 Vue 文件的支持。 Color Info 这个便捷的插件,将为你提供你在 CSS 中使用颜色的相关信息。你只需在颜色上悬停光标,就可以预览色块中色彩模型的(HEX、 RGB、HSL 和 CMYK)相关信息了。 8、Mardown 相关插件 Markdown Preview Github Styling 【荐】 以 GitHub 风格预览 Markdown 样式,十分简洁优雅。就像下面这样,左侧书写 Markdown 文本,右侧预览 Markdown 的渲染效果: Markdown Preview Enhanced 预览 Markdown 样式。 Markdown All in One 这个插件将帮助你更高效地在 Markdown 中编写文档。 9、通用工具类插件 sftp:文件传输 【荐】 如果你需要将本地文件通过 ftp 的形式上传到局域网的服务器,可以安装sftp这个插件,很好用。在公司会经常用到。 详细配置已经在上面讲过。 Live Server 【荐】 在本地启动一个服务器,代码写完后可以实现「热更新」,实时地在网页中看到运行效果。就不需要每次都得手动刷新页面了。 使用方式:安装插件后,开始写代码;代码写完后,右键选择「Open with Live Server」。 open in browser 安装open in browser插件后,在 HTML 文件中「右键选择 --> Open in Default Browser」,即可在浏览器中预览网页。 Project Manager 工作中,我们经常会来回切换多个项目,每次都要找到对应项目的目录再打开,比较麻烦。Project Manager 插件可以解决这样的烦恼,它提供了专门的视图来展示你的项目,我们可以把常用的项目保存在这里,需要时一键切换,十分方便。 WakaTime 【荐】 统计在 VS Code 里写代码的时间。统计效果如下: Code Time Code Time插件:记录编程时间,统计代码行数。 安装该插件后,VS Code 底部的状态栏右下角可以看到时间统计。点击那个位置之后,选择「Code Time Dashboard」,即可查看统计结果。 备注:团长试了一下这个 code time 插件,发现统计结果不是很准。 File Tree to Text Generator:快速生成文件的目录树 如题。 Settings Sync 地址:https://github.com/shanalikhan/code-settings-sync 作用:多台设备之间,同步 VS Code 配置。通过登录 GitHub 账号来使用这个同步工具。 同步的详细操作,下一段会讲。 另外,北京时间的2020年8月14日,微软发布 Visual Studio Code 1.48 稳定版。此版本原生支持用户同步 VS Code的配置,只需要登录微软账号或者 GitHub账号即可。 vscode-syncing 地址:https://github.com/nonoroazoro/vscode-syncing 作用:多台设备之间,同步 VS Code 配置。 minapp:小程序支持 小程序开发必备插件。 Search node_modules node_modules模块里面的文件夹和模块实在是太多了,根本不好找。好在安装 Search node_modules 这个插件后,输入快捷键「Cmd + Shift + P」,然后输入 node_modules,在弹出的选项中选择 Search node_modules,即可搜索 node_modules 里的模块。 RemoteHub 不要惊讶,RemoteHub 和 GitLens 是同一个作者开发出来的。 RemoteHub插件的作用是:可以在本地查看 GitHub 网站上的代码,而不需要将代码下载到本地。 这个插件目前使用的人还不多,赶紧安装起来尝尝鲜吧。 Live Share:实时编码分享 Live Share这个神奇的插件是由微软官方出品,它的作用是:实时编码分享。也就是说,它可以实现你和你的同伴一起写代码。这绝对就是结对编程的神器啊。 安装方式: 打开插件管理,搜索“live share”,安装。安装后重启 VS Code,在左侧会多出一个按钮: 上图中,点击红框部分,登录后就可以分享你的工作空间了。 Import Cost 在项目开发过程中,我们会引入很多 npm 包,有时候可能只用到了某个包里的一个方法,却引入了整个包,导致代码体积增大很多。Import Cost插件可以在代码中友好的提示我们,当前引入的包会增加多少体积,这很有助于帮我们优化代码的体积。 10、主题插件 给你的 VS Code 换个皮肤吧,免费的那种。 Dracula Theme Material Theme Nebula Theme One Dark Pro One Monokai Theme Monokai Pro Ayu Snazzy Plus Dainty SynthWave '84 GitHub Plus Theme:白色主题 Horizon Theme:红色主题 七、无缝切换:VS Code 配置云同步 我们可以将配置云同步,这样的话,当我们换个电脑时,即可将配置一键同步到本地,就不需要重新安装插件了,也不需要重新配置软件。 下面讲的两个同步方法,都可以,看你自己需要。方法1是 VS Code自带的同步功能,操作简单。方法2 需要安装插件,支持更多的自定义配置。 方法1:使用 VS Code 自带的同步功能 1、配置同步: (1)在菜单栏选择「 Code --> 首选项 --> 打开设置同步」: (2)选择需要同步的配置: (3)通过Microsoft或者GitHub账号登录。 上图中,点击“登录并打开”,然后弹出如下界面: 上图中,使用 微软账号或者 GitHub账号登录: (4)同步完成后,菜单栏会显示“首先项同步已打开”,最左侧也会多出一个同步图标,如下图所示: 2、管理同步: (1)点击菜单栏「Code --> 首选项 --> 设置同步已打开」,会弹出如下界面,进行相应的同步管理即可: (2)换另外一个电脑时,登录相同的账号,即可完成同步。 参考链接: VS Code原生的配置同步功能——Settings Sync 方法2:使用插件 settings-sync 使用方法2,我们还可以把配置分享其他用户,也可以把其他用户的配置给自己用。 1、配置同步:(将自己本地的配置云同步到 GitHub) (1)安装插件 settings-sync。 (2)安装完插件后,在插件里使用 GitHub 账号登录。 (3)登录后在 vscode 的界面中,可以选择一个别人的 gist;也可以忽略掉,然后创建一个属于自己的 gist。 (4)使用快捷键 「Command + Shift + P」,在弹出的命令框中输入 sync,并选择「更新/上传配置」,这样就可以把最新的配置上传到 GitHub。 2、管理同步:(换另外一个电脑时,从云端同步配置到本地) (1)当我们换另外一台电脑时,可以先在 VS Code 中安装 settings-sync 插件。 (2)安装完插件后,在插件里使用 GitHub 账号登录。 (3)登录之后,插件的界面上,会自动出现之前的同步记录: 上图中,我们点击最新的那条记录,就可将云端的最新配置同步到本地: 如果你远程的配置没有成功同步到本地,那可能是网络的问题,此时,可以使用快捷键 「Command + Shift + P」,在弹出的命令框中输入 sync,并选择「下载配置」,多试几次。 使用其他人的配置: 如果我们想使用别人的配置,首先需要对方提供给你 gist。具体步骤如下: (1)安装插件 settings-sync。 (2)使用快捷键 「Command + Shift + P」,在弹出的命令框中输入 sync,并选择「下载配置」 (3)在弹出的界面中,选择「Download Public Gist」,然后输入别人分享给你的 gist。注意,这一步不需要登录 GitHub 账号。 插件推荐 嵌入式相关插件推荐 serial terminal 这款插件提供了一个简单的串口终端,可以帮助我们轻松地与串口设备进行通信。它支持多种波特率和数据位格式,并且可以轻松地发送和接收数据。 GitLens GitLens 是强大的Git集成插件,可以帮助我们实时查看Git提交信息,轻松进行代码溯源。 安装GitLens 插件之后在每行代码的末尾,GitLens 都会公开最后一次提交的作者、提交的时间以及其他详细的备注信息。 GitLens提供了可单击的链接,公开了提交详细信息,并允许您从快速选择菜单中进行选择,以比较、导航和进一步探索每个提交。 我们只需单击一个按钮,就可以在任何文件的历史记录中来回导航。比较随时间推移而发生的变化,并查看整个文件或每行代码的修订历史记录。 Code Runner Code Runner 插件支持多种语言的代码执行,包括C/C++、Python等。我们平时要写一些C语言小demo验证时可以直接在VSCode中运行我们的代码,无需跳出编辑器就能获取代码执行结果,省去额外安装运行环境的麻烦。 Remote - SSH 通过这个插件我们可以使用任何带有 SSH 服务器的远程计算机作为开发环境。我们嵌入式开发,有时候需要到服务器上去编译代码,通过这个插件我们可以很方便地修改、编译服务器上的代码。 Markdown插件 Markdown是一种轻量级标记语言,它的特点是简单、易学、易用。我们程序员写文档一般都是基于Markdown来写,我们可以使用一些Markdown文档工具,也可以在vscode里安装Markdown Preview Enhanced等Markdown插件。 C/C++插件 C/C插件应该是我们嵌入式中最常用的插件了。这个插件提供了包括智能代码补全、代码格式化、调试支持等在内的全方位的C/C开发功能。 CMake Tools CMake Tools 是一个用于快速创建和管理CMake项目的插件,可以帮助我们简化嵌入式开发中的构建过程。 DeviceTree DeviceTree是一个设备树语法插件,可以方便我们阅读设备树文件。 Doxygen 在进行嵌入式开发时,编写高质量的文档是十分重要的。Doxygen Documentation Generator插件可以帮助你自动生成代码的文档,使你能够更专注于编码,而无需担心文档的编写。 最后一段 如果你还有什么推荐的 VS Code 插件,欢迎留言。 大家完全不用担心这篇文章会过时,随着 VS Code 的版本更新和插件更新,本文也会随之更新。关于 VS Code 内容的后续更新,你可以关注我在 GitHub 上的前端入门项目,项目地址是: https://github.com/qianguyihao/Web 一个超级详细和真诚的前端入门项目。 todo issues 84 参考链接 2021年 中文版 Awesome VS Code:https://github.com/formulahendry/awesome-vscode-cn 2020年 VSCode 插件大全| VSCode 高级玩家之第二篇 http://www.supuwoerc.xyz/tools/vscode/plugins.html 如何让 VS Code 更好用 10 倍?这里有一份 VS Code 新手指南 那些你应该考虑卸载的 VSCode 扩展 VS Code 折腾记 - (16) 推荐一波实用的插件集 VSCode 前端必备插件,有可能你装了却不知道如何使用? 能让你开发效率翻倍的 VSCode 插件配置(上) https://segmentfault.com/a/1190000012811886 「Vscode」打造类 sublime 的高颜值编辑器 Mac Vscode 快捷键 使用 VSCode 的一些技巧 转载来源 GitHub 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/10/18
articleCard.readMore

如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers Containers 的反向代理

How To Use Traefik v2 as a Reverse Proxy for Docker Containers on Ubuntu 20.04 Traefik 适合配合Dockers swarm 做服务, Dockers portainer 做管理,ELK集群做监控日志。 traefik 与 nginx 一样,是一款优秀的反向代理工具,或者叫 Edge Router。至于使用它的原因则基于以下几点 无须重启即可更新配置 自动的服务发现与负载均衡 与 docker 完美集成,基于 container label 的配置 漂亮的 dashboard 界面 metrics 的支持,支持对 prometheus 和 k8s 集成 Introduction Docker can be an efficient way to run web applications in production, but you may want to run multiple applications on the same Docker host. In this situation, you’ll need to set up a reverse proxy. This is because you only want to expose ports 80 and 443 to the rest of the world. Traefik is a Docker-aware reverse proxy that includes a monitoring dashboard. Traefik v1 has been widely used for a while, and you can follow this earlier tutorial to install Traefik v1). But in this tutorial, you’ll install and configure Traefik v2, which includes quite a few differences. The biggest difference between Traefik v1 and v2 is that frontends and backends were removed and their combined functionality spread out across routers, middlewares, and services. Previously a backend did the job of making modifications to requests and getting that request to whatever was supposed to handle it. Traefik v2 provides more separation of concerns by introducing middlewares that can modify requests before sending them to a service. Middlewares make it easier to specify a single modification step that might be used by a lot of different routes so that they can be reused (such as HTTP Basic Auth, which you’ll see later). A router can also use many different middlewares. In this tutorial you’ll configure Traefik v2 to route requests to two different web application containers: a Wordpress container and an Adminer container, each talking to a MySQL database. You’ll configure Traefik to serve everything over HTTPS using Let’s Encrypt. Prerequisites To complete this tutorial, you will need the following: One Ubuntu 20.04 server with a sudo non-root user and a firewall. You can set this up by following our Ubuntu 20.04 initial server setup guide. Docker installed on your server, which you can accomplish by following Steps 1 and 2 of How to Install and Use Docker on Ubuntu 20.04. Docker Compose installed using the instructions from Step 1 of How to Install Docker Compose on Ubuntu 20.04. A domain and three A records, db-admin.your_domain, blog.your_domain and monitor.your_domain. Each should point to the IP address of your server. You can learn how to point domains to DigitalOcean Droplets by reading through DigitalOcean’s Domains and DNS documentation. Throughout this tutorial, substitute your domain for your_domain in the configuration files and examples. Step 1 — Configuring and Running Traefik The Traefik project has an official Docker image, so you will use that to run Traefik in a Docker container. But before you get your Traefik container up and running, you need to create a configuration file and set up an encrypted password so you can access the monitoring dashboard. You’ll use the htpasswd utility to create this encrypted password. First, install the utility, which is included in the apache2-utils package: sudo apt-get install apache2-utils Then generate the password with htpasswd. Substitute secure_password with the password you’d like to use for the Traefik admin user: htpasswd -nb admin secure_password The output from the program will look like this: Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/ You’ll use this output in the Traefik configuration file to set up HTTP Basic Authentication for the Traefik health check and monitoring dashboard. Copy the entire output line so you can paste it later. To configure the Traefik server, you’ll create two new configuration files called traefik.toml and traefik_dynamic.toml using the TOML format. TOML is a configuration language similar to INI files, but standardized. These files let us configure the Traefik server and various integrations, or providers, that you want to use. In this tutorial, you will use three of Traefik’s available providers: api, docker, and acme. The last of these, acme, supports TLS certificates using Let’s Encrypt. Create and open traefik.toml using nano or your preferred text editor: nano traefik.toml First, you want to specify the ports that Traefik should listen on using the entryPoints section of your config file. You want two because you want to listen on port 80 and 443. Let’s call these web (port 80) and websecure (port 443). Add the following configurations: traefik.toml [entryPoints] [entryPoints.web] address = ":80" [entryPoints.web.http.redirections.entryPoint] to = "websecure" scheme = "https" [entryPoints.websecure] address = ":443" Note that you are also automatically redirecting traffic to be handled over TLS. Next, configure the Traefik api, which gives you access to both the API and your dashboard interface. The heading of [api] is all that you need because the dashboard is then enabled by default, but you’ll be explicit for the time being. Add the following code: traefik.toml ... [api] dashboard = true To finish securing your web requests you want to use Let’s Encrypt to generate valid TLS certificates. Traefik v2 supports Let’s Encrypt out of the box and you can configure it by creating a certificates resolver of the type acme. Let’s configure your certificates resolver now using the name lets-encrypt: traefik.toml ... [certificatesResolvers.lets-encrypt.acme] email = "your_email@your_domain" storage = "acme.json" [certificatesResolvers.lets-encrypt.acme.tlsChallenge] This section is called acme because ACME is the name of the protocol used to communicate with Let’s Encrypt to manage certificates. The Let’s Encrypt service requires registration with a valid email address, so to have Traefik generate certificates for your hosts, set the email key to your email address. You then specify that you will store the information that you will receive from Let’s Encrypt in a JSON file called acme.json. The acme.tlsChallenge section allows us to specify how Let’s Encrypt can verify that the certificate. You’re configuring it to serve a file as part of the challenge over port 443. Finally, you need to configure Traefik to work with Docker. Add the following configurations: traefik.toml ... [providers.docker] watch = true network = "web" The docker provider enables Traefik to act as a proxy in front of Docker containers. You’ve configured the provider to watch for new containers on the web network, which you’ll create soon. Our final configuration uses the file provider. With Traefik v2, static and dynamic configurations can’t be mixed and matched. To get around this, you will use traefik.toml to define your static configurations and then keep your dynamic configurations in another file, which you will call traefik_dynamic.toml. Here you are using the file provider to tell Traefik that it should read in dynamic configurations from a different file. Add the following file provider: traefik.toml [providers.file] filename = "traefik_dynamic.toml" Your completed traefik.toml will look like this: traefik.toml [entryPoints] [entryPoints.web] address = ":80" [entryPoints.web.http.redirections.entryPoint] to = "websecure" scheme = "https" [entryPoints.websecure] address = ":443" [api] dashboard = true [certificatesResolvers.lets-encrypt.acme] email = "your_email@your_domain" storage = "acme.json" [certificatesResolvers.lets-encrypt.acme.tlsChallenge] [providers.docker] watch = true network = "web" [providers.file] filename = "traefik_dynamic.toml" Save and close the file. Now let’s create traefik_dynamic.toml. The dynamic configuration values that you need to keep in their own file are the middlewares and the routers. To put your dashboard behind a password you need to customize the API’s router and configure a middleware to handle HTTP basic authentication. Let’s start by setting up the middleware. The middleware is configured on a per-protocol basis and since you’re working with HTTP you’ll specify it as a section chained off of http.middlewares. Next comes the name of your middleware so that you can reference it later, followed by the type of middleware that it is, which will be basicAuth in this case. Let’s call your middleware simpleAuth. Create and open a new file called traefik_dynamic.toml: nano traefik_dynamic.toml Add the following code. This is where you’ll paste the output from the htpasswd command: traefik_dynamic.toml [http.middlewares.simpleAuth.basicAuth] users = [ "admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/" ] To configure the router for the api you’ll once again be chaining off of the protocol name, but instead of using http.middlewares, you’ll use http.routers followed by the name of the router. In this case, the api provides its own named router that you can configure by using the [http.routers.api] section. You’ll configure the domain that you plan on using with your dashboard also by setting the rule key using a host match, the entrypoint to use websecure, and the middlewares to include simpleAuth. Add the following configurations: traefik_dynamic.toml ... [http.routers.api] rule = "Host(`monitor.your_domain`)" entrypoints = ["websecure"] middlewares = ["simpleAuth"] service = "api@internal" [http.routers.api.tls] certResolver = "lets-encrypt" The web entry point handles port 80, while the websecure entry point uses port 443 for TLS/SSL. You automatically redirect all of the traffic on port 80 to the websecure entry point to force secure connections for all requests. Notice the last three lines here configure a service, enable tls, and configure certResolver to "lets-encrypt". Services are the final step to determining where a request is finally handled. The api@internal service is a built-in service that sits behind the API that you expose. Just like routers and middlewares, services can be configured in this file, but you won’t need to do that to achieve your desired result. Your completed traefik_dynamic.toml file will look like this: traefik_dynamic.toml [http.middlewares.simpleAuth.basicAuth] users = [ "admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/" ] [http.routers.api] rule = "Host(`monitor.your_domain`)" entrypoints = ["websecure"] middlewares = ["simpleAuth"] service = "api@internal" [http.routers.api.tls] certResolver = "lets-encrypt" Save the file and exit the editor. With these configurations in place, you will now start Traefik. Step 2 – Running the Traefik Container In this step you will create a Docker network for the proxy to share with containers. You will then access the Traefik dashboard. The Docker network is necessary so that you can use it with applications that are run using Docker Compose. Create a new Docker network called web: docker network create web When the Traefik container starts, you will add it to this network. Then you can add additional containers to this network later for Traefik to proxy to. Next, create an empty file that will hold your Let’s Encrypt information. You’ll share this into the container so Traefik can use it: touch acme.json Traefik will only be able to use this file if the root user inside of the container has unique read and write access to it. To do this, lock down the permissions on acme.json so that only the owner of the file has read and write permission. chmod 600 acme.json Once the file gets passed to Docker, the owner will automatically change to the root user inside the container. Finally, create the Traefik container with this command: docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $PWD/traefik.toml:/traefik.toml \ -v $PWD/traefik_dynamic.toml:/traefik_dynamic.toml \ -v $PWD/acme.json:/acme.json \ -p 80:80 \ -p 443:443 \ --network web \ --name traefik \ traefik:v2.2 This command is a little long. Let’s break it down. You use the -d flag to run the container in the background as a daemon. You then share your docker.sock file into the container so that the Traefik process can listen for changes to containers. You also share the traefik.toml and traefik_dynamic.toml configuration files into the container, as well as acme.json. Next, you map ports :80 and :443 of your Docker host to the same ports in the Traefik container so Traefik receives all HTTP and HTTPS traffic to the server. You set the network of the container to web, and you name the container traefik. Finally, you use the traefik:v2.2 image for this container so that you can guarantee that you’re not running a completely different version than this tutorial is written for. A Docker image’s ENTRYPOINT is a command that always runs when a container is created from the image. In this case, the command is the traefik binary within the container. You can pass additional arguments to that command when you launch the container, but you’ve configured all of your settings in the traefik.toml file. With the container started, you now have a dashboard you can access to see the health of your containers. You can also use this dashboard to visualize the routers, services, and middlewares that Traefik has registered. You can try to access the monitoring dashboard by pointing your browser to https://monitor.your_domain/dashboard/ (the trailing / is required). You will be prompted for your username and password, which are admin and the password you configured in Step 1. Once logged in, you’ll see the Traefik interface: You will notice that there are already some routers and services registered, but those are the ones that come with Traefik and the router configuration that you wrote for the API. You now have your Traefik proxy running, and you’ve configured it to work with Docker and monitor other containers. In the next step you will start some containers for Traefik to proxy. Step 3 — Registering Containers with Traefik With the Traefik container running, you’re ready to run applications behind it. Let’s launch the following containers behind Traefik: A blog using the official WordPress image. A database management server using the official Adminer image. You’ll manage both of these applications with Docker Compose using a docker-compose.yml file. Create and open the docker-compose.yml file in your editor: nano docker-compose.yml Add the following lines to the file to specify the version and the networks you’ll use: docker-compose.yml version: "3" networks: web: external: true internal: external: false You use Docker Compose version 3 because it’s the newest major version of the Compose file format. For Traefik to recognize your applications, they must be part of the same network, and since you created the network manually, you pull it in by specifying the network name of web and setting external to true. Then you define another network so that you can connect your exposed containers to a database container that you won’t expose through Traefik. You’ll call this network internal. Next, you’ll define each of your services, one at a time. Let’s start with the blog container, which you’ll base on the official WordPress image. Add this configuration to the bottom of the file: docker-compose.yml ... services: blog: image: wordpress:4.9.8-apache environment: WORDPRESS_DB_PASSWORD: labels: - traefik.http.routers.blog.rule=Host(`blog.your_domain`) - traefik.http.routers.blog.tls=true - traefik.http.routers.blog.tls.certresolver=lets-encrypt - traefik.port=80 networks: - internal - web depends_on: - mysql The environment key lets you specify environment variables that will be set inside of the container. By not setting a value for WORDPRESS_DB_PASSWORD, you’re telling Docker Compose to get the value from your shell and pass it through when you create the container. You will define this environment variable in your shell before starting the containers. This way you don’t hard-code passwords into the configuration file. The labels section is where you specify configuration values for Traefik. Docker labels don’t do anything by themselves, but Traefik reads these so it knows how to treat containers. Here’s what each of these labels does: traefik.http.routers.adminer.rule=Host(`````blog.your_domain`````) creates a new router for your container and then specifies the routing rule used to determine if a request matches this container. traefik.routers.custom_name.tls=true specifies that this router should use TLS. traefik.routers.custom_name.tls.certResolver=lets-encrypt specifies that the certificates resolver that you created earlier called lets-encrypt should be used to get a certificate for this route. traefik.port specifies the exposed port that Traefik should use to route traffic to this container. With this configuration, all traffic sent to your Docker host on port 80 or 443 with the domain of blog.your_domain will be routed to the blog container. You assign this container to two different networks so that Traefik can find it via the web network and it can communicate with the database container through the internal network. Lastly, the depends_on key tells Docker Compose that this container needs to start after its dependencies are running. Since WordPress needs a database to run, you must run your mysql container before starting your blog container. Next, configure the MySQL service: docker-compose.yml services: ... mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: networks: - internal labels: - traefik.enable=false You’re using the official MySQL 5.7 image for this container. You’ll notice that you’re once again using an environment item without a value. The MYSQL_ROOT_PASSWORD and WORDPRESS_DB_PASSWORD variables will need to be set to the same value to make sure that your WordPress container can communicate with the MySQL. You don’t want to expose the mysql container to Traefik or the outside world, so you’re only assigning this container to the internal network. Since Traefik has access to the Docker socket, the process will still expose a router for the mysql container by default, so you’ll add the label traefik.enable=false to specify that Traefik should not expose this container. Finally, define the Adminer container: docker-compose.yml services: ... adminer: image: adminer:4.6.3-standalone labels: - traefik.http.routers.adminer.rule=Host(`db-admin.your_domain`) - traefik.http.routers.adminer.tls=true - traefik.http.routers.adminer.tls.certresolver=lets-encrypt - traefik.port=8080 networks: - internal - web depends_on: - mysql This container is based on the official Adminer image. The network and depends_on configuration for this container exactly match what you’re using for the blog container. The line traefik.http.routers.adminer.rule=Host(`````db-admin.your_domain`````) tells Traefik to examine the host requested. If it matches the pattern of db-admin.your_domain, Traefik will route the traffic to the adminer container over port 8080. Your completed docker-compose.yml file will look like this: docker-compose.yml version: "3" networks: web: external: true internal: external: false services: blog: image: wordpress:4.9.8-apache environment: WORDPRESS_DB_PASSWORD: labels: - traefik.http.routers.blog.rule=Host(`blog.your_domain`) - traefik.http.routers.blog.tls=true - traefik.http.routers.blog.tls.certresolver=lets-encrypt - traefik.port=80 networks: - internal - web depends_on: - mysql mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: networks: - internal labels: - traefik.enable=false adminer: image: adminer:4.6.3-standalone labels: labels: - traefik.http.routers.adminer.rule=Host(`db-admin.your_domain`) - traefik.http.routers.adminer.tls=true - traefik.http.routers.adminer.tls.certresolver=lets-encrypt - traefik.port=8080 networks: - internal - web depends_on: - mysql Save the file and exit the text editor. Next, set values in your shell for the WORDPRESS_DB_PASSWORD and MYSQL_ROOT_PASSWORD variables: export WORDPRESS_DB_PASSWORD=secure_database_password export MYSQL_ROOT_PASSWORD=secure_database_password Substitute secure_database_password with your desired database password. Remember to use the same password for both WORDPRESS_DB_PASSWORD and MYSQL_ROOT_PASSWORD. With these variables set, run the containers using docker-compose: docker-compose up -d Now watch the Traefik admin dashboard while it populates. If you explore the Routers section you will find routers for adminer and blog configured with TLS: Navigate to blog.your_domain, substituting your_domain with your domain. You’ll be redirected to a TLS connection and you can now complete the WordPress setup: Now access Adminer by visiting db-admin.your_domain in your browser, again substituting your_domain with your domain. The mysql container isn’t exposed to the outside world, but the adminer container has access to it through the internal Docker network that they share using the mysql container name as a hostname. On the Adminer login screen, enter root for Username, enter mysql for Server, and enter the value you set for MYSQL_ROOT_PASSWORD for the Password. Leave Database empty. Now press Login. Once logged in, you’ll see the Adminer user interface. Both sites are now working, and you can use the dashboard at monitor.your_domain to keep an eye on your applications. Conclusion In this tutorial, you configured Traefik v2 to proxy requests to other applications in Docker containers. Traefik’s declarative configuration at the application container level makes it easy to configure more services, and there’s no need to restart the traefik container when you add new applications to proxy traffic to since Traefik notices the changes immediately through the Docker socket file it’s monitoring. To learn more about what you can do with Traefik v2, head over to the official Traefik documentation. 服务集群 k8s 太重了,虽然也有 k3s 之类的轻量级 k8s 解决方案,不过我还是选择了原生的 docker swarm。VPS 安装好 Docker 之后,不需要额外安装软件,就可以马上建立集群。 # 集群初始化,节点成为 manager 节点 docker swarm init --advertise-addr=x.x.x.x # 集群丢失 Leader 时,强制重建集群 docker swarm init --advertise-addr=x.x.x.x --force-new-cluster # 获取作为 worker 节点加入集群的命令 docker swarm join-token worker # 获取作为 manager 节点加入集群的命令 docker swarm join-token manager # 加入集群 docker swarm join --token xxx x.x.x.x:xxx --advertise-addr=x.x.x.x 参考: digitalocean shanyue 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/10/14
articleCard.readMore

如何通过IPV6访问Qnap NAS中Docker的服务

目前找到了两个解决方案 socat 端口转发 docker-ipv6nat 很早就和QNAP官方反馈请求支持IPV6,但一直没反应 socat 端口转发 环境 系统:QTS 4.3.6 网络:IPV4 & IPV6 Docker: 由Container Station提供 问题 通过ipv6地址可以打开NAS的管理页面,但是无法访问Docker对应端口的服务。 排查 QTS中Docker使用的虚拟交换机网络没有启动IPV6,且无法在虚拟交换机设置中手动启动。 解决方案 在主机上开一个tcp6的端口,将其转发到主机上与docker关联的tcp4端口。 在qts上安装包管理器:Entware. https://github.com/Entware/Entware/wiki/Install-on-QNAP-NAS 执行opkg update,更新 安装端口转发工具,这里使用socat:opkg install socat 设置转发host(tcp6)–>host(tcp4) socat TCP6-LISTEN:6880,reuseaddr,fork TCP4:127.0.0.1:7880 & 大功告成 docker-ipv6nat IPv4 & IPv6 可以平等使用(端口可以在主机系统上共享) 容器并不完全在线,因为 Docker 容器并不总是以安全着称 步骤1: 为 ip6tables NAT 安装内核模块。不幸的是,QNAP 没有自带这些模块,所以你必须自己构建它们。 qnap-ip6tables_nat-module。在 Release 下,您已经可以在此处下载当前构建的模块。我将它们放在 Docker 容器的应用程序目录中: /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/ 然后,您必须确保在启动时加载这些模块。为此,必须在您的 autorun.sh 中输入以下行。 # ipv6-tables # some required modules are already built into QTS, so you can load them with 'modprobe' /sbin/modprobe ip6_tables /sbin/modprobe nf_nat /sbin/modprobe xt_MASQUERADE # then load the new module insmod /share/CACHEDEV1_DATA/Container/container-station-data/application/ipv6nat/kernel_mods/ip6table_nat.ko 您可以在 QNAP Wiki 中了解如何在您的 QNAP 模型上编辑此文件:Running_Your_Own_Application_at_Startup 添加模块后,您需要重新启动 NAS。 第2步: 为了设置 docker-ipv6nat 容器,我准备了一个 docker-compose 文件。您可以通过 Create 简单地将其插入 ContainerStation: version: '3' services: ipv6nat: container_name: ipv6nat restart: always image: robbertkl/ipv6nat privileged: true network_mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - /lib/modules:/lib/modules:ro 容器应该在终端上没有任何输出的情况下启动。不起眼……现在呢?创建也应该可以通过 IPv& 访问的容器时是否需要一些手动工作。至少我还没有通过 QNAP 界面找到更简单的方法。 如果需要,您必须为每个容器创建至少一个支持 IPv6 的网络。 为此,请通过 SSH 登录 QNAP 并创建一个新的 Docker 网络: docker network create --ipv6 --subnet fd00:dead:beef::/48 ipv6net-1 当然,您也可以使用任何其他 ULA 范围 (fc00::/7)。 现在只需使用 ipv6net-1 作为容器的外部网络。这是一个小例子: version: "3" services: alp1: image: yeasy/simple-web:latest ports: - 80:80 networks: - ipv6net-1 networks: ipv6net-1: external: true 现在您的容器端口来自 IPv4: nmap <ipv4 ip> -p 80 PORT STATE SERVICE 80/tcp open http 也可以通过 IPv6 访问: nmap <ipv6 ip> -6 -p 80 PORT STATE SERVICE 80/tcp open http 享受通过 IPv4 和 IPv6 托管您的服务的乐趣! 实操 遇到问题: robbertkl/ipv6nat 启动日志报错 开启防火墙使用到了geoip会遇到如下错误 iptables exit status 1: Can't find library for match `geoip' 可能的解决方案 编译支持 geoip Install geoip for iptables in Debian 10 Xtables-Addons On Centos 6 & Iptables GeoIP Filtering 不使用 geoip 把防火墙中的规则设计到geoip 的都修改为任何地区,防火墙规则设计的好,针对一个地区开发某些端口和针对所有地区开发端口基本一样的风险。 使用第二种方案,实际测试使用发现丢包率还不低! # 在开启了ipv6的docker中运行如下命令 # ping6 2409:804c:2000:2::1 PING 2409:804c:2000:2::1 (2409:804c:2000:2::1): 56 data bytes ping: getnameinfo: Temporary failure in name resolution 64 bytes from unknown: icmp_seq=1 ttl=57 time=4.073 ms ... ^Cping: getnameinfo: Temporary failure in name resolution 64 bytes from unknown: icmp_seq=24 ttl=57 time=3.654 ms --- 2409:804c:2000:2::1 ping statistics --- 25 packets transmitted, 22 packets received, 12% packet loss round-trip min/avg/max/stddev = 3.606/4.100/5.562/0.608 ms Temporary failure in name resolution 似乎是DNS配置问题 测试IPV6 Windows 以下Windows版本的ping命令支持ping IPv6地址: Windows XP with SP1 及以上 Windows Vista 及以上 Windows Server 2003 及以上 ping ipv6主机名 ping -6 ipv6.google.com ping -6 ipv6.test-ipv6.com ping -6 ipv6.baidu.com **/!\注意:**当ping ipv6主机名时,必须加上参数-6;直接ping IPv6地址时可以省略。 ping ipv6地址 ping IPv6Address[%ZoneID] 例如: ping 2001:4860:0:2001::68 如果要ping link-local地址,则需要指定网络接口索引,如: ping fe80::260:97ff:fe02:6ea5%4 其中**%4**表示“用索引为4的网络接口”ping目标计算机。 Linux 在Linux发行版中,使用ping6命令ping IPv6主机或者地址。 ping ipv6主机名 ping6 ipv6.google.com ping ipv6地址 ping6 IPv6Address[%InterfaceName] 如果要ping link-local地址,则需要指定网络接口名称,如: ping fe80::260:97ff:fe02:6ea5%eth0 其中**%eth0**表示“用网络接口eth0 ping目标计算机”。 ping dns ping6 2409:804c:2000:2::1 ssh ssh root@fe80::c09a:4363:5763:32%enpxxx(网卡名称) chrome IPV6 Chrome 地址栏输入 about:net-internals/#dns 访问 https://www.test-ipv6.com/ nginx支持ipv6 nginx 1.14 开始就默认支持ipv6了,不再需要添加编译参数 --with-ipv6,可以直接配置监听 ipv6 检查nginx是否监听了ipv6 netstat -tuln 同时监听IPV4和IPV6 server { .... listen [::]:80; listen [::]:443; ... } 只监听IPV6 server { .... listen [::]:80 default ipv6only=on; listen [::]:443 default ipv6only=on; ... } 监听指定IPV6地址 { .... listen [3608:f0f0:3002:31::1]:80; listen [3608:f0f0:3002:31::1]:443; ... } 重启nginx nginx -s reload 安全设置 暴露Nas到公网是会有很大安全隐患的,请注意你已经做好了安全防范! 开启动态安全码 开启防火墙,最好最高安全级别,自己控制端口开启 开启IP访问保护 失败登录尝试阻止时间调整 暴露出去的服务全部采用高强密码,最好所有服务全部采用高强度密码 尽量使用Docker,而不是套件版软件服务 重要数据定期离线备份 IPv6: 为什么Link-local地址后面要有百分号(%)? 由于所有的link-local地址都有相同的前缀FE80::/64,并且每个网络接口都必须分配一个link-local地址,因而导致当发送数据包到一个link-local地址时,如果路由器使用普通的路由方法就无法决定选用哪个网络接口。因此,引入了一种被叫做zone index的标识符,它提供额外的路由信息,这个标识符通常指网络接口,并且通过一个百分号(%)被附加在IPv6地址后面。但是准确的表示方法还取决于操作系统: Windows: 使用网络接口索引表示 如: fe80::3%1 fe80::260:97ff:fe02:6ea5%4 要查看网络接口索引,请执行该命令: netsh interface ipv6 show address Linux: 使用网络接口名称表示 如: fe80::3%eth0 fe80::260:97ff:fe02:6ea5%tun0 Linux只需要ifconnfig命令就可列出所有网络接口名称。 参考 qnap-docker-ipv6-desater/ Enable IPv6 support IPv6: 如何正确ping ipv6地址 ipv6_dns 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 附赠 alpine linux 使用国内镜像源进行加速 Alpine 的源文件为: /etc/apk/repositories 这里面的默认配置例如: http://dl-cdn.alpinelinux.org/alpine/v3.11/main http://dl-cdn.alpinelinux.org/alpine/v3.11/community 可以使用以下命令来进行源的切换(阿里云源): sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories 中国科技大学的源: sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories 清华源: sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories 目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。 Alpine 使用 apk 来进行包管理。 可以在 Docker file 中添加以下语句,来加速 apk 的包管理。 ... RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories RUN apk add --no-cache gcc musl-dev linux-headers ... 注: sed 可依照脚本的指令来处理、编辑文本文件。 Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

2021/10/12
articleCard.readMore

CMake快速入门教程

1.cmake简介 cmake是跨平台的makefile文件生成工具,是为了解决各个平台下面make工具不同造成的makefile文件格式不同的问题.也就是cmake是用来解决跨平台编译问题的.常见的还有autotool工具集,该工具集用于GNU软件协议的makefile文件生成,方便GNU包的编译和安装。 2.cmake文件编辑规则 1)命令不区分大小写,但是变量区分大小写。 2)注释使用#符号 3)命令如果有多个参数,互相之间用空格隔开 3.cmake保留变量 cmake里面有很多的预定义变量,是程序环境固有的,比如CUDA_NVCC_FLAGS,不同的变量有固定的作用,比如CUDA_NVCC_FLAGS是nvcc的参数list,变量可以使用set命令和list命令进行赋值和追加值,要注意的是变量可能可以有多个值,值与值之间用分号分开,可以使用set(var a b c)给var赋值a b c,还可以使用list命令给var追加删除插入值等,不同的变量有不同的值域,需要查阅手册 4.cmake变量引用 cmake里面变量的取值引用要使用${var}的形式,但是在赋值的时候是不需要的,和shell命令有点相似. 5.cmake指定Debug和Release版本 指定Debug和Release一共有三种方法: 1.使用ADD_COMPILE_OPTIONS()加入-g指定Debug版本. 2.使用SET( CMAKE_BUILD_TYPE Debug/Rrelease)指定Debug SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb") SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") 上面的设置C++编译选项,对于C语言,设置CMAKE_C_FLAGS_DEBUG、CMAKE_._FLAGS_RELEASE变量,一般来说最好两个都设置原因是CMake 中有一个变量 CMAKE_BUILD_TYPE ,可以的取值是 Debug Release等.当这个变量值为 Debug 的时候,CMake 会使用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile 编译动态库or静态库时,最好通过修改CXXFLAGS和CFLAGS,以支持-fPIC,这个选项有时是默认开启,有时默认关闭,但为了以后的应用,库文件最好都使用-fPIC编译 在使用cmake命令时加上-DCMAKE_BUILD_TYPE=Debug/Release 5.cmake指定生成文件 CUDA_ADD_LIBRARY()指明目标文件是库文件,CUDA_ADD_EXECUTABLE()指明生成的文件为可执行文件 6.配置模板 通常我们要在工程目录下面创建include、src文件夹,include文件夹里面存放头文件,src文件夹里面存放源代码,注意这时候的源代码里面包含头文件的路径应该是“…/include/xx.h”,然后在工程根目录下面创建CMakeLists.txt文件,里面写入命令.在编译的时候为了不搞乱工程目录,在工程根目录下面创建build文件夹,在里面使用“cmake …”命令创建CMakefile,再make即可。 #指定cmake最低版本号 cmake_minimum_required(VERSION 3.2) #指定项目名称 PROJECT(Liner_Struct) #指定头文件目录,不同目录用空格隔开,目录中有空格可用引号 #如果是相对路径,相对于CMakeLists.txt文件 INCLUDE_DIRECTORIES(include) #指定源文件目录,DIR_SRCS值自定义变量,下面的命令对其进行了赋值 AUX_SOURCE_DIRECTORY(src DIR_SRCS) #设置变量用于存放所有的编译文件, #TEST_LINER_STRUCT是自定义变量,使用SET给其赋值 SET(TEST_LINER_STRUCT ${DIR_SRCS}) #增加编译选项 #判断是否为gcc编译器,如果是,增加编译选项 #c99是c语言的标准,常用的还有c++标准c++11 #下面的命令判断是否编译器是gcc #message命令是输出信息,例如下面的输出“optional:-std=c99” if(CMAKE_COMPILER_IS_GNUCXX) ADD_COMPILE_OPTIONS(-std=c99) message(STATUS "optional:-std=c99") endif(CMAKE_COMPILER_IS_GNUCXX) #配置生成文件 #${PROJECT_NAME}是cmake自带变量,其值和PROJECT()命令指定的一样 #${TEST_LINER_STRUCT}是自定义变量,上文赋值的 ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_LINER_STRUCT}) 7.if-else语句 cmake中的if-else语句 if(exp) cmdA cmdB elseif(exp) cmdC endif(exp) 最简单得到一个应用 if(ARM) #ARM平台 else() #非ARM平台 endif() 使用cmake -DARM=1 … 时编译ARM代码,使用cmake -DAMR=0 …编译非ARM代码 8.与平台编译器的结合 8.1windows 在windows上运行cmake可以生成对应的VS的工程文件,然后使用相应的VS打开工程就可以进行编译。要注意的是如果使用VS2010及其以前的版本,C不支持C99,也就是变量的命名必须放在函数或者域的最前面,不能放在中间,特别麻烦。VS2015在安装后可能还需要打开VS,新建工程时选择VC可能相关组件还没有安装,如果这时候使用cmake会提示找不到C、C编译器(类似yuNo CMAKE_CXX_COMPILER could be found)的错误。安装了相关的组件后cmake即不会有错误。 8.2 为VS2015生成的项目 打开工程文件后可以看到有3个项目,其中只有一个和我们有直接关系,就是我们在CMakeLists.txt里面定义的PROJECT_NAME,剩下的两个是ALL_BUILD和ZERO_CHECK. ZERO_CHECK 如果确信 CMakeLists.txt 不会被更新,或者希望手工运行 CMake 重新生成工程文件,可以在 CMakeLists.txt 配置文件中添加 set(CMAKE_SUPPRESS_REGENERATION FALSE) 命令, ZERO_CHECK 目标将不会生成。 ALL_BUILD 转载 CMake快速入门教程

2021/10/12
articleCard.readMore

如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕

注意使用V3版本,V4版本收费! 所以升级V3版本即可,不要升级到V4版本!不要升级到V4版本!不要升级到V4版本! Plex是一款很好用的个人媒体中心软件,但是因为国内网络的原因,使用默认的TMDB刮削器挂出来的效果并不好,要么就是影片信息不正确,要么就是海报不正常显示,实在让人头疼。 tinyMediaManager是一款电影信息刮削和整理的软件,正好可以和plex配合,完美的解决这一问题。tinyMediaManager在刮削影片的过程中会把影片的海报、演员表、背景图片等等都保存到影片所在文件夹,自动生成电影的nfo信息文件,并对文件和文件夹进行重新命名的操作。在plex设置刮削代理的时候,需要用一款插件可以直接读取nfo的信息,完成刮削,下面把使用方法分享给大家, 下载和安装tinyMediaManager 官网下载地址:https://www.tinymediamanager.org/download/ V3版本在这里下载 Download Java for Windows TMM 需要 java 1.8 以上版本 tmm下载 下载后直接解压文件夹 客户端需要java支持,先在电脑安装java 客户端下载后是一个压缩包,解压之后就可以用 解压之后打开tinyMediaManager.exe TMM设置 TMM代理设置 重要:很多源都需要代理才能访问。这里正确的配置才能正确的刮削! 可以调整这里使用的内存,大内存可以极大加速刮削速度。 电影刮削设置 进行相关设置。Tmm可以对电影和电视剧的刮削进行分别设置,打开设置后选择电影选项,可以选择分级标准、自动重命名等选项。 电影信息选项 点击侧边栏媒体库目录,添加电影目录 刮削器设置 选择电影刮削器 刮削器选项 nfo选项,建议选择生成两种命名放视的nfo 图片刮削器选择全选,图片文件名建议两边都选上,会分别生成两组命名格式不同的图片,为了保证plex能读取 图片命名选项 Tmm还可以自动下载预告片,字幕。字幕下载时可以输入opensubtitles账户 字幕下载选项 重命名规则 这里重点讲一下重命名规则,刮削完后可以选择对电影文件和文件夹进行重命名,可能对于pt用户重命名可能会影响资源上传,可以不进行重命名操作。 一般情况下电影刮削出来的信息,title是电影的中文标题名称,originaltitle是电影的原标题名称,一般是英文名称。软件默认的设置是文件和文件夹都命名成title,也就是中文标题,但是我发现这样在后期使用的时候有弊端。英文电影在检索字幕时会用文件名来检索,而用中文名称很多情况下检索不出来,所以这里把文件的命名规则改一下,改成originaltitle,并去掉年份信息的括号,中间连接符改成点,文件名设置成 originaltitle{- ,edition,}. year.{videoFormat}.${audioCodec}的格式。 电影文件重命名选项 刮削完的文件夹内文件信息 刮削完的电影文件夹目录 电视节目刮削设置类似,如果挂不出来可以用the tvdb来刮削。 tmm有时候会出现网络不稳定,刮不到的情况,可以修改host解决 改host 在host文件最后加一行13.224.161.90 http://api.themoviedb.org 退出设置,开始刮削 更新电影源 选中要刮削的电影自动匹配 电影手动刮削 电视剧&动画手动刮削 电视剧元数据刮削 季和集元数据刮削前整理 刮削季元素 整理好正确的季和集之后,才能正确的刮削季元素 TMM整理完效果 这里用海贼王做展示,一个季和集都特别多的剧。 TMM目录重命名整理 刮削完后,可以重命名视频文件,并进行目录整理。 方法1 方法2 等所有电影的信息刮削完后,选择重命名和清理,这样就完成了刮削的操作。以后下载了新电影,直接打开tmm,更新源之后直接选择搜索未刮削过的电影完成刮削。刮削出来的信息kodi,emby等软件也都能用。 Plex设置 plex插件的安装和设置 下载plex的插件 插件XBMCnfoMoviesImporter和XBMCnfoTVImporter分别是刮削电影和电视剧的插件 下载地址:https://github.com/gboudreau/XBMCnfoMoviesImporter.bundle 如果不能下载的话可以联系我获取,还有几个很好用的plex插件 下载完插件后就需要把插件解压到plex的插件目录:C:\\Users\\用户名\\AppData\\Local\\Plex Media Server\\Plug-ins plex插件目录 注意解压后要把文件夹名后边的master去掉。 plex代理设置 Plex的代理设置就是选择刮削电影所用的刮削器及优先级。 装好插件后重启plex,进行plex的设置。在代理设置中选择XBMCnfoMoviesImporter,把它的优先级调到最高,第二个可以设置成字幕插件。 设置电影资料库的刮削器代理 点击设置界面下方管理里边的资料库,选择电影资料夹的高级设置,设置如下 plex代理设置 刷新电影源数据资料 设置完成后就可以在plex主页对电影文件夹刷新元数据了。等待刷新完后就可以载入所有的电影信息了。 管理资料库-刷新电影元数据 更新后的电影信息 采用类似的设置,电视剧信息也能刮削。 电视剧更新后的信息 Emby设置 Emby内置刮削工具,但是速度较慢。下面设置基于外部刮削工具TMM,所以没有勾选Emby刮削源! 最终效果演示 开始设置 新增媒体库 已有媒体库属性设置 Emby字幕设置 字幕下载设置,字幕下载工具见后面的[字幕下载]章节 字幕下载 想要较好的自动下载字幕,最好用前面介绍的tmm刮削改名之后再使用下面工具。 subfinder 自动下载字幕 Docker: superng6/subfinder 下载完成,刮削后的目录,挂载到subfinder的media目录,就会自动下载字幕。 字幕下载对电影,英文剧集支持较好。对于一些tv,动画手动下载字幕会更好一些。 注意:官方的配置文件有问题,时效问题。修改URL到最新即可。 chinesesubfinder Docker: allanpk716/chinesesubfinder 新开发的中文字幕查找工具,上面那个很久没更新了,这个刚出来。使用nfo里面刮削出来的文件名来匹配字幕。所以就原理来说,这个字幕匹配更准确。 bazarr Docker:linuxserver/bazarr 字幕下载管理,配合sonarr, radarr 使用效果更好。对于英文剧集命名规范的支持较好,比如[name]S01E01 tinyMediaManager 破解 Power 本项目只做个人学习研究之用,不得用于商业用途! ja-netfilter tinyMediaManager 4 破解 power.conf文件配置 [Result] ; tinyMediaManager EQUAL,8630757501743642474097255044263570352684017656721020257535853201009899319687425782165282064796127603308259281595234513417333265009792301721615397359280849629133412233835828756819167588254001206400797570673452581858162969385412635998542457688319518187361665435616211663738293023751998984763244849554409283905806741550843609045949098379453835211021356935854652145036408058534280517201922175457527823511640833551008542638353155946242172001873369454067403155639128713334107588511323091987132843211721921554657376250465757925304142530090462817875274786037327875410447778794471350439131533860021653761166305610613929184255,65537,24727125652606355449965534471427156023350099597994490506507713341912306496563021166152677249027965321789848834729809902911806740445767002100807674700362396558567035577150643203400446146497612913744824152837680881642876928709753797537574652985337199808338261100773937616204974417659383459000710718258741071638125033399831524388809092948345089352808322362674190618697732507738374259091305808486391160153350340004713677863069207330711835021340142816443405418680867515100803735831594532024774597095396300615924299450809820530743854878808508438754957122002060049512204045465820395106589768553215005202526112100710029727397->986236757547332986472011617696226561292849812918563355472727826767720188564083584387121625107510786855734801053524719833194566624465665316622563244215340671405971599343902468620306327831715457360719532421388780770165778156818229863337344187575566725786793391480600129482653072861971002459947277805295727097226389568776499707662505334062639449916265137796823793276300221537201727072401742985542559596685092673521228140822200236743113743661549252453726123450722876929538747702356573783116197523966334991563351853851212597377279504828784749025539275525568327959057446141950786113749166506186864056372274749084589132 tinyMediaManager激活码 LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQoKbmFtZT1uZW8KdmFsaWRVbnRpbD0yMDk5LTEyLTMxCndlYnNpdGU9aHR0cHM6Ly96aGlsZS5pbwotLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLQoKd3NCY0JBQUJDQUFRQlFKZlJtOWpDUkR6ZW9adU9nVVluUUFBVmtvSUFFUmVaNlBwM1NpbVlLYkgrSkh6d1c4cQpMaVdlUUlQTmF0RndEUUhnRDRpcFQ5YVhNYU9iblhYbDgzS1VRNWxQeDhCdzc3QnhQYXJwVWJ0Q1JOVHJXb1U1ClhaMWlrZnF6bWVWRUpyazRZc05LRGlCcHZqYnlGODZGOEtTa1hod2RMV1NtMWU2eWVtblhLY1RIZzJMMTNBaVMKNlRJcVhYYmNSbUZGN1JUTzREUXJqaXJhMllZbFc4ZUhQSWNDbU9xMFlqUjRRcHorUi8rM0JsZlYyVEFjTC9zZApTZUtBY3pndmRQNkNTNmJlMXJQQTBubGd3OVQ4NTNCcGdxcGxRVk0zMHBVaFZsbmk3Z2ExWVJ6RU5tNlFpYzVBCnVFYm1QeXVuaW0yV0h5dFB1TFFxK0JRdkFxK1dycjJraU03RGh5dllGaWhETmRGV1c2N1krZlNsZ1B4T2kvOD0KPVFLcGMKLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0t -javaagent配置 我们假设你的ja-netfilter.jar所在文件路径是:/path/to/ja-netfilter.jar(实际使用以你真实安装路径为准) 在tinyMediaManager安装目录下找到:launcher-extra.yml文件 编辑launcher-extra.yml文件,在文件中找到jvmOpts节配置,添加:- '-javaagent:/path/to/ja-netfilter.jar' 其实编辑launcher.yml文件也是可以的。 注意一定用你ja-netfilter.jar的真实绝对地址替换上面的-javaagent:后面的地址 由于tinyMediaManager最新版本升级到Java17,故而需要添加额外的JVM参数。具体请看这篇文章。 保存launcher-extra.yml文件后启动tinyMediaManager,填入上述的激活码即可。 Windows/macOS/Linux操作系统不限。 一个最简的示例launcher-extra.yml文件内容最起码应该有这些: --- javaHome: '' jvmOpts: - '--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED' - '--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED' - '-javaagent:/path/to/ja-netfilter.jar' env: [] tinyMediaManager 5 破解 tinyMediaManager4.x版本的power配置和激活码 7都是对的,RSA验证都通过了,最后发现是5.x新版本启动时把-javaagent参数给抹掉了,没有完全按照launcher.yml里的参数进行设置,而且还强制增加了下面两个参数: -XX:+DisableAttachMechanism -XX:-EnableDynamicAgentLoading 解决办法: 方法一: 简单写个shell脚本,用自己的java参数命令启动 #/bin/bash cd /Applications/tinyMediaManager.app/Contents/Resources/Java/ ./jre/bin/java -Xms64m -Xmx512m -Xss512k \ -XX:+IgnoreUnrecognizedVMOptions \ -XX:+UseG1GC \ -XX:+UseStringDeduplication \ -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine \ -Djava.net.preferIPv4Stack=true \ -Dfile.encoding=UTF-8 \ -Dsun.jnu.encoding=UTF-8 \ -Djna.nosys=true \ -Dtmm.consoleloglevel=INFO \ -Dapple.awt.graphics.UseQuartz=true \ -Xdock:name=tinyMediaManager \ -Dapple.awt.application.name=tinyMediaManager \ -Dapple.awt.application.appearance=system \ -Dapple.eawt.quitStrategy=CLOSE_ALL_WINDOWS \ --add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ --add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ -javaagent:/xxx/ja-netfilter.jar \ #-Dtmm.contentfolder="/Users/xxx/Library/Application Support/tinyMediaManager" \ -classpath "tmm.jar:./lib/*" org.tinymediamanager.TinyMediaManager 方法二: 直接把启动程序/Applications/tinyMediaManager.app/Contents/MacOS/tinyMediaManager换成4.x版本的,主程序都是java的,功能上感觉应该影响不大 一些说明 本文是对Power插件和非对称加密的学习研究,不是让你做商业用途的! 希望大家用Power插件玩出更多玩法。 希望大家为ja-netfilter多开发好用好玩的插件。 MediaElch MediaElch TMM 的开源替代品 功能:支持电影、电视剧刮削,生成NFO文件及海报墙,兼容Kodi/Plex/Emby;支持多数据源(TMDB、TVDB)。 优势:开源免费、跨平台(Win/macOS/Linux),界面简洁,可批量管理元数据。 局限:无文件重命名功能,需配合其他工具整理文件。 参考 利用tinyMediaManager刮削影片,解决家用nas软件plex电影墙的问题 Power插件应用:搞定tinyMediaManager tinyMediaManager-5.0.4激活遇到的问题及解决方法 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/10/11
articleCard.readMore

如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库

背景 动画、电影、剧集可使用TinyMediaManager生成nfo元数据文件,多媒体软件解析生成海报墙展示丰富的影片信息。 而音乐文件则是将歌名、歌手、专辑、发行时间、歌词、封面图等信息写入文件标签,称为ID3 Tag 。桌面软件、多媒体管理软件(Foobar2000/Plex/Emby/Jellyfin等)都能解析展现歌曲信息。ID3标签是MP3音乐档案中的歌曲附加讯息,它能够在MP3中附加曲子的演出者、作者以及其它类别资讯,方便众多乐曲的管理。缺少ID3标签并不会影响 MP3的播放,但若没有的话,管理音乐文件也会相当的麻烦。 音乐下载方法和工具,参见 私人在线音乐服务器搭建与使用介绍 刮削效果 Foobar2000读取效果: Jellyfin读取效果: Mp3tag 纯手工修改,开源工具。 Media Go 不要使用最新版!老版本才有我们最需要的功能。 添加媒体库 自动获取属性 歌曲属性修改 MusicBrainz MusicBrainz官网:https://musicbrainz.org/ MusicBrainz Picard下载地址:https://picard.musicbrainz.org/ MusicBrainz Picard使用教程: 如果以上两种方法都搜索不到,或者添加的文件名变成乱码,右击”查找相似的音轨“ 手动输入歌曲名字,搜索,选择正确的歌曲信息,载入Picard。 右侧窗口载入专辑信息。展开列表,绿色方块的就是匹配成功的音乐。底部窗口展示文件原始标签信息和MusicBrainz网站上的信息对照。 最后点“保存”,将标签信息写入音乐文件。 如何重命名文件: musictag 『音乐标签』是一款可以编辑歌曲的标题,专辑,艺术家,歌词,封面等信息的应用程序, 支持FLAC, APE, WAV, AIFF, WV, TTA, MP3, MP4, M4A, OGG, MPC, OPUS, WMA, DSF, DFF等音频格式,绿色无广告,无任何功能限制。 和前面几个工具混合使用效果更好! 最新版下载: 当前版本:1.0.9.0 运行环境:.NET Framework 4.6.1 操作系统:Windows Vista以上 下载链接:https://pan.baidu.com/s/18vN9wWGbbNC2foEy4MfJEA 提取码:x081 https://wwc.lanzouy.com/ik0lo0ae7bcf 解码密码:www.coolapk.com music-tag-web xhongc/music-tag-web: 音乐标签编辑器,可编辑本地音乐文件的元数据(Editable local music file metadata.) (github.com) 安装 docker run -d -p 8001:8001 -v /path/to/your/music:/app/media -v /path/to/your/config:/app/data --restart=always xhongc/music_tag_web:latest version: '3' services: music-tag: image: xhongc/music_tag_web:latest container_name: music-tag-web ports: - "8001:8001" volumes: - /path/to/your/music:/app/media:rw # 改成你的音乐文件夹路径 - /path/to/your/config:/app/data # 配置文件路径 command: /start restart: always 用户界面 音乐下载方法和工具,参见 私人在线音乐服务器搭建与使用介绍 参考: 使用MusicBrainz Picard刮削音乐 整理音乐资料库 音乐标签pc版 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/10/11
articleCard.readMore

http 错误代码表

所有 HTTP 状态代码及其定义。 HTTP 400 - 请求无效  HTTP 401.1 - 未授权:登录失败  HTTP 401.2 - 未授权:服务器配置问题导致登录失败  HTTP 401.3 - ACL 禁止访问资源  HTTP 401.4 - 未授权:授权被筛选器拒绝  HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败   HTTP 403 - 禁止访问  HTTP 403 - 对 Internet 服务管理器 (HTML) 的访问仅限于 Localhost  HTTP 403.1 禁止访问:禁止可执行访问  HTTP 403.2 - 禁止访问:禁止读访问  HTTP 403.3 - 禁止访问:禁止写访问  HTTP 403.4 - 禁止访问:要求 SSL  HTTP 403.5 - 禁止访问:要求 SSL 128  HTTP 403.6 - 禁止访问:IP 地址被拒绝  HTTP 403.7 - 禁止访问:要求客户证书  HTTP 403.8 - 禁止访问:禁止站点访问  HTTP 403.9 - 禁止访问:连接的用户过多  HTTP 403.10 - 禁止访问:配置无效  HTTP 403.11 - 禁止访问:密码更改  HTTP 403.12 - 禁止访问:映射器拒绝访问  HTTP 403.13 - 禁止访问:客户证书已被吊销  HTTP 403.15 - 禁止访问:客户访问许可过多  HTTP 403.16 - 禁止访问:客户证书不可信或者无效  HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效  HTTP 404.1 - 无法找到 Web 站点  HTTP 404 - 无法找到文件  HTTP 405 - 资源被禁止  HTTP 406 - 无法接受  HTTP 407 - 要求代理身份验证  HTTP 410 - 永远不可用  HTTP 412 - 先决条件失败  HTTP 414 - 请求 - URI 太长  HTTP 500 - 内部服务器错误  HTTP 500.100 - 内部服务器错误 - ASP 错误  HTTP 500-11 服务器关闭  HTTP 500-12 应用程序重新启动  HTTP 500-13 - 服务器太忙  HTTP 500-14 - 应用程序无效  HTTP 500-15 - 不允许请求 global.asa  Error 501 - 未实现  HTTP 502 - 网关错误

2021/10/6
articleCard.readMore

解决Thinkpad笔记本喇叭破音问题!

问题 主力笔记本笔记本播放音乐再次出现破音,换了几首音乐后问题依旧,前后对比强烈。 分析 从几年前上一次维修经验来看,应该是喇叭老化破裂了!拆机查看,发现的确事喇叭破裂。 解决方案 如是,网购了一个新喇叭,拆机,换上,完美解决问题! 喇叭施压后,能明显看到断裂痕迹。这样的喇叭音色就会出现明显的破音!如下图所示。 这已经是这台笔记本第二次出现喇叭破裂问题了! 感觉喇叭材料或者工艺有问题。 型号:Thinkpad T4X0S

2021/10/5
articleCard.readMore

从文学的角度,分析韩红的《天亮了》

现场MV .bbplayer{width: 100%; max-width: 850px; margin: auto} document.getElementById("mmedia-dtAPUHbhLnKZnBVM").style.height=document.getElementById("mmedia-dtAPUHbhLnKZnBVM").scrollWidth*0.76+"px"; window.onresize = function(){ document.getElementById("mmedia-dtAPUHbhLnKZnBVM").style.height=document.getElementById("mmedia-dtAPUHbhLnKZnBVM").scrollWidth*0.76+"px"; }; 精品分析: 原作:石晶兰 短文吧 再做个传送门: 天亮了,听歌时,关灯,准备纸巾。 先分析结构。 看歌词。 那是一个秋天,风儿那么缠绵, 共八行,等于两个四行。 继续看《天亮了》歌词: 我看到爸爸妈妈就这么走远, 六行都是转。具体在这里,自然不是转折,而是高那个潮。 此处值得一说的是合,只有三个字“天亮了”。 题都城南庄/唐/崔护 不难看出,最后一句“桃花依旧笑春风”跟前面三句的叙述,是接不上的。 《天亮了》末尾的合“天亮了”,就是“桃花依旧笑春风”这种表现手法。太多的感情,千言万语,加总在一起,实在难以挽上疙瘩。于是,就另起一行,来了句看似关系不大的“天亮了”,让一切,尽在无言中。 文学结构分析,就到这儿。第二段的结构跟第一段相同,就不讲了。 下面进行逐句评讲。 “那是一个秋天,风儿那么缠绵,”没毛病。“那是”开头,虽然不出彩,但是很自然,容易被人接受,接着往下听。 “就在那美丽风景相伴的地方,我听到一声巨响震彻山谷。”这两小句,没有基础毛病。 “就是那个秋天,再看不到爸爸的脸。” “我看到爸爸妈妈就这么走远,留下我在这陌生的人世间。不知道未来还会有什么风险。” “天亮了。”尽在不言中,就不再讲了。 “这是一个夜晚天上宿星点点,我在梦里看见我的妈妈。” 唐/李白有句:“千里江陵一日还”。“千里江陵”说的是千里之外的江陵。站在什么地方能够说出此话,自然是白帝城。“还”,指回来,站在什么地方能够说“还”,当然只能是江陵。就这么一句,视角就从白帝城跳到了江陵。 “你不要离开不要伤害”上一段出现过,就不讲了。 “我看到爸爸妈妈就这么走远,留下我在这陌生的人世间。我愿为他建造一个美丽的花园。” “我想要紧紧抓住他的手。妈妈告诉我希望还会有,看到太阳出来、天亮了。” “我看到爸爸妈妈就这么走远,留下我在这陌生的人世间。我愿为他建造一个美丽的花园。 不知道是哪年哪天了,无意中,我就这么偶然听到了这首歌。 生活中,有各种各样的事故。最常见的,恐怕应该是车祸。 最容易想到的角度,有两个。 是的,韩红,把自己当作那个孩子的父母,并且还把自己当作了孩子死去的父母。《天亮了》这首歌,表达的是死者对生者的寄托! 题外话又冒出来了。 这番题外话,表达的是,前面关于《天亮了》的评论,或许韩红自己并没那么想,或者韩红没想那么多,或许《天亮了》就仅仅是韩红的偶然之得。 最后,我还要说的是,文学水平,所指的,并不仅仅是文字方面的能力。 (全文完) 系列教程 全部文章RSS订阅 音乐推荐 音乐推荐-爱是你我 音乐推荐-曾经我也想过一了百了 从文学的角度,分析韩红的《天亮了》 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版

2021/10/3
articleCard.readMore

1.5 万字 CSS 基础拾遗(核心知识、常见需求)

1.5 万字 CSS 基础拾遗(核心知识、常见需求) 本篇文章围绕了 CSS 的核心知识点和项目中常见的需求来展开。虽然行文偏长,但偏基础,适合初级中级前端阅读,阅读的时候请适当跳过已经掌握的部分。 这篇文章断断续续写了比较久,也参考了许多优秀的文章,但或许文章里还是存在不好或不对的地方,请多多指教,可以评论里直接提出来哈。 小tip:后续内容更精彩哦。 核心概念和知识点 语法 CSS 的核心功能是将 CSS 属性设定为特定的值。一个属性与值的键值对被称为声明(declaration)。 color: red; 而如果将一个或者多个声明用 {} 包裹起来后,那就组成了一个声明块(declaration block)。 { color: red; text-align: center; } 声明块如果需要作用到对应的 HTML 元素,那还需要加上选择器。选择器和声明块组成了CSS 规则集(CSS ruleset),常简称为 CSS 规则。 span { color: red; text-align: center; } “ 规则集中最后一条声明可以省略分号,但是并不建议这么做,因为容易出错。 CSS 中的注释: /* 单行注释 */ /* 多行 注释 */ 在 CSS 文件中,除了注释、CSS 规则集以及 @规则 外,定义的一些别的东西都将被浏览器忽略。 @规则 CSS 规则是样式表的主体,通常样式表会包括大量的规则列表。但有时候也需要在样式表中包括其他的一些信息,比如字符集,导入其它的外部样式表,字体等,这些需要专门的语句表示。 而 @规则 就是这样的语句。CSS 里包含了以下 @规则: @namespace 告诉 CSS 引擎必须考虑XML命名空间。 @media, 如果满足媒体查询的条件则条件规则组里的规则生效。 @page, 描述打印文档时布局的变化. @font-face, 描述将下载的外部的字体。 @keyframes, 描述 CSS 动画的关键帧。 @document, 如果文档样式表满足给定条件则条件规则组里的规则生效。 (推延至 CSS Level 4 规范) 除了以上这几个之外,下面还将对几个比较生涩的 @规则 进行介绍。 @charset @charset[1] 用于定义样式表使用的字符集。它必须是样式表中的第一个元素。如果有多个 @charset 被声明,只有第一个会被使用,而且不能在HTML元素或HTML页面的 <style> 元素内使用。 注意:值必须是双引号包裹,且和 @charset "UTF-8"; 平时写样式文件都没写 @charset 规则,那这个 CSS 文件到底是用的什么字符编码的呢? 某个样式表文件到底用的是什么字符编码,浏览器有一套识别顺序(优先级由高到低): 文件开头的 Byte order mark[2] 字符值,不过一般编辑器并不能看到文件头里的 BOM 值; HTTP 响应头里的 content-type 字段包含的 charset 所指定的值,比如: Content-Type: text/css; charset=utf-8 CSS 文件头里定义的 @charset 规则里指定的字符编码; <link> 标签里的 charset 属性,该条已在 HTML5 中废除; 默认是 UTF-8。 @import @import[3] 用于告诉 CSS 引擎引入一个外部样式表。 link 和 @import 都能导入一个样式文件,它们有什么区别嘛? link 是 HTML 标签,除了能导入 CSS 外,还能导入别的资源,比如图片、脚本和字体等;而 @import 是 CSS 的语法,只能用来导入 CSS; link 导入的样式会在页面加载时同时加载,@import 导入的样式需等页面加载完成后再加载; link 没有兼容性问题,@import 不兼容 ie5 以下; link 可以通过 JS 操作 DOM 动态引入样式表改变样式,而@import不可以。 @supports @supports[4] 用于查询特定的 CSS 是否生效,可以结合 not、and 和 or 操作符进行后续的操作。 /* 如果支持自定义属性,则把 body 颜色设置为变量 varName 指定的颜色 */ @supports (--foo: green) { body { color: var(--varName); } } 层叠性 层叠样式表,这里的层叠怎么理解呢?其实它是 CSS 中的核心特性之一,用于合并来自多个源的属性值的算法。比如说针对某个 HTML 标签,有许多的 CSS 声明都能作用到的时候,那最后谁应该起作用呢?层叠性说的大概就是这个。 针对不同源的样式,将按照如下的顺序进行层叠,越往下优先级越高: 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。 用户样式表中的常规声明(由用户设置的自定义样式。由于 Chrome 在很早的时候就放弃了用户样式表的功能,所以这里将不再考虑它的排序。)。 作者样式表中的常规声明(这些是我们 Web 开发人员设置的样式)。 作者样式表中的 !important 声明。 用户样式表中的 !important 声明S。 理解层叠性的时候需要结合 CSS 选择器的优先级以及继承性来理解。比如针对同一个选择器,定义在后面的声明会覆盖前面的;作者定义的样式会比默认继承的样式优先级更高。 选择器 CSS 选择器无疑是其核心之一,对于基础选择器以及一些常用伪类必须掌握。下面列出了常用的选择器。 想要获取更多选择器的用法可以看 MDN CSS Selectors[5]。 基础选择器 标签选择器:h1 类选择器:.checked ID 选择器:#picker 通配选择器:* 属性选择器 [attr]:指定属性的元素; [attr=val]:属性等于指定值的元素; [attr*=val]:属性包含指定值的元素; [attr^=val] :属性以指定值开头的元素; [attr$=val]:属性以指定值结尾的元素; [attr~=val]:属性包含指定值(完整单词)的元素(不推荐使用); [attr|=val]:属性以指定值(完整单词)开头的元素(不推荐使用); 组合选择器 相邻兄弟选择器:A + B 普通兄弟选择器:A ~ B 子选择器:A > B 后代选择器:A B 伪类 条件伪类 :lang():基于元素语言来匹配页面元素; :dir():匹配特定文字书写方向的元素; :has():匹配包含指定元素的元素; :is():匹配指定选择器列表里的元素; :not():用来匹配不符合一组选择器的元素; 行为伪类 :active:鼠标激活的元素; :hover: 鼠标悬浮的元素; ::selection:鼠标选中的元素; 状态伪类 :target:当前锚点的元素; :link:未访问的链接元素; :visited:已访问的链接元素; :focus:输入聚焦的表单元素; :required:输入必填的表单元素; :valid:输入合法的表单元素; :invalid:输入非法的表单元素; :in-range:输入范围以内的表单元素; :out-of-range:输入范围以外的表单元素; :checked:选项选中的表单元素; :optional:选项可选的表单元素; :enabled:事件启用的表单元素; :disabled:事件禁用的表单元素; :read-only:只读的表单元素; :read-write:可读可写的表单元素; :blank:输入为空的表单元素; :current():浏览中的元素; :past():已浏览的元素; :future():未浏览的元素; 结构伪类 :root:文档的根元素; :empty:无子元素的元素; :first-letter:元素的首字母; :first-line:元素的首行; :nth-child(n):元素中指定顺序索引的元素; :nth-last-child(n):元素中指定逆序索引的元素;; :first-child:元素中为首的元素; :last-child :元素中为尾的元素; :only-child:父元素仅有该元素的元素; :nth-of-type(n):标签中指定顺序索引的标签; :nth-last-of-type(n):标签中指定逆序索引的标签; :first-of-type :标签中为首的标签; :last-of-type:标签中为尾标签; :only-of-type:父元素仅有该标签的标签; 伪元素 ::before:在元素前插入内容; ::after:在元素后插入内容; 优先级 优先级就是分配给指定的 CSS 声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。为了记忆,可以把权重分成如下几个等级,数值越大的权重越高: 10000:!important; 01000:内联样式; 00100:ID 选择器; 00010:类选择器、伪类选择器、属性选择器; 00001:元素选择器、伪元素选择器; 00000:通配选择器、后代选择器、兄弟选择器; 可以看到内联样式(通过元素中 style 属性定义的样式)的优先级大于任何选择器;而给属性值加上 !important 又可以把优先级提至最高,就是因为它的优先级最高,所以需要谨慎使用它,以下有些使用注意事项: 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important; 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important; 永远不要在你的插件中使用 !important; 永远不要在全站范围的 CSS 代码中使用 !important; 继承性 在 CSS 中有一个很重要的特性就是子元素会继承父元素对应属性计算后的值。比如页面根元素 html 的文本颜色默认是黑色的,页面中的所有其他元素都将继承这个颜色,当申明了如下样式后,H1 文本将变成橙色。 body { color: orange; } h1 { color: inherit; } 设想一下,如果 CSS 中不存在继承性,那么我们就需要为不同文本的标签都设置一下 color,这样一来的后果就是 CSS 的文件大小就会无限增大。 CSS 属性很多,但并不是所有的属性默认都是能继承父元素对应属性的,那哪些属性存在默认继承的行为呢?一定是那些不会影响到页面布局的属性,可以分为如下几类: 字体相关:font-family、font-style、font-size、font-weight 等; 文本相关:text-align、text-indent、text-decoration、text-shadow、letter-spacing、word-spacing、white-space、line-height、color 等; 列表相关:list-style、list-style-image、list-style-type、list-style-position 等; 其他属性:visibility、cursor 等; 对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为: inherit:继承父元素对应属性的计算值; initial:应用该属性的默认值,比如 color 的默认值是 #000; unset:如果属性是默认可以继承的,则取 inherit 的效果,否则同 initial; revert:效果等同于 unset,兼容性差。 文档流 在 CSS 的世界中,会把内容按照从左到右、从上到下的顺序进行排列显示。正常情况下会把页面分割成一行一行的显示,而每行又可能由多列组成,所以从视觉上看起来就是从上到下从左到右,而这就是 CSS 中的流式布局,又叫文档流。文档流就像水一样,能够自适应所在的容器,一般它有如下几个特性: 块级元素默认会占满整行,所以多个块级盒子之间是从上到下排列的; 内联元素默认会在一行里一列一列的排布,当一行放不下的时候,会自动切换到下一行继续按照列排布; 如何脱离文档流呢? 脱流文档流指节点脱流正常文档流后,在正常文档流中的其他节点将忽略该节点并填补其原先空间。文档一旦脱流,计算其父节点高度时不会将其高度纳入,脱流节点不占据空间。有两种方式可以让元素脱离文档流:浮动和定位。 使用浮动(float)会将元素脱离文档流,移动到容器左/右侧边界或者是另一个浮动元素旁边,该浮动元素之前占用的空间将被别的元素填补,另外浮动之后所占用的区域不会和别的元素之间发生重叠; 使用绝对定位(position: absolute;)或者固定定位(position: fixed;)也会使得元素脱离文档流,且空出来的位置将自动被后续节点填补。 盒模型 在 CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。 盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。 如果给某个元素设置如下样式: .box { width: 200px; height: 200px; padding: 10px; border: 1px solid #eee; margin: 10px; } 标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框 所以 .box 元素内容的宽度就为 200px,而实际的宽度则是 width + padding-left + padding-right + border-left-width + border-right-width = 200 + 10 + 10 + 1 + 1 = 222。 IE 盒模型认为:盒子的实际尺寸 = 设置的宽/高 = 内容 + 内边距 + 边框 .box 元素所占用的实际宽度为 200px,而内容的真实宽度则是 width - padding-left - padding-right - border-left-width - border-right-width = 200 - 10 - 10 - 1 - 1 = 178。 现在高版本的浏览器基本上默认都是使用标准盒模型,而像 IE6 这种老古董才是默认使用 IE 盒模型的。 在 CSS3 中新增了一个属性 box-sizing,允许开发者来指定盒子使用什么标准,它有 2 个值: content-box:标准盒模型; border-box:IE 盒模型; 视觉格式化模型 视觉格式化模型(Visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。CSS 中一切皆盒子,而视觉格式化模型简单来理解就是规定这些盒子应该怎么样放置到页面中去,这个模型在计算的时候会依赖到很多的因素,比如:盒子尺寸、盒子类型、定位方案(是浮动还是定位)、兄弟元素或者子元素以及一些别的因素。 Visual formatting model 从上图中可以看到视觉格式化模型涉及到的内容很多,有兴趣深入研究的可以结合上图看这个 W3C 的文档 Visual formatting model[6]。所以这里就简单介绍下盒子类型。 盒子类型由 display 决定,同时给一个元素设置 display 后,将会决定这个盒子的 2 个显示类型(display type): outer display type(对外显示):决定了该元素本身是如何布局的,即参与何种格式化上下文; inner display type(对内显示):其实就相当于把该元素当成了容器,规定了其内部子元素是如何布局的,参与何种格式化上下文; outer display type 对外显示方面,盒子类型可以分成 2 类:block-level box(块级盒子) 和 inline-level box(行内级盒子)。 依据上图可以列出都有哪些块级和行内级盒子: 块级盒子:display 为 block、list-item、table、flex、grid、flow-root 等; 行内级盒子:display 为 inline、inline-block、inline-table 等; 所有块级盒子都会参与 BFC,呈现垂直排列;而所有行内级盒子都参会 IFC,呈现水平排列。 除此之外,block、inline 和 inline-block 还有什么更具体的区别呢? block 占满一行,默认继承父元素的宽度;多个块元素将从上到下进行排列; 设置 width/height 将会生效; 设置 padding 和 margin 将会生效; inline 不会占满一行,宽度随着内容而变化;多个 inline 元素将按照从左到右的顺序在一行里排列显示,如果一行显示不下,则自动换行; 设置 width/height 将不会生效; 设置竖直方向上的 padding 和 margin 将不会生效; inline-block 是行内块元素,不单独占满一行,可以看成是能够在一行里进行左右排列的块元素; 设置 width/height 将会生效; 设置 padding 和 margin 将会生效; inner display type 对内方面,其实就是把元素当成了容器,里面包裹着文本或者其他子元素。container box 的类型依据 display 的值不同,分为 4 种: block container:建立 BFC 或者 IFC; flex container:建立 FFC; grid container:建立 GFC; ruby container:接触不多,不做介绍。 值得一提的是如果把 img 这种替换元素(replaced element)申明为 block 是不会产生 container box 的,因为替换元素比如 img 设计的初衷就仅仅是通过 src 把内容替换成图片,完全没考虑过会把它当成容器。 参考: CSS 原理 - 你所不知道的 display[7] 格式化上下文[8] 格式化上下文 格式化上下文(Formatting Context)是 CSS2.1 规范中的一个概念,大概说的是页面中的一块渲染区域,规定了渲染区域内部的子元素是如何排版以及相互作用的。 不同类型的盒子有不同格式化上下文,大概有这 4 类: BFC (Block Formatting Context) 块级格式化上下文; IFC (Inline Formatting Context) 行内格式化上下文; FFC (Flex Formatting Context) 弹性格式化上下文; GFC (Grid Formatting Context) 格栅格式化上下文; 其中 BFC 和 IFC 在 CSS 中扮演着非常重要的角色,因为它们直接影响了网页布局,所以需要深入理解其原理。 BFC 块格式化上下文,它是一个独立的渲染区域,只有块级盒子参与,它规定了内部的块级盒子如何布局,并且与这个区域外部毫不相干。 图来源于 yachen168 BFC 渲染规则 内部的盒子会在垂直方向,一个接一个地放置; 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠; 每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此; BFC 的区域不会与 float 盒子重叠; BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。 计算 BFC 的高度时,浮动元素也参与计算。 如何创建 BFC? 根元素:html 非溢出的可见元素:overflow 不为 visible 设置浮动:float 属性不为 none 设置定位:position 为 absolute 或 fixed 定义成块级的非块级元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid BFC 应用场景 1、 自适应两栏布局 应用原理:BFC 的区域不会和浮动区域重叠,所以就可以把侧边栏固定宽度且左浮动,而对右侧内容触发 BFC,使得它的宽度自适应该行剩余宽度。 <div class="layout"> <div class="aside">aside</div> <div class="main">main</div> </div> .aside { float: left; width: 100px; } .main { <!-- 触发 BFC --> overflow: auto; } 2、清除内部浮动 浮动造成的问题就是父元素高度坍塌,所以清除浮动需要解决的问题就是让父元素的高度恢复正常。而用 BFC 清除浮动的原理就是:计算 BFC 的高度时,浮动元素也参与计算。只要触发父元素的 BFC 即可。 .parent { overflow: hidden; } 3、 防止垂直 margin 合并 BFC 渲染原理之一:同一个 BFC 下的垂直 margin 会发生合并。所以如果让 2 个元素不在同一个 BFC 中即可阻止垂直 margin 合并。那如何让 2 个相邻的兄弟元素不在同一个 BFC 中呢?可以给其中一个元素外面包裹一层,然后触发其包裹层的 BFC,这样一来 2 个元素就不会在同一个 BFC 中了。 <div class="layout"> <div class="a">a</div> <div class="contain-b"> <div class="b">b</div> </div> </div> .demo3 .a, .demo3 .b { border: 1px solid #999; margin: 10px; } .contain-b { overflow: hidden; } 针对以上 3 个 示例 ,可以结合这个 BFC 应用示例 配合观看更佳。 参考:CSS 原理 - Formatting Context[9] IFC IFC 的形成条件非常简单,块级元素中仅包含内联级别元素,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。 IFC 渲染规则 子元素在水平方向上一个接一个排列,在垂直方向上将以容器顶部开始向下排列; 节点无法声明宽高,其中 margin 和 padding 在水平方向有效在垂直方向无效; 节点在垂直方向上以不同形式对齐; 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的线盒(line box)。线盒的宽度是由包含块(containing box)和与其中的浮动来决定; IFC 中的 line box 一般左右边贴紧其包含块,但 float 元素会优先排列。 IFC 中的 line box 高度由 line-height 计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同; 当内联级盒子的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定; 当一个内联盒子超过父元素的宽度时,它会被分割成多盒子,这些盒子分布在多个 line box 中。如果子元素未设置强制换行的情况下,inline box 将不可被分割,将会溢出父元素。 针对如上的 IFC 渲染规则,你是不是可以分析下下面这段代码的 IFC 环境是怎么样的呢? <p>It can get <strong>very complicated</storng> once you start looking into it.</p> 对应上面这样一串 HTML 分析如下: p 标签是一个 block container,对内将产生一个 IFC; 由于一行没办法显示完全,所以产生了 2 个线盒(line box);线盒的宽度就继承了 p 的宽度;高度是由里面的内联盒子的 line-height 决定; It can get:匿名的内联盒子; very complicated:strong 标签产生的内联盒子; once you start:匿名的内联盒子; looking into it.:匿名的内联盒子。 参考:Inline formatting contexts[10] IFC 应用场景 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align: middle,其他行内元素则可以在此父元素下垂直居中。 偷个懒,demo 和图我就不做了。 层叠上下文 在电脑显示屏幕上的显示的页面其实是一个三维的空间,水平方向是 X 轴,竖直方向是 Y 轴,而屏幕到眼睛的方向可以看成是 Z 轴。众 HTML 元素依据自己定义的属性的优先级在 Z 轴上按照一定的顺序排开,而这其实就是层叠上下文所要描述的东西。 -w566 我们对层叠上下文的第一印象可能要来源于 z-index,认为它的值越大,距离屏幕观察者就越近,那么层叠等级就越高,事实确实是这样的,但层叠上下文的内容远非仅仅如此: z-index 能够在层叠上下文中对元素的堆叠顺序其作用是必须配合定位才可以; 除了 z-index 之外,一个元素在 Z 轴上的显示顺序还受层叠等级和层叠顺序影响; 在看层叠等级和层叠顺序之前,我们先来看下如何产生一个层叠上下文,特定的 HTML 元素或者 CSS 属性产生层叠上下文,MDN 中给出了这么一个列表,符合以下任一条件的元素都会产生层叠上下文: html 文档根元素 声明 position: absolute/relative 且 z-index 值不为 auto 的元素; 声明 position: fixed/sticky 的元素; flex 容器的子元素,且 z-index 值不为 auto; grid 容器的子元素,且 z-index 值不为 auto; opacity 属性值小于 1 的元素; mix-blend-mode 属性值不为 normal 的元素; 以下任意属性值不为 none 的元素: transform filter perspective clip-path mask / mask-image / mask-border isolation 属性值为 isolate 的元素; -webkit-overflow-scrolling 属性值为 touch 的元素; will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素; contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。 层叠等级 层叠等级指节点在三维空间 Z 轴上的上下顺序。它分两种情况: 在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在 Z 轴上的上下顺序; 在其他普通元素中,它描述定义的是这些普通元素在 Z 轴上的上下顺序; 普通节点的层叠等级优先由其所在的层叠上下文决定,层叠等级的比较只有在当前层叠上下文中才有意义,脱离当前层叠上下文的比较就变得无意义了。 层叠顺序 在同一个层叠上下文中如果有多个元素,那么他们之间的层叠顺序是怎么样的呢? 以下这个列表越往下层叠优先级越高,视觉上的效果就是越容易被用户看到(不会被其他元素覆盖): 层叠上下文的 border 和 background z-index < 0 的子节点 标准流内块级非定位的子节点 浮动非定位的子节点 标准流内行内非定位的子节点 z-index: auto/0 的子节点 z-index > 0的子节点 如何比较两个元素的层叠等级? 在同一个层叠上下文中,比较两个元素就是按照上图的介绍的层叠顺序进行比较。 如果不在同一个层叠上下文中的时候,那就需要比较两个元素分别所处的层叠上下文的等级。 如果两个元素都在同一个层叠上下文,且层叠顺序相同,则在 HTML 中定义越后面的层叠等级越高。 参考:彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index[11] 值和单位 CSS 的声明是由属性和值组成的,而值的类型有许多种: 数值:长度值 ,用于指定例如元素 width、border-width、font-size 等属性的值; 百分比:可以用于指定尺寸或长度,例如取决于父容器的 width、height 或默认的 font-size; 颜色:用于指定 background-color、color 等; 坐标位置:以屏幕的左上角为坐标原点定位元素的位置,比如常见的 background-position、top、right、bottom 和 left 等属性; 函数:用于指定资源路径或背景图片的渐变,比如 url()、linear-gradient() 等; 而还有些值是需要带单位的,比如 width: 100px,这里的 px 就是表示长度的单位,长度单位除了 px 外,比较常用的还有 em、rem、vw/vh 等。那他们有什么区别呢?又应该在什么时候使用它们呢? px 屏幕分辨率是指在屏幕的横纵方向上的像素点数量,比如分辨率 1920×1080 意味着水平方向含有 1920 个像素数,垂直方向含有 1080 个像素数。 而 px 表示的是 CSS 中的像素,在 CSS 中它是绝对的长度单位,也是最基础的单位,其他长度单位会自动被浏览器换算成 px。但是对于设备而言,它其实又是相对的长度单位,比如宽高都为 2px,在正常的屏幕下,其实就是 4 个像素点,而在设备像素比(devicePixelRatio) 为 2 的 Retina 屏幕下,它就有 16 个像素点。所以屏幕尺寸一致的情况下,屏幕分辨率越高,显示效果就越细腻。 讲到这里,还有一些相关的概念需要理清下: 设备像素(Device pixels) 设备屏幕的物理像素,表示的是屏幕的横纵有多少像素点;和屏幕分辨率是差不多的意思。 设备像素比(DPR) 设备像素比表示 1 个 CSS 像素等于几个物理像素。 计算公式:DPR = 物理像素数 / 逻辑像素数; 在浏览器中可以通过 window.devicePixelRatio 来获取当前屏幕的 DPR。 像素密度(DPI/PPI) 像素密度也叫显示密度或者屏幕密度,缩写为 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。从技术角度说,PPI 只存在于计算机显示领域,而 DPI 只出现于打印或印刷领域。 计算公式:像素密度 = 屏幕对角线的像素尺寸 / 物理尺寸 比如,对于分辨率为 750 * 1334 的 iPhone 6 来说,它的像素密度为: Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi 设备独立像素(DIP) DIP 是特别针对 Android设备而衍生出来的,原因是安卓屏幕的尺寸繁多,因此为了显示能尽量和设备无关,而提出的这个概念。它是基于屏幕密度而计算的,认为当屏幕密度是 160 的时候,px = DIP。 计算公式:dip = px * 160 / dpi em em 是 CSS 中的相对长度单位中的一个。居然是相对的,那它到底是相对的谁呢?它有 2 层意思: 在 font-size 中使用是相对于父元素的 font-size 大小,比如父元素 font-size: 16px,当给子元素指定 font-size: 2em 的时候,经过计算后它的字体大小会是 32px; 在其他属性中使用是相对于自身的字体大小,如 width/height/padding/margin 等; 我们都知道每个浏览器都会给 HTML 根元素 html 设置一个默认的 font-size,而这个值通常是 16px。这也就是为什么 1em = 16px 的原因所在了。 em 在计算的时候是会层层计算的,比如: <div> <p></p> </div> div { font-size: 2em; } p { font-size: 2em; } 对于如上一个结构的 HTML,由于根元素 html 的字体大小是 16px,所以 p 标签最终计算出来后的字体大小会是 16 * 2 * 2 = 64px rem rem(root em) 和 em 一样,也是一个相对长度单位,不过 rem 相对的是 HTML 的根元素 html。 rem 由于是基于 html 的 font-size 来计算,所以通常用于自适应网站或者 H5 中。 比如在做 H5 的时候,前端通常会让 UI 给 750px 宽的设计图,而在开发的时候可以基于 iPhone X 的尺寸 375px * 812px 来写页面,这样一来的话,就可以用下面的 JS 依据当前页面的视口宽度自动计算出根元素 html 的基准 font-size 是多少。 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', psdWidth = 750, // 设计图宽度 recalc = function () { var clientWidth = docEl.clientWidth; if ( !clientWidth ) return; if ( clientWidth >= 640 ) { docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px'; } else { docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px'; } }; if ( !doc.addEventListener ) return; // 绑定事件的时候最好配合防抖函数 win.addEventListener( resizeEvt, debounce(recalc, 1000), false ); doc.addEventListener( 'DOMContentLoaded', recalc, false ); function debounce(func, wait) { var timeout; return function () { var context = this; var args = arguments; clearTimeout(timeout) timeout = setTimeout(function(){ func.apply(context, args) }, wait); } } })(document, window); 比如当视口是 375px 的时候,经过计算 html 的 font-size 会是 100px,这样有什么好处呢?好处就是方便写样式,比如从设计图量出来的 header 高度是 50px 的,那我们写样式的时候就可以直接写: header { height: 0.5rem; } 每个从设计图量出来的尺寸只要除于 100 即可得到当前元素的 rem 值,都不用经过计算,非常方便。偷偷告诉你,如果你把上面那串计算 html 标签 font-size 的 JS 代码中的 200 替换成 2,那在计算 rem 的时候就不需要除于 100 了,从设计图量出多大 px,就直接写多少个 rem。 vw/vh vw 和 vh 分别是相对于屏幕视口宽度和高度而言的长度单位: 1vw = 视口宽度均分成 100 份中 1 份的长度; 1vh = 视口高度均分成 100 份中 1 份的长度; 在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。 vw/vh 的出现使得多了一种写自适应布局的方案,开发者不再局限于 rem 了。 相对视口的单位,除了 vw/vh 外,还有 vmin 和 vmax: vmin:取 vw 和 vh 中值较小的; vmax:取 vw 和 vh 中值较大的; 颜色体系 CSS 中用于表示颜色的值种类繁多,足够构成一个体系,所以这里就专门拿出一个小节来讲解它。 根据 CSS 颜色草案[12] 中提到的颜色值类型,大概可以把它们分为这几类: 颜色关键字 transparent 关键字 currentColor 关键字 RGB 颜色 HSL 颜色 颜色关键字 颜色关键字(color keywords)是不区分大小写的标识符,它表示一个具体的颜色,比如 white(白),黑(black)等; 可接受的关键字列表在CSS的演变过程中发生了改变: CSS 标准 1 只接受 16 个基本颜色,称为 VGA 颜色,因为它们来源于 VGA 显卡所显示的颜色集合而被称为 VGA colors (视频图形阵列色彩)。 CSS 标准 2 增加了 orange 关键字。 从一开始,浏览器接受其它的颜色,由于一些早期浏览器是 X11 应用程序,这些颜色大多数是 X11 命名的颜色列表,虽然有一点不同。SVG 1.0 是首个正式定义这些关键字的标准;CSS 色彩标准 3 也正式定义了这些关键字。它们经常被称作扩展的颜色关键字, X11 颜色或 SVG 颜色 。 CSS 颜色标准 4 添加可 rebeccapurple 关键字来纪念 web 先锋 Eric Meyer。 如下这张图是 16 个基础色,又叫 VGA 颜色。截止到目前为止 CSS 颜色关键字总共有 146 个,这里可以查看 完整的色彩关键字列表[13]。 VGA 颜色 需要注意的是如果声明的时候的颜色关键字是错误的,浏览器会忽略它。 transparent 关键字 transparent 关键字表示一个完全透明的颜色,即该颜色看上去将是背景色。从技术上说,它是带有 alpha 通道为最小值的黑色,是 rgba(0,0,0,0) 的简写。 透明关键字有什么应用场景呢? 实现三角形 下面这个图是用 4 条边框填充的正方形,看懂了它你大概就知道该如何用 CSS 写三角形了。 div { border-top-color: #ffc107; border-right-color: #00bcd4; border-bottom-color: #e26b6b; border-left-color: #cc7cda; border-width: 50px; border-style: solid; } 用 transparent 实现三角形的原理: 首先宽高必须是 0px,通过边框的粗细来填充内容; 那条边需要就要加上颜色,而不需要的边则用 transparent; 想要什么样姿势的三角形,完全由上下左右 4 条边的中有颜色的边和透明的边的位置决定; 等腰三角形:设置一条边有颜色,然后紧挨着的 2 边是透明,且宽度是有颜色边的一半;直角三角形:设置一条边有颜色,然后紧挨着的任何一边透明即可。 看下示例: 增大点击区域 常常在移动端的时候点击的按钮的区域特别小,但是由于现实效果又不太好把它做大,所以常用的一个手段就是通过透明的边框来增大按钮的点击区域: .btn { border: 5px solid transparent; } currentColor 关键字 currentColor 会取当前元素继承父级元素的文本颜色值或声明的文本颜色值,即 computed 后的 color 值。 比如,对于如下 CSS,该元素的边框颜色会是 red: .btn { color: red; border: 1px solid currentColor; } RGB[A] 颜色 RGB[A] 颜色是由 R(red)-G(green)-B(blue)-A(alpha) 组成的色彩空间。 在 CSS 中,它有两种表示形式: 十六进制符号; 函数符; 十六进制符号 RGB 中的每种颜色的值范围是 00~ff,值越大表示颜色越深。所以一个颜色正常是 6 个十六进制字符加上 # 组成,比如红色就是 #ff0000。 如果 RGB 颜色需要加上不透明度,那就需要加上 alpha 通道的值,它的范围也是 00~ff,比如一个带不透明度为 67% 的红色可以这样写 #ff0000aa。 使用十六进制符号表示颜色的时候,都是用 2 个十六进制表示一个颜色,如果这 2 个字符相同,还可以缩减成只写 1 个,比如,红色 #f00;带 67% 不透明度的红色 #f00a。 函数符 当 RGB 用函数表示的时候,每个值的范围是 0~255 或者 0%~100%,所以红色是 rgb(255, 0, 0), 或者 rgb(100%, 0, 0)。 如果需要使用函数来表示带不透明度的颜色值,值的范围是 0~1 及其之间的小数或者 0%~100%,比如带 67% 不透明度的红色是 rgba(255, 0, 0, 0.67) 或者 rgba(100%, 0%, 0%, 67%) “ 需要注意的是 RGB 这 3 个颜色值需要保持一致的写法,要嘛用数字要嘛用百分比,而不透明度的值的可以不用和 RGB 保持一致写法。比如 rgb(100%, 0, 0) 这个写法是无效的;而 rgb(100%, 0%, 0%, 0.67) 是有效的。 在第 4 代 CSS 颜色标准中,新增了一种新的函数写法,即可以把 RGB 中值的分隔逗号改成空格,而把 RGB 和 alpha 中的逗号改成 /,比如带 67% 不透明度的红色可以这样写 rgba(255 0 0 / 0.67)。另外还把 rgba 的写法合并到 rgb 函数中了,即 rgb 可以直接写带不透明度的颜色。 HSL[A] 颜色 HSL[A] 颜色是由色相(hue)-饱和度(saturation)-亮度(lightness)-不透明度组成的颜色体系。 色相(H)是色彩的基本属性,值范围是 0~360 或者 0deg~360deg, 0 (或 360) 为红色, 120 为绿色, 240 为蓝色; 饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取 0~100% 的数值;0% 为灰色, 100% 全色; 亮度(L),取 0~100%,0% 为暗,100% 为白; 不透明度(A),取 0100%,或者01及之间的小数; 写法上可以参考 RGB 的写法,只是参数的值不一样。 给一个按钮设置不透明度为 67% 的红色的 color 的写法,以下全部写法效果一致: button { color: #ff0000aa; color: #f00a; color: rgba(255, 0, 0, 0.67); color: rgb(100% 0% 0% / 67%); color: hsla(0, 100%, 50%, 67%); color: hsl(0deg 100% 50% / 67%); } 小提示:在 Chrome DevTools 中可以按住 shift + 鼠标左键可以切换颜色的表示方式。 媒体查询 媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式。 你可以通过给 <link> 加上 media 属性来指定该样式文件只能对什么设备生效,不指定的话默认是 all,即对所有设备都生效: <link rel="stylesheet" src="styles.css" media="screen" /> <link rel="stylesheet" src="styles.css" media="print" /> 都支持哪些设备类型? all:适用于所有设备; print:适用于在打印预览模式下在屏幕上查看的分页材料和文档; screen:主要用于屏幕; speech:主要用于语音合成器。 需要注意的是:通过 media 指定的 资源尽管不匹配它的设备类型,但是浏览器依然会加载它。 除了通过 <link> 让指定设备生效外,还可以通过 @media 让 CSS 规则在特定的条件下才能生效。响应式页面就是使用了 @media 才让一个页面能够同时适配 PC、Pad 和手机端。 @media (min-width: 1000px) {} 媒体查询支持逻辑操作符: and:查询条件都满足的时候才生效; not:查询条件取反; only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型; 逗号或者 or:查询条件满足一项即可匹配; 媒体查询还支持众多的媒体特性[14],使得它可以写出很复杂的查询条件: /* 用户设备的最小高度为680px或为纵向模式的屏幕设备 */ @media (min-height: 680px), screen and (orientation: portrait) {} 常见需求 自定义属性 之前我们通常是在预处理器里才可以使用变量,而现在 CSS 里也支持了变量的用法。通过自定义属性就可以在想要使用的地方引用它。 自定义属性也和普通属性一样具有级联性,申明在 :root 下的时候,在全文档范围内可用,而如果是在某个元素下申明自定义属性,则只能在它及它的子元素下才可以使用。 自定义属性必须通过 --x 的格式申明,比如:–theme-color: red; 使用自定义属性的时候,需要用 var 函数。比如: <!-- 定义自定义属性 --> :root { --theme-color: red; } <!-- 使用变量 --> h1 { color: var(--theme-color); } 上图这个是使用 CSS 自定义属性配合 JS 实现的动态调整元素的 box-shadow,具体可以看这个 codepen demo。 1px 边框解决方案 Retina 显示屏比普通的屏幕有着更高的分辨率,所以在移动端的 1px 边框就会看起来比较粗,为了美观通常需要把这个线条细化处理。这里有篇文章列举了 7 中方案可以参考一下:7种方法解决移动端Retina屏幕1px边框问题[15] 而这里附上最后一种通过伪类和 transform 实现的相对完美的解决方案: 只设置单条底部边框: .scale-1px-bottom { position: relative; border:none; } .scale-1px-bottom::after { content: ''; position: absolute; left: 0; bottom: 0; background: #000; width: 100%; height: 1px; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; } 同时设置 4 条边框: .scale-1px { position: relative; margin-bottom: 20px; border:none; } .scale-1px::after { content: ''; position: absolute; top: 0; left: 0; border: 1px solid #000; -webkit-box-sizing: border-box; box-sizing: border-box; width: 200%; height: 200%; -webkit-transform: scale(0.5); transform: scale(0.5); -webkit-transform-origin: left top; transform-origin: left top; } 清除浮动 什么是浮动:浮动元素会脱离文档流并向左/向右浮动,直到碰到父元素或者另一个浮动元素。 为什么要清楚浮动,它造成了什么问题? 因为浮动元素会脱离正常的文档流,并不会占据文档流的位置,所以如果一个父元素下面都是浮动元素,那么这个父元素就无法被浮动元素所撑开,这样一来父元素就丢失了高度,这就是所谓的浮动造成的父元素高度坍塌问题。 父元素高度一旦坍塌将对后面的元素布局造成影响,为了解决这个问题,所以需要清除浮动,让父元素恢复高度,那该如何做呢? 这里介绍两种方法:通过 BFC 来清除、通过 clear 来清除。 BFC 清除浮动 前面介绍 BFC 的时候提到过,计算 BFC 高度的时候浮动子元素的高度也将计算在内,利用这条规则就可以清楚浮动。 假设一个父元素 parent 内部只有 2 个子元素 child,且它们都是左浮动的,这个时候 parent 如果没有设置高度的话,因为浮动造成了高度坍塌,所以 parent 的高度会是 0,此时只要给 parent 创造一个 BFC,那它的高度就能恢复了。 而产生 BFC 的方式很多,我们可以给父元素设置overflow: auto 来简单的实现 BFC 清除浮动,但是为了兼容 IE 最好用 overflow: hidden。 .parent { overflow: hidden; } 通过 overflow: hidden 来清除浮动并不完美,当元素有阴影或存在下拉菜单的时候会被截断,所以该方法使用比较局限。 通过 clear 清除浮动 我先把结论贴出来: .clearfix { zoom: 1; } .clearfix::after { content: ""; display: block; clear: both; } 这种写法的核心原理就是通过 ::after 伪元素为在父元素的最后一个子元素后面生成一个内容为空的块级元素,然后通过 clear 将这个伪元素移动到所有它之前的浮动元素的后面,画个图来理解一下。 可以结合这个 codepen demo 一起理解上图的 clear 清楚浮动原理。 上面这个 demo 或者图里为了展示需要所以给伪元素的内容设置为了 ::after,实际使用的时候需要设置为空字符串,让它的高度为 0,从而父元素的高度都是由实际的子元素撑开。 该方式基本上是现在人人都在用的清除浮动的方案,非常通用。 参考:CSS中的浮动和清除浮动,梳理一下[16] 消除浏览器默认样式 针对同一个类型的 HTML 标签,不同的浏览器往往有不同的表现,所以在网站制作的时候,开发者通常都是需要将这些浏览器的默认样式清除,让网页在不同的浏览器上能够保持一致。 针对清除浏览器默认样式这件事,在很早之前 CSS 大师 Eric A. Meyer 就干过。它就是写一堆通用的样式用来重置浏览器默认样式,这些样式通常会放到一个命名为 reset.css 文件中。比如大师的 reset.css[17] 是这么写的: html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } 他的这份 reset.css 据说是被使用最广泛的重设样式的方案了。 除了 reset.css 外,后来又出现了 Normalize.css[18] 。关于 Normalize.css, 其作者 necolas 专门写了一篇文章介绍了它,并谈到了它和 reset.css 的区别。这个是他写那篇文章的翻译版:让我们谈一谈 Normalize.css[19]。 文章介绍到:Normalize.css 只是一个很小的CSS文件,但它在默认的 HTML 元素样式上提供了跨浏览器的高度一致性。相比于传统的 CSS reset,Normalize.css 是一种现代的、为 HTML5 准备的优质替代方案,现在已经有很多知名的框架和网站在使用它了。 Normalize.css 的具体样式可以看这里 Normalize.css 区别于 reset.css,Normalize.css 有如下特点: reset.css 几乎为所有标签都设置了默认样式,而 Normalize.css 则是有选择性的保护了部分有价值的默认值; 修复了很多浏览器的 bug,而这是 reset.css 没做到的; 不会让你的调试工具变的杂乱,相反 reset.css 由于设置了很多默认值,所以在浏览器调试工具中往往会看到一大堆的继承样式,显得很杂乱; Normalize.css 是模块化的,所以可以选择性的去掉永远不会用到的部分,比如表单的一般化; Normalize.css 有详细的说明文档; 长文本处理 默认:字符太长溢出了容器 字符超出部分换行 字符超出位置使用连字符 单行文本超出省略 多行文本超出省略 查看以上这些方案的示例: codepen demo 有意思的是刚好前两天看到 chokcoco 针对文本溢出也写了一篇文章,主要突出的是对整块的文本溢出处理。啥叫整块文本?比如,下面这种技术标签就是属于整块文本: 另外他还对 iOS/Safari 做了兼容处理,感兴趣的可以去阅读下:CSS 整块文本溢出省略特性探究[20]。 水平垂直居中 让元素在父元素中呈现出水平垂直居中的形态,无非就 2 种情况: 单行的文本、inline 或者 inline-block 元素; 固定宽高的块级盒子; 不固定宽高的块级盒子; 以下列到的所有水平垂直居中方案这里写了个 codepen demo,配合示例阅读效果更佳。 单行的文本、inline 或 inline-block 元素 水平居中 此类元素需要水平居中,则父级元素必须是块级元素(block level),且父级元素上需要这样设置样式: .parent { text-align: center; } 垂直居中 方法一:通过设置上下内间距一致达到垂直居中的效果: .single-line { padding-top: 10px; padding-bottom: 10px; } 方法二:通过设置 height 和 line-height 一致达到垂直居中: .single-line { height: 100px; line-height: 100px; } 固定宽高的块级盒子 方法一:absolute + 负 margin 方法二:absolute + margin auto 方法三:absolute + calc 不固定宽高的块级盒子 这里列了 6 种方法,参考了颜海镜 写的文章 ,其中的两种 line-height 和 writing-mode 方案看后让我惊呼:还有这种操作?学到了学到了。 方法一:absolute + transform 方法二:line-height + vertical-align 方法三:writing-mode 方法四:table-cell 方法五:flex 方法六:grid 常用布局 两栏布局(边栏定宽主栏自适应) 针对以下这些方案写了几个示例: codepen demo 方法一:float + overflow(BFC 原理) 方法二:float + margin 方法三:flex 方法四:grid 三栏布局(两侧栏定宽主栏自适应) 针对以下这些方案写了几个示例: codepen demo 方法一:圣杯布局 方法二:双飞翼布局 方法三:float + overflow(BFC 原理) 方法四:flex 方法五:grid 多列等高布局 结合示例阅读更佳:codepen demo 方法一:padding + 负margin 方法二:设置父级背景图片 三行布局(头尾定高主栏自适应) 列了 4 种方法,都是基于如下的 HTML 和 CSS 的,结合示例阅读效果更佳:codepen demo <div class="layout"> <header></header> <main> <div class="inner"></div> </main> <footer></footer> </div> html, body, .layout { height: 100%; } body { margin: 0; } header, footer { height: 50px; } main { overflow-y: auto; } 方法一:calc 方法二:absolute 方法三:flex 方法四:grid 结了个尾 这是我断断续续写了 2 周完成的文章,算是自己对 CSS 的一个总结,虽然写得很长,但不足以覆盖所有 CSS 的知识,比如动画和一些 CSS3 的新特性就完全没涉及,因为这要写下来估计得有大几万字(其实就是懒 😝 )。 码字作图不易,如果喜欢或者对你有丝毫帮助的话,帮忙点个👍 哈,点赞就是我的动力。同时也希望自己能坚持认真的写下去,因为在总结提升自己的同时如果也能帮助更多的前端er,那将会让我感觉很开心。 参考资料 [1] @charset: [2] Byte order mark: [3] @import: [4] @supports: [5] MDN CSS Selectors: [6] Visual formatting model: [7] CSS 原理 - 你所不知道的 display: [8] 格式化上下文: [9] CSS 原理 - Formatting Context: [10] Inline formatting contexts: [11] 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index: [12] CSS 颜色草案: [13] 完整的色彩关键字列表: [14] 众多的媒体特性: [15] 7种方法解决移动端Retina屏幕1px边框问题: [16] CSS中的浮动和清除浮动,梳理一下: [17] reset.css: [18] Normalize.css: [19] 让我们谈一谈 Normalize.css: [20] CSS 整块文本溢出省略特性探究: 编辑整理From https://mp.weixin.qq.com/s/UtYENocSsl0R10h8fww7Iw

2021/9/15
articleCard.readMore

Vim IDE Docker 以及中文指南

Docker Vim IDE 由博主定制,加入中文环境配置,支持CJK。并升级到最新版本! Vim Docker docker pull bloodstar/vim alias edit='docker run -ti --rm -v $(pwd):/home/developer/workspace bloodstar/vim' edit some.file alias edit_update="docker pull bloodstar/vim:latest" Vim IDE Docker What’s inside: Alpine Linux Vim + a ton of awesome plugins see bloodstar/vim:latest Good support of Golang development with bloodstar/go-tools container tmux powerline Mosh OpenSSH, Bash, OMF, Python, etc. how to start the daemon(and all containers) docker create -v '/usr/lib/go' --name go-tools \ 'bloodstar/go-tools' '/bin/true' docker run -v $('pwd'):/home/developer/workspace \ --volumes-from go-tools \ -v ~/.ssh/pub_rsa:/etc/ssh_keys:ro \ -v /etc/localtime:/etc/localtime:ro \ -d -p 80:80 -p 8080:8080 -p 62222:62222 -p 60001:60001/udp \ --name drop-in bloodstar/drop-in -v /etc/localtime:/etc/localtime:ro - makes tmux display local time how to connect: mosh --ssh="ssh -p 62222" -- developer@$<ip> tmux -u or without host identity check: mosh --ssh="ssh -o StrictHostKeyChecking=no -p 62222" -- developer@$<ip> tmux -u Useful Bash scripts Connect #!/bin/bash ip=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' drop-in) mosh --ssh="ssh -p 62222" -- developer@$ip tmux -u start the daemon(and all containers) #!/bin/bash dtc_id=$(docker ps -a -q --filter 'name=vim-go-tools') if [[ -z "${dtc_id}" ]]; then echo 'vim-go-tools container not found. Creating...' docker create -v '/usr/lib/go' --name 'vim-go-tools' \ 'bloodstar/go-tools' '/bin/true' echo 'Done!' fi echo 'starting daemon...' docker run -v $('pwd'):/home/developer/workspace \ --volumes-from vim-go-tools \ -v ~/.ssh/pub_rsa:/etc/ssh_keys:ro \ -v /etc/localtime:/etc/localtime:ro \ -e "GEMAIL=<github email>" \ -e "GNAME=<github name>" \ -d -p 80:80 -p 8080:8080 -p 62222:62222 -p 60001:60001/udp \ --name drop-in bloodstar/drop-in echo 'Done!' Vim 中文快查表 <= 戳这里 Tips: 在网页上端导航栏,[快查] => [更多快查表],有更多快查表! Vim Vim简明教程 1. 键位图 vi-vim-cheat-sheet-sch vi-vim-cheat-sheet-sch vim分为三种主要模式,分别是命令模式(Command mode),输入模式(Insert mode)和底线命令模式(Last line mode) 2. 命令模式 用户刚刚启动 vi/vim,便进入了命令模式。 2.1. 光标移动 按键 动作 h 或 向左箭头键(←) 光标向 左 移动一个字符 j 或 向下箭头键(↓) 或<Enter> 光标向 下 移动一个字符 k 或 向上箭头键(↑) 光标向 上 移动一个字符 l 或 向右箭头键(→) 或 <space> 光标向 右 移动一个字符 w/W 移动到下一个单词,大写把标点符号当做单词的一部分 e/E 移动到词尾,大写把标点符号当做单词的一部分 b/B 移动到上一个单词,大写把标点符号当做单词的一部分 + 光标移动到非空格符的下一行 - 光标移动到非空格符的上一行 G 移动到这个档案的最后一行 gg 移动到这个档案的第一行,相当于 1G [Ctrl] + f 或 [Page Down] 屏幕『向下』移动一页 [Ctrl] + b 或 [Page Up] 屏幕『向上』移动一页 [Ctrl] + d 屏幕『向下』移动半页 [Ctrl] + u 屏幕『向上』移动半页 0 或功能键[Home] 数字『 0 』,移动到这一行的最前面字符处 $ 或功能键[End] 移动到这一行的最后面字符处 H 光标移动到这个屏幕的最上方那一行的第一个字符 M 光标移动到这个屏幕的中央那一行的第一个字符 L 光标移动到这个屏幕的最下方那一行的第一个字符 2.2. 复制、粘贴 按键 动作 y + 光标移动符 复制光标所在到移动范围的内容,例如: yj:复制游标所在的那一整行 yG:复制光标所在到最后一行的内容 yw:复制光标所在到下一个单词的内容 yy 复制游标所在的那一行 p 在光标后粘贴,如果是单词级的粘贴,就会在光标后一位粘贴,如果是行级的粘贴,就会在光标下一行粘贴,下面的 P 粘贴时同理。 P 在光标前粘贴 2.3. 文本修改 按键 动作 x 向 后 删除一个字符 ,相当于[del] X 向 前 删除一个字符,相当于 [backspace] d + 光标移动符 删除光标所在到移动范围的内容,例如: dj:删除游标所在的那一整行 dG:删除光标所在到最后一行的内容 dw:删除光标所在到下一个单词的内容 dd 删除游标所在的那一整行 J 将光标所在行与下一行的数据结合成同一行 r + 「字符」 替换光标处的单词为该字符 R 进入replace mode,直到接收到[Esc]按键信号退出该模式 2.4. 重复动作 按键 动作 u Undo,复原前一个动作。 [Ctrl] + r 重做上一个动作。 . 重复前一个动作。 n 向下重复前一个搜寻的动作。 N 向上重复前一个搜寻的动作。 「n」+ 命令符 「n」是数字,一般可以理解为重复n次该动作,例如: 10j 表示向下移动10行 2.5. 可视模式(vim only) 命令模式下按ctrl + v进入可视模式,这是一个比较特别地模式。 这个模式可以移动光标,选择一大片区域,然后可以对这片区域进行操作。 3. 输入模式 在命令模式下按下i就进入了输入模式。 在输入模式中,除了ESC键退出输入模式,其他按键和平常编辑模式是一样的。 3.1. 进入输入模式 按键 动作 i Insert,从当前光标前开始输入 I Insert,在目前所在行的第一个非空格符处开始输入 a Append,从当前光标后开始输入 A Append,从光标所在行的最后一个字符处开始输入 o 在当前光标所在的下一行处输入新的一行 O 在当前光标所在处的上一行输入新的一行 c + 光标移动符 可以理解先按d + 光标移动符,然后再按a C 可以理解先按dd,然后再按a 4. 底线命令模式 在命令模式下按下:、/、?键位就进入了底线命令模式。 按ESC键退出底线命令模式。 4.1. 查找替换 语句 动作 /word 向光标之下寻找一个名称为 word 的字符串。例如要在档案内搜寻 vbird 这个字符串,就输入 /vbird 即可! (常用) ?word 向上搜索word字符串 :n1,n2 s/word1/word2/g n1 与 n2 为数字。在第 n1 与 n2 行之间将 word1 替换为 word2 。特别地,最后一行为$, :n1,n2 s#word1#word2#g 效果同上,这个主要用于替换/符号,例如每一行行首添加//,可以这样操作: :1,$ s#^#//#g 4.2. 文件操作 按键 动作 :w [filename] 将编辑的数据写入到filename文件中,如果不加参数,默认是当前文件 :w! 若文件属性为『只读』时,强制写入该档案,前提是得有文件的写权限。 :q 或 ZQ 退出vim,如果未保存的内容,该指令执行失败 :q! 若曾修改过档案,又不想储存,使用 ! 为强制离开不储存档案。 :wq 或 ZZ 储存后离开 :wq! 强制储存后离开 :r [filename] 在编辑的数据中,读入另一个档案的数据。亦即将 『filename』 这个档案内容加到游标所在行后面 :n1,n2 w [filename] 将 n1 到 n2 的内容储存成 filename 这个档案。 :! command 不退出vim执行command指令,多用于调试脚本。 4.3. 其他功能 按键 动作 :set nu 显示行号 :set nonu 取消行号 :sv 当前界面打开文件,并呈纵向分布 :vs 当前界面打开文件,并呈横向分布 :set fileformat=unix 由Windows上传到linux的脚本文件,直接执行会报错,需要将其由dos文件格式改unix格式 5. 扩展的vim功能 当然,如果仅仅只有原生态的功能还不能让vim成为一个好用的ide,扩展功能才是vim的灵魂所在。 参考 菜鸟驿站的vim教程 系列教程 全部文章RSS订阅 tools系列 Tools 分类 RSS 订阅 Doxygen入门教程 Vim IDE Docker 以及中文指南 第一次使用VS CODE时你应该指导的一切配置 winrar去广告和破解 RSS的使用与Tiny Tiny RSS Selfhost自建 如何创建属于自己的私人资料库与私人搜索引擎 信息时代必备的搜索引擎高级技巧使用指南 如何安装OfficeLTSC2021并KMS破解激活教程 windows系统空间清理与速度优化 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/9/15
articleCard.readMore

深度学习之视频人脸识别系列

系列1 简介 出品 | 磐创AI技术团队 【磐创AI导读】本文是深度学习之视频人脸识别系列的第一篇文章,介绍了人脸识别领域的一些基本概念,分析了深度学习在人脸识别的基本流程,并总结了近年来科研领域的研究进展,最后分析了静态数据与视频动态数据在人脸识别技术上的差异。欢迎大家点击上方篮子关注我们的公众号:磐创AI。 一、基本概念 1. 人脸识别(face identification) 人脸识别是1对n的比对,给定一张人脸图片,如何在n张人脸图片中找到同一张人脸图片,相对于一个分类问题,将一张人脸划分到n张人脸中的一张。类似于管理人员进行的人脸识别门禁系统。 2.人脸验证(face verification) 人脸验证的1对1的比对,给定两张人脸图片,判断这两张人脸是否为同一人,类似于手机的人脸解锁系统,事先在手机在录入自己的脸部信息,然后在开锁时比对摄像头捕捉到的人脸是否与手机上录入的人脸为同一个人。 3.人脸检测(face detection) 人脸检测是在一张图片中把人脸检测出来,即在图片上把人脸用矩形框出来,并得到矩形的坐标,如下图所示。 4. 人脸关键点检测 根据输入的人脸图像,识别出面部关键特征点,如眼睛、鼻尖、嘴角点、眉毛以及人脸各部件轮廓点的坐标,如下图所示。 5. 人脸矫正(人脸对齐) 通过人脸关键点检测得到人脸的关键点坐标,然后根据人脸的关键点坐标调整人脸的角度,使人脸对齐,由于输入图像的尺寸是大小不一的,人脸区域大小也不相同,角度不一样,所以要通过坐标变换,对人脸图像进行归一化操作,如下图所示。 二、基于深度学习的人脸识别算法基本流程 随着神经网络的迅速发展和其对图像数据的强大的特征提取,深度学习运用于人脸识别也成为热点研究方向;2014年的开山之作DeepFace,第一个真正将大数据和深度学习结合应用于人脸识别与验证,确立人脸识别的常规流程:图片->人脸与关键点检测->人脸对齐->人脸表征(representation)->分类。首先将图片中的人脸检测处理并通过关键点进行对齐,如何输入到神经网络,得到特征向量,通过分类训练过程,该向量即为人脸的特征向量。要求出两张人脸的相似度即计算两个特征的向量度量之差,方法包括:SVM、SiameseNetwork、JointBayesian、L1距离、L2距离、cos距离等。 三、科研领域近期进展 科研领域近期进展主要集中于loss函数的研究,包括DeepId2(Contrastive Loss)、FaceNet(Triplet loss)、L-Softmax、SphereFace(A-Softmax)、Center Loss、L2-Softmax、NormFace、CosFace(AM-Softmax)、ArcFace(AA-Softmax)等。 四、基于视频人脸识别和图片人脸识别的区别 (_该小结部分参考于博客园 - 米罗西http://www.cnblogs.com/zhehan54/p/6727631.html_) 相对于图片数据,目前视频人脸识别有很多挑战,包括:(1)视频数据一般为户外,视频图像质量比较差;(2)人脸图像比较小且模糊;(3)视频人脸识别对实时性要求更高。 但是视频数据也有一些优越性,视频数据同时具有空间信息和时间信息,在时间和空间的联合空间中描述人脸和识别人脸会具有一定提升空间。在视频数据中人脸跟踪是一个提高识别的方法,首先检测出人脸,然后跟踪人脸特征随时间的变化。当捕捉到一帧比较好的图像时,再使用图片人脸识别算法进行识别。这类方法中跟踪和识别是单独进行的,时间信息只在跟踪阶段用到。 【总结】:本期文章主要介绍了基于深度学习的人脸识别算法的一些基本入门知识,下一期我给大家介绍人脸识别中获取神经网络输入的算法,即关于人脸检测、人脸关键点检测与人脸对齐的一些重要算法和相关论文解析。 系列2 人脸检测与对齐 一、人脸检测与关键点检测 1. 问题描述: 人脸检测解决的问题为给定一张图片,输出图片中人脸的位置,即使用方框框住人脸,输出方框的左上角坐标和右下角坐标或者左上角坐标和长宽。算法难点包括:人脸大小差异、人脸遮挡、图片模糊、角度与姿态差异、表情差异等。而关键检测则是输出人脸关键点的坐标,如左眼(x1,y1)、右眼(x2,y2)、鼻子(x3,y3)、嘴巴左上角(x4,y4)、嘴巴右上角(x5,y5)等。 2. 深度学习相关算法: (1)Cascade CNN Cascade CNN源于发表于2015年CVPR上的一篇论文A Convolutional Neural Network Cascade for Face Detection【2】,作者提出了一种级连的CNN网络结构用于人脸检测。算法主体框架是基于V-J的瀑布流思想【1】,是传统技术和深度网络相结合的一个代表,Cascade CNN包含了多个分类器,这些分类器使用级联结构进行组织,与V-J不同的地方在于Cascade CNN采用卷积网络作为每一级的分类器。整个网络的处理流程如下图所示: 整个处理流程里包含了六个网络:12-net、12-calibration-net、24-net、24-calibration-net、48-net、48-calibration-net,其中三个二分类网络用于分类其是否为人脸,另外三个calibration网络用于矫正人脸框边界。其中第二个网络之后、第四个网络之后、第五个网络之后使用NMS算法过滤掉冗余的框。 12-net,24-net和48-net的网络结构如下图所示: 13-12-calibration-net,24-calibration-net,48-calibration-net的结构如下图所示: 该算法结合了V-J框架构造了级连的CNN网络结构并设计边界矫正网络用来专门矫正人脸框边界,在AFW数据集上准确率达到97.97%。 (2)Faceness-Net Faceness-Net源于论文A convolutional neural network cascade for face detection【3】,该算法基于DCNN网络【5】的人脸局部特征分类器,算法首先进行人脸局部特征的检测,使用多个基于DCNN网络的facial parts分类器对人脸进行评估,然后根据每个部件的得分进行规则分析得到Proposal的人脸区域,然后从局部到整体得到人脸候选区域,再对人脸候选区域进行人脸识别和矩形框坐标回归,该过程分为两个步骤。 第一个步骤:每个人脸局部特征使用attribute-aware网络检测并生成人脸局部图,其中一共五个特征属性: 头发、眼睛、鼻子、嘴巴、胡子。然后通过人脸局部图根据评分构建人脸候选区域,具体如下图所示: 第二个步骤:训练一个多任务的卷积网络来完成人脸二分类和矩形框坐标回归,进一步提升其效果,具体如下图所示: Faceness从脸部特征的角度来解决人脸检测中的遮挡和姿态角度问题,其整体性能在当时是非常好的,在AFW数据集上准确率可以达到98.05%。 (3)MTCNN MTCNN源于论文Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks【6】,是基于多任务级联卷积神经网络来解决人脸检测和对齐问题,同时输出图片的人脸矩阵框和关键点坐标(左眼、右眼、鼻子、嘴巴左上角、嘴巴右上角)。MTCNN为三阶的级联卷积神经网络,整体框架如下图所示: 输入阶段:为应对目标多尺度问题,将原始图像resize到不同尺寸,构建图像金字塔,作为三阶级联架构的输入,这样处理可以更好地检测大小不一的人脸。 第一阶段:通过一个全部由卷积层组成的CNN,取名P-Net,获取候选人脸框、关键点坐标和人脸分类(是人脸或不是),之后采用NMS过滤掉高重叠率的候选窗口。如下图所示: 第二阶段:第一阶段输出的候选人脸框作为更为复杂的R-Net网络的输入,R-Net进一步筛除大量错误的候选人脸框,同样也通过NMS过滤掉高重叠率的候选窗口。如下图所示: 第三阶段:与第二阶段类似,最终网络输出人脸框坐标、关键点坐标和人脸分类(是人脸或不是)。如下图所示: MTCNN通过三级的级联卷积神经网络对任务进行从粗到细的处理,还提出在线困难样本生成策略(online hard sample mining )可以进一步提升性能。兼并了速度与准确率,速度在GPU上可以达到99FPS,在 FDDB数据集上可以达到95.04准确率,具体如下图所示: 二、人脸对齐(部分参考于GraceDD的博客文章) 人脸对齐通过人脸关键点检测得到人脸的关键点坐标,然后根据人脸的关键点坐标调整人脸的角度,使人脸对齐,由于输入图像的尺寸是大小不一的,人脸区域大小也不相同,角度不一样,所以要通过坐标变换,对人脸图像进行归一化操作。人脸关键点检测有很多算法可以使用包括:ASM、AAM、DCNN 、TCDCN 、MTCNN 、TCNN、TCNN等,这里就不详细介绍,主要说一下得到人脸关键点之后如何进行人脸对齐,是所有人脸达到归一化效果,该过程如下图所示: 该过程涉及到图像的仿射变换,简单来说,“仿射变换”就是:“线性变换”+“平移”,即坐标的变换。假如我们希望人脸图片归一化为尺寸大小600600,左眼位置在(180,200),右眼位置在(420,200)。 这样人脸中心在图像高度的1/3位置,并且两个眼睛保持水平,所以我们选择左眼角位置为( 0.3width, height / 3 ),右眼角位置为(0.7*width , height / 3) 。 利用这两个点计算图像的变换矩阵(similarity transform),该矩阵是一个2*3的矩阵,如下: 如果我们想对一个矩形进行变换,其中x、y方向的缩放因为分别为sx,sy,同时旋转一个角度 ,然后再在x方向平移tx, 在y方向平移ty 利用opencv的estimateRigidTransform方法,可以获得这样的变换矩阵,但遗憾的是,estimateRigidTransform至少需要三个点,所以我们需要构选第三个点,构造方法是用第三个点与已有的两个点构成等边三角形,这样第三个点的坐标为: 代码如下: 经过上一步的处理之后,所有的图像都变成一样大小,并且又三个关键点的位置是保持一致的,但因为除了三个点对齐了之外,其他点并没有对齐。所以根据得到的变换矩阵对剩下所有的点进行仿射变换,opencv代码如下所示: img为输入图像; warped为变换后图像,类型与src一致; M为变换矩阵,需要通过其它函数获得,当然也可以手动输入; Image_size为输出图像的大小; 三、 总结 本期文章主要介绍了人脸检测与对齐的相关算法,下一期我给大家介绍一下人脸表征的相关算法,即通过深度学习提取人脸特征,通过比较人脸特征进行人脸识别与验证。 参考文献: 【1】 S.Z.Li, L.Zhu, Z.Q.Zhang, A.Blake, H.J.Zhang, H.Y.Shum. Statistical learning of multi-view face detection. In: Proceedings of the 7-th European Conference on Computer Vision. Copenhagen, Denmark: Springer, 2002.67-81. 【2】Li H, Lin Z, Shen X, et al. A convolutional neural network cascade for face detection[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015: 5325-5334. 【3】Yang S, Luo P, Loy C C, et al. Faceness-Net: Face detection through deep facial part responses[J]. IEEE transactions on pattern analysis and machine intelligence, 2017. 【4】Yang S, Luo P, Loy C C, et al. From facial parts responses to face detection: A deep learning approach[C]//Proceedings of the IEEE International Conference on Computer Vision. 2015: 3676-3684. 【5】Sun Y, Wang X, Tang X. Deep convolutional network cascade for facial point detection[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2013: 3476-3483. 【6】Zhang K, Zhang Z, Li Z, et al. Joint face detection and alignment using multitask cascaded convolutional networks[J]. IEEE Signal Processing Letters, 2016, 23(10): 1499-1503. 系列3:人脸表征 一、人脸表征 把人脸图像通过神经网络,得到一个特定维数的特征向量,该向量可以很好地表征人脸数据,使得不同人脸的两个特征向量距离尽可能大,同一张人脸的两个特征向量尽可能小,这样就可以通过特征向量来进行人脸识别。 二、论文综述 1. DeepFace: 2014年论文DeepFace: Closing the Gap toHuman-Level Performance in Face Verification提出了DeepFace算法,第一个真正将大数据和深度学习神经网络结合应用于人脸识别与验证。在该人脸识别模型中分为四个阶段:人脸检测 => 人脸对齐 => 人脸表征 => 人脸分类,在LFW数据集中可以达到97.00%的准确率。 (1)人脸检测与对齐:该模型使用3D模型来将人脸对齐,该方法过于繁琐,在实际应用中很少使用,经过3D对齐以后,形成的图像都是152×152的图像,具体步骤如下图。 分为如下几步: a. 人脸检测,使用6个基点 b. 二维剪切,将人脸部分裁剪出来 c. 67个基点,然后Delaunay三角化,在轮廓处添加三角形来避免不连续 d. 将三角化后的人脸转换成3D形状 e. 三角化后的人脸变为有深度的3D三角网 f. 将三角网做偏转,使人脸的正面朝前。 g. 最后放正的人脸 h. 一个新角度的人脸(在论文中没有用到) (2)人脸表征:人脸表征使用了5个卷积层和1个最大池化层、1个全连接层,如下图所示。前三层的目的在于提取低层次的特征,为了网络保留更多图像信息只使用了一层池化层;后面三层都是使用参数不共享的卷积核,因为主要是因为人脸不同的区域的特征是不一样的,具有很大的区分性,比如鼻子和眼睛所表示的特征是不一样的,但是使用参数不共享的卷积核也增加了模型计算量以及需要更多的训练数据。最后输出的4096维向量进行L2归一化。 a. Conv:32个11×11×3的卷积核 b. max-pooling: 3×3, stride=2 c. Conv: 16个9×9的卷积核 d. Local-Conv: 16个9×9的卷积核,Local的意思是卷积核的参数不共享 e. Local-Conv: 16个7×7的卷积核,参数不共享 f. Local-Conv: 16个5×5的卷积核,参数不共享 g. Fully-connected: 4096维 h. Softmax: 4030维 (3)分类:论文介绍了两种方法进行分类,加权的卡方距离和使用Siamese网络结构,设f1和f2为特征向量,上一个步骤的输出,则有: ①加权卡方距离:计算公式如下,加权参数由线性SVM计算得到: ②Siamese网络:网络结构是成对进行训练,得到的特征表示再使用如下公式进行计算距离: 2. DeepID1: DeepID1 是2014年Deep LearningFace Representation from Predicting 10,000 Classes一文提出的,是DeepID三部曲的第一篇。DeepID1 使用softmax多分类训练,主要思想第一个是数据集的增大,包括训练集使用celebface,包含87628张图片,5436个人脸,增大了训练集;使用多尺寸输入,通过5个landmarks将每张人脸划分成10regions,每张图片提取60patches=10regions3scales2(RGB orgray),第二个是网络结构,DeepID提取的人脸特征就是一个由连接第三层与第四层组成的全连接层特征,如下图所示,每个patches经过这个cnn网络,第四层的特征更加全局化(global),第三层的特征更加细节,因此DeepID连接了两者,以求同时包含全局,细节信息。 60个patches使用60个CNN,每个CNN提取2*160=320维特征(与水平翻转一起输入),总网络模型如下图所示,最后分别使用联合贝叶斯算法与神经网络进行分类,并比较结果。 模型最终以CelebFaces+中202,599图像作为训练集, patch数提升为100(10r10s2) ,特征数提升为1001602=32000 然后使用PCA降为150维 ,使用联合贝叶斯算法进行验证, 最终在LFW上达到97.20%的验证准确率。 3. DeepID2: DeepID2是Deep Learning Face Representationby Joint Identification-Verification一文提出的,对DeepID1进行了进一步的改进,提出了contrastive loss,在分类任务,我们需要的是减少类内差距(同一人脸),增加类间差距(不同人脸),softmax loss分类的监督信号可以增大类间差距,但是却对类内差距影响不大,所以DeepID2加入了另一个loss,contrastive loss,从而增加验证的监督信号,就可以减少类内差距。 网络结构类似DeepID1,不同之处在于使用了两种不同的损失函数,网络结构如下图所示。 损失函数: ①分类信号,Softmax loss。 ②验证信号,contrastiveloss,使用l2范数距离表示,m为阈值不参与训练,括号内的θve={m},该损失函数可以让类间的距离给定一个限制margin,即m大小的距离。 两loss的组合方式: 首先使用2个输入,计算Softmax loss和contrastive loss,总损失为二者通过λ加权求和,通过总损失来执行梯度下降更新卷积参数,通过Softmax loss来更新softmax层的参数。 整个模型使用celebrate+数据集训练,每张图片使用了21 facial landmarks,分成200patches(20regions5scales2RGB&Gray),水平翻转后变为400patches,使用了200个卷积神经网络,提取400(2002)个Deepid2特征,使用贪婪算法降为25个Deepid2特征,使用PCA将25160Deepid2特征降为180维,最后使用联合贝叶斯算法进行验证,最终在LFW上得到的最终准确率是98.97%,使用7组25个Deepid2特征,SVM融合可得到准确率为99.15% 。DeepID2在2014 年是人脸领域非常有影响力的工作,也掀起了在人脸领域引进 MetricLearning 的浪潮。 4. DeepID2+: DeepID2+源于论文Deeply learned facerepresentations are sparse, selective, and robust,DeepID2+是对DeepID2的改进。①卷积层在原来基础上再增加128维,第四层全连接层从160增加到512,训练数据增加了CelebFaces+ dataset,WDRef等,有12000个人脸的大约290,000张图片; ②每个卷积层的后面都加了一个512为的全连接层,并添加contrastive loss监督信号,而不仅在第四层全连接层上有 。网络结构如下图所示。 最终在LFW数据集上准确率为99.47%。 5. DeepID3: DeepID3源于2015年的Deepid3:Face recognition with very deep neural networks论文,该论文探究了复杂神经网络对人脸识别的作用。论文研究VGG与GoogleNet用于人脸识别的效果,论文在VGG和GooLeNet的基础上进行构建合适的结构,使得方便人脸识别。结果发现DeepID3的结果和DeepID2+相当,可能是由于数据集的瓶颈,需要更大的数据才能有更好的提升,两个网络结构如下图所示。 网络输出使用PCA降维到300维的向量,使用联合贝叶斯算法进行验证,最终在LFW上得到的最终准确率是99.53%。 6. FaceNet: FaceNet由论文Facenet: A unified embedding forface recognition and clustering提出,这篇 2015 年来自 Google 的 论文同样具有非常大的影响力,不仅仅成功应用了 TripletLoss 在 benchmark 上取得state-of-art 的结果,更因为他们提出了一个绝大部分人脸问题的统一解决框架,即:识别、验证、搜索等问题都可以放到特征空间里做,需要专注解决的仅仅是如何将人脸更好的映射到特征空间。FaceNet在DeepID的基础上,将 ContrastiveLoss 改进为 Triplet Loss,去掉softmaxloss。FaceNet实验了ZFNet类型网络和Inception类型网络,最终Inception类型网络效果更好,网络结构如下图所示。 FaceNet没有使用PCA降维,而是在网络中直接训练输出128维的向量,用全连接层来完成降维,最后的128维的向量经过Triplet Loss。 Triplet Loss输入不再是 Image Pair,而是三张图片(Triplet),分别为 Anchor Face(xa),Negative Face(xn)和 Positive Face(xp)。Anchor 与 Positive Face 为同一人,与 Negative Face 为不同人,在特征空间里 Anchor 与 Positive 的距离要小于 Anchor 与 Negative 的距离,且相差超过一个 Margin Alpha。 loss的目标为: 总loss公式为: Contrastive Loss与Triplet Loss的比较, Contrastive Loss目标是减少类内差距(两个蓝点),增加类间差距(蓝点与红点);Triplet Loss则是输入三张图片,Anchor 与 Positive 的距离要小于 Anchor 与 Negative 的距离,且相差超过一个 Margin Alpha,即Triplet Loss同时约束了两个距离。 最后FaceNet在LFW数据集上达到了99.63%的准确率。 基于 ContrastiveLoss 和 Triplet Loss 的 MetricLearning 符合人的认知规律,在实际应用中也取得了不错的效果,但同时也有很多问题,由于ContrastiveLoss 和 Triplet Loss 的训练样本都基于pair 或者 triplet 的,可能的样本数是 O(N2) 或者 O (N3) 的,所以模型需要很久的计算才能拟合并且训练集需要足够大。 三、总结 本期文章主要介绍人脸表征相关算法和论文综述,主要是2014年到2016年的研究成果, ContrastiveLoss 和 Triplet Loss在实际应用中也取得了很好的效果,但是也有很多问题,由于Contrastive Loss 和 Triplet Loss 的训练样本都基于 pair 或者 triplet 的,可能的样本数是 O (N2) 或者 O (N3) 的,所以模型需要很久的计算才能拟合并且训练集要足够大,所以在之后的人脸识别研究中,大部分在于loss函数的研究,这部分将会在下一期给大家介绍。 参考文献: 【1】 Taigman Y, Yang M, Ranzato M A, et al.Deepface: Closing the gap to human-level performance in faceverification[C]//Proceedings of the IEEE conference on computer vision andpattern recognition. 2014: 1701-1708. 【2】Sun Y, Wang X, Tang X. Deep learning facerepresentation from predicting 10,000 classes[C]//Proceedings of the IEEEconference on computer vision and pattern recognition. 2014: 1891-1898. 【3】Sun Y, Chen Y, Wang X, et al. Deeplearning face representation by joint identification-verification[C]//Advancesin neural information processing systems. 2014: 1988-1996. 【4】Sun Y, Liang D, Wang X, et al. Deepid3:Face recognition with very deep neural networks[J]. arXiv preprintarXiv:1502.00873, 2015. 【5】Simonyan K, Zisserman A. Very deepconvolutional networks for large-scale image recognition[J]. arXiv preprintarXiv:1409.1556, 2014. 【6】Szegedy C, Liu W, Jia Y, et al. Goingdeeper with convolutions[C]//Proceedings of the IEEE conference on computervision and pattern recognition. 2015: 1-9. 【7】Sun Y, Wang X, Tang X. Deeply learned facerepresentations are sparse, selective, and robust[C]//Proceedings of the IEEEconference on computer vision and pattern recognition. 2015: 2892-2900. 【8】Schroff F, Kalenichenko D, Philbin J.Facenet: A unified embedding for face recognition andclustering[C]//Proceedings of the IEEE conference on computer vision andpattern recognition. 2015: 815-823. 系列4:人脸表征-续 一、人脸表征 把人脸图像通过神经网络,得到一个特定维数的特征向量,该向量可以很好地表征人脸数据,使得不同人脸的两个特征向量距离尽可能大,同一张人脸的两个特征向量尽可能小,这样就可以通过特征向量来进行人脸识别。 二、论文综述 1. L-Softmax: Softmax Loss函数被广泛应用于深度学习,较为简单实用,但是它并不能够明确引导神经网络学习区分性较高的特征。L-Softmax能够有效地引导网络学习使得样本类内距离较小、类间距离较大的特征,L-Softmax不但能够调节类间距离的间隔(margin)大小,而且能够防止过拟合。 L-Softmax是对softmax loss的改进,softmax loss公式如下所示: 其中 fj 表示最终全连接层的类别输出向量 f的第 j个元素, N为训练样本的个数,则 fyi可以表示为 fyi=WTyi xi,其中 0≤θj≤π,最终的损失函数可得: softmax的目的是使得WT1x>WT2x,即 ∥W1∥∥x∥cos(θ1)>∥W2∥∥x∥cos(θ2),从而得到输入x(来自类别1)输出正确的分类结果。L-Softmax通过增加一个正整数变量m,从而产生一个决策余量,能够更加严格地约束上述不等式,即: 其中0≤θ1<π/m。如果W1和W2能够满足∥W1∥∥x∥cos(mθ1)>∥W2∥∥x∥cos(θ2),那么就必然满足∥W1∥∥x∥cos(θ1)>∥W2∥∥x∥cos(θ2),这样的约束对学习W1和W2的过程提出了更高的要求,在训练学习过程中,类间要比之前多了一个m的间隔,从而使得1类和2类有了更宽的分类决策边界。这种Margin Based Classification使得学习更加的困难,从而使类间距离增加了一个margin距离,L-Softmax loss的总公式如下: 当m越大时,分类的边界越大,学习难度当然就越高。 论文仅使用了WebFace数据集作为训练集和一个简单的卷积网络,就在LFW上达到了98.71%的正确率,证明了L-Softmax loss取得了比softmax loss更好的结果。 2. SphereFace : SphereFace在MegaFace数据集上识别率在2017年排名第一,提出A-Softmax Loss使人脸识别达到不错的效果。A-Softmax Loss基于softmax loss和L-Softmax loss,在二分类模型中,softmax loss为: 如果x为类别一,则希望p1>p2,则二分类的划分函数为: 权重归一化||w||为1,b为0,此时特征上的点映射到单位超球面上,则二分类的划分函数为: 然后使用与L-Softmax loss相同的原理,使 则A-Softmax Loss最终为: 因此A-Softmax Loss是样本类别之间产生了角度距离,让决策函数更加严格并且更加具有可区分性。当m增大,角度距离也会增加。 A-Softmax与L-Softmax的最大区别在于A-Softmax的权重归一化了,而L-Softmax则没有。A-Softmax权重的归一化导致特征上的点映射到单位超球面上,A-Softmax仅仅能从角度上划分类别,而L-Softmax是在角度与长度方向进行考量,两个方向如果划分不一就会收到干扰,导致精度下降。 SphereFace使用的模型如下图所示: 训练与测试过程如下图所示,在测试过程中使用余弦计算相似度: 最终SphereFace在训练集较小的情况下,LFW数据集上准确率为99.42%。Sphereface效果很好,但是它不优美。在测试阶段,Sphereface通过特征间的余弦值来衡量相似性,即以角度为相似性的度量,在训练阶段,其实Sphereface的损失函数并不是在直接优化特征与类中心的角度,而是优化特征与类中心的角度在乘上一个特征的长度,这就造成了训练跟测试之间目标不一致。 3. Normface : 在优化人脸识别任务时,softmax本身优化的是没有归一化的内积结果,但是最后在预测的时候使用的一般是cosine距离或者欧式距离,这会导致优化目标和最终的距离度量其实并不一致。 Normface的核心思想是既然最后在特征对比的时候使用归一化的cosine距离,那么在训练的过程中把特征也做归一化处理,做了归一化之后,softmax的优化就变成了直接优化cosine距离了,归一化过程如下,其中e是为了防止除0的较小正数: 相应的损失函数如下: 其中 W 是归一化的权重,f_i 是归一化的特征,参数 s 的引入是因为保证梯度大小的合理性,去掉bias是因为softmax之前的fc有bias的情况下会使得有些类别在角度上没有区分性但是通过bias可以区分,在这种情况下如果对feature做normalize,会使得中间的那个小类别的feature变成一个单位球形并与其他的feature重叠在一起,所以在feature normalize的时候是不能加bias的。 Normface使用了较小的模型使用多种loss训练,然后在LFW数据集上测试,证明了feature normalize的效果,结果如下: 4. CosFace : Normface用特征归一化解决了Sphereface训练和测试不一致的问题。但是却没有了margin的惩罚,腾讯AI Lab的CosFace或者AM-softmax是在Normface的基础上引入了margin,损失函数为: 其中特征与权值都做了归一化: 分类决策为: ,比之前增加了m的margin,m 是一个超参数,控制惩罚的力度,m 越大,惩罚越强。 CosFace使用mtcnn进行人脸检测与对齐,人脸表征训练模型使用基于residual units 64层卷积网络的Sphere Face,在5M的训练集上训练,在LFW数据集上测试,精度达到99.73%。 5. ArcFace : ArcFace源于论文Additive angular margin lossfor deep face recognition,也叫做InsightFace,论文基本介绍了近期较为流行的人脸识别模型,loss变化从softmax到AM-softmax,然后提出ArcFace,可以说起到了很好的综述作用,论文从三个方面探讨影响人脸识别模型精度的主要因素。 (1)数据:数据方面,论文探讨了各个数据集的数据质量和优缺点,并对MS-Celeb-1M,MegaFace FaceScrub做了清洗,清洗后的数据公开。 (2)网络:详细对比了不同的主流网络结构的性能,包括输入层尺寸大小、最后输出几层的不同结构、基本网络单元残差网络的不同结构、主干网络的不同模型。经过实验的证明,最后的网络结构:输入图片大小112x112;第一层convLayer 卷积核为33 stride 1时,网络输出77;主干网络使用ResNet100,并使用改进后的改进的残差网络结构,如下图;最后的几层输出层为最后一个卷积层后+BN-Dropout-FC-BN的结构。 (3)损失函数:与 AM-softmax相比,区别在于Arcface引入margin的方式不同,损失函数为: Arcface的m是在余弦里面,AM-softmax的在外面,ArcFace更为直观并且在超球面维度上有更清晰的解释。Arcface在VGG2和MS-Celeb-1M数据集上训练,在LFW数据集上精度达到99.83%。 三、总结 本期文章主要介绍人脸表征相关算法和论文综述,人脸检测、对齐、特征提取等这些操作都可以在静态数据中完成,下一期将给大家介绍在视频数据中进行人脸识别的另一个重要的算法,视频人脸跟踪的概念与方法。 参考文献: 【1】 Liu W, Wen Y, Yu Z, et al. Large-MarginSoftmax Loss for Convolutional Neural Networks[C]//ICML. 2016: 507-516.1708. 【2】Liu W, Wen Y, Yu Z, et al. Sphereface:Deep hypersphere embedding for face recognition[C]//The IEEE Conference onComputer Vision and Pattern Recognition (CVPR). 2017, 1: 1. 【3】Wang F, Xiang X, Cheng J, et al. Normface:l 2 hypersphere embedding for face verification[C]//Proceedings of the 2017 ACMon Multimedia Conference. ACM, 2017: 1041-1049. 【4】Wang F, Cheng J, Liu W, et al. Additivemargin softmax for face verification[J]. IEEE Signal Processing Letters, 2018,25(7): 926-930. 【5】Wang H, Wang Y, Zhou Z, et al. CosFace:Large margin cosine loss for deep face recognition[J]. arXiv preprintarXiv:1801.09414, 2018. 【6】Deng J, Guo J, Zafeiriou S. Arcface:Additive angular margin loss for deep face recognition[J]. arXiv preprintarXiv:1801.07698, 2018. 编辑整理 磐创AI技术团队 系列教程 全部文章RSS订阅 AI系列 AI 分类 RSS 订阅 深度学习之视频人脸识别系列 中国区注册ChatGPT并使用全流程图解教程 关于普朗克概率的的讨论 信用卡对个人、社会以及国家的影响——ChatGPT辅助编写 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/9/14
articleCard.readMore

自动曝光原理

自动曝光的原理 曝光是摄影中十分重要的一个环节,它决定了一张图片的明暗,如下图所示,第一张图片太暗,而第三种图片太亮。 曝光由什么来决定 使用过数码相机的人都知道曝光由光圈、曝光时间、ISO三者共同决定,详细的关系就不赘述。 光圈:控制进光量; 曝光时间:光到达的时间长度; ISO:增益; 但是对于手机以及其他电子产品使用的微型摄像头,光圈大小是固定的,所以手机拍照的曝光由曝光时间和**增益(ISO)**来控制。 什么是自动曝光 数码相机中有一种手动模式,可手动设置光圈、曝光时间、ISO来控制曝光,该模式的使用对摄影师的要求会比较高。另外 数码相机的全自动模式、光圈优先模式、快门优先模式以及手机等电子产品的曝光都属于自动曝光。 自动曝光就是相机代替人的操作,自动调节曝光时间、光圈、ISO进行曝光,使得所摄物体亮度正常。这句话解释起来很简单,但是存在两个难点问题:第一,相机不如人眼这样可以直观的分辨图像明暗,如何判断这幅图像是否亮度合适;第二,如何调整曝光时间、光圈、ISO,这三者调节的比例。 自动曝光的标准 在此之前需要了解物体的亮度与色彩是由物体对光线的反射率来决定的。例如纯黑色的放射率是0,纯白色的反射率是100%,处于中间的灰度的反射率是18%,这就是18%中间灰度。 具有一定反射率的物体在最终的图像中被还原到了其相应的灰度级,这就意味着达到了正确的曝光。例如摄影师们通常在拍摄之前使用中性灰卡测试曝光是否正常。 但是相机在各种场景下无法识别物体的反射率,因此采用了一个简单粗暴而又行之有效的方法,统一将图像整体平均亮度设置为中性灰的亮度。该方法基于**科学家认为自然界的平均反射率是18%**这一理论。当然,这个方法也不是走遍天下都不怕,比如拍摄雪景时需要增加曝光补偿,不然会偏暗,因为雪景的亮度远远大于中性灰度。这也就是摄影中的一句口诀的由来“白增黑减”。 自动曝光算法 上面已经讲了自动曝光的标准,也就确立了曝光目标,要达到这一目标还要自动曝光算法来实现。 目前比较常见的算法有平均亮度法、权重均值法、亮度直方图等。其中最普遍的就是平均亮度法。平均亮度法就是对图像所以像素亮度求平均值,通过不断调整曝光参数最终达到目标亮度。而权重均值法是对图像不同区域设置不同权重来计算图像亮度,例如相机中的各种测光模式的选择就是改变不同区域的权重。亮度直方图法是通过为直方图中峰值分配不同权重来计算图像亮度。 自动曝光实现的过程: 第一步:对当前图像进行亮度统计; 第二步:根据当前图像亮度确定曝光值; 第三步:计算新的曝光参数,曝光时间、光圈、增益; 第四步:将新的曝光参数应用到相机; 第五步:重复步骤一到四,直到亮度满足要求。 曝光参数调整_曝光表 前面留下两个问题:“第一,相机不如人眼这样可以直观的分辨图像明暗,如何判断这幅图像是否亮度合适;第二,如何调整曝光时间、光圈、ISO,这三者调节的比例。” 第一个问题在前面有过解释,第二个问题也就是自动曝光实现步骤的第三步,曝光值由光圈、曝光时间、增益沟通决定,当计算出一个曝光量,曝光三要素有很多种组合方式。一般情况下有曝光曲线,每个曝光量对应一组参数。手机中曝光曲线可以通过Tuning调整。 From: 积极的悲观主义者 系列教程 全部文章RSS订阅 Embeded系列 Embeded 分类 RSS 订阅 海思MPP&UNF构架源代码级分析 3G,4G,Wifi选型需求分析及技术简介 自动曝光原理 ISP 数字图像处理 算法概述、工作原理、架构、处理流程 QNAP添加man pages

2021/9/14
articleCard.readMore

浏览器的渲染过程

通常,我们只需要编写HTML,CSS,JavaScript,浏览器上就能呈现出漂亮的网页了,但是浏览器是如何使用我们的代码在屏幕上渲染像素的呢? 首先,请先看一张大图 浏览器将HTML,CSS,JavaScript代码转换成屏幕上所能呈现的实际像素,这期间所经历的一系列步骤,叫做关键渲染路径(Critical Rendering Path)。其中包含: 构建对象模型(DOM,CSSOM) 构建渲染树(RenderTree) 布局 渲染 在构建对象模型到构建渲染树的这一过程,还穿插着JS脚本的加载和执行。如下图所示: 1.DOMTree的构建 浏览器的渲染从解析HTML文档开始,宏观上,可以分为下面几个步骤: 第一步(解析):从网络或者磁盘下读取的HTML原始字节码,通过设置的charset编码,转换成相字符 第二步(token化):通过词法分析器,将字符串解析成Token,Token中会标注出当前的Token是开始标签,还是结束标签,或者文本标签等。 第三步(生成Nodes并构建DOM树):浏览器会根据Tokens里记录的开始标签,结束标签,将Tokens之间相互串联起来_(带有结束标签的Token不会生成Node)_。 <img src="xxx.png" >标签最终生成出的节点对象中会保存图片地址等信息。 深度遍历算法消耗Token来生成Node,如下图所示: html Token,并消耗Token创建出html 节点对象,接着生成head Token并消耗Token创建出head节点对象…,当所有的Tokens都消耗完了,紧接着DOM树也就构建完了。 这里抛出个小问题,为什么有时在js中访问DOM时浏览器会报错呢? script或者link标签,就会根据src对应的地址去加载资源,在script标签没有设置async/defer属性时,这个加载过程是下载并执行完全部的代码,此时,DOM树还没有完全创建完毕,这个时候如果js企图访问script标签后面的DOM元素,浏览器就会抛出找不到该DOM元素的错误。 2.CSSOMTree的构建 DOM会记录页面的内容,但是浏览器还需要知道这些内容该用什么样式去展示,所以还需要构建CSSOMTree。CSSOM的生成过程和DOM的生成过程十分相似,也是:1.解析,2.Token化,3.生成Nodes并构建CSSOMTree: 假设浏览器收到了下面这样一段css: body {font-size: 16px;} p {font-weight: bold;} p span {display:none;} span {color: red;} img {float: right;} 最终会生成如下的CSSOMTree: 从图中可以看出,最开始body有一个样式规则是font-size:16px,之后,在body这个样式基础上每个子节点还会添加自己单独的样式规则,比如span又添加了一个样式规则color:red。正是因为样式这种类似于继承的特性,浏览器设定了一条规则:CSSOMTree需要等到完全构建后才可以被使用,因为后面的属性可能会覆盖掉前面的设置。比如在上面的css代码基础上再添加一行代码p {font-size:12px},那么之前设置的16px将会被覆盖成12px。 下面是官方给的一种解释: 未构建完的CSSOMTree是不准确的,浏览器必须等到CSSOMTree构建完毕后才能进入下一阶段。 那么回到上面生成DOM时提到的JS问题:在标签没有设置async/defer属性时,js会阻塞DOM的生成。原因是js会改变DOMTree的内容,如果不阻塞,会出现一边生成DOM内容,一边修改DOM内容的情况,无法确保最终生成的DOMTree是确定唯一的。 同理,JS也会可以修改CSS样式,影响CSSOMTree最终的结果。而我们前面提到,不完整的CSSOMTree是不可以被使用的,如果JS试图在浏览器还未完成CSSOMTree的下载和构建时去操作CSS样式,浏览器会暂停脚本的运行和DOM的构建,直至浏览器完成了CSSOM的下载和构建。也就是说,JS脚本的出现会让CSSOM的构建阻塞DOM的构建。 平时谈及页面性能优化,经常会强调css文件应该放在html文档中的前面引入,js文件应该放在后面引入,这么做的原因是什么呢? 举个例子:本来,DOM构建和CSSOM构建是两个过程,井水不犯河水。假设DOM构建完成需要1s,CSSOM构建也需要1s,在DOM构建了0.2s时发现了一个link标签,此时完成这个操作需要的时间大概是1.2s,如下图所示: 而此时我们在HTML文档的中间插中入了一段JS代码,在DOM构建中间的过程中发现了这个script标签,假设这段JS代码只需要执行0.0001s,那么完成这个操作需要的时间就会变成: 那如果我们把css放到前面,js放到最后引入时,构建时间会变成: 由此可见,虽然只是插入了小小的一段只运行0.0001s的js代码,不同的引入时机也会严重影响DOMTree的构建速度。 简而言之,如果在DOM,CSSOM和JavaScript执行之间引入大量的依赖关系,可能会导致浏览器在处理渲染资源时出现大幅度延迟: 当浏览器遇到一个script标签时,DOMTree的构建将被暂停,直至脚本执行完毕 JavaScript可以查询和修改DOMTree与CSSOMTree 直至CSSOM构建完毕,JavaScript才会执行 脚本在文档中的位置很重要 3.渲染树的构建 现在,我们已经拥有了完整的DOM树和CSSOM树。DOM 树上每一个节点对应着网页里每一个元素,CSSOM树上每个节点对应着网页里每个元素的样式,并且此时浏览器也可以通过 JavaScript 操作DOM/CSSOM树,动态改变它的结构。但是DOM/CSSOM树本身并不能直接用于排版和渲染,浏览器还会生成另外一棵树:Render树 接下来我们来谈几条概念 Render 树上的每一个节点被称为:RenderObject。 RenderObject跟 DOM 节点几乎是一一对应的,当一个可见的 DOM 节点被添加到 DOM 树上时,内核就会为它生成对应的 RenderOject 添加到 Render 树上。 其中,可见的DOM节点不包括: 一些不会体现在渲染输出中的节点(<html><script><link>….),会直接被忽略掉。 通过CSS隐藏的节点。例如上图中的span节点,因为有一个CSS显式规则在该节点上设置了display:none属性,那么它在生成RenderObject时会被直接忽略掉。 Render 树是衔接浏览器排版引擎和渲染引擎之间的桥梁,它是排版引擎的输出,渲染引擎的输入。 此时的Render树上,已经包含了网页上所有可见元素的内容和位置信息 排版引擎会根据Render树的内容和结构,准确的计算出元素该在网页上的什么位置。到此,我们已经具备进入布局的一切准备条件,但是通过上面我们知道,布局后面还有一个渲染过程,那么_Render 树是衔接浏览器排版引擎和渲染引擎之间的桥梁,它是排版引擎的输出,渲染引擎的输入。_这句话是什么意思呢? RenderObject and RenderLayer 浏览器渲染引擎并不是直接使用Render树进行绘制,为了方便处理Positioning,Clipping,Overflow-scroll,CSS Transfrom/Opacrity/Animation/Filter,Mask or Reflection,Z-indexing等属性,浏览器需要生成另外一棵树:Layer树 浏览器会为一些特定的RenderObject生成对应的RenderLayer,其中的规则是: 是否是页面的根节点 It’s the root object for the page 是否有css的一些布局属性(relative absolute or a transform) It has explicit CSS position properties (relative, absolute or a transform) 是否透明 It is transparent 是否有溢出 Has overflow, an alpha mask or reflection 是否有css滤镜 Has a CSS filter 是否包含一个canvas元素使得节点拥有视图上下文 Corresponds to canvas element that has a 3D (WebGL) context or an accelerated 2D context 是否包含一个video元素 Corresponds to a video element 当满足上面其中一个条件时,这个RrenderObject就会被浏览器选中生成对应的RenderLayer。至于那些没有被命运选中的RrenderObject,会从属与父节点的RenderLayer。最终,每个RrenderObject都会直接或者间接的属于一个RenderLayer。 浏览器渲染引擎在布局和渲染时会遍历整个Layer树,访问每一个RenderLayer,再遍历从属于这个RenderLayer的 RrenderObject,将每一个 RenderObject 绘制出来。可以理解为:Layer 树决定了网页绘制的层次顺序,而从属于RenderLayer 的 RrenderObject决定了这个 Layer 的内容,所有的 RenderLayer 和 RrenderObject 一起就决定了网页在屏幕上最终呈现出来的内容。 4.布局 到目前为止,浏览器计算出了哪些节点是可见的以及它的信息和样式,接下来就需要计算这些节点在设备视口内的确切位置和大小,这个过程我们称之为“布局”。 布局最后的输出是一个“盒模型”:将所有相对测量值都转换成屏幕上的绝对像素。 5.渲染 最后,既然我们知道了哪些节点可见、它们的计算样式以及几何信息,我们终于可以将这些信息传递给最后一个阶段:将渲染树中的每个节点转换成屏幕上的实际像素:浏览器通过发出“Paint Setup”和“Paint”事件,将渲染树转换成屏幕上的像素。 至此,我们就能够在浏览器上看到漂亮的网页了 谈及页面性能优化,我们也常说要尽量减少浏览器的重排和重绘,浏览器重排和重绘时究竟做了哪些工作呢? 我们平时常说的重排,其实就是浏览器计算render树,布局到渲染的这个过程,而重绘就是计算layer树到渲染的这个过程,每当触发一次重绘和重排时,浏览器都需要重新经过一遍上述的计算。很显然,重排会产生比重绘更大的开销,但无论是重排还是重绘,都会给浏览器渲染线程造成很大的负担,所以,我们在实际生产中要严格注意减少重排和重绘的触发。至于如何减少重排和重绘的次数,这里就不多做展开了,详细请听下回分解~ 总结: 经过:1.构建对象模型(DOM,CSSOM),2.构建渲染树(RenderTree),3.布局,4.渲染 这几个步骤后,我们就能在浏览器上看到漂亮的网页啦。 CSS被视为阻塞渲染的资源,应放到代码的头部尽快加载。 同步的JavaScript会暂停DOMTree的构建,应放到代码的尾部最后加载,或者使用async/defer属性异步加载JavaScript。 重排和重绘会给浏览器渲染线程造成很大的负担,尽量减少重排和重绘的触发次数 参考文献: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model?hl=zh-cn https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=zh-cn https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css?hl=zh-cn https://mp.weixin.qq.com/s?__biz=MzA5NzkwNDk3MQ==&mid=2650588806&idx=1&sn=408a54e7c8102fd6944c9a40b119015a&scene=21#wechat_redirect

2021/9/13
articleCard.readMore

在浏览器输入 URL 回车之后发生了什么

前言 这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最近闲的无聊,然后就自己做了一篇笔记,感觉比之前理解更透彻了。 这篇笔记是我这两天看了数十篇文章总结出来的,所以相对全面一点,但由于我是做前端的,所以会比较重点分析浏览器渲染页面那一部分,至于其他部分我会罗列出关键词,感兴趣的可以自行查阅, **注意:**本文的步骤是建立在,请求的是一个简单的 HTTP 请求,没有 HTTPS、HTTP2、最简单的 DNS、没有代理、并且服务器没有任何问题的基础上,尽管这是不切实际的。 大致流程 URL 解析 DNS 查询 TCP 连接 处理请求 接受响应 渲染页面 一、URL 解析 地址解析: 首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。 HSTS 由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。详见:你所不知道的 HSTS (opens new window)。 其他操作 浏览器还会进行一些额外的操作,比如安全检查、访问限制(之前国产浏览器限制 996.icu)。 检查缓存 二、DNS 查询 基本步骤 1. 浏览器缓存 浏览器会先检查是否在缓存中,没有则调用系统库函数进行查询。 2. 操作系统缓存 操作系统也有自己的 DNS 缓存,但在这之前,会向检查域名是否存在本地的 Hosts 文件里,没有则向 DNS 服务器发送查询请求。 3. 路由器缓存 路由器也有自己的缓存。 4. ISP DNS 缓存 ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。 根域名服务器查询 在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域,下面这个图很好的诠释了整个流程: 根域名服务器:维基百科 (opens new window) 需要注意的点 递归方式:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地 DNS 服务器的过程) 迭代方式,就是本地 DNS 服务器到根域名服务器查询的方式。 什么是 DNS 劫持 前端 dns-prefetch 优化 三、TCP 连接 TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装: 1. 应用层:发送 HTTP 请求 在前面的步骤我们已经得到服务器的 IP 地址,浏览器会开始构造一个 HTTP 报文,其中包括: 请求报头(Request Header):请求方法、目标地址、遵循的协议等等 请求主体(其他参数) 其中需要注意的点: 浏览器只能发送 GET、POST 方法,而打开网页使用的是 GET 方法 2. 传输层:TCP 传输报文 传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。 在建立连接前,会先进行 TCP 三次握手。 关于 TCP/IP 三次握手,网上已经有很多段子和图片生动地描述了。 相关知识点: SYN 泛洪攻击 3. 网络层:IP 协议查询 Mac 地址 将数据段打包,并加入源及目标的 IP 地址,并且负责寻找传输路线。 判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。 注意:在 OSI 参考模型中 ARP 协议位于链路层,但在 TCP/IP 中,它位于网络层。 4. 链路层:以太网协议 以太网协议 根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分: 标头:数据包的发送者、接受者、数据类型 数据:数据包具体内容 Mac 地址 以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。 广播 发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。 注意:接收方回应是单播。 相关知识点: ARP 攻击 服务器接受请求 接受过程就是把以上步骤逆转过来,参见上图。 四、服务器处理请求 大致流程 HTTPD 最常见的 HTTPD 有 Linux 上常用的 Apache 和 Nginx,以及 Windows 上的 IIS。 它会监听得到的请求,然后开启一个子进程去处理这个请求。 处理请求 接受 TCP 报文后,会对连接进行处理,对 HTTP 协议进行解析(请求方法、域名、路径等),并且进行一些验证: 验证是否配置虚拟主机 验证虚拟主机是否接受此方法 验证该用户可以使用该方法(根据 IP 地址、身份信息等) 重定向 假如服务器配置了 HTTP 重定向,就会返回一个 301永久重定向响应,浏览器就会根据响应,重新发送 HTTP 请求(重新执行上面的过程)。 关于更多:详见这篇文章 (opens new window) URL 重写 然后会查看 URL 重写规则,如果请求的文件是真实存在的,比如图片、html、css、js 文件等,则会直接把这个文件返回。 否则服务器会按照规则把请求重写到 一个 REST 风格的 URL 上。 然后根据动态语言的脚本,来决定调用什么类型的动态文件解释器来处理这个请求。 以 PHP 语言的 MVC 框架举例,它首先会初始化一些环境的参数,根据 URL 由上到下地去匹配路由,然后让路由所定义的方法去处理请求。 五、浏览器接受响应 浏览器接收到来自服务器的响应资源后,会对资源进行分析。 首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。 如果响应资源进行了压缩(比如 gzip),还需要进行解压。 然后,对响应资源做缓存。 接下来,根据响应资源里的 MIME (opens new window) 类型去解析响应内容(比如 HTML、Image 各有不同的解析方式)。 六、渲染页面 浏览器内核 不同的浏览器内核,渲染过程也不完全相同,但大致流程都差不多。 基本流程 1. HTML 解析 首先要知道浏览器解析是从上往下一行一行地解析的。 解析的过程可以分为四个步骤: 1. 解码(encoding) 传输回来的其实都是一些二进制字节数据,浏览器需要根据文件指定编码(例如 UTF-8)转换成字符串,也就是 HTML 代码。 2. 预解析(pre-parsing) 预解析做的事情是提前加载资源,减少处理时间,它会识别一些会请求资源的属性,比如img标签的src属性,并将这个请求加到请求队列中。 3. 符号化(Tokenization) 符号化是词法分析的过程,将输入解析成符号,HTML 符号包括,开始标签、结束标签、属性名和属性值。 它通过一个状态机去识别符号的状态,比如遇到<,>状态都会产生变化。 4. 构建树(tree construction) 注意:符号化和构建树是并行操作的,也就是说只要解析到一个开始标签,就会创建一个 DOM 节点。 在上一步符号化中,解析器获得这些标记,然后以合适的方法创建DOM对象并把这些符号插入到DOM对象中。 浏览器容错进制 你从来没有在浏览器看过类似"语法无效"的错误,这是因为浏览器去纠正错误的语法,然后继续工作。 事件 当整个解析的过程完成以后,浏览器会通过DOMContentLoaded事件来通知DOM解析完成。 2. CSS 解析 一旦浏览器下载了 CSS,CSS 解析器就会处理它遇到的任何 CSS,根据语法规范 (opens new window)解析出所有的 CSS 并进行标记化,然后我们得到一个规则表。 CSS 匹配规则 在匹配一个节点对应的 CSS 规则时,是按照从右到左的顺序的,例如:div p { font-size :14px }会先寻找所有的p标签然后判断它的父元素是否为div。 所以我们写 CSS 时,尽量用 id 和 class,千万不要过度层叠。 3. 渲染树 其实这就是一个 DOM 树和 CSS 规则树合并的过程。 注意:渲染树会忽略那些不需要渲染的节点,比如设置了display:none的节点。 计算 通过计算让任何尺寸值都减少到三个可能之一:auto、百分比、px,比如把rem转化为px。 级联 浏览器需要一种方法来确定哪些样式才真正需要应用到对应元素,所以它使用一个叫做specificity的公式,这个公式会通过: 标签名、class、id 是否内联样式 !important 然后得出一个权重值,取最高的那个。 渲染阻塞 当遇到一个script标签时,DOM 构建会被暂停,直至脚本完成执行,然后继续构建 DOM 树。 但如果 JS 依赖 CSS 样式,而它还没有被下载和构建时,浏览器就会延迟脚本执行,直至 CSS Rules 被构建。 所有我们知道: CSS 会阻塞 JS 执行 JS 会阻塞后面的 DOM 解析 为了避免这种情况,应该以下原则: CSS 资源排在 JavaScript 资源前面 JS 放在 HTML 最底部,也就是 </body>前 另外,如果要改变阻塞模式,可以使用 defer 与 async,详见:这篇文章 (opens new window) 布局与绘制 确定渲染树种所有节点的几何属性,比如:位置、大小等等,最后输入一个盒子模型,它能精准地捕获到每个元素在屏幕内的准确位置与大小。 然后遍历渲染树,调用渲染器的 paint() 方法在屏幕上显示其内容。 5. 合并渲染层 把以上绘制的所有图片合并,最终输出一张图片。 6. 回流与重绘 回流(reflow) 当浏览器发现某个部分发现变化影响了布局时,需要倒回去重新渲染,会从html标签开始递归往下,重新计算位置和大小。 reflow 基本是无法避免的,因为当你滑动一下鼠标、resize 窗口,页面就会产生变化。 重绘(repaint) 改变了某个元素的背景色、文字颜色等等不会影响周围元素的位置变化时,就会发生重绘。 每次重绘后,浏览器还需要合并渲染层并输出到屏幕上。 回流的成本要比重绘高很多,所以我们应该尽量避免产生回流。 比如: display:none 会触发回流,而 visibility:hidden 只会触发重绘。 JavaScript 编译执行 大致流程 可以分为三个阶段: 1. 词法分析 JS 脚本加载完毕后,会首先进入语法分析阶段,它首先会分析代码块的语法是否正确,不正确则抛出“语法错误”,停止执行。 几个步骤: 分词,例如将var a = 2,,分成var、a、=、2这样的词法单元。 解析,将词法单元转换成抽象语法树(AST)。 代码生成,将抽象语法树转换成机器指令。 2. 预编译 JS 有三种运行环境: 全局环境 函数环境 eval 每进入一个不同的运行环境都会创建一个对应的执行上下文,根据不同的上下文环境,形成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是当前执行上下文。 创建执行上下文 创建执行上下文的过程中,主要做了以下三件事: 创建变量对象 参数、函数、变量 建立作用域链 确认当前执行环境是否能访问变量 确定 This 指向 3. 执行 JS 线程 虽然 JS 是单线程的,但实际上参与工作的线程一共有四个: 其中三个只是协助,只有 JS 引擎线程是真正执行的 JS 引擎线程:也叫 JS 内核,负责解析执行 JS 脚本程序的主线程,例如 V8 引擎 事件触发线程:属于浏览器内核线程,主要用于控制事件,例如鼠标、键盘等,当事件被触发时,就会把事件的处理函数推进事件队列,等待 JS 引擎线程执行 定时器触发线程:主要控制setInterval和setTimeout,用来计时,计时完毕后,则把定时器的处理函数推进事件队列中,等待 JS 引擎线程。 HTTP 异步请求线程:通过 XMLHttpRequest 连接后,通过浏览器新开的一个线程,监控 readyState 状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推进事件队列中,等待 JS 引擎线程执行。 注:浏览器对同一域名的并发连接数是有限的,通常为 6 个。 宏任务 分为: 同步任务:按照顺序执行,只有前一个任务完成后,才能执行后一个任务 异步任务:不直接执行,只有满足触发条件时,相关的线程将该异步任务推进任务队列中,等待 JS 引擎主线程上的任务执行完毕时才开始执行,例如异步 Ajax、DOM 事件,setTimeout 等。 微任务 微任务是 ES6 和 Node 环境下的,主要 API 有:Promise,process.nextTick。 微任务的执行在宏任务的同步任务之后,在异步任务之前。 代码例子 以上代码输出顺序为:1,3,5,4,2 参考文档 what-happens-when-zh_CN (opens new window) Tags to DOM (opens new window) 彻底理解浏览器的缓存机制 (opens new window) 浏览器的工作原理:新式网络浏览器幕后揭秘 (opens new window) 深入浅出浏览器渲染原理 (opens new window) js 引擎的执行过程(一) (opens new window) 还有一些找不到了。。。。。 From: 4ark.me

2021/9/13
articleCard.readMore

Joplin 插件使用推荐

Joplin插件推荐 Gif图片加载较慢,请耐心等待! persistent-text-folding-in-editor Ctrl(or Cmd) + Alt + F to fold all Ctrl(or Cmd) + Alt + U to unfold all Plugin: Conflict Resolution Joplin Kanban Plugin Usage To get started, you’ll need a notebook which will contain all tasks that you want to see on the board. The plugin will only show tasks in a single notebook and it’s sub-notebooks. A kanban board is defined by a special type of note, which contains all of its configuration. Create a new note, and paste in the following: ```kanban columns: - name: Backlog backlog: true - name: Work in progress tag: wip - name: Finished tag: done ``` It is important that the confiuration is surrounded by a code block (kanban ... ), otherwise it won’t be detected. joplin_plugin_nlr 插件安装后会在工具菜单添加一项:NLR 点击 NLR 打开新的panel,即可在输入框输入书名或作者名称搜索小说 点击卡片右上方 INFO 打开新的小说目录,章节卡片右上checkbox选中即代表下载此chapter,选中后,点击上方DOWNLOAD开始下载,在笔记列表中即可看到小说文本了。 joplin-outline joplin-persistent-layout Save editor layout (editor/split view/viewer/rich text) for each note separately. To persist the layout for a note follow these steps: Specify the tags for which a specific layout should be used. To do this, go to the plugin’s settings/options page and add the tags to the settings. An example configuration could like this: Make sure that the correct value is selected in View > Layout button sequence. To be able to use the layout switching correctly, this setting must be set accordingly. Otherwise the editor layout might not be switched to the expected one. For example: If a tag is specified in option Tags for editor layout mode: Rendered Markdown viewer and least one note uses it, the setting must also contain Viewer. Add the appropriate tags to the notes. If not already done. When the selected note is changed, the editor layout is switched. If none of the selected note’s tags matches a specified layout tag, the default layout from the option Default editor layout is used. If nothing is selected as default editor layout, the currently active editor layout will be kept. If more than one tag is specified for a note, the first matching one is used. Plugin: inline tags joplin-plugin-note-overview Create one or more notes with the following content: <!-- note-overview-plugin search: -tag:* fields: updated_time, title alias: updated_time AS Last edit, title AS Title sort: title DESC --> Several of these blocks can be included in one note, also between text. The note content is updated every x minutes (depending on your setting) or manualy by Tools > Create Note overview. joplin-plugin-embed-search ```search your search query ``` Additional features you can paste sort:asc or sort:desc to sort notes by title ascending or descending A shorthand notebook:this, that narrows search to current notebook only. Basic content embedding content:true (beta): Spoilers 可使用%%遮盖部分文字。 格式: %%扰流板、遮挡板%% 软件内呈现: 点击前 点击后 以及一个类似闪卡的可折叠块 格式: :[ 测试,标题 测试,内容 ]: 软件内呈现: 点击前 点击后 Notes statistics 笔记内部的数据统计。 Note tabs 像浏览器一样浏览文档,支持多个打开放置。 Quick links 使用@@快速链接笔记文件。 Jira Issue Homenotes 选择一个笔记作为每次打开软件时的首个笔记,可以把这个功能当作书签用。 Admonition !!! note This is the admonition title This is the admonition body !!! The following admonition types, supported by Docarys, are recognized by this plugin: Type note abstract info tip success question warning failure danger bug example quote Encrypted notes 字面意义,加密笔记,记住密码不得找回。 Favorites 收藏夹,支持笔记、标签笔记本的收纳(随取随用) 更改收藏夹中的笔记名不会更改原始笔记。 Highlight 打出[h:colour:scope]后,插件会自动识别成代码。 颜色 范围(自动选择的) m = mark e = empty r = red w = word g = green s = sentence b = blue l = line y = yellow 其他插件: 官方插件下载地址及其介绍 系列教程 全部文章RSS订阅 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/9/10
articleCard.readMore

[十万字图文教程]基于Hexo的matery主题搭建博客并深度优化一站式完全教程

All in one 一站式Hexo配置优化教程!自建独立博客全流程教程! 本文很长,特别长,快卡死编辑器了,如是被拆分为6篇文章了,见文末链接。 如果你遇到了什么问题,可以尝试搜索本文,你很可能有收获! CtRL + F,还可以试试右上角菜单搜索功能。 欢迎光临博主的独立博客 夜法之书,本文授权CC4.0非商用,转载请注明出处 本文就教你搭建一个美观实用的博客系统,步骤极尽详细! 本文中提到的大量特性,已经被博主提交到matery主题develop分支,提交记录见Commit。所以下面很多特性已经不用自己修改了,可以直接使用。 参考列表放到了最后一篇末尾,去找找看,里面能发现很多好东西。 Tips:友情提示,部分内容RSS输出获取不到,请跳转到源网页地址浏览全文! 选择Hexo的理由? 优点 中文支持:Hexo创建者是台湾人Tommy Chen,对中文支持很友好! 开源:Hexo开源,方便学习和修改 开源生态丰富:Hexo生态非常完善,各种插件极其丰富!而且基本全部免费、开源! MarkDown友好:Hexo对Markdown支持非常完善,对比遍各种博客框架,hexo对Markdown支持最友好 方便部署:Hexo静态部署,不需要php,java之类的运行环境,方便各种部署环境,有很多免费的静态网页部署服务可用。不需要购买vps,就有各种免费的部署环境!最低0成本建立独立博客! Git管理:所有文章和源码可以使用Git管理备份,方便保存和维护 缺点 对于初学者需要花费时间学习和配置:Hexo 基于 Node.js 开发,因此需要一定的技术水平和时间去学习和配置环境及插件等使用,但网上各种教程极其丰富。 功能不如动态网站丰富:相比于动态网站,Hexo 可以实现的功能相对有限,例如用户登录、评论系统等功能尚需其他工具或服务支持。 不利于频繁更改内容:由于 Hexo 是生成静态文件的方式,因此如果需要频繁更新网站内容,则需要重新构建整个网站并重新部署,这可能导致网站维护成本较高。 需要服务器来托管静态文件:虽然 Hexo 生成的静态文件可以直接访问,但仍需要一个服务器供其托管和发布,这可能会带来一些成本。 写博客的重要性 立德、立功、立言“三不朽” 《左传》载曰:“太上有立德,其次有立功,其次有立言,虽久不废,此之谓不朽。” 纸上得来终觉浅,绝知此事要躬行!赶紧跟着教程自己做一个独立博客吧! 最终效果如下图所示! 本博客大量使用webp格式图片加速网络访问,请确保您的浏览器支持webp,使用最新版的Firefox,Edge,Chrome可以有最佳体验! 支持Work Service PWA离线访问。 新增另一种浅色/深色模式。大部分组件会实时切换浅色/深色模式! 背景随机图片随机切换,并区分黑暗模式图片!切换浅色/深色模式时,背景图会跟随实时 支持文章RSS订阅,并支持文章分类订阅。 新增文章阅读模式,代码框全屏 新增文章目录栏状态保存,文章刷新后目录状态依旧保存 新增看板娘文字功能提示,当鼠标移动到特定位置,看板娘将会给出特定的文字提示! footer 栏新增支持繁简转换 支持新博文订阅通知,右下角小铃铛点击订阅! chrome用户可能由于网络原因链接不到Google的服务器而看不到这个小铃铛。edge 和 Firefox 用户可以正常订阅。 service worker 实现的渐进式App,不仅可以离线浏览,还可以加速缓存访问! 深色模式,夜晚保护您的视力! RSS Hub 和 TTRSS 私有部署实现订阅。 配合浏览器扩展 RSSHub Radar (opens new window)和 移动端辅助 App RSSBud (opens new window)(iOS) 与 RSSAid (opens new window)(Android) 食用。 教程:RSS的使用与Tiny Tiny RSS Selfhost自建 对所有菜单和常用按钮做了文字功能提示。 支持看板娘模型切换,服装切换,某些模型还有语音互动! 看板娘还可以自定义时间提示,特殊节日提示等等。参考 Hexo博客个性定制篇中来完成吧。 经过多次优化,新版看板娘资源异步加载体积大拖累的性能分数。其它几乎都是满分了! 大量使用本地缓存,牺牲了第一次加载的体积,保证了第二次打开几乎都是使用缓存,异步加载对第一次渲染速度影响不大,但可以极大的提高第二次来自后续的访问速度! 本教程还有其它五大部分,更多内容请见Hexo系列教程 Hexo Docker环境使用篇 Docker 简介: Docker 是一种轻量级的虚拟机环境,可以隔离主机的运行环境,内核公用主机的,运行库和环境是 Docker 私有的。运行 Docker 程序只比主机直接运行程序性能损失微乎其微。使用 Docker 你可以同时运行各种各样运行库环境而不用担心搞乱你的主机运行库环境! Docker 运行负载远小于 Vmware 这类虚拟机, Vmware 需要模拟对应的CPU指令,再虚机运行一个虚拟机自己的内核,再这个虚拟机内核之上,再运行虚拟机的运行库和程序。比 Docker 多了一个内核模拟和运行,Cpu 和内存开销大增! 什么是 Docker? Docker 是一个开源平台,支持开发人员构建、部署、运行、更新和管理容器,这些容器是标准化的可执行组件,结合了应用源代码以及在任何环境中运行该代码所需的操作系统 (OS) 库和依赖项。 容器简化了分布式应用的部署和交付过程。 随着组织转向云原生开发和混合多云环境,它们已变得越来越流行。 开发人员可以直接使用 Linux和其他操作系统中内置的功能,在没有 Docker 的情况下创建容器。 但 Docker 使容器化更加迅速、简便和安全。 截至本文撰写之时,Docker 报告称,已有超过 1300 万名开发人员在使用该平台(链接位于 ibm.com 外部)。 Docker 也指 Docker, Inc.(链接位于 ibm.com 外部),即销售 Docker 商业版本的企业,还可以是 Docker, Inc. 和许多其他组织和个人开展的 Docker 开源项目。 容器的工作原理 容器是通过 Linux 内核中内置的过程隔离和虚拟化功能来实现的。 控制组 (Cgroups) 用于为各进程分配资源,名称空间(namespace)用于限制进程访问或对其他资源或系统区域的可视性 ,这些功能支持多个应用组件共享主机操作系统的单个实例的资源,这与系统管理程序支持多台虚拟机 (VM) 共享单个硬件服务器的 CPU、内存和其他资源的方式大致相同。 容器的架构 Docker 包括三个基本概念: 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。 Docker的优势 因此,容器技术可提供虚拟机的所有功能和优势,包括应用隔离、经济高效的可扩展性和可处置性,以及其他重要的优势: 更轻巧:与虚拟机不同,容器不会承载整个操作系统实例和系统管理程序的有效负载。 它们仅包括执行代码所需的操作系统进程和依赖项。 容器大小以兆字节为单位(某些虚拟机则是以千兆字节为单位)来衡量,因此它们可以更好地利用硬件容量,启动速度也更快。 提高了开发人员的工作效率:容器化应用可以“一次编写,随处运行”。 与虚拟机相比,容器的部署、配置和重启过程更迅速且更简单。 这使得容器非常适合在持续集成和持续交付 (CI/CD) 管道中使用,并且更适合采取敏捷和 DevOps 实践的开发团队。 提高了资源利用率:开发人员使用容器在硬件上运行的应用副本数量是使用虚拟机的数倍。 这可以减少云支出。 为何使用 Docker? Docker 如今非常受欢迎,甚至可以与“容器”一词互换使用。 而在 Docker 于 2013 年面世之前,第一批与容器相关的技术早已存在数年,甚至数十年(链接位于 IBM 外部)。 最值得注意的是,2008 年,Linux 内核中实现了 LinuXContainers (LXC),LXC 完全支持单个 Linux 实例的虚拟化。 虽然目前仍在使用 LXC,但也提供了使用 Linux 内核的新技术。 现代的开源 Linux 操作系统 Ubuntu 也提供了此功能。 Docker 支持开发人员使用简单的命令访问这些本机容器化功能,并通过节省工作量的应用程序编程接口 (API) 自动执行。 与 LXC 相比,Docker 提供了以下功能: 增强的无缝容器可移植性:虽然 LXC 容器通常引用特定于机器的配置,但 Docker 容器无需修改即可在任何桌面、数据中心和云环境中运行。 更轻巧且更细粒度的更新:通过使用 LXC,可以在单个容器中组合多个进程。 这样就可以构建持续运行的应用,即使为了更新或修复而关闭某个部分也不例外。 自动化容器创建:Docker 可以基于应用源代码自动构建容器。 容器版本控制:Docker 可以跟踪容器映像的版本,回滚到先前的版本,以及跟踪版本的构建者和构建方式。 它甚至可以只上传现有版本和新版本之间的增量。 容器复用:现有容器可用作基本映像(本质上类似于用于构建新容器的模板)。 共享容器库:开发人员可以访问包含数千个用户贡献容器的开源注册表。 如今,Docker 容器化也适用于 Microsoft Windows 和 Apple MacOS。 开发人员可以在任何操作系统上运行 Docker 容器,大多数领先的云提供商(包括 Amazon Web Services (AWS)、Microsoft Azure 和 IBM Cloud)都提供了一些专用服务,这些服务可帮助开发人员构建、部署和运行使用 Docker 进行容器化的应用。 Docker 版 hexo 环境一键部署 博主开源定制,推荐使用!省去您大量环境配置时间。 使用Hexo Docker之前需要Docker 环境,请参阅后文Docker安装方法 docker-hub Github-hexo 使用推荐Docker来搭配本文,阅读使用,将更省事,方便,快捷。hexo环境一键搞定! Docker一键安装 docker create --name=hexo \ -e HEXO_SERVER_PORT=4000 \ -e GIT_USER="17lai" \ -e GIT_EMAIL="17lai@domain.tld" \ -v /mnt/blog.17lai.site:/app \ -p 4000:4000 \ bloodstar/hexo Docker镜像直接提供最新版本node ,hexo hexo web 后台写作 基于 hexo-admin 实现,具体配置实现方法见后文。 最终效果如下图所示。 blog.17lai.fun 访问blog, 添加后缀 admin 访问 hexo 后台。 使用前面提到的 hexo docker ,启动运行 hexo docker 后,非自动安装 hexo-admin 以及常用插件,你也可以自定义安装你虚幻的插件, vi /app/useRun.sh。 配置 hexo-admin 根目录下_config.yml: admin: username: myfavoritename #用户名 password_hash: be121740bf988b2225a313fa1f107ca1 #密码 secret: a secret something # secret is used to make the cookies secure deployCommand: '/app/tools/cide.sh' # 自定义的部署脚本,在 hexo admin 的 deploy 标签页 deploy 按钮点击调用 配置 post metadata 根目录下_config.yml: # add and edit your own post metadata with the admin interface metadata: author_id: defaultAuthorId language: hexon Github: hexon 另一个hexo web 编辑界面,界面比hexo-admin更现代化。安装配置方法见Github hexo-editor hexo-editor 又一个hexo web 编辑器 支持手机 Qexo https://github.com/Qexo/Qexo A Quick, Powerful and Pretty Online Manager for Hexo. 类似项目 https://github.com/Wexagonal/Wexagonal 轻量级\多平台\开箱即用的hexo后端管理器 ssh key 部署 Docker会自动随机生成ssh key 在 /app/.ssh 目录下面。自动部署请把ssh key添加到github 等平台。 Github详细教程 将SSH 公钥复制到剪贴板。 … 在任何页面的右上角,单击您的个人资料照片,然后单击Settings(设置)。 在用户设置侧边栏中,单击SSH and GPG keys(SSH 和GPG 密钥)。 单击New SSH key(新SSH 密钥)或Add SSH key(添加SSH 密钥)。 SSH 进入docker docker exec -it hexo /bin/bash 然后就可以正常运行hexo的各种命令了,是不是非常简单? 快来试试吧。 远程 SSH 访问Docker 推荐使用SecurtCRT 来远程访问你的Docker。 自定义用户自动运行脚本 用户可以在这里添加自动配置,自动安装插件,等各种启动docker运行的命令。 它将在Docker启动完成后自动调用运行! vi /app/useRun.sh 反向代理 Hexo Docker Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。 一些测试可能需要ssl支持,那么用nginx来反向代理一下,就可以在本地愉快的测试ssl加密功能了。 访问docker,需要 192.168.0.100:4000这样数字ip + 端口号的方式不觉得很丑陋,而且需要开大量的端口,使用nginx反向代理,可以直接使用域名访问。 如果你想使用blog.17lai.fun这样的域名访问你的 docker 里面运行的博客,请参考下文。 Nginx也使用docker来运行,blog.17lai.fun为本地域名,修改本地hosts dns信息来访问。 docker compose 配置 nginxweb: image: bloodstar/nginx-purge container_name: "nginxweb" hostname: nginxweb ports: - "80:80" - "443:443" restart: always volumes: # ${USERDIR}为你docker运行目录 - ${USERDIR}/nginx/conf.d:/etc/nginx/conf.d:ro - ${USERDIR}/nginxproxy/certs:/etc/nginx/certs:ro - ${USERDIR}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro bloodstar/nginx-purge nginx配置 文件 blog.conf ,配置文件放到${USERDIR}/nginx/conf.d目录中 upstream blog { server hexo:4000; } server { listen 80; listen 443 ssl http2; server_name blog.17lai.fun; ssl_certificate /etc/nginx/certs/17lai.pem; ssl_certificate_key /etc/nginx/certs/17lai.key; ssl_session_cache shared:aria2SSL:10m; ssl_session_timeout 30m; #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; access_log /var/log/nginx/blog.17lai.fun_access.log combined; error_log /var/log/nginx/blog.17lai.fun_error.log; keepalive_requests 10000; location / { #proxy_redirect off; proxy_pass http://blog; proxy_buffering off; add_header X-Cache-Status $upstream_cache_status; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Frame-Options SAMEORIGIN; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } Windows DNS修改 windows hosts文件路径为: C:\Windows\System32\drivers\etc\HOSTS 管理员权限用文本编辑器打开这个文件并添加 192.168.0.100 blog.17lai.fun,然后,你就可以在本地浏览器中使用域名访问你的blog了! Linux DNS 修改 Linux hosts 文件路径为: /etc/hosts 用文本编辑器或者命令行工具vim打开这个文件并添加 192.168.0.100 blog.17lai.fun,然后,你就可以在本地浏览器中使用域名访问你的blog了! # root用户一条指令搞定 echo "192.168.0.100 blog.17lai.fun" >> /etc/hosts #或者使用 vi 或者 vim vi /etc/hosts 获取 SSL 证书 如果你购买了域名,可以在域名服务商获得免费的ssl证书。 自己生成私有证书,使用时需要给本地计算机,浏览器添加你自己的根证书,才能使你的ssl 证书在你自己的浏览器中生效。 使用Hexo Docker之前需要Docker 环境,下面是Docker 环境安装方法。 Centos 安装Docker X86(一键安装脚本): curl -sSL https://get.docker.com/ | sh Arm: 步骤1 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 步骤2 添加仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 步骤3 安装Docker sudo yum install docker-ce docker-ce-cli containerd.io 完成安装 步骤4 启动Docker sudo systemctl start docker QNAP 安装Docker 在系统应用的AppCenter中找到 Container Station,可以直接点击安装即可。 群晖 安装 Docker 首先要说的是,x86 平台的群晖才能用的上 Docker 套件,因此,ARM 架构平台的群晖只能说非常遗憾了。 Docker 并安装: 配置 docker 代理 最近 hub.docker.com 被屏蔽了,如是你需要下面设置 Docker container 运行代理 Configure Docker to use a proxy server | Docker Docs Docker pull 代理设置 Configure the daemon with systemd | Docker Docs Dockerd 代理 在执行docker pull时,是由守护进程dockerd来执行。因此,代理需要配在dockerd的环境中。而这个环境,则是受systemd所管控,因此实际是systemd的配置。 sudo mkdir -p /etc/systemd/system/docker.service.d sudo touch /etc/systemd/system/docker.service.d/proxy.conf 在这个proxy.conf文件(可以是任意*.conf的形式)中,添加以下内容: [Service] Environment="HTTP_PROXY=http://127.0.0.1:8888/" Environment="HTTPS_PROXY=http://127.0.0.1:8888/" Environment="NO_PROXY=localhost,127.0.0.1,.example.com" Container 代理 在容器运行阶段,如果需要代理上网,则需要配置 ~/.docker/config.json。以下配置,只在Docker 17.07及以上版本生效。 { "proxies": { "default": { "httpProxy": "http://127.0.0.1:8888", "httpsProxy": "http://127.0.0.1.com:8888", "noProxy": "localhost,127.0.0.1,.example.com" } } } 这个是用户级的配置,除了 proxies,docker login 等相关信息也会在其中。而且还可以配置信息展示的格式、插件参数等。 此外,容器的网络代理,也可以直接在其运行时通过 -e 注入 http_proxy 等环境变量。这两种方法分别适合不同场景。config.json 非常方便,默认在所有配置修改后启动的容器生效,适合个人开发环境。在CI/CD的自动构建环境、或者实际上线运行的环境中,这种方法就不太合适,用 -e 注入这种显式配置会更好,减轻对构建、部署环境的依赖。当然,在这些环境中,最好用良好的设计避免配置代理上网。 Docker Build 代理 虽然 docker build 的本质,也是启动一个容器,但是环境会略有不同,用户级配置无效。在构建时,需要注入 http_proxy 等参数。 docker build . \ --build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \ --build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \ --build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \ -t your/image:tag 注意:无论是 docker run 还是 docker build,默认是网络隔绝的。如果代理使用的是 localhost:3128 这类,则会无效。这类仅限本地的代理,必须加上 --network host 才能正常使用。而一般则需要配置代理的外部IP,而且代理本身要开启 Gateway 模式。 重启生效 代理配置完成后,reboot 重启当然可以生效,但不重启也行。 docker build 代理是在执行前设置的,所以修改后,下次执行立即生效。Container 代理的修改也是立即生效的,但是只针对以后启动的 Container,对已经启动的 Container 无效。 dockerd 代理的修改比较特殊,它实际上是改 systemd 的配置,因此需要重载 systemd 并重启 dockerd 才能生效。 sudo systemctl daemon-reload sudo systemctl restart docker 官方示例 下面是来自 官方文档 的操作步骤和详细解释: 创建 dockerd 相关的 systemd 目录,这个目录下的配置将覆盖 dockerd 的默认配置 $ sudo mkdir -p /etc/systemd/system/docker.service.d 新建配置文件 /etc/systemd/system/docker.service.d/http-proxy.conf,这个文件中将包含环境变量 [Service] Environment="HTTP_PROXY=http://proxy.example.com:80" Environment="HTTPS_PROXY=https://proxy.example.com:443" 如果你自己建了私有的镜像仓库,需要 dockerd 绕过代理服务器直连,那么配置 NO_PROXY 变量: [Service] Environment="HTTP_PROXY=http://proxy.example.com:80" Environment="HTTPS_PROXY=https://proxy.example.com:443" Environment="NO_PROXY=your-registry.com,10.10.10.10,*.example.com" 多个 NO_PROXY 变量的值用逗号分隔,而且可以使用通配符(*),极端情况下,如果 NO_PROXY=*,那么所有请求都将不通过代理服务器。 重新加载配置文件,重启 dockerd $ sudo systemctl daemon-reload $ sudo systemctl restart docker 检查确认环境变量已经正确配置: $ sudo systemctl show --property=Environment docker 从 docker info 的结果中查看配置项。 这样配置后,应该可以正常拉取 docker 镜像。 总结 提供一种生产环境可选方式 内网环境可以通过 sonatype 或者 harbor 搭建私有注册服务器,然后在私有注册服务上配置隧道代理,让私有注册服务通过隧道代理缓存外部镜像。这么做即可以减少容器运行时配置隧道代理复杂性,可以在后续使用中从本地私有注册服务中获取镜像,内网使用速度更快,而且可以保证本地镜像重用。 两种工具都提供多样的部署策略,如本地化部署,docker 方式,和 k8s 方式。 在部署复杂度方面, harbor 依赖 redis 和 postgres ,对于运维能力要求较高。sonatype 可以使用内嵌本地数据库,在部署时记得做好数据备份。 相关链接: docker ce install config docker proxy config docker registry mirror How to run “sudo apt-get update” through proxy in commandline? config containerd registry 方案组合: dockerhub --> proxy --> docker daemon dockerhub --> cloudflare --> docker daemon dockerhub --> cloudflare --> nexus-rm --> docker daemon dockerhub --> proxy --> nexus-rm --> docker daemon 其他组合 使用私服和不使用私服最大的区别就是是否在本地环境缓存一份远程镜像。在使用私服的情况下,即使断网或者代理不通,依然可以在内网环境继续使用已经缓存了的镜像,还有就是命中已经缓存的镜像在内网速度更快。 提供一种服务器快捷部署特定梯子的方式 xtls 是一个功能强大的代理软件,当你有代理服务时,可以通过容器化的方式在服务器部署客户端,供内网其他程序使用。 x-base: &default-config restart: unless-stopped ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000 stop_grace_period: 1m logging: driver: json-file options: max-size: '100m' max-file: '1' mem_swappiness: 0 services: v2ray: image: teddysun/xray container_name: xray <<: *default-config ports: - 1080:1080 - 1081:1081 volumes: - ${PWD}/config.json:/etc/xray/config.json networks: default: external: true name: other 最后建议大家在使用社区提供的镜像加速时,额外关注镜像安全方面的问题,尽可能使用可信的镜像,特别是在生产环境中。因为大多数使用 docker 都是以特权模式运行,在其他容器运行时环境中的特定需求中也会使用特权模式运行容器。如果容器存在漏洞后门,或者植入挖矿脚本,会带来风险性问题。 Qnap docker 代理配置 登录 nas ssh 命令行 sudo -i切换 admin 操作 cd /share/CACHEDEV2_DATA/.qpkg/container-station/script 测试时container安装在/share/CACHEDEV2_DATA/,自己环境根据自己的路径修改 vi run-docker.sh 倒数第二行加入(改成自己的网段与端口): export http_proxy="http://192.168.168.89:7890" export https_proxy="http://192.168.168.89:7890" export no_proxy= "192.168.168.0/24,localhost,127.0.0.1,::1" 重启 container /etc/init.d/container-station.sh restart Docker Hub 镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。 Dockerized 实践 https://github.com/y0ngb1n/dockerized 国内的 Docker Hub 镜像加速器,由国内教育机构与各大云服务商提供的镜像加速服务 | Dockerized 实践 https://github.com/y0ngb1n/dockerized Docker daemon 配置代理 参考 Docker daemon 配置代理 自建镜像加速服务 自建镜像仓库代理服务 利用 Cloudflare Workers 自建 Docker Hub 镜像 国内三方加速镜像 ⚠️⚠️⚠️ 自 2024-06-06 开始,国内的 Docker Hub 镜像加速器相继停止服务,可选择为 Docker daemon 配置代理或自建镜像加速服务。 Ubuntu 16.04+、Debian 8+、CentOS 7+ 创建或修改 /etc/docker/daemon.json: sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://dockerproxy.com", "https://docker.mirrors.ustc.edu.cn", "https://docker.nju.edu.cn" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker Docker Hub 镜像加速器列表 Docker 官方和国内很多云服务商都提供了国内加速器服务。以下镜像站来源于互联网(感谢热心网友),可能出现宕机、转内网、关停等情况,建议同时配置多个镜像源。 镜像加速器 镜像加速器地址 专属加速器? 其它加速? Docker 中国官方镜像 https://registry.docker-cn.com Docker Hub(已关闭) DaoCloud 镜像站 https://docker.m.daocloud.io Docker Hub、GCR、K8S、GHCR、Quay、NVCR 等 Azure 中国镜像 https://dockerhub.azk8s.cn 仅供内部访问 Docker Hub、GCR、Quay 科大镜像站 https://docker.mirrors.ustc.edu.cn 仅供内部访问 Docker Hub、GCR、Quay 阿里云 https://<your_code>.mirror.aliyuncs.com 需登录,系统分配 Docker Hub 七牛云 https://reg-mirror.qiniu.com Docker Hub、GCR、Quay 网易云 https://hub-mirror.c.163.com Docker Hub 腾讯云 https://mirror.ccs.tencentyun.com 仅供内部访问 Docker Hub Docker 镜像代理 https://dockerproxy.com Docker Hub、GCR、K8S、GHCR 百度云 https://mirror.baidubce.com Docker Hub 南京大学镜像站 https://docker.nju.edu.cn Docker Hub、GCR、GHCR、Quay、NVCR 等 上海交大镜像站 https://docker.mirrors.sjtug.sjtu.edu.cn Docker Hub、GCR 等(已关闭) 中科院软件所镜像站 https://mirror.iscas.ac.cn Docker Hub ⚠️ 部分网友反馈以下镜像站存在未同步最新源镜像问题,请按需选用(评论区可考古) 阿里云 检查加速器是否生效 命令行执行 docker info,如果从结果中看到了如下内容,说明配置成功。 Registry Mirrors: [...] https://docker.m.daocloud.io Docker Hub 镜像测速 使用镜像前后,可使用 time 统计所花费的总时间。测速前先移除本地的镜像! $ docker rmi node:latest $ time docker pull node:latest Pulling repository node [...] real 1m14.078s user 0m0.176s sys 0m0.120s Hexo入门篇 Hexo 通用简明教程 Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 前提 安装 Hexo 相当简单,只需要先安装下列应用程序即可: Node.js (Node.js 版本需不低于 8.10,建议使用 Node.js 10.0 及以上版本) Git nmp 安装 所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。 npm install -g hexo-cli 安装以后,可以使用以下两种方式执行 Hexo: npx hexo 将 Hexo 所在的目录下的 node_modules 添加到环境变量之中即可直接使用: hexo echo 'PATH="$PATH:./node_modules/.bin"' >> ~/.profile 升级 后期需要升级的化,进入 blog 目录,先检查更新: $ npm outdated Package Current Wanted Latest Location hexo 3.9.0 3.9.0 4.2.0 hexo-site hexo-deployer-git 1.0.0 1.0.0 2.1.0 hexo-site hexo-generator-archive 0.1.5 0.1.5 1.0.0 hexo-site hexo-generator-category 0.1.3 0.1.3 1.0.0 hexo-site hexo-generator-feed 1.2.2 1.2.2 2.2.0 hexo-site hexo-generator-index 0.2.1 0.2.1 1.0.0 hexo-site hexo-generator-tag 0.2.0 0.2.0 1.0.0 hexo-site hexo-renderer-ejs 0.3.1 0.3.1 1.0.0 hexo-site hexo-renderer-marked 0.3.2 0.3.2 2.0.0 hexo-site hexo-renderer-stylus 0.3.3 0.3.3 1.1.0 hexo-site hexo-server 0.3.3 0.3.3 1.0.0 hexo-site 修改 package.json 文件,基于 Latest 列内容更新版本号,然后更新并检查版本号: $ npm install --save # 检查版本号 $ hexo -v hexo: 4.2.0 hexo-cli: 3.1.0 ...... 建站 安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。 hexo init <folder> cd <folder> npm install 启动网页服务 此时,通过 hexo s 命令即可在本地启动您的博客站点了。 $ hexo s INFO Start processing INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop. 接下来将安装主题,配置博客托管平台,实现一键发布并刷新 CDN 缓存。 npm下载加速 安装淘宝镜像, 加速NPM npm config set registry http://registry.npmmirror.com 安装CNPM 个人使用体验来说,npm兼容性最好,如果你遇到某个包cnpm或者yarn安装失败,试试最原始的老婆吗,或许有奇效! npm install -g cnpm --registry=http://registry.npmmirror.com Hexo 日常操作命令 # 进入hexo docker 环境。需要你已经安装了docker环境,并安装了上文提到的hexo docker docker exec -it hexo /bin/bash # 运行完这条命令后,你就发现命令提示符变了,你此时进入了一个独立于你的主机运行环境的新的 node + hexo 开发环境了。 # 生成新页面 404 hexo new page 404 # 新增新文章 2022-03-26-blog.17lai.site hexo new post 2022-03-26-blog.17lai.site # 清理上次生成的静态网页,可以不运行,但你修改了一些源码后,很可能有各种不生效或错误 hexo clean # 生成静态网页 hexo g # gulp调用gulpfile.js压缩静态网页相关代码,减小网页体积 gulp # 调用根目录中 _config.yml 文件的deploy配置的参数来部署你的静态网页 hexo d hexo 目录结构说明 在执行过Hexo deploy命令之后,目录结构新增了.deploy_git,public,.gitignore,如下: $ tree -L 2 . ├── .deploy_git ├── node_modules ├── public ├── scaffolds │ ├── draft.md │ ├── page.md │ └── post.md ├── source │ ├── _posts │ ├── _drafts ├── themes ├── _config.yml ├── db.json ├── package.json └── package-lock.json _config.yml 用来配置博客相关的参数,初始化时自动创建。具体参数设置,可参照 Hexo 配置 文档。 node_modules 和 package.json 都是在初始化时自动创建。 node_modules用来存储已安装的各类依赖包。 package.json用来查看 Hexo 的版本以及相关依赖包的版本。 Hexo 会默认安装: hexo:主程序 hexo-deployer-git:实现 git 部署方式 hexo-generator-archive:存档页面生成器 hexo-generator-category:分类页面生成器 hexo-generator-index:index 生成器 hexo-generator-tag:标签页面生成器 hexo-renderer-ejs:支持 EJS 渲染 hexo-renderer-marked:Markdown 引擎 hexo-renderer-stylus:支持 stylus 渲染 hexo-server:支持本地预览,默认地址 localhost:4000 新安装的依赖包,也会保存在node_module文件夹下。 scaffold 模板文件夹,初始化时自动创建。包含page,post,draft三种模板,分别对应 页面、要发布的文章、草稿。 themes 主题文件夹,初始化时自动创建。每一个主题,都有一个单独的文件夹。默认主题为 landscape。 source , public 和 .deploy_git source:资源文件夹。用来存放图片、Markdown 文档(文章、草稿)、各种页面(分类、关于页面等)。 public:将 source 文件夹里的 Markdown 文档,转换成 index.html。再结合主题进行渲染,就是我们最终看到的博客。 .deploy_git:将 public 文件夹的内容提交到 Github 后生成,内容与 public 文件夹基本一致。 这三者的关系大致是:source -> public -> .deploy_git 执行hexo generate,根据 source,更新 public。 执行hexo deploy,根据 public,更新 .deploy_git。 常用命令 指令说明 hexo server #启动本地服务器,用于预览主题。Hexo 会监视文件变动并自动更新,除修改站点配置文件外,无须重启服务器,直接刷新网页即可生效。 hexo server -s #以静态模式启动 hexo server -p 5000 #更改访问端口 (默认端口为 4000,’ctrl + c’关闭 server) hexo server -i IP地址 #自定义 IP hexo clean #清除缓存 ,网页正常情况下可以忽略此条命令,执行该指令后,会删掉站点根目录下的 public 文件夹 hexo g #生成静态网页 (执行 $ hexo g后会在站点根目录下生成 public 文件夹, hexo 会将”/blog/source/“ 下面的.md 后缀的文件编译为.html 后缀的文件,存放在”/blog/public/ “ 路径下) hexo d #自动生成网站静态文件,并将本地数据部署到设定的仓库(如 github) hexo init 文件夹名称 #初始化 XX 文件夹名称 npm update hexo -g#升级 npm install hexo -g #安装 node -v #查看 node.js 版本号 npm -v #查看 npm 版本号 git --version #查看 git 版本号 hexo -v #查看 hexo 版本号 hexo new page “music” #新增页面music hexo new post “文章名称” #新增文章 简写指令 hexo n "我的第一篇文章" 等价于 hexo new "我的第一篇文章" 还等价于 hexo new post "我的第一篇文章" hexo p 等价于 hexo publish hexo g 等价于 hexo generate hexo s等价于 hexo server hexo d 等价于 hexo deploy hexo g -d等价于hexo generate --deploy 注: hexo clean 没有 简写, git --version 没有简写 hexo版本升级 Docker镜像直接提供最新版本node ,hexo 升级 Node # n 是交互式 node.js 版本管理工具 sudo npm install -g n # 更新到 node 16 LTS sudo n 16 升级 Hexo # 安装 npm-check 和 npm-upgrade npm install -g npm-check npm-upgrade # 检查本地插件版本 npm-check # 交互式升级,根据提示即可完成升级 npm-upgrade 现在 Hexo 及插件已经升级成功,执行 hexo version 查看版本。 设置npm源的几种方式 原始源 # the original source https://registry.npmjs.org/ 方案: 使用nrm 安装 npm install -g nrm 列出源的候选项 nrm ls 输出结果: * npm -------- https://registry.npmjs.org/ yarn ------- https://registry.yarnpkg.com/ cnpm ------- http://r.cnpmjs.org/ taobao ----- https://registry.npmmirror.com/ nj --------- https://registry.nodejitsu.com/ npmMirror -- https://skimdb.npmjs.com/registry/ edunpm ----- http://registry.enpmjs.org/ 使用淘宝源 nrm use taobao 方案: 改变全局的注册 设置成淘宝源 npm config set registry https://registry.npmmirror.com 查看结果 npm config get registry 输出结果: https://registry.npmmirror.com/ 测试一下 npm info underscore 方案: 在命令行里指定源 npm --registry https://registry.npmmirror.com install [name] 方案: 修改 ~/.npmrc registry = https://registry.npmmirror.com 方案: 使用cnpm npm install -g cnpm --registry=https://registry.npmmirror.com cnpm install [name] Hexo基础配置篇 下载主题 hexo-theme-matery 是一个采用 Material Design 和响应式设计的 Hexo 博客主题,点击 这里 可以查看示例效果。点击 这里 下载 master 分支的最新稳定版的代码,解压缩后,将 hexo-theme-matery 的文件夹复制到 Hexo 的 themes 文件夹中即可。 Docker环境命令 git clone https://github.com/blinkfox/hexo-theme-matery.git /app/themes/matery; 切换主题 修改 Hexo 根目录下的 _config.yml 的 theme 的值:theme: hexo-theme-matery _config.yml 文件的其它修改建议 请修改 _config.yml 的 url 的值为你的网站主 URL(如:http://xxx.github.io)。 建议修改两个 per_page 的分页条数值为 6 的倍数,如:12、18 等,这样文章列表在各个屏幕下都能较好的显示。 如果是中文用户,则建议修改 language 的值为 zh-CN。 在本主题的 _config.yml 中可以修改部分自定义信息,有以下几个部分: 菜单 我的梦想 首页的音乐播放器和视频播放器配置 是否显示推荐文章名称和按钮配置 favicon 和 Logo 个人信息 TOC 目录 文章打赏信息 复制文章内容时追加版权信息 MathJax 文章字数统计、阅读时长 点击页面的’爱心’效果 我的项目 我的技能 我的相册 Gitalk、Gitment、Valine 和 disqus 评论配置 不蒜子统计和谷歌分析(Google Analytics) 默认特色图的集合。当文章没有设置特色图时,本主题会根据文章标题的 hashcode 值取余,来选择展示对应的特色图 新建主题必备about、tags、404等页面 新建分类 categories 页 categories 页是用来展示所有分类的页面,如果 source 目录下还没有 categories/index.md 文件,那么就需要新建一个,命令如下: hexo new page "categories" 编辑你刚刚新建的页面文件 /source/categories/index.md,至少需要以下内容: --- title: categories date: 2018-09-30 17:25:30 type: "categories" layout: "categories" --- 新建标签 tags 页 tags 页是用来展示所有标签的页面,如果 source 目录下还没有 tags/index.md 文件,那么就需要新建一个,命令如下: hexo new page "tags" 编辑刚刚新建的页面文件 /source/tags/index.md,至少需要以下内容: --- title: tags date: 2018-09-30 18:23:38 type: "tags" layout: "tags" --- 新建留言板 contact 页 contact 页是用来展示留言板信息的页面,如果在你的博客 source 目录下还没有 contact/index.md 文件,那么你就需要新建一个,命令如下: hexo new page "contact" 编辑你刚刚新建的页面文件 /source/contact/index.md,至少需要以下内容: --- title: contact date: 2018-09-30 17:25:30 type: "contact" layout: "contact" --- 注:本留言板功能依赖于第三方评论系统,请激活你的评论系统才有效果。并且在主题的 _config.yml 文件中,第 19 至 21 行的“菜单”配置,取消关于留言板的注释即可。 新建友情链接 friends 页 friends 页是用来展示友情链接信息的页面,如果在你的博客 source 目录下还没有 friends/index.md 文件,那么你就需要新建一个,命令如下: hexo new page "friends" 编辑你刚刚新建的页面文件 /source/friends/index.md,至少需要以下内容: --- title: friends date: 2018-12-12 21:25:30 type: "friends" layout: "friends" --- 同时,在你的博客 source 目录下新建 _data 目录,在 _data 目录中新建 friends.json 文件,文件内容如下所示: [{ "avatar": "https://blog.17lai.site/favicon.png", "name": "夜法之书的Blog", "introduction": "嵌入式,Linux Kernel&Driver, PT, Docker, Nas等等", "url": "https://blog.17lai.site", "title": "前去学习" },{ "avatar": "http://image.luokangyuan.com/1_qq_27922023.jpg", "name": "码酱", "introduction": "我不是大佬,只是在追寻大佬的脚步", "url": "http://luokangyuan.com/", "title": "前去学习" }, { "avatar": "http://image.luokangyuan.com/4027734.jpeg", "name": "闪烁之狐", "introduction": "编程界大佬,技术牛,人还特别好,不懂的都可以请教大佬", "url": "https://blinkfox.github.io/", "title": "前去学习" }, { "avatar": "http://image.luokangyuan.com/avatar.jpg", "name": "ja_rome", "introduction": "平凡的脚步也可以走出伟大的行程", "url": "https://me.csdn.net/jlh912008548", "title": "前去学习" }] 新建关于我 about 页 about 页是用来展示关于我和我的博客信息的页面,如果 source 目录下还没有 about/index.md 文件,那么就需要新建一个,命令如下: hexo new page "about" 编辑刚刚新建的页面文件 /source/about/index.md,至少需要以下内容: --- title: about date: 2018-09-30 17:25:30 type: "about" layout: "about" --- 新建404页 新建一个404.md文件 在hexo的souce文件夹下创建一个404.md,之后输入如下内容: --- title: 404 date: 2019-11-23 21:10:10 type: "404" layout: "404" --- 然后hexo g生成页面中就有404。只是页面较丑。 404页面美化 下载404特效 点击下载代码:点我去代码出处 移植 放入js文件到主题中 将下载的压缩包解压,会发现里面有两个js文件和一个html页面,重要的就是js文件,将文件移植到主题的source文件的libs文件夹下,需要自己创建一个文件夹,我给文件夹取的名字叫做404。 导入404 js 因为该主题的js文件都是写_config.yml文件里面的,为了规范,也需要将文件的路径写到该文件夹下 如下,之后导入js文件的时候就可以使用404bodymovin和404data来代替了 编辑404.esj <style type="text/css"> /* don't remove. */ .page404-cover { /* height: 75vh; */ height: 88vh; } #svgContainer { width: 100%; height: 100%; background-color: white; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } </style> <script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.404bodymovin) %>"></script> <script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.404data) %>"></script> <div class="bg-cover pd-header page404-cover"> <div id="svgContainer"></div> <script type="text/javascript"> var svgContainer = document.getElementById('svgContainer'); var animItem = bodymovin.loadAnimation({ wrapper: svgContainer, animType: 'svg', loop: true, animationData: JSON.parse(animationData) }); </script> </div> 现在就移植成功了,使用下面命令上传,之后输入一个错误的页面就可以查看到了 hexo cl && hexo g -d Tips: 不要再本地试验,本地的时候输入错误的页面不会显示404页面的。 新建友情连接 friends 页(可选的) friends 页是用来展示友情连接信息的页面,如果 source 目录下还没有 friends/index.md 文件,那么就需要新建一个,命令如下: hexo new page "friends" 编辑刚刚新建的页面文件 /source/friends/index.md,至少需要以下内容: --- title: friends date: 2018-12-12 21:25:30 type: "friends" layout: "friends" --- 同时,在 source 目录下新建 _data 目录,在 _data 目录中新建 friends.json 文件,文件内容如下所示: [{ "avatar": "https://blog.17lai.site/favicon.png", "name": "和博主交换链接", "introduction": "如何和博主交换友情链接介绍。", "url": "https://blog.17lai.site/friends", "title": "前去交换" },{ "avatar": "https://images.weserv.nl?url=https://einverne.github.io/images/favicon.ico", "name": "Ein Verne的Blog", "introduction": "毅力帝!坚持写了99页的独立BLog博主!", "url": "https://blog.einverne.info/", "title": "前去学习" },{ "avatar": "https://images.weserv.nl?url=https://blinkfox.github.io/favicon.png", "name": "闪烁之狐", "introduction": "Matary 主题的作者。", "url": "https://blinkfox.github.io/", "title": "前去学习" }] 菜单导航配置 配置基本菜单导航的名称、路径url和图标icon. 1.菜单导航名称可以是中文也可以是英文(如:Index或主页) 2.图标icon 可以在Font Awesome 中查找 menu: Index: url: / icon: fas fa-home Tags: url: /tags icon: fas fa-tags Categories: url: /categories icon: fas fa-bookmark Archives: url: /archives icon: fas fa-archive About: url: /about icon: fas fa-user-circle Friends: url: /friends icon: fas fa-address-book 二级菜单配置方法 如果你需要二级菜单则可以在原基本菜单导航的基础上如下操作 在需要添加二级菜单的一级菜单下添加children关键字(如:About菜单下添加children) 在children下创建二级菜单的 名称name,路径url和图标icon. 注意每个二级菜单模块前要加 -. 注意缩进格式 menu: Index: url: / icon: fas fa-home Tags: url: /tags icon: fas fa-tags Categories: url: /categories icon: fas fa-bookmark Archives: url: /archives icon: fas fa-archive About: url: /about icon: fas fa-user-circle-o Friends: url: /friends icon: fas fa-address-book Medias: icon: fas fa-list children: - name: Music url: /music icon: fas fa-music - name: Movies url: /movies icon: fas fa-film - name: Books url: /books icon: fas fa-book - name: Galleries url: /galleries icon: fas fa-image 文章 Front-matter 介绍 Front-matter 选项详解 Front-matter 选项中的所有内容均为非必填的。但仍然建议至少填写 title 和 date 的值。 配置选项 默认值 描述 title Markdown 的文件标题 文章标题,强烈建议填写此选项 date 文件创建时的日期时间 发布时间,强烈建议填写此选项,且最好保证全局唯一 author 根 _config.yml 中的 author 文章作者 img featureImages 中的某个值 文章特征图,推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如: http://xxx.com/xxx.jpg top true 推荐文章(文章是否置顶),如果 top 值为 true,则会作为首页推荐文章 hide false 隐藏文章,如果hide值为true,则文章不会在首页显示 cover false v1.0.2版本新增,表示该文章是否需要加入到首页轮播封面中 coverImg 无 v1.0.2版本新增,表示该文章在首页轮播封面需要显示的图片路径,如果没有,则默认使用文章的特色图片 password 无 文章阅读密码,如果要对文章设置阅读验证密码的话,就可以设置 password 的值,该值必须是用 SHA256 加密后的密码,防止被他人识破。前提是在主题的 config.yml 中激活了 verifyPassword 选项 toc true 是否开启 TOC,可以针对某篇文章单独关闭 TOC 的功能。前提是在主题的 config.yml 中激活了 toc 选项 mathjax false 是否开启数学公式支持 ,本文章是否开启 mathjax,且需要在主题的 _config.yml 文件中也需要开启才行 summary 无 文章摘要,自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要 categories 无 文章分类,本主题的分类表示宏观上大的分类,只建议一篇文章一个分类 tags 无 文章标签,一篇文章可以多个标签 keywords 文章标题 文章关键字,SEO 时需要 reprintPolicy cc_by 文章转载规则, 可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprint 或 pay 中的一个 注意: 如果 img 属性不填写的话,文章特色图会根据文章标题的 hashcode 的值取余,然后选取主题中对应的特色图片,从而达到让所有文章都的特色图各有特色。 date 的值尽量保证每篇文章是唯一的,因为本主题中 Gitalk 和 Gitment 识别 id 是通过 date 的值来作为唯一标识的。 如果要对文章设置阅读验证密码的功能,不仅要在 Front-matter 中设置采用了 SHA256 加密的 password 的值,还需要在主题的 _config.yml 中激活了配置。有些在线的 SHA256 加密的地址,可供使用:开源中国在线工具、chahuo、站长工具。 以下为文章的 Front-matter 示例。 最简示例 --- title: 基于Hexo的hexo-theme-matery主题搭建博客并优化 date: 2019-10-03 14:25:00 --- 最全示例 --- title: 基于Hexo的hexo-theme-matery主题搭建博客并优化 date: 2019-12-30 09:25:00 author: 17lai.site img: /medias/cover/hexo.jpg top: true cover: true coverImg: /medias/cover/hexo.jpg password: 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 toc: false mathjax: false summary: 这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要 categories: Hexo keywords: Hexo GitHub blog tags: - Hexo - Blog - GitHub --- 新建文章模板修改 首先为了新建文章方便,我们可以修改一下文章模板,建议将/scaffolds/post.md修改为如下代码: --- title: {{ title }} date: {{ date }} author: img: coverImg: top: false cover: false toc: true mathjax: false password: summary: tags: categories: --- 这样新建文章后 一些Front-matter参数不用你自己补充了,修改对应信息就可以了。 代码高亮 从 Hexo5.0 版本开始自带了 prismjs 代码语法高亮的支持,本主题对此进行了改造支持。 如果你的博客中曾经安装过 hexo-prism-plugin 的插件,那么你须要执行 npm uninstall hexo-prism-plugin 来卸载掉它,否则生成的代码中会有 { 和 } 的转义字符。 然后,修改 Hexo 根目录下 _config.yml 文件中 highlight.enable 的值为 false,并将 prismjs.enable 的值设置为 true,主要配置如下: highlight: enable: false line_number: true auto_detect: false tab_replace: '' wrap: true hljs: false prismjs: enable: true preprocess: true line_number: true tab_replace: '' 主题中默认的 prismjs 主题是 Tomorrow Night,如果你想定制自己的主题,可以前往 prismjs 下载页面 定制下载自己喜欢的主题 css 文件,然后将此 css 主题文件取名为 prism.css,替换掉 hexo-theme-matery 主题文件夹中的 source/libs/prism/prism.css 文件即可。 添加文章搜索功能 这个插件比广大教程提到的hexo-generator-search插件更加强大和好用! matery目前只支持search.xml xml格式的搜索文件! 本主题中还使用到了 hexo-generator-searchdb 的 Hexo 插件来做内容搜索,安装命令如下: npm install hexo-generator-searchdb --save 在 Hexo 根目录下的 _config.yml 文件中,新增以下的配置项: search: path: search.xml field: post content: true format: html 参数含义 path - file path. By default is search.xml. If the file extension is .json, the output format will be JSON. Otherwise XML format file will be exported. field the search scope you want to search, you can chose: post (Default) - will only cover all the posts of your blog. page - will only cover all the pages of your blog. all - will cover all the posts and pages of your blog. content - whether contains the whole content of each article. If false, the generated results only cover title and other meta info without mainbody. By default is true. format the form of the page contents, options are: html (Default) - original html string being minified. striptags - original html string being minified, and remove all the tags. raw - markdown text of each posts or pages. 修改页脚 页脚信息可能需要做定制化修改,而且它不便于做成配置信息,所以可能需要你自己去再修改和加工。修改的地方在主题文件的 /layout/_partial/footer.ejs 文件中,包括站点、使用的主题、访问量等。 修改社交链接 在主题的 _config.yml 文件中,默认支持 QQ、GitHub 和邮箱的配置,可以在主题文件的 /layout/_partial/social-link.ejs 文件中,新增、修改需要的社交链接地址,增加链接可参考如下代码: <a href="https://github.com/appotry" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50" > <i class="fab fa-github"></i> </a> 其中,社交图标(如:fa-github)可以在 Font Awesome 中搜索找到。以下是常用社交图标的标识,供参考: Facebook: fa-facebook Twitter: fa-twitter Google-plus: fa-google-plus Linkedin: fa-linkedin Tumblr: fa-tumblr Medium: fa-medium Slack: fa-slack 新浪微博: fa-weibo 微信: fa-wechat QQ: fa-qq 修改打赏的二维码图片 在主题文件的 source/medias/reward 文件中,可以替换成你的的微信和支付宝的打赏二维码图片。 配置音乐播放器 支持接入第三方音乐,如 QQ 音乐,网易云音乐,酷狗音乐等等 主题的 _config.yml 配置文件中激活 music 配置即可: # Whether to display the musics. # 是否在首页显示音乐. music: enable: true title: #非吸底模式有效 enable: true show: 咕咕星的歌单 autoHide: true # hide automaticaly server: netease #require music platform: netease, tencent, kugou, xiami, baidu type: playlist #require song, playlist, album, search, artist id: 2888085740 #require song id / playlist id / album id / search keyword fixed: false # 开启吸底模式 autoplay: false # 是否自动播放 theme: '#42b983' loop: 'all' # 音频循环播放, 可选值: 'all', 'one', 'none' order: 'random' # 音频循环顺序, 可选值: 'list', 'random' preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' volume: 0.7 # 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 listFolded: true # 列表默认折叠 hideLrc: true # 隐藏歌词 server 可选 netease(网易云音乐),tencent(QQ 音乐),kugou(酷狗音乐),xiami(虾米音乐), baidu(百度音乐)。 type 可选 song(歌曲),playlist(歌单),album(专辑),search(搜索关键字),artist(歌手) id 获取示例:浏览器打开网易云音乐,点击我喜欢的音乐歌单,地址栏有一串数字,playlist 的 id 即为这串数字。 单独的音乐页面 效果如下: # Whether to display the musics. # 单独的音乐页面. musics: enable: true title: #非吸底模式有效 enable: true show: 听听音乐 server: netease #require music platform: netease, tencent, kugou, xiami, baidu type: playlist #require song, playlist, album, search, artist id: 4965675848 #require song id / playlist id / album id / search keyword fixed: false # 开启吸底模式 autoplay: true # 是否自动播放 theme: '#42b983' loop: 'all' # 音频循环播放, 可选值: 'all', 'one', 'none' order: 'random' # 音频循环顺序, 可选值: 'list', 'random' preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' volume: 0.7 # 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 listFolded: false # 列表默认折叠 listMaxHeight: "525px" #列表最大高度 开启配置方法如上,和 Matery 的音乐播放器配置参数差不多一样 server 可选 netease(网易云音乐),tencent(QQ 音乐),kugou(酷狗音乐),xiami(虾米音乐), baidu(百度音乐)。 type 可选 song(歌曲),playlist(歌单),album(专辑),search(搜索关键字),artist(歌手) id 获取示例:浏览器打开网易云音乐,点击我喜欢的音乐歌单,地址栏有一串数字,playlist 的 id 即为这串数字。 # 创建音乐页面 hexo new page musics # 编译网站 hexo g # 然后就可以在 [ip | 域名]/musics 这个链接访问到在线音乐页面 配置文章基本信息 new_post_name: :title.md # 新文章的文件名称 default_layout: post # 预设布局 auto_spacing: false # 在中文和英文之间加入空格 titlecase: false # 把标题转换为 title case external_link: # 在新标签中打开链接 enable: true # 在新标签中打开链接 field: # 对整个网站(site)生效或仅对文章(post)生效 exclude: # 需要排除的域名。主域名和子域名如 www 需分别配置 [] filename_case: 0 # 把文件名称转换为 (1) 小写或 (2) 大写 render_drafts: false # 显示草稿,默认为:false post_asset_folder: true # 启动 Asset 文件夹 relative_link: false # 把链接改为与根目录的相对位址 future: true # 显示未来的文章 highlight: # 代码块的设置 enable: false # 开启代码块高亮 line_number: false # 显示行数 auto_detect: false # 如果未指定语言,则启用自动检测 tab_replace: # 用 n 个空格替换 tabs;如果值为空,则不会替换 tabs 配置代码高亮及样式 从 Hexo5.0 版本开始自带了 prismjs 代码语法高亮的支持,本主题对此进行了改造支持。 如果你的博客中曾经安装过 hexo-prism-plugin 的插件,那么你须要执行 npm uninstall hexo-prism-plugin 来卸载掉它,否则生成的代码中会有 { 和 } 的转义字符。 然后,修改 Hexo 根目录下 _config.yml 文件中 highlight.enable 的值为 false,并将 prismjs.enable 的值设置为 true,主要配置如下: highlight: # 代码块的设置 enable: false # 开启代码块高亮 line_number: true # 显示行数 auto_detect: false # 如果未指定语言,则启用自动检测 tab_replace: '' # 用 n 个空格替换 tabs;如果值为空,则不会替换 tabs wrap: true hljs: false prismjs: enable: true preprocess: true line_number: true tab_replace: '' 注意事项 Hexo 内建的 PrismJS 支持浏览器端高亮(preprocess 设置为 false)和服务器端高亮(preprocess 设置为 true)两种方式。 使用服务器端高亮时(preprocess 设置为 true),只需要在站点引入 Prismjs 的主题(CSS 样式表)即可;而使用浏览器端高亮时(preprocess 设置为 false),需要将 JavaScript 文件也引入。 主题中默认的 prismjs 主题是 Tomorrow Night,如果你想定制自己的主题,可以前往 prismjs 下载页面 定制下载自己喜欢的主题 css 文件,然后将此 css 主题文件取名为 prism.css,替换掉 hexo-theme-matery 主题文件夹中的 source/libs/prism/prism.css 文件即可。 配置代码的样式 code: lang: true # 代码块是否显示名称 copy: true # 代码块是否可复制 shrink: false # 代码块是否可以收缩 break: false # 代码是否折行 配置是否启用转载限制模块 reprint: enable: false #是否启用“转载规则限定模块” default: cc_by 文章转载规则,可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprint 或 pay 中的一个 配置文章阅读密码功能 阅读文章的密码验证功能,如要使用此功能请激活该配置项,并在对应文章的 Front-matter 中写上 password 的键和加密后的密文即可。 请注意:为了保证密码原文不会被泄露到网页中,文章的密码必须是通过 SHA256 加密的,这样就不会被破解。 verifyPassword: enable: true promptMessage: 请输入访问本文章的密码 errorMessage: 密码错误,将返回主页! 如何一键部署hexo 通过 hexo-deployer-git 插件可以实现一键将博客同时部署到多个 git 仓库中。如同时发布到 github 及 gitee 提供的 pages 服务。安装: npm install hexo-deployer-git --save 修改 Hexo 根目录下的 _config.yml 文件中的如下内容: ## Docs: https://hexo.io/docs/deployment.html deploy: - type: git repo: https://github.com/appotry/blog.git branch: gh-pages ignore_hidden: false - type: git repo: https://gitee.com/appotry/blog.git branch: master ignore_hidden: false 也可以如本站一样,采用 hexo-deployer-cos-enhanced 插件将静态内容部署到腾讯云对象存储服务中,在 DNS 配置中将境内线路解析到腾讯云 CDN 地址,实现加速。部署完成后会自动刷新被更新文件的 CDN 缓存。 安装: npm install hexo-deployer-cos-enhanced --save _config.yml 配置如下: deploy: - type: git repo: https://github.com/appotry/blog.git branch: gh-pages ignore_hidden: false - type: cos bucket: hexo-130**** region: ap-beijing secretId: AKIDh9****F8FvL secretKey: Z3IGiur****QZR3PgjXmlVg cdnConfig: enable: true cdnUrl: https://static.17lai.site bucket: static-130**** region: ap-beijing folder: static secretId: AKIDh9****F8FvL secretKey: Z3IGiur****QZR3PgjXmlVg 然后通过 hexo g -d 即可实现一键发布,并更新 CDN 缓存。 文章链接转静态短地址(可选的) 如果文章名称是中文的,那么 Hexo 默认生成的永久链接也会有中文,这样不利于 SEO,且 gitment 评论对中文链接也不支持。我们可以用 hexo-permalink-pinyin Hexo 插件生成文章时生成中文拼音的永久链接,或者用hexo-abbrlink 生成静态文章链接。以下结合 hexo-abbrlink 生成类似 /yyyy/mmdd+随机数.html 的文章链接地址。 安装命令如下: npm install hexo-abbrlink --save npm下载太慢怎么办? 修改国内淘宝源加速,戳 在 Hexo 根目录下的 _config.yml 文件中,修改 permalink: ,并在文件末尾新增 abbrlink:配置项: permalink: :year/:month:day:abbrlink.html abbrlink: alg: crc16 #算法选项:crc16丨crc32 rep: dec #输出进制:dec为十进制,hex为十六进制 添加 emoji 表情支持(可选的) Matery主题新增了对 emoji 表情的支持,使用到了 hexo-filter-github-emojis 的 Hexo 插件来支持 emoji 表情的生成,把对应的 markdown emoji 语法(::, 例如::smile:)转变成会跳跃的 emoji 表情,安装命令如下 npm install hexo-filter-github-emojis --save npm下载太慢怎么办? 修改国内淘宝源加速,戳 在 博客根目录下的 _config.yml 文件中,新增以下的配置项: githubEmojis: enable: true className: github-emoji inject: true styles: customEmojis: 执行 hexo clean && hexo g 重新生成博客文件,然后就可以在文章中对应位置看到你用 emoji 语法写的表情了。 文章字数统计插件 如果你想要在文章中显示文章字数、阅读时长信息,可以安装 hexo-wordcount插件。 安装命令如下: npm i --save hexo-wordcount 然后只需在本主题下的 _config.yml 文件中,激活以下配置项即可: wordCount: enable: false # 将这个值设置为 true 即可. postWordCount: true min2read: true totalCount: true 添加 RSS 订阅支持 本主题中还使用到了 hexo-generator-feed 的 Hexo 插件来做 RSS,安装命令如下: npm install hexo-generator-feed --save 在 Hexo 根目录下的 _config.yml 文件中,新增以下的配置项: feed: type: atom path: atom.xml limit: 20 hub: content: content_limit: 140 content_limit_delim: " " order_by: -date 执行 hexo clean && hexo g 重新生成博客文件,然后在 public 文件夹中即可看到 atom.xml 文件,说明已经安装成功了。 hexo-feed 这个RSS插件更加强大,支持分类订阅,标签订阅。但对hexo 6.x没有做支持,虽然在hexo6.x上面工作正常。 增加百度统计功能 首先注册百度统计站长版,登陆后点击 新增网站,然后直接输入你的博客地址例如: https://blog.17lai.site,网站域名 和 网站首页 都写这个,网站名称 可以填 我的博客, 然后点击左侧菜单的 代码获取,找到 hm.src = "https://hm.baidu.com/hm.js?……" 问号后的这一段十六进制代码 # Add baidu analytics configuration # 添加 baidu Analytics 配置 baiduAnalytics: enable: false # 开启时设置为true 并填写正确的id id: f614xxxxxxxxxxxxxxxx05d25e Leancloud+Valine打造Hexo个人博客极简评论系统 Leancloud配置 首先访问Leancloud官网https://leancloud.cn/ 这样我们就创建好啦! 接着点击应用右上角的设置进入设置界面 选择应用key,这样就可以看到我们接下来需要使用到的key 接着进入应用中心绑定你的个人博客域名 Valine配置 然后我们去主题配置文件中进行修改 matery_config.yml # Valine. # You can get your appid and appkey from https://leancloud.cn # more info please open https://valine.js.org valine: enable: true //打开valine评论功能 appid: 你的leancloud appid appkey: 你的leancloud appkey notify: false //邮件提醒 verify: true //评论时是否有验证码,需要在Leancloud 设置->安全中心 中打开 placeholder: 说点什么吧! //评论框默认显示 avatar: hide //评论者的头像,我这里设置的不显示 guest_info: nick # custom comment header pageSize: 10 # pagination size PS:评论者头像可以进行如下设置 到此,一个极简评论系统就完成啦! 本教程还有其它五大部分,更多内容请见Hexo系列教程 系列教程 全部文章RSS订阅 Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab

2021/9/10
articleCard.readMore

Joplin 插件以及其Markdown语法。All in One!

Joplin是一个以Markdown为主要语法的笔记程序,发展到今天增加了许多插件,这些插件也大大增强了它的功能,今天我们就讲讲Joplin的各个插件的作用和使用方法。 首先我们打开Joplin,依次点击工具->选项设置页面,然后点击Markdown选项卡,我们就可以看到如下界面 下面我们一个一个讲解一下每个插件的大概作用和用法,某些插件的详细使用方法可能需要我独立写一篇文章来介绍,这里我就先抛砖引玉大致介绍一下。 启动软中断插件 Joplin默认使用的是硬中断方式,那么什么是软中断什么是硬中断呢?如果你刚开始使用Markdown撰写自己的笔记你可能会非常的不习惯,因为标准的Markdown语法里面换行需要两个回车符号,但是像word之类的编辑器都是一个回车,普通人会感觉很不习惯,所以Joplin默认采用了硬中断方式,这样你可以使用一个回车符实现换行。但是当我们启用软中断插件之后,我们就需要两个回车符来实现换行(准确说应该是分段),使用两个空格加一个回车来实现换行,前者的间距会比后者的大。启用软中断其实对于普通人来说不是很好用,很难适应,所以我不建议大家开启该插件! 启用typographer支持 这个插件的作用是用来申明我们的版权的,因为有时候我们可能需要将我们的笔记分享给别人,但是想要声明文章是我们写的,我们就可以启用该插件来声明我们的著作权,而且该插件会给我们渲染成指定的版权声明格式,讲讲怎么用: 我们启用插件之后,在我们想要声明著作权的地方键入: (c)著作权所有人 然后Joplin就会给我们渲染为: 是不是很熟悉,很多网页的底部都会有这个声明! 启用数学表达式 这个是Markdown自带语法,Joplin使用插件来实现的,其实就是大家在Markdown语法里面看到的行内公式使用 …,行间公式使用$$…$$。需要说明的是Joplin使用的是Katex来解析数学符号,它的语法和Latex的数学公式写法差不多,我到现在还没有碰到很大的不同的地方! 启用高亮==Mark==句法 这个其实就是一个语句高亮插件,中间的语句会被高亮显示,有助于我们对重要的内容进行强调,自己一试就一目了然了。 启用脚注 脚注的功能就是对文中的某一个特定的术语等进行解释补充说明,有点像是论文的参考文献,下面是一个简单的示例,相信大家一看就懂 根据图片你可能明白了脚注的使用方法:在我们想要使用脚注的地方使用[^唯一标识符]注明,然后在文章的最后使用响应的标识符进行说明即可,比如例子中的 [^lightzhan]:知乎搜索light zhan即可找到我了 注意那个冒号一定要是英文冒号,中文冒号可能无法被成功解析。 启用目录扩展 启用该扩展,我们就可以使用相应的语法在某个位置插入我们文章的目录,具体的语法为 [toc] 注意着是一个固定的符号,不需要改变什么,只需要在我们想要插入目录的地方放上**[toc]**即可,例如 上图最重要的就是坐上脚的[toc]指令,该指令自动生成了右边的整个目录! 启用下标~sub~和上标^sup^句法 一看到sub如果不小心就会认为这个是删除线,大错特错了,一定要明白两者的区别,删除线是左右都是两个波浪线,而这个只有一个波浪线,一定要搞清楚这个。下面我们看看这个插件的作用和用法。 这两个插件的作用其实很简单,就是下标和上标,看例子应该就明白的 启用术语表插件 对于这个插件得先知道什么是术语表。所谓的术语表其实可以理解为一个定义的列表,很多专业的书籍的前面都会有术语表,因为它需要给出书中所用术语的定义和解释。还不懂?我们在Joplin中启用该插件,然后新建一个笔记,输入如下文字: Qdown : Qdown是由lightzhan开发的全功能软件下载程序,这里是程序的介绍页哦:http://lightzhan.xyz/index.php/qdown/ LightZhan : 计算机爱好一名,爱折腾哎生活,*欢迎知乎关注lightzhan哦* 可以嵌入一些代码 定义第三段 这些文字会被解析显示为: 对比一下发现了什么没有?术语表的每一项由两个部分组成,第一部分是术语,第二部分是该术语的解释,多个术语及其解释组合在一起就组成了表,这就是术语表!需要特别注意的是术语表的书写格式是固定的,如果你想要快速上手,建议你拷贝上面我提供的示例进行修改,修改两下你就懂格式到底是怎么回事了! 启用缩写句法 这个插件很有意思,也很有用。你是否记得有些程序的按钮,当你把鼠标放上去的时候它会显示按钮的作用。不记得了?不存在,我们也使用例子来说明。下面我们启用缩写句法插件,然后新建笔记,在笔记里面输入: *[Qdown]: 由lightzhan开发 *[LightZhan]: 欢迎知乎关注我哦 Qdown 是由 LightZhan 开发的一款全协议下载器. 该文本会被Joplin显示为 这可能并不能完全显示出该插件的作用,因为截图的原因截不到,当我们把鼠标放在Qdown上面的时候,鼠标所在的位置处会弹出“由lightzhan”开发的提示。不理解的可以拷贝上面的代码到Joplin感受一下,记得要开启该插件哦!需要注意的是该句中对应的缩写词前后都要有空格,负责你可能看不到上面的效果。 启用Markdown emoji 该插件是用于在我们的笔记中插入表情的,这是一个简单的示例截图 详细的表情和表情的代码,可以参考这里。 启用++insert++句法 这个插件很好理解,一试便知道作用和用法了 说了那么多,就是在对应的文字下面显示一个下划线! Markdown是非常好用的笔记书写规范,记着,Markdown不是某一个软件,而是一个通用的笔记书写规范,通过使用该规范进行写作,解析器会按照规定的样式将其渲染显示出来,说得直白点就是用于文字排版的。 Markdown的排版语法 这里的讲解如果有不懂的可以参见下一节的示例: 标题。markdown的标题使用“#”符号开头,一级标题一个”#”,二级标题两个“#”(也就是“##”),以此类推三级标题四级标题…….,不同级的标题会被渲染为不同的大小和样式(根据各个软件和相应的主题而定); 粗体。markdown的粗体字使用两个“**”包裹即可,比如 “你好”解析后变为“你好”; 斜体。markdown的斜体使用“*”或者“_”包裹,比如“你好”解析显示为“你好”; 引用。markdown的引用使用“>”开头,大部分软件要求“>”要和引用内容之间有一个空格; 代码。对于程序员来说可能想要在文中插入代码,markdown是支持插入代码的,行间代码使用一个"`"符号包裹,注意这个符号是键盘左上角Esc下面的那个键,不是我们所谓的英文上一撇; 数学公式。markdown的数学解析一般使用latex语法,行内公式使用一个$包裹即可,行间公式使用两个$包裹; markdown的列表分为有序列表和无序列表。有序列表就是有序号,无序列表就是 无序号,有序列表就是在数字后面一个点,然后空一格写正文,比如:1. xxxxxxx,第二点需要新起一行2. xxxxxx。无序列表是使用“*”或者“-”开始,后面跟一个空格写上正文。 markdown的勾选框。markdown的勾选框使用- [ ],注意字符之间都是有空格的。比如:第一行- [ ] A,第二行- [ ] B。这样对应的渲染结果就是勾选框和对应的选项。注意字符之间的空格! 表格。markdown的表格非常易于理解,请看下面的示例。 示例代码和渲染结果 下面的示例左边是书写文字,右边是渲染结果,注意书写文字里面的标识符和内容之间的空格: 需要说明的是上面的粗体显示为了橘红色的字体,这是我自己设置的格式,这个等大家熟悉了后可以使用CSS设计自己喜欢的样式。下面是表格的渲染结果 (其中左边的源代码不用那样对齐 ,横线的个数一处最少3个就行 ,右边是解析后的显示结果) : 额~,左边左下角那个是鼠标光标,不是文字内容哈。需要说明的是不同的软件的不同的主题可能显示的结果会不一样,但是书写的语法是不变的。 启用 multimarkdown 表格扩展 这个插件说高深也不高深,看名字应该就能知道这是一个增强Markdown表格功能的插件,大家记得Markdown的表格是怎么使用的吗?如果忘记的话赶紧看看这篇文章回顾一下,不然下面的内容可能体会不会那么深! 好啦,我这里假设读者知道markdown的表格是怎么用的,然后我们开始讲解multimarkdown扩展。Markdown自带的表格功能是非常有限的,如果你使用过的话就会发现它能做出来的表格一定是规整的,行和列一定是划分均匀整齐的,但是有时候我们需要的表格可能是这样的: 这种表格使用Markdown的表格是不可能做出来的,因为分组的效果和占用两个格子的效果是做不出来的,但是如果你启用了MultiMarkdown插件,你就可以使用下面的代码渲染出来: | | 分组 || 第一个表头 | 第二个表头 | 第三个表头 | ------------ | :-----------: | -----------: | 内容 | 占用两个格子 || 内容 | **内容** | 内容 | 新的一部分 | 更多 | 更多 | 更多 | 带有一个跳过的 '\|' || [LightZhan制作] 你可以把上面的代码拷贝进Joplin编辑器研究一番就能理解MultiMardown表格扩展的用法了,下面我详细讲解一下。 MultiMarkdown的表格扩展支持下面的功能: 使得元素占据多个列(上面的示例中有) 使得元素占据多个行 在表格上面或者下面对表头进行分组(上面的例子中有) 在表格的上面或者下面标注表格标题(上面的例子中有) 在表格中包含分块元素(列表、代码、段落等等) 表格不需要表头 上面标注了“上面的例子中有”的我这里就不在讲了,因为代码一研究或者修改修改就知道咋回事的,下面我们主要讲讲上面的例子中没有涉及到的。 1.使得表格占据多行。这个其实很好用,但是有两种情况。第一种情况是一个项目占据两格。这种情况要占据多行的话,在我们对应列的起始行写上内容,然后接下来要合并的行直接写“^^”。不明白不存在,我们来一个例子: 上面对应的代码是什么呢?看下面: 作者 | 信息 | 信息 | ----: | --------------: | ---------: | LightZhan | ligthzhan.xyz || ^^ | 更多Joplin教程 | Qdown下载器 | [LightZhan制作,允许规范转载] 把上面的代码拷贝进编辑器改改试试,很容易明白里面的玄机的! 第二种情况是我们添加块,看下面一点。 2.**在表格中添加块元素。**这个不用多说,直接在表格的格子里面用Markdown语法写作,渲染成对应的Markdown格式!比如加粗、斜体、代码块等等。下面来一个简单的例子,需要注意的是下面的例子当中我们的内容有几行! | Markdown | 渲染结果 | |--------------|---------------| | *斜体* | *斜体* | \ | | | | - 项目1 | - 项目1 | \ | - 项目2 | - 项目2 | | ```python | ```python \ | .1 + .2 | .1 + .2 \ | ``` | ``` | [LightZhan制作,允许规范转载] 注意代码后面的”\”,这个符号是指定换行的,如果项目占据多行一定要写上。上面的代码复制黏贴进编辑器可以看到下面的渲染结果 **3.表格不需要表头。**这个也很简单,直接不写表头即可。拷贝下面的代码进编辑器 ----: | --------------: | ---------: | LightZhan | lightzhan.xyz || ^^ | 更多Joplin教程 | Qdown下载器 | [LightZhan制作,允许规范转载] 然后你就可以看到惊喜 启用Fountain语法支持 这个插件的目标人群非常少,Fountain语法是用来写电影剧本的,而且要是要细讲的话估计又是一篇文章,因为使用的人非常少,所以我这里就不讲这个了。 Mermaid插件的作用 Mermaid是一个用于画流程图、时序图、类图、状态图、甘特图、饼图的Markdown扩展,其中状态图是最新8.4版本的新功能。如果你不知道这些图是干什么的,不存在,下面的教程里面我会每个都给出例子。 在Joplin里面使用Mermaid 在Joplin里面如果想要使用Mermaid,那么你需要使用代码块,并且代码的类型填写mermaid,详细的格式如下: ```mermaid graph TD Start --> Stop ``` 在渲染区我们就能得到如下的结果 Mermaid流程图 下面我们讲解在Mermaid里面画流程图。上一节的示例便是流程图,我们把上一节的代码拿出来分析一下。首先我们看代码的第一行:graph TD,这一行代码有两个作用,graph表示我们图的类型,graph表示流程图,而第二个TD表示图的方向,可能的方向有如下几个 TB:自顶向下 BT:自底向上 RL:从右到左 LR:从左到右 TD:和TB一样 上面我们的例子使用的是TD,如果你对其它的方向不明白,可以把代码拷贝到编辑器里面修改方向参数就可以理解各个方向的意义了。 上面的代码非常基础,因为如果要实现比较复杂的流程图,我们就需要使用一些比较高级的语法,比如定义节点。所谓的节点,你可以简单的理解为上面图片中的方框,但是如果我们要使用其它形状的节点怎么办呢?在上面的例子中我使用了默认的节点定义方法,也就是直接使用文本,这种方式定义节点的话id和显示文本是一样的,而且形状是固定的矩形。如果要定义不同的节点形状,或者使得id和显示文本不一样,可以使用下面的语法 定义矩形形状的节点:id[text] 定义圆角矩形的节点:id(text) 定义椭圆形的节点:id([text]) 定义圆柱形的节点:id[(text)] 定义圆形的节点:id((text)) 定义非对称图形的节点:id>text] 定义菱形的节点:id{text} 定义六角形的节点:id 定义平行四边形的节点(两个方向):id[/text/]或者[\text] 定义梯形的节点(两个方向):id[/text] 或者 di[\text/] 注意上面的id和text是需要我们自己定义替换的,如果同一个id有多个text,取最后一次的定义值! 有了节点我们还需要将节点连接起来,也就是我们要使用线条或者箭头来进行节点的连接,Mermaid支持下面的方式: 实线箭头:A–>B 实线无箭头:A–B 无箭头实线上带文本:A–text–B 实线箭头带文本:A–>|text|B 或者 A–text–>B 虚线箭头:A-.->B 虚线箭头带文本:A-.text.->B 粗线箭头:A==>B 粗线箭头带箭头:Atext>B 最好的办法就是把上面的代码拷贝进编辑器看看,一看你应该就能理解各个图形的形状! 上面我们讲解了节点和连线,下面我们说说图形的绘制。上面我使用的例子非常基础,下面来一个复杂点的例子供大家修改和研究 ```mermaid graph TD light[LightZhan] url[lightzhan.xyz] QdownUrl[访问LightZhan博客Qdown页面] Qdown((Qdown)) function[功能] Qdown-->|作者|light light--个人主页-->url Qdown-->function Qdown-->QdownUrl function1[极速下载] function2[磁链/BT下载] function3[迅雷下载] function5[下载体验] function4[Http/Https/FTP/SFTP] function-.功能1.->function1 function-.功能2.->function2 function-.功能3.->function3 function-.功能4.->function4 function-.更多功能.->function5 annocement[本文首发于lightzhan.xyz,允许规范转载] ``` 上面代码的渲染结果如下: 如果不清楚,可以把上面的代码拷贝到编辑器进行修改和摸索! Mermaid时序图 时序图是用于展示过程的方式和顺序的。举例来说,两个人之间的对话: A先问B:Qdown是啥?B回答:Qdown是全功能的下载软件!A又问:哪里可以下载呀?B回答: http://lightzhan.xyz/index.php/qdown/ 。我们使用mermaid绘制时序图来展示上面的对话过程: 这样是不是看上去清晰了很多了呢?希望通过这个例子能让你深切地感受到时序图是干什么用的!好了,放上上面的时序图的代码供大家研究: ```mermaid sequenceDiagram A->>B:Qdown是啥? B-->>A:Qdown是全功能的下载软件! A->>B:哪里可以下载呀? B-->>A:http://lightzhan.xyz/index.php/qdown/ ``` 让我们来简单分析一下上面的代码。你可能注意到了第一行的sequenceDiagram,这个就是告诉mermaid我们在这里绘制时序图,然后下面有箭头,在时序图里面,mermaid支持下面类型的箭头和线段: 实线并且没有箭头:A->B:text 虚线没有箭头:A–>B:text 实线带箭头:A->>B:text 虚线带箭头:A–>>B:text 实线并且在终点带一个x:A-xB:text 虚线并且在终点带一个x:A–xB:text 上面的text就是要显示在箭头或线段上的文本,在mermaid的时序图里面被称为消息,线段或箭头类型如果有不清楚的可以拷贝到编辑器里面看看,一目了然! 还记得上面我们在流程图里面的节点吗?在时序图里面不是定义节点,而是定义参与者,也就是上面的A和B。上面的代码中我们定义参与者的方式采用的是默认方式,也就是不显示定义,有时候我们的参与者的名字太长的话可以使用显示定义来定义别名: participant John participant Alice participant A as Alice participant J as John 上面代码的第一二行仅仅是显式定义我们的参与者,第三四行给我们的参与者定义别名,定义了别名后我们在下面的使用中就可以直接使用A代替Alice,使用J代替John了,这样输入会方便很多! 好了,时序图差不多就讲到这里,接下来的一些高级用法大部分我们都用不到,或者要使用的话不如使用专业的绘图软件使用插图的方式导入。 使用Mermaid绘制类图 类的定义 在讲解如何绘制类图之前我们先了解一下什么是类图!如果你是计算机专业或者会计算机编程的话应该就懂面向对象编程,对象是类的实例,而这里要绘制的类图就和面向对象编程里面的类相关。 对于编程人员来说,函数具有参数和返回值,属性具有变量类型,我们举一个例子来说一下: class BankAccount{ +String owner +BigDecimal balance +deposit(amount) bool +withdrawl(amount) } 上面的代码的渲染结果为: 上面的代码是我直接从官方借鉴的,可以直观地看出对于银行账户(BankAccount),一共有两个属性和两个方法,属性都是具有对应的变量类型,而对于函数具有参数(amount),并且deposit函数还具有bool类型的返回值。你或许看到了前面的+号,这个是对应变量或属性的可见性,分别有: + public – private # protected ~ Package/Internal 如果我们想要定义的函数是抽象函数咋办呢?在括号的后面添加*即可: someAbstractMethod()* 在渲染过后抽象函数会使用斜体进行显示,这里就不截图展示了。对于静态函数,将后面的*换为$即可,在显示时静态函数会具有下划线。 类之间的关系 在编程中我们常常会用到的关系: <|– 继承(Inheritance) *– 组成(Composition) o– 聚集(Aggregation) –> 关联(Association) — 实线(Link (Solid)) …> 依赖(Dependency) …|> 实现(Realization) … 虚线(Link (Dashed)) 下面我们举一个例子:“狗”继承自“动物”类别 ```mermaid classDiagram class 动物{ 特点1:能动 特点2:能叫 } class 狗{ 特点1:4条腿 特点2:会汪汪叫 特点3:可爱至极 汪汪叫(陌生人) } 动物 <|-- 狗 ``` 渲染结果为: 结合代码和展示结果应该很好理解,这就是一个狗继承自动物的简单例子,我们还可以对关系结果打标签: ```mermaid classDiagram class 动物{ 特点1:能动 特点2:能叫 } class 狗{ 特点1:4条腿 特点2:会汪汪叫 特点3:可爱至极 汪汪叫(陌生人) } 动物 <|-- 狗:属于(继承) ``` 我们在关系指示后面加上冒号,然后后面加上关系说明,这样在渲染结果当中我们就可以看到箭头上出现了我们需要的标签说明: 好了,使用mermaid绘制类图就讲到这里,还有一些用法不是很常用,我就不讲了。 使用mermaid绘制饼图 绘制饼图的需求比较多,很多数据展示需要我们绘制饼图,幸运的是mermaid给我们提供了绘制饼图的功能,使用方法极其简单: ```mermaid pie title LightZhan创作,允许规范转载(http://lightzhan.xyz) "Joplin" : 42.96 "Qdown" : 50.05 " 黑科技" : 10.01 "其它" : 5 ``` 在上面的代码中,pie关键字指定我们要绘制饼图,然后tiltile指定我们的标题,后面是数据分布,注意,mermaid会将我们输入的数据进行计算,上面的数据加起来并不是100,所以我们看到在下面的渲染结果中数据对应不上。 Joplin插件非常丰富,你能找到各种各样的功能,这里推荐一些插件使用,见下面这篇文章, Joplin插件推荐。 参考: lightzhan.xyz 系列教程 全部文章RSS订阅 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/9/9
articleCard.readMore

替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化

Evernote笔记是我们常用的一个笔记服务,国内叫印象笔记,免费版本的Evernote笔记其实已经足够我们使用了,但是对于重度的笔记用户,Evernote某些功能可能需要付费升级才可以使用,而且你的笔记是存放在Evernote的服务器上。 有些同学可能觉得放在Evernote服务器上的笔记会不安全,况且有些隐私性很强的笔记确实不适合放在公共的服务器上。此时,你需要一个可以保护个人隐私同时还可以与Evernote笔记功能相媲美的免费笔记服务:Joplin,它是一款免费开源的笔记软件。 Joplin跨平台支持,包括PC桌面端,移动端,甚至提供了命令行版本,原生支持 markdown 格式,搜索速度快,可以通过其他第三方同步工具 (Dropbox/NextCloud/OneDrive/WebDAV/etc) 进行备份以及同步 ,支持浏览器Web clipper即网页剪贴。 Evernote笔记该有的功能Joplin都有了,如果你不想掏钱购买Evernote付费版本,Joplin将是最佳的替代品。更多的自建服务还有: Chevereto免费相册程序安装与使用-免费自建图床和公共图片相册 自建RSS阅读器Tiny Tiny RSS安装和配置自动更新,全文RSS,更换主题,手机RSS登录 放弃付费1Password改用免费开源的bitwarden_rs自建密码管理系统-安装,使用和备份 PS:更新记录 1、平时经常要校对文本,以及有大量的文件需要在电脑和移动硬盘同步,可以试试这些免费的同步对比工具:八大免费的文件对比同步工具-免费文件对比分析与复制同步备份软件。2021.3.24 2、对于1Password这类的密码管理软件重度依赖,但是苦于囊中羞涩的话,不防自建密码管理平台:Bitwarden自建密码存储系统图文教程-开源免费的bitwarden_rs安装与使用。2020.10.10 一、Joplin安装和使用 网站: https://joplinapp.org/ 直接到官网下载Joplin安装包,安装好了就可以启动Joplin了,以下是Joplin的软件界面,分成三栏,和我们平时熟悉的笔记软件是一样的。(点击放大) 这是Joplin的编辑器,支持 MarkDown,图片、数学公式、复选框等 MarkDown 语法。 不习惯MarkDown,直接切换为可视编辑即可。 在Joplin的设置选项中还提供了非常多的MarkDown的插件,对于MarkDown深度用户来是一个福音。 二、Joplin的特色功能 2.1 笔记历史版本 Joplin提供了笔记历史版本,让你轻松地恢复任意时间的笔记版本。在“工具” > “选项” > “笔记历史”中启用,以及设置保留的笔记历史天数。要查看笔记的历史版本,点击编辑器上方的笔记属性图标,然后选择恢复: 2.2 E2EE安全加密 在同步过程中,笔记本、笔记、标签等均以纯文本文件的方式同步,如果你还觉得不安全,你可以开启端到端加密(E2EE),把文件加密后同步到云端。由于 Joplin 的去中心化,密码必须手动在每个终端设置。 **注意:不要在多个设备上同时启用加密,否则可能会造成加密密钥问题。特别提醒:**加密之前,先将笔记导出JEX备份一份,以防万一。 2.3 Joplin手机APP Joplin可以直接在各大应用市场上下载,使用起来也很方便。 2.4 外部编辑器 Joplin自带的编辑已经非常强大的,如果你想要使用自己的编辑器来编辑笔记也是可以的,包括 文本编辑器(如 Notepad++)、 Markdown 编辑器(如 Typora)等。 通过 Ctrl+E,或 Joplin 编辑器上方的图标(如下图)从外部编辑器打开笔记,从外部编辑器打开后,Joplin 将持续监控该文件,当你从外部编辑机保存后,Joplin 将自动同步最新变动。 你可以在“工具” > “选项” > “通用选项”中指定编辑器的路径。 三、Joplin同步与备份 Joplin与其它的笔记软件很大的不同就是没有存储功能,你需要将Joplin的笔记放在自己的主机或者网盘里,幸运的是Joplin支持多种方式的云同步:Nextcloud / Dropbox / OneDrive / File system / WebDAV。 3.1 Joplin免费网盘同步 目前,Joplin支持Dropbox 、OneDrive 网盘同步,在同步选项中选择OneDrive,然后就会打开认证。 同意验证。 与 OneDrive 同步时,Joplin 会在 OneDrive 中创建一个子目录:/Apps/Joplin,Joplin 仅有此目录的读写权限。如下图: 3.2 Joplin使用WebDAV同步 WebDAV 可以自建,或使用支持 WebDAV 的云盘,另外 NAS(如群晖)通常也支持 WebDAV。 **Nextcloud:**Nextcloud是一个开源的免费的自建个人云存储方案,要启用 Nextcloud 同步,你需要在 Nextcloud 中创建一个目录(比如:Joplin),在左下角的“设置”中获取 WebDAV 的 URL,在 Joplin 同步设置中,填入 WebDAV URL、用户名和密码。 有关于Nextcloud安装与使用教程,请参考:Oneinstack安装NextCloud以及使用Aria2离线下载和ocDownloader插件配置。 **坚果云:**首次同步时会因为 WebDAV 短时间内的大量请求被坚果云临时限制,坚果云提示为“Too many requests”,这个封锁会持续大约6小时。同步之前,在 Joplin 的“工具” > “选项” > “同步” > “高级选项”中,将“最大并发连接数”改为1可以有效避免。 关于坚果云的使用方法,请参考:巧用又拍云FTP和坚果云WebDAV-打造个人文件备份和数据云存储。 四、Joplin导入与导出 Joplin可以很方便地支持从Evernote(印象笔记)导入,方法如下: 从 Evernote(印象笔记)导入: 打开 Evernote,右击要导出的笔记本,选择“导出笔记“,导出 .enex 格式文件。 在 Joplin 中,选择“文件” > “导入” > “ENEX – Evernote导出文件(Markdown)”即可导入。 从 Markdown 文件导入: 使用 Joplin 可以轻松导入 Markdown 文件或整个目录,选择“文件” > “导入” > “MD – Markdown(文件/目录)”导入即可。 从其他应用程序导入: 通常,很多应用程序都支持导入到 Evernote 中,所以从其他应用程序导入的思路是先导入 Evernote,再导出 .enex 文件,最后导入 Joplin 中。 如下图: 如果哪天你不想使用Joplin了,也可以很方便地导出。Joplin 支持多种导出格式,导出格式均为标准格式,可以在不依赖 Joplin 的情况下查看、编辑,部分格式支持无损/有损重新导入: JEX:Joplin 的无损导出格式,包含所有的元数据如标签、更新时间等。JEX是实际上是一个tar文件,可以直接解压出 MarkDown 文件。这种格式常用于备份,可以无损重新导入。 RAW:同 JEX 格式相似,只是数据会保存为目录,并且每个笔记都会导出为一个单独的文件。可以无损重新导入。 JSON:导出为 JSON 格式的文件。不支持重新导入。 MD:按照笔记本的分级结构导出为目录,每条笔记在对应的目录中导出为 Markdown 格式的文件,目录名和文件名与原笔记本对应,此种格式易于读取,但是导出的文件将丢失元数据。可以有损导入(丢失元数据)。 HTML:导出为网页文件,将 Markdown 格式转为 html 标签,带有样式。不支持导入。 PDF:将单个笔记导出为 PDF 格式的文件。不支持导入。 如下图: 五、总结 免费开源的笔记Joplin无论在功能上还是使用体验上基本上与Evernote印象笔记无异了,在隐私保护方面做得非常好,特别适合那些想要保存个人信息笔记的用户。 使用免费开源的笔记Joplin最大的问题就是找好同步的网盘或者云存储,另外强烈建议大家在对Joplin的设置进行调整时先备份一个,以免同步后删除了所有的笔记。 编辑整理 From:挖站否 系列教程 全部文章RSS订阅 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/9/9
articleCard.readMore

Joplin 入门指南&实践方案

Evernote笔记是我们常用的一个笔记服务,国内叫印象笔记,免费版本的Evernote笔记其实已经足够我们使用了,但是对于重度的笔记用户,Evernote某些功能可能需要付费升级才可以使用,而且你的笔记是存放在Evernote的服务器上。 有些同学可能觉得放在Evernote服务器上的笔记会不安全,况且有些隐私性很强的笔记确实不适合放在公共的服务器上。此时,你需要一个可以保护个人隐私同时还可以与Evernote笔记功能相媲美的免费笔记服务:Joplin,它是一款免费开源的笔记软件。 Joplin跨平台支持,包括PC桌面端,移动端,甚至提供了命令行版本,原生支持 markdown 格式,搜索速度快,可以通过其他第三方同步工具 (Dropbox/NextCloud/OneDrive/WebDAV/etc) 进行备份以及同步 ,支持浏览器Web clipper即网页剪贴。 Evernote笔记该有的功能Joplin都有了,如果你不想掏钱购买Evernote付费版本,Joplin将是最佳的替代品。更多的自建服务还有: Chevereto免费相册程序安装与使用-免费自建图床和公共图片相册 自建RSS阅读器Tiny Tiny RSS安装和配置自动更新,全文RSS,更换主题,手机RSS登录 放弃付费1Password改用免费开源的bitwarden_rs自建密码管理系统-安装,使用和备份 PS:更新记录 1、平时经常要校对文本,以及有大量的文件需要在电脑和移动硬盘同步,可以试试这些免费的同步对比工具:八大免费的文件对比同步工具-免费文件对比分析与复制同步备份软件。2021.3.24 2、对于1Password这类的密码管理软件重度依赖,但是苦于囊中羞涩的话,不防自建密码管理平台:Bitwarden自建密码存储系统图文教程-开源免费的bitwarden_rs安装与使用。2020.10.10 一、Joplin安装和使用 网站: https://joplinapp.org/ 直接到官网下载Joplin安装包,安装好了就可以启动Joplin了,以下是Joplin的软件界面,分成三栏,和我们平时熟悉的笔记软件是一样的。(点击放大) 这是Joplin的编辑器,支持 MarkDown,图片、数学公式、复选框等 MarkDown 语法。 不习惯MarkDown,直接切换为可视编辑即可。 在Joplin的设置选项中还提供了非常多的MarkDown的插件,对于MarkDown深度用户来是一个福音。 二、Joplin的特色功能 2.1 笔记历史版本 Joplin提供了笔记历史版本,让你轻松地恢复任意时间的笔记版本。在“工具” > “选项” > “笔记历史”中启用,以及设置保留的笔记历史天数。要查看笔记的历史版本,点击编辑器上方的笔记属性图标,然后选择恢复: 2.2 E2EE安全加密 在同步过程中,笔记本、笔记、标签等均以纯文本文件的方式同步,如果你还觉得不安全,你可以开启端到端加密(E2EE),把文件加密后同步到云端。由于 Joplin 的去中心化,密码必须手动在每个终端设置。 **注意:不要在多个设备上同时启用加密,否则可能会造成加密密钥问题。特别提醒:**加密之前,先将笔记导出JEX备份一份,以防万一。 2.3 Joplin手机APP Joplin可以直接在各大应用市场上下载,使用起来也很方便。 2.4 外部编辑器 Joplin自带的编辑已经非常强大的,如果你想要使用自己的编辑器来编辑笔记也是可以的,包括 文本编辑器(如 Notepad++)、 Markdown 编辑器(如 Typora)等。 通过 Ctrl+E,或 Joplin 编辑器上方的图标(如下图)从外部编辑器打开笔记,从外部编辑器打开后,Joplin 将持续监控该文件,当你从外部编辑机保存后,Joplin 将自动同步最新变动。 你可以在“工具” > “选项” > “通用选项”中指定编辑器的路径。 三、Joplin同步与备份 Joplin与其它的笔记软件很大的不同就是没有存储功能,你需要将Joplin的笔记放在自己的主机或者网盘里,幸运的是Joplin支持多种方式的云同步:Nextcloud / Dropbox / OneDrive / File system / WebDAV。 3.1 Joplin免费网盘同步 目前,Joplin支持Dropbox 、OneDrive 网盘同步,在同步选项中选择OneDrive,然后就会打开认证。 同意验证。 与 OneDrive 同步时,Joplin 会在 OneDrive 中创建一个子目录:/Apps/Joplin,Joplin 仅有此目录的读写权限。如下图: 3.2 Joplin使用WebDAV同步 WebDAV 可以自建,或使用支持 WebDAV 的云盘,另外 NAS(如群晖)通常也支持 WebDAV。 **Nextcloud:**Nextcloud是一个开源的免费的自建个人云存储方案,要启用 Nextcloud 同步,你需要在 Nextcloud 中创建一个目录(比如:Joplin),在左下角的“设置”中获取 WebDAV 的 URL,在 Joplin 同步设置中,填入 WebDAV URL、用户名和密码。 有关于Nextcloud安装与使用教程,请参考:Oneinstack安装NextCloud以及使用Aria2离线下载和ocDownloader插件配置。 **坚果云:**首次同步时会因为 WebDAV 短时间内的大量请求被坚果云临时限制,坚果云提示为“Too many requests”,这个封锁会持续大约6小时。同步之前,在 Joplin 的“工具” > “选项” > “同步” > “高级选项”中,将“最大并发连接数”改为1可以有效避免。 关于坚果云的使用方法,请参考:巧用又拍云FTP和坚果云WebDAV-打造个人文件备份和数据云存储。 四、Joplin导入与导出 Joplin可以很方便地支持从Evernote(印象笔记)导入,方法如下: 从 Evernote(印象笔记)导入: 打开 Evernote,右击要导出的笔记本,选择“导出笔记“,导出 .enex 格式文件。 在 Joplin 中,选择“文件” > “导入” > “ENEX – Evernote导出文件(Markdown)”即可导入。 从 Markdown 文件导入: 使用 Joplin 可以轻松导入 Markdown 文件或整个目录,选择“文件” > “导入” > “MD – Markdown(文件/目录)”导入即可。 从其他应用程序导入: 通常,很多应用程序都支持导入到 Evernote 中,所以从其他应用程序导入的思路是先导入 Evernote,再导出 .enex 文件,最后导入 Joplin 中。 如下图: 如果哪天你不想使用Joplin了,也可以很方便地导出。Joplin 支持多种导出格式,导出格式均为标准格式,可以在不依赖 Joplin 的情况下查看、编辑,部分格式支持无损/有损重新导入: JEX:Joplin 的无损导出格式,包含所有的元数据如标签、更新时间等。JEX是实际上是一个tar文件,可以直接解压出 MarkDown 文件。这种格式常用于备份,可以无损重新导入。 RAW:同 JEX 格式相似,只是数据会保存为目录,并且每个笔记都会导出为一个单独的文件。可以无损重新导入。 JSON:导出为 JSON 格式的文件。不支持重新导入。 MD:按照笔记本的分级结构导出为目录,每条笔记在对应的目录中导出为 Markdown 格式的文件,目录名和文件名与原笔记本对应,此种格式易于读取,但是导出的文件将丢失元数据。可以有损导入(丢失元数据)。 HTML:导出为网页文件,将 Markdown 格式转为 html 标签,带有样式。不支持导入。 PDF:将单个笔记导出为 PDF 格式的文件。不支持导入。 如下图: 五、总结 免费开源的笔记Joplin无论在功能上还是使用体验上基本上与Evernote印象笔记无异了,在隐私保护方面做得非常好,特别适合那些想要保存个人信息笔记的用户。 使用免费开源的笔记Joplin最大的问题就是找好同步的网盘或者云存储,另外强烈建议大家在对Joplin的设置进行调整时先备份一个,以免同步后删除了所有的笔记。 编辑整理 From:挖站否 系列教程 全部文章RSS订阅 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/9/9
articleCard.readMore

为知笔记私有化Docker部署

已经不建议使用! 格式私有,不支持导出数据到其它类型笔记软件。数据进入后,基本只能用为知笔记编辑了,导出图片和PDF? what? 收费吃相难看,VIP到期后,功能限制严重! 不推荐任何不支持导入导出数据的笔记软件。推荐使用开放格式的 Joplin 软件 登陆NAS,打开套件中心,搜索docker,并安装。 搜索wiznote,找到wiznote/wizserver,双击下载 在NAS中创建共享目录,用于存放笔记数据 启动File Station 在docker目录下创建文件夹: wiz 在wiz文件夹下创建文件夹:data 双击创建容器,启用资源限制,设置为内存限制4096MB,官方介绍说需要4G内存 高级设置,启动自动重新启动 卷设置,使用刚才我们创建的data目录进行配置,装载路径/wiz/storage,docker/wiz/config装载路径/wiz/app/wizserver/config 网络设置不动,端口设置添加映射:8888映射80端口(8888可以随便设置,跟访问地址有关) 设置环境变量 SEARCH=true TZ=Asia/Shanghai 直接应用,启动docker,然后就静静的等待吧,可以看看镜像的日志,看到这些基本上就差不多启动好了(最新的镜像在NAS上首次启动非常慢,本人等了一个多小时才完全启动完毕,在本地安装速度非常快) 通过 http://NAS的IP:8888,进行访问,就可以看到已经启动完成 默认管理员账号:admin@wiz.cn,密码:123456 管理后台登陆地址:http://IP地址:端口/wapp/pages/admin NAS开启SSH 首先在NAS上启动SSH 登陆NAS,打开控制面板-终端机和SNMP,在启动SSH功能前打上勾 打开命令行,输入 ssh NAS管理员账号@NAS的IP地址 ssh端口号默认是22 看到提示符,输入账号的密码,输入时不可见,输入完成按回车,看到命令行提示符变了,登陆成功。 进入容器 在命令行中输入 sudo docker ps 可能提示输入密码,就输入NAS管理员的密码即可,显示列表,查看到如下列表,找到其中运行了为知笔记的一行 复制为知笔记的CONTAINER ID,然后再输入如下命令并回车: sudo docker exec -it 粘贴刚复制好的ID号 /bin/bash 至此进入到容器中 修改配置文件 输入如下命令打开配置文件进行编辑: vi /wiz/app/wizserver/config/default.json vi命令的具体使用方法请自行百度,保存好后退出,重启容器生效。 进入docker,修改文件/wiz/wizserver/app/config/default.json "as": { "admin": ["admin@wiz.cn"], "share": { "admin": ["admin@wiz.cn"], "enableHttps": false, "enableSubDomain": false, "appShareUrl": "127.0.0.1:5001" }, 其中127.0.0.1:5001修改为自己的服务器访问地址,可以给docker做个端口映射(因为群晖NAS占用了5001端口),譬如映射8889端口到容器的5001端口,则设置为xxx.xxx.xxx.xxx:8889,分享后的链接即为该链接。 在NAS上可以用反向代理来解决二级域名的问题。 分享功能需要用户绑定手机,并完成认证,在docker中登陆数据库,并修改数据 mysql -u root -p 输入密码,密码在docker中/wiz/wizserver/app/config/default.json中查看 "mysql": { "as": { "host": "127.0.0.1", "user": "root", "password": "******************", "database": "wizasent", "connectionLimit": 50, "connectTimeout": 60000, "aquireTimeout": 60000, "waitForConnections": true }, 其中password就是密码,进入mysql控制台后,执行以下命令: use wizasent; update wiz_user set MOBILE='你的手机号', MOBILE_VERIFY='1' where ID='1'; web端登陆为知笔记,并修改默认账号后,修改后的账号无法登陆管理后台,需要做以下配置,修改文件/wiz/wizserver/app/config/default.json,找到以下代码: "as": { "admin": ["admin@wiz.cn"], "share": { "admin": ["admin@wiz.cn"], "enableHttps": false, "enableSubDomain": false, "appShareUrl": "127.0.0.1:5001" }, 其中admin@wiz.cn修改为修改后的账号。 登陆NAS,打开控制面板-应用程序门户-反向代理 点击新增,然后输入如下: 实际测试来源协议选择https时只有网页端可以登陆,客户端无法登陆,暂时还是选择http为好,也可以网页端通过https登陆,客户端通过http登陆,配置两个不同的端口(记得要在路由上配置端口映射)。 修改default.json { "debug": true, "enableHttps": true, "storage": { "__comments": "oss|local|s3|cos", "use": "local", "oss": { "bucket": "data_root", "region": "test", "accessKeyId": "test", "accessKeySecret": "test", "internal": false }, 其中enableHttps配置成true 重启服务 cd /wiz/app/wizserver pm2 restart all 删除/wiz/storage/index/.search文件和/wiz/storage/index/nodes目录 重启容器 链接数据库,执行下列SQL update wizksent.wiz_kb_stat set index_new_status=4 进入容器,执行 cd /wiz/app/wizserver pm2 start app.js --name="index2" -f -- -c 1 -i 1 -t 2 -s index pm2 start app.js --name="index2" -f -- -s copy 查看日志 pm2 logs index2 下载官方插件,并安装到Chrome中 http://www.wiz.cn/downloads-webclipperchrome.html 在浏览器中输入chrome://extensions/打开插件列表,开启开发者模式 看ID号,在浏览器中输入chrome://inspect/#extensions在打开的列表中找到WizClipper,点击inspect,开启调试窗口。 选择Sources标签,并打开文件Scripts\wiz\WizConstant.js 在代码中查看note.wiz.cn和api.wiz.cn的网址全部替换成自己私有云的地址,实测,登陆没问题,保存失败。 管理功能 增加重建索引功能,以备不时之需 增加备份与恢复功能 增加markdown语法扩展: flow(流程图)、sequence(时序图)、mermaid(流程图、时序图、甘特图)、LaTeX(公式) 增加手动配置分享链接 支持社交绑定的配置 支持对象存储或webdav存储 Web&Mac客户端 增加自定义模板 增加偏好设置,自定义快捷键(主要是编辑和预览切换的快捷键非常不适应) 增加同步预览模式,可以参考下Typora,Bear都不错 增加https访问方式 支持导出jpg、png、docx格式 浏览器插件 增加支持私有云登陆 【部署环境】 【出现的问题】 网页版上提示,自动保存失败,网络错误,请尽快保存(最后发现是时区不通道导致的,第8点解决了此问题) 所有社交平台账号无法绑定 mywiz邮箱不可修改 绑定手机无法收到验证码,即无法绑定手机(通过修改数据库搞定) 存储设置功能多余(因为已经本地化部署了),改成数据备份/恢复就好了 支付信息是支付到为知去的,这个功能容易产生误解(如果多人使用的话) docker容器的时区与宿主机时区不同,添加环境变量解决,TZ=Asia/Shanghai 数据导出 方法很困难。 ExportToMd 最新版Wiznote测试这个插件已经不可用了。 WizNotePlus 第三方客户端导出,已在 v2.11 中初步实现,见如下issue链接。 https://github.com/altairwei/WizNotePlus/issues/182 Memocast客户端 随后搜索到Memocast,是重写为知笔记的客户端。 使用OpenAPI 为知笔记提供了OpenAPI来查看和编辑笔记,Memocast也是类似方式,服务说明及登录和笔记接口介绍了如何登录获取Token,如何查询文件夹文档,下载html,下载资源(图片)等接口。 对于为知笔记来说,所有的笔记保存为html,所以下载后需要做转换。 通过Postman的接口测试发现完全可行,那么就可以编程导出了。具体的代码。html转md的库使用html-to-markdown,案例代码在这。 如何使用?按照下面提示输入账户和密码,然后设置导出的文件夹即可。 go install github.com/GalaIO/wiz_export@latest wiz_export --output './' --userId 'xx' --password 'xx' --folders '/日记/,/工作/' 借助Pandoc转换到HTML再转换到Markdown For .html files within a directory for f in *.html ; do pandoc ${f} -f html -t markdown -s -o ${f}.md ; done or For recursive directory conversion with subfolders find . -name "*.ht*" | while read i; do pandoc -f html -t markdown "$i" -o "${i%.*}.md"; done wiz2joplin 这个需要Mac环境,看提交记录时间,可行性很高。 参考: 大大木头 [为知社区] 如何导出为知笔记? Importing notes from other notebook applications 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/9/9
articleCard.readMore

Mariadb/Mysql命令行常用命令

一、初始化等 1、登陆数据库方法 mysql -u用户名 -p用户密码 2、修改root及用户密码 use mysql; update user set password=password('11111111') where user='root' and host='localhost'; flush privileges; MariaDB [mysql]> update user set password=password('11111111') where user='root' and host='localhost'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [mysql]> flush privileges; Query OK, 0 rows affected (0.01 sec) MariaDB [mysql]> exit 3、创建用户 insert into mysql.user(host,user,password)values("localhost","test",password("password")); flush privileges; 4、删除用户 DELETE FROM user WHERE User="test" and Host="localhost"; flush privileges;   5、删除用户的数据库 drop database test1; 6、交互模式初始化 mysql_secure_installation 二、 常用操作 1、显示数据库列表 show databases;:查看所有的数据库 2、创建数据库 create database zxg;:创建名尾zxg的数据库 3、进入数据库 use zxg;:进入zxg的数据库 4、显示库中的数据表 show tables;:查看数据库里有多少张表 5、创建数据表 create table t1 (id varchar(20),name varchar(20));:创建名为t1表,并创建两两个字段,id、name,varchar表示设置数据长度,用字符来定义长度单位,其 6、插入数据 insert into t1 values("1","zxg");:向表中插入数据 7、查看数据表 select * from t1; :查看t1表数据内容 8、多条件查询 select * from t1 where id=1 and age = 'zxg ' ;: id、age 多个条件查询 9、查看字段内容 desc t1;:查看t1 表字段内容 10、修改字段长度 alter table t1 modify column name varchar(20);:修改name字段的长度 11、修改该字段内容 update t1 set name='zxg.net' where id=1;:修改name字段的内容 12、权限刷新 flush privileges; :刷新权限 13、清空表单 delete from t1;` :清空表内容 14、删除数据表 `drop table t1:删除表 15、删除数据库 drop database zxg;:删除zxg数据库 16、查看数据库字符集 show variables like '%char%';:查看数据库字符集 17、查看存储引擎 show engines;:查看MySQL存储引擎。 18、查看默认存储引擎 show variables like '%storage_engine%';:查看MySQL默认的存储引擎 19、修改存储引擎 alter table t1 engine=innodb;:修改MySQL t1表存储引擎 [root@web2 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 2 Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) MariaDB [(none)]> create database zxg; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> use zxg; Database changed MariaDB [zxg]> show tables; Empty set (0.00 sec) MariaDB [zxg]> create table t1(id varchar(20),name varchar(20)); Query OK, 0 rows affected (0.00 sec) MariaDB [zxg]> show tables; +---------------+ | Tables_in_zxg | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec) MariaDB [zxg]> MariaDB [zxg]> insert into t1 values ("1","zxg"); Query OK, 1 row affected (0.01 sec) MariaDB [zxg]> select *from t1; +------+------+ | id | name | +------+------+ | 1 | zxg | +------+------+ 1 row in set (0.00 sec) MariaDB [zxg]> select *from t1 where id=1; +------+------+ | id | name | +------+------+ | 1 | zxg | +------+------+ 1 row in set (0.00 sec) MariaDB [zxg]> select *from t1 where id=1 and name='zxg'; +------+------+ | id | name | +------+------+ | 1 | zxg | +------+------+ 1 row in set (0.01 sec) MariaDB [zxg]> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | varchar(20) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) MariaDB [zxg]> alter table t1 modify column name varchar(20); Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [zxg]> update t1 set name='zxg.net' where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [zxg]> 三、mysql 数据库字符集设置 mysql数据库存储数据时,默认编码为latinl,存储中文字符时,在调用时会显示为乱码,为了解决该乱码问题,需修改该mysql默认字符集为UTE-8 装mariadb的是时候看已经默认为ute-8 MariaDB [(none)]> show variables like '%char%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) 如不是,可以设置 SET character_set_client = utf8; SET character_set_results = utf8; SET character_set_connection = utf8; 四、mysql 数据库密码管理 设置密码访问,密码破解、密码权限、修改密码; 1、创建用户及授权 grant all on zxg.* to test@localhost identified by 'pas'; grant select,insert,update,delete on *.*to test@"%" identified by 'pas'; grant all on zxg.* to test@`192.168.216.53` identified by 'pas' 2、破解密码方法 停止服务—》跳过权限方式启动—》单开一个窗口登陆—》登陆修改密码即可 1)systemctl stop mariadb 2)mysqld_safe --skip-grant-tables & [root@web2 ~]# mysqld_safe --skip-grant-tables & [1] 47542 [root@web2 ~]# 190520 15:45:22 mysqld_safe Logging to '/var/log/mariadb/mariadb.log'. 190520 15:45:22 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql [root@web2 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 1 Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use mysql; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [mysql]> update user set password=password('11111111') where user='root' ; Query OK, 3 rows affected (0.01 sec) Rows matched: 4 Changed: 3 Warnings: 0 MariaDB [mysql]> flush privileges; Query OK, 0 rows affected (0.00 sec) MariaDB [mysql]> exit Bye [root@web2 ~]# 然后退出”跳过权限方式“ ctrl+c ,正常启动mysql就可以了 五、mysql 配置文件详解 1、参数说明 [mysqld] #服务端配置 port = 3306 #监听端口 socket = /tmp/mysql.sock #通信设置 user = mariadb #使用mariadb用户启动 basedir = /usr/local/mariadb #安装路径 datadir = /data/mysql #数据目录 log_error = /data/mysql/mariadb.err     #错误日志 pid-file = /data/mysql/mariadb.pid     #pid进程文件 skip-external-locking #避免mysql的外部锁定,减少出错几率提高稳定性 key_buffer_size = 64M #缓存存储引擎参数,这个参数可以设置为64M max_allowed_packet = 1M #允许最大接收数据包的大小,防止服务器发送过大的数据包,可以设置为16MB或者更大,但设置太大也可能有危险 table_open_cache = 256 #mysql每打开一个表,都会读入一些数据到table_open_cache缓存中,当MYSQL在这个缓存中找不到相应的信息时,才会去磁盘读取,默认值64,假设系统有200个并发连接,则需将此参数设置为200*N(N为每个连接所需的文件描述符数目);当设置为很大时,如果系统处理不了那么多文件描述符,那么就会出现客户端失效,连接不上 sort_buffer_size = 1M #在表进行order by和group by 排序操作时,由于排序的字段没有索引,会出现Using filesort,为了提高性能,可用此参数增加每个线程分配的缓存区大小,默认时256k,这个参数不要设置过大,一般128~256k,另外一般出现using filesort的时候,要通过增加索引来解决 net_buffer_length = 8K #包消息缓冲区初始化net_buffer_length字节,但需要时可以增长到max_allowed_packet字节 read_buffer_size = 1M #该参数用于表的顺序扫描,表示每个线程分配的缓冲区大小,比如在进行全表扫描时,mysql会按照数据的存储顺序一次读取数据块,每次读取的数据块首先会暂存在read_buffer_size中,当buffer空间被写满或者全部数据读取结束后,在将buffer中的数据返回给上层调用者,以提高效率默认128k,也不要设置过大 read_rnd_buffer_size = 512K #该参数用于表的随机读取,表示每个线程分配的缓冲区大小,比如,按照一个非索引字段做order by排序操作时,就会利用这个缓冲区来暂存读取的数据,默认时256k,也不要设置过大 myisam_sort_buffer_size = 16M #当myisam表执行repair table或创建索引时,用以缓冲排序索引,设置太小可能会遇到"myisam_sort_buffer_size is to small" thread_cache_size = 32 #线程池,线程缓冲。用来缓冲空闲的线程,以至于不被销毁,如果线程缓冲在的空闲线程,需要重新建立新连接,则会优先调用线程池中的缓冲,很快就能相应连接请求,每建立一个连接,都需要一个线程与之匹配。 query_cache_size = 32M #缓存select语句和结果集大小的参数。查询缓存会存储一个select查询的文本与被传送到客户端的相应结果。如果之后接收到一个相同的查询,服务器会从查询缓存中检索结果,而不是再次分析和执行这个同样的查询。如果你的环境中写操作很少,读操作频繁,那么打开query_cache_type=1,会对性能有明显提升。如果写操作频繁,则应该关闭它(query_cache_type=0)。 tmp_table_size = 64M #临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。 # explicit_defaults_for_timestamp = true        #是否显示默认时间戳 #skip-networking # max_connections = 500 #该参数用来设置最大连接数,告诉你当前你的服务器允许多少并发连接。默认为100,一般设置为512-1000即可。请记住,太多的连接会导致内存的使用量过高并且会锁住你的 MySQL 服务器。一般小网站需要 100-200 的连接数,而较大可能需要 500-800 甚至更多。这里的值很大程度上取决于你 MySQL/MariaDB 的使用情况。 max_connect_errors = 100 #如果有时网络抽风,或者应用配置错误,或者其他原因导致客户端短时间内不断的尝试连接,客户端可能会被列入黑名单,然后将无法连接,直到再次刷新主机缓存。这个选项默认值太小了,可以考虑设的足够大(如果你的服务器配置够强大的话)。 open_files_limit = 65535 #mysql打开最大文件数 # log-bin=mysql-bin #这些路径相对于datadir binlog_format=mixed #日志格式 server-id = 1 #给服务器分配一个独一无二的ID编号; n的取值范围是1~2的32次方启用二进制日志功能。在复制数据同步的时候会用到,Helloweba后面会有文章介绍。 expire_logs_days = 10 #启用二进制日志后,保留日志的天数。服务器会自动清理指定天数前的日志文件,如果不设置则会导致服务器空间耗尽。一般设置为7~14天。 # default_storage_engine = InnoDB  #新数据表的默认存储引擎(默认设置是MyISAM)。这项设置还可以通过–default-table-type选项来设置。 innodb_file_per_table = 1 #提供了更灵活的方式,它把每个数据库的信息保存在一个 .ibd 数据文件中。每个 .idb 文件代表它自己的表空间。通过这样的方式可以更快地完成类似 “TRUNCATE” 的数据库操作,当删除或截断一个数据库表时,你也可以回收未使用的空间。这样配置的另一个好处是你可以将某些数据库表放在一个单独的存储设备。这可以大大提升你磁盘的 I/O 负载。 innodb_data_home_dir = /data/mysql     #InnoDB主目录,所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下,这个主目录就是MySQL的数据目录。 innodb_data_file_path = ibdata1:10M:autoextend            #用来容纳InnoDB为数据表的表空间: 可能涉及一个以上的文件; 每一个表空间文件的最大长度都必须以字节(B)、兆字节(MB)或千兆字节(GB)为单位给出; 表空间文件的名字必须以分号隔开; 最后一个表空间文件还可以带一个autoextend属性和一个最大长度(max:n)。 innodb_log_group_home_dir = /data/mysql       #用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下,InnoDB驱动程序将使用 MySQL数据目录作为自己保存日志文件的位置。 innodb_buffer_pool_size = 256M   #这个参数是InnoDB存储引擎的核心参数,默认为128KB,这个参数要设置为物理内存的60%~70%。 innodb_log_file_size = 64M #事务日志文件写操作缓存区的最大长度(默认设置是1MB)。 innodb_log_buffer_size = 8M #事务日志所使用的缓存区。InnoDB在写事务日志的时候,为了提高性能,先将信息写入Innodb Log Buffer中,当满足innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)时,再将日志写到文件(或者同步到磁盘)中。可以通过innodb_log_buffer_size参数设置其可以使用的最大内存空间。默认是8MB,一般为16~64MB即可。 innodb_flush_log_at_trx_commit = 1     #这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写(术语称为”同步”)到硬盘上。设置值0的意思是每隔一秒写一次日 志并进行 同步,这可以减少硬盘写操作次数,但可能造成数据丢失; 设置值1(设置设置)的意思是在每执行完一条COMMIT命令就写一次日志并进行同步,这可以防止数据丢失,但硬盘写操作可能会很频繁; 设置值2是一般折衷的办法,即每执行完一条COMMIT命令写一次日志,每隔一秒进行一次同步。 innodb_lock_wait_timeout = 50 #如果某个事务在等待n秒(s)后还没有获得所需要的资源,就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被InnoDB数据表驱动 程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。 # [mysqldump] # quick # max_allowed_packet = 16M # # [mysql] # no-auto-rehash # # [myisamchk] # key_buffer_size = 64M # sort_buffer_size = 1M # read_buffer = 2M # write_buffer = 2M # # [mysqlhotcopy] # interactive-timeout # 2、mysql数据库索引案例(百万量级) [client] port =3306 socket =/tmp/mysql.sock [mysqld] port = 3306 socket = /tmp/mysql.sock user = mysql server_id  = 10 datadir  = /data/mysql/ old_passwords  = 1 lower_case_table_names  = 1 character-set-server  = utf8 default-storage-engine  = MYISAM log-bin  = bin.log log-error  = error.log pid-file  = mysql.pid long_query_time  = 2 slow_query_time  = 2 slow_query_log  slow_query_log_file  = slow.log binlog_cache_size  = 4MB binlog_format  = mixed max_binlog_cache_size  = 16MB max_binlog_size  = 1GB expire_logs_days  = 30 ft_min_word_len  = 4 back_log  = 512 max_allowed_packet  = 64MB max_connections  = 4096 max_connect_errors  = 100 join_buffer_size  = 2MB read_buffer_size  = 2MB read_rnd_buffer_size  = 2MB sort_buffer_size    = 2MB query_cache_size  = 2MB table_open_cache  = 10000 thread_cache_size  = 256 max_heap_table_size  = 64MB tmp_table_size  = 64MB thread_stack  = 192KB thread_concurrency  = 24 local-infile  = 0 skip-show-database skip-name-resolve skip-external-locking connect_timeout  = 600 interactive_timeout  = 600 wait_timeout  = 600 #MyISAM key_buffer_size  = 512MB bulk_insert_buffer_size  = 64MB mysiam_sort_buffer_size  = 64MB mysiam_max_sort_file_size  = 1GB mysiam_repair_threads  = 1 concurrent_insert  = 2 myisam_recover #INNODB innodb_buffer_pool_size  = 64G innodb_additional_mem_pool_size  = 32MB innodb_data_file_path  = ibdata1:1G;ibdata2:1G:autoextend innodb_read_io_threads  = 8 innodb_write_io_threads   = 8 innodb_file_per_table  = 1 innodb_flush_log_at_thx_commit  = 2 innodb_lock_wait_timeout  = 120 innodb_log_buffer_size  = 8MB innodb_log_file_size  = 256MB innodb_log_files_in_group  = 3 innodb_max_dirty_pages_pct  = 90 innodb_thread_concurrency  = 16 innodb_open_files  = 10000 #innodb_force_recovery  = 4 #replication slave read-only #skip-salve-start relay-log  = relay.log log-slave-updates 本文参考: mariadb-mysql配置文件my-cnf解读 MySQL教程 《曝光:Linux企业运维实战》 夜法之书 整理编辑 From: zhangxingeng

2021/9/8
articleCard.readMore

【Gitlab】GitBook+GitLab撰写发布技术文档-Part2:GitLab篇

上一篇文章介绍了如果用 gitbook 写书,并且我们已经通过 gitbook build命令把书的内容打包成 HTML 格式发布到了_book文件夹中。 原理 简单来说CI 就类似一个触发器,你可以设定响应触发的条件,比如 master 分支有新的 commit合并进来,或者带有特殊 tag 的合并,亦或者其他指定分支的特殊提交,可以触发指定的指令。 实现 我们就按照原理,来一步一步尝试着完成工作吧。 CI配置 还记得我们上一篇文章中最后介绍目录结构时,有提到一个文件: gitlab-ci.yml。 这个文件是用YAML 进行配置,我们来看一下我们要用到的配置文件吧 deploy: stage: deploy script: # make backup - sudo rm -rf /usr/share/nginx/html/TechDocs/example_bak - sudo mv /usr/share/nginx/html/TechDocs/example /usr/share/nginx/html/TechDocs/example_bak - sudo mkdir /usr/share/nginx/html/TechDocs/example # deploy latest files - cd _book - sudo cp -rf . /usr/share/nginx/html/TechDocs/example/ only: - master # this job will affect only the 'master' branch 这段 yaml 配置就只有deploy 的步骤,我们在 script部分进行了一系列的操作,完成旧文件的备份以及新文件的部署。当我们的代码上传到远端后,就会自动执行 script 里的内容了。让我们尝试下吧。 查看 CI 任务执行状态 上传代码到 gitlab 的步骤这里就不介绍了。理论上说,当代码上传到 master 分支后,会自动执行我们设定好的部署任务。我们可以通过访问gitlab对应项目的页面, 在左侧菜单栏点击CI/CD来查看任务的执行情况。 原因页面上也给出了我们提示This job is waiting to be picked by a runner。 Runner 这里就需要引入第2个概念: runner。很容易从字面上理解,runner 就是我们任务的执行者,也很形象,我们提交了一个任务以后,总得有人来执行。这些任务有些是需要shell 脚本执行,有些可能需要登录到远程机器,有些可能需要 docker 的执行权限,所以这些执行者也都有个子的分工,可能有些执行者只负责执行特定项目的任务,有些执行者执行特殊 tag 的。所以接下来我们看看如何才能创建 runner 吧。 shared runner 前文提到了我们可能需要一些高权限的 runner 来跨项目间来执行任务。因为我们要做的是多个项目的技术文档,所以会有多个 gitbook 的项目,那这些项目的 CI 任务自然是公用1个 runner 就好,这种 runner 就叫做 shared runner。 这个页面会显示当前所有的 runner,包括项目独享的 runner 和共享的 shared runner。 我们看到目前还没有一个可用的 runner,所以之前的任务才会停留在等待 runner 来运行的状态。 安装 gitlab-runner 工具 第一步是安装工具,可以通过页面上的提示来进行不同主机环境的安装。我们这里用到的是 RHEL/CentOS,其他版本可以参见页面链接。 $ sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 $ sudo chmod +x /usr/local/bin/gitlab-runner $ sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash $ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner $ sudo gitlab-runner start 新建 shared runner 工具安装好了之后,我们就可以来创建用户了。 $ gitlab-runner register 之后按照提示,一步一步创建就好了: 输入URL 输入token。 URL 和 token 按照页面上给出的提示来创建就好了。token 用来标识创建的 runner 是某个项目特有的,还是 shared runner 输入 runner 的描述,这个可以随便填写,只要自己能看明白,能区分就好了 输入特定的 tag。 注意,这里最好留空,否则该 runner 仅会执行特定 tag 的提交 选择执行类型。这里提供了很多常见的执行类型,例如 docker, docker-ssh, shell 等,我们这里输入 shell。 之后我们就创建好了一个可以执行 shell 命令的 shared runner。再次回到之前的 web 页面上查看我们创建的 runner 信息。 可以看到页面提示我们已经创建了一个 runner 可以执行all unassigned projects的任务 我们还可以进入到特定的项目,在设置里面查看 runner 的情况,可以看到已经有一个可用的 shared runner。如果想创建该项目特有的 runner,按照页面上的提示,输入特定的 token 就好了。 其他细节 我们重新查看CI任务页面,大多数情况下,你的任务状态会是failed或者pendding。 如果是 failed,我们可以点击查看具体失败的原因,例如我遇到的问题就是 gitlab-runner 用户没有 sudo 权限。 如果一切都设置妥当,我们可以看到 CI 页面任务的最终状态是 passed,也就是成功执行了。这样,gitbook 的内容就成功部署到你的 web 页面上了。 致谢&引用 基于 GitLab 的 CI 实践(https://zhuanlan.zhihu.com/p/41330476) 如何使用 GitLab CI(https://medium.com/@mvpdw06/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-gitlab-ci-ebf0b68ce24b) Configuring GitLab Runners(https://docs.gitlab.com/ee/ci/runners/) Registering Runners(https://docs.gitlab.com/runner/register/) Gitbook CI With Gitlab(https://xiaosuiba.github.io/Gitbook-CI-With-Gitlab/) 在 Gitlab 平台簡單創建 GitBook 電子書的步驟(https://www.kenming.idv.tw/simple-create-gitbook_at_gitlab_steps/) How to create a static website using GitLab Pages(https://getpublii.com/docs/host-static-website-gitlab-pages.html) Install GitLab Runner manually on GNU/Linux(https://docs.gitlab.com/runner/install/linux-manually.html) From: lipeng1667 系列教程 全部文章RSS订阅 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab 后话 Gitbook 团队现在基本不再维护 Gitbook 软件,而专注于 Gitbook 网站的开发。可以考虑 mkdocs-material Github Mkdocs

2021/9/7
articleCard.readMore

【Gitbook】GitBook+GitLab撰写发布技术文档-Part1:GitBook篇

随着工作时间越来越久,项目越做越多,很多时候,手里面的技术文档都是零散的技术点。最近一直在着手把项目的技术开发文档(Technical Document)系统地整理一下。正好看到了非常棒的 GitBook 工具,又顺带研究了如何借助 Gitlab 的 CI/CD 功能实现自动部署。 GitBook + GitLab怎样来撰写并发布文档。 系统环境 惯例列出来我们的环境以及用到的工具。 MacOS 10.12 Node.js (版本 > 4.0.0) Atom/MWebLite 其实 Gitbook 有官方的编辑器,但是似乎对中文的支持不是很好,而且会有 bug,虽然最新版本做了优化,Mardown 格式的文字有些会自动显示成最终样式,而我个人还是比较喜欢原生的 markdown,所以我个人就没有用官方的编辑器。 基本使用 安装 安装过程非常简单 npm install gitbook-cli -g 新建book 安装成功后,我们就可以开始用gitbook 的命令来进行各种操作了。如果熟悉hexo的同学会发现,其实大同小异,只不过一个用来写blog,一个用来写 book。 $ mkdir myBook $ cd myBook $ gitbook init 初始化后,我们能在myBook目录下看到两个 markdown 文f件。这两个文件就是我们写一本书唯二必须要用的文件了。 预览book 先不做任何变动,模拟一下我们发布之后的页面的成品吧。 $ gitbook serve 我们打开浏览器,在浏览器中输入0.0.0.0:4000就可以在本地预览了。 可以看到,左侧是我们的菜单栏,自带一个搜索栏,右侧就是我们的 book 的内容了,右上角有默认的诸如 twitter,facebook 等分享快捷方式。基本上和其他人用 gitbook 写出来的页面是一样的。 注: gitbook 新版本提供了本地预览功能的热更新,也就是说本地预览的页面会随着我们写书的内容变化而自动更新,这着实是一个很使用的功能。 在命令行ctrl+c可以关闭本地服务器,即预览页面。 我们可以尝试修改一下书的内容,看一下页面的变化。打开README.md文件,修改成如下内容: # Introduction Hello World! 再回头看一眼我们的预览页面,是不是自动变成了下面的样子。 关于 gitbook 自建的 README.md 文件我就不做过多的介绍了,都是一些 Markdown 的基本语法,相信使用 gitbook 的各位一定是对 markdown 语法非常熟悉的了。 目录 现在我们把注意力放到 gitbook 为我们创建的第二个文件SUMMARY.md上,这个文件决定了我们的目录结构。 一个比较简单的目录结构如下: # Summary * [前言](README.md) * [第一章](xx.md) * [第二章](xx.md) * [第三章](xx.md) xx.md就是我们每个章节独立的 markdown 文件,所以用 gitbook 写一本书真的非常方便,一个目录文件,和若干个你的书的内容就好了。 目录分层 简单的目录有一个小的问题就是我们目录都只有一级,如果想要分层,比如第一章有1,2,3个小节,该怎么办呢? 这里有两种方式: 标题区分 我们把SUMMARY.md文件修改成如下内容 # Summary ## 前言 * [前言](README.md) ## 第一章 * [1.1小节]() * [1.2小节]() ## 第二章 * [2.1小节]() * [2.2小节]() ## 第三章 * [3.1小节]() * [3.2小节]() 最终的样式如下: 缩进区分 我们还可以用缩进的方式对目录进行级别的区分 # Summary * [前言](README.md) * [第一章]() * [1.1小节]() * [1.2小节]() * [第二章]() * [2.1小节]() * [2.2小节]() * [第三章]() * [3.1小节]() * [3.2小节]() 最终的样式如下: 大家可以根据自己的喜好选择不同的样式,也可以把这两者结合起来一起用,as you wish. 打包发布 通过预览模式,我们可以随时掌握书籍的更新内容。当你完成了部分章节或者全书的编写后,我们需要把写好的内容打包并发布。 $ gitbook build 执行完上面的命令后,我们会发现在根目录下出现了_build文件夹,里面的文件就是我们需要发布的内容,你可以把所有的内容放到你的网站目录下,或者 gitlab/github 的 page页面,就实现了 gitbook 的线上发布了~ 进阶技巧 看完上面的章节,你已经可以独立完成一本书的编写和发布,接下来的章节,我们提供一些进阶的技巧,你可以安装一些插件、更直观地规划你的目录结构等等。 插件 和众多开源的软件一样,gitbook 也有一些插件,这些插件可以让你的书更加完美。这里我仅附上我个人觉得比较有用的几个插件,更多的插件,可以访问社区来获取。 book.json文件来修改当前书的一些配置,因为是 json 格式的,所以诸如书的标题、作者、内容等都可以在配置文件中完成,我们重点来说插件。 { "plugins": [ "-lunr", "-search", "search-plus", "splitter", "copy-code-button", "expandable-chapters-small" ] } 以上是我的book.json配置文件,只有一个关于插件的配置项,其实总共就4个 search-plus 让搜索支持中文,注意需要先把默认的两个插件lunr和serach禁用掉,禁用的方式就是在前面加上-号 spliter 菜单栏宽度可调节 copy-code-button 代码可以一键 copy expandable-chapters-small 菜单栏可以折叠 注: gitbook install 命令来安装新的插件,否则在打包发布的时候会提示错误。 目录结构 一个基本的目录结构是这样的 . ├── _book/ ├── book.json ├── README.md ├── SUMMARY.md ├── xx1.md ├── xx2.md ├── xx3.md ├── xx4.md ├── ... 不过为了我们自己方便,个人建议的目录结构如下 . ├── _book/ ├── node_modules/ ├── .gitlab-ci.yml ├── book.json ├── SUMMARY.md ├── content/ | ├── chapter1/ | ├── README.md | └── something.md | ├── chapter2/ | ├── README.md | └── something.md ├── res/ | ├── 1.png | └── 2.jpg | └── 3.jpeg | └── ... 说明: _book 目录是我们打包后要发布的文件目录 node_modules 目录是我们安装插件后默认生成的目录 .gitlab-ci.yml这个是 gitlab 要用的 ci 配置文件,下一章节我们马上就会用到 book.json 是我们的配置文件 content目录是我们的书的内容,所有章节都可以分类继续整理,方便自己查看 res目录是我们要用到的一些图片资源文件夹,除了用到床图,我们可以把其他本地图片资源也包含进来 参考&致谢 Gitbook 简要介绍 GitBook 学习笔记 From: lipeng1667 系列教程 全部文章RSS订阅 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab 后话 Gitbook 团队现在基本不再维护 Gitbook 软件,而专注于 Gitbook 网站的开发。可以考虑 mkdocs-material Github Mkdocs Like Gitbook but implemented in Rust Github mdBook

2021/9/7
articleCard.readMore

通过宝塔面板实现MySQL性能简单调优

在PHP+MYSQL架构网站运行过程中,往往会遇到各种性能问题影响,如MySQL、PHP、CPU、磁盘IO、缓存等,其中MySQL瓶颈就是最常见也最难解决的一种影响网站性能的因素;通常,我们会使用redis、memcached等缓存软件来缓存内容,这确实是最优的解决方案之一,但这需要网站程序的支持,然而多数常用网站程序并不支持或者不能完美支持这些缓存软件,今天我们就来谈谈如何通过MySQL自身的配置调整来优化MySQL性能,以缓解MySQL瓶颈问题。 准备: ​ 1、宝塔Linux面板 正式版 5.2.0+ (2017/09/20发布) 测试版5.2.4+ ​ 2、MySQL 5.x 通常MySQL调优我们分以下几部分: ​ 1、MySQL配置参数调优 (需要根据网站运行情况调整) ​ 2、数据表索引调优 (效果明显,但通常优秀的开源程序都不需要调整) ​ 3、SQL语句调优 (这是程序员或DBA干的事) 今天我们主要谈谈如果配合宝塔面板的新功能来进行MySQL配置参数调优,我们先来看两张图片: (图1) (图2) 很明显,(图1)显示的是MySQL当前的运行状态,(图2)显示的是MySQL主要配置参数 下面我们就来解读一下这两张图: 1、活动/峰值连接数 ​ (图1)中当前活动的连接为1个,自MySQL服务启动以来,最高连接数为54;当最高连接数接近或等于(图2)中的max_connections时,应适当增加max_connections,需要注意的是,不要一下子增加过多,建议每次增加50,观察一段时间,不够再继续增加。 2、线程缓存命中率 ​ (图1)中线程缓存命中率为99.78%,若这个值小于90%,建议适当增加(图2)中的thread_cache_size,建议每次增加8。 3、索引命中率 ​ (图1)中索引命中率为99.50%,若这个值小于95%,建议适当增加(图2)中的key_buffer_size,建议每次增加64,需要说明的是,若您的数据库使用的是Innodb引擎,可忽略这个选项 4、Innodb索引命中率 5、查询缓存命中率 ​ MySQL查询缓存是个比较受争议的功能,个人建议当你有在使用redis、memcached等缓存软件时,在(图2)中将query_cache_size设为0可以将其关闭,当你没有使用缓存软件,有多余的内存使用,且数据库瓶颈明显存在时,可以尝试开启查询缓存,这是个非常依赖数据表结构及SQL语句优化的功能,若数据表结构和SQL语句都针对查询缓存进行过优化,它的效果还是很不错的。 6、创建临时表到磁盘 ​ (图1)中创建临时表到磁盘的比例是0.42%,这说明大部分临时表创建到内存了,不会过多增加磁盘IO的开销,建议,当比例大于2%时适当增加(图1)中的tmp_cache_size,建议每次增加32,当比例大于60%时,放弃吧,有些开源程序并没有专门优化过SQL语句,所以在运行过程中会开启大量临时表,加多少缓存都是不够用的。 7、已打开的表 ​ 当(图1)中的已打开的表接近或等于(图2)中的table_open_cache时,可以适当增加table_open_cache,但若设置过大可能导致您的程序频繁中断MySQL连接,建议在1024以内,最大不要超过2048。 8、没有使用索引的量、没有使用索引的JOIN量 ​ 若不为0,就检查下数据表索引吧,其实只要没有疯涨,比如一天增涨几千,一般可以忽略,必竟优化索引还是程序员或DBA去干比较合适。 9、排序后的合并次数 ​ 如果这个值在缓慢增张,建议适当增加(图2)中的sort_buffer_size,建议每次增加512,但最大不要超过8192,如果这个值一直在疯涨,增加sort_buffer_size也没用,就放弃这个选项吧,这个锅还是给程序开发者背。 10、锁表次数 ​ 如果服务器CPU开销不大的情况下,疯狂锁表,建议你将所有数据表转换成innodb,记得转换前备份哦。 11、优化方案 ​ 这个是我们根据内存大小给的一个推荐优化方案,仅是建议仅用于基础参考值,还是要根据实据情况来调整每一个配置项。 注意:保存参数配置后不会立即生效,记得要重启MySQL服务。 写在最后: 来自网络整理。

2021/9/6
articleCard.readMore

ESNI和加密DNS - 保护信息隐私的最后一块拼图

随着TLS1.3的发布,让该协议成为有史以来最安全、也是最复杂的TLS协议。在该协议之中,有很多的对于以往协议安全漏洞的修复,包括废弃RSA启用新的秘钥交换机制PSK等等。而Encrypted SNI作为一个TLS1.3的扩展协议用来防止传统的HTTPS流量受到ISP或者陌生网络环境的窥探以及一些网络审查。在过去,由于HTTPS协议之中Server Name Indication - SNI的使用,我们的HTTPS流量经常被窥探我们所访问站点的域名 那么什么是SNI? 服务器名称指示(英语:Server Name Indication,简称SNI)是一个扩展的TLS计算机联网协议,在该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书,并且因此允许在相同的IP地址上提供多个安全(HTTPS)网站(或其他任何基于TLS的服务),而不需要所有这些站点使用相同的证书。它与HTTP/1.1基于名称的虚拟主机的概念相同,但是用于HTTPS。所需的主机名未加密, 因此窃听者可以查看请求的网站 为了使SNI协议起作用,绝大多数访问者必须使用实现它的Web浏览器。使用未实现SNI浏览器的用户将被提供默认证书,因此很可能会收到证书警告 SNI协议示意图 TLS1.3完整握手流程 为了弥补缺陷因应运而生的ESNI 在上述过程之中,存在的问题就是,在ClientHello环节中,TLS会在这个位置以明文的形式讲要请求的Host写在数据包之中,如果在网络路由中有任何的监听节点,那么用户所访问网站的域名将暴露无遗,这将是巨大的用户隐私泄露: 所以在最新的关于ESNI的草案中,IETF重新设计了一种加密的Client Hello机制,从而修复了这个问题: 不过这里问题又来了,之前服务器和客户端并没有事先交换任何数据啊,这个加密的凭证从何而来啊??? 依靠安全DNS的ESNI 上一个问题没有难倒工程师们,他们设计了这样一个办法。首先让网站提供者在DNS提供商上公布一个记录,这个记录包含着一个公钥,这个公钥由网站提供者生成,其私钥存储在Web服务器等待着被Web程序读取。如此,当用户想通过TLS1.3协议访问这个域名的时候,首先读取这个公开的公钥,在用公钥加密其想访问的域名Host,装在Client Hello里面发送给目标服务器,目标服务器再用自己的私钥解密,从而和用户建立HTTPS链接,这样就不会暴露Host信息 这时候有人会想,如果有人某Wall想给你的DNS偷天换日,那会不会很不安全啊,请继续向下看 在ESNI的实现草案之中,里面要求安全加密的DNS是推荐的。大家都知道我们的DNS查询一般是TCP报文或者是UDP报文,本身它是不加密的,所以如果有人想在篡改你的DNS是相对简单的,大家可能都知道我们伟大的妨炎蔷会使用DNS污染的方式干扰一些网站的正常访问。正式由于DNS的非加密性,DNS也成为了审查信息的利器。此时加密的DNS势在必行 DNS over TLS (DoT) and DNS over HTTPS (DoH) 于是出现了这两种新型的DNS查询方式 DNS over HTTPS (DoH) DNS Over HTTPS (DOH) 是一个进行安全化的域名解析的方案,当前尚处于实验性阶段。其意义在于以加密的HTTPS协议进行DNS解析请求,避免原始DNS协议中用户的DNS解析请求被窃听或者修改的问题(例如中间人攻击)来达到保护用户隐私的目的。 Google及Mozilla基金会正在测试这一协议,作为其提高网络安全性的努力的一部分。 当前,该方案由IETF支持,其规范文档以 RFC 8484 的名义发布。2018年9月5日发布的Firefox 62正式版加入了这项功能,但需要用户手动开启 DNS Over HTTPS利用HTTP协议的GET命令发出经由JSON等编码的DNS解析请求。较于传统的DNS协议,此处的HTTP协议通信处于具有加密作用的SSL/TLS协议(两者统称作HTTPS)的保护之下。但是,由于其基于HTTPS,而HTTPS本身需要经由多次数据来回传递才能完成协议初始化,其域名解析耗时较原DNS协议会显著增加。 传统的DNS协议形成于互联网早期,直接基于UDP或TCP协议,且彼时未虑及现代安全性的需要,未利用密码学等手段进行加密或验证。因而,其无法抵御现代互联网常见的DNS投毒污染等攻击手段或监听。虽然后来的DNSSEC方案通过电子签名进行验证,强化了DNS的安全性,并能够抵御DNS投毒污染等篡改通信的手段,但其对于中间网络设备进行的监听仍然没有抵御能力(随后,监听者可以通过获取的通信数据知晓用户访问了哪一域名,而域名往往与具体的网站相关系)。此外,DNSSEC的起效要求现有的大量DNS解析服务的提供商(常为互联网服务提供商或第三方大型互联网机构)对已有的DNS服务器进行大范围修改等问题,其推进进程并不理想。而对于DNS Over HTTPS,在正确部署服务端并妥善配置客户端的前提下,互联网服务提供商或其它中间网络设备无法解密(亦即无法获知请求的实际内容)或者篡改已经加密的HTTPS通信,故其能够有效保护互联网用户的安全及隐私;另一方面,其基于已经成熟并已广泛部署的HTTPS协议,客户端进行利用较为方便。 DNS over TLS (DoT) DNS over TLS (DoT) 是通过传输层安全协议(TLS)来加密并打包域名系统(DNS)的安全协议。此协议旨在防止中间人攻击与控制DNS数据以保护用户隐私。 RFC 7858及RFC 8310定义了DNS over TLS。 截至2018年,Cloudflare、Quad9与CleanBrowsing均向大众提供支持DNS over TLS的公共DNS解析服务。2018年4月,Google宣布Android P将包含对DNS over TLS的支持。PowerDNS的DNSDist也宣布在其最新的1.3.0版本中添加了对DNS over TLS的支持。BIND用户也可以通过stunnel代理提供DNS over TLS服务。 手动配置 Firefox所在的Mozilla宣布从Firefox 62版本之后开始支持ESNI,默认没有开启,需要用户手动配置打开,那么我们现在试验一下 这里Firefox的解决方案是使用DNS over HTTPS (DoH)和ESNI 安装Firefox Nightly版本,这个版本是预发布版本,使得开发这和即可门可以提前尝鲜到新功能。下载地址 在浏览器地址栏输入about:config并回车,打开配置页面,在搜索位置搜索network.trr.mode,这个是打开浏览器对于DoH的支持,将此项的数值修改为3(0对应的是不开启此功能;1对应的是交由浏览器选择DoH与传统方式那种更快;2代表优先使用加密DNS查询,如果失败则回落到普通DNS查询;3代表只使用加密DNS查询;5代表明确的关闭此功能) 继续搜索network.trr.uri,将此项的值修改为https://mozilla.cloudflare-dns.com/dns-query,这个是默认的DoH查询地址,当然我们也可以使用诸如https://1.1.1.1/dns-query、https://dns.google.com/experimental这样的地址,我们可以事先ping检测一下对比哪个延迟更低来使用 (可选)搜索network.trr.bootstrapAddress,讲此值修改位第三步的DNS域名的IP。此举是为了避免使用操作系统DNS查询域名受到劫持,一般来说这些DNS的IP是不会变的 将network.security.esni.enabled设置为true,此举为了打开浏览器对于ESNI的支持(感谢chenlshi同学的提醒,在原版的文章中我不小心遗漏了这个关键的步骤) 完成配置后重启浏览器,再打开在线验证页面验证来查询你的浏览器是否完全支持ESNI功能,如果出现如图说明配置成功了 验证 为了验证是否真的加密了Client Hello,我们使用Wireshark进行网络抓包 由于这个特性仍在试验阶段,并没有太多站点支持这个特性,CloudFlare是第一个全站支持ESNI的网站,这里我们使用blog.cloudflare.com来做测试: 首先打开Wireshark的抓包功能,然后开启Chrome浏览器打开上述网址,页面加载完后停止抓包,在得到的结果中查询协议为TLS1.3和报文为Client Hello的报文,通过观察发现域名的Host果然被以明文形式写在数据包中(参见Server_Name字段): 然后打开Firefox Nightly浏览器重复上述操作,这次发现在整个数据包中根本找不到Server_Name字段,说明Host已经被加密: 目前来说,我查阅了相关的关键词,仍然没有任何一篇教程有介绍如何在自己的服务器上支持ESNI,同时我也看到在Nginx的论坛里面有人呼吁尽快支持ESNI,所以我推测这个功能仍然在试验期,还没有被这两个Web软件所支持,起劲为止我也没有查阅到任何的Web软件预计支持此项功能。这项扩展已经进入IETF的草案阶段,可以预见到,在不就的将来,这项技术可以普及开来,为我们的网络隐私保驾护航 目前来说,有了HTTPS+TLS1.3+ESNI+DoH/DoT的加持,我们的网络隐私的到了极大的保障,最后还有一个问题是访问服务器IP的泄露仍然无法被避免,迫于IP协议设计的机制,他目前还不能被解决。不过我相信,随着网技术不断的趋于保护个人隐私和更快速的发展方向,这个问题可以最终被解决 From: hackerchai

2021/9/6
articleCard.readMore

使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程

使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程,打造一个完整的HTPC。全流程全部使用开源软件实现! 持续滚动更新,欢迎收藏关注。也可以RSS订阅本博客! jackett 作为种子源,sonarr剧集管理,bt下载,qbittorrent主力下载,使用iyuu转移辅种,emby,jellyfin做海报墙,sunfinder自动下载字幕。基本算是完美打通全流程自动追剧。bt种子文件命名规则SxxExx的自动识别下载,已完结老资源推荐使用PTPP搜索推送下载,硬链接后使用TMM刮削,再使用emby欣赏。追番推荐使用sonarr , radarr 自动下载,结合 JProxy 手动选择种子,自动推送到emby。 结合本地 dnamasq + DNSCrypt Proxy DNS管理,DNS去广告。再使用Nginx 反向代理去端口访问,形成一个完整解决方案。 整体流程较复杂,多查阅相关软件的官方文档!基本都有详细的使用说明! graph TD 1[Sonarr] == request Jackett / Prowlarr Torznab api ==> 2(JProxy) == proxy Sonarr request ==> 3(Jackett / Prowlarr) 3(Jackett / Prowlarr) == return ==> 2(JProxy) == return result after format ==> 1(Sonarr) 2(JProxy) == replace search key ==> 2(JProxy) 2(JProxy) == format result title ==> 2(JProxy) 更多有趣相关工具集介绍: PTtool 概论 全流程简介: qBittorrent + Jackett + Radarr & Sonarr + ChineseSubFinder + Jellyfin & emby + Jellyseerr & Ombi 组件介绍: qBittorent 没什么好说的,一个常用的 BT 下载器,同类的还有 Transmission。 Jackett 老牌资源索引器,用于对接 PT、BT 站搜索资源,对于 PT 站支持较好;同类的还可选 Prowlarr,但是对 PT 站支持一般,比如 M-Team 站在 Jackett 上可以成功添加但在 Prowlarr 添加失败(2022-07-24),优点是支持中文,可以对接 Radarr 和 Sonarr 一键设置 Indexer,如果你同时使用大量的 Indexer,使用上会方便很多。 Radarr/Sonarr Radarr/Sonarr,一个负责电影,一个负责剧集(电视剧和番剧),是整套系统能够全自动的关键。可以自动整合资源索引器和下载器,当找到了资源时,自动推送到下载器中下载资源;当下载完成时,自动刮削供影视库使用并调用 API 来更新影视库内容,支持配置信息通知。 替代品: MoviePilot 国人开发的NAS媒体库自动化管理工具 ChineseSubFinder 字幕下载器,网上的资源很多并不自带中文字幕,当资源下载完毕后,中文字幕会根据资源的名称自动匹配并下载下来,同类还有 Bazarr。 Jellyfin 完全免费的影视库,提供了解析资源文件/文件夹,利用 IMDB/TMDB/TVDB 等影视索引网站索引你的本地资源(即刮削),并播放的功能。同类的还有 Emby、Plex、Kodi,除了 Kodi 另外两个影视库部分功能需要付费才可使用。本地播放推荐 Kodi,苹果全家桶用户强烈推荐 Infuse(需要付费订阅但不贵,建议土区年付)。 Jellyseerr/Overserr 整合了 Radarr/Sonarr 的搜索,提供了一个统一的搜索框,让你不用关心到底是 Sonarr 还是 Radarr 负责这类资源,你只需要提供个名字就好。同时还整合了影视库,让你知道什么样的资源已经在库中,而且界面美观易上手。Jellyseerr/Overserr 本质是一样的,只是 Jellyseerr 对接的是 Jellyfin,Overserr 对接的是 Plex,同类的还可选 Ombi(适合 Emby/Plex)。 优缺点 优点: 免费开源,方案成熟度高,拥有较多插件的对接支持 搜索界面美观易用,支持手机 APP 管理(Radarr & Sonarr Companion / LunaSea / nzb360),可以同步影音库账号 刮削体验优秀,电影刮削对中文支持友好,支持自动中文重命名和资源整理 可以实现对资源的监控,自动追番追剧,自动下载和高画质升级 支持中文字幕的自动下载 缺点: 剧集刮削对于国产剧和番剧支持不好,剧集 INFO 信息和资源整理不支持中文(可以在 Sonarr 自动整理完资源后,让影音库覆盖一遍刮削信息) 对于 PT 站的支持一般,主要是命名不符合 Sonarr 的规范,如果资源标题中没有季信息,就无法识别匹配资源,所以下载剧集时基本什么都搜不到,添加多个 BT 站可以缓解 对于老剧老番支持一般,因为资源主要是来源于 BT 站,比较老的剧集由于没人保种,质量参差不齐,可以手动下载后再导入 Sonarr 自动整理 剧集分季不符合国人习惯,Sonarr 的剧集元数据是从 TVDB 拉取的,例如国内【全职猎人 2011】只分为一季,在 Sonarr 上分成了三季 其他: Ani-RSS:追番神器Ani-RSS 的工作原理和功能与 AutoBangumi非常类似,但是解决了不少AutoBangumi的痛点问题。 AutoBangumi 官网 MoviePilot nastool 作者的新坑,外围组件开源,核心组件闭源!功能性,安全性,稳定性来说 radarr 全家桶更好,mp 中文支持更好一些但核心闭源,而 radarr 全套中目前只有 radarr 元数据支持中文刮削。就目前版本来说,MP 胜在插件多,有自动推荐,其它功能来说还不如 Radarr/Sonarr。 更多组件,详细介绍见下文 indexer 种子索引源 种子索引来源。 jackett docker: linuxserver/jackett:latest 老牌选手,种子源非常丰富。 prowlarr indexer manager/proxy Docker: linuxserver/prowlarr:develop 新开发的,和sonarr, lidarr等结合比jackett 配置更简单。 动画管理 Github Sonarr DockerHub Sonarr 管理剧集名,查找剧集种子推送到下载工具 剧集管理示例图片 管理剧集目录,剧集日历,提醒你那一天哪些节目播放 自动识别下载对英文剧集支持较好,对于中文资源,结合手动识别下载更佳。 手动识别下载 示例图片 电影使用radarr, 音乐使用lidarr,同样可以自动化过程 自定义过滤器 Sonarr 自定义适配格式升级 例如升级到中日双语字幕方法如下 注意这是 sonarr v4 版本功能,目前是Docker linuxserver/sonarr:develop develop 分支才有的功能 Custom Formats,自定义关键字,匹配出来中日双语 Profiles,自定义分数,分数高的会优先下载。Upgrades Allowed 勾上可以自动升级格式 多媒体中心 Emby,Jellyfin, Plex都是优秀的多媒体中心。Jellyfin是开源的,基于Emby早期版本。 emby海报墙,流媒体中心 emby作为海报墙,元数据查看器,结合tampermonkey js脚本调用外部potplayer播放减少nas服务器压力,并且得到更好解码性能。手机端也有emby客户端。jellyfin,plex也可以 方法一:浏览器安装拓展Tampermonkey+脚本embyLaunchPotplayer js脚本: embyLaunchPotplayer 安装JS脚本之前,需要安装tampermonkey 最新版本的Potplayer存在bug: 调用插件提示 无法播放。 服务器已关闭或地址错误 在渲染下列 Pin 时失败了。 修复方法: potplayer 跳转时,如果文件名有空格则无法正常播放。即使进行了 url 编码。所以需要对标题去除空格。 let poturl = `potplayer://${encodeURI(mediaInfo.streamUrl)} /sub=${encodeURI(mediaInfo.subUrl)} /current /title=${encodeURI(intent.title.replace(/\s*/g,""))} /seek=${getSeek(intent.position)}`; 方法二:浏览器安装拓展PotPlayer YouTube Shortcut PotPlayer YouTube Shortcut是Chrome浏览器的一款拓展程序,可将Youtube的视频直连到PotPlayer上播放,也适用于Plex、Emby、Jellyfin。 Chrome谷歌浏览器下载地址:https://www.extfans.com/accessibility/cfdpeaefecdlkdlgdpjjllmhlnckcodp/ Firefox火狐浏览器下载地址:https://addons.mozilla.org/zh-CN/firefox/addon/potplayer-youtube-shortcut/?src=search Edge浏览器下载地址:https://microsoftedge.microsoft.com/addons/detail/potplayer-youtube-shortcu/jonlafindjlhgmohhepcchpkjonbfcie 插件设置项目: 安装好后插件后打开插件选项,“右键选单”-“用PotPlayer开启连结”勾选“任何连结”。 jellyfin 开源版本的emby jellyfin硬件解码 jellyfin中文字体显示方块问题 上面两个问题见下面compose 配置解决方法 version: '3' services: jellyfin: image: jellyfin/jellyfin container_name: jellyfin user: ${PUID}:${PGID} hostname: jellyfin restart: always devices: - /dev/dri:/dev/dri #使jellfin支持硬件解码 environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} # 给一些插件做代理 - http_proxy=http://xxx.17lai.site:1089/ - https_proxy=http://xxx.17lai.site:1089/ # ports: # 使用nginx 反向代理,所以这里就不用开端口了 # - 8098:8096 volumes: - ${USERDIR}/jellyfin/config:/config - ${USERDIR}/jellyfin/cache:/cache # 把windowsfonts目录下面的字体都复制到`jellyfin/fonts`目录中 - ${USERDIR}/jellyfin/fonts:/usr/share/fonts # 给jellyfin装载更多字体,使中文显示正确,不再是方块 - ${USERDIR}/nginx/resolv.conf:/etc/resolv.conf # 定制dns 赋予emby,jellyfin访问硬件加速驱动权限 chmod 755 /dev/dri chmod 666 /dev/dri/renderD128 刮削,改名,目录整理 电影,电视剧,动画等视频为了更好的体验效果,需要刮削元数据。 一些命名不规范,不能被emby识别的剧集使用tmm刮削改名,配合硬链接工具,可以不影响做种的前提下改名,该目录。大文件硬链接,小文件直接复制方便刮削,推荐一个自己写的硬链接bash shell脚本,PTtool在nas,linux环境使用更方便。 tinyMediaManager 电影,电视剧,动画完整刮削教程,见如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕。 Github: appotry/PTtool 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 注意:使用v3版本,不要升级到v4,v4版本收费。 MediaElch MediaElch TMM 的开源替代品 功能:支持电影、电视剧刮削,生成NFO文件及海报墙,兼容Kodi/Plex/Emby;支持多数据源(TMDB、TVDB)。 优势:开源免费、跨平台(Win/macOS/Linux),界面简洁,可批量管理元数据。 局限:无文件重命名功能,需配合其他工具整理文件。 硬链接工具 博主编写的脚本,自推一下,在Nas,linux环境使用的Shell 脚本。 PT hard link tools。方便PT用户硬链接文件,在最大可能情况下节约空间,并保持做种。 小于1M的文件直接复制,方便emby,tmm等工具刮削修改nfo等小文件。 大于1M的文件硬链接到目的目录,可以随意修改文件名,但是不能修改文件内容! 从此,做种,刮削改名两不误! Github: PTools 使用教程: Linux PT硬链接助手使用教程 BT下载工具 qBittorrent下载,种子分类整理较好,但占用资源,内存较多。Transmissoin种子整理分类远不如qBittorrent,但资源占用低,是PT做种混魔力的首选!建议qBittorrent和Transmissoin搭配使用,使用Iyuu自动在两者之间转移种子。 Transmissoin transmission 使用及其配置 qBittorrent qBittorrent 参数详细设置教程 都分别有docker版本和套件版本。 虽然下载工具很多,但IYUU只支持这两个辅种工具,开发者的话是这两个工具的RPC调用接口稳定。 rtorrent 功能强大,适合专门做种时使用 Docker rtorrent-flood 种子发布信息获取 ptgen https://api.iyuu.cn/ptgen/index.html MediaInfo 辅种工具IYUU Doker版本 iyuucn/iyuuautoreseed 命令行版本 iyuucn/iyuuplus 图形界面版本,更轻松上手。 自动辅种,解放双手,更多魔力,更容易养多站。 PT 助手 Plus PT 助手 Plus,为 Microsoft Edge、Google Chrome、Firefox 浏览器插件(Web Extensions),主要用于辅助下载 PT 站的种子 优势: PT种子聚合搜索,选择做种最多,free或者其它优惠的最佳工具!PT 站点 Cookies 管理 PT-depiler PT-depiler 是在原 PT-Plugin-Plus 基础上, 基于浏览器最新的 Manifest v3 标准开发的一款浏览器插件(Web Extensions), 一个可以提升 PT 站点使用效率的工具。 适用于各 PT 站,可使下载种子等各项操作变化更简单、快捷。配合下载服务器(如 Transmission、qBittorrent 等),可一键下载指定的种子。 功能 Features 多站点支持:兼容 NexusPHP、Unit3D、Gazelle 等多种类型的 PT 站点,提供聚合搜索相同关键字的种子、批量下载等功能 下载器集成:支持 qBittorrent、Transmission、Deluge、ruTorrent、Synology Download Station、Aria2 等多种下载器,并保存下载历史记录 备份服务器管理:集成 WebDav、Gist、CookieCloud、Google Drive、DropBox、OWSS 等备份服务,方便数据同步 智能搜索:增强搜索功能,支持多站点同时搜索并合并结果 用户信息管理:集中显示和管理各站点的用户信息和统计数据 地址栏快速搜索:在浏览器地址栏中输入 ptd 后按 Tab 键即可快速调用智能搜索功能 更多功能请参考 Wiki PT-Plugin-Plus PT 助手 Plus,为 Microsoft Edge、Google Chrome、Firefox 浏览器插件(Web Extensions),主要用于辅助下载 PT 站的种子。 注意:已经不能在最新的Chrome上面运行了。Chrome 升级了Manifest 支持的版本 V2 -> V3 字幕下载 想要较好的自动下载字幕,最好用前面介绍的tmm刮削改名之后再使用下面工具。 subfinder 自动下载字幕 Docker: superng6/subfinder Github: docker-subfinder subfinder 下载完成,刮削后的目录,挂载到subfinder的media目录,就会自动下载字幕。 字幕下载对电影,英文剧集支持较好。对于一些tv,动画手动下载字幕会更好一些。 注意:好几年没更新了。官方的配置文件有问题,时效问题。修改URL到最新即可。 chinesesubfinder 已经停止开发!等作者复出! Docker: allanpk716/chinesesubfinder Github: ChineseSubFinder 新开发的中文字幕查找工具,上面那个很久没更新了,这个刚出来。使用nfo里面刮削出来的文件名来匹配字幕。所以就原理来说,这个字幕匹配更准确。 bazarr 还说 sonarr/radarr 全家桶生命力更强。只剩下这个可用了 Docker:linuxserver/bazarr 字幕下载管理,配合sonarr, radarr 使用效果更好。对于英文剧集命名规范的支持较好,比如[name]S01E01 电影管理 电影,电视剧,动画等视频都是类似。 使用radarr管理电影 radarr示例图片 使用Emby观看电影 Emby win desktop 客户端 从 Emby 官网 下载并安装 Emby 官方客户端。 在Emby Theater桌面快捷方式上右键, 然后单击属性, 在弹出的页面上选择打开文件所在位置。 删除目录下的data文件夹(如果没有则忽略) 右上角搜索框输入main.js并执行搜索,点击编辑 -> 替换, 然后在弹出的窗口中输入替换内容为https://tv.emby.media, 替换为为http://embycrack.tk. 最后点击全部替换按钮。 音乐管理 使用lidarr管理音乐 音乐刮削 使用Mp3tag, MediaGo, MusicBrainZ等工具刮削 音乐刮削教程: 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 使用Mstream听音乐 教程: 私人在线音乐服务器搭建与使用介绍 图书管理 DockerHub lazylibrarian DockerHub readarr Github lazylibrarian 漫画管理 mylar3 Github mylar3 DockerHub mylar3 更擅长英文漫画追订 Komga Web 在线漫画查阅管理工具。擅长本地下载好的漫画管理阅读,支持OPDS! Github Komga Docker hub 9KG管理 Whisparr DockerHub Whisparr 整个系列都介绍了,是一套非常完整又强大的管理工具! MetaTube **官网:**https://metatube-community.github.io/ **项目地址:**https://github.com/metatube-community/jellyfin-plugin-metatube MetaTube 支持的成人影片检索网站挺多的,大家可以在后端代码的这个文件夹里看到支持的网站: https://github.com/metatube-community/metatube-sdk-go/tree/main/provider MetaTube 插件的安装与配置 弄完了上面的服务端,接着安装对应的 Jellyfin 插件配置就可以了,因为这部分比较简单,我就直接复制一下作者提供的安装步骤了: 1.进入 Jellyfin 控制台 > 插件 > 存储库,点击添加 2.输入存储库名称:MetaTube 3.输入存储库URL:https://raw.githubusercontent.com/metatube-community/jellyfin-plugin-metatube/dist/manifest.json 4.在插件目录下找到 MetaTube,点击安装 重启Jellyfin**安装说明参考:**https://metatube-community.github.io/wiki/plugin-installation/ 安装好 MetaTube 的插件后,在插件目录里找到 MetaTube,点击它就能打开设置页面。 由于是针对初期配置的说明,关于 MetaTube 那些具体选项的作用我就不一一细说了,只说下怎么填写我们前面搭建好的服务端信息。 Server:填写服务端的地址和端口,比如 http://ip:8080 Token:填写服务端配置的密钥(密码),没有就留空 只是想要连接配置好服务端,写好这两项就够了,后面的都是针对刮削器的设置,大家根据自己的情况设置即可。 搞定设置之后,记得点下最下面的 Save 按钮保存配置,剩下的就是和我们平常使用 Jellyfin 刮削器一样了,可以直接在媒体库设置里指定使用 MetaTube 作为数据提供源~ Plex,emby等同理 mdc-ng docker hub mdc-ng 使用教程 services: mdc: image: mdcng/mdc:latest container_name: mdc environment: - PGID=1000 # 可选,设置组ID - PUID=1000 # 可选,设置用户ID - MDC_USERNAME=admin # 用户名密码可选,配置后开启登录鉴权模块 - MDC_PASSWORD=admin volumes: - /path/to/data:/config # 配置目录,必须 - /path/to/media:/media # 媒体库,可映射多个 ports: - 9208:9208 restart: unless-stopped AutoLady docker hub services: byte-muse: image: envyafish/byte-muse:latest container_name: byte-muse restart: always networks: - bridge ports: - "8043:80" volumes: - ./data:/data networks: bridge: driver: bridge 其它 https://github.com/hitchao/Jvedio https://github.com/yoshiko2/Movie_Data_Capture https://github.com/JavScraper https://github.com/stashapp/stash https://github.com/stashapp/CommunityScrapers metatube-community/jellyfin-plugin-metatube: MetaTube Plugin for Jellyfin/Emby 媒体管理 Jellyseerr/Overserr 整合了 Radarr/Sonarr 的搜索,提供了一个统一的搜索框,让你不用关心到底是 Sonarr 还是 Radarr 负责这类资源,你只需要提供个名字就好。同时还整合了影视库,让你知道什么样的资源已经在库中,而且界面美观易上手。Jellyseerr/Overserr 本质是一样的,只是 Jellyseerr 对接的是 Jellyfin,Overserr 对接的是 Plex,同类的还可选 Ombi(适合 Emby/Plex) Docker管理 使用docker compose 管理docker配置文件,一键安装,升级 使用portainer管理docker version: '3' services: portainer-ce: container_name: portainer-ce image: portainer/portainer-ce command: -H unix:///var/run/docker.sock restart: always ports: - 9300:9000 - 9301:8000 environment: - TZ=Asia/Shanghai - LANG=en_US.UTF-8 volumes: - /var/run/docker.sock:/var/run/docker.sock - /share/Container/portainer_data:/data 使用watchtower自动升级docker 使所有软件保持最新最佳状态 version: '3' services: watchtower: container_name: watchtower image: containrrr/watchtower:latest volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - TZ=Asia/Shanghai - WATCHTOWER_CLEANUP=true - WATCHTOWER_SCHEDULE=0 0 1 * * * restart: always command: nginx redis 上述配置文件中volumes使用了绝对路径,使这个容器能访问系统docker.sock目录,用于方便监控容器镜像的版本以便更新.其他的一些环境变量,例如时区,清理旧镜像,定时任务都转换为environment,而特殊的command命令则定义了指定监控nginx和redis两个容器。没有command这一行,默认监控升级所有运行中的docker # 运行一次,更新所有的容器,并清除旧的容器 docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --cleanup --run-once #只更新nginx和redis docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --cleanup --run-once nginx redis 使用muximux来管理多个docker入口 主页面 配置页面 更进阶定制本地域名访问 nginx 管理域名访问 Docker: bloodstar/nginx-purge Github: nginx 去掉烦人的端口后缀,实现80,443 端口复用。这个docker 是博主定制功能版。 配置SSL证书访问,密码等敏感数据从此加密传输。并可以使用http2高级特性。 version: '3' services: nginxweb: image: bloodstar/nginx-purge container_name: "nginxweb" hostname: nginxweb ports: - "80:80" - "443:443" restart: always volumes: # 映射主机目录 - ${USERDIR}/nginx/conf.d:/etc/nginx/conf.d:ro - ${USERDIR}/nginxproxy/certs:/etc/nginx/certs:ro - ${USERDIR}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro 这里推荐博主制作的nginx docker镜像: bloodstar/nginx-purge 支持ARM64, ARMV7, AMD64 ,增加 CA 证书,防火墙,brotli, Proxy-cache-purge, htpasswd 支持 DNS 域名管理 和nginx 配合使用。 简单的可以直接修改/etc/hosts。 DNSCrypt Proxy: 作为DNS前端访问DOH的DNS DNSMasq: 作为DNS后端,连接到DNSCrypt Proxy,并配置本地域名。还可以添加DNS去广告功能,浏览器插件去广告非常消耗CPU和内存,但是在DNS前端去广告,资源消耗低,并一次性解决所有的访问终端(pc,手机,平板)广告问题。 配置一个去广告,本地域名管理工具。 也许是宣传太多导致这两个软件被商店屏蔽了,除了套件版,还有Docker版, entware 仓库版本!再次,还可以自己编译使用! Xteve 看IPTV Docker: dnsforge/xteve 结合Emby, jellyfin直接看iptv。 IPTV 直播源 EMBY安装插件:XmlTV 管理员打开EMBY后台设置 找到“电视直播” 选择“添加指南数据源”,区域设置“China”,指南源设置“XmlTV” 下一步,文件或URL 填写:“http://epg.51zmt.top:8000/e.xml” ,其他保持默认。 IPTV源文件处理 点此下载一个直播源 将下载下来的文件上传到这里(这个系统会根据name自动匹配台标和tvg-id) 将自动处理完毕的文件下载下来,并添加到EMBY中的电视源中。 完毕 解码 由于H.265(HEVC,high efficiency Video Coding)专利费用过高,谷歌公司转而支持开源免费的AV1编码格式,因此Chrome浏览器和使用Chromium内核的Edge浏览器不支持H.265(HEVC)硬解码。从caniuse网站可知,截至2021年9月16日,仅有macOS和iOS的Safari浏览器支持HEVC硬解码,Windows下所有还在持续升级的浏览器均不支持HEVC硬解码。 Hevc 插件安装 How to Download HEVC Video Extension for Free (free-codecs.com) 第一步:在 Microsoft Store 上找到应用程序的 URL https://www.microsoft.com/en-us/p/hevc-video-extensions-from-device-manufacturer/9n4wgh0z6vhq 第二步:使用 Adguard 生成下载链接 https://store.rg-adguard.net/ 并将应用程序的 URL 粘贴到提供的空间中。然后,点击复选标记按钮以生成直接下载链接。 页面将显示 msixbundle、appx 或 appxbundle 文件,以及其他相关文件。在大多数情况下,你只需要下载完整的应用程序包,而不需要下载应用程序依赖项。 例如,对于 HEVC 视频扩展,你只需要下载 .appxbundle 文件,这是列表中最大的文件(约 7MB)。请确保根据你的系统架构检查文件的体系结构兼容性(x64、x86、Arm)。 第三步:下载 HEVC 视频扩展 Microsoft.HEVCVideoExtension_2.1.861.0_neutral_~_8wekyb3d8bbwe.appxbundle 微软 Edge 有时可能会将下载视为不安全。在这种情况下,检查你的浏览器的“下载历史记录”,选择“保留”文件,或者你可以使用 Google Chrome 或 Firefox 等替代浏览器完成下载。 HEVC 视频扩展是一个出色的工具,可播放文件大小更小的高质量视频。 Adguard 是一个第三方网络服务,可以轻松地从 Microsoft Store 下载 appx、appxbundle 和 msixbundle 文件。 可以这里下载安装插件 Chrome 插件 H.265 / HEVC player You can download sample H.265 / HEVC streams (creative commons license) from http://www.libde265.org/downloads-videos/ 视频抖动问题 edge://flags/ 进入,搜索 Media Foundation playback for Windows 10,右边切换成 Enabled,重启浏览器。 Win 10 Hevc 解码 许多 OEM 商已经为你支付过 HEVC 的授权了,你可以下载 “来自设备制造商的 HEVC 视频扩展” 到支持的设备上。点击下面链接安装! ms-windows-store://pdp/?ProductId=9N4WGH0Z6VHQ Safari 安装 Click here to download Safari 5.1.7 setup file from Apple. The setup supports both 32-bit and 64-bit Windows 11/10/8/7 systems. Run the installer and then follow the on-screen directions to get it installed. 最新版Safari 没法在Win 10/11上面安装,Apple 停止了开发Windows版本的Safari! 兼容性不好,不建议使用! 浏览器硬件加速 一、GPU硬件加速的工作原理 GPU硬件加速利用图形处理器的并行处理能力,将一些复杂的计算任务交给GPU来处理,从而减轻CPU的负担。在网页渲染过程中,GPU硬件加速主要应用于以下方面: 2D和3D图形渲染:GPU加速可以显著提高网页中2D和3D图形的渲染速度。 视频解码和播放:GPU加速的视频解码可以提高视频播放的流畅度。 CSS动画和转换:GPU加速可以大幅提升CSS动画和转换的性能。 二、如何在Chrome浏览器中开启GPU硬件加速 Windows系统: (1) 打开Chrome浏览器,进入设置页面。 Mac OS系统: (1) 打开Chrome浏览器,进入偏好设置页面。 chrome://flags强制启用 Chrome 的 GPU 加速 如果 Chrome 硬件加速没有如预期那样发挥作用,可以尝试覆盖内置的软件渲染列表,在不受支持的系统上强制启用 GPU 加速: 打开 Google Chrome 浏览器,在地址栏中执行chrome://flags/#ignore-gpu-blocklist, 将「Override software rendering list」设置为「Enable」启用状态。 点击「Relaunch」重启 Chrome 浏览器。 该选项可以忽略 Chrome 默认的 GPU 黑名单,从而在某些不被推荐的系统上强制启用 GPU 加速。 chrome://gpu/查看 Chrome 硬件加速状态 我们可以通过一个简单的步骤来检查硬件加速功能是否已经启用: 打开 Google Chrome 浏览器,在地址栏中执行chrome://gpu/。如果是edge 浏览器,则是 edge://gpu 在「Graphics Feature Status」区域,查看各项功能是否已经开启了硬件加速。 注意,windows 休眠功能会导致硬件加速失效!这时候重启浏览器就可以重新启用硬件加速 从中可以看出,对于 视频解码 而言,Chrome 启用了 GPU 的硬件加速。当然我们还能从如上的信息中获取更多内容,例如 WebGL 是否有 GPU 支持,GPU 的硬件加速是采用的 OpenGL 还是 Metal,…… 通常情况下,大多数功能都应该处于「Hardware accelerated」状态,表示硬件加速正常工作;如果发现有功能被禁用(Disabled),可能需要进一步检查硬件或驱动程序的设置,以确保图形加速能够正确启用。 Video Acceleration Information Video Acceleration Information 显示了 Chrome 支持的硬件编解码的编解码器类型以及相关编解码器的 profile。从中我们可以判断,对于某种编解码器而言,Chrome 是否支持硬编解码。该信息大致如下表所示: Decoding(VideoDecoder) Decode h264 baseline 16x16 to 4096x4096 pixels …… …… Encoding Encode h264 baseline 0x0 to 4096x2160 pixels, and/or 30.000 fps …… …… chrome://media-internals 如上所述,对于播放的视频,根据视频属性以及 chrome://gpu 和 chrome://flags 提供的信息,我们可以大致判断出在播放该视频时,Chrome 是否使用了硬件解码。 但是,我们要时刻提醒自己,目前为止我们的判断还仅仅是一种猜测而言,要想确切的判断 Chrome 是否使用了硬件解码,就需要获取 Chrome 播放视频时使用的解码器。此时,就该用到 chrome://media-internals 工具啦。 chrome://media-internals chrome://media-internals 是一个研究 Chrome 音频/视频内部堆栈结构的工具。目前,chrome://media-internals 可以显示如下信息: 从媒体堆栈中挖掘有关正在使用的媒体播放器的所有内容,包括已缓冲数据、视频属性、事件之间的测量时间和事件日志。 当前音频流的状态和音量,这些信息不会与特定的 tab 关联。 缓存活动信息,包括对媒体缓存的读取和写入。 我们可以用 Chrome 浏览器播放 B 站视频上的视频,然后使用 chrome://media-internals 工具进行分析,如下图所示: 如上图所示,媒体播放器的所有信息都会以列表的形式展现,同时列表中的每一项都会展现该项对应的播放状态。因为视频正在播放中,因此我们选择状态为 kPlay 的项目来查看对应的媒体播放器的信息。Player Properties 信息展示了媒体播放器的详细属性,例如: Property Value …… …… kVideoDecoderName VDAVideoDecoder kVideoTracks [{“alpha mode”:“is_opaque”,“codec”:“h264”,“coded size”:“1920x1080”,“color space”:“{primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}”,“encryption scheme”:“Unencrypted”,“has extra data”:false,“hdr metadata”:“unset”,“natural size”:“1920x1080”,“orientation”:“0°”,“profile”:“h264 high”,“visible rect”:“0,0 1920x1080”}] 根据 VDAVideoDecoder 的源码可以知道,VDAVideoDecoder 解码器是通过 MojoVideoDecoder 而运行于 GPU,因此我们可以确定,该 h264 编码的视频在播放时使用的是硬件解码。 使用 Chrome 播放一个 8K 视频,然后使用 chrome://media-internals 工具进行分析,可以得到如下信息: Property Value …… …… kVideoDecoderName Dav1dVideoDecoder kVideoTracks [{“alpha mode”:“is_opaque”,“codec”:“av1”,“coded size”:“7680x4320”,“color space”:“{primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}”,“encryption scheme”:“Unencrypted”,“has extra data”:false,“hdr metadata”:“unset”,“natural size”:“7680x4320”,“orientation”:“0°”,“profile”:“av1 profile main”,“visible rect”:“0,0 7680x4320”}] dav1d 解码器 是一个跨平台的开源 AV1 解码器,因此,对于该 8K 视频而言,Chrome 在播放时使用的是 CPU 解码。 三、注意事项 开启GPU硬件加速后,可能会带来一些潜在的问题。以下是一些需要注意的事项: 兼容性问题:并不是所有的显卡都支持GPU硬件加速。如果您的显卡不支持GPU硬件加速,开启该功能可能会导致浏览器崩溃或出现其他问题。在这种情况下,您可以选择关闭GPU硬件加速或尝试升级您的显卡驱动程序。 电池续航时间:开启GPU硬件加速可能会消耗更多的电池电量。在移动设备上使用Chrome浏览器时,请注意电池续航时间。 安全风险:开启GPU硬件加速可能会增加一些安全风险,因为某些恶意软件可能会利用GPU的特性来攻击您的系统。请确保您的浏览器和操作系统保持最新状态,并定期进行安全更新。 关闭不必要的扩展程序:一些扩展程序可能会影响GPU硬件加速的性能。在开启GPU硬件加速后,尝试关闭不必要的扩展程序,以观察是否有所改善。 检查您的浏览器版本:确保您使用的是最新版本的Chrome浏览器。开发者选项和功能可能在不同版本之间有所不同。 GPU状态监视:您可以定期检查浏览器的GPU状态,以确保一切正常工作。在Chrome浏览器中,可以按Shift+Esc打开任务管理器来查看GPU使用情况。 浏览器硬件加速闪屏问题 Chrome开启“硬件加速模式”后,在观看视频时,尤其是全屏时,会出现短暂黑屏或黑块或闪屏。如果关闭“硬件加速”,则会造成播放某些高清视频(例如HEVC)视频或弹幕卡顿。 原因 硬件系统里一般有一个主板集成显卡(集卡,板卡)和一个独立显卡(独卡),在Windows设置里,默认是让Chrome浏览器使用集卡。很多笔记本电脑只有集卡。 在Chrome硬件加速模式,默认开启的是Default(D3D11)模式。 解决办法 1. 让浏览器使用独立显卡 此方法适用于有较高性能的独立显卡的情况,Edge设置方式一样。 Windows设置 - 左侧“系统”,右侧“屏幕” - 显示卡,(这是Windows 11家庭版的路径,如果是Windows 10或者专业版,则路径会有所不同。可以在设置里搜索“图形设置”快速定位到此) 下面应用列表里如果没有Google Chrome,就点“浏览”按钮,一般在C:\Program Files\Google\Chrome\Application路径下找到chrome.exe,添加进来。 点击Google Chrome图标,点击“选项”按钮,在弹出窗口如下选择“高性能”,然后“保存”,就完事了。 2. 关闭硬件加速 下载播放视频,使用于电脑主要是工作,浏览器看视频主要是看情节,高不高清无所谓,要看高清就下载来看。 就不必设置上面1.了,直接在浏览器设置里关闭“硬件加速”。PotPlayer开启硬件加速(H/W)模式,资源占用好很多 3. 折中方案 使用场景:(1)只有集卡或独卡性能不佳,但又想用“硬件加速”。(2)独卡(英伟达Nvidia)性能好,追求更好效果。 首先根据硬件情况,在上面1.里做好选择。 在Chrome浏览器地址栏输入:chrome://flags 回车 找到“Choose ANGLE graphics backend”,在右侧选中“D3D9”,重启浏览器即可。 如果英伟达显卡且性能不错,可以考虑“OpenGL”选项。建议性能较好的显卡 (1060以上) 在 “Choose ANGLE graphics backend” 选项中选择 “D3D11on12” 选项,硬件开销比OpenGL低,在播放视频等场景下更不容易发生卡顿或者崩溃。 在选择 ANGLE 图形后端时,通常会提供以下几个选项: Default: 这是默认选项,浏览器会根据系统和硬件配置自动选择最适合的 ANGLE 后端。通常情况下,它会选择 Direct3D 11 (D3D11) 后端。 Direct3D 9: 使用 Direct3D 9 (D3D9) 作为 ANGLE 后端。这个选项适用于一些较老的硬件或者在某些情况下可能与 D3D11 不兼容的系统。 Direct3D 11: 使用 Direct3D 11 (D3D11) 作为 ANGLE 后端。这是目前大多数现代 Windows 系统上的默认选项,它提供了较好的性能和兼容性。 OpenGL: 使用原生的 OpenGL 作为 ANGLE 后端。这个选项通常用于在不支持 Direct3D 的系统上,或者在需要测试 OpenGL 兼容性时使用。 D3D11on12:它利用了 Windows 系统中的 DirectX 12 (D3D12) API。这种后端的存在是为了在兼容性和性能之间取得平衡,并提供一种更好的图形渲染体验。 ​ “D3D11on12” 后端的主要特点和区别包括: DirectX 12 的使用: D3D11on12 后端直接利用了 DirectX 12 API,而不是之前版本的 DirectX 11。这使得它能够更好地利用现代硬件的性能优势,并提供更高效的图形渲染。 向后兼容性: 尽管使用了 DirectX 12 API,但 D3D11on12 后端仍然能够向后兼容支持 DirectX 11 的硬件和驱动程序。这意味着它可以在较老的系统上运行,同时也能够充分利用新硬件的性能。 性能优化: 相对于传统的 D3D11 后端,D3D11on12 后端可能会在某些情况下提供更好的性能。特别是在需要大量渲染调用的场景下,以及需要更高的并发性能时,D3D11on12 可能会有所优势。 总的来说,D3D11on12 后端是一种在性能和兼容性之间取得平衡的选择,适用于那些希望利用现代硬件性能的用户,同时又需要保持向后兼容性的场景。 Nvidia 增强 Nvidia 3、4代显卡 浏览器更新到最新 Nvidia 驱动更新到最新 【硬件科普】GeForce Experience里那些被你忽略的强大功能 (youtube.com) Alt + F1 抓拍屏幕 Alt + F2 照片模型 Alt + F3 游戏滤镜 Alt + Z 开启 geforce experience N卡 RTX Super Resolution N卡开启 RTX Super Resolution Nvidia 控制面板 NVDIA App Geforce Experence Win11 设置 设置应用程序GPU 高性能模式 浏览器设置 edge 设置外部N卡视频增强选择如下。如果选择超分辨率,就是使用edge内置视频增强功能 完成以上设置之后,就可以开启浏览器视频增强。 随便一个在线视频,鼠标移动到视频上面就可以看到增强按钮 N卡颜色偏差 NVIDIA显卡显示器看起来灰蒙蒙的,可能原因有 显示器对比度低 传输线规格低 默认参数设置没有跳转 第三个原因解决方法如下 Shield Moonlight Game Streaming: Play Your PC Games Remotely (moonlight-stream.org) https://github.com/moonlight-stream/moonlight-android/releases https://github.com/moonlight-stream/moonlight-android/releases 在这里下载安装android app moonlight 然后在手机端打开moonlight 软件,添加 PC 同一网段的IP 注意事项 tmm,jackett,sonarr最好配置代理。否则,刮削,图片墙可能工作不正常。 docker最好配置镜像加速,提高安装docker速度 一些docker初始化安装,运行、更新时需要访问github,最好配置代理。推荐博主定制Docker bloodstar/v2fly-privoxy 附赠 使用TMDB(themoviedb)无法刮削电影的解决办法 原因:因为api.themoviedb.org被墙无法访问,导致使用]无法刮削或刮削特别慢 可通过修改本机host,指定api.themoviedb.org解析到可用IP来解决,可用的IP有: 查看api.themoviedb.org 解决: 威联通 修改\etc\hosts文件增加一行 api.themoviedb.org 威Windows 修改C:\Windows\System32\drivers\etc\hosts文件 api.themoviedb.org 群晖 修改\etc\hosts文件增加 api.themoviedb.org api.thetvdb.com 群晖Docker 设备不支持硬解输入以下代码: docker run --name=jellyfin --add-host=api.themoviedb.org:13.224.161.90 --add-host=image.tmdb.org:104.16.61.155 --add-host=api.themoviedb.org:13.35.67.86 --add-host=www.themoviedb.org:54.192.151.79 jellyfin/jellyfin:latest 支持硬解输入以下代码: docker run --name=jellyfin --add-host=api.themoviedb.org:13.224.161.90 --add-host=image.tmdb.org:104.16.61.155 --add-host=api.themoviedb.org:13.35.67.86 --add-host=www.themoviedb.org:54.192.151.79 --device=/dev/dri:/dev/dri jellyfin/jellyfin:latest version: '3' services: jellyfin: image: jellyfin/jellyfin:latest container_name: jellyfin extra_hosts: - "api.themoviedb.org:13.224.161.90" - "image.tmdb.org:104.16.61.155" - "www.themoviedb.org:54.192.151.79" Windows 性能优化 如何修复 Windows 10/11 中的桌面窗口管理器高 GPU 使用率 系列教程 全部文章RSS订阅 图书、音乐、视频多媒体锦集 Nas RSS分类订阅 视频图书和音乐完全自动化管理框架图解 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 如何使用media Go,MusicBrainz,Mp3tag工具刮削音乐 整理音乐资料库 私人在线音乐服务器搭建与使用介绍 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/9/1
articleCard.readMore

QNAP 修改应用启动顺序

关于本blog,图床一般使用github,已经配置了CDN,如果图片还是未显示请自行代理解决 有时候,你想修改一下安装的应用启动顺序。该怎么做了? 在无意中,博主发现了这个技巧。配置方法如下: 配置文件路径 配置文件内容 RC_Number是qnap配置应用启动顺序,数字越小优先级越高。看着100差不多就是用户程序高优先级上限了。如此,你可以把一些应用调整高优先级启动,例如代理配置v2ray, dns配置DNSCrypt Proxy和DNSMasq,以实现其它应用采用这些服务。把一些应用调整低优先级,如qbittorrent等。 ls /etc/config -alh lrwxrwxrwx 1 admin administrators 21 2021-08-31 17:20 /etc/config -> /mnt/HDA_ROOT/.config/ qnap使用init v系统。 如果改为systemd 系统启动,可以加快启动速度。一些应用延迟加载技术看起来也没做好。用户这里修改RC_Number 可以手动实现一些延迟加载功能。 /etc/init.d/QTransmission3.sh start #启动 /etc/init.d/QTransmission3.sh stop #停止 /etc/init.d/QTransmission3.sh restart #重启 原创首发 可以转载,但必须完整转载,并且带上原始地址链接。 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/9/1
articleCard.readMore

几种常用管理模型和方法

这些只是基本的工具,你需要了解。但是,和行业相关的知识更重要。就像做数学题,把一堆错综复杂的线索中归纳总结出来问题,提出解决方法,这中间需要丰富的行业知识,这个没法速成。总结完后,执行阶段,就像数学加减乘除一样,这些是基本的工具和方法。 PDCA原则意义 Plan:制定目标与计划; Do:任务展开,组织实施; Check:对过程中的关键点和最终结果进行检查; Action:纠正偏差,对成果进行标准化,并确定新的目标,制定下一轮计划。 意义:每一项工作,都是一个pdca循环,都需要计划、实施、检查结果,并进一步进行改进,同时进入下一个循环,只有在日积月累的渐进改善中,才可能会有质的飞跃,才可能取得完善每一项工作,完善自己的人生。 PDCA原则的八大步骤 5W2H分析法的意义 What:工作的内容和达成的目标; Why:做这项工作的原因; Who:参加这项工作的具体人员,以及负责人; When:在什么时间、什么时间段进行工作; Where:工作发生的地点 ; Which:哪一种方法或途径; How:用什么方法进行; How much:需要多少成本? 意义:做任何工作都应该从6W2H来思考,这有助于我们的思路的条理化,杜绝盲目性。我们的汇报也应该用6W2H,能节约写报告及看报告的时间。 5W2H分析法的内容 SMART原则的意义 Specific 具体的; Measurable 可测量的; Attainable 可达到的; Relevant 相关的; Time based 时间的; 意义:人们在制定工作目标或者任务目标时,考虑一下目标与计划是不是SMART化的。只有具备SMART化的计划才是具有良好可实施性的,也才能指导保证计划得以实现。 有的又如此解释此原则: ——S代表具体(Specific),指绩效考核要切中特定的工作指标,不能笼统; ——M代表可度量(Measurable),指绩效指标是数量化或者行为化的,验证这些绩效指标的数据或者信息是可以获得的; ——A代表可实现(Attainable),指绩效指标在付出努力的情况下可以实现,避免设立过高或过低的目标; ——R代表现实性(realistic),指绩效指标是实实在在的,可以证明和观察; ——T代表有时限(time bound),注重完成绩效指标的特定期限。 SMART原则实施要领 STAR法则的意义 STAR法则的内容 SWOT分析模型的意义 Strengths:优势 Weaknesses:劣势 Opportunities:机会 Threats:威胁 意义:帮您清晰地把握全局,分析自己在资源方面的优势与劣势,把握环境提供的机会,防范可能存在的风险与威胁,对我们的成功有非常重要的意义。 SWOT分析模型组合 GROW教练模型的意义 GROW教练模型的内容 时间管理-重要与紧急 A、重要且紧急 紧急状况 迫切的问题 限期完成的工作 你不做其他人也不能做 B、重要不紧急 准备工作 预防措施 价值观的澄清 计划 人际关系的建立 真正的再创造 增进自己的能力 C、紧急不重要 造成干扰的事、电话、 信件、报告 会议 许多迫在眉捷的急事 符合别人期望的事 D、不重要不紧急 忙碌琐碎的事 广告函件 电话 逃避性活动 等待时间 优先顺序=重要性*紧迫性在进行时间安排时,应权衡各种事情的优先顺序,要学会“弹钢琴”;对工作要有前瞻能力,防患于未然,如果总是在忙于救火,那将使我们的工作永远处理被动之中。 任务分解法[WBS] 即Work Breakdown Structure,如何进行WBS分解:目标→任务→工作→活动 WBS分解的原则: 将主体目标逐步细化分解,最底层的任务活动可直接分派到个人去完成;每个任务原则上要求分解到不能再细分为止。 WBS分解的方法: 至上而下与至下而上的充分沟通; 一对一个别交流; 小组讨论。 WBS分解的标准: 分解后的活动结构清晰; 逻辑上形成一个大的活动; 集成了所有的关键因素包含临时的里程碑和监控点; 所有活动全部定义清楚。 意义:学会分解任务,只有将任务分解得足够细,您才能心里有数,您才能有条不紊地工作,您才能统筹安排您的时间表。 OKR,目标与关键结果 OKR 实施过程中起草制定好目标和关键结果是非常重要的一环,有效的 OKR 制定需要满足 SMART 原则——明确的、可衡量的、可实现的、有相关性和有时限性。 目标(O)回答的是“我们想做什么”的问题,是定性的,要求能够鼓舞人心,激发团队共鸣。 关键结果(KR)回答的是“我们如何知道自己是否达成了目标要求”的问题,是定量的,设计 KR 最具挑战的部分是如何把目标中定性的描述抽象为定量的表示。 最后:只有掌握了正确科学的工作方法,才可能在未来的工作中,做到事半功倍的效果,才能更加从容且有重点的开展工作。好的工作方法,是成功的一半! 系列教程 全部文章RSS订阅 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2021/8/18
articleCard.readMore

qBittorrent 参数详细设置教程

全文将以目前的最新版v4.3.7为例,进行参数设置,老版本某些功能不太一致,请知悉。 行为参数 可用的UI主题清单:https://github.com/qbittorrent/qBittorrent/wiki/List-of-known-qBittorrent-themes 连接参数 速度参数 BT参数 匿名模式说明:https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode RSS设置 RSS正则表达式教程:https://www.jianshu.com/p/54e6137ea4e3 web参数 可用的备用WebUI清单见:https://github.com/qbittorrent/qBittorrent/wiki/List-of-known-alternate-WebUIs 高级参数 关于磁盘缓存的补充说明: 经常有人吐槽qB特别吃内存,个人猜测应该是磁盘缓存设置不正确导致的。磁盘缓存设置过小,磁盘缓存到期间隔过长,先下载的文件块来不及写入硬盘,新的文件块又到了,可能就会导致内存爆掉甚至磁盘I/O错误。个人建议:在进行高速下载时,适当将磁盘缓存调高,磁盘缓存到期间隔调低(下载时间隔越低写入越频繁,自己根据电脑的资源占用情况调整最适合自己的值)。实在不知道怎么调的,就干脆把磁盘缓存设置为-1(自动)好了,还不行,就把磁盘缓存到期间隔再调低一些。举一个例子,比如设置2048MiB磁盘缓存、300s磁盘缓存到期间隔时,当下载速度为50MiB/s的时候,300s的时间总共可以下载15000MiB,早就远远超过2048MiB了,不爆内存、不I/O错误才怪。所以当达到这个下载速度的时候,在磁盘缓存不变的情况下,根据简单的除法(磁盘缓存除以下载速度)可知,磁盘缓存到期间隔就应该设置到40s以下了。 qB在正常运行后,其占用的内存会比你所设置的磁盘缓存多几百M。所有的参数没有标准答案,一切都得根据你机子的本身属性以及实际的使用场景(比如CPU性能、内存大小、硬盘写入速度、下载速度等)来设置,建议大家多试验。 关于TCP、UTP的补充说明: TCP是Internet上最常用的协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP的优势在于双向互动机制兼顾数据传输的完整性、可控制性和可靠性,但复杂的校验与控制机制也使其没有UDP传输效率高。 UDP协议与TCP协议一样用于处理数据包,是一种无连接的协议。UDP的缺点是不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP优势在于带宽占用小、传输效率和连接成功率高,有益于内网用户(如通过UDP内网穿透UDP Hole Punching连接),但UDP与TCP协议相比也存在无反向确认机制、无流量和序列控制等弊端。 uTP(Micro Transport Protocol)是一种正在标准化的开放式BT协议,主要功能是提高宽带使用效率、减少网络问题。在减缓网络延迟和拥堵的同时最大化网络吞吐量、克服多数防火墙和NAT的阻碍,增强网络穿透和传输效率,同时增益流量控制,这对BT用户和ISP都是互利的。uTP虽基于UDP协议但有所不同,uTP通过拥堵控制算法(Ledbat)可限制延时,当延时不严重时可最大限度利用带宽,并能通过uTP提供的信息用于选择TCP连接的传输率,即使在不作限速设置的情况下,也能减少网络拥堵产生,当用户端之间都启用uTP时,可见明显的传输速率提升。内网无法实现端口映射的用户启用uTP,可以改善与网外用户的连接。 使用uTP进行连接的用户,其标志将包含“P”。 更多参数,官方说明 libtorrent 参数设置说明 整理 From qBittorrent 设置教程 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/8/18
articleCard.readMore

qnap IO 错误消除

问题 [Storage & Snapshots] Failed to check file system of volume "SYS". Storage pool: 1. Volume could not be unmounted. 检测问题 检测问题可选命令有 md_checker pvdisplay vgdisplay lvdisplay 处理步骤 备份 先备份数据,rsync比HBS3好用多了。 如果没有坏块 如果没有坏块,就在下图位置扫描坏块,扫描完,自动清除异常标志 如果有坏块 坏块修复 如果有坏块,可以使用 “DiskGenius”扫描修复 强制消除异常标志 開啟SSH 登入 console # sed -i '/pd_err_wwn_/d' /mnt/HDA_ROOT/.conf 重啟 NAS. The Solution Change the “/etc/lvm/lvm.conf” as described above In general one should configure the LVM to filter out all sd* devices and only see the /dev/emcpower* or /dev/mapper/* devices. If there are other non-mutipathed SCSI devices LVM volumes, e.g: /dev/cciss/*, then set the filter accordingly, for example: filter = [ "r/sd.*/" "a/dev/cciss/*/" "a/dev/emcpower.*/" "a/dev/mapper/*/" ] With this setting, the ‘lvmdiskscan’ and ‘pvscan’ commands should only find the /dev/ccisss/, /dev/emcpower and /dev/mapper/* devices. Stop any applications/services that access LVM managed devices/filesystems. Unmount all LVM-based filesystems. Deactivate all Volume Groups. # vgchange -an Rescan Volume Groups. # vgscan Re-activate Volume Groups. # vgchange -ay \8. Mount any LVM-based filesystems. Start any applications/services requring access to LVM managed devices/filesystems. 总结: 为了安全和稳定性,有坏块后,备份数据,使用DiskGenius修复坏块,(只能修复逻辑坏块,不能修复物理坏块),然后最好全盘格式化再使用。 SDD可以使用低级格式化,但会全盘减少一次写寿命。尽量少用。 进入维护模式,在进行修复,有可能解决问题! 参考 [I always get a failed to check Filesystem message](https://forum.qnap.com/viewtopic.php?t=162182) Duplicate PV Warnings for Multipathed Devices ‘Found duplicate PV’ warnings when using LVM with multipath storage in RHEL/CentOS pvdisplay shows “Found duplicate PV” on multipath device 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/8/18
articleCard.readMore

Debian Lenny Laptop安装记录

Debian Lenny Laptop安装记录 这是一篇非常有历史的文章了,写了十多年了。只在个人google doc中公开共享过。时至今日,参考价值还是非常大的。 目的是完全采用Linux系统来完成所有工作。 这篇文章当年我写了一周,每个步骤都是实践后仔细记录的。 摘 要 ​ 在现在电子信息化社会中,网络越来越重要,各种电子商务,网上银行,网络交友,SNS社区等越来越红火,各国政府都在进行电子信息化建设,准备网上办公,无纸化作业。信息化就是现代化的思想已经深入人心,然而信息化建设的基础硬件和软件: 硬件:CPU、主板、内存,硬盘等 软件:操作系统(Operate System如Linux,Windows,Mac OS等),浏览器(如Firefox,Opera,Maxthon,IE等),文档处理(OpenOffice,WPS,Word等),媒体播放(Mplayer,Realplayer等),以及其它软件工具。 则是其中的重中之重,电子信息化社会信息安全最为关键。因为你不知道微软的Windows中给你预留了多少漏洞和后门,你不知道Intel或者AMD在它们生产的硬件中留下了什么缺陷,了解一点软硬件知识的人都知道,软件后门可以使微软进入你的电脑如同自己的电脑一样,微软可以看到所有你的文档,照片,工作生活的数据,你的电脑中的数据对微软而言没有任何秘密而言;硬件缺陷同样可以做后门用,甚至发送一段短码瞬间可以使你的电脑崩溃。可见安全多么重要,那么如何提高安全了? ​ 答案就是使用开源!开源早已经形成了一套完整的套件,上面介绍的软件中每样的地一种都是开源工具,完全免费!而且开放源代码,你可以知道每行代码的作用,后门、间谍将不复存在!你常用的Windows工具每样Linux都有替代品,很多工具甚至本来就是Linux中移植到Windows中来的,如暴风影音,比特精灵,Vim,Emacs等。 ​ 本文简单的介绍了开源操作系统Debian的安装和配置,包括操作系统的安装、配置,常用工具的安装等详细过程,下文所叙全部经过测试,稳定运行。通过本文,您可以了解Linux操作系统大体组成结构,并且获得一部完全自己定制的操作系统! [TOC] 一:前言 从今天开始做个Debianer 刚从OpenSuSE 换过来的,感觉Debian非常强大。SuSE的yast2真的非常强大,刚离开yast感觉很痛苦,Novll的yast系统设置几乎在里面实现,它包括了系统硬件,软件设置,网络配置,服务器配置,各种系统设置等等。它把很多底层配置都接管了,使用SuSE的用户会发现SuSE比其他Linux发行版少很多配置文件。SuSE的yast2有命令行和图形界面两种操作方式,还有zypper这种完全命令行包管理工具。不过Debian的apt包管理更加强大,比zypper强大多了。 Debian以定制性非常强,运行稳定而著称,是最符合GNU精神的发行版,对各种硬件构架都支持,是世界上唯一一种几乎可以在所有硬件平台运行的操作系统。Ubuntu就是在Debian的基础上发行的衍生版。但是本人使用感觉Ubuntu的感觉不好,Ubuntu就像一个在Debian testing基础上优化过得Debian一样,而且阉割的厉害。不过正由于阉割的厉害,把用户管理的东西Ubuntu都自己设置了,Ubuntu才成为最容易操作的Linux操作系统,而且也是最流行的Linux操作系统。不过Ubuntu限制用户操作非常严,感觉这样很大程度上失去了Linux的自由,可定制等特性。对Linux新人来说一开始使用Debian会非常困难的,强烈建议对Linux包管理,运行结构了解大概后再开始使用Debian。 推荐的发行版有: OpenSuSE:优点是从Windows转过来几乎马上就可以上手,用户不需要改变多少使用习惯,并且图形界面非常华丽,号称是最华丽的Linux操作系统。默认的就比Windows XP漂亮多了,开启Compiz Fusion后的3D特效比Vista,Win 7都要漂亮。对一般用户家庭使用和办公使用完全可以满足要求。缺点就是国内源很少,官方源在国外比较慢,速度也不保证,升级只能是半夜了,不过采用DVD安装的话就没多大问题。SuSE的中文社区不完善也是一大缺点。 Fedora:著名的Redhat公司出品,国内源非常多,中文化非常好,中文社区也非常活跃,很多问题可以直接中文搜出结果。缺点是对习惯Windows的用户来说,一开始就使用Fedora对大家的入门门坎比OpenSuSE高。 Ubuntu:最流行的Linux发行版,使用非常简单,中文社区建设的非常好,源很多,缺点就是阉割的太厉害了。感觉这样的版本对深入了解Linux不好,个人看法,不过对非技术型用户使用到是个不错的选择。 Debian是最自由,定制性最高的发行版,当然对用户的入门要求就更高了。但是,一经你上手了,那么就再别无他求。Debian的好是谁用谁知道! 刚用上Debian,总结下,下面可能有错误之处,希望大家指出来。参考了很多人的文章下来的,对他们表示感谢! 注意:本教程为 二:安装Debian之前的准备工作 ● 强烈建议新人刚开始装不要按《 Debian etch 简要安装指南》那篇文章来,特别是笔记本用户,除非你对你的硬件非常熟悉。建议大家安装的时候选择图形界面安装。安装的时候选择图形界面,把Base system,Loptop,Desktop都安装上,这样会少很多麻烦的,它装了多余的东西和服务还是等进入桌面后再自己删除比较好。发现这样安装还是非常干净的,比之SuSE,Fedora之类的发行版默认安装东西要少多了。 ● 阵痛了好几天了,这几天重装了好多次Debian了,现在终于差不多了,3d打开了,系统很稳定。 笔记本是Dell Inspiron6400。 ● 强烈建议大家装机之前看看debian的官方wiki 例如我,就看下面这个: http://wiki.debian.org/InstallingDebianOn/Dell/Inspiron6400/lenny ● 大家的笔记本其他型号的话到下面网址找对应的型号 http://wiki.debian.org/InstallingDebianOn/ 上面网址的参考下就可以了,有些问题很多种解决方法的。 三:开始安装Debian 3.1:安装前的准备和安装方法选择 debian提供了很多安装方法,有网络安装,光盘安装,U盘安装,硬盘安装等多种方法。这里介绍下载光盘安装,这是对大多数人来说最为方便的安装发放,下载第一张光盘CD或者DVD镜像准备刻录安装。 注意:先备份好重要的资料!比如copy到移动硬盘,或者其它主机上等以免错误的操作造成不必要的损失。 进入Bios中设置光驱第一启动,放入光盘,等加载内核界面过去后,就进入安装界面了。 3.2:开始安装Debian 选择安装程序使用的语言,推荐选择English,选中文会装zhcon。 选择国家,首先选择 other ,然后在选择 Asia ,最后选上 China 。 选择键盘,直接默认就好了,也就是 American English ,如果你的不是美式键盘,就选择相应的键盘。 设置网络,如果是 DHCP ,填上主机名和所在的域名就好了,如果是静态 IP ,根据相应的填上就 OK。这里有无线网卡的朋友就有些郁闷了,记得先去下载你的无线驱动的deb包,放到u盘根目录插上usb结构,系统会自动安装你的无线驱动。(但是这里安装好了还是无法dhcp连上无线,我采用有线装的,不知道谁这里无线配成功了。装完系统后再使用#apt-get install firmware-iwlwifi 也可以。) 磁盘分区,根据个人的情况进行。这里要小心了,如果你有重要的资料的话,推荐手动分区。 对分区进行确认后就开始安装基本的系统,等待一段时间。 然后就是设置 root 账户的密码,以及日常使用的一个账户名称和密码。 账户设置好后对源进行设置,这里推荐手工输入。选择最上面一项。 ○ 输入:debian.cn99.com 或者:mirrors.163.com ○ 目录就是/debian/ 不需要改动。这两个其实都是一个源,我看到主机ip地址一样。这个应该是国内最快的源了。至少对大部分人来说。 根据个人的情况选择安装软件,推荐选择base system,laptop,desktop。 安装中,看网络状况时间不同,等待…。 安装 GRUB ,Yes安装到 MBR。 安装完毕,最后 Continue 回车重启进入期待已久的 Debian Lenny GNU/Linux。 四:配置Debia的基本中文操作环境 他哦难过上面二、三步,到现在你已经获得了一个基本的Debian Lenny操作系统了。但是到现在为止说能够顺手使用还太早,在正是使用之前还有几个事情需要做。 (注意#号提示的是root用户权限) 4.1:中文语言环境 4.1.1:重新配置locale,添加中文locale ​ 选择以下locale,以下为推荐语言环境,用户可以根据自己语言习惯自由选择: #dpkg-reconfigure locales en_US ISO-8859-1 en_US.UTF-8 UTF-8 zh_CN GB2312 zh_CN.GB18030 GB18030 zh_CN.GBK GBK zh_CN.UTF-8 UTF-8 zh_HK BIG5-HKSCS zh_HK.UTF-8 UTF-8 zh_TW BIG5 zh_TW.EUC-TW EUC-TW zh_TW.UTF-8 UTF-8 选择默认的locale为en_US.UTF-8或者 zh_CN.UTF-8。 4.1.2:安装localepurge #apt-get install localepurge ​ 在对话框中选择你要保留使用的locale,默认情况下它已经选好了你现前设置的那些locale,不过还是请仔细确认后再回车。当然你也可以使用 dpkg-reconfigure localepurge 来进行详细的配置。 ● 清除你用不着的locale,让他们释放你的磁盘空间 #localepurge ​ 以后你不管安装什么软件,它都将自动帮你清除那些没用的locale。清除完,它会提示你释放了多少磁盘空间。当然你可以配置它让它显示清除了哪些locale。 ​ Linux下面还有其他工具清理,如BleachBit,这是一款专为Linux 设计的系统清理工具。使用BleachBit,你可以清理系统中的缓存、不要的语言文件,历史、临时文件、cookies 等不需要的东西,这样可以释放你空间。推荐,不过Stable的源中没有该包,需要手动下载安装。 4.2:实现root用户登录自动Tab补全 修改 .bashrc ,打开bash_completion,让apt-get install 在ROOT 登录的情况下自动补全,其他用户自动设置好了的,不用修改。你可以先用VI打开 /etc/bash.bashrc ,在最下面用命令模式下的V 再按上下左右键老选择,按y键复制,(默认打开VI就处于命令模式。i a o s键插入,编辑模式,ESC返回,:q! 退出。) 然后 vi ~/.bashrc 按p 键粘贴。最后象这样 if [ -f /etc/bash_completion ]; then . /etc/bash_completion fi 当然你也可以用nano ,更简单。要复制功能,那么apt-get install gpm 然后 /etc/init.d/gpm start ,现在动下鼠标。是不是在动了,gpm是一个控制台下的鼠标服务。用鼠标左击拖动选中,右键粘贴。 4.3:将用户加入到sudoers列表中 #chmod +w /etc/sudoers #vim /etc/sudoers 添加一行:username ALL=(ALL) ALL 其中username是你的用户名,保存 #chmod 0440 /etc/sudoers 这样,您的普通用户可以使用"sudo + [命令]"来执行需要管理员权限的操作 4.4:配置更新源并更新系统 4.4.1:备份旧的源 #cp /etc/apt/sources.list /etc/apt/sources.list.old 4.4.2:配置新源 把下面的加进去,应该可以满足绝大多数人的要求了。 #gedit /etc/apt/sources.list ###====sources.list Begin===### ##cn99 deb http://debian.cn99.com/debian/ lenny main non-free contrib deb-src http://debian.cn99.com/debian/ lenny main non-free contrib deb http://debian.cn99.com/debian/ lenny-proposed-updates main non-free contrib deb-src http://debian.cn99.com/debian/ lenny-proposed-updates main non-free contrib deb http://debian.cn99.com/debian-security/ lenny/updates main contrib non-free deb-src http://debian.cn99.com/debian-security/ lenny/updates main contrib non-free deb http://debian.cn99.com/debian-backport/ lenny-backports main contrib non-free deb-src http://debian.cn99.com/debian-backport/ lenny-backports main contrib non-free deb http://security.debian.org/ lenny/updates main contrib non-free deb-src http://security.debian.org/ lenny/updates main contrib non-free deb http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free deb-src http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free deb http://http.us.debian.org/debian/ lenny main contrib non-free deb-src http://http.us.debian.org/debian/ lenny main contrib non-free deb http://www.debian-multimedia.org/ lenny main deb-src http://www.debian-multimedia.org/ lenny main deb http://download.virtualbox.org/virtualbox/debian lenny non-free ###===sources.list End===### 注意:debian-multimedia.org的源需要安装KEY,在http://debian-multimedia.org 下载安装debian-multimedia-keyring_2008.10.16_all.deb Debian采用严格的GPG认证来保证安装包不被恶意篡改,使您已经安装就是最新最稳定的系统! 4.4.3:更新源并升级系统 #apt-get update 这里就会提醒你有那些源没有GPG密匙,把错误密匙代号放到 iceweasel的搜索框,回车,就会看到大量的相关问题,随便点开2个就可以看到怎么样取得密匙。这个是偷懒的办法,但是非常有效!建议。 #apt-get update && apt-get upgrade 这次才是真的升级系统。如果通过网络安装,一般安装过程中就会自动选择最新的稳定的最新无漏洞包,一般来说没有更新包。 四:网卡,声卡及显卡驱动安装 4.1: 配置无线网卡和ADSL来上网 系统默认一般会识别有线的网卡驱动,Linux几乎可以识别现在所有的有线网卡,而无线网卡驱动由于是非 4.1.1:配置无线网卡 ● 驱动 这个看个文的硬件了 ​ #apt-get install firmware-iwlwifi ​ #modprobe iwl3945 #加载内核模块 ​ 这个我的Dell Inspiron6400的无线网卡是Intel 3945,其他无线网卡型号的用户请自己查找相关驱动包。 ● 安装管理工具 ​ apt-get install wifi-radar ● 配置无线 看大家的无线设置,选择Essid,加密方式,频段等。 4.1.2:使用PPPOE连接ADSL ● 使用PPPOE连接Adsl #apt-get install pppoeconf #pppoeconf #设置用户名与密码 #pon dsl-provider #连接 #poff #断开 4.2:让alsa把你的声卡驱动起来 #apt-get install alsa-base alsa-utils alsa-oss **配置声卡:**执行 alsaconf 一路回车。 再执行alsa-mixer 设置音量,M键取消静音,ESC 键退出。保存设置 alsactl store。 **测试 声卡:**cat /dev/urandom > /dev/dsp 你将会听到非常好听的声音,恭喜你,你的声卡工作了。 ctrl+c 终止它,当然你喜欢它的话,可以不那么做_ 到这里,你的X服务器和声卡就安装配置好了。 #apt-get install gnome-audio esound esound是gnome下的软件混音器 4.3:显卡驱动的安装及配置 http://wiki.cchtml.com/index.php/Ubuntu_Dapper_Installation_Guide 安装编译驱动所需的环境 sudo apt-get update sudo apt-get install module-assistant build-essential sudo apt-get install fakeroot dh-make debconf libstdc++5 linux-headers-$(uname -r) 创建安装包 sudo ./ati-driver-installer-8.x.x.run --buildpkg debian/testing 安装这些创建的包b sudo dpkg -i xorg-driver-fglrx_8.x.x-1_i386.deb -f sudo dpkg -i fglrx-kernel-source_8.x.x-1_i386.deb -f sudo dpkg -i fglrx-control_8.x.x-1_i386.deb -f 删除旧的源码包 sudo rm /usr/src/fglrx-kernel*.deb 编译并安装驱动模块 sudo module-assistant build fglrx sudo module-assistant install fglrx sudo depmod -a 编辑你的/etc/X11/xorg.conf 在 Section “Module” 中加入 Load "fglrx" Load "dri" Load "glx" 在Section “Device” 中把驱动换成 Driver "fglrx" 4.3.1:ATI显卡驱动安装 To build your own .deb packages you will need to install at least the following packages from the apt repositories: ● fakeroot ● debhelper ● build-essential ● make ● module-assistant Installing from Debian non-free Note: in lenny, they’ve renamed fglrx-kernel-src to fglrx-source (but the following worked for me with that substitution). Install the driver sudo apt-get update sudo apt-get install module-assistant fglrx-driver fglrx-kernel-src build and install the module #:sudo module-assistant auto-install fglrx-kernel-src After this, you need #:sudo aticonfig --initial This will update your xorg.conf to use the new driver. Restart for the changes to take effect. ==================== 1 构建相应的系统驱动包: ./ati-driver-installer-8.41.7-x86.x86_64.run --buildpkg Debian/unstable 我们可以用下面的命令来列出所有可以构建的程序包: ./ati-driver-installer-8.41.7-x86.x86_64.run --listpkg 我们可以从这个输出中选择适合我们系统的参数来进行构建相应的程序包。 2 安装所构建的程序包: # dpkg -i fglrx*.deb 3 安装module-assistant工具: # apt-get install module-assistant 4 使用m-a安装驱动模块 # m-a prepare # m-a a-i fglrx 驱动模块的安装需要相应的内核头文件,所以我们在进行这一步之前需要安装相应的头文件: # apt-get install linux-headers-`uname -r` 这样就可以自动来安装fglrx驱动模块了。 此时我们可以通过下面的命令来测试fglrx驱动模块是否安装成功: # modprobe fglrx 5 配置Xorg.conf 在配置中我们要做的主要工作就要载入fglrx模块,在"Deveice"部分,将vesa驱动改为fglrx,重新启动X。如果一切正常,我们就可以享受到ATI驱动的带来的视觉效果了。 我们可以用下面的命令来检测我们的ATI驱动是否安装成功: $ fglrxinfo 我们应得到下面的输出: display: :0.0 screen: 0 OpenGL vendor string: ATI Technologies Inc. OpenGL renderer string: ATI Mobility Radeon HD 2400 XT OpenGL version string: 2.1.7059 Release $ glxinfo | grep direct 我们希望的输出结果为: direct rendering: Yes 而我们在源中也可以找到相应的fglrx程序包: # apt-cache search fglrx 个人觉得没有必要非得安装所谓的官方驱动包,因为由所谓的官方驱动包中所解出正是源中的几个程序包,而我在安装了官方的驱动程序包后进行了一下upgrade,居然更新其中的两个包,既然这样,我们还不如直接安装源中的驱动程序包方便: # apt-get install fglrx* 使用m-a安装驱动模块时,我们也可以使用分步的安装方式,先编译,再安装,而不必一步到位: # m-a get fglrx # m-a build fglrx 这 时就会在/usr/src/目录下生成一个fglrx的deb包。编译驱动程序模块时需要安装Linux内核头文件,我的内核是自己编译的2.6.23, 但是在源中却迟迟没有相应的头文件包,真是相当郁闷的说。但是即使是这样,我却依然得到了一个编译生成的fglrx的deb包。我们可以使用dpkg来进 行安装。 最后需要进行Xorg的配置。最简单的就是将驱动改为fglrx。当然我们也可以使用ati所提供的相应工具来进行配置: # aticonfig --initial --input=/etc/X11/xorg.conf 这会进行相应的检测,并且修改xorg.conf文件。 4.3.2:NVIDIA显卡驱动的安装 五:常用软件安装及配置 ​ 发现Debian 即使是选择了base system,laptop,desktop其实也没有装多少东西,很多还需要自己安装,例如alsa-oss,gnome-audio等默认没有安装(应该没有记错)。下面很多东西可能系统已经安装了,但是这么做没有错的,下面的都是几乎不可缺少的组件。 5.1:Gnome相关 5.1.1:Gnome基本系统及基本管理工具 #apt-get install xorg gnome-core gdm gdm-themes gnome-system-tools gconf-editor nautilus-open-terminal gnome-power-manager gnome-screensaver xorg X窗口系统 gnome-core gnome核型组件 gdm #gnome 默认的窗口管理器 gnome-system-tools 服务、网络等系统工具 gconf-editor 配置编辑器 nautilus-open-terminal 在右键菜单中加入终端 gnome-power-manager #电源管理,休眠支持 gnome-screensaver #锁屏 gconf-editor #配置编辑器 ntfs-3g #支持NTFS文件格式的读写 nautilus-gksu #以管理员权限打开目录 5.1.2:安装gnome主题、图标、背景 #apt-get install gnome-themes gnome-icon-theme-dlg-neu gnome-backgrounds 5.3:常用软件工具安装 5.3.1:字体安装 ● 使用apt # apt-get install ttf-bitstream-vera ttf-arphic-uming ttf-freefont #ttf-freefont 解决flash菜单可能的乱码, WQY点整字体: apt-get install xfonts-wqy ttf-wqy-zenhei #文泉驿正黑字体 ● 手工安装字体 把字体".ttf"字体copy到"/usr/share/fonts"下面的某目录中 sudo mkfontscale sudo mkfontdir sudo fc-cache ● 系统字体优化: 1.右击桌面,打开外观管理器中的字体选项卡,将其中的字体全部改成雅黑字体,同时把窗口标题设置为加粗,并选择LCD模式。 2.在终端里输入指令 sudo gedit /etc/fonts/conf.d/49-sansserif.conf 将其中的字体全部改成雅黑,该操作也可以同时解决flash中出现方框的问题。 5.3.2:输入法 ● 安装scim中文输入法,可选其他的如fcitx #apt-get install scim scim-pinyin scim-tables-zh im-switch #im-switch -z en_US -s scim #英文系统下使用SCIM: scim-qtimm #scim兼容QT程序 #im-switch -s scim -z default ● 光标跟随 #gedit /etc/X11/xinit/xinput.d/scim #GTK_IM_MODULE=xim #QT_IM_MODULE=xim GTK_IM_MODULE=scim QT_IM_MODULE=scim ● 或者选择fctix 不管你是kde还是gnome 安装fcitx就这样: apt-get install fcitx im-switch im-switch -s fcitx -z default 5.3.3:双击安装deb文件 #apt-get install gdeb 5.3.4:压缩与解压缩 #apt-get install file-roller p7zip-full cabextract rar unrar p7zip-rar rar unrar cabextract#7z,rar,cab #apt-get install gnochm gnochm #CHM阅读,或者chmsee 5.3.5:安装OpenOffice.org #apt-get install openoffice.org-writer openoffice.org-calc openoffice.org-math openoffice.org-impress openoffice.org-gtk openoffice.org-help-en-us #apt-get install openoffice.org-l10n-zh-cn openoffice.org-help-zh-cn #中文界面和中文帮助 5.3.6:安装视频播放器 #apt-get install mplayer w32codecs smplayer w32codecs #多媒体库 5.3.7:PDF阅读 #apt-get install evince xpdf xpdf-chinese-simplified xpdf-chinese-traditional poppler-data xpdf-chinese-simplified xpdf-chinese-traditional poppler-data完美中文支持 5.3.8:图像处理 #apt-get install gimp 5.3.9:网络通讯 #apt-get install pidgin 编程环境支持 #apt-get install build-essential libgtk2.0-dev freeglut3-dev libtool autoconf automake subversion deb http://apt.jenslody.de/ any main deb-src http://apt.jenslody.de/ any main deb http://apt.wxwidgets.org/ etch-wx main #KEY: wget -q http://apt.jenslody.de/jens.asc -O- | sudo apt-key add - wget -q http://apt.wxwidgets.org/key.asc -O- | sudo apt-key add - 其他安装 安装Multiget:http://multiget.sourceforge.net/download.html 安装Opera:http://www.opera.com/download/ 安装RealPlayer:http://www.real.com/linux 安装AdobeReader:http://www.adobe.com/products/acrobat/readstep2_allversions.html 安装FlashPlayer:http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&P2_Platform=Linux 编译CodeBlocks的SVN版本: svn checkout svn://svn.berlios.de/codeblocks/trunk ~/Downloads/CodeBlocks 安装CodeBlocks: sudo apt-get install codeblocks alien a package converter,将rpm,dpkg,stampede slp己slackware tgz档格式间的转换 pdfedit 修改pdf文件 linux开发工具: gcc,make,autoconf,diff,patch,rcs,emacs mysql-admin,mysql-navigator,mysql-query-browser 安装版本控制软件 sudo apt-get install subversion cvs 安装中文输入法 sudo apt-get install scim-pinyin 安装词典 http://stardict.sourceforge.net sudo apt-get install stardict sox /usr/share/stardict/dic/stardict-langdao-ce-gb-2.4.2 (郎道汉英辞典) /usr/share/stardict/dic/stardict-langdao-ec-gb-2.4.2 (郎道英汉辞典) /usr/share/WyabdcRealPeopleTTS (英文语音词库) 安装邮件客户端 sudo apt-get install thunderbird 安装 win-xchm查看器 sudo apt-get install xchm 安装 msn for linux sudo apt-get install emesene 安装下载工具 ( bt 工具 transmission 默认已安装 ; amule 对应windows平台的 emule) sudo apt-get install gwget amule 安装 rss 订阅工具 sudo apt-get install liferea 硬件监控工具 sudo apt-get install sensors-applet 远程桌面管理,RDP默认已安装 sudo apt-get install xvnc4viewer 安装视频/音频解码器 gnome 平台推荐用 totem+gstreamer*, 直接点击多媒体文件,totem会自动搜索匹配解码器安装 特殊的rm, rmvb格式文件, RealPlayer 11 for Linux 刚发布 (http://www.real.com/linux) ,效果不错,可以不用 w32codecs 了. 安装 flash for firefox, 新版多了一个选项”swfdec player”, 推荐, 其对CPU消耗改善了 swfdec player for adobe/macromedia flash adobe flash player gnash swf player 中文编码配置 sudo vi /var/lib/locales/supported.d/zh 加入以下编码支持 zh_CN.GB18030 GB18030 zh_CN.GBK GBK zh_CN.GB2312 GB2312 zh_HK.BIG5 BIG5 zh_TW.BIG5 BIG5 立即应用更新 sudo locale-gen 安装 vim sudo apt-get install vim 配置 vim sudo vi /etc/vim.local 加入以下设置(个人喜好) syntax on set expandtab set tabstop=4 set shiftwidth=4 set sts=4 set autoindent set smartindent set cindent set number let &termencoding=&encoding set fileencodings=utf-8,gb18030,gbk,gb2312,big5 配置 gedit 执行 sudo gconf-editor 选择 apps/gedit-2/preferences/encodings 找到 auto_detected 编辑,在Values中分别加入 GB18030,GBK,GB2312,BIG5 界面风格 http://art.gnome.org Ubuntu 默认的橘黄风格让我”焦躁”,一直偏向用蓝,灰的风格 窗体用 SimpleBox (2.6 kb, 下载安装) 图标用 tango ( apt-get install tango-icon-theme ) Others apt-show-source apt-show-versions archmage chmsee aria2 debian-faq-zh-cn fontforge gedit-plugins gtkcookie gupnp-tools htmldoc powersaved tor ttf-bitstream-vera vim-addon-manager 六:笔记本配置专辑 Dell Inspiron 6400 - Video card: Intel Corporation- Mobile 945GM/GMS/940GML Express Integrated Graphics Controller- RAM: 2Go- Hard disk drive: 100Go- Processor: Pentium Dual-core 1.86GHz (T2130)- Ethernet card: Broadcom Corporation BCM4401-B0 100Base-TX- Wifi Card: Intel Corporation PRO/Wireless 3945ABG Network Connection- Optical device: DVD+RW- Screen WSXGA+: resolution=1200x800, size=15,4" wide Overall Status Core Components Boot Standard Kernel: LAN network card: Detect CD/DVD: Detect hard drives: Extra Features CPU Frequency Scaling Hibernation Sleep / Suspend Xorg - OpenGL - Resize-and-Rotate(randr) Switch to External Screen Mouse - Built-in (Trackpoint) [-] - Built-in (Touchpad) Modem [?] Wireless/Wifi Keyboard’s Hotkeys Legend : = OK ; Unsupported(No Driver) ; = Error (Couldn’t get it working); [?] Unknown, Not Test ; [-] Not-applicable = Configuration Required; = Only works with a non-free driver/firmware Configuration Display You will need to install the 915resolution package: # apt-get install 915resolution xserver-xorg-video-intel # 915resolution The 915resolution will try to get highest resolution, you can change this at /etc/default/915resolution. If you wish to enable DRI, GLX, etc. see Xorg.conf_Lenny_DellInspiron6400.txt . My configuration works fine with Compiz. If using newer “xserver-xorg” (version 7.3 +), do not install “915resolution” as it conflicts with “xserver-xorg-video-all” and “xserver-xorg-video-intel”. Also install “libgl1-mesa-dri” (and this also installs “libgl1-mesa-glx”) for OpenGL support. Use “glxinfo | grep direct” to check for direct rendering. The “glxinfo” util comes with the “mesa-utils” package. (Thanks to enouf and Nemoder on #debian@OFTC) Hibernation and Sleep/Suspend Works fine. Install, # apt-get install acpid hal pm-utils uswsusp powermgmt-base We will need to unload the “b44” module before hibernating, add the following to “/etc/pm/config.d/unload_modules”: SUSPEND_MODULES=“b44” The wireless drivers will be automatically handled by pm-utils. You should then be able to hibernate: # pm-hibernate And suspend: # pm-suspend Note that if you are trying to hibernate/suspend from within GNOME, you will need to be a member of the " powerdev" group. CPU Power Scaling Add a few modules to be loaded, # echo "acpi-cpufreq" >> /etc/modules # echo "speedstep_centrino" >> /etc/modules Then, install the “powernowd” daemon: # apt-get install powernowd Powenowd’s default settings should be OK for most people. Hotkeys These are automatically configures by: # apt-get install hotkey-setup WiFi We need to install the firmware: # apt-get install firmware-iwlwifi And it should work. If you get an error like “Kill switch must be turned off in order for wireless networking to work.” during system boot, you need to press the magic Fn + F2 button. 七:其他问题 0.多源混合使用 安装完稳定版系统,请先为整个系统所有软件包设置 hold on 状态,aptitude 可以很容易的完成此任务。 接着,添加多个版本的源,即由上而下依次为: stable stable-backports (当前是 lenny-backports,http://wiki.debian.org/Backports) testing sid experimental, 然后,请针对特定软件包的特定版本升级,注意一次升级一个包彻底解决一个包,勿贪心。 升级完成,再次设置 hold on 状态,如此反复。 有时需要人工介入满足特定软件包的依赖关系。 如,为了使用 DRI,给 lenny 安装新版 ati 开源驱动 radeon 软件包, 需要先手工升级 mesalib-7.4.、xorg-server-1.6. 等, 再手工安装 radeon 软件包,而不能直接安装 radeon 软件包的新版本, 混用多个版本的源时,aptitude 自动计算的依赖关系并不总是可靠的。 如果仍不够新,那就要自己动手配置编译。 如果愿意可以使用 debian 方式编译打包。 如果升级的软件包依赖一些基本的软件包如 glibc,最终得到的系统将不再是 debian 稳定版。 自动挂载U盘中文文件名乱码问题 解决方法:系统工具->配置编辑->/system/storage/default_options/vfat,双击mount_options,”添加”,在“新列表值”中填入“utf8”。 apt-get与dpkg的基本用法 #apt-get install packagename #安装一个新软件包 #apt-get remove packagename #卸载一个已安装的软件包(保留配置文件) #apt-get --purge remove packagename #卸载一个已安装的软件包(删除配置文件) #dpkg --force-all --purge packagename #强制卸载,风险大! #apt-get upgrade #更新所有已安装的软件包 #apt-get dist-upgrade #将系统升级到新版本 $apt-cache search 正则表达式 #在软件包列表中搜索字符串 $dpkg -l 正则表达式 #列出所有与模式相匹配的软件包 #apt-get clean #清理所有软件缓存 #apt-get autoclean #清理旧版本的软件缓存 #apt-get autoremove #删除系统不再使用的孤立软件 #apt-cdrom add #增加一个光盘源 $dpkg -l |grep ^rc|awk '{print $2}' | #xargs dpkg -P #清除所有已删除包的残馀配置文件 #auto-apt run ./configure #编译时缺少h文件的自动处理 安装RealPlay 下载bin包,到realplayer主页上下载 http://www.real.com/linux #chmod 755 ./*.bin #或chmod +x ./*.bin #./*.bin #一定要root安装,否则安装后无法启动。 安装FlashPlayer 在iceweasel提示安装时选择安装,如果安装失败: 下载install_flash_player_9_linux.tar.gz并解压,进入解压目录,执行 安装: sudo ./flashplayer-installer 若flashplayer菜单有乱码问题的话,执行:sudo mv /etc/fonts/conf.d/49-sansserif.conf /etc/fonts/conf.d/49-sansserif.conf.bak 安装ttf-freefont字体可解决swf文件中文乱码。 编译Code::Blocks的SVN版本 (a) 下载源码 svn checkout svn://svn.berlios.de/codeblocks/trunk ~/Sources/CodeBlocks (b) 编译 export ACLOCAL_FLAGS="-I `wx-config --prefix`/share/aclocal" ./bootstrap ./configure 或 ./configure --with-contrib-plugins=all make sudo make install © 缷载 sudo make uninstall (d) 重新编译 make clean make distclean make clean-bin make clean-zipfiles 详情:http://wiki.codeblocks.org/index.php…ource_on_Linux ● 关于64位系统使用32位软件额外需求 64位系统同样能使用32位的软件,只要在终端输入以下命令,安装相应的32位包: sudo apt-get install ia32-libs ia32-libs-gtk linux32 lib32asound2 ● MLdonkey+sancho安装 MLdonkey被誉为速度最快的电驴,同时支持很多种P2P的下载协议,包括edonkey2000、gnutella、gnutella2、bt、FileTP 等等。网上有很多安装和设置的文章,但是有点乱,有些也不够完整,今天有空将它整理如下 下载最新版 MLdonkey & sancho(左键点击) 一.安装 mldonkey: 解压缩mldonkey源代码并进入其目录,然后 $ sudo apt-get install ocaml $ ./configure $ make $ make install (使用新版本的mldonkey源代码编译安装后已不会有下载后文件名不支持中文的问题) 二.安装 sancho: sancho是mldonkey最好用的一个前端,下载回来的sancho只有一个文件,是一个脚本,先右键单击它,找到属性-权限部分,钩上“可执行”,然后在终端中运行之: $ ./sancho-*-linux-gtk.sh 然后会显示 Extract to directory [<sancho-*-linux-gtk>]: 输入自定义安装目录,随便你,我安装在/usr/local/sancho 稍等一会就装好了,在/usr/local/sancho/下有个sancho,双击它就能运行sancho # 下载 sancho 后用 root权限安装 user@~$ sudo sh sancho-0.9.4-59-linux-gtk.sh # 选择安装目录, 这里我安装在 /opt/sancho/ # 修改用户配置文件目录的权限 user@~$ sudo chown user:user -R ~/.sancho/ # 把 user 改成自己的用户名 三.sancho设置 先运行mlnet,在/usr/local/bin或/usr/bin下,然后运行sancho,首次运行会有配置向导,需要设置mlnet位置。在sancho里面也可以设置mlnet的运行路径 在工具->首选项->**sancho:**主要->可选的可执行core 那里填上你的mlnet路径。这样以后就可以直接启动sancho。 设置中文: 在工具->首选项->**sancho:**主要->使用本地文件 选择zh-CN,重启sancho后即为中文。 在工具->首选项->Main 设置 client_name 推荐设置成[CHN][VeryCD]yourname的形式,支持中文。 在工具->首选项->Bandwidth 设置 max_hard_upload_rate 和 max_hard_download_rate 分别是上传和下载速度,单位是KB 在工具->首选项->Networks 勾选 enable_overnet 和 enable_kademlia 在工具->首选项->Networks->Donkey有这两项: ED2K-force_client_high_id ED2K-force_high_id 如果你是公网用户,或者你是内网,且设置了端口映射,则勾选它们,如果你打死都是内网低ID用户,就不要选了,否则会很难连上服务器。 你可以选上试试看,不行再取消。 在工具->首选项->Networks->Donkey->ED2K-port 设置端口,如果你有windows下的emule,最好把他们的端口(tcp的)设成一样,因为有些路由器有记忆功能,导致windows下的端口在重启后仍然保留。一般emule默认端口为4662,但有些宽带运营商会封掉该端口,建议改掉。 在工具->首选项->Networks->Donkey->ED2K-max_connected_servers 设置服务器最大连接数,默认为3,不用太大,大了也没用,一般稳定下来也就三四个左右,我把它设为7 打开sancho主界面,点击控制台,然后在最下方的命令输入框那里 用如下命令导入服务器 servers http://www.emule.org.cn/server.met 用ov_load命令导入overnet的node列表,推荐下载http://download.overnet.org/contact.dat 用kad_load命令导入kad的node列表,推荐下载http://www.emule-inside.net/nodes.dat 或http://renololo1.free.fr/e/nodes.dat,也可使用eMule的nodes.data 对于ov_load和kad_load,需要先下载回本地,比如把contact.dat下载到桌面后,输入: ov_load /home/xxb/桌面/contact.dat 路径请修改为适合你自己的。 修改下载目录和temp目录: 默认目录分别为 ~/.mldonkey/incoming/files (BT则为~/.mldonkey/incoming/directories) 和 ~/.mldonkey/temp 修改 ~/.mldonkey/downloads.ini,找到“SECTION : Paths”,然后修改第一段和倒数第二段的路径,注意这里是相对路径。下载目录和temp目录最好放在同一个硬盘分区,否则下载完成转移临时文件时,硬 盘灯会狂闪。或者通过建立软链接来更改下载目录也可以(推荐)。 比如我把下载目录和临时目录都移到/home/xxb/Videos/下,则把~/.mldonkey/下的incoming和temp目录都剪切到/home/xxb/Videos/下,然后建立软链接: $ ln -s ~/Videos/incoming ~/.mldonkey/incoming $ ln -s ~/Videos/temp ~/.mldonkey/temp 四.设置浏览器关联 这里只说firefox的关联,如果需要设置其它浏览器,请参考mldonkey 和浏览器关联的办法,适用 firefox, konqueror 先建立脚本,这里我们把它取名为 submit, 放在 ~/.mldonkey 下面。内容如下: #!/bin/bash echo dllink $*|nc -q 1 127.0.0.1 4000 如果系统是ArchLinux,则需安装netcat(gnu-netcat),并改为 #!/bin/bash echo dllink $*|nc 127.0.0.1 4000 然后右键单击它,找到属性-权限部分,钩上“可执行” 接下来在firefox地址栏输入 about:config 新建 字符串(string) network.protocol-handler.app.ed2k 值为submit 脚本的位置,比如我的是 /home/xxb/.mldonkey/submit 也可以安装firefox扩展,以关联ed2k、bt等,解压后的mldoneky-distrib-xxx/ed2k_mozilla/文件夹下 有个 mldonkey_protocol_handler-xx.xpi,把它拖到fx窗口选择安装。重启后就可以双击MLdonkey Protocal Handler这个扩展设置关联了,这个扩展也可以关联到amule。不过扩展当然是能不装就不装,所以推荐使用submit脚本的方法。 五.WEB界面 你也可以用浏览器控制和观察mldonkey,地址是 http://localhost:4080/ 我比较推崇用这个,不占额外资源(不必一直开着sancho,毕竟java的东西会占不少内存和cpu),设置更强,不过是英文的。你还可以编辑~/.mldonkey下的各个文件进行设置,这里不再敖述。 六.端口映射 打开 http://localhost:4080/后,点击Help+->Sysinfo 这里可以查看mldonkey的端口使用情况,除了core那3个,建议其余的都在路由器里设置端口映射,如果有防火墙,还要打开相应端口。 点击查看各种主流路由器映射的设置方法 七.其它 本文基本只涉及电驴部分,如果还需要其它比如BT功能,请自行摸索,附一些主要的配置文件: ~/.mldonkey/downloads.ini 基本的设置( 这个是for edonkey和其他协议的) ~/.mldonkey/servers.ini 服务器列表文件 ~/.mldonkey/files.ini 当前已经完成的和未完成的文件列表 ~/.mldonkey/friends.ini 好友列表 ~/.mldonkey_gui.ini 图形前端的配置文件 另外其他的网络协议都有其单独的配置文件,一般都放在~/.mldonkey目录下 祝骑驴愉快 _

2021/8/18
articleCard.readMore

transmission 使用及其配置

安装 qnapclub docker docker hub version: "2.1" services: transmission: image: ghcr.io/linuxserver/transmission container_name: transmission environment: - PUID=1000 - PGID=1000 - TZ=Europe/London - TRANSMISSION_WEB_HOME=/combustion-release/ #optional - USER=username #optional - PASS=password #optional - WHITELIST=iplist #optional - HOST_WHITELIST=dnsnane list #optional volumes: - <path to data>:/config - <path to downloads>:/downloads - <path to watch folder>:/watch ports: - 9091:9091 - 51413:51413 - 51413:51413/udp restart: unless-stopped 控制脚本 /etc/init.d/QTransmission.sh start /etc/init.d/QTransmission.sh stop Transmission 配置详解 vi /share/CACHEDEV1_DATA/.qpkg/QTransmission/etc/settings.json "alt-speed-up": 500, # 限速时段上传限速值 "alt-speed-down": 500, # 限速时段下载限速值 "alt-speed-enabled": false, "alt-speed-time-begin": 540, "alt-speed-time-day": 127, # 时段限速日期(星期几),127 表示每天,更复杂配置参考官网。用 7 位二进制数表示,然后转换成十进制数,0000001 表示周日,1000000 表示周六,0000010 表示周一,0000100 表示周二。如果你只要在周末限速,该数应该 1000001,转换为十进制就是 65 "alt-speed-time-enabled": true, # 启用限速,为 false 时,以上计划配置则不生效,生效时会自动禁用 alt-speed-enabled 配置,二者只能选一个 "alt-speed-time-end": 420, # 限速时段结束时间,这个配置表示的是凌晨零点到开始时间的分钟数,比如 7:00 就是 7*60=420。需要注意的是,该时间是用的 GMT 时间,即北京时间 -8 小时。比如你计划北京时间 7 点 30 分开始,这个数字应该是(7-8+24)*60+30=1410 "bind-address-ipv4": "0.0.0.0", # IPv4 地址绑定,一般不要改动 "bind-address-ipv6": "::", #IPv6 地址绑定,一般不要改动 "blocklist-enabled": true, # 启动白名单,默认不启动,需要启动改为 true "blocklist-updates-enabled": false, "blocklist-url": "http://www.example.com/blocklist", "cache-size-mb": 4, #缓存大小,以 MB 为单位,建议设大一些,避免频繁读写硬盘而伤硬盘,建议设为内存大小的 1/6~1/4 "compact-view": false, "dht-enabled": false, #关闭 DHT(不通过 tracker 寻找节点)功能,不少 PT 站的要求,但 BT 下载设置为 true 会使得下载更好 "download-dir": "/share/Downloads", #下载的内容存放的目录 "download-queue-enabled": true, # 下载队列开关 "download-queue-size": 5, # 下载队列数量 "encryption": 1, # 加密。指定节点的加密模式,默认 1。0 表示关闭 , 0= 不加密,1= 优先加密,2= 必须加密 "lazy-bitfield-enabled": true, # 默认为 true,设置为 true 时可以避免某些 ISP 通过查询完整位段来屏蔽 BT,从而破解部分 ISP 对 BT 的封杀,当然不一定完全有效 "idle-seeding-limit": 30, "idle-seeding-limit-enabled": false, "incomplete-dir": "/share/Downloads", # 临时文件路径 "incomplete-dir-enabled": false, "inhibit-desktop-hibernation": true, "lpd-enabled": false, #禁用 LDP(本地节点发现,用于在本地网络寻找节点), 不少 PT 站的要求 "main-window-height": 500, "main-window-is-maximized": 0, "main-window-width": 615, "main-window-x": 337, "main-window-y": 211, "message-level": 2, "open-dialog-dir": "/share/Download", # 网页对话框打开的根目录 "peer-congestion-algorithm": "", "peer-limit-global": 240, # 全局连接数 "peer-limit-per-torrent": 60, # 每个种子最多的连接数 "peer-port": 51413, # 传入端口,预设的 port 口 "peer-port-random-high": 65535, # 传入端口随机值范围上限 "peer-port-random-low": 49152, # 传入端口随机值范围下限 "peer-port-random-on-start": false, # 启用随机端口,默认关闭,不建议改为 true "peer-socket-tos": "default", "pex-enabled": false, # 是否启用用户交换,默认为 true,关于 PEX,有兴趣的朋友可参考 http://en.wikipedia.org/wiki/Peer_exchange,对于只用 PT 的朋友,可以设为 false, 禁用 PEX(节点交换,用于同已与您相连接的节点交换节点名单), 不少 PT 站的要求 "port-forwarding-enabled": true, # 启用端口转发(uPnP),如果路由支持并且也开启了 uPnP,则路由会自动做端口映射,但是需要注意的是如果内网有几台机器同时使用 transmission,就必须更改 peer-port 值为不一样 "preallocation": 1, # 预分配文件磁盘空间,0= 关闭,1= 快速,2= 完全。建议取 1 开启该功能,防止下载大半了才发现磁盘不够。取 2 时,可以减少磁盘碎片,但速度较慢。 "prefetch-enabled": 1, "queue-stalled-enabled": true, "queue-stalled-minutes": 30, "ratio-limit": 2, # 分享率限制 "ratio-limit-enabled": false, # 启用分享率限制,默认不启用 "rename-partial-files": true, #在未完成的文件名后添加后缀.part,false= 禁用 "rpc-authentication-required": true, # 远程控制需要验证,默认为需要 "rpc-bind-address": "0.0.0.0", # 远程控制地址绑定,允许 IP 通过 RPC 访问,默认值表示任何地址都可以访问 "rpc-enabled": true, # 启用远程控制,默认启用 "rpc-host-whitelist-enabled": true, # 是否开启主机白名单 "rpc-host-whitelist": "", # 白名单,如果需要远程访问,最好配置 "rpc-password": "{cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaE", #web-ui 的密码,可直接修改,重新运行或者 reload 服务的时候密码会自动 HASH 增加安全性 "rpc-port": 9091, # 默认 web-ui 的 port 口,也是远程控制端口,可自行更改 "rpc-url": "/transmission/", "rpc-username": "transmission", #默认登入名称,也是远程控制用户名 "rpc-whitelist": "127.0.0.1", # 远程控制白名单,默认值为所有地址,支持通配符*,如 192.168.2.* "rpc-whitelist-enabled": true, # 启用远程控制白名单,如果启用,则仅仅上面列出的地址可以远程连接 "scrape-paused-torrents-enabled": true, "script-torrent-done-enabled": false, "script-torrent-done-filename": "/home/", "seed-queue-enabled": false, "seed-queue-size": 10, "show-backup-trackers": true, "show-extra-peer-details": false, "show-filterbar": true, "show-notification-area-icon": false, "show-options-window": true, "show-statusbar": true, "show-toolbar": true, "show-tracker-scrapes": true, "sort-mode": "sort-by-age", "sort-reversed": false, "speed-limit-down": 300, #平时的下载限速 "speed-limit-down-enabled": true, #启用平时下载限速 "speed-limit-up": 30, #平时上传限速 "speed-limit-up-enabled": true, #启用平时上传限速 "start-added-torrents": false, "statusbar-stats": "total-ratio", "torrent-added-notification-enabled": true, "torrent-complete-notification-enabled": true, "torrent-complete-sound-enabled": true, "trash-can-enabled": true, "trash-original-torrent-files": false, "umask": 18, "upload-slots-per-torrent": 14 "utp-enabled": true, #启用μTP 协议 "watch-dir": "/share/bt", # 监听文件夹目录 "watch-dir-enabled": false # 是否监听文件夹 Q:TR提示FILE NAME TOO LONG A:TR最大文件名MAX_PATH ,260个字符 方法2:遇到个名字特长的,一直下载失败,使用软连接进一步缩短路径名长度 #cd / #ln -s /share/CACHEDEV1_DATA/Download/ DL 方法3: 不过,最近有好消息,这个bug我去看了下源代码,找到原来有人试图修复过它,但是并没有合并到最新版本。发个post提醒bug没有修复,居然有回复了。这个bug将在3.0版本修复,见下图。 Q: transmission 如何修改登陆密码 A: 第一种方式 /share/CACHEDEV1_DATA/.qpkg/QTransmission3/etc/settings.json cd /share/CACHEDEV1_DATA/.qpkg/QTransmission3/etc/settings.json vim settings.json 找到”rpc-password”: 后面引号内就是经过加密的密码,不要管他怎么加密的,直接把引号内的内容修改为你的新密码就可以了,比如”rpc-password”:”xxorg.com” 然后按“ESC”键,输入:wq 保存退出,然后重启tr即可 第二种方式: # 1、控制台输入,-u后边是用户名,-v后边跟着的是登陆密码 transmission-daemon --paused -t -u admin -v 123456 # 将会把生成的密码保存到:~/.config/transmission-daemon/settings.json # 其实是生成配置文件并保存到当前登陆用户的家目录下 # 2、打开~/.config/transmission-daemon/settings.json并复制加密的密码 # 3、将加密的密码粘贴到/media/AiCard_01/transmission/config/settings.json # 替换掉内容为:rpc-password 后面的密码 # 4、重启Transmission ps:通过ps定位transmission位置 ps aux | grep trans # cd /share/CACHEDEV1_DATA/.qpkg/QTransmission3/bin # ./transmission-daemon --paused -t -u [name] -v [password] # cd ~/.config/transmission-daemon [~/.config/transmission-daemon] # vi settings.json 复制生成的密码到前面的配置文件里面。 Q: 为Transmission增加种子目录监控,实现自动下载 /share/CACHEDEV3_DATA/.qpkg/QTransmission3/etc 改/var/packages/transmission/target/var/settings.json 在最后面增加2行。 "upload-slots-per-torrent": 14,(原文件最后一行,注意添加个逗号,不添加transmission好像不能启动) "watch-dir": "/XXXXX/XXXXX", (修改成自己nas上的同步目录) "watch-dir-enabled": true(无逗号) 保存,退出。 启动Transmission 等待1-2分钟,就好了。 "speed-limit-up-enabled": false, "start-added-torrents": true, "trash-original-torrent-files": false, "umask": 18, "upload-slots-per-torrent": 14, "utp-enabled": true, "watch-dir": "/share/Download/Seed/complete", "watch-dir-enabled": true } Q: Nas 上面 Transmission 如何做种? A: 注意,此方法仅适用于开启了ssh的机器 方法也很简单,写一个范例 ./transmission-create -p -o /volume1/data/Wi kiLeaks-Year-Zero-2017-v1.torrent -t https://announce.XXXXXXXXXX.cc/announce.php -s 2048 /volume1/da ta/WikiLeaks-Year-Zero-2017-v1.7z & 参数 种子已经躺在这了 [/opt/QTransmission3/bin] # ./transmission-create -p -o /share/CACHEDEV1_DATA/Download/Seed/海贼王\ \(1999\).torrent -t https://announce.XXXXXXXX.video/announce.php -s 2048 /share/CACHEDEV1_DATA/Download/海贼王\ \(1999\)/ & 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/8/18
articleCard.readMore

Gitlab的安装及使用教程完全版

1. Gitlab概述 1.1 GitLab介绍 GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。 GitLab能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。 它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找 1.2 Gitlab服务构成 Nginx:静态web服务器。 gitlab-shell:用于处理Git命令和修改authorized keys列表。 gitlab-workhorse: 轻量级的反向代理服务器。 logrotate:日志文件管理工具。 postgresql:数据库。 redis:缓存数据库。 sidekiq:用于在后台执行队列任务(异步执行)。 unicorn:An HTTP server for Rack applications,GitLab Rails应用是托管在这个服务器上面的。 1.3 Gitlab工作流程 1.4 GitLab Shell GitLab Shell有两个作用:为GitLab处理Git命令、修改authorized keys列表 当通过SSH访问GitLab Server时,GitLab Shell会: 限制执行预定义好的Git命令(git push,git pull,git annex) 调用GitLab Rails API检查权限 执行pre-receive钩子(在企业版中叫做Git钩子) 执行用户请求的动作,处理GitLab的post-receive动作 处理自定义的post-receive动作 当通过http(s)访问GitLab Server时,工作流程取决于你是从Git仓库拉取(pull)代码还是向git仓库推送(push)代码: 如果是从Git仓库拉取(pull)代码,GitLab Rails应用会全权负责处理用户鉴权和执行Git命令的工作 如果是向Git仓库推送(push)代码,GitLab Rails应用既不会进行用户鉴权也不会执行Git命令,它会把以下工作交由GitLab Shell进行处理: 调用GitLab Rails API 检查权限 执行pre-receive钩子(在GitLab企业版中叫做Git钩子) 执行你请求的动作 处理GitLab的post-receive动作 处理自定义的post-receive动作 1.5 GitLab Workhorse GitLab Workhorse是一个敏捷的反向代理。它会处理一些大的HTTP请求,比如文件上传、文件下载、Git push/pull和Git包下载。其它请求会反向代理到GitLab Rails应用,即反向代理给后端的unicorn。 2. Gitlab的安装部署 Gitlab要求服务器内存2G以上 2.1 方式一:下载gitlab-ce的rpm包 gitlab官方rpm包下载 清华的源 将对应版本的gitlab-ce下载到本地后,直接yum安装即可 # 要先将这个rpm包下载到本地 yum install -y gitlab-ce-13.6.1-ce.0.el7.x86_64.rpm 2.2 方式二:配置yum源 在 /etc/yum.repos.d/ 下新建 gitlab-ce.repo,写入如下内容: [gitlab-ce] name=gitlab-ce baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ Repo_gpgcheck=0 Enabled=1 Gpgkey=https://packages.gitlab.com/gpg.key 然后创建cache,再直接安装gitlab-ce yum makecache # 这一步会创建大量的数据 # 直接安装最新版 yum install -y gitlab-ce # 如果要安装指定的版本,在后面填上版本号即可 yum install -y gitlab-ce-13.6.1 # 如果安装时出现gpgkey验证错误,只需在安装时明确指明不进行gpgkey验证 yum install gitlab-ce -y --nogpgcheck 2.2.1. 单服务启动模式 docker run -d --name gitlab --hostname gitlab.example.com \ -e GITLAB_OMNIBUS_CONFIG=" external_url 'https://gitlab.example.com' gitlab_rails['gitlab_shell_ssh_port'] = 22 nginx['redirect_http_to_https'] = true nginx['ssl_dhparam'] = '/etc/gitlab/ssl/dhparam.pem' nginx['ssl_certificate'] = '/etc/gitlab/ssl/domain.crt' nginx['ssl_certificate_key'] = '/etc/gitlab/ssl/domain.key' nginx['custom_gitlab_server_config'] = 'location ^~ /.well-known {\n alias /var/opt/gitlab/letsencrypt/.well-known;\n}\n' high_availability['mountpoint'] = ['/etc/gitlab', '/var/log/gitlab' '/var/opt/gitlab' # 严格限定gitlab服务启动前,指定文件系统挂完毕 " \ -p 22:22 -p 80:80 -p 443:443 \ -v /srv/gitlab/config:/etc/gitlab \ -v /srv/gitlab/logs:/var/log/gitlab \ -v /srv/gitlab/data:/var/opt/gitlab \ -v /etc/certs:/etc/gitlab/ssl \ --restart=always gitlab/gitlab-ce:latest 2.2.1. Compose服务编排模式(推荐方式) docker pull gitlab/gitlab-ce:latest ############################ 多行命令开始 ########################## cat > docker-compose.yaml <<EOF version: '2' services: Gitlab: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' hostname: 'gitlab.example.com' restart: always ports: - '22:22' - '80:80' - '443:443' environment: GITLAB_OMNIBUS_CONFIG: | # Add any other gitlab.rb configuration here, each on its own line external_url 'https://gitlab.example.com' gitlab_rails['gitlab_shell_ssh_port'] = 22 nginx['redirect_http_to_https'] = true nginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparam.pem" nginx['ssl_certificate'] = "/etc/gitlab/ssl/domain.crt" nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/domain.key" nginx['custom_gitlab_server_config'] = "location ^~ /.well-known {\n alias /var/opt/gitlab/letsencrypt/.well-known;\n}\n" high_availability['mountpoint'] = ["/etc/gitlab", "/var/log/gitlab", "/var/opt/gitlab"] # 严格限定gitlab服务启动前,指定文件系统挂完毕 volumes: - /srv/gitlab/config:/etc/gitlab - /srv/gitlab/logs:/var/log/gitlab - /srv/gitlab/data:/var/opt/gitlab - /etc/certs:/etc/gitlab/ssl EOF ############################ 多行命令结束 ########################## # 启动服务 docker-compose -f docker-compose.yaml up -d 2.3 gitlab的配置 配置文件位置 /etc/gitlab/gitlab.rb [root@centos7 test]# vim /etc/gitlab/gitlab.rb [root@centos7 test]# grep "^[a-Z]" /etc/gitlab/gitlab.rb external_url 'http://10.0.0.51' # 这里一定要加上http:// # 配置邮件服务 gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.qq.com" gitlab_rails['smtp_port'] = 25 gitlab_rails['smtp_user_name'] = "hgzerowzh@qq.com" # 自己的qq邮箱账号 gitlab_rails['smtp_password'] = "xxx" # 开通smtp时返回的授权码 gitlab_rails['smtp_domain'] = "qq.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = false gitlab_rails['gitlab_email_from'] = "hgzerowzh@qq.com" # 指定发送邮件的邮箱地址 user["git_user_email"] = "shit@qq.com" # 指定接收邮件的邮箱地址 修改好配置文件后,要使用 gitlab-ctl reconfigure 命令重载一下配置文件,否则不生效。 gitlab-ctl reconfigure # 重载配置文件 gitlab-ctl restart 测试邮件服务器 gitlab-rails console Notify.test_email('rollinghell@foxmail.com','testbiaoti','testzhegnwen1').deliver_now [root@test102 ~]# gitlab-rails console -------------------------------------------------------------------------------- GitLab: 12.5.0 (1f0ab8978ef) GitLab Shell: 10.2.0 PostgreSQL: 10.9 -------------------------------------------------------------------------------- Loading production environment (Rails 5.2.3) irb(main):001:0> Notify.test_email('andycrusoe@gmail.com','test','test').deliver_now Notify#test_email: processed outbound mail in 1.4ms Sent mail to anliven@126.com (73.0ms) Date: Wed, 27 Nov 2019 15:12:58 +0800 From: GitLab <gitlab@192.168.16.102> Reply-To: GitLab <noreply@192.168.16.102> To: anliven@126.com Message-ID: <5dde21fa612d4_3a1b3fcb38fcf9c0651b@test102.mail> Subject: test Mime-Version: 1.0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit Auto-Submitted: auto-generated X-Auto-Response-Suppress: All <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html><body><p>test</p></body></html> => #<Mail::Message:70141649239780, Multipart: false, Headers: <Date: Wed, 27 Nov 2019 15:12:58 +0800>, <From: GitLab <gitlab@192.168.16.102>>, <Reply-To: GitLab <noreply@192.168.16.102>>, <To: anliven@126.com>, <Message-ID: <5dde21fa612d4_3a1b3fcb38fcf9c0651b@test102.mail>>, <Subject: test>, <Mime-Version: 1.0>, <Content-Type: text/html; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>, <Auto-Submitted: auto-generated>, <X-Auto-Response-Suppress: All>> irb(main):002:0> irb(main):003:0> exit [root@test102 ~]# 配置gitlab代理 Setting custom environment variables | GitLab Log system | GitLab gitaly['env'] = { "http_proxy" => "http://USERNAME:PASSWORD@example.com:8080", "https_proxy" => "http://USERNAME:PASSWORD@example.com:8080" } 也可以使用单独模块代理 # Needed for proxying Git clones gitaly['env'] = { "http_proxy" => "http://USERNAME:PASSWORD@example.com:8080", "https_proxy" => "http://USERNAME:PASSWORD@example.com:8080" } gitlab_workhorse['env'] = { "http_proxy" => "http://USERNAME:PASSWORD@example.com:8080", "https_proxy" => "http://USERNAME:PASSWORD@example.com:8080" } gitlab_pages['env'] = { "http_proxy" => "http://USERNAME:PASSWORD@example.com:8080", "https_proxy" => "http://USERNAME:PASSWORD@example.com:8080" } # If you use the docker registry registry['env'] = { "http_proxy" => "http://USERNAME:PASSWORD@example.com:8080", "https_proxy" => "http://USERNAME:PASSWORD@example.com:8080" } 应用生效 gitlab-ctl reconfigure 2.4 Gitlab常用命令 gitlab-ctl start # 启动所有 gitlab 组件 gitlab-ctl stop # 停止所有 gitlab 组件 gitlab-ctl restart # 重启所有 gitlab 组件 gitlab-ctl status # 查看服务状态 gitlab-ctl reconfigure # 启动服务 gitlab-ctl show-config # 验证配置文件 gitlab-ctl tail # 查看日志 gitlab-rake gitlab:check SANITIZE=true --trace # 检查gitlab vim /etc/gitlab/gitlab.rb # 修改默认的配置文件 2.5 gitlab-ctl常用命令介绍 命令 说明 check-config 检查在gitlab中是否有任何配置。在指定版本中删除的rb deploy-page 安装部署页面 diff-config 将用户配置与包可用配置进行比较 remove-accounts 删除所有用户和组 upgrade 升级 service-list 查看所有服务 once 如果GitLab服务停止了就启动服务,如果已启动就不做任何操作 restart 重启GitLab服务 start 如果GitLab服务停止了就启动服务,如果已启动就重启服务 stop 停止GitLab服务 status 查看GitLab服务状态 reconfigure 重新配置GitLab并启动 3. Gitlab的使用 Gitlab安装好后,设置密码,管理账户为root 3.1 创建Group 填上组名即可,这里组名为java 3.2 创建User 创建四个User:pm、dev1、dev2、dev3 3.3 添加User到Group中并授权 3.4 创建Project并配置SSH 3.5 在项目中添加成员 3.6 将本地文件推送到Gitlab # 将app01项目克隆下来 git clone git@10.0.0.51:java/app01.git # 初始化配置 git config --global user.name "hgzero" git config --global user.email "hgzero@qq.com" # 在app01目录下新建一些文件 # 推送到gitlab git add . git commit -m "first edition" git push origin master 4. 制定开发计划 4.1 创建开发计划 项目:app01 版本:v1.0 4.2 创建里程碑Milestones 用pm账号登录gitlab后操作(先要在admin中设置pm账号的密码) 要根据开发计划来创建Milestones 4.3 根据开发计划创建issue 创建4个issue,分派给dev1和dev2这两个开发人员 **4.4 开发者登录账号查看分派的任务 ** 然后开发dev1登录gitlab,就能看到任务已经分配过来了 4.5 开发流程 公司里的开发开始任务 # 1. 先从仓库把项目拉下来 git clone git@10.0.0.51:java/app01.git cd app01/ # 2.先创建一个自己的分支,然后进行开发 git checkout -b index # 创建一个叫index的分支,并切换到这个分支 git status # 3. 开始开发首页 echo "<h1>welcome to this app</h1>" > index.html # 假设就开发了一个index页面 # 4. 开发完成后,把项目传到仓库 git add . git commit -m "index" # 如果写成 git commit -m "close #2" ,则表示merge请求允许且merge成功之后,自动删除编号为#2的issue # 传到index分支 git push origin index 4.6 合并分支 1)开发dev1发送合并分支请求给pm 2)pm收到开发的Merge请求后进行处理 使用pm登录,就可以看到pm已经收到了合并请求merge request 3)开发dev1确认任务完成 退出pm账户,登入dev1账户: 或者点进去后,在侧边栏进行标识Done,然后已经完成的issue,可以将其Close 这个时候Milestones的进度已经往前进了一些了: 4.7 开发其他功能 然后其他开发者或者自己再次进行开发时,先要把刚刚更新后的内容(master主干)拉回来,然后再进行开发 git checkout master # 切换到master 5. Gitlab备份恢复 5.1 备份gitlab 1)修改配置文件 /etc/gitlab/gitlab.rb # 备份保存的位置,这里是默认位置,可修改成指定的位置 gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" # 设置备份保存的时间,超过此时间的日志将会被新覆盖 gitlab_rails['backup_keep_time'] = 604800 # 这里是默认设置,保存7天 # 特别注意: # 如果自定义了备份保存位置,则要修改备份目录的权限,比如: # chown -R git.git /data/backup/gitlab 配置完成后要重启以使配置生效 # 重读配置文件 gitlab-ctl reconfigure # 重启gitlab gitlab-ctl restart 2)设置定时任务 # 每天凌晨2点定时创建备份 # 将一下内容写入到定时任务中 crontab -e 0 2 * * * /usr/bin/gitlab-rake gitlab:backup:create # 备份策略建议: # 本地保留3到7天,在异地备份永久保存 3)备份时间的识别 # 备份后的文件类似这样的形式:1494170842_gitlab_backup.tar,可以根据前面的时间戳确认备份生成的时间 data -d @1494170842 5.2 恢复gitlab 1)停止停止相关数据连接,数据写入服务 # 停止数据写入服务 gitlab-ctl stop puma gitlab-ctl stop sidekiq 2)进行数据恢复并重启 # 进行恢复 gitlab-rake gitlab:backup:restore BACKUP=1627839447_2021_08_01_14.1.1-ee # 这个时间戳就是刚刚备份的文件前面的时间戳 # 重启 gitlab-ctl restart 6. gitlab邮件通知配置 vim /etc/gitlab/gitlab.rb gitlab_rails['time_zone'] = 'Asia/Shanghai' gitlab_rails['gitlab_email_enabled'] = true gitlab_rails['gitlab_email_from'] = 'example@163.com' # 填写发件人的邮箱地址 gitlab_rails['gitlab_email_display_name'] = 'gitlab' gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.163.com" # smtp服务器的地址,如网易的地址 gitlab_rails['smtp_port'] = 25 # 要注意如果使用了SSL/TLS的话,端口可能不是25 gitlab_rails['smtp_user_name'] = "smtp用户名" gitlab_rails['smtp_password'] = "smtp用户密码" gitlab_rails['smtp_domain'] = "163.com" gitlab_rails['smtp_authentication'] = "login" 启用邮件功能 GITLAB_OMNIBUS_CONFIG 节点下增加如下几行: ########## 邮件服务配置 ########## gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.exmail.qq.com" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_tls'] = true gitlab_rails['smtp_user_name'] = "账号" gitlab_rails['smtp_password'] = "密码" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['gitlab_email_from'] = "发件人邮箱" 7. 使用SourceTree进行项目开发 7.1 项目拉取 先把项目克隆下来 如果ssh的方式克隆失败,可能是因为SSH Key没找到,可以在这里添加 7.2 创建分支进行功能开发 1)新建立一个叫“pay”的分支 2)进行功能开发 7.3 提交项目 1)开发pay功能完成后进行提交 可以看到SourceTree中已经有“未提交的更改” 2)添加“用户信息” ** 3)进行提交** 注释也可以写成 close #3 ,作用是提交完成后关闭3号issue 7.4 推送到仓库 然后就可以在gitlab上进行发送merge请求了,后面就可以进行其他操作了 7.5 项目上线 1)当所有工作完成之后,就可以进行上线了 2)打标签 上线先打个标签 ** 3)删除无用分支** 然后删除已经合并到主干中的不必要的分支,如index、pay等 最后一定要注意时间一定要同步,不然会错乱 8. Gitlab调优 gitlab对内存资源的消耗比较厉害 unicorn['worker_processes'] = 1 unicorn['worker_memory_limit_min'] = "300 * 1 << 20" unicorn['worker_memory_limit_max'] = "400 * 1 << 20" unicorn['worker_timeout'] = 15 sidekiq['concurrency'] = 10 sidekiq_cluster['enable'] = false sidekiq_cluster['ha'] = false redis['maxclients'] = "100" nginx['worker_processes'] = 2 nginx['worker_connections'] = 512 nginx['keepalive_timeout'] = 300 nginx['cache_max_size'] = '200m' mattermost['enable'] = false mattermost_nginx['enable'] = false gitlab_pages['enable'] = false pages_nginx['enable'] = false postgresql['shared_buffers'] = "256MB" postgresql['max_connections'] = 30 postgresql['work_mem'] = "8MB" postgresql['maintenance_work_mem'] = "16MB" postgresql['effective_cache_size'] = "1MB" postgresql['checkpoint_timeout'] = "5min" postgresql['checkpoint_warning'] = "30s" 配置调整后需要重载一下 docker exec gitlab gitlab-ctl reconfigure docker-compose down docker-compose up -d 9. Gitlab 启用 ContainerRegistry ContainerRegistry是Gitlab内置的Docker Registry集成组件 集成后每个项目可获得私有的 Docker 镜像存储空间 ContainerRegistry 可以复用 Gitlab 域名 或者 独立域名 这里配置为复用域名(此时ContainerRegistry 将复用 Gitlab 的 TLS 证书) docker-compose.yaml中Gitlab服务的 GITLAB_OMNIBUS_CONFIG 节点下增加如下配置: registry_external_url "https://gitlab.example.com:4567" # ContainerRegistry的外部访问地址 registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/domain.crt" registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/domain.key" gitlab_rails['registry_host'] = "gitlab.example.com" gitlab_rails['registry_port'] = "4567" gitlab_rails['registry_api_url'] = "http://localhost:5000" gitlab_rails['gitlab_default_projects_features_builds'] = false gitlab_rails['gitlab_default_projects_features_container_registry'] = false 端口开放增加 - 4567:4567 服务重启 docker-compose restart Gitlab ContainerRegistry 集成后可以通过 Gitlab 账户登录: docker login gitlab.example.com:4567 日常维护命令 # Gitlab维护 docker exec gitlab gitlab-ctl status # gitlab各组件服务状态 docker exec gitlab gitlab-ctl start/restart/stop [组件名] # gitlab所有组件的统一控制(其中Unicorn组件重启完成前GitLab会报502) docker exec gitlab gitlab-ctl tail [/var/log/gitlab下的某子目录] # 实时查看日志 docker exec gitlab update-permissions # 修复gitlab版本升级后出现的权限问题 docker exec gitlab gitlab-ctl reconfigure # 重载配置 docker exec -t gitlab gitlab-rake gitlab:backup:create # 创建备份 # ContainerRegistry维护 docker exec gitlab gitlab-ctl registry-garbage-collect # 垃圾回收,清理废弃layer(registry停机) Import Repository(Repo By Url) # 账号密码若存在特殊字符则需要url编码 https://username:password@host:port/group/project.git 10. GitLab重置用户名密码 打开终端,访问: gitlab-rails console 输入: user = User.where(id: 1).first user.password='123456' user.password_confirmation = '123456' user.save! #注意加上 “!” 然后退出命令行即可。 quit gitlab-rails console production 命令 开始初始化密码 # 在irb(main):001:0> 后面通过 u=User.where(id:1).first 来查找与切换账号(User.all 可以查看所有用户) # 通过u.password='12345678'设置密码为12345678(这里的密码看自己喜欢): # 通过u.password_confirmation='12345678' 再次确认密码 # 通过 u.save!进行保存 11. HTTPS SSL 支持 nginx反向代理方式 注意docker 内部没有ca支持, 需要手动添加 域名提供商提供的免费证书 这种证书直接用,如果是自签名证书,需要添加自己的ca root证书到服务器 12. Gitlab恢复数据出现must be owner of解决方法 按正常Gitlab备份数据gitlab-rake gitlab:backup:create ERROR: must be owner of extension plpgsql ERROR: must be owner of schema public ERROR: schema “public” already exists ERROR: must be owner of schema public ERROR: must be owner of extension plpgsql WARNING: no privileges could be revoked for “public” WARNING: no privileges could be revoked for “public” WARNING: no privileges were granted for “public” WARNING: no privileges were granted for “public” 解决方法: **1. 修改postgresql配置 ** cd /var/opt/gitlab/postgresql/data $ vi /var/opt/gitlab/postgresql/data/postgresql.conf listen_addresses = '*' 找到listen_addresses = ” 改为listen_addresses = ‘*’ 修改 /var/opt/gitlab/postgresql/data/pg_hba.conf $ vi /var/opt/gitlab/postgresql/data/pg_hba.conf local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust #ipv6 可以不配置 2. 重启gitlab生效 gitlab-ctl restart 3. 修改gitlab账号为超级用户 进入postgresql命令行 cd /opt/gitlab/embedded/bin su gitlab-psql ./psql -h 127.0.0.1 gitlabhq_production 查看账户权限 \du 执行修改gitlab用户为超级权限 ALTER USER gitlab WITH SUPERUSER; 退出 \q 4. 从1462989681编号备份中恢复 gitlab-rake gitlab:backup:restore BACKUP=1462989681 这样Gitlab恢复数据就不会再报must be owner of extension plpgsql错误。 4. 重启gitlab gitlab-ctl restart 13. Gitlab Pages 官方文档:https://docs.gitlab.com/ee/user/project/pages/ 。 Gitlab Pages 使用 GitLab Pages daemon 服务,它是用 GO 语言实现的简单 HTTP 服务,并且可以监听外部 IP 地址以及为自定义域名和自定义证书提供支持。它通过 SNI 支持动态证书并且默认通过 HTTP2 协议发送页面。最后推荐你去看官方文档 README 以便全面了解它的工作原理。 启用 Pages 打开 gitlab.rb: sudo vim /etc/gitlab/gitlab.rb 修改 Pages 配置: # Pages 服务地址 pages_external_url "http://git.17lai.io" # 启用 pages gitlab_pages['enable'] = true # fails to start in Docker gitlab_pages['inplace_chroot'] = true 让 Gitlab 使用当前配置: sudo gitlab-ctl reconfigure # stdout > gitlab Reconfigured! 如果没有域名怎么办呢?可以参考 Linux智能DNS服务搭建之Bind服务。 使用 Pages 官方的案例库:https://gitlab.com/pages 用户文档 一般有两种类型的Pages可以创建 对于用户(username.example.io)或组(groupname.example.io) 对于Project(username.example.io/projectname 或 groupname.example.io/projectname ) 在GitLab中,usernames或groupnames是唯一的,我们经常把他们称为namespaces。在一个GitLab实例中只能有一个namespace。 下面是Gitlab Pages类型、Project Name和 website URL对照表: GitLab Pages前提条件: 简而言之,这是上传web站点到GitLab Pages需要的: Gitlab Pages使用的域名(向管理员询问)。 创建一个Project。 仓库的根目录放一个.gitlab-ci.yml,其中有个叫做pages的job。 设置一个GitLab Runner构建web站点。 部署简单的 html 项目 我们在自己的 gitlab 上面创建一个测试项目:plain-html 把项目拉取到本地: # 换成你自己的仓库地址 git clone git@git.17lai.io:pages/plain-html.git 在项目中新建 public 目录,然后添加 index.html 、 style.css 文件: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="generator" content="GitLab Pages"> <title>Plain HTML site using GitLab Pages</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="navbar"> <a href="https://pages.gitlab.io/plain-html/">Plain HTML Example</a> <a href="https://gitlab.com/pages/plain-html/">Repository</a> <a href="https://gitlab.com/pages/">Other Examples</a> </div> <h1>Hello World!</h1> <p> This is a simple plain-HTML website on GitLab Pages, without any fancy static site generator. </p> </body> </html> body { font-family: sans-serif; margin: auto; max-width: 1280px; } .navbar { background-color: #313236; border-radius: 2px; max-width: 800px; } .navbar a { color: #aaa; display: inline-block; font-size: 15px; padding: 10px; text-decoration: none; } .navbar a:hover { color: #ffffff; } 在项目根目录添加 .gitlab-ci.yml 文件: # This file is a template, and might need editing before it works on your project. # Full project: https://gitlab.com/pages/plain-html pages: tags: - html stage: deploy script: - mkdir .public - cp -r * .public - mv .public public artifacts: paths: - public only: - master 提交代码: git add . git commit -m"feat(pages): 开启 pages 服务" git push 最后我们回到 gitlab 服务,在 plain-html 仓库中的 Settings / pages 页面可以看到已经有对应的服务地址了: gitlab 服务的域名跟 pages 的不要使用同一个,防止 XSS 攻击。 管理员文档:https://docs.gitlab.com/ce/administration/pages/ 用户文档:https://docs.gitlab.com/ce/user/project/pages/index.html gitlab pages:https://pages.gitlab.io/ Container Registry 官方文档:https://docs.gitlab.com/ee/user/packages/container_registry/ 本节修改中 开启 Container Registry 修改gitlab配置文件: vim /etc/gitlab/gitlab.rb //外部访问地址,此处被nginx代理,暴露给外部访问 registry_external_url 'http://xxx.com' //启用 gitlab_rails['registry_enabled'] = true //registry 服务ip gitlab_rails['registry_host'] = "172.29.1.70" //registry 服务真正端口 gitlab_rails['registry_port'] = "5000" 这里需要注意的是,registry_external_url是外部访问的url,如docker需要pull和push,都是访问该路径。然后,刷新配置,重启: gitlab-ctl reconfigure gitlab-ctl restart 访问Docker # docker login https://xxx.com -u root -p xxx Login Succeeded 默认需要SSL,请使用反向代理 官方文档有说明,如果启用了双重验证(Two-Factor Authentication)则不应该输入密码,而是token: docker login xxx.com -u <username> -p <token> CI GitLab Continuous Integration (GitLab CI/CD) CI: Continuous Integration:持续集成。 CD: Coninuous delivery and deployment:持续交付和部署。 Gitlab CI/CD 是以可持续方法论进行软件开发的内建工具(continuous integration service )。 在使用 Gitlab CI 之前,我们需要先了解几个概念: Stage 阶段:通俗的讲就是步骤(把一件事分解成多个步骤来完成)。 从最上面的图中可以看到在 CI 中可能会有:Build、Unit Test 、Integration Tests 等多个阶段。 Job 任务:就是我们在每个阶段具体要做的事情,而一个阶段可能会有多个任务。 Pipelines 一条流水线 ( pipeline)就是 一组 在各个阶段执行的任务。在同一阶段的多个任务是可以并行的(如果 Runner 足够多的话),当全部的任务都执行成功之后流水线将会进入下一个阶段。反之,如果其中有一个任务失败,流水线的下一个阶段将不再执行。 Runners 在 Gitlab CI 中,Runner 负责运行定义在 .gitlab-ci.yml 中的代码。Runner 为三种:Shared Runners、Group Runners、Specific Runners,分别表示全局共用 Runner、组共用 Runner、单个项目指定的 Runner。 .gitlab-ci.yml Gitlab CI 的配置文件,该文件声明了流水线的结构和顺序,以任务为最小单元。 文件中允许定义的元素: image:docker 镜像,当 Gitlab-Runner 的类型为 docker 时,会根据该属性指定的镜像为脚本执行容器。 services: 指定另一个 docker 镜像,主要用于提供服务层的能力,比如 mysql 。 before_script:任务执行前的钩子事件,比如一个 node 项目,我们可以在这里安装依赖。 after_script:任务执行后的钩子事件,当所有的任务都执行完毕之后被调用,不管任务是否执行成功。 stages:定义流水线中的阶段,默认的为 build 、test、deploy。如果我们要在任务中指定其他的 stage,则需要使用该属性先申明。 cache:需要缓存的文件,比如 node 项目可以把 node_modules 缓存起来。提示:可以定义在 .gitlab-ci.yml 顶级表示项目级别的,也可以申明在单个任务中。 variables:变量,同样可以在顶级或者单个任务中申明。 pages:内置的一个任务,用于上传任务执行的结果到 Gitlab Pages。 include:合并其他的 .gitlab-ci.yml 文件配置。 在单个任务中申明的元素: script:需要执行的脚本。 stage:标识该任务所属的阶段。 tags:为任务打上标签,用于选择特定的 Runner。 only:用于表明何时创建该任务。 except:用于表明何时不创建该任务。 when:用于表明何时运行该任务。 allow_failure:允许失败,该任务失败时不会影响整个流水线的结果。 artifacts:任务执行的结果,比如执行 打包任务 后的产出资源。 dependencies:依赖的其他任务。 retry:当任务失败时最多重试的次数。 coverage:指定如何从任务结果中提取代码覆盖率。 parallel:允许并行的任务实例个数。 请注意版本问题,每个属性对版本的要求并不一致,具体的可以点击属性查看官方文档。 使用 Gitlab CI 使用 Gitlab CI 服务的两种方式: 1. Auto DevOps 2. 手动配置 CI/CD Auto DevOps Auto DevOps 是 Gitlab 11.0 推出的新功能,它提供了预定义的 CI/CD 配置,允许我们自动检测、构建、测试、发布以及监控应用。 暂未使用,待补充。 手动配置 CI/CD 手动配置主要就 2 个步骤,配置 .gitlab-ci.yml 文件,添加 Gitlab Runner 运行该文件。 下面,我们看看如何配置 Gitlab Runner: Gitlab Runner Gitlab Runner 是一个开源项目,用来运行 .gitlab-ci.yml 中定义的任务并把结果返给 Gitlab。 安装 官方文档:https://docs.gitlab.com/runner/install/linux-repository.html 首先,添加离线仓库: curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash 然后,安装最新版本: sudo apt-get install gitlab-runner 注册 官方文档:https://docs.gitlab.com/runner/register/index.html 首先,我们进入要配置 Runner 的 Gitlab 仓库,在 Settings -> CI / CD 页面展开 Runners 配置面板可以看到已经分配的 Runner 以及注册 Runner 需要的参数: 然后,我们使用 Gitlab-Runner 命名开始注册: gitlab-runner register 执行完会该命令,终端会有交互,要求我们输入以下参数: gitlab-ci coordinator url :gitlab 服务地址 gitlab-ci token:上图中的 token description:描述信息 tags:标签,对应 .gitlab-ci.yml 任务中配置的 tags,只有 tags 匹配的任务才会被该 Runner 执行。 executor:执行器,即任务脚本执行的环境 如果使用 docker 执行,则需要事先安装 Docker 环境。 参数填写完毕之后,一个 Runner 便被注册成功了: 我们回到 gitlab 仓库页面,然后刷新便可以看到 _fzBq4PN 这个 Runner 已经被注册到该项目: 我们可以点击 编辑图标 对该 Runner 进行修改。我比较喜欢把 Run untagged jobs 选项勾上,这样就不用每个任务都添加对应的 tags 了(因为现在涉及到的都是一些简单的流程)。 总结 首先,CI/CD 是一种软件开发流程,Gitlab CI/CD 是 Gitlab 为实现该流程而提供的一个内置工具(服务)。 其次,我们有 Auto DevOps 与 手动配置 两种方式使用,本文讲解的主要是 手动配置 方式。 加速Gitlab Runner gitlab runner构建镜像每次RUN 安装依赖包,都远程下载?可以缓存加速吗? 可以的! 在将GitLab Runner注册到GitLab page上,让GitLab page可以和你的Runner通信时,有一步是填写使用的executor 输入Runner的executor: Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: 如果你选择Docker作为Runner的executor,你还要选择默认的docker image来运行job(当然,你也可以在.gitlab-ci.yml里指明你需要用的image),这句话就跟文章使用gitlab-runner往k8s上发送curl命令实现pod中容器使用的镜像版本更新,地址: 开头讲述的那样,不过.gitlab-ci.yml里指明的image优先级高。 注册完成后你可以在/etc/gitlab-runner里发现 config.toml文件,该文件是Runner的配置文件 接下来就牵涉到一个重要的话题 —— Executor Shell Executor Docker Executor # 仅作展示,未显示完整 [runners.docker] image = "jdd.io/jre:1.8.275" volumes = ["/cache","/run/docker.sock:/run/docker.sock"] 当你使用docker 或 docker+machine executors时,你可以通过设置pull_policy来决定Runner如何pull docker image。pull_policy有三种值: always —— Runner始终从远程pull docker image。 if-not-present —— Runner会首先检查本地是否有该image,如果有则用本地的,如果没有则从远程拉取。 never —— Runner始终使用本地的image。 注意:这一步就是本文开头提到的,使用本地镜像,不用再从dockerhub上拉取了 # 仅作展示,未显示完整 [runners.docker] image = "jdd.io/jre:1.8.275" pull_policy="if-not-present" # 添加这个选项就可以了 volumes = ["/cache","/run/docker.sock:/run/docker.sock"] 当你使用docker, docker+machine 或 kubernetes作为executor时,GitLab Runner将会使用特定的container来处理Git、artifacts 和cache 操作。 权限管理 以管理员的身份登入gitlab,点击Settings,然后选择Members,可以通过输入名字选择要分配权限的小组成员,然后分配角色,选择权限有效时间,点击Add to Project就把人员拉近到项目中。 GitLab的角色有以下四种: Guest:可以创建issue、发表评论,不能读写版本库 Reporter:可以克隆代码,不能提交,可以赋予测试、产品经理此权限 Developer:可以克隆代码、开发、提交、push,可以赋予开发人员此权限 MainMaster:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,一般GitLab管理员或者CTO才有此权限 访问权限 - Visibility Level: 这个是在建立项目时就需要选定的,主要用于决定哪些人可以访问此项目,包含3种 Private - 私有,只有属于该项目成员才有原先查看 Internal - 内部,用个Gitlab账号的人都可以clone Public - 公开,任何人可以clone 本文作者:夜法之书 写作不易,转载请注明来源地址! 参考链接: https://www.cnblogs.com/hgzero/p/14088215.html http://www.51blogs.net/2017/11/10/1110113243.html https://my.oschina.net/u/2400083/blog/808097 系列教程 全部文章RSS订阅 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2021/8/2
articleCard.readMore

docker使用简明教程

关于docker安装,查看,镜像管理,以及一个实用Dockerfile, LAMP,PHP,LTMJ。 关于本blog,图床一般使用github,已经配置了CDN,如果图片还是未显示请自行代理解决 Docker安装 在Ubuntu系统下安装: apt-get install docker 在Fedora/CentOS系统下安装: yum install docker dnf install docker # Fedora 25+ 在SUSE系统下安装: zypper install docker Docker容器 首先启动Docker # 启动Docker systemctl start docker # 设置开机自启动,可选 systemctl enable docker 启动Docker测试容器 docker run "hello-world" 在启动容器时,如果使用的镜像在本地不存在,会尝试从网络上获取。 在一般情况下,启动Web服务的容器,使用以下命令: # -d:daemon,使容器在后台运行 # -p:port,指定容器的端口,这里是将容器的80端口映射到主机的8001端口 docker run -d -p 8001:80 "image_name" 查看容器运行情况 docker ps Docker会为容器分配一个Container ID和一个Container Name,Name可以在运行时通过-name自行指定,这两个可以用来标识容器。 需要停止容器时,使用以下命令: docker stop "container_name" # 或使用ID查找 docker stop "container_id" # 重启 docker restart "container_id" Docker镜像 Dokerfile编译镜像 Docker容器是运行的Docker镜像实例,一般情况下,我们需要制作自己的Docker镜像。 Docker镜像的制作依赖于Dockerfile,我们稍后在讨论Dockerfile的编写,这里假定我们有一个编写好的Dockerfile。 下面的命令将在当前路径查找Dockerfile并构建一个名为“image_name”的镜像。 docker build -t "image_name" ./ 查看本地所有镜像 在构建过程中需要在网络上下载来源镜像,可能需要一段时间。 如果Dockerfile中的命令都正确结束(Exit code 0),那么Docker镜像的构建也将顺利完成,我们可以通过下面的命令查看我们的所有镜像: docker images 导出备份已有镜像文件 我们还可以导出我们制作好的Docker镜像,下面的命令将image_name镜像导出为image_name.tar docker save "image_name" > image_name.tar 导入已有镜像备份 在另一台机器上,我们不需要网络就可以导入并使用该镜像: docker load < image_name.tar Dockerfile Dockerfile本质上是一组命令集合,用于自动化构建镜像,下面以几个实例来说明Dockerfile的编写方法: 实例一:LAMP(Linux+Apache+MySQL+PHP)环境配置 # 来源镜像,一般可以使用标准的系统或者带有各种环境的系统 # 显然这里使用的是标准的Ubuntu 14.04系统 FROM ubuntu:14.04 # 镜像作者 MAINTAINER wrlu # 刷新日期 ENV REFRESHED_AT 2018-08-05 # 设定字符集 ENV LANG C.UTF-8 # RUN命令用于执行系统命令 # 因为需要自动化安装,所以最好通过-y命令跳过确认 # 更新APT软件源 RUN apt-get update -y # 安装MySQL RUN apt-get -y install mysql-server # 安装Apache RUN apt-get -y install apache2 # 安装PHP5 RUN apt-get -y install php5 libapache2-mod-php5 RUN apt-get install -yqq php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl # 删除Apache2列出目录配置 RUN sed -i 's/Options Indexes FollowSymLinks/Options None/' /etc/apache2/apache2.conf # COPY命令可以复制文件,但是似乎不能递归复制文件 COPY IncludeAirline/* /var/www/html/ COPY IncludeAirline/airlines/* /var/www/html/airlines/ # 删除默认的主页 RUN rm /var/www/html/index.html # 复制启动脚本 COPY start.sh /root/start.sh RUN chmod +x /root/start.sh # 设置启动目录以及启动脚本 ENTRYPOINT cd /root; ./start.sh # 设置需要暴露的端口 EXPOSE 80,3306 本例中还有一个启动脚本start.sh,用于导入数据库,编写如下: #!/bin/bash # 启动后延时 sleep 1 # 启动Apache服务器 /etc/init.d/apache2 start # 启动MySQL数据库 find /var/lib/mysql -type f -exec touch {} ; && service mysql start # 定义SQL文件路径 sqlfile=/var/www/html/includeAirline.sql if [ -f $flagfile ]; then # 修改MySQL的密码 mysqladmin -u root password "root" # 登录MySQL并导入SQL文件执行 mysql -uroot -proot < $sqlfile # 删除SQL文件 rm -f $sqlfile fi # 此处注意,如果命令执行完后脚本退出 # 则Docker容器也会因为没有前台应用运行而中止 # 所以这里使用一个前台命令来保活Docker容器 tail -f /var/log/apache2/error.log 实例二:PHP环境配置: # 来源镜像,自带Apache+PHP环境 FROM php:7.0-apache MAINTAINER tl ENV REFRESHED_AT 2018‐08‐03 ENV LANG C.UTF‐8 # ADD命令在COPY命令的基础上,具有自动解包tar的功能 ADD web_tired.tar /var/www/html/ EXPOSE 80 实例三:LTMJ(Linux+Tomcat+MySQL+JSP)环境配置 FROM ubuntu:16.04 MAINTAINER wrlu ENV REFRESHED_AT 2018-08-05 ENV LANG C.UTF-8 RUN apt-get update -y RUN apt-get -y install mysql-server # 安装wget,因为Docker提供的镜像是最小镜像,所以用到的其他工具需要自行安装 RUN apt-get -y install wget # 安装Java 8 RUN apt-get -y install openjdk-8-jre # 下载Tomcat 8服务器 RUN wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bin/apache-tomcat-8.5.32.tar.gz # 解压tar.gz RUN tar -xzf apache-tomcat-8.5.32.tar.gz -C /root RUN mv /root/apache-tomcat-8.5.32 /root/tomcat # 删除默认页面 RUN rm -rf /root/tomcat/webapps/* # 拷贝war文件 COPY CAAC-SQL-Injection.war /root/tomcat/webapps/ COPY wafwtf.sql /root/ COPY start.sh /root/start.sh RUN chmod +x /root/start.sh ENTRYPOINT cd /root; ./start.sh # Tomcat使用8080端口,不同于Apache EXPOSE 8080 启动脚本如下: #!/bin/bash sleep 1 find /var/lib/mysql -type f -exec touch {} ; && service mysql start chmod +x /root/tomcat/bin/startup.sh # 启动Tomcat服务器 /root/tomcat/bin/startup.sh sqlfile=/root/wafwtf.sql if [ -f $flagfile ]; then mysqladmin -u root password "root" mysql -uroot -proot < $sqlfile rm -f $sqlfile fi # 容器保活 tail -f /root/tomcat/conf/server.xml 系列教程 全部文章RSS订阅 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/8/1
articleCard.readMore

宝塔linux面板重启、重置等命令整合

宝塔linux面板重启、重置等命令整合 宝塔对新手入门还是比较友好的,方便了入门小站搭建。入门可用,一些新东西也可以在里面看看。大型应用还是的自己搭建。 来源于网络,原作已经不可考据,整理更新到目前最新版。 现在有很多网友都在使用宝塔主机管理系统、对一些不懂linux操作的朋友来说,是一个很好的管理系统、 Linux面板7.6.0安装命令: Centos安装命令: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 咨询离线安装版本 试验性Centos/Ubuntu/Debian安装命令 独立运行环境(py3.7) 可能存在少量兼容性问题 不断优化中 curl -sSO http://download.bt.cn/install/install_panel.sh && bash install_panel.sh Ubuntu/Deepin安装命令: wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh Debian安装命令: wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh Fedora安装命令: wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh Linux面板7.6.0升级命令:curl http://download.bt.cn/install/update6.sh|bash 以上节点无法使用的情况下,请使用下面的备用节点: 备用节点【香港】: (宝塔推荐使用CN2 双程GIA高品质,免备案的尊云zun.com香港云服务器安装) yum install -y wget && wget -O install.sh http://103.224.251.67:5880/install/install_6.0.sh && sh install.sh 管理宝塔 #停止 /etc/init.d/bt stop #启动 /etc/init.d/bt start #重启 /etc/init.d/bt restart #卸载 /etc/init.d/bt stop && chkconfig --del bt && rm -f /etc/init.d/bt && rm -rf /www/server/panel #查看当前面板端口 cat /www/server/panel/data/port.pl #修改面板端口,如要改成8881(centos 6 系统) echo '8881' > /www/server/panel/data/port.pl && /etc/init.d/bt restart iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 8881 -j ACCEPT service iptables save service iptables restart #修改面板端口,如要改成8881(centos 7 系统) echo '8881' > /www/server/panel/data/port.pl && /etc/init.d/bt restart firewall-cmd --permanent --zone=public --add-port=8881/tcp firewall-cmd --reload #强制修改MySQL管理(root)密码,如要改成123456 cd /www/server/panel && python tools.pyc root 123456 #修改面板密码,如要改成123456 cd /www/server/panel && python tools.pyc panel 123456 #查看宝塔日志 cat /tmp/panelBoot.pl #查看软件安装日志 cat /tmp/panelExec.log #站点配置文件位置 /www/server/panel/vhost #删除域名绑定面板 rm -f /www/server/panel/data/domain.conf #清理登陆限制 rm -f /www/server/panel/data/*.login #查看面板授权IP cat /www/server/panel/data/limitip.conf #关闭访问限制 rm -f /www/server/panel/data/limitip.conf #查看许可域名 cat /www/server/panel/data/domain.conf #关闭面板SSL rm -f /www/server/panel/data/ssl.pl && /etc/init.d/bt restart #查看面板错误日志 cat /tmp/panelBoot #查看数据库错误日志 cat /www/server/data/*.err #站点配置文件目录(nginx) /www/server/panel/vhost/nginx #站点配置文件目录(apache) /www/server/panel/vhost/apache #站点默认目录 /www/wwwroot #数据库备份目录 /www/backup/database #站点备份目录 /www/backup/site #站点日志 /www/wwwlogs # 执行宝塔Linux面板升级命令 curl https://download.bt.cn/install/update_panel.sh|bash Nginx服务管理 #nginx安装目录 /www/server/nginx #启动 /etc/init.d/nginx start #停止 /etc/init.d/nginx stop #重启 /etc/init.d/nginx restart #启载 /etc/init.d/nginx reload #nginx配置文件 /www/server/nginx/conf/nginx.conf Apache服务管理 #apache安装目录 /www/server/httpd #启动 /etc/init.d/httpd start #停止 /etc/init.d/httpd stop #重启 /etc/init.d/httpd restart #启载 /etc/init.d/httpd reload #apache配置文件 /www/server/apache/conf/httpd.conf MySQL服务管理 #mysql安装目录 /www/server/mysql #phpmyadmin安装目录 /www/server/phpmyadmin #数据存储目录 /www/server/data #启动 /etc/init.d/mysqld start #停止 /etc/init.d/mysqld stop #重启 /etc/init.d/mysqld restart #启载 /etc/init.d/mysqld reload #mysql配置文件 /etc/my.cnf FTP服务管理 #ftp安装目录 /www/server/pure-ftpd #启动 /etc/init.d/pure-ftpd start #停止 /etc/init.d/pure-ftpd stop #重启 /etc/init.d/pure-ftpd restart #ftp配置文件 /www/server/pure-ftpd/etc/pure-ftpd.conf PHP服务管理 #php安装目录 /www/server/php #启动(请根据安装PHP版本号做更改,例如:/etc/init.d/php-fpm-54 start) /etc/init.d/php-fpm-{52|53|54|55|56|70|71} start #停止(请根据安装PHP版本号做更改,例如:/etc/init.d/php-fpm-54 stop) /etc/init.d/php-fpm-{52|53|54|55|56|70|71} stop #重启(请根据安装PHP版本号做更改,例如:/etc/init.d/php-fpm-54 restart) /etc/init.d/php-fpm-{52|53|54|55|56|70|71} restart #启载(请根据安装PHP版本号做更改,例如:/etc/init.d/php-fpm-54 reload) /etc/init.d/php-fpm-{52|53|54|55|56|70|71} reload #配置文件(请根据安装PHP版本号做更改,例如:/www/server/php/52/etc/php.ini) /www/server/php/{52|53|54|55|56|70|71}/etc/php.ini Redis服务管理 #redis安装目录 /www/server/redis #启动 /etc/init.d/redis start #停止 /etc/init.d/redis stop #redis配置文件 /www/server/redis/redis.conf Memcached服务管理 #memcached安装目录 /usr/local/memcached #启动 /etc/init.d/memcached start #停止 /etc/init.d/memcached stop #重启 /etc/init.d/memcached restart #启载 /etc/init.d/memcached reload 参考 bt doc 宝塔面板手册 附赠 强制升级宝塔数据库版本 方法一 打开/www/server/panel/class目录下的panelPlugin.py文件 修改如下所示的部分代码 注释下面代码 8.0.0版本约802行 if not self.check_mem_limit(versionInfo['mem_limit']): return public.returnMsg( False, '至少需要[%dMB]内存才能安装' % versionInfo['mem_limit']) 重启宝塔面板 此时就可以顺利升级数据库版本了! 方法二:修改宝塔面板文件/www/server/panel/date/plugin.json /www/server/panel/date,修改plugin.json文件。搜索 /www/server/mysql/bin/mysql 根据所要安装的mysql版本修改对应的配置,mem_limit是内存限制,CPU_limit是CPU限制。将对应值修改为小于你服务器你内存或者CPU的值。

2021/7/31
articleCard.readMore

3G,4G,Wifi选型需求分析及技术简介

3G,4G,Wifi选型需求分析及技术简介 文章写了好多年了,只在一个网站发布过PDF版本,行业内应该很多人看过这个。 关于本blog,图床一般使用github,已经配置了CDN,如果图片还是未显示请自行代理解决 原创声明警告,本文禁止转载,禁止发布到其它任何网站,可以接受约稿。 用户需求分析 减少布线,或有的地方很难布线。 ​ 例如:偏远森林,沙漠,海岛,土地所有制导致不能随便开挖等各种原因。 –3G,4G– 优点: 布线,距离远。 缺点:流量费高(可以和运营商合作 ) –Wifi– 优点:费用低, 缺点:距离近 研发需求分析 WANTED! 3G,4G选型标准需求 1:产品生命周期,时间空间的重叠。 初产时间较近,出货时间长, 2:客户那里运营商网络制式??(例如TD-LTE****,FDD-LTE,CDMA2000等等), ​ 运营商名称??(一般不同国家不一样,一个国家很多个运营商) 3:3G,4G具体型号选择: 1:厂家选择??? 2:网络制式选择(需要选择制式尽可能支持区域大的,亚洲,欧美,日韩)??? 3:USB 使用的技术代差(1:usb猫,2:usb光驱,3:html拨号) 4:客户3G,4G使用场景??。流量大小,费用 **注意:**可能客户那里支持的制式和国内不一样,我们这边验证的制式在客户那里不能用,客户那里支持的制式在国内又没法验证。选择制式的时候特别需要注意。 Wifi选择需求 5:芯片厂家需要支持Linux驱动。 芯片出来年代???,价格???,协议标准(决定速度),网络信号质量???,传输速度(不同距离速度,是否要求穿墙)??? 6:对应的无线路由器调试 7:客户Wifi使用场景??。 主要是使用距离引起速度衰变, 现在有2,4G,5G路由,速度有150Mbit/s 300Mbit/s,450Mbit/s。需要ap评估这种速度能否满足各种场景使用需求 3G,4G部分 中国2G,3G,4G制式标准 UMTS(Universal Mobile Telecommunications System),意即通用移动通信系统。UMTS是国际标准化组织3GPP制定的全球3G标准之一。作为一个完整的3G移动通信技术标准,UMTS并不仅限于定义空中接口。它的主体包括CDMA接入网络和分组化的核心网络等一系列技术规范和接口协议。除WCDMA作为首选空中接口技术获得不断完善外,UMTS还相继引入了TD-SCDMA和HSDPA技术。 电信 2G CDMA 3G CDMA2000 4G TD-LTE**,**FDD-LTE 移动 2G GSM 3G TD-SCDMA 4G TD-LTE**,**FDD-LTE 联通 2G GSM 3G WCDMA 4G TD-LTE**,**FDD-LTE 中国移动TD-LTE:支持频段38、39、40 中国联通TD-LTE:支持频段40、41 中国电信TD-LTE:支持频段40、41 中国联通FDD-LTE:支持频段3 中国电信FDD-LTE:支持频段3 全球制式和区域 2G有GSM,还有CDMA。 ​ 我们平时说的G 网或者C 网了。联通和移动都是GSM,电信的133号段(之前是联通主营,后来转移给电信)是C网 3G有3种:WCDMA,CDMA2000,TD_CDMA WCDMA(日本、欧洲)、CDMA2000(北美)、TD-SCDMA(中国移动) 使用最广泛的是WCDMA。美国、欧洲等国很多是WCDMA和CDMA2000都有的。 WCDMA(欧洲版):这个是欧洲的主流,也是目前世界范围3G 的使用模式最广的,在中国大陆,是中国联通3G (沃)的模式。 4G有2种: LTE FDD,LTE TDD LTE FDD(世界绝大多数国家)、LTE TDD(中国移动和国外极少数地区的个别运营商)。 TD- LTE是我国自主研发的4G标准,是由TD-SCDMA(3G网络)发展而来。 LTE FDD是现在国际上主流的,使用最广泛的4G网络,由WCDMA演化而来。 现在全球有超过200个LTE的商用网络,其中超过90%是FDD的。 从技术上说,TD- LTE采用的是时分双工,而LTE FDD采用的是频分双工 TD-LTE和FDD-LTE 是4G的两种国际标准,各有利弊。TD-LTE占用频段少,节省资源,带宽长,适合区域热点覆盖;FDD速度更快,覆盖更广,但占用资源多。适合广域覆盖。 国内三家运营商4G网络制式分别如下: 联通4G:TD-LTE、FDD-LTE 电信4G:TD-LTE、FDD-LTE 移动4G:TD-LTE 虽然联通跟电信都是采用双4G网络制式,但目前4G网络仅在部分地区覆盖,3G网络仍然是不可或缺的。而联通3G采用的是WCDMA,为欧洲标准,是技术发展最成熟、国际通用和覆盖范围最广的制式,目前是国内3G网络最快的,最高可达42Mbps,在国外已将其定义为4G标准。 综合以上,选型推荐。 3G推荐选型:WCDMA欧洲,CDMA2000美国 4G推荐选型:FDD-LTE WIFI部分 2.4G和5G究竟是什么 以往我们一直使用的Wi-Fi大多数是支持 IEEE 802.11n(第四代)无线标准的,而且工作在2.4GHz这个频段上的,所以称之为2.4gWi-Fi,但是严格来说工作在5GHz频段上的不一定就是5G Wi-Fi,因为IEEE 802.11a(第一代)IEEE 802.11n(第四代)和IEEE 802.11ac(第五代)这三种标准都可以工作在5GHz这个频段上。 严格来说只有支持802.11ac的才是真正5G Wi-Fi(在这个视频里我们将它称作ac 5G),现来在说支持2.4G和5G双频的路由器其实很多都是指支持第四代无线标准,也就是802.11n的双频,而真正支持ac 5G的路由最便宜都要400、500甚至上千元 我们的路由器一般会有标有一些类似54Mbps,150Mbps,300Mbps这样的参数,要说明一下,这个参数不是指路由器的无线覆盖范围,而是指它的最高传输速率。若要支持ac 5G的也要双方同时支持,单方面支持是不行的。 这个速率就相当于车道上的限速标志,当然也不能完全等同与限速标志,因为如果网络中多个设备同时传输要分流的 最后不要忘记要考虑空间的大小,200多平米的房子一般普通无线路由器的2.4G勉强可以覆盖,5G的话150平米就开始有压力,如果房屋太大或者多楼层的话可能就要考虑一下多个无线路由桥接了。 5GWifi速度快,穿墙弱 5G Wi-Fi的最大缺点就是穿墙能力比较弱,墙体对Wi-Fi信号的强度影响是比较大的,每穿过一面墙,Wi-Fi信号就要减弱不少。 路由器摆放小技巧。增强信号。 最根本一半是有线速度限制,但信号强度也很重要 另外分享一个摆放路由器的方法,如果受制与网线或者台式电脑的位置就没得说,但是如果可以移动的话,这个位置的原则是要经过尽量少的墙体 最好不要放在地上,更不要放在角落, 放在高处 而且应该经适当的放高一点,而不是放在地上,这和手机信号塔的原理是一样的,更加不应该因为他碍眼把它放进抽屉、柜子等里面。这些方法可以略微增强信号强度,不过想从根本上解决信号问题,还是要换一款更好的路由。 无线网卡选购简介 常见值得选购的USB无线网卡按技术规格和价位,大致可以分为如下3类: 单频11n网卡,标注速度200-300M,20-30元。 双频11n网卡,支持5g频段,标注速度600M,40-50元。 双频11ac网卡,支持5g频段,标注速度900-1200M或更高,80元以上。 无线网卡要想达到标注的技术标准和速度,首先需要路由器支持该标准及速度,否则会降速运行。 USB协议:速度,选择2.0还是3.0 USB2.0的速度传输,理论最大速率480M bit/S。 60MB/S USB3.0的理论最大速率是5G bit/S,要比USB2.0快10倍! 640MB/S 看线路,工艺质量,实际速度可能不到理论速度一半 USB3.0 对wifi和BlueTooth干扰。 USB3.0的传输频率确实是5GHz串行,但USB3.0使用4条数据线组成2组,每组负责一个传输方向,实现全双工双向5GHz,而每条数据线的基准频率是2.5GHz。 所以,总带宽是5GHz没错,但每条线上是2.5GHz,这个频率距离2.4G Wifi的频率太近了,又因为高频设备大多数都使用了SSC技术(扩频时钟?)使得信号不完全分布在一个固定频率上,所以就波及了2.5GHz附近的其它频率,所以对Wifi和蓝牙产生了较大的干扰。 USB 3.0 干扰 Wifi 2.4G通讯的问题和解决方法 USB3.0 WIFI干扰解决方法 USB3.0的确对2.4G有影响,不过一样可以解决,比如网件的解决方法就是,USB3.0 和网口,天线不在一面,USB3.0接口弄到前面,而且是所有接口有金属屏蔽罩(包括WAN和LAN口),连USB接口与主板连线处都用屏蔽胶布包裹。可惜国内厂商哪怕是大如华为,网口也舍不得这点成本用金属屏蔽的。 带有USB 3.0接口的无线路由,如果出现外接3.0移动硬盘后网速下降,断网,或者ping延时变得很高,说明出现了3.0对无线的干扰。 USB3.0与无线冲突解决办法: 第一种:给USB接口加金属膜做屏蔽可以适当降低干扰,但不能完全屏蔽 第二种:给主板的USB底座增加统一(并与使用设备)接地和增加金属屏蔽罩,基本可以排除 【推荐】第三种:用1.2米 双磁环带屏蔽层的USB延长线将移动硬盘放到一米外的地方使用,基本可以完全可以排除 其实不单是无线路由,像我们平常使用的无线鼠标键盘、蓝牙、wifi电视、iPad、手机等各种使用民用2.4G的通信设备都会出现与USB3.0冲突的情况。 USB3.0 移动硬盘干扰解决方法 相信随着USB3.0使用的用户越来越多,不少人遇到了一插上USB3.0的硬盘,wifi就出现降速或者中断的问题。其本质原因是USB 3.0 干扰2.4GHz下的Wifi通讯。 解决方法如下, 1.更换无线路由为5GHz,因为USB 3.0对5GHz的Wifi干扰程度较低 Intel官方对USB3.0对WIFI干扰的描述文档: http://www.usb.org/developers/whitepapers/327216.pdf 目前在调试的两款型号: TL-WN823N ​ Bus 002 Device 007: ID 0bda:818b ​ RTL8192EU ​ 300M迷你型无线USB网卡 TL-WN823N TL-WN725N ​ Bus 002 Device 008: ID 0bda:8179 ​ rtl8188eu ​ 150M无线USB网卡 TL-WN725N ​ 网上的驱动版本数据结构和3.10差异较大,不能用 Wifi芯片厂家 Realtek: ​ 官方无linux驱动支持 Ralink (已经被MTK收购): 官方有linux驱动 Atheros (已经被高通qualcomm收购):AR9271 整理推荐芯片型号: USB 2.0 Mbit/s rt3070 http://www.mediatek.cn/products/broadbandWifi/rt3070 IEEE 802.11:b/g/n Wi-Fi Frequency:2.4GHz Antenna:1T1R Data Throughput:150Mbit/s rt5370 http://www.mediatek.cn/products/broadbandWifi/rt5370 IEEE 802.11:b/g/n Wi-Fi Frequency:2.4GHz Antenna:1T1R Data Throughput:150Mbit/s RT3573 http://www.mediatek.cn/products/broadbandWifi/rt3573 IEEE 802.11:b/g/n/ac Wi-Fi Frequency:2.4GHz, 5GHz Antenna:3T3R Data Throughput:450Mbit/s RT5572 http://www.mediatek.cn/products/broadbandWifi/rt5572 IEEE 802.11:b/g/n/ac Wi-Fi Frequency:2.4GHz, 5GHz Antenna:2T2R Data Throughput:300Mbit/s 集成分析 3G,4G集成分析 根据拨号技术流程,现在已经发现的USB上网有三种 1:默认识别为USB Modem,使用pppoe拨号脚本拨号。 2:默认识别为usb cdrom,使用usb-modeswitch 转换usb设备工作状态,转换为USB Modem后再采用pppoe拨号脚本拨号。 3:使用CGI 调用Html链接方式拨号。不需要我们配置用户名密码,网络制式,最方便。 1:Pppoe拨号 pppd call wcdma 2:usb_modeswitch转换usb设备工作模式。 usb_modeswitch -W -c /etc/usb_modeswitch.d/19D2:0117 3:CGI拨号示例 从集成实现来说,这种最方便。 ./curl --header "Referer: http://192.168.0.1/index.html" http://192.168.0.1/goform/goform_set_cmd_process?goformId=SET_CONNECTION_MODE&ConnectionMode=auto_dial ./curl --header "Referer: http://192.168.0.1/index.html" http://192.168.0.1/goform/goform_process?goformId=MODE_SWITCH&switchCmd=FACTORY Wifi集成分析 步骤: 1:驱动移植识别 2:wireless_tools或者wpa_supplicant拨号 wpa_supplicant依赖openssl和libnl,支持PSK加密需要用到这个。wireless_tools只支持普通web加密。 带宽性能测试 服务器运行 iperf -s 客户端运行 iperf -c 服务器ip -t 60000 -i 2 iperf -c 192.168.1.100 -t 60000 -i 2 TP—Link 845 笔记本有线连接运行服务端, H3531a(2716TE_C)使用TL-WN823N连接 [root@Tvt iperf]# ./iperf.hisi3531A -c 192.168.1.100 -t 60000 -i 2 \------------------------------------------------------------ Client connecting to 192.168.1.100, TCP port 5001 TCP window size: 21.0 KByte (default) \------------------------------------------------------------ [ 3] local 192.168.1.103 port 47671 connected with 192.168.1.100 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0- 2.0 sec 2.25 MBytes 9.44 Mbits/sec [ 3] 2.0- 4.0 sec 256 KBytes 1.05 Mbits/sec [ 3] 4.0- 6.0 sec 128 KBytes 524 Kbits/sec [ 3] 6.0- 8.0 sec 256 KBytes 1.05 Mbits/sec [ 3] 8.0-10.0 sec 1.25 MBytes 5.24 Mbits/sec [ 3] 10.0-12.0 sec 3.75 MBytes 15.7 Mbits/sec [ 3] 12.0-14.0 sec 4.25 MBytes 17.8 Mbits/sec [ 3] 14.0-16.0 sec 3.13 MBytes 13.1 Mbits/sec [ 3] 16.0-18.0 sec 1.75 MBytes 7.34 Mbits/sec [ 3] 18.0-20.0 sec 1.38 MBytes 5.77 Mbits/sec [ 3] 20.0-22.0 sec 1.13 MBytes 4.72 Mbits/sec [ 3] 22.0-24.0 sec 256 KBytes 1.05 Mbits/sec [ 3] 24.0-26.0 sec 128 KBytes 524 Kbits/sec [ 3] 26.0-28.0 sec 128 KBytes 524 Kbits/sec [ 3] 28.0-30.0 sec 512 KBytes 2.10 Mbits/sec [ 3] 30.0-32.0 sec 2.88 MBytes 12.1 Mbits/sec [ 3] 32.0-34.0 sec 1.63 MBytes 6.82 Mbits/sec [ 3] 34.0-36.0 sec 3.50 MBytes 14.7 Mbits/sec [ 3] 36.0-38.0 sec 768 KBytes 3.15 Mbits/sec [ 3] 38.0-40.0 sec 4.38 MBytes 18.4 Mbits/sec [ 3] 40.0-42.0 sec 5.38 MBytes 22.5 Mbits/sec [ 3] 42.0-44.0 sec 7.13 MBytes 29.9 Mbits/sec [ 3] 44.0-46.0 sec 6.63 MBytes 27.8 Mbits/sec [ 3] 46.0-48.0 sec 5.38 MBytes 22.5 Mbits/sec [ 3] 48.0-50.0 sec 5.75 MBytes 24.1 Mbits/sec [ 3] 50.0-52.0 sec 7.50 MBytes 31.5 Mbits/sec [ 3] 52.0-54.0 sec 4.63 MBytes 19.4 Mbits/sec [ 3] 54.0-56.0 sec 7.50 MBytes 31.5 Mbits/sec [ 3] 56.0-58.0 sec 6.75 MBytes 28.3 Mbits/sec [ 3] 58.0-60.0 sec 5.13 MBytes 21.5 Mbits/sec [ 3] 60.0-62.0 sec 5.38 MBytes 22.5 Mbits/sec [ 3] 62.0-64.0 sec 4.75 MBytes 19.9 Mbits/sec [ 3] 64.0-66.0 sec 6.00 MBytes 25.2 Mbits/sec [ 3] 66.0-68.0 sec 3.50 MBytes 14.7 Mbits/sec [ 3] 68.0-70.0 sec 5.50 MBytes 23.1 Mbits/sec [ 3] 70.0-72.0 sec 4.75 MBytes 19.9 Mbits/sec [ 3] 72.0-74.0 sec 1.50 MBytes 6.29 Mbits/sec [ 3] 74.0-76.0 sec 4.50 MBytes 18.9 Mbits/sec [ 3] 76.0-78.0 sec 4.25 MBytes 17.8 Mbits/sec [ 3] 78.0-80.0 sec 5.13 MBytes 21.5 Mbits/sec [ 3] 80.0-82.0 sec 7.88 MBytes 33.0 Mbits/sec [ 3] 82.0-84.0 sec 7.38 MBytes 30.9 Mbits/sec [ 3] 84.0-86.0 sec 4.38 MBytes 18.4 Mbits/sec [ 3] 86.0-88.0 sec 5.25 MBytes 22.0 Mbits/sec [ 3] 88.0-90.0 sec 6.63 MBytes 27.8 Mbits/sec [ 3] 90.0-92.0 sec 5.00 MBytes 21.0 Mbits/sec [ 3] 92.0-94.0 sec 6.88 MBytes 28.8 Mbits/sec [ 3] 94.0-96.0 sec 8.25 MBytes 34.6 Mbits/sec [ 3] 96.0-98.0 sec 7.25 MBytes 30.4 Mbits/sec 附录 1:TD- LTE和LTE FDD标准差异 TD- LTE是我国自主研发的4G标准,是由TD-SCDMA(3G网络)发展而来。 LTE FDD是现在国际上主流的,使用最广泛的4G网络。 现在全球有超过200个LTE的商用网络,其中超过90%是FDD的。 从技术上说,TD- LTE采用的是时分双工,而LTE FDD采用的是频分双工 那什么是频分双工,什么又是时分双工呢? 先来解释“双工”。 移动通信系统的工作方式分为:单工、半双工和全双工 1,单工就是信息只能向一个方向传播。例如寻呼机和收音机,只能接收信息,不能发出信息。 2,半双工就是信息可以双向传播,但是上传信息的时候只能上传,下载的时候只能下载。例如对讲机,你说话的时候听不见别人别人说,听别人说的时候自己不能说。 3, 全双工就是信息可以同时双向传播。例如手机,可以边听边说。 ​ 所谓的频分双工就是将信息上传和信息下载放在两个不同的频段,称为上行频段和下行频段,且这两个频段必须对称。为了不防止上下行频段之间的信息串频,两个频段不能重叠,而且中间必须隔开一段,称为保护频。如下图:上行和下行频段相互分开 所谓的时分双工就是将上传和下载放在同一个频段,也就是上行频段和下行频段完全一样。那它是如何做到上下的信息不串频呢?其实很简单,顾名思义,频分双工分的是频段,那时分双工分的就是时间。将波传播的时间轴一分为二, 前半部分用于信息的上传,后一部分用于信息的下载。其实这从理论上更像是同步的半双工,但是由于上行和下行时间差距极短,我们无法感觉到,所以从效果上也是全双工。如下图:时间帧的第一帧为上行,第二帧而为下行,上下行共用一个频段,用时间的差将他们隔开。 ​ 接下来说一说移动TD- LTE和电信联通LTE FDD的优缺点,其实就是时分双工与频分双工的特点。 ​ TD- LTE由于采用上行和下行分时,所以上行和下行的时间差导致他信息传输的速度受到一定的限制。他的理论下载峰值为100Mbps,相比FDD的150Mbps来说,慢了不少。当然TD- LTE的基站信号覆盖半径也比LTE FDD小一点。 ​ LTE FDD也并非都是优点。FDD制式必须要找对称分开的上行、下行频段,也就是说它必须浪费更多的频段资源。那中国联通的FDD网为例,工信部给他发的频段牌照为,上行17551765MHz和下行18501860MHz(2×10M),实际联通只得到了上下各10M的频段,但是加上当中的保护频段,一共占用了1755~1860MHz也就是105MHz的频段。这就导致了频段资源利用率低,是一种资源的浪费。目前,频率资源本身就紧张,能找到对称的上行和下行频段就尤其难。频率除了用在手机上网通讯上,像广播,军事,甚至无线路由器等民用领域也广泛使用。将来随着科技的进步,频率频段的稀缺会日益严重。 ​ TD-LTE和FDD-LTE 是4G的两种国际标准,各有利弊。TD-LTE占用频段少,节省资源,带宽长,适合区域热点覆盖;FDD速度更快,覆盖更广,但占用资源多。适合广域覆盖。 Kernel wireless 支持列表 系列教程 全部文章RSS订阅 Embeded系列 Embeded 分类 RSS 订阅 海思MPP&UNF构架源代码级分析 3G,4G,Wifi选型需求分析及技术简介 自动曝光原理 ISP 数字图像处理 算法概述、工作原理、架构、处理流程 QNAP添加man pages

2021/7/30
articleCard.readMore

qnap硬盘移动位置

qnap硬盘移动位置,改变硬盘位 需求:硬盘位4的硬盘移动到硬盘位3 步骤1 造作步骤: 存储和快照总管app->存储/快照->管理->操作->安全卸载磁盘区 如此,硬盘4卸载下来了,如下图 步骤2 再把硬盘4拔下来,插入硬盘位3。等待硬盘被识别到,一般1分钟之内。 步骤3 造作步骤: 存储和快照总管app->磁盘/VJBOD->点击磁盘3->还原->链接并回复存储池 系列教程 全部文章RSS订阅 Nas系列 Nas 分类 RSS 订阅 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! Zlibrary 图书资源下载与 Calibre 图书管理打造结构化电子图书馆高阶教程 音视频图书和音乐自动化管理框架图解 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 Potplayer终极优化教程实现PC视频播放最强画质 Transmission 使用及其配置 Qbittorrent 参数详细设置教程 IPFS从零开始快速入门教程 家庭网络优化指南:提升NAT类型,降低游戏延迟、提高下载速度 如何创建属于自己的私人资料库与私人搜索引擎 PT 工具集,Linux硬链接助手 QNAP 修改应用启动顺序 qnap硬盘移动位置 qnap IO 错误消除 Docker系列 Docker 分类 RSS 订阅 Docker使用简明教程 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 为知笔记私有化Docker部署 Earthly 一个更加强大的镜像构建工具 使用 Shell 脚本实现一个简单 Docker 如何使用Traefik V2 在Ubuntu20.04 上面来做 Dockers 通过IPV6访问Qnap NAS中Docker的服务

2021/7/25
articleCard.readMore

完美笔记进化论

前言: 受够了一些网络服务随意被关闭,如google reader等。经过google doc, 有道笔记,为知笔记,手机备忘录,记事本,git,等等方式记录笔记,使用过txt,word,gitbook,markdown等格式,找到一种接近完美的解决记录笔记的方式。主要采用selfhost,自主搭建服务器,每个组件都可以被取代,大多数都是开源可定制的。 经历了很长时间,使用了各种各样的方案,最终选择了一种相对完美的方式。docker私有部署运行的joplin,使用markdown语法,github作为图床,picgo作为图像自动上传后端,Typora作为MD编辑器,Snipaste作为截图工具。采用gitlab ee docker selfhost备份,VPS自建图床DNS多线负载均衡。cloudflare partner cdn加速,jsdelivr加速。 笔记进化历史 浏览器书签 优点:使用方便,一些实时更新的内容可以直达。 缺点:需要联网,没办法搜索编辑,经常有链接失效。很多有实效的资源,或者可能只能存在一定时间的资源。 由于时效更新的缘故,一直和其它笔记记录方式一起使用。 word笔记 优点:富文本支持 缺点:word相对笨重,很多低端平台没有word可用 txt笔记 优点:多平台,随时随地,格式简单 缺点:富文本支持不好,同步机制只能自己想办法,没有富文本 gitbook 优点:同步机制,修改版本机制 缺点:富文本相对缺乏 单独来说只解决了修改日志问题 markdown 优点:富文本 缺点:无修改日志,显示上传不友好 单独来说解决了富文本问题 google doc 优点:在线编辑,富文本支持,修改历史支持,搜索支持。 缺点:文件是google专有格式,数据保存在网上,国内访问需要代/理支持,google还有关闭热度不高网络服务先例。 有道笔记 优点:对markdown支持非常好 缺点:收费,多平台不够友好,同步问题 手机’'备忘录"app 优点: 方便,随时随地 缺点:一般只能同型号手机之间同步, 对于多平台同步没有支持,也没有富文本,没有修改历史。 最终选择方案 为知笔记docker版+Typora+Picgo+github+snipaste 最近替换wiznote为Joplin,完全开源免费。Joplin插件异常强大,支持各种Markdown语法。 wiznote docker版作为笔记管理搜索工具,typora作为markdown编辑器,只使用markdown格式笔记,Picgo作为图上上传工具,github作为图像图床,Snippaste作为截屏工具。一起组成笔记工具链。 怎么样? 够复杂吧,作者也觉得很复杂,但整体免费,满足selfhost, 富文本,多平台,版本管理,目录管理,可搜索,对图像友好的苛刻要求,超越市面所有产品,wiznote 还可以对外网提供服务。 优点:selfhost, 富文本,多平台,版本管理,目录管理,可搜索,对图像友好。只使用其中部分功能,每个功能都是有其它可替代方案 缺点:配置异常复杂,配置完整难度较高,一些组件还不够成熟,稳定性不够好,存在bug wiznote docker版 数据完整保存在自己搭建的服务器上面,备份转移方便。其实主要是使用wiznote docker版的目录管理,多文档搜索,修改记录功能。可以使用gitlab docker版来代替。 教程: 为知笔记私有化Docker部署 最近更新 Joplin docker +Typora+VIM + Picgo+github+snipaste 最近抛弃了wiznote,全面投入了Joplin的怀抱 选用理由: 从服务器到客户端,到APP完全开源,支持dropbox,webdav,本地文件系统,docker镜像等同步方式。 Jopin配合Typora才是最佳搭档, 配置如下 Joplin Joplin教程: 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 入门指南&实践方案 Joplin 插件使用推荐 官方插件下载地址 中文界面 工具–>选项 点击下方图的按钮来触发Joplin设置的外部编辑器 把 Joplin 用在日常工作中 此处主要介绍 Joplin 在终端中的使用,主要参考了官方文档。 和 Vim 协作编辑文档 我喜欢 Joplin 终端的设计,它很符合 tmux 和 Vim 的逻辑。 终端 Joplin 由三个横向的 Panel 组成,切换的时候用 tab 和 Shift-Tab。为了使得它更符合 Vim 的风格(Control + 方向键),可以在 ~/.config/joplin/keymap.json 中加入以下的设置(完整版见此 gist keymap.json ): ... { "keys": ["TAB","l"], "type": "function", "command": "focus_next" }, { "keys": ["SHIFT_TAB","h"], "type": "function", "command": "focus_previous" }, { "keys": ["UP","k"], "type": "function", "command": "move_up" }, { "keys": ["DOWN","j"], "type": "function", "command": "move_down" }, { "keys": ["PAGE_UP","K","{"], "type": "function", "command": "page_up" }, { "keys": ["PAGE_DOWN","J","}"], "type": "function", "command": "page_down" }, ... 这样就变成了 HJKL 风格了。 选择好要编辑的笔记之后,回车就会用默认的终端编辑器打开了。对我来说,必然是 Vim。要注意的是编辑中的语法高亮需要加入 vim-markdown.vim,预览则要 markdown-preview.nvim。 利用 CLI 快速记录 假设你正在工作环境中(例如 Shell 下、tmux 下或着 Vim 下),不想离开终端,更不想离开现在的窗口,这种情况下 Joplin 的命令行介面就很有帮助了。你可以快速记录、查询一些笔记内容。 我在这里写了一些例子供你参考。 创建一个笔记本 = 为项目建立日志存储: $ joplin mkbook "My-Project" $ joplin use "My-Project" 创建新笔记并以当前时间命名 = 记录当前进度: $ joplin mknote `date +%Y/%m/%d` 查看已有的笔记: $ joplin ls -l 完成当前进度: $ joplin todo toggle "Feature1" 更多的命令行,你可以通过 joplin help all 查看。 Joplin 插件以及Markdown语法 教程: Joplin 插件以及其Markdown语法 Gitlab docker 和上面的wiznote docker基本一样的使用功能。 除了记录笔记,还可以保存自己的各种代码。 Typora Typora官方介绍及下载地址 编辑器演示 上传图片图示 后端图像上传工具picgo 一次性上传本MD文件中所有图片 picgo Picgo官方下载地址 官方插件下载地址及其介绍 picgo插件配置 要想picgo用的过得去,一般来说需要插件 picgo使用github作为图床需要github配置,也可以使用sm.ms, gitee。选择github相对来说被随意关闭可能性更低。 Picgo 上传 gif 后变为静态图片? 图片内容上右键复制图片只会读取成png。你如果要上传GIF,win10可以直接在系统里右键图片文件,有一个upload with PicGo选项,可以直接上传原图片。或者拖拽上传都可以 Snipaste截图工具 Snipaste官方下载地址 系列教程 全部文章RSS订阅 笔记系列 Note分类RSS订阅 完美笔记进化论 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Joplin入门指南&实践方案 替代Evernote免费开源笔记Joplin-网盘同步笔记历史版本Markdown可视化 Joplin 插件以及其Markdown语法。All in One! Joplin 插件使用推荐 为知笔记私有化Docker部署 Gitbook使用系列 Gitbook分类RSS订阅 GitBook+GitLab撰写发布技术文档-Part1:GitBook篇 GitBook+GitLab撰写发布技术文档-Part2:GitLab篇 自己动手制作电子书的最佳方式(支持PDF、ePub、mobi等格式) Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Hexo系列 HexoRSS分类订阅 [十万字图文教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程 Hexo Docker环境与Hexo基础配置篇 hexo博客自定义修改篇 hexo博客网络优化篇 hexo博客增强部署篇 hexo博客个性定制篇 hexo博客常见问题篇 hexo博客博文撰写篇之完美笔记大攻略终极完全版 Hexo Markdown以及各种插件功能测试 markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe 在 Hexo 博客中插入 ECharts 动态图表 使用nodeppt给hexo博客嵌入PPT演示 GithubProfile美化与自动获取RSS文章教程 Vercel部署高级用法教程 webhook部署Hexo静态博客指南 在宝塔VPS上面采用docker部署waline全流程图解教程 自建Umami访问统计服务并统计静态博客UV/PV

2021/7/25
articleCard.readMore

PT 工具集,Linux硬链接助手

由于自我需求,写了两个脚本完成PT下载和保种两全其美的硬链接 Linux shell 脚本方案。 PTtool Github: appotry/PTtool 纯Bash Shell硬链接工具!支持所有Linux, BSD, Mac,群辉,威联通等支持标准Shell的操作系统! PT工具集合 硬链接工具 自动硬链接工具 flexget-nexusphp, 自动下载刷流工具。Flexget插件,增强对NexusPHP的过滤 nas-tools 源码备份,已经停止开发!注意暂时功能不够完善,Bug较多,评价是试用,尝鲜,还不能胜任主力!后续Bug得不到修正,强烈建议切换到Sonarr,radarr,flexget。 MoviePilot nas-tools 作者重构项目,提升了速度,在功能,bug稳定性方面还待提升。可以提前试用 PTools 一个新的自动签到,种子推送工具,刚出来,可以关注 IYUUAutoReseed 自动辅种助手。PT三剑客 PTPP 浏览器辅种助手。PT三剑客 pt_helper, 非开源软件 自动刷流与签到。PT三剑客 nas-tools可以替代刷流 PT站生成海报墙 一键转种脚本 PT一键转种脚本(树大版) PT_signin PT自动签到 Github Action 版 flexget qbittorrent删种、辅种 自动签到 插件 Auto_Upload 自动发种机 全自动将本地资源发布到 PT 站并自动辅种 使用教程 Upload_Machine 自动将本地资源发布到PT站 看简介比 Auto_Upload 功能更强大 qBittorrent rss订阅规则管理 Mkv Auto Subset ASS字幕字体子集化 MKV批量提取/生成 jproxy 优化 Sonarr 对资源的识别率,主要是针对动漫 xarr-rss 剧情Rss订阅处理器 目前非开源? pter 猫站使用脚本集合 auto-bangumi 基于Mikan Project的中文自动追番解决方案 解决中文自动追番痛点 BangumiBot 类似auto-bangumi的中文自动追番工具,只是auto-bangumi支持Qbittorrent,BangumiBot支持Aria2/Tr embyExternalUrl Emby调用外部播放器播放视频,以使用本地解码能力 subtitle-translator-electron Translate subtitle using ChatGPT,使用ChatGPT翻译字幕 相关教程 从零开始玩PT-入门到精通 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! 视频图书和音乐完全自动化管理框架图解 如何使用tinyMediaManager刮削电影和电视剧,动画,并自动下载字幕 使用jeckett,sonarr,iyuu,qt,emby打造全自动追剧流程 如何建立自己的私人电子图书馆–出版书籍,网络小说,漫画一网打尽! qBittorrent 参数详细设置教程 transmission 使用及其配置 Potplayer终极优化教程实现PC视频播放最强画质 框架自动化构架图解 点击放大 graph LR 1[Sonarr / Radarr] == 请求 Jackett / Prowlarr Torznab 接口 ==> 2(JProxy) == 代理 Sonarr / Radarr 请求 ==> 3(Jackett / Prowlarr) 3(Jackett / Prowlarr) == 返回原始结果 ==> 2(JProxy) == 返回格式化结果 ==> 1(Sonarr / Radarr) 2(JProxy) == 优化查询关键字 ==> 2(JProxy) 2(JProxy) == 格式化查询结果 ==> 2(JProxy) jproxy 使用图解 硬链接工具 设计目的 方便PT用户硬链接文件,在最大可能情况下节约空间,并保持做种。 例如: 然后直接运行mklink.sh。就可以把src下面的文件全部硬链接到dst目录。mklink适合一次性把源文件夹链接到目的文件夹 SRC="/share/Download/src" DST="/share/Download/dst" 注意: 源目录,目的目录需要在一个硬盘分区里面。硬链接不能跨分区。 硬链接过的文件可以使用mv来修改存储目录,不影响硬链接效果。但是cp会增加一份存储空间。所以对于已经硬链接过的文件,使用mv,不要使用cp。 解决的问题 tmm,emby刮削的时候,必定修改nfo文件,下载的封面等图片不同刮削站点都不同,所以小文件复制,不怕修改。大文件硬链接,占有一份空间 使用说明 下载资源目录/share/Download,qbittorrent资源分类下载到/share/Download/src/下面的各个子目录,例如tv, anime, tv, movie, 4k, soft等等 小文件直接复制,方便tmm刮削修改nfo文件,大文件硬链接,只占有一份空间,但有2分文件,可以改名,移动目录,方便tmm整理刮削。 做种,emby使用两不误! 建议目录结构 /share/Downlosd/src # BT下载工具默认保存主目录 /share/Download/dst # 硬链接目的目录,Emby,tmm,使用的目录,保存各种刮削信息。以及个人文件名修改,目录结构修改。 在src目录下面建立子目录movie,music,anime,tv,4k等等,在qbittorrent里面设置分类, 指向这里的movie,music,anime,tv等子目录。下载完后使用下面的硬链接脚本, 把文件硬链接到目的文件夹。tmm,emby使用目的文件夹刮削数据。 qbittorrent使用设置 移动种子保存位置 设置分类目录 mklink.sh 修改脚本参数源目录,目的目录,替换为你自己的目录。 mklink 直接针对2个文件夹做硬链接,小于1m的复制,但是没有判断是否已经硬链接过。适合全新的没有硬链接过的目录。 #mklink.sh sourcedir dstdir mklink.sh /share/Download/tmp/src /share/Download/tmp/dst dirlink.sh 设计原理:针对输入原路径下一级子目录判断是否有文件islinked.lk, 可以直接修改脚本源目录,目的目录参数,也可以从参数$!,$2输入源目录,目的目录。 原理是在源文件夹目录下添加文件islinked.lk,通过检测这个文件来判断是否硬链接过 SRC="/share/Download/tmp/src/movie" DST="/share/Download/tmp/dst/movie" 注意:src目录下面的文件需要放到各个子目录下面去,例如src/anime/amine1,src/tv/tv2,这样才能保证islinked.lk工作正常 #dirlink.sh sourcedir dstdir dirlink.sh /share/Download/tmp/src /share/Download/tmp/dst 重新建立连接,一次性删除所有islinked.lk文件 find /share/Download/tmp -name "islinked.lk" | xargs rm -f 替换前面的路径/share/Download/tmp为你自己的路径,操作和rm相关的命令一定注意不要输入错误,删错文件代价极大! 一次性硬链接多个目录 如下所示脚本link.sh #!/bin/sh /share/Download/source/dirlink.sh /share/Download/source/anime /share/Download/dst/anime /share/Download/source/dirlink.sh /share/Download/source/movie /share/Download/dst/movie /share/Download/source/dirlink.sh /share/Download/source/tv /share/Download/dst/tv 修改限制2M大小以下的复制 修改脚本参数FILEGIG,原脚本是1M大小,修改为下面这样就是2M大小 FILEGIG=2000000c 1000000c 表示 1000000 字节,也就是 1MB。在 find 命令中,可以使用 c 表示字节,k 表示千字节,M 表示兆字节,G 表示吉字节等,这些后缀可以用来指定 -size 选项所匹配的文件大小。 如果要计算具体的字节大小,可以使用以下转换关系: 1 字节(Byte)= 8 比特(Bit) 1 千字节(KB)= 1024 字节 1 兆字节(MB)= 1024 KB 1 吉字节(GB)= 1024 MB 因此,如果要查找大于 10MB 的文件,可以使用 -size +10M,如果要查找大于 100MB 的文件,可以使用 -size +100M。 autolink.sh qBittorrent 下载完成时自动硬链接下载完的种子,适用于新下载完成的种子文件。以前下载完成的文件建议使用link.sh脚本的方法。 修改脚本目标目录 your_path的等号后。 设置下载完成后自动运行 /path/to/autolink.sh "%N" "%D" "%L" 这个脚本使用,需要手动修改脚本中的分类,下面这一行! if [[ "$torrent_category" == *"movies"* || "$torrent_category" == *"series"* || "$torrent_category" == *"documents"* || "$torrent_category" == *"operas"* ]] $torrent_category 是qBittorrent分类名称,也是目录名称! 注意事项 注意Linux权限,如果运行出错,请检查所使用的的用户和用户组权限。目的目录是否可写! 使用声明 数据无价,小心操作。 感觉对你有帮助,来个star吧 Contributing Fork it ( https://github.com/appotry/PTtool/fork ) Create your feature branch (git checkout -b my-new-feature) Commit your changes (git commit -am 'Add some feature') Push to the branch (git push origin my-new-feature) Create a new Pull Request

2021/7/9
articleCard.readMore

Gitlab的安装及使用

Gitlab概述 1.1 GitLab介绍 GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。 GitLab能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。 它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找 1.2 Gitlab服务构成 Nginx:静态web服务器。 gitlab-shell:用于处理Git命令和修改authorized keys列表。 gitlab-workhorse: 轻量级的反向代理服务器。 logrotate:日志文件管理工具。 postgresql:数据库。 redis:缓存数据库。 sidekiq:用于在后台执行队列任务(异步执行)。 unicorn:An HTTP server for Rack applications,GitLab Rails应用是托管在这个服务器上面的。 1.3 Gitlab工作流程 1.4 GitLab Shell GitLab Shell有两个作用:为GitLab处理Git命令、修改authorized keys列表 当通过SSH访问GitLab Server时,GitLab Shell会: 限制执行预定义好的Git命令(git push,git pull,git annex) 调用GitLab Rails API检查权限 执行pre-receive钩子(在企业版中叫做Git钩子) 执行用户请求的动作,处理GitLab的post-receive动作 处理自定义的post-receive动作 当通过http(s)访问GitLab Server时,工作流程取决于你是从Git仓库拉取(pull)代码还是向git仓库推送(push)代码: 如果是从Git仓库拉取(pull)代码,GitLab Rails应用会全权负责处理用户鉴权和执行Git命令的工作 如果是向Git仓库推送(push)代码,GitLab Rails应用既不会进行用户鉴权也不会执行Git命令,它会把以下工作交由GitLab Shell进行处理: 调用GitLab Rails API 检查权限 执行pre-receive钩子(在GitLab企业版中叫做Git钩子) 执行你请求的动作 处理GitLab的post-receive动作 处理自定义的post-receive动作 1.5 GitLab Workhorse GitLab Workhorse是一个敏捷的反向代理。它会处理一些大的HTTP请求,比如文件上传、文件下载、Git push/pull和Git包下载。其它请求会反向代理到GitLab Rails应用,即反向代理给后端的unicorn。 Gitlab的安装部署 Gitlab要求服务器内存2G以上 2.1 方式一:下载gitlab-ce的rpm包 gitlab官方rpm包下载 清华的源 将对应版本的gitlab-ce下载到本地后,直接yum安装即可 要先将这个rpm包下载到本地 yum install -y gitlab-ce-13.6.1-ce.0.el7.x86_64.rpm 2.2 方式二:配置yum源 在 /etc/yum.repos.d/ 下新建 gitlab-ce.repo,写入如下内容: [gitlab-ce] name=gitlab-ce baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ Repo_gpgcheck=0 Enabled=1 Gpgkey=https://packages.gitlab.com/gpg.key 然后创建cache,再直接安装gitlab-ce yum makecache # 这一步会创建大量的数据 直接安装最新版 yum install -y gitlab-ce # 如果要安装指定的版本,在后面填上版本号即可 yum install -y gitlab-ce-13.6.1 如果安装时出现gpgkey验证错误,只需在安装时明确指明不进行gpgkey验证 yum install gitlab-ce -y --nogpgcheck 2.3 gitlab的配置 配置文件位置 /etc/gitlab/gitlab.rb [root@centos7 test]# vim /etc/gitlab/gitlab.rb [root@centos7 test]# grep "^[a-Z]" /etc/gitlab/gitlab.rb external_url 'http://10.0.0.51' # 这里一定要加上http:// 配置邮件服务 gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.qq.com" gitlab_rails['smtp_port'] = 25 gitlab_rails['smtp_user_name'] = "hgzerowzh@qq.com" # 自己的qq邮箱账号 gitlab_rails['smtp_password'] = "xxx" # 开通smtp时返回的授权码 gitlab_rails['smtp_domain'] = "qq.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = false gitlab_rails['gitlab_email_from'] = "hgzerowzh@qq.com" # 指定发送邮件的邮箱地址 user["git_user_email"] = "shit@qq.com" # 指定接收邮件的邮箱地址 修改好配置文件后,要使用 gitlab-ctl reconfigure 命令重载一下配置文件,否则不生效。 gitlab-ctl reconfigure # 重载配置文件 2.4 Gitlab常用命令 gitlab-ctl start # 启动所有 gitlab 组件 gitlab-ctl stop # 停止所有 gitlab 组件 gitlab-ctl restart # 重启所有 gitlab 组件 gitlab-ctl status # 查看服务状态 gitlab-ctl reconfigure # 启动服务 gitlab-ctl show-config # 验证配置文件 gitlab-ctl tail # 查看日志 gitlab-rake gitlab:check SANITIZE=true --trace # 检查gitlab vim /etc/gitlab/gitlab.rb # 修改默认的配置文件 Gitlab的使用 Gitlab安装好后,设置密码,管理账户为root 3.1 创建Group 填上组名即可,这里组名为java 3.2 创建User 创建四个User:pm、dev1、dev2、dev3 3.3 添加User到Group中并授权 3.4 创建Project并配置SSH 3.5 在项目中添加成员 3.6 将本地文件推送到Gitlab 将app01项目克隆下来 git clone git@10.0.0.51:java/app01.git # 初始化配置 git config --global user.name "hgzero" git config --global user.email "hgzero@qq.com" 在app01目录下新建一些文件 推送到gitlab git add . git commit -m "first edition" git push origin master 制定开发计划 4.1 创建开发计划 项目:app01 版本:v1.0 4.2 创建里程碑Milestones 用pm账号登录gitlab后操作(先要在admin中设置pm账号的密码) 要根据开发计划来创建Milestones 4.3 根据开发计划创建issue 创建4个issue,分派给dev1和dev2这两个开发人员 **4.4 开发者登录账号查看分派的任务 ** 然后开发dev1登录gitlab,就能看到任务已经分配过来了 4.5 开发流程 公司里的开发开始任务 1. 先从仓库把项目拉下来 git clone git@10.0.0.51:java/app01.git cd app01/ 2.先创建一个自己的分支,然后进行开发 git checkout -b index # 创建一个叫index的分支,并切换到这个分支 git status # 3. 开始开发首页 echo "<h1>welcome to this app</h1>" > index.html # 假设就开发了一个index页面 4. 开发完成后,把项目传到仓库 git add . git commit -m "index" 如果写成 git commit -m “close #2” ,则表示merge请求允许且merge成功之后,自动删除编号为#2的issue 传到index分支 git push origin index 4.6 合并分支 1)开发dev1发送合并分支请求给pm 2)pm收到开发的Merge请求后进行处理 使用pm登录,就可以看到pm已经收到了合并请求merge request 3)开发dev1确认任务完成 退出pm账户,登入dev1账户: 或者点进去后,在侧边栏进行标识Done,然后已经完成的issue,可以将其Close 这个时候Milestones的进度已经往前进了一些了: 4.7 开发其他功能 然后其他开发者或者自己再次进行开发时,先要把刚刚更新后的内容(master主干)拉回来,然后再进行开发 git checkout master # 切换到master git pull # 从远端仓库拉取数据 然后再进行其他操作 Gitlab备份恢复 5.1 备份gitlab 1)修改配置文件 /etc/gitlab/gitlab.rb 备份保存的位置,这里是默认位置,可修改成指定的位置 gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" 设置备份保存的时间,超过此时间的日志将会被新覆盖 gitlab_rails['backup_keep_time'] = 604800 # 这里是默认设置,保存7天 特别注意: # 如果自定义了备份保存位置,则要修改备份目录的权限,比如: # chown -R git.git /data/backup/gitlab 配置完成后要重启以使配置生效 重读配置文件 gitlab-ctl reconfigure # 重启gitlab gitlab-ctl restart 2)设置定时任务 每天凌晨2点定时创建备份 # 将一下内容写入到定时任务中 crontab -e 0 2 * * * /usr/bin/gitlab-rake gitlab:backup:create # 备份策略建议: # 本地保留3到7天,在异地备份永久保存 3)备份时间的识别 备份后的文件类似这样的形式:1494170842_gitlab_backup.tar,可以根据前面的时间戳确认备份生成的时间 data -d @1494170842 5.2 恢复gitlab 1)停止数据写入服务 停止数据写入服务 gitlab-ctl stop unicorn gitlab-ctl stop sidekiq 2)进行数据恢复并重启 进行恢复 gitlab-rake gitlab:backup:restore BACKUP=1494170842 # 这个时间戳就是刚刚备份的文件前面的时间戳 重启 gitlab-ctl restart gitlab邮件通知配置 vim /etc/gitlab/gitlab.rb gitlab_rails['time_zone'] = 'Asia/Shanghai' gitlab_rails['gitlab_email_enabled'] = true gitlab_rails['gitlab_email_from'] = 'example@163.com' # 填写发件人的邮箱地址 gitlab_rails['gitlab_email_display_name'] = 'gitlab' gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.163.com" # smtp服务器的地址,如网易的地址 gitlab_rails['smtp_port'] = 25 # 要注意如果使用了SSL/TLS的话,端口可能不是25 gitlab_rails['smtp_user_name'] = "smtp用户名" gitlab_rails['smtp_password'] = "smtp用户密码" gitlab_rails['smtp_domain'] = "163.com" gitlab_rails['smtp_authentication'] = "login" 使用SourceTree进行项目开发 7.1 项目拉取 先把项目克隆下来 如果ssh的方式克隆失败,可能是因为SSH Key没找到,可以在这里添加 7.2 创建分支进行功能开发 1)新建立一个叫“pay”的分支 2)进行功能开发 7.3 提交项目 1)开发pay功能完成后进行提交 可以看到SourceTree中已经有“未提交的更改” 2)添加“用户信息” ** 3)进行提交** 注释也可以写成 close #3 ,作用是提交完成后关闭3号issue 7.4 推送到仓库 然后就可以在gitlab上进行发送merge请求了,后面就可以进行其他操作了 7.5 项目上线 1)当所有工作完成之后,就可以进行上线了 2)打标签 上线先打个标签 ** 3)删除无用分支** 然后删除已经合并到主干中的不必要的分支,如index、pay等 最后一定要注意时间一定要同步,不然会错乱 参考 Praywu 系列教程 全部文章RSS订阅 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2021/7/9
articleCard.readMore

破解Gitlab EE

由于需要一些镜像等 gitlab 高级功能,所有破解gitlab ee版本。 安装ruby 安装完gitlab ee之后 安装ruby:yum install ruby ruby版本需要2.3或以上。 生成许可证 gem install gitlab-license 创建一个rb文件 license.rb require "openssl" require "gitlab/license" key_pair = OpenSSL::PKey::RSA.generate(2048) File.open("license_key", "w") { |f| f.write(key_pair.to_pem) } public_key = key_pair.public_key File.open("license_key.pub", "w") { |f| f.write(public_key.to_pem) } private_key = OpenSSL::PKey::RSA.new File.read("license_key") Gitlab::License.encryption_key = private_key license = Gitlab::License.new license.licensee = { "Name" => "none", "Company" => "none", "Email" => "example@test.com", } license.starts_at = Date.new(2020, 1, 1) # 开始时间 license.expires_at = Date.new(2050, 1, 1) # 结束时间 license.notify_admins_at = Date.new(2049, 12, 1) license.notify_users_at = Date.new(2049, 12, 1) license.block_changes_at = Date.new(2050, 1, 1) license.restrictions = { active_user_count: 10000, } puts "License:" puts license data = license.export puts "Exported license:" puts data File.open("GitLabBV.gitlab-license", "w") { |f| f.write(data) } public_key = OpenSSL::PKey::RSA.new File.read("license_key.pub") Gitlab::License.encryption_key = public_key data = File.read("GitLabBV.gitlab-license") $license = Gitlab::License.import(data) puts "Imported license:" puts $license unless $license raise "The license is invalid." end if $license.restricted?(:active_user_count) active_user_count = 10000 if active_user_count > $license.restrictions[:active_user_count] raise "The active user count exceeds the allowed amount!" end end if $license.notify_admins? puts "The license is due to expire on #{$license.expires_at}." end if $license.notify_users? puts "The license is due to expire on #{$license.expires_at}." end module Gitlab class GitAccess def check(cmd, changes = nil) if $license.block_changes? return build_status_object(false, "License expired") end end end end puts "This instance of GitLab Enterprise Edition is licensed to:" $license.licensee.each do |key, value| puts "#{key}: #{value}" end if $license.expired? puts "The license expired on #{$license.expires_at}" elsif $license.will_expire? puts "The license will expire on #{$license.expires_at}" else puts "The license will never expire." end ruby license.rb 生成 GitLabBV.gitlab-license license_key license_key.pub 这三个文件。 使用许可证 用 license_key.pub 文件替换 /opt/gitlab/embedded/service/gitlab-rails/.license_encryption_key.pub。 GitLabBV.gitlab-license 即是许可证,填入 ${address}/admin/license 地址并重启 gitlab-ctl restart 。 修改等级 --- /opt/gitlab/embedded/service/gitlab-rails/ee/app/models/license.rb +++ /opt/gitlab/embedded/service/gitlab-rails/ee/app/models/license.rb @@ -458,7 +458,7 @@ end def plan - restricted_attr(:plan).presence || STARTER_PLAN + restricted_attr(:plan).presence || ULTIMATE_PLAN end def edition Gitlab添加许可证 14.x Gitlab之前添加许可证位置 菜单->管理员->订阅->许可证上传 新版Gitlab添加许可证的位置在 菜单->管理员->设置->通用->添加许可证处点击展开->点击上传 修改完成后使用 gitlab-ctl restart 重新加载配置。 菜单->管理员->订阅 在这里可以看到激活状态,上面操作没问题的话,这里可以看到激活成功! 参考 https://www.rubydoc.info/gems/gitlab-license/1.0.0/file/README.md 现在你已经破解好了Gitlab ee, 可以使用其中的高级功能。 更多的Gitlab ee详细教程,请参考下面的gitlab系列教程! 👇︎ 系列教程 全部文章RSS订阅 Gitlab 使用系列 Gitlab RSS 分类订阅 Gitlab的安装及使用教程完全版 破解Gitlab EE Gitlab的安装及使用 CI/CD与Git Flow与GitLab Devops系列 Devops 分类 RSS 订阅 自建全套开源Devops开发系统 Git介绍以及分支模型图解 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境 DevOps系列—【Jenkinsfile+Dockerfile+nginx+vue】 项目开发管理工具推荐 Gitlab的安装及使用教程完全版 Gitlab的安装及使用 那些有用的Github工具介绍!Action、app、workflow等 项目管理系列 AI 分类 RSS 订阅 如何做一个完整的硬件项目的项目管理之简明教程 几种常用管理模型和方法 PMBOK指南(第6版) 如何做好竞品分析 一大堆寓意深刻的管理故事锦集 人格类型分类总结归纳

2021/7/9
articleCard.readMore

海思MPP&UNF构架源代码级分析

文章写了好多年了,只在一个网站发布过PDF版本,行业内应该很多人看过这个。由于早期笔记使用Word格式,转换格式时有不少格式错误,笔者尽量修正。 关于本blog,图床一般使用github,已经配置了CDN,如果图片还是未显示请自行代理解决 原创声明警告,本文禁止转载,禁止发布到其它任何网站,可以接受约稿。 前言: ​ 本文通过分析海思文档和代码,把海思SDK的MPI和UNF构架大概实现思想和构架进行了简略的分析。着重分析了内存管理,底层功能如何实现。 ​ 前面章节简要分析了NVR芯片MPI构架及其内存管理机制,后面着重详细分析了3798M底层模块api和drv实现的细节过程及其方法流程。 ​ 本文前面简略分析了DVR,MPI构架的大体实现机制。后面就具体分析3798M UNF构架的实现。 本文不光分析了UNF构架,还使用了很多工具,辅助分析代码。这里从三个层面分析了UNF的实现。 1: 应用层,驱动层的实现框架,使用source insight查看代码并着重分析了avplay等几个模块。 2:静态分析函数调用。使用cflow,dot工具生成调用关系图 3:动态追踪运行过程。Ltrace, strace, valgrind分析函数调用,perf动态分析内核调用。 1:Hi35xx系列芯片MPP构架 1.1 概述 海思提供的媒体处理软件平台(Media Process Platform,简称 MPP),可支持应用软件快速开发。该平台对应用软件屏蔽了芯片相关的复杂的底层处理,并对应用软件直接提供MPI(MPP Programe Interface)接口完成相应功能。该平台支持应用软件快速开发以下功能:输入视频捕获、H.264/MJPEG/JPEG/MPEG4 编码、H264/H.265/VC1/MPEG4/MPEG2/AVS 解码、视频输出显示、视频图像前处理(包括去噪、增强、锐化、Deinterlace) 、编码码流叠加 OSD、视频侦测分析、智能分析、音频捕获及输出、音频编解码等功能。 1.2 整体软硬件构架 MPP 平台支持的典型的系统层次如上图所示,主要分为以下层次: 硬件层 硬件层由 Hi35xx 芯片加上必要的外围器件构成。外围器件包括 Flash、DDR 操作系统层 基于 Linux 3.10.y 的 OS 系统。 媒体处理平台 基于操作系统层,控制芯片完成相应的媒体处理功能。它对应用层屏蔽了硬件处理细节,并为应用层提供 API 接口完成相应功能。 其他驱动 除媒体处理平台外,海思为 Hi35xx 芯片的其他相关硬件处理单元提供了相应的驱动, 包括 GMAC、SDIO、I2C、USB、SSP 等驱动。 应用层 基于海思媒体处理平台及其他驱动,由用户开发的应用软件系统。 1.3 海思媒体处理平台架构 海思媒体处理平台的主要内部处理流程如上图所示,主要分为视频输入(VI) 、视频处理(VPSS) 、视频编码(VENC) 、视频解码(VDEC) 、视频输出(VO)、视频侦测分析(VDA)、音频输入(AI)、音频输出(AO)、音频编码(AENC) 、音频解码(ADEC) 、区域管理(REGION)等模块。主要的处理流程介绍如下 VI 模块捕获视频图像,可对其做剪切、缩放、镜像等处理,并输出多路不同分辨 解码模块对编码后的视频码流进行解码,并将解析后的图像数据送 VPSS 进行图 VPSS 模块接收 VI 和解码模块发送过来的图像,可对图像进行去噪、图像增强、 编码模块接收 VI 捕获并经 VPSS 处理后输出的图像数据,可叠加用户通过 Region VO 模块接收 VPSS 处理后的输出图像,可进行播放控制等处理,最后按用户配置 AI 模块捕获音频数据,然后 AENC 模块支持按多种音频协议对其进行编码,最后 用户从网络或外围存储设备获取的音频码流可直接送给 ADEC 模块,ADEC 支持 1.4 MMZ与模块绑定 MPP 提供系统绑定接口(HI_MPI_SYS_Bind) ,即通过数据接收者绑定数据源来建立 两者之间的关联关系(只允许数据接收者绑定数据源) 。绑定后,数据源生成的数据将 自动发送给接收者。 Uboot环境变量中定义linux内核使用的内存大小 setenv 'mem=288M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:768K(boot),2304K(sdr021000),13M(rootfs)' 加载内核模块分配MMZ内存大小 insmod mmz.ko mmz=anonymous,0,0x8E000000,792M anony=1 例如512M的DDR DDR: DDR: -----------|----------| 0x80000000 # Memory managed by OS. 64M | OS | | | -----------|----------| 0x84000000 # Memory managed by MMZ block anonymous. 448M | MMZ | | | -----------|----------| 0xA0000000 # Memory managed by MMZ block jpeg. 1.5 HiMPP 支持的绑定关系 数据源 数据接收者 VI VO VENC VDA VPSS PCIV VPSS VO VENC VDA VPSS PCIV VDEC VPSS VO(只能是标清设备或 single 模式分割) VDA PCIV vo(WBC) VO VENC VPSS PCIV AI AENC AO ADEC AO 1.6 函数约定说明 Open/Close Create/ Destroy Handle Attach /Detach Attach 后,目的设备将自动处于 Start/Enable 状态; Detach 后,目的设备将自动处于Stop/Disable 状态。 要求从最后一个设备逐级向前绑定,解绑定的顺序则相反,要求逐级向后。** Get/Put Acquire/Release Get/Put和Acquire/Release推荐成对使用 1.7 MPP优缺点 1.7.1 MPP优点 ​ 内存VB管理和模块绑定子系统,proc运行时调试信息是MPP构架节约用户时间最大的设计。 ​ 大部分外围接口都封装好,用户调用接口直接使用,快速,方便。 1.7.2 MPP缺点 ​ 没有相应子系统的源代码。出了问题,有bug必须需要海思查看,解决。 ​ MPI接口和标准linux接口差异非常大,构架也不一样。有问题需要找海思。中间时间成本。 不利于研发技术积累。 2: MPP和UNF对比 从函数命名,参数,使用方法来看。UNF和MPP分开比较早,UNF构架在上面函数约定说明基础上的MPI接口封装了一层,UNF->MPI调用,UNF开发支持更多的模块接口。MPP的模块接口比较固定,比UNF少得多,增强了MMZ内存,VB管理功能,模块绑定功能。 MPP由HI_MPI_SYS_Bind来绑定两个模块,而UNF还是使用Hi_XXX_Attach来绑定两个模块。 MPP内存管理MMZ,VB也比UNF更细致,强大。 UNF支持更多的外设模块。如TUNER(广播电视),CIPHER(芯片内部加密),Subtitle(字幕),PDM(低功耗),SCI(智能卡),GPU等。 UNF开源。在一些模块的实现中,也使用了一些开源项目,如FFmpeg,Alsa,wpa_supplicant等。 3: 3798芯片UNF处理构架 3.1 应用架构 海思媒体处理平台( MSP)实现了对海思高清机顶盒解决方案处理器中媒体、图形以 3798比35xx多了一个UNF层,它在MPI基础上进行了一层封装 软件架构主要包含以下 4 层: UNF层 媒体处理平台( MSP)对外统一的应用开发接口。 MPI层 处理器各模块硬件能力实现层的用户态部分。 DRV层 处理器各模块硬件能力实现层的内核态部分。 HAL层 处理器各模块的硬件抽象层。 3.2 3798SDK 概览(功能介绍) 媒体处理平台( MSP)中所有模块按照功能可以分为媒体处理,图形处理,外设处理 3 媒体处理 DEMUX、 AVPLAY、 SOUND、 DISPLAY、 VO、 HDMI、 PVR、 VDEC、 VENC、 图形处理 HIFB、 HIGO、 TDE、 JPEG、 JPGE、 GPU 外设处理 Cipher、 OTP、 PMOC、 Frontend、 I2C、 SCI、 KEYLED、 GPIO、 IR、 WDG、 C51 3.3 3798内存管理 3.3.1 Mmz内存 3798的mmz内存在uboot bootargs环境变量中分配,在内核中大块连续内存使用dma_alloc_from_contiguous(drv/mmz/drv_media_mem_v2.c)来分配内存, 小块内存使用kmalloc分配,并且使用内核链表标记管理。和应用层交互使用mamp,umamp,并使用内核链表管理内存。这点和35xx DVR芯片有很大区别,DVR芯片模块内存和linux内核使用内存不再一个地方,应该是通过物理地址往虚拟地址映射来使用的。 # cat /proc/cmdline mem=1G console=ttyAMA0,115200 root=/dev/romblock3 rootfstype=squashfs mtdparts=hinand:5M(boot),1M(baseparam),7M(kernel),18M(rootfs),64M(appfs),16M(qte),4M(config),12M(log),1M(logo) mmz=ddr,0,0,500M 具体就是在bootargs中配置mem=1G mmz=ddr,0,0,435M 查看内存使用情况跟监控相同,通过cat /proc/media-mem 3.3.2 解码vid内存 关于码流解码过程中视频缓冲buffer u32VidBufSize配置: 创建avplay时,可以指定视频es buf大小,参考如下代码 Ret = HI_UNF_AVPLAY_GetDefaultConfig(&AvplayAttr, HI_UNF_AVPLAY_STREAM_TYPE_ES); AvplayAttr.stStreamAttr.u32VidBufSize = 2*1024*1024; Ret |= HI_UNF_AVPLAY_Create(&AvplayAttr, &hAvplay[i]); Es buf的作用存储码流原始es流。 这个buffer的大小跟码流分辨率、码率都有关系,一般情况下,D1/720P/1080P/4K 码流的配置为 2M/3M/5M/16M 即可,特殊码流除外。 3.4 3798模块 DEMUX: ​ 数据输入模块。IF,TSI,RAM。 ​ NVR使用的是RAM接口输入ES码流。 VI: 虚拟VI VDEC ​ 解码器模块提供一组函数指针,供解码使用。目前有264,mpeg4两个。 视频解码的简单流程是: SYNC: 音视频同步工具 DISPLAY:显示设备 WINDOW:显示通道 msp 目录下的“ windowXXYY”节点的中的 XX 为显示通道的编号, YY 为 window 序号。比如 window0100, bit[15:8]的 01 表示该 window 基于 DISPLAY1 创建, bit[7:0]的00 表示 window 序号为 0。有支持3D显示 DISP( Display)模块接收 WINDOW 提供的视频图像、 Frame Buffer 提供的图形画 窗口类型 Display:独立显示窗口 Virtual:虚拟窗口 Main:同源显示主窗口 Slave:同源显示从窗口 SO( Subtitle Output) PDM PDM(Product Data Manager)模块用于管理与产品相关的数据,包括基本参数、开机画 用户通过镜像制作工具制作基本参数镜像与瞬播镜像,通过烧写工具烧写至 FLASH,PDM 模块在 BOOT 下将基本参数及瞬播数据读入内存,并传递至 KERNEL。 KERNEL下瞬播从 PDM 模块获取参数及数据,调用 DEMUX、 VDEC、 VO 等模块驱动,完成瞬播播放 demux DEMUX 模块接收 DEMOD 或内存中的 TS 流,按客户应用程序(下简称 APP)的设 AVPLAY 主要依赖 ADEC/VDEC/DEMUX 等模块,其向应用或中间件播放器提供基本 3.5 3798和NVR模块使用方面区别: 3798模块中vpss,sync等模块是其它模块自动创建,自动绑定处理的。这点和NVR系列芯片差别很大,nvr中vi,vpss,vo都需要用户自己绑定,设置属性,而3798中vpss,vo创建,属性设置是在上层模块中自动处理的(少量设置属性上层传递下去)。 ​ 简单来说,MPP接口只实现了基本的功能接口,没有封装或很少封装。 UNF 应用层实现了很多业务接口,对底层驱动进行了多层封装,并且实现了一些常用的业务。 4: 3798代码祥看 4.1 分析方法 4.1.1:查看代码,静态分析应用层,驱动层实现方法 ​ 使用Source insight分析kernel,msp代码。 4.1.2:图示静态分析函数调用关系 ​ 使用cflow, tree2dotx,和dot生成函数静态调用图。 4.1.3:图示动态分析函数调用关系:库函数,系统调用,内核调用 ​ 使用ltrace分析系统库函数 ​ strace分析系统调用流程 ​ 使用Ftrace,valgrind,gprof2dot生成运行时调用图。 ​ Perf分析内核空间调用。发现一些依赖库在ubuntu12.04里面不可用。 这一步实现了valgrind动态分析,其它的几个工具需要交叉编译,TODO。使用Perf可能需要换更新的linux版本。 其它还有time(大概运行时间),gconv(覆盖率统计)等分析方式。 4.2 基础模块:hi_media hi_mmz hi_common ​ 可以从lsmod中很清晰的看出来hi_media hi_mmz hi_common这几个模块的基础地位。hi_media基础模块管理,hi_mmz提供内存管理,hi_common提供proc,log等基础功能,符号导出供其他海思模块使用。 Common COMMON 模块是 SDK 的基础模块,提供的 API 主要供 SDK 的其他模块调用。 系统初始化和去初始化; 版本信息获取; 获取时间戳; 寄存器读写、映射功能; MMZ 内存使用; 调试信息控制; Flash 操作。 4.2.1 基本通用模块应用层接口common/api HiSTBLinuxFS/source/common/api mpi_mem.c MEM_POOL_Init 应用层的内存池,重复利用。 mpi_memmap.c 映射使用链表区分。管理mmap映射 mpi_module.c HI_MODULE_Init中有打开内存操作,内存统一管理。 模块id,名称注册,相互查找。 mpi_stat.c 线程时间归零,等相关处理 hi_common.c proc,sys一些路径目录增删提供了用户层接口,mmz内存管理用户层接口 mpi_userproc 用户层提供线程 通用proc接口,proc读写是在其它模块内部实现的,函数指针形式 注:himedia 相关模块是海思自己实现的内核子系统。有自己实现的总线,驱动,设备模型结构体。也是在标准linux模型基础上封装的。 4.2.2 基本通用模块驱动接口common/dev HiSTBLinuxFS/source/common/dev drv_dev_ext_k.c 重要 HI_DRV_DEV_Init 所有模块宏定义在这里,注册模块结构体在这里 himedia.c himedia_bash.c 模块注册,注销基础函数 #define DYNAMIC_MINORS 128 /* like dynamic majors */ himedia主设备号218 static unsigned char himedia_minors[DYNAMIC_MINORS / 8]; typedef struct tagPM_BASEDEV_S{ HI_S32 id; const HI_S8 * name; struct device dev; }PM_BASEDEV_S; #define TO_PM_BASEDEV(x) container_of((x), PM_BASEDEV_S, dev) typedef struct tagPM_BASEOPS_S { HI_S32 (*probe)(PM_BASEDEV_S *); HI_S32 (*remove)(PM_BASEDEV_S *); HI_VOID (*shutdown)(PM_BASEDEV_S *); HI_S32 (*prepare)(PM_BASEDEV_S *); HI_VOID (*complete)(PM_BASEDEV_S *); HI_S32 (*suspend)(PM_BASEDEV_S *, pm_message_t state); HI_S32 (*suspend_late)(PM_BASEDEV_S *, pm_message_t state); HI_S32 (*resume_early)(PM_BASEDEV_S *); HI_S32 (*resume)(PM_BASEDEV_S *); }PM_BASEOPS_S; typedef struct tagPM_BASEDRV_S { HI_S32 (*probe) (PM_BASEDEV_S *); HI_S32 (*remove)(PM_BASEDEV_S *); HI_VOID (*shutdown)(PM_BASEDEV_S *); HI_S32 (*suspend)(PM_BASEDEV_S *, pm_message_t state); HI_S32 (*suspend_late)(PM_BASEDEV_S *, pm_message_t state); HI_S32 (*resume_early)(PM_BASEDEV_S *); HI_S32 (*resume)(PM_BASEDEV_S *); struct device_driver driver; }PM_BASEDRV_S; typedef struct tagPM_DEVICE_S { HI_S32 minor; const HI_S8 *name; struct module *owner; const struct file_operations *app_ops; PM_BASEOPS_S *base_ops; struct list_head list; struct device *app_device; PM_BASEDEV_S *base_device; PM_BASEDRV_S *base_driver; }PM_DEVICE_S; static struct class *himedia_class; static struct file_operations himedia_fops = { .owner = THIS_MODULE, .open = himedia_open, }; 设备模型结构体 struct himedia_devobj { PM_BASEDEV_S pdev; char name[1]; }; typedef struct tagPM_BASEDEV_S{ HI_S32 id; const HI_S8 * name; struct device dev; }PM_BASEDEV_S; 海思模块顶层总线himedia_bus struct device himedia_bus = { .init_name = "himediaBusDev", .release = himedia_bus_release }; /*top level bus, parent and bus member are both NULL*//*CNcomment:这是顶层总线,parent 和 bus 成员为 NULL*/ struct bus_type himedia_bus_type = { .name = "himediaBus", .dev_attrs = himedia_dev_attrs, .match = himedia_match, .uevent = himedia_uevent, .pm = HIMEDIA_PM_OPS_PTR, }; 定义HIMEDIA_PM_OPS_PTR static struct dev_pm_ops himedia_dev_pm_ops = { .prepare = himedia_pm_prepare, .complete = himedia_pm_complete, .suspend = himedia_pm_suspend, .resume = himedia_pm_resume, .freeze = himedia_pm_freeze, .thaw = himedia_pm_thaw, .poweroff = himedia_pm_poweroff, .restore = himedia_pm_restore, .suspend_noirq = himedia_pm_suspend_noirq, .resume_noirq = himedia_pm_resume_noirq, .freeze_noirq = himedia_pm_freeze_noirq, .thaw_noirq = himedia_pm_thaw_noirq, .poweroff_noirq = himedia_pm_poweroff_noirq, .restore_noirq = himedia_pm_restore_noirq, }; #define HIMEDIA_PM_OPS_PTR (&himedia_dev_pm_ops) 内核到用户往用户空间写文件调试 drv_file_ext.c 提供内核空间创建,读写用户空间文件函数,/mnt文件存储路径。提供了内核数据导出到用户空间的方法。 应该是echo * > /proc/msp/** 这种调试方式的实现方式 内核log日志 drv_log_ioctl.h 打印日志相关。 这里日志位置可选0:串口 1:网络 2:U盘 /*structure of mode log level */ /*CNcomment: 模块打印级别控制信息结构 */ typedef struct hiLOG_CONFIG_INFO_S { HI_U8 ModName[16+12]; /*mode name 16 + '_' 1 + pid 10 */ HI_U8 u8LogLevel; /*log level*//*CNcomment: 模块打印级别控制 */ HI_U8 u8LogPrintPos; /*log output location, 0:serial port; 1:network;2:u-disk*//*CNcomment: 模块打印位置控制 0:串口 1:网络 2:U盘 */ HI_U8 u8UdiskFlag; /* u-disk log flag */ }LOG_CONFIG_INFO_S; hi_debug.h log调试级别 /**Default level of the output debugging information*/ /**CNcomment: 默认的调试信息输出级别*/ #define HI_LOG_LEVEL_DEFAULT HI_LOG_LEVEL_ERROR /**Level of the output debugging information*/ /**CNcomment: 调试信息输出级别*/ typedef enum hiLOG_LEVEL_E { HI_LOG_LEVEL_FATAL = 0, /**<Fatal error. It indicates that a critical problem occurs in the system. Therefore, you must pay attention to it.*/ /**<CNcomment: 致命错误, 此类错误需要特别关注,一般出现此类错误代表系统出现了重大问题 */ HI_LOG_LEVEL_ERROR = 1, /**<Major error. It indicates that a major problem occurs in the system and the system cannot run.*/ /**<CNcomment: 一般错误, 一般出现此类错误代表系统出现了比较大的问题,不能再正常运行 */ HI_LOG_LEVEL_WARNING = 2, /**<Warning. It indicates that a minor problem occurs in the system, but the system still can run properly.*/ /**<CNcomment: 告警信息, 一般出现此类信息代表系统可能出现问题,但是还能继续运行 */ HI_LOG_LEVEL_INFO = 3, /**<Message. It is used to prompt users. Users can open the message when locating problems. It is recommended to disable this message in general.*/ /**<CNcomment: 提示信息, 一般是为提醒用户而输出,在定位问题的时候可以打开,一般情况下建议关闭 */ HI_LOG_LEVEL_DBG = 4, /**<Debug. It is used to prompt developers. Developers can open the message when locating problems. It is recommended to disable this message in general.*/ /**<CNcomment: 提示信息, 一般是为开发人员调试问题而设定的打印级别,一般情况下建议关闭 */ HI_LOG_LEVEL_BUTT } HI_LOG_LEVEL_E; drv_media_mem_v2.c 实现了cat /proc/media-mem drv_mem_ext.c 实现了 KMEM_POOL_S 的管理, 内核模块管理 drv_module_ext.c COMMON_DRV_ModInit MMNGR_DRV_ModInit s32Ret = HI_DRV_MODULE_Register(HI_ID_SYS, "HI_SYS", HI_NULL); s32Ret |= HI_DRV_MODULE_Register(HI_ID_MODULE, "HI_MODULE", HI_NULL); s32Ret |= HI_DRV_MODULE_Register(HI_ID_LOG, "HI_LOG", HI_NULL); s32Ret |= HI_DRV_MODULE_Register(HI_ID_PROC, "HI_PROC", HI_NULL); s32Ret |= HI_DRV_MODULE_Register(HI_ID_STAT, "HI_STAT", HI_NULL); s32Ret |= HI_DRV_MODULE_Register(HI_ID_MEM, "HI_MEM", HI_NULL); drv_media_mem.c 使用dma_alloc_from_contiguous来分配 HI_DRV_MMZ_Init 这里根据bootargs传递的mmz参数分配内存大小。 mmz分配时的参数:<mmz_name>,<gfp>,<phys_start_addr>,<size>,<alloc_type>" 内核Proc的实现 drv_proc_ext.c HI_DRV_PROC_Init 实现cat /proc/hisi/msp/ proc_mkdir("graphics", g_pHisi_proc); proc_symlink("msp", NULL, "hisi/msp"); proc_symlink("graphics", NULL, "hisi/graphics"); drv_userproc.c proc使用红黑树管理目录路径 ​ 创建销毁目录,路径在这里实现,具体每一个不同模块的proc文件读写在每个模块内部实现,使用函数指针。 4.2.3 业务模块应用层通用组件source/component /home/andy/HiSTBLinuxFS/source/component 这个目录里面很多目录只有.so .a库,没有源代码。 /source/component/hiplayer 没有源码。 hi_debug.h 各种调试宏定义,不同级别调试定义 HI_MALLOC 内存分配使用了内核链表管理 内存在一个模块内分配,往用户空间传递物理地址,其它模块使用这个物理地址映射到虚拟地址,这样来共享内存 ​ 海思这里大多数模块都只提供了编译后的库 4.3 海思专用组件 4.3.1 海思MSP模块应用层接口source/msp/api Avplay分析 HI_MPI_AVPLAY_Create AVPLAY_FrcCreate 帧率控制? HI_MPI_SYNC_Create 音视频同步 AVPLAY_CreateThread ​ 上图插图的是svg格式图片,可以使用IE,firefox打开,最好使用专门的看图软件打开。 HI_MPI_VDEC_AllocChan VPSS_Control(pstVdec->hVdec,VPSS_CMD_CREATEVPSS,&(pstVdec->hVpss)) UNF调用一般过程,最终采用ioctl调用驱动 HI_UNF_AVPLAY_GetBuf HI_MPI_AVPLAY_GetBuf HI_MPI_VDEC_ChanGetBuffer VDEC_GetStreamBuf /* If get but not put, return last address */ 这里有对不对称调用特殊处理 ioctl(s_stVdecAdpParam.s32DevFd, UMAPC_VDEC_GETBUF, &stBufParam); HI_MPI_AVPLAY_Start AVPLAY_StartVidChn HI_MPI_SYNC_Start HI_MPI_VDEC_ChanStart ioctl(g_SyncDevFd, CMD_SYNC_START_SYNC, &SyncId); HI_MPI_SYNC_Play 结构体状态改变 AVPLAY_Play 结构体状态控制 HI_MPI_STAT_Event HI_MPI_AVPLAY_Stop AVPLAY_StopVidChn HI_MPI_VDEC_ChanStop VDEC_ChanStop 这里调用函数指针 HI_MPI_VDEC_ResetChan VDEC_ResetStreamBuf VDEC_VPSSCMD(hVdec, VPSS_CMD_RESETVPSS, HI_NULL); 调用函数指针,指向VPSS_Control AVPLAY_ResetWindow HI_MPI_SYNC_Stop HI_MPI_STAT_Event(STAT_EVENT_VSTOP, 0); VDEC使用函数指针集来支持多种解码方式,内部vfmw。mjpeg,内部硬件265协处理器 mpi_vdec_vpu.c HI_MPI_VDEC_Init HI_CODEC_Register(VDEC_MJPEG_Codec()); HI_CODEC_Register(VDEC_VFMW_Codec()); static HI_CODEC_S hi_codecVPU_entry = { .pszName = "VPU", .unVersion = {.stVersion = {1, 0, 0, 0}}, .pszDescription = "Hisilicon H265 codec", .GetCap = HI_VPU_GetCap, .Create = HI_VPU_Create, .Destroy = HI_VPU_Destroy, .Start = HI_VPU_Start, .Stop = HI_VPU_Stop, .Reset = HI_VPU_Reset, .SetAttr = HI_VPU_SetAttr, .GetAttr = HI_VPU_GetAttr, .DecodeFrame = HI_VPU_DecodeFrame, .EncodeFrame = HI_NULL, .RegFrameBuffer = HI_VPU_RegFrameBuffer, .GetStreamInfo = HI_VPU_GetStreamInfo, .Control = HI_VPU_Control, }; avplay,vi和 vo之间使用vpss关联。 HI_UNF_VO_DetachWindow HI_MPI_AVPLAY_DetachWindow HI_MPI_VDEC_DestroyPort HI_MPI_VI_Detach(hSrc, hWindow); VI_DetachFromVpss HI_MPI_AVPLAY_ChnClose AVPLAY_FreeVidChn HI_MPI_VDEC_ChanBufferDeInit VDEC_VFMWSpecCMD(hVdec, VFMW_CMD_DETACHBUF, HI_NULL); VDEC_DestroyStreamBuf(pstVdec->hStreamBuf); ummap内存块,ioctl通知内核vdec销毁内存 AVPLAY_FreeVdec HI_MPI_VDEC_FreeChan VPSS_Control(pstVdec->hVdec,VPSS_CMD_DESTORYVPSS,&(pstVdec->hVpss)); VDEC_DestroyCodec(pstVdec); HI_UNF_AVPLAY_Destroy HI_MPI_AVPLAY_Destroy HI_MPI_SYNC_Destroy(pAvplay->hSync); ioctl(g_AvplayDevFd, CMD_AVPLAY_DESTROY, &AvplayUsrAddr.AvplayId); avplay内部的线程 (HI_VOID)pthread_join(pAvplay->AvplayDataThdInst, HI_NULL); #ifdef AVPLAY_VID_THREAD (HI_VOID)pthread_join(pAvplay->AvplayVidDataThdInst, HI_NULL); #endif (HI_VOID)pthread_join(pAvplay->AvplayStatThdInst, HI_NULL); 4.3.2 海思MSP模块驱动层接口source/msp/drv/ VENC VENC 模块的具体工作原理如上图所示,注意图中褐色箭头,是 VENC 调用到VPSS 模块,来对帧信息做缩放处理后编码的数据流,该处理只用于外部用户送帧的模式。若在绑定情况下出现帧信息分辨率与编码分辨率不匹配, VENC 模块会通知绑定的前级模块进行缩放处理,而不会自行调用 VPSS 模块缩放。 VENC_DRV_ModInit VENC_DRV_Init HI_DRV_MODULE_Register(HI_ID_VENC, "HI_VENC", (HI_VOID*)&s_VencExportFuncs); MODULE_DRV_Register ModuleMgr_Link_AddNode(g_pstKModuleHeader, &stModule); 链表管理 LOGAddModule((HI_PCHAR)pu8ModuleName, (HI_MOD_ID_E)u32ModuleID); 在log模块中注册 HI_DRV_DEV_Register(&g_VencRegisterData) HI_DRV_PM_Register 海思模块管理非常重要的模块,了解这个函数实现过程就大概明白海思内核模块实现思想了 VENC_DRV_BoardDeinit(); 一些寄存器配置,reset,clock操作。 venc调用硬件协处理器,涉及263,264,mpeg4, snprintf(g_VencRegisterData.devfs_name, 64, "%s", UMAP_DEVNAME_VENC); g_VencRegisterData.fops = &VENC_FOPS; g_VencRegisterData.minor = UMAP_MIN_MINOR_VENC; g_VencRegisterData.owner = THIS_MODULE; g_VencRegisterData.drvops = &venc_drvops; avplay AVPLAY 主要由以下三部分组成: 音视频解码器 同步播放控制模块 命令与状态管理模块 主要负责响应外部控制命令的执行、状态查询上报、使解码后的帧数据通过同步控制 avplay初始化分析 AVPLAY_DRV_ModInit ​ HI_DRV_MODULE_Register ​ HI_DRV_MODULE_Register(HI_ID_AVPLAY, AVPLAY_NAME, HI_NULL); ​ ModuleMgr_Link_AddNode 内核模块管理 ​ KMODULE_MEM_POOL_AddModule ​ KMODULE_MEM_POOL_FindNode 找到空的没有使用的节点 ​ KMODULE_MEM_POOL_MALLOC 分配内存,然后放到链表 ​ LOGAddModule 日志 ​ HI_DRV_DEV_Register(&g_AvplayRegisterData) ​ HI_DRV_PM_Register(&s_umap_devs[i]); himedia封装处理 ​ himedia_device_alloc(himedia->name, -1); ​ himedia_device_add(bdev); ​ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); ​ device_add(&pdev->dev); ​ device_create(himedia_class, &(bdev->dev), dev, NULL, "%s", himedia->name); ​ himedia_driver_alloc(himedia->name, himedia->owner, himedia->base_ops); ​ himedia_driver_register(bdrv); ​ driver_register(&drv->driver); ​ g_AvplayRegisterData.fops = &AVPLAY_FOPS; g_AvplayRegisterData.minor = UMAP_MIN_MINOR_AVPLAY; g_AvplayRegisterData.owner = THIS_MODULE; g_AvplayRegisterData.drvops = &AVPLAY_DRVOPS; s_umap_devs[i].minor = umapd->minor; s_umap_devs[i].name = umapd->devfs_name; s_umap_devs[i].owner = umapd->owner; s_umap_devs[i].app_ops = umapd->fops; s_umap_devs[i].base_ops = umapd->drvops; IOCTL实现分析 基于avplay 在HI_DRV_DEV_Register中注册 static struct file_operations AVPLAY_FOPS = { .owner = THIS_MODULE, .open = AVPLAY_DRV_Open, .unlocked_ioctl = AVPLAY_DRV_Ioctl, .release = AVPLAY_DRV_Close, }; AVPLAY_DRV_Ioctl HI_DRV_UserCopy(ffile->f_dentry->d_inode, ffile, cmd, arg, AVPLAY_Ioctl); func(inode, file, cmd, (parg)); 这里对ioctl进行了一层封装,copy_from_user,copy_to_user的自动化处理 AVPLAY_Ioctl(struct inode *inode, struct file *file, unsigned int cmd, HI_VOID *arg) CMD_AVPLAY_CREATE AVPLAY_Create HI_DRV_MMZ_AllocAndMap(BufName, MMZ_OTHERS, 0x2000, 0, &MemBuf); HI_DRV_PROC_AddModule(ProcName, HI_NULL, HI_NULL); 这里实现了proc目录的生成,下面是读写proc pProcItem->read = AVPLAY_ProcRead; pProcItem->write = AVPLAY_ProcWrite; avplay 多个实例如何找到对应实例 AVPLAY_GET_INST_AND_LOCK(); AVPLAY_CheckHandle pAvplayUsrAddr->AvplayId = hAvplay & 0xff; ioctl(g_AvplayDevFd, CMD_AVPLAY_CHECK_ID, pAvplayUsrAddr); drv中的实现 AVPLAY_Ioctl AVPLAY_CheckId pAvplayUsrAddr->AvplayUsrAddr = g_AvplayGlobalState.AvplayInfo[pAvplayUsrAddr->AvplayId].AvplayUsrAddr; VPSS g_VpssRegisterData.fops = &s_VpssFileOps; g_VpssRegisterData.minor = UMAP_MIN_MINOR_VPSS; g_VpssRegisterData.owner = THIS_MODULE; g_VpssRegisterData.drvops = &s_VpssBasicOps; VPSS_DRV_Init VPSS_CTRL_Init VPSS_CTRL_RegistISR 注册中断 VPSS_CTRL_InitInstList((VPSS_IP_E)i) 管理vpss实例链表初始化 VPSS_HAL_Init 内存,寄存器配置 VPSS_CTRL_CreateThread 内核线程 VPSS_CTRL_ThreadProc VPSS_CTRL_CreateTask 创建任务 VPSS_CTRL_StartTask 开始任务 VDEC Avplay解码ES流过程 步骤 1 初始化并配置相关设备,如 DISPLAY、 VO、 SOUND、 DEMUX 设备等。 步骤 7 调用 HI_UNF_AVPLAY_SetAttr 接口设置音频解码器或视频解码器属性,同步设置为自由播放。 MCE实现了启动过程画面的平滑切换 IR 驱动层 负责完成红外模块的中断处理,在底半部中遍历所有协议并调用 match 函数来判定当前收到的红外帧属于哪种协议。如果没有匹配,则丢弃当前帧。完成最顶层的错误处理:如果当前帧当前时刻还不能被解析,则会等待大约 200ms 之后再次尝试,如果失败,则丢弃当前帧。 协议适配层 完成各个协议的初始化工作,向上提供遍历协议的接口,向下提供容纳协议描述符的存储空间。 协议处理层 协议处理层完成判定:由从某个 symbol 开始的一连串 symbol 是不是符合本协议的一 4.4 Sample_mosaic分析 应用层调用 上图是部分截图,完整大的原图见目录中svg文件 valgrind --tool=callgrind ./sample_mosaic 1080P.h264 h264 系统调用 Strace分析 5:小结: 海思MPI驱动其实就是在标准linux驱动基础之上封装了一层,增加了log,proc,内存管理(映射,链表)功能。MPI是在标准linux驱动基础上封装了DVR常用外围逻辑接口,并且统一并简化了接口操作方式,原来各个外围子系统操作方式差别很大,不同实现框架,实现方式使用方法也不一样(如VI,VO,AI/AO,VPSS,如果自己用标准linux子系统实现要复杂得多)。 应用层MPI接口是在MPI驱动基础上再次封装了一层,封装了驱动的调用,配置等操作,在驱动功能的基础上进一步封装完成了一些简单的业务功能接口,方便了用户的使用。UNF就是在MPI基础上增加了业务逻辑封装,把常用的业务逻辑封装成接口,大大方便用户的应用程序开发。 5.1 UNF相对标准内核模块区别 5.1.1 Proc读写调试。 实时查询运行状态,修改设置。通用的proc目录、文件创建销毁有通用接口。读写proc文件在每个内核模块中有单独实现。 5.1.2 内核空间往应用空间写文件 方便调试,Dump内核数据到用户控件方便定位Bug。 HI_DRV_FILE_Open filp_open HI_DRV_FILE_Close ​ filp_close HI_DRV_FILE_Read ​ pFile->f_op->read HI_DRV_FILE_Write ​ pFile->f_op->write HI_DRV_FILE_Lseek ​ vfs_llseek 5.1.3Log管理 日志打印分级,实时修改。如何实现的见前面章节。 5.1.4内存映射 物理地址,虚拟地址映射关系管理,小块内存使用kmalloc申请,大块内存使用dma_alloc_from_contiguous申请。 使用内核链表管理。 打印到proc,log模块中,实时查看运行状态,内存。 方便查找,打印。 在多个内核共享数据也是这样实现的。 5.2代码分析方法 5.2.1 查看代码,静态分析应用层,驱动层实现方法 5.2.2 图示静态分析函数调用关系. Cflow, dot 5.2.3 图示动态分析函数调用关系:库函数,系统调用,内核调用 ​ Ltrace, strace, valgrind, perf 具体分析方法,使用工具见前面章节。 参考文档: 03-HMS 开发指南.pdf HiSTBAndroidV600R001C00SPC060_cn\document\01-Development Guide HiMPP V3.0 媒体处理软件开发参考.pdf HiSTBAndroidV600R001C00SPC060_cn\document\01-Development Guide 3798m SDK 代码 HMS API Development Reference.chm HiSTBAndroidV600R001C00SPC060_cn\document\01-Development Guide\09-API Reference 相关文章 如何编写Linux驱动 本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标! 3G,4G,Wifi选型需求分析及技术简介 详细介绍了3G,4G,wifi技术类型,选型,移植,性能介绍全过程。写了好多年了,禁止转载,第一次公开发表。 海思MPP&UNF构架源代码级分析 行业中分析海思MPP内核构架,源码分析,多年经验总结积累结果。写了好多年了,禁止转载,第一次公开发表。 如何实现自己的操作系统 作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库! 手把手教你构建 C 语言编译器 “手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。 系列教程 全部文章RSS订阅 Embeded系列 Embeded 分类 RSS 订阅 海思MPP&UNF构架源代码级分析 3G,4G,Wifi选型需求分析及技术简介 自动曝光原理 ISP 数字图像处理 算法概述、工作原理、架构、处理流程 QNAP添加man pages

2021/7/1
articleCard.readMore

Github Pages + jekyll 全面介绍极简搭建个人网站和博客

利用github pages搭建个人博客。本文指导建立github工程,并配置github pages搭建博客的全过程。 注意:图床使用github,图片显示问题自己解决 第一步,建立Github仓库 首先到这里Github,创建一个仓库。 仓库名称有固定的格式: username.github.io,其中username必须是Github账户的用户名(我的是scottcgi),github.io是固定的,这个地址将会成为个人站点的网站地址。另外,我们可以勾选Initialize this repository with a README,让仓库自动创建一个README.md文件,我们用它来做站点的首页(当然也可以不创建,后面自行创建,或是建立index.html也行)。 注意: username如果不是Github账户名,这个仓库就会成为username.github.io的子站点,比如访问地址会是:username.github.io/aaa.github.io。可见,username.github.io是github默认分配给你的域名,同名仓库即代表着默认网站内容。而username.github.io/仓库名称,是用来访问你的其它仓库的地址。 第二步,设置仓库开启Github Pages 进入仓库设置界面,如图。 这里能够重新修改仓库的名称,比如这个仓库内容是fork别人的,就可以在这里修改成自己的username.github.io名称。 在Setting页面下有Github Pages的设置选项。绿色表示部署成功,每次修改仓库内容,都会出发Github jekyll重新编译部署,需要1-2分钟的时间,更新才能体现。如果有编译错误,包括js,css,html,markdown语法问题,都会显示红色以及错误页面和行号,同时会发邮件通知。其中,Source有以下几个选项: gh-pages branch 是项目新建一个分支命名为这个,使用这个分支来做站点内容。 第三步,使用Github内置主题 选择好主题,过一会刷新网站地址就已经能看到效果了,而在Code页面仅有两个文件。 编辑README.md文件的内容,就会默认显示在网站首页,_config.yml 是jekyll的全局配置文件,现在里面只有一句话,theme: jekyll-theme-modernist。我们可以手动修改这个theme主题配置,网站就会应用不同的主题。 Github内置支持的几个主题,官方的仓库在这里:https://pages.github.com/themes,每个README.md里都有介绍如何设置。 那么我们现在就有两种方法来使用这些主题: 第一种,就是直接fork一个主题仓库,然后修改仓库名称为我们自己的,然后修改我们需要的部分。 第二种,只是简单的Choose (Change) theme(或在_config.yml设置theme),然后我们对照着官方仓库的主题目录,需要改什么文件就按照同样的路径拷贝单独一个文件到自己的仓库来修改(保持路径一致),这样就可以保持自己仓库的简洁。(如果使用了github内置的主题,github就会把你仓库的内容和内置主题内容合并到一起编译成静态网页。) 另外,更多主题可以参看这两个地址(不要挑花眼了): jekyll themes 和 jekyll wiki site。 第四步,jekyll的目录结构 我们只需要关注几个核心的目录结构如下(可以自己创建): - _layouts (存放页面模板,md或html文件的内容会填充模板) - _sass(存放样式表) - _includes (可以复用在其它页面被include的html页面) - _posts(博客文章页面) - assets(原生的资源文件) - js - css - image - _config.yml (全局配置文件) - index.html, index.md, README.md (首页index.html优先级最高,如果没有index,默认启用README.md文件) - 自定义文件和目录 更多更详细的目录结构参看jekyll官网:https://jekyllrb.com/docs/structure 第五步,jekyll的模板编程语言Liquid的使用 变量 被嵌入在页面中,会在静态页面生成的时候被替换成具体的数值。常用的全局变量对象有:site 和 page。这两个对象有很多默认自带的属性,比如:,。更多的默认值参看:https://jekyllrb.com/docs/variables。 site对象对应的就是网站范围,自定义变量放在_config.yml中,比如title:标题使用访问。 page对象对应的是单个页面,自定义变量放在每个页面的最开头,比如: myNum:100 myStr:我是字符串 使用 和 访问。 https://shopify.github.io/liquid/tags/control-flow 循环迭代,更多详见:https://shopify.github.io/liquid/tags/iteration 默认函数,可以对变量进行一些处理,比如大小写转化、数学运算、格式化、排序等等,在Liquid中叫做Filters。比如{{ "Hello World!" | downcase }}转换字符串为小写。更多内置函数详见:https://jekyllrb.com/docs/liquid/filters 第六步,使用_config.yml文件设置jekyll 如果不是fork别人的仓库,就需要自己创建一个这个文件。然后,我们就可以配置一些默认的属性来控制jekyll的编译过程。更多详细的内置属性详见:https://jekyllrb.com/docs/configuration/default 同时我们可以自定变量,会自动绑定到site对象上,比如我们可以把导航配置到_config.yml中: 当然,我们也可以把一些数据单独放入一个yml文件,然后放在固定的数据文件夹_data下,比如_data/navigation.yml,这样访问这个文件的数据对象就是site.data.navigation。 第七步,_layouts模板配置 _layouts文件夹存放的是页面模板,默认需要一个default.html,什么意思?就是说,layout提供一个页面的布局框架,这是固定的模式,包括样式、结构、布局、脚本控制等等。然后,我们在用其它md或html文件去动态填充这个框架,这样就形成了一个完整的页面。比如我的default.html页面如下: {% seo %} 是jekyll的一个插件提供的seo优化,详情在这里:https://github.com/jekyll/jekyll-seo-tag 核心在于 content 这个变量是内置的,会用我们的md或html页面填充这部分内容。 其它的,我们看到会大量使用变量和流程控制代码,来填充模板的方方面面。 于是,填充模板的内容,一方面是来自读取配置文件的变量,一方面是来自_includes的页面,还有就是来自 content 对应的页面。 第八步,md和html页面编写 站点内容页面,可以使用markdown或html来编写,但markdown编写的md文件,在浏览器地址访问的时候依然使用html文件后缀。推荐使用markdown来书写内容,语法参见:Github md 示例 和 Github md 教程。比如下面这个About.md页面: --- layout: default title: About --- # About page This page tells you a little bit about me. layout: default 就是告诉jekyll这个页面使用哪个模板,即这个页面会放入哪个模板的content。当然,我们可以在_layouts文件夹下提供多个不同的模板,然后根据需要不同的页面使用不同的layout。 页面可以放在任意位置和目录,访问的时候从站点域名开始,带上目录名称,再次注意需要使用html结尾。如果想要自定义浏览器的访问路径,可以参看详细设置:permalinks。 md和html页面的区别: md有自己的语法,可以使用少量的html标签,最终会编译成html,侧重于内容编写。 第九步,博客文章编写和管理 我们自然可以新建目录,提交文章,然后添加一个文章列表页面。但我们也可以把这些交给jekyll的内置机制来完成,因为它提供了一些方便的内置文章管理功能。 _posts文件夹是内置的放置文章的目录,我们可以将固定格式year-moth-day-name.md名称的md文件放到这里。比如新建一篇md的博客文章放到_posts目录下: --- layout: post --- 这是一篇博客文章。 接下来我们需要添加一个post的模板页面到_layouts文件夹下面。 可见,模板页面本身也可以使用模板,这里post使用了default模板,而这里 content 就会填充_posts下面编写的页面(如果页面使用了layout: post模板)。 最后,我们还需要编写一个博客文章列表的页面,用来展示所有的文章。比如在根目录新建blog.html页面: site.posts jekyll会自动生成_posts目录的对象。 _post.url jekyll会自动会设置在_posts目录下的页面url。 post.title 默认是md文件名称,但也可以在文章页面自定义title: 我的文章自定义名称。 post.excerpt 默认是文章第一段的摘要文字。 第十步,Github Pages的限制 Github Pages 并不是无限存储和无限流量的静态站点服务,一些限制如下: 内容存储不能超过1GB。 每个月100GB流量带宽。 每小时编译构建次数不超过10次。(在线修改重新编译并未发现这个限制) 更多参看官方说明:usage-limits。 总结 在实际的使用过程中,我发现完全可以在Github网站上,编写md和html页面,修改js和css文件,来完成站点的设置和搭建。只不过每次修改都要触发Github jekyll的编译行为,有点慢(不知道是不是增量编译),没有在本地修改调试的速度快。 更多jekyll详细的设置和功能,参看官方网站的文档:https://jekyllrb.com/docs。 原文链接:https://blog.csdn.net/tom_221x/article/details/84630283

2021/3/3
articleCard.readMore

服务器相关资源使用说明

7d9c186f5a0db09a1fa137a45562808384fb40784d4201cea9e674fb3cd5f4ae92ddd173133ab5aec771ccd45e9cd4fc560af244356ee72190c1af8a195f390214ee68247d56bd660b188abc80c7da881f2ab5917165f26fdbf76419b3c7203d3362e06f03d7df05c5fb6c5c95d8ab51c7cc327cdff2068d46e5e0d5ca9dd7b0cd7467ec3bde933dfd524b9627b1b067a540ab6c434d2c2720121097dcce02de49c451139628f5f56d30b7b32e5935a3578f8dfeeb26d4e3000678ff9e90a1862d41f5484bbdccc5cd3fdb2fb0f6cb96019337e6a40bf78087aa2884572ef0776cd1e96d4200482a75b81757367875edf289cbe5b8c12ef53e48bed184a39917adab8c2aca60e369d837dccbac85d476bd1eb128d7c4701ec3e6452d90fc1c72e67c44261eefc11e476296a4333942dc28cf8e8aea4eae01a014cb5e0fd64056bc0c1d67e9e0fdb1126ad90864a32cb6d2ddef0e47771fa9b198fb9f37f9857f1183366a3ecec7067faa0b639214e1970f110f21dfea5b89f7b60dfe43dde011d3ce183c97e0398eef106f977b619b04d6d973e6381426f5cf3fc0be745e9866a98366b1b36a08257a2c621e7421163e8947962529e572cc2eb62baf5cc19096962da7cd1430f0ec199db6f1e42340b73d416469b73cec0d6da982272637e6266b8ec31b03d9b7a3407dcb40ab6b96a0d5805995c7a020ffe7e9aafb44fb151572de1097b08ecf8d6384ef2ca299bfe0cf7627f5899b69de21c7ae057ef5d6001a15213b4c6110661170eaffe86d4b54ad17d11660790df25e38ea03f27c4a309eb8a5eca7e7114bd54d0665a2be71e2a1b12dd2e0a5f91e42f1697f42edbe87ba18c3555ab283fd708572690e381fd0e52671773a6c53a53b5fdd12596e12615405b0b282f4854f5633622e0f2aa02cb58c687262ae9d6aaab3a86f9fc53f614c363e723e45eb6a983e805ac52a0a4208db6123a2ce4803793945c816d0b9efde1c2da6bb67d25d0e55943cfd390be9b1eafca2b11b8825cb33ca98bc6ca60d42b3615a906c7018944b90529a782535cea91f6fce492be0da9abb64d022c4c2785d6e12fbb6f82a1e31d4db147a4e93016157af68182dccb95a407c476c62730d827ef683c578939c267cffd8fbbfacf1797f33fd5a1fe7800cb20e73bdf7215209ee97473fc75344084fa8bf33364337105befbb47fdd8d6f0a037d0785872598445d54dacf117a5d64a6d883efc82ebf2523bdabe153d95198f364a4c21ceb525fdda660220f8eb8ba3f49343597b045bc4c7db1f53d5ea9c97905146f3d935833be090137d32a827f55d1f760cf71330ba601367ae7afdcdf4542461a628ad40733ce9236e66dad6a43c8c89de7c4b345822213d4a2a309d01daf32bcad9266fa080dff829466b243ed7e630956a957f77b81781293cac5d925f46d3facf991fbfbfe22b3f23d7004373e4b7566a4ab803abf176efb2315b0d049fc4e474d73ab8135095436b96c562a8b407c2c97e80282e2fcaa56e03205fa3c3872dec4163a33df096e04368d96c2e301ea4e7c0a353af908f9c10257e7af9cdd9eaa0371757b625e515e2d8417441da38f46370f1368c04d012d14132a428ad9179a287c6d0beffe0bdfc72d48f43c12bdeb578aff96106eae095e861badfe4066e444243fb1b402c1c04d2363a342317b25b3559317d0da93262677c7b98981c2439537e17d92eeed578d75850eb3d0f9dd6edf2511da3aa96986b615392181610c3fae921acf9c60f33c9a558a1dc12282072e0b43ae8f4b0b60f2aab19fc6ca3ad95b72e42ff3f8f78c41f384f7fd268d94d8b249a5105d81df18ec48461454feef677c0c5a0907e33a81f0aa43d39aefeae241a55e75499fc4b140c14d3673fe86d2e6f62d28f2aa214664e556bc885b02528394faa6eafb78a39d74e080f993b8c928825c06aef73ab497cbc65352543df1b029e59029d55bfe71b5aaea6dd5889bcc047aace19c93bd00b0c4f8d4f1b27a5e22085016f8209e514ba301d6e2ae6f1886733a5819b42964cd001526180c57fd66b353fc3b25a2408ddaa9026509ed5e05d0494c53e5e471bffd5cce57323f2f02be3b0f656cf480b16de2295e265873d319c3bb61b84792b470f0b52359b3b01dc0e76645a209e9c1bd4a0980c0ac495a07778c813adbddd48a7d85a262e7fcaadc0414eb4442ad91ec9815b8e45a8a05b0a0eb05469965293e893993101fb170a3e2d167ef4cfdea165e7e463e21bd42581228c741cfb0cbe45055da8a4e4c12275ae2e07c5c92699216f6a71f9e0027261e1586b6dcbe58bad649f561b1b0675011b5bed93321110150e18d006a0df0e1b57be7d5fe5d9e6d20d53ece7aad8c0ac17e2c66ea585d2e66c184cf86483dcd3cd3e04ab4fec2664782ee7391b99ed9531b7dc5e9e0c635ff4344bb871badd54459f100401aa52c15b19c28395b3dad128e6f34e6b2aa26b263fb371fd13c06551ff69a4873515ab0c96b60034f1d84f49ce48fd05050c1b657be4cc9bdc344edb1dba79b254edbe5147e440529bc48772781a24c125b91ab5401f92929f5f4a7ada06e5402ea03cd0ad6f8390ef6d472f7d9dd6740fbe462c8d213458bb76a739a840599c611b3757ffa40d21ba51dec673e252a45dd8cbd4cdb2854bb7e61b8607d3483715bbeb7bbfba95285025f13c9684e34474ca326dfa16bd3382b7b875d33e4f9f0db0d005deac719364df7392e7e363948d0beee60f3fdfda73c30a08bd52cd3b033591aa5062c051735a484fe5ec9a9e357d45b9cb8e54fc744901be23a4624089ee738795e7cb683625186421e593f1b1dc946e127c484da1001995a30ed6203c41c82ad4771904f629f64c6bf684c88d68c6dbfa0327327c62042e213ea4567b826986a0f0efac717954d727167481edab5d320cbb784cad678ed10880560545ce2c6cfb0fb71c857cca22c2b0099646c082c24373816d4e5e38f1dc3982c09eb4a3e6cde7bd04b8e6606db9aef74b534fc2f397e0e24c54da87748653f211ce0bac21af64a6b3111cced0d6973d9e1ccefe522663596845ce98fce3d8dac1d4f3e9145850cc20972019232f01171ec0814622c04f3fd03365935b00732d7dd315b0580129489e47850fb18fae8b28505921b269aa79b711ab5c43b6c5984232e8f5fc70953d32fb17270efaebe1501da8865449d1a6150a93239d6e44269c9df687ea515b04da76ef25398bb77a59dc459d761e528a1514c7bae965a4ecd937b4d7ccbbcbd988672e7eccb0351f4da02b5f955b69dc737fe495976d9dd922fbc26f833ff5f8fe4b8e72807deee7f90f5dfa36efff6319b39c5d87ba5f8e66b370a159154783553935a281c8206b6c28d7b54044ef045e6b08ac495fe67e8ded663ac27946db1cf65a5439780f505443cc49ed5cc45e09486449dd4534ea52cba9b0e50c82b66ebd67e0bc2c4a299017144fd95751ae02e738f5568a97b3fdc7183b3f808e15baf646a1b80408b39b8998b7aab0a6ffea9121dfab1585676e65cc9b4d731e55fd8d49f64780204267ece37ee115f9827c9cb8f6070969667da3f8f05ab6f20868c9bfe42857f26052288996ea077974aca0c71e3b64eb9ee4aa3e3f18acbf9adbba7bec4d7afff8ec43dfc93f207bb55a66bc10eeac1de1af67f5241e2d11ffe5d83bb93b2179eea380eb9ce8a4d9f78566a1a3f12bbea36ef2500647d854e92eaab635f72834bdd5469e47329915c7bbc79c0b08c095ab182437c2e5410b6793ce89643a2bbdcf8c44790cd46d4ed2267304fbaba81656a83a27b219906037f9252c81fd3ea6b789bc401093f134a0b45e02bbc92b86a92ffb049f755591e3461157814ab074166280fedec64db89b5cbc05c2999aacfc5c123c660858409abef0f23ac441fa7c6f7bc60d57e923a18a55025be42cb89a094bb03596aa6b3b07c4c36485bcc37bb082180c0af16ae2a29818bfb8691a0dd1876f5b56e0e4e486923d5501db5c49b404a79cc0762aa4fe56d788dc5627beaa52166203e4689fc1e423d630f086023293394d20b09e51ebdb751490b3ae649670a53355760d3349d14f78d8113b556e94f359bcd4f1409bab72931f9eac726d5f3f89355c78be26aebaedb42ad58a85bea35ba729a0ddfb163af1d0348c09a2d765870f425e945c8ce876258d97a30e743edb484aac9745d245b6704160225587093b79bad0f69fa93762079cc881db2b7b7c1922b9ccd55b238148cb44a14e62c0a74ef4c4e95114bd7521d311c9c99422fa3c5502b62c334c077097c55205a547692cb7d99b0dace0334f34bf6d3da1f5bbc9a2bde84a4be5f73e9aa2f32a10340d54703b0ff931ed1a8752edbf74d6fc0a2e0eb29fcdc1208734ddd53da1a0368ed83d81959606254947d83bcb616abdddb1c2e30211bfb66d63a06b09e95d34f6d1d851c8bcaef9699242ab92774e8b22414146c667b27808f38c475f839625a6611c03c1953aaa19b6016a679ad0b47c1c91e9394d18b537e5aec41332fd59364be42d7e11d9c1798d223938a07a35c23823944b8c16e57e2df4a678675c71af5ae465c249606a3268adaa944f06996774d52483fc5f01a9dc3d669d11598c6fabe0b2319d50889ae8b2cb1f524a60735777c056270d2a427b7839f23092c6fc05af5d042457643720471b5d4506a877282e827330bfd87acbdb212bc341e8a859cbdf7959cfa8e364817502ca790e9f4301d7047a2d8a46292105d2f6fc5925543ae9115d669d5896af2638a22c01813b007a0d0ec353d98b86828e194d1aa866d7f4859db06a2bc639cc2820057ad03982a2f36f320313ff4c4a09f2db086abede008540c3f7ca403f590f86192ccd20815d6209d9943817b17164cf5c4e87b9af99beae2c195750c5421d65f0bd4a1c99ba6d1a6701e8ac1005606104c146f74e74d4133b60a1f47477fee7dd47ff0edc45e34329a70b01eb3c2861878453ebeba23dc90f04d0e948ae6f9ad3b0d3056af50ac6ceb13540f1660340d0f24d856fc3b0c63b6250b94191b27f98e3ce67abff3b2e744d927bd9fb9e0cd90645d7fb7953bc311d935a0726945412ed5259a0677d0d30d52f27a965668b005536b7729ea4cf26339b08979697f7f6be09579a7a359408dc156bd38183d23deec5224d0c9d930758410285f2f3f548cf3211599a84daf17528ff5639e1fbb054a0df4230dcda9229defa9fe64713dd04ddcc71c4d01609abe326eac82a1460e5c48548f878179de859f2d2bc4a0446ca1b290767b2ec40969b53fdf984bb8de4a1ab06197645076df0516b94fa0728eb254f2d9972d79ac762c7236bc9bd3697d2c89fb2c6a5863c01d08598e75830a9ee96327f7c152a466bcee1302e44fff769518f85d3c13f7e385b7791f3ad9c483c36f9e6aeeb5109c2aeda8a2fadc84c575a879c6f498e05b0a4b49c4aa4642e85041f4766714b03fcb0ded49d794ba0994cc6bcee90228b9a9c601cdc8fd1a8ebc66ea6eb3e04d3baad1b264f0675e8034f68c1d6a4c356a6d7496097363fcc0aa6e9afad34b728fa246fb5d6c0365898202c5f447331a1f57bc755b778d106a68e0a255f472c986dd685ebd906aed0943fdca4201a3e42dfcaa96a58aefbad0c3a37f0c764fa35993ad2a00bff8a8c02f92d9c11cfe2123eeec74ac43b7ff078628586885f333b63d5202a4d257a1c2682f6e7cc5e844b1cc8ca8d7ff08422929aee5f3a3fc2b1e2477fc37c447a17f6dfa311878b544f8de206f6496f47cb14b3df19d1c7c509362c80fb07634b1408dcbbda6af46ffe4369bde2fc68eaf39a771661004b9d7f201fd76241fe2a9dde32e228314acc9ba85b238f6bbdcbf59190515d5551c5c60d533ac356888c903a9201b2a676b7f527fe30866b218cc94dcb24c85077396417f4df62963599c490b0f91075c8ef217cb4c4d6c36c1a117dfb5a881624db4b2cba64b92c5ec78d11c86b20288c8be4fe9bd617a7c3dc1f75f8ac6de75bea1d025f37b1c62c68b65f523db6e596b344b75567f5fb47c482d49a41594895beff5d58ed35bf6a124eed3212137a3af7bbfeb3f223c3d66a8c984ed068b5cdc8029bc315de8c5dce978b6c2cfdf94fd284c898cbcd5f0a64f962cef77f5f891728cdc8a6ae676e562698474317b05b893e95104e121ecdf759d869c6d7780a7869864e6e0f51030dd83431170c3d2589000d862419b135ac70b5d2fe5b1528e37d2a64c85340c95900485c00745a3532919d3fd51768adf4cde708b2623addc6b0f5cc6de1ac5a93ba63640a5cd1c7f84570a0bb6bc9f5d3baaf4b313b54802da5dce731f6aea1e1d8c903a06e0d3c01b17a68251357a4ca69a1b6fe9ac8a9062e143fc0a6319d0f1fb187336f5be3399a5af8ba8296e2b7e9f5337653334771c0d334d4fd679f6898b59e2d32d731cb9e32f4f18a17c27b500fbec0132820451529151df9bab1c698c9f3380838d1f8248cd032bcf255cea544a66f0e46a55d0f1638516280fbff22890fbfb1363ba3147b5acc5aa13e10a9f69ba0e95edc7d7ad7b031e18d8cb4a633b5af38d816d22e0ebdc809a2f9c62a1d344fcb16a086442098fe5680437bd1c0697f9187dbe425e9b13a34ffb78983ede05b038cc89a4d2b5a33c8de251fe0bca13e6e71656db56f8f8858304028816a825a3c93a2b00b0efb005b4be90b5cdef22f89ed4815621bd44d6fc28725349b7dcc1cbd04e90eb2017dbfacbf4929f53b866c06e5f2b7c249f741af765d82bf36f9cbe73494a0b7425b3205e56efcd3e0d43aab2f8b382fcb741a3c5c6ef7a8ee55b48063f0a2e06ac9c4b3aa5f54a89d6826c403d68452f5c32f3ee160d7ac751b2936ed2adc032f06cb6abbcc140bef780f3d6cc7bc0fd12df8adc7deea5a4cc18a3b4acd80983c84cbc4e0cca0d87e30665b7fbbce061dbb479c822c26bd1687c54a4951146acdf7a86e0d001c6da5ffa55dbf77e4b1ce5f50b810c62c10fa008df83b680afed6512ac9e04c077e058983bd5cec7ed6214dff1a6b6a50d94d1375d9c625622643f8ad80d2d9c0b43016c3d9f10aec7947ca72da7cd9b8f1db6c011a106484a4a4b358a2f52c0354bf49199a447428c77773ee8bbea3c3658430d0cdf2c0575b29521ea453bcd291acab2353a6f45b4058c3c781930f5c09ace63ec92a6ccde878541c0513521a7921c90262f9b6594e004fc8c2c0d8922d01e5677eecbeb2da8f67df69c3281a0437aca672972fc5b2e0542cdb4a8c2a6e7b180f816976b4a1eae6d1ec9a1a634af637fa41aaf5cf90fcaf2bcb3b066f38b6db974bf264a9a119e81fe1e2fe6b7ad2c44f9f6e7597129d7be5af06c0572f0ed31b58dc3726b465db1b7527db1ae277a350eb6e98bbd88fbb9b36de1bc41d1d7259e45130097cdf41a02c9b5ac4ca50ae7165428c634affc878b6478fbc6598d7c0f41d1d8de4c27a4a9b9452433fe7853c2212c17ababfc9aee8e6cfc67cb1f527bd4481880c0a9fa9d2b383ac2bf97e4c32dc46f8579aa66b201cf23997cc3962250d5b38953dc4b7940216349d4cd7add9dc3c5ef40752c72328236b4c13baf85b9bb9e5151d0b4e0cbc2fe628b2e8aa25319712af0e7977a881b2762a5c172346312dcfbe22d8e50945c55b287ed8f108e17c7d0cd5757be33d6de5a558698027fdb3339c05bac6ee972351ed5d8f47b3ea0605968bcbe1a7bac2f0f6f9b6bfff8536d142dd612d26847aa685d3c7192d025d12d4360c04f0e4e8e16fe1f4547807cb5a875584c158c58fc4b7183000a8a324350d519ce28345ab44e2f2b96867f67b3704b7de3f423422ba64af0773f897b97426f5c4a16dab115ed8a06d391b6e7d3879fdc4ff58bcf28f6ae51dcd418b4f0cfff2395bbe98d37b49e400f2b86181ec76cdb831864881dcc20b351d2a5523292dd9bc014d95459cae56a56375c296efd358fe160aa3ce214aa1cdd24636f632e1310ed16a06f7e10f3b72a762a651769ea98ec56685e2ed25ac309ee0a19e61136d3bcaef755c467c659be89f6d10048c35ab489653bc2d139f5489bc013cc01cbcd486029bd3de526969570484b9149f846039a39d1c5ca732ce028d5a04b844eea3aa85ea12a21bc0876ba821af58ea0a07df7d9af13987ff5e2fb605eb1d5a1f770dc239799f05b5cb5750e928dcf43b016d009a542b619c5e3d5fd0438c8d40118cc917b0511604a1745339fde67388447f77c8aad2b8f1f6e5a6afb72f6f0e43d5142d738648dd631a4cfb811f2bd8a9f86d5fc99c1106375680708522ea218967185c4e34db403631d9574d38fae523bce357da5908499ec58f7bd482d203dab5c38519478e3f084c2e7d417aa771e21996560d035b1008f9a97132113a052fd9f84a674f6436dcd1f5d361d6ab227fc5db68c1c034925c5906d327c01b24a72164fda96fca69ea4159140137476d74bc4557623241a797d2a76edc9a2c48b3498defe29fbf72300ba32aa8c4d82b007500260c22ce57c5097a6974e1f3760905278c7ac2db75ef2b35769c2c9839d7dc82af9a1bfd7d33cf11aeaf21cbd2a9eff628a7bc629d0ddb647c878ef360ab22f2843505d4288f4339e4ef7828afa7c19043a1134d6ea94f54ebf67d8344602e5271c9803dd224cdc8cc0df86f21b98e815be6def98af16e1568b17c5184ebcbd5e6d8bb190e3bcba8d04957a3a1bf863fd4daf2f7371fe3738ac083c0881e994a0f86a0671e006cb198185a83d7fb0a9f4aa40998f35fc297cc7f95146bf55704b55e7299a44084413876baf2f340a7c6218a2a4ff986bdf3ef4cb41236eb8471005c7af68ff982361603575da1f2f301e20d7c7daef72afb382600acc952550493dfa6e92da1e551427ea79f7383c7a4e1d588adea57c870fcfebf2a80d7b1ee8f39f816c1cc33967c66407eaf9cd425776183fbf733b00b3454ca6ae1ef5fa85439006c5e1049f4ac31e885f30317627c5653b82ae23cf0ba8a9cfa17693042b1e7e7a7df8a36e9bfd1bf73e21ce5ff27d7e144dc6973fa1880f098691099441b36322880b7fbc7558310a21bb848f6b6e4217dd2a16ed64ba26b629d6e9490e24332225bfb64c0b1087a2677a923616e60bc8e5362af6b746498fef3478d5f6b56d3aafc2021c35d218d6453abbba5060b427faef41024a175e2f0c7552ad3fe0bb554d86c46ec819198372966cf593dc561b1a08293d35bc24c2cadc4be2b0223bd1adfca8f5e6cbe91decf05ee6df68885e90c33b378046727923b6e5d7fdc02c99b8745bffe2e20595d1b70631440ecf4ed7f3d118b4cd62622939942475f2bb7307e82d0db6e4fb78b092db851c4b8cf2b1a045818bb340409ea17c69ca893d571a8f3b90e41a5013e9c332598650a4ed742be32297300da88358ac88a7554778a8fe398a6a3ccb986bdb17f5af2552a9b95f3aee2492c1e19dd9518423a2bbceef8d2b487a14e3d16450767f426478d9f806f37c153deeac056fdb449f7c7718bcb3958104b183f7c098b317ca547f0bcc65be77123c5ce2b330fafbefbee3eac10185af828e33468381ff859b6c9eda304619817f29e71c0e73b7d8ea33e5c83d5a6a52f752ac4fecf239a1b7651066487d5b37592066c1f0d7dfff21b678feb270ca30680bfa60f0df596777dcffa344451593fc29f164c0059b98de58c662b9d6b3a564a65a4d16d1a1b1ef82ffbcdf632fe96e9518096c894fc65f6007f6ca27769c826746dca16ec5b3b0b172b571cf216a966f95f027a570a59b214ebfd30bbaf25197eeb77f6293cb1017d55cf6435a5a7f73d45d1ea85855d6a9add81ecd4b9d8dad65ca7d3bdaf594524a54a2d071fd20e693357c36d9c8ca2b032f2eee9767da7e4a14452e88b969c69d2ee848f8b2583d671ae4d5c0dd03eddd0c887e0037e62b06f265c1df2a3e696a2af8cb59bea9926d37fe3477daec024e6e2ed34dbc91d33aeb95b293b0834c9155dbefe59a0800553c41498f588eed12ab8ae9bfba6bdafe79bb6e3394f034c393d13d3e3d02bc2bb2086fc33a45aa414540785d9e0c81b684f30b76a511fcfac4a359a306955142f01b120a6bcf523fe51a6929ab1850155f4dee5c7830731ad82734c0426a01cdf8428b698a603ff29848d77cf52992e8188633fd1f8d2be7d0dfaaf7f283e2522c49fc8a3428eda0d07513c5feb80e580037f976de854ff1da90a5c599d4a15d4bd3336374ab0fcef597e056a67c600b43d3fe63614c26ca03ca71f38deae41b2969e045ace0758462f4b2bce70ba8572941c0d212b62be5ff6d482eee87e7db0ab01a234d456850fe97b91ffe04a4e96221e3fe11715dd5861264a254f5d42c5b0a684191b06d20af178e400868b63c3b2d043143e242c93f2396e8e37a4bcf1554127bca49d491513ddebb2e33649b2f8ba1279d82873f8b0fefd63177af555fb2c36f9e890d189527b391268d605624330a936887af1f79a59026fc2169cfc8395cbcf13b56e8757f6e0525cb7cfe8a052cbf3fec3015bddc9be5f9d3e60d04e071943be8085828ad222d91b67411db1c7c351adf571853756a93aafbaebb5488c78b7958cd0083443f8a264c23d257fb7f0dc75f7cb8ab01cc6aee03fb62908591c3e372fe6c5c53d270c0fdccc9daea8395321420be6ed18e1661fba92dc7ec88fe86103a8c87c2df875644510ffff2b0bf2e1efe001951cfa2ef6d613bccfd19ed5f41ca35ff4867b9f713e369d7a891551fc9e69ceac73674c66facb3da1d44e0723c3bf8ae63a1e2e8682100e8260af1975fa6ffd7f85a65b4657e9b737220eaa8247a6b9915f912a843ebf15c5e94b0afc0ce255b95eb676ca98cadb6441cedfcc71bb04815fd59a964414582ca9d99a0260c28b019335eee448945cde3804abcc618dbfc0f4bd923ea54c80261ea1159cedaf25d658b0277b11822e79ce7fb62eaf9e0d6e9e153e5c0b177703a424848b49350a156fb1e53a1492ec75f25a8a492081457575868836083524cfb737835d21fd5091dc7c682eb5bee4916e1fea7b5488363c5c783d13f7257d2f6b9830ccf438d76d14de64a5fb7eaf1894ceca6d97b1af3dea1b3072a4d1881c01aeca2c93840e3ab133935ce2936f14038df653088bae8a52d188bf32d1a0afb758ea3fb789382ce1379f6ef1d1f746ac7fbe25c3eb602e745ba439036e0b635d22bc1655e332a4eb2f32b83832616fa9e64f21e84f1ec0fed34b8825357dbc3ec1c349d29069681635422ee40764dc724791ba6b14b1a14c8424c5dda2f52cef7844f2ee5ab618a6000c21c851341c0b5952b4f655af10ea80458c70f2df0a8b4bc0d3af6aa5d751a8b4a3ad5fb96dc912c077dd2662f656901a88601e6be8d6d0de5f5fb663742f879474cd15ed8f2827011e80c268aa7d97a1364fa3a268d0f10bddd9468371412d05b0d6b5c549e9e815558e9265dbd88a04e356e1617e92217d37ad83d64e1a14dae35c65aef1ea4d52660dbe1fce6f856810603fdcbd7305cb8c2b4aaa5e2408d02de9e759284331ef01bb2118c5e2244aede506571a9bc780637d154579544e0b47251f897430dea7e97e7ea9248e99ebc81c4b78d0e322bdc876be3fdceb278f3c78e48522b367b31113bb71715b9ac5bd983722048eb9a86c5a54ebcec60b9865fc6df11d098e57f4bce952dd34ae57cb9c973ec8ccd71a96a830d7db5b1a2ca756c1f15557a827f3f175e44be1dd254abed2421b2697db50c43ab82b53cbe788aa1f0569603e58e5fda34a8f02cb430e829ec8424285eb6216458dca265567a949aa70a33412b1d472a0298a58f7aa4803ea84dc55b3c251172dbc7ee868d915c00af85e3c93f8753886189a806a87f856508df6503d8e6e3daa3d003adfad34af835293e09e944bf98e864e14d2fc4480043bc9c757db63f606023c10d35dfdcf33479a43a9bff42ff65886974e6cc47fcd5a0c6b5c263659b84efd33ed9e28bd630da9dd7505b26a0fc2b95bfbe365c226f1b6edf23987b17b5c7fe0c0eacd6292d1ce92e2340c3484ed18d17d3cac057ad33318c5b1887eb0b683596c96f8c0686b9493b1a76612536bf6f4e96c5ee4161626c315ce7ca7ca608149b060080379d57fc3393512c3510d0c0c0aafc9518a66b4bcdddc00d4952d393f2007f1e921f2d545a8ac843b681283cff7d7273067633d5b280e5aa8163cc37ddc9d8e21e02e3e63f2c8d88d63329e901bc7151933e368b3a2836a268041a943ca91a9ad0ad5ffbd07ff6455cd620450cc57bbb6f05b2f4600c0bc85c8683476d3cf2281b05a03b7863f9ccda5e829d5bf20d5c15b1e7008de139c80d0fa2a63c010fbccff94672a8d1a68613e9b5bd07a5ef27e11ba70bb697d3bc55e31c08dc873a78ccd745f2fcf42917342ddd5930d4eb36db39f62644188ce89a665b1c23511223d144f8644f876b67b3570aac160c23f3d1d99a7301b1d894caa9b7ce50568bc9bfd36271a2717089e76b2a0d593788623fc227ed9103bc1691806a4fb5ae21669e4d91d24ab3e8496243180a0319bf2b7839c3cc3872ac5857f192eb299906a6e7a4b2777059a1a0145af2b49aab49a898ab10924920c89d887d5f791bd24931edcde1294f3ed26558ba79c6a3331d09bb69b4a30eea6043bf163245edae8a0748aa61c15a6f4daf5cb21dc6a244c34c4ea0bc47632b42fa9ee6e27d01162d8c53f2e94ec500b3076ef838f7bec73dc956b84ea48698f3faa4951849c0584f18f8accf85c3af4c4093f4b94ea854b5e331f9f863e188247fd2bd99e215391cee90309aefa6c8ec3708843261d2ac56c53f81baf411ac2316ca17fab731977e5dd004f8add9f32dbe2c6f48acbf8d7b2ffa17a94b38907c1b5d223968d2afc8bb405f21d3dccc5d115d757b3f30d89812469efca626164e6b55a5fa7c4603ebf46c0165691baa4f73f93e80831b9d0ea700b252dd7447631726795adb3945f85ce5f9d1badb08a2752214e5b5d0939fbe123af9b9b46314d84f09ce2f634f3e64d9b619b16d83c64000453f17c088c1337140194a454e4475adb556233b70713f8f2447ea8c2f980fd9eb219f57728f1555d74175b16367588ce317208a0034d4b4f368f178602f41b74ae0d1f487d07316494bf0b8b73a8855057e1e3a93cea376d9c20e344d108403065c3a5284bcfebc762290c71ebcd16ffa9fe2d5bcd994c0cc7c954702dc6289c55621c79589e4154fc6983832cc290ab3d7086b56484d3de8d32c1b9115eba09a8eb3716651326c06afe31a286f2c32fa76cfeb9315ae41cc338fe6f79d119cdd99cfeaac94c307167dfdbc2da59a42420d05a07b59038e9e741f9488208eb3d67424b049d3efc3fdf9943962accc2c8b3179fafbf7ed917bc483521901572c6a436b3674cb3750031d53c4f2e6729250d1b84a5f7379cf6bbdaa89e1a2593aa3e09547c8731911c5931e832d5c5ac02f1a0326128c73c4870568b82a81e9a457ec9bdb73fe62c32bfbd825f31700752f91abfc756900fa39ebef727f969696670752164faaded51d88d285aae3769c02fd9a6df363092901e5ca6e056082bb8c7c2e49b13a7da2f53be12f4995336f3c917a78a803f1d3c76e2f22a7249906cebf15553ffbc63cf0ae6dd411244b435718430067e1740557e3657d39f75a699c3a8b71d036768fb8d650253d886696adf77748ef9fb4b578bedd00aca241c8de1343c0fbd928053f9ea9c4a513396da35ce7747034e6b4d9d6de66422e4c93770902f033af54510edcd206aa0dec0568f0022107c7d1170cc1524efddbb6ee8724222b6cfc2335b27f19b764054724d3e697330122abaf9bc47c129f12a023202fe4516fb40ee82307a647aa265f0b2a98d39606ed549b611f4d49b83fa854e473a461ddee0eebea5df0b1a7feb02e1a1117292a6fdff97186d86be1ae4acd606834eccd1fc3fb17d00edc7f7eed947a395e9d5d4567cac7b18d1d624b2905353b33fa29d4391f126bb58880166b3f9f7f3d142aa944bbecfe93c4e4abe2289ab05c3cefb34a7a2f69a0fd9c20b5a0042ffe645082123b6113676bea93d17b2cc616a4ecf977f10aab15f95e55c8625bf593173a75f698f69c5d6838455656dd60734c947d31f424118dc8d08c3d5b3ccaed3237e06321246beb8d714664598cb9d392db3cdcc2fb391fed75d201ecb66f2244c12c24ba18a1ae9caa4b23f3e46bee0c110fab23012b64ff41e9979fa8bb7d562b229710c0789832998b7fcac2cd21cb0676e3aa187ff2982b8d471f63b8c361addc04240e034b681050a73434b3cd4d37ab55c46a4d3db2b277f9f1f0d76457e588d5741a5f4c1f3cac73feda97e0eae91f669d5f08938cb7d737d1389bfaf0b2b3a145519552d29d569305b1a514eba461a548aca05fc6a0de6447670fb66f2cf37681b2750a62c41c18d1420f42cafba96eccfa801315dc619708ec9ba1252bfe6ed776f52b4f0341b3a90ab6fcbe2c30a40984a4b87905dac9d539848c4c7d36a87bbaa663685d5c28392eeae90e6a99e71db8deacf7a51eabeb4538b5d670591599d974c2aedf650809dcf00b91d8154eecf71ba35559a1c9ec2a990c1c86484e5a3f764b55627725ae9a207b5002ddda10edc58f8d0d79c317ede0ec2f6785e6aab0fd64c192518346c887682b34d09b3302dabee3d61ad8e718abf1e42336f6f494950e70ca5a1319c8264c072903d7fbbbbb7a3353470dc6c800ec9c8b62ba7397ecfa3f7a0c54c7111a7ea0790791848a088e67b5b2d41292bacf3956af77e9467840bbef33761c99d44026189f73e1abe4879518b26826e91d0e04c0e1e36c877ba899d6096d92ffa96032f9d2553480b916f1c6c7c106181dcf7a12217fbb66760805085686ac2e45c2fe59102007e72a703320859a966d81783eb83d33e7bdf3c9fa9be5fb78aef571d6688982d8164bb265765ebcf2eed2a0efd7fd105f9a20a672439f3092d4843abb6133abfa940e2cfba056a33d0c0ead3e5474d1688c5703b71e2a25e6529ed9360d69bfef8bd86c082227d5b3662278e3c3f8d9e29c5928cc10238e25a1488d55d5e5c19a83f6e4c0460ddc57546e1d67b18d7857b36caca004cf06fefa47027ecda66bb3bdfa703174dbe6bc07ed3e5ef90a2b6956c3175a3494e3916ab8243fdf7010673636418704802bc11c48854a378770960c194b64b3aa81f038556232bb22a8bd041a407a60faaf47c07f7b05b7e7e820d17489c4eaa65b5942a96cd5d0cc2b001d8514a3911c5ea7b4082e7cd716fd0530de8e3d4f8b7bdae6a1bf337942df77aa199e9924e28a50940fc32e46ae4a5b679f40ea63e689c154837c9a8ed5bbfc3216fe9a083b6566ef8c2a808d176c526fdaaf08494b4a1298fead4ae0f615afb4a646b5d5033c9c609066445b3484a5ef2fb7e823e7a1c796b96c36cd3e9ee3ee93b4dc3215233c76b7420ef56aeb4c7d7546a996c1c835051f1742a651db2752ce5a4497bd5ec4eaae1a1de5141081b65ffae29e7a9f87b452cbe4b66bb46ace4e1fc40f271790f414276f4e700617d25307ab050cdc9fd99260c646292f14cea41193a15d041180eccce99a4fcbcbcea6544fef34cbacf0ce1160018a264d4e0b437020738839162235d98ee28efead7bdf0a0a7ff4ba676a81b918f38cafefb1cb79940f0f65e83191af70e0810d80036b86f61f758f670e5b457c3f84d19efd4be4ac534ba2074d9f781cde55dc246c8ce0dc8322099e5499d4f8707755ea93dfa99edf0eaadcd0fe80ce5dd5130e7c39456ac6dd8865a3d5d5e89e7ffe35b98b8d4149aac2b850376395fe9140a917932604434668b4872a815d0dd669431e8f0dcbc36405db6ef3f30367afe4ef0919283ac41a05e95bf289847ae902f3fcce7276da2618976daf8ddc0ea031640db284e667d388ab859fe330eb203f4d77f6bbcc073ba235b90c1265e91532cdd8268c1feb540c58c4630ad96828f9844c7e911c8c350767cac190b4910f10f1b63bd7e65dd6013bed3fee0f7601c0fbc887669ca670bc2d2544844f078747aa1eb42b4698b1c9702988a348993a941e3b57383b4de10cf9b8f0b976cb5bb4272bc3f2be93074ec60817b637bf1bf8752393807c0f9b5e0c5f4b0d6073c2d073b7122890da1de2fb054d36f17644e790c28790999bb51b67141d5deb7da9886894d5780de7bd35c60cd1f294b703d41c90a5e5a5f999d8ec86c77a73b544e29a15b661733d65c0df60f0456413aeff97a60b0d8616b8034234dc339dc7f7b74174224c4b82f2844e5f5858f8f49e7e3754d503ddc9ccca645dd22e9cad1ac65bfd2c37747909ed8796c591eaa4b2da5cf18c93deba251210a7d4a7f236ca5b40edc51dc10e0e5d0ab3bbded5e03a608387890697c2610e3fcc8abf71243cc8c0186b7adeccded9e6e23186e3b462f6a5556bc345cd19dfaf834048cf4765b21a0925ea08db26563a5893a9cb751085bc129afd77e0ba42e4b0e99332dce416ea67eb8ed79e695f3586a817790457f43006676a3943a12f8147f2a7097fa32bbfabd563b468d84dcd70951a99de5ca6f68e91745da0715417ac14108bc77803b7243ea21bb96387780188f305642a0bfcf5702bf6310f65d429e836a8a1fe4c0a104a4cf282998d53d010d56a5e56b8d0f18e1a306b202a84b231678eace3c012e8e8286efdaac644783bf8a715f985dbdd82c89a7464d009159eadfe34cdf4d950e9e13a751e39912f9aeeeb985f3f974526e07d537dde388a35a0274a54dc8a8a4fe019e6ce9b03ad02618060532f0027618409d8dfafc4c28aef55def121dead82447f687007d5481f52d3c6dc30fb1a1d2831f6b88a6d1c68b87d0d20945c42dbdc59406f36e32166e0ed582529fc9faae17704d7d642bd635b0e0e3449a0a13d389c2116ddbb8ea2ce5a779a78385675ba61e960e653b798d799f6dd78e70d782d42748a0260dac6c4fc1ec43e92dfe46a7f06efdd07eb80563f4e0c31da5f1c7a5ae164f68435fbb1e88e02fb08e0fc9e2c52637230f5e395a3f7a770f2bb63d48c5e33c4dd737317d1ab8b3edef24dc48ab669e8abeb142d10cc2a91cc586f9b97c1b767f57ff2739dfcc3b87ae357f52f89c6f4435f06b8087fc480ca858a12e67ca55df43f7ef03ce2a596255db7891776eb0a100178d52d18ecd3688ceab40ba1f2e7c771b81f1814ffb3678b66436e6396f049d7a65a5c6ed0db2a06e12a3e873ace510cfd7c1c8f9f2d10d203b7e8668e70f4287dadbb7e78e0f8aebea4cebf091484370e5001916f310fb87ecbaa7321b4ac41d935fb4cf6069295d208d3ed4b6276437cefee4532412fde72f2ec67febea10520d60cb082a269202585a4bd259440f47a6584ed5c95bf9ea6a14a8e576c9e8a14d3077c79aac159dbac60901733f5d79cd04759a6d9afc33440f8a65cdf0de579236226ada724048267c9394aa52bc4fedc9411cccb043420779ef5a3a31b36f9a5097637c19490e0eca5bd5d7117b91ba438ca65fda42af58749d4a8fd3f892fea6997314f3d831b30f9f71f2e04b390ba5910d57ec909b05c913259d6f90ad70faa2c76d52a4ae183ed7abc4b13a31fda58d988833c438102766b8449f4907fb1758703ec46a3e4ecc4334f8880d9126cdc814eccff0d8b5a3d0c90a8a93e640994cbbe2015e6fc1c9fe819e760ead3bf75966e6757b1871b53ed3d45e1ccee3d9e4b6400ee88a9b247a5de1fcef5ad95a2031d5fefe0b6708203546ffac53edaab64cf14360aef240dfd2ae2b768224b9fd910d04b0b5c0cffc038e431fcc5012409602ed55edf3d5102ccace9bd543268dc9be708e31c8e276639c5245becce07c6b0d1a6c287e1293772e8901eb854954e5ecd3d2ed122c382a88c75c3e63a303ba5f68d69556aac36909ef8a2e10d27c1280bac0a2905b602f7501dbaaf926ffb8b33e53cb296650f4260820fbc040e6abb25003afe202d4528f1b64e8ed465b3860795ed051428fd72e165e3e01d850e34b85e8037fb3511d3b45481345d9cb4d2bbeef4fa35b9291168d0f1499964be1ee4dae82bcb0ca339e0f2930951a0059926346b88aebcca90dd5f3f58d21c83f1b3d93c913837daaf619f04db1a1770fd98acab1863eb06f659d6897fd669168ddfddcaad08936f98f1ee32502ec7f3147dd59bca16b046d8600f66ece89670883371aa2377e1ddb588c0d8de5e58d7b3782f485e2a5c91b45c0e9d51514dfea37387c600b3b467712bc40c742d7fe5f89de851b5346d6c3ee7fff21e67ae4578e1e3ba91aed311224e2bce6fa4125a0190ec3c2e611e28a6d6f6b192e82f10fa8a7d0850dfcb0b107dc60b5387c095eae9147f92722115955df19bf8ec7114893ff5ac089c3c64eb4c59c2319ff4d4d0c2fbb7e9effcb2109896f64964360a271f5665c7a9795b80e7e06f54f54d01d141a9710848cc5ed3c328acf85909fd2e9254fd3a9a0185400065410180ddbe07ea3cfbb515c6a705611ba47b7c85efcdd4d6f5596ab383a1e13f86e9ac36c2b6d05e18f70d60b0e56800a388393899e4f332b668583888b9b500b6b5fe342bc3913a81b9657f5f182a9a3a3acb2ffb314944be64a9fabacf794597464642b17b1b529edbbc927e613fd8be838f12c1b15010030295025d5f8c92397d277a47f81452b4a202a0243f841c58e24b1200ad5fdd441fb26363295c101f204a10b4504238c4013bc7914db2c5c2d550d08b9ed74705c91fd8f2c0e93c76002a759d75ffcf9227de721079914c0eebba7ab65f256cdc5a81937db01e6574e69299b3225076c1131ce604167f7069bd7fb9ab714ab93d109d58c61eaba19d0dd940b311b83460e9001d6648b3c11f008682d633f354a67fab6c5bd1fc31a48edf395da3b8e642b478da9ab0607c9fe28ed3bc53504cd34c8d9bc2ad211f13b90f18b4d3959ac4ba489dd3058832b9ed82a0610fc4f33df8a344e91abbaa1770f93971c81a2cdf42bcb72ce98da49327f47052dd8810ece7ebcabe649d74ba5fd27cf6ecb8f9b21bfbd239ccfbaddf4f4f0a605227b4b1d35af73feb78dc28fd7a7ea92c19ad44b1eb36e52c44d3989872fc3b666515936c7555bf16cc50b399a9c1136a0a23904254709590fa8aacd79a3db369f158f52aa074d828c752f9dda6d515311271a77390568dc050c516fa4a6bb0a2027f0f46526dfe56fd776186c244ef214a86fd1b2ac400516c376a19595d0c01fbea90d0d85050b5c654ab9854a52b69ee930ce3c5f9cef011c6ae3e128d7a567cd80297ae20e16f1abfc66e1cf2c5dceba87c9198cef8703445ee7b728536338ee35467407a0d0f8254fc1c2fc8f7295e7b8b58ba416f0d0b1f76c72ab3a43017e00607b2d2a867a48e8e790924e599f1e94e3e91d793e66748207bb1f22043545dafbec189533820a8a280ec2dd4454ab2801b0a0a382d6a4bb748d9ced3028ca15de7dacf0c6db63d21e61b96764d65a9697626d658b1421380e91063f98eb330a79f8e91f98c3434fba3884d4efa0b77ebda7f5bb5ff8bfc2b5a5fca3f23b01c1e65dd477d180ff4125bf7745fe7501355a526773032f020a43d3ee79894cafdc7fb55d4b5085f70766e6b44317ed592c78d4dc9d15e86bb337474a3e3205ac620e27ec50d8fa68a71dd044cd394e2ad920cea68f87d33008bc6d858c7e49808371688028e26732025af38f6a4e3e7f2ff2b7a43cf67015faf44574c6662d5e30796acb08ac9efeef51a56ce408d192511190f0e1143554eca8f5283d233b10236b1ffa426c7a04af3ee2044b7dcc4bcd44dd32f09be6dc1805392f1be14ddef27ce3a45f6778a78cbcafdd153f8b9375acf7c310c2825d8b45f7ea342a90e193521076edf0dc8de3a75c098813a8c47a8b74ad5b81221f9ea339ede0b9bd3e4f9557abdfd144ea38f1afaeed73703441b00ae229d0bc7eb3c122be3204f240326b82d35d339d814cff63b49ad17cd5cfc449616f757ca359cd1a045876b6b62a5fe714b3a3b6270464dea9350a7d395a4a2b1a565dd7374d352757c67f167f6e354ca69fb5f23e2b60bccdce8473be1d37154f2adb4a898c94cbddeb54d3d1a3f53c26c9b21385abb51126fd796b9c7419d5335e81772156736e6b78eab9b9f3fa7e2f59429f2f77268947613d9c8cd432733e4ac284824e4155d8688d780db4703e8b19d08b6c86fce583748ef4742231bcda3327238f941ed22b31650507d02e6288789507490712ae73629af758c8809e664db49f24e2535e1b26ee9f6eefebf2703387de7aec18e36d260a568b1d44b6eef3f73b3de8750e9dd15df939eb62156b34a8f37eda3a89ee919a35237159c972a5328e7817f99da18a741ff7c1fb365d5719cfb65a0c541dd306a8de199fe035dc1a2bfcf3abb783a78c5ae8c3bfb9de8ce78808b82de70e03ed9f31e335db046dc89f849544eae6d45a4dc384bc799b2520da78c13d97e3280694fb545e3369753b97982b898f7db3e101fd2f40c593fae62395b1ecb07ae9b029339a82a86aef27af4cbdd0850b7d743090dee6c0bc9a28db2187e63e6b7858c2af5524f7b62b1048e5dda2955e16f940f7157f98ea846688e2802ac7dd5a88003f54fc5cafb744eac5d9e2604e8e2aec58be1f64a2a2c8c01144010fbfbee31c532397ac4ef13209253329f6b190f3ef45a9bb906a6459f5ddc46c839747484e6820f0f9a12d7f85267242cfa016909b8965c2e2bd9dc28da0fef4da1105dd77df979b41f1c103fae141b7aff131787a1c6e4a2e29c2e767bf13886c46b2d3a71f265c7b047e58d57ab0312b52adf605e1a5c73459095e50ba1cb0aae972025a13ab74d61c1014c2a8c386a28bcbffd943432abbf24d4565ecd3265afa94f43ebf7beec61b594f5e2be3366a5031d24641c2b9f92811afa11f475599b00f9c884202583c6976edd1aea4d8fa58e5e33241f652a169cf945001ed360103ae2f07fdd67aee2146aae575be7f5c805ac61d91d9005a8c63cdb06cca89d6000376f6177b44ea691017f50c180a39500bffb473425e266ea86dd4798b1dd01a85019081af3104d42b0e9f26f42004dde2a8c6acd3293c14a7550fb56334180e42f099fc0b9d2a6888e236f1287ac3659a8059af0641f0c99048b41fcfa764c3109319f5ec8be550ce306cf666f1d68a2807f1a28a72cae765302d0717092c813f68787f6fee47fd7a0cf3748e69b81e95ecc323b94387e1301797be282ee0fb5e8d8cd8b4e27f0ddc94ecd612f74ef05a2b45814ac373a88ba42799611e1934d08152a24b75aa7a4bd5369e5f223bfb3a63e12099b97f67af4d08e3d1aa67491d511050bcdc61d81dd6eadf7bb58aabf0fa4d55e4cc5fb3f2cb96fd279c7531ccdaf6620a6198c42b69147341e624a6d61ffa57021a1ec9f4ba0b281c4cbcf1dd2f0fbe21a826586a2d974dd010aa08064cef37afd823903ca9d748f38313eceb703125d6b94a447a03495a0533426a27c483ff72f0553fcdb82b38e9c482f1e1bdafeb77b1db1b681aaf4bc2db26832e9d5e9fd1aa33aa6777abb47aa319437f702f4bb5173e49fe3d6d1333d4c2a1c8463e373021c67764203bbef69d32b9304eff78f754b6c1a1c470e397a5dc3b770bffda2600708f58fd85e4621b3791fdc1075a8580ef31000bb610ec1572d515b2c2c34bdded15879658534583fb05178d087b4d615c9fa694baf0af2358f44a9c4d64b477fa50575be7c53ca9424bff3f6c0de70994bd06b75c3c5a55d3c5d9f912f7ad59b5a303dfc4f430d38817f49019b27d9ef64aca250ff25e0a3df32584380815a60b10d91e0c5134485f51325f315bc44038831761faabfe0f29accb6809911635ce24bf72fb0bd0e0489f14d3ffadc7c10c2ab6d93c3fa49b63d80213d58e04e93c44b57937868c1d9adc553ef50caecb83548a6f33d12039b9d686833b10b538ab75801697d579b81d162cf0781a7f7b1e6717a830fe82acacf9b626e461ba4753c7e9b99da0a2d817b33612301f985584585450c018464110ed5e88176bf4b83d95d322ba8de9fd2c0e1aaefcaa07c74d20e2ac6c6e38f9dd33f15bb07b21270046dc2fa3328fa69d75193fa9837e2b1d222150bda4cfa87c77a89fdc7b95403aebb4433371753547008505eef3cfbc2b2909e74a2f1d25665b8b7e4dd8981e6666e3d1fc4cacf31e917b234ff41a6089211a9870fe5e2986d7eb6fa2d3325730ab61103b4ff051d4688b4b0847365b740051d8d68fe0f2a5e0235c006b5b7ffce88928ff4e072b07137bb54c8a6482d2ec0ac83cf1361f07bcdac9b9408dd9fb70cce9752347d1f75d8d98df9a922b7206fcc8cdce3abcef6a6477bc1312e94dbf80a53083d78339f4c26a40ed2313404e2f08dec676135d7ba912c044f71101b3829ee660d90b0c6851449caa6a7b3a0e2650a26aa034b097fd6efa280de9a48f7e89ef1d8fccd6cdc1773af1ac77889320a242ff5dc52c724a87f35944e8061b2807da3cee5f8ee4e03dc1e21350c40c437f0c76f7fa2071505f18ae7b5d6d8119020fc22d8c4359c6815eae356ef30e26b51cf779fba788add5b4f93f92f503378e0888feaafbcd9beb1f16569f9377a71c78f1dcaa665ce3f402cb0f2d6f69ad2b6fd2c6facfff2d7bda7e13338b2e5c3dd7ae0cc2c273cbbcf8ecb3b3803e4c87bdc363fdebf179aaf2d186445b9527cbaf79aa1c701882af68c474971d430853452e4a203f765045bc4b22de391fa922db58c4be1d3cf93f5fc87974730fff5446a6344cf18bd2e9bb5c066be0eb67a58520ae7a1462d1d4996693d9ae172576ce0f11c56033beed5c129c192ab2847798237da664441a1e48e5cfe5f897219f5ec45e86256b71f7c2fe4babc8869a8f7d6cfb0c7895b44785d76d94c0e87eee65f18c60f1c6cedffd5bce46ce9f5754f576da2d372231a4213fc695ef1565e31d829a1e1d8de44169a842825c3bd46081cdf8702cae620973c41062850328d116fa65d2adf50cb0a4069e21122b9037f085d14655acf8c20439a6104aaca31b9a30e8a5ecc853b2f46b4ad0ce3041daf0973d27ef2fe71dc763b3db9b6128fec94ffd3a4d3930d8220313af308c887d8dc7733269245d66daa069eebcfa6847d1f347d9e9b4f6a6858cdf14c1c5ebc64ec13f4200a3e82bc5bb71efd33d4d62a8f03cda7652af8cd8b0dafe563944d2097346bf55870207f691733e7a90ba416f58b5d09f3bac03ac1b8c4e4930041b99f3a6b6f4a44874aa726ec300669acbf75bc230517bbe008ba5aeefcf8154a5ccbd00c54e057e8c8c312d077f12e5a0cc92aec70dbbe1be2e91c7f57cdc3d555dd51dbacb46ee2f44f8f919423bd93bea874de4d22b94494320f7e8aa700a407aced52f89d5c3c79f26da81be89cf3fc78b05b7bb5a7d00ca0b3afdaad6a48f8aae1513d5c078f1df7a2c38a9b3e8f1ce73cfa72a28f4ff77ee39af673f6afbcfe0fd1dc155b69bc272cdaca5d1de554ff878efb49794e13505a01bdd3afc8cc386b4a96b4f534c93da439f6a4098f0c1918d2909902e1cd3653e88c5cecfddd697578f7a02520ed8c67b08d417a7a2535d0cc4e2d64dddd1c0ecb31610c4c2cff8cc96e2766f4c618f87e4106f19713725edb0c2e70c726919a46dda719d2a6e70c25afba66bad7ba4962b55ab02aa21aef9dc0280eb270003bd4e184ad4652aef13473370ccf57d6d443df3126a2cf8c11d9cc03a5666ea92ab2890f7380d97cae30a54bfc0aec2cb36021cbc89ebd0cd8ca0f7ce9fa9b4c8a88bc2f5b5242e5c0c59d36d9867228a88ddbcf01699b7c6b5f8797c0698817d07b870dab734511a9b58cd523f78f09d30dbb2ba6d0a529360f3eb95d5ee6da5d13555b8749c4772bff98c8bf7353824cea89fcee4490dae7ef2c2d78b258ce5e4607ee7f7725127a1f8571fa3c4a8e30c0bc35a335b54483e9d16977d474df99f82dde0e2dce8e078bba1f2c4f5e53d46ed16fca8933e12eb50c3aa187ccc9d8eaaff260832bb337937ff249b1e23800c904d0916da2d0d822b3ff5f2b8a438418292fcd572f244cecfe58f873d5750759b6b36ced6d79cd3d5eaadcf0e0c105e40a8f84104efbf72c3c0c7213bbf896bcb4af0adeb509e9ac8afdbab16bfb109716a98b7eccd14dd7afc0d9ca01f67a45ce2954ba124cb618d7f0d1e583b90c47855c8a4798112ea17dbbc8ce0020dd33ba111205e428b80240f0e782f708a9ecbc587397896929ddd28a9179b6dd8801cfd62c0e116527223e63e46c98c0c52ef7cd44e4ce5fc4132d63c59340903ae54bb9f7c71a4730f70de87a01368b7589eb44f635023c3d742f2859d466a1db48c8d10af16382982496ba61b058e917bce2f2bc0aefdca5076ed897881dc16426c7db26ae1c24bf349c80fae1133945c1e7597f92d481664e245a5f07e40eac78370943c846ea96beb12bca2f01847d78ecf56875e8ac7719a0cc6b53e1712ba32eecf04706c42e995752fba0ec3c1bbb6c85f683a2aec3e01b439d5736fb8543f254a0a911e4278926fa147d54679c4f21b954f58505e1873bc57f06ef6bc79d984c720e54579b8368d3003bbcf8901179ea01c22f989021b4b46670ff523223c291c5348f114d898506eee9f7dd2b1a01d8e78622c3370ae9fd39dccabb6b1dd2fe26fea8856fef7bdb2fc729afd08d03f40573adbe521e3eb95f9d4498743ced9ea40bfb611e29a02a5eb4e748395eea806c9afd1937a751a83f2bf57935490ba5276d7f858969ce748b89bb7aefb1f341a4fc29add10014407e268e671d5528ba354b9d6f7c8823ff30e83e7f39608f13cde64de0a621522353dc2586d1c127f7d644aefddd5f32d4642f438afa6501850eb2a4e1012c32936afeadd3cc097f001a72b4714f5ff5021b09c5832823860073645b3dfb773cec2b5a8e87a5ad0f953efeea35357ccc9a2811a80360011df687d0e6efcc4e16684dffe600888ac526e8db96efb067f6007da6c3ca191900ddbdda28414f9509e427ea39b00d8923acdefa2df1220b91fc7ef0545694932084867e80aabe3586315d4c9e9f0e051ed6a0357bb8afc74280fc9787be12b8491b89264b1f85042db005c4d8ccc0a9840ca7f40d6f820fe702ad66d5a49df51b85d48ee267b6c42195f83d90753cf434ec4738ea06f62f1c6c6ecd2051892bf394cbc693bde384b67a5cda45bcbb5caacfd1fccbf21791db4767dce587f5a031fa8018bcc879aaabfecffac028f712a00420d6ffe5879f45865900f8a3fe2c8671960ee530931cb58669bbe8533762042a1f2849bedbca3d3d2857048f474d5e2c72b6c260241c9cf0a13b34dad58f22189e1931a9ee48cb208cd1294f097397dc04d3f76e0004a9515b2b7c8ab152bca03f59078826f72b6ea6534b105576ded6c934d34e5d7bab112a806d428bb630b72e03fe74e5f220a962c0b73fde3a1c4cbaa29c42335e6c568ee48d6b5fe3944864bad1e26030c7dd2bba6c15b31e66da695ac0eeb8cd7dcc4ce771f6fc671a7d6525b4e0fd52c246f8c2dd2bd31c063570007a798b06321b1ecb0c6cd75e0b26604e5fc63b1521f41e71a95429aae866fc727283fca670301db4e69a5a27490a53df68af70d8f2f25c0f0780f3298e51a9d0b615c159f56698391caeb49e631bb610d0a235d7452b8c53ac0f0f3006c88d04a1d5d2eb18d4dde6fee9146e5285ec2f8c174ad5afabeadf84ad65840ef213cf35f18975f23140843aaffd81911e1d84a80b0f966bbc8ad97b3d01c98720bd8ff901534d0d62d3479a1e28e3a0b4ad2498852ad3ec41053fd98823090479d80655c1f61a0e664d7b633b9b73d59aea2ece253062cb93c6ba07f4c26ab266099a5a6c92a95091a72c30035c7f38c42a19f336b23d5e51c79df2780d48506ecb99c407b6f92e7b375cca483b93dbae747be2b709e8beda005b9c8e0a260e9934748c3d1992d9051de9f0aa0df959ce0cc0d9f5c295562d4d90167c58d57c30fde27d7e2ff0c2532dd8231133a097406794f407bdeac7cdefc6f1fab93ef002a2590b6fff883b8b8275a45ec4eef7022b3e0ff5278bc6740fd972839b8b18f8ff4795ed91b9635f9c5efaddd6f0cf16b1500cd54e8c392460b0e005aad45cd24c008aed570bd1a504fb41f49f1e7fda29ffa8932d7af733ef590226d3b20782045385b78c198745d205857dfd6213e9572ca113f2c23b297da535a1f568a612bebc5272866b183b9fe3e8408875847122c9844ceb56a6d2572712e4f3cd073389c202c402825b3732f23da942d526b67955e60a71d21c4642be195578c050a1f13788cacbbbf901628851062a023ad098073587f13d04eebfa9799b195b84c0b7e385862f9ce9fc147741cf8bf034b2e65e9e41b8349d193688e6d89af959e7aea314fbfeb611bbc3832b1e71acabd9dcaa91810e8f1926ea75b316cce8cc7e0f02388894ee0f3d8f40edb2aa0899b9383c0470c94dfb262bd61a2a61750bdc2f0100110c9db68d49a1a1c817f563bd115874d4edd979c66a63b80eac7061da53e2f7bf81a9fb251bbf72d163c9eede658879883c2386be26818eb21a0a6265f92b3f385dc46f3ec123dfa70c3d0c63de0a5b8ac0cdf71dd6e01d2c42382adf109b290ad69bb7150d063ce5fbbbd0b1b9bb195a198e1cd0c5575de8c2acb1742a5af16f07097f8a0452fcfae9997a142589f0f96e09c7885fa4410c4775db8cbd810eafa7c1bd3726c0a4a55ad940013b85b5b5bdf0b159c5d090d40ca6aa188c4d1e8cbad2543e9771d6769a8b1068974274336fba032a916667e6d71183461208c2bf3c1dc23afff5389f675dee1b3f9854230e8518f5b487224c704fa943378b2705fcece87fb8c4383d1e2e78b75490e53780f16bcece935a26ff2749895a5a4a679fab1173743a0ab67c1f68c2676c5435ab6e1fdeb71b6f3d26a4e0bef968af9bd7599beb479118126509a786373baabed2b6b4a6a70fe9d83d16df543d1cc760d4422bfca0b4efbd99098bd5682ad3d2ed977d9cd0ec2aa488e8c259eccdbc2f0ed54d53475f32166874ef904ccbb4fc3f3e0b6bed50dd94e589328da5e9f9b63439179d9cc3af9198027770d569e2e5d59a4fa4f9e721b6a0bd5b59369ca8687076ebc834797733792a416e7fa5dbb8bb977f56a53ff2d625042e746c9eb102ab1c02a41a6d96bc8dd7fc1e49222c3caa2d98ddc30cc27c7e4f8b0f7aed0f90e38dae8a13e748ee0dfb8e4f8ff240732e1b3bff555f78173e169752824498671af052467b3d6191a08d89d14689928b0208fdeaca426ff86929768f566421b86cf88dd895961384b28e3e0eba058eabdf131eb53f2c28aa23f55453d63a4ddae864cbfe6b0ac830ea7fd3555c7379414780aa83e1bd644c667efcb6be185dcdb7967c359b75297497dd0ef3b509b67270cf5a591766c9fe8cd44b048324491aaf406ceda20e97714a628e7acdcf6c802aa9cc0e6a92ae7452b8f3d76993fef616762996109d3f0d15f668f8999acea6ddfe7ce038ea8ab1ec5d650951eee025c1197aa6eaf50ee8d6e7b2cc10571e895ad5a3df826d083f7dc8510a4f433ddff3a5f044a95958d302f391be0b11e8e6dc20ebef8ac360a4c8c13514206791b66abba1fdcaf36ef398a009a039a22c93b2c04c6e806b4e72b97366454ac5476b5cd095a850e37a2ac6cf449d30b5323c0d02a17fedcb1f8f4f4791229470f81b3018021beaf4e3ab6e498cc503cc2c2b03ce2f5bcf1169c2a657dad2b4b7e97f3fda4f5dceb9b93c15a06a6f6442db0d099eedde4b8cda2d7601e609eca2d442ac4b31a1c2ca0c9233ae3a1df4afc4d898dd8fe771e7c53a15994a2f3f6f34b66637782226fb7ba5c093649135f2de5bd227daec4f0fe3b019a894e8e285aad682e55cd421bb5b838c06e97da4f99b5f8cf2a1dd7a50ef6d2072ea538098463c4cc48117e7317f5a8efb3dde594fd6834d041cdf28a6f8eca5e390e555db0c245baf97c45798b87cd7473e2e6cfe846ca6303e90c47b9b2257bd84022fd52c51033683d7a4834b49016e6614794a7090e158c8dcbbdd3cd115488f69b5d4a0807338bd8675f3967e7687dc73d9ec65595cce2ee0067d954f3cf58b5bd2d1205d700ee0b0801099becb06edd43d5ce8722afa058773c35acb440a05381ba0c5340e3c437fd9fdd82905234ed6aa3db316139189480ca4f4435c9bfc8ed633c66ab7c1786898782bb037ea712a429fe5b6fc4680aecd3704c42e8761b977f9f9cbccd1c926a9eb655d2847dd79304c275a38c65cd4b9e2fd8b7b8457ba9b9f75b250bad36192fce3885a667adc02acfd29a3651959341f3dbfb3d7df3a2cc20c14c3e7914e124ae5938e93b09569a2a3eafbd209e0dabea0202162df0a65949f994ef13c83e09db87de3216dc6aaf46b7d70a705207e4411c5d84db8ab4c6a0799cd00812166a7a54a625be984e55fcb3fceb755d7c55f0a4972177dfd80b8c90ef27935059a4396c2990ca72caa82140d229b65a233688aac5c3a117094edf7b7aeca150e9f3c8edcceb145d00dea13d3d70bd73001d9426898def60e5f3eb87fa89ed7e2094f07188b817d89cb7a561db09c1361b143f586d7aa5e3d6512043d60dd578becb54251545cb68683ebfa9194eb6cc212650e689548970ccbda2e51e28b6a6d266b045f07950850526896dedb871025489d6ea4fc824fb80c099f8ce97203fa7c0d84df5e223ddc6c189c0202196b44869093ffe1afc4dfe3b947913150df43d563110fa8ca5dc7713cd72d4d5ecdf33e91d0287019c745c99293f65be4afc17c510c386bc76fc663508a4c305371598fbcb19f0d83612514e91ee537083413869d112ec79118aeed1e7e14ae3d0b086df4d8dfd7706beeac84ec03c398539c4d9c81594c074c5af2b2b1c9c52b10fab8a5605bffe8886ef8fc5e29e6849af0ffd81355c9dcbb1d2f9f3308e3953b3264d2247d074ab0298002eab4d54c2247558021bd311e2efe0227b9a452cddf74b0ead354d9667928c79c7fb8959575d12d4633f733311135b52853289a66be4b06270fb256f558c38208fcc63923efc1187c8e0100b5c1a0e2f1fa0dbd5677a94cb235838e37a7a8816839e4cc354a2f2bc2dccadc437b355ad94be0fbb302de7f5091d906128301ec8c82f126a5668fff2bb90df4c0c11de0c188088c1c43648a3259ad58580e08670b1695ade952e6852ea7c01b74ee1c265df6f5451c0ff754fe34d3ede4c086e0d67312f87317d173bd52dcdf19b344d70ee4b2904fc2daa07858c7ae239630349cfb4c2c09fe7d21bf6520cdfd3e8ae0793017c79183ae4f241efc96daddd8d90e7902b5c7a551fca35ac98c206108a8d3be7e5ffba42591f431e99b28a421dabae37d14ec689906c7412160773092093a4b2dc6dee7bac3e893519b03d8e3d5f262c0b46ad4ee7c9491b282255f51e29b73d935c5dfd85f34856104398798ea93cc6c7556687d2d43f0d6c213bd5a15bd19834720fec9523c26df377447f2ed5c35a370d7616f086d2d55b6ff96380b0e483855d5dc54d23196da12626bbc445ff4007d0555c27e831d1136c65dcb72069bcfdbafeede1498e8c8a110d2ef4f898e6e5318b268a756d70480e72d5f604667852e17ec663b0fc17ef81dd6d5078671ecd99bd1f15813446412999b50354487752a56e9bca6139a53d2da232d2ed60343e58bda52886036710a9f51ff9e4745a0c93f1a3a22b8486195122314fe18fecad4d8526932392d65023ad06a2ef3ae08a34986e1aac606434c44bf36306360cabff25e9b1c7e5617f239982ad270b9ec01e70f6c6a42245b3d6f9023c877ed9057ef0d5ca8804192ea363c17dbc8a2695f8e584e0872e06578d7aeac4ee90718381ece8f81656b85569d76f5ef0a1a99efe9abc8ae9c12a0e2d7a43f3ab079093c51550ace1d194e4ae876069240dd44f6c2f00fe3aeab36b67aaead46eeac6d190ab909d732a005210a993c7c22f5509b1d0b8fa677f0ee36c92f66159e814362d2ab8127c979da7a9f1197bb6638fe753909da090d36e0e56cef22b136126f6cd1463d9d461a600b0d0f357a8d88eee7b0a3a55579694519cee8686674072057b3d96c92befd41b87f4c0e0aaea1d5e24c06ef8f020a98983cc431cdd417fc83d5dbe79a5b0874870194603cb07b9c5fb398ace47f996c829ec03304953b23825623d4163e1f0c2e7cc760a0cab34cdb76e590ad29ba5b528fe296f34941736cd7b84bd1fa6d454bc159cd8367c1b63713b5741c635690af75b548a96d2e5c16e22566c2fffb6750103d73adf541fb07062082819749a7f69a91a04a7548dfca87427096c57e595ad177a4f8b37bc7cd893be46462effd52ef08235516862df63066af1979425e09c6c56a76add8dc4208530d58de2b74f8e67b64c398c2959ab5eb875795eaa40c4c09fea8f5e572c49f1733f0e2c67890fea9fdbf6b7d0457bd3c9cd4279143bcc61b70db2007afef02c30a9ad88253e09497a5946fa1e0a497feb28d7df9802e48cb9da15a9164745703cc967e256750d6dd6692f4861b79e6bdfb6333cf2fd82ee105669d7830293eaa802d24fac096f4b4e92ec16d44e09246b2a3d37d70825d83798d1716b1404dce7b1f26346fcd831d928da8ff52b656062f1f228948733f3831b324768b32a5fcfcf6f2f4cf3ed19bb1dd79a276bebff19744bec53b9f325009b5e01e362469fc5206a488bea7738422915258d855d8b38b8607c4759b272eef03caf2685cb837994606f3bb2d40070a07ae073ca37a84660849ebe3be26ac7437b93671edb40085ed284236f5306645870a1e132f3b396aae478f9e86131440112479c9832fb0357305bae374ce417cce9e4131e176322ab77379242d6692fa16ab98d24130cd4a32c9bd58c2ded8b05924a667be3e80361d97762818fbdb846a9e4b86f0b3a87ad7222c3772eac49969465a0e921b10ab4470577efeeca320054ec7e12a1fab715f456605a47fe7423b39d06278ddea27f8fd279a9441951ce0e7f4e6344ddd925513c84fd4bcac819dabb68642f1e546506f62af323e8268031328c058855314e5af55e7d7d749ae26a4a37c04eebbf9a44380e036bdd065f9b81f067b3a290abdb4ad6fa52ba7c3287a08da00202f6077ea97cb0a609d07670e5649919571359ae6d679fcf31a7a134782f44827baae155f2a2b291424503f2ce431a474ce74d6b478dd26f5c2d4958508888e81240f2c4f87a50a59d0246d52be5dab05931b0efc8428fea439b2d840f7971f3250c4bcbfa1d3968edacc0b6dfdc0818951a23d8c91c2a7c0ca17531aa000e2ba0abfb04acd8593ad5063402e7fa23d9161af5ca6b8d054b9a14b46a53869e56619752aa01450ebe19df4fb47bb44f1379dbed5fc10c2305fb4c55bde8af372ec49100ea497e1c1c765ebeb4f2483755dc5f7512afa5cb846ade6649c88823b6afa4fc99613a059a5a062a3e7c231898e833b236d511a33b6f4e78fe32e93ec5db042740e496966e3661ecf984424d52d32b0d80034917bcfe265dc1b67253ebdd5049a0c27577df144c138e555f2a927ed02b4aa72ff5d8ee6348b122ae1f512f99a49eb2fa1982f997ea48b89a2b522bf05c407e2cb8d7a3f5d40597ccb3edcd43324b8573b206b21727a764ec5e0d48a3244f3bd07f55c20997a6898a7d0ebd6fe44ac6900ac3822ffccadedc1df4a2c811f53f3421f769b71d72f70ecbff893f9645d7a7ce4718968ebb6c2cb9b25c2512fcc3f509115e9990fb1481c3b9464104f380cf76ad28a7e733d04d646ee17678691a4c1391f394cc4b14155345f5f7a73b1650a7f27e476d46a9cb3e8ef6a03fd729d167a7433b0a42d708e793e78268313576b69cd253babb94d32cb4b20f543092158f15d67450e9b35cfee280a0acb1a884d6ccbccac96acc5697ad02dacd51f0e2a0093dca0697853800f18a280b63ef2ae163f4ad0825aba1aba65f18064a26fa071c7dca03f5b88b7bfd269a422185711b9b51a5cb74b83cf410e8ced3f28f0d5bf18a6da74a02ea2556a4fbd97d4fdf03292a785ddac3cccfc8059edba9382fe322a20dd6696a1f61d2e381f1cebf5e8b1a3e61ef5b7e8259f876599222f984ae91d212f34216211e20cee1cb0c52fced86cb2c99adbe1c33d32e71c531707eac98233a9b6193cce971354bc6c6dfd02b3716c5d14aca0c7a9db5679b5cfedc5763c2a6068a7af266fa371ac9266e2644a21545937511d438abb1d44c5308eb8a9c0a23ebe64f15746dc29b54b7d6d04cc5988fcd07061eb133e68a6ed36b13e134cb6af653f74447d1a04055b25fcb940267b336224eface27a8e6656f5b56843d4d0daacf7ac13978218039d9706648b12c1da70ed13713b15b7b30169583cb3649afb02c6f077ba57728e124bd64d9190172617e0560e450731626b618a149b344e9e1e6f7fe6fdb9d719060167cdc94b696a36c853c18a4f1cc560e5d530a3693811f306d7703c41d7350f0ac129325f431d14c861f4b11112395e4864bfa3056df75e679a086030b8a6878202190fa26502e704e4c3bb502e2e1d4cb16e19897f119a1762de894163fa1de9e8e9be16805b8f091ef42547b4d9d9cb5d8b55551700109aa2e1f5ef7a835b6c7b7f11ab5664037d1cc1de9518007b50d64fc3a1731eb51cf1c93d9634400346626befec71630f3dec333a6109d5aaf39aa4a7304fb89372a68d39587f5509a358af08dc9c3cc481413b185b9d3e3d47c143f6255ad8cf72b6ec81047442315bc6b26f9a6d3334eb2355012522c5d4305fb0a4781474ae79c97cd10ec6d046dc823712bef95dabb7f8ca27d940ff746cfb8af1dcd19158838309cf8a8f1305d8821e1ac08a25bc2195fc9054a1b94c3db26a245625b53e7703d73450522c80a7241d2208d396fcd8ab6dfe0e19aeb4ffb40e3c938dcd0db7c3e82e6a13ed637bcf02ed78851880fc95697b4a1774f7c18dddeb652528099277aacfea0ed8d0b8b236f141c7112eb8d52b907ea112173f5cdd085a27551e2d2a2d79fc00c1e674f820785786e560099436ddf4846ab8be29ca1b3cf86cc8ee008085c72601b698f46530351059a07b6d014cb9ef8d0a88239e9ee720f4948a4bc7eef7f38383d8d11132bcfbee741940df498968be2a99eee7017dc5a62f9274598c6fb5a3883ec38a8548ca8dec7069a7645951acbbe870df976b687c03484501f0a5a44a92ce186386405be1674457474c8a9cd6a5881c94934a88712b2b963391ac08e7f0ff7ff9439fe2aef7ee99282724cc90186b1f6c6029dbc5f6db9f34ed336eef4448b31502322e6203513b93c7b4972c57ab0faeeb2dd3285406b0703a213799c08b6f1e9d4edfc8151bb10c06cf8682c1b74d1d834402cb32f0cc9bff281c5c9d2022bb09cda6657e118b9f1adb0af354a7bd5c8c5d6a97d68faf968eeb0151e86a38c0add751b4705bcae3223e695054f9c62c52a39d24d24ca2871e11adf7b2f1b83b8f0e951153907a15bf62a5ef4fea469fabbf2082f2369ee5274ecae3759618e847a93ee571f522be5928594fbcae0d3c491555d8bb1a0fd71325bcdd9a73aa25dd05838d73ef9951b985ff66154ff590d7af745d62cc1ed417a9035f20a1d0702d67fafca87da63e8b159ede502961a8a855b30facb06f3314dfb9f90e6d5a3fa5d5434c10b00fc3f5913444d4680f6a2f156529c1ac984a491fb5d3e59386fdfb6bf0b77ae8cc0edbb86b41689546aa50d55e7e5b4fbf71c271ba09ff794cb7c87ef5008c1a1b52cf5cfa640f971fd5e6a723478b70d43db0fd9a525579d32718a9fd21d1caeea978b3135fcb368a010144cd8a18641ba1ba7aa2dbbb4e9f504536240c6eb160b8592056faae2c0f6b18d3a40b2e639e959abd5ec8553824984f345b28099d4fabe1a5cbe2838408db153482596d291c9cb042f0e6a23a7751ceada32a138633f91b49930c7c56365de2de460ad0301165a902d986f9eaefcacc6cce8e4b65e7f311dc78ed96c3e30a20d14b8e9f9d859d45594d29f16c072d7bae11f29c232115bf922aa683e86eacb28e6a6eb4d3876bdc0ef104783ece20f5d46e6b752b4478aa50cb63b98d74652b7c83d9bf8c197f966bf7fa0f7c4eefeb1bf4c60c3860fab1918906fd38bd2a8ed2f22217c7adf2bfbf1a8ecbec91cfb86b5863507e5a40c15bc51b2905577acddc2ba0ae005aa537f8af407b637c13a93d94839b4fa07a37ba743c52c0c74b208a0fe98c19b2a1f898d0b1dbf6ac1fceb9cefeaf4c958a460ddbf07fb8d00b3f5c8e81cedaa7c87ef63bd2dfcb3e30f5c80f4b075a1e38f83e20262d8cda76464bfd041cdec8cf17c928337a7d1086efda07c007b9abdce21864934f445aa5ebfa8eedd58d6514efb3031720c1823b125323b4628c73602913f9f1b7d11725a7ae8dd7111330652c41d4d7744eb663caca9fb26dd422487636942e200a0c8527817c3bc5968fbcb92f601720f658bdcbd53201afe6b7ba2949a45c73fad450546f31b62d302a8f271117cc6ef47315422539ded7a9b163655a726eaff84ca2c4204db1d3fb433e5a7ca35ef085730a7551e077bd46b0fcdbb00503b50168efac25dba4157f5bd04b14941c60f4e579a9acb8e2e5a05e1a7ca0216894db1645fa281eb2ed3f9f36c8a240e45d276811956b558d3d4f4c759a66512821cfd3b1f00f9fb80af23d0aee72cfd22fa4e7ed860a715a3d94c1adb524d5399c8660b397456586bdf8c986db83c8cc4e2302fffe1c3c553db2d934b648cd6fb1fc198085a816c8793827f394addffcac9ec45a0eb78c26a5e6ce1cc3d32ad7bb364a8f910c71983e51bd3bb6f1692b2e9ae19a716958410d5f10c73cc500fbc50aad6de5e7200efcf791a9411ec0202a8eef51d206499ed436d3f4362877f28b4154003d86ad78e94235b2b41981786d1a023a1cc2b4595874266259a7979076908a76553ac6316d1b7de5b5d2ba1708f624da919a53260e2bb50ac1c6c80b153ec1cb262f5d45f72a564659f3d0a138a2b4f55efbee14b55f15f5547ae0e1d97a737432bce2678ac15d844b23bb21e0dc26926a44b64ad8adaed3b9c3741a57a2ef55d7719691c3e6a5d072d44ef407e93e463f719ba5fef6cea57a34cf833def8939db9e022cecda5e592e51b2084191577b9fd393c8b13e09d46e74ff0bb27e825b5373c40003e8a49e23ab2c65f77a325846dcc4c9081af1b2c21a31216478e377d5a1c28d91d8ba71a156c52d9ca605839bb5c5ac38adcd0fd21af0800948d1396798632d4d02239a79ce42858ead96f2735a29e29cf6b3181e7b1d3e0f03dc84621cd6bd4c0027df7db949f58bea8d93078e86ca49bdddd5db22bd4aa04c0596ab216a4becfd3d584be1d4b53fee9ea7b76e2387482162e8115058a67d57ab4e525c8a56cc85a891263864fc37791a6e0368134ff4a7f4e14d2016f13590ae55dcc2934218d5d1908496763d07ffba4aca42b97ab3eca8b58e7fa9528db01863062262f508af0153c346a13d4a27cca7de28ae546e07095d557b153ee2c90871ad26064178a865782b608034346494f357f4261cbb4c8a136ad0e4cc0c06f648595a55cd1ac264efaf8b917be820f891199ca6a92e31bf1cea6d892a8a9c23a19f60f71039fec337f851ce0a2a0d734ffc452a514a72abf0ac24c5f0d59159c42d15901b78b5b1647a3842b272eac658db6a539d1bbbcdd9690465ea7679c3c15a5e5839b4cc250e75edd35f372c2ec509e2c2edd7ac885b3fdfbb1d1bf31e2c2de03ae9e8f3f195fe44a961d2da128f6c710f2efa96c35523e7001415b2be069b88e7de1ca7bea55648492ae03acd32ea2fc15a6f793eea78efc5faf72e18c273e5a70439c16db4223dde80dac0206d4e1d3687c4b3ad82dc867f2069ad072b3282cecd5d1d8a0a8c124845aaa839c32ee7725f3d1b9f733481056a3f1442a3422d43c93a1a8a85ba716d3cd0832a65cad45ffc137633b441f597eefdfd0772d7f6bd49b2f14ca49646c930246d202f219ae71d88936a55c10af4ca011ab8d704cf074c553567bb730791c021eeca09d3bebf45d39b78c77a6366db809ec8d9bef7766dae49d4a9152b2b7e6499a8c8cb978a469bd10299f3ac6b08055cd56846b010994c8ece2b6a78aebe82b86ada9d464f6771ca3fd8a7cc3e84158a5e5dc4b97046efbcfa8cd83bcd1dcd851ff92c4622075eca56ecf3f8833085c5ffbfb9af9e192cb299d77fd6fc78ea6d37be470297cc15167ab6032b59bbb1fe9f20fd36a563210a3330cb9d2dc0d341bbb994693529a573fe9eb31b676ce139b95f498094f19c030bc34234b62db19e6ee667ace3267d897b55b50942904cbb376a99ac9947f1d83e316e6358411e9ec3fce05e8f7390b052f312fae53eb0eb5f1aa7f8c5d96a887370534863fed36f85ef15d797c977e4bd2b3ef5453451de9d42edf942190342fb61edfd9f35c71aeb847772e19cdb01aef734f7b5bdf9cd494d3816c5d065055299223a64cf1b0bd2b59e942ad90250962295bf8948a5c1d273bf843eef47bbf1b94d93b2a2d4c22b4606d50f96c5213dafe0df4d134489eaa3285df819fe21b835c971a990d6abf40bc2c944fd0501b49420e417a3d7d3b752b44734e70a239e607964d74a5a2186747a1c280166afad23434691eb4a6f0fd94ef4443fdb35c1b6ee86461a2c4d0da0ade45d03b12e71a3cf8b5622338bb79922111bcd2674750fc925cd039545601cf5c7a4a525afe2810f72e613efe5009b2ac7587ded9b80c358f122b8b56b5a0905c8f54618c256bc4e9db508d72bfe52705f6d78591bfe0330f4b33bfabd69c20500c6feeba71b1928427c1920f0d06896b42c413948bc0d451e4031b87cdcdc3ed69cdb29a0e236461830b888ccb3c653fcaffd12e8c3103068f159ee2e16d177e73f1daa0296418216d906a50b763c612fe1448252b893af71d1e1516392337f3741793a6406ccd37d786e50b26964dc6e3ff67faf523a6db0e4395901062b0d039c756f6a57609a123c28f3c1c977ff7c04ed578c7ee842eb7a2fdc0eee41e239b58952785446002a09d65c4ac18b9b39e05e6f2f8affebff03b27028f411b12a8d25248a69b3b0e5811b74e0fba34531589f9439bed6a7231d46a21906312eb52ec789943cf6d2b15fa4a8286433cec04510fd9913db362e368ad7271b4cbde0d16039f5abd589c9becd7e9eaab368d2a82f994ccc08562f85cd4d82ccb1cac5289864a32065b71ddbef4807217f41bff2d8d247e7b29bbf7ab523848998ad1bac13f72046f21cc2a34688339c03b442a0092add0ff44b85467b384b8a36129e2c9c4bcb0ea055d6ffda4b3ef804fa70ce4f15d5239fd2b7cdf3fd17b284cdb1d6819315302de6dea8c73443c10b6c8e10a58f34d75d04955e2ad1b92a7dc6e35bbea5daf3e81cf6965d665bf6f5f28a59fb764a840de3a7ef2cd187a959f082ee1ddab3c1f9a7d35c6707fb4d1d1b0a6b0c03d37ce150f64aff9a4965fa9cfceffeb52da9f83b5c91fc0a159d083dd66ab6a2b001b51bb0e275dc42f5f90a264461c25e0b1a7352ee2a43cee9d1b57bb8674a0e4c6b6b87a46e78a0e2e5e783bd8c5b098d441550c21475c481f439bbaf93490dfaa1e2d009fafe796aca8049386c559c73bf335a90455a4fc379e11c80dfe8737a131ce83b101e51864d0d3cc3a5443bb6d6e2c674ea2708b365903b559535bc1f9b5965fbb8af615803e247252384199964c59cbdc3f961301352496ba8a92e653c476fc786b8c46f754228312d67d4851ec6e3a577b5e62d66ee666cba6b974eba3eea8d11ac4e9912666b401b1a4b91fdaa69c0d646bdfb4e7c382436601197711c181396632b04b8521428d38abbd27d5aa057bc42cb065f68ca756a7c42bd19f9f0ca046f0787a3c5b3564bf05012c50a0f4a8dc5cb059afdd7cfdfa13c585e29db6196ae68fc34e61e11eba92fcedac25daef57218bcdc16596564bfa7bb2aeea836bc0d136d8c2192e7b85ac5c9a2255b76e685ec21057cddc4cdad893046c8a2c60b2c4a413c56487d54807ffd4f0adc0b772cb7efc1c0a41674c68a1f4b16b9b85066139fca8773d544727e946831c0650d605458751c7789d7b3cebb3adaa3dfeb8e01baae654bf13a088cdca91b91fa523edec4b5e38b5b3c966a77a5c5470141dc60ce8c4b5b835de5e2761a6d79fd2727ccb50609976c1bc4d089b4c20e25acec59c7534b32acc4429e719fffdb2398b1bcfe4a4d2aff408009f4dd3cb7710b7fd3f48887dfbbb7ed75d47b547ad7ff6abcf9958220757c5a0892a4d88fdcb310f1f41c9005b20a8b8bf745f103be681d6adc171736ecaff092ec9ae7d7ce5772ee2b9d592b873b89c89bdda91680da0a40a85352f4111dff0532a5cc459d30b8925bfb23cb7ce27c66451a74587568771c2a934ed311595ace16c5f27f55fd0bf53a32c6223598909c7115981132be488403b4d63be8ab07319a376e628fab826db5fb600273c042f9ceea21d6efc4cc55cb58cb8c24d90cf807c55466da87856ef5db8df81bec24449c71ccd1a2f3c28f18be3d33e0c7c23372646f6743c3960dd6c2b9138c95683ec53e204fafb75c23ad3ceb91d1e3d4fc8aa0d8ed631785a2539b9aba9ad23a6bfe38ef59c724e3c2c0dba5f8b8a6b13740e9d668b5f5beb3c4bd59892ce4030139d21e93c210ade89e56497d9b4b0f92369ab35c5f5f4d52c6ad320ce3f53cbdd2b5dc021dc17b08d096b28eb7d4d00f21a26e94c872d0fdef07e35bdcf836b40cdb0cbab5c62ff696278f1e0fa0b688d6a82cfaf89a981d9eaa6c145b16d3e60c7bfe22381c0377517a7c59b90c216ce0bea7cc6e95a6da41033b69ca63e345fb24ea46ea3734de9f5fbdb3930a0a5e4705d705c4e37c4fd436040785d8db586795fe90cd397a9b1370baa52adce38a9b6a435fb74ece304fe74629a982539ca72a26706efe513b3ae13a7e84cd283304330c959ee9250d319bc6bcbced2dd8553e419784376f0f1f7b01431c546f86621bd25d0972196fd2a0cc8af16e8d4a1d66d9cef2b07395f322c066f4da655d4ec2d5ba6fcecf3da36ebe966841038c1b1330d9eed95116d6195f8801f7b248f6b5a2f81f5cc6df8cca4208f0808039df7d07625bc089d544d1c8db1a6732cec3dc301475c9d86261737ce2b853990e232a4935da28b065ff0b7315a456052b0649ab223fee6158b4c5cbec3412f7832c4080bf4fa43e194d3f594c469bc7c2452892daf098b27eecfa44cde8366e59f6fb76ca86fca0d504a548e1e73949b6d9d0bf4624a8365816c5a37239a701b8f0b54381f186720c9b18e516709b5a5bf8213b36ccb197cd1e22d29048c9dd976f722cd2cca798992b7e87a9723f8cbe6d8c8f85afba1e47789b602998e27637f0af97329dd2042bc51050fd9accb0833b4e4cef5da262529eb4661f3927213e167b81ebebe1577ca1ab6aefab7debf036892193da2156816629b04279665d4ef9542dcc5461293df97c120fae5c0b24d981876f9c30c384622b1860d81000de81cfa271db84d14bb7a8b7260fc527edcc393dd09a4f91708edcf4d645afab0a409b7ff72b02ce4668d90270466a3fdd6594ac5be3676bf97c5479542f22ee428592ff1172cee659bb8d439142f7ac4e8c76a24da8976ab9257be96240a03d1f865c2e6bcea3daf91951e2f69b060d7c847bef4e5252ba881c574ff62d32029d3eb91da129afa5e2981fe8f5f2eb0f39dc32a54db95df66dc8aace26ba379db6c8556c8f974cec06dcb35f736dff729db436798c48728297ed989eb8c7f2fbed64704c3f1df6c6566b219885a0787eaec10fe3358b97c7adc452986233581ecd514b50f9c7ec19453d775cc0c9ed9ef118cf7063f47521d238b11df71943e32548ab4c180113ce56d112b54f677c3095cace8ef8763dbb7d1fe10f47e7c4ef90a0025e42a73220a630ef2909914142766fd8050826a8bcda8b59765765e7f2363696176f0c7ea290b5cba1984f6c82136032e8042cc49ac22377e1589a9f5c1af8f32549c8621ed4cbf8931e379e4ae063b847d829cfecf3f47b78832492e02c26cd260a29bd20357cd9eedaa72b0118d5b668d9f45f83f87308b6e75ce90b681a14e3fc8e8eb71e1c27d41a5f686cb25e7f42fa58fb99e0fcf7e4a85021270dbe3f6ef7494702d1eb659fe38111bfb7853a5f21f5cf46eb5af65511f77382fad8e1c42f1126834ff4f69577cf021bd8fe0d1823eaf8dff7dd6e85340054e4bd516a9e118a8afb3a85bee0acdcae017a5d20b172ecbd8433154aa5205d638190d9cd92e34417695a9acdfd96ce76a8d21597c9a1ec298b97842cd4533fcb9e8561da38b1b4fc1f7447a61826943d6b6d47b33496323754ddca1c7675f2f6cb8406c53e766e8a8aab8953a530ce5ef8267551c60910392c8dad234c8301bc7043068f025b1cfd97a7fc507ac4f9e7eb86419c42613507a2813be2d69e978bb9ae0c0a7371b575d4324da122835d6feb40e4a406fefbb4c0a2169d5dababa7ba1b200d2d7ee352fc6e649366921a09fb0da7361a544f58d45030460728b8ba4b604961467b630e5f4c032413b4444c3a08a094636c123e17729bb7acafecca39657640237bec52f1123e02137f15c105496dba24cee74394ef57eaf108f05d99d54635d028e8fc8f10d38a549f45fa8d4cdc67ae4954e639efcd2084cc6506c34c68340890e86cbf912abbc998e0ddf174d015c3e00ce63d71638af6e69adb39c5952dbec2b325a296053c76dbfd1abaef44528e98136055810278c63df786f321b2e51b7986edda711b7c8452625bd13c7e2ef04da724aafa787fc0311485daba535477f648de4697f49ecd1e26cd09087b84e39a4149cc704177caa3083df84e6bd872d855d02d44d0ed66be2bdc2f9b4a72f81c4c26e358992c4fb19caf5920124637820c4da1a1163a5a4f263aa7ed3847979e30ef0d5671e0dbda99b3a26eda91edf4320b27421d5f296e1776b4898a8a0c41db5706879ee7bb188acd09c7718448369f257b47300f790626d20d3a5b61713724d78482767415d37ba76a74267b6bfba9e876118048c40d90e860edb69e8f3ac2dfd720195bcfd5d6f0936e70fba83ae9ccb75025bb11e2e53cd8424248af28a1b6810a695edc20f159436324fb5bece19d932af38d2abc8603c6bc2e6b7eab2154ff5823368a6f4be0a5bd8cc9ad5d8668924acfa38f8d36cb287756a5ee780bd03b2255eaa16d5b471c064941502de12cf18a1c02efa3204f78aee51d6ff37d0a594b401371897833d8516a166f2ad07b8d62b6b192afda86ce5fa4f64c252dc15816f5a8a85a13e4051b4e356b4a5e63bee7d65f62fc1725c83d9a393cecfb08373df5bcadec6ae46c44ac4a1aa1d905921c49a52c2832241a1f5bd0886a68e8c3382884006f5475d4c2f5c861dde5bed897a1fa4c9d06a36f640ab7b77fec160f8de9b7e6e01f9938e898f587c33b650d43ad49220ac065140d865611a9d484e456bef14001446f70b8e40fb084154ffa3dc54af6f52a92527dcad3c6e5d025d52b9d55236462d8d85fa1dc482a0bf5cf69846420fa6bffadae918168a334fdca998c3f48cacc139acdf1a72b25af85ad77662964c68eaf09e74c407e5f9d14edc2a6ec3ffdf457f28b895be851c79c463e8049eda4cd949c0374b7aaae86f5843bec2516f0e20040e480ceef09316cea21d5b888af429532a125453b1c06af05017353275251ca07477825b32c17535a6d2d77619e02c242e067592a05f0843d1d4c973b8a56689990cbedb3d86deca3d9d382b4fa5e0e273811930b13daac2c3f175ebe7dca953f32e6a34843f7320db4813c6427026e374e3a43d2891450e426e66259c1d40115cd85e38d3ab8d3972ab544ae8d9ccf41812815d76c033ac76c1c2530fc037f7a2149ae49a5b14b66aa1b337baa1f6e488558d853fefb0b4b1533c2735ba08e79005a166e73dcdfb853cdcc708482cf8576d9f213ad7c5e82e76fdd2b17152ba48e6545a17df040444f8176b868e377846f10e9e9f24e29c571515160a231468f9f52418a8c2491121fa84bdb657ea3e4dd0ae97271a75afd0047c1d545567a054df5252be01857d3aee39e203f02e7b510eb7052ee397500c154e407dba20d4fb1c5e131f705d769598bfb992e228cdf0bd79510f1f1a2b284d841a732db3a76071b3b0d3c37d39adf4027b054bc2ce9de97638dd05534478884abb32516c5427a5b74309cbb8ac1eb2e88cfe1c6ddf2f58236330ec37db6410aac8b4bb41e347828738a2c774b9d0e9cc902b6ba9294102441422e0da7c85e05ce3bc8cae636fac230d00b229921c5a7efbedda1c7b3d15e13f511025eee619f8b2c0f8b3c79bf7654efef7677ef6458af2769b7d7ab3e2535a76fdc9f0741772da8cd84e48d41f9fb41e1561bb2448a772d9840db43db156e479e2bdf64826979c47d988522e5405f6fb0b84201428a35956b32d2db569216d809e5fc66f615cc3363d8168ea248833c0cb5bfb2f99323cf0889490daa6f7fa9bc2bee16a9554905f04d2fd2eb06f26cfd4e9243e92be85eda67b4535fa83cfdce7b3bbb325b2201b590f0769233ed96946f2a79a7aee210914dc34751bd415727d0e1eaf1c6e7f4b5331b7eed6b9cf6fb4cc816d154dd313dd8307272af883f0e06dac6fb66235dbf12c1e652584cba4f8ab5a7d704731362150d228a67af7577cbe710d0c35632f33b8ee279128f78e35eba5827b5ffa7ead4c13bc4949893eb3a8b46ce95cb29dd92647288ea33bdc04aba15423afaa420a60e61fb94bee7da624899828dde03c89f612a0487cdd5c567af694b3acc0ea8211b4ce9417f8fa499982cc700fcec096a46eecf88314fd93e96257f36dc0d16c7c3740fb1c931fff67bde40d3be4ae9fe7642cf0c13ccb1539ef0117a731575dafd532a53f3336b220cde558f1e5f79687e2c7cad30cda375c5f42c183ee926e5e11e5fa9577c31b17df888d2e3be58bd242c64b88e3d7494f074ab0cd35a33ed03f5fca59b3e9ca3e8dfdde43480569d22ab008d66ef6f4efce3488dde4750d8724ea1136215d8b9a3669a194a288c11fcbfb26dcf9a6733bdf9459a7d03635168e8d35bce05494ea5457c6273febb61ab5cacef19344bc923570cd836f6e7670e6069d699378f1f25b615f76c022ff9331bbffc33f8f0db05f2eca7cce2aa54cae2dd0992d988b0587c9e66eef65708411dfdea30e748501b86d8367c1111d6269225404b99da5b1b47a166f07093e89c97142457d4a75df35a2dc993936214032c1baf7f168e22f690713d9ea038515eeac204e6efa932085c4654bd1a182112777a05b06dcd8a0994694438fffd37260a0874c6256abd157ac9e19a6385a0d3a80e217a7638c0d18ac9add94d0160c17c78cee764ce5457185d7595b4dd10bdaa31a7045cc5bf802052fe5d8537fb3ecf353ef8bca65d2ee4d342f045ef1708bc568e2cba0ddb48a1c7fdebe20c212de8a884c2e273e63f16f72c8ae83d3d6f1ff4c00da7b9b6dc81c513c3eba1ef32048922e1ee8ecf5f24e91e45e86ea86ec60106873d21f49dffbfddc71662da416691b061c3e802db3a96009290e27271c1776ca3e6ab2c69de861afedd2a80e7dd411743d15136e7e236d41a44dfad1ecd5c6f81636579bfbf1653c573124f435f7d89d1d1a7970b71b846e8600275aabfc1daca813f0b59efaa8f632d796276d059c2fbb7b1faf3ac2a2ce664fe00f29bb92a63a8d5c86ba11626d875e41f2e58eaa5a1f665db3647ef3ac9a777276b46d8862ed74c3b2aa5635842ffa0dd3049156ec6d72f1ee01a2b37525f72841df942aabe300c06926058d92056da6e46546c70c84a6dc5317b720ee412dc9c25f088fdbbd64af96f2c371c993057472ac3d26a2344069bf9e0dc6753db938d6bd082bfa079eded85fa1ae47e8c97013b148afeeb905d97e30c80e786fe872fd6d60c82c29fa0016f78516b6277f06ada37599ab34f5b38f5f04e8dc4cfea45f2ec29078bf7b5b62e843fa6300b7922482b228ac1bc763d347355b1b4573dd41659c32a36db5cf4cf711f22b508fe5b25f76acbd83f7807c49e9984af1843ea83748690ed5699470038ea934a018a34364934ae9972df002012f3c8db4071da9c6201d84ba8d49ab8767eb0d1c97d643c9bc49ae24482b6b6064b46e3aa7e884c35604c15120ef590755a7f316dc754dc1b3440af7654654a7deec63947783fadf083474a672d70c89ab2082a2614f6ae2a5813666353d39f404956b3eea450ffdd0e7066b7316744dfb922a89c7669acf3b558b62f07147c28942d45851396f27848760a2abd379f99f8669bcb0d3caf265c5de9b96da40338f05a3951ad782e3f3cd9866b9bfbaff87c8ec9250ff2fb5cfae6ec10f88e1751ba1ac69ad2ff3e01660962b0879f90ebaeb3789a91d6a6914e9d134a94747c76f54b9bf75b76710e42eae7705487202a11a2f0d44802c4ef286feb56100e578879d2c524bf84f4080adaa4007f5ae4a657b0401ce3a26e157be48fb7e1582f274b9aebaff8d35384faea4fa690053093bacdbd228696c78541e70498b3eb6af22e5b9ca06b6fcf689627501a5d63da1a9eb5ec0574e70183edb66cee833c9d03232dc062b86e4912edfe9bfef1dc50ce04a6a13d23a96e78009364e38b707e1f9c6f1ca01f14a60b4b1b95a1870dccc84aacff89911b1f7d320baa8a60a264d780f1bf8881d7656faa6d9ff3c4ceca276438cc0eb37894bbdb641244966a5d58f37a60a5d658483d6b93111b4fb771979cc6cbc0a4dea74f5934e8211552b44d3df5081540fed0af119e70718ff12c928bbff22bcbacb7a785236da690b72edfc3426961a85a6dab99a9aa1ac5557376262c283f5a98cfe8e29f2666af976d9c69165c310ee3039a7f7c6d2237c6bddc68fcd12a83264f40412616af8d576ca9641d46d9a9b684d7998eb27e901444b6e42bca672f05c6fadffebfb3800f7ad66e4d079157cbd6fce4ed5f7ba5ff36e1bde8b77487203fe097088bf190c64ac3f5781bb82009bd75da551e3fb3cb8c82dbbd78cee6b84753be089392713e47cafa92d48e40243cb473a43619f0a8d0f546f5a6f34be310aca044502e490a413b1b4c460e7d760089a9fc6cea51e7025461ce48dd33deea510a2cbc34f2d5f08fd417e616e402ca575ede7d6290c32f8b45922f6106cff49dab1715ca8eb83074dca4da73566022113e8d34a076d79d113d31b49ab160ce962c6da8dbe65bb824402fd9da8747748e2a2dc627701a9a0ce5049bd6f6f79b27459f0bc28868dfa2a5c8a6ce7f733dbf8c6629ec57a1eed652f9a9b761df82d381ecffb475cbc827946c0ae412360e2527e2eb8de23c5586bca2819b1a61d592c0d6ea97f1e1133b7b120377e0153c15a2ee8726d0be49669320a57d4494e0bdcaadd3ba1959057c177168b27c8ecf2562729361a9dc661574c6db5f5f45ab9ae24f71c76a99fdf2270db5e4458517bd2c0a03dbada7b5f24f794142a4c1e37105b55daddb1761ff8438ac0a276f8b2f680d09906a3de6d573885d994f084237a4c1db58c4a1e0e0f6ce3de1dca6700024d7d7b7694b40cf5dfc9cbaf8192779c83175fa66b6d80bbeb71b0ec5d025b9f449c883270033e11f76d4684a3b5487e26c8f240f7089013724d78f69800f47e01482bde3c7933262292d8765dc8e5243eb6995a6f3d5169a11f65a9ee40c21c452db3c2c09e9fc80a80dbf3eb17e2f8d789b034f47b7b52642445b6faf38fd94bd6576e06e0ad8ab689b934e8c2653a725f36faa4ee035cac07ea73df89e6278ea083c9222581463f1dad5654fcc63b2eeb30b7aabe2bc4b5aabfd666dc552e7ff80bce3743cd83aefe7785cf449fe4af70726f2f4ab74d01a7b83ddbc7467c639d9e965f6dd17c8894d5f6210b2713da7d2cd367b7e3afceb9ffe9088bbdea39d59f4786598f170f436dc2dd55a2c02de84a5fc382d59eacaef560b46d4e8b8d328ed19b421e14dc33ac9c1ef35d8b69bfa56fe5baf244d4b12e30aa42da01cb75cd425394ebf0969696a6c5f4a53dc9346563556df7308effd37d4bb9628c568aeb567c53a8c0182c233c6f221b093ed0b172172c0ab818c22924e9975ac989a19e4db62a07b069f13028f12bb227c7bcd8f213c18b770f6a39ffed597e30f088b333f388d320e665c0c72865fc8c84d05aad252add3a1c939116639f0bb63925acaa7c7b3a0aff37c7f59f70995c6b838777dd963a009394931f08c2997d0bce0a6916ee23a88c2df3518addb5a2c53b5fb57e4498a756ec69da1bf6f609efaca12dc8fe36805e56d1f39cc9073146fdd22ec0a74febb35120011def0e90f96a3fad02349f3bd83a5cccf6f0f3ffcdc33f5b3ffc40e3fcc28e4ed1f189230f29333897a3af8f1df49afffc40aa6aacf4463a063d33e471aae9e3c3296bc486070ba429775aeaebc2d6ed9b8d24a869f05d301e831a5b7efd44e3d4f5c0da67ab0809a9a6294bcd81bfbff408780d690b1329f13f880d941409f134e4dbd938687dbdef909ec283addcb9feceb03fbf2f0a1ba697c2cb3aa834976efc0d097a34c026ae88501a0e552bb2ebb3b19e24442309943a1010e0a222ae8ab281283fe543c60882e5a08cbb0556d692f55022e597e776d4c56a47428d9b0c99f7a03bd1568ae4c4ed69bc57c7c88a4b5edc7bd8c67f227600188720f0dca02b680cdaad31110319f537b3187e1c367abfc5b7f2113566450e8be3dfe2629a9e26de06aefaa6a950e5d31270bd8c8a3493fdbedb5d16458a2b1f35dd4039148297197638971bc1b933caa7785ba1c1a027823bbad0d97ac996399f9ef704bd89beef5f7009b5524db0c1c0dd1eb4ec02e8af58994ecbea3699ffcd66fcf63ced7249dc53ba18c9c6eb95c8b350e5da0521a8c444e46e391c5969711895b874257ebb8665f5e99185cd767283557cc3094b377fefccc963bb4ddf3ca588b2c2c590a4ea5b02ddd560d0580eacfdad392c634c31ba0a8340628eb69c115b61cb53058f1c0e7f61d170f9bbf13d68f9fb8e9052f74e7a488a46970f1271b026c3f4c7661934ad20919d4c54b231dbd7ad2d94a0964557caf34d457100c028f051e5238c5c61adf01885b2302936e07b60e82f4024317b3641738fcf7cc3bdff89e29bba0d2535dd235d1f59af1e89220d4a86ec6e37ac5493cc591b9fe94620729490cc9604d5464a87914c767bb2ec24054f3695c67ba8a48d98de7b7f250ecd1ba40d7f0a2a6fba4f0e26a9bde1dc3f2e7c82e63cfd9d51e0405410c7d61e93e9d6bd131db1b43c3671ab1591ebfafec2daec300905d19b8c448bf7318375616231004b4d88e48822d74a398f8c477fec64ff61b5df5b2ca7ba2f8763bc66c7836883d8390aa2bb0dd12ae76128b92c84416dc301a03704c7067b0a597a110f1aa07d16572d2c6aac28153beacc7eb007f5e72020b34f872bd5e29716148b30dd2aabb2a96cbe41f1825207d4ac69e84983cb1a5cd7527c3366200c568f6e022b7a338d0348193b454165e2ab7a5cc486e46aee4e38413b7302830a4ada63eac9a4e0de655ff0ee7aedef3aa9375c2a589e4de5c9aaaade4393c73f47c19ba7c3cdbc9795e721b474fb964e23f253ef16969bb7a88ecac2b51a50469475a3526bb621150d29a7e049a6542e0140e2d37cec8e0b8c7e4db52bd23afd6409aac0cc2631a2415e8a11e171d45e3d2ec5746c6cf2dfe40960aea365ed02bdb7ddce40378a5b138912a3b59ffa90bd1846769cf68291d8a5eea90253816dee7b44a5780c215e0c35cd8dcaad5314eb0af20d1808067a29e5a2217e2ecbf8803bc52d9e860a49608fe150cd71bb940a02d66182c9357b0203383b216c3ed537af6427816799ac2dcc8400aa3d27fa0c086f0128e5e885e80caf8b3e4fd10f597a2519f14e6b8012c8e487789ac2da1f76afd944d84c56592379986e1e7180767573956f5622f33ac359f63e847875ecbd43540cd29d5f653f9f0b458fa1ab7c373836fb6fca50d47fb83aab3a1c1f50429ef754e1c7a3548ca564a3c4fbfcfad144396c467edd9d4b75bf9c3f5728a5b627bf31664e0cf9c901ea53bb54dfe2083866d03634928fec4b3c4291836732a634a8921fb45a608f5038e2f59d29d4b790176bb07a5283286edf6ff955b048fb7fcc58477c200d63e8990e982b6fb62afccbe89933f96eb90f1f11a06d9637fdbeb45c1578f97e9e98dd1fa7b220caf16cf82e4bb50adf12ab3c3a1a9d728f38ae89206232f978e7413d7bde1f794d9aa87cdd48743d1ef8ff3609f06cb7d96afa3368713a1b34ed8dd5ae03a1c930e527080dbddbd20f0b570a9a3b3ab5ef71d4280159db42d16a4cc19236e444ef23ab0173f7835168fee791d9ac2259b4e6e87455995e7ab31bd37dcb0f5c070b0512f8bc6ba68cb10334bf32bc2e0b69ba0ac746dc0faf5d8859362d46e60cf444373cf58e31bad69f4185c5ce4521db2c80769b34c7e08788e4f7e598a3a7fc48f0b65e88802b92ad42db5cb8a7dd17d13a349ea29418c333df7de5852f1d6fb175cc34dabb19ea0f68e186388539c88dff9eb084c5968674800cd0c6de20e3cfa93ee27b7061b11713b075fbca26fcb561b3259a02d5fd02b854f862448c8bd43311f66f4660d412f441f4c2997819f3ee6dcac5c5cb831ada82a907c9f3ed3cf9db727d2954b353ac05ebe29bc85198b0d23d14fb6815b483045473069e2a70d42a9f7b640e288fa9134c25c5dd3f597355cc43087fa03d610922b95ed7473bdfbe01eff08f8c54dfcde79810dbef752542f558200a4d8f9172e6c280f2f9cb327e073c0917e1dde25b569100affcd039e28601e383f2d59ffeff148643be134e9ada822d85078cfbcb9911a6819fc5adc582c9e1248f79e1e3fdcc6c61696601aa4706aede75b1b9de62c0c64c610fc6fbc814c015dc9599bf77564532483bff0e663e12d6d0c31bfdf9599ce062fc18067381ed353aed6cdd2435acd320a918499a6701ee7a10ae883913fe5cb5ba89e9e72fe207fb19da89dbe79c17118b0c54a581d8fda0d622af69c2dee9c38e5c44dfcca0208c9e31f151c80482ffedcbabaa81d43bbfa15c3aeeadc37687207ff5bf2c7af14c0cc70516f79c980ad88454f532a4bb6a21226f22fa21b934bced92a246cc5ff28c71b5dc60b899fce627c6170d61d8ac174160b0423b5ab552f866fd862761a51053533b66ac6f63aa6d71f7a78c1d121821c0731b956f612aad40124e64709e2230166ba55e6909581b18b824d3dbd95e8195a44fee81aae15e330e2d810cabf9a81fe04068efe875e248eff6db96c2ff9ac7126bcd68ba221b0fdb749e968c1d912a56088d90bb1604715a425afc23a5bc66855ab5463ae8fba537447bfbaac86808486d0ffd43eb1b345bb2685cb4ce4896617af9e84bdb8fd77aef12bc39fad9fc290c1e70f6d26a61bda9f252807d97377061955eb2f9b5338a262e49efc0e0d33ca2b3c453fcdf43d42275907c6aaef23fbc76d55ce3bd2cfd95a128844b1049ed35b99e4b4fef376cac9858be130d896f88b0d97c778e0c199651728350467101ca7b0bc8e3399b5f84b2cad7b4ae341bc22f0abb5ddc5a9cd75fd388596f7cc1273b864e249e0a2e077f14e58653a25eee0dd2fb3fefd6cd0489419bfe32507bdaa7554d814bd1be8a39605f92ff26f548f7e0f867c945e0875199fca6769ea1b27e9212794014040a4021027c729fb1f3a40df140f551d2b85c7d5922f2f272e4f8860cb3933fc1248486ed525554ef76c9c375d2bd3e445791402fe3319ce0328a9e8ff7ff7c0123487c80868f7aee6db51a0c676b97c282afd02a91a42261521f24d7047708c3b7eda032fa9453a9c96c5564c5d2c2d2fa87d3fa70f4da41d7bbd6e73e1c2f63f834b5772aa9d6a338643de6af287a2d83de9bb68a1dd2ec63c4a9f252fc06af57e8552a7fed38b540c1dcb98b8712ec27250f27a719ebf0040db85ce9c96e80971098eeeea914ca06678e98af50844f70c77007dd8b75e27eb0c32ee2e7143ab3d64c4ac0fbf6ad6ee7b5fc6e709a54a5c35047f958de9ca2c90328999ec45cceba21c9059dda69d4723d426725ffc5490e4863f58b3e345b6959a3560b5da78615acb5bf24208184ff828607f87e48fec93a3c2dc0f6710aa545e2d3a7333daed98fc0a7bbcbe4fe8fffb9ed7ea30e2109f86b829b9e845eefe1729fdb2a8c5fc64f6ebb31749c40dca7b0e22a7ed54cf3b4840107c92c6f36b8d870e9161f1825d6d4fb0fefddaef829a81920e56e0187d166fac9f80153737556872a3fab9a766e491cc2f5f7b7427d2cd4a07f1f1a31264dba3c85b3c8208f4d3a32073d5a5f2662fe20f250294c3940570f7b56a4981d6f06fbab69c0e0c412a0d255e7094cb76c32e7c20fadb6f1c26c3e82e1b6638d7d97e0bfe481e7fff9888787b9d21d8f89a1ff8855a1d037a0e0cc1834a962fd65e00fffe1c1d242b4783d6bf1a836b01eff59f3b1fdb77ae7a39fe801bc05605bc93036c97559475f706bec8861d0f222b5f5fbd1aaf8a62c556656a27ef1714b5385e44ed9a5886b4e8b87c6525df6ab20d1bae3efc3b752b20f444bedc6332298bc1a4fb9e577670f2e9601938ce15f7b75257471edd90098e7a75ff71e0d29b0539cad0ab572f50c68a066b1200c7c20bebe33cfd89ea340ab73961e3162b89a4ec82ec2e1996cb6a65f667bc22cb8e7b7ee91e4ff6f786c4a857c8f1c63b71df016c3069613e2e50b14a5a991fb9aa67913da73fa5cf3cc861029d1550f8e562756430d35b7f4c92094327471b71e4a52da765902dc4a4f58b2354d5b42cb8ff992e8a8cd7711de5cbdbadfbab7684ef80d73d60c38ad74532a751c8904d76329bbaa33489081f2f96cfcc08a43f98a46d90da7108172584abd8f3c0aba93a82328f6b0e4c2fcbd3a8e02a6cbb5f5dee9587a186f6b2704bd63ec28554a6e2c1ea5199a4d394a0a745932e97e90c01fe9479b9978a5731be36f9f0fe8c376865aa57a0a9ea3ee28ec5bae7c252354a6f3eada088ec2f83621d5323665ccba46c0f5075303b7540466612181318b17793ba5f352d0c620a4959220fce962b3d0a17955a9ed27259aac3fbd3e98e67f208e23f9329e2927839180312bfa1a5e9e8c6e7c8bdaf9674c14fb3f929ad576ddf4b525364bbb2a33f1e2f16225e48d8a6bb5569f451da5d7dc5c095f44db46e01d9a33be6f6cbb6c03046e2dda85ff0be39d005e2d9ae011dcc0928474c1d7fb07b8ca26e163591c42dd59b2faee37364a59d4067592b623b3330beafd44729ca9121ab320ddab8339ef2cbc3e0158f7368aeb5398e51c11ddb35275098630bdda7e613a859f7ff720245f28d1b753f961e7c542dfcc0c9bb9534908677e575337739dcfa511978427ca5ca840299ee92fcd8f6d63b65c03217feba4717ef6687cbac0ac6da24b9dceecc08c93f716d7f6ea704a48f310186165f6afc536f5eba7ab056c3b68659f95aff4ef3ae4c6f30702f7153acee1995be5b1afe608202523b74d88b544403dbf6a69f86eee84c0a6ccd537a9fecffa555786b74bc927744800195e9c8c9a6cd243425a9d60fac5550b40c7a21e5877484f9a5de728220b9258f5962e9e2458c9db1ca34103e58a3206eeb37eca1ffa3ac2d84f1171a95f09fc8dceffe92cff726a971c28f1b6607cca3a9cd72497b74f8a3414ee3dcdc80552576c27007e84f784daf278184a49e5f7f570e2ac724f72998f0ed41610e7427014a0da6e47d11f8f9d2486f3465cf0e3b7d71a2079111fd31061e3722d4baf6facd016c6e512afe6aaf6f9163ed9fe81374fc3466a7067168cf63b4f2a6625fbfa1844b9948c44ded393882956debe7b0c97d84c71c680386db63ae43e847b9452847029964674581974228e9392ecb9b5d23b4281145b90c00ed68526cd75ffe6db153f2f7f7c349cb31c673084a4cce6f31347d91a5de75952b24b7235d804ce47356a9025ec5cb1ab6e8dc5f9e4c3984deea069ee66de4ce7390097bb9e03306d0af2ae48ef356c25ca364b654884fd980bd896b6758fc5199765971eed48fd24d92e4b8254d11aec8a098b94478502a7a5af7d0e94e0a67fd2d064b5b02b7a8a13f058f5c873f9021e2c094b3d845a56feaaa27eb7e2db676c3df3cbfa2c38cdccf5252f131b8eca2bdfff21ccd0fc631ac27fd9c5b63be67b80652f244b011908233742a605f1841604cf12b2ac8ef055b69679427e6f8b1304618d8858990b200a07e0efb6603c13e3f87c1717585f4f6825f4e1970132b525cef1419c2f8f4e57e1ea5689b5918b0f43e1d5d2e9398a4303fe747164d0c558df1d9054ef2a8a650362884c820719b8c08198bc1cdac8a8f4579b5f0131bc06a4f844ad7421251f10a3cabf3900aea9ea19488a2b321185beff77bc3c8550cf240474ead950ec627c9cd9b3ef2fdb90d5f18be63223b940824c5b570f69f89eeed91370a7690e2b489099e1e698da828814790d4443bdbabc5e659a7f02c3ddaf285449255f0999b11371acef8c66774f6dd9f5b2d2a73efb7890625167de56f47cdcae76e1058eb839ae6e4c15ad7e693a5e1a87151c4e58e4114eb22d958a7551470c772dd45a0358476fe073149219c70de0c4f82a017f019f89d9ad08ff793ccceca2b8d9d2ac4061a7b5b4622de8cdfd0d76df9683fda03294e79fb3285b7ba1c5dd68b719a6ac18d783edce39831c1ed7514307407db79c0d5c2e7dd4e34134bfa35c66b463b3022114cf2b8564da8ab2dff36bb00f000d84e9b5c8c6ba0167205acdb12c531621d4fa0fee587c40402dc4ca2cac4015466194a70e829c47e3e1678977d110b066ab5a9b6ab9d8a6c0d5caae916056880cbfa5b1e0fb21ab8971b487e075d2082536e3b29b00d6187290144f87abe25b5ec5b0dda601b3bab09cc68bc2a3bd480968d3db9696891d41303fcd2201da9e3e703ea6ae5d6fd730b9bd3505eab9ea98c5a690f1ac4f7d08b319784334cf13603c3a1be9bd9840bd23aa687d98d4d83156dfbeb4648b7f922282bbc499a76cd79e639bd946a59df524bbfba46ad8727dcff26f7a14bdb63a55eca2fe1a82cb14cfd29df50b9cc19a308f6deec258b3a31321d7a282c6cadb7d88539632821d30845dc5e64d08801c25f10aefb7256d7d2201cbae6d5c6e12d161556ffb1de9bfade60062a08fa5389d0fe5323781668e03cf53bde114593e90ac8d8fae1b593d3cb30cdfdb282a2cfaac0780733ff6f85f4c5b5b99d42aed5aa94ea96fae9f70db45a4df2f4cd3e68a2dcf0855300e7ad742c6e829004b44746cbd123b280ccff2a7b8641b491bd28eaca09c9ec2546c1abca444c9cf55657394ba5879a1dc50b5116ee48cee8f4e9440e2d805fd1117e2ab67ff31b4244093c2461ba37b053448fa15e878c9de4b4b6d088dd8f7f74a303c1367ba1f789c5f12de44c19ae4ce8bf76564a8facf3ed2526d8afa930afe17412ba41237bb0e07edd5dab7697758a1fb42d7d5b618b444fe27304047da7aa010950fa59187967baf21a1dee78a6a8924f07489cb5fe4a0de4cf110daa255596c8218ca4e0a7012cb2f2d10c175c4032c50ff1f4557b8c726a412cbb6ce3f0262c48c23d8f5b2845e5b69e45edcdbbdbec2bddf4baa6d57f927795d99fee2420bd06a41a171fb08e10d4c6243beb114f5207d842042e1562f3dd490c1ee43b06d4b0eec4e99b2a4af944c4ed43c96eafb6877672fad98bff84ebba55aea387e72090724b096bbcc97416c92eeb2a8c7a119bffb6a44f35016d6523124d9fcd47d3944fcc94dff1dd19c90a633db1c569608d3ad3263249a64f85479a2ec89670a89b44a4668f8e42b73459401d895936ab587f43872abf3e477c6fccea4693dd3fbd0cce5da470c7c127d971bafdf2bbfd844849029229b5415437f9c0df46ee948157ce7733496a2b19288c80cf88486a8fd724838b99fd0b7676ce590c041fdc7be261fdb5424ffa25c11829c011fc0c3c6506c6842992fd043ed8a0a1bf9856d2c06a729c8941200f763c4cdc8304da13e84c80059a05ac2a1f59da01280cc083533f9d5234f3315ae3264c16f265c8c35f8cd04cb081eecb36f3287e0d93a945beb51cae988e1f18d2a17144e23e0dc7714ac65ed38e0728f6f815e6488186b3bc527a74e469cb393929bed40a90de452cecc95ada7f1b4aec32a94a3eb3865aceb5b47ca65e26aa27a23bfde1d9c0c8e51c98c59fe07f39b04f20f74df4742927e5fa4b0db45c63c2bf0c7da0f3b216d774fd1a98c18be2c0a73d96d64879af17b5f7f254fe4eb2db48d8e51bdc04e0873eec103865e584135bd4dda47aded5eaa21f8f55f636571b04a3c344d2d75ba11812604e19fba514b8cd0cf959e6fe9ae4f4b510136eda0b8caeb2109496278a24dab20d239794c4a03f6462e92aecd4dba1f28d6d3a4803650d36f9f566ccd07d781f4e90d4e2f4bd62ae6d28422966a6d84931e70dd6d7c223aa7f2aeed51c9ebaca442004f25238ddd43d4228d865f2abb6d3fd9c08863df261e94a68e07281db282d2f58abbaf51aa34215489d4e14aa10342cba2e6be706e23448d37f33a7b5f4510ea51e5b2ca26b170a8216199f4b70a9723dd8d91c1a6645f08fe349204e6996a3db49b0e21aac150ba2f0c2865c9bbd3b57e6a6e42cdac63c37289ac4544856ed2d1cda1dff43d50c6a2f5aa6354bc9b9d8847a193eaa2aca6def7bc163a07d2b11ff681342448918b9b02cdeb598587a9befd559e088aa6da94cf1cb8805fb483a3c24ba4132db2bd63b9870cc865b479316f1143124a1218e08433efac0817914338a313eda1db49bb4d2a03e3d867c50ec48d69dabaa8e4a85e0b42124f2e84be7be612e2b8871a3b75c39677ac4b4ac892139f9bb3e60059ec546b8ae2a35e5be71b4e4c01f0cc93fc9df79bd3593cc5881a6cd09d5141a0ece80a28a637105805d317b3c3f4ac140e84ea9d1311b4824af3bce6b7b384a7b6f5d9d8c68bf2d062e097b90e5179a005bc7455f2d760f32eb77723c873b46e6faca34d265c5b8cfcee609a0a580c63a463f2aedc502b1a44830095eb4852ad9997ef0371c4ca0823cce15a177f3eb3af0497ecf6e747c016115f22260020a423cbb9d809f82df48442bc48e1974fc32319cd0102147acdfabc5c9ddfe958ca4771fe04fbc06f22aabc5b2d04110ac45cb1afd169ec832628adee724b3425f6ec715edcc265929f2a714c61a8bea5c34c4be9a944e2789d71f47b225455ff0d59865cfa35c4bd2ecb2b59ad68071b1fb7c7acf479875728f7a07b9cc8b45c8075d989c185bd85e64b0eaff2c5f3780e1e37077d52346add44f71da86892b84de8ce643ec1c1230cf29e3531c6dc752802e6270a28dbe2a7746205300e19b95c986bf02c8a813065c3a93bf602612fe04407943ca378baa6bc5fe709aae5ffc03963fc123bfad8e224ce3b3af9809689aa483a32405c3adbe8d18940a1c34f755a1c60f154912da1f5f6b3e4c0dd90e8732355954980d90ae1b0988589d9a136eee5100ceff46ed0c8e6e29ecd15da0899f24a0cc2c4f7081f100e0485b076d5f7ed34f5cc49ab53fc1213991c8189ae88abe91b5c8a1397714c2aa534a1f56ee0b5fa9eb145b37d5591b5a73d3a54ca24a5fa7ff7d490c083a21e84d4efabdf4aec6d9953ddee5063c630998255e04215799f27b38e00adfaf3ae1f019e0d5ea58312cc85071de1b6eff6d38d42289fbceac5cbe82d0716923db10b169df70ceb1f86e7ee310dc4a616a0beca976ae6ffaf89b2939c8cb11643c98f74991fbab76395e408233439bf8d71591154fed55f2bd8b159ef8709595e0961fab591166865df950ddec3855fc5cd8f2ae19aec444357ead7a29188b68fb37b839c1faae360448c9922fca6205616920227d73b0e8ff0bd9c1963a664d89374d987c13e82527843ac275b8ae9f0c011123a68d86ced6d70f5c5be30107e770f6f56ca667c07e3c8a295a0d74385c068405ee4264df552c19d0b1c31083ffadc86386208dfdf6eff243e30af25345ade0110a1ce2b6db53e06fce648175824b912cc566e5d93b22a883b929bb230b725d92f7a88dc9d3728729499975e846a0376970500d2b4be2964da8d3243bc27a8fec6d961010d9f1cc961f79db376f8daef50bd942708627074ee7bcdc812030884831fda241d124ef198c689336c93611e4a097e020eb6c15e5cbd31d47b993a6e9f6f0dab147c519601fa4941a260fd488b3344847d7d6bb3023e0d89d16faac81eb4a3bf0187607da10b2ee83223106f62e369bd2c6d54fb0e62525f7a355b9dc0b33e2b2299a8a58f34ebdcbf7f947d443e0ef05eb5211d24daa4cb98055c46434376e854239452906aedc48dc193afee0ce9dbe2c63c300636ee639faaf1cda5bf022b79df993d0826b348df984a209afc1ebea84675d94a005674b646ab98b60bdd108c6e69a2f021162ed618224f483ed34abb49c7b166a096676c3a0b41cc92f238c801986a209939e73959d4029b96e8d82ff13f6f42ec75ca9b5c242fb59b747f7a459d3c5e85a563a501dfadeae23579c0bfa7f1e982cabb02b2d0a0d4e2b6feff399a07090963e86b07298f46214804e4fa339c098d649b74489bcb43e351a1028da67641c4bd0011de092cb2cabda1c1599c5428390936c10a741606f74132c6ceb2d83f5e57cd3d6ce84b368d0fb880a8416a25168d7dfb02daa25dde0c89d47a75f9e9c896b1e7e6051f65ff609aba0cace09395b131a33a21b02623ca23527fa45dc39a5decb49141762cb9b2f3dad5416640cbd0b12eeb992797578408aa43e649856f20dae9d1848fd96bcfefbfd20ed59b834a5d21fa2fd5ef91d6ae3b066fb006daeaea0c86a3710908da881531d3d7de17ca023de02afcde2165683a0b007df14210d535404d7220a23d5e2be44e7594c1d911d69db352f56dccb86f7f89f93b19c3105df4126bdd431b696be5f6a7a7abdd57de7a2ea9efa4c36235f5daa853f0cb5cfaf75f48ac70e32bd7a4b330d3af21a85a8abfc754cc026c3d6a719988ad1493064597437d1f9bd74ebfb1d3baa8c705430329f92a26afcbbe0952eb6f415bdc2e937ac61515a03f57a34e101d79e102930ed8fd61b63f674c9db5eadcb7c2a57e0da2c06b42bb7091beae3d2e655ab67b3d3cc4ac8813e52190632234951ebbd225e637abf3397615951558c8d65b8bb503107b4919a7280133f4f7cb22233ac6baa44b2a39bebdf2276330e8928b3dbe26abf017dedc6ac49a847286479698647b29ae47c6ebad94ed603b83a21e460045542ec05d7cf0b54d1ad07684a3696f1ce68693e1dfa881b1e9e29b597095e4a3bc3a1c3968d6aca746bc8623b3a6f8ec5219384e78eefa942713715c7b92358f938e1a47d45e8f9d44e566f5dd1cece355c551135a988ec157d743208e44aca9f1c0f2621c160f2450683c24d0d7552b0856045665486c5b5e4595571a3ead860e15cc915f0ac78b28e51cb1d7261fe08ebfed82e8f15e5109f2290d98b6e0d9ba61775bd314d2d69f8ceb6329f14cce326c8284f989e0329a55cd59186e899253b328d5a7871d5c9c95c113d86580e1a4442ee8d55bcb261f584e9e066eb30282b95f76f54496b9d46a6e646ea5f010b0a86260699862e18afa398b05c04bbfda3cf75a59d171a05e6534c35824e9940ddc790d525cf2c29d346d4d3805f18324b5a5e74dea339dff13740a5e14b9da9a01f7d3376b4bb9b4a17122a04a89140884541e04485068125e3aa73af82ca4768fdf3e42cf50b2d9214fb9be57107c439f4f7c077fc2975e2f2530c8fdbdcb74be95316b1dcac66d95272cea8a5aa3406ffeabcff729e895413a16d4c1215632d81347fc21d5fd111954193da775e3c8dddd8eb5fac32201dd3db2b4be08468f62f2d181358253677146c40d6604e592c2be1fa4031e92f24d45dce5c19520172a0e90974359fcea2d4538b75a7326acdb18288f28ebe245e98eb32c8dd729882635a3b5ec41c35423a656c0b7c176f413005f5479111b6f8c417564692721ecfa6e04a07bb85d65c3ca6d8423f42f116995a927d7852447e7f06a46a496b38f3ceca4d32af67227b124e1b58702589347acb0a4c985199cc58b630dbf41655dc5bcb3483b25783231caff47259d2ae24511ab1126ff4d28d1338e18d56887bcc8b4ca90fbb7360e53e2bda16df13a54c6c9065bba1a86426cb9ed6ed451670f28ad4d0b919dcd999456a6e96c950292fbe1916fd450e3a9787e910396c277447a6e884683eb67bdf4679983603b26cbab3459b5e10c1c29d19a0b37ba8f7fbff1d5da4daab4a930c3a87cb13cfc364a76013e77835354536bd4e5e1c3c8f89211361e23a97e052b41e05f86aa5ed604df9d141ad6d5b5bb873c7a7b6381bf78430fc240f7b08675065073f7a59175281530c39d64c4ba4df11d88d531d3753db6eb3d5cf0348eed7d05442880eca7f3cb76d5e401dbc54f190539bc15882f66664b0354ba9542ab9d9c10b8d5ee3efa000bde4c61de310027d834af9e4a628b557c3845ced15dc6c879d449e89cb8fb41e4b640ffc3858ce783ca920d29973cf2e9a19f8dda481b3f738a8fc87a53789e3294c2c0cacb19dc07db40a10d4bb4a8c379070262a01f58d0d86e851fb7db8c6372d04a844c1b11b321e660ca99159f7cf55e90c4115971a2d292cefd68647f9709f6b335bc141d0c0caf6330b5a79a9ae5ba939d7b9089c80afcea7cfe365421c4c469754aff5c64db1cb28570af5eb2bd114ba6ea4d556a55e8d3e48ce223761d984292b75c5963c2acb1a1267ea23dfd3f0d592979eab1e919b192b1bbe837628d458f96be8eb50d67c55e58f680e4e8a377af32cad6dbf9a827f083311f477c23e8c6bf1d6958d2365d2c0bee0f4b5f723bfcb3350d6d0e63bcbded9fe000b8523be58a41cb755a300815e533a8c678d25afaabd705d4844d0c4cad931d182ba713ea3bbb297553308670f05c66a50973d85e98d584024afbfcfd4e9de5bcf506a519dfb0542f6b77969155b50b65b92d933d3f49d2a684a5a8752b1cb4e3b6e949b1b2b93843f9b216e8cc2562d28faf9033cce29230b1be723f78ed05e1d8f5f35fa27af5e9dea2d22b88b808fa930160d8e8d2728501230eea40d3971c769d8e513b22502fb5f2428e1a4bc04043eab40dbfb2d512f3b144762856333f599f55cc48de375e47f579b1998b9c3d4f4a6b65343deb74e8269b77dd17b246b3e5dae2758c95cdfe64c9b1e293272948d9ff2f48a0cb08fdb7799383094cda8ac8e2a8dbb537e14bfd67718896f2f6f7c885baa1c14234d96dfef47753f491af8e0fc3d055b00a69331dd923fc28ecc1e778fad22cbbbcdba70209ff1aeaa8f30ebfc18ea550cbf376402e573b4617cf66ba3d6915409341b7197060af351fe476a2db5ef9696976561a29b8358851dd2de9dcb6411bf052d4dd4fa5b2c16325343e9c4fb5829bbd6a94c18a247a69039b956485da7fc0321a7b8fd1a1e9e1619a62e3669026beda48c820d71985e08ddcacebc2559af441c48c22ce22fb272ddd39ba8a64af016e771bf68851e8e14d51b1747bd4fadb9774c0a79b513c3cc0ab7a03debe4a4931557d29a1ca082f90d9fb38e9e387070db731f415d543cdd34ed53cabdad1fd471ab7b634a7451a21aee54d497fa49577e7e5ef84cf1898924e88b5b59c16082e1c00b8f073c599820a284f43d35d6748739bc8d384862c4894197bc544e8b7c14cf93ce5fdb157073c3defaef0583a17314b2dc6b45fab1ead3ec70ed8ea674840d91f1cd75389247413e090da5c3c936ad2ac6ebddf5169ba11b06c77da846cb23a5b38da7c1dcd1e40cdbb56596a14a8796f50189bacd28d577cc7146a35ddeda0626ab9569e0f150ac4d80b1f707388ea428ad747fd4c609db6285a9b23cc7fce5190385af1ffa7f4560039d43e166a1114559f04d18577eb24b23ee55fa8157415db95b5c04fa7af1e66b59382142e6a47217a4735b473826b904684701963a1fc181ad9ac354a06ea279e53bbe0aee6ce4bde15163fb7f08fc744eb667a93570a0eabb45fc96f4442342c466acd8ab6416e34f8ac61957dc0e8e32cc8fa73346d3bc9e6a3ef0d4089a5471cf51dfdae2f45fd7bed4d718b1dabb5af0746449423e5d54c842fd258ca163b26d66ae0b039224753dc0fe4eded58f6b5afda6d8645e1dd1e58f66cbea5e3cd7c3321c235ce7dd739d871514a58eff4755994ff25bd897ade3e0bbb676e94eae1acf1c558a11dc2b98c98b2e6129101c2a0d685b539d4413b89336e2c741060017693b9fb94f863127da64ee4a769a0ffe6fd91367807557cd3ed73ad2c9665d31017ea59ab6694a103c25d5e66d138d7907f0cd3d68776f9bd32987ec49642da51240b4af0030f57dcbfea0eab2e99fb53342ab7da51b2f1e779536c378daba37651480d24f987b89cad168b935a444ba9e42edff3fd6d52c02dac92d1717a0d1399b788c991e2293351ce1f57ada62751e75a9b2ce68435c6135d2100743ce7306d0dfb8d410fa3b32ade93bb3ffc97027452ee425e3e33e7f9ba06901aa1f4bc9e9c81652e6ea842f759fcc02b271c7518540abc63bc56a27d17d1be4be0f0d2b8d617e47e99cd7d44f074768337898b675d846acfc898cecb48fa629e95d590a971d9490b443d6d0ee02a9471d888b1b7b96e0aee8966434ddaa3a4a7cd343349a9f979c6ef6808b1b287b8bfdc2e8b78caa02a47fefe54e147363ca99b4b1d8f18d165f859baf54c79e61633a99160f1233636a3091fc0f2ecf65faf4ab4cf9c9119f43be4319f668715738c0a9eca6d68f3b9648ef0a88778afc633c556509c49fcf9500f3e7900755a22238f7d65769087f49b75f32f00c0277a367963023751faf4d35e7f8ed059eef6c58d1f79a89391c6c5d8deb5d6055d9e8e4d62f480d4f2eaa3e27b2ccf7ae13b1021a1fa97007357bbaedc8d8054394eae85ae3514aea9fa61d23ad7f5f09108897ddabbac7a3cb3706e83334390cbd6942fc07b7b11e79f7b6b742af358af662f08630da07761e0220d285f70e6792841f274b7e33f769fcb6bb0af570ee03b640b62adf938d824df6eee353ec8e8b2998c4dca7c33d169215c2f32ed5716696d8a463fbd15e2985225bf666a60072bcfb503f475a023e2d1d2edb1932b821f271e23eede1e36b37c41f419e6369cd601bf115b073f92c9f6df1cf3e6a32d685319d2a5cd167641dfb90d55c4412a0803b5d08564915f4c62896fb6e9b29565d5e876d626c2bea45f8925824d12e15685dde6d2cc9767f61357f0c6f3eab11b0b398e3f1123a50e7fae77a9ceec0f07012ebd92b041d4b25de7a406410bc1e21a4ef20376bad085329736728a29a74aa6a3cf51b107dadcfa139252035ac1cd52d4605f96ebf7d941f2b5a83a117ea48820c847e78d99e59a6dad18153c2a66f3ebcf25636a7d80ae046c16a207fb22d8c80e32ff7b803e40d94354cdda2fa2e218e2f8b5180f35d40f243c284ed8f3a58d7d4e666e4079a1cd4b31f9b186c76adcabcfe544841c1cca6babe302a399bec5cd2781bc5f53dda7547ba7485404a6cd308ee45789ceb440b0f9b887d7e987be70bc3e559f62b7d5f21970f1ab16c1d240148faf9b564335208947fb98d5964aec37e2592e6bf1200ce81c984fde75a1c09d0f955c9fb410c8f94b52661044259d4d9c99a7756587c8a060e31ca7e2428f62d8ec8d68bbbd1220116a27b4cceadc37e8dcbdeecb111cf22421914a2e917cfb8d1c77c10db9941f2e47d9e4c3d8d500bc111b602809e023b6e1f4b766dafdabfe3a4f7ad6a52ff82988847d8dffc3738a08dafac847bb1bd2bd71781ccfbd136a410606e68e9ebefd96f9eaad3becf1a95da53a9894aeaf261cd5877065694ffab84d9a4355f35b3474aaa55ff2a850d80f44e60e006669ab698b98971ae83ae0e8772d213a7a26aa14c2286c2b0e54529e7b5208b00ce919dc6e742ae03e6286b5006f30b2cddc79b6c637c11958adf25f253268b13d1cc1b83fa2d80ee569b1544ed662fff3159c1c19c34e66efcaef24d2a06ebe3dfb1d87ab7a52e4a3bb156d05bcb5e1e6334c1120c5fa2e9bdc2781e7e67efb2faef9f2e6a2df13cee5fa0ab79fb9e3f333d3f19859b945e64e11710cce852161e1f651114aadda444f520fcc8cec7bf3fb3ee6aaeddfee645398e9b1893b7fb654f27b967f98966859d2032c6dad6b427f1cb4069dcec086ad4255165559a8f053e5fa3b4b72fe4b14c8ecdd62a5dfd352dbf5100ee9c5a2835be795892c8576043f8125485ce2f94304377f5d12ec4ff55297fa2793a5f519a1805cb0dbd594255962caf4642cc3eb1b8dc5626548738445612f040e8479835994d4b650bdebe7fb74679358e0fd4ba3aa823fa4a81723551607e0fdc375374ab09ceac366b5ab87b4fd978b3d1f4a1b32e8c0c8c4fa62ef83ed4364e471c940a07df069343dcd2ab2f5a0a317c5b87492bd5966e4b24a61bc603cf0e7d5128d57529e52155abf12fbc8c878342f8578c93f9f4014b5c387e85bc5f3ffe146896774e58374ce6539ea99168f57c656752c7b27641d5d46fe6699380c13d2a3bbaf8d5d795ce9e576fe17cefed32899d79725cca3264b3a0050133cbd42ebf6408ac34276f8a878e1a043d54bdb331bb886ad396c584f4ae8c0a318438eb845477c56ca49089187761212b7de9c4bb1e3a70b2b8ff61714d9c2dbf040bdc24db71a5b419895fa93e81f6dcdacc11a74effbd4e022ebe824cd64903cd325bf8b6e92265169262657c7f41620edd19c67c8d3b6ebe5109203bf5410394f33f7d3e96f6ff27534e2b780443985914fed32da257df0beed1d376e982d3074d9e5b9fea1a2140560510eaaf3425d1894a7bad16714bdba4f3250526a0dfc0d697f16d375e7e4d5b99a8db41b6b35dad96aaa11950cb8112149c7550d3e774183026a9f5e32a6b04c6a2bf9b593b3de524d6e0ef6eba2414a5f9ae6b4440df50633bb5aba0fbdde7411161e2aa95ce28916a0eff7a277adfe0e69f1319bd003910bf6f8785fe45c0e7563dd7af64ff056e1b6b05a1cb851185ec6f7303e0478a087b7cd2dddb1da62cef7e9376bc3c19af9745b7409c23e4467533b2c8b886133993f155d02cd6ca22974adea8f22209623ecb3a9862d92e19b0238d44011fc9a7a3aa4f988f2c9ef41abd2c14f0273b8dd137ec901cf83bce62ec932c66d0f319f2ec2e3a00bf6ad610ddfce1dbcd53bd170bf8556097f48f9e8387013b77720f7fefe5d2b47c1bd081f46882d3ad801007303a02c958aa931956aa3ddf8190ea4dde479d87c629df1d7f0ee50bb17c9b002ea882580bb0f485e183301f135e821eb5c6eac3d996172805d5b7a6ecac3c9764739ecedf7f1d9f43fb42a9f5cfc4c4ee312ae3b292fa42f56e74e946fa0a1cba79b3d39c68a39a30712b817cac990b6f819a60e37230b79292189101f9992bbad53ac523a257424bacf5432226602f3c7c435a67559552c21a4d09d600f9504a4c6a687fe75775a1ad004116bbfeb49c4072cd976de16418b47608b8c6b040158d1185edcbb2337bdf1f2267f498e1c305c55c730633ef75a60b3dff04056705746bc00439b784a8047324f80e98268c870a69851b55fb7d01bcbeb68082892379bf465676de057347ea77e348caa100680a132088ef811370e1d4ddc2523c85b6644cbeeb4f8dbb85ce8776d62988e99ae3de8cb5b2dc6f394d022788e8c92b1f398b19f78ed04df99818b7cbb0f1bf3e66d481ffe101c89bd37faeb5d5dfe307f0525bb0b7581f0598c2c80363b85aeef8ac4caaca0ec91e0c7b05f9c365d072477c214f6b7f63206512f24f509d926bb337467bdca0766a6e8a82ca9dd828be5f571e1a355ca1d6dc613c830da2b653bcb11688d7a8e8f852738680f789eee354f9ce9602cf2dfd7bce84ed211b4f12a2240664ce531188caebf77d64c335920205f0ba4dcf3ead2951897edded067d4777c3dec97862456deafcaa48fa272e243ae31491fd81d1e461156d3ec35204877ab33ac7b95122b301d99ba86534112517c81c82cbf4ccb983f29a6049201c35fb6c31946d640a6c9191a99733aadf76b215f5b831eebd24476eca28d03e36ba6f2681673b3523211b07fc8c96b3e0c2c6f6a9599e0f0655f454f97da663c91d05e88940ea8da448dae740bc35b2be1e39ce30266967bcd01edd70f711c58c8f6ed0d5276f1dde76db614cb362e7ea50dd7fff6ea39cb9089aac80e462536fc6d7aac26db64dec4658baa6281c72d2445fbf7e0bd249ffc5a5a3c6e2e28f6247ed5b3fbbaafdcc7496d277c3c3dcb34320d70fd2eeb1b7f7fb4db48a25f7522d9daa452af1528d631c299c44f604194e58abee70193301e08f61351b8e746b124eab1a0a105a378f085afe0b4d58a7e3b1b9d2a669ea646cb4c80686ad68711ea06fb1e8f718f4dd5de6e239b49758cf9adce6d26c17333f479c901f899f2a4259f992f462d78d7c92835775f6d809dc3f41d43bf280b8952f2dbc2a716a6958f88fadbb0bdfb866d5f8d77127c917cbdff82ee984a6de1d0d4a712960541909aa09017d20d33f9c4aed55eb82dba5af7d82b936a319d7c662747b6639e49ad17c143c339724caa02cbb630cf745497ff8f9c4dd853f7fdee9168c6de00402b936a5e29a21f86b7dbf18c8427616c1420da299214585520562d9cf301a3e7a295611f2720bbd17cf25ecba278ca34671b3245e912d58e6ef832f3daa3403eca4a8c79aeb397bc19f556ffcedbdc9b0c4ec7b063da352a97811696e85a878c408fe6a2bcad56465c9ec60fe9315a7f5238b5deee3e3d1cc0e2da1a02126c141206e530855ada25f9b690882464fd0883ee6130a0bf303ec6388bdc27290cf8503ee9588191be08c2b3fcd2eb00e39cf6c3b7cdc5086ed80e83b48d7cf93c7e075008e962d4dec3e05863b10454492fd316eb89411cc2d89f9cd1e2c5767daa2518f89a78fe0c9d7cd44e8c495d878d0b3d1d6a24cf08ad58c6fc465c6d81cc6a4314c6ff62a142c8c8449c14872e78ad4cd3ce496d545c69f8d20a2f1a6a3641a9c0d0f8186c6483333c9d88967a3750ca0bd239dee97be036e1774ca80ac1f9db56ea653c482ac859342c7adcb8d8fe8942b87c32c3d95f4c524c5272836b47ca6f80b01fb7c30e7d6d1ebd1fed889ae52805468c370b9d74ef782887c1f6b17d5b67f07faf0474bfcf7ecf0d5c888948dd524296629737514b389f74311e28140534bd40801ecddc35ed1984605dc356a9d827630ccbd6f169b3949a406d488d8ab4a7e890fe07731c0dd5285c32927d94b8fef4e72cf6856a2b84e4214963c1ed815bec194577540b49979e4c7cc8660cc24f167069fd728ef5b5857a9992bea456de3203c97688fb351bd5a1d6327a9cfa0a8b396d2bd8ee3f7a9b61776ec898b5ae24f94eda499f8eda6b8a88c39b858d245012dcb9d3657e96fbdc59c5833d67429b4f524bbfa977b429c0f4d1a81522b1c50c69ab1f8685e3446c91813286f51a1b0f0098d725f85819e2ba2af3b0f472f1e9520660a98c3d2af08d6a9b986e311475556f28868cd37e8dcce6d48aae09669b7350e817c4f4d455813a49ac93959cbdeaf9ab9ef8662dbdbadb81c21628e4ac6d9a273f6bc999e708fee204f9f297cea9a680d4d7d84b208200d4d0e37a0b2e9aa7a375942a75bffc12a29239cac189d4a669e41081c201cc6b53530478c198211fbcff3124a19f9d8417b4085cc50d775776590b4afe196af3f19f22493f1fa1003c10d0130cee73f3a9211894d3fefd9c5af426588b0ee9c2209ccaff5a32d987705fc1f2a1aba4425a32ba8e5c8dfe7d2871b07c4ac66c9659ed583381e8388a7f3e9b7aa6231dd6d19a099e0cf8ae1a32c8bfb66be82dec5f50902f90516ae6d12f07bc329bf06dc67b36c5bf9c147a610e99a794d8914fc9e71926c572dcba97c09ce513edb1d1a2674f224c9bc50e55beea87759404a6f3d73a0affad11aee8de0cd15dda0b778d7b1127bd42305dd55c589556c7fd2523e410f18a4822d07b23ebe59349c3304025d19da0d3cad9e7447f63c255daf0adec04b8d139190245131c98251500919008bd7cc29e0e46162c5e6d415a9b72ac1fb8e0158d0bd18c3d43c5874d13d08aca9f070a4d53e3c6a672bd52a04537b49936bd2bb09fdeadf6a68279b0c739b744d1114867b83c8154ad2f195e3cd509c7c2533d4c5c2aca452db1109b81b12ecccd355086dd0a23a9ffb7288a10e64e42309b27fb7f131f54072a83a7a80b7fa2ddc67ec652f8d28c5fd46dd15d09deca299b73ee2567b7522d7d479aeefb2c49e3e9b7941cae558d284c1c45d2a82fa21a5c2ff30526cef1d900f1e6a0a4630a529de427efd714074fda231fc5c5fbcf9283407a94ec2f853a06642a01c0f59b1ac093f40b2a457b1974fee993755a7a350d12b40a1d5836bf41a2f2848bc5315f06198cb53813ec7153abb34aa1ea9d3fc0ecae48a3ec52bfbebb61a9e4e436fd8fbd0089537bf4618fb2776bce76bfe2e4134f44dbbcbd7920b595f456fc741aea0c3cbfc792d64524ea73b3b4691c9246c659f49f1bd426b301e2b98b4777edc7b5289b1e4137b00bffc492a0dc69ff65ef5d187488a6ab1452b6e220d3c78c3d6c038f8ab5a920f0a334e6662b77ea5db3ac903fbfa61c296b62966c935c10f4d9203d4f65b9f1431e831d9f42966e8f5c4feda3f3eb4b7d9bf996f5768a5b5974fa4c71fbf0d217721266d101d4666e06e5b72c86f00a98f0626cc6803e8b9683cca73dc52946b287f863976e9c2d640f505390e458af9c450abd85c8603e08f3db1656728a2d01e4cf632f969c94aa393f0daebfb85976b84feddbabe020b3aecb55d437c1a7683f79c7d2fe5598e6890f94c5f7d0420c11617a6036217a3348bdf62576d221afad37b9e3e5ec8fe85cee021b1113bd01b3d7a1dd536479d667347ec8059d7924b0a3e56d0a6d6211495eb1e823999d12b1a3b1ecd7467178f6df683e7ec1a23d8105c403823b7bf0e0b13b588e2aeb78ea1f8166f4b5a6f267d9612755abcf9641923dceb8fd35a0e7106a15274d4561910a5c66d21e0cae82937f282015cc20a8d25672f6779d933ab1fb3fe24b52668848ad80bfbb617d40acfe910323a74a33540f2007289291e838ea2e8bb58db7e32be5ec0eb6d1efbcda7545e30a11ad07dc054f0b9f339495f8a4a4656b0573b8ef0f8386c3a6550afbd0f7231ef15caebee5e86175285ce38d5df6619d95cab3581a83ee5b0cfb984394879a1102da9183b2d3e86e64a1bd4f50a40e4dca4735ba5e451a13cb3ba0983056145d087afa74d4211608ba473cec1c99b32c374364656e5b5dd3a7952bb4465f1cb5e12ef5c9e8119f64c310838fdff6ce12b6b897fa07223f2fe96eea5a8e57abed2bdb8005c0eec8e31567c9593dbe0b10c2bf6bf0f286f8f37ab008de692dd80690f7b571f359136d1b4fa321cc0626a06dc7cc5f6bdf8138aa7b663d8f3cc05eb1c29715f40e8e478d54e1fabbeb90fc0f5cb50e616fdf5ee7d70f55411ae7bc12b600222b0ee7f87ca81bd78832fd2ecd8941a1cc1326ff60ebf193c01b2a1cdfaea174b2b5473081810d69555733970d94343b98188dca3582979d70a3d06555874b1882261960f348a1c32b905c0564b42b69ecc971159e9c5957afbc1d30a8aefaf02227d7a83210e160307978d4aa6b08fcaf0be8ad683c42f394d846728e8e527dd9b18d50a83da1d8f87ffbf2f227ecaf52d0c925c6cd397be7d2f1788404794b041183ccd4342b6a052414833cefbce233d08e722a97df4fda25231804cfb5e65c260e88aeba955bebb39bd641c95f526ca7479c247045b10187620a9f5ddc8c6bc9575b5a5b46e598030a65e84a96c1f595f97e9683fa9aa7d46ec243ba096043a6fcacb5592b3ead3d3bc93c184de524650c3ce8544f625bf00e57cfd04f007c80a86d10a23be522ec117f6823476eea489958c6296f93f0211f6448cec030a6f04868ab1bc8cc37ecf880dcda0dd01dc2fd311821d8d3caa74886a341599574a98f02b661e6418f0d4f6617c1ff4c131e3f5a279424d4000472ff96d1e82a6929eb59cf2b6394c5bd4f753b99867b8067603142cc4ccbbf0beb1c74581d50bdf3b8e9d5e6ba48383a124245d9f1a07d5804cd4d90806d99f016a890013b9c3d7889433b6674f37634fa4de65b8aa90a025b5312cf2c39e60f8849669e29f9c971decdea75d96bd4e21d607210b2a00f842769068ae6d43d9b3b1f49e65f1ac98098bdd048d7b1193e1dc3a62ff5be06e1ea3003aa58470e9a2ee4ae7e7a7c51ba2e576527987a558d63599eacc700585f8b364cbcdc43c290732ee84f9f8b981020f936dc46f2ba35e44556014cac72b5652044cc5720a9bf72e6be8dac263d42eaa0069721325cb1445acfbe3b10ddddad88dc19bc0d77730e127692798068ea214e4b073364de21944df6c81f00db2cb771300a0153dabee5ac7b71ceec051f9281a6a9c51f51a1f7781c55ffdf94767dbc79f45d99a92af1d902c96121542c0b99fa1f5218d4be88417dbc6830692e5aeacf072cf0bbf54320226ec3efb270f9276a9893279071cfaf73754f12e1488cc04e835e06e7024955c5ce197b329565083feae294095ddc6bcd6f16be5c9f677a4f09f040b4dc2aef0c1b2846209e72690bb2dabde670e342d953a9967f62f268f21b609e7e0f25d3f351c55849678c849ddf66be2595c491acffcfcdb4327872c52363fed09ff3ca658a34ee71b8a31c987c82abb4329b4909fe112ac9ff1ffd9b59e242b29876c8e39808689d2783f24e5b074880d007b2bbe6d8d811fa4013f4d09431ef2061f1058f4c7310136bdec1af9b4a72296aa2bfe71610ee302d0c998b3bcdbe9b8c75228918405e227f409d73b652cd565e436b90427666d095f193e0f506b067b333a5b57d953fec574e06322e8be9c31ad79dc8c97b168590f77f2262be51e522b516b45120c012ba48ede0409f202a990521a06fb2dfac476f644fc6606037a0b5764d10a94e35a055e6a34278e71f78e0178d27bb7f566ad73192868b340792ec21955a6ea50701523d51b5ef402dec73e465d5cd2ae75528395697f94bf3dad102d6d708a941d8579f4da3385e32a138386b0e0987fd0f5c1ece2622ac524474df29b26c5ebdd9c7bd67660232dbac97125051109e84136b8cfb9273aa910c508a04bca12f0d642f2a5517ffdc32d74380bf4e0cb0199b945a987d57182e049c8bb08961f07d9a64e37fb8ec90d7a04e25e6b53a4f0c0638f7fdf2fedf646975e527477ae961a11b7d90a02ab0ed904f217d6081a36ac43db36d5f4016e8d7f84208829c8b6c4429a1ab9b2771f35b5c28374d8946749f774d06a0bc67355958d77647ae30ef38d9ec56fdfc8043c07d01d52efe020aded91fc01dd5a0cb9e782b167f1c32e991b8545d5c683fab35c6f85b14964408b50b7426d71f54581e648006590f2fadcc9013f17c5c701362db18ba443b6631d593582e89c4be66c44a489921c8a887a1dbe4279f844859b8b63ab3712880bab9da64fe4d3e131d5a3c0dd8f04989df59a0fe00795658ab785b3415ecc7735fc8377f79f9ab15a54610150e277885c3549accb1a169e12203e18be84fb92235e026f347f2dd09739ce88230ee8f866a290bd18df4def21aa60fad5b67686a6137f251ea141f7e976a60fe6c5707d729fea5f4be527d100fa10e9d29057022f79a3c360e55b341743e2565c6d3f31aab0c9580196ec58109257b84b8e22d09a4c97f890700a5e8f51280fd5457d2c210ae5860e7bb4197ff5ac6892ade10c36c59e743e71dfa7572061b273a292e24ee714c2310be5a330034d5d075fcea025ec6a1d483f75ab1b8d85627bafaa84f40baaf628601eb6e8803b9b3802d8466e7beb4d426817e8349f958e7e7b780ccfafe2fe59d7218183bb83323b3f797a2b924a16b15f5d83f2feda2f2dfc4a346637df10da5b8269b8da9a05db0df64dc484e533fafe94102d8495dec6ba9cc70b6bf1c6eb19cb02b03386516d02cdc953a438e01f3de5875d043e62f6669d1973407dc64fca22fc6985ea5f4e3619eac9059a6cda2417daa7eabe63f813346d3c936e8b4ec201badf7a1cd0a81597d81b6badeeb802b7eb9c8a30e40521f8008fc5882d51f83cc378c98c8fa19b507eadda79d9e93960f3e75978136b90f07c347448195bc913e10da551cac8c868568338b311814f928d97dbb493e874dc9f1154debaebbb3d67908b7fd3e00648042e47b251ef8c28ae37452de0da26ec303f57f7cf4514636fff83c576bce1d639a11f89adea8f26f8819df653d71de1c54e34b849e24f4f28c6b39565ee00fadfb1b99768b260adcb92be9ee0d35899dfdc8ce57f697d9bdb51161742d0c2f63109322cbbe9e0dfcf7c252d2f9c3684a65755b24ef090add42985fd620842f69082af220954db74cb30e387be335d349de0d9c310dc4ee2ff94bc8f371892ca9f6d90af0a6e8bd0209d94b57993c2777d32d9a3dec217effd1e026963b85d2ab05c1ba5f1ce5de39a9e7a5f0d78fa32b41944eb35b2d5aad411cbce16e8e97e5e19fe6a535d4250eb41b42801a0dc3cb46183179a5b87714e914c45d3fd289db5521624b3b1089817895488afa307d357a41977cbf84a6c414d5351e1b5820867f9cdc018f703bc4fe690a4e6887c49c8fb55e61dede91acd24d38c8576d883edb14f945879bce170967f31c6f29000de8740589b6fd9385d19c82e0bb1cf4907fafa0e5dbf18f0523a9a10b2ee350cf66c46444ec255294e67925b2f4b53414cf347f4d2eea2a008e6ba1bdf131c90a790d5bf3dd24bc44b345ba6390cda2053c9821d51521935cea2971cf574208b5a02ecc6c6530a3c1589b32c91fb8abf154053d98f4dd9e0e44ad6b36ee005b9d28f738613ce4b3d1eab2a3f337e7b585a01a2c7a96e2c641acb2ca7f096701665054e697a95f0724cb386b37aee07f9ff8487ff16826b89d59a8c06945efb409dde3d78dce18a7dc6ec706db32a3d9df5325d3db459eed8250cdc6d8d281594ebcb9ee76257be426430c8467167d1703d7138d226423e7fbaaa52015e80ace8f6e4b152bde1bebe36f94955319208004fa10a8aef91bb7764024426088c58172c7c8a189b331e8f3df15587c9442aa2035dcc157fe01c6d4269b1d1da8fa5319d2b3de454a82d19713998fdbb0718640b83b3337bf727c4b2a6ad0743d1377174a2a3ae7611c4df0372f3a83838f397e587712eb5e7c1f6f271d2b4ffd8026fb747742c236421c127b931a6916d9a1d6f114f98dcbff869172c6e0fe1be6438e63a852d84a67afdbd779cf74d3ee3c117e3689f2076df006e98e74ccdc5fde646b59f66453e53baff78af4513ad26d09780c585eb7b7d201ba17323ead86baf881fb4d8f532f7dfa4e14761158d2b3092d236163f02a7f2b18d7743928b51a1a118100a8b69654361c7144e77a22e3bdd2484df630c49f49d65e8a83276c8e2c8d0fef7485933c8646e63635dfb437f083a645d82f1ed23cba9ab90d3e5bfe37a403570b493ef0565f681d97acb597e0a29ed885afd41fdc8214d47175d8391b473454e418902cfb27458461aecd4ede6714bd7233bc56256166f718b6fc065341e5d691ca7676cdef071ba9b70b5467676f69a5e337c38cfe919f922ff265e644a18a9245d15e9a06633b026ab9dc8d0ee0b792a2b3120311a746e61d12dc3cd62a5cc0f58ff135331d317ce5b72c08af229084ced862db0082e0bb5acf324bdf5ee6820d9133778683e243ace2373452872848cfdae6fe5f888a75034adaa68e6ef3f21d787f78bd48f00d96d637626bf14c71a2a2e9458a73b495f627886d5964ee4c1d1a247abc84379e8b135211760cc46c1620106bb29dfd5ce4bee57a3c837e9982ab1defbb0fbc8e066c6f95f2e1f7a04a3c49d427273c10c6642b30e8ce42c15335b4f7a84b4da426063a633b2290ee9ca7d3ed89d017c0dc918b2b3a87b587092b7c8f3fd64a8b1c256c23525af1ecd0e0998b8ebd01c36e4b498f3c50dc155439c047828a86bb2453722bce06262f3b8c357846fd43fd14f973ba3b787b058561bc2bd465b091ad4265985ecf2098b1c0b0b9e410d3154b185a4e80e314818acdb025f7a7c23d271a0224a853bfca23ad8fd43ef143914b8f670a428e29f8b30a3d08a3300f84d02a01a1a07bbfb3fc63de534e34ff6c80f34705a0397f86a1911736949b098d2a1181e3afd825821738e56d493426b6f5f72b22db277a7ed99b66b39088cf5e1e1c65d5f67d0426200cd927ea4d1da9380fa34b2d26c58e5aaeb31c1ea5c4ed3ab2ec4661bc699f10b6b55c8809c4997e04a0d43c0177ed56014a7a33987314fd504588bb60430d6babd99e1457855e9d7092ea69dde4d02aa59119749654798614983888981a34b3911566f6e92c556cf9fb7c650666d11b93cf3fdc4f5832c8f3a1e35c0e7ca6d7cb4f31b1522f415e047e80301985c769be1ff648f17d6439b96c7dac069d969e4d27dcd68f9b81ffe1c8242a7687af2ac2e6a26da37c8b30d293e488dfd5453dddd2e501779c3b1580fb037a34ab2a5c9a9269b566834bf8d40aa225714574848767eac05889b0ff6a1843004fa6b63168780d85f964276e6a83c7c4b84ddbb48c612ef5ab279831e4f242903fd73c413c1cabb75bdd54bd1e0cbdf655e5f43b2841a1db53629ccd77d72e6c315365aad3814952777b35abce3f7b536550f671426d4abee4f37b7c231ec24a13e19fb3780c7aa59e874994d0389edebc3df5a9130f6b50304bc8934951b3f9f02f479dfb3e873bca5ce4a63c4327fd4e75ac2be89e775844c7109d35c0d9631df7ad10e86db6d93cde0984e8fabff696867474600688ba5d025713adaa1ad801fb0d313c28c721eb1cd1a4b4ab385c015106d9d368008ea1d336d46f1fc5d66d77434f17e2cf5c05c60eae7c8ff397e10940268ba72b9d1eb64723c9ca5090e2546e0fa24e2e5f85cb7c8433acadcd1022e15388a91ee5ac37165d735cf5eabc2546ac1f0d76203cb6870d321727ca0770271017286c94fa9abb6eab1cf1affb9b5d42ebaf3f923ebac39c5876f9b50001bfea35f7eea389cd3c10b87193b2071297f0fa025584fbafe662df8570229c30b280c6ba25de2527e277a56d7c3ad4b282164693c5ee854e0a87a8e104f9950a593901b4a5dc90dd939d14c092387023f885081f32840487518930bc057d4f4f41931e46d60d44f525280fe5cd3d0d86b2ffca54d8f8640989d2cba8ff47ea8a086514266095cbf890b551b688ce21c152ff77b68ccab03f2f017b314013cb9e30c4e2a6e9bc33e288c7741b7871fbe47d3a2d9bbc0bb6905f319294152d5b170d750019069844d2ec9090f75b25320eab7efa7f5d16fab4db5b41a24a78f948e26b8ade70f3078a433760379d542428df07a4ab7a11cbd89668234101589625c7cc71e9bc7dedda4d75d950cf7f75adbeea7646bd5eba045802e2376145d5482b29c7ecc0081be8f8d2ec56c409f00dde6246ec4e568e77a2c0f5c4bf9c9fd03303223ed625ea2789c599ac4c141b34342489b947208ca5c6f1a4c99be394a2efbc8abcc24c9ccc30ce7a7ba9841247e4ac4ab4a18bfef4c5e6cb412101572d3a65e8c5093d897fd38cea2c0270ec996cb1dff212f189af05e424b88e82ab52774a572833e274b08052a750014e812a618cc5c4fd422e8a350fd5784b3e3dbca46c600e870b43b9024f8d89d4ec0aabda8b7f86d146d70f8818814eb8b4481c445c7aa4838785545c9ab54a0fb884d485a61da0288bfafe7feef44ead805dbc3c3c35f9456d6a74e1251b87af87b0056d785968b3bb220731493c19df36154f59db0dbee25790afab2c02fb9c700bd025c9e9381db82e8ed2e4ddaee9952d05c938b8c6cbf4d31ab99b31aa2f91fadc5a8e37b089d4f46cb6e3a2023a80d83ebb7212b262b469bd19be81f375ceffbba845585cfd7d5c551c18d915929b1afc5dec18c7ade1fe2f9e86e5eca35019e583b8e2076d050b8f150a716aedb7664fa9192dd85caf712ee6cb599fa112b81e7186d81212fb7c706244d8b0a2bc4095fbb235eabf313eccf3976658cfa741d58f8aa7f7164753bbc0b871b029810323bccb7673aa1fd6c0c82345473b296810fc9a09fdca11fd26c9e13786e71144c2bd878fad8ef45e60d3fc95e8cd0145a7f02ae696c4c4c384919e4cc89f965aa49e5508dfd880a1a82de9d2f4deca6c6bf1809903f7b28373c8a516b812f026c71013c050860560d0bc02b68d9236d097556d1da53f0057eefa361afb337313a5f3a315c4b3c83371ae226b24e0e117202ba0ed3ba2ea61d4353e25b9a52759186fa1fb9a0c1e2688886b978527c5dda8cf89fbe95ed07cc2d7d9e1f3ca8f882afb089063439b6822f319ef03d0793c41ac67a4436a4894763c508154291a9e020a85cc4fa0c0ddd0a363b3b4609a895c31d0916411a03655b4196c20de14b75a3fbf720fb055c51b4b0074801f8085bb47747cec99b737467d1c11cd738c3e31f1c941fc46cc0180d9f4384c54c985f097db83bfbf6f99cfe8d580949b8e2e0220570b2cb3766876c253468a46fc08fc82ebf877bedb80d1b808d0b80a6d4f9b4e2a10642ee2f971715372b6f929c6824f2a2b8daf6efaf99b5e163049f311ec5f2313b3e6bf4b32b528911d504b9ff33828aaa7737a2ae2cd86073050842095eaf358f7956d34eaead0bcc8d14ceba455bf7ebc8bbd6a1f211f6479510106fb4856e9a9e4ffcb777b6d6679aaadd9a8627ad9fe53756a01259adc0c24aac99884e7fb5a05ff49d45ac09ca0accd3462982c23aa1eb395afbc5e7c3f5f6b40a80e4a88875be546c6264a44203b759453bd65ed32559f3208dc677a214a354f3c9ea24fb8a675ed3b562a29474f350f09a60b16479352dcc657d24c3e392426dcbdafcc9cc1a049551c762b462defe95decda8917732ff10cbeecb7f5152b78c43e2dc396607c7f6ce2d88518c073a124fcbc7aa2544b1a0008f89f717c1a5d7cd5367c1eacb9d66866a1f5b86daba4ccef3802e53343aedbb9130da917cdecaab4276f50949e7e506cf1b60bf9233874774030a48ebecc14b8ea409a4c22a71ab94220dbba7895ee82bf48712a38f567ed17875e095337edea6197e6c190705f8a3e4cc435b3e021427d2f4a915b2f9816cb2743f7f169758a024d8dfb96c1c7d5827826ee7e954893dd9e00abb652c8625f008adc38d0cf70eccafb453fded44480d7691d2d156c8569f73a56d01644340ef079b01762806a67259b81e3cd919fc9834038cfa9b3f032f1d4d22a4018011d822597b809fb696907c05a5fb479219ca3b1d6bea0f194c173d26abecd0d754f34028853631704e20cd991d8e9e7eb7eff2017fd421afc67e67676fbc77597b522235ee31ffe1a5344984ebd5ab184aa576e547dcdba10330b4c9100eb6ae83bf6d256edbed88a1721a53552ca7c1e96278d38bf95681a7a3e47a8de688255300228fd571870fc82a4df60f971916691179b8000f56af1d58c12e0ba7d455cfa1328a6e6d993c6ed59cea0dff06377416c6c5c557d3f3f758d18c188e29e2ad6764be1a763985b3dbf9aa1d2c14a24b11a966a6dd57d75eba137118ad2a8b59aa27466f604bbe4701e5f0a8e4b118721d73c89a928bd46d6d2865274d49be19cdd2562c00415e9bcd894999bda5ef014358b36bf79a297a87b779c6001f2d498cdea2709dfcd205c0ff4a09c8259ef092f12ae508306bba89628b43133693536ebeea780631dbf55c5b50b7af23203a6ecaa51a1db10c9bdb52c29232c55df6282e852fd7c109ca87a5156d45f4a95002c922798b74ebc6eb8f476f7aad6d9156d4942eb5d8f39a6daeb192a460af4d3f6741dc35dfed6846649ee3c51b63a20b186129f2374dbb92d7750591445bfcaa03d228e82ea0098acfc2cf9d324b4161840de1921aea117f1859825646c33a49e371339f4b83ceaf1e53615fe5733f6c31edeba9b2a4668dafcc6bd28e615087191a513423f494452400b31afe7262b304eb237951b56603a04e897751dd26b89e033d7dc0cc656ec3a08cda515c4d9f3b67a8e8af9e56da15ceeeeb0048de4cb6d63efcb63afef2a721f757d31ad1e0346d62da6e5685c3f76d6d11fd17468f19451f32d3328a86dbead727e7a45bc05d3800eef1daead84b467651f01098d1763296493e72ad702cd252f3709e4f12edae0b1acb671c3dff55371bd1d502ce1eac2c264490b7941550b031dc1e685c19727314552ff4b7c9a2ced6a83a4be5e5f743ef9eca976c7519449c433787da49737710797c25e147da153c9f57919746f8d2b6de85710c25b40e2d6ee5fa396146da866ae2e1ee64e37098792edc9ad48f4cca662b1976a60eab7c90d917e7af8b04347134796b6d8e44534522109aaf9d5828f8c541972861ad4212f9b54e9a23c19927f4164312859b53204340dd892745e1b12c1f47ba5f891d7ab3f029f3e847bd31e413dad4122351ee411a03512b9bba82b905c7d882427265b751fe29b5d517bf26170e3d6fe13c64640570db495c127dedcb0f469d653bc703c6feb5dc415f53da75f82a84df60be96de63dd9a409d59d5e2692ca8f083d3641d5f6f87dbab7b528e6a0b7dbde54c53d831a9172ba71ef8db19058ede6aca61e323b2c00b660a55bcb23ab4439d950be7ac145452f85d312f746fdf7097cc22699d7291f3881b88047ce06555eb078a4dc6afdebd33b3f31450d02c688396d778447be5c21ed6a68bd5ea0fb9ed0f2873726a1b739f3fccba85b94a1b3ba819c76fc97915fbe25b18db6fa3410246e64948ef1a1f1c6f06c73ba4ce64621a01d33f0c2a71068f72f0337fec7aa2457b8da620e954e4c2e3e6a4f145f966bc2c30b0ff514d23ca4b85c11f35b1c32d98d8d25cd4f4140a0e207affe6e50eb58eca5c7c4aaeeb58c81214d3e75036ce3d2d90c5fe81c9beeb344c3058da6994d7faa642e55ce0a3b7fabccfbf45aa135fa927561ee455aea00cad181d6dd8e2bc9a34883ec2564ac663c0040aeb0907096302d5b25e030ba8ed05d95d3f67e6360d14c25dcf5630b3358cc7edcdce6c55171a102fb8afde4018a4434bfb291729aa55d315c5b40b208536010fe255004ca31ad31b5555eae58a0b13d3637cad000bf9061d26aa2e86c5050db188ec194eb9a45d13a63f0ec028b5eda34df51816aab170086350d534a257b926557daf21db41d8e3b3777351fcb73c8c114a9c9df4e247017005166e99a6e31a5423479c5a468c6bfedb4e503cc4a5825d96c2e4d390d2cf8db9cfd67b78983ef01627cd32faef46718c49c1221fe5f8f18feee3abe0863696b11b0ec48cfea741859ac4a550233461e0e1d1cc8de2c757ce9880fd1ef68265fb2a9b98c258289291dc46f1979d9c076f268f4c6f5c72551f70dfb15956ed1cbbd1d0327f7574fab0bc759fa5bed52305c811f171167d2ab73127e8890b6ab975febca219d50c1409454a3ba2a2d42ff45dbcf0c826d1c7e4ae3eb989eef9b33e9aa4a1d84c5d1754d785c2b2f44f3ed2616b4642535cd86c0d157acce6fe7b440eeb9a3973f12d6b97a98d4e7c1d7ee191ae3e69d319b829222c7a2072522beae856ab7864c470cced6bd3a7f6625ddc946d63a2ae280c538c41a8e03a2606de1d55d6f1e9894b15e272ad72f06c6459b344026608f34389eccdca7701394f39b501d3b85977fb1ebf45824c9b59c2778f9c2ba3c07d71d1543ea9117cf9e5087e9b8f3ec1a50e2dc9ea72f0d1a35a663318b76b9ec437ee9baaf1a93eaf6e29cba9a8c7314f61070c5db4032adacf2e67bf935d2105a7abecc6034faf2d2778a5083efe2ccc09dd3d6bd6297a8c6a377dd764b2856e903a2f2687cf4d07894c7e727725f48a2f0a0247edab32c1f5111fa33bd4b4ae0915979af8c0b9e3c08832038476c37af5a8b789d27645ef520689daf3e6c866762afdac4613e980dacae86b042c528c6e2de32267eb2a62063b15153003e6e8def33526f7914975c0c43b1d4da2b840681721de0cc6eff136ee6c7822e056ad9d6ecbb008a22f9f625bcb4ee967706fdfb87338241dad0cfd2f9611425f5656927eb66c4e8e18ed769ad92c96ac90b70bf9eb0d0817438558d598a2516f66d0b8e5a1dcb4d16f2b06d490c76e6243b589688f458c4e9549d33f90c19448cc205e592cb66bea62e1f468a20f3f94fb0938a3160774e8ab30516b13a22227bca961e5c3944dfbc49f692f8244af7107b04cdb21f939cabd96d2533b0477c174f27296d5ca565ac2aedf6751923c9b551a967ea75a01026b757b507fd5e3e13d83f232e596c86c97172f34c944465a4e31af81cd2de14f23d67297a1c6289c7df6cc08a2704b4756b7b32ed7ad9c35f8e1a693b95929ae0eb436bb89317c5790ca78b20afd9eee99d19cd5f9863ea4c3e8b1f426a1b4a9e35ef1afe70bccf8bbcbb0d9e027d72849c0dd2a504826ff8825af099e6f2db1d0594e4eeea1c3bdd3f8bf5b84a5ca21eae0190b0b56e1846a4dfa3e9f2aa0efa76664608c90d022b85b3c94fab974515074e12ea0127466cdc9ec2c6f5c76d8b3c18a67448b58b98f9228d9d3fe14916d71f1f258a0ebbe6f5bdee4445643ccc0be0ddbb495da2a87c71f38a13a837cdbf0a1b95eb729a95ef6bcf5f78d9ed202b47a0cb11486faef42b9ffece64ce4a6a4fe0c01151bf2ec4a53a8bfa648626160b2bcc8b89933b957ba9bc754be167b9ed9c11b8b8ff0a724dcdaebce719c8a8bab7a38cd5187efc65a5d974ba0a05302fcae7ecd5d05777071eef37432e46eca3857b887b655225fdee9fdc458a33829139e1ab0ed0bc911d2d9b1f1cf0cd47190b089e431aa38fde10cdcfae7c3070b2d10e5ac2becfc954432d5ad9f3e5191b047086ab0f5f0fc3f6efa8ec9b0f84aba490e118917efab7f28e6f98a8594804576fa7f79f9bc311330f7b89bb491aaa9b7867516e5a99fa02821a2cb471160cc503eac963cdde966b5d571e7cc45310b25cf142da177fea75c1253ddd78805afc6b601b979203b086ad43733efbfce617b6a7cb6e3de449bc7f0405cb56898cd8c8ce00e085191a8455a1f29a87d4e8a538b1905ac925aa57cce31fa85e54e860c82b1f9e2c38a766bd921bb8a211fe7bde991e6467a3538a7f4fca94e0cb2a64827ccf1ed3cf934d6bb7bd90f37c9d16f142d24851da3e305871f3c8cc85508dde20e5b086df1b8e6d73ac92529aeba338d1bc15a53753dea611b760762940a9e79f4c7b3a0cf710f8cd1b2cfd7bded476c438a8e1152546748385c76e47dc5a6bdc8c7cab452649bc49880334970ea49d93457cc4eb71455a28056721fd9f07ceb38a46eff4d2cc329aa5fd7eb386839078cc25a3da253863ce61e26ca3353883cb3109edc32e6ef957d6bd8828bd9eb5bc2bc1e7368c4ac01b6aebc761cd9f427ea2277393fcc0db6bf5e30d9205ea94bade6e026dbf36fa4813d7050780f7e220423d3cdb49b2a09baf097370a420924d6b59a89eea70cd79acf9c778ea79849cbcede311a1f0d9aa1776f9372df03954132a9ff492a31b1f225a9aa12d620e3743f6279a55f47706e33f71d54287e1cccee608be7d9e1a86ddc951c7aeba6c08b0872c9e0c2614070a63139f4165e62c40f95c24e90af1a620f4f66648257677335d7becda9436c1b9e3e3aac58e162a44bedd76b3a2e299c740117fec78bf40bd750cb9d4db372094332a7cb710799a57195df30bcadb7b668a21928b364a254f6c26fa8cffc9d42226e7a1101da0abaade5f255dbf77390a57fa29275a2d264a9695d3af576b8cd77fd02f2753590ffcc862c8e9e6f1490db46de298c186a4d896c560ec5e8e38783131cd047ec608ead0b1debc25e007674a5b78a0910e931d5bcba99d20604c502c1c35995d446efea21b8e387b285dd70764bb83f38192c72ce0e8f2c8037bc634ff314585bc22df6ed10fdfd30bf5d5f0ddf60fb68bcbd5db9846d9d728b167f8eb0668cdcadc9af8adb1d0f946a6c2318d9e87346adbad062e79d21d3f3718c7196d5a551f21e21514c0c7ad52ae8ff7898b5510c845d8ad726f613974ecfd372044e2f4b30a3c4d8fbd750537a3d1ec4bf8d412b8ae90113967cce7ff948897e3b49300f57b5c90851e36db8327072d7209478d867af352cedc0149f613366df2b57ad8ac3c0ac57255963e2a51b2564e716010c256f290ddb6a245c311a83e6183ce04c1c21b221fd6ebdb67a95000a2cfd6e713b5776d698063b74a55f27277283dbdc8ae47292932c177ac0ff98ba14194ee6f4247f355761784cbec4e34b1bf40ad9bdee4831b0a1b2c0502cbe9e1ceac703e64e4729ab83ffcc2657cb68702806bfda9c5d2cfd84d010574013a9243ed57640dcde406b8772123ec85049a889ac20af16b8cb743f48a346e5d4c5dc9af66b631f464af5d0476512e2fae8c294dc05b675c6717c7d6a48d4ef2179cda65a81da981e59dbc4e3cf574f4c50d76d40d5b3e51fbbbff9ed011292a551ea24f025572ce52cf998916d8281c1173ed0e5bc37d128d01ec3c341beb8c449280628e33992ba664e808af73743f0564fe2d6292d05674261efe47c61ffa7949051995dd21a1c20769a5fa3a5279d6ce25376223da6981f701f899d1b90384c6f56dc4d2a6462f9bcebbcb85ba460625fb3dca735b316d52b70a745bd7780831a75dbc11bcd95d01e34d760be3dbbc59eaf57b73282c30c3f2c42176b30a96f61a0301505baf79f4b6258f6a473bc1edf103f37c00d3d606fb0142ab20258850eecf752a6a9c69e6e4a30479fc78a2745d5d7f2e74207b119a46f35d2b7a7b6c10a213948bd066542d2660207849c72ca2554989284730136574ed5059d21afb2673a9f93954bc8b0e5122448a59de9a0afe4d9da2adb13865867e21a8c9f63e1ee49bbc6c85cdd50b550202e79e8a04b9df584b2388fbeec3dde220cb44bd81b6754f7c5719e26671037385cdca0054b32566393d772b883b8b3775f86b9c20f533954396b321877223b6792c6bcdd1c171395b9c87e618aace5a660ec96f59e419225b13050f661dadece6e0ecd3ce96da7f88af709b1539ab25daf85a8c43bcce3c5b5b95c351a7020201f4f8fe4949e1e877d23e32f0faf33d695064d061bda2ea25056595afb7a73817a60df60041cc0c755ae2795e141c19aeb3748b9b26628a547fa7c0aa8c24cb5986b761e593a00a47beb73bd6ed6e14e34e984e5eeb9491e9cfd866a62dd1b959320f4f5d1f27aeb75db571d47b47d6fdd629711fea2510e14476a9268d75e095a7e3046a73e53c7061c7b132e1cecf245d5290c5dfb7d5c4764c67933287e876d9d9271a8b6fb136cabf1e5c105c6b524f77670fae1b0b8defaca5566ae2f479348e544167345988eb9c7dfbf9b8a7e905c5654ce21638282007896e4b4552b6c9f04f9bddf8f5d4d3b4a859c6ff4f8bd52b0e7ddbcd4d5a94f7fb9fcfc937e239d1a0785a1683d0db8e1ed48a553c44f67a49b1d5ff452e54f45068f04641d2db28371c250736c4a896666ebcb148bf99bf0751ec1dd49988cb17c6e1019568c1091c8293d2663e76dd6c2dfc175198cdbff5501d0a15be8e273fb02850df658363db680bbe716bf0a552b1feb59e2bc56ab63322b5d3c12849002c0b2b934c979ded9110deefb3439b1c3355e5fa046c89140904480884469b029955ebffd29823a24af4032b77567a0f805f99bb3fb54454d718727f41422acca6a63a12908ecbce5371904890e07935938a6f4836a9b2590062e4c18bfea8f288396a0e446662d1bcd20a4893cea04cea35db6b007dcfc71337fa5a7c8df9c7183bacdeea32161f04fafa454bbba8c3fd1f96f6f0ad129ac3546a401b1b28f795bc291c08b6b7809ef437e1440971f6a5baad5409f97ce34bbd191665a7ccb90de21a1600cebf8e61edeefd5a5e64906029aa0f195a9e2061a96ee9c14b613e66a9c6d25dbd0cc8ec32e69eecdfcf9e4100d57b4c41836f0f7d94fbd20e1978b60ae584fc7e5362fe0c0f6e89d169425b241bc98478fd7202b5d75d047eef7db2c6b7f803fbc98a15278a450cd99e55c726e8f2311dd5af20260ec514e98565a8acd67879737d3023b565865f2ca1b1912df815cf3a2badd5a8a859e2f1c11986078bc406841e10c7aeeac9df2ade9f0f000d29f261b2d8978702f4489da59212c8ed7644dd855e3b4e3298b9c33c5a3ab248a176329b4c6a80c0c5f2067f3de2cc8dd02c84dace6c3c45b188e0dd64932c3ec4d1f55b83885249dfe07ce15912f059c8d50d65a2e14c70c0b627c8f8d8a8aa7201b3b9f951f8bb2b09c927e8e207f7e7673c334155fa9553757cd99ca1a9a2a2e206041cd2ccae6b578a713481156a9cd9eb005964201ba51a811c7b82e4e9e0add6c45cc18681cbf6d043abbb5343506c6886ddb58399d9c56167aab2dadce866d25834810aea0f8ab711883c54511ad4d94900ade9c5df85f3cd7ea175a52bea549ff016f625f835baa642f43dfcc414f0d8e2094f79a9e3ac06bfe4c5d052b9afdb8870636985be601e652c58e01b6ab0f92932b89df396ece4c2d36b71f54b228cdcaefb006e2db72c65ac8b16351fc1d3d61db359a68ee42772a41b462fb84d2cd4ab87e91b4745ed31a36a8d9a92a051fb46dea5d67e6247f4440a43eed8bfac8624da8e1d5ff41cf187fc20bc20c8fb51f9199da46b25f83885f7fa42ef4b44b9fe6cd3262241ec8f8a0518273e69e079f2f4acd9c632c6e11e69da454b586664d6b4a702b317f40cf4dd5e2564c01cb8152f24a3d5f71a11549cb9fc367eef52ceb3de291bcbd597b98f8ad02659f354d2420c05ccf7cb247d88d8e853ce750f9f6783252b4cee9ae915e9359d2629ec52152cf547b75ad7ce5caa3fda7da2bba39d1b7d013ed75f74b0da29a9494485d5ae4510f95f2f1709195af06f528245e75a6deb1b8a073e158b28e3f6dea13d0cb5954d2c99a9f79f1b13119ed4571822ea3b49c200b5f2ef663a2b17915a6b53da2e7b2a23179512411ad83b3c89e65bedd445c30d6a6b5312a6a3f28d40f01c4326a7bba4ef8f134d515efb6a80cb0a544c601a57f2850c05fe745259bd44534645bcc2367b6b6dfdbb9cd1cd34ce26cf0eae02ee60594a78465bfc719d2b73fda139d47c62d95517e2c11c6516340c5aaa42505bb72103e089a20e6dae4a57c6cd7d46e82fe8bcaf6ee0771985e38bc78241d55364af14ff88f922e94f075458d6507cf3fae191c9f57f7a915745c00f922f9da080e979cecc8603b81702cf9314d5c5f0ce0f76449d21b0641d26464dc53561abec1f660b50ef95242ed07d623006fba816a0cd26e7b65b67821fa9b0c1aac7b66582b397c4590b7255c5f2b9aef30028bffa91dc3dd7ea92ac8f9a83d3a5c94f194c8a664c5024a4968b1f2e6992f6990bc556766f4c3ac66eba8ec2b5c165759955cb6f28ac74aea20389906ddf55505efa0c61da8f2254597d8fe1e7537e5d395c9b5bbc54f5333bfcd3e1505174bf7aa3a641a1700f41928743148f10c0d6f02fa6af0b0299b86097c9de2442753ad099f9a45e7fb1da30834dc95a4c5f9838db4cc789d8465da4582e4038b11d7f3763da293aff6bd8a42b6c7924cfd57d86b2c821173bc79048c7601b4c713f2bc7e42b0f780985708eb10e0026ce8af8ccd2e35da6270ba4a15cdd7ebdb010187225fc7c7045308d94912521ffe00965126a8768515e642e230a2638279fc07d5f463ebd70df8e899a07bae10bed3f701332bcb64056acc108910f96306ed5f9d4b5198158a4fae4b8760f48bdcd1514d003394f394b321aea7a33f50269e099dc7f4341be8f5f810de6d69a3c26f979ae9023b213a258c06eed2603aa379599c03c339a1cf2a81bae415b332ee0c977f56be39f55a5367125cefd3e3aa5a60b4421f1b12ee32e74ae89224e3a3cf4a87f026a6b8ac76c0adf873672ce1ce95e618602c0499fabcf4baeaccb24b9e5cb46df0fa2dd85a29ab97a0b907e9b810cc1b7d7966d25f4ff048ce2fc74f0d27e0dd511c3191f75a2c26bce1c16ed9c04e6ee5355073dbda6effe12d8514bb6783ccb303ed75b4f3ee0bd5e8ab6e1341d5071f99dfbd78ca5f1833c896f79d27247f98765e30223bc8d5966a2fccb7045c1c2cc7f6f02fb9e79934f8a238c2ccf4bbcc4699d2084b3a2ad7034e9e0c46362e6daf3a4195aed3fefb505adabb572a592013e1955ca4d9dfe4a38b501f9653ca68d46d0dcec1f7c3cb8bc954d6cc475130b1721d1598ccb2b43c0e2e9ae23309af67299d5e5f8bcac36b52f04e725b17841e598431e6026e8e9d9aa8b640d06b8acea8f144c64c6cf06e7f4f3bf398dba37d37715d72f59633aef22922f130017ca8c2f5db37309df7d087572204d0b376de7a142f45715f7ac22425d096ec6f5f80d95973c738fd612f2203a87a75b31313254a4aea58ddd36cd179ec5859ea9e4da21a4c374ef5893d9fa94eb178cbd582be42d85692c1c82ba707f2475dc4795855c168c844ed7a5cb8e28e158b090969f93a768bfe94d8368ae47ac063a3efad0e2ffb9c5fcc83aec4a43d5b4ad56ece8c0edc42ab0c13f8478ecf9b972d111f714a1a87b0da32699e3893e025a19f6c07f8ae44ff0aca8abad46205daaedb4e5bf04d293be6406af2377f978836f1f9fdb9e6674f4d60b6e2a0ec7580c75e8d66baebe70f9a612e8a43c62d00836c48ba98360e98918693a86e01848578cbd9052f88dc8084141dec61c24a5b820694468b1a87b31989f21932e22dc6da0055bb5f77a89ee1556331600c62d751fda3438e767bf27e1b27a6ff5c0c958a1da8446348979cf460568bb48690d34239bb019a0551bd8b3b03e9578fb59cc64e73df177a79abedab6055cd4fc16d625121a876cf5388806ecefa0bacc1e237da31a5bed749c05e1c85078d252d92f189c14b3b8fe3c480ecd229377bdcf2498e47fda1224b010bd64e04e5083b25594a6be31154894821cf102b02fec9e8fa08ab4c9e26496257ab5d2201783b4502ab5fa5acf6ddc387c0a3038ba36af45668139e2c60e1869c5479e5c2f67b59b8ae4cb35be3fe565915151b88489f1bbd0874377ea126d201cba09df8c777b925641e674c538e4e1d524e99c670d7debf487a2cd4bf33906b5c7d4225b5b233f511d5e03d9837175237bfa8a8dbc570ed79131455de6900b51edbf3a85cef3810f97058f4ff5c061fa45b3862e1fd847a62816cd6e9352fb8e1739af26ffc5bf098469cc29037b3266642e753221aa23c5fc5bbbcbd2ebb0a016c0d88ada146be5ac52e7cf824c95ae6b34f9b507c4446da8445fa5a9eaf77885322d38f218ee43f4b5c853030599adacf2fa0e07a5f31ee0f9839fc657deb74fd5b69a201a21f6f048b69558184de8dd3c2600525606852a5e2f35b334fbb6936dfc2450f9e227327de7e85e11f08ee00a419600ea27970d280f50cbc65c92747c28c68db899412ef990b70e486bcd90d25e4415ee0a14f9b55b08a6d5c766b0411f3eff3cb7f611b5a435f20a3d05af4b828ef8385bf4cafc7b6225c48936d77f0fd2a9e704cb2197237bbb637aa61830692dde746e13d18a9a65b4824bf5e9d07517321e9f75a815c34267dcf491a8936ab70748cb4c253626307433a35db438d8378e489b95fa34885c295e2f2e1d5fa9453555b648464184e2a53ad8a3f66de55fe1cdbbdb85e4ec29e84ddd8dc47fa4247e4ef2820287179014fac041911786232ec74c3c8fb82ce63915fa91295f5c7843d78fb4224569055c0208755206e0416678fb72e1d0cd5d3c508d331f8034788f80d19853c4ba6311b80f3d9d52ca92d003f6376ff9674f25719456d6bf0af85351a15fa4be2de541078d796506d2ace3ebec3790a791385b6429a432729fb98e937e888797a9ea6263e94a1780f3865ab534dd31d749ed079c6daf9438b76650bef13a3bec04ccd83f54eed626153a4d15aaa331081f2b0718f4252369bf2cdfe7244ef9772af597244e58c58d6c30953a9a5f80edfd184ff26f75f3a5217c05a25e00665fb01ff83da6873666076187156477c6f5e37b232dcac47f8ceffe72fac3060caf31609f47012383293291c93e6272b74644a6067879c74949012c19e5c7b1197340c12f71c3f56dcbd730f955cf939b7f9c16d13cec1baf85f716198792ee2a3103c89eba9227b0712ebfb736fceb9f499ce53dcf46480100c20709256bfe8c182956a4906f198ca282b58c591827ba54a03c3009e0c9ed3288f5f4313b3e97f2c5eb48a3502127aaf5eeaee7b09ce634f55d50fcd7188d733979e832f8feb8a465bfdcd6eca4661af605f1499d6e00ece3139a078ee31d1dd6d412acdfabb5cd0630234438cf04fb6930500a808f6b5837de668fd0eb71541ec60c49018dd4efd06f365162b5c0de60e0a49e9b4938bf998c604cc2ec209cbaa450cda0106fa4086732a395acec3a41076856af8565c8e109860ed5068228d32b5c678f137186991c3b3bdd4515c37b0eaf4f2b251c7ce29d8bcc250d093c7b629204c3c3ee0c68a4bad4da9a3df64a4ecbdce7f565929dc3bc28a9094097b3ad67e0acf0407c09ed2c419624db279098834f7da3b091a776b851fc18c66e04814761e816ebd076b27efc5d7b09b3b6285221ffec476a82be9ecf2e5af71d491595e159db8607a2b33584fc1a38712e36c35a2f7e803591aef03cd7d370ca8f2099831b1716a3a26389147e10ea1b419b482a2c232c15187935f8b9d53c69f28b1de32ad3f96b05646ce883324b238a7e0ddfe944963d98e5fa1048de474de08a4c5c9562391ab1dac8e6e7235953439d2b0eb98f9545e00fcc0e0aabca61fd15f660c9c3510d7304a3e3c1e1c0ebc3239f0822d4ba692faf240284cd3f62101b61c04c9bed8a473a22af3417edcb93e636b66b18585d455ef893e8b3d63734408e406d3346f59741631cee89269132da1a10d506957466fabbd72b603edac531252f00f27f9c8744929861f5301a6195bbdb5c03692e5916c16733d73e19a38ca42dadefce65b558bbeb2508b00d792ca5270db3a9e5d86b6644d953acec57b583505d317352fe7cf13f07e6af93cb3bc2d95fe0da2069c0c380abc422ffdf1738df0236d486d4c12f7e909b708187234f7d8d98f2cb34ff861a7e4683a4b9b41bb24710d48f283994019cd956aaa436a9dffec8fc32cde1fe277bdce4c2dad34ecc97319560ca35731fc32e9526a6e01d06c46144b3ef635f959147aec34c005f233c88199beb47a841b23a2de9e4f542add3a149d767ad6df1d3e28b689bb979c54c64711125482d1c7c5e67bcb3d4cebc4ecfe62bd146d6a69638dc62aab3a8c57590533d5d8bb939f76e950f387321b81c449b4defc77122cd0c303f8f9dd952b0f26175adcade74299a0365db1edf08e94690e3bd9566100cc0c468d57ae13996b9a09d7a5e6204cba74b67905b3149640226cf4507ae4ce9ca543811ca3d9ecaff32131f419a6cf4e58cf964efc927a5ec9a86a0c87e21b3850a4472ae8c992ae9c910237c0ed116cee764446689a5a431e3b7745e13346724177e31b70563b750e34c0012c094338954a21017fec2aa991fb5c14f37059e035e191bedda0ac85927b47cb59d941e68a0670a0e6bbac821edffe606731897ccda575e7058b32cc41829d7551b20e4d89facc3347ff55943b1a857a07a45e4bf66134cbb89ce46eb6f14e977fd3d7864f6ba53aca9888bde31da1f54642e2f913f60e81b9774e163acfd4f2a827b9353c3179c66d10d420e47bdb2228116f430788697eae5c546e5bed4c787a7f63999c5167d1a30db3588bda9321ca8c043918fc5acee633575ad7fe0894cd32e75e4d6d26f294353fe7d2303443bcbe36e3fdbc4dcb812291d57b0f5780c331e12b3c57ae4ab357e2d33498ace44161286d94e324e29afb171fea4dec7034398eefaca8a41cadf320cb71b130488c44340b8d505c55fc118b3238a9ba6e16a1026501bb034c24d7b513e38fd6ec223a64160e7f9b22a0573dddb6cc1c64fe0d66e98e8f01222b06882c6c7c4379736fb78f45fd0487a05e6eb5f996d4b5060cd5ff13a2d64b23f78fd05253b85f1a791cbcf4aad1bad0cfb3cdba9c87bd938611c1e7afc848826fd641ad6a8bfbcae6be44eeb97ff5518d92b80c31ff8930d6e35dc3b45423174f6b3b479f53c6bc95224ed13d76a06606646f81dc0efd4a0c97e07ae015fcc0abc5f7fda6675e0c19fa512557bd9c57527feb2189d2a9f9c7a054f575b8f4f92db4aac2afffeb52fd07f6d21c8e812a8cd8f779afa9cccd5e95354f0812fa7a5aee42ce7133af5431cdd8bca98284d95c0fd821ecbe3468716507e4f5261ef9f200ef6dc0bfe581e7534d973fe392ce324eda356af03c9db2c84e84eafb5abab77c5c46c116f3337144510afad3a1a1dd3c47127b384ff08f7ae66e2834c5b8203e38059b831057f133c1c25a520ccd575e04cea37610ed7d168bf7c0895cb51526cc918633ca26ac1c5cf90a7d1d64e95dd47ec157f47d519d18b654006e601f2f303f2dc7771c598aea23471029d9df2987d97fdd06e8d113417fbaaa24b6819db3dc329a7c4496d8d2cda936e318e51941aa8b07653983dd98ac7f735745fb304d59e355c3bed9fc3ac6ebf6ae6633ad8470d58f585a2098c0a13b16df7cbbd0cd8f17c5a5df8a2fa31fa4fc7a86381d68f212b110e75a851777818433c08419696155740f76b1955678cd1fe59673eb9e5f8839b0cee9771625a982324fca9756ee3187709fa8852842ec47aabfb728358ccc09bfaae3253d1dba401a5401c59bf6970462dae33c27d525974916e107b748ff087f784ed4257b75326bcee53b8e2777271be2ac3b3c7a1a72894381ae90834ccd2977171df9299ed025ca9274fddace8a843c09a6d80df2879bea14a27555a25be3d705fe1f5e98447c646f56eb4998f0bb9fed97d8100e67f313fcbb99cf68acb77dc8cb1ffda502a5b6010098d09506df2524cef4cde88fdc9dcca3fb54512a212031fa5f2d892562553d2423a51bb8dc0d43ac6ae5f81eaebb69794f205b71276ae5c282dc0d77ae3f6b489f849955463cf4d30ed47986be55cd92eaa11bf119dd394ecbd32694161ac0bceb84ae98da964c8146f321c55ba5d48ec11d4614e51583cefcab5385a05c1db02289ab77466059cfc5e29b4469ec7d666992d92744daab0a1e8305ceb44571443084fcda7107e955065b946fdd22bab54997dd67a6ce9da5325390e88cb96106c844872b9cb354c753a398d490251290f50e21670aaedde5cef703c3892dd3d2964890c9639acd826ab8d952430f030523c2fb9807a91f12bad0985a037f0b33cb7f2b1b95a8e749dd06bad488d9c33e3ddfbe5ade97866e3495c43edda119421ba226d64bd0ba6780fdd33a9159f65e7c0968a37877ff9ecb12ee50135849e220587b5547a3a69b016bb7508efb9694fc963f957698e826890c6722f6e4ca58a54090946da32fda636f8fb18b64d847235d97a23143c59b312d9d193e720cbfb77c60095c1e8f663d45318bd2046759b8df069655f133c3fae16a81f4238219fde018d9ea6d42dc96fb00efdb234e6934adcd61234d796ee9afa05ce9f25baa6fca76c22aa6342415d2caa71c789dd77ee224f722969a842a94898cfc4ee8e68f43954e803d5b4eb59f0acc9e73f7370d80914c4af658ecfa716bc243d41884cb25faed92071c23000ec6477cf3bd15feaed746d59222c1f448e3356409bab57059b46d5524a2efc83f71f7c42b1b0a44b8335b728a5b2b5cf98e1f5126ca3f28f5714ff792083654dd712c2790fb52c9cdbccf64bf630834a3871a2aacb04e5ac26c4596b082265d3977971190cd540f44963aa74a65923d727e89da53568be9f39c447f8018e803caf2ea418e6f7ea3295b6348b2780b3785a69cf0a1a560e85077db954a87b21a6a8f5b4e2ed6380cc585788397c2e4c8d39fa57859b7918703e3d8469370b2a5168e8f86b0c4d0fab50dda6725e9bba9e36f12918a30fa0c7850f78b19cc096063a0b9c0ee62c707960f04e46001aeea5bda98a223bef69f353414345729035435ef1889dca92e66f4696ea4807931b2dd8123d7d66cac3ba849f8ec27b6106398c67ffa1975afb25957aa29d28c91d64cc9b4223a6e267f6c3c2cb0742065e0898f85a25363ccaad05805b59a5ead9c7b1470df588a9a850f3008413d29c6d04e8a72d024363e6bf3f9098933189305592a6480c3ad0b3bf5f93ded69e284878256a1678b6b63e455573dea333991146fa0e4016e2bd3cd9dd573c5ba0245df263f74d9cf526258c3097fca5ba0fd904a849a083b905aedfcb24957a3924467ea53a91179a01ecec53192160fe7fed6a8df075d438935948dc59fa45bfc91edbaed175dbff9ead65c7a500503d08bf1e4e7f6e84c2faa182f04ccbc3a9915721f949eead0da3eb6694b74eec260855174d9e7a71d2cb02019a6e78c2cdb373e9431d7ea1d919084301637b37928d2431a868405a432ef5242d597d8b54ed1689a18688a3c777d48865f931c536ff4015261c4aa62a262472ce7c3228670fb0c408b7cdb9e85877ba72a807b1c5043f2665360cd62b4074b246a2bed28294dddc379a7a52d4e220cd55052a2e1131ada1ba9c83ee568e18252967c283893c39031ea458c8faf1e06cd62f5c8342e83a44232316e1407f3359e80009ffa908909fc30701d844c99b3b1e4e4a7e39528670de869109bdf1a611d3071b09541d27f4dc4dbd7ab1643352fe09d429223c7ef76ae85c1a313425a71fda82a7ab0512bee54859b82c56a060a3bbf1cc6fb8b258931d47b08208ff30149810cffeb31cc4494cd0d0d61e18e2378ea6ea5f0326574888aa930b26f042a24c3c58dc4a0884b1428966d2e3825d0865b38309798e1a8d7a22520a52a0127e4619600e80fc0904bb0c71dd852822f5bc223b8ecd58e648425669f006afb16ab183af04f7f4eed3efbb5757ae23f59e90f74f9d07f9008f74e8eea5ba520ef12c69b2b58d9b73b622027620daf58bb9eede546990ae03eeeea793814c7c0ca5e896c62f9884eba064d4453f43a7aa3835243bf09b587fd12ad3e3a071db7b94a1c9c1effde6713b4d56d57b16f70fc331f4a9f5ea0cfea2dfa766d4efe94b60a03d53934de64c3dc4f332813898ca930828a134e5cd1fa8742e8c12b1576f18949b5945b5f0a586d945d7b8657edece158a9e0b87b300b84f2e77bfc19cb87c0da164a5c72bc789c8cb330116d09f817fe367f2b8c27c9719907f549fa028e95e6afae1b90f7adb431638965bdac918d75790ab9d0e891f9002c1a55b705ea850606fb3f9ff0368b352811dfd5a44227d0c73a3e928a94f68d2e1e83d4807260f68ea0cb72a2fd7f2e512347b1b59b50f602de6669b0a4d321e12bcd01ca537047300cec9f182e3b27e93aea975f21affa25eb04d00ab2f85a2a87d24e8de59d12446d6771a73359b45291853da963013b590f57df9659c55d949d24ca972ebd2502b88ee171ab148c5d9f51b1241ff6907c9ed048de9682b20da203e89801d7359dfc7f6e9a15e56ba993df6d1b75ec6ee4c5a7e550ac685890f77fb2a149a3dd0f0d4ca29a146d02134a1134f2f16e5697d779d39d0be3f00e416cbaac0f7798e6a494e6b83bc519ce044a343c5174e6d377d459e2d8f3797642e5db3a08eec046a126fa95676dcbb8f36f1226942b2856d4e4174aa9371afad870e1b7692472713df28fc68b53c7a4744412c3588b81ecde7885be1764f2f3685e5fed448590d0d56f93f6ae75dd24f1cfdd81aadd6fb8475ca865b84617d5fa78a5520c052e081680af7c1397f17b9fb7f4182f1be704771a775a87b57244157d39287bc4677c7ef9bf74b685e448f4a9f5b0a6e288a3314c634772d723c515d959b1117b77dc4bc342a6ad8b2f1f255c9acf51bb070f65023729180a365978775595ba6841f68eae5c50116d7704a5efe35fb0329e8d6648ce3dc0120288259f9d83d74135d6953d4532e4cabb749f6ef0c95ec50a8d031f86269a8a77353b7a60f7dee53c145dad8dfcf810c43826f6c6d7dd622547318af62449fc205f6b67084e28af3935b8e374f0a07e043d595b9f4071bd6be5718f78c93458ff7cdc11e5143de657927b72d4b631c4ec52b42af17092b5bf39751a682a8625152c3151cbb73f4a63f2e3b80edc0c82706373a9e3ded25e0a6b991b37d60a46fa85e076b8dd711c4d53d1348ea4b9a919aee73d9097790393cd05faedecdb2ff51a2beb8e4ebdcb805e5f149d58ff9f7acfb8bcd20b6d79586b87c213837da14650d3614f4204956d3b65d50d10d3a6f0cfffc87cb6ba616d9d3cceb2e4ec61461891895916815c30c041a3d6cdb3114dd818d6fca582d98c66323ec3585782e37753535754868a96fd38c5b165b2caa18a32902ae76e86983e97ba47f71ffefd12183842ec1e86540b398979bedbf7a1c1c2a7ef92fd1612ed3f09c573272bb6d6f56c72aa1ba94f866394447c8b6f7c6dbaad338e88d48353f3435dc8393095269c592b64a929c0b24c2c99df47e4b3f5599b313b6971cd78a20788586a5ddf454f38671834839511992f144b87998c6cf0eab584035fb595d9cfa94b8deace97a7da010d255528dd61673a1abe2dc6b6d7aa74342363aea757bd9fe871d0cee776b7737da0ce75a3483c64fcb911b7dc8e3ee881277c538fce491c027fc765f9d33d67181df0c9e37ac5e9e7f1dc1f7febbd73acce019adf4234e2929f50244d1b7242c3760d9de253c2ec8d78386a5f75496f3cb6fed1ec6ffacec9e0306e8f6d0d1380a1b998484ebc72cf283951056379cd70d3ae2fd67e5bd61f9140d01cb30510e9bb91a1157535cb0a09658ba2566885261416b9b7b4c22075f23edeccdce071d8197e180014cd71fbf4bd4f690aedb2927ddcf625c512c6cc9ed5d257c2742c0f03abee98bb163284bcc14a94854fddc9b25a58cce951c8888aaf945be62d88aca83f77ca73f8d040a8e7889982c98b279cebde8c33dffd451f8471c145fae06698b28cfb8867d079a7344e79043a30de19571b33c8eb1cf70c8b2c865a86539a44342eaf1369b5e8464e1909320e5e692e4b6541b360407ad4ecddad7a7da39f1820ca74294060a564e49915a9f1b8d3894f2bb4a1331056cdf53adfd039fa43994776e867b03134ec4daf74cd8893f0c65f5328677f2fca6327ebb0faf8fc7ed59f28f79fa0d1c2f26725a720fee52523fc025dfe4dc3884f308d10e2b93eb494066f7c255bf8f4e43145b7a23d6ddd082d1bdd0fc54e4f3f3d6fcad26b2783fb693f990f8c8aeaf0e300e2a89486cf83cacdd27f24755816c383ed1a7673687f80a8d948a174e6f041dfb6d9ced36adaa2f672418a79a211ed4f29a03484d18f80e40c54581090a1a0fb6cac78f2c07f3da4b787311b6f52cef8a7c9074e0d29f2607f23ff01faf9900dbf0f795f69580eb78482b3b717ca8347b09f35f3c740cf15e23249770791eff66a51d2ab7a9036331b7d96df4d8d7524a58cf4eba3ff83c19f86c008575b8114af0ffc7fb5cb84e58e5154b3ba61f38fd2a6147805ba83fc72f21fd28aa7080235444bdbcccf0f19ff534e3478bfb63f06b03461cfbfd661d8fbfcfe823f61350d62d1e2abd600a9bba3447bf72723b22f26ae5abd8012818b5143fe94dd6a6e64ad4cc396616ad37a3cdab084a5715f264dd2fab01408d2cbe4e7e24932add7ffbb904ff3ddae33bb6a27c3782816bfe6b48933b089506eee11e5c0f2589f0f2f2a47eeea45c6fd09bdfa6e70f3795b8a2628faa08e38cccec5f27c04e0c9b726cc1cb997a1c83ac8a74af74a9c766512e4ff954f1fd74eb3f6861d1c7fdb39266fc7ac8abb3578f65cbc3e83153b464bbd48248b32724362758982f460d03e824a2d0dd42d7d3e1ae7e3d20c870be58889a287cd6d7c0dd4a9f05310c9be774af49563b3028c9958272c7195471f438d1abf7ac45c36a8d36df517e1157c35f769647bc66e2e1cc14a4ceb9dd7b45862bf53accd9bc3cbae78ba01e7cb1351e162e2e3127bf6d479eb4b935832494d5aa94d8a29481b85a59cc3e9b0bdfeab054390664fe02b9d002a921a540c758df35e3e32cc3bfa3feee93fe648a1e168df762179e1b12f618e884a9456dd04cc4981a9ef5c07926a08781f980c7d30c51998097d8d1315d1cf65c1f1c3158d0ff8e8cf782a555dc59c426a18b10e7a1c169d8a2d0fa912071b32834171ec993518f3255a28018916d118549cf682c1fb4c47763aa618734d58adc9d11583fcc8fc03951943ca76722dc44efa48b031bb38aeddf00859cec2f0eadcc7e6ccb60c0edfd97e893a6fe25d3fcef61e017aec0cb44fc2acff618d143d34a13df9d703b85ad34e226c23ddeb09053312b55c517170df95a91974a9342344641639e7ecd72558d46bf870ab90ead15353aa476107add4459ec4e75deec8324954b2ac1db436ef08782cebd1afd0d4d87c32fab2f0bfbe7bc32bede3f485d339fc0d8139488bce369c797ab30f2e96e44a6156172c07ab50152bc95d3d23b64af3c23a2d8d04953fb5e4d57f4dc6874eff4ffe1147400984a07686a829ea1bb697aeef35e773454ae3420882225a7d9d759d734c74db72533318ee234d655f351b24546b127db2e2463a9dde63adc004e921831677a156fbdf867ac50c3dd9c25223957d54a477d8f16b3c37a8cae058a6b69225b44522f3874edf29c6598ebb04a60d866f1edce772ceedb4325569b479745a1b890957b2d77fe93071021095f565526dc99009fc4fd9df048ac64a75854e0511a207618bbef1d1a8b0b8231cbfc2f56b2a6e31b23ea7e96ecc768ca38fdd8f46bb93eb1effc40f7459a5b0080264d93a1394835f1737431fd4cd9bba028721efea49f733fab6ba3bd56a982e9318430f8bf475f7328cc00d0437db5954941a3e5274a56a28132616ec075810303adcf3d3fe9434c722ba9d3a56f4fe1045e6066ccd29544dac536795d5766b94cbe87a274b14f020358c9741aa0217116699332d28a7d5301ab331ad8374dab409dead938ecaf261ba2b49d758b0425056620327796a9002ab47d503fdcbdab5ff7a5f78dfea16f39db9a639de45d84a0de495f2da6c056eee0d1f91c5ce480996b4c59bd201f97c51f838e7740535adb4361e3928540d03d35645f4cab013807d65a6ca879266b1753789d53028c909aa71a0040a91af6f2c838a8a0dc59af7bb0e2ea0cebf349cdc6a10b2b0da4aec8e408fc5cafcdfebfc6da66c97bd9b1861868db19db7d8c8470a51d5538135f8368b2f58c1d7df3514037bc00f68952f1e27b24eb55377626be24e26ad015134520c1132741ab5423b74ce5f266f143f431256a304ba2fdc78fe2ea7ac8cab6998a85bddfed808ca53eff729919807a4bc24a45bb89f2070f88767709f03a475b9fc749b6f80fa68678a2a701076914dae792bba15ac2a427a52d6f010bfcb80ceb5583461b61f1645f94eab18181796cf99aad6be48b4c7f278c91e7adafb16020587890b32c393915725e845d5fd8e40729c840ae23a39e3b56a4583609cdaddd491bfed3bcef781932b59c7482bb17713a3d086b475f71ad942ddfd5de3a2b3b43658da6f73d72e9ec0c63c976621905c0d4f222bb19f28f7e59c6b1d58dab4e5eb8a2296ac1e4e420ffc306a9374a02e3681f94df31b161bd33f38c6c0d2911ea6389894207d3f225068acc96606cddf08675de1620bfad5f4932ed9f553ec96d5f0e1fff0474945f0136357b3d8f532b88922fbef9a69d6aa3fc127e2d2ed29fbdfca42883fd00898266a9eb4e0df3f97bfa979856f2be6286f49c5a1509aa0b06ad8f3441df3d87f56cec5ec34ea7b6031b210120c4e33d6c52076fdf665e210a8ed3ff8e60c2d23ddab0a456935be046b00326024cdc702f0bb6c8a1e75272b6bda0c92ba9279ba7519eb60c7fc3c964d676f005b44991cfc2d90da431ffe3e2697f03224344ff809f35e7c142a0af48d709fd775e080496b125f98b6eb27f4d5ea88aafa8cb732344f1c65d3b912cf17461acc91d150096e2d66f185b6dcc1978bf01d8a8c32d5ffce6489d1c4f9012a973aa19236d88fe50cbacf6d67c77dc1adf66e7b781b73ff4715d76c39ba04acaad29c961ada309ba5c24a2b90ec85291583675aca2e606ff7267e951cd02020e6d0fab03f463aef7b9ef0bcf1a835259816040b4af7274542db12395dc33e7df803a39fe8d0b3a3a4fc677a4423c014178cc998efe0f2463e7f96103ac8630752785c7ff0d05968d323f724496af8e3f6da7baef8981c7f6fbe78263d4dc09f0fecf73e3cae06bd027d7933478a9684071ce360389e29244530460570e34455934b4bd5ff5c757b555ea28387f0852712acc163db6ca4e768f8fd47573b19a2e134daad592318b5aa3dd8b2eeabd0f5bef8bb99a3055b71367445d927cdbf7baa8c441825dc50dce4bba376b16f92b79ab9773afc0babac207aa3d82e9e0197f91aa97d08c6ba67431170e8c7d48a3f2f3e480d66cfb7b0be03710196429a095f858ef8e2e29533885ba83995d0901035c03985aa8462eab0626d0a831f975364e3df41a5d50e1548b603b37430e992c7d4c8ea47aaec16bf0d12459576d289bf1e4bd6b5c1a9918ab07e870686e3e93176a59cf1a162cfe16dfea72a26b76d3a19ffcd89f4dccdbd045a6eaca5bac3aea6aa30f87ae4e04c07f7936d9554d8eac8e422f2b06284e9ddad845283eed64479a509584bce513068722698d2e994bc80469018324c58fe03aa72ef45f46cf6c9f5d4c598e21c9f816b5096403ae0b4a2847ee171a69c28dcd1e3dca53d7137b7d9173aab542bb1c21e45faa1771993753f579c2a2b7fc68384b36ebc42c9b461e8899233b2d4ac9d59c93f168842ca9b61721228bc5549a3c40edadded5aa355d639742104c73a503ed133a34f37f8853d458dbbc3611e30d2d40e0841b7b4c3a6bd199eb6adb00a835c72872ab119a28dbf79c8a172e47bc781acf2020df7833935ebb5cd3a116981fac3922917a21f62ec7fc4d350ea94b809ac5aed910e7dd0c1b45a9d25c663ad97d9fcc0ad2493095ef14c56973db349b2748e76f24995429bb3cd375d360e690752fb6296a4eb77ae0f9f23e59db813de7ada8531fd7a73038c9a99a8013fab4e6f01c077e4bc0d370022bedeba0d0c3595bd2f26f9a3ad5d7f0911f2f10cb8a79042a3e3d215f34096940dc93faafb708a1d49f244f9a272ef4fc9668a9f49a61d2bb008488536065e509b772633c4eeb434e8d6b1fe3f5d2b526fcb8bc37f7e10ed15995137628529c5903102653852755cec9b1364a688a0d0a7864956e1681d8bf4f36ede8577d73404e1ba6252e2c8ec9b224cabe3a6acf2922e33d510f5c8fb8b37a3f5f9d857a4805d6dc4d8b44b5277d570001c7bef42a3897f3e3f6f049c0fa23928189d6daf54cf468dfb86d596df6c68e3c45d734d9aaebbc59dbe1a5afa510adb9b4c11bfe91c0529aedec1b888a5647b5cecc829eb0a5670e2a9bfa6ed73d10ce71cf69486821ba79d375baaa4fe475b032f82224cfc3e2d3b8b622bb089b7ebd2411ff5578903ece72a7cd01a451a73150a2c7c55ec97b75758b7f41a6aa58bec407ad4e498cf28288f03feb57d35af13e89d45f6885775bf5f5b6dff76f24e00c94bcd1d031c1393bb939d4479edf1e4f6185a4fe39de821d79b4fbd609fd933f78a4a092b784fce7c406bc84530d02f5e795e1063f43fe3cba00fba36df347a1eedfe0b50cd57e60c1412b047bd6eaae9fb826e5001d347b4a59ddbf0e6946cb40a225ad0500aeb36ca44e12ac061b4ff39371585b2116e77b0c90974321555c2e35f88677dbdde7ecc27d847be763bf4f0c5162bede5afcbc2e1a78746aae7c26729a7c70fbbbf179122d2f6278d5d60b79cc8fcb126e02165eeb1958c84b73ab160c13bb7b1002af0108e6087de7242743adef098a8e5b5e7e372968eaf029920c6a6d0c6598ff983a87cb270db3154e66f34c2e8e9531fa17ede5b24d3790cc5ff34417339091de9412d89d0c0c8f597045f27f1de3b552129c326f3edf64f0430e33cb38abd0a45eb3def33d9a99665074ba9aaa762fef2f340d98008cfe85cf73a60dc11bc4251a6b43097603c312b3ad7d827233ca2a2ee5b5bc082ad6212c634262e51900bf636a1ea07855d226902ea575ae50e9bce7308a5aac6858d24139d08e10f0fc607745a92ae8f1bcf5d3ee0257ce7690dbd9e576e0635f13ce83436d10af6b8bac718ad3f70646f491a2d34425df8ef6080aa0c3ed67892012fb1e7d833e08a694468caee6edaecca49cd5f3b43faf01e795aad2298f0a44f334c0a3730d80d845678782e3523f0aadf2c50280a1339d41a65f7c7620d17488d79cda0419b6f7620e087317f7c5b31d39707d5b2448df48d0edb06e2bfe7651ddaae62fa8548bbab399323365ede7b64da6e9714b17e6d71d4f3ffe982eb2a2ad7b728ec7ee4da5e83db332a633e1f92f23616d35c0530e2243d2b3243f4de396ed1bd5cd96a1d646b006e2435d0a36d1da7b1d998842a11c33494724368d5d1031069d7bb8540e7cae9efa4bcc478b7ad8fd0c612f3da0d7f6e93fa82a52680c948ab4b84c90b9cc5e65077224ecafca016d060f82db6d942ce83d8fc073329a7b08aaa1bdfdc3fb797610f0e373ca0ac25e33ce26d364c618609e4ce6bd085057ac454bb04ff2fc8442e0e3c91f2f62cb7165c360caadfe46f66aa958cf98f4a2ee2162a4218d2ecc5861bb2d1e6a5911665f0c6e20f2816b12fc395b3966c09608e9307fb14349bd52928ccd81d07ffc24b2a1f1875d962861a31182b7aa2f3fbe9f9bec7c06e9bc4b3452d7ca9f4a8dfe17d9e640d91854eb9844f420a24824ef2b9de01dc41f489c397630c609d1c1ab2075f1d95b415b05f39e14af6daf7a2a8441832c2116f55f738e5b53334e36d873b7d3a358fbe8a522247f84f1f59cb7bc993ce5dc800db5e2628b35ef7f41a448d46560eb9824565c5136e5f68e20565b2d7689b3bbabccfa8229540f6ee70b0dccd79c8898a15b092f77e9f32d53b56e8c617453a804130612a8228e51dbeb65197de910048e80082046e59df473e9352e1e4fed1e0fde160057a64d7259530b6f18beba3a1d491d7d0eff306ca75bdfebace999f454c1b43962a75577b3bef598bd4ded53602dbfe55bfddd9ef88f58775cd70504fb11d8282f58eed8eca86a9bfa7c4e80b0ed40c188f9b725aa2da7dbb909b2abf128571d031ee078e3d15bab956554da297c4b9e3f4843a8d19c1e01900517e3504fa77d81d6134a31a5fd8da64d981cfdb539c3c5148be2b4942fbce01b8ed9a0338a1b1e72db56014833464bf6f377a1bfb62124638ab6d4e011360d5b56243911f46e33dde47bd23430c04c4d4173a62760335461ced422d18bc7612c3bba00b59f110ab6a4978ef16bcff32e7b305a0dddd8ba5035a8efdf681f979b56a624ae2675dbbebfd763b46edd5dfe1c2cb97cdf3896d589fd720faa84790cfd8bdd4b5d256d14c13fdb3c356bf2009e3ce355f8cc0bd227220ece0a9c93fc1d13f299a06676fa21d672def68726d4a4d97244110b1de4c00c54c81ee9993a037ea89d2a32a694f0b97ee85cf9710bb64d31187ee57e1960b7b9d6bd922cd525e239083f6923970e8f745283665240510ecde426aee14b1f257eacde424eda6b89e8d3ad44345b659c4e0df4640262ff5066cfa2980526380846ec4b39d0b09441bfeca2df5718e9d4aec38d9152bb398b2212e0a27a3b60c796d7a5ed1109288200f5396633e04e874c2869ef97837b1d52cbf323ff8a8c3ba7ade389d8deb66dc6b8e106e06c15ecaa6f55a476882ec5a7c8c8d58b57e5daa4c4d86cd23b196ae4f74bbba8d121ad4c28fe116348497dee06036c04d2eb3398872757b010d93832dcbf60d8441facfaea0db7ddd248fd61b3a65fab2c16e02e78921b934a7bb72cf185088233cd3b45caad99f978e08aae48c2a61fc6dd851204d651336c6c8b551b040914dac8c56ade3f32974c348ae7863f4a243d61f8b8f14ea9f48ab58f15d7d99213455f8bfc236d975e80680c9eaf73b585324f09296b8ce1583bf0a02344a79136cdc3d80d766805071e94aef55f3af4bc59c4c3519606a4e2bb842e79023dc779be90826f1c7d5c64769a4322bcb90adf1f61ff2eedf0a74fd07a92b2a7796b156a90842c28ef49926bb3a551ba6102c4acef08bbc151ecc48195945d5e220ebc50535aefccc126feff5a74b6d7da0f9f39b17c0b6dc3a948542429ddd8c2dd8d6c2b81a8dadc88c7a0c076866bf3c8f2ed02126db42a5007de941ca508228d4b3a615d7b56a3e05559a15baec1a219e92f2380c6c4f874e6d60081acfd3e183eef07b4b4f08d466adc7447e730f3eb219e115bf1cfa1535683b972458cac3b91fcc66fea5cb3c20445453597ad842c09098a0c6abd3fe60412c0c455b1641a4428c1076e1e69dec6f61c0ec3ae23592d3de73ef871f937718cb6f196e6abbcdf377c3215679ccab928f6de6d94a6a129e4e3eb352221124cca52c62e4fddd12db8de083a783a231c2fcc878c65aedeaaa5370e304cee6f8a56e1f3c1933bf7e49467ae1a0b25eb19ac47361d00996e05e49f95c8a34639a26735e3ca00cc972aedc4c24177183d1426d83652a7b69b18f142b968201cd959b50b7e3d13efb2ce858874aecfea25e776843f0a2947c218a05869a76a9838cd132ab1b3b2c94a0355ce7eacaf8db9795f3e779cd3d5b31623ec7725190e5598d8b1e2881861fb9b537c0a1498d6ea5fce4262a72d410b5c368d102237172c871751a1cec2eb141533e718004647c6da54ae8462a53fa6cbb444597e00f34cba3d0295cdcc4ed6b0e697033b06198daa9f655470761f545cc27b345799a912641b7111975dd18e62e7388023ce2981bec35c4fc1a6c22266f5e8555373d74e9cb16830a9f7ebb6cb30b0a08e1f921d8ecc638e8a35282a58b5d0f352145b4fbf9682314b403fa91ff80b0ed25fc691006c56b43a7ba9a654b674f4bd1af4a5d475ceb1b8722559cea64ae16cce87e58daeea64948d25aea7172cdc78c843aa9944c5befa6b81e8bdf9246bddc1532f6928bf3ba63bcf1e4ea9cd31d7a7b088615daa112f74c6e1a04f5bd49575161009a7b156885b110b2ae656cf2773e1da0ed0a820f30d20d787872896d638ae3f8f5cab9e0475c45727fbf79753bcc78ae6d799c08aa329f772a41730b7b9ac1e3f0981ff594e5000cba84c520c05b52c2a36fc6d7967909e70163d6a40cff1628c77602ece67a5452799cd71e48aa935fe63fa73a62aa6a9ac2272d68a478d2813de8a03f31c55b44bc53d32d80954f3ec6b17b9e70bcd76576b04e1f9266b0b983d9576da587a264498a5d96aaca0cc3fda37efad8c2eea9a0308089a97c824bd86dbc29ddf1ddc5af0fab966d5cff915387843eb7e6049ded084e6f0af1bb41c93b613f4029e0af71fe5d6a488e1fa2da98ff27a43c6566e3fc9e4b9940028617da0600582ecd46ac5823186c06acad63d785e42fdf9623408d9c61d73c4daacce4c834455a791d990825fcd4711fc6e2283690bd054ceb6f8a3412aab651fa54738df2932dac3af5b0aa9ffc4d795f6e7a432defc334ec07203882874312efc1e57cc1036b0c044c9508069a780eebb18d7607b64f95a3725c1290cae470412cef1d4ef7832abf318f1a67d1b5acc156adfa563901cc65a78abe49cb27bfef9e77d3a58384c1086f128f642235c238ebb49aa2d51171732d5112d014a6dcefd27ac604092224a21118dd6c4f95e5600aeba5586d77f8d1559420486d8be6109cb6303c84a1294910081c05d9f95f8c56448dff8a7b0c6edb9e89974ecbb5e7c84bb37b748cb0996c5455d83a4108d3959f38ded45a41fb421d17941fbef34e6a867e77c0843b2023c99c03a43960af5511ac1cad628aaebca6cd269d74ef19f06ef8817e497aff0ef92926319bdce6f3f0770435a37882ceb0dcd1b61e9a4496ddf29779247171773487f19078a28b3df1c2bad4424a9d4d430ba9c21fb65c79e14c8757e512ceacd5d1c0daea1bebc07bb25ceb3191b89b883a5c0a95cdac78a72f4f9a985d7c37d2e6151d42be415493ba458590eb0d851025aa914c85724d41c0b46ffbd8c739e8a38181ce365a7fee6262bf5164e084b7e1ec344b56163d1cf6cda61346e63e3c6e4b05509a0b40adabf33d23cec146c3cf9abfb79f647c2d2df506f414c82af06a463acd5e4fc7a31dba4cf5f10586183982e81b2177941b8b422c05d075965e318705f6711efada33d8e4a08e6c7b0d6061e51ecf0267c36d6cb2c4cd99e88225a17979c5558 您好, 这里需要密码.

1023/3/18
articleCard.readMore