diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index a2e4019..4bd6323 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -2,53 +2,278 @@ const base = "/blog-vue-vitepress/"; export default { - base, - // 站点级选项 - title: "是柠新呀的博客", - description: "是柠新呀用来写博客的地方", - head: [ - // 配置网站的图标(显示在浏览器的 tab 上) - ["link", { rel: "icon", href: `${base}favicon.ico` }], - ], - themeConfig: { - docFooter: { - prev: "上一页", - next: "下一页", - }, - nav: [ - { - text: "大前端", - items: [ - { text: "html", link: "/bigFrontEnd/html/" }, - { text: "css", link: "/bigFrontEnd/css/" }, - { text: "js", link: "/bigFrontEnd/js/" }, - ], - }, - { text: "关于", link: "/about" }, + base, + // 站点级选项 + title: "代码港湾", + description: "个人后端知识体系地图", + head: [ + // 配置网站的图标(显示在浏览器的 tab 上) + ["link", {rel: "icon", href: `${base}favicon.ico`}], ], - sidebar: { - "/bigFrontEnd/html/": { - text: "html", - items: [ - { text: "html", link: "/bigFrontEnd/html/" }, - { text: "html1", link: "/bigFrontEnd/html/html1" }, - { text: "html2", link: "bigFrontEnd/html/html2" }, - ], - }, - "/bigFrontEnd/css/": { - text: "css", - items: [ - { text: "css1", link: "/bigFrontEnd/css/css1" }, - { text: "css2", link: "/bigFrontEnd/css/css2" }, + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: 'assets/favicon.png', + //开启本地搜索 + search: { + provider: "local" + }, + //修改侧边栏导航的标题 + outline: { + label: "目录导航" + }, + // 修改文档页脚的文字 + docFooter: { + prev: "上一页", + next: "下一页" + }, + returnToTopLabel: "回到顶部", + sidebarMenuLabel: "菜单", + darkModeSwitchLabel: "主题", + lightModeSwitchTitle: "切换到浅色模式", + darkModeSwitchTitle: "切换到深色模式", + nav: [ + {text: '主页', link: '/index'}, + { + text: '开发', + items: [ + {text: '开发', link: '/开发/index'}, + {text: 'My Java Guide', link: '/开发/My Java Guide/index'}, + {text: '框架', link: '/开发/框架/index用'}, + {text: '前端', link: '/开发/前端/index'}, + ] + }, + { + text: '软件', + items: [ + {text: 'Linux', link: '/软件/Linux/index'}, + {text: 'Windows', link: '/软件/Windows/index'}, + ] + }, + {text: '硬件', link: '/硬件/index'}, + {text: '杂谈', link: '/杂谈/index'}, + {text: '关于我', link: '/about'}, ], - }, - "/bigFrontEnd/js/": { - text: "js", - items: [ - { text: "js1", link: "/bigFrontEnd/js/js1" }, - { text: "js2", link: "/bigFrontEnd/js/js2" }, + + sidebar: { + '/开发/': [ + { + text: '开发', + items: [ + {text: 'JDBC和JAVA类型对比', link: '/开发/JDBC和JAVA类型对比'}, + {text: '对Java中多态的理解', link: '/开发/对Java中多态的理解'}, + {text: 'ThreadLocal原理和使用', link: '/开发/ThreadLocal原理和使用'}, + {text: 'C++的STL库常见函数', link: '/开发/C++的STL库常见函数'}, + {text: 'MYDB操作手册', link: '/开发/MYDB操作手册'}, + {text: 'SSO单点登录的实现原理', link: '/开发/SSO单点登录的实现原理'}, + {text: '批量导出zip压缩包和Excel表格', link: '/开发/批量导出zip压缩包和Excel表格'}, + {text: '阿里云OSS && 内容安全 Java实现参考代码', link: '/开发/阿里云OSS && 内容安全 Java实现参考代码'}, + { + text: 'My Java Guide', + collapsed: false, + items: [ + {text: "My Java Guide - Java基础", link: "/开发/My Java Guide/My Java Guide - Java基础"}, + {text: "My Java Guide - JVM", link: "/开发/My Java Guide/My Java Guide - JVM"}, + {text: "My Java Guide - Spring", link: "/开发/My Java Guide/My Java Guide - Spring"}, + {text: "My Java Guide - 分布式", link: "/开发/My Java Guide/My Java Guide - 分布式"}, + {text: "My Java Guide - 数据库", link: "/开发/My Java Guide/My Java Guide - 数据库"}, + {text: "My Java Guide - 算法", link: "/开发/My Java Guide/My Java Guide - 算法"}, + {text: "My Java Guide - 缓存", link: "/开发/My Java Guide/My Java Guide - 缓存"}, + {text: "My Java Guide - 计算机基础", link: "/开发/My Java Guide/My Java Guide - 计算机基础"}, + {text: "My Java Guide - 项目", link: "/开发/My Java Guide/My Java Guide - 项目"}, + ] + }, + { + text: "框架", + collapsed: false, + items: [ + {text: "Juint5断言的代码使用", link: "/开发/框架/Juint5断言的代码使用"}, + {text: "Kafka原理", link: "/开发/框架/Kafka原理"}, + {text: "kafka配置属性说明", link: "/开发/框架/kafka配置属性说明"}, + {text: "MongoDB和MySQL的常用语法对比", link: "/开发/框架/MongoDB和MySQL的常用语法对比"}, + {text: "MybatisPlus依赖和配置文件", link: "/开发/框架/MybatisPlus依赖和配置文件"}, + {text: "Mybatis注解开发使用举例", link: "/开发/框架/Mybatis注解开发使用举例"}, + {text: "MySql数据库命令", link: "/开发/框架/MySql数据库命令"}, + {text: "Netty与NIO的前世今生", link: "/开发/框架/Netty与NIO的前世今生"}, + {text: "Nginx的配置和使用命令", link: "/开发/框架/Nginx的配置和使用命令"}, + {text: "Quarkus云原生时代的Java框架", link: "/开发/框架/Quarkus云原生时代的Java框架"}, + {text: "RabbitMQ快速上手", link: "/开发/框架/RabbitMQ快速上手"}, + {text: "Redis在SpringBoot的配置", link: "/开发/框架/Redis在SpringBoot的配置"}, + {text: "Redis基本数据类型常用命令", link: "/开发/框架/Redis基本数据类型常用命令"}, + {text: "RocketMQ原理", link: "/开发/框架/RocketMQ原理"}, + {text: "SpringMVC注解和配置 + fastjson的简单使用", link: "/开发/框架/SpringMVC注解和配置 + fastjson的简单使用"}, + {text: "thymeleaf的th-href带参数转跳", link: "/开发/框架/thymeleaf的th-href带参数转跳"}, + {text: "Tomcat启动关闭命令", link: "/开发/框架/Tomcat启动关闭命令"}, + ] + }, + { + text: "前端", + collapsed: false, + items: [ + {text: 'HTML标签重点划注', link: '/开发/前端/HTML标签重点划注'}, + {text: 'CSS知识重点划注', link: '/开发/前端/CSS知识重点划注'}, + {text: '几个免版权图片网站', link: '/开发/前端/几个免版权图片网站'}, + {text: 'Vue的事件修饰符', link: '/开发/前端/Vue的事件修饰符'}, + ] + }, + ] + } + ], + '/软件/': [ + { + text: "软件", + items: [ + {text: "Git的配置和使用命令", link: "/软件/Git的配置和使用命令"}, + {text: "Docker安装配置及使用命令", link: "/软件/Docker安装配置及使用命令"}, + {text: "nodejs相关命令", link: "/软件/nodejs相关命令"}, + {text: "curl命令的用法", link: "/软件/curl命令的用法"}, + {text: "Hexo常用命令", link: "/软件/Hexo常用命令"}, + {text: "基于YOLOv8模型的抽烟行为检测系统", link: "/软件/基于YOLOv8模型的抽烟行为检测系统"}, + {text: "JetBrains全家桶破解", link: "/软件/JetBrains全家桶破解"}, + {text: "关于bing国内重定向解决方案", link: "/软件/关于bing国内重定向解决方案"}, + {text: "哔哩哔哩成分鉴定器(个人魔改版)", link: "/软件/哔哩哔哩成分鉴定器(个人魔改版)"}, + {text: "markdown语法", link: "/软件/markdown语法"}, + { + text: "Linux", + collapsed: false, + items: [ + {text: "Linux常用命令.md", link: "/软件/Linux/Linux常用命令.md"}, + {text: "zsh与bash的切换.md", link: "/软件/Linux/zsh与bash的切换.md"}, + {text: "安装oh my zsh主题.md", link: "/软件/Linux/安装oh my zsh主题.md"}, + {text: "CentOS my zsh主题.md", link: "/软件/Linux/CentOS my zsh主题.md"}, + {text: "CentOS7安装ohmyzsh.md", link: "/软件/Linux/CentOS7安装ohmyzsh.md"}, + {text: "在ARM架构的Mac上运行exe程序.md", link: "/软件/Linux/在ARM架构的Mac上运行exe程序.md"}, + {text: "切换jdk版本的方法(环境变量法).md", link: "/软件/Linux/切换jdk版本的方法(环境变量法).md"}, + {text: "切换jdk版本的方法(jenv法).md", link: "/软件/Linux/切换jdk版本的方法(jenv法).md"}, + {text: "option和shift特殊符号.md", link: "/软件/Linux/option和shift特殊符号.md"}, + {text: "Unix系统下的Shell命令.md", link: "/软件/Linux/Unix系统下的Shell命令.md"}, + {text: "Mac调整docker Shell命令.md", link: "/软件/Linux/Mac调整docker Shell命令.md"}, + {text: "Mac调整docker栏目.md", link: "/软件/Linux/Mac调整docker栏目.md"}, + {text: "Mac查看固态使用情况.md", link: "/软件/Linux/Mac查看固态使用情况.md"}, + {text: "Mac删除OBS的虚拟摄像头.md", link: "/软件/Linux/Mac删除OBS的虚拟摄像头.md"}, + {text: "Mac上PD17虚拟机终端启动命令.md", link: "/软件/Linux/Mac上PD17虚拟机终端启动命令.md"}, + {text: "Homebrew常用命令.md", link: "/软件/Linux/Homebrew常用命令.md"}, + {text: "bash与zsh的切换.md", link: "/软件/Linux/bash与zsh的切换.md"} + ] + }, + { + text: "Windows", + collapsed: false, + items: [ + {text: "windows终端美化.md", link: "/软件/Windows/windows终端美化.md"}, + {text: "VMware固定虚拟机ip.md", link: "/软件/Windows/VMware固定虚拟机ip.md"}, + {text: "更改固态硬盘磁盘为GPT格式.md", link: "/软件/Windows/更改固态硬盘磁盘为GPT格式.md"}, + {text: "win批量硬盘磁盘为GPT格式.md", link: "/软件/Windows/win批量硬盘磁盘为GPT格式.md"}, + {text: "win批量删除特定格式开头的文件.md", link: "/软件/Windows/win批量删除特定格式开头的文件.md"}, + {text: "Windows上解决端口占用.md", link: "/软件/Windows/Windows上解决端口占用.md"}, + {text: "winWindows11安装卸载安卓软件.md", link: "/软件/Windows/winWindows11安装卸载安卓软件.md"} + ] + }, + { + text: "Python", + collapsed: true, + items: [ + {text: "人工智能十大算法", link: "/软件/Python/人工智能十大算法"}, + {text: "conda创建虚拟环境,安装Pytorch", link: "/软件/Python/conda创建虚拟环境,安装Pytorch"}, + {text: "解决Anaconda安装后命令行前出现 (base)", link: "/软件/Python/解决Anaconda安装后命令行前出现 (base)"}, + { + text: "jupyter相关", + collapsed: false, + items: [ + {text: "jupyter 常用操作和命令", link: "/软件/Python/jupyter常用操作和命令"}, + {text: "jupyter 增加、删除内核", link: "/软件/Python/jupyter增加、删除内核"}, + {text: "jupyter 快捷键", link: "/软件/Python/jupyter notebook快捷键"}, + {text: "jupyter 更换主题", link: "/软件/Python/jupyter更换主题"}, + ] + }, + {text: "Pytorch下载配置,Anaconda创建虚拟环境", link: "/软件/Python/Pytorch下载配置,Anaconda创建虚拟环境"}, + {text: "torch常用命令", link: "/软件/Python/torch常用命令"}, + {text: "YOLOv5的使用", link: "/软件/Python/YOLOv5的使用"}, + {text: "图像处理模块封装函数", link: "/软件/Python/图像处理模块封装函数"}, + ] + }, + ] + } + ], + '/硬件/': [ + { + text: "硬件", + items: [ + {text: "人工智能十大算法", link: "/Python/人工智能十大算法"}, + {text: "conda创建虚拟环境,安装Pytorch", link: "/Python/conda创建虚拟环境,安装Pytorch"}, + {text: "解决Anaconda安装后命令行前出现 (base)", link: "/Python/解决Anaconda安装后命令行前出现 (base)"}, + { + text: "jupyter相关", + collapsed: false, + items: [ + {text: "jupyter 常用操作和命令", link: "/Python/jupyter常用操作和命令"}, + {text: "jupyter 增加、删除内核", link: "/Python/jupyter增加、删除内核"}, + {text: "jupyter 快捷键", link: "/Python/jupyter notebook快捷键"}, + {text: "jupyter 更换主题", link: "/Python/jupyter更换主题"}, + ] + }, + {text: "Pytorch下载配置,Anaconda创建虚拟环境", link: "/Python/Pytorch下载配置,Anaconda创建虚拟环境"}, + {text: "torch常用命令", link: "/Python/torch常用命令"}, + {text: "YOLOv5的使用", link: "/Python/YOLOv5的使用"}, + {text: "图像处理模块封装函数", link: "/Python/图像处理模块封装函数"}, + ] + } + ], + '/杂谈/': [ + { + text: "杂谈", + items: [ + {text: "项目master心得体会", link: "/杂谈/项目master心得体会"}, + {text: "分享一下我Mac使用的软件", link: "/杂谈/分享一下我Mac使用的软件"}, + {text: "Stable Diffusion信息备忘录", link: "/杂谈/Stable Diffusion信息备忘录"}, + {text: "stable-diffusion-webui结合NovelAI的模型生成动漫人物图片", link: "/杂谈/stable-diffusion-webui结合NovelAI的模型生成动漫人物图片"}, + {text: "实验室服务器-用户初始化入门流程指南", link: "/杂谈/实验室服务器-用户初始化入门流程指南"}, + {text: "重装系统需下载软件清单", link: "/杂谈/重装系统需下载软件清单"}, + {text: "个人动漫、游戏生涯总结表", link: "/杂谈/个人动漫、游戏生涯总结表"}, + {text: "日语假名、罗马音大全", link: "/杂谈/日语假名、罗马音大全"}, + {text: "AI作画杀疯了", link: "/杂谈/AI作画杀疯了"}, + {text: "终于把Revit搞完了", link: "/杂谈/终于把Revit搞完了"}, + {text: "硬件好难搞啊!", link: "/杂谈/硬件好难搞啊!"}, + {text: "读研实在太难了", link: "/杂谈/读研实在太难了"}, + {text: "开学被移动人员搞了", link: "/杂谈/开学被移动人员搞了"}, + {text: "给三星T7加装散热片,改善Mac上的发热问题", link: "/杂谈/给三星T7加装散热片,改善Mac上的发热问题"}, + {text: "又增加了奇怪的属性", link: "/杂谈/又增加了奇怪的属性"}, + {text: "还得是你啊牛奶社", link: "/杂谈/还得是你啊牛奶社"}, + {text: "小孩真头疼", link: "/杂谈/小孩真头疼"}, + {text: "22年7月我觉得最棒的动画捏!", link: "/杂谈/22年7月我觉得最棒的动画捏!"}, + {text: "一种全新的博客图片显示方式", link: "/杂谈/一种全新的博客图片显示方式"}, + {text: "听说你喜欢搞BIM", link: "/杂谈/听说你喜欢搞BIM"}, + {text: "无职转生事件,动画区不会忘记的历史", link: "/杂谈/无职转生事件,动画区不会忘记的历史"}, + { + text: "后日谈", + collapsed: true, + items: [ + {text: "2024年9月记录", link: "/杂谈/后日谈/2024年9月记录"}, + {text: "2024年暑期记录", link: "/杂谈/后日谈/2024年暑期记录"}, + {text: "2024年4、5月记录", link: "/杂谈/后日谈/2024年4、5月记录"}, + {text: "2024年3月记录", link: "/杂谈/后日谈/2024年3月记录"}, + {text: "2024年1月记录", link: "/杂谈/后日谈/2024年1月记录"}, + {text: "2023年12月记录", link: "/杂谈/后日谈/2023年12月记录"}, + {text: "2023年11月记录", link: "/杂谈/后日谈/2023年11月记录"}, + {text: "2023年10月记录", link: "/杂谈/后日谈/2023年10月记录"}, + {text: "2023年9月记录", link: "/杂谈/后日谈/2023年9月记录"}, + {text: "2023年暑假记录", link: "/杂谈/后日谈/2023年暑假记录"}, + {text: "2023年6月记录", link: "/杂谈/后日谈//2023年6月记录"}, + {text: "2023年4、5月记录", link: "/杂谈/后日谈/2023年4、5月记录"}, + {text: "2023年3月记录", link: "/杂谈/后日谈/2023年3月记录"}, + {text: "2023年2月记录", link: "/杂谈/后日谈/2023年2月记录"}, + {text: "2023年1月记录", link: "/杂谈/后日谈/2023年1月记录"}, + {text: "2022年12月记录", link: "/杂谈/后日谈/2022年12月记录"}, + {text: "2022年11月记录", link: "/杂谈/后日谈/2022年11月记录"} + ] + + }, + ] + + } + ] + }, + socialLinks: [ + {icon: 'github', link: 'https://github.com/01Petard'} ], - }, - }, - }, + } }; diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 0000000..d610a7b --- /dev/null +++ b/docs/about.md @@ -0,0 +1,46 @@ +--- +title: 关于我 +date: 2022-08-02 16:08:07 +type: "about" +comments: false +--- + +
+

+ I wish you to become your own sun , no need to rely on who’s light. +

+

+ —— 愿你成为自己的太阳,无需凭借谁的光芒。 +

+
+ +## 👲 基本信息 + +```yaml +Name: 伪音花火 / 01Petard +Address: Zhejiang, Hangzhou +Github: https://github.com/01Petard +Blog: https://01petard.github.io +Hobbies: Bangumis, Doujin, Surfing Online, Digital Devices +``` + +## 🔨 技术栈 + +- 一直在学SpringBoot,已经会部署和跨域了(好耶✌️) +- 苦学Vue,梦想是全栈,得理不饶人(JavaScript,🍋什么时候🌲?) +- 除了开发,还了解一点Opencv(GAN超分辨好棒👍) +- 懂点安卓,但是好久没做项目了(Unix才是程序员永远的🏠) +- 了解Java、Python、C++等语法(Java是格式最好看的语言!☕️) +- …… + +## 💘 关于本站 + +采用 Hexo 框架 + Butterfly 主题搭建。博客中的图片均由PicGo管理,并上传至我的Github图床。本博客文章采用 CC BY-NC-SA 4.0 协议,转载请注明出处。 + +## 🙋 免责声明 + +本站以分享经验、知识还有我的个人爱好为为目的,所有文章所涉及使用的工具、资源均源自互联网,本人不对因浏览网站内容而产生的实际问题负责。 +本网站仅进行搬运和分享以供学习和研究使用,版权归作者所有,如果无意之中侵犯了您的版权,请右下角私信与我取得联系,我将在第一时间删除!另外, 本站内的文章仅供学习交流之用,不参与商业用途。 + +**Last Update:2022-04-23** + diff --git a/docs/index.md b/docs/index.md index 83102d4..b69197a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,19 +2,31 @@ layout: home hero: - name: 是柠新呀的博客 + name: "代码港湾" text: awesome-front-end-world. - tagline: 前端 知识体系地图 + tagline: 个人后端知识体系地图 image: - src: /logo.jpg - alt: logo + src: /01petard.jpg + alt: 01petard actions: - theme: brand - text: Get Started - link: /bigFrontEnd/html/ + text: 开发 + link: /开发/index + - theme: brand + text: 前端 + link: /前端/index + - theme: brand + text: 软件 + link: /软件/index + - theme: brand + text: 硬件 + link: /硬件/index + - theme: alt + text: 关于我 + link: /about - theme: alt text: View on GitHub - link: https://github.com/xuxing409/blog-demo + link: https://github.com/01Petard --- +``` + +**3、外部样式(优先级:覆盖原则)** + +```html + +``` + +```css +h1{ + color: yellow; +} +``` + +### 二、选择器 + +#### 2.1 基本选择器 + +**1、标签选择器**,特点:选择一类标签 + +**2、类选择器(.class)**,特点:选择所有class属性一致的标签,跨标签 + +**3、id选择器(#id)**,***id必须保证全局唯一*** + +**优先级:id选择器>类选择器>标签选择器** + +#### 2.2 层次选择器 + +**1、后代选择器(后代,所有)** + +```css +/*对象:选中元素下的所有对象。例子中是选中了body下的所有p标签*/ +body p{ + background: red; +} +``` + +**2、子选择器(儿子,所有)** + +```css +/*对象:选中对象下的所有子级标签。例子中是选中了body下的所有子级p标签*/ +body > p{ + background: red; +} +``` + +**3、相邻弟级选择器(同辈,一个)** + +```css +/*对象:选中对象下的一个弟标签。例子中是选中了class名为bro下面的一个弟级p标签*/ +.bro + p{ + background: red; +} +``` + +**4、通用弟级选择器(同辈,所有)** + +```css +/*对象:选中对象下的所有弟级标签。例子中是选中了class为bro下面的所有弟级p标签*/ +.bro ~ p{ + background: red; +} +``` + +#### 2.3 结构、伪类选择器(了解即可) + +**1、选择第一个子元素** + +```css +/*ul的第一个子元素*/ +ul li:first-child{ + background: red; +} +``` + +**2、选择最后一个子元素** + +```css +/*ul的最后一个子元素*/ +ul li:last-child{ + background: yellow; +} +``` + +**3、层级选择** + +```css +/*选择当前层级的父元素模型中的第n个子元素标签*/ +p:nth-child(n){ + background: green; +} +/*选择当前层级的父元素模型中的第n个同类型的标签*/ +p:nth-of-type(n){ + background: blue; +} +``` + +**4、伪类选择器** + +```css +/*悬浮的样式,重要‼️*/ +a:hover{ + color: orange; +} +/*被选择的样式,重要‼️*/ +a:active{ + color: green; +} +/*未访问的样式*/ +a:link{ + color: green; +} +/*已访问的样式*/ +a:visited{ + color: purple; +} +``` + +#### 2.4 属性选择器(把id和class结合了) + +**1、id选择器**(=绝对等于) + +```css +a[id="first"]{ + background:red; +} +``` + +**2、类选择器**(*=包含等于) + +```css +a[class*="links"]{ + background:yellow; +} +``` + +**3、选择href中以http开头的元素**(^=以这个开头) + +```css +a[href^=http]{ + backfround: green; +} +``` + +**4、选择href中以jpg结尾的元素**($=以这个开头) + +```css +a[href$=http]{ + backfround: blue; +} +``` + +### 三、美化网页元素 + +文字排版、背景图片…… + +### 四、渐变 + +也略了,没什么好说的,直接网页拿就行了⬇️ + +> [Grabient快速获取渐变css代码](https://www.grabient.com/) + +### 五、盒子模型(重要‼️) + +**margin:外边距** + +**border:边框** + +**padding:内边距** + +**块级元素:**独占一行 + +> h1~h6 p div 列表…… + +**行内元素:**只有内容的大小 + +> span a img strong + +行内元素可以被包含在块级元素中,反之,则不可以~ + +**display:**可以修改标签的块级/行内属性 + +**float:**可以让元素悬浮,脱离父级元素 + +**position:**可以规定元素的定位类型,可能的值有relative、absolute、fixed diff --git "a/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/HTML\346\240\207\347\255\276\351\207\215\347\202\271\345\210\222\346\263\250.md" "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/HTML\346\240\207\347\255\276\351\207\215\347\202\271\345\210\222\346\263\250.md" new file mode 100644 index 0000000..41fe0b1 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/HTML\346\240\207\347\255\276\351\207\215\347\202\271\345\210\222\346\263\250.md" @@ -0,0 +1,213 @@ +--- +title: HTML标签重点划注 +date: 2022-02-17 21:42:15 +updated: +categories: +- 学习 +tags: +- 前端 +- HTML +keywords: +- 前端 +- HTML +description: 不如elementUI和飞冰,但是基础还是要掌握的 +cover: https://www.oxfordwebstudio.com/user/pages/06.da-li-znate/sta-je-html/sta-je-html.jpg +top_img: http://vimaj.com/images/html-dersleri.jpg +--- + +- 1、粗体: + +```html +粗体 +``` + +- 2、斜体 + +```html +斜体 +``` + +- 3、特殊符号: + +[HTML特殊字符符号大全](https://www.webhek.com/post/html-enerty-code.html)(查看更多) + +![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/Snipaste_2022-08-05_20-33-43.png) + +- 4、锚链接 + +```html + +... + + + +... +... + + +``` + +- 5、功能性链接 + +```html + + +``` + +例子:qq推广链接 +https://shang.qq.com/v3/widget.html + +```html + +点击这里给我发消息 +``` + +注:51标准型,52简洁型,53扩展型 + +![](https://s3.bmp.ovh/imgs/2022/02/9b23f129b54f556b.png) + +- 6、行内元素 + +```html + + + +``` + +- 7、块元素 + +```html +

+

+... +
+``` + ++ 8、有序列表 + +```html +
    +
  1. 1
  2. +
  3. 2
  4. +
  5. 3
  6. +
+``` + +- 9、无序列表 + +```html + +``` + +- 10、自定义列表 + +```html +
+
课程
+
语文
+
数学
+
英语
+
老师
+
王老师
+
张老师
+
刘老师
+
+``` + +- 11、表格 + +```html + + + + + + + + + + + + + + + + + + +
1-11-21-3
2-12-22-3
3-13-23-3
+``` + +- 12、视频 + +```html + + + +``` + +- 13、页面结构分析 + +![](https://s3.bmp.ovh/imgs/2022/02/25a08233bf4835ff.png) + +14、iframe(内联框架) + +```html + + + +``` + +```html + + +``` + +- 15、表单的提交方式: + +> get:不安全,但是高效 + +> post:安全,可以传输大文件 + +表单的属性 + +![](https://s3.bmp.ovh/imgs/2022/02/79ddff777a41e251.png) + +- 16、一组单选框(type="radio")要指定name属性的值相同(组名) + +![](https://s3.bmp.ovh/imgs/2022/02/c1a68c17e87266f2.png) + +- 17、一组多选框(type="checkbox")“最好”指定name的属性值相同 + +![](https://s3.bmp.ovh/imgs/2022/02/7d6b158b0f7e785c.png) + +- 18、表单中的四种按钮 + +![](https://s3.bmp.ovh/imgs/2022/02/5d635e77d6899fc9.png) + +- 19、下拉框 + +![](https://s3.bmp.ovh/imgs/2022/02/09feae55302a2648.png) + +其中,select标签的“name属性值”和option标签的“value属性值”将分别作为表单提交的“键”和“值” + +![](https://s3.bmp.ovh/imgs/2022/02/41e2a032625f2fe1.png) + +- 20、其他表单type属性 + +![](https://s3.bmp.ovh/imgs/2022/02/3e89985f2e35d6b8.png) + +- 21、label标签,单击label标签内的文字,就可以编辑与for属性与id属性值相同的input标签,如此一来就可以增强鼠标可用性![](https://s3.bmp.ovh/imgs/2022/02/05aff21393b8aa9b.png) + +- 22、pattern属性,利用正则表达式自定义格式 + +```html + +``` diff --git "a/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/Vue\347\232\204\344\272\213\344\273\266\344\277\256\351\245\260\347\254\246.md" "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/Vue\347\232\204\344\272\213\344\273\266\344\277\256\351\245\260\347\254\246.md" new file mode 100644 index 0000000..91921ec --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/Vue\347\232\204\344\272\213\344\273\266\344\277\256\351\245\260\347\254\246.md" @@ -0,0 +1,25 @@ +--- +title: Vue的事件修饰符 +date: 2022-03-11 18:51:15 +updated: +categories: +- 学习 +tags: +- Vue +- 事件修饰符 +keywords: +- Vue +- 事件修饰符 +description: Vue的几个常见事件修饰符 +cover: https://positivethinking.tech/wp-content/uploads/2021/01/Logo-Vuejs.png +top_img: https://pic1.zhimg.com/v2-bfc9c0f0b8668f3ecf84ac5da71d9aea_720w.jpg?source=172ae18b +--- + +Vue的事件修饰符: + +- prevent:阻止默认事件(常用); +- stop:阻止事件冒泡(常用); +- once:事件只触发一次(常用); +- capture:使用事件的捕获模式; +- self:只有event.target是当前操作的元素时才触发事件; +- passive:事件的默认行为立即执行,无需等待事件回调执行完毕; diff --git "a/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/index.md" "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/index.md" new file mode 100644 index 0000000..2f3abb1 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/index.md" @@ -0,0 +1 @@ +## 前端 \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/\345\207\240\344\270\252\345\205\215\347\211\210\346\235\203\345\233\276\347\211\207\347\275\221\347\253\231.md" "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/\345\207\240\344\270\252\345\205\215\347\211\210\346\235\203\345\233\276\347\211\207\347\275\221\347\253\231.md" new file mode 100644 index 0000000..061dc7e --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\345\211\215\347\253\257/\345\207\240\344\270\252\345\205\215\347\211\210\346\235\203\345\233\276\347\211\207\347\275\221\347\253\231.md" @@ -0,0 +1,61 @@ +--- +title: 几个免版权图片网站 +date: 2022-03-06 20:00:15 +updated: +categories: +- 学习 +tags: +- 图片 +keywords: +- 图片 +- 免版权 +description: 适合找素材的图片网站 +cover: https://pic1.zhimg.com/v2-f05bfdfc20ce6e1111c0fdd5c015aa61_720w.jpg?source=172ae18b +top_img: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSgqwFBTACF4LfF55ZDUsxNespfkJ-uta1JcAjL2MdCYx1Wo9v18kLZGjI_JBeedKZZeyA&usqp=CAU +--- + + + +**Unsplash** + +非常著名的一家无版权图片网站,提供大量的无版权图片,而且图片质量非常的高,也是我经常关顾的一家。这个网站的图片以风景为主,很多图片的滤镜感很强,适合做背景或者壁纸。 + +![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/fc1f4134970a304ec0400d855afa0982c9175c22-20220802154238852.jpeg) + +**Pixabay** + +这个网站支持中文搜索,图片数量十分的巨大,据说是世界上最大的免费图片网站,在配图的时候也经常用这个网站代替百度图片。在图片的数量上应该远大于unsplash,是我除了百度图片外最常用的图片搜索引擎。 + +![img](https://pics5.baidu.com/feed/42a98226cffc1e176c315b91c1a25807728de9b8.jpeg?token=f6dbfab1e4f9536f8b778eb5490a82fa&s=2F504C83172A35094E18949703001091) + +**visualhunt** + +这个无版权图片网站的图片数量也比较的丰富,比较有特色的是,可以根据色系来选择和搜索照片,这项功能还是非常人性化的。 + +![img](https://pics5.baidu.com/feed/ae51f3deb48f8c54708187f3b01b83f1e1fe7f57.jpeg?token=f5cbacca2c067f9a242b2ea0003648ea&s=1D98AD5F3C69130D4B6C02E50300E023) + +**别样网** + +现在好像改名沙沙野了,不过还是喜欢叫它别样图,全球高质量图片聚合中心 + +图库不算大,但是个人比较喜欢的网站,在内容上主要以旅行内容为主,每天都会有一定数量的照片更新在主页,所以每天打开这个网站基本上都是不一样的,图片的质量都很高。 + +![img](https://pics6.baidu.com/feed/7af40ad162d9f2d35579faad22de24176327cc3b.jpeg?token=91a91290ca0c446b7ff09d00d5d99a6d&s=6DD2578304722B9A5C24551E0300C091) + +**pngimg** + +国内也有不少做免抠素材的网站,不过基本上都是免费的,而我说的这个网站则是完全免费的,据说提供有七万张透明背景的图片素材全都免费使用,而且按分类检索和搜索框搜索。 + +![img](https://pics7.baidu.com/feed/d058ccbf6c81800a8af963b33a079dfe828b4722.jpeg?token=1f077dec217ff81471abfde545db45d1&s=109E5033598E44C8027DA0DA01005032) + +**Pexels Videos** + +除了图片有版权问题,视频也有版权问题,这个网站提供免版权的视频素材,平常制作短视频的时候不要乱用内容了,可以到这个网站看看有没有合适的素材。 + +![img](https://pics4.baidu.com/feed/279759ee3d6d55fbc654cb7ee610e14e21a4dd8b.jpeg?token=6090d2e0146bae6920277a100a46a727&s=BB3245810430898A0A91100C030030D0) + +**Flaticon** + +这个网站提高免费图标的,我们在做PPT或者海报的时候经常需要找一些图标,这个网站提供一百多万的图标素材,而且全部免费使用。 + +![img](https://pics1.baidu.com/feed/d833c895d143ad4b19c39f1c0830f4aba50f0630.jpeg?token=bc9e7e0c7e30e5bc188d6415940f31e0&s=12B1E9205CA82C886CA755CC030030B2) \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\345\257\271Java\344\270\255\345\244\232\346\200\201\347\232\204\347\220\206\350\247\243.md" "b/docs/\345\274\200\345\217\221/\345\257\271Java\344\270\255\345\244\232\346\200\201\347\232\204\347\220\206\350\247\243.md" new file mode 100644 index 0000000..a184556 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\345\257\271Java\344\270\255\345\244\232\346\200\201\347\232\204\347\220\206\350\247\243.md" @@ -0,0 +1,172 @@ +--- +title: 对Java中多态的理解 +date: 2022-02-25 21:59:15 +updated: +categories: +- 学习 +tags: +- Java +- 多态 +keywords: +- Java +- 多态 +description: 理解Java中的多态 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212221954.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212222914.png +--- + +### 一、“多态”的理解 + +先看Java代码: + +```java +public class Example { + public static void main(String[] args) { + System.out.println("====人===="); + Person person = new Person("叽里呱啦","默认皮肤"); + person.say(); + person.showSkin(); + person.walk(); + person.eat(); + person.sleep(); + + //多态 + System.out.println("====中国人===="); + Person chinese = new Chinese("中文","黄皮肤"); + chinese.say(); + chinese.showSkin(); + chinese.walk(); + chinese.eat(); + chinese.sleep(); + + System.out.println("====美国人===="); + Person american = new American("英文","白皮肤"); + american.say(); + american.showSkin(); + american.walk(); + american.eat(); + american.sleep(); + } +} +class Person { + String language; + String skinColor; + public Person() {} + public Person(String language, String skinColor) { + this.language = language; + this.skinColor = skinColor; + } + public void say(){ + System.out.println("说"+this.language); + } + public void showSkin(){ + System.out.println(this.skinColor); + } + public void walk(){ + System.out.println("人走路"); + } + public void eat(){ + System.out.println("人吃饭"); + } + public void sleep(){ + System.out.println("人睡觉"); + } +} +class Chinese extends Person { + public Chinese(){} + public Chinese(String language, String skinColor) { + super(language,skinColor); + } +} +class American extends Person { + public American(){} + public American(String language, String skinColor) { + super(language,skinColor); + } +} +``` + +运行结果: + +![image-20220225175107033](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/e6c9d24ely1gzpwleppjpj211e0nutad.jpg) + +#### 总结:多态的意义就是,当new出来的对象中自己“独特的”方法时,默认采用申明类型中“普遍的”方法,“多态”这一词的含义就来源于这种用于对创造的对象的广泛性的意义。 + + + +### 二、“向上转型”和“向下转型”的用法 + +```java +class Animal{ + public void shout() { + System.out.println("动物叫"); + } + public void eat(){ + System.out.println("动物吃"); + } +} +class Dog extends Animal{ + @Override + public void shout() { + System.out.println("狗叫"); + } + public void home() { + System.out.println("狗看门"); + } + +} +class Cat extends Animal{ + @Override + public void shout() { + System.out.println("猫叫"); + } + public void sleep() { + System.out.println("猫趴窝"); + } +} + +public class AnimalInf{ + //public static void shout(Animal an) { + // an.shout(); + //} + public static void main(String[] args) { + Dog dog1 = new Dog(); + Animal dog2 = new Dog();//向上转型后只会调用父类中方法 + System.out.print("dog1.shout():"); + dog2.shout(); + System.out.print("dog2.shout():"); + dog2.shout();//虽然转型成了Animal类,但是因为Dog类中重写了shout方法,所以是“狗叫”,这就叫《方法的调用看父类,运行结果看子类,重写的方法看子类》 + System.out.print("dog1.home():"); + dog1.home(); + System.out.print("dog2.eat():"); + dog2.eat();//调用了Animal类中的方法, +// dog2.home();//这里会报错,因为向上转型调用方法看左边,结果看重写,而Animal类中没有home方法 + + Dog dog3 = (Dog)dog2;//向下转型后,dog2才成为了一个Dog类的对象 + System.out.print("dog3.shout():"); + dog3.shout(); + System.out.print("dog3.home():"); + dog3.home(); + System.out.print("dog3.eat():"); + dog3.eat(); + + //用instaceof测试一个对象是否为一个类的实例 + Animal cat1 = new Cat(); + System.out.println(dog1 instanceof Dog);//true + System.out.println(dog2 instanceof Animal);//true + System.out.println(cat1 instanceof Dog);//false + System.out.println(cat1 instanceof Cat);//true,因为cat1是Cat的间接子类 + System.out.println(cat1 instanceof Animal);//true + + /* + 会报错ClassCastException的异常,因为不能由子类(Dog)推出父类(Animal)中的细节,多态因该是由上到下的"抽象模糊形态" + Dog dog = (Dog) new Animal(); + dog.eat(); + */ + + } +} + +``` + +#### 总结:向上转型和向下转型还是Java多态中比较重要的一个知识点! \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\211\271\351\207\217\345\257\274\345\207\272zip\345\216\213\347\274\251\345\214\205\345\222\214Excel\350\241\250\346\240\274.md" "b/docs/\345\274\200\345\217\221/\346\211\271\351\207\217\345\257\274\345\207\272zip\345\216\213\347\274\251\345\214\205\345\222\214Excel\350\241\250\346\240\274.md" new file mode 100644 index 0000000..7fde1d6 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\211\271\351\207\217\345\257\274\345\207\272zip\345\216\213\347\274\251\345\214\205\345\222\214Excel\350\241\250\346\240\274.md" @@ -0,0 +1,67 @@ +--- +title: 批量导出zip压缩包和Excel表格 +date: 2024-06-28 14:31:00 +updated: 2024-08-10 18:40:00 +categories: +- 学习 +tags: +- 文件操作 +- 压缩包 +- 表格 +- 导入 +- 导出 +keywords: +- 文件操作 +- 压缩包 +- 表格 +- 导入 +- 导出 +description: 批量导出zip压缩包和Excel表格 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212200646.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212201073.png +--- + +## 批量导出压缩包 + +> 前提:需要导出的文件都有url,且保存在文件服务器上 + +总的来说使用Redis和MQ完成,共分为三步: + +1. 前端发送需要导出的id集合对象,后端将请求对象序列化后发送到mq触发**后台任务**,返回给前端一个uuid; + - **后台任务**:向文件服务器查询需要下载的文件url,获取所有文件后使用 `File.createTempFile()`方法生成一个临时压缩文件,使用`ZipEntry`将文件转化成Zip文件类型,再用`ZipOutPutStream`将所有文件合并成一个压缩包,然后使用`HttpRequest.post(URL)`向文件服务器发起请求,获得请求体,解析后获得压缩包的url,缓存该url到”业务字段+uuid“。 +2. 前端再根据uuid向服务端查询url地址,后端根据”业务字段+uuid“查询缓存,返回文件url; +3. 前端最后根据url向文件服务器发送下载请求,用户端实现在浏览器中下载文件。 + + + +## 批量导出表格 + +> 前提:准备枚举类`ExportExcelEnum`和常量类`ExportExcelHeaderConstant`,枚举类保存Excel模板类型,常量类保存表格模板的列名 + +使用EasyExcel完成 + +1. 前端发送需要导出的id集合对象和`HttpServletResponse`对象; +2. 后端根据请求对象中的导出类型选择模板、根据请求对象中的id列表获取导出Excel所需的数据并封装在响应对象中,包括文件名、表头列表和数据行列表; +3. 使用EasyExcel写入数据; + + - 调用`EasyExcel.write(httpServletResponse.getOutputStream())`开始写入Excel文件到HTTP响应的输出流中; + - 注册`LongestMatchColumnWidthStyleStrategy`处理器来自适应列宽,确保数据能完整显示; + - 为`EasyExcel`配置不自动关闭输出流(因为在响应结束后,容器会负责关闭); + - 指定Excel的工作表名称、表头和数据行,最终通过`doWrite`方法完成写入。 +4. 设置`HttpServletResponse`对象。 + - 设置响应的`Content-Type`为`Excel`文件类型; + - 使用`URLEncoder.encode`方法对文件名进行编码,防止中文乱码; + + - 设置`Content-Disposition`头以指示浏览器将响应内容作为附件下载,同时指定下载的文件名。 + + + +## 批量导入表格 + +> 前提:准备好表格传输类ExcelImportDTO,里面定义好接收Excel每列数据的字段 + +使用EasyExcel读取表格内容 + +1. 前端上传一个Excel文件 +2. 后端使用`@RequestPart("file") MultipartFile file`接收文件 +3. 使用`EasyExcel.read(file.getInputStream())`读取文件 diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Juint5\346\226\255\350\250\200\347\232\204\344\273\243\347\240\201\344\275\277\347\224\250.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Juint5\346\226\255\350\250\200\347\232\204\344\273\243\347\240\201\344\275\277\347\224\250.md" new file mode 100644 index 0000000..3e725df --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Juint5\346\226\255\350\250\200\347\232\204\344\273\243\347\240\201\344\275\277\347\224\250.md" @@ -0,0 +1,186 @@ +--- +title: Juint5断言的代码使用 +date: 2024-07-02 11:08:00 +updated: 2024-08-10 18:48:00 +categories: +- 学习 +tags: +- Juint +- 断言 +keywords: +- Juint +- 断言 +description: Juint5断言的代码使用 +cover: https://media.licdn.com/dms/image/D4D12AQETC9Kq3s452A/article-cover_image-shrink_720_1280/0/1675287063027?e=2147483647&v=beta&t=iHwyGvQNKHlxJhLcooHzt6Ofgep20A6xJ94LoMLxNpY +top_img: https://miro.medium.com/v2/resize:fit:982/0*2E4rp0xfGhVJx94Q.png +--- + +## JUnit5断言 + +> 断言,简单理解就是用来判断的语句。判断待测试的代码的结果和我们期望的结果是否一致。如果不一致,则说明这个UT失败了。JUnit5的断言非常丰富,下面举例几个工作中常用的断言,还有第三方库断言也会介绍下。 + +直接看代码,不多废话 + +```java +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class AssertionTests { + + @Test + void testEquality() { + int actual = 5; + int expected = 10; + assertEquals(expected, actual, "两端的值应该相等"); // 验证两个值是否相等 + } + + @Test + void testInequality() { + int value1 = 5; + int value2 = 5; + assertNotEquals(value1, value2, "两端的值不应该相等"); // 验证两个值是否不相等 + } + + + Object object1 = new Object(); + Object object2 = object1; + Object object3 = new Object(); + + @Test + void testSameReference() { + assertSame(object1, object3, "引用了不同的对象"); // 验证是否引用同一个对象 + } + + @Test + void testDifferentReferences() { + assertNotSame(object1, object2, "引用了相同的对象"); // 验证不是引用同一个对象 + } + + + Object nullableObject = null; + Object notNullableObject = new Object(); + + @Test + void testIsNull() { + assertNull(notNullableObject, "对象应该为空"); // 验证对象是否为null + } + + @Test + void testIsNotNull() { + assertNotNull(nullableObject, "对象不能为空"); // 验证对象不为null + } + + + @Test + void testTrueCondition() { + boolean condition = false; + assertTrue(condition, "判断不是True"); // 验证条件为真 + } + + @Test + void testFalseCondition() { + boolean condition = true; + assertFalse(condition, "判断不是False"); // 验证条件为假 + } + + + @Test + void testExceptionThrown() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> { +// throw new IllegalArgumentException("预期异常"); + }, "应该抛出异常的代码"); // 验证是否抛出指定异常 + } + + + @Test + void testNoExceptionThrown() { + assertDoesNotThrow(() -> { + int i = 1 / 0; + // 这里执行不应该抛出异常的代码 + }, "不应该抛出异常的代码"); // 验证没有异常被抛出 + } + + + @Test + void testMultipleAssertions() { + + Person person = new Person(); + person.setName("John1"); + person.setAge(29); + person.setEmployed(false); + + assertAll("Person properties", + () -> assertEquals("John", person.getName(), "name 不匹配"), + () -> assertEquals(30, person.getAge(), "age 不匹配"), + () -> assertTrue(person.isEmployed(), "employed 不匹配") + ); // 执行多个断言,任何一个失败则整体测试失败 + } + + // 假设有一个Person类 + static class Person { + String name; + int age; + boolean employed; + + // 省略构造函数和getter + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public boolean isEmployed() { + return employed; + } + + public void setEmployed(boolean employed) { + this.employed = employed; + } + } + + + @Test + void testAssertThat() { + assertThat(testAdd(1, 2)).isEqualTo(3); + assertThat(testAdd(1, 2)).isNotEqualTo(4); + assertThat(testAdd(0, 0)).isZero(); + assertThat(testAdd(1, 2)).isNotZero(); + assertThat(returnNull()).isNull(); + assertThat(testAdd(1, 2)).isNotNull(); + assertThat(returnTrue()).isTrue(); + assertThat(returnFalse()).isFalse(); + assertThat(new ArrayList<>().isEmpty()); + assertThat(getStringList().contains("A")); + assertThat(Optional.of("A")).hasValue("A"); + assertThat("I am good").containsPattern("I am"); + } + public Object returnNull() {return null;} + public int testAdd(int a, int b) {return a + b;} + public boolean returnTrue() {return true;} + public boolean returnFalse() {return false;} + public List getStringList() {return Arrays.asList(new String[]{"A", "B", null});} + + +} + +``` + diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Kafka\345\216\237\347\220\206.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Kafka\345\216\237\347\220\206.md" new file mode 100644 index 0000000..4f3007d --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Kafka\345\216\237\347\220\206.md" @@ -0,0 +1,178 @@ +--- +title: Kafka原理 +date: 2024-08-15 10:28:00 +updated: 2024-08-15 10:28:00 +categories: +- 学习 +tags: +- Kafka +keywords: +- Kafka +description: Kafka原理 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212144558.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212145761.png +--- +# 1.什么是kafka + +kafka是用于构建实时数据管道和数据流的应用程序,是一个高性能分布式消息系统。具有实时横向扩展、高吞吐量、支持大量堆积、具有容错性和速度快等特点。 + +# 2.kafka的应用 + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150857130.png) + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150857325.png) + + + +# 3.kafka中的术语 + + broker:kafka服务器,用于存储消息,一般是由多个broker组成kafka集群。 + topic:kafka给消息提供的分类方式。broker用来存储不同topic的消息数据。 + producer:往broker中某个topic里面生产数据。 + consumer:从broker中某个topic获取数据。 + +# 4.kafka中各部分的工作原理 + +## 1.Broker + +Kafka 服务器,用于储存消息,一般是由多个broker组成kafka集群。 + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150857165.png) + +## 2.topic与消息 + +kafka将所有消息组织成多个topic的形式存储,而每个topic又可以拆分成多个partition,每个partition又由一个一个消息组成。每个消息都被标识了一个递增序列号代表其进来的先后顺序,并按顺序存储在partition中。这样,消息就以一个个id的方式,组织起来。 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150959434.png) +producer选择一个topic,生产消息,消息会通过分配策略append到某个partition末尾。 +consumer选择一个topic,通过id指定从哪个位置开始消费消息。消费完成之后保留id,下次可以从这个位置开始继续消费,也可以从其他任意位置开始消费。 + +上面的id在kafka中称为offset(偏移量),这种组织和处理策略提供了如下好处: +1.消费者可以根据需求,灵活指定offset消费。 +2.保证了消息不变性,为并发消费提供了线程安全的保证。每个consumer都保留自己的offset,互相之间不干扰,不存在线程安全问题。 + 3.消息访问的并行高效性。每个topic中的消息被组织成多个partition,partition均匀分配到集群server中。生产、消费消息的时候,会被路由到指定partition,减少竞争,增加了程序的并行能力。 + 4.增加消息系统的可伸缩性。每个topic中保留的消息可能非常庞大,通过partition将消息切分成多个子消息,并通过负责均衡策略将partition分配到不同server。这样当机器负载满的时候,通过扩容可以将消息重新均匀分配。 + 5.保证消息可靠性。消息消费完成之后不会删除,可以通过重置offset重新消费,保证了消息不会丢失。 + 6.灵活的持久化策略。可以通过指定时间段(如最近一天)来保存消息,节省broker存储空间。 + 7.备份高可用性。消息以partition为单位分配到多个server,并以partition为单位进行备份。备份策略为:1个leader和N个followers,leader接受读写请求,followers被动复制leader。leader和followers会在集群中打散,保证partition高可用。 + +## 3.partitions + +每个Topics划分为一个或者多个Partition,并且Partition中的每条消息都被标记了一个sequential id ,也就是offset,并且存储的数据是可配置存储时间的 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150857528.png) + +## 4.Producer + +消息生产者,生产消息需要如下参数: + 1.topic:往哪个topic生产消息。 + 2.partition:往哪个partition生产消息。 + 3.key:根据该key将消息分区到不同partition。 + 4.message:消息。 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150959792.png) + +## 5.Comsumer + +传统消息系统有两种模式:1.队列 2.发布订阅 +kafka通过consumer group将两种模式统一处理:每个consumer将自己标记consumer group名称,之后系统会将consumer group按名称分组,将消息复制并分发给所有分组,每个分组只有一个consumer能消费这条消息。 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150854330.png) +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150857699.png) +于是推理出两个极端情况: +当所有consumer的consumer group相同时,系统变成队列模式 +当每个consumer的consumer group都不相同时,系统变成发布订阅 + +### 注意点 + +1、Consumer Groups 提供了topics和partitions的隔离。如上图Consumer Group A中的consumer-C2挂掉,consumer-C1会接收P1,P2,即一个consumer Group中有其他consumer挂掉后能够重新平衡 +2、多consumer并发消费消息时,容易导致消息乱序,通过限制消费者为同步,可以保证消息有序,但是这大大降低了程序的并发性。 + kafka通过partition的概念,保证了partition内消息有序性,缓解了上面的问题。partition内消息会复制分发给所有分组,每个分组只有一个consumer能消费这条消息。这个语义保证了某个分组消费某个分区的消息,是同步而非并发的。如果一个topic只有一个partition,那么这个topic并发消费有序,否则只是单个partition有序。 + +### consumer存在两种消费模型 + +push:优势在于消息实时性高。劣势在于没有考虑consumer消费能力和饱和情况,容易导致producer压垮consumer。 + pull:优势在可以控制消费速度和消费数量,保证consumer不会出现饱和。劣势在于当没有数据,会出现空轮询,消耗cpu。 + +kafka采用pull,并采用可配置化参数保证当存在数据并且数据量达到一定量的时候,consumer端才进行pull操作,否则一直处于block状态。kakfa采用整数值consumer position来记录单个分区的消费状态,并且单个分区单个消息只能被consumer group内的一个consumer消费,维护简单开销小。消费完成,broker收到确认,position指向下次消费的offset。由于消息不会删除,在完成消费,position更新之后,consumer依然可以重置offset重新消费历史消息。 + +# 5.可用性 + +在kafka中,正常情况下所有node处于同步中状态,当某个node处于非同步中状态,也就意味着整个系统出问题,需要做容错处理。 + +## 1.同步 + +同步中的状态: +该node与zookeeper能连通。 +该node如果是follower,那么consumer position与leader不能差距太大(差额可配置)。 + +ISR: 某个分区内同步中的node组成一个集合,即该分区的ISR (即分区集群)。 + +## 2.容错机制 + +kafka通过两个手段容错: +1.数据备份:以partition为单位备份,副本数可设置。当副本数为N时,代表1个leader,N-1个followers,followers可以视为leader的consumer,拉取leader的消息,append到自己的系统中。 +2.failover: +当leader处于非同步中时,系统从followers中选举新leader。 + 当某个follower状态变为非同步中时,leader会将此follower剔除ISR,当此follower恢复并完成数据同步之后再次进入 ISR。 + +另外 kafka有个保障:当producer生产消息时,只有当消息被所有ISR确认时,才表示该消息提交成功。只有提交成功的消息,才能被consumer消费。 +因此,当有N个副本时,N个副本都在ISR中,N-1个副本都出现异常时,系统依然能提供服务。 +假设N副本全挂了,node恢复后会面临同步数据的过程,这期间ISR中没有node,会导致该分区服务不可用。kafka采用一种降级措施来处理:选举第一个恢复的node作为leader提供服务,以它的数据为基准,这个措施被称为脏leader选举. + +# 6.一致性 + +有时高可用是体现在对一致性的牺牲上。如果希望达到强一致性,可以采取如下措施: +1.禁用脏leader选举,ISR没有node时,宁可不提供服务也不要未完全同步的node。 +2.设置最小ISR数量min_isr,保证消息至少要被min_isr个node确认才能提交。 + +# 7.持久化 + +## 7.1概述 + +Kafka很大程度上依赖文件系统来存储和缓存消息。有一普遍的认识:磁盘很慢。这让人们怀疑使用磁盘作为持久化的性能。实际上,磁盘是快还是慢完全取决于我们是如何使用它。 + 就目前来说,一个 six 7200rpm SATA RAID-5磁盘线性(顺序)写入的性能能达到600MB/sec,而任意位置写(寻址再写)的性能只有100k/sec。并且现在的操作系统提供了预读取和后写入的技术。实际上,顺序的磁盘读写比任意的内存读写更快。 + +### 基于jvm内存有以下缺点: + +1.对象的内存开销非常高,通常会让存储数据的大小加倍(或更多) +2.随着堆内数据的增加,GC的速度越来越慢,而且可能导致错误 + +### 基于操作系统的文件系统来设计有以下好处: + +1.可以通过os的pagecache来有效利用主内存空间,由于数据紧凑,可以cache大量数据,并且没有gc的压力 +2.即使服务重启,缓存中的数据也是热的(不需要预热)。而基于进程的缓存,需要程序进行预热,而且会消耗很长的时间。(10G大概需要10分钟) +3.大大简化了代码。因为在缓存和文件系统之间保持一致性的所有逻辑都在OS中。以上建议和设计使得代码实现起来十分简单,不需要尽力想办法去维护内存中的数据,数据会立即写入磁盘。 + +## 7.2 kafka数据持久化 + +1.线性的访问磁盘(即:按顺序的访问磁盘),很多时候比随机的内存访问快得多,而且有利于持久化; +2.传统使用的内存做为磁盘的缓存 +3.Kafka直接将数据写入到日志文件中,以追加的形式写入 + +## 7.3日志数据持久化 + +写操作:通过将数据追加到文件中实现 +读操作:读的时候从文件中读就好了 + +## 7.4 持久化的优势 + +读操作不会阻塞写操作和其他操作(因为读和写都是追加的形式,都是顺序的,不会乱,所以不会发生阻塞),数据大小不对性能产生影响; +没有容量限制(相对于内存来说)的硬盘空间建立消息系统; +线性访问磁盘,速度快,可以保存任意一段时间! + +## 7.5持久化的具体实现 + +1.一个topic可以认为是一类消息,每个topic将被分成多个partition,每个partition在存储层面是append log文件。任何发布到此partition的消息都会被追加到log文件的尾部,每条消息在文件中的位置成为offset(偏移量),partition是以文件的形式存储到文件体统中的。 +2.Logs文件根据broker中的配置要求,保留一定时间后删除来释放磁盘空间(默认7天)。 + +## 7.6 kafka的索引 + +稀疏存储,每隔一定字节的数据建立一条索引(这样的目的是为了减少索引文件的大小)。 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150959871.png) +1.现在对6.和8建立了索引,如果要查找7,则会先查找到8然后,再找到8后的一个索引6,然后两个索引之间做二分法,找到7的位置 +2.每一个log文件中又分为多个segment + +# 8.kafka分布式实现 + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408150959325.png) +1.当生产者将消息发送到Kafka后,就会去立刻通知ZooKeeper,zookeeper中会watch到相关的动作,当watch到相关的数据变化后,会通知消费者去消费消息。 +2.消费者是主动去Pull(拉)kafka中的消息,这样可以降低Broker的压力,因为Broker中的消息是无状态的,Broker也不知道哪个消息是可以消费的 +3.当消费者消费了一条消息后,也必须要去通知ZooKeeper。zookeeper会记录下消费的数据,这样当系统出现问题后就可以还原,可以知道哪些消息已经被消费了 +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151000790.png) \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MongoDB\345\222\214MySQL\347\232\204\345\270\270\347\224\250\350\257\255\346\263\225\345\257\271\346\257\224.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MongoDB\345\222\214MySQL\347\232\204\345\270\270\347\224\250\350\257\255\346\263\225\345\257\271\346\257\224.md" new file mode 100644 index 0000000..2795c07 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MongoDB\345\222\214MySQL\347\232\204\345\270\270\347\224\250\350\257\255\346\263\225\345\257\271\346\257\224.md" @@ -0,0 +1,59 @@ +--- +title: MongoDB和MySQL的常用语法对比 +date: 2024-07-10 12:47:00 +updated: 2024-08-10 18:52:00 +categories: +- 学习 +tags: +- MongoDB +- MySQL +keywords: +- MongoDB +- MySQL +description: MongoDB和MySQL的常用语法对比 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212156404.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212156404.png +--- +| 方法 | 说明 | 语法 | +| ---- | ------- | ------------------------------------------------------------ | +| 新增 | MongoDB | db.getCollection('user').insert({"userId" : "014","uclass" : "B","name" : "Back","age" : 11,"email" : "b14@sina.com","birthday" : ISODate("2018-07-31T03:46:13.885Z"),"dataStatus" : 1}); | +| | MySQL | INSERT INTO `sz-temp`.`user` (`userId`, `uclass`, `name`, `age`, `email`, `birthday`, `dataStatus`) VALUES ('014', 'B', 'Back13', '20', 'b14@sina.com', '2013-07-31 11:46:13', '0'); | + +| 方法 | 说明 | 语法 | +| ---- | ------- | -------------------------------------------------- | +| 删除 | MongoDB | db.getCollection('user').remove({"userId":"014"}); | +| | MySQL | delete from user where userId = '014'; | + +| 方法 | 说明 | 语法 | +| ---- | ------- | ------------------------------------------------------------ | +| 修改 | MongoDB | db.getCollection('user').update({"userId":"013"}, {$set:{"email":"b13@sina.com", "age":20}}); | +| | MySQL | update user set email = 'b13@sina.com', age = 20 where userId = '013'; | + +| 方法 | 说明 | 语法 | +| ------------------ | ------- | ------------------------------------------------------------ | +| 查询所有 | MongoDB | db.getCollection('user').find({}); | +| | MySQL | select * from user; | +| 查询条件:= | MongoDB | db.getCollection('user').find({"age":16});等效于db.getCollection('user').find({"age":{$eq:16}}); | +| | MySQL | select * from user where age = 16; | +| 查询条件:like | MongoDB | db.getCollection('user').find({"name":/Ba/}); | +| | MySQL | select * from user where name like '%Ba%'; | +| 查询条件:distinct | MongoDB | db.getCollection('user').distinct("name"); | +| | MySQL | select distinct uclass from user u; | +| 查询条件:> | MongoDB | db.getCollection('user').find({"age":{$gt:16}}); | +| | MySQL | select * from user where age >16; | +| 查询条件:>= | MongoDB | db.getCollection('user').find({"age":{$gte:16}}); | +| | MySQL | select * from user where age >= 16; | +| 查询条件:< | MongoDB | db.getCollection('user').find({"age":{$lt:16}}); | +| | MySQL | select * from user where age < 16; | +| 查询条件:<= | MongoDB | db.getCollection('user').find({"age":{$lte:16}}); | +| | MySQL | select * from user where age 16; | +| 查询条件:or | MongoDB | db.getCollection('user').find({$or:[{"uclass":"A"},{"class":"B"}]}); | +| | MySQL | select * from user where uclass = 'A' or uclass = 'B'; | +| 查询条件:时间 | MongoDB | db.getCollection('user').find({"birthday":{$gt: new Date("2008-08-14T06:24:40.110Z"), $lt: new Date("2015-08-14T06:14:40.089Z")}}); | +| | MySQL | select * from user where birthday > '2008-08-14 06:24:40' and birthday < '2015-08-14 06:14:40'; | +| 查询条件:count | MongoDB | db.getCollection('user').find({"uclass":"A"}).count(); | +| | MySQL | select count(1) from user where uclass = 'A'; | +| 查询条件:sort升序 | MongoDB | db.getCollection('user').find({}).sort({"age":1}); | +| | MySQL | select * from user order by age asc; | +| 查询条件:sort降序 | MongoDB | db.getCollection('user').find({}).sort({"age":-1}); | +| | MySQL | select * from user order by age desc; | \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MySql\346\225\260\346\215\256\345\272\223\345\221\275\344\273\244.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MySql\346\225\260\346\215\256\345\272\223\345\221\275\344\273\244.md" new file mode 100644 index 0000000..8685219 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MySql\346\225\260\346\215\256\345\272\223\345\221\275\344\273\244.md" @@ -0,0 +1,191 @@ +--- +title: MySql数据库命令 +date: 2022-01-26 16:13:15 +updated: +categories: +- 学习 +tags: +- Mysql +keywords: +- Mysql +description: 涵盖了能用得到Mysql命令 +cover: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSd40RJxu6f27D-WN-Y2l5khctyeGywaWZWB0Ma6vP9pSaaYMKFLgT_efTeLQUQsjS4x9I&usqp=CAU +top_img: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSrBtVoNNXsOC0nXSRP3HGLVgFaB0zBI0nOsPck1D1KfopBKLGz-vx2MCVfO4x2FLXe2g&usqp=CAU + +--- + +开启数据库服务 + +```shell +# 先将路径放进环境变量中 +export PATH=/usr/local/mysql/support-files:$PATH +# 完成以上操作后就可以直接用命令了⬇️⬇️ +sudo mysql.server start +``` + +关闭数据库服务 + +```shell +sudo mysql.server stop +``` + +登陆数据库 + +```shell +cd /usr/local/MySQL/bin +mysql -u root -p12345678 +``` + +显示数据库 + +```sql +show databases; +``` + +创建数据库 + +```sql +create databases 数据库名; +``` + +删除数据库 + +```sql +drop database 表名; +``` + +打开数据库 + +```sql +use 数据库名; +``` + +显示当前数据库内的表 + +```sql +show tables; +``` + +查看表结构 + +```sql +desc 表名; +``` + +查询表的索引 + +```sql +show index form 表名; +``` + +![image-20220127160432110](https://tva1.sinaimg.cn/large/e6c9d24egy1gznt0gfadxj21xe06sabx.jpg) + +![img](https://img2020.cnblogs.com/blog/1436863/202005/1436863-20200507100522709-1803986961.png) + +新建(唯一)索引 + +```sql +create (unique) index 索引名 on 表名(列名); +``` + +删除索引 + +```sql +--当索引被引用时不能删除,必须先删除所有引用了索引的约束-- +alter table 表名 drop index 索引名 (on 表名); +``` + +创建表 + +```sql +--可加可不加-- +drop table 表名 if exist; +create table 表名( + integer(整型) not null primary key auto_increment, + varchar(字符串类型,必须要跟最大字符串), + text(大文本), + float(单精度,即7-8位有效数字), + double(双精度,即15-16位有效数字), + date(只有年月日), + time(只有时分秒), + datetime(既有年月日,又有时分秒), +); +eg1.主键+外键 +CREATE table course( + cno char(7) not null PRIMARY KEY, + cname VARCHAR(7) not null, + ccredit int(2) not null, + cpno char(7) REFERENCES course(con) +); +eg2.复合主键+复合外键(多对多情况) +CREATE table sc( + sno char(7), + cno char(7), + score DECIMAL(4,1), + point DECIMAL(2,1) + PRIMARY key(sno,cno), + FOREIGN key sno REFERENCES students(sno), + FOREIGN key cno REFERENCES course(cno) +); +``` + +查看新建表的命令/查看表约束和索引 + +```sql + show create table 表名; +``` + +查询表 + +```sql +select 列名 form 表名 (join 从表 on 条件) where 条件 having 条件 group by 列名 order by 列名 (asc) limit 数量; +``` + +插入表 + +```sql +insert into 表名(列名1,列名2,...) values(value1,value2,...); +``` + +修改表 + +```sql +1、添加列 +alter table 表名 add 列名 类型; +2、修改列 +alter table 表名 change 列名 (新列名) 类型; +3、删除列 +alter table 表名 drop 列名; +4、添加主键约束 +(4.1)、单主键 +alter table 表名 add constraint primary key(列名); +(4.2)、复合主键(注意顺序) +alter table 表名 add constraint primary key(列名1,列名2,...); +5、添加外键约束 +(5.1)、单外键(单外键可以和复合主键中的单键相连,但是这样会不稳定) +alter table 表名 add foreign key(列名) references 外表(主键); +(5.2)、复合外键(注意顺序) +alter table 表名 add foreign key(列名1,列名2,...) references 外表(主键1,主键2,...); +6、删除主键约束(主键在链接了外键的情况下不能删除) +alter table 表名 drop primary key; +7、删除外键约束 +alter table 表名 drop constraint 约束名 (on 表名); +``` + +复合主/外键内部是有顺序的,请注意!顺序由创建时决定![image-20220127172122931](https://tva1.sinaimg.cn/large/e6c9d24egy1gznt0ihzehj2142070dgb.jpg) + +![image-20220127172640923](https://tva1.sinaimg.cn/large/e6c9d24egy1gznt0f7tr3j212g05ujs8.jpg) + +单键可以和复合主键的单键相连,但是不建议这么做![image-20220127171218341](https://tva1.sinaimg.cn/large/e6c9d24egy1gznt15c5g2j213i05udgn.jpg) + +删除表 + +```sql +drop table 表名; +``` + +清空表 + +```sql +delete from 表名; +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MybatisPlus\344\276\235\350\265\226\345\222\214\351\205\215\347\275\256\346\226\207\344\273\266.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MybatisPlus\344\276\235\350\265\226\345\222\214\351\205\215\347\275\256\346\226\207\344\273\266.md" new file mode 100644 index 0000000..854c1ed --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/MybatisPlus\344\276\235\350\265\226\345\222\214\351\205\215\347\275\256\346\226\207\344\273\266.md" @@ -0,0 +1,136 @@ +--- +title: MybatisPlus依赖和配置文件 +date: 2022-03-07 22:01:15 +updated: +categories: +- 学习 +tags: +- MybatisPlus +- 依赖 +- 配置文件 +keywords: +- MybatisPlus +- 依赖 +- 配置文件 +description: MybatisPlus的依赖和配置文件 +cover: https://img-blog.csdnimg.cn/img_convert/dcaab75e2a3a75cd7b336667739e4a86.png +top_img: https://www.chendan116.com/upload/2021/02/relationship-with-mybatis-d54d359809b54f1886d97258ebf0b4c8.png + +--- + +### 依赖 + +``` + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + mysql + mysql-connector-java + runtime + + + + com.alibaba + fastjson + 2.0.7 + + + + org.projectlombok + lombok + provided + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.2 + + + + org.apache.velocity + velocity-engine-core + 2.3 + + + + com.alibaba + druid + 1.2.11 + + + + log4j + log4j + 1.2.17 + + + +``` + +### 配置文件 + +```yml +server: + port: 9000 + address: 0.0.0.0 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/easyproject?useSSL=false&characterEncoding=utf-8&useUnicode=true&serverTimezone=Asia/Shanghai + username: root + password: 12345678 + type: com.alibaba.druid.pool.DruidDataSource + dbcp2: + initial-size: 5 + min-idle: 10 + max-conn-lifetime-millis: 20 + max-total: 50 + max-wait-millis: 60000 + timeBetweenEvictionRunsMillis: 60000 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + poolPreparedStatements: true + max-open-prepared-statements: 20 + +mybatis-plus: + type-aliases-package: com.hzx.easysport.bean + mapper-locations: classpath:mapper/*.xml + global-config: + db-config: + # 配置逻辑删除 + logic-not-delete-value: 0 + logic-delete-value: 1 + configuration: + # 配置日志 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + #查询时为null字段不加入,比如QueryWrapper中的应用 + call-setters-on-nulls: true + lazyLoadingEnabled: true + aggressiveLazyLoading: false +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Mybatis\346\263\250\350\247\243\345\274\200\345\217\221\344\275\277\347\224\250\344\270\276\344\276\213.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Mybatis\346\263\250\350\247\243\345\274\200\345\217\221\344\275\277\347\224\250\344\270\276\344\276\213.md" new file mode 100644 index 0000000..d3b511c --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Mybatis\346\263\250\350\247\243\345\274\200\345\217\221\344\275\277\347\224\250\344\270\276\344\276\213.md" @@ -0,0 +1,147 @@ +--- +title: Mybatis注解开发使用举例 +date: 2022-02-06 16:12:15 +updated: +categories: +- 学习 +tags: +- Mybatis +- 注解 +keywords: +- Mybatis +- 注解 +description: 有关Mybatis单表操作、多表操作,立即加载、延迟加载的操作 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/1620.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/1620.jpg + +--- + +单表操作 + +```java +public interface IUserDao { + + /** + * 查询所有用户 + * @return + */ + @Select(value = "select * from user") + List findAll(); + + /** + * 保存用户 + */ + @Insert(value = "insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})") + void saverUser(User user); + + /** + * 更新用户 + */ + @Update("update user set username = #{username},birthday = #{birthday},sex = #{sex},address = #{address} where uid = #{uid}") + void updateUser(User user); + + + /** + * 删除用户 + */ + @Delete("delete from user where uid = #{uid}") + void deleteUser(Integer id); + + + /** + * 根据id查询用户 + */ + @Select("select * from user where uid = #{uid}") + User findById(Integer id); + + + /** + * 根据用户名称模糊查询 + */ +// @Select("select * from user where username like #{username}")//需要传百分号 + @Select("select * from user where username like '%${value}%'")//不需要传百分号 + List findUserByName(String name); + + /** + * 查询用户总数量 + */ + @Select("select count(*) from user") + int findTotalUser(); + +} +``` + +多表操作(一对一,立即加载) + +```java +public interface IAccountDao { + + /** + * 查询所有账户,并且获取每个账户所属的用户信息 + * @return + */ + @Select("select * from account") + @Results(id = "accountMap",value = { + @Result(id = true,property = "id",column = "id"), + @Result(property = "uid",column = "uid"), + @Result(property = "money",column = "money"), + @Result(property = "user",column = "uid", + one = @One(select="com.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER)) + }) + List findAll(); + + /** + * 根据用户id查询账户信息 + * @param userId + * @return + */ + @Select("select * from account where uid = #{userId}") + List findAccountByUid(Integer userId); + + +} +``` + +多表操作(一对多,延迟加载) + +```java +//开启二级缓存 +@CacheNamespace(blocking = true) + +public interface IUserDao { + /** + * 查询所有用户 + * + * @return + */ + @Select(value = "select * from user") + @Results(id = "userMap", value = { + @Result(id = true, property = "userId", column = "uid"), + @Result(property = "userName", column = "username"), + @Result(property = "userSex", column = "sex"), + @Result(property = "userAddress", column = "address"), + @Result(property = "userBirthday", column = "birthday"), + @Result(property = "accounts", column = "uid", + many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid", fetchType = FetchType.LAZY)) + }) + List findAll(); + + /** + * 根据uid查询用户 + */ + @Select("select * from user where uid = #{uid}") + @ResultMap(value = {"userMap"}) + User findById(Integer uid); + + + /** + * 根据用户名称模糊查询 + */ + @Select("select * from user where username like #{username}")//需要传百分号 +// @Select("select * from user where username like '%${value}%'")//不需要传百分号 + @ResultMap(value = {"userMap"}) + List findUserByName(String name); + + +} +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Netty\344\270\216NIO\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Netty\344\270\216NIO\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" new file mode 100644 index 0000000..ebe1d86 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Netty\344\270\216NIO\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" @@ -0,0 +1,345 @@ +--- +title: Netty与NIO的前世今生 +date: 2024-08-15 10:27:00 +updated: 2024-08-15 10:27:00 +categories: +- 学习 +tags: +- Netty +keywords: +- Netty +description: Netty与NIO的前世今生 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212150339.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212151754.png +--- +# 1.JavaNIO的三件套 + +在NIO有几个核心对象需要掌握: + +- 缓冲区(Buffer) +- 选择器(selector) +- 通道(channel) + +# 1.1 缓冲区Buffer + +### 1. Buffer操作基本API + +缓冲区实际是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是都是用缓存区处理的。读取数据时,它是直接读取到缓冲区中;在写入数据时,它也是直接写到缓冲区中;任何是访问NIO中的数据,都是将它放到缓冲区中。在面向流I/O系统中,所有数据都是直接写入或读取到Stream对象中。 +在NIO中,所有缓冲区对象都是继承于抽象类Buffer,最常用的就是ByteBuffer,对于Java的基本类型,基本上都有一个具体Buffer类型与之对应,它们之间的继承关系如下图: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151001591.png) + +下面是一个简单使用InBuffer的案例 + +```java +public class IntBufferDemo { + public static void main(String[] args) { + //分配新的int缓冲区,参数为缓冲区容量 + //新缓冲区的当前位置为零,其界限(限制位置)将为其容量。它将具有一个底层实现数组,其数组偏移量将为零 + IntBuffer buffer = IntBuffer.allocate(8); + + for (int i=0; i < buffer.capacity(); i++) { + int j = 2 * (i+1); + //将给定整数写入此缓冲区的当前位置,当前位置递增 + buffer.put(j); + } + //重设此缓冲区,将限制位置为当前位置,然后将当前位置设置为0 + buffer.flip(); + //查看在当前位置和限制位置之间是否有元素 + while (buffer.hasRemaining()) { + //读取此缓冲区当前位置的整数,然后将当前位置递增 + int j = buffer.get(); + System.out.print(j + " "); + } + + } + +}COPY +``` + +运行后可以看到 + +file + +### 2.Buffer的基本原理 + +在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化,如果我们使用get()方法从缓冲区获取数据或者使用put()方法把数据写入缓冲区,都会引起缓冲区状态的变化 +在缓冲区中,最重要的属性有下面三个,它们一起合作完成对缓冲区内部装填的变化跟踪: + +position: 指定下一个将要被写入或者读取的元素索引,它的值由get()/put()方法自动更新,在新创建一个Buffer对象时,position被初始化为0。 + +limit: 指定还要多少数据需要取出(从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。 + +capacity: 指定了可以存储在缓冲区中的最大数据容量,实际上,它指定了底层数组的大小,或者至少是指定了准许我们使用的底层数组的容量。 + +以上三个属性之间有一些相对大小的关系:0 <= position <= limit <= capacity。如果我们创建一个新的容量大小为10的ByteBuffer对象,在初始化的时候,position设置为0,limit和capacity被设置为10,在以后使用ByteBuffer对象过程中,capacity的值不会再发生变化,而其它两个将会随着使用而变化。 + +下面我们用代码来演示一遍,准备一个txt文档,存放的E盘,输入以下内容: +test +下面用一段代码来验证position,limit和capactiy这几个值的变化过程,代码如下: + +```java +public class BufferDemo { + public static void main(String[] args) throws Exception { + //这里使用的是文件id处理 + FileInputStream fin = new FileInputStream("E://test.txt"); + //创建文件的操作管道 + FileChannel fc = fin.getChannel(); + //分配一个10个大小缓冲区,就是分配一个10个大小的byte数组 + ByteBuffer buffer = ByteBuffer.allocate(10); + output("初始化", buffer); + //先读取一下 + fc.read(buffer); + output("调用read()", buffer); + //准备操作之前,先锁定操作范围 + buffer.flip(); + output("调用flip()", buffer); + //判断有没有可读数据 + while (buffer.remaining() > 0){ + byte b = buffer.get(); + } + output("调用 get()", buffer); + //可以理解为解锁 + buffer.clear(); + output("调用clear()", buffer); + //最后把管道关闭 + fin.close(); + + } + + private static void output(String step, ByteBuffer buffer) { + System.out.println(step + ":"); + //容量,数组大小 + System.out.print("capacity: " + buffer.capacity() + ", " ); + //当前操作数据所在的位置,也可以叫游标 + System.out.print("position: " + buffer.position() + ", "); + //锁定值, flip, 数据操作范围索引只能在position - limit之间 + System.out.println("limit: " + buffer.limit()); + System.out.println(); + } + +}COPY +``` + +完成的输出结果为: +file + +运行的结果我们可以看到,下面对以上结果进行图解,四个属性分别如图所示 + +file + +我们可以从通道中读取一些数据到缓冲区中,注意从通道读取数据,相当于往缓冲区中写入数据。如果读取4个自己的数据,则此时position的值为4,即下一个将要被写入的字节索引为4,而limit仍然是10,如下图所示: + +file + +下一步把读取的数据写入到输出通道中,相当于从缓冲区中读取数据,在此之前,必去调用flip()方法,该方法将会完成两件事情: +1.将limit设置为当前的position值 +2.把position设置为0 +由于position被设置为0,所以可以保证在下一步输出是读取到的是缓冲区中的第一个字节,而limit被设置为当前的position,可以保证读取的数据正好是之前写入到缓冲区中的数据, 如下图所示: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151002870.png) +现在调用get()方法从缓冲区中读取数据写入到输出通道,这会导致position的增加而limit保持不变,但position不会超过limit的值,所以在读取我们之前写入到缓冲区中的4个自己之后,position和limit的值都为4,如下图所示: +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151002577.png) + +在从缓冲区读取数据完毕后,limit的值仍然保持在我们调用flip()方法的值,调用clear()方法能够把所有的状态变化为初始化的值,如下图所示: +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151002598.png) + +### 3.缓冲区的分配 + +在前面的几个例子中,我们已经看过了,在创建一个缓冲区对象时,会调用静态方法allocate()来指定缓冲区的容量,其实调用allocate()相当于创建一个指定大小的数组,并把它包装为缓冲区对象。或者我们也可以直接将一个现有的的数组,包装为缓冲区对象,如下实例所示: + +```java +/** + * 手动分配缓冲区 + */ +public class BufferWrap { + + public void myMethod(){ + //分配指定大小的缓冲区 + ByteBuffer buffer = ByteBuffer.allocate(10); + //包装一个现有的数组 + byte array[] = new byte[10]; + ByteBuffer buffer1 = ByteBuffer.wrap(array); + } +}COPY +``` + +### 4.缓冲区分片 + +在NIO中,除了可以分配或者包装一个缓冲区对象外,还可以根据现有的缓冲区对象创建一个子缓冲区,即在现有缓冲区上切出一片作为一个新的缓冲区,但现有的缓冲区与创建的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区相当于是现有缓冲区的一个视图窗口。调用slice()方法可以创建一个子缓冲区,让我们通过例子看一下: + +```java +public class BufferSlice { + + public static void main(String[] args) { + ByteBuffer buffer = ByteBuffer.allocate(10); + //缓冲区的数据 0-9 + for (int i=0; i < buffer.capacity(); i++){ + buffer.put((byte)(i)); + } + + //创建子缓冲区 + buffer.position(3); + buffer.limit(7); + ByteBuffer slice = buffer.slice(); + + //改变子缓冲区的内容 + for (int i=0; i < slice.capacity(); i++){ + byte b = slice.get(i); + b *= 10; + slice.put(i, b); + } + + buffer.position(0); + buffer.limit(buffer.capacity()); + + while (buffer.remaining() > 0){ + System.out.println(buffer.get()); + } + + } +}COPY +``` + +在该示例中,分配了一个容量大小为10的缓冲区,并在其中放入数据0-9,而在该缓冲区基础上又创建一个子缓冲区,并改变子缓冲区的内容,从最后输出的结果来看,只有子缓冲区“可见的”那部分数据发生了变化,并且说明子缓冲区与原缓冲区时数据共享的,输出结果如下所示: +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151002993.png) + +### 5.只读缓冲区 + +只读缓冲区非常简单,可以读取它们,但是不能向它们写入数据,可以通过调用缓冲区的asReadOnlyBuffer()方法,将任何常规缓冲区转换为只读缓冲区,这个方法返回一个与原缓冲区完全相同的缓冲区,并与原缓存取共享数据,只不过它是只读的,如果原缓冲区的内容发生了变化,只读缓冲区的内容也随之变化: + +```java +public class ReadOnlyBuffer { + + public static void main(String[] args) { + ByteBuffer buffer = ByteBuffer.allocate(10); + + //缓冲区的数据 0-9 + for (int i=0; i< buffer.capacity(); i++){ + buffer.put((byte)i); + } + + //创建只读缓冲区 + ByteBuffer readOnly = buffer.asReadOnlyBuffer(); + + //改变原缓冲区的内容 + for (int i=0; i< buffer.capacity(); i++){ + byte b = buffer.get(i); + b *= 10; + buffer.put(i, b); + } + + readOnly.position(0); + readOnly.limit(buffer.capacity()); + //只读缓冲区的内容也随之改变 + while (readOnly.remaining() > 0){ + System.out.println(readOnly.get()); + } + } +} +COPY +``` + +如果尝试修改只读缓冲区的内容,则会报ReadOnlyBufferException异常。只读缓冲区对于保护数据很有用。在将缓冲区传递给某个对象方法时,无法知道这个方法是否会修改缓冲区中数据。创建一个只读的缓冲区可以保证该缓冲区不会被修改。只可以把常规缓冲区转换为只读缓冲区,而不能将只读的缓冲区转换为可写的缓冲区。 + +### 6.直接缓冲区 + +直接缓冲区是为加快I/O速度,使用一种特殊方式为其分配的内存的缓冲区,JDK文档中描述为:给定一个直接字节缓冲区,Java虚拟机将尽最大努力直接对它执行本机I/O操作。也就是说,它会在每一次调用底层操作系统的本机I/O操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区或者从一个中间缓冲区中拷贝内容。要分配直接缓冲区,需要调用allocateDirect()方法,而不是allocate()方法,使用方式与普通缓冲区并无区别,如下面的拷贝文件示例: + +```java +public class DirectBuffer { + public static void main(String[] args) throws Exception { + //从磁盘上读取文件内容、 + String infile = "E://test.txt"; + FileInputStream fin = new FileInputStream(infile); + FileChannel fcin = fin.getChannel(); + + //把刚刚读取的内容写入到新的一个文件中 + String outfile = String.format("E://testcopy.txt"); + FileOutputStream fout = new FileOutputStream(outfile); + FileChannel fcout = fout.getChannel(); + + //使用allocateDirect ,而不是allocate + ByteBuffer buffer = ByteBuffer.allocateDirect(1024); + while (true){ + buffer.clear(); + int r = fcin.read(buffer); + if (r == -1){ + break; + } + buffer.flip(); + fcout.write(buffer); + } + } +} +COPY +``` + +### 7.内存映射 + +内存映射是一种读和写文件数据的方法,它可以比常规的基于流或者基于通道的I/O快的多。内存映射文件I/O是通过使文件中的数据出现为内存数组的内容来完成的,这其初听起来似乎不过就是将整个文件读到内存中,但是事实上并不是这样。一般来说只有文件中实际读取或者写入的部分才会映射到内存中g.如下面的示例代码: + +```java +public class MappedBuffer { + + private static final int start = 0; + + private static final int size = 1024; + + public static void main(String[] args) throws Exception { + RandomAccessFile raf = new RandomAccessFile("E://test.txt", "rw"); + FileChannel fc = raf.getChannel(); + + //把缓冲区跟文件系统进行一个映射关联 + //只要操作缓冲区里面的内容,文件内容也会跟着改变 + MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, start, size); + mbb.put(0, (byte)97); + mbb.put(1023, (byte)122); + raf.close(); + } + +}COPY +``` + +## 1.2选择器 Selector + +传统的Server/Client模式基于TPR(Thread Request),服务器会为每个客户请求建立一个线程,由该线程单独负责处理一个客户请求。这种模式带来的一个问题就是线程数量的剧增,大量的线程会增大服务器的开销。大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大数量,这又带来了新的问题,如果线程池中有200个线程,而有200个用户都在进行大文件下载,会导致第201用户的请求无法及时处理,即便第201个用户想请求一个几kb大小的页面,传统的Server/Client模式如下图所示 + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151003919.png) + +NIO 中非阻塞 I/O 采用了基于 Reactor 模式的工作方式,I/O 调用不会被阻塞,相反是注册感兴趣的特定 I/O 事件,如可读数据到 +达,新的套接字连接等等,在发生特定事件时,系统再通知我们。NIO 中实现非阻塞 I/O 的核心对象就是 Selector,Selector 就是 +注册各种 I/O 事件地方,而且当那些事件发生时,就是这个对象告诉我们所发生的事件,如下图所示: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151003130.png) + +从图中可以看出,当有读或写等任何注册的事件发生时,可以从 Selector 中获得相应的 SelectionKey,同时从 SelectionKey 中可 +以找到发生的事件和该事件所发生的具体的 SelectableChannel,以获得客户端发送过来的数据。 +使用 NIO 中非阻塞 I/O 编写服务器处理程序,大体上可以分为下面三个步骤: + +1. 向 Selector 对象注册感兴趣的事件。 +2. 从 Selector 中获取感兴趣的事件。 +3. 根据不同的事件进行相应的处理。 + 接下来我们用一个简单的示例来说明整个过程。首先是向 Selector 对象注册感兴趣的事件: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151003608.png) + +创建了 ServerSocketChannel 对象,并调用 configureBlocking()方法,配置为非阻塞模式,接下来的三行代码把该通道绑定到指定 +端口,最后向 Selector 中注册事件,此处指定的是参数是 OP_ACCEPT,即指定我们想要监听 accept 事件,也就是新的连接发 生 +时所产生的事件,对于 ServerSocketChannel 通道来说,我们唯一可以指定的参数就是 OP_ACCEPT。 +从 Selector 中获取感兴趣的事件,即开始监听,进入内部循环: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151006724.png) + +在非阻塞 I/O 中,内部循环模式基本都是遵循这种方式。首先调用 select()方法,该方法会阻塞,直到至少有一个事件发生,然后 +再使用 selectedKeys()方法获取发生事件的 SelectionKey,再使用迭代器进行循环。 +最后一步就是根据不同的事件,编写相应的处理代码: + +![file](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151006234.png) + +此处分别判断是接受请求、读数据还是写事件,分别作不同的处理。在 Java1.4 之前的 I/O 系统中,提供的都是面向流的 I/O +系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的 +I/O 速度非常慢,而在 Java 1.4 中推出了 NIO,这是一个面向块的 I/O 系统,系统以块的方式处理处理,每一个操作在 +一步中产生或者消费一个数据库,按块处理要比按字节处理数据快的多。 + +## 1.3 通道Channel \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Nginx\347\232\204\351\205\215\347\275\256\345\222\214\344\275\277\347\224\250\345\221\275\344\273\244.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Nginx\347\232\204\351\205\215\347\275\256\345\222\214\344\275\277\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..ecc20fa --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Nginx\347\232\204\351\205\215\347\275\256\345\222\214\344\275\277\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,60 @@ +--- +title: Nginx的配置和使用命令 +date: 2022-07-26 13:10:15 +updated: +categories: +- 学习 +tags: +- 服务器 +- Nginx +keywords: +- 服务器 +- Nginx +description: 安装和简单使用Nginx部署项目 +cover: https://uzbox.com/wp-content/uploads/2022/04/e5b0bc8d2560c94ecf913d99525b6525.png +top_img: https://wtit.com/wp-content/uploads/2022/01/WTIT-header-NGINX.png +--- + +### 1、配置文件地址 + +``` +/opt/homebrew/etc/nginx/nginx.conf +``` + +### 2、bin目录 + +``` +/opt/homebrew/Cellar/nginx/1.23.1/bin +``` + +### 3、前端页面地址 + +``` +/opt/homebrew/var/www +``` + +### 4、启动nginx + +```shell +sudo nginx +``` + +### 5、关闭nginx + +```shell +sudo nginx -s stop +``` + +### 6、解决跨域 + +``` + server { + listen 8080; + server_name 192.168.0.114; #前端主机地址,我前后端都部署在局域网同一电脑上 + + location / { + root html/dist; + index index.html index.htm; + proxy_pass 192.168.0.114; #后端主机地址 + } +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Quarkus\344\272\221\345\216\237\347\224\237\346\227\266\344\273\243\347\232\204Java\346\241\206\346\236\266.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Quarkus\344\272\221\345\216\237\347\224\237\346\227\266\344\273\243\347\232\204Java\346\241\206\346\236\266.md" new file mode 100644 index 0000000..f0c3132 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Quarkus\344\272\221\345\216\237\347\224\237\346\227\266\344\273\243\347\232\204Java\346\241\206\346\236\266.md" @@ -0,0 +1,201 @@ +--- +title: Quarkus——云原生时代的Java框架 +date: 2024-08-15 10:26:00 +updated: 2024-08-15 10:26:00 +categories: +- 学习 +tags: +- Quarkus +- 云原生 +keywords: +- Quarkus +- 云原生 +description: Quarkus——云原生时代的Java框架 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212154303.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212153128.png +--- +# Quarkus: 云原生时代的Java框架 + +## 云原生简介 + +### 什么是云原生? + +云原生体系结构和技术是一种方法,用于设计、构造和操作在云中构建并充分利用云计算模型的工作负载。 +云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。 + +### 云原生的代表技术 + +#### 微服务 + +云原生系统采用微服务,而微服务是一种用于构造新式应用程序的常用体系结构样式。 +微服务构建为一组通过共享结构进行交互的分布式小型独立服务,共同具有以下特征: + +- 各自都在较大的域上下文中实现特定业务功能。 + +- 各自都自主开发,可以独立部署。 + +- 各自都是独立的,封装其自己的数据存储技术、依赖项和编程平台。 + +- 各自都在自己的进程中运行,并使用 HTTP/HTTPS、gRPC、WebSocket 或 AMQP 等标准通信协议与其他微服务进行通信。 + +- 它们组合在一起形成应用程序。 + + #### 容器 + + 容器是与系统其他部分隔离开的一系列进程 + 容器提供进程级的隔离,可以将操作系统管理的资源划分到相互隔离的组中,在相互隔离的组之间解决资源使用存在冲突的问题 + 容器是微服务的最佳载体,Docker是使用最广泛的一种容器技术。 + + #### Kubernetes + + Kubernetes用于编排管理容器的生命周期,是整个云原生的基石,云原生的整个生态体系都是依靠Kubernetes建立起来的。 + Kubernetes作为云应用的部署标准,直接面向业务应用,大大提高了云应用的可移植性,解决云厂商锁定的问题,让云应用可以在跨云之间无缝迁移,甚至用来管理混合云,成为企业 IT 云平台的新标准。 + +#### 服务网格 + +服务网格(Service Mesh),是指用以处理服务与服务之间通信的基础设施层。 +服务网格 核心是业务逻辑与非业务逻辑解耦,实现开发只需关注业务逻辑的实现。将一大堆和业务逻辑无关的客户端 SDK(如服务发现,路由,负载均衡,限流降级等)从业务应用中剥离出来,放到单独的 Proxy(Sidecar) 进程中,之后下沉到基础设施中间件 Mesh(类似 TDDL 到 DRDS 的模式)。 +服务网格的出现弥补了Kubernetes在微服务的连接、管理和监控方面的短板,为Kubernetes提供更好的应用和服务管理。 +Istio是是目前最广为人知的一款服务网格架构。 + +### 云原生的优点 + +#### 快速迭代 + +利用云原生应用程序开发,使得交付团队可以使用重复的自动化和编排来快速迭代,让开发人员有更多的精力聚焦于业务开发上。 + +#### 自动部署 + +相比于传统方法需要投入大量的精力来构建开发环境,云原生架构具备自动化和组合功能,交付十分敏捷,而不再需要人工干预重复执行。 + +#### 独立高效 + +云原生将应用程序代码解耦成独立模块化单元,降低微服务的部属时间与互依性,提高应用的扩展性等。 + +## Java在云原生时代的挑战 + +### Java的优势 + +- 庞大的生态,丰富的插件,活跃的社区; +- 平台无关性,一次运行,处处运行; +- 垃圾回收机制,不用手动回收内存; + +### Java的劣势 + +- 依赖JDK +- 启动慢 +- 资源占用率高 + +## Quarkus + +### 什么是Quarkus + +Quarkus 是专为 OpenJDK HotSpot 和 GraalVM 定制的全栈 Kubernetes 原生 Java 应用程序框架。与如 Spring 之类的其他框架相比,它提供了较小的内存占用并缩短了启动时间。它允许结合命令式和非阻塞响应式编程。 +![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010877) + +### Quarkus的特性 + +![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010909) + +### Quarkus与传统Java应用的启动步骤对比 + +- 传统应用的启动步骤 + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010555) +- Quarkus应用的启动步骤 + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010255) + +### Quarkus功能介绍 + +![页面-2](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010924.png) + +### 将应用从SpringBoot 迁移到Quarkus + +#### 依赖替换 + +- `io.quarkus:quarkus-spring-boot-properties`: 使用注释如`@ConfigurationProperties`时需要; +- `io.quarkus:quarkus-spring-di`:使用注释如`@Service`、`Configuration`时需要; +- `io.quarkus:quarkus-spring-web`:使用注释如`@RestController`、`GetMapping`时需要; + +#### 类替换 + +![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010225) + +#### 注解替换 + +![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151010068) + +#### 异常处理替换 + +- SpringBoot + + ```java + import javax.ws.rs.WebApplicationException; + import javax.ws.rs.core.Response; + import javax.ws.rs.ext.ExceptionMapper; + import javax.ws.rs.ext.Provider; + @Provider + public class UncaughtExceptionMapper implements ExceptionMapper { + //... + @Override + public Response toResponse(Exception ex) { + if (ex instanceof WebApplicationException) { + return ((WebApplicationException)ex).getResponse(); + } + logger.error("Uncaught exception", ex); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + }COPY + ``` + +- Qurakus + + ```java + @ControllerAdvice + public class GlobalExceptionHandlers { + //... + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception ex) { + logger.error("Uncaught exception", ex); + return ResponseEntity.badRequest().build(); + } + }COPY + ``` + +### 案例演示 + +#### SpringBoot工程 + +- 打包`mvn install` + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151011711) +- 打包后产物 + img +- 启动运行`java -jar -Dserver.port=3050 target/wakatime-sync.jar + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151011218) + +#### Quarkus工程 + +- 打包 `mvn package -Dnative` + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151011344) +- 打包后产物 + img +- 启动`./target/wakatime-sync-1.0-runner` + ![img](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202408151012829) + +### Quarkus的局限性和缺点 + +- 动态类加载 +- 反射 +- 动态代理 +- JNI +- Java 安全管理器 +- 编译原生镜像耗时且占用资源较多 +- 生成的镜像没法做到**一处编译,处处运行** +- 虽然社区活跃,支持的插件已有100多个,但相比Spring生态来说还是远远不够,需要插件都需要自己开发 + +## 参考阅读 + +1. [GraalVM指南](https://www.graalvm.org/22.1/guides/) +2. [Quarkus指南](https://cn.quarkus.io/guides/) +3. [Quarkus插件社区](https://github.com/quarkiverse) +4. [Quarkus实战教程](https://quarkus.io/quarkus-workshops/super-heroes/) +5. [原生镜像兼容性和优化指南](https://www.graalvm.org/22.1/reference-manual/native-image/Limitations/) \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RabbitMQ\345\277\253\351\200\237\344\270\212\346\211\213.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RabbitMQ\345\277\253\351\200\237\344\270\212\346\211\213.md" new file mode 100644 index 0000000..69523e2 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RabbitMQ\345\277\253\351\200\237\344\270\212\346\211\213.md" @@ -0,0 +1,174 @@ +--- +title: RabbitMQ快速上手 +date: 2024-06-29 15:24:00 +updated: 2024-10-26 15:39:00 +categories: +- 学习 +tags: +- RabbitMQ +- 消息队列 +keywords: +- RabbitMQ +- 消息队列 +description: RabbitMQ快速上手 +cover: https://www.meshiq.com/wp-content/uploads/rabbitmq.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212159254.png +--- + +#### 常见的交换机类型: + +- **Direct Exchange**:直连交换机。消息会被路由到所有`路由键`与`绑定队列`。 +- **Fanout Exchange**:广播交换机。消息会被路由到所有`绑定队列`,忽略路由键。 +- **Topic Exchange**:主题交换机。消息会被路由到所有`绑定队列`,支持通配符。 + +最简单的消息队列只需要`生产者类`和`消费者类`,如下: + +```java +@SpringBootTest +public class RabbitProducer { + + @Test + public void testSimpleQueue() { + // 创建连接工厂 + CachingConnectionFactory connectionFactory = new CachingConnectionFactory("192.168.20.80"); + connectionFactory.setUsername("leke"); + connectionFactory.setPassword("leke@@@"); + // 创建 RabbitTemplate + RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); + // 发送消息 + rabbitTemplate.convertAndSend("e.test", "q.test", "hello, spring amqp!"); + + } +} + + +@Component +public class RabbitConsumer { + // 表明监听的队列名称 + @RabbitListener(bindings = @QueueBinding( + value = @Queue(value = "q.test", durable = "true"), + exchange = @Exchange(value = "e.test"))) + public void listenSimpleQueueMessage(String msg) { + //3、打印消息,模拟处理消息 + System.out.println("spring 消费者接收到消息:【" + msg + "】"); + } + +} +``` + + + +**但从项目设计角度出发,我们需要这样使用消息队列,如下:** + +`RabbitMqConstant`常量类:存放交换机名称和队列名称 + +```java +public class RabbitMqConstant { + + public static final String TEST_EXCHANGE = "e.test"; + public static final String TEST_QUEUE = "q.test"; + +} +``` + +`RabbitConfig`配置类:注册交换机类和队列类,绑定交换机和队列(如果采用注解绑定,可以不写) + +```java +public class RabbitConfig { + @Bean + public DirectExchange testExchange() { + return new DirectExchange(RabbitMqConstant.TEST_EXCHANGE); + } + + @Bean + public Queue testQueue() { + return new Queue(RabbitMqConstant.TEST_QUEUE); + } + + @Bean + public Binding testBinding() { + return BindingBuilder.bind(testQueue()) + .to(testExchange()) + .with(RabbitMqConstant.TEST_QUEUE); + } + + // 其他的配置,例如配置消息监听容器工厂。以下代码定义了如何处理消息消费过程中的异常情况,特别是通过自定义的异常策略来控制消息的重试逻辑,增强了消息处理的健壮性和灵活性。 + @Bean + public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory( + SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + configurer.configure(factory, connectionFactory); + @SuppressWarnings("unchecked") + FatalExceptionStrategy strategy = LekeFatalExceptionStrategy.retryOn(DataAccessException.class, + RemoteAccessException.class, Exception.class); + factory.setErrorHandler(new ConditionalRejectingErrorHandler(strategy)); + return factory; + } +} +class FatalExceptionStrategy extends DefaultExceptionStrategy { + + // 构建策略 + @SuppressWarnings("unchecked") + public static FatalExceptionStrategy retryOn(Class... exClasses) { + Set> set = new HashSet<>(); + for (Class clazz : exClasses) { + set.add(clazz); + } + return new FatalExceptionStrategy(set); + } + + final Set> retryables; + + public FatalExceptionStrategy(Set> exceptions) { + this.retryables = exceptions == null ? Collections.emptySet() : Collections.unmodifiableSet(exceptions); + } + + @Override + protected boolean isUserCauseFatal(Throwable e) { + boolean needRetry = retryables.stream().anyMatch(clazz -> clazz.isInstance(e)); + return !needRetry; + } +} +``` + +`RabbitConsumer`消费者类 + +```java +@Component +public class RabbitConsumer { +// @RabbitListener(queues = RabbitMqConstant.TEST_QUEUE) + @RabbitListener(bindings = @QueueBinding( + value = @Queue(value = RabbitMqConstant.TEST_QUEUE, durable = "true"), + exchange = @Exchange(value = RabbitMqConstant.TEST_EXCHANGE))) + public void listenSimpleQueueMessage(String msg) { + System.out.println("spring 消费者接收到消息:【" + msg + "】"); + } + +} +``` + +`RabbitProducer`生产者类 + +```java +@SpringBootTest +public class RabbitProducer { + + @Test + public void testSimpleQueue() { + // 创建连接工厂 + CachingConnectionFactory connectionFactory = new CachingConnectionFactory("192.168.20.80"); + connectionFactory.setUsername("leke"); + connectionFactory.setPassword("leke@@@"); + // 创建 RabbitTemplate + RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); + // 配置交换机和队列 +// DirectExchange testExchange = new DirectExchange(RabbitMqConstant.TEST_EXCHANGE); +// Queue testQueue = new Queue(RabbitMqConstant.SUBMIT_TASK_QUEUE); +// Binding binding = BindingBuilder.bind(testQueue).to(testExchange).with(RabbitMqConstant.TEST_QUEUE); + // 发送消息 + rabbitTemplate.convertAndSend(RabbitMqConstant.TEST_EXCHANGE, RabbitMqConstant.TEST_QUEUE, "hello, spring amqp!"); + + } +} +``` + diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\234\250SpringBoot\347\232\204\351\205\215\347\275\256.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\234\250SpringBoot\347\232\204\351\205\215\347\275\256.md" new file mode 100644 index 0000000..66fb857 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\234\250SpringBoot\347\232\204\351\205\215\347\275\256.md" @@ -0,0 +1,55 @@ +--- +title: Redis在SpringBoot的配置 +date: 2022-04-02 13:25:15 +updated: +categories: +- 学习 +tags: +- Redis +- SpringBoot +keywords: +- Redis +- SpringBoot +description: 将Redis集成到SpringBoot上 +cover: https://images.velog.io/images/jinmin2216/post/3d9a578e-53f4-4cf4-8807-7c91d61f35bf/%E1%84%89%E1%85%B3%E1%84%91%E1%85%B3%E1%84%85%E1%85%B5%E1%86%BC%20%E1%84%85%E1%85%A6%E1%84%83%E1%85%B5%E1%84%89%E1%85%B3.jpeg +top_img: https://miro.medium.com/max/1200/1*BJA4Po0UTCoBt1hVaEm6KA.png +--- + +### 1、添加依赖 + +``` + + org.springframework.boot + spring-boot-starter-data-redis + +``` + +### 2、配置文件 + +``` + redis: + host: localhost # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + jedis: + pool: + max-active: 8 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 8 # 连接池中的最大空闲连接 + min-idle: 0 # 连接池中的最小空闲连接 + timeout: 3000ms # 连接超时时间(毫秒) + +``` + +### 3、自定义key的配置 + +``` +# 自定义redis key +redis: + key: + prefix: + authCode: "portal:authCode:" + expire: + authCode: 120 # 验证码超期时间 +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213\345\270\270\347\224\250\345\221\275\344\273\244.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213\345\270\270\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..2c3930e --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Redis\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213\345\270\270\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,217 @@ +--- +title: Redis基本数据类型常用命令 +date: 2022-03-15 21:58:15 +updated: +categories: +- 学习 +tags: +- Redis +keywords: +- Redis +description: 初识Redis +cover: https://www.w3cschool.cn/attachments/image/20170622/1498119653712274.png +top_img: https://s1.51cto.com/oss/202004/10/727f6a7cee2af212d5a6675238898dad.jpeg +--- + +## 简介 + +Redis是一个高性能的key-value数据库。Redis对数据的操作都是原子性的。 + +**优缺点** + +优点: + +1. **基于内存操作,内存读写速度快。** +2. Redis是**单线程**的,避免线程切换开销及多线程的竞争问题。单线程是指在处理网络请求(一个或多个redis客户端连接)的时候只有一个线程来处理,redis运行时不只有一个 线程,数据持久化或者向slave同步aof时会另起线程。 +3. **支持多种数据类型**,包括String、Hash、List、Set、ZSet等。 +4. 支持**持久化**。Redis支持**RDB和AOF**两种持久化机制,持久化功能有效地避免数据丢失问题。 +5. redis采用**IO多路复用**技术。多路指的是多个socket连接,复用指的是复用一个线程。redis使用单线程俩轮询描述符,将数据库的开、关、读、写都转换成了时间。多路复用主要有三种技术:select、poll、epoll。epoll是最新的也是目前最好的多路复用技术。 + +缺点:对join或其他结构化查询的支持就比较差。 + +**io多路复用** + +**应用场景** + +1. 缓存热点数据,缓解数据库的压力 +2. 利用Redis中原子性的自增操作,可以用于实现计算器的功能,比如统计用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力。 +3. 简单消息队列,不要求高可靠地情况下,可以使用Redis自身的发布/订阅模式或者List来实现一个队列,实现异步操作。 +4. 好友关系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能。 +5. 限速器,比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购,防止用户疯狂点击带来不必要的压力。 + +Redis支持五种数据类型: + +- string(字符串) +- hash(哈希) +- list(列表) +- set(集合) +- zset(sorted set) + +## String + +String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化对象。 + +### 常用命令 + +| 命令 | 简述 | 使用 | +|:------ |:------------ |:-------------- | +| get | 读取存储在给定键中的值 | get key | +| set | 设置存储在给定键中的值 | set key value | +| del | 删除存储在给定键中的值 | del key | +| incr | 将键存储的值加1 | incr key | +| decr | 将键存储的值减1 | decr key | +| incrby | 将键存储的值加上指定整数 | incrby key num | +| decrby | 将键存储的值减去指定整数 | decrby key num | + +- **赋值(set)和取值(get)** + + ```shell + set name gmt + get name + ``` + +- **递增(incr)和递减(decr)** + + ```bash + incr num // 若键值不是整数时,会提示错误 + incrby num 3 // 增加指定整数 + decr num // 递减数字 + incrbyfloat num 12.3 // 增加指定浮点数 + ``` + +- **其他** + + `key list*` 列出所有匹配的key + + `append name "123"`追加值 + + `strlen name` 获取字符串长度 + + `mset num 1 float 2` 同时设置多个值 + + `mget name gender` 同时获取多个值 + + `getbit name 0` 获取0索引处二进制位的值 + + `flushdb` 删除当前数据库所有的key + + `flushall` 删除所有数据库中的key + +- setnx和setex + +`setnx key value`:当key不存在时,将key的值设为value。若给定的key已经存在,则SETNX不做任何操作。 + +`setex key seconds value`:比SET多了seconds参数,相当于`SET KEY value` + `EXPIRE KEY seconds`,而且SETEX是原子性操作。 + +- expire + +```dart +expire key num // 设置key过期时间为num秒 +ttl key // 查看键的剩余生存时间,-1为永不过期 +``` + +expire时间单位是秒,pexpire时间单位是毫秒。 + +在键未过期前可以重新设置过期时间,过期之后键被销毁。 + +注意: + +- 如果key不存在或者已过期,返回-2 +- 如果key存在并且没有设置过期时间(永久有效),返回-1 + +### 实战场景 + +- **缓存**:经典使用场景,把常用信息,字符串,图片或者视频等信息放到redis中,redis作为缓存层,mysql作为持久化层,降低mysql的读写压力。 +- **计数器**:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。 +- **session**:常见方案spring session + redis 实现session共享。 + +## List + +**Redis中的List其实就是链表(Redis使用双端链表实现List)** + +### 常用命令 + +| 命令 | 简述 | 使用 | +|:------- |:--------------------------------------------- |:----------------------------------------------------------- | +| rpush | 将给定值推入到列表右端 | rpush list value | +| lpush | 将给定值推入到列表左端 | lpush list value | +| rpop | 从列表的右端弹出一个值,并返回被弹出的值 | rpop list | +| lpop | 从列表的左端弹出一个值,并返回被弹出的值 | lpop list | +| lrange | 获取列表在给定范围上的所有值 | lrange list 0 -1 | +| lindex | 通过索引获取列表中的元素,可以使用负数下标,-1表示最后一个,-2表示倒数第二个,以此类推 | lindex key index | +| linsert | 从左到右寻找职位pivot的值,向列表插入value | linsert list after(before) pivot value 往pivot后面(前面)插入value; | +| ltrim | 删除索引begin到end以外的所有元素 | ltrim list begin end | +| llen | 获取列表元素个数 | llen list | +| lset | 修改指定索引处的值 | lset list index value | + +### 常用技巧 + +- lpush + lpop = Stack(栈) +- lpush + rpop = Queue(队列) +- lpush + ltrim = Capped Collection(有限集合) +- lpush + brpop = Message Queue(消息队列) + +### 实战场景 + +- **微博TimeLine**:有人发布微博,用lpush加入时间轴,显示新的消息列表 +- **消息队列** + +## Set + +Redis 的 Set 是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 + +Redis 中集合是通过哈希表实现的,所以添加、删除、查找的时间复杂度都是O(1) + +### 常用命令 + +| 命令 | 简述 | 使用 | +|:----------- |:----------------------------------------------------------------------- |:------------------------- | +| sadd | 向集合添加一个或多个成员 | sadd set value1 value2... | +| scard | 获取集合的成员数 | scard set | +| smembers | 返回集合中的所有成员 | smembers set | +| srem | 删除集合中一个或多个成员 | srem set value1,value2... | +| sismember | 判断元素是否在集合中 | sismember set value | +| sdiff | 差集运算 | sdiff setA setB ... | +| sinter | 交集运算 | sinter setA setB ... | +| sunion | 并集运算 | sunion setA setB ... | +| srandmember | 随机获取集合里的一个元素,count大于0,则从集合随机获取count个不重复元素,count小于0,则随机获取的count个元素有些可能相同 | srandmember set count | + +### 实战场景 + +- **标签**:给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或这关注的人。 +- **点赞,点踩,收藏** + +## Hash + +Redis hash 是一个string类型的field(字段)和value(值)的映射表,hash特别适合用户存储对象。 + +### 常用命令 + +| 命令 | 简述 | 使用 | +|:------- |:-------------------- |:--------------------------------------- | +| hset | 添加键值对 | hset myhash key1 value1 key2 value2 ... | +| hget | 获取指定散列键的值 | hget myhash key1 | +| hgetall | 获取散列中包含的所有键值对 | hgetall myhash | +| hdel | 如果给定键存在于散列中,那么就移除这个键 | hdel myhash key1 | + +### 实战场景 + +- **缓存**:能直观,相比string更节省空间 + +## Zset + +Redis 有序集合和集合一样也是string类型的元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 + +有序集合的成员是唯一的,但是分数(score)可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1) + +### 常用命令 + +| 命令 | 简述 | 使用 | +|:------ |:---------------------------- |:-------------------------- | +| zadd | 将一个带有给定分值的成员添加到有序集合里面 | zadd zset key | +| zrange | 根据元素在有序集合中所处的位置,从有序集合中获取多个元素 | zrange zset 0 2 withscores | +| zrem | 如果给定元素成员存在于有序集合中,那么就移除这个元素 | zrem zset member | + +### 实战场景 + +- **排行榜:**有序集合经典使用场景。例如小说视屏等网站需要对用户上传的小说视频做排行榜,榜单可以按照用户关注数、更新时间、字数等打分,做排行。 diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RocketMQ\345\216\237\347\220\206.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RocketMQ\345\216\237\347\220\206.md" new file mode 100644 index 0000000..c2f4003 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/RocketMQ\345\216\237\347\220\206.md" @@ -0,0 +1,302 @@ +--- +title: RocketMQ原理 +date: 2024-07-10 12:47:00 +updated: 2024-08-10 18:52:00 +categories: +- 学习 +tags: +- 消息队列 +- RocketMQ +keywords: +- 消息队列 +- RocketMQ +description: RocketMQ原理 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212158381.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212157755.png +--- + +# 1. 什么是RocketMQ + +rocketmq是阿里巴巴开源的一款基于高可用分布式集群的消息中间件,可为分布式系统提供异步、解耦和流量削峰的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等性能,是阿里巴巴双11使用的核心产品。 + +# 2. 应用场景 + +1.削峰填谷:诸如秒杀、抢红包、企业开门红等大型活动时皆会带来较高的流量脉冲,或因没做相应的保护而导致系统超负荷甚至崩溃,或因限制太过导致请求大量失败而影响用户体验,消息队列 RocketMQ 可提供削峰填谷的服务来解决该问题。 + +2.异步处理,应用解耦:交易系统作为淘宝/天猫主站最核心的系统,每笔交易订单数据的产生会引起几百个下游业务系统的关注,包括物流、购物车、积分、流计算分析等等,整体业务系统庞大而且复杂,消息队列 RocketMQ 可实现异步通信和应用解耦,确保主站业务的连续性。 + +3.顺序收发:细数日常中需要保证顺序的应用场景非常多,比如证券交易过程时间优先原则,交易系统中的订单创建、支付、退款等流程,航班中的旅客登机消息处理等等。与先进先出(First In First Out,缩写 FIFO)原理类似,消息队列 RocketMQ 提供的顺序消息即保证消息 FIFO。 + +4.分布式事务:交易系统、支付红包等场景需要确保数据的最终一致性,大量引入消息队列 RocketMQ 的分布式事务,既可以实现系统之间的解耦,又可以保证最终的数据一致性。 + +5.大数据分析:数据在“流动”中产生价值,传统数据分析大多是基于批量计算模型,而无法做到实时的数据分析,利用阿里云消息队列 RocketMQ 与流式计算引擎相结合,可以很方便的实现将业务数据进行实时分析 + +# 3. 对比rabbitMQ,kafka主要的优势 + +支持事务型消息 +支持延迟消息 +支持指定次数和时间间隔的失败消息重发 +支持consumer端tag过滤,减少不必要的网络传输 +支持重复消费(rabbitmq不支持,kafka支持) + +# 4. RocketMQ中核心的概念 + +1.Topic:消息主题一级消息类型,生产者向其发送消息。 + +2.生产者:也称为消息发布者,负责生产并发送消息至 Topic。 + +3.消费者:也称为消息订阅者,负责从 Topic 接收并消费消息。 + +4.消息:生产者向 Topic 发送并最终传送给消费者的数据和(可选)属性的组合。 + +5.消息属性:生产者可以为消息定义的属性,包含 Message Key 和 Tag。 + +6.Group:一类生产者或消费者,这类生产者或消费者通常生产或消费同一类消息,且消息发布或订阅的逻辑一致。 + +# 5. Rocket的原理和架构图 + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506435265.png) + +结合部署结构图,描述集群工作流程: + +1,启动Namesrv,Namesrv起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。 + +2,Broker启动,跟所有的Namesrv保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有topic信息。注册成功后,namesrv集群中就有Topic跟Broker的映射关系。 + +3,收发消息前,先创建topic,创建topic时需要指定该topic要存储在哪些Broker上。也可以在发送消息时自动创建Topic。 + +4,Producer发送消息,启动时先跟Namesrv集群中的其中一台建立长连接,并从Namesrv中获取当前发送的Topic存在哪些Broker上,然后跟对应的Broker建长连接,直接向Broker发消息。 + +5,Consumer跟Producer类似。跟其中一台Namesrv建立长连接,获取当前订阅Topic存在哪些Broker,然后直接跟Broker建立连接通道,开始消费消息。 + +# 6.RocketMQ各组件的功能 + +#### 1.NameServer 注册中心 + +就是一个注册中心,存储当前集群所有Brokers信息、Topic跟Broker的对应关系。 + +1.NameServer用于存储Topic、Broker关系信息,功能简单,稳定性高。多个Namesrv之间相互没有通信,单台Namesrv宕机不影响其他Namesrv与集群;即使整个Namesrv集群宕机,已经正常工作的Producer,Consumer,Broker仍然能正常工作,但新起的Producer, Consumer,Broker就无法工作。 + +2.Namesrv压力不会太大,平时主要开销是在维持心跳和提供Topic-Broker的关系数据。但有一点需要注意,Broker向Namesr发心跳时,会带上当前自己所负责的所有Topic信息,如果Topic个数太多(万级别),会导致一次心跳中,就Topic的数据就几十M,网络情况差的话,网络传输失败,心跳失败,导致Namesrv误认为Broker心跳失败。 + +#### 2.Broker 消息服务器 + +集群最核心模块,主要负责Topic消息存储、管理和分发等功能。 + +1.高并发读写服务 + +消息顺序写,所有Topic数据同时只会写一个文件,一个文件满1G,再写新文件,真正的顺序写盘,使得发消息TPS大幅提高。 + +消息随机读,RocketMQ尽可能让读命中系统pagecache,因为操作系统访问pagecache时,即使只访问1K的消息,系统也会提前预读出更多的数据,在下次读时就可能命中pagecache,减少IO操作。 + +2.负载均衡与动态伸缩 +负载均衡:Broker上存Topic信息,Topic由多个队列组成,队列会平均分散在多个Broker上,而Producer的发送机制保证消息尽量平均分布到所有队列中,最终效果就是所有消息都平均落在每个Broker上。 + +动态伸缩能力(非顺序消息):扩大topic的队列数,或 增加broker的数量 + +3.高可用&高可靠 + +高可用:集群部署时一般都为主备,备机实时从主机同步消息,如果其中一个主机宕机,备机提供消费服务,但不提供写服务。 + +高可靠:所有发往broker的消息,有同步刷盘和异步刷盘机制;同步刷盘时,消息写入物理文件才会返回成功,异步刷盘时,在返回写成功状态时,消息可能只是被写入了内存的PAGECACHE,写操作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘操作。只有机器宕机,会产生少量消息丢失,broker挂掉可能会发生,但是机器宕机崩溃是很少发生的,除非突然断电 + +4.Broker与Namesrv的心跳机制 + +单个Broker跟所有Namesrv保持心跳请求,心跳间隔为30秒,心跳请求中包括当前Broker所有的Topic信息。Namesrv每隔10秒会反查Broker的心跳信息,如果某个Broker在2分钟之内都没有心跳,则认为该Broker下线,调整Topic跟Broker的对应关系。但此时Namesrv不会主动通知Producer、Consumer有Broker宕机。 + +#### 3. consumer 消费者 + +消费者启动时需要指定Namesrv地址,与其中一个Namesrv建立长连接。消费者每隔30秒从nameserver获取所有topic的最新队列情况,这意味着某个broker如果宕机,客户端最多要30秒才能感知。连接建立后,从namesrv中获取当前消费Topic所涉及的Broker,直连Broker。 + +Consumer跟Broker是长连接,会每隔30秒发心跳信息到Broker。Broker端每10秒检查一次当前存活的Consumer,若发现某个Consumer 2分钟内没有心跳,就断开与该Consumer的连接,并且向该消费组的其他实例发送通知,触发该消费者集群的负载均衡。 + +消费者端的负载均衡,就是集群消费模式下,同一个groupID的所有消费者实例平均消费该Topic的所有队列。 + +但是Consumer 数量要小于等于队列数量,如果Consumer 超过队列数量,那么多余的Consumer 将不能消费消息。 + +消费者的消费模式:集群消费,广播消费。 + +广播消费:每个消费者消费Topic下的所有队列。 + +集群消费:一个topic可以由同一个groupID下所有消费者分担消费。 + +#### 4. producer 生产者 + +Producer启动时,也需要指定Namesrv的地址,从Namesrv集群中选一台建立长连接。如果该Namesrv宕机,会自动连其他Namesrv。直到有可用的Namesrv为止。 + +生产者每30秒从Namesrv获取Topic跟Broker的映射关系,更新到本地内存中。再跟Topic涉及的所有Broker建立长连接,每隔30秒发一次心跳。在Broker端也会每10秒扫描一次当前注册的Producer,如果发现某个Producer超过2分钟都没有发心跳,则断开连接。 + +生产者端的负载均衡 +生产者发送时,会自动轮询当前所有可发送的broker,一条消息发送成功,下次换另外一个broker发送,以达到消息平均落到所有的broker上。 + +这里需要注意一点:假如某个Broker宕机,意味生产者最长需要30秒才能感知到。在这期间会向宕机的Broker发送消息。当一条消息发送到某个Broker失败后,会往该broker自动再重发2次,假如还是发送失败,则抛出发送失败异常。业务捕获异常,重新发送即可。客户端里会自动轮询另外一个Broker重新发送,这个对于用户是透明的。 + +# 7.RocketMQ中Topic、Tag、GroupName的设计 + +#### Topic + +Topic是生产者在发送消息和消费者在拉取消息的类别,Topic与生产者和消费者之间的关系非常松散。一个Topic可能N多个生产者向它发送消息;一个生产者可以发送不同类型Topic的消息。类似的,消费者组可以订阅一个或多个主题,只要该组的实例保持其订阅一致即可。 + +我们可以理解为第一级消息类型,类比于书的标题 + +#### Tag + +标签,换句话的意思就是子主题,为用户提供了额外的灵活性。有了标签,来自同一业务模块的具有不同目的的消息可以具有相同的主题和不同的标签。标签有助于保持代码的清晰和连贯,同时标签也方便RocketMQ提供的查询功能。 + +我们可以理解为第二级消息类型,类比于书的目录,方便检索使用消息 + +groupName +代表具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组。 + +在消费者组中,可以实现消息消费的负载均衡和消息容错目标。 + +另外,有了GroupName,在集群下,动态扩展容量很方便。只需要在新加的机器中,配置相同的GroupName。启动后,就立即能加入到所在的群组中,参与消息生产或消费。 + +#### 7.1集群中topic的创建 + +https://blog.csdn.net/lblblblblzdx/article/details/88234641 + +1.手动创建 +手动选择 broker,以及创建队列的数量 +2.自动创建 + +# 8. 部署方式 + +#### 1. 单Master模式 + +只有一个Master节点 + +优点:配置简单,方便部署 + +缺点:风险较大,一旦broker重启或者宕机,导致整个服务不可用 + +https://blog.csdn.net/weixin_42576761/article/details/82774332 + +#### 2. 多Master模式 + +一个集群存在多个Master,没有Slave + +优点:配置简单,单个Master重启或者宕机对应用无影响。在磁盘配置为RAID10 时,即使机器宕机不可恢复情况下,由与 RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢) + +缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到受到影响 + +#### 3. 多Master多Slave模式(异步复制) + +每个 Master 配置一个 Slave,有多对Master-Slave, HA,采用异步复制方式,主备有短暂消息延迟,毫秒级。 + +优点:磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为Master 宕机后,消费者仍然可以从 Slave消费 + +缺点:Master 宕机,磁盘损坏情况,会丢失少量消息 + +#### 4. 多Master多Slave(同步双写) + +每个 Master 配置一个 Slave,有多对Master-Slave, HA采用同步双写方式,主备都写成功,向应用返回成功 + +优点:数据与服务都无单点, Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高 + +缺点:性能比异步复制模式略低,大约低 10%左右。 + +# 9. rockmq的分布式事务 + +1.Producer向RocketMQ发送一条待确认的事务类型消息。并获取到transactionId。 + +2.Producer执行本地事务。 + +3.Producer 根据本地执行的结果对RocketMQ进行二次确认。本地执行成功,将待确认的消息变成可投递消息,本地执行失败,mq将half message消息丢弃。 + +4.由于某种原因,导致二次确认的没有发送到RocketMQ,RocketMQ提供回查机制,就是在一段时间后,待确认的消息没有被确认,RocketMQ就会主动向producer询问 + +5.producer查询本地事务执行的情况。 + +6.向RocketMQ发送确认消息。 + +# 10. RocketMQ持久化原理 + +#### 1.存储架构设计 + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506513913.png) + +RocketMQ主要存储文件有三个,分别是: + +CommitLog:消息存储文件,所有的消息存在这里; + +ConsumeQueue:消费队列文件,消息在存储到CommitLog后,会将消息所在CommitLog偏移量、大小、tag的hashcode异步转发到消费队列存储,供消费者消费,其类似于数据库的索引文件,存储的是指向物理存储的地址,每个topic下的每个Message Queue都有一个对应的ConsumeQueue文件; + +Index:索引文件,消息在存储到CommitLog后,会将消息key与消息所在CommitLog偏移量转发到索引文件存储,供消息查询。 + +我们可以看出消息的生产与消费进行了分离,Producer端发送消息最终写入的是CommitLog,Consumer端先从ConsumeQueue读取持久化消息的起始物理位置偏移量offset、大小size和消息Tag的HashCode值,再从CommitLog中进行读取待拉取消费消息的真正实体内容部分。 + +#### 2.RocketMQ中如何做到消息存储的高效性 + +高性能磁盘在顺序写入的时候,速度基本可以堪比内存的写入速度,但是磁盘随机写入的时候,性能瓶颈非常明显,速度会比较慢。 + +所以RocketMQ采用了全部消息都存入一个CommitLog文件中,并且对写操作加锁(putMessageLock),保证串行顺序写入消息,避免磁盘竟争导致IO WAIT增高,大大提高写入效率。 + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506555037.png) + +生产者按顺序写入CommitLog,消费者通过顺序读取ConsumeQueue进行消费,这里有一个地方需要注意,虽然消费者是按照顺序读取ConsumeQueue,但是并不代表它就是按照顺序读取消息,因为根据ConsumeQueue中的起始物理位置偏移量offset读取消息真实内容,在并发量非常高的情况下,实际上是随机读取CommitLog,而随机读取文件带来的性能开销影响还是比较大的,所以在这里,RocketMQ利用了操作系统的pagecache机制,批量从磁盘读取,作为cache存在内存中,加速后速的读取速度。 + +#### 3.存储文件 + +RocketMQ在磁盘上持久化的目录: + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506568519.png) + +CommitLog文件夹中的内容: + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506578093.png) + +可以看到每个文件1G大小,以该文件中第一个偏移量为文件名,偏移量小于20位用0补齐。如图所示,第一个文件的初始偏移量为9663676416,第二个文件的初始偏移量为10737418240。 + +CommitLog文件内部存储逻辑是,每条消息的前4个字节存储该条消息的总长度(包含长度信息本身),随后便是消息内容。如图所示: + +![file](https://blog.leke.cn/wp-content/uploads/2022/07/image-1657506597380.png) + +消息的长度=消息长度信息(4字节)+ 消息内容长度。 + +实现消息查找的步骤: + +1.消费者从消费队列中获取到某个消息的偏移量offset与长度size; + +2.根据偏移量offset定位到消息所在的commitLog物理文件; + +3.用偏移量与文件长度取模,得到消息在这个commitLog文件内部的偏移量; + +4.从该偏移量取得size长度的内容返回即可。 + +ConsumeQueue文件: + +不同主题下的消息都交错杂糅在同一个文件里,想要提高查询速度,必须要构建类似于搜索索引的文件,于是就有了消费队列ConsumeQueue文件。 + +从实际物理存储来说,每个ConsumeQueue文件对应每个Topic和QueuId。 + +# 11. RocketMQ的顺序消息 + +顺序消息(FIFO 消息)是 MQ 提供的一种严格按照顺序进行发布和消费的消息类型。RocketMQ可以严格的保证消息有序。但这个顺序,不是全局顺序,只是分区(queue)顺序,要全局顺序只能一个分区。 + +需要从发送到消费整个过程中保证有序: + +1.发送消息是顺序的:producer发送消息需要同步 + +2.boker存储消息是顺序的 + +3.consumer消费是顺序的:需要保证一个queue只在一个线程内被消费。 + +#### 1.发顺序消息 + +因为broker存储消息有序的前提是producer发送消息是有序的,producer发送消息应该是依次发送的,所以要求发送消息的时候保证: + +1.消息不能异步发送,同步发送的时候才能保证broker收到是有序的。 + +2.每次发送选择的是同一个MessageQueue。 + +#### 2.producer顺序发送 + +一个订单的流程 创建,支付,完成。订单号相同的消息需要先后写入同一个队列。 + +通过MessageQueueSelector来实现分区的选择,使相同订单号的消息写入同一队列 +Producer发送消息的时候需要同步发送。producer发送消息之后不会立即返回,会等待broker的response。broker收到producer的请求之后虽然是启动线程处理的,但是在线程中将消息写入commitLog中以后会发送response给producer,producer在收到broker的response并且是处理成功之后才算是消息发送成功。 + +#### 3.consumer顺序消费 + +MessageListenerOrderly类,不再使用MessageListenerConcurrently类,这样就可以保证消费端只有一个线程去消费消息 \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/SpringMVC\346\263\250\350\247\243\345\222\214\351\205\215\347\275\256 + fastjson\347\232\204\347\256\200\345\215\225\344\275\277\347\224\250.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/SpringMVC\346\263\250\350\247\243\345\222\214\351\205\215\347\275\256 + fastjson\347\232\204\347\256\200\345\215\225\344\275\277\347\224\250.md" new file mode 100644 index 0000000..344931d --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/SpringMVC\346\263\250\350\247\243\345\222\214\351\205\215\347\275\256 + fastjson\347\232\204\347\256\200\345\215\225\344\275\277\347\224\250.md" @@ -0,0 +1,153 @@ +--- +title: SpringMVC注解和配置 + fastjson的简单使用 +date: 2022-02-14 20:47:15 +updated: +categories: +- 学习 +tags: +- SpringMVC +- 注解 +- 配置 +- fastjson +keywords: +- SpringMVC +- fastjson +description: Controller层常用注解、fastjson简单上手使用 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/7a46220cec7e445508245e0e7cebccbf62dff0b2.png_320w_200h_1c.jpg +top_img: https://www.yht7.com/upload/image/20200519/2024393-20200518230425868-1113585406.jpg +--- + +```java +@Controller +``` + +@Controller负责处理前端控制器(DispatcherServlet )发过来的请求,经过业务逻辑层处理之后封装层一个model,并将其返回给view进行展示 + +```java +@RestController +``` + +@RestController = @Controller + @ResponseBody(@ResponseBody 注解是将返回的数据结构转换为 JSON 格式) + +```java +@RequestMapping(value="/hello",method={RequestMethod.GET}) +``` + +@RequestMapping用来处理请求地址映射 + +```java +@RequestParam(value="username",required=true,defaultValue=null) +``` + +@RequestParam获取请求参数,可以用在对象属性名与方法参数名不一样的场景中 + +```java +@PathVariable +``` + +@PathVariable注解用来获取 URL 参数,**用于支持Restful风格的 URL,请求的URL也需要相应地有所改变。** + +例如:GetMapping(“user/{id}”) + +```java +@ResponseBody +``` + +@ResponseBody要写在方法名上。如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,返回的是json数据(所以你应该return字符串,而不是URL地址)。如果不加@ResponseBody,就走视图解析器,返回页面 + +```java +@RequestBody +``` + +@RequestBody用于接收前端传来的实体,要写在方法的参数前,**只能发送POST请求。** + +```javascript + + +``` + +统一解决JSON在SpringMVC中的乱码问题 + +```xml + + + + + + + + + + + + + + +``` + +fastJSON部分方法的使用 + +```java +public class FastJsonDemo { + public static void main(String[] args) { + //创建一个对象 + User user1 = new User("秦疆1号", 3, "男"); + User user2 = new User("秦疆2号", 3, "男"); + User user3 = new User("秦疆3号", 3, "男"); + User user4 = new User("秦疆4号", 3, "男"); + List list = new ArrayList(); + list.add(user1); + list.add(user2); + list.add(user3); + list.add(user4); + + System.out.println("*******Java对象 转 JSON字符串*******"); + String str1 = JSON.toJSONString(list);//返回数组的JSON字符串 + System.out.println("JSON.toJSONString(list)==>"+str1); + String str2 = JSON.toJSONString(user1);//返回对象的JSON字符串 + System.out.println("JSON.toJSONString(user1)==>"+str2); + + System.out.println("\n****** JSON字符串 转 Java对象*******"); + User jp_user1=JSON.parseObject(str2,User.class);//把User的JSON字符串转换成Java对象 + System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1); + + System.out.println("\n****** Java对象 转 JSON对象 ******"); + JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);//把一个User对象转换成JSON对象 + System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));//获取JSON对象某个属性的值 + + System.out.println("\n****** JSON对象 转 Java对象 ******"); + User to_java_user = JSON.toJavaObject(jsonObject1, User.class);//将一个JSON对象转成一个指定的java对象 + System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user); + } +} +``` + +输入结果: + +![img](https://s3.bmp.ovh/imgs/2022/02/cb141f0b46e77708.png) + +lombok依赖要引入的几个必要注解: + +```java +@Data +@AllArgsConstructor +@NoArgsConstructor +public class person(){ + +} +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Tomcat\345\220\257\345\212\250\345\205\263\351\227\255\345\221\275\344\273\244.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Tomcat\345\220\257\345\212\250\345\205\263\351\227\255\345\221\275\344\273\244.md" new file mode 100644 index 0000000..5ef414a --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/Tomcat\345\220\257\345\212\250\345\205\263\351\227\255\345\221\275\344\273\244.md" @@ -0,0 +1,28 @@ +--- +title: Tomcat启动关闭命令 +date: 2022-02-02 20:14:15 +updated: +categories: +- 学习 +tags: +- Tomcat +keywords: +- Tomcat +description: Mac上Tomcat启动和关闭的命令 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212223754.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212225858.png +--- + +启动Tomcat + +```shell +sudo sh /Users/hzx/devTools/apache-tomcat-9.0.58/bin/startup.sh +sudo sh startup.sh +``` + +关闭Tomcat + +```shell +sudo sh /Users/hzx/devTools/apache-tomcat-9.0.58/bin/shutdown.sh +sudo sh shutdown.sh +``` diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/index.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/index.md" new file mode 100644 index 0000000..42a610f --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/index.md" @@ -0,0 +1 @@ +## 框架 \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/kafka\351\205\215\347\275\256\345\261\236\346\200\247\350\257\264\346\230\216.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/kafka\351\205\215\347\275\256\345\261\236\346\200\247\350\257\264\346\230\216.md" new file mode 100644 index 0000000..ea05229 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/kafka\351\205\215\347\275\256\345\261\236\346\200\247\350\257\264\346\230\216.md" @@ -0,0 +1,144 @@ +--- +title: kafka配置属性说明 +date: 2024-03-30 21:51:00 +updated: 2024-03-30 21:51:00 +categories: +- 学习 +tags: +- kafka +keywords: +- kafka +description: kafka配置属性说明 +cover: https://media.licdn.com/dms/image/D4D12AQE3Xxg0OpF06g/article-cover_image-shrink_720_1280/0/1690687577573?e=2147483647&v=beta&t=di9wRe_GO5fHxP-yUMojJrbCVDPJADRVQjcetN5awkE +top_img: https://contabo.com/blog/wp-content/uploads/2023/12/image-6.jpeg +--- + +## 生产者配置 + +| NAME | DESCRIPTION | TYPE | DEFAULT | VALID VALUES | IMPORTANCE | +| ---------------------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | ------------------ | ---------- | +| bootstrap.servers | host/port列表,用于初始化建立和Kafka集群的连接。列表格式为host1:port1,host2:port2,....,无需添加所有的集群地址,kafka会根据提供的地址发现其他的地址(你可以多提供几个,以防提供的服务器关闭) | list | | | high | +| key.serializer | 实现 org.apache.kafka.common.serialization.Serializer 接口的 key 的 Serializer 类。 | class | | | high | +| value.serializer | 实现 org.apache.kafka.common.serialization.Serializer 接口的value 的 Serializer 类。 | class | | | high | +| acks | 生产者需要leader确认请求完成之前接收的应答数。此配置控制了发送消息的耐用性,支持以下配置: | string | 1 | [all, -1, 0, 1] | high | +| | acks=0 如果设置为0,那么生产者将不等待任何消息确认。消息将立刻添加到socket缓冲区并考虑发送。在这种情况下不能保障消息被服务器接收到。并且重试机制不会生效(因为客户端不知道故障了没有)。每个消息返回的offset始终设置为-1。 | | | | | +| | acks=1,这意味着leader写入消息到本地日志就立即响应,而不等待所有follower应答。在这种情况下,如果响应消息之后但follower还未复制之前leader立即故障,那么消息将会丢失。 | | | | | +| | acks=all 这意味着leader将等待所有副本同步后应答消息。此配置保障消息不会丢失(只要至少有一个同步的副本或者)。这是最强壮的可用性保障。等价于acks=-1。 | | | | | +| buffer.memory | 生产者用来缓存等待发送到服务器的消息的内存总字节数。如果消息发送比可传递到服务器的快,生产者将阻塞max.block.ms之后,抛出异常。 | long | 33554432 | [0,...] | high | +| | 此设置应该大致的对应生产者将要使用的总内存,但不是硬约束,因为生产者所使用的所有内存都用于缓冲。一些额外的内存将用于压缩(如果启动压缩),以及用于保持发送中的请求。 | | | | | +| compression.type | 数据压缩的类型。默认为空(就是不压缩)。有效的值有 none,gzip,snappy, 或 lz4。压缩全部的数据批,因此批的效果也将影响压缩的比率(更多的批次意味着更好的压缩)。 | string | none | | high | +| retries | 设置一个比零大的值,客户端如果发送失败则会重新发送。注意,这个重试功能和客户端在接到错误之后重新发送没什么不同。如果max.in.flight.requests.per.connection没有设置为1,有可能改变消息发送的顺序,因为如果2个批次发送到一个分区中,并第一个失败了并重试,但是第二个成功了,那么第二个批次将超过第一个。 | int | 0 | [0,...,2147483647] | high | +| ssl.key.password | 密钥仓库文件中的私钥的密码。 | password | null | | high | +| ssl.keystore.location | 密钥仓库文件的位置。可用于客户端的双向认证。 | string | null | | high | +| ssl.keystore.password | 密钥仓库文件的仓库密码。只有配置了ssl.keystore.location时才需要。 | password | null | | high | +| ssl.truststore.location | 信任仓库的位置 | string | null | | high | +| ssl.truststore.password | 信任仓库文件的密码 | password | null | | high | +| batch.size | 当多个消息要发送到相同分区的时,生产者尝试将消息批量打包在一起,以减少请求交互。这样有助于客户端和服务端的性能提升。该配置的默认批次大小(以字节为单位): | int | 16384 | [0,...] | medium | +| | 不会打包大于此配置大小的消息。 | | | | | +| | 发送到broker的请求将包含多个批次,每个分区一个,用于发送数据。 | | | | | +| | 较小的批次大小有可能降低吞吐量(批次大小为0则完全禁用批处理)。一个非常大的批次大小可能更浪费内存。因为我们会预先分配这个资源。 | | | | | +| client.id | 当发出请求时传递给服务器的id字符串。这样做的目的是允许服务器请求记录记录这个【逻辑应用名】,这样能够追踪请求的源,而不仅仅只是ip/prot。 | string | "" | | medium | +| connections.max.idle.ms | 多少毫秒之后关闭闲置的连接。 | long | 540000 | | medium | +| linger.ms | 生产者组将发送的消息组合成单个批量请求。正常情况下,只有消息到达的速度比发送速度快的情况下才会出现。但是,在某些情况下,即使在适度的负载下,客户端也可能希望减少请求数量。此设置通过添加少量人为延迟来实现。- 也就是说,不是立即发出一个消息,生产者将等待一个给定的延迟,以便和其他的消息可以组合成一个批次。这类似于Nagle在TCP中的算法。此设置给出批量延迟的上限:一旦我们达到分区的batch.size值的记录,将立即发送,不管这个设置如何,但是,如果比这个小,我们将在指定的“linger”时间内等待更多的消息加入。此设置默认为0(即无延迟)。假设,设置 linger.ms=5,将达到减少发送的请求数量的效果,但对于在没有负载情况,将增加5ms的延迟。 | long | 0 | [0,...] | medium | +| max.block.ms | 该配置控制 KafkaProducer.send() 和 KafkaProducer.partitionsFor() 将阻塞多长时间。此外这些方法被阻止,也可能是因为缓冲区已满或元数据不可用。在用户提供的序列化程序或分区器中的锁定不会计入此超时。 | long | 60000 | [0,...] | medium | +| max.request.size | 请求的最大大小(以字节为单位)。此设置将限制生产者的单个请求中发送的消息批次数,以避免发送过大的请求。这也是最大消息批量大小的上限。请注意,服务器拥有自己的批量大小,可能与此不同。 | int | 1048576 | [0,...] | medium | +| partitioner.class | 实现Partitioner接口的的Partitioner类。 | class | org.apache.kafka.clients.producer.internals.DefaultPartitioner | | medium | +| receive.buffer.bytes | 读取数据时使用的TCP接收缓冲区(SO_RCVBUF)的大小。如果值为-1,则将使用OS默认值。 | int | 32768 | [-1,...] | medium | +| request.timeout.ms | 该配置控制客户端等待请求响应的最长时间。如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽,则该请求将失败。 这应该大于replica.lag.time.max.ms,以减少由于不必要的生产者重试引起的消息重复的可能性。 | int | 30000 | [0,...] | medium | +| sasl.jaas.config | JAAS配置文件使用的格式的SASL连接的JAAS登录上下文参数。这里描述JAAS配置文件格式。该值的格式为:'(=)*;' | password | null | | medium | +| sasl.kerberos.service.name | Kafka运行的Kerberos主体名称。可以在Kafka的JAAS配置或Kafka的配置中定义。 | string | null | | medium | +| sasl.mechanism | SASL机制用于客户端连接。这是安全提供者可用与任何机制。GSSAPI是默认机制。 | string | GSSAPI | | medium | +| security.protocol | 用于与broker通讯的协议。 有效值为:PLAINTEXT,SSL,SASL_PLAINTEXT,SASL_SSL。 | string | PLAINTEXT | | medium | +| send.buffer.bytes | 发送数据时,用于TCP发送缓存(SO_SNDBUF)的大小。如果值为 -1,将默认使用系统的。 | int | 131072 | [-1,...] | medium | +| ssl.enabled.protocols | 启用SSL连接的协议列表。 | list | TLSv1.2,TLSv1.1,TLSv1 | | medium | +| ssl.keystore.type | 密钥存储文件的文件格式。对于客户端是可选的。 | string | JKS | | medium | +| ssl.protocol | 最近的JVM中允许的值是TLS,TLSv1.1和TLSv1.2。 较旧的JVM可能支持SSL,SSLv2和SSLv3,但由于已知的安全漏洞,不建议使用SSL。 | string | TLS | | medium | +| ssl.provider | 用于SSL连接的安全提供程序的名称。默认值是JVM的默认安全提供程序。 | string | null | | medium | +| ssl.truststore.type | 信任仓库文件的文件格式。 | string | JKS | | medium | +| enable.idempotence | 当设置为‘true’,生产者将确保每个消息正好一次复制写入到stream。如果‘false’,由于broker故障,生产者重试。即,可以在流中写入重试的消息。此设置默认是‘false’。请注意,启用幂等式需要将max.in.flight.requests.per.connection设置为1,重试次数不能为零。另外acks必须设置为“全部”。如果这些值保持默认值,我们将覆盖默认值。 如果这些值设置为与幂等生成器不兼容的值,则将抛出一个ConfigException异常。如果这些值设置为与幂等生成器不兼容的值,则将抛出一个ConfigException异常。 | boolean | FALSE | | low | +| interceptor.classes | 实现ProducerInterceptor接口,你可以在生产者发布到Kafka群集之前拦截(也可变更)生产者收到的消息。默认情况下没有拦截器。 | list | null | | low | +| max.in.flight.requests.per.connection | 阻塞之前,客户端单个连接上发送的未应答请求的最大数量。注意,如果此设置设置大于1且发送失败,则会由于重试(如果启用了重试)会导致消息重新排序的风险。 | int | 5 | [1,...] | low | +| metadata.max.age.ms | 在一段时间段之后(以毫秒为单位),强制更新元数据,即使我们没有看到任何分区leader的变化,也会主动去发现新的broker或分区。 | long | 300000 | [0,...] | low | +| metric.reporters | 用作metrics reporters(指标记录员)的类的列表。实现MetricReporter接口,将受到新增加的度量标准创建类插入的通知。 JmxReporter始终包含在注册JMX统计信息中。 | list | "" | | low | +| metrics.num.samples | 维护用于计算度量的样例数量。 | int | 2 | [1,...] | low | +| metrics.recording.level | 指标的最高记录级别。 | string | INFO | [INFO, DEBUG] | low | +| metrics.sample.window.ms | 度量样例计算上 | long | 30000 | [0,...] | low | +| reconnect.backoff.max.ms | 重新连接到重复无法连接的代理程序时等待的最大时间(毫秒)。 如果提供,每个主机的回退将会连续增加,直到达到最大值。 计算后退增加后,增加20%的随机抖动以避免连接风暴。 | long | 1000 | [0,...] | low | +| reconnect.backoff.ms | 尝试重新连接到给定主机之前等待的基本时间量。这避免了在循环中高频率的重复连接到主机。这种回退适应于客户端对broker的所有连接尝试。 | long | 50 | [0,...] | low | +| retry.backoff.ms | 尝试重试指定topic分区的失败请求之前等待的时间。这样可以避免在某些故障情况下高频次的重复发送请求。 | long | 100 | [0,...] | low | +| sasl.kerberos.kinit.cmd | Kerberos kinit 命令路径。 | string | /usr/bin/kinit | | low | +| sasl.kerberos.min.time.before.relogin | Login线程刷新尝试之间的休眠时间。 | long | 60000 | | low | +| sasl.kerberos.ticket.renew.jitter | 添加更新时间的随机抖动百分比。 | double | 0.05 | | low | +| sasl.kerberos.ticket.renew.window.factor | 登录线程将睡眠,直到从上次刷新ticket到期时间的指定窗口因子为止,此时将尝试续订ticket。 | double | 0.8 | | low | +| ssl.cipher.suites | 密码套件列表。这是使用TLS或SSL网络协议来协商用于网络连接的安全设置的认证,加密,MAC和密钥交换算法的命名组合。默认情况下,支持所有可用的密码套件。 | list | null | | low | +| ssl.endpoint.identification.algorithm | 使用服务器证书验证服务器主机名的端点识别算法。 | string | null | | low | +| ssl.keymanager.algorithm | 用于SSL连接的密钥管理因子算法。默认值是为Java虚拟机配置的密钥管理器工厂算法。 | string | SunX509 | | low | +| ssl.secure.random.implementation | 用于SSL加密操作的SecureRandom PRNG实现。 | string | null | | low | +| ssl.trustmanager.algorithm | 用于SSL连接的信任管理因子算法。默认值是JAVA虚拟机配置的信任管理工厂算法。 | string | PKIX | | low | +| transaction.timeout.ms | 生产者在主动中止正在进行的交易之前,交易协调器等待事务状态更新的最大时间(以ms为单位)。如果此值大于broker中的max.transaction.timeout.ms设置,则请求将失败,并报“InvalidTransactionTimeout”错误。 | int | 60000 | | low | +| transactional.id | 用于事务传递的TransactionalId。这样可以跨多个生产者会话的可靠性语义,因为它允许客户端保证在开始任何新事务之前使用相同的TransactionalId的事务已经完成。如果没有提供TransactionalId,则生产者被限制为幂等传递。请注意,如果配置了TransactionalId,则必须启用enable.idempotence。 默认值为空,这意味着无法使用事务。 | string | null | non-empty string | low | + +## 消费者配置 + +| NAME | DESCRIPTION | TYPE | DEFAULT | VALID VALUES | IMPORTANCE | +| ------------------------------------------------------ | ------------------------------------------------------------ | -------- | ----------------------- | ------------------------ | ---------- | +| bootstrap.servers | host/port,用于和kafka集群建立初始化连接。因为这些服务器地址仅用于初始化连接,并通过现有配置的来发现全部的kafka集群成员(集群随时会变化),所以此列表不需要包含完整的集群地址(但尽量多配置几个,以防止配置的服务器宕机)。 | list | | | high | +| key.deserializer | key的解析序列化接口实现类(Deserializer)。 | class | | | high | +| value.deserializer | value的解析序列化接口实现类(Deserializer) | class | | | high | +| fetch.min.bytes | 服务器哦拉取请求返回的最小数据量,如果数据不足,请求将等待数据积累。默认设置为1字节,表示只要单个字节的数据可用或者读取等待请求超时,就会应答读取请求。将此值设置的越大将导致服务器等待数据累积的越长,这可能以一些额外延迟为代价提高服务器吞吐量。 | int | 1 | [0,...] | high | +| group.id | 此消费者所属消费者组的唯一标识。如果消费者用于订阅或offset管理策略的组管理功能,则此属性是必须的。 | string | "" | | high | +| heartbeat.interval.ms | 当使用Kafka的分组管理功能时,心跳到消费者协调器之间的预计时间。心跳用于确保消费者的会话保持活动状态,并当有新消费者加入或离开组时方便重新平衡。该值必须必比session.timeout.ms小,通常不高于1/3。它可以调整的更低,以控制正常重新平衡的预期时间。 | int | 3000 | | high | +| max.partition.fetch.bytes | 服务器将返回每个分区的最大数据量。如果拉取的第一个非空分区中第一个消息大于此限制,则仍然会返回消息,以确保消费者可以正常的工作。broker接受的最大消息大小通过message.max.bytes(broker config)或max.message.bytes (topic config)定义。参阅fetch.max.bytes以限制消费者请求大小。 | int | 1048576 | [0,...] | high | +| session.timeout.ms | 用于发现消费者故障的超时时间。消费者周期性的发送心跳到broker,表示其还活着。如果会话超时期满之前没有收到心跳,那么broker将从分组中移除消费者,并启动重新平衡。请注意,该值必须在broker配置的group.min.session.timeout.ms和group.max.session.timeout.ms允许的范围内。 | int | 10000 | | high | +| ssl.key.password | 密钥存储文件中的私钥的密码。 客户端可选 | password | null | | high | +| ssl.keystore.location | 密钥存储文件的位置, 这对于客户端是可选的,并且可以用于客户端的双向认证。 | string | null | | high | +| ssl.keystore.password | 密钥仓库文件的仓库密码。客户端可选,只有ssl.keystore.location配置了才需要。 | password | null | | high | +| ssl.truststore.location | 信任仓库文件的位置 | string | null | | high | +| ssl.truststore.password | 信任仓库文件的密码 | password | null | | high | +| auto.offset.reset | 当Kafka中没有初始offset或如果当前的offset不存在时(例如,该数据被删除了),该怎么办。 | string | latest | [latest, earliest, none] | medium | +| 最早:自动将偏移重置为最早的偏移 | | | | | | +| 最新:自动将偏移重置为最新偏移 | | | | | | +| none:如果消费者组找到之前的offset,则向消费者抛出异常 | | | | | | +| 其他:抛出异常给消费者。 | | | | | | +| connections.max.idle.ms | 指定在多少毫秒之后关闭闲置的连接 | long | 540000 | | medium | +| enable.auto.commit | 如果为true,消费者的offset将在后台周期性的提交 | boolean | TRUE | | medium | +| exclude.internal.topics | 内部topic的记录(如偏移量)是否应向消费者公开。如果设置为true,则从内部topic接受记录的唯一方法是订阅它。 | boolean | TRUE | | medium | +| fetch.max.bytes | 服务器为拉取请求返回的最大数据值。这不是绝对的最大值,如果在第一次非空分区拉取的第一条消息大于该值,该消息将仍然返回,以确保消费者继续工作。接收的最大消息大小通过message.max.bytes (broker config) 或 max.message.bytes (topic config)定义。注意,消费者是并行执行多个提取的。 | int | 52428800 | [0,...] | medium | +| max.poll.interval.ms | 使用消费者组管理时poll()调用之间的最大延迟。消费者在获取更多记录之前可以空闲的时间量的上限。如果此超时时间期满之前poll()没有调用,则消费者被视为失败,并且分组将重新平衡,以便将分区重新分配给别的成员。 | int | 300000 | [1,...] | medium | +| max.poll.records | 在单次调用poll()中返回的最大记录数。 | int | 500 | [1,...] | medium | +| partition.assignment.strategy | 当使用组管理时,客户端将使用分区分配策略的类名来分配消费者实例之间的分区所有权 | list | class org.apache.kafka | | medium | +| .clients.consumer | | | | | | +| .RangeAssignor | | | | | | +| receive.buffer.bytes | 读取数据时使用的TCP接收缓冲区(SO_RCVBUF)的大小。 如果值为-1,则将使用OS默认值。 | int | 65536 | [-1,...] | medium | +| request.timeout.ms | 配置控制客户端等待请求响应的最长时间。 如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽则客户端将重新发送请求。 | int | 305000 | [0,...] | medium | +| sasl.jaas.config | JAAS配置文件中SASL连接登录上下文参数。 这里描述JAAS配置文件格式。 该值的格式为: '(=)*;' | password | null | | medium | +| sasl.kerberos.service.name | Kafka运行Kerberos principal名。可以在Kafka的JAAS配置文件或在Kafka的配置文件中定义。 | string | null | | medium | +| sasl.mechanism | 用于客户端连接的SASL机制。安全提供者可用的机制。GSSAPI是默认机制。 | string | GSSAPI | | medium | +| security.protocol | 用于与broker通讯的协议。 有效值为:PLAINTEXT,SSL,SASL_PLAINTEXT,SASL_SSL。 | string | PLAINTEXT | | medium | +| send.buffer.bytes | 发送数据时要使用的TCP发送缓冲区(SO_SNDBUF)的大小。 如果值为-1,则将使用OS默认值。 | int | 131072 | [-1,...] | medium | +| ssl.enabled.protocols | 启用SSL连接的协议列表。 | list | TLSv1.2,TLSv1.1,TLSv1 | | medium | +| ssl.keystore.type | key仓库文件的文件格式,客户端可选。 | string | JKS | | medium | +| ssl.protocol | 用于生成SSLContext的SSL协议。 默认设置是TLS,这对大多数情况都是适用的。 最新的JVM中的允许值为TLS,TLSv1.1和TLSv1.2。 较旧的JVM可能支持SSL,SSLv2和SSLv3,但由于已知的安全漏洞,不建议使用SSL。 | string | TLS | | medium | +| ssl.provider | 用于SSL连接的安全提供程序的名称。 默认值是JVM的默认安全提供程序。 | string | null | | medium | +| ssl.truststore.type | 信任存储文件的文件格式。 | string | JKS | | medium | +| auto.commit.interval.ms | 如果enable.auto.commit设置为true,则消费者偏移量自动提交给Kafka的频率(以毫秒为单位)。 | int | 5000 | [0,...] | low | +| check.crcs | 自动检查CRC32记录的消耗。 这样可以确保消息发生时不会在线或磁盘损坏。 此检查增加了一些开销,因此在寻求极致性能的情况下可能会被禁用。 | boolean | TRUE | | low | +| client.id | 在发出请求时传递给服务器的id字符串。 这样做的目的是通过允许将逻辑应用程序名称包含在服务器端请求日志记录中,来跟踪ip/port的请求源。 | string | "" | | low | +| fetch.max.wait.ms | 如果没有足够的数据满足fetch.min.bytes,服务器将在接收到提取请求之前阻止的最大时间。 | int | 500 | [0,...] | low | +| interceptor.classes | 用作拦截器的类的列表。 你可实现ConsumerInterceptor接口以允许拦截(也可能变化)消费者接收的记录。 默认情况下,没有拦截器。 | list | null | | low | +| metadata.max.age.ms | 在一定时间段之后(以毫秒为单位的),强制更新元数据,即使没有任何分区领导变化,任何新的broker或分区。 | long | 300000 | [0,...] | low | +| metric.reporters | 用作度量记录员类的列表。实现MetricReporter接口以允许插入通知新的度量创建的类。JmxReporter始终包含在注册JMX统计信息中。 | list | "" | | low | +| metrics.num.samples | 保持的样本数以计算度量。 | int | 2 | [1,...] | low | +| metrics.recording.level | 最高的记录级别。 | string | INFO | [INFO, DEBUG] | low | +| metrics.sample.window.ms | The window of time a metrics sample is computed over. | long | 30000 | [0,...] | low | +| reconnect.backoff.ms | 尝试重新连接指定主机之前等待的时间,避免频繁的连接主机,这种机制适用于消费者向broker发送的所有请求。 | long | 50 | [0,...] | low | +| retry.backoff.ms | 尝试重新发送失败的请求到指定topic分区之前的等待时间。避免在某些故障情况下,频繁的重复发送。 | long | 100 | [0,...] | low | +| sasl.kerberos.kinit.cmd Kerberos | kinit命令路径。 | string | /usr/bin/kinit | | low | +| sasl.kerberos.min.time.before.relogin | 尝试/恢复之间的登录线程的休眠时间。 | long | 60000 | | low | +| sasl.kerberos.ticket.renew.jitter | 添加到更新时间的随机抖动百分比。 | double | 0.05 | | low | +| sasl.kerberos.ticket.renew.window.factor | 登录线程将休眠,直到从上次刷新到ticket的指定的时间窗口因子到期,此时将尝试续订ticket。 | double | 0.8 | | low | +| ssl.cipher.suites | 密码套件列表,用于TLS或SSL网络协议的安全设置,认证,加密,MAC和密钥交换算法的明明组合。默认情况下,支持所有可用的密码套件。 | list | null | | low | +| ssl.endpoint.identification.algorithm | 使用服务器证书验证服务器主机名的端点识别算法。 | string | null | | low | +| ssl.keymanager.algorithm | 密钥管理器工厂用于SSL连接的算法。 默认值是为Java虚拟机配置的密钥管理器工厂算法。 | string | SunX509 | | low | +| ssl.secure.random.implementation | 用于SSL加密操作的SecureRandom PRNG实现。 | string | null | | low | +| ssl.trustmanager.algorithm | 信任管理器工厂用于SSL连接的算法。 默认值是为Java虚拟机配置的信任管理器工厂算法。 | string | PKIX | | low | \ No newline at end of file diff --git "a/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/thymeleaf\347\232\204th-href\345\270\246\345\217\202\346\225\260\350\275\254\350\267\263.md" "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/thymeleaf\347\232\204th-href\345\270\246\345\217\202\346\225\260\350\275\254\350\267\263.md" new file mode 100644 index 0000000..856ff31 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\241\206\346\236\266/thymeleaf\347\232\204th-href\345\270\246\345\217\202\346\225\260\350\275\254\350\267\263.md" @@ -0,0 +1,35 @@ +--- +title: thymeleaf的th:href带参数转跳 +date: 2022-03-08 23:35:15 +updated: +categories: +- 学习 +tags: +- SpringBoot +- thymelef +keywords: +- SpringBoot +- thymelef +description: th:href携带参数转跳的几种情况 +cover: https://i.morioh.com/210619/24860a44.webp +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/thylemef.png +--- + +**带一个参数**: + +```html + +``` + +**带两个参数:** + +```html + +``` + +**传统URL传递多参数使用?和&拼接** + +```html + +``` + diff --git "a/docs/\345\274\200\345\217\221/\351\230\277\351\207\214\344\272\221OSS && \345\206\205\345\256\271\345\256\211\345\205\250 Java\345\256\236\347\216\260\345\217\202\350\200\203\344\273\243\347\240\201.md" "b/docs/\345\274\200\345\217\221/\351\230\277\351\207\214\344\272\221OSS && \345\206\205\345\256\271\345\256\211\345\205\250 Java\345\256\236\347\216\260\345\217\202\350\200\203\344\273\243\347\240\201.md" new file mode 100644 index 0000000..f4caf54 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\351\230\277\351\207\214\344\272\221OSS && \345\206\205\345\256\271\345\256\211\345\205\250 Java\345\256\236\347\216\260\345\217\202\350\200\203\344\273\243\347\240\201.md" @@ -0,0 +1,539 @@ +--- +title: 阿里云OSS && 内容安全 Java实现参考代码 +date: 2024-04-01 22:20:00 +updated: 2024-04-01 22:20:00 +categories: +- 学习 +tags: +- 阿里云 +- OSS +- 内容安全 +keywords: +- 阿里云 +- OSS +- 内容安全 +description: 阿里云OSS && 内容安全 Java实现参考代码 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212051708.jpeg +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212052354.jfif +--- + +## 内容安全 + +### 引入maven依赖 + +```xml + + com.aliyun + aliyun-java-sdk-core + + + + com.aliyun + aliyun-java-sdk-green + + + + + com.aliyun + green20220302 + 1.0.3 + + + 以下是余下全文 +``` + +## 写作 + +``` +hexo new page +hexo new post <title> +``` + +| 变量 | 描述 | +| -------- | ------------- | +| :title | 标题 | +| :year | 建立的年份(4 位数) | +| :month | 建立的月份(2 位数) | +| :i_month | 建立的月份(去掉开头的零) | +| :day | 建立的日期(2 位数) | +| :i_day | 建立的日期(去掉开头的零) | diff --git "a/docs/\350\275\257\344\273\266/JetBrains\345\205\250\345\256\266\346\241\266\347\240\264\350\247\243.md" "b/docs/\350\275\257\344\273\266/JetBrains\345\205\250\345\256\266\346\241\266\347\240\264\350\247\243.md" new file mode 100644 index 0000000..cfcef27 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/JetBrains\345\205\250\345\256\266\346\241\266\347\240\264\350\247\243.md" @@ -0,0 +1,44 @@ +--- +title: JetBrains全家桶破解 +date: 2022-08-07 17:00:15 +updated: +categories: +- 软件 +tags: +- JetBrains +- Idea +- 破解 +keywords: +- JetBrains +- Idea +- 破解 +description: Mac上破解Jetbrains全家桶的办法 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212216079.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212216107.png +--- + + + +参考网址: + +> [JetBrains全系列软件激活教程激活码以及JetBrains系列软件汉化包 (macwk.com)](https://www.macwk.com/article/jetbrains-crack) + +无限激活方式: + +1. [JetBrains官网](https://www.jetbrains.com/) 下载安装你需要的 IDE,如果下载慢可以在 <a href="[MacWk - 精品mac软件下载](https://www.macwk.com/)">MacWk</a> 搜索 jetbrains。 + +2. 下载 [Jetbrains.zip](https://macwk.lanzouo.com/i8eElxh573a),下载后解压,得到 fineagent.jar,将该文件复制到 `/Users/你的用户名/` 文件夹下 + +3. 打开访达,点击左侧的 `应用程序` 找到 `WebStorm`,在 WebStorm 图标上右键,点击 `显示包内容` + +4. 进入 `Contents` 目录,再进入 `bin` 目录,使用文本编辑器打开 `webstorm.vmoptions` 文件 + +5. 在最后面添加 `-javaagent:/Users/你的用户名/fineagent.jar`,记得修改一下你的用户名。 + +6. 运行 WebStorm, 选择 `Activate WebStorm`,再点击 `Activation Code` + +7. 复制下面的的激活码粘贴到激活窗口的输入框中,点击 `Activate`。可以用到 2099 年! + +5AYV1D1RE5-eyJsaWNlbnNlSWQiOiI1QVlWMUQxUkU1IiwibGljZW5zZWVOYW1lIjoiaHR0cHM6Ly93d3cuaml3ZWljaGVuZ3podS5jb20iLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJJSSIsImZhbGxiYWNrRGF0ZSI6IjIwOTktMTItMzEiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEifSx7ImNvZGUiOiJBQyIsImZhbGxiYWNrRGF0ZSI6IjIwOTktMTItMzEiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEifSx7ImNvZGUiOiJEUE4iLCJmYWxsYmFja0RhdGUiOiIyMDk5LTEyLTMxIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIn0seyJjb2RlIjoiUFMiLCJmYWxsYmFja0RhdGUiOiIyMDk5LTEyLTMxIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIn0seyJjb2RlIjoiR08iLCJmYWxsYmFja0RhdGUiOiIyMDk5LTEyLTMxIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIn0seyJjb2RlIjoiRE0iLCJmYWxsYmFja0RhdGUiOiIyMDk5LTEyLTMxIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIn0seyJjb2RlIjoiQ0wiLCJmYWxsYmFja0RhdGUiOiIyMDk5LTEyLTMxIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIn0seyJjb2RlIjoiUlMwIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IlJDIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IlJEIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IlBDIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IlJNIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IldTIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IkRCIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IkRDIiwiZmFsbGJhY2tEYXRlIjoiMjA5OS0xMi0zMSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSJ9LHsiY29kZSI6IlJTVSIsImZhbGxiYWNrRGF0ZSI6IjIwOTktMTItMzEiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEifV0sImhhc2giOiIxMjc5Njg3Ny8wIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-HNPogO0kWkHCVMnsjmBXUqQt87UPHqdkYqZGveSJtu8hb2V2Yq7gHsHenp4UuEd3jwEwC+YrUIf7U5yDA/56F5Sdn0RLUHZX5DHeQbJPbmYCBsDRT7m8rnmMFOSZn3vwNatvv1cooZbcGOk3Wwxx6bF7XcgaIrmXRcmZMZgv2PZehr0WS1HxNKe3X4nbGP3MwiSbg4ypmxNDrljmgv+Si9QDDwNLDffqeO0Lce0FqEJuMWmvBS42S0aeIYF8IS5bp4+LFKLJ8T7tF40OxKYDurBb9+9c43GZBscM/eLB8Jos66jNGFwgebFUlvhzJKVHZtuc/N8zGeEnTq6K0T/B8w==-MIIDTjCCAjagAwIBAgIBDTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMCAXDTE4MTEwMTEyMjk0NloYDzIwOTkwODA5MDIyNjA3WjAfMR0wGwYDVQQDDBRwcm9kMnktZnJvbS0yMDIwMTAxOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMK3eyr0+Oys/TwcQO+qYaXWGBmXcEP4fR0bHHzZd/4WNGltXhecM80OWthA38BQRYAJBCKz/dSkO2Kj1H2y+7KB5cIaOiJEyTESfTSgzQdot6laRBU8oxy9mmagI46M8zEEmplPybY4YJj4HOwZiBsMQEMxoTgMDLpuHX6uASoVhSj6koB55lOj4wEgsQBeAMWTAXmTl88ixE179J8aBUkBGpL8w/tZzl9BJXZNF15gPfkS58rw8cdPzXLS0Yym37A2/KKFhfHzJc5KhbaxqYzmkAfTMqPsIqCQ1lQUAqfiPn2gN2I1Z3/cQuEW27M55fXVr2DduQe5DWzYJs85L50CAwEAAaOBmTCBljAJBgNVHRMEAjAAMB0GA1UdDgQWBBQk2hEilvWFQcCTR+gxI0z0wIQC/zBIBgNVHSMEQTA/gBSjnrZIZ0ISNkG9beC5tKBSi5fxs6EcpBowGDEWMBQGA1UEAwwNSmV0UHJvZmlsZSBDQYIJANJssYOyg3nhMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAQEAsCQBjO5wttco/Z5cj/o4GBrku8UtBBBVFq4xsBanshTHm4deVxcTvta4aScV0TPKcaLqGqWx8A9v8XXO8dBbCuyXvWZteZ/C2Covg1xXiM99lz7VxqpjVmLdKanZn5u0gQSiYJdcfF+TdbmEIeSOnN/kLXNq2hXdJQK2zk2J25UZqu5EibRtTbdOzw6ZcfwJ8uOntXfsmAhnNICP3Wf/4wR/mwB0Ka4S+JA3IbF5MUmUZ/fjUaFarnin70us+Vxf/sZUi7u67wilvwVV0NAqDpthHUV0NRc4q+yOr2Dt/uCHdy4XRXLJfAv/z9/xBwNZZALNz3EtQL6IeIWWJByl3g== + + \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/CentOS7\345\256\211\350\243\205ohmyzsh.md" "b/docs/\350\275\257\344\273\266/Linux/CentOS7\345\256\211\350\243\205ohmyzsh.md" new file mode 100644 index 0000000..c11e70d --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/CentOS7\345\256\211\350\243\205ohmyzsh.md" @@ -0,0 +1,172 @@ +--- +title: CentOS7安装ohmyzsh +date: 2022-11-08 20:44:15 +updated: +categories: +- 软件 +tags: +- Linux +- ohmyzsh +- 终端美化 +- zsh +keywords: +- Linux +- ohmyzsh +- 终端美化 +- zsh +description: 美化你的终端,Z门! +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212210367.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212210587.png +--- + +> 前提:安装好**Git** + +## 1、安装zsh并更改默认终端 + +安装软件包 + +```shell +yum -y install zsh git +``` + +更改默认终端 + +```shell +chsh -s /bin/zsh +``` + +## 2、配置oh-my-zsh + +拉取oh-my-zsh + +```shell +git clone https://gitee.com/mirrors/oh-my-zsh.git ~/.oh-my-zsh +``` + +默认配置 + +```shell +cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc +``` + +## 3、安装高亮、自动补全插件 + +安装高亮插件:zsh-syntax-highlighting + +```shell +git clone https://gitee.com/dawnwords/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting +``` + +安装自动补全:zsh-autosuggestions + +```shell +git clone https://gitee.com/lhaisu/zsh-autosuggestions.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions + +``` + +安装autojump目录跳转 + +```shell +git clone https://gitee.com/gentlecp/autojump.git +cd autojump +./install.py +``` + +## 4、插件配置 + +```shell +vim ~/.zshrc +``` + +```shell +plugins=( + git + sudo + zsh-autosuggestions + zsh-syntax-highlighting + autojump +) +``` + +```shell +source ~/.zshrc +``` + +## 5、修改主题 + +```shell +vim ~/.zshrc +``` + +个人比较喜欢这套 + +```shell +ZSH_THEME="maran" +``` + +除了自带的两个主题外我个人还比较喜欢两个 + +分别是sobole和jovial + +- sobole + + ![74af970abbf731048fef10bb85c0b92b.png](https://img-blog.csdnimg.cn/img_convert/74af970abbf731048fef10bb85c0b92b.png) + +- jovial + + ![48ada5d75ea2044b132b85bc106b2ae3.png](https://img-blog.csdnimg.cn/img_convert/48ada5d75ea2044b132b85bc106b2ae3.png) + +![screenshot](https://i0.hdslb.com/bfs/album/d96c49f36aadd0c4a7709312c42c11dbff04e71e.png) + +sobole安装地址: + +> [sobolevn/dotfiles: dotfiles for the developer happiness: macos, zsh, brew, vscode, codespaces, python, node, elixir (github.com)](https://github.com/sobolevn/dotfiles) + +jovial安装地址: + +> [zthxxx/jovial: Jovial - A lovely zsh theme with responsive-design, it's pretty fast, keep simple but useful (github.com)](https://github.com/zthxxx/jovial) + +dracula-theme安装地址 + +> [Dark theme for Zsh and 266+ apps — Dracula (draculatheme.com)](https://draculatheme.com/zsh) + +```shell +source ~/.zshrc +``` + +## 6、其他 + +**zsh粘贴慢问题:一个字符一个字符粘贴。这是zsh的问题** + +解决:修改zsh配置:`vim ~/.zshrc`,增加如下代码: + +```shell +vim ~/.zshrc +``` + +``` +pasteinit() { + OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]} + zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`? +} + +pastefinish() { + zle -N self-insert $OLD_SELF_INSERT +} +zstyle :bracketed-paste-magic paste-init pasteinit +zstyle :bracketed-paste-magic paste-finish pastefinish +``` + +```shell +source ~/.zshrc +``` + +## LAST:效果展示 + +美化前: + +![image-20231108204645514](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20231108204645514.png) + +美化后: + +![image-20231108204754639](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20231108204754639.png) diff --git "a/docs/\350\275\257\344\273\266/Linux/Homebrew\345\270\270\347\224\250\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Linux/Homebrew\345\270\270\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..ab60a34 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Homebrew\345\270\270\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,35 @@ +--- +title: Homebrew常用命令 +date: 2022-02-08 12:37:15 +updated: +categories: +- 软件 +tags: +- Homebrew +keywords: +- Homebrew +description: Mac下最好的包管理工具 +cover: http://n.sinaimg.cn/sinakd202126s/506/w840h466/20210206/2eff-kirmaiu5118776.png +top_img: https://i.ytimg.com/vi/N-SDrN4G4lE/maxresdefault.jpg +--- + +### 安装: + +```shell +/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +``` + +### 卸载: + +```shell +/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" +``` + +### 常用命令: + +安装软件:`brew install xxx` +卸载软件:`brew uninstall xxx` +搜索软件:`brew search xxx` +更新软件:`brew upgrade xxx` +查看列表:`brew list` +更新brew:`brew update` diff --git "a/docs/\350\275\257\344\273\266/Linux/Linux\345\270\270\347\224\250\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Linux/Linux\345\270\270\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..62b821c --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Linux\345\270\270\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,175 @@ +--- +title: Linux常用命令 +date: 2023-04-06 18:05:15 +updated: +categories: +- 学习 +tags: +- Linux +keywords: +- Linux +description: 实验室服务器常用的Linux常用命令 +cover: https://bloximages.newyork1.vip.townnews.com/redandblack.com/content/tncms/assets/v3/editorial/4/59/45940eb2-5403-11e9-a843-db0e4491cc90/5ca13d8453042.image.jpg +top_img: https://blog.desdelinux.net/wp-content/uploads/2021/10/Linux-Desktop-1.jpg +top: 990 +--- + +# Linux初级命令 + +~~太低级的我也不想说了~~ + +### 复制 + +```shell +cp file file_copy +cp -a folder/ folder_copy/ +``` + +### 移动/重命名 + +```shell +mv file /usr/local/file_rename +mv file1 file2 /usr/local +mv folder/ /usr/local/lib/folder_rename/ +``` + +### 删除 + +```shell +rm file +rmdir folder/ +rm -rf folder/ +``` + +### *链接 + +#### 软链接 + +- 软链接:在Mac中被称为“替身”,在Windows被称为“快捷方式”,名称只要和源文件的“名称+后缀“不同就行 +- 硬链接:MacOS和Linux独有,属于源文件的分身,源文件删除不影响硬链接,硬链接修改源文件也会跟着改 +- 创建文件软链接(软链接即为文件的替身,删除源文件即删除了文件,替身将失效。软链接的名称可以随便取)(MacOS下必须写绝对路径,且不能在同目录下生成软链接) + +```shell +ln -s file file_lnk +ln -s folder/ folder_lnk/ +``` + +#### 硬链接 + +- 硬链接即为指针,硬链接的后缀必须和源文件一致 + +- MacOS下可以使用相对路径,且可以在目录下生成硬链接 + +```shell +ln Hello.py Hello_lnk.py +``` + + + +# Linux高级命令 + +### 获取指定目录下所有文件夹名 + +```shell +ls -l 文件夹路径 |awk '/^d/ {print $NF}' +``` + +### 杀死指定端口 + +```shell +kill -9 `lsof -t -i:端口号` +``` + + + +# zip解压缩命令 + +### 压缩/解压 + +`zip -r 压缩包包名.zip ./*`:将当前目录下的文件压缩成压缩包,*表示全部压缩,-r表示递归压缩子目录下所有文件 + +- -o:不提示,覆盖同名文件夹 + +- -d: 指定某个解压目录 + +`unzip -o -d /home/hzx 待解压.zip`:把压缩包解压到指定目录 + +### 添加/删除包中的文件 + +`zip -m 压缩包.zip ./待添加文件`:添加文件到压缩包中 + +`zip -d 压缩包.zip 待删除文件`:删除压缩包中文件 + +# tar解压缩命令 + +## 参数 + +- -c : 建立压缩文件 +- -x :解压压缩文件 +- -t :查看压缩文件内容 +- -v : 压缩过程中显示文件 +- -f :使用压缩名,注意一般放在参数最后,紧跟压缩名 +- -z :用gzip压缩,以tar.gz结尾,压缩速度快 +- -j :用bzip2压缩,以tar.bz2结尾,压缩率高 + +### 压缩 + +`tar -cvf xxx.tar /data` : 仅打包 +`tar -zcvf xxx.tar /data` : 打包,gzip压缩 +`tar -jcvf xxx.tar /data` : 打包,bzip2压缩 + +### 解压 + +`tar -xvf xxx.tar` : 解压 +`tar -zxvf xxx.tar` : 解压gzip压缩文件 +`tar -jxvf xxx.tar` : 解压bzip2压缩文件 +`tar -zxvf xxx.tar.gz etc/passwd` :解压到指定目录 + +# 读取文件夹大小 + +```shell +sudo du -h --max-depth=1 home/ +``` + +读取home文件下的大小 + +![image-20230609140738378](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20230609140738378.png) + +# 查看硬盘占用情况 + +## 查看硬盘使用情况 + +```shell +df -h . +``` + +![image-20230626190856450](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20230626190856450.png) + +## 查看目录下一级文件夹的大小 + +```shell +sudo du -h --max-depth=0 * +``` + +深度就是--max-depth,0不展示子文件夹 + +![image-20230626191226972](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20230626191226972.png) + +然后查看某个文件夹下各文件的大小 + +```shell +du -h -max-depth=1 /home/hzx +``` + +> 更多关于磁盘信息的命令:[linux查询磁盘使用情况_linux查看磁盘使用情况_沐已成风的博客-CSDN博客](https://blog.csdn.net/weixin_42854904/article/details/124944311) + + + +# 清理显卡显存占用 + +```shell +sudo fuser -v /dev/nvidia* |awk '{for(i=1;i<=NF;i++)print "kill -9 " $i;}' | sudo sh +``` + + + diff --git "a/docs/\350\275\257\344\273\266/Linux/Mac\344\270\212PD17\350\231\232\346\213\237\346\234\272\347\273\210\347\253\257\345\220\257\345\212\250\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Linux/Mac\344\270\212PD17\350\231\232\346\213\237\346\234\272\347\273\210\347\253\257\345\220\257\345\212\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..078118b --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Mac\344\270\212PD17\350\231\232\346\213\237\346\234\272\347\273\210\347\253\257\345\220\257\345\212\250\345\221\275\344\273\244.md" @@ -0,0 +1,27 @@ +--- +title: Mac上PD17虚拟机终端启动命令 +date: 2022-08-07 16:01:15 +updated: +categories: +- 软件 +tags: +- PD虚拟机 +- Mac +keywords: +- PD虚拟机 +- Mac +description: Mac上跳过PD检测启动虚拟机的方法 +cover: https://www.parallels.com/fileadmin/res/img/pd/2020/overview/heroImg_xs.png +top_img: https://www.parallels.cn/fileadmin/res/img/pdb/2021/overview/hero-img_xs_upd.png +--- + + + +**pd17虚拟机启动命令** +prlctl start ‘Windows 11’ +prlctl start ‘Ubuntu 20.04.3’ + +快捷工具 +PD_START V2.0(支持PD17.1.1) +https://wwi.lanzouo.com/b0114r70b +密码:Cc \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/Mac\345\210\240\351\231\244OBS\347\232\204\350\231\232\346\213\237\346\221\204\345\203\217\345\244\264.md" "b/docs/\350\275\257\344\273\266/Linux/Mac\345\210\240\351\231\244OBS\347\232\204\350\231\232\346\213\237\346\221\204\345\203\217\345\244\264.md" new file mode 100644 index 0000000..9aca8ab --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Mac\345\210\240\351\231\244OBS\347\232\204\350\231\232\346\213\237\346\221\204\345\203\217\345\244\264.md" @@ -0,0 +1,38 @@ +--- +title: Mac删除OBS的虚拟摄像头 +date: 2022-06-02 22:13:15 +updated: +categories: +- 软件 +tags: +- Mac +- OBS +- 虚拟摄像头 +keywords: +- OBS +- 虚拟摄像头 +description: 解决Mac下无法彻底删除OBS虚拟摄像头插件的问题 +cover: https://cdn.akamai.steamstatic.com/steam/apps/1905180/capsule_616x353.jpg?t=1654173198 +top_img: https://cdn.cloudflare.steamstatic.com/steam/apps/1905180/ss_f7aa6c7a804e0a06ea5a9742a9afc15f637d498e.1920x1080.jpg?t=1654173198 + +--- + +### 先容我吐槽一波! +我在“简中互联网”上找了好久,几乎都是教你怎么用的,而且用途都不正经。就没有教你怎么删的,windows几乎都是清一色注册表删除,但是Mac哪来的注册表?所以搞了一下午,都快给我气晕了。首先,下载老版本没有,因为老Mac版的OBS在“工具”里也没有关闭的按钮,这OBS的mac版真的纯纯的沙壁,自带一个没娘的插件,随意修改用户的电脑配置,我好好地写代码想调用一下摄像头,没想到居然被0还是1给搞了(opecv里调摄像头的参数)。这次就直接怒卸这狗避的。 +### 吐槽完了,上方法: +参考帖子: +>https://obsproject.com/forum/threads/how-to-uninstall-obs-virtual-camera.146837/ + +国外老哥的方法就是输两行命令,不愿看的就直接复制下面两行就完事了。 +```shell +sudo rm -rf /Library/CoreMediaIO/Plug-Ins/DAL/obs-mac-virtualcam.plugin +``` + +```shell +sudo rm -rf /Library/Application\ Support/obs-studio/plugins/obs-mac-virtualcam +``` + +### 解决! +![在这里插入图片描述](https://img-blog.csdnimg.cn/bc9eec8b4d404a518a2b977400f07daa.png) + +可以看到Edge浏览器里已经找不到OBS Virtual Camera了,芜湖撒花🎉 diff --git "a/docs/\350\275\257\344\273\266/Linux/Mac\346\237\245\347\234\213\345\233\272\346\200\201\344\275\277\347\224\250\346\203\205\345\206\265.md" "b/docs/\350\275\257\344\273\266/Linux/Mac\346\237\245\347\234\213\345\233\272\346\200\201\344\275\277\347\224\250\346\203\205\345\206\265.md" new file mode 100644 index 0000000..f90ea5b --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Mac\346\237\245\347\234\213\345\233\272\346\200\201\344\275\277\347\224\250\346\203\205\345\206\265.md" @@ -0,0 +1,165 @@ +--- +title: Mac查看固态使用情况 +date: 2022-03-02 16:26:15 +updated: +categories: +- 软件 +tags: +- Mac +- 磁盘使用情况 +keywords: +- Mac +- 磁盘 +description: 一种查看Mac硬盘使用情况的简单方法 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/5d202f7e165106451.jpg_fo742.jpg +top_img: https://support.apple.com/library/content/dam/edam/applecare/images/zh_CN/macos/monterey/macos-monterery-about-this-mac-storage.png +--- + +检测工具安装: + +```shell +brew install smartmontools +``` + +命令: + +```shell +smartctl -a disk0 +``` + +附上我使用了**2个月**的情况: + +```shell +smartctl 7.3 2022-02-28 r5338 [Darwin 21.2.0 arm64] (local build) +Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org + +=== START OF INFORMATION SECTION === +Model Number: APPLE SSD AP0512R +Serial Number: 0ba0181281e13c26 +Firmware Version: 386.60.2 +PCI Vendor/Subsystem ID: 0x106b +IEEE OUI Identifier: 0x000000 +Controller ID: 0 +NVMe Version: <1.2 +Number of Namespaces: 3 +Local Time is: Mon Mar 7 22:18:27 2022 CST +Firmware Updates (0x02): 1 Slot +Optional Admin Commands (0x0004): Frmw_DL +Optional NVM Commands (0x0004): DS_Mngmt +Maximum Data Transfer Size: 256 Pages + +Supported Power States +St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat + 0 + 0.00W - - 0 0 0 0 0 0 + +=== START OF SMART DATA SECTION === +SMART overall-health self-assessment test result: PASSED + +SMART/Health Information (NVMe Log 0x02) +Critical Warning: 0x00 +Temperature: 25 Celsius +Available Spare: 100% +Available Spare Threshold: 99% +Percentage Used: 0% +Data Units Read: 6,502,421 [3.32 TB] +Data Units Written: 5,517,000 [2.82 TB] +Host Read Commands: 99,276,810 +Host Write Commands: 58,002,374 +Controller Busy Time: 0 +Power Cycles: 144 +Power On Hours: 64 +Unsafe Shutdowns: 5 +Media and Data Integrity Errors: 0 +Error Information Log Entries: 0 + +Read 1 entries from Error Information Log failed: GetLogPage failed: system=0x38, sub=0x0, code=745 +``` + +``` +smartctl 7.3 2022-02-28 r5338[Darwin 21.2.0 arm64](本地构建) + +版权所有(C)2002-22,Bruce Allen,Christian Franke,www.smartmontools。组织 + + + +==信息部分的开始=== + +型号:苹果SSD AP0512R + +序列号:0ba0181281e13c26 + +固件版本:386.60.2 + +PCI供应商/子系统ID:0x106b + +IEEE OUI标识符:0x000000 + +控制器ID:0 + +NVMe版本:<1.2 + +名称空间数:3 + +当地时间:周一至三月7日22:18:27 2022 CST + +固件更新(0x02):1个插槽 + +可选管理命令(0x0004):Frmw_DL + +可选NVM命令(0x0004):DS_Mngmt + +最大数据传输大小:256页 + + + +支持的大国 + +St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat + +0+0.00W--0 + + + +==智能数据段的开始=== + +SMART整体健康自我评估测试结果:通过 + + + +智能/健康信息(NVMe日志0x02) + +严重警告:0x00 + +温度:25摄氏度 + +可用备件:100% + +可用备用阈值:99% + +使用百分比:0% + +数据单位读取:6502421[3.32 TB] + +写入的数据单位:5517000[2.82 TB] + +主机读取命令:99276810 + +主机写入命令:58002374 + +控制器繁忙时间:0 + +动力循环:144次 + +开机时间:64小时 + +不安全停机:5 + +媒体和数据完整性错误:0 + +错误信息日志项:0 + + + +从错误信息日志读取1个条目失败:GetLogPage失败:系统=0x38,子=0x0,代码=745 +``` + diff --git "a/docs/\350\275\257\344\273\266/Linux/Mac\350\260\203\346\225\264docker\346\240\217.md" "b/docs/\350\275\257\344\273\266/Linux/Mac\350\260\203\346\225\264docker\346\240\217.md" new file mode 100644 index 0000000..c4c776f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Mac\350\260\203\346\225\264docker\346\240\217.md" @@ -0,0 +1,45 @@ +--- +title: Mac调整docker栏 +date: 2022-07-30 22:39:15 +updated: +categories: +- 软件 +tags: +- Mac +- docker栏 +keywords: +- Mac +- docker栏 +description: 修改Mac的docker栏的动画效果 +cover: https://pica.zhimg.com/v2-18cc4dff3c2eebfcebd7769288325eef_1440w.jpg?source=172ae18b +top_img: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTk1UcE6VDX7MJNKUTp7cYmd0RvRs_x1bip8uvzKFlANeeredFd +--- + + + +### 恢复docker默认状态 + +```shell +sudo defaults delete com.apple.dock; killall Dock +``` + +### 关闭动画 + +```shell +sudo defaults write com.apple.dock autohide-time-moidifier -int 0;killall Dock +``` + +### 恢复默认的滑动效果 +```shell +sudo defaults write com.apple.dock autohide-time-moidifier -int 0;killall Dock +``` + +### 关闭延迟 +```shell + sudo defaults write com.apple.Dock autohide-delay -float 0; killall Dock +``` + +### 还原指令 +```shell + sudo defaults delete com.apple.Dock autohide-delay; killall Dock +``` \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/Unix\347\263\273\347\273\237\344\270\213\347\232\204Shell\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Linux/Unix\347\263\273\347\273\237\344\270\213\347\232\204Shell\345\221\275\344\273\244.md" new file mode 100644 index 0000000..aba57a1 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/Unix\347\263\273\347\273\237\344\270\213\347\232\204Shell\345\221\275\344\273\244.md" @@ -0,0 +1,147 @@ +--- +title: Unix系统下的Shell命令 +date: 2022-01-26 22:01:15 +updated: +categories: +- 学习 +tags: +- Unix +- Shell +keywords: +- Unix +- Shell +description: Mac和Linux下都能使用的命令 +cover: https://www.w3cschool.cn/attachments/image/20170622/1498119961561899.png +top_img: https://atts.w3cschool.cn/attachments/cover/cover_shellbook.png?t=1542281091?imageView2/1/w/48/h/48 +--- + +/ 根目录 + +~ home目录(当前用户的目录) + +进入目录 + +```shell +cd /usr/local +``` + +返回目录 + +```shell +cd ../ +``` + +新建文件 + +```shell +touch 123.txt +或 +touch abc +``` + +新建文件夹(“/”可加可不加) + +```shell +mkdir file/ +``` + +编辑文件 + +```shell +vim 123.txt +i为从头编辑 +o为从尾编辑(推荐) +编辑完后按esc,结束编辑 +按:w保存,按:q退出,一般按:wq,加!为强制 +``` + +复制文件 + +```shell +cp abc1.txt abc2.txt +``` + +复制文件夹 + +```shell +cp -a file1/ file2/ +``` + +移动文件到文件夹 + +```shell +mv 123.txt /usr/local +或者顺便重命名 +mv 123.txt /usr/local/321.txt +``` + +移动多个文件到文件夹 + +```shell +mv 123.txt 1234.txt /usr/local +``` + +移动文件夹到别的文件夹 + +```shell +mv 666/ /usr/local/lib/ +``` + +重命名文件/文件夹 + +```shell +mv 123.txt 321.txt +mv 666/ 777/ +``` + + 删除文件 + +```shell +rm 123.txt +``` + +删除空文件夹 + +```shell +rmdir 666/ +``` + +删除文件夹 + +```shell +rm -rf 666/ +``` + +软链接:在Mac中被称为“替身”,在Windows被称为“快捷方式”,名称只要和源文件的“名称+后缀“不同就行 +硬链接:MacOS和Linux独有,属于源文件的分身,源文件删除不影响硬链接,硬链接修改源文件也会跟着改 +创建文件软链接(软链接即为文件的替身,删除源文件即删除了文件,替身将失效。软链接的名称可以随便取)(MacOS下必须写绝对路径,且不能在同目录下生成软链接) + +```shell +创建同名的软链接1234.txt +ln -s /usr/local/666/123.txt /usr/local/ +创建自定义名称的软链接123_lnk.abctxt(软链接只是源文件的替身,起什么名字都可以) +ln -s /usr/local/666/123.txt /usr/local/123_lnk.abctxt +``` + +创建文件夹软链接 + +```shell +ln -s 666/ 666_lnk/ +``` + +创建文件硬链接(硬链接即为文件的指针,删除所有硬链接包括源文件才能彻底删除文件。硬链接的后缀如果与源文件不一致,则有可能无法正常打开查看)(MacOS下可以使用相对路径,且可以在目录下生成硬链接) + +```shell +ln 123.txt 234.txt +``` + +获取指定目录下所有文件夹名 + +```shell +ls -l 文件夹路径 |awk '/^d/ {print $NF}' +``` + +更多linux指令⬇️ + +> https://www.cnblogs.com/effortfu/p/12270990.html + diff --git "a/docs/\350\275\257\344\273\266/Linux/bash\344\270\216zsh\347\232\204\345\210\207\346\215\242.md" "b/docs/\350\275\257\344\273\266/Linux/bash\344\270\216zsh\347\232\204\345\210\207\346\215\242.md" new file mode 100644 index 0000000..8724fc2 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/bash\344\270\216zsh\347\232\204\345\210\207\346\215\242.md" @@ -0,0 +1,114 @@ +--- +title: bash与zsh的切换 +date: 2022-06-15 17:37:01 +updated: +categories: +- 软件 +tags: +- Mac +- bash +- zsh +keywords: +- Mac +- bash +- zsh +description: 在Mac上更好地使用终端命令 +cover: https://kruschecompany.com/wp-content/uploads/2022/02/Cover-image-for-blog-comparing-and-contrasting-Z-shell-ZSH-vs-Bash-shell-1280x595.png +top_img: https://eshop.macsales.com/blog/wp-content/uploads/2019/12/BashToZsh-1400x788-1.jpg +--- + +## 1、问题由来 + +网上冲浪解决问题时,听闻zsh很好用,于是稀里糊涂入坑了,于是记录一下使用zsh过程中遇到的坑和一些常用的命令 + +## 2、解决思路 + +安装oh my zsh(安装完成后自动进入zsh界面) + +```shell +sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" +``` + +卸载oh my zsh + +```shell +uninstall_oh_my_zsh +``` + +如果遇到**command not found**的错误,可以先执行这条命令 + +```shell +export PATH=/bin:/usr/bin:/usr/local/bin:"${PATH}" +``` + +切换成bash + +```shell +chsh -s /bin/bash +``` + +切换成zsh + +```shell +chsh -s /bin/zsh +``` + +下载主题 + +```shell +git clone git://github.com/jeremyFreeAgent/oh-my-zsh-powerline-theme +``` + +执行目录下的脚本install.sh + +```shell +sudo ./oh-my-zsh-powerline-theme/install.sh +``` + +安装字体,防止乱码 + +```shell +git clone https://github.com/powerline/fonts.git +``` + +执行install.sh安装字体 + +```shell +sudo ./fonts/install.sh +``` + +- 到此字体安装完成,之后在终端命令行工具的偏好设置设置: +- 找到“文本->>字体->>更改” ,"所有字体"中选中“ Meslo LG M for powerLine“ 字体 + +修改zsh主题 + +```shell +vim ~/.zshrc +``` + +```shell +ZSH_THEME="robbyrussel" 修改此项为设置主题: ZSH_THEME="powerline" +``` + +保存,重启**终端命令行**即可看到powerLine 主题 + +使用alias别名 + +```shell +alias pod_update='pod update --verbose --no-repo-update' +``` + +如果遇到brew命令失效,可以执行一下两行代码 + +```shell +echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> /Users/hzx/.zprofile +eval $(/opt/homebrew/bin/brew shellenv) +``` + +```shell +echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> /Users/hzx/.zprofile +eval $(/opt/homebrew/bin/brew shellenv) +``` + +解决brew命令和mvn命令不能用的问题 + diff --git "a/docs/\350\275\257\344\273\266/Linux/index.md" "b/docs/\350\275\257\344\273\266/Linux/index.md" new file mode 100644 index 0000000..f70da63 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/index.md" @@ -0,0 +1 @@ +## Linux \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/option\345\222\214shift\347\211\271\346\256\212\347\254\246\345\217\267.md" "b/docs/\350\275\257\344\273\266/Linux/option\345\222\214shift\347\211\271\346\256\212\347\254\246\345\217\267.md" new file mode 100644 index 0000000..cfd7a4c --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/option\345\222\214shift\347\211\271\346\256\212\347\254\246\345\217\267.md" @@ -0,0 +1,26 @@ +--- +title: option和shift特殊符号 +date: 2022-03-27 23:33:15 +updated: +categories: +- 软件 +tags: +- Mac +- 特殊符号 +keywords: +- 特殊符号 +description: 在Mac上打出特殊符号 +cover: https://n.sinaimg.cn/tech/crawl/770/w550h220/20200510/8a23-itmiwry5336482.png +top_img: https://support.apple.com/library/content/dam/edam/applecare/images/zh_CN/social/keyboards-social-card.jpg +--- + +### 引号 + +![引号](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/%E5%BC%95%E5%8F%B7.jpg) + +### option + +![option键](https://i0.hdslb.com/bfs/album/08efc98507264f80508d13cab4f7d8764009e184.jpg) + +### option+shift +![option+shift键](https://i0.hdslb.com/bfs/album/1a2b6d77cf901b4c99a2e43d31aeed12a50fdd73.jpg) \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/zsh\344\270\216bash\347\232\204\345\210\207\346\215\242.md" "b/docs/\350\275\257\344\273\266/Linux/zsh\344\270\216bash\347\232\204\345\210\207\346\215\242.md" new file mode 100644 index 0000000..9ea04de --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/zsh\344\270\216bash\347\232\204\345\210\207\346\215\242.md" @@ -0,0 +1,112 @@ +--- +title: zsh与bash的切换 +date: 2022-03-04 20:41:15 +updated: +categories: +- 软件 +tags: +- zsh +- bash +keywords: +- zsh +- bash +description: zsh和bash的切换 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212220854.png +top_img: https://i.ytimg.com/vi/xzU4I5UO1Qg/maxresdefault.jpg +--- + +## 1、问题由来 + +网上冲浪解决问题时,听闻zsh很好用,于是稀里糊涂入坑了,于是记录一下使用zsh过程中遇到的坑和一些常用的命令 + +## 2、解决思路 + +安装oh my zsh(安装完成后自动进入zsh界面) + +```shell +sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" +``` + +卸载oh my zsh + +```shell +uninstall_oh_my_zsh +``` + +如果遇到**command not found**的错误,可以先执行这条命令 + +```shell +export PATH=/bin:/usr/bin:/usr/local/bin:"${PATH}" +``` + +切换成bash + +```shell +chsh -s /bin/bash +``` + +切换成zsh + +```shell +chsh -s /bin/zsh +``` + +下载主题 + +```shell +git clone git://github.com/jeremyFreeAgent/oh-my-zsh-powerline-theme +``` + +执行目录下的脚本install.sh + +```shell +sudo ./oh-my-zsh-powerline-theme/install.sh +``` + +安装字体,防止乱码 + +```shell +git clone https://github.com/powerline/fonts.git +``` + +执行install.sh安装字体 + +```shell +sudo ./fonts/install.sh +``` + +- 到此字体安装完成,之后在终端命令行工具的偏好设置设置: +- 找到“文本->>字体->>更改” ,"所有字体"中选中“ Meslo LG M for powerLine“ 字体 + +修改zsh主题 + +```shell +vim ~/.zshrc +``` + +```shell +ZSH_THEME="robbyrussel" 修改此项为设置主题: ZSH_THEME="powerline" +``` + +保存,重启**终端命令行**即可看到powerLine 主题 + +使用alias别名 + +```shell +alias pod_update='pod update --verbose --no-repo-update' +``` + +如果遇到brew命令失效,可以执行一下两行代码 + +```shell +echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> /Users/hzx/.zprofile +eval $(/opt/homebrew/bin/brew shellenv) +``` + +```shell +echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> /Users/hzx/.zprofile +eval $(/opt/homebrew/bin/brew shellenv) +``` + +解决brew命令和mvn命令不能用的问题 + diff --git "a/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210jenv\346\263\225\357\274\211.md" "b/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210jenv\346\263\225\357\274\211.md" new file mode 100644 index 0000000..cf281da --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210jenv\346\263\225\357\274\211.md" @@ -0,0 +1,93 @@ +--- +title: 切换jdk版本的方法(jenv法) +date: 2022-03-04 20:01:15 +updated: +categories: +- 学习 +tags: +- Java +- jdk +keywords: +- Java +- 切换jdk版本 +description: 利用jenv管理jdk版本 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/295a1f378135ca0be39d325ff5ab1af14af5d797.jpg +top_img: https://static.getiot.tech/java-logo.png +--- + +今天要跑个人博客项目,用mvn打包完,想在本地跑一下,结果我装了三个jdk版本,分别是8、11、17,于是想到了进行jdk的版本管理。但是我去网上搜索了一番,发现jenv教程很详细,但是我就是没法切换,后来捣鼓了4小时,终于发现原因了,竟然是**没重启!**,我真的日了🐶了。特此记录一下安装jenv的教训! + +### **安装** + +```shell +brew install jenv +``` + +```shell +echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.zshrc +``` + +```shell +echo 'eval "$(jenv init -)"' >> ~/.zshrc +``` + +```shell +mkdir -p ~/.jenv/versions +``` + +### 链接java版本 + +```shell +jenv add /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home +``` +```shell +jenv add /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home +``` +```shell +jenv add /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home +``` + +因为我有三个jdk版本,都全部链接进去了,**以后也可以将别的环境的版本这样子进行管理,比如mysql、tomcat、maven** + +### jenv的常用命令 + +查看安装的版本 + +```shell +jenv versions +``` + +查看在用的版本 + +```shell +jenv version +``` + +设置默认版本1.8 + +```shell +jenv global 1.8 +``` + +设置当前版本为1.8 + +```shell +jenv local 1.8 +``` + +强制maven使用jenv配置的java版本 + +```shell +jenv enable-plugin maven +``` + +重启Shell终端 + +```shell +exec $SHELL +``` + +### 最后,不要忘记重启! + +这世上果然99%的问题都是可以重启解决的,淦!之前害我弄了好久,都要崩溃了! + diff --git "a/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210\347\216\257\345\242\203\345\217\230\351\207\217\346\263\225\357\274\211.md" "b/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210\347\216\257\345\242\203\345\217\230\351\207\217\346\263\225\357\274\211.md" new file mode 100644 index 0000000..ee9ab2b --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/\345\210\207\346\215\242jdk\347\211\210\346\234\254\347\232\204\346\226\271\346\263\225\357\274\210\347\216\257\345\242\203\345\217\230\351\207\217\346\263\225\357\274\211.md" @@ -0,0 +1,46 @@ +--- +title: 切换jdk版本的方法(环境变量法) +date: 2022-03-07 22:14:15 +updated: +categories: +- 学习 +tags: +- Java +- jdk +keywords: +- Java +- 切换jdk版本 +description: 引入环境变量切换jdk版本 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/295a1f378135ca0be39d325ff5ab1af14af5d797.jpg +top_img: https://static.getiot.tech/java-logo.png +--- + +首先配置好java环境,这一步每个人可能会不一样 + +``` +#配置java环境 +export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home +export CLASSPAHT=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar +export PATH=$JAVA_HOME/bin:$PATH: +``` + +然后引入下面这样的格式,可以根据个人情况修改,我安装了8、11、17三个版本 + +``` +# 设置 JDK 1.8 +export JAVA_8_HOME=`/usr/libexec/java_home -v 1.8` +# 设置 JDK 11 +export JAVA_11_HOME=`/usr/libexec/java_home -v 11` +# 设置 JDK 17 +export JAVA_17_HOME=`/usr/libexec/java_home -v 17` + +# 默认JDK 8 +export JAVA_HOME=$JAVA_8_HOME + +# alias命令动态切换JDK版本 +alias jdk8="export JAVA_HOME=$JAVA_8_HOME" +alias jdk11="export JAVA_HOME=$JAVA_11_HOME" +alias jdk17="export JAVA_HOME=$JAVA_17_HOME" +``` + +大功告成了,在终端输入jdk8、jdk11、jdk17即可快速切换jdk版本,真不戳! \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/\345\221\275\344\273\244\350\241\214\347\263\273\347\273\237\344\277\241\346\201\257\345\267\245\345\205\267.md" "b/docs/\350\275\257\344\273\266/Linux/\345\221\275\344\273\244\350\241\214\347\263\273\347\273\237\344\277\241\346\201\257\345\267\245\345\205\267.md" new file mode 100644 index 0000000..801f00a --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/\345\221\275\344\273\244\350\241\214\347\263\273\347\273\237\344\277\241\346\201\257\345\267\245\345\205\267.md" @@ -0,0 +1,221 @@ +> **系统信息查看工具**可以用于获取和显示系统硬件、软件和环境信息(如内核版本、内存使用情况、处理器负载等),通过这些工具可以在主流操作系统的运行中获取系统信息。 + +# macchina + +1. **最小化**:相比于 `neofetch` 和 `fastfetch`,`macchina` 更加简单,更适合小型设备或资源受限的环境。 +2. **可定制化**:提供主题系统,主题配置文件与主要配置文件是分开的,用户可以创建一堆主题并随时在它们之间切换。 + +## 安装 + +```shell +eval "$(curl https://get.x-cmd.com)" # 安装 x-cmd +x env use macchina # 使用 x-cmd 安装 macchina +``` + +## 使用 + +1. 获取和显示系统信息: + + ```shell + macchina + macchina -o machine + macchina -o machine -o terminal -o shell + ``` + +2. 定制 macchina: + + - 存放配置文件的目录: + + - Linux 和 BSD:`~/.config/macchina/` 或 `$XDG_CONFIG_HOME/macchina/` + - macOS:`$HOME/.config/macchina/` + - Windows:`%AppData%/macchina/` + + - [`macchina.toml`](https://github.com/Macchina-CLI/macchina/blob/main/macchina.toml):macchina 的配置文件,用于调整 macchina 需要显示或隐藏的内容以及使用的主题。 + + - [主题配置文件](https://github.com/Macchina-CLI/macchina/tree/main/contrib/themes):用配置 macchina 显示信息的外观,文件格式请参考[官方文档](https://github.com/Macchina-CLI/macchina/blob/main/doc/macchina.7.scd)。 + + - 示例 - 自定义主题: + + ```shell + x touch "$HOME/.config/macchina/themes/" + printf "%s + ``` + +" \n 'hide_ascii = true' \n '[box]' \n 'border = "plain"' \n 'visible = true' > "$HOME/.config/macchina/themes/x.toml" macchina -l macchina -t x ``` + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202411032341203.png" alt="image-20241103234124163" style="zoom: 67%;" /> + +# neofetch + +兼容性好,neofetch 基于`bash`,所以不需要编译,同时兼容性也好: + +举个例子,`main`函数内部的`cache_uname`方法,就会使用 Linux 和 macOS 都有的命令:`uname -srm` + +## 安装 + +Neofetch 的安装非常简单,在各大的软件包管理器都有发布: + +```shell +# macOS +brew install neofetch +# Linux Debian/Ubuntu +sudo apt install neofetch +# Linux CentOS +sudo yum install neofetch +``` + +安装完成,我们看看 Neofetch 的版本: + +```shell +neofetch --version +``` + +## 使用 + +输出系统信息: + +```shell +neofetch +``` + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202411032341598.png" alt="image-20241103234143567" style="zoom:67%;" /> + +## 扩展 + +如果细看 Neofetch 的脚本,会发现还有很多可选项,这些在 Neofetch 的 wiki 内也有记录: + +- [Neofetch Wiki: https://github.com/dylanaraps/neofetch/wiki](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fgithub.com%2Fdylanaraps%2Fneofetch%2Fwiki&objectId=2443476&objectType=1) + +接下来我们看看可选项有那些? + +### 扩展使用 + +根据官方的 wiki,Neofetch 在安装后,会自动生成默认配置文件,配置文件的存放地址在:`${HOME}/.config/neofetch/config.conf`内。里面其实就是默认的输出内容定义: + +代码语言:bash + +复制 + +```bash +cat ${HOME}/.config/neofetch/config.conf +``` + +<img src="https://developer.qcloudimg.com/http-save/7704194/7a9ceb4ee93944402ef47350d54f168c.webp" alt="neofetch默认配置" style="zoom:40%;" /> + +neofetch默认配置 + +可以看到,默认情况下打印的内容,就在配置文件内的 `print_info` 所定义。如果我们需要修改呢,有两种方法: + +- 直接使用`vim`等文本编辑器修改这个文件即可。 +- 在运行`neofetch`的时候,使用参数开启即可。 + +举个例子,默认情况,只显示内存,并没有显示内存使用的百分比;但是实际上在`config.conf`文件内是可以开启的,比如: + +代码语言:bash + +复制 + +```bash +# 直接输出 +neofetch --memory_percent on +``` + +或者直接修改配置文件 + +<img src="https://developer.qcloudimg.com/http-save/7704194/fc76855ebafebc9d5142e7ab90cf1ccc.webp" alt="修改配置文件" style="zoom:40%;" /> + +修改配置文件 + +最后的结果: + +<img src="https://developer.qcloudimg.com/http-save/7704194/e76029119fdf53b2a45987b9780d204e.webp" alt="显示内存比" style="zoom:40%;" /> + +显示内存比 + +### 操作前提 + +本次文章的操作前提,需要你有一台电脑。如果你是希望使用NeoFetch,那么需要用Bash的支持: + +1. 系统为Linux或Unix; +2. Bash的版本最少需要`3.2`,你可以使用`bash --version`查看bash版本。 + +<img src="https://developer.qcloudimg.com/http-save/yehe-7704194/fdb57beefbdf88382cd45a9c4c9edc1f.png" alt="适用于NeoFetch的系统" style="zoom: 40%;" /> + +适用于NeoFetch的系统 + +如果你希望使用 FastFetch ,那么原则上没有什么受限,经过测试,目前的Windows 7也可以使用,Windows 11 ON ARM使用也正常。如果在Windows Server上,那么目前常用的2016、2019和2022都可以使用: + +<img src="https://developer.qcloudimg.com/http-save/yehe-7704194/1c1b055b9d844e430e72fecb14d6f33c.png" alt="都是支持的" style="zoom:40%;" /> + +都是支持的 + +最后,如果你希望有一台Linux进行练手,或者使用一台服务器部署网站,甚至使用Linux服务器测试本文章内容,强烈推荐使用腾讯云轻量应用服务器进行操作。 + +本文对应的视频教程: + +- [摸不透系统当前状态和配置?一条命令快速查看! NeoFetch和FastFetch使用详解: https://www.bilibili.com/video/BV1fHYLeSEr4](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fwww.bilibili.com%2Fvideo%2FBV1fHYLeSEr4&objectId=2443476&objectType=1) + +### 项目归档 + +Neofetch完全基于`bash`,使其兼容性很不错;即使你的Debian从8已经到12,但是 Neofetch 版本一直没有更新,那么 Neofetch 的使用,也不会出现什么问题。 + +这也是为什么,Neofetch在归档前,已经三年没有更新,但使用起来也没有任何问题。可以预想到,未来很长一段时间也不会有任何问题。那些基础的命令`free -m`、`uname -s`等等,都是不会改变的。 + +但是,为什么 Neofetch 停止维护了呢? 或者说是项目归档了呢? + +<img src="https://developer.qcloudimg.com/http-save/7704194/8e1b2a6ab6d7eb74952e85dca14a22ae.gif" alt="为什么停止维护呢?" style="zoom:40%;" /> + +为什么停止维护呢? + +其实,根据 reddit 上的两篇文章,可能可以略知一二: + +- [Neofetch development discontinued, repository archived](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fwww.reddit.com%2Fr%2Flinux%2Fcomments%2F1cga3q4%2Fneofetch_development_discontinued_repository%2F&objectId=2443476&objectType=1) +- [Found a text file at work titled "Why should I quit my job and become a goat farmer? (written during my "on-call" week)"](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fwww.reddit.com%2Fr%2Fsysadmin%2Fcomments%2F4l7kjd%2Ffound_a_text_file_at_work_titled_why_should_i%2F&objectId=2443476&objectType=1) + +大概就是作者换行了(回家开农场了,不过不清楚是否真的回去开农场?),项目维护者经常面临着巨大的工作量,包括但不限于代码更新、设备兼容考虑、错误修复、功能请求处理以及社区管理等等繁琐事物,加上作者自己从事的软件工作;作者在技术工作中感到厌倦和疲惫。而且即使从事的是技术,也需要考虑政治和不同人的立场,也需要站队。 + +综合上述的内容,他现在更倾向于追求他认为更简单、压力更小、更纯粹的生活方式。 + +自然而然地,项目就放弃维护了。 + +说实话,有点可惜;不过也确实为作者感到高兴,他找到了更好的生活。虽然不知道他是否真的是回去开设农场,但是应该是一个不错的新生活。 + +回到NeoFetch,其实也有很多继任者: + +- [hyfetch: Neofetch with LGBTQ+ pride flags!](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fgithub.com%2Fhykilpikonna%2Fhyfetch&objectId=2443476&objectType=1) +- [fastfetch: About An actively maintained, feature-rich and performance oriented, neofetch like system information tool.](https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fgithub.com%2Ffastfetch-cli%2Ffastfetch&objectId=2443476&objectType=1) + +接任者都是非常好用的项目;不过受限于篇幅,接下来,我们就取其中的 Fastfetch 来一起看看。 + +# fastfetch + +1. **可替代性**:通常情况下,可以把 FastFetch 当作 NeoFetch 使用。安装方式也是一样,FastFetch 已经在各个平台的软件包管理器发布。 + +2. **可扩展性**:相比于 NeoFetch 全部基于`bash`的 shell 脚本,FastFetch 是基于C的。 + +## 安装 + +```shell +# macOS +brew install fastfetch +# Linux Debian/Ubuntu (Debian 13 or newer) +sudo apt install fastfetch +# Linux CentOS +sudo yum install fastfetch +``` + +安装完成,我们看看 fastfetch的版本: + +```shell +fastfetch --version +``` + +## 使用 + +输出系统信息: + +```shell +neofetch +``` + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202411032347936.png" alt="image-20241103234731900" style="zoom:67%;" /> \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Linux/\345\234\250ARM\346\236\266\346\236\204\347\232\204Mac\344\270\212\350\277\220\350\241\214exe\347\250\213\345\272\217.md" "b/docs/\350\275\257\344\273\266/Linux/\345\234\250ARM\346\236\266\346\236\204\347\232\204Mac\344\270\212\350\277\220\350\241\214exe\347\250\213\345\272\217.md" new file mode 100644 index 0000000..c00999f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/\345\234\250ARM\346\236\266\346\236\204\347\232\204Mac\344\270\212\350\277\220\350\241\214exe\347\250\213\345\272\217.md" @@ -0,0 +1,90 @@ +--- +title: 在ARM架构的Mac上运行exe程序,以文字游戏为例 +date: 2022-09-14 18:06:15 +updated: +categories: +- 软件 +tags: +- Mac +- ARM +- Windows +- CrossOver +- Wine +keywords: +- Mac +- ARM +- Windows +- CrossOver +- Wine +description: 一种可以在ARM架构Mac上运行exe程序的办法 +cover: https://www.omgubuntu.co.uk/wp-content/uploads/2016/03/wine.jpg +top_img: https://i.ytimg.com/vi/nVxzCteaWnc/maxresdefault.jpg +--- + +记录一下,如何在arm架构芯片的Mac上打开exe后缀的windows程序 + +也是参考了这个视频 + +> https://www.bilibili.com/video/BV1mW4y1k7GF + +# PS + +这种方法是安装**Wine CrossOver**,但是Github上还有一种方法,就是安装**CrossOver**,它们俩都可以实现mac打开exe程序,相比之下,Wine CrossOver使用方便,即开即关,CrossOver有客户端界面,可以自己定制容器。 + +我下面介绍的方法是左边的,你也可以去MacWk安装右边的CrossOver,有兴趣可以自己研究一下。 + +> https://macwk.com/soft/crossover + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914180954000.png" alt="image-20220914180954000" style="zoom: 50%;" /> + +# Wine CrossOver安装步骤 + +1、安装好homebrew,这个程序员都懂的,就不提了。 +2、运行下面的代码,不太懂,应该是要创建一个wine的tap + +```shell +brew tap gcenx/wine +``` + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914173839105.png" alt="image-20220914173839105" /> + +3、安装wine-crossover,装完后可以右键exe程序使用wine运行了 + +```shell +brew install --cask --no-quarantine wine-crossover +``` + +下图是装完了的结果 + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914173901541.png" alt="image-20220914173901541" style="zoom: 50%;" /> + +# 调整 + +```shell +winecfg +``` + +会弹出一个古老的窗口(win2003?)窗口,如果没声音,可以调整一下音频。 + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914174005477.png" alt="image-20220914174005477" style="zoom: 50%;" /> + +# 完成 + +然后开一个游戏试试 + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914174158757.png" alt="image-20220914174158757" style="zoom: 50%;" /> + +很不幸,报错打不开(悲) + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914174910056_1.png" alt="image-20220914174910056" style="zoom: 50%;" /> + +但是万华镜就打开了……说明还得看情况,暂时不清楚打不开的原因是什么(大悲) + +另外,有些游戏的存档如果不是在根目录的话也会消失,但是万华镜的还在。。 + +所以还是得具体问题具体分析。 + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220914175300224.png" alt="image-20220914175300224" style="zoom: 50%;" /> + +然后又试了很多,发现问题百出,有的文字显示不了、有的显示比例不对,总之还是不能完美地运行,但是起码有了一个比较好的开始了,有总比没有强吧。 + diff --git "a/docs/\350\275\257\344\273\266/Linux/\345\256\211\350\243\205oh my zsh\344\270\273\351\242\230.md" "b/docs/\350\275\257\344\273\266/Linux/\345\256\211\350\243\205oh my zsh\344\270\273\351\242\230.md" new file mode 100644 index 0000000..4d3c96e --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Linux/\345\256\211\350\243\205oh my zsh\344\270\273\351\242\230.md" @@ -0,0 +1,43 @@ +--- +title: 安装oh my zsh主题 +date: 2022-03-07 22:42:15 +updated: +categories: +- 软件 +tags: +- ohmyzsh +- 终端美化 +keywords: +- zsh +description: 美化你的终端 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212218198.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212218476.png +--- + + + +oh my zsh除了自带的两个主题外我个人还比较喜欢两个 + +分别是sobole和jovial + +- sobole + + ![74af970abbf731048fef10bb85c0b92b.png](https://img-blog.csdnimg.cn/img_convert/74af970abbf731048fef10bb85c0b92b.png) + +- jovial + + ![48ada5d75ea2044b132b85bc106b2ae3.png](https://img-blog.csdnimg.cn/img_convert/48ada5d75ea2044b132b85bc106b2ae3.png) + +![screenshot](https://i0.hdslb.com/bfs/album/d96c49f36aadd0c4a7709312c42c11dbff04e71e.png) + +sobole安装地址: + +> [sobolevn/dotfiles: dotfiles for the developer happiness: macos, zsh, brew, vscode, codespaces, python, node, elixir (github.com)](https://github.com/sobolevn/dotfiles) + +jovial安装地址: + +> [zthxxx/jovial: Jovial - A lovely zsh theme with responsive-design, it's pretty fast, keep simple but useful (github.com)](https://github.com/zthxxx/jovial) + +draculatheme安装地址 + +> [Dark theme for Zsh and 266+ apps — Dracula (draculatheme.com)](https://draculatheme.com/zsh) \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Python/Pytorch\344\270\213\350\275\275\351\205\215\347\275\256\357\274\214Anaconda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203.md" "b/docs/\350\275\257\344\273\266/Python/Pytorch\344\270\213\350\275\275\351\205\215\347\275\256\357\274\214Anaconda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203.md" new file mode 100644 index 0000000..0a03a6f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/Pytorch\344\270\213\350\275\275\351\205\215\347\275\256\357\274\214Anaconda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203.md" @@ -0,0 +1,85 @@ +--- +title: Pytorch下载配置,Anaconda创建虚拟环境 +date: 2022-08-06 21:05:15 +updated: +categories: +- 软件 +tags: +- Pytorch +- Anaconda +keywords: +- Pytorch +- Anaconda +- 虚拟环境 +description: 下载、配置Pytorch,并用Anaconda创建虚拟环境 +cover: https://pic3.zhimg.com/v2-d90c131bec1b3358415a6b73b57561de_1440w.jpg?source=172ae18b +top_img: https://pic2.zhimg.com/v2-0cd1af42c8b073bcb0d0fbbc9dc292b3_720w.jpg?source=172ae18b +--- + + + +## 一、使用Anaconda创建虚拟环境 + +### 1、可以引入需要依赖的包,以下仅作演示 + +- numpy: python数值计算包 +- matplotlib: 支持python画图 +- pandas : 数据软件包 +- jupyter notebook: 集成开发环境,可直接本地起服务调试python代码 + +```shell +conda create -n 环境名 python=3.8 numpy matplotlib pandas jupyter notebook +``` + +### 2、进入虚拟环境 + +```shell +conda activate 环境名 +``` + +可以看到命令行开头变了 + +![image-20220807105109020](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105109020.png) + +### 3、退出虚拟环境 + +```shell +conda deactivate +``` + +![image-20220807105232709](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105232709.png) + +## 二、安装、配置Pytorch + +### 1、下载Pytorch,按照电脑配置安装适合的版本 + +> [pytorch官网](https://pytorch.org/get-started/locally/) + +比如我是Mac,就运行下面这句话 + +![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105508024.png) + +### 2*、如果安装慢,可以添加清华源和第三方源 + +```shell +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ +conda config --set show_channel_urls yes +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/ +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/ +conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ +``` + +**去掉-c pytorch,默认从清华源下载安装包** + +```shell +conda install pytorch torchvision +``` + +### 3、验证Pytorch是否安装成功 + +![image-20220807110231063](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807110231063.png) + +如果能输出torch版本就算成功了! \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Python/YOLOv5\347\232\204\344\275\277\347\224\250.md" "b/docs/\350\275\257\344\273\266/Python/YOLOv5\347\232\204\344\275\277\347\224\250.md" new file mode 100644 index 0000000..f910fcd --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/YOLOv5\347\232\204\344\275\277\347\224\250.md" @@ -0,0 +1,80 @@ +--- +title: YOLOv5的使用 +date: 2022-08-11 16:21:15 +updated: +categories: +- 学习 +tags: +- YOLOv5 +keywords: +- YOLOv5 +description: 初始YOLOv5 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212213438.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212214643.png +--- + +# 参考网站 + +> [ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite (github.com)](https://github.com/ultralytics/yolov5) + +# 代码推断 + +```python +import torch +# Model +model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # or yolov5n - yolov5x6, custom +# Images +img = 'https://ultralytics.com/images/zidane.jpg' # or file, Path, PIL, OpenCV, numpy, list +# Inference +results = model(img) +# Results +results.print() # or .show(), .save(), .crop(), .pandas(), etc. +``` + +# 命令使用 + +```shell +python detect.py --source 0 # webcam + img.jpg # image + vid.mp4 # video + path/ # directory + 'path/*.jpg' # glob + 'https://youtu.be/Zgi9g1ksQHc' # YouTube + 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream +``` + +# 性能排行 + +![155040763-93c22a27-347c-4e3c-847a-8094621d3f4e.png (2400×1200) (user-images.githubusercontent.com)](https://user-images.githubusercontent.com/26833433/155040763-93c22a27-347c-4e3c-847a-8094621d3f4e.png) + +**640 Figure** + +![155040757-ce0934a3-06a6-43dc-a979-2edbbd69ea0e.png (2400×1200) (user-images.githubusercontent.com)](https://user-images.githubusercontent.com/26833433/155040757-ce0934a3-06a6-43dc-a979-2edbbd69ea0e.png) + +# Pretrained Checkpoints + +| Model | size (pixels) | mAPval 0.5:0.95 | mAPval 0.5 | Speed CPU b1 (ms) | Speed V100 b1 (ms) | Speed V100 b32 (ms) | params (M) | FLOPs @640 (B) | +| ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------- | ------------- | ----------------- | ------------------ | ------------------- | ---------- | -------------- | +| [YOLOv5n](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5n.pt) | 640 | 28.0 | 45.7 | **45** | **6.3** | **0.6** | **1.9** | **4.5** | +| [YOLOv5s](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s.pt) | 640 | 37.4 | 56.8 | 98 | 6.4 | 0.9 | 7.2 | 16.5 | +| [YOLOv5m](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5m.pt) | 640 | 45.4 | 64.1 | 224 | 8.2 | 1.7 | 21.2 | 49.0 | +| [YOLOv5l](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5l.pt) | 640 | 49.0 | 67.3 | 430 | 10.1 | 2.7 | 46.5 | 109.1 | +| [YOLOv5x](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5x.pt) | 640 | 50.7 | 68.9 | 766 | 12.1 | 4.8 | 86.7 | 205.7 | +| | | | | | | | | | +| [YOLOv5n6](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5n6.pt) | 1280 | 36.0 | 54.4 | 153 | 8.1 | 2.1 | 3.2 | 4.6 | +| [YOLOv5s6](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s6.pt) | 1280 | 44.8 | 63.7 | 385 | 8.2 | 3.6 | 12.6 | 16.8 | +| [YOLOv5m6](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5m6.pt) | 1280 | 51.3 | 69.3 | 887 | 11.1 | 6.8 | 35.7 | 50.0 | +| [YOLOv5l6](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5l6.pt) | 1280 | 53.7 | 71.3 | 1784 | 15.8 | 10.5 | 76.8 | 111.4 | +| [YOLOv5x6](https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5x6.pt) + [TTA](https://github.com/ultralytics/yolov5/issues/303) | 1280 1536 | 55.0 **55.8** | 72.7 **72.7** | 3136 - | 26.2 - | 19.4 - | 140.7 - | 209.8 - | + +# 训练 + +```shell +python train.py --data coco.yaml --cfg yolov5n.yaml --weights '' --batch-size 128 + yolov5s 64 + yolov5m 40 + yolov5l 24 + yolov5x 16 +``` + +![90222759-949d8800-ddc1-11ea-9fa1-1c97eed2b963.png (2400×1200) (user-images.githubusercontent.com)](https://user-images.githubusercontent.com/26833433/90222759-949d8800-ddc1-11ea-9fa1-1c97eed2b963.png) diff --git "a/docs/\350\275\257\344\273\266/Python/conda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203\357\274\214\345\256\211\350\243\205Pytorch.md" "b/docs/\350\275\257\344\273\266/Python/conda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203\357\274\214\345\256\211\350\243\205Pytorch.md" new file mode 100644 index 0000000..8027edd --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/conda\345\210\233\345\273\272\350\231\232\346\213\237\347\216\257\345\242\203\357\274\214\345\256\211\350\243\205Pytorch.md" @@ -0,0 +1,170 @@ +--- +title: 使用conda创建虚拟环境,安装Pytorch +date: 2022-10-23 19:09:15 +updated: +categories: +- 学习 +tags: +- Python +- conda +- Pytorch +- 深度学习 +keywords: +- Python +- conda +- Pytorch +- 深度学习 +description: conda的常见使用方式 +cover: https://miro.medium.com/max/1200/1*O5Jgl-KFuvUyujAZhXHYlQ.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/conda_top_image.png +--- + +> 事先声明:并不需要一定Anaconda,Mac用户比较推荐Miniconda,这里只是介绍一款关于conda的软件,conda的操作都是一样的。截止本文章发布,Anaconda和Miniconda都适配M1 Mac,所以都可以安装。 + +## 一、使用Anaconda创建虚拟环境 + +### 1、创建环境 + +可以引入需要依赖的包,以下仅作演示 + +- numpy: python数值计算包 +- matplotlib: 支持python画图 +- pandas : 数据软件包 +- jupyter notebook: 集成开发环境,可直接本地起服务调试python代码 + +```shell +conda create -n 环境名 python=3.x numpy matplotlib pandas jupyter notebook +``` + +``` +pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117 +``` + +### 2、进入虚拟环境 + +```shell +conda activate 环境名 +``` + +可以看到命令行开头变了 + +![image-20220807105109020](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105109020.png) + +### 3、退出虚拟环境 + +```shell +conda deactivate +``` + +![image-20220807105232709](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105232709.png) + +### 4、删除虚拟环境 + +```shell +conda remove -name 虚拟环境名称 --all +``` + +### 5、删除环境中的某个包 + +```shell +conda remove --name 虚拟环境名称 包名称 +``` + +## 二、安装、配置Pytorch + +### 1、下载Pytorch,按照电脑配置安装适合的版本 + +> [pytorch官网](https://pytorch.org/get-started/locally/) + +比如我是Mac,就运行下面这句话 + +![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807105508024.png) + +### 2*、如果安装慢,可以添加清华源和第三方源 + + #添加镜像源 + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/ + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/ + conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ + + #显示检索路径 + conda config --set show_channel_urls yes + + #显示镜像通道 + conda config --show channels + +**删除之前的镜像源,恢复默认状态** + + ```shell + conda config --remove-key channels + ``` + +**去掉-c pytorch,默认从清华源下载安装包** + +```shell +conda install pytorch torchvision +``` + +### 3、验证Pytorch是否安装成功 + +![image-20220807110231063](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220807110231063.png) + +如果能输出torch版本就算成功了! + +### 4、pip和conda导出requirement.txt + +pip批量导出包含环境中所有组件的requirements.txt文件 + +```shell +pip freeze > requirements.txt +``` + +conda批量导出包含环境中所有组件的requirements.txt文件 + +```shell +conda list -e > requirements.txt +``` + +### 5、pip和conda从requirement.txt安装 + +pip批量安装requirements.txt文件中包含的组件依赖 + +```shell +pip install -r requirements.txt +``` + +conda批量安装requirements.txt文件中包含的组件依赖 + +```shell +conda install --yes --file requirements.txt +``` + +### 6、克隆环境、重命名环境 + +```shell +conda create --name B --clone A +``` + +```shell +conda create --name B --clone A +conda remove --name A --all +``` + +### 7、删除环境 + +```shell +conda remove --name B --all +``` + +### 8、查看源 + +```shell +conda config --show-sources +``` diff --git "a/docs/\350\275\257\344\273\266/Python/index.md" "b/docs/\350\275\257\344\273\266/Python/index.md" new file mode 100644 index 0000000..f5e17fe --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/index.md" @@ -0,0 +1 @@ +## Python \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Python/jupyter notebook\345\277\253\346\215\267\351\224\256.md" "b/docs/\350\275\257\344\273\266/Python/jupyter notebook\345\277\253\346\215\267\351\224\256.md" new file mode 100644 index 0000000..19e4ce7 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/jupyter notebook\345\277\253\346\215\267\351\224\256.md" @@ -0,0 +1,20 @@ +--- +title: jupyter notebook快捷键 +date: 2022-08-18 11:11:15 +updated: +categories: +- 学习 +tags: +- jupyter +- 快捷键 +keywords: +- jupyter +- 快捷键 +description: 适合win和mac的jupyter快捷键,学起来! +cover: https://clwasblog-1301107071.cos.ap-shanghai.myqcloud.com/doc/jupyter-notebook.png +top_img: https://img-blog.csdnimg.cn/img_convert/18f2cc96eac73b8c79991758e9323bf3.png +--- + +## jupyter notebook快捷键 + +![534772F4-4AAF-404E-B6E3-809A6C23F0E4_1_201_ab](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/534772F4-4AAF-404E-B6E3-809A6C23F0E4_1_201_ab.jpeg) \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Python/jupyter\345\242\236\345\212\240\343\200\201\345\210\240\351\231\244\345\206\205\346\240\270.md" "b/docs/\350\275\257\344\273\266/Python/jupyter\345\242\236\345\212\240\343\200\201\345\210\240\351\231\244\345\206\205\346\240\270.md" new file mode 100644 index 0000000..0d9a473 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/jupyter\345\242\236\345\212\240\343\200\201\345\210\240\351\231\244\345\206\205\346\240\270.md" @@ -0,0 +1,52 @@ +--- +title: jupyter增加、删除内核 +date: 2022-08-18 11:11:15 +updated: +categories: +- 学习 +tags: +- jupyter +- 快捷键 +keywords: +- jupyter +- 快捷键 +description: 适合win和mac的jupyter快捷键,学起来! +cover: https://clwasblog-1301107071.cos.ap-shanghai.myqcloud.com/doc/jupyter-notebook.png +top_img: https://img-blog.csdnimg.cn/img_convert/18f2cc96eac73b8c79991758e9323bf3.png +--- + +# 安装 + +```shell +pip install ipykernel -i https://pypi.tuna.tsinghua.edu.cn/simple +``` + +# 增加kernel + +为了隔离python环境,使用了[虚拟环境](https://so.csdn.net/so/search?q=虚拟环境&spm=1001.2101.3001.7020)。如果想在jupyter中使用这个虚拟环境,则需要把这个环境添加到jupyter里 + +```shell +source venv/bin/activate # 进入虚拟环境 +pip install ipykernel # 安装ipykernel +python -m ipykernel install --user --name=<kernel-name> +``` + +# 查看jupyter所有kernel + +这步的操作形同于:`conda env list` +```shell +jupyter kernelspec list +``` + +# 删除某个kernel + +```shell +jupyter kernelspec remove <kernel-name> +``` + +或 + +```shell +jupyter kernelspec uninstall <kernel-name> +``` + diff --git "a/docs/\350\275\257\344\273\266/Python/jupyter\345\270\270\347\224\250\346\223\215\344\275\234\345\222\214\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Python/jupyter\345\270\270\347\224\250\346\223\215\344\275\234\345\222\214\345\221\275\344\273\244.md" new file mode 100644 index 0000000..43f981e --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/jupyter\345\270\270\347\224\250\346\223\215\344\275\234\345\222\214\345\221\275\344\273\244.md" @@ -0,0 +1,89 @@ +--- +title: jupyter常用操作和命令 +date: 2022-08-18 11:11:15 +updated: +categories: +- 学习 +tags: +- jupyter +- 快捷键 +- 美化 +keywords: +- jupyter +- 快捷键 +- 美化 +description: 关于jupyter的知识 +cover: https://clwasblog-1301107071.cos.ap-shanghai.myqcloud.com/doc/jupyter-notebook.png +top_img: https://img-blog.csdnimg.cn/img_convert/18f2cc96eac73b8c79991758e9323bf3.png +--- + +## 增加、删除内核 + +### 安装轮子 + +```shell +pip install ipykernel -i https://pypi.tuna.tsinghua.edu.cn/simple +``` + +### 增加kernel + +为了隔离python环境,使用了[虚拟环境](https://so.csdn.net/so/search?q=虚拟环境&spm=1001.2101.3001.7020)。如果想在jupyter中使用这个虚拟环境,则需要把这个环境添加到jupyter里 + +```shell +source venv/bin/activate # 进入虚拟环境 +pip install ipykernel # 安装ipykernel +python -m ipykernel install --user --name=<kernel-name> +``` + +### 查看jupyter所有kernel + +这步的操作形同于:`conda env list` +```shell +jupyter kernelspec list +``` + +### 删除某个kernel + +```shell +jupyter kernelspec remove <kernel-name> +``` + +或 + +```shell +jupyter kernelspec uninstall <kernel-name> +``` + + + +> cover: https://www.nextplatform.com/wp-content/uploads/2021/02/Jupyter_main.png +> top_img: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR2g6gmpR19CGiHggS37HOXUu0X2Onr24whFbwI0pWFIthY2ry7NvkakcN6M7S5MCnrz9k&usqp=CAU + +## 更换主题 + +### 安装主题轮子 + +```shell +pip install jupyterthemes +``` + +### 查看可选择的主题 + +```shell +jt -l +``` + +### 安装主题 + +```shell +jt -t 主题名 -T -N![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/images) +``` + + + +> cover: https://clwasblog-1301107071.cos.ap-shanghai.myqcloud.com/doc/jupyter-notebook.png +> top_img: https://img-blog.csdnimg.cn/img_convert/18f2cc96eac73b8c79991758e9323bf3.png + +## jupyter notebook快捷键 + +![534772F4-4AAF-404E-B6E3-809A6C23F0E4_1_201_ab](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/534772F4-4AAF-404E-B6E3-809A6C23F0E4_1_201_ab.jpeg) diff --git "a/docs/\350\275\257\344\273\266/Python/jupyter\346\233\264\346\215\242\344\270\273\351\242\230.md" "b/docs/\350\275\257\344\273\266/Python/jupyter\346\233\264\346\215\242\344\270\273\351\242\230.md" new file mode 100644 index 0000000..551daa6 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/jupyter\346\233\264\346\215\242\344\270\273\351\242\230.md" @@ -0,0 +1,35 @@ +--- +title: jupyter更换主题 +date: 2022-08-18 16:24:15 +updated: +categories: +- 学习 +tags: +- jupyter +- 美化 +keywords: +- jupyter +- 美化 +description: 给jupyter更换舒适的主题 +cover: https://www.nextplatform.com/wp-content/uploads/2021/02/Jupyter_main.png +top_img: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR2g6gmpR19CGiHggS37HOXUu0X2Onr24whFbwI0pWFIthY2ry7NvkakcN6M7S5MCnrz9k&usqp=CAU + +--- + +# 安装 + +```shell +pip install jupyterthemes +``` + +# 查看可选择的主题 + +```shell +jt -l +``` + +# 安装主题 + +```shell +jt -t 主题名 -T -N![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/images) +``` diff --git "a/docs/\350\275\257\344\273\266/Python/torch\345\270\270\347\224\250\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/Python/torch\345\270\270\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..b88bdc9 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/torch\345\270\270\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,105 @@ +--- +title: torch常用命令 +date: 2023-06-12 15:27:15 +updated: +categories: +- 学习 +tags: +- torch +- 深度学习 +keywords: +- torch +- 深度学习 +description: 通过torch查看信息 +cover: https://pytorch.org/tutorials/_static/img/thumbnails/cropped/profiler.png +top_img: https://imagingsolution.net/wordpress/wp-content/uploads/2022/03/pytorch_logo_icon.png +top: 200 +--- + +# 1、服务器信息查询 + +## `CPU`查询 + +```shell +# 查看CPU信息 +cat /proc/cpuinfo | grep "physical id" | uniq | wc -l #查看CPU个数 +cat /proc/cpuinfo | grep "cpu cores" | uniq #查看CPU核数 +cat /proc/cpuinfo | grep 'model name' |uniq #查看CPU型号 +``` + +## `GPU`查询 + +```shell +# 查看GPU信息 +sudo dpkg --list | grep nvidia-* # 查看驱动版本 +lshw -c video #查看显卡型号 +$ lspci | grep -i nvidia # 可以查询所有nvidia显卡 +$ lspci -v -s [显卡编号] # 可以查看显卡具体属性 +$ nvidia-smi # 可以查看显卡的显存利用率 +$ cat /etc/issue # 查看Linux发布版本号 +$ lsb_release -a # 查看Linux发布版本号 +$ uname -sr # 查看内核版本号 +$ uname -a # 查看内核版本号 +``` + +`lspci`是一种实用程序,用于在系统中显示有关[pci总线](https://so.csdn.net/so/search?q=pci总线&spm=1001.2101.3001.7020)的信息以及连接到它们的设备。 + +## `CUDA`版本 + +```shell +nvidia-smi # 右上角CUDA Version,但可能不准确,推荐使用nvcc -V +nvcc -V # 建议以nvcc -V查询为主 +``` + +![在这里插入图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/19b97250915d432f8af3cea56df6db2c.png) + +## 实时查看`nvidia-smi` + +```shell +nvidia-smi -l 1 # 以每秒刷新一次进行信息,结果为1s一次输出nvidia-smi,不流畅,建议使用吓一条命令 +watch -n 1 nvidia-smi # 会在同一位置处1s更新窗口信息 +``` + +# 2、显卡信息查看 + +```python +torch.cuda.is_available() # 查看是否有可用GPU +torch.cuda.device_count() # 查看GPU数量 +torch.cuda.get_device_capability(device) # 查看指定GPU容量 +torch.cuda.get_device_name(device) # 查看指定GPU名称 +torch.cuda.empty_cache() # 清空程序占用的GPU资源 +torch.cuda.manual_seed(seed) # 设置随机种子 +torch.cuda.manual_seed_all(seed) # 设置随机种子 +torch.cuda.get_device_properties(i) # i为第几张卡,显示该卡的详细信息 +``` + +# 3、输出模型增肌信息 + +```python +s = f'MODEL 🚀 torch {torch.__version__} ' + n = torch.cuda.device_count() + space = ' ' * (len(s)+1) + for d in range(n): + p = torch.cuda.get_device_properties(d) + s += f"{'' if d == 0 else space}CUDA:{d} ({p.name}, {p.total_memory / 1024 ** 2}MB)\n" # bytes to MB + print(s) +``` + +![在这里插入图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/230468572b0048dcb2eb1de6f79a9823.png) + +# 4、指定使用显卡 + +通过`os.environ["CUDA_VISIBLE_DEVICES"]`指定所要使用的显卡: + +```python +import os +os.environ['CUDA_VISIBLE_DEVICES'] = "2,1,3,4" +print("torch.cuda.device_count() {}".format(torch.cuda.device_count())) +``` + +这种设置方式,`2`号卡就变成了主卡。`CUDA_VISIBLE_DEVICES `表示当前可以被python环境程序检测到的显卡。`os.environ["CUDA_VISIBLE_DEVICES"] = "2,1,3,4"`进行指定使用设备,这样会修改`pytorch`感受的设备编号,`pytorch`感知的编号还是从`device:0`开始。如上会把`2`号显卡改为`device:0`,`1`号显卡改为`device:1`。 + +如果有多个显卡,设置了`os.environ["CUDA_VISIBLE_DEVICES"]`后,其他没有设置的显卡将不会在本次代码中显示。`os.environ["CUDA_VISIBLE_DEVICES"]`需要设置在代码开头。 + +另外,使用终端也可以直接选择选择显卡,输入`CUDA_VISIBLE_DEVICES=0 python train.py`也可以 + diff --git "a/docs/\350\275\257\344\273\266/Python/\344\272\272\345\267\245\346\231\272\350\203\275\345\215\201\345\244\247\347\256\227\346\263\225.md" "b/docs/\350\275\257\344\273\266/Python/\344\272\272\345\267\245\346\231\272\350\203\275\345\215\201\345\244\247\347\256\227\346\263\225.md" new file mode 100644 index 0000000..ca7cb1f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/\344\272\272\345\267\245\346\231\272\350\203\275\345\215\201\345\244\247\347\256\227\346\263\225.md" @@ -0,0 +1,162 @@ +--- +title: 人工智能十大算法 +date: 2022-03-27 08:28:15 +updated: +categories: +- 学习 +tags: +- 人工智能 +- 算法 +keywords: +- 线性回归 +- 逻辑回归 +- 决策树 +- 朴素贝叶斯 +- 支持向量机 +- 最近邻 +- 随机森林 +- 降维 +- 神经网络 +description: 几种比较知名的人工智能算法 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/人工智能图片.jpeg +top_img: https://pica.zhimg.com/50/v2-7100922719a47ff8e9bf353665ca3628_bh.jpg + +--- + +**人工智能是什么?**很多人都知道,但大多又都说不清楚。 + +事实上,人工智能已经存在于我们生活中很久了。 + +- 比如我们常常用到的邮箱,其中垃圾邮件过滤就是依靠人工智能; +- 比如每个智能手机都配备的指纹识别或人脸识别,也是用人工智能技术实现的; +- 比如疫情期间大规模使用的无人体温检测仪,同样也使用了人工智能; + +但对很多人来讲,人工智能还是一个较为“高深”的技术,然而再高深的技术,也是从基础原理开始的。 + +人工智能领域中就流传着10大算法,它们的原理浅显,很早就被发现、应用,甚至你在中学时就学过,在生活中也都极为常见。 + +## **一、线性回归** + +**线性回归(Linear Regression)**可能是最流行的机器学习算法。线性回归就是要找一条直线,并且让这条直线尽可能地拟合散点图中的数据点。它试图通过将直线方程与该数据拟合来表示自变量(x 值)和数值结果(y 值)。然后就可以用这条线来预测未来的值! + +这种算法最常用的技术是**最小二乘法(Least of squares)**。这个方法计算出最佳拟合线,以使得与直线上每个数据点的垂直距离最小。总距离是所有数据点的垂直距离(绿线)的平方和。其思想是通过最小化这个平方误差或距离来拟合模型。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2Fba86266cj00r31ji6000jd200me00eeg00bd007a.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +例如,简单线性回归,它有一个自变量(x 轴)和一个因变量(y 轴)。 + +比如预测明年的房价涨幅、下一季度新产品的销量等等。听起来并不难,不过线性回归算法的难点并不在于得出预测值,而在于如何更精确。为了那个可能十分细微的数字,多少工程师为之耗尽了青春和头发。 + +## **二、逻辑回归** + +**逻辑回归(Logistic regression)**与线性回归类似,但逻辑回归的结果只能有两个的值。如果说线性回归是在预测一个开放的数值,那逻辑回归更像是做一道是或不是的判断题。 + +逻辑函数中Y值的范围从 0 到 1,是一个概率值。逻辑函数通常呈S 型,曲线把图表分成两块区域,因此适合用于分类任务。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F1b0b9a05j00r31ji6000jd200q200e3g00dg0079.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +比如上面的逻辑回归曲线图,显示了通过考试的概率与学习时间的关系,可以用来预测是否可以通过考试。 + +逻辑回归经常被电商或者外卖平台用来预测用户对品类的购买偏好。 + +## **三、决策树** + +如果说线性和逻辑回归都是把任务在一个回合内结束,那么**决策树(Decision Trees)**就是一个多步走的动作,它同样用于回归和分类任务中,不过场景通常更复杂且具体。 + +举个简单例子,老师面对一个班级的学生,哪些是好学生?如果简单判断考试90分就算好学生好像太粗暴了,不能唯分数论。那面对成绩不到90分的学生,我们可以从作业、出勤、提问等几个方面分开讨论。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F9c87e3f4j00r31ji6000kd200dm00d5g00ai00a4.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +以上就是一个决策树的图例,其中每一个有分叉的圈称为节点。在每个节点上,我们根据可用的特征询问有关数据的问题。左右分支代表可能的答案。最终节点(即叶节点)对应于一个预测值。 + +每个特征的重要性是通过自顶向下方法确定的。节点越高,其属性就越重要。比如在上面例子中的老师就认为出勤率比做作业重要,所以出勤率的节点就更高,当然分数的节点更高。 + +## **四、朴素贝叶斯** + +**朴素贝叶斯(Naive Bayes)**是基于贝叶斯定理,即两个条件关系之间。 它测量每个类的概率,每个类的条件概率给出 x 的值。 这个算法用于分类问题,得到一个二进制“是 / 非”的结果。 看看下面的方程式。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F6fed0894j00r31ji7000ad200ah006hg00a00066.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +朴素贝叶斯分类器是一种流行的统计技术,经典应用是过滤垃圾邮件。 + +当然,小编赌一顿火锅,80%的人没看懂上面这段话。(80%这个数字是小编猜的,但经验直觉就是一种贝叶斯式的计算。) + +用非术语解释贝叶斯定理,就是通过A条件下发生B的概率,去得出B条件下发生A的概率。比如说,小猫喜欢你,有a%可能性在你面前翻肚皮,请问小猫在你面前翻肚皮,有多少概率喜欢你? + +当然,这样做题,等于抓瞎,所以我们还需要引入其他数据,比如小猫喜欢你,有b%可能和你贴贴,有c%概率发出呼噜声。所以我们如何知道小猫有多大概率喜欢自己呢,通过贝叶斯定理就可以从翻肚皮,贴贴和呼噜的概率中计算出来。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2Fe9a2150bj00r31ji70010d200j600egg009f0073.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +猫:别算了,我不喜欢你 + +## **五、支持向量机** + +**支持向量机(Support Vector Machine,SVM)**是一种用于分类问题的监督算法。支持向量机试图在数据点之间绘制两条线,它们之间的边距最大。为此,我们将数据项绘制为 n 维空间中的点,其中,n 是输入特征的数量。在此基础上,支持向量机找到一个最优边界,称为超平面(Hyperplane),它通过类标签将可能的输出进行最佳分离。 + +超平面与最近的类点之间的距离称为边距。最优超平面具有最大的边界,可以对点进行分类,从而使最近的数据点与这两个类之间的距离最大化。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F3d2da9c1j00r31ji7000hd200hu00fag007v006q.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +所以支持向量机想要解决的问题也就是如何把一堆数据做出区隔,它的主要应用场景有字符识别、面部识别、文本分类等各种识别。 + +## **六、K- 最近邻算法(KN****N)** + +**K- 最近邻算法(K-Nearest Neighbors,KNN)**非常简单。KNN 通过在整个训练集中搜索 K 个最相似的实例,即 K 个邻居,并为所有这些 K 个实例分配一个公共输出变量,来对对象进行分类。 + +K 的选择很关键:较小的值可能会得到大量的噪声和不准确的结果,而较大的值是不可行的。它最常用于分类,但也适用于回归问题。 + +用于评估实例之间相似性的距离可以是欧几里得距离(Euclidean distance)、曼哈顿距离(Manhattan distance)或明氏距离(Minkowski distance)。欧几里得距离是两点之间的普通直线距离。它实际上是点坐标之差平方和的平方根。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F3ff5ef93j00r31ji7000gd200hd00esg007j006e.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +KNN分类示例 + +KNN理论简单,容易实现,可用于文本分类、模式识别、聚类分析等。 + +**七、K-均值** + +**K-均值(K-means)**是通过对数据集进行分类来聚类的。例如,这个算法可用于根据购买历史将用户分组。它在数据集中找到 K 个聚类。K- 均值用于无监督学习,因此,我们只需使用训练数据 X,以及我们想要识别的聚类数量 K。 + +该算法根据每个数据点的特征,将每个数据点迭代地分配给 K 个组中的一个组。它为每个 K- 聚类(称为质心)选择 K 个点。基于相似度,将新的数据点添加到具有最近质心的聚类中。这个过程一直持续到质心停止变化为止。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2Ffc9d0ef7j00r31ji70013d200u000bqg00hx0070.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +生活中,K-均值在欺诈检测中扮演了重要角色,在汽车、医疗保险和保险欺诈检测领域中广泛应用。 + +## **八、随机森林** + +**随机森林(Random Forest)**是一种非常流行的集成机器学习算法。这个算法的基本思想是,许多人的意见要比个人的意见更准确。在随机森林中,我们使用决策树集成(参见决策树)。 + +(a)在训练过程中,每个决策树都是基于训练集的引导样本来构建的。 + +(b)在分类过程中,输入实例的决定是根据多数投票做出的。 + +随机森林拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来源、保留及流失,也可以用来预测疾病的风险和病患者的易感性。 + +## **九、降维** + +由于我们今天能够捕获的数据量之大,机器学习问题变得更加复杂。这就意味着训练极其缓慢,而且很难找到一个好的解决方案。这一问题,通常被称为**“维数灾难”(Curse of dimensionality)**。 + +降维(Dimensionality reduction)试图在不丢失最重要信息的情况下,通过将特定的特征组合成更高层次的特征来解决这个问题。主成分分析(Principal Component Analysis,PCA)是最流行的降维技术。 + +主成分分析通过将数据集压缩到低维线或超平面 / 子空间来降低数据集的维数。这尽可能地保留了原始数据的显著特征。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2F885454cfj00r31ji80009d200n000apg008x0045.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +可以通过将所有数据点近似到一条直线来实现降维的示例。 + +## **十、人工神经网络(ANN)** + +**人工神经网络(Artificial Neural Networks,ANN)**可以处理大型复杂的机器学习任务。神经网络本质上是一组带有权值的边和节点组成的相互连接的层,称为神经元。在输入层和输出层之间,我们可以插入多个隐藏层。人工神经网络使用了两个隐藏层。除此之外,还需要处理深度学习。 + +人工神经网络的工作原理与大脑的结构类似。一组神经元被赋予一个随机权重,以确定神经元如何处理输入数据。通过对输入数据训练神经网络来学习输入和输出之间的关系。在训练阶段,系统可以访问正确的答案。 + +如果网络不能准确识别输入,系统就会调整权重。经过充分的训练后,它将始终如一地识别出正确的模式。 + +![img](https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1124%2Fc7b8a0f4j00r31ji90010d200og00jqg007z006f.jpg&thumbnail=660x2147483647&quality=80&type=jpg) + +每个圆形节点表示一个人工神经元,箭头表示从一个人工神经元的输出到另一个人工神经元的输入的连接。 + +**图像识别**,就是神经网络中的一个著名应用。 + +现在,你已经了解了最流行的人工智能算法的基础介绍,并且,对它们的实际应用也有了一定认识。 diff --git "a/docs/\350\275\257\344\273\266/Python/\345\233\276\345\203\217\345\244\204\347\220\206\346\250\241\345\235\227\345\260\201\350\243\205\345\207\275\346\225\260.md" "b/docs/\350\275\257\344\273\266/Python/\345\233\276\345\203\217\345\244\204\347\220\206\346\250\241\345\235\227\345\260\201\350\243\205\345\207\275\346\225\260.md" new file mode 100644 index 0000000..63ce2c1 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/\345\233\276\345\203\217\345\244\204\347\220\206\346\250\241\345\235\227\345\260\201\350\243\205\345\207\275\346\225\260.md" @@ -0,0 +1,91 @@ +--- +title: 图像处理模块封装函数 +date: 2022-09-26 16:24:15 +updated: +categories: +- 学习 +tags: +- 图像处理 +- PIL +- opencv +- 图像处理 +- PIL +- opencv +description: 一种在图像处理时便于显示图像的方法(附带源码) +cover: https://pic4.zhimg.com/v2-1067e4845923cd36e185c33a1bc9b790_1440w.jpg?source=172ae18b +top_img: https://pic2.zhimg.com/v2-f704cff60610715b37b1c8e8270eb0c2_720w.jpg?source=172ae18b +--- + +# 图像处理导入模块和封装好的函数 + +```python +import numpy as np + + +import matplotlib.pyplot as plt + +# 修复pyplot的中文乱码 +plt.rcParams['font.sans-serif'] = ['SimHei'] + +# 调整全局图表大小 +# print("默认图片大小是 ", plt.rcParams["figure.figsize"]) # (4, 8) +# plt.rcParams["figure.figsize"] = (4, 8) +# print("修改后默认图片大小是", plt.rcParams["figure.figsize"]) # (a, b),以上面那行为准 + + + +from PIL import Image +import cv2 as cv + +# 为opencv和PIL提供的图片显示方式,可选参数为标题title,使用matplotlib的方式显示图片,会在cell格下生成一个图标 +def show(img, title='null'): + # 如果是数组类型,就按照opencv的步骤显示图片 + if type(img) == np.ndarray: + if img.ndim == 2: + plt.imshow(img,cmap='gray') + else : + plt.imshow(cv.cvtColor(img,cv.COLOR_BGR2RGB)) # opencv的通道顺序为[B,G,R],而matplotlib通道顺序为[R,G,B],需要调换一下 + #如果不是数组类型,就按照PIL的步骤显示图片 + # img.show() PIL推荐的方法,会使用系统自带的看图软件打开 + else: + img_ndim = len(np.array(img).shape) + if img_ndim == 3: + plt.imshow(img) # PIL格式图片不需要进行BGR2RGB转换 + elif img_ndim == 2: + plt.imshow(img, cmap='gray') + else: + print("PIL类型图片的维度异常,维度:",img_ndim) + if title != 'null': + plt.title(title, fontsize=18) + plt.show() + +# 为opencv提供的图片显示方式,标题为可选选参数,会打开一个尺寸和原图一样的系统窗口 +# bug: windwos下正常,macos下会卡死 +def show_cv(img, title='123'): + cv.namedWindow(title,flags=cv.WINDOW_NORMAL) + h,w,r = img2.shape + cv.resizeWindow(title,w,h) + cv.imshow(title,img) + cv.waitKey(0) + cv.destroyAllWindows() + _ = cv.waitKey(1) +``` + +# 使用封装函数显示图像 + +```shell +# 兼容PIL和opencv的导入 +img1 = Image.open('pic/8.jpg') +img2 = cv.imread('pic/9.jpg') +show(img1,'悉尼歌剧院') +show(img2,'tiger') +``` + +# 实际使用 + +1. 在jupter中新建一个notebook +2. 导入一下模块和函数 + <img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220926162112262.png" alt="image-20220926162112262" style="zoom:50%;" /> +3. 再使用PIL和opencv加载两张不同的图片,成功了!只需要调用show()方法就能显示图片了,相比调用系统看图文件看图方便多啦! + + <img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/image-20220926162157838.png" style="zoom:50%;" /> diff --git "a/docs/\350\275\257\344\273\266/Python/\350\247\243\345\206\263Anaconda\345\256\211\350\243\205\345\220\216\345\221\275\344\273\244\350\241\214\345\211\215\345\207\272\347\216\260 (base).md" "b/docs/\350\275\257\344\273\266/Python/\350\247\243\345\206\263Anaconda\345\256\211\350\243\205\345\220\216\345\221\275\344\273\244\350\241\214\345\211\215\345\207\272\347\216\260 (base).md" new file mode 100644 index 0000000..3a9a9d0 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Python/\350\247\243\345\206\263Anaconda\345\256\211\350\243\205\345\220\216\345\221\275\344\273\244\350\241\214\345\211\215\345\207\272\347\216\260 (base).md" @@ -0,0 +1,34 @@ +--- +title: 解决Anaconda安装后命令行前出现 (base) +date: 2022-03-25 13:53:15 +updated: +categories: +- 学习 +tags: +- Anaconda +keywords: +- Anaconda +description: 解决Mac下Anaconda安装后的小麻烦 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212219583.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212219245.png +--- + +### 方法一: + +每次在命令行通过conda deactivate退出base环境回到系统自带的环境 + +### 方法二 + +1,通过将auto_activate_base参数设置为false实现: + +```shell +conda config --set auto_activate_base false +``` + +2,那要进入的话通过conda activate base + +3,如果反悔了还是希望base一直留着的话通过来恢复 + +```shell +conda config --set auto_activate_base true +``` diff --git "a/docs/\350\275\257\344\273\266/Windows/VMware\345\233\272\345\256\232\350\231\232\346\213\237\346\234\272ip.md" "b/docs/\350\275\257\344\273\266/Windows/VMware\345\233\272\345\256\232\350\231\232\346\213\237\346\234\272ip.md" new file mode 100644 index 0000000..e48926e --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/VMware\345\233\272\345\256\232\350\231\232\346\213\237\346\234\272ip.md" @@ -0,0 +1,80 @@ +--- +title: VMware固定虚拟机ip +date: 2023-12-24 15:06:00 +updated: 2024-09-21 22:47:00 +categories: +- 学习 +tags: +- VMware +- 虚拟机 +- Linux +- ip +keywords: +- VMware +- 虚拟机 +- Linux +- ip +description: 在Vmware中固定虚拟机的ip地址 +cover: https://i0.wp.com/www.techjunkie.com/wp-content/uploads/2020/03/How-to-Create-Virtual-Machine-From-a-Physical-Machine-in-VMWare.jpg?resize=400%2C202&ssl=1 +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202312241509647.pngq +--- + +> ## 起因 +> +> 在学习微服务过程中,由于电脑数据要迁移,因此虚拟机的ip也发生了变化,但是新装的VMware总是会改变虚拟机的ip,因此出此文档记录如何在VMware中固定虚拟机的ip地址,这样可以免去修改微服务中的一些配置。 + +## 修改配置文件 + +```shell +vi /etc/sysconfig/network-scripts/ifcfg-ens33 +``` + +修改里面的`BOOTPROTO`,把`DHCP`改为`static` + +``` +BOOTPROTO="static" +``` + +添加 + +``` +IPADDR=192.168.179.129 # 想要固定的ip +NETMASK=255.255.255.0 # 子网掩码 +GATEWAY=192.168.179.2 # 网关和VM虚拟机编辑中中设置的一样 +DNS1=192.168.179.2 # DNS1和网关一样 +``` + +## 重启网络 + +```shell + systemctl restart network +``` + +这个过程中可能会报错,例如: + +> Job for network.service failed... + +此时可以将networkmanager服务停了: + +```shell +systemctl stop NetworkManager +systemctl disable NetworkManager +``` + +重启网卡,就ok了 + +```shell +systemctl restart network +systemctl status network +``` + +查看所有已安装服务 + + ```shell + systemctl list-units --type=service + ``` + +IP绑定成功,结束! + +![image-20231215155034126 - 副本](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202312151727007.png) + diff --git "a/docs/\350\275\257\344\273\266/Windows/Windows\344\270\212\350\247\243\345\206\263\347\253\257\345\217\243\345\215\240\347\224\250.md" "b/docs/\350\275\257\344\273\266/Windows/Windows\344\270\212\350\247\243\345\206\263\347\253\257\345\217\243\345\215\240\347\224\250.md" new file mode 100644 index 0000000..950151e --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/Windows\344\270\212\350\247\243\345\206\263\347\253\257\345\217\243\345\215\240\347\224\250.md" @@ -0,0 +1,70 @@ +--- +title: Windows上解决端口占用 +date: 2022-08-20 16:30:00 +updated: +categories: +- 软件 +tags: +- Windows +- 端口占用 +keywords: +- Windows +- 端口占用 +description: 利用命令行解决Windows上的端口占用 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/897393-20180808081044172-1318415163.png +top_img: https://img-blog.csdnimg.cn/img_convert/59fd236da82b50799be27b20c64bf959.png + +--- +参考网址: + +> [解决端口占用问题(port is already in use)_奔跑的大白啊的博客-CSDN博客_端口占用](https://blog.csdn.net/zt15732625878/article/details/80904437) + +### 1、windows+R 组合键,调出命令行窗口 + +![这里写图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/70.jpeg) + +### 2、查找占用端口对应的PID(进程号) + +```shell +# 列出所有端口占用情况 +netstat -ano +# 精确找到被占用的端口对应的PID +netstat -ano|findstr "port" +# 示例 +netstat -ano|findstr "6644" +``` + +![这里写图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/70.png) + +![这里写图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/70-20220820165351491.png) + +### 3、查看是哪个进程或程序占用了端口 + +```shell +tasklist|findstr "PID" +# 示例 +tasklist|findstr "4" +``` + +![这里写图片描述](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/70-20220820165359174.png) + +### 4、通过命令结束进程 + +```shell +taskkill /f /t /im xx进程 +# 示例 +taskkill /f /t /im System +``` + +### 5、命令解析 + +| 命令 | 描述 | +| ------------ | ---------------------------------------------------------- | +| netstat | 显示协议统计信息和当前TCP/IP网络连接 | +| netstat | 查看当前哪些端口正在被使用 | +| findstr | 查找字符串,类似Linux下的grep命令 | +| tasklist | 显示运行在本地或远程计算机上的所有任务的应用程序和服务列表 | +| taskkill | 结束一个或多个任务或进程 | +| taskkill /f | 指定强制终止的过程(我觉得是进程) | +| taskkill /t | 指定那个终止与父进程一起的所有子进程,常被认为是“树终止” | +| taskkill /im | imageName 指定将被终止的过程的图像名称 | \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Windows/index.md" "b/docs/\350\275\257\344\273\266/Windows/index.md" new file mode 100644 index 0000000..714143b --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/index.md" @@ -0,0 +1 @@ +## Windows \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Windows/win11\345\256\211\350\243\205\345\215\270\350\275\275\345\256\211\345\215\223\350\275\257\344\273\266.md" "b/docs/\350\275\257\344\273\266/Windows/win11\345\256\211\350\243\205\345\215\270\350\275\275\345\256\211\345\215\223\350\275\257\344\273\266.md" new file mode 100644 index 0000000..afa78ab --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/win11\345\256\211\350\243\205\345\215\270\350\275\275\345\256\211\345\215\223\350\275\257\344\273\266.md" @@ -0,0 +1,50 @@ +--- +title: win11安装卸载安卓软件 +date: 2023-07-20 13:32:15 +updated: +categories: +- 软件 +tags: +- Windows +- Android +keywords: +- Windows +- Android +description: 在windows11上使用安卓软件 +cover: https://img4.xitongzhijia.net/allimg/220916/141-2209160946201R.jpg +top_img: https://imgslim.geekpark.net/uploads/image/file/0f/88/0f887f8faebdef731f396fe20fa7a78a.jpg +--- + +### 前置操作 + +- 开启CPU虚拟化 +- “区域”设置中将地区改为“美国” +- 微软商店下载“Windows Subsystem for Android with Amazon” +- 打开“Windows Subsystem for Android”的开发人员模式 + +### 常用命令 + +连接端口: + +```shell +adb connect 127.0.0.1:58526 +``` + +安装软件: + +```shell +adb install 'G:\Software\Android实用软件\XXX.apk' +``` + +卸载软件: + +```shell +按照windows卸载方式卸载即可 +``` + +### 参考文章: + +> [win11系统安装安卓应用教程 - 系统城装机大师 (pcxitongcheng.com)](http://www.pcxitongcheng.com/xtjc/win11/2023-06-22/37257.html) +> +> [Windows11安卓子系统怎么安装和卸载安卓APK (0451nkw.com)](http://www.0451nkw.com/jiaocheng/315869.html) + diff --git "a/docs/\350\275\257\344\273\266/Windows/windows\347\273\210\347\253\257\347\276\216\345\214\226.md" "b/docs/\350\275\257\344\273\266/Windows/windows\347\273\210\347\253\257\347\276\216\345\214\226.md" new file mode 100644 index 0000000..cab475f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/windows\347\273\210\347\253\257\347\276\216\345\214\226.md" @@ -0,0 +1,275 @@ +--- +title: windows终端美化 +date: 2024-10-27 15:19:00 +updated: +categories: +- 软件 +tags: +- windows +- 终端 +- ohmyposh +keywords: +- windows +- 终端 +- ohmyposh +description: Terminal + oh-my-posh +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410271521094.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410271521546.png +--- + +> 俗话说,RGB就是战斗力,颜值就是生产力!所以,max和linux有iTerm + ohmyzsh,windows就有Terminal + ohmyposh +> +> 这次就来折腾一下,还是挺方便的。 + +## 1. 去微软商店下载 `Windows Terminal` + +## 2. 安装Chocolatey + +在[Chocolatey Software | Installing Chocolatey](https://chocolatey.org/install)网页下,复制安装脚本 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/135dba74fade69aaada79a0025f5312e.png" alt="img" style="zoom: 50%;" /> + +Chocolatey安装脚本 + +```shell +Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) +``` + +复制到终端中 + +即可自动安装`Chocolatey` + +使用`choco -v`检查一下 + +## 3. 设置管理员权限启动 + +启用管理员模式,不然后面可能会权限不足,安装失败。 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/cebec2ec3649bda0fb0350cdf9c7b2e1.png" alt="img" style="zoom:67%;" /> + +## 4. 安装字体 + +推荐使用等宽连体带图标(终端显示的花样多一点)的字体 + +如果用默认字体,ohmyposh会乱码 + +我使用[Nerd Fonts](https://www.nerdfonts.com/) + +安装使用`Chocolatey`即可 + +```shell +choco install nerd-fonts-hack +``` + +## 5. 编辑windows terminal 配置使用Nerd Fonts字体 + +这里很多人都会去下载一个powershell,其实没有必要,Windows自带的powershell的版本和功能已经可以满足要求。 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/e0547c1027f29d4dc2590790efab2f4c.png" alt="img" style="zoom:67%;" /> + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/ebeaabf0f74eb37d41173f7f4bfbbc47.png" alt="img" style="zoom:67%;" /> + +当然也可以直接使用配置文件,`"defaults"`在`"profiles"`属性下 + +``` +json"defaults": +{ + "backgroundImage": null, + "colorScheme": "Campbell", + "cursorShape": "filledBox", + "experimental.retroTerminalEffect": false, + "font": + { + "face": "CodeNewRoman Nerd Font Mono", + "size": 14.0, + "weight": "normal" + }, + "opacity": 90, + "padding": "0", + "scrollbarState": "hidden", + "useAcrylic": false +}, +``` + +其余的配置文件内容 + +``` +json"copyFormatting": "none", +"copyOnSelect": false, +"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", +"alwaysOnTop": false, +"alwaysShowTabs": true, +"autoHideWindow": false, +"disableAnimations": false, +"firstWindowPreference": "defaultProfile", +"focusFollowMouse": false, +"initialCols": 88, +"initialPosition": "750,350", +"initialRows": 24, +"launchMode": "focus", +``` + +大概在这个行数 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/075e892a965f8d16d6aae7516bf7a769.png" alt="img" style="zoom:67%;" /> + +添加快捷键 + +``` +json"actions": +[ + { + "command": + { + "action": "copy", + "singleLine": false + }, + "keys": "ctrl+c" + }, + { + "command": "paste", + "keys": "ctrl+v" + }, + { + "command": + { + "action": "splitPane", + "split": "auto", + "splitMode": "duplicate" + }, + "keys": "alt+shift+d" + }, + { + "command": "find", + "keys": "ctrl+shift+f" + }, + { + "command": "toggleFocusMode", + "keys": "alt+z" + } +], +``` + +这样可以使用`alt+z`打开标题栏 + +## 5. 允许终端运行本地脚本 + +输入这个命令即可 + +```shell +set-ExecutionPolicy RemoteSigned +``` + +这一步是确保后面终端自动使用ohmyposh启动 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/77680a9388ce0afedeffe5407637f452.png" alt="img" style="zoom:80%;" /> + +## 6. 安装oh-my-posh + +1. 安装`oh-my-posh` + + ```shell + choco install oh-my-posh + ``` + +2. 创建`powershell`配置文件 + + ```shell + if (!(Test-Path -Path $PROFILE )) { New-Item -Type File -Path $PROFILE -Force } + ``` + +3. 打开配置文件 + + ```shell + notepad $PROFILE + ``` + +4. 写入指令,这里是让终端在启动时加载`oh-my-posh`配置文件,其中`~/.omp.theme.json`是配置文件的所在路径,windows的话就是在`C:\Users\Administrator`下创建`.omp.theme.json`文件并写入配置即可 + + ```shell + oh-my-posh init pwsh --config ~/.omp.theme.json | Invoke-Expression + ``` + +5. 关闭启动时的banner,添加`-nologo`项即可 + +<img src="https://picgo-img-repo.oss-cn-beijing.aliyuncs.com/img/3714b3074d1258af263f5a066f6e03c5.png" alt="img" style="zoom:67%;" /> + +## 7. 安装自动补全插件 + +1. 先安装最新的`PowerShellGet` + + ```shell + bashInstall-Module -Name PowerShellGet -Force + Exit + ``` + +2. 再安装`PSReadLine` + + ```shell + Install-Module PSReadLine -AllowPrerelease -Force + ``` + +3. 在`powsershell`输入 + + ```shell + notepad.exe $PROFILE + ``` + +4. 在打开的界面输入下面内容 + + ```shell + bashSet-PSReadLineKeyHandler -Key Tab -Function MenuComplete #Tab键会出现自动补全菜单 + Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward + Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward + # 上下方向键箭头,搜索历史中进行自动补全 + ``` + +5. 保存重启`powershell`即可 + +## 8. 安装oh-my-posh主题 + +1. 查看 `oh-my-posh` 提供的所有主题: + + ```shell + Get-PoshThemes + ``` + +2. 预览一个主题(将 `name.omp.json` 替换为你想要的主题名称): + + ```shell + oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\your_theme.omp.json" | Invoke-Expression + ``` + +3. 设置默认主题 + + 1. 编辑 PowerShell 配置文件 + + ```shell + notepad $PROFILE + ``` + + 2. 将以下命令添加到文件中(将 `your_theme.omp.json` 替换为你选择的主题): + + ```shell + oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\your_theme.omp.json" | Invoke-Expression + ``` + +4. 自定义主题 + + 1. 查看主题的配置文件目录,我的是在 `C:\Program Files (x86)\oh-my-posh\themes` + + ```shell + echo $env:POSH_THEMES_PATH + ``` + + 2. 直接编辑 `your_theme.omp.json` 文件。也可以在文件中更改提示符的布局、颜色和显示信息等。配置项的说明可以在 [oh-my-posh]([oh-my-posh/themes at main · JanDeDobbeleer/oh-my-posh](https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/themes)) 官方文档 中找到。 + +> 友情链接: +> +> [Themes | Oh My Posh](https://ohmyposh.dev/docs/themes#json) +> +> [oh-my-posh/themes at main · JanDeDobbeleer/oh-my-posh](https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/themes) + +## 9. 展示 + +<img src="https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410252354435.png" alt="image-20241025235417348" style="zoom:80%;" /> \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/Windows/win\346\211\271\351\207\217\345\210\240\351\231\244\347\211\271\345\256\232\346\240\274\345\274\217\345\274\200\345\244\264\347\232\204\346\226\207\344\273\266.md" "b/docs/\350\275\257\344\273\266/Windows/win\346\211\271\351\207\217\345\210\240\351\231\244\347\211\271\345\256\232\346\240\274\345\274\217\345\274\200\345\244\264\347\232\204\346\226\207\344\273\266.md" new file mode 100644 index 0000000..05effc3 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/win\346\211\271\351\207\217\345\210\240\351\231\244\347\211\271\345\256\232\346\240\274\345\274\217\345\274\200\345\244\264\347\232\204\346\226\207\344\273\266.md" @@ -0,0 +1,36 @@ +--- +title: win批量删除特定格式开头的文件 +date: 2022-12-15 20:44:15 +updated: +categories: +- 软件 +tags: +- Windows +keywords: +- Windows +description: 一种批量删除.DS_Store和._文件的办法 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/62637770440134478jpg_fo742.jpg +top_img: https://miro.medium.com/max/920/1*dkE1TrK5K3jlSA0gY1-ggQ.png +--- + +博主将文件从MacOS拷贝到Windows时,经常会遇到有很多.DS_Store和.\_的文件,这些在MacOS里用来保存类型和创建者代码、修改日期、图标等信息的。 + +但是MacOS因为有一个孪生文件系统:数据分叉和资源分叉,所以不会显示,而Windows只有一个数据分支。所以Windows用户会看到这些文件,这些文件不仅看着烦,而且占屏幕空间,所以最好删了。 + +下面介绍一下方法,用Windows自带的**命令行**就行。 + +> 列出当前目录及所有子目录所有以._开头的文件 + +```shell +dir ._* /a/s +``` + +> 删除当前目录及所有子目录所有以._开头的文件 + +```shell +del ._* /a/s +``` + +**警告:不要直接用.\*删除,因为你可能误删一些重要文件,比如:.gitignore等文件** + +大功告成!再也没有那些烦人的文件了,文件夹一下子变得清爽了很多。 diff --git "a/docs/\350\275\257\344\273\266/Windows/\346\233\264\346\224\271\345\233\272\346\200\201\347\241\254\347\233\230\347\243\201\347\233\230\344\270\272GPT\346\240\274\345\274\217.md" "b/docs/\350\275\257\344\273\266/Windows/\346\233\264\346\224\271\345\233\272\346\200\201\347\241\254\347\233\230\347\243\201\347\233\230\344\270\272GPT\346\240\274\345\274\217.md" new file mode 100644 index 0000000..90a7a32 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/Windows/\346\233\264\346\224\271\345\233\272\346\200\201\347\241\254\347\233\230\347\243\201\347\233\230\344\270\272GPT\346\240\274\345\274\217.md" @@ -0,0 +1,49 @@ +--- +title: 更改固态硬盘磁盘为GPT格式 +date: 2022-07-30 22:00:15 +updated: +categories: +- 软件 +tags: +- 硬盘格式 +- 装机 +keywords: +- 装机 +description: 解决装机时的麻烦 +cover: https://pica.zhimg.com/v2-37670246d2a0e0e8667731ed91dea46b_1440w.jpg?source=172ae18b +top_img: https://picx.zhimg.com/v2-76671028cebf97688dc6a3732a491ba6_r.jpg?source=172ae18b +--- + +### 起因 + +在装机时发现磁盘是“MBR”格式的,装不了win10,而众所周知win10系统安装系统的快速启动功能要求的是UEFI+GPT格式的硬盘,所以记录一下 + +### 参考网址 + +> [磁盘有mbr分区安装不了系统怎么办 - 装机吧 (zhuangjiba.com)](http://www.zhuangjiba.com/jiaocheng/16597.html) + +### 步骤: + +1、按shift+f10调出命令提示符。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/cb1db42f8e360c2c81a8b7ec8d78b2d9.png) + +2、输入diskpart后回车确定,进入分区工具。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/297e92fb08524bfabc96cd58a5561926.png) + +3、输入list disk后回车确定,一般下面是安装系统的U盘,切勿把有数据的盘GPT格式,不然会清空数据。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/7889ea678a626fe408d51d018fe3160a.png) + +4、输入select disk +磁盘编码即0,回车确定。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/8064cde1dfb421231afe2161962bdf8f.png) + +5、输入clean,回车确定,将会清除硬盘上所有分区。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/b4b755ca4d611b14479445dc14b62e5c.png) + +6、输入convert gpt,回车确定,即可将硬盘转换成GPT格式。再继续重装系统即可。 + +![image.png](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/1eb8bf05bcd271ddcfc27767bc6a027a.png) diff --git "a/docs/\350\275\257\344\273\266/curl\345\221\275\344\273\244\347\232\204\347\224\250\346\263\225.md" "b/docs/\350\275\257\344\273\266/curl\345\221\275\344\273\244\347\232\204\347\224\250\346\263\225.md" new file mode 100644 index 0000000..ba59d0e --- /dev/null +++ "b/docs/\350\275\257\344\273\266/curl\345\221\275\344\273\244\347\232\204\347\224\250\346\263\225.md" @@ -0,0 +1,113 @@ +--- +title: curl命令的用法 +date: 2024-10-22 17:58:00 +updated: +categories: +- 软件 +tags: +- curl +keywords: +- curl +description: 一个命令行工具 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410221800461.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410221802081.png +--- + +`curl` 是一个非常强大的命令行工具,用于从服务器传输数据或向服务器传输数据。它支持许多协议(如 HTTP、HTTPS、FTP 等)。以下是使用 `curl` 发送不同类型的请求的基本方法。 + +在开发中,`curl`可以替代`postman`完成一些简单的前端模拟请求 + +## 发送请求 + +发送无状态的请求,参数类型指定的形式比较自由,url的双引号可加可不加,参数前缀指定也比较随意 + +```shell +curl www.baidu.com +``` + +```shell +curl "http://localhost:5050/test-redis" +``` + +```shell +curl -X GET "http://localhost:5050/test-redis" +``` + +```shell +curl --request GET --url "http://localhost:5050/test-redis" +``` + +携带token发送请求 + +```shell +curl "http://localhost:5050/api/profile" -H "Authorization: <token>" +``` + +```shell +curl --request GET --url "http://localhost:5050/api/profile" --header "Authorization: <token>" +``` + +模拟一个POST请求 + +1. 通过数据的方式 + + ```shell + curl -X POST -d "username=admin&password=123" "http://localhost:5050/api/login" + ``` + +2. 通过表单的方式(一般用于PUT请求) + + ```shell + curl -X POST "http://localhost:5050/api/login" -d "username=admin" -d "password=123" + ``` + +3. 通过查询参数或路径参数的方式 + + ```shell + curl -X POST "http://localhost:5050/api/login?username=admin&password=123" + ``` + +4. 通过 Json 的方式*(我没有测试成功,推测是Windows 命令行解释器的解析有问题)* + + ```shell + curl -X POST "http://localhost:5050/api/login" -H "Content-Type: application/json" -d '{"username":"admin", "password":"123"}' + ``` + + ```shell + curl --request POST --url 'http://localhost:5050/api/login' --header 'content-type: application/json' --data "{"username":"admin", "password":"123"}" + ``` + +模拟一个DELETE请求 + +```shell +curl -X DELETE http://localhost:5050/api/logout?userId=666 +``` + +```shell +curl --request DELETE --url http://localhost:5050/api/logout?userId=666 +``` + +## 下载文件 + +通过 `-O` 参数可以保存下载的文件到当前目录,通过 `--connect-timeout` 参数来设置连接的超时时间(以秒为单位) + +```shell +curl -O https://api.ee123.net/img/bingimg/dayimg.jpg --connect-timeout 5 +``` + +```shell +curl -O http://example.com/file.zip --connect-timeout 5 +``` + +![dayimg](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410221737880.jpg) + + + + + + + + + + + diff --git "a/docs/\350\275\257\344\273\266/index.md" "b/docs/\350\275\257\344\273\266/index.md" new file mode 100644 index 0000000..aaca994 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/index.md" @@ -0,0 +1 @@ +## 软件 \ No newline at end of file diff --git "a/docs/\350\275\257\344\273\266/markdown\350\257\255\346\263\225.md" "b/docs/\350\275\257\344\273\266/markdown\350\257\255\346\263\225.md" new file mode 100644 index 0000000..2e1b660 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/markdown\350\257\255\346\263\225.md" @@ -0,0 +1,66 @@ +--- +title: markdown语法 +date: 2022-03-05 14:06:15 +updated: +categories: +- 软件 +tags: +- markdown +keywords: +- markdown +description: 梦开始的地方 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/format_f_auto.png +top_img: https://resources.jetbrains.com/help/img/idea/2022.2/markdown-basics.png +--- + +**常用语法** + +| **Markdown语法** | **详解** | **快捷键** | **效果** | +| :-----------------------: | :-----------------------: | :----------------: | :----------------------------------------------------------: | +| \*斜体\* | 无 | Ctrl/⌘ + I | *斜体* | +| \**粗体\** | 无 | Ctrl/⌘ + B | **粗体** | +| # 一级标题 | "#"后需加空格 | 无 | 无 | +| ## 二级标题 | 以此类推三级标题为三个“#” | 无 | 无 | +| \[链接](http://a) | “[ ]”间为显示的超文本 | Ctrl/⌘ + K | [链接](https://baike.baidu.com/item/链接/2665501) | +| ![图片](http://url/a.png) | “[ ]”间为图片名 | Ctrl/⌘ + Shift + I | [![img](https://bkimg.cdn.bcebos.com/pic/d009b3de9c82d158ccbf98bc1b430ed8bc3eb135e42e?x-bce-process=image/resize,m_lfit,w_440,limit_1/format,f_auto)](https://baike.baidu.com/pic/markdown/3245829/0/d009b3de9c82d158ccbf98bc1b430ed8bc3eb135e42e?fr=lemma&ct=single) | +| “ > ”引用 | “ > ”后需加空格 | Ctrl + Q | 无 | +| * 无序列表 | 无 | Ctrl + L | 无 | +| 1. 有序列表 | 无 | 无 | 无 | +| --- | 水平分割线 | 无 | ———— | +| \`内联代码` 的使用 | 无 | Ctrl/⌘ + Shift + K | 无 | +| \```代码块``` | 无 | 无 | 无 | +| 颜色代码 | 无 | 无 | 无 | +| \*\*\*斜体+粗体*** | 无 | 无 | ***斜体+粗体\*** | +| 居中格式 | 文字 | 无 | 文字 | +| 自动换行 | 例:1234567890 | Enter | 1234567890 | +| 输入框 | 例:1234 | 无 | 输入框内的1234 | +| 颜色第二种 | 文字 | 无 | 无 | +| 文字大小 | 文字 | 无 | 无 | +| 字体 | 无 | 无 | 无 | + +音频 + +``` +<audio id="audio" controls preload> + <source id="mp3" src=""> +</audio> +``` + +<audio id="audio" controls preload width=330 height=400> + <source id="mp3" src=""> +</audio> + +网易云外链音频 + +``` +<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="//music.163.com/outchain/player?type=2&id=409649830&auto=1&height=66"></iframe> +``` +<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="//music.163.com/outchain/player?type=2&id=409649830&auto=1&height=66"></iframe> + +b站外链视频 + +``` +<iframe src="//player.bilibili.com/player.html?aid=59317437&bvid=BV1Pt411G7qh&cid=103365806&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width=800 height=600 > </iframe> +``` + +<iframe src="//player.bilibili.com/player.html?aid=59317437&bvid=BV1Pt411G7qh&cid=103365806&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width=800 height=600 > </iframe> diff --git "a/docs/\350\275\257\344\273\266/nodejs\347\233\270\345\205\263\345\221\275\344\273\244.md" "b/docs/\350\275\257\344\273\266/nodejs\347\233\270\345\205\263\345\221\275\344\273\244.md" new file mode 100644 index 0000000..af11476 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/nodejs\347\233\270\345\205\263\345\221\275\344\273\244.md" @@ -0,0 +1,366 @@ +--- +title: 使用node与nvm部署hexo博客 +date: 2024-03-30 21:51:00 +updated: 2024-11-03 21:50:00 +categories: +- 学习 +tags: +- node +- npm +- nvm +keywords: +- node +- npm +- nvm +description: 从0开始部署hexo博客的node、nvm常用命令 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212202027.png +top_img: https://www.myfreax.com/content/images/size/w816/2019/07/nvm.webp +--- + +# nodejs环境安装相关 + +## 安装curl + +```shell +sudo yum install curl +``` + +## 安装nvm + +`nvm`是一个非常好用的node版本管理工具,避免了我们需要重复安装卸载不同版本的`node.js`的问题,提高了我们的工作效率。安装nvm还是比较推荐使用下载安装包的方式,更为直接,能够直接看到步骤,也更容易定位问题。 + +```shell +wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash +``` + +```shell +export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" +``` + +```shell +source ~/.bashrc +``` + +## 安装nodejs + +在Windows和Macos上安装nodejs较方便,但是在Linux上就非常不方便,特此记录 + +去官网下载链接:[http://nodejs.cn/download](http://nodejs.cn/download/) + +选择Linux二进制文件(x64) + +![image-20240401230017772](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202404012300868.png) + +或用wget命令下载指定版本的包 + +```shell +wget https://nodejs.org/dist/v14.15.4/node-v14.15.4-linux-x64.tar.xz +``` + +```shell +wget https://nodejs.org/dist/v16.13.0/node-v16.13.0-linux-x64.tar.xz +``` + +解压缩 + +```shell +tar -xvf node-v14.15.4-linux-x64.tar.xz +mkdir -p /usr/local/nodejs +(之后所有nodejs安装的文件,例如“hexo”都会保存在/usr/local/nodejs目录下) +mv node-v14.15.4-linux-x64/* /usr/local/nodejs/ +``` + +```shell +tar -xvf node-v16.13.0-linux-x64.tar.xz +mkdir -p /usr/local/nodejs +(之后所有nodejs安装的文件,例如“hexo”都会保存在/usr/local/nodejs目录下) +mv node-v16.13.0-linux-x64/* /usr/local/nodejs/ +``` + +创建软链接 + +```shell +# 建立node软链接 +ln -s /usr/local/nodejs/bin/node /usr/local/bin +# 建立npm 软链接 +ln -s /usr/local/nodejs/bin/npm /usr/local/bin +``` + +更换镜像源 + +```shell +# 设置镜像源加速 +npm config set registry https://registry.npmmirror.com +# 查看设置信息 +npm config list +# 验证配置是否加载成功 +npm config get registry +npm info express +``` + +验证是否安装成功 + +```shell +node -v +npm -v +``` + +## 安装hexo + +安装hexo + +```shell +npm install hexo-cli -g +``` + +创建软链接 + +```shell +(如果之前已经链接过hexo了,则删除/usr/local/bin目录下的hexo软链接,重新添加hexo软链接) +ln -s /usr/local/nodejs/bin/hexo /usr/local/bin +(这里的“/usr/local/nodejs/bin/hexo”就是nodejs安装的hexo命令文件目录) +``` + +查看是否生效 + +```shell +hexo -v +``` + +## 安装pm2 + +安装pm2 + +``` +npm install pm2 -g +``` + +(如果命令没有找到,则需要软链接一下pm2) + + ```shell +ln -s /usr/local/nodejs/bin/pm2 /usr/local/bin + ``` + +在博客根目录下创建文件`hexo_run.cjs` + +```javascript +const { exec } = require('child_process') +exec('hexo server -p 80',(error, stdout, stderr) => { + if(error){ + console.log('exec error: ${error}') + return + } + console.log('stdout: ${stdout}'); + console.log('stderr: ${stderr}'); +}) +``` + +在博客目录下运行脚本 + +```shell +pm2 start hexo_run.cjs +``` + +![image-20240401225914113](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202404012259254.png) + +关闭脚本 + +```shell +pm2 stop hexo_run.cjs +``` + +![image-20240401225935604](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202404012259639.png) + +## 安装zip + +```shell +yum install zip unzip +``` + +## 安装Git、配置Git + +```shell +yum install git +``` + +```shell +git config --global user.name "01Petard" +git config --global user.email "1520394133@qq.com" +git config --global init.defaultBranch main # 设置默认分支名为main,而不是master + +# 选择题用配置 +git config --global gui.encoding utf-8 # gui界面的编码方式改为utf-8 +git config --global i18n.commitencoding utf-8 # 将commit时信息转为urf-8,默认二进制 +git config --global i18n.logoutputencoding utf-8 # 显示日志时的转为utf-8,默认二进制 +git config --global core.quotepath false # (推荐:false,不要转义)是否转义中文文件名或路径,默认转义 +git config --global core.autocrlf true # (推荐:true,开启)是否开启crlf自动换行(项目涉及windows时建议开启) +git config --global core.filemode true # (推荐:true,忽略)是否忽略文件的权限改变 +git config --global core.safecrlf true # (推荐:true,检查)是否检查行结束符在提交或检出时被正确转换 + +git config --global pull.rebase true # git pull时,不合并,而是将本地更改rebase在最新的远程提交之上,默认false为merge合并 +``` + +```shell +ssh-keygen -t rsa -C "1520394133@qq.com" +``` + +```shell +cat ~/.ssh/id_rsa.pub +``` + +## 使用脚本安装1panel 和 docker + +用`pi.sh`安装 + +项目地址:[Pseudnuos/OrangePiShell_hzx](https://gitee.com/HuaLuoTianJi/OrangePiShell_hzx) + +作者地址:[wukongdaily/OrangePiShell: 在Linux上快速部署一些好用的docker项目。起初只是为了香橙派制作。推荐使用1panel面板轻松管理docker。](https://github.com/wukongdaily/OrangePiShell) + +## 单独安装docker(如有必要) + +1. 卸载系统之前的 docker + + ``` + sudo yum remove docker \ + docker-client \ + docker-client-latest \ + docker-common \ + docker-latest \ + docker-latest-logrotate \ + docker-logrotate \ + docker-engine + ``` + +2. 安装 Docker-CE + + 安装必须的依赖 + + ``` + sudo yum install -y yum-utils \ + device-mapper-persistent-data \ + lvm2 + ``` + + 设置 docker repo 的 yum 位置 + + ``` + sudo yum-config-manager \ + --add-repo \ + https://download.docker.com/linux/centos/docker-ce.repo + ``` + + 安装 docker,以及 docker-cli + + ``` + sudo yum install docker-ce docker-ce-cli containerd.io + ``` + +3. 启动Docker + + ``` + sudo systemctl start docker + ``` + +4. 设置Docker开机自启 + + ``` + sudo systemctl enable docker + ``` + +5. 配置镜像加速(Ubuntu、CentOS) + + ``` + sudo mkdir -p /etc/docker + sudo tee /etc/docker/daemon.json <<-'EOF' + { + "registry-mirrors": ["https://uf5mphyd.mirror.aliyuncs.com"] + } + EOF + sudo systemctl daemon-reload + sudo systemctl restart docker + ``` + +## 启动项目 + +```shell +npm install +``` + +```shell +hexo ... +``` + +# node常用命令 + +## 查看安装过的依赖模块 + +全局 + +```shell +npm list -g --depth 0 +``` + +当前项目 + +```shell +npm list --depth 0 +``` + +## 查看node版本列表 + +```bash +nvm list # 显示已安装的版本(同 nvm list installed) +nvm list installed # 显示已安装的版本 +nvm list available # 显示所有可以下载的版本 +``` + +## 安装node + +```bash +nvm install 12.22.0 # 安装12.22.0版本node +nvm install latest # 安装最新版本node +``` + +注:当运行`nvm install`命令时,若出现权限问题,可以使用管理员身份运行 + +## 使用指定版本的node + +```bash +nvm use 12.122.0 # 使用12.22.0版本node +``` + +**注:当我们要使用npm时,需要先指定node版本,即先运行`nvm use`命令,再使用`npm`命令** + +## 卸载指定版本的node + +```bash +nvm uninstall 16.16.0 # 卸载16.16.0版本node +``` + +#MacOS相关的配置 + +## node版本管理工具n + +```shell +sudo npm install n -g +``` + +## 查看当前有哪些node版本 + +```shell +sudo n +``` + +## 安装一个node版本 + +```shell +sudo n 16.13.0 +``` + +## 查看当前项目安装过的依赖模块 + +```shell +npm list --depth 0 +``` + diff --git "a/docs/\350\275\257\344\273\266/\345\205\263\344\272\216bing\345\233\275\345\206\205\351\207\215\345\256\232\345\220\221\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/\350\275\257\344\273\266/\345\205\263\344\272\216bing\345\233\275\345\206\205\351\207\215\345\256\232\345\220\221\350\247\243\345\206\263\346\226\271\346\241\210.md" new file mode 100644 index 0000000..67fec5f --- /dev/null +++ "b/docs/\350\275\257\344\273\266/\345\205\263\344\272\216bing\345\233\275\345\206\205\351\207\215\345\256\232\345\220\221\350\247\243\345\206\263\346\226\271\346\241\210.md" @@ -0,0 +1,27 @@ +--- +title: 关于bing国内重定向解决方案 +date: 2023-02-12 12:34:15 +updated: +categories: +- 软件 +tags: +- 必应bing +keywords: +- 必应bing +description: 仲裹初拼,毕输经拼 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/下载.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212226188.png +--- + +去年因为chatGPT火了嘛,所以微软也乘机搞起了大规模语言生成模型,于是最近就有了这个东西,但是中国的用户去必应首页会被重定向到国内的网站的(也就是cn版),于是我就发一下如何解决这个问题吧: + +1.在你的浏览器扩展商店里获取**header editor**插件。 + +![](https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/20230215005613.png) + +2.在插件里面导入这个脚本,并保存后再次访问即可解决问题 + +```html +https://gist.githubusercontent.com/yuhangch/9abc4220af46a1f4a7fc97393e2f040e/raw/89c889b0e7a80446c931823edd612630fd62d165/header-editor-config.json +``` + diff --git "a/docs/\350\275\257\344\273\266/\345\223\224\345\223\251\345\223\224\345\223\251\346\210\220\345\210\206\351\211\264\345\256\232\345\231\250\357\274\210\344\270\252\344\272\272\351\255\224\346\224\271\347\211\210\357\274\211.md" "b/docs/\350\275\257\344\273\266/\345\223\224\345\223\251\345\223\224\345\223\251\346\210\220\345\210\206\351\211\264\345\256\232\345\231\250\357\274\210\344\270\252\344\272\272\351\255\224\346\224\271\347\211\210\357\274\211.md" new file mode 100644 index 0000000..70f9d91 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/\345\223\224\345\223\251\345\223\224\345\223\251\346\210\220\345\210\206\351\211\264\345\256\232\345\231\250\357\274\210\344\270\252\344\272\272\351\255\224\346\224\271\347\211\210\357\274\211.md" @@ -0,0 +1,29 @@ +--- +title: 哔哩哔哩成分鉴定器(个人魔改版) +date: 2022-09-20 14:53:15 +updated: +categories: +- 软件 +tags: +- 油猴插件 +- 哔哩哔哩 +keywords: +- 油猴插件 +- 哔哩哔哩 +description: 更简洁的哔哩哔哩成分鉴定器,代码理清楚了 +cover: https://www.freedidi.com/wp-content/uploads/2021/08/v2-aeea17a3da87918c0eca3fc06cfa2563_720w.png +top_img: https://pic4.zhimg.com/80/v2-e4ba2b20642bd758061ca0adce81866b_1440w.jpg +--- + +最近在网上看到了一种可以查看别人动态关键词,来鉴定用户成分的一个脚本。于是我找来学习了一下,并魔改了一下,如果需要加入新的关键词很方便,可以自定义任何称号。 + +具体视频可以查看下面这个视频 + +> [【油猴】三相之力脚本(用户自动标注)的使用与自定义设置方法_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1Pe4y1h7BX?vd_source=3ff954868f64ecb51872efabed3a44ca) + +代码大差不差,我做了一些简化,去掉了双重称号,每个关键词都有一个称号,如果想要添加自己想看的成分,只需要自己添加关键词就好了。 + +将我的代码覆盖作者源码即可 + +> 链接: https://pan.baidu.com/s/15G3FLzh0vHbfNZGP1uliwg?pwd=9v3g 提取码: 9v3g 复制这段内容后打开百度网盘手机App,操作更方便哦 + diff --git "a/docs/\350\275\257\344\273\266/\345\237\272\344\272\216YOLOv8\346\250\241\345\236\213\347\232\204\346\212\275\347\203\237\350\241\214\344\270\272\346\243\200\346\265\213\347\263\273\347\273\237.md" "b/docs/\350\275\257\344\273\266/\345\237\272\344\272\216YOLOv8\346\250\241\345\236\213\347\232\204\346\212\275\347\203\237\350\241\214\344\270\272\346\243\200\346\265\213\347\263\273\347\273\237.md" new file mode 100644 index 0000000..3024444 --- /dev/null +++ "b/docs/\350\275\257\344\273\266/\345\237\272\344\272\216YOLOv8\346\250\241\345\236\213\347\232\204\346\212\275\347\203\237\350\241\214\344\270\272\346\243\200\346\265\213\347\263\273\347\273\237.md" @@ -0,0 +1,182 @@ +--- +title: 基于YOLOv8模型的抽烟行为检测系统 +date: 2023-12-14 09:35:00 +updated: +categories: +- 学习 +tags: +- Python +- Pyside6 +- YOLOv8 +keywords: +- Python +- Pyside6 +- YOLOv8 +description: 基于Yolo特殊动作检测系统 +cover: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212307670.png +top_img: https://cdn.jsdelivr.net/gh/01Petard/imageURL@main/img/202410212307210.png +--- + +## 基于YOLOv8模型的抽烟行为检测系统(PyTorch+Pyside6+YOLOv8模型) + +原创 BestSongC [BestSongC](javascript:void(0);) *2023-10-16 21:56* *发表于江苏* + +> 摘要:基于YOLOv8模型的抽烟行为检测系统可用于日常生活中检测与定位抽烟行为,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集,使用Pysdie6库来搭建前端页面展示系统。另外本系统支持的功能还包括训练模型的导入、初始化;检测置信分与检测后处理IOU阈值的调节;图像的上传、检测、可视化结果展示与检测结果导出;视频的上传、检测、可视化结果展示与检测结果导出;摄像头的图像输入、检测与可视化结果展示;已检测目标个数与列表、位置信息;前向推理用时等功能。本博文提供了完整的Python代码与安装和使用教程,适合新入门的朋友参考,部分重要代码部分都有注释,完整代码资源文件请转至文末的下载链接。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GndLHxhcj7k1usiaIPo8jAmQYBpUzWsd8P4vumf4NsCt5B5sibOmb4TaQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**基本介绍** + +近年来,机器学习和深度学习取得了较大的发展,深度学习方法在检测精度和速度方面与传统方法相比表现出更良好的性能。YOLOv8 是 Ultralytics 公司继 YOLOv5 算法之后开发的下一代算法模型,目前支持图像分类、物体检测和实例分割任务。YOLOv8 是一个 SOTA模型,它建立在之前YOLO 系列模型的成功基础上,并引入了新的功能和改进,以进一步提升性能和灵活性。具体创新包括:一个新的骨干网络、一个新的 Ancher-Free 检测头和一个新的损失函数,可以在从 CPU 到 GPU 的各种硬件平台上运行。因此本博文利用YOLOv8目标检测算法实现一种抽烟行为检测模型,再使用Pyside6库搭建出界面系统,完成目标检测页面的开发。本博主之前发布过关于YOLOv5算法的相关模型与界面,需要的朋友可从我之前发布的博客查看。另外本博主计划将YOLOv5、YOLOv6、YOLOv7和YOLOv8一起联合发布,需要的朋友可以持续关注,欢迎朋友们关注收藏。 + +**环境搭建** + +(1)打开项目目录,在搜索框内输入cmd打开终端 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G6nQeauHF7scrAuufd0iarDEkOGy0r5CaeBsrX1rEE9TvYJuMkSdbPWQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +(2)新建一个虚拟环境(conda create -n yolo8 python=3.8) + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GUSicb3k45piaibWRdiaQbxV9Ju1ED1w38SPxjNA3MuS1jECL7wagU1Nuag/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +(3)激活环境,安装ultralytics库(yolov8官方库),pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GpPkLJ7N6icv9ZDDGjeASOXnUoUDdLbe4MXkHfSOgYSFGzEtA9btdvOw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +(4)注意到这种安装方式只会安装cpu版torch,如需安装gpu版torch,需在安装包之前先安装torch:pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 -f https://download.pytorch.org/whl/torch_stable.html;再,pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G33liaN8ZqtViaoEe5C1bTzgXVp5YHiagzyxkdlCfxete2xraJBTtsnADw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +(5)安装图形化界面库pyside6:pip install pyside6 -i https://pypi.tuna.tsinghua.edu.cn/simple + +**界面及功能展示** + +下面给出本博文设计的软件界面,整体界面简洁大方,大体功能包括训练模型的导入、初始化;置信分与IOU阈值的调节、图像上传、检测、可视化结果展示、结果导出与结束检测;视频的上传、检测、可视化结果展示、结果导出与结束检测;已检测目标列表、位置信息;前向推理用时。初始界面如下图: + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G0ax30ItlWRm1XwvXeab0TzW4g5vSpzXUKyKB2klecO36xyy8Ae9KdA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**模型选择与初始化** + +用户可以点击模型权重选择按钮上传训练好的模型权重,训练权重格式可为.pt、.onnx以及engine等,之后再点击模型权重初始化按钮可实现已选择模型初始化的配置。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4Gs7ETUqS3zsccBNs8riad9rvs02oChTfpw3hHT6LOLg34rKbiafYlTcgQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**置信分与IOU的改变** + +在Confidence或IOU下方的输入框中改变值即可同步改变滑动条的进度,同时改变滑动条的进度值也可同步改变输入框的值;Confidence或IOU值的改变将同步到模型里的配置,将改变检测置信度阈值与IOU阈值。 + +**图像选择、检测与导出** + +用户可以点击选择图像按钮上传单张图像进行检测与识别,上传成功后系统界面会同步显示输入图像。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G2trlibRSHodFPibPCl5oibmLFjcWZWe6qvslYry9ia8lQibzmMINMFWC65A/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +再点击图像检测按钮可完成输入图像的目标检测功能,之后系统会在用时一栏输出检测用时,在目标数量一栏输出已检测到的目标数量,在下拉框可选择已检测目标,对应于目标位置(即xmin、ymin、xmax以及ymax)标签值的改变。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GMlJ6VBw9IaiajC3SQvyNOUgE73JyRMU3JdYf0brbdGYZMhId2lJp0pQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +再点击检测结果展示按钮可在系统左下方显示输入图像检测的结果,系统将显示识别出图片中的目标的类别、位置和置信度信息。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GndLHxhcj7k1usiaIPo8jAmQYBpUzWsd8P4vumf4NsCt5B5sibOmb4TaQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +点击图像检测结果导出按钮即可导出检测后的图像,在保存栏里输入保存的图片名称及后缀即可实现检测结果图像的保存。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GJUd3k1PJqQc3aq1wePlc5HS1MAONuBnSK6nxXIBJqd2RNA2Sp2sAew/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +点击结束图像检测按钮即可完成系统界面的刷新,将所有输出信息清空,之后再点击选择图像或选择视频按钮来上传图像或视频,或者点击打开摄像头按钮来开启摄像头。 + +**视频选择、检测与导出** + +用户点击选择视频按钮上传视频进行检测与识别,之后系统会将视频的第一帧输入到系统界面中显示。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G3S7FZJKm2SJmDx0AlSpAhnKlkFtj6K4l0KPSScbDhbv9MChyoyh3icg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +再点击视频检测按钮可完成输入视频的目标检测功能,之后系统会在用时一栏输出检测用时,在目标数量一栏输出已检测到的目标数量,在下拉框可选择已检测目标,对应于目标位置(即xmin、ymin、xmax以及ymax)标签值的改变。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GDOeynVmXCKBTnNY9ibJXR835dq9DtPLIiaCqRkuQ8MiaaKOw4qEN2ibrIQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +点击暂停视频检测按钮即可实现输入视频的暂停,此时按钮变为继续视频检测,输入视频帧与帧检测结果会保留在系统界面,可点击下拉目标框选择已检测目标的坐标位置信息,再点击继续视频检测按钮即可实现输入视频的检测。 + +点击视频检测结果导出按钮即可导出检测后的视频,在保存栏里输入保存的图片名称及后缀即可实现检测结果视频的保存。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GE4BdMldOhdrXD0iaz58SU54e2aEEqXIxPJbYZ8WyOOgDsfzxF1EX2zQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +点击结束视频检测按钮即可完成系统界面的刷新,将所有输出信息清空,之后再点击选择图像或选择视频按钮来上传图像或视频,或者点击打开摄像头按钮来开启摄像头。 + +**摄像头打开、检测与结束** + +用户可以点击打开摄像头按钮来打开摄像头设备进行检测与识别,之后系统会将摄像头图像输入到系统界面中显示。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GzdFmnP5am1Dlf1aF3Xum7De0Y5Wiag8WgD04D3VxNfDdEY3aQM38SVA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +再点击摄像头检测按钮可完成输入摄像头的目标检测功能,之后系统会在用时一栏输出检测用时,在目标数量一栏输出已检测到的目标数量,在下拉框可选择已检测目标,对应于目标位置(即xmin、ymin、xmax以及ymax)标签值的改变。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G3hEur2icSkiaWCAktzZgJBicA9Mrxll2FJFGFopGOa4EQ0OznMsDHicq6g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +点击结束视频检测按钮即可完成系统界面的刷新,将所有输出信息清空,之后再点击选择图像或选择视频按钮来上传图像或视频,或者点击打开摄像头按钮来开启摄像头 + +**算法原理介绍** + +本系统采用了基于深度学习的单阶段目标检测算法YOLOv8,相较于之前的YOLO系列目标检测算法,YOLOv8目标检测算法具有如下的几点优势:(1)更友好的安装/运行方式;(2)速度更快、准确率更高;(3)新的backbone,将YOLOv5中的C3更换为C2F;(4)YOLO系列第一次尝试使用anchor-free;(5)新的损失函数。YOLOv8模型的整体结构如下图所示,原图见mmyolo的官方仓库。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GtcO6BjjWoUCcxskZzJthJuuOEND2qYZ6HoMX69yD78B7iaFCdJcHPZg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +YOLOv8与YOLOv5模型最明显的差异是使用C2F模块替换了原来的C3模块,两个模块的结构如下图所示,原图见mmyolo的官方仓库。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GvkGlIw7jSObickpsiaUD9SJaQUZ4QCXXJzQqfsBNFOzE2qtAiaacAYmYA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +另外Head 部分变化最大,从原先的耦合头变成了解耦头,并且从 YOLOv5 的 Anchor-Based 变成了 Anchor-Free。其结构对比如下图所示。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GxXSibJJP1QjbPnXp3bCEshNMgicmbicOXuL5wQpcmtBorSwCqk481RVXw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**数据集介绍** + +本系统使用的抽烟行为数据集手动标注了抽烟行为这一个类别,数据集总计3232张图片。该数据集中类别都有大量的旋转和不同的光照条件,有助于训练出更加鲁棒的检测模型。本文实验的抽烟行为检测识别数据集包含训练集2640张图片,验证集592张图片,选取部分数据部分样本数据集如下图所示。此外,为了增强模型的泛化能力和鲁棒性,我们还使用了数据增强技术,包括随机旋转、缩放、裁剪和颜色变换等,以扩充数据集并减少过拟合风险。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G2ERr6C9mdU7mTibeWyfiaGMl4nRIzibgufjq5ZyzpZ1ITZ5mgXP4y5ibIQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**关键代码解析** + +在训练阶段,我们使用了预训练模型作为初始模型进行训练,然后通过多次迭代优化网络参数,以达到更好的检测性能。在训练过程中,我们采用了学习率衰减和数据增强等技术,以增强模型的泛化能力和鲁棒性。一个简单的单卡模型训练命令如下。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4Gx9LfYRf30cN6NDZHKYZOfBLqA6YqicqtPxLZjaDxdoibdhlKu96yhrYg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +在训练时也可指定更多的参数,大部分重要的参数如下所示: + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GzNuLKcYgfD0vBd7FOg2jXCnVbqDJ8BU39j2GdicbkxkJqhrtyHfo8KQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +在测试阶段,我们使用了训练好的模型来对新的图片和视频进行检测。通过设置阈值,将置信度低于阈值的检测框过滤掉,最终得到检测结果。同时,我们还可以将检测结果保存为图片或视频格式,以便进行后续分析和应用。本系统基于YOLOv8算法,使用PyTorch实现。代码中用到的主要库包括PyTorch、NumPy、OpenCV、Pyside6等。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GZBr1gC5vV1mWc0Mp9ibK7XLWLKCAXcdx6kyLtpBbZ4uQKB7icaBjtA2Q/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +**Pyside6界面设计** + +PySide是一个Python的图形化界面(GUI)库,由C++版的Qt开发而来,在用法上基本与C++版没有特别大的差异。相对于其他Python GUI库来说,PySide开发较快,功能更完善,而且文档支持更好。在本博文中,我们使用Pyside6库创建一个图形化界面,为用户提供简单易用的交互界面,实现用户选择图片、视频进行目标检测。 + +我们使用Qt Designer设计图形界面,然后使用Pyside6将设计好的UI文件转换为Python代码。图形界面中包含多个UI控件,例如:标签、按钮、文本框、多选框等。通过Pyside6中的信号槽机制,可以使得UI控件与程序逻辑代码相互连接。 + +**实验结果与分析** + +在实验结果与分析部分,我们使用精度和召回率等指标来评估模型的性能,还通过损失曲线和PR曲线来分析训练过程。在训练阶段,我们使用了前面介绍的数据集进行训练,使用了YOLOv8算法对数据集训练,总计训练了100个epochs。在训练过程中,我们使用tensorboard记录了模型在训练集和验证集上的损失曲线。从下图可以看出,随着训练次数的增加,模型的训练损失和验证损失都逐渐降低,说明模型不断地学习到更加精准的特征。在训练结束后,我们使用模型在数据集的验证集上进行了评估,得到了以下结果。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GwicuQ8gGRp5bDXbn2dy8vcBLBpjIMRY2GiamHcBNacKNYkgdiaoOhibQgA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +下图展示了我们训练的YOLOv8模型在验证集上的PR曲线,从图中可以看出,模型取得了较高的召回率和精确率,整体表现良好。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GcVfoIoT6NjMyAbo6HAxKIql8Zia6EYnurhtnfRc6NZmpu52UjCkKe8g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +下图展示了本博文在使用YOLOv8模型对数据集进行训练时候的Mosaic数据增强图像。 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4G8PataEeicgfmic5aSWicib7tibaqVqSu7MN5F5tDh03I1bAo4l3Vh7Aafyg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +综上,本博文训练得到的YOLOv8模型在数据集上表现良好,具有较高的检测精度和鲁棒性,可以在实际场景中应用。另外本博主对整个系统进行了详细测试,最终开发出一版流畅的高精度目标检测系统界面,就是本博文演示部分的展示,完整的UI界面、测试图片视频、代码文件等均已打包上传,感兴趣的朋友可以关注我私信获取。另外本博文的PDF与更多的目标检测识别系统请关注笔者的微信公众号 BestSongC。 + +**完整代码和数据集从以下链接获取: https://mbd.pub/o/bread/ZZWWmZxs** + +**里面包含所有源码文件、UI界面、数据集以及训练好的模型,另外支持远程环境部署** + +其他基于深度学习的目标检测系统如西红柿、猫狗、山羊、野生目标、烟头、二维码、头盔、交警、野生动物、野外烟雾、人体摔倒识别、红外行人、家禽猪、苹果、推土机、蜜蜂、打电话、鸽子、足球、奶牛、人脸口罩、安全背心、烟雾检测系统等有需要的朋友关注我,从博主其他视频中获取下载链接。 + +完整项目目录如下所示 + +![图片](https://mmbiz.qpic.cn/mmbiz_png/TtoFbnkI4OYibWoXak8vq3JROmFfrcw4GkibZvWia8yjfxnFataet1c1j186tXJzE8zwF8WklqzRwQOjrngryZhqA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) \ No newline at end of file