-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 440 KB
/
content.json
1
{"meta":{"title":"Sustart","subtitle":" ","description":"record and study","author":"Sustart He","url":"https://zy68.top","root":"/"},"pages":[{"title":"404 Not Found","date":"2022-01-22T12:42:28.973Z","updated":"2022-01-22T12:42:28.973Z","comments":true,"path":"404.html","permalink":"https://zy68.top/404.html","excerpt":"","text":"404 Not Found **很抱歉,您访问的页面不存在** **小博正在努力维护+完善,敬请期待** 可能是输入地址有误或该地址已被删除"},{"title":"书单","date":"2020-05-19T15:51:53.000Z","updated":"2022-01-22T12:42:28.973Z","comments":true,"path":"ReadBooks/index.html","permalink":"https://zy68.top/ReadBooks/index.html","excerpt":"","text":"未读完 《Linux就该这么学》 《java核心技术 卷一》 《经典算法竞赛入门》 《Spring boot实战》 正在阅读 《Spring实战》 《网络是怎样连接的》 已读完计划要读"},{"title":"关于","date":"2019-12-12T15:50:51.000Z","updated":"2022-01-12T06:46:30.000Z","comments":true,"path":"about/index.html","permalink":"https://zy68.top/about/index.html","excerpt":"","text":"Gratitude ❤welcome❤ About the blog 建站时间——12 Dec 2019 博客搭建——Hexo+Github Page 博客主题——由xaoxuxu编写的volantis 建站目的——记录&分享 About me Sustart He 大四 Major in CS Java Commit ~~虽然vegetable~~ 按自己的计划划水学习中 路很长 欢迎交流学习 欢迎评论灌水 互友 🌹🌹"},{"title":"所有分类","date":"2019-12-12T15:50:51.000Z","updated":"2022-01-12T06:46:30.000Z","comments":true,"path":"categories/index.html","permalink":"https://zy68.top/categories/index.html","excerpt":"","text":""},{"title":"关注大本营","date":"2019-12-12T15:50:51.000Z","updated":"2022-01-12T06:46:30.000Z","comments":true,"path":"friends/index.html","permalink":"https://zy68.top/friends/index.html","excerpt":"","text":""},{"title":"留言区","date":"2020-05-25T15:50:51.000Z","updated":"2022-01-12T06:46:30.000Z","comments":true,"path":"message/index.html","permalink":"https://zy68.top/message/index.html","excerpt":"","text":"Facing the sea, with spring blossoms"},{"title":"","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"mylist/index.html","permalink":"https://zy68.top/mylist/index.html","excerpt":"","text":""},{"title":"Projects","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"projects/index.html","permalink":"https://zy68.top/projects/index.html","excerpt":"","text":"欢迎访问我的GitHub"},{"title":"所有标签","date":"2019-12-12T15:50:51.000Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"tags/index.html","permalink":"https://zy68.top/tags/index.html","excerpt":"","text":""},{"title":"小站事记","date":"2022-01-12T03:15:14.000Z","updated":"2022-01-14T15:08:14.000Z","comments":true,"path":"timeline/index.html","permalink":"https://zy68.top/timeline/index.html","excerpt":"","text":"2022-01-14 添加百度统计 添加百度统计,监测访问信息。 2022-01-13 Hexo版本更新 Hexo 版本由原来的 4.2.1 更新至 6.0.0. 2022-01-12 增加访问量统计 接入 LeanCloud 数据存储的访问量统计.由不蒜子切换至 leanCloud,网站&文章 访问量刷新. 2022-01-11 支持rss 支持RSS订阅 2022-01-09 主题更新版本 博客由 Volantis v2 更新至 v5.留照纪念:全平台PC首页 …… 未记录的过去 博客样式更改、域名绑定、评论系统由 Valine 更换至 Gitalk、Github Action 托管…… 2019-12-12 博客创建 🎉🎉"},{"title":"主题使用功能记录","date":"2022-01-12T07:58:09.000Z","updated":"2022-01-12T07:58:09.000Z","comments":true,"path":"v5/index.html","permalink":"https://zy68.top/v5/index.html","excerpt":"","text":"开始使用站点设置主题配置页面设置标签插件进阶设定开发文档"},{"title":"进阶设定","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/advanced-settings/index.html","permalink":"https://zy68.top/v5/advanced-settings/index.html","excerpt":"","text":"设置子模块 将主题添加为子模块 开始前需要确认不存在 themes/volantis 文件夹, 如果有, 请自行删除.sshhttps1git submodule add [email protected]:volantis-x/hexo-theme-volantis.git themes/volantis1git submodule add https://github.com/volantis-x/hexo-theme-volantis.git themes/volantis 多人协同默认的作者信息在主题配置文件中设置: blog/themes/volantis/_config.yml12345678910# 文章布局article: ... body: ... meta_library: author: avatar: name: 请设置文章作者 url: / Volantis 支持多个作者在一个站点发布文章,其他作者信息需要写在数据文件中,例如: blog/source/_data/author.yml12345678Jon: name: Jon Snow avatar: https://cn.bing.com/th?id=AMMS_fc8f99fd41ebd737a71c4e13806db9a0&w=110&h=110&c=7&rs=1&qlt=80&pcl=f9f9f9&cdv=1&dpr=2&pid=16.1 url: https://gameofthrones.fandom.com/wiki/Jon_SnowDany: name: Daenerys Targaryen avatar: https://tse1-mm.cn.bing.net/th?id=OIP.Yax4wLzIFbcBVUa_RsKywQHaLH&w=80&h=80&c=8&rs=1&qlt=90&dpr=2&pid=3.1&rm=2 url: https://gameofthrones.fandom.com/wiki/Daenerys_Targaryen 在文章的 front-matter 中新增 author 即可: 1234---title: Jon Snow | Game of Thrones Wiki | Fandomauthor: Jon--- 为网站提速加载速度 减少不必要的 js 插件,例如字数统计、动态背景。 查找并解决拖慢速度的资源,以 Chrome 浏览器为例: 页面中点击右键,选择「检查」。 在右边的窗口中「Network」选项卡,并勾选「Disable cache」。 刷新网页,查看加载速度慢的资源。 加载缓慢的图片,建议使用 CDN。 加载缓慢的可以不用的 js 插件,建议舍弃。 加载缓慢却必须使用的 js 插件,建议下载并自己上传至 jsdelivr。 运行速度 访问具有动态特效背景(如雪花、粒子等)的网站时,手机很快会发烫变卡,笔记本很快会风扇狂转并且浏览器提示建议关闭此页面。如果你希望网站有好的使用体验请尽量不要安装这类插件。 优化 SEORobotsblog/_config.volantis.yml123456789101112seo: # When there are no keywords in the article's front-matter, use tags as keywords. use_tags_as_keywords: true # When there is no description in the article's front-matter, use excerpt as the description. use_excerpt_as_description: true robots: home_first_page: index,follow home_other_pages: noindex,follow archive: noindex,follow category: noindex,follow tag: noindex,follow # robots can be written in front-matter 在 front-matter 中,可以设置 keywords、description、robots 和 seo_title。其中 seo_title 仅仅用作网页标题,优先级高于 title。 文章内部不要使用 H1 标题。 通过死链检测工具检查并删除无法访问的链接。 安装 SEO 优化插件: hexo-autonofollowhttps://github.com/liuzc/hexo-autonofollow hexo-generator-seo-friendly-sitemaphttps://github.com/ludoviclefevre/hexo-generator-seo-friendly-sitemap 页面不要堆砌关键词,不要频繁更改路径。 Open Graphblog/_config.volantis.yml1234567# https://ogp.me/# https://hexo.io/zh-cn/docs/helpers#open-graphopen_graph: image: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/android-chrome-192x192.png twitter_card: summary # summary_large_image , summary #twitter_id: #twitter_site: Structured Datablog/_config.volantis.yml123456789101112131415161718# SEO 入门文档: https://developers.google.com/search/docs# https://schema.org.cn/# 结构化数据用于更改搜索结果的显示效果# 目前内置的结构化数据: blogposting, breadcrumblist, organization, person, website# 目前内置的富媒体搜索结果: 路径(面包屑导航), 徽标(Logo), 站点链接搜索框(SearchAction)# https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data# 富媒体搜索结果测试: https://search.google.com/test/rich-resultsstructured_data: enable: true # 以下是覆盖配置, 默认配置见 scripts/helpers/structured-data/lib/config.js data: person: sns: - https://github.com/volantis-x logo: path: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/android-chrome-192x192.png width: 192 height: 192 使用 CDN对于大部分将博客 deploy 到 GitHub 的用户来说,直接加载本地资源速度比较慢,可以使用 jsdelivr 为开源项目提供的 CDN 服务。 开启方法blog/_config.volantis.yml123456789101112# 本地静态文件使用jsdelivr的min版本加速 https://www.jsdelivr.com/features# 默认使用 https://cdn.jsdelivr.net/npm/hexo-theme-volantis@<%- theme.info.theme_version %>/source/js/*.min.js 的CDN压缩版本(min.js),注意版本号对应关系!!可以通过修改以下配置项覆盖# 开发者注意 cdn.enable 设置为 falsecdn: enable: false prefix: # CDN 前缀,为空使用默认值,链接最后不加 "/",例如: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page 填写最后编译生成的源码CDN地址前缀,此路径下应该含有/js与/css目录,该配置默认值是:"https://cdn.jsdelivr.net/npm/hexo-theme-volantis@"+ theme.info.theme_version +"/source" # 以下配置可以覆盖 cdn.prefix,配置项的值可以为空,但是要使用CDN必须依据路径填写配置项的键 set: js: app: #/js/app.js css: style: #/css/style.css # (异步加载样式) 如果你需要对样式进行 DIY,可以只关闭 style 文件的 CDN。 从V5版本开始,首屏样式采用硬编码的方式写在HTML中。首屏样式内含 cover navbar search 的样式,其他样式放入/css/style.css异步加载。 如果你需要对样式进行 DIY,请注意首屏渲染和异步延迟加载的差异。 可以对 style.css 使用 HTTP/2 Server Push,但是此方案并不推荐。我们已经对style.css进行了preload处理,推荐使用对服务器压力成本较小的 CDN 服务。 ### 自定义 CDN 如果你把对应的文件上传到自己的 CDN 服务器,可以把对应的链接改为自己的 CDN 链接。 ## 尝试使用 Terser 压缩 ES6 ### 安装压缩工具 12npm install -g gulpnpm install --save-dev gulp gulp-html-minifier-terser gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-terser ### gulp 配置文件 gulp 配置文件 blog/gulpfile.js123456789101112131415161718192021222324252627282930313233343536373839404142434445var gulp = require('gulp');var minifycss = require('gulp-minify-css');var htmlmin = require('gulp-html-minifier-terser');var htmlclean = require('gulp-htmlclean');var terser = require('gulp-terser');// 压缩css文件const minify_css = () => ( gulp.src(['./public/**/*.css']) .pipe(minifycss()) .pipe(gulp.dest('./public')));// 压缩html文件const minify_html = () => ( gulp.src(['./public/**/*.html','!./public/{lib,lib/**}']) .pipe(htmlclean()) .pipe(htmlmin({ removeComments: true, minifyJS: true, minifyCSS: true, minifyURLs: true, })) .pipe(gulp.dest('./public')))// 压缩js文件const minify_js = () => ( gulp.src(['./public/**/*.js', '!./public/**/*.min.js','!./public/{lib,lib/**}']) .pipe(terser()) .pipe(gulp.dest('./public')))module.exports = { minify_html: minify_html, minify_css: minify_css, minify_js: minify_js};gulp.task('one', gulp.parallel( minify_html, minify_css, minify_js))gulp.task('default', gulp.series('one')); ### 运行压缩 1gulp ## 安装 Service Worker 服务 ### 方案一 安装插件 安装 [hexo-offline-popup](https://github.com/Colsrch/hexo-offline-popup) 或者 [hexo-offline](https://github.com/JLHwung/hexo-offline) 插件,初次加载速度不变,后期切换页面和刷新网页速度越来越快。 ### 方案二 使用 workbox 自定义配置 step 1. 修改 blog/_config.yml 文件。 blog/_config.yml1234# 全局导入import: script: - <script>"serviceWorker"in navigator&&navigator.serviceWorker.register("/sw.js").then(function(n){n.onupdatefound=function(){var e=n.installing;e.onstatechange=function(){switch(e.state){case"installed":navigator.serviceWorker.controller?console.log("Updated serviceWorker."):console.log("serviceWorker Sucess!");break;case"redundant":console.log("The installing service worker became redundant.")}}}}).catch(function(e){console.log("Error during service worker registration:",e)}); </script> step 2. 在 blog/source 中创建 sw.js 文件。 blog/source/sw.js123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139importScripts('https://cdn.jsdelivr.net/npm/[email protected]/workbox/workbox-sw.js');workbox.setConfig({ modulePathPrefix: 'https://cdn.jsdelivr.net/npm/[email protected]/workbox/'});const { core, precaching, routing, strategies, expiration, cacheableResponse, backgroundSync } = workbox;const { CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate } = strategies;const { ExpirationPlugin } = expiration;const { CacheableResponsePlugin } = cacheableResponse;const cacheSuffixVersion = '-000010', // 缓存版本号 极端重要,修改静态文件后发布网页一定要修改缓存版本号 maxEntries = 100;self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => { return Promise.all(keys.map((key) => { if (!key.includes(cacheSuffixVersion)) return caches.delete(key); })); }) );});core.setCacheNameDetails({ prefix: 'volantis', // 极端重要 自己拟定一个名字 suffix: cacheSuffixVersion});core.skipWaiting();core.clientsClaim();precaching.cleanupOutdatedCaches();/* * Precache * - Static Assets */precaching.precacheAndRoute( // 极端重要 定义首次缓存的静态文件 如果开启CDN需要修改为CDN链接 [ { url: '/css/first.css', revision: null }, { url: '/css/style.css', revision: null }, { url: '/js/app.js', revision: null }, ],);/* * Cache File From CDN * * Method: CacheFirst * cacheName: static-immutable * cacheTime: 30d */// cdn.jsdelivr.net - cors enabledrouting.registerRoute( /.*cdn\\.jsdelivr\\.net/, new CacheFirst({ cacheName: 'static-immutable' + cacheSuffixVersion, fetchOptions: { mode: 'cors', credentials: 'omit' }, plugins: [ new ExpirationPlugin({ maxAgeSeconds: 30 * 24 * 60 * 60, purgeOnQuotaError: true }) ] }));// m7.music.126.net - cors enabledrouting.registerRoute( /.*m7\\.music\\.126\\.net/, new CacheFirst({ cacheName: 'static-immutable' + cacheSuffixVersion, fetchOptions: { mode: 'cors', credentials: 'omit' }, plugins: [ new ExpirationPlugin({ maxAgeSeconds: 30 * 24 * 60 * 60, purgeOnQuotaError: true }) ] }));/* * No Cache * * Method: networkOnly */routing.registerRoute( /.*baidu\\.com.*/, new NetworkOnly());/* * Others img fonts * Method: staleWhileRevalidate */routing.registerRoute( // Cache image fonts files /.*\\.(?:png|jpg|jpeg|svg|gif|webp|ico|eot|ttf|woff|woff2|mp3)/, new StaleWhileRevalidate());/* * Static Assets * Method: staleWhileRevalidate */routing.registerRoute( // Cache CSS files /.*\\.(css|js)/, // Use cache but update in the background ASAP new StaleWhileRevalidate());/* * sw.js - Revalidate every time * staleWhileRevalidate */routing.registerRoute( '/sw.js', // 本文件名 new StaleWhileRevalidate());/* * Default - Serve as it is * networkFirst */routing.setDefaultHandler( new NetworkFirst({ networkTimeoutSeconds: 3 })); 如果你使用了此方案,修改静态文件后发布网页一定要修改缓存版本号。 ## 安装「相关文章」插件 1. 安装插件 1npm i -S hexo-related-popular-posts 2. 插件的自定义配置方法: hexo-related-popular-postshttps://github.com/tea3/hexo-related-popular-posts 如果您使用了头图,可以在站点配置文件中添加以下设置来让相关文章显示正确的文章头图: blog/_config.yml12popularPosts: eyeCatchImageAttributeName: headimg 注意需要升级到 5.0.1 及以上版本才可以支持自定义头图,详见 #29 分析与统计数据统计PV 和 UV默认支持 不蒜子 的访问统计和 leancloud 统计,在配置文件中设置。 字数和阅读时长 安装以下插件:1npm i --save hexo-wordcount 修改配置文件,将 wordcount 插件打开blog/_config.volantis.yml12345plugins: ... # 文章字数统计、阅读时长,开启需要安装插件: npm i --save hexo-wordcount wordcount: enable: #true 然后修改配置文件,将 wordcount 写入需要显示的 meta 位置:blog/_config.volantis.yml123456789101112# 文章布局article: ... # 文章详情页面的文章卡片本体布局方案 body: # 文章顶部信息 # 从 meta_library 中取 top_meta: [..., wordcount, ...] ... # 文章底部信息 # 从 meta_library 中取 bottom_meta: [..., wordcount, ...] 数据分析百度统计blog/_config.yml1baidu_analytics_key: 百度统计的key Google Analyticsblog/_config.yml1google_analytics_key: Google Analytics Key 腾讯前端性能监控blog/_config.yml1tencent_aegis_id: 上报 id CNZZ 统计请参考 ZYMIN 的这篇教程: Hexo hexo+ejs+material x 添加CNZZ统计代码https://zymin.cn/arcticle/hexo+ejs+material.html 更多进阶玩法详见 @TRHX 的这篇博客: Hexo 博客主题个性化https://www.itrhx.com/2018/08/27/A04-Hexo-blog-topic-personalization/ 内含卡片半透明、增加卡通人物、自定义鼠标样式、鼠标特效、烟花特效、彩色滚动字体、网站运行时间、动态浏览器标题、雪花飘落特效等多种详细教程。 主题官网 #进阶玩法https://volantis.js.org/categories/进阶玩法/"},{"title":"","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/getting-started/index.html","permalink":"https://zy68.top/v5/getting-started/index.html","excerpt":"","text":" Volantis5 A Wonderful Theme for Hexo Volantis 是一个功能丰富、高度模块化的 Hexo 博客主题。得益于其强大的模块化特性,您可以轻松搭建一个极简风格的博客,也可以仿照官网搭建一个多人协作的、包含文档模块的大体量综合型博客。 示例博客https://volantis.js.org/examples/ 所有的 Volantis 用户都可以按照格式自行创建 Issue 来将自己的博客添加到官网的示例博客页面中。 准备工作能力条件环境配置条件自建博客需要一定的相关知识,在开始前,请务必确保您会使用 markdown 语法,掌握简单的 git 知识,最最重要的是,遇到困难知道该怎么寻求解决: 翻阅和搜索文档 搜索 issues 中是否有解决办法 新建 issue 并按照要求进行操作,详尽地描述您遇到的问题 如果您没有使用过 Hexo 也不要着急,可以先通读一遍 Hexo 中文文档,要想使用地得心应手,最好参照团队提供的开源项目的源码进行搭建: Demo 源码 | 官网源码如果您从旧版本更新或着其它主题迁移,请确保环境版本不要太低,否则会产生兼容性问题。 1234Hexo: 4.2 ~ 5.xhexo-cli: 3.1 ~ 4.xnode.js: 12.16 ~ latest # 推荐使用 LTS 版npm: 6.13 ~ latest 快速体验如果您已经具备环境配置条件,可以在终端中输入下面这行代码,稍等片刻即可尝鲜体验: 1git clone https://github.com/volantis-x/demo.git && cd demo && npm i && hexo s 下载与安装volantis 5.x 目前正处于 「alpha 阶段」 volantis 4.x 目前正处于 「stable 阶段」 volantis 开发发布周期依次经过: 「alpha 阶段」=>「beta 阶段」=>「rc 阶段」=>「stable 阶段」 rc 阶段的测试版本和 stable 阶段的正式版本 我们统称为 「稳定版本」 , 只有 「稳定版本」 发布到 npm alpha 阶段的开发测试版本 和 beta 阶段的测试版本 我们统称为 「小白鼠测试版本」, 「小白鼠测试版本」 仅存在于 Github 仓库的 dev 分支 安装或更新 「稳定版本」 (rc 阶段的测试版本 或 stable 阶段的正式版本) 全新博客安装从其它主题迁移第 1/2 步:修改站点配置文件在 blog/_config.yml 文件中找到并修改:1theme: volantis第 2/2 步:下载主题在终端中输入:1npm i hexo-theme-volantis 如果您是 Mac 用户,可以使用脚本完成全部流程 在博客路径打开终端,下载安装并应用主题:1curl -s https://volantis.js.org/start | bash这行命令将会自动检测并安装所需环境,初始化博客,然后下载安装并应用主题。脚本详细使用方法:#hexo.sh 第 1/3 步:修改站点配置文件在 blog/_config.yml 文件中找到并修改:1theme: volantis第 2/3 步:下载主题如果您已经升级到 Hexo 5.0.2 及以上,可以直接使用 npm 命令安装:1npm i hexo-theme-volantis对于旧版本,需要下载主题源码到 themes/ 文件夹:1git clone https://github.com/volantis-x/hexo-theme-volantis themes/volantis如果您无法访问 GitHub 可以使用国内镜像源:1git clone https://e.coding.net/volantis-x/p/hexo-theme-volantis.git themes/volantis第 3/3 步:检查并安装依赖安装 Hexo 搜索的依赖包:1npm i hexo-generator-search hexo-generator-json-content安装 Stylus 渲染器:1npm i hexo-renderer-stylus 安装或更新 「小白鼠测试版本」 (alpha 阶段的开发测试版本 或 beta 阶段的测试版本) 第 1/3 步:修改站点配置文件在 blog/_config.yml 文件中找到并修改:1theme: volantis第 2/3 步:将主题仓库添加为子模块 将主题添加为子模块 开始前需要确认不存在 themes/volantis 文件夹, 如果有, 请自行删除.sshhttps1git submodule add [email protected]:volantis-x/hexo-theme-volantis.git themes/volantis1git submodule add https://github.com/volantis-x/hexo-theme-volantis.git themes/volantis 第 3/3 步:将主题仓库切换为 dev 分支在终端中输入:12cd themes/volantisgit checkout dev第 n/n 步:更新主题在终端中输入:1git pull ## 版本更新注意事项 使用主题的时候,尽量 fork 主题到自己的 GitHub,然后进行修改并使用。这样做的好处是:当主题进行重要更新的时候可以根据需要拉取合并代码,使自己 DIY 的主题能够通过更新获取 BUG 修复或者新特性。 如果不懂请自行搜索关键词:fork 更新 实用小技巧所有需要写在主题配置文件中的配置都可以写在站点配置文件的 theme_config: 中,在 Hexo 5.0 后,还可以写在 _config.volantis.yml 文件中,详见 Hexo 官方文档:覆盖主题配置https://hexo.io/zh-cn/docs/configuration#%E8%A6%86%E7%9B%96%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE也可以直接查看本站源码中站点配置文件的写法:_config.volantis.yml 请对照 更新日志 进行更新. 如何正确地更新主题/how-to-update/ 许可协议本主题采用 MIT开源许可协议 ,永久无限制免费使用。 MIT开源许可协议被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本。被授权人可根据程式的需要修改授权条款为适当的内容。在软件和软件的所有副本中都必须包含版权声明和许可声明。 配置与使用配置与使用/v5/site-settings/"},{"title":"页面配置","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/page-settings/index.html","permalink":"https://zy68.top/v5/page-settings/index.html","excerpt":"","text":"页面布局模板布局模板 取值 含义 page 独立页面 post 文章页面 docs 文档页面 category 分类页面 tag 标签页面 friends 友链页面 list 列表页面 page & post & docs这三种页面相同,但是有以下细微区别: post 文章有 title 时,向下滚动网页,导航栏会向上移出屏幕显出文章标题,而 page 和 docs 不会。 post 文章末尾最多可以显示「参考资料」、「相关文章」、「版权标识」、「打赏」四个模块。 docs 文章末尾最多可以显示「参考资料」一个模块。 除了归档页面是自动生成的,其它独立页面都需要手动创建 md 文件。 归档页面归档页面是自动生成的,并且初始化的时候已经生成,路径如下: blog/_config.yml12# Directoryarchive_dir: archives 关于页面Create file if not exists: source/about/index.md1234567891011---layout: docsseo_title: 关于bottom_meta: falsesidebar: []valine: placeholder: 有什么想对我说的呢?---下面写关于自己的内容 分类页面Create file if not exists: source/categories/index.md12345---layout: categoryindex: truetitle: 所有分类--- 标签页面Create file if not exists: source/tags/index.md12345---layout: tagindex: truetitle: 所有标签--- 列表页面Create file if not exists: source/mylist/index.md12345---layout: listgroup: mylistindex: true--- 结果就是筛选出所有文章中 front-matter 部分含有 group: mylist 的文章。 友链页面创建页面文件Create file if not exists: source/friends/index.md1234567891011---layout: friends # 必须title: 我的朋友们 # 可选,这是友链页的标题---这里写友链上方的内容。<!-- more -->这里可以写友链页面下方的文字备注,例如自己的友链规范、示例等。 插入友链数据可以 选择布局方案 或 使用友链标签 选择布局方案在主题配置文件中找到以下内容: 1234pages: # 友链页面配置 friends: layout_scheme: traditional # simple: 简单布局, traditional: 传统布局 目前提供2种布局方案: simple: 简单布局,只有头像和标题。 traditional: 传统布局,是 Volantis 旧版本的风格。 以上2种友链的数据源写在以下路径,如果没有请自行创建: 1blog/source/_data/friends.yml 内容格式为: blog/source/_data/friends.yml123456789101112131415- group: # 分组标题 description: # 分组描述 items: - title: # 名称 avatar: # 头像 url: # 链接 screenshot: # 截图 keywords: # 关键词 description: # 描述 - title: # 名称 avatar: # 头像 url: # 链接 screenshot: # 截图 keywords: # 关键词 description: # 描述 不同的布局方式,会用到一部分的字段,一般来说,title、avatar 和 url 都是必须的。这些数据被转成 HTML 标签插入到友链页面的 <!-- more --> 部分。 Volantis 4.x 新增的网站卡片标签的样式 sites 网站卡片布局 在5.0版本移除 被 sites标签 friends标签 contributors标签 替代 issues 标签在5.0版本移除 被 sites标签 friends标签 contributors标签 替代 使用友链标签使用 友链标签 您可以在任何位置插入友链,支持静态数据和动态数据, 关于如何使用 友链标签 插入友链,详见: volantis 主题文档 #友链标签/v5/tag-plugins/#友链标签 404页面Create file if not exists: source/404.md12345678910111213141516---cover: truerobots: noindex,nofollowsitemap: falseseo_title: 404 Not Foundbottom_meta: falsesidebar: []valine: path: /404.html placeholder: 请留言告诉我您要访问哪个页面找不到了---{% p logo center huge, 404 %}{% p center bold, 很抱歉,您访问的页面不存在 %}{% p center small, 可能是输入地址有误或该地址已被删除 %} front-matterfront-matter 是文件最上方以 --- 分隔的区域,用于指定个别文件的变量。更多请见 Hexo 官方文档:#front-matter 字段 含义 值类型 默认值 layout 布局模版 String - title 页面标题 String - seo_title 网页标题 String page.title short_title 页面标题(在group列表中显示) String page.title date 创建时间 Date 文件创建时间 updated 更新日期 Date 文件修改时间 link 外部文章网址 String - music 内部音乐控件 [Object] - robots robots String - keywords 页面关键词 String - description 页面描述、摘要 String - cover 是否显示封面 Bool true top_meta 是否显示文章或页面顶部的meta信息 Bool true bottom_meta 是否显示文章或页面底部的meta信息 Bool true sidebar 页面侧边栏 Bool, Array theme.layout.*.sidebar body 页面主体元素 Array theme.layout.on_page.body thumbnail 缩略图 String false icons 图标 Array [] pin 是否置顶 Bool false headimg 文章头图 url - layout:post 时特有的字段: 字段 含义 值类型 默认值 author 文章作者 [Object] config.author categories 分类 String, Array - tags 标签 String, Array - toc 是否生成目录 Bool true music 字段 是否必须 值类型 server 是 netease, tencent, kugou, xiami, baidu type 是 song, playlist, album, search, artist id 是 song id / playlist id / album id / search keyword 文章置顶在 front-matter 中设置以下值: front-matter1pin: true 文章分类多个分类有两种关系,一种是层级(等同于文件夹),一种是并列(等同于标签)。 多级分类: front-matter123---categories: [分类A, 分类B]--- 或者 front-matter12345---categories: - 分类A - 分类B--- 并列分类 front-matter123categories: - [分类A] - [分类B] 多级+并列分类 front-matter123categories: - [分类A, 分类B] - [分类C, 分类D] 文章摘要在文章中插入 <!-- more -->,前面的部分即为摘要。 某篇文章源码12345678910---title: xxxdate: 2020-02-21---这是摘要<!-- more -->这是正文 注意: <!-- more --> 前后一定要有空行,不然可能导致显示错位。 设置文章作者Volantis 支持多个作者在一个站点发布文章,其他作者信息需要写在数据文件中,例如: blog/source/_data/author.yml12345678Jon: name: Jon Snow avatar: https://cn.bing.com/th?id=AMMS_fc8f99fd41ebd737a71c4e13806db9a0&w=110&h=110&c=7&rs=1&qlt=80&pcl=f9f9f9&cdv=1&dpr=2&pid=16.1 url: https://gameofthrones.fandom.com/wiki/Jon_SnowDany: name: Daenerys Targaryen avatar: https://tse1-mm.cn.bing.net/th?id=OIP.Yax4wLzIFbcBVUa_RsKywQHaLH&w=80&h=80&c=8&rs=1&qlt=90&dpr=2&pid=3.1&rm=2 url: https://gameofthrones.fandom.com/wiki/Daenerys_Targaryen 在文章的 front-matter 中新增 author 即可: front-matter1234---title: Jon Snow | Game of Thrones Wiki | Fandomauthor: Jon--- 引入外部文章利用 link,搭配自定义的文章作者信息,你可以在文章列表中显示外部文章或者网址,例如: blog/source/_data/author.yml1234xaoxuu: name: xaoxuu avatar: https://cdn.jsdelivr.net/gh/xaoxuu/assets@master/avatar/avatar.png url: https://xaoxuu.com front-matter12345678910111213---layout: postdate: 2017-07-05title: [转]如何搭建基于Hexo的独立博客categories: [Dev, Hexo]tags: - Hexoauthor: xaoxuulink: https://xaoxuu.com/blog/2017-07-05-hexo-blog/---![](https://img.vim-cn.com/d9/a9af7dc49fc0af8ca3e6dd2450a2f7095a87db.png) 置顶对于任何文章或者页面,设置 pin: true 即可置顶在首页。 front-matter123---pin: true--- 这会导致一个小问题:首页 post 卡片数量多于设定值,如果有强迫症希望每一个分页数量一致,可以安装插件来实现,详见:#421 不归档存放在 _posts 文件夹下的文章一般都会出现在归档页,如果某篇文章不希望出现在归档页面: front-matter123---archive: false--- 页面自定义布局显示迷你音乐播放器标题右边显示迷你音乐播放器,支持的字段有:server、type、id。 front-matter123456---music: server: netease # netease, tencent, kugou, xiami, baidu type: song # song, playlist, album, search, artist id: 16846091 # song id / playlist id / album id / search keyword--- 实际效果见: #contributors 显示 meta 标签文章顶部和底部的日期、分类、更新日期、标签、分享等属于 meta 标签。 front-matter1234---top_meta: falsebottom_meta: false--- 如果一个页面没有 title 则不会显示 top_meta ,像404、关于页面就可以完全隐藏: front-matter12345---seo_title: 关于top_meta: falsebottom_meta: false--- 标题右边显示缩略图front-matter123---thumbnail: https://img.vim-cn.com/17/0c7b02722686d1527a1df807dae0794d995860.png--- 缩略图仅在文章列表和文章页面显示,不会在归档页面显示。 标题右边显示图标front-matter123---icons: [fas fa-fire red, fas fa-star green]--- 图标仅在归档页面中显示,可以用来标注热门文章。 可以通过 red / blue / green / yellow / orange / theme / accent 来设置图标的颜色 是否要显示封面如果某个页面需要封面,可以这样写: front-matter123---cover: true--- 显示侧边栏通过自由设置边栏卡片来删减对应页面的冗余信息,提高有价值的信息在页面中的权重。 如果某个页面不需要侧边栏,可以这样写: front-matter123---sidebar: []--- 某个页面想指定显示某几个侧边栏,就这样写: front-matter123---sidebar: [grid, toc, tags] # 放置任何你想要显示的侧边栏部件--- 关闭评论front-matter123---comments: false--- 页面插件 (page plugins)在 front-matter 中配置页面插件 front-matter123456789101112---plugins: - mathjax - katex - artitalk - bbtalk - hpptalk - fcircle - gitter - indent - snackbar: oldversion--- 说说页面以 Artitalk页面 为例: 创建页面文件Create file if not exists: source/artitalk/index.md123456789---seo_title: 说说comments: falseplugins: - artitalk # - bbtalk # - fcircle # - hpptalk--- 配置Artitalk在主题配置文件中找到以下内容 123456789101112131415161718192021# Artitalk https://artitalk.js.org# 配置过程请参考:https://artitalk.js.org/doc.html# 使用过旧版本的请修改Leancloud shuoshuo class部分列名:https://artitalk.js.org/release.html# 除appID和appKEY外均为选填项artitalk: # Set `plugins: ["artitalk"]` to enable in front-matter # 不支持 Pjax # 配置项按照yml格式继续填写即可 appId: # your appID appKey: # your appKEY # serverURL: #leancloud绑定的api访问域名,使用国际版的话不需要填写 # lang: # 语言设置,zh为汉语,en为英语,es为西班牙语。默认为汉语 # pageSize: #每页说说的显示数量 # shuoPla: #在编辑说说的输入框中的占位符 # avatarPla: #自定义头像url的输入框的占位符 # motion: #加载动画的开关,1为开,0为关,默认为开 # bgImg: #说说输入框背景图片url # color1: #说说背景颜色1&按钮颜色1 # color2: #说说背景颜色2&按钮颜色2 # color3: #说说字体颜色 # cssUrl: #自定义css接口 最后记得屏蔽Artitalk页面的pjax 渲染公式默认是不渲染的,如果文章内有公式,需要在 front-matter 中设置开启。即便开启了,文章列表中也不会进行渲染,请注意不要把公式写在文章开头。 example.md:123456789101112131415161718192021222324252627282930---title: 渲染公式(MathJax)date: 2020-02-23plugins: - mathjax---添加一段描述性文字<!-- more -->$$t+1=2$$$$\\mbox{积累因子}=\\begin{cases}1+ni & \\mbox{单利}\\\\\\\\(1+i)^n & \\mbox{复利}\\end{cases}$$$$\\begin{equation}\\sum_{i=0}^n F_i \\cdot \\phi (H, p_i) - \\sum_{i=1}^n a_i \\cdot ( \\tilde{x_i}, \\tilde{y_i}) + b_i \\cdot ( \\tilde{x_i}^2 , \\tilde{y_i}^2 )\\end{equation}$$$$\\begin{equation}\\beta^*(D) = \\mathop{argmin} \\limits_{\\beta} \\lambda {||\\beta||}^2 + \\sum_{i=1}^n max(0, 1 - y_i f_{\\beta}(x_i))\\end{equation}$$ 查看公式渲染效果 $$t+1=2$$$$\\mbox{积累因子}=\\begin{cases}1+ni & \\mbox{单利}\\\\(1+i)^n & \\mbox{复利}\\end{cases}$$$$\\begin{equation}\\sum_{i=0}^n F_i \\cdot \\phi (H, p_i) - \\sum_{i=1}^n a_i \\cdot ( \\tilde{x_i}, \\tilde{y_i}) + b_i \\cdot ( \\tilde{x_i}^2 , \\tilde{y_i}^2 )\\end{equation}$$$$\\begin{equation}\\beta^*(D) = \\mathop{argmin} \\limits_{\\beta} \\lambda {||\\beta||}^2 + \\sum_{i=1}^n max(0, 1 - y_i f_{\\beta}(x_i))\\end{equation}$$ 如果公式仍无法正确渲染可以阅读 @MicDZ 的这篇文章: 在Material-X上使用KaTeXhttps://www.micdz.cn/article/katex-on-volantis/ 页面 gitter页面配置 front-matter1234---plugins: - gitter--- 配置 gitter在主题配置文件中找到以下内容 123456plugins: .... # Gitter # https://gitter.im gitter: room: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 文章页首行缩进front-matter1234---plugins: - indent--- Snackbar (页面通知)配置数据源数据源写在以下路径,如果没有请自行创建: 1blog/source/_data/notification.yml 内容格式为: blog/source/_data/notification.yml12345678910oldversion: title: 过期的文档 message: 这份文档过于久远,如果您使用的是新版的主题,请查看新版本的文档。 position: bottom # bottom (底部通知), right (右侧通知,会自动消失) theme: warning # default, warning cache: false # 是否记住选项(下次不再弹出) buttons: - title: 查看新版文档 url: /getting-started/ dismiss: false # 点击了是否关闭底部横幅 配置 front-matterfront-matter1234---plugins: - snackbar: oldversion---"},{"title":"站点配置","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/site-settings/index.html","permalink":"https://zy68.top/v5/site-settings/index.html","excerpt":"","text":"博客根目录下的 _config.yml 文件通常负责站点相关配置、第三方 npm 插件相关的配置。 网站标题blog/_config.yml12# 网站标题title: my blog 网站图标简单方式完全自定义blog/_config.yml12# 网站图标,更多尺寸等图标请使用import方式批量导入favicon: https://cdn.jsdelivr.net/gh/xaoxuu/assets@master/favicon/favicon.icoblog/_config.yml123456789101112import: meta: - <meta name="msapplication-TileColor" content="#ffffff"> - <meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/browserconfig.xml"> - <meta name="theme-color" content="#ffffff"> link: - <link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/apple-touch-icon.png"> - <link rel="icon" type="image/png" sizes="32x32" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon-32x32.png"> - <link rel="icon" type="image/png" sizes="16x16" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon-16x16.png"> - <link rel="manifest" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/site.webmanifest"> - <link rel="mask-icon" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/safari-pinned-tab.svg" color="#5bbad5"> - <link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon.ico"> 多语言设置blog/_config.yml12345language: - zh-CN - en - zh-HK - zh-TW 对应的翻译文件路径: themes/volantis/languages/ 使用 Import 导入外部文件Volantis 用户可以在不修改主题文件的情况下向 head 和 body 中添加各种标签。meta 和 link 对应 head 中的 <meta> 和 <link> 标签。script 可以在 body 末尾导入 js 代码。 blog/_config.yml1234567891011121314import: meta: - <meta name="msapplication-TileColor" content="#ffffff"> - <meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/browserconfig.xml"> - <meta name="theme-color" content="#ffffff"> link: - <link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/apple-touch-icon.png"> - <link rel="icon" type="image/png" sizes="32x32" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon-32x32.png"> - <link rel="icon" type="image/png" sizes="16x16" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon-16x16.png"> - <link rel="manifest" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/site.webmanifest"> - <link rel="mask-icon" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/safari-pinned-tab.svg" color="#5bbad5"> - <link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/favicon.ico"> script: - <script></script> 更多Hexo 官方文档 #配置https://hexo.io/zh-cn/docs/configuration"},{"title":"开发文档","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/development-api/index.html","permalink":"https://zy68.top/v5/development-api/index.html","excerpt":"","text":" Volantis5 Development API for Volantis 样式文件说明/source/css/Readme.md 全局变量 volantis我们提供了全局变量 volantis 和一些全局函数等主题开发调用接口。 源码参考:layout/_partial/scripts/global.ejs PjaxPjax 重载区域划分接口我们提供了可以实现Pjax重载区域灵活划分的开发接口。 源码参考:layout/_plugins/pjax/index.ejs <pjax></pjax> 标签所有被 <pjax></pjax> 标签包裹的所有元素将被pjax重载。 请检查并确保 pjax 标签必须存在于所有页面 否则 pjax error. 12345678<pjax> <!--我是将被pjax重载的内容 begin--> <div> <div></div> <script></script> </div> <!--我是将被pjax重载的内容 end--></pjax> 使用案例:/layout/_partial/scripts/index.ejs script[data-pjax]所有含有 data-pjax 标记的 script 标签将被pjax重载。 1<script data-pjax>我是将被pjax重载的内容</script> .pjax-reload script所有在 pjax-reload Class元素内部的 script 标签将被pjax重载。 123456<div class="pjax-reload"> <div> <div>我不是将被pjax重载的内容</div> <script>我是将被pjax重载的内容</script> </div></div> Pjax 回调方法我们提供了灵活的 Pjax 回调方法。 源码参考: layout/_partial/scripts/global.ejs layout/_plugins/pjax/index.ejs 使用案例:layout/_plugins/pjax/animate.ejs 中括号[]里面的内容表示选项是可选的,可以不填。下同,不再赘述。 volantis.pjax.push 在Pjax请求完成后触发。使用 volantis.pjax.push(callBack[,"callBackName"]) 传入pjax:complete回调函数。 callBack是回调函数,必填。 "callBackName" string类型 默认值是回调函数的函数名,选填。 volantis.pjax.send 在Pjax请求开始后触发。使用 volantis.pjax.send(callBack[,"callBackName"]) 传入pjax:send回调函数。 callBack是回调函数,必填。 "callBackName" string类型 默认值是回调函数的函数名,选填。 volantis.pjax.error 在Pjax请求失败后触发。使用 volantis.pjax.error(callBack[,"callBackName"]) 传入pjax:error回调函数。 callBack是回调函数,必填。 "callBackName" string类型 默认值是回调函数的函数名,选填。 暗黑模式我们提供了暗黑模式灵活的开发接口。 源码参考: layout/_partial/scripts/global.ejs layout/_partial/scripts/darkmode.ejs 暗黑模式样式详见:/source/css/Readme.md 当前模式调用 volantis.dark.mode 查看当前模式。返回值为字符串 dark 或者 light。 暗黑模式触发器调用 volantis.dark.toggle() 触发切换亮黑模式。 暗黑模式触发器回调函数调用 volantis.dark.push(callBack[,”callBackName”]) 传入触发器回调函数. 使用案例:layout/_plugins/comments/utterances/script.ejs Message 消息提示我们在 iziToast 的基础上封装了一个简单的消息提示: 源码参考: layout/_plugins/message/script.ejs 12volantis.message(title, message, option, done);volantis.question(title, message, option, success, cancel, done); title:标题(必填),字符串(String) message:内容(必填),字符串(String) option:配置项,对象(Object) done:完成时回调,函数(Function) success:确认时回调,函数(Function) cancel: 取消时回调,函数(Function) option 可选参数: icon, // Fontawesome 图标 time, // 持续时间 position, // 弹出位置 transitionIn, // 弹窗打开动画 transitionOut, // 弹窗关闭动画 messageColor, // 消息颜色 titleColor, // 标题颜色 backgroundColor, // 默认背景色 zindex // 层级 option 配置优先级大于配置文件设置值。 使用范例: 123456789101112131415161718// 同样弹窗volantis.message('这里是标题', '这里是弹窗内容');// 居中弹窗volantis.message('系统提示', '这里是 Volantis 主题站,欢迎访问。', { icon: 'fad fa-smile-wink light-blue', position: 'topCenter', transitionIn:'bounceInDown', transitionOut: 'fadeOutDown', time: 10000});// 询问弹窗volantis.question('问卷调查', '你是否喜欢 Volantis 主题', {}, () => { alert('谢谢支持')}, () => { console.log('再接再厉')}); 如果以上两个接口仍然不能满足您的需求,可以参考 iziToast 的内容直接调用 iziToast() 动态加载脚本源码参考: layout/_partial/scripts/global.ejs 12volantis.js("src", cb)volantis.css("src") src String类型 加载脚本URL cb 可选 可以传入onload回调函数 或者 JSON对象 例如: volantis.js("src", ()=>{}) 或 volantis.js("src", {defer:true,onload:()=>{}}) 返回 Promise 对象 如下方法同步加载资源,这利于处理文件资源之间的依赖关系,例如:APlayer 需要在 MetingJS 之前加载 1234(async () => { await volantis.js("...theme.plugins.aplayer.js.aplayer...") await volantis.js("...theme.plugins.aplayer.js.meting...")})(); 使用案例:layout/_plugins/aplayer/script.ejs 由于返回的是 Promise 对象,也可以采用以下方式实现加载完成后调用回调函数: 123volantis.js("https://cdn.jsdelivr.net/npm/jquery").then(()=>{ console.log("我在脚本加载完成后调用")}) 按需加载的插件源码参考: layout/_partial/scripts/global.ejs jQuery12345volantis.import.jQuery().then(()=>{ // 依赖 jQuery 的代码段 // ..... // .....}) requestAnimationFrame1、requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。 2、在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。 12345volantis.requestAnimationFrame(() => { // 包含 DOM 操作的代码段 // ......... // .........}) Layout Helper向目标元素动态注入 HTML 1volantis.layoutHelper(helper, html, opt) helper:Helper id(必填),字符串(String) html:HTML(必填),字符串(String) opt:配置项,对象(Object) opt 可选参数: clean, // 清除 Layout Helper 原有的所有内容, 默认 false pjax, // 支持 pjax, 默认 true helper 可选参数: page-plugins, // 页面插件 Layout, 位于 layout/_partial/article.ejs comments, // 评论 Layout, 位于 layout/_plugins/comments/index.ejs 12// 向 page-plugins 入口动态注入 id 为 artitalk_main 的 div, 不启用 pjax, 不清除 Layout Helper 原有的内容volantis.layoutHelper("page-plugins",`<div id="artitalk_main"></div>`, { pjax:false, clean:false }) 滚动事件处理源码参考:layout/_partial/scripts/global.ejs 获取滚动条距离顶部的距离1volantis.scroll.getScrollTop() 获取滚动方向1volantis.scroll.del volantis.scroll.del 中存储了一个数值, 该数值检测一定时间间隔内滚动条滚动的位移, 数值的检测频率是浏览器的刷新频率. 数值为正数时, 表示向下滚动. 数值为负数时, 表示向上滚动. 滚动事件回调函数使用 volantis.scroll.push(callBack[,"callBackName"]) 传入滚动事件回调函数, 当页面滚动时触发回调函数。 1234567volantis.scroll.push(()=>{ if (volantis.scroll.del > 0) { console.log("向下滚动"); } else { console.log("向上滚动"); }}) 使用 volantis.scroll.unengine.push(callBack[,"callBackName"]) 传入非滚动事件回调函数, 当页面没有滚动时触发回调函数。 使用 volantis.scroll.unengine.remove("callBackName") 移除名称为 “callBackName” 的非滚动事件回调函数。 触发页面滚动至目标元素位置12// 滚动到目标 Dom 元素 "ele" 位置volantis.scroll.to(ele, option) ele:Dom 元素(必填) option 可选参数: top, // 类型 Float,文档中的纵轴坐标, 默认值 ele.getBoundingClientRect().top + document.documentElement.scrollTop addTop, // 类型 Float,向上面的 top 参数中 添加补偿值. behavior, // 类型 String, 表示滚动行为, 支持参数 smooth (平滑滚动), instant (瞬间滚动) observer, // 类型 Boolean, 是否启用监视器,默认值 false, 监视器用于监视元素是否滚动到指定位置 目前用于处理 toc 部分 lazyload 引起的 cls 导致的定位失败问题. observerDic, // 类型 Float, 监视器监视距离, 默认值 25. 例如: 1volantis.scroll.to(document.getElementById("locationID"),{addTop: - volantis.dom.header.offsetHeight - 10, behavior: 'instant'}) 对本地文件使用CDN源码参考: layout/_partial/scripts/_ctrl/cdnCtrl.ejs 12theme.cdn.addJS("name","source","force")theme.cdn.addCSS("name","source","force") 参数都为 String 类型,其中 source 和 force 是可选的。 返回值为 CDN 处理后的链接,并存入theme.cdn.map.js和theme.cdn.map.css中 可以使用theme.cdn.map.js["name"]再次调用。 "name" 是自定义名称 "source" 是资源路径 "force" 是强制覆盖的资源路径 如果"source"为空,则将"name"赋值给"source"。 例如: 对于文件source/js/plugins/sites.js使用CND链接,使用如下方法生成。 1theme.cdn.addJS("sites","plugins/sites") 生成的CDN链接可使用 theme.cdn.map.js.sites 回调。 以下用于配置项 cdn.set 覆盖配置,下面是覆盖配置的方法 123456789101112131415cdn: enable: true # 以下配置可以覆盖 cdn.prefix,配置项的值可以为空,但是要使用CDN必须依据路径填写配置项的键 set: js: app: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/app.js rightMenu: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/rightMenu.js parallax: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/parallax.js plugins: contributors: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/contributors.js friends: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/friends.js sites: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/sites.js css: style: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/css/style.css message: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/css/message.css 直接使用cdn配置项,不使用theme.cdn.addJS("sites","plugins/sites") 也可以生成 theme.cdn.map.js.sites CDN链接回调 Custom Files 自定义文件在不修改主题原始源代码的情况下添加自定义内容 注入点我们提供了一些注入点接口: 123456789101112131415161718let points={ styles:[ "first", "style", "dark", "darkVar", ], views:[ "head", "header", "side", "topMeta", "bottomMeta", "footer", "postEnd", "bodyEnd", ]} 样式注入点 first: 向 theme/source/css/first.styl 文件末尾注入自定义内容, 该文件中包含首屏样式,首屏样式采用硬编码的方式写在HTML中。首屏样式内含 cover navbar search 的样式. style: 向 theme/source/css/style.styl 文件末尾注入自定义内容, 该文件中包含异步延迟加载的样式,除首屏样式,其他样式放入此处异步加载. dark: 向 theme/source/css/_style/_plugins/_dark/dark_plugins.styl 文件末尾注入自定义内容, 该文件中包含异步暗黑模式样式 的 强制覆盖样式. darkVar: 向 theme/source/css/_style/_plugins/_dark/dark_async.styl 调用函数 async_dark() 末尾注入自定义内容, 该文件中包含异步暗黑模式样式 的 暗黑模式 CSS 变量. 布局视图注入点 head: 向 theme/layout/_partial/head.ejs 文件 <head> 标签末尾注入自定义内容. header: 向 theme/layout/_partial/header.ejs 文件 导航栏 .nav-main 末尾注入自定义内容. side: 向 theme/layout/_partial/side.ejs 文件 侧边栏 #l_side 末尾注入自定义内容. topMeta: 向 theme/layout/_partial/meta.ejs 文件 topMetas 末尾注入自定义内容. bottomMeta: 向 theme/layout/_partial/meta.ejs 文件 bottomMetas 末尾注入自定义内容. footer: 向 theme/layout/_partial/footer.ejs 文件 <footer> 标签末尾注入自定义内容. postEnd: 向 theme/layout/_partial/article.ejs 文件 <article> 标签末尾注入自定义内容. bodyEnd: 向 theme/layout/layout.ejs 文件 <body> 标签末尾注入自定义内容. blog/source/_volantis/ 文件夹一般的, 创建 blog/source/_volantis/ 文件夹并在此文件夹下创建与注入点同名同扩展名的文件,用以写入注入点自定义内容. 123456789101112blog/source/_volantis/ ├─ first.styl ├─ style.styl ├─ dark.styl ├─ darkVar.styl ├─ head.ejs ├─ header.ejs ├─ topMeta.ejs ├─ bottomMeta.ejs ├─ postEnd.ejs └─ bodyEnd.ejs 当然,你仍然可以修改主题配置文件将自定义布局或样式放置在特定位置.以下是默认配置,该配置已隐藏. blog/_config.volantis.yml1234567891011custom_files: first: source/_volantis/first.styl style: source/_volantis/style.styl dark: source/_volantis/dark.styl darkVar: source/_volantis/darkVar.styl head: source/_volantis/head.ejs header: source/_volantis/header.ejs topMeta: source/_volantis/topMeta.ejs bottomMeta: source/_volantis/bottomMeta.ejs postEnd: source/_volantis/postEnd.ejs bodyEnd: source/_volantis/bodyEnd.ejs 示例: blog/source/_volantis/darkVar.styl12body --color-site-body: blue !important theme_inject 过滤器使用 Hexo 过滤器 theme_inject ,可以将所需的自定义内容添加到任何注入点。 如果您的代码很简单,建议您编写脚本,您只需要把 JavaScript 文件放到 scripts 文件夹,在启动时就会自动载入。您可以直接在 blog 文件夹下创建 scripts 文件夹. 123hexo.extend.filter.register('theme_inject', function(injects) { // ...}); 对于注入布局视图: 123456789// The name of same `injectPoint` suggest be unique. If same, it will override low priority configurations.// `locals` and `options` is the same as partial https://hexo.io/docs/helpers#partial.// `order` defines the order of injection, which by default depends on the priority of injection.hexo.extend.filter.register('theme_inject', function(injects) { // it will put code from this filePath into injectPoint. injects.[injectPoint].file(name, filePath, [locals, options, order]); // it will put raw string as code into injectPoint. injects.[injectPoint].raw(name, raw, [locals, options, order]);}); 对于注入样式: 1234hexo.extend.filter.register('theme_inject', function(injects) { // it will put styleFile into injectPoint. injects.[injectPoint].push(styleFile);}); Examples以文件的形式向 theme/css/style.styl 文件末尾注入自定义样式 blog/scripts/example-1.js123hexo.extend.filter.register('theme_inject', function(injects) { injects.style.push('source/_data/mystyle.styl');}); 以文本的形式向 <body> 标签末尾注入自定义脚本内容 blog/scripts/example-2.js123hexo.extend.filter.register('theme_inject', function(injects) { injects.bodyEnd.raw('load-custom-js', '<script src="js-path-or-cdn.js"></script>');}); 以文件的形式向侧栏注入自定义布局视图内容 blog/scripts/example-3.js123hexo.extend.filter.register('theme_inject', function(injects) { injects.sidebar.file('my-favourite-food', 'source/_data/my-favourite-food.ejs');}); 插件系统我们还支持 hexo 的插件系统,无需修改核心模块的源代码即可轻松扩展功能。你可以参考 https://hexo.io/docs/plugins.html#Plugin 学习如何创建插件。 请注意,以上是主题开发文档,不是使用文档!"},{"title":"标签插件","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/tag-plugins/index.html","permalink":"https://zy68.top/v5/tag-plugins/index.html","excerpt":"","text":"为了兼容老用户,旧的标签插件在重构之前依然沿用旧的格式,即 command + 空格 作为参数分隔符,而部分新增标签插件是 空格 + 英文竖线 + 空格 ,请注意区分。 我们也在探索哪种分隔符既简单又不容易引起冲突,所以可能存在多种格式,具体以对应文档描述为准。 5.0 版本起临时实验使用英文双冒号 ( :: ) 作为分隔符,之前版本的分隔符写法向下兼容 5.0 版本的分隔符最终计划使用 stellar 的分隔符,之前版本的分隔符写法没有兼容计划 ## text 效果源码带 下划线 的文本;带 着重号 的文本;带 波浪线 的文本;带 删除线 的文本 键盘样式的文本:⌘ + D 密码样式的文本:这里没有验证码12345带 {% u 下划线 %} 的文本;带 {% emp 着重号 %} 的文本;带 {% wavy 波浪线 %} 的文本;带 {% del 删除线 %} 的文本键盘样式的文本:{% kbd ⌘ %} + {% kbd D %}密码样式的文本:{% psw 这里没有验证码 %} ## span 语法效果源码参数本插件最后更新于 5.0 版本1{% span 样式参数::文本内容 %}各种颜色的标签,包括:红色、黄色、绿色、青色、蓝色、灰色。 超大号文字: Volantis A Wonderful Theme for Hexo12345各种颜色的标签,包括:{% span red::红色 %}、{% span yellow::黄色 %}、{% span green::绿色 %}、{% span cyan::青色 %}、{% span blue::蓝色 %}、{% span gray::灰色 %}。超大号文字:{% span center logo large::Volantis %} {% span center small::A Wonderful Theme for Hexo %} 属性 可选值 字体 logo, code 颜色 red, yellow, green, cyan, blue, gray 大小 small, h4, h3, h2, h1, large, huge, ultra 对齐方向 left, center, right ## p 参数效果源码参数本插件最后更新于 5.0 版本1{% p 样式参数::文本内容 %}红色 黄色 绿色 青色 蓝色 灰色 Volantis A Wonderful Theme for Hexo123456789{% p red::红色 %}{% p yellow::黄色 %}{% p green::绿色 %}{% p cyan::青色 %}{% p blue::蓝色 %}{% p gray::灰色 %}{% p center logo large::Volantis %}{% p center small::A Wonderful Theme for Hexo %} 属性 可选值 字体 logo, code 颜色 red, yellow, green, cyan, blue, gray 大小 small, h4, h3, h2, h1, large, huge, ultra 对齐方向 left, center, right ## note NoteBlock 是 Blockquote 的增强版,在左边显示图标,并且可以自定颜色。而 Note 是 NoteBlock 的简便写法。 最后更新于 5.0 版本1{% note 样式参数::文本内容 %} ### 演示效果 #### 经典用法 可以在配置文件中设置默认样式,为简单的一句话提供最的简便写法。 note quote 适合引用一段话 note info 默认主题色,适合中性的信息 note warning 默认黄色,适合警告性的信息 note error/danger 默认红色,适合危险性的信息 note done/success 默认绿色,适合正确操作的信息 #### 更多图标 这些都是默认样式,可以手动加上颜色: note radiation 默认样式 note radiation yellow 可以加上颜色 note bug red 说明还存在的一些故障 note link green 可以放置一些链接 note paperclip blue 放置一些附件链接 note todo 待办事项 note guide clear 可以加上一段向导 note download 可以放置下载链接 note message gray 一段消息 note up 可以说明如何进行更新 note undo light 可以说明如何撤销或者回退 ### 上述示例的源码 example:123456789101112131415161718192021222324#### 经典用法{% note::可以在配置文件中设置默认样式,为简单的一句话提供最的简便写法。 %}{% note quote::note quote 适合引用一段话 %}{% note info::note info 默认主题色,适合中性的信息 %}{% note warning::note warning 默认黄色,适合警告性的信息 %}{% note danger::note error/danger 默认红色,适合危险性的信息 %}{% note success::note done/success 默认绿色,适合正确操作的信息 %}#### 更多图标这些都是默认样式,可以手动加上颜色:{% note radiation::note radiation 默认样式 %}{% note radiation yellow::note radiation yellow 可以加上颜色 %}{% note bug red::note bug red 说明还存在的一些故障 %}{% note link green::note link green 可以放置一些链接 %}{% note paperclip blue::note paperclip blue 放置一些附件链接 %}{% note todo::note todo 待办事项 %}{% note guide clear::note guide clear 可以加上一段向导 %}{% note download::note download 可以放置下载链接 %}{% note message gray::note message gray 一段消息 %}{% note up::note up 可以说明如何进行更新 %}{% note undo light::note undo light 可以说明如何撤销或者回退 %} ### 可以支持的参数 样式参数位置可以写图标和颜色,多个样式参数用空格隔开。 #### 图标 彩色的1quote, info, warning, done/success, error/danger 灰色的,也可以指定颜色1radiation, bug, idea, link, paperclip, todo, message, guide, download, up, undo #### 颜色 指定颜色1clear, light, gray, red, yellow, green, cyan, blue ## noteblock NoteBlock 是 Blockquote 的增强版,在左边显示图标,并且可以自定颜色。而 Note 是 NoteBlock 的简便写法。 最后更新于 5.0 版本123{% noteblock 样式参数(可选)::标题(可选) %}文本段落{% endnoteblock %} ### 演示效果 可以在区块中放置一些复杂的结构,支持嵌套。 标题(可选)Windows 10不是為所有人設計,而是為每個人設計嵌套测试: 请坐和放宽,我正在帮你搞定一切… Folding 测试: 点击查看更多 不要说我们没有警告过你我们都有不顺利的时候 上述示例的源码example:1234567891011121314151617{% noteblock::标题(可选) %}Windows 10不是為所有人設計,而是為每個人設計{% noteblock done %}嵌套测试: 请坐和放宽,我正在帮你搞定一切...{% endnoteblock %}{% folding yellow::Folding 测试: 点击查看更多 %}{% note warning::不要说我们没有警告过你 %}{% noteblock bug red %}我们都有不顺利的时候{% endnoteblock %}{% endfolding %}{% endnoteblock %} 可以支持的参数样式参数位置可以写图标和颜色,多个样式参数用空格隔开。 图标彩色的1quote, info, warning, done/success, error/danger 灰色的,也可以指定颜色1radiation, bug, idea, link, paperclip, todo, message, guide, download, up, undo 颜色指定颜色1clear, light, gray, red, yellow, green, cyan, blue checkbox最后更新于 5.0 版本1{% checkbox 样式参数(可选)::文本(支持简单md) %} 演示效果 纯文本测试 支持简单的 markdown 语法 支持自定义颜色 绿色 + 默认选中 黄色 + 默认选中 青色 + 默认选中 蓝色 + 默认选中 增加 减少 叉 上述示例的源码example:12345678910{% checkbox 纯文本测试 %}{% checkbox checked::支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %}{% checkbox red::支持自定义颜色 %}{% checkbox green checked::绿色 + 默认选中 %}{% checkbox yellow checked::黄色 + 默认选中 %}{% checkbox cyan checked::青色 + 默认选中 %}{% checkbox blue checked::蓝色 + 默认选中 %}{% checkbox plus green checked::增加 %}{% checkbox minus yellow checked::减少 %}{% checkbox times red checked::叉 %} 可以支持的参数颜色1red, yellow, green, cyan, blue 样式1plus, minus, times 选中状态1checked radio最后更新于 5.0 版本1{% checkbox 样式参数(可选)::文本(支持简单md) %} 演示效果 纯文本测试 支持简单的 markdown 语法 支持自定义颜色 绿色 黄色 青色 蓝色 上述示例的源码example:1234567{% radio 纯文本测试 %}{% radio checked::支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %}{% radio red::支持自定义颜色 %}{% radio green::绿色 %}{% radio yellow::黄色 %}{% radio cyan::青色 %}{% radio blue::蓝色 %} 可以支持的参数颜色1red, yellow, green, cyan, blue 选中状态1checked timeline最后更新于 3.0 版本123456789101112131415{% timeline 时间线标题(可选) %}{% timenode 时间节点(标题) %}正文内容{% endtimenode %}{% timenode 时间节点(标题) %}正文内容{% endtimenode %}{% endtimeline %} 演示效果 2020-07-24 2.6.6 -> 3.0 如果有 hexo-lazyload-image 插件,需要删除并重新安装最新版本,设置 lazyload.isSPA: true。2.x 版本的 css 和 js 不适用于 3.x 版本,如果使用了 use_cdn: true 则需要删除。2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。2.x 版本的置顶 top: true 改为了 pin: true,并且同样适用于 layout: page 的页面。如果使用了 hexo-offline 插件,建议卸载,3.0 版本默认开启了 pjax 服务。 2020-05-15 2.6.3 -> 2.6.6 不需要额外处理。 2020-04-20 2.6.2 -> 2.6.3 全局搜索 seotitle 并替换为 seo_title。group 组件的索引规则有变,使用 group 组件的文章内,group: group_name 对应的组件名必须是 group_name。group 组件的列表名优先显示文章的 short_title 其次是 title。 上述示例的源码example:123456789101112131415161718192021222324252627{% timeline %}{% timenode 2020-07-24 [2.6.6 -> 3.0](https://github.com/volantis-x/hexo-theme-volantis/releases) %}1. 如果有 `hexo-lazyload-image` 插件,需要删除并重新安装最新版本,设置 `lazyload.isSPA: true`。2. 2.x 版本的 css 和 js 不适用于 3.x 版本,如果使用了 `use_cdn: true` 则需要删除。3. 2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。4. 2.x 版本的置顶 `top: true` 改为了 `pin: true`,并且同样适用于 `layout: page` 的页面。5. 如果使用了 `hexo-offline` 插件,建议卸载,3.0 版本默认开启了 pjax 服务。{% endtimenode %}{% timenode 2020-05-15 [2.6.3 -> 2.6.6](https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.6) %}不需要额外处理。{% endtimenode %}{% timenode 2020-04-20 [2.6.2 -> 2.6.3](https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.3) %}1. 全局搜索 `seotitle` 并替换为 `seo_title`。2. group 组件的索引规则有变,使用 group 组件的文章内,`group: group_name` 对应的组件名必须是 `group_name`。2. group 组件的列表名优先显示文章的 `short_title` 其次是 `title`。{% endtimenode %}{% endtimeline %} link最后更新于 5.0 版本1{% link 标题::链接::图片链接(可选) %} 演示效果如何参与项目https://volantis.js.org/contributors/ 上述示例的源码example:1{% link 如何参与项目::https://volantis.js.org/contributors/::https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets@master/logo/256/safari.png %} button"},{"title":"主题配置","date":"2022-01-22T12:42:28.977Z","updated":"2022-01-22T12:42:28.977Z","comments":true,"path":"v5/theme-settings/index.html","permalink":"https://zy68.top/v5/theme-settings/index.html","excerpt":"","text":"创建主题配置文件主题目录下的 _config.yml 文件通常负责主题相关配置,我们强烈建议您使用代替的主题配置文件以防止自己的配置丢失。那么如何使用代替主题配置文件呢? 第 1/2 步:创建配置文件 在博客根目录的 _config.yml 文件旁边新建一个文件: _config.volantis.yml ,这个文件中的配置信息优先级高于主题文件夹中的配置文件。 第 2/2 步:覆盖自定义配置 当您需要修改某项内容时,例如导航栏菜单,那么您需要在主题配置文件中找到相关内容,复制进自己创建的配置文件中:blog/_config.volantis.yml12345678910navbar: visiable: auto # always, auto logo: # choose [img] or [icon + title] img: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/[email protected] icon: title: menu: - name: 博客 icon: fas fa-rss url: /小提示使用「npm i hexo-theme-volantis」方式安装的主题,主题配置文件在「blog/node_modules/hexo-theme-volantis/_config.yml」使用传统方式安装的主题,主题配置文件在「blog/themes/volantis/_config.yml」 自定义主题外观最大布局宽度blog/_config.volantis.yml123custom_css: ... max_width: 1080px # Sum of body width and sidebar width 网页所呈现的内容的最大宽度,即 body 和 sidebar 的宽度之和。 抗锯齿blog/_config.volantis.yml123custom_css: ... font_smoothing: true # font-smoothing for webkit 自定义光标样式blog/_config.volantis.yml1234567891011custom_css: ... cursor: enable: true text: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/text.png pointer: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/pointer.png default: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/left_ptr.png not-allowed: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/circle.png zoom-out: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/zoom-out.png zoom-in: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/zoom-in.png grab: https://cdn.jsdelivr.net/gh/inkss/common@master/cursor/openhand.png 导航栏样式您可以设置导航栏的高度以及视觉特效,视觉特效目前可选的有: shadow:卡片阴影。 floatable:当鼠标移动到容器内时,呈现出浮起来的效果。 blur:背景模糊效果(毛玻璃),当浏览器不支持时显示为不透明。 blog/_config.volantis.yml12345custom_css: ... navbar: height: 64px effect: [shadow, blur] # [shadow, floatable, blur] 滚动条样式blog/_config.volantis.yml1234567custom_css: ... scrollbar: size: 4px border: 2px color: '#2196f3' hover: '#ff5722' 侧边栏样式视觉特效参数同上,值得注意的是:卡片的 floatable 效果和 blur 效果相冲突。 blog/_config.volantis.yml1234custom_css: ... sidebar: effect: [shadow] # [shadow, floatable, blur] 正文区域样式视觉特效参数同上,值得注意的是:卡片的 floatable 效果和 blur 效果相冲突。您可以在 language: true 这里设置代码块显示语言名称。text_align 可以设置 h1/h2/h3/h4/p 的文字对齐方向。 blog/_config.volantis.yml12345678910111213141516custom_css: ... body: effect: [shadow] # [shadow, floatable, blur] highlight: language: true # show language of codeblock copy_btn: true text_align: # left, right, justify, center h1: left h2: left h3: left h4: left p: justify note: # style for default note: {% note text %} icon: '\\f054' color: '' 布局间距您可以设置几种标题的布局间距 h2/h3/h4、段落间距 line、区块内部的段落间距 inline。 blog/_config.volantis.yml12345678custom_css: ... gap: h2: 48px # Spacing above H2 (only px unit) h3: 32px # Spacing above H3 (only px unit) h4: 16px # Spacing above H4 (only px unit) paragraph: 1rem # Paragraph spacing between paragraphs row: .5rem # Paragraph spacing between other elements 自定义字体您可以自定义正文和代码字体。 blog/_config.volantis.yml123456789101112131415161718192021custom_css: ... fontfamily: logofont: fontfamily: '"Varela Round", "PingFang SC", "Microsoft YaHei", Helvetica, Arial' name: 'Varela Round' url: https://cdn.jsdelivr.net/gh/volantis-x/cdn-fonts/VarelaRound/VarelaRound-Regular.ttf weight: normal style: normal bodyfont: fontfamily: 'UbuntuMono, "PingFang SC", "Microsoft YaHei", Helvetica, Arial' name: 'UbuntuMono' url: https://cdn.jsdelivr.net/gh/volantis-x/cdn-fonts/UbuntuMono/UbuntuMono-Regular.ttf weight: normal style: normal codefont: fontfamily: 'Menlo, Monaco' name: 'Monaco' url: https://cdn.jsdelivr.net/gh/volantis-x/cdn-fonts/Monaco/Monaco.ttf weight: normal style: normal 自定义颜色多彩配色方案 blog/_config.volantis.yml12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091color_scheme: # ------------ # 通用颜色 common: # 主题色 theme: '#44D7B6' # 链接色 link: '#2196f3' # 按钮色 button: '#44D7B6' # 鼠标放到交互元素上时的色 hover: '#ff5722' # 主题色块内部的文字颜色 inner: '#fff' # 选中区域文字的背景颜色 selection: 'alpha(#2196f3, 0.2)' # ------------ # 亮色主题(默认) light: # 网站背景色 site_bg: '#f4f4f4' # 网站背景上的文字 site_inner: '#fff' # 网站页脚文字 site_footer: '#666' # 卡片背景色 card: '#fff' # 卡片上的普通文字 text: '#444' # 区块和代码块背景色 block: '#f6f6f6' # 代码块高亮时的背景色 codeblock: '#FFF7EA' # 行内代码颜色 inlinecode: '#D56D28' # 文章部分 h1: '#444' h2: '#444' h3: '#444' h4: '#444' h5: '#444' h6: '#444' p: '#444' # 列表文字 list: '#666' # 列表 hover 时的文字 list_hl: 'mix($color-theme, #000, 80)' # 辅助性文字 meta: '#888' # ------------ # 暗色主题 dark: # 网站背景色 site_bg: '#222' # 网站背景上的文字 site_inner: '#eee' # 网站页脚文字 site_footer: '#aaa' # 卡片背景色 card: '#444' # 卡片上的普通文字 text: '#eee' # 区块和代码块背景色 block: '#3a3a3a' # 代码块高亮时的背景色 codeblock: '#343a3c' # 行内代码颜色 inlinecode: '#D56D28' # 文章部分 h1: '#eee' h2: '#eee' h3: '#ddd' h4: '#ddd' h5: '#ddd' h6: '#ddd' p: '#bbb' # 列表文字 list: '#aaa' # 列表 hover 时的文字 list_hl: 'mix($color-theme, #fff, 80)' # 辅助性文字 meta: '#888' # 夜间图片亮度 brightness: 70% 自定义右键菜单blog/_config.volantis.yml1234567891011121314151617181920212223242526272829303132333435363738394041# 自定义右键菜单rightmenu: enable: true faicon: fa # 公共图标类型 fa fal fas fad # hr: 分割线, music: 音乐控制器 layout: [home, hr, help, examples, contributors, hr, source_docs, source_theme, hr, print, darkmode, music] ### 可选功能项 ### print: # 只有文章页才允许自定义打印 name: 打印页面 icon: fa fa-print defaultStyles: true # 是否使用预制的打印样式 # js: # 自定义 js ,可用于修饰打印样式~, 右键剔除了对 Jquery 的依赖,所以此处你只能使用原生 js # - document.querySelector('article#comments').remove() # 移除评论 darkmode: # 需开启 plugins.darkmodejs name: 暗黑模式 icon: fa fa-moon customPicUrl: # 右键的图片复制:只有 Chrome 支持,且只支持 PNG 格式的图片。 enable: false # 如果使用了对象存储且开启了自适应 Webp,那么可以提供额外的链接用以替换图片的访问地址 old: #https://static.inkss.cn/img/article/ new: #https://cdn.jsdelivr.net/gh/inkss/inkss-cdn@master/img/article/ ### 自定义菜单 ### help: name: 常见问题 icon: fa fa-question url: https://volantis.js.org/faqs/ examples: name: 示例博客 icon: fa fa-rss url: https://volantis.js.org/examples/ contributors: name: 加入社区 icon: fa fa-fan fa-spin url: https://volantis.js.org/contributors/ source_docs: name: 本站源码 icon: fa fa-code-branch url: https://github.com/volantis-x/volantis-docs/ source_theme: name: 主题源码 icon: fa fa-code-branch url: https://github.com/volantis-x/hexo-theme-volantis/ 设置网站导航栏导航栏配置导航栏分为 logo、menu、search 三个区域设置,其中 logo 区域如果设置了图片,则不能显示图标和标题, menu 区域的设置可以写在一个单独的文件中。 blog/_config.volantis.yml123456789101112131415161718192021222324252627# 注意事项:建议规范全站路径 URL 最后带一个 "/" 例如 "about/"navbar: logo: # choose [img] or [icon + title] img: icon: title: menu: # The following can be written in `blog/source/_data/menu.yml` - name: 博客 icon: fas fa-rss url: / - name: 分类 icon: fas fa-folder-open url: categories/ - name: 标签 icon: fas fa-tags url: tags/ - name: 归档 icon: fas fa-archive url: archives/ - name: 友链 icon: fas fa-link url: friends/ - name: 关于 icon: fas fa-info-circle url: about/ search: 搜索 # Search bar placeholder 菜单嵌套导航栏菜单支持嵌套,嵌套的属性名为 rows ,写法示例: 123456789101112131415161718192021222324...- name: 更多 icon: fas fa-ellipsis-v rows: - name: 主题源码 url: https://github.com/volantis-x/hexo-theme-volantis/ - name: 更新日志 url: https://github.com/volantis-x/hexo-theme-volantis/releases/ - name: hr - name: 有疑问? rows: - name: 看 FAQ url: faqs/ - name: 看 本站源码 url: https://github.com/volantis-x/volantis-docs/ - name: 提 Issue url: https://github.com/volantis-x/hexo-theme-volantis/issues/ - name: hr - name: 公告和测试博文 url: archives/ - name: 示例博客 url: examples/ - name: 特别感谢 url: contributors/ 分割线在子菜单中,新增一个只有 name: hr 的“菜单”就会被渲染成一个分割线。 1- name: hr 小标题在子菜单中,新增一个只有 name: 小标题内容(也可以有 icon: 小标题的图标)的“菜单”就会被渲染成一个小标题。 12345678910111213...- name: 近期 icon: fas fa-clock url: / rows: - name: 热门文章 icon: fas fa-fire - name: ProHUD 开源库的设计思路 url: blog/2019-08-27-prohud/ - name: ValueX:实用的安全对象类型转换库 url: blog/2019-08-29-valuex/ - name: 心率管家 App 的设计与开发 url: blog/2019-07-23-heartmate/ 播放器在子菜单中,新增一个 icon: fas fa-compact-disc 的“菜单”就会被渲染成一个 APlayer 播放器。 12- name: 背景音乐 icon: fas fa-compact-disc 设置网站页脚您通过 layout 可以自由布局网站页脚内容 aplayer, social, license, info, copyright。 blog/_config.volantis.yml123456789101112131415site_footer: # layout of footer: [aplayer, social, license, info, copyright] layout: [aplayer, social, license, info, copyright] social: - icon: fas fa-rss url: atom.xml - icon: fas fa-envelope url: mailto:[email protected] - icon: fab fa-github url: https://github.com/xaoxuu - icon: fas fa-headphones-alt url: https://music.163.com/#/user/home?id=63035382 copyright: '[Copyright © 2017-2021 XXX](/)' # You can add your own property here. (Support markdown, for example: br: '<br>') br: '<br>' 其中,aplayer 需要在插件部分设置中启用。您可以新增文字属性,用于展示其它文字信息,例如: blog/_config.volantis.yml123456site_footer: layout: [..., br, hello, ...] ... # You can add your own property here. (Support markdown, for example: br: '<br>') br: '<br>' hello: '[Hello World](/)' 网站与文章封面封面高度blog/_config.volantis.yml123cover: height_scheme: full # full, half ... 目前主题提供两种首页封面高度方案,其它页面均为半屏幕高度。 封面布局方案blog/_config.volantis.yml1234cover: ... scheme: dock # search (搜索), dock (坞), featured (精选), focus (焦点) ... 布局方案 适合场景 search 注重搜索 dock 入口选项比较多 featured 选项在4个左右 focus 选项在4个左右 默认显示设置blog/_config.volantis.yml123456cover: ... display: home: true archive: false others: false # can be written in front-matter 'cover: true' 由于主页、归档是 hexo 自动生成的,您需要在主题配置文件中设置是否显示封面,而其它页面则可以在 front-matter 中通过设置 cover: true/false 来决定显示封面或者不显示封面。 文章布局配置123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109# 文章布局article: # 文章列表页面的文章卡片布局方案 preview: scheme: landscape # landscape # pin icon for post pin_icon: https://cdn.jsdelivr.net/gh/twitter/[email protected]/assets/svg/1f4cc.svg # auto generate title if not exist auto_title: true # false, true # auto generate excerpt if not exist auto_excerpt: true # false, true # show split line or not line_style: solid # hidden, solid, dashed, dotted # show readmore button readmore: auto # auto, always # 文章详情页面的文章卡片本体布局方案 body: # 文章顶部信息 # 从 meta_library 中取 top_meta: [author, category, date, counter] # ---------------- # 文章页脚组件 footer_widget: # ---------------- # 参考资料、相关资料等 (for layout: post/docs) references: title: 参考资料 icon: fas fa-quote-left # 在 front-matter 中: # references: # - title: 某篇文章 # url: https:// # 即可显示此组件。 # ---------------- # 相关文章,需要安装插件 (for layout: post) # npm i hexo-related-popular-posts related_posts: enable: false title: 相关文章 icon: fas fa-bookmark max_count: 5 # 设为空则不使用文章头图 placeholder_img: https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/046.jpg # ---------------- # 版权声明组件 (for layout: post/docs) copyright: enable: true permalink: '本文永久链接是:' content: - '博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议' - permalink # ---------------- # 打赏组件 (for layout: post/docs) donate: enable: false images: - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] # 文章底部信息 # 从 meta_library 中取 bottom_meta: [updated, tags, share] # meta library meta_library: # 默认文章作者(可在 front-matter 中覆盖) author: avatar: name: 请设置文章作者 url: / # 文章创建日期 date: icon: fas fa-calendar-alt title: '发布于:' format: 'll' # 日期格式 http://momentjs.com/docs/ # 文章更新日期 updated: icon: fas fa-edit title: '更新于:' format: 'll' # 日期格式 http://momentjs.com/docs/ # 文章分类 category: icon: fas fa-folder-open # 文章浏览计数 counter: icon: fas fa-eye unit: '次浏览' # 文章评论数量:只支持 valine valinecount: icon: fas fa-comment-dots desc: '' # 条评论 # 文章字数和阅读时长 wordcount: icon_wordcount: fas fa-keyboard icon_duration: fas fa-hourglass-half # 文章标签 tags: icon: fas fa-hashtag # 分享 share: - id: qq img: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qq.png - id: qzone img: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qzone.png - id: weibo img: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/weibo.png - id: # qrcode # 当id为qrcode时需要安装插件 npm i hexo-helper-qrcode img: # https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/wechat.png - id: # telegram img: # https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/telegram.png 其中 top_meta 和 bottom_meta 部分的取值自 meta_library 库。 侧边栏配置侧边栏小组件与 meta 库不同的是:除了现有的 widget ,您可以很轻易地创建自己的 widget ,然后放在需要的地方。此外,您还可以将 widget 写在单独的文件中。 查看所有相关配置 blog/_config.volantis.yml1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798sidebar: # 主页、分类、归档等独立页面 for_page: [blogger, category, tagcloud, qrcode] # layout: docs/post 这类文章页面 for_post: [toc] # 侧边栏组件库 widget_library: # --------------------------------------- # blogger info widget blogger: class: blogger display: [desktop, mobile] # [desktop, mobile] avatar: https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/[email protected] shape: rectangle # circle, rectangle url: /about/ title: subtitle: jinrishici: true # Poetry Today. You can set a string, and it will be displayed when loading fails. social: true # --------------------------------------- # toc widget (valid only in articles) toc: class: toc display: [desktop, mobile] # [desktop, mobile] header: icon: fas fa-list title: 本文目录 list_number: false min_depth: 2 max_depth: 5 # --------------------------------------- # category widget category: class: category display: [desktop] # [desktop, mobile] header: icon: fas fa-folder-open title: 文章分类 url: /blog/categories/ # --------------------------------------- # tagcloud widget tagcloud: class: tagcloud display: [desktop, mobile] # [desktop, mobile] header: icon: fas fa-tags title: 热门标签 url: /blog/tags/ min_font: 14 max_font: 24 color: true start_color: '#999' end_color: '#555' # --------------------------------------- # qrcode widget donate: class: qrcode display: [desktop, mobile] # [desktop, mobile] height: 64px # Automatic height if not set images: - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] # --------------------------------------- # webinfo widget webinfo: class: webinfo display: [desktop] header: icon: fas fa-award title: 站点信息 type: article: enable: true text: '文章数目:' unit: '篇' runtime: enable: true data: '2020/01/01' # 填写建站日期 text: '已运行时间:' unit: '天' wordcount: enable: true text: '本站总字数:' # 需要启用 wordcount unit: '字' siteuv: enable: true text: '本站访客数:' # 需要启用 busuanzi unit: '人' sitepv: enable: true text: '本站总访问量:' # 需要启用 busuanzi unit: '次' lastupd: enable: true friendlyShow: true # 更友好的时间显示 text: '最后活动时间:' unit: '日' 每一个小部件都有 class 和 display,前者代表这个小部件是什么,后者代表这个小部件在什么桌面和移动平台中是否显示,如果在移动平台显示,由于屏幕宽度有限,侧边栏的小部件则会被移动到正文区域下方,因此部分侧边栏小部件便失去意义,建议设置为仅桌面端显示。 1234小部件名: class: 小部件类别 display: [小部件在桌面端是否显示, 小部件在移动设备是否显示] pjaxReload: true # 是否 pjax 重载 默认 true; 设置为 false 时 确保所有页面都含有该小部件 博主信息部件blog/_config.volantis.yml12345678blogger: class: blogger display: [desktop] # [desktop, mobile] avatar: https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png title: subtitle: jinrishici: true # Poetry Today. You can set a string, and it will be displayed when loading fails. social: true 其中,今日诗词 jinrishici 如果设置为一个字符串,这个字符串会变成占位文字,加载失败时显示。如果不需要,就请设置为 jinrishici: false。social 的具体内容请在网站页脚部分设置。 文章目录部件blog/_config.volantis.yml123456789toc: class: toc display: [desktop, mobile] # [desktop, mobile] header: icon: fas fa-list title: 本文目录 list_number: false min_depth: 2 max_depth: 5 这个部件只能放置在侧边栏,并且在文章中有效。在移动设备中预览时,手指向上滑动时,导航栏右边会出现 TOC 按钮,点击即可展开 TOC 部件。如果您需要显示章节序号,请设置 list_number。 min_depth 和 max_depth 代表 TOC 支持的标题层级,最大范围是2~6。 文章分类部件blog/_config.volantis.yml1234567category: class: category display: [desktop] # [desktop, mobile] header: icon: fas fa-folder-open title: 文章分类 url: /blog/categories/ 这个部件可以直接显示所有文章分类,如果您希望有一个独立的页面来展示,需要自己创建一个文件,具体操作在「页面」部分文档中。 标签云部件blog/_config.volantis.yml123456789101112tagcloud: class: tagcloud display: [desktop] # [desktop, mobile] header: icon: fas fa-tags title: 热门标签 url: /blog/tags/ min_font: 14 max_font: 24 color: true start_color: '#999' end_color: '#555' 这个部件可以直接显示所有文章的标签,如果您希望有一个独立的页面来展示,需要自己创建一个文件,具体操作在「页面」部分文档中。 二维码部件blog/_config.volantis.yml1234567donate: class: qrcode display: [desktop, mobile] # [desktop, mobile] height: 64px # Automatic height if not set images: - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] - https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/qrcode/[email protected] 您可以放置在文章页脚用于展示打赏图片,也可以放置在侧边栏。 通用文本部件blog/_config.volantis.yml123456789101112repos: class: text display: [desktop] # [desktop, mobile] header: icon: fab fa-github title: 点个赞吧 url: https://github.com/xaoxuu/ content: - '您的赞对我来说很重要,如果您喜欢本主题,希望能够给下面的项目点个赞来支持一下。' - '[<img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/proj/prohud/logo.png" height="50px">](https://github.com/xaoxuu/ProHUD)' - '[<img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/proj/valuex/logo.png" height="50px">](https://github.com/xaoxuu/ValueX)' - '[<img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/proj/inspire/logo.png" height="50px">](https://github.com/xaoxuu/Inspire)' 您可以创建用于展示任何文本内容的文本部件。 通用列表部件blog/_config.volantis.yml123456789101112wiki-hexo-theme: class: list display: [desktop, mobile] # [desktop, mobile] header: icon: fas fa-chevron-left title: Hexo Themes url: /wiki/ rows: - name: Volantis for Hexo url: /wiki/volantis/ - name: Resume for Hexo url: /wiki/resume/ 您可以创建用于展示任何链接列表的列表部件。列表的 rows 中的每一项支持的属性有: name、url、icon、img、avatar,其中 img 是方形图片的链接,avatar 是圆形图片的链接。 组索引这个部件的布局继承自 list 部件,用于展示文章所属的分组的文章列表。请将您的 Volantis 升级至 2.5 版本以上使用。 blog/_config.volantis.yml1234567group-1: class: group display: [desktop, mobile] # [desktop, mobile] header: icon: fab fa-github title: Git url: /wiki/git/ 在文章的 front-matter 中设置: front-matter123group: group-1order: 16sidebar: [group-1, toc] 「group-1」卡片将会以列表的形式显示所有设置了 group: group-1 的文章,顺序按照 order 从小到大排列。 通用网格部件blog/_config.volantis.yml123456789101112131415161718feedback: class: grid display: [desktop, mobile] header: icon: fas fa-headset title: 联系开发者 url: https://github.com/volantis-x/hexo-theme-volantis fixed: true # 固定宽度 rows: - name: 反馈BUG icon: fas fa-bug url: https://github.com/volantis-x/hexo-theme-volantis/issues/ - name: 疑问求助 icon: fas fa-question-circle url: https://github.com/volantis-x/hexo-theme-volantis/issues/ - name: 提个建议 icon: fas fa-lightbulb url: https://github.com/volantis-x/hexo-theme-volantis/issues/ 您可以创建用于展示任何链接列表的网格部件。网格默认根据文字长度自动确定每一个格子的宽度,如果文字长短不一,建议通过设置 fixed: true 来固定宽度,此时文字过长的格子中的文字会换行显示。 通用页面部件blog/_config.volantis.yml12345test: class: page display: [desktop, mobile] pid: haha content: excerpt # excerpt, more, content 您可以把整个页面的md内容作为一个小部件渲染显示出来。只需要设置小部件里的 pid 属性和文章的 front-matter 中设置一样的 pid 即可。 content 代表这个部件显示的内容,可选 excerpt,more,content 分别对应文章的摘要、摘要后面的内容、全文。 音乐部件blog/_config.volantis.yml1234music: class: music display: [desktop, mobile] # [desktop, mobile] pjaxReload: false 选择评论系统目前共支持 15 款评论系统: artalk, giscus, beaudar, utterances, valine, twikoo, waline, minivaline, disqus, disqusjs, gitalk, vssue, livere, isso, hashover blog/_config.volantis.yml1234comments: title: <i class='fas fa-comments'></i> 评论 subtitle: service: giscus GitHub Discussions 系列 giscus A comments system powered by GitHub Discussions. https://giscus.app/blog/_config.volantis.yml12345678910111213141516171819comments: ... service: giscus ... # giscus # https://giscus.app # https://github.com/laymonage/giscus giscus: theme: light: https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@master/css/giscus/light.css dark: https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@master/css/giscus/dark.css # 以下配置按照 yml 格式增删填写即可 # repo: xxx/xxx # repo-id: xxx # category: xxx # category-id: xxx # mapping: "pathname" # reactions-enabled: "1" # emit-metadata: "0" GitHub Issues 系列 beaudarutterancesVssueGitalk Beaudar 名称源于粤语“表达”的发音,是 Utterances 的中文版本。 https://beaudar.lipk.org/blog/_config.volantis.yml1234567891011121314151617comments: ... service: beaudar ... # beaudar # https://beaudar.lipk.org/ beaudar: repo: xxx/xxx issue-term: pathname issue-number: branch: main position: top order: desc theme: light: github-light dark: github-dark label: ✨💬✨ A lightweight comments widget built on GitHub issues. https://utteranc.es/blog/_config.volantis.yml1234567891011121314comments: ... service: utterances ... # utterances # https://utteranc.es/ utterances: repo: xxx/xxx issue-term: pathname issue-number: theme: light: github-light dark: github-dark label: ✨💬✨ Vue 驱动的、基于 Issue 的评论插件 https://vssue.js.org/zh/blog/_config.volantis.yml123456789comments: ... service: vssue ... vssue: owner: repo: clientId: clientSecret: A modern comment component based on Github Issue and Preact. https://gitalk.github.io/blog/_config.volantis.yml12345678910comments: ... service: gitalk ... gitalk: clientID: clientSecret: repo: owner: admin: # []clientID 和 clientSecret 的获取方法可自行搜索教程,这里仅简单描述一下步骤:点击 GitHub -> Settings https://github.com/settings/profile点击 Developer settings https://github.com/settings/developers点击 New OAuth App https://github.com/settings/applications/new填写信息:Application name 随便填,我的是:xaoxuu.comHomepage URL 和 Authorization callback URL 都写你的网址,我的是:https://xaoxuu.com可以通过设置 gitalk.id 实现多个页面共用一个评论框。front-matter1234---gitalk: id: /wiki/volantis/--- Disqus 系列 DisqusDisqusJSIsso Disqus - The #1 way to build an audience on your website. https://disqus.com/blog/_config.volantis.yml123456comments: ... service: disqus ... disqus: shortname:可以通过设置 disqus.path 实现多个页面共用一个评论框。front-matter1234---disqus: path: /wiki/volantis/--- Render Disqus comments in Mainland China using Disqus API https://github.com/SukkaW/DisqusJSblog/_config.volantis.yml1234567891011121314comments: ... service: disqusjs ... # DisqusJS # https://github.com/SukkaW/DisqusJS disqusjs: path: # 全局评论地址 # 配置项按照yml格式继续填写即可 除了 [siteName url identifier] 选项 #shortname: #api: #apikey: #admin: #nesting: A commenting server similar to Disqus. https://posativ.org/isso/blog/_config.volantis.yml1234567comments: ... service: isso ... isso: url: https://example.com/(path/) src: https://example.com/(path/)js/embed.min.js Valine 及其衍生 ValineWalineMiniValine 一款快速、简洁且高效的无后端评论系统 https://valine.js.orgblog/_config.volantis.yml123456789101112comments: ... service: valine ... valine: # js: https://cdn.jsdelivr.net/npm/[email protected]/dist/Valine.min.js path: # 全局评论地址 目前设置全局评论地址后visitor失效,这是valine的问题 placeholder: 快来评论吧~ # 评论占位提示 # 其他配置项按照yml格式继续填写即可 除了 [el path placeholder emojiCDN emojiMaps] 选项 appId: # your appId appKey: # your appKey ... 可选配置项详见源码其中,placeholder 支持在 front-matter 中设置。front-matter1234---valine: placeholder: 你觉得xxx怎么样呢?---也可以通过设置 valine.path 实现多个页面共用一个评论框。front-matter1234---valine: path: /--- 一个简洁、安全、免费的静态网站评论系统 | A simple, safe, free comment system. https://waline.js.org/blog/_config.volantis.yml1234567891011121314comments: ... service: waline ... # Waline # https://waline.js.org/ waline: js: https://cdn.jsdelivr.net/npm/@waline/client/dist/Waline.min.js path: # 全局评论地址 目前设置全局评论地址后visitor失效,这是waline的问题 placeholder: 快来评论吧~ # 评论占位提示 imageHosting: https://7bu.top/api/upload # 图床api(默认使用去不图床) # 其他配置项按照yml格式继续填写即可 除了 [el path placeholder uploadImage] 选项 serverURL: xxxxxxxxxxxxxxx # Waline 的服务端地址(必填) 测试用地址: https://waline-ruddy.vercel.app ... 可选配置项详见源码其中,placeholder 支持在 front-matter 中设置。front-matter1234---waline: placeholder: 你觉得xxx怎么样呢?---也可以通过设置 waline.path 实现多个页面共用一个评论框。front-matter1234---waline: path: /--- 一款快速、简洁且高效的评论系统 https://github.com/MiniValine/MiniValine/blog/_config.volantis.yml12345678910111213comments: ... service: minivaline ... # MiniValine # https://github.com/MiniValine/MiniValine minivaline: js: https://cdn.jsdelivr.net/npm/minivaline@latest path: # 全局评论地址 placeholder: 快来评论吧~ # 全局评论占位提示 # 更多选项 https://minivaline.js.org/docs/cn/#/Options 按照yml格式继续填写即可 (除了 [el path placeholder] 选项) # 下面是一个例子: serverURL: https://hello.com其中,placeholder 支持在 front-matter 中设置。front-matter1234---minivaline: placeholder: 你觉得xxx怎么样呢?---也可以通过设置 minivaline.path 实现多个页面共用一个评论框。front-matter1234---minivaline: path: /--- Others 其他系列 ArtalktwikooLivereHashoverMore... 一款简洁的自托管评论系统 | A Selfhosted Comment System. https://artalk.js.org/blog/_config.volantis.yml12345678comments: ... service: artalk ... artalk: js: https://cdn.jsdelivr.net/npm/[email protected]/dist/Artalk.js css: https://cdn.jsdelivr.net/npm/[email protected]/dist/Artalk.css server: http://127.0.0.1:8080/api # 修改为自建的后端服务地址其中,placeholder 支持在 front-matter 中设置。front-matter1234---artalk: placeholder: 你觉得xxx怎么样呢?---也可以通过设置 artalk.path 实现多个页面共用一个评论框。front-matter1234---artalk: path: /--- 一个简洁、安全、免费的静态网站评论系统 | A simple, safe, free comment system. https://twikoo.js.org/blog/_config.volantis.yml123456789comments: ... service: twikoo ... twikoo: js: https://cdn.jsdelivr.net/npm/twikoo@latest # 建议锁定版本 path: # 全局评论地址 # 其他配置项按照yml格式继续填写即可 除了 [el path] 选项 envId: xxxxxxxxxxxxxxx # 腾讯云环境id其中,placeholder 支持在 front-matter 中设置。front-matter1234---twikoo: placeholder: 你觉得xxx怎么样呢?---也可以通过设置 twikoo.path 实现多个页面共用一个评论框。front-matter1234---twikoo: path: /--- Communication makes better world. https://www.livere.com/blog/_config.volantis.yml123456comments: ... service: livere ... livere: uid: #你的livere的uid在这里查看你的 uid:https://livere.com/insight/myCode,在【代码管理 -> 一般网站】中找到如下这段代码,其中 data-uid 中的内容就是你的 livere_uid。123<!-- 来必力City版安装代码 --><div id="lv-container" data-id="city" data-uid="你的livere的uid">... A free and open source PHP comment system designed to allow completely anonymous comments and easy theming. https://www.barkdull.org/software/hashoverblog/_config.volantis.yml123456comments: ... service: hashover ... hashover: src: https://example.com/(path/)comments.phpblog/themes/volantis/layout/_third-party/comments/评论系统名称/layout.ejs1这里写布局代码blog/themes/volantis/layout/_third-party/comments/评论系统名称/script.ejs1这里要写加载 js 的代码收录更多评论系统 可以通过在 front-matter 设置 config 实现在特定页面修改评论系统的相关配置。 支持的有(按字母顺序): giscus, gitalk, minivaline, twikoo, valine, waline front-matter12345---gitalk: config: id: /233/--- 站内搜索blog/_config.volantis.yml1234search: enable: true service: hexo # hexo js: https://cdn.jsdelivr.net/xxxxxxxx/js/search/hexo.js 默认配置为 Hexo 搜索,但是需要安装插件才能使用: 1npm i -S hexo-generator-json-content"}],"posts":[{"title":"电子邮件服务及其在Spring中的应用","slug":"emailAndUse","date":"2022-01-08T05:15:14.000Z","updated":"2022-01-08T05:15:14.000Z","comments":true,"path":"2022/01/08/emailAndUse/","link":"","permalink":"https://zy68.top/2022/01/08/emailAndUse/","excerpt":" 最近在 Spring Boot 项目中需要添加邮件功能,在完成应用开发后对邮件服务还存在些许迷雾。因此顺便回顾下电子邮件系统的工作原理以及 SMTP、MIME、POP3 和 IMAP 协议,做一次从基本原理到应用的知识点扫盲。","text":" 最近在 Spring Boot 项目中需要添加邮件功能,在完成应用开发后对邮件服务还存在些许迷雾。因此顺便回顾下电子邮件系统的工作原理以及 SMTP、MIME、POP3 和 IMAP 协议,做一次从基本原理到应用的知识点扫盲。 一、电子邮件 邮件服务,我们常见有普通的邮件服务(即线下邮局服务)和电子邮件服务。电子邮件服务是因特网在初期就发展起来的产物,该服务能够利用网络的便捷性实现和扩展传统邮件业务,如快速发送、多用户分发和价格低廉。现代电子邮件更是具备传输包含附件、超链接、HTML格式文本和图片的功能特性。 传统邮件服务我们都知道,下面就来认识一下电子邮件服务系统及原理。(参考《计算机网络·自顶向下方法》) 1.0 电子邮件系统 一个最基本的电子邮件系统如上图所示,主要包含三个部分:用户代理、邮件服务器和 SMTP协议。用户代理为一个邮件编写发送和查看删除的客户端;邮件服务器为该系统核心,每一个邮件服务器下含开放了多个“用户邮箱”,用于存储该服务器接收到的对应的用户的邮件;SMTP协议为 TCP/IP 网络中的应用层协议,能够实现单向的邮件 Push 传输功能。 如上图所示(Alice 和 Bob 为系统中任意两个用户),邮件系统的工作原理为: Alice 在其代理客户端中编写好邮件,通过 SMTP 协议发送到她的邮件服务器的外出报文队列中; Alice 的邮件服务器根据 Alice 邮件中写入的接收方 Bob 的邮箱地址,将该邮件通过 SMTP 协议发送到 Bob 的邮件服务器。(例如:从谷歌的 Gmail邮箱服务器 发送到网易的 163邮箱服务器) Bob 的邮件服务器接收到邮件后,根据邮件中的写入的接收方 Bob 的邮箱地址前缀(“@”的前面部分)定位到该服务器下的 Bob 的用户邮箱,并将该邮件存入该邮箱中。 Bob 可以选择直接在他的邮件服务器中查看(即如果他有该服务器的登录权限,则可以直接进入服务器查看邮件,此时不需要后面的用户代理)。也可以选择使用用户代理的方式(常见方式),在自己的用户代理中通过 POP3/IMAP/HTTP 协议从邮件服务器中 Pull 他的邮件到其代理客户端进行查看等操作。 一次邮件系统工作完成。 要点补充 外出报文队列:顾名思义,为邮件服务器向其他邮件服务器发送邮件报文(即邮件内容)的队列。所有的服务器用户将邮件报文发送到队列中集中排队向外发送。如果发送失败则进行重复尝试(连接不到目的邮件服务器等问题),间隔指定时间尝试指定次数仍然失败后,邮件服务器(将会删除该邮件报文)以邮件的形式通知该用户他的邮件发送失败。 邮件服务器间直连:SMTP 一般不使用中间邮件服务器发送邮件。即两个用户的邮件服务器直接进行 TCP 连接后通过 SMTP 协议进行邮件报文传输。 1.1 SMTP SMTP 是邮件系统的重要组成部分之一,是 Internet 电子邮件的核心。上面已经说明和体现了 SMTP 的大部分功能和特性,这里再介绍和总结一下 SMTP协议。 SMTP协议,即 Simple Mail Transfer Protocol 简单邮件传输协议,是一个作用类似于 HTTP 协议的互联网协议标准(但比 HTTP 早)。SMTP协议 与 HTTP 使用报文的方式不同,SMTP 没有类似的传输严格格式化的报文格式,而是通过命令事务来完成协议的实现。 1.1.1 SMTP交互模型 如上图SMTP模型所示,为 RFC 5321 SMTP 中的SMTP工作模型图。SMTP 实现为 C/S 架构,即含客户端和服务端。由客户端向服务端发送命令,服务端接收到命令后执行命令并反馈信息到客户端(即传统的C/S命令交互)。通过一次邮件事务的命令发送和执行完成邮件的发送。即SMTP交流模型: 当用户需要发邮件时候,邮件发送者(Client-SMTP)建立一个与邮件接收者(Server-SMTP)通信的通道,发送者发送SMTP命令给接收者,接收者收到后对命令做回复响应。 基本事务:通信通道被建立后,发送者发送 MAIL 命令来指定发送者的邮件,如果接受者接收这个邮件,就回复 OK;接着发送者发送 RCPT命令来指定接收者的邮箱,如果被接收同样回复OK,如果不接受则拒绝(不会终止整个通话)。接收者邮箱确定后,发送者用DATA命令指示要发送数据,并用一个.结束发送。如果数据被接收,会收到OK,然后用QUIT结束会话。 一个SMTP邮件发送例子 1234567891011121314S: MAIL FROM:<[email protected]> # 向服务器说明邮件发送者R: 250 OK # 服务器返回状态码和描述S: RCPT TO:<[email protected]> # 向服务器说明邮件接收者R: 250 OKS: RCPT TO:<[email protected]>R: 550 No such user hereS: RCPT TO:<[email protected]>R: 250 OKS: DATA # 启动邮件数据内容(ASCII编码)传输指令R: 354 Start mail input; end with <CRLF>.<CRLF> # 服务器已经准备好接收数据并说明结束传输方式S: Blah blah blah...S: ...etc. etc. etc.S: <CRLF>.<CRLF> # 发送者发送数据终止语句R: 250 OK 进一步的简单了解请参考 SMTP协议详解,官方详细了解请参考 RFC 5321 SMTP。 1.1.2 邮件报文 SMTP协议将互联网邮件报文封装在邮件对象中。SMTP协议的邮件对象由两个部分组成:信封和内容。 信封实际上是SMTP命令。 邮件报文是邮件对象中的内容,包含首部和主体两个部分。 RFC 文档的对报文格式的要求: 所有报文都是由 ASCII 码组成; 报文由报文行组成,各行之间用回车(CR)、换行(LF)符分隔; 报文的长度不能超过 998 个字符; 报文行的长度 ≤78 个字符之内(不包括回车换行符); 报文中可包括多个首部字段和首部内容; 报文可包括一个主体,主体必须用一个空行与其首部分隔; 除非需要使用回车与换行符,否则报文中不使用回车与换行符。 1.1.3 SMTP 的扩展协议:MIME 上面的邮件报文格式要求中有说到:所有的报文都是由 ASCII 码组成,那么一些非英语字符消息和二进制文件、图像、声音等非文字消息就都不能在电子邮件中传输。在互联网初期仅传输 ASCII码 还能满足需求,但到了互联网快速发展的图像视频时代就存在局限性了。因此,需要一个辅助性协议帮忙传输报文,它就是MIME。 WiKi:多用途互联网邮件扩展(Multipurpose Internet Mail Extensions,MIME)是一个互联网标准,它扩展了电子邮件标准,使其能够支持: 非ASCII字符文本; 非文本格式附件(二进位制、声音、图片等); 由多部分(multiple parts)组成的消息体; 包含非ASCII字元的标头资讯(Header information)。 MIME是通过标准化电子邮件报文的头部的附加域(fields)而实现的。这些头部的附加域,描述新的报文类型的内容和组织形式。主要的附加域有三条: 123MIME-Version: 1.0 # MIME版本Content-Type: text/plain; charset="ISO-8859-1" # 传递的信息类型和采用的编码Content-transfer-encoding: base64 # 编码转换方式 一个SMTP邮件发送例子 一封MIMI邮件的源码如下(借阮大佬图片一用): 进一步了解可参考 阮一峰-MIME笔记 和 WiKi-MIME。 1.2 POP3如上 图2-16 所示,SMTP 实现了邮件发送到邮件服务器的 Push 传输,而 POP协议 主要用于支持客户端远程下载和管理在服务器上的电子邮件。 WiKi:邮局协议(Post Office Protocol,POP)是TCP/IP协议族中的一员,主要用于支持使用客户端远程管理在服务器上的电子邮件。最新版本为POP3,全名“Post Office Protocol - Version 3”,而提供了 SSL 加密的 POP3协议 被称为 POP3S。 POP协议的远程管理是电子邮件客户端调连接邮件服务器,并下载所有未阅读的电子邮件。这种离线访问模式是一种存储转发服务,将邮件从邮件服务器端送到个人终端机器上。一旦邮件下载到个人终端上,邮件服务器上的邮件将会被删除。但目前的POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”。 POP3协议 也是通过C/S架构的命令模式完成邮件管理事务: 客户端先连接到邮件服务器,建立双方的 POP3 连接; 客户端发送命令执行对邮件服务器中的邮件管理。 常用命令参考如下: 1.3 IMAP 因特网信息访问协议(Internet Message Access Protocol,IMAP;以前称作交互邮件访问协议)与 POP协议一样,都是客户端对邮件服务器中邮件的管理,但 IMAP 提供了更加丰富的功能。其主要优点如下: 使用IMAP4可以获得更快的响应时间。 使用IMAP4可支持多个设备,同时连接到一个邮箱。 IMAP4支持获取部分或全部 MIME 格式的电子邮件。 IMAP4支持服务器查看当前的信息状态。 IMAP4支持在服务器访问多个邮箱。 IMAP4支持在服务器端搜索电子邮件。 IMAP4支持一个定义良好的扩展机制。 1.4 其他应用要点 使用邮件发送,邮箱中必须开启 SMTP服务。以 QQ 为例: 相关服务器端口: 为了安全,邮件服务器都要求必须支持 SSL。QQ 邮箱收发邮件使用说明。 二、Java中的邮件服务2.1 Jakarta Mail Jakarta Mail(以前称为 JavaMail)是一个Jakarta EEAPI,用于通过SMTP、POP3和IMAP发送和接收电子邮件。Jakarta Mail 内置于Java EE平台中,但也提供了用于Java SE的可选包。—— WiKi 摘取。 WiKi百科介绍及使用Demo,官网详细解析和应用文档, Github 中开源。 Maven 坐标: 123456<dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>x.x.x</version> <scope>compile</scope></dependency> 2.2 Spring Boot Mail Spring Boot Mail 是基于 JavaMail 封装起来的便于使用的邮件依赖,使得用户能够避免接触底层细节,更快更方便的使用邮件服务。—— Spring官方使用介绍 Maven 坐标: 1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency> 简单来说,Spring 封装了一个JavaMailService 接口及其丰富了的具体实现 JavaMailServiceImpl类。通过JavaMailServiceImpl类的send()方法能够执行发送邮件的功能。其中,简单邮件可以通过SimpleMailMessage来发送邮件,而复杂的邮件(如添加附件)可以借助MimeMessageHelper来构建MimeMessage发送邮件。 此外,Spring Boot Mail 还支持发送HTML邮件、图片、模板邮件,具体可简单参考。 简单看一眼源码 JavaMailService接口JavaMailServiceImpl类 三、Spring Boot 中应用 Mail3.1 引入和配置 引入和配置 pom 引入依赖1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency>application 配置文件中配置,QQ邮箱为例(参考+修改)1234567891011121314151617181920# 字符集编码 默认 UTF-8spring.mail.default-encoding=UTF-8# (必须)SMTP 服务器 host qq邮箱的为 smtp.qq.com 端口 465 587spring.mail.host=smtp.qq.com# (必须)SMTP 服务器端口 不同的服务商不一样spring.mail.port=465# SMTP 服务器使用的协议(JavaMailServiceImpl类中默认为smtp)spring.mail.protocol=smtp# SMTP服务器需要身份验证 所以 要配置用户密码# (必须)发送端的用户邮箱名[email protected]# (必须)发送端的密码(授权码) 注意保密spring.mail.password=oooooxxxxxxxx# 指定mail会话的jndi名称 优先级较高 一般我们不使用该方式spring.mail.jndi-name=# 这个比较重要 针对不同的SMTP服务器 都有自己的一些特色配置该属性 提供了这些配置的 key value 封装方案 例如 Gmail SMTP 服务器超时配置 spring.mail.properties.mail.smtp.timeout= 5000spring.mail.properties.<key> =# 指定是否在启动时测试邮件服务器连接,默认为falsespring.mail.test-connection=false 3.2 简单使用示例 在上述配置完成的基础上,编码如下简单使用的服务示例。引例参考 简单使用 12345678910111213141516171819202122232425@Autowiredprivate JavaMailSenderImpl mailSender;public void sendMail() throws MessagingException { //简单邮件 SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); simpleMailMessage.setFrom("[email protected]"); simpleMailMessage.setTo("[email protected]"); simpleMailMessage.setSubject("Happy New Year"); simpleMailMessage.setText("新年快乐!"); // true 为 HTML 邮件 //messageHelper.setText(htmlStringSrc, true); mailSender.send(simpleMailMessage); //复杂邮件(带附件) MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage); messageHelper.setFrom("[email protected]"); messageHelper.setTo("[email protected]"); messageHelper.setSubject("Happy New Year"); messageHelper.setText("新年快乐!"); messageHelper.addInline("doge.gif", new File("xx/xx/doge.gif")); messageHelper.addAttachment("work.docx", new File("xx/xx/work.docx")); mailSender.send(mimeMessage);} 3.3 封装使用示例 封装使用目的是为了方便业务调用,形成单独的发送邮件业务。 封装一个邮件类 **MailDO.java** 封装数据对象 12345678910111213141516171819202122232425262728293031323334353637383940414243444546public class MailDO { /** * 邮件id */ private String id; /** * 发信方 */ private String from; /** * 收信方(多个邮箱用逗号“,”隔开) */ private String to; /** * 邮件主题 */ private String subject; /** * 邮件内容 */ private String text; /** * 发送时间 */ private Date sentDate; /** * 抄送(多个邮箱用逗号“,”隔开) */ private String cc; /** * 密送(多个邮箱用逗号“,”隔开) */ private String bcc; /** * 状态 */ private String status; /** * 报错信息 */ private String error; /** * 附件 */ private File[] files;} 编写一个服务 **MailService.java** 邮件服务接口 123456789public interface MailService { /** * 发送邮件 * * @param mailDO 邮件对象 * @return 邮件对象 */ MailDO sendMail(MailDO mailDO);} 编写服务实现类 **MailServiceImpl.java** 接口实现 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283@Service@Slf4jpublic class MailServiceImpl implements MailService { /** * 引入 spring-boot-mail 包中的关键邮件服务实现类 */ @Resource private JavaMailSenderImpl mailSender; @Override public void sendMail(MailDO mailDO) { try { // 1. 检测必须的信息是否都存在 checkMail(mailDO); // 2. 发送邮件 sendMimeMail(mailDO); } catch (Exception e) { log.error("发送邮件失败:", e); mailDO.setStatus("failed"); mailDO.setError("发送邮件失败:" + e.getMessage()); } } /** * 检测邮件对象必须的信息是否都存在的方法 * * @param mailDO 邮件对象 */ private void checkMail(MailDO mailDO) { if (Objects.isNull(mailDO.getTo())) { throw new RuntimeException("邮件收信人不能为空"); } if (Objects.isNull(mailDO.getSubject())) { throw new RuntimeException("邮件主题不能为空"); } if (Objects.isNull(mailDO.getText())) { throw new RuntimeException("邮件内容不能为空"); } } /** * 具体邮件发送方法 * * @param mailDO 邮件对象 */ private void sendMimeMail(MailDO mailDO) { try { // 构造一个复杂邮件发送 MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true); mimeMessageHelper.setFrom(mailDO.getFrom()); mimeMessageHelper.setTo(mailDO.getTo().split(",")); mimeMessageHelper.setSubject(mailDO.getSubject()); mimeMessageHelper.setText(mailDO.getText()); // 抄送 if (!Objects.isNull(mailDO.getCc())) { mimeMessageHelper.setCc(mailDO.getCc().split(",")); } // 密送 if (!Objects.isNull(mailDO.getBcc())) { mimeMessageHelper.setCc(mailDO.getBcc().split(",")); } //附件 if (!Objects.isNull(mailDO.getFiles())) { // 多个附件 for (File file : mailDO.getFiles()) { mimeMessageHelper.addAttachment(Objects.requireNonNull(file.getName()), file); } } // 发送时间 if (Objects.isNull(mailDO.getSentDate())) { mailDO.setSentDate(new Date()); } mimeMessageHelper.setSentDate(mailDO.getSentDate()); mailSender.send(mimeMessageHelper.getMimeMessage()); mailDO.setStatus("ok"); log.info("发送邮件成功:{} -> {}", mailDO.getFrom(), mailDO.getTo()); } catch (RuntimeException | MessagingException e) { e.printStackTrace(); } }} 测试 测试 123456789101112131415161718// @Test void sendMail() { MailDO mailDO = new MailDO(); mailDO.setFrom("[email protected]"); mailDO.setTo("[email protected]"); mailDO.setSubject("邮件业务测试"); mailDO.setText("简单测试"); String filePath1 = "F:\\\\XXXProjects\\\\XXXService\\\\common\\\\common.iml"; String filePath2 = "F:\\\\XXXProjects\\\\XXXService\\\\common\\\\pom.xml"; File attachment1 = new File(filePath1); File attachment2 = new File(filePath2); File[] files = new File[]{attachment1, attachment2}; mailDO.setFiles(files); mailService.sendMail(mailDO); } 四、参考 个人博客-SMTP协议 CSDN-SMTP协议介绍 阮一峰-MIME笔记 SpringBoot 发送邮件和附件(实用版) SpringBoot 发送邮件全解析","categories":[{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/categories/Spring/"}],"tags":[{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://zy68.top/tags/SpringBoot/"},{"name":"Email","slug":"Email","permalink":"https://zy68.top/tags/Email/"},{"name":"ComputerNetworks","slug":"ComputerNetworks","permalink":"https://zy68.top/tags/ComputerNetworks/"}]},{"title":"2021 年终总结","slug":"2021AnnualReview","date":"2021-12-31T14:15:14.000Z","updated":"2021-12-31T14:15:14.000Z","comments":true,"path":"2021/12/31/2021AnnualReview/","link":"","permalink":"https://zy68.top/2021/12/31/2021AnnualReview/","excerpt":"今天,是 2021 年 12 月 31 日,2021 的最后一天。我们即将与 2021 年说再见,迎接充满未知和期待的 2022。在这年终之际,之前很早就看到许多优秀的同学作了自己的 21 年总结(都是非常厉害、非常有追求的大佬,respect!),现在也该对我的 2021 做一个希望是相对全面、相对深刻的回顾与总结。认清过去、认清自己,以全新的姿态去面对未来、迎接新的挑战、成就更好的自己。","text":"今天,是 2021 年 12 月 31 日,2021 的最后一天。我们即将与 2021 年说再见,迎接充满未知和期待的 2022。在这年终之际,之前很早就看到许多优秀的同学作了自己的 21 年总结(都是非常厉害、非常有追求的大佬,respect!),现在也该对我的 2021 做一个希望是相对全面、相对深刻的回顾与总结。认清过去、认清自己,以全新的姿态去面对未来、迎接新的挑战、成就更好的自己。 今年,对我而言,不是普通的 2021,因为它还是我作为 2022 届应届毕业生最关键的过渡年。在金秋九月开学之后,我就成为了大四的同学,转眼明年六月我也将毕业走出校园,走进社会,迎来人生的一大关键转变。所以,今年,也是我为明年顺利毕业和进入社会所做努力的一年。 回味2021回顾这一年,个人认为是努力与幸运相伴的普通却又不普通的一年。没有巨大惊喜,也没有非常失意,稳稳当当,努力终会有所收获,它也许会迟到,但绝不会缺席。 从去年,也就是2020年中旬开始,我就有接触到所谓的春秋招聘,有提前做好准备意识。但事实是,那时候我刚处于启蒙阶段,同时作为一个慢热的人,外加校内课程的干扰,我是在2021年初的时候才算是开始相对认真的准备(当然,这也是为什么我后面春招如此碰壁的原因之一😥😥)。因为在2020年下旬的时候,虽然我自己很有意识的深入学习一些关于Java后端、CS核心基础以及LeetCode刷题等相关知识和技术,读了不少书、看不了不少教程,但精进效果并非立竿见影,因为在编程学习这方面,我无论是学习方法、对开发全局的认识、抑或是动手实践都还处在入门阶段,还未形成适合自己的学习开发的方法和技巧。另外,不得不说的是,学习确实是一个循序渐进的过程。只能说,DDDD 了。 由上可知,今年,对于应届毕业生的我最主要的目标、最重要的主题那必然求职和准备毕业了。年初的时候无论是在哪个阶段、无论对这些所有的所谓的技术掌握得如何,与其在原地纠结,我要不要重新学这个、重新学那个,不如全部推倒重来,重新学一遍。我开始,准确的说是才开始真正认真的把所学的知识通过笔记和文档记录下来,真正成为语雀的重度使用用户(虽然其实很早就开始了,我也不记得,但所谓的重度的程度也是对我自己而言)。从JavaSE开始,到JavaWeb,后面的计算机网络、TCP/IP和HTTP、操作系统、数据结构与算法、MySQL原理等,同时也在积极完善着 SyPastebin。 在春招的时候,一边复习一边面试,一边学习一边面试。虽然春招前中期的结果都不那么尽人意,但每次通过一次面试都是对我的思考和努力的肯定和认可,每一次面试结束也是我对自己的总结和反思。总的来说,面试无论结果怎么样,反正我不亏。但关键的问题就在于,最后的结果总是挂掉,这也让我不得不认清能力不足的现实。所以,在后期,每一场面试自己都积极的参与、认真的对待,但心里已经做好了这是该公司的最后一场面试的准备,无畏者无惧。也许确实如此,坚持,总会有奇迹发生。后来,我遇到也接受了 WeBank,以不那么完美但也算有个相对不错的结果结束了春招,收获了人生中的第一次实习。 这里不得不提的是非常感谢给予我面试机会的公司以及面我的各位面试官,面试对人的成长也只能说DDDD了。 一段实习下来,对我这小白而言,真的收获不少。实习期间遇到了几个来自各高校同实习的研究生大佬和另外一个同本科的广工大佬。工作时间每天一起恰饭、散步,讨论未来、准备秋招、一起吐槽以及一起准备科室的下午茶……,比较遗憾的可能就是没有一起到深圳其他地方玩吧,但周末也确实都是用来休息的,工作一周下来还是蛮累的。(突然有一丝想念了哈哈~~~)另外,虽然实习比较打杂,但初来乍到,mentor 和 leader 和科室的其他前辈也对我指导了不少,不过关键还是需要自己多积极主动提出问题。总体来说,抛开工作内容不谈,整个实习体验以及对科室和公司自己还是觉得挺好的。最后,非常感谢一起实习的同学、我的 mentor 和leader、科室以及公司,虽然最后自己还是因为各种原因婉拒了转正。(也许这一决定让我感到最愧疚的,应该是对我的 leader 吧😣😣) 接下来就是激烈的秋招了,但是我感触不深,因为也许我算是错过了不少大厂的秋招,整个秋招下来没有参加多少个公司的面试,或者说也没有收到多少面试机会,原因无非是学历、时间点、经历以及简历、能力的许多复杂问题吧。比较庆幸的是也有收获offer,经过反复挣扎,最后选择了跟东哥混,希望我的职场生涯能有个稳定的开始。最后,也是以不那么完美但也算有个相对不错的结果结束了秋招。 在2021后面的两三个月里,除了反复挣扎,自己也基本属于摆烂的状态(当然,也处理了不少课内外和身体上的事情,纯纯属于技术之路上的摆烂),最大的收获可能是看书和准备毕业的事情了。在这两个月里,摆烂的看书,速读速览看了不少书,涨了不少见识。另外,学业上,在目前为止,已经基本取得了毕业和学位所需的所有相关学分;稍微做了准备的参加了大学最后一次的CET-6考试;早早的和导师沟通了毕设,顺利完成答辩,项目开发也有了一点进展;还有最后一门Android实践课,自己做了6天时间的安卓课设,带着两个考研的室友安稳渡过了最后一门课(我们都有美好的未来[/手动狗头])。 2021小结2021 就这样过来了,也这样就过去了。在这期间,所有提交的代码、刷的题、熬的夜、看的书和完成的课程,都指向了:工作和毕业。 另外在技术和成长上,也算是终于找到了自己的方向,正在努力的构建自己的知识体系和框架。这里需要提到的是,今年的博客发布量确实少,每次学完并没有及时的通过文章进行分享,以后需要更有针对性的挑选题材来进行理解性的分享,多写博客。 对于自己的学习的反思发现,自己其实是一个非常容易打断连续的学习状态的人,无论是自己主动还是来自外界的被动。所以,以后还是要注意培养连续不断学习的习惯,为培养良好的学习状态准备一个稳定的生活习惯,避免外界的过多干扰。 其他的还是要多读书。最重要的,要注意自己的身体健康少熬夜了,确实伤身。 结语最后,2021的年终总结到此结束,2021的任务圆满完成,明天就是2022年01月01日,整顿一下,以全新的姿态再次出发吧,加油,造梦人! 2022,希望自己顺利毕业、顺利工作;希望自己会读更多的书,不局限于技术;希望自己的技术和开发能力有质的提升和变化;希望通过自己的努力带家人外出旅游一次。","categories":[{"name":"Experience","slug":"Experience","permalink":"https://zy68.top/categories/Experience/"}],"tags":[{"name":"年终总结","slug":"年终总结","permalink":"https://zy68.top/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"}]},{"title":"“云” 与 “开发”","slug":"cloud-known","date":"2021-09-16T16:22:14.000Z","updated":"2021-09-16T16:22:14.000Z","comments":true,"path":"2021/09/16/cloud-known/","link":"","permalink":"https://zy68.top/2021/09/16/cloud-known/","excerpt":"前言:回顾一下最近的学习,除了扎入CS的基础,也看了网站架构、了解了微服务实践的 Spring Cloud。同时,也关注了下云原生的 Kubernetes 和 Docker,当然还有实习的大数据生态。在感受这些有趣的东西的同时,也不禁要思考自己到底喜欢什么?自己到底应该想走什么方向,那么所有的这些东西又代表了什么?与未来发展的方向又有什么关系?越了解,发现这个坑越深,也越有趣,随手梳理记录一下,扫一下互联网的盲点。","text":"前言:回顾一下最近的学习,除了扎入CS的基础,也看了网站架构、了解了微服务实践的 Spring Cloud。同时,也关注了下云原生的 Kubernetes 和 Docker,当然还有实习的大数据生态。在感受这些有趣的东西的同时,也不禁要思考自己到底喜欢什么?自己到底应该想走什么方向,那么所有的这些东西又代表了什么?与未来发展的方向又有什么关系?越了解,发现这个坑越深,也越有趣,随手梳理记录一下,扫一下互联网的盲点。 从单机到互联作为一名开发者,说到互联网的发展史,单体计算机和网络是不可不谈的。 单机时代:从最开始基本的冯·诺伊曼结构:运算器、控制器、存储器、输入设备、输出设备,到与操作系统的有机组合成为了一个具有多用户、多任务调度功能的计算机。这样的计算机能够接收大量的计算任务,减少了大量的手工计算并能满足早期基本的工作使用。 互联时代:有了单个计算机的计算,很自然地就会增加机器间的数据传输的需求,在经历了机械的磁盘搬运之后,产生了网络通信。从最开始的点到点,到后来至今的端到端。计算机及其网络的变革,带来了现代社会的快速发展。 这里,也不得不了解一下计算机的分类。对于个人工作和学习的使用而言,我们可以选择使用个人计算机,如笔记本、台式电脑。而对于企业应用或服务端应用而言,就需要选择能够通过网络对外提供服务的、更多功能的、更高性能的计算机,也就是服务器,这样的计算机能够为其他的服务器或计算机(如个人计算机)提供服务。当然,还有其他类型的计算机,如超级计算机、以及路由器、嵌入式等。显然,聚焦互联网的发展,重心当然在服务器类型的计算机。 服务器: 从软件角度 —— 一个管理资源并为用户提供服务的计算机软件。 从硬件角度 —— 运行上述计算机软件的计算机。 从单体到分布式在传统的网站部署时代,需要由企业自行购买服务器设备、部署应用和自行维护。而应用的类型有相对较小的单体架构和相对较大的分布式架构: 单体架构:在单体架构的应用程序中,一个应用包括应用层、服务层、数据层集成为一个应用对外提供服务。单体应用存在简单但不易扩展等许多优缺点,仅适合小型应用程序。 分布式架构:分布式架构是在单体架构的基础上进行了拆分。比如原来的单体架构的三层拆分后分别部署在具备不同特性的服务器上提供服务,如应用程序服务器、文件服务器、数据库服务器。不同的部分分别部署在不同的服务器,不同的服务器之间的服务通过网络交换信息,形成分布式架构。分布式架构,易于扩展和更新,能够更好地支持的高并发、高可用,支撑起更大应用系统。同时,在遇到业务工作的高峰期时,可以通过增加服务器来保障系统的稳定和升级,在业务工作较为低迷时,可以通过减少不必要的服务器来另作它用,提高服务器的利用率。 使用了基于分布式架构系统的电子商务巨头 —— Amazon,率先提供了云计算服务。简单地说,因为网上零售存在季节性的高流量期。在用户购物高峰期时,需要采购更多的服务器以满足业务的需求。在经过了高峰期后,用户流量变小,那么先前采购的大量的服务器作何使用?作为具有较为完善的服务器运维团队和在网站优化上的技术和经验优势的顶级公司,Amazon 将这些空闲的机器打包为产品提供给其他企业使用,即提供可用于其他企业应用部署的服务器服务,亦即云服务。云服务提供的计算能力使得其他企业不需要再进行自主采购服务器、招聘服务器运维团队等工作,这对一个较小的企业而言,能省下不少的开销。随着云服务的不断完善和增强,云计算的优势不断增强,云服务也越来越受到市场的欢迎。云计算时代,也开始逐渐铺展开来。 云计算“云计算是一种基于互联网的计算新方式,通过互联网上异构、自治的服务为个人和企业用户提供按需即取的计算。” —— 维基 “简单来说,云服务可以将企业所需的软硬件、资料都放到网络上,在任何时间、地点,使用不同的IT设备互相连接,实现数据存取、运算等目的。” —— 百度 总的来说,云计算服务能够给企业开发者、个人开发者更轻易得到的计算机服务。目前云计算提供的服务类型主要有两种:公有云和私有云。 公有云公共云是最基础的服务,多个客户可共享一个服务提供商的系统资源,他们毋须架设任何设备及配备管理人员,便可享有专业的IT服务,这对于一般创业者、中小企来说,无疑是一个降低成本的好方法。 公共云又可根据提供的服务封装程度不同细分为3个类别,分别是基础设施、平台及软件。 IAASInfrastructure as a Service,基础设施即服务,云计算的最底层服务。指把IT基础设施作为一种服务通过网络对外提供,主要提供存储,网络和虚拟化等服务。 IAAS的好处之一在于提供商能够提供物理IT基础架构和维护,用户只需要相信服务提供商提供的服务即可,可直接研发、部署、维护自己的产品而不需要自行购买服务器和维护。另外,IaaS具有高度的灵活性和高度的可扩展性,用户可随时切换和扩容服务。 IAAS最典型的例子就是阿里云、腾讯云、华为云提供的云服务器,我们可以直接在云服务器上安装自己的服务环境并部署自己的应用。 PAASPlatform as a Service,平台即服务,PAAS通过Internet提供硬件和软件工具,人们使用这些工具来开发应用程序,用户无需关心底层系统,而只需要关心自己的业务逻辑,PaaS用户往往是开发人员。 典型的PAAS服务可参考:15种流行的平台即服务 SAASSoftware as a Service,软件即服务,SAAS也就是用户使用软件产品,该产品的研发、部署和维护都由服务提供商提供,用户只负责使用。我们所使用的互联网产品基本都是SAAS。换个角度来看,就是我们需要使用一个具备某些功能的产品软件,但是这个产品软件不需要我们自己研发、部署和维护,已经有开发商提供这个产品了,我们直接使用即可。 私有云私有云与公有云类似,区别在于私有云是因为部分企业有数据安全等需求,不放心交给公有云而自己搭建的云服务。 作为一名软件开发者,我们更应该关注的是在一个系统平台上构建自己的应用而不是思考如何从物理机上架设自己的服务平台。那么有了这一部分平台基础之后,我们就可以从机房上云了。 有了 Cloud 平台,那么就可以在 Cloud 上进行上层应用的架设。 云开发 云时代下的一些新兴开发技术和理念。 微服务微服务可以认为是可以独立部署的、小的、自治的业务组件,业务组件彼此之间通过消息进行交互。微服务的组件可以按需独立伸缩,具备容错和故障恢复能力。 微服务架构使应用程序更易于扩展和更快地开发,从而加速创新并缩短新功能的开发和实现时间。 那么这样一个细化系统,各个微小的服务独立发布、独立部署、自治。对于 Java 开发的微服务系统而言,由于Java本身支持跨平台部署和运行,那么Java开发的系统可直接部署到不同操作系统的云平台上。而对于其他非跨平台语言开发的微服务系统,则有容器化的思维和技术实现——Docker。当然Java开发的服务也可以基于Docker来部署。 这也是为什么如今存在对Java的未来担心的原因之一了。 DockerDocker 是一个应用虚拟化、容器化的引擎,它能将一个应用搭建为一个容器,该容器可以移动和运行,即支持 “Build, Ship and Run”。本质上实现的是:同一个软件发布,在不同的平台上运行。到底还是 Java 的那一套意思。 另外,Docker 实现的是轻量级的虚拟化。虚拟技术,例如 KVM虚拟技术是在操作系统级别上进行虚拟和隔离,每一个虚机都是独立的OS,即能够使得一套物理设备运行多个操作系统,多个操作系统共享分割物理资源。而Docker是在一个操作系统上的虚拟,本质上是同一个操作系统中的进程隔离,其优势 Docker 比 KVM 更省资源、资源利用率更高。 Docker的轻量级虚拟化、同一软件多平台部署,使得容器化技术在云平台上得到了很好的发展和运用。 Kubernetes利用 Docker 容器化技术使得服务能够独立开发和部署,一个个容器构建起一个大型的分布式系统。但是分布式系统的复杂性是不言而喻的,众多服务如何实现科学合理的调度、扩展、自动化等?这是Docker在大型分布式系统中存在的问题。 好在有容器编排系统——Kubernetes,它主要解决一下两个问题: 分布式容器应用的可靠性,在服务器或容器应用出现问题的情况下,自动感知,自动将容器应用在集群内的其他机器里重新运行起来 分布式容器应用的可扩展性,通过启动相同的容器应用,自动的提升应用的负载支撑能力。 通过 K8s 这一云原生操作系统的布道,互联网逐步进入云计算时代。 DevOpsDevOps 是 Development 和 Operations 的组合,重视软件开发人员和运维人员的沟通合作,通过自动化流程来使得软件构建、测试、发布更加迅速和可靠。 小结参考——知乎@李学峰 总的来说,就是基于容器和 Kubernetes 的平台提供了云原生应用的标准发布和运行环境;基于容器的微服务架构定义了云原生应用的标准架构。 通过这些技术,为软件应用在架构、支撑服务和支持组件、基准平台上进行了标准化;同时通过这些技术,解决了升级、扩容、稳定性、私有云/公有云/混合云统一基础架构等问题。 微服务架构的重要目标就是:快速发布,那么就需要在敏捷文化、自动化工具链上对流程提出了高要求。在这个基础上,利用devops的自动化文化、协作文化、敏捷文化,在软件的开发、测试、部署、运维流程上,提升了开发效率、降低了沟通成本、提升了部署和上线速度。 DevOps 是云原生应用在开发、测试和发布流程上的必要手段,基于容器的 Paas 平台和微服务架构,为 DevOps 的流行提供了土壤。 这种扫盲文章也就自己看看,毕竟level还不足,参考了挺多文章,也慢慢磨着写了好久,内容有错漏不足的地方欢迎各位 Dalao 一起讨论学习。另外, github.dev 真香,虽然没有 codespace,但 Web Editor 写文章也不错。以前想写博客,还得自己在本地 new 一下,现在直接在 github 上写,写完了在扔到博客完善、优化和发布,把写博客中心突出了一下,另外写博客的能动性也增加了。 参考 IaaS,PaaS,SaaS 的区别 —— 阮一峰 IaaS,PaaS,SaaS 的区别 —— 知乎-白码科技 微服务、容器、云原生、Kubernetes、SOA、PaaS平台、Devops 之间的关系 - 李学峰的文章 - 知乎","categories":[{"name":"Cloud Native","slug":"Cloud-Native","permalink":"https://zy68.top/categories/Cloud-Native/"}],"tags":[{"name":"Cloud Computing","slug":"Cloud-Computing","permalink":"https://zy68.top/tags/Cloud-Computing/"},{"name":"Cloud Native","slug":"Cloud-Native","permalink":"https://zy68.top/tags/Cloud-Native/"}]},{"title":"ECS部署Springboot简记","slug":"aliEcsDeploySpringboot","date":"2021-07-11T04:13:14.000Z","updated":"2021-07-11T04:13:14.000Z","comments":true,"path":"2021/07/11/aliEcsDeploySpringboot/","link":"","permalink":"https://zy68.top/2021/07/11/aliEcsDeploySpringboot/","excerpt":"","text":" 最近要重装一下 PC 系统,考虑到重装后各个环境的配置可能变得更麻烦而不易于 Sypastebin 的上线,同时也为了学习一下传统的项目部署,故顺手先部署了。果不其然,遇到了很多问题。但问题虽多,却也都是很基础的问题,也可以感受一下。 一、部署部署主流程及要点: 服务器启动(可考虑在服务商主页打开终端,执行安装宝塔面板命令,能省去ssh、ftp等麻烦); 服务器供应商服务器主页处开放相应的安全组端口; 服务器防火墙开放相应端口(更安全); 12345678910# 查看防火墙状态,没有则根据提示安装firewall-cmd --state# 开启防火墙systemctl start firewalld.service# 开放相应端口(记得开放宝塔面板正在用的8888)firewall-cmd --zone=public --add-port=8080/tcp --permanent# 开放完后,重新加载防火墙firewall-cmd --reload# 查看开放的端口firewall-cmd --list-ports 安装Nginx,将前端文件上传并配置页面; 安装MySQL并配置数据库和表,启动服务; 安装MongoDB并配置数据库和集合,启动服务; ……其他程序及其配置等(看需要),启动服务; 安装 Java 开发环境(宝塔安装 Tomcat 间接安装并配置好 JDK 8.0); 在 IDEA 利用 Maven 将 Springboot 打包:clean 后 package,在 target 目录下得到项目的 Jar包; 注:打包前需更改数据源的ip地址等,可直接使用公网ip。 上传Jar包到服务器并启动:nohup java -jar 包名 &,持续运行,会输出日志到当前目录下的nohup.out文件(可自定义),用于观察服务运行状况,查看日志; 完成。 因为服务器配置不够,MySQL 8.0 都需要 2 核。所以,直接转战Docker,索性 MySQL 和 MongoDB 都用 Docker 容器提供了。因为都是 Docker 及应用的基本操作,这里不详细介绍。(好像 Docker 容器的服务不需要开放远程连接授权)运行完之后,可以直接使用,跟服务器自身安装无差别,本地PC可直接远程连接。 利用Docker容器(代替部分程序的安装)提供服务: 拉取MySQL镜像、运行容器并配置; 录取MongoDB镜像、运行容器并配置; 二、遇到的问题和关键操作 问题很多,但基础,随缘记! Ubuntu 安装 MySQL 注意事项:MySQL安装完成后,若需要授权外部连接(默认只有 localhost),需要执行授权指令或更新权限表,使得某个ip的PC(或所有PC)可以连接。授权命令: 123# 用户user使用password密码从任何主机连接MySQL服务器GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;# 若要指定主机,则将%更改为对应的ip地址。 补充:若项目中使用角色非root,需要创建对应的角色并授权。 Navicat连接服务器MySQL Navicat连接服务器MySQL(老生常谈了,总有error想害朕): Ubuntu 安装 MongoDB 注意事项:下载 MongoDB压缩包,解压后,需要同时在安装目录(推荐)增加 data目录、log目录 及其.log文件,以及conf目录里的.conf文件,在.cong文件中编写好相应的配置(将bind_ip修改,或删除,否则无法远程连接),启动时直接利用配置文件启动。(具体操作参考) 补充:启动后,初始进入的是admin,没有账号和密码。需要新创建用户(包括root),用户创建规则:创建超级用户,在admin库,use admin后createUser,然后再在当前库进行db.auth("账号","密码")。其他普通用户也是如此,在哪个数据库下创建就在哪个库进行授权,否则出现授权失败的错误,导致无法连接。(权限部分可参考学习) 查看参考命令 123456789101112131415161718192021222324252627# 使用admin库use admin# 创建超级用户rootdb.createUser( { user:"root", pwd:"123456", roles:[{role:"root",db:"admin"}] } ) # 创建普通用户db.createUser({ 'user': "sustart", 'pwd': "password", 'roles': [{ role: "readWrite", db: "sypastebin" }]})# 授权认证db.auth('user','admin123')# 本地Mongo客户端远程连接,库admin、端口27018、用户root。(也可以使用MongoDBCompass连接)mongo 39.108.141.102:27018/admin -u root -p 其他 本地 IDEA 使用数据源时,需要添加数据源并测试是否连通,在右侧 DataSource栏。避免盲目配置,运行时连接靠运气。 因为前后端分离,所以部署后,相当于有了四个服务:两个前端、两个后端,分别跑在本地和服务器上。那么可以修改ip等参数,相互测试。(有点意思! 数据库权限授权部分还不得,折腾半天,不如认真回顾一下。 MongoDB不正常结束进程会导致应用被锁,需要删除data目录下的.lock文件和日志目录下的.log日志文件。 三、总结&收获 虽说是第一次部署服务,但其实不难,难在细节,难在各个部件的安装和配置,以及某些玄学的错误。 这次部署涉及到了很多内容,包括: 服务器重装系统,从零开始部署项目; 进一步熟悉Linux:基本的Linux命令、文件常规保存位置等; 服务器安全组、端口和防火墙的开关和配置; 宝塔面板的熟练使用; Nginx部署Web页面,域名配置; MySQL的安装、远程连接、数据库恢复和表创建、遭遇版本不对等; MongoDB的安装、远程连接(Win终端连接、MongoDBCompass连接、IDEA连接)、数据库创建和使用、权限管理等; Docker的安装、回顾了一波容器使用、常用命令; 项目服务的部署需要修改的参数和配置; 了解了波整个项目的部署的操作,下次遇到经历过的问题更轻车熟路。 发现了新东西、也回顾和一下旧东西,有助于整个项目的改进和个人能力的提升。 这次部署花了很多时间在探索和试错上,以为时间一晚上够用,可惜,花了一天。 不足: 服务器的运维能力不得,还得多玩一下服务器; 数据库的安装和配置不熟,还得多玩几次; 数据库本身不熟,还得回顾学习,不只是理论。 四、未来 对于下一次部署,会集成更多的服务组件,比如 redis 和 MySQL 的读写分离。因此,下次会结合 Dockerfile 一起配置,将整个服务容器化,方便一键拉取运行。 五、部署结果SyPastebin","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[{"name":"Springboot","slug":"Springboot","permalink":"https://zy68.top/tags/Springboot/"},{"name":"Ubuntu","slug":"Ubuntu","permalink":"https://zy68.top/tags/Ubuntu/"}]},{"title":"Innodb的底层存储结构","slug":"InnodbSavingStructure","date":"2021-05-01T03:22:14.000Z","updated":"2021-05-01T03:22:14.000Z","comments":true,"path":"2021/05/01/InnodbSavingStructure/","link":"","permalink":"https://zy68.top/2021/05/01/InnodbSavingStructure/","excerpt":" 以前学习MySQL的时候,由于过于初级,学习到的都是“概念”,过于抽象,今天把了解到的Innodb对数据的存储结构做一个整理和梳理,加深自己的印象,也希望读者能有所收获。 文章围绕着 《MySQL是怎样运行的:从根儿上理解》 的部分内容展开,挑选几个关键的图表对Innodb的底层存储结构进行解释。主要包括:行结构、页结构、页的组织(B+树、索引)。","text":" 以前学习MySQL的时候,由于过于初级,学习到的都是“概念”,过于抽象,今天把了解到的Innodb对数据的存储结构做一个整理和梳理,加深自己的印象,也希望读者能有所收获。 文章围绕着 《MySQL是怎样运行的:从根儿上理解》 的部分内容展开,挑选几个关键的图表对Innodb的底层存储结构进行解释。主要包括:行结构、页结构、页的组织(B+树、索引)。 Innodb行结构——Compact型 我们平时使用关系型数据库的时候,都是一张张表,每一张表里都是自己定义的一列列的字段、一行行的记录,事实上,还有许多我们看不见的字段,而我们自定义的字段只是这一行记录的一部分内容,并且这些我们看不见的字段都具有不同的功能,它们的作用就是支撑着我们所使用的那几个字段。根据不同的使用要求,设定不同字段实现不同功能,这样的一行记录的格式,称为行格式。 这里了解一下Innodb的行格式,设计Innodb存储引擎的前辈们到目前为止设计了4种不同类型的行格式,分别是:Compact、Redundant、Dynamic 和 Compressed。以Compact为例: 由图可以知道,Compact行格式的一行记录可以分为两个部分,分别是:记录的额外信息 和 记录的真实数据。 记录的额外信息 记录的额外信息内又可以分为:变长字段长度列表、NULL值列表 和 记录头信息。 变长字段长度列表:顾名思义,这一字段是用于记录真实数据中每个变长数据类型字段的具体的占用字节数,把所有变长字段的真实数据占用的字节长度都保存起来,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放(即列表跟真实数据字段呈对称形式的一一对应)。——好处:节省空间。 NULL值列表:用于统一记录真实数据字段中所有值为NULL的字段的值,只需要通过 0-不为NULL,1-为NULL 即可如同变长字段长度列表一样一一对应真实数据字段中哪些字段为NULL,从而利用 bit 轻松避免了在真实数据中存储。——好处:节省空间 记录头信息:用于描述记录的记录头信息,它是由固定的5个字节组成。5个字节也就是40个二进制位,不同的位代表不同的意思,如图: 各字段介绍: Innodb的底层结构中,最主要的就是上面的几个字段了。但是我这里为了突出底层存储结构,主要是要呈现一个数据结构。所以对一些字段并不详细介绍,有疑问或者想了解的同学的可以留言,我给你解答。 先看到next_record 字段,从上面的描述可以知道它就是指向下一条记录的开始,如下图所示,其原理就是数组下标能够直接定位到某个元素的原理。 至此,我们可以看到,一个表中的数据就是一个单链表结构,每行记录通过 next_record 字段链接起来,在进行范围遍历的时候,就可以直接通过这个指针来定位到下条记录。 记录的真实数据 下面我们再来看一下记录的真实数据字段。真实数据字段也并没有我们想的那么简单,根据需要还是会增加额外的字段。 具体增加的列有:DB_ROW_ID——行id(可选)、DB_TRX_ID——事务id、DB_ROLL_PTR——回滚指针。 首先看行id,Innodb表在生成主键时,优先使用用户自定义的主键作为主键;如果用户没有定义,那么就会选择一个 Unique 键作为主键;如果唯一键也没有,Innodb就会为表创建一个默认的 DB_ROW_ID 作为隐藏主键。 然后剩余两个字段都是由Innodb自动为表添加的。从名称就可以简单地看出它们的作用,这里也不做详细介绍。 综上,我们了解了一个表中每一行数据的主要字段的作用以及行与行之间的链接关系。另外需要说明并强调的是,这个链接关系是有大小顺序的,即按照主键id的大小从小到大链接,形成一个有序的单向链表结构。如果新插入的记录的主键不是当前链表的最大值,那么它会插入到原来的单向链表的对应位置中,维持链表的单向有序。 下面,我们再来看一下Innodb的页结构。 页结构 页,是Innodb管理存储空间的基本单位,一个页的大小一般是16KB。 根据不同的使用目的,Innodb设计了许多不同类型的页,比如undo日志页、存放INODE信息的页等。这里,我们主要介绍 Innodb 的数据页结构。 可以看到,一个16KB大小的页,被划分为了多个具有不同功能的存储段。 很明显,User Record,也就是用户记录,就是我们上面说的行记录。而它下面的 Free Space,顾名思义,是存储为空的空间,用于给用户记录分割的。也就是,我们每次插入一条记录的时候,会从 Free Space 开辟一行记录大小,并将其归并到 User Record 管理(也就是上面的next_record)。 其他模块: File Header:文件头,用于记录页的一些通用信息; Page Header:数据页专有的一些信息; Infimum + Supremum:最大记录和最小记录,是两个虚拟的行记录; Page Directory:页目录,页中某些记录的相对位置; File Trailer:文件尾部,用于校验页是否完整。 这里重点介绍File Header,文件头部。了解页与页之间的关系是怎么建立起来的。 文件头部也包含了不少字段内容,但是这里主要介绍三个:FIL_PAGE_OFFSET——页号、FIL_PAGE_PREV——上一个页的页号、FIL_PAGE_NEXT——下一个页的页号。 可以很容易的发现,这就是一个双向链表中一个节点的基本属性字段。也就是说,页与页之间,是一个双向链表的结构。 做个小结,从文章一开始,我们从平时熟悉的表字段知道实际存储的时候,Innodb还给我们增加了几个其他字段,具体增加的字段取决于我们选择的行格式,但基本大同小异。然后我们重点注意了行格式字段中的 next_record 得到行与行之间是一个链式存储结构,再结合主键的顺序也就是有序的单向链表。了解了行记录之后,我们又了解了页结构,发现,一个16KB的页划分了几个不同的功能模块,前面所有的行都是 User Record 的内容,然后重点了解了 File Header 字段,发现一个页保存了上一页的地址和下一页的地址。总的来说、宏观上来说:Innodb的页与页之间是就是一个双向链表结构,每一个页内的行与行之间就是一个单向链表结构。 B+树结构 到这里,我们回头再看一下记录头信息中的 record_type,它代表的是当前记录的记录类型。记录类型一共有四种,上面说的用户的记录是 0 普通记录。这里我们要讨论的是 1 B+树非叶子节点记录。当一条记录的记录类型为B+树的非叶子结点记录时,也就是索引的记录。不会B+树的同学请Google~~~。 在所有的记录中,也就是上一个双向链表图结构,Innodb会选取一部分记录的主键id来组织成新的16KB特殊页,这个特殊页的User_Record 存储的就是主键id和它对应的页号。由此,我们就得到了同样的一个双向链表结构,并且每一个节点的每一条记录都映射到我们原来的所有记录中。这样,我们就可以通过得到的主键id快速定位到对应的数据页。同理,如果两层不足,那么可以根据需要继续增加。(从某个角度来说也就是跳表。 但B+树的强大使得其树高一般不超过四层)然后,我们便可以得到如下的数据结构——B+树: 总结 在本篇文章中,我们通过行结构,认识页内记录的组织,并且认识必然存在的每条记录的主键id,然后认识了指向下一行记录的 next_record 了解到每条记录就是单向链表的一个节点。认识了每个页中文件头的双向存储——上一个页、下一个页。然后我们得到了页页组织的双向链表结构、行行组织的有序单向链表结构。在此基础上,我们回头看行结构中的记录头中的 record_type,认识到还有记录类型的概念。所有值为1的为B+树的非叶子结点的记录,这些记录提取出了主键id和对应的页号组织为了新的特殊页,在这新的特殊页上就可以通过主键id快速访问到它所在的完整信息的页,这也就是一层索引,如果一层不够,我们可以在一层的基础上再抽取一层,同理可以抽取出很多层(一般四层足矣)。由此得到一个B+树的结构。 后话 文章选取了《MySQL 是怎样运行的:从根儿上理解 MySQL》的七张图片,并基本阐释了Innodb的底层存储结构,但还有许多细节我并没有详细解释,主要体现的是Innodb存储的结构。但其实每一个细节都是不应该被忽视的,它们对我们理解Innodb整一个存储结构具有非常重要的作用。 了解了实际的存储结构后,对于其他的一些概念上的东西也就迎刃而解了。什么主键索引、辅助索引、回表等就会有真正的自己的理解,而不仅仅是概念。 注:作者在书中利用了两篇很长篇幅的文章来介绍Innodb的记录结构和页结构,讲解得非常详细且无废话,给我的感觉可以用醍醐灌顶来形容。而这篇文章是我从里面提取出来的总结梳理性的文章,个人理解能力有限,欢迎勘误。另外,如果对MySQL感兴趣的话,本书值得一读,豆瓣9.4。(非广告) 参考《MySQL是怎样运行的》豆瓣 掘金上有电子版","categories":[{"name":"Database","slug":"Database","permalink":"https://zy68.top/categories/Database/"}],"tags":[{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/tags/MySQL/"},{"name":"Database","slug":"Database","permalink":"https://zy68.top/tags/Database/"}]},{"title":"关于跨源资源共享CORS的问题","slug":"aboutCORS","date":"2021-03-06T07:00:14.000Z","updated":"2021-03-06T07:00:14.000Z","comments":true,"path":"2021/03/06/aboutCORS/","link":"","permalink":"https://zy68.top/2021/03/06/aboutCORS/","excerpt":"之前遇到问题的时候在语雀撸的笔记,整一份到博客,方便浏览。","text":"之前遇到问题的时候在语雀撸的笔记,整一份到博客,方便浏览。 前言:问题来自在进行前后端分离的过程中,前端部分单独运行自己的服务,后端部分单独运行自己的服务,但二者之间却无法进行数据接口的连接,问题就是在于资源跨域问题,下面来了解一下这个资源跨域及其解决办法。 在跨源之前先了解一下源和同源是什么? 一、同源策略同源策略,我觉得wiki解释得不错: 同源策略是指在Web浏览器中,允许某个网页脚本访问另一个网页的数据,但前提是这两个网页必须有相同的URI、主机名和端口号,一旦两个网站满足上述条件,这两个网站就被认定为具有相同来源。此策略可防止某个网页上的恶意脚本通过该页面的文档对象模型访问另一网页上的敏感数据。 同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie[1]来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。 值得注意的是同源策略仅适用于脚本,这意味着某网站可以通过相应的HTML标签[2]访问不同来源网站上的图像、CSS和动态加载脚本等资源。 下面再来看个例子,判断下列哪些URL与URL**http://www.example.com/dir/page.html** 属于相同来源: URL 结果 原因 http://www.example.com/dir/page2.html 是 只有路径不同 http://www.example.com/dir2/other.html 是 只有路径不同 **http://**username:[email protected]/dir2/other.html 是 只有路径不同 http://www.example.com:81/dir/other.html 否 不同端口(若未标明,http:// 默认端口号为80) https://www.example.com/dir/other.html 否 不同协议(https和http) http://en.example.com/dir/other.html 否 不同域名 http://example.com/dir/other.html 否 不同域名(需要完全匹配) http://v2.www.example.com/dir/other.html 否 不同域名(需要完全匹配) 总的来说就是无论是几个网站,只要有相同的URI、主机名和端口号它们就是同源,禁止非同源的脚本相互访问是浏览器的安全措施。因此解决跨域问题即解决URI、主机名和端口的问题。 了解了同源,我们再来了解一下跨源问题。 二、跨源跨源问题可以基于同源进行探讨,同源要求URI、主机名和端口号相同,那么跨源即是一个页面访问多个不同的URI、主机名和端口号的资源的问题,即跨源资源共享CORS。详情可看WIKI。 同源策略是一个安全策略,它是具有两面性的,它能屏蔽恶意请求,但当我们需要进行跨域操作的时候就无法进行,比如前后端分离的时候。因此,当我们有需求的时候,我们可以进行跨源资源共享操作。 没有同源策略的带来的影响,可以看一眼:对于浏览器的同源策略你是怎样理解的呢? - 王泥煤的回答 - 知乎,另外后面华为开发社区号的回答也不错。 三、如何进行跨域访问解决跨域问题有四种方法: 架设服务器代理(浏览器请求同源服务器,再由同源服务器进行外部服务); JSONP(思想是通过添加Script元素,向服务器请求JSON数据); WebSocket协议(该协议不遵循同源策略); 跨源资源分享(CORS,Cross-Origin Resource Sharing) 这四种方法,详情可见浏览器同源政策及其规避方法——阮一峰的网络日志 四、跨源资源分享CORS跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的”预检”请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。 CORS允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。 CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。 五、SpringBoot项目中使用CORS参考SpringBoot 实现前后端分离的跨域访问(CORS) 方式1:返回新的CorsFilter(全局跨域) 方式2:重写WebMvcConfigurer(全局跨域) 1234567891011121314151617181920212223242526package com.hehe.yyweb.config;@Configurationpublic class GlobalCorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override //重写父类提供的跨域请求处理的接口 public void addCorsMappings(CorsRegistry registry) { //添加映射路径 registry.addMapping("/**") //放行哪些原始域 .allowedOrigins("*") //是否发送Cookie信息 .allowCredentials(true) //放行哪些原始域(请求方式) .allowedMethods("GET","POST", "PUT", "DELETE") //放行哪些原始域(头部信息) .allowedHeaders("*") //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息) .exposedHeaders("Header1", "Header2"); } }; }} 方式3:使用注解(@CrossOrigin)(局部跨域) 方式4:手工设置响应头(HttpServletResponse )(局部跨域) 六、本地实操未配置CORS通过web访问服务端接口时浏览器端的错误: http请求头 配置了CORS且请求成功的请求头 可以看到配置 Access-Control-Allow-Origin: * ,放行所有原始域。 参考资源 同源策略——wiki 浏览器同源政策及其规避方法——阮一峰的网络日志 跨源资源共享-MDN 跨域资源共享CORS详解——阮一峰 SpringBoot 实现前后端分离的跨域访问(CORS) SpringBoot升级至2.4.0中出现的跨域问题分析及修改方案","categories":[{"name":"HTTP","slug":"HTTP","permalink":"https://zy68.top/categories/HTTP/"}],"tags":[{"name":"network","slug":"network","permalink":"https://zy68.top/tags/network/"},{"name":"cors","slug":"cors","permalink":"https://zy68.top/tags/cors/"}]},{"title":"MySQL事务机制","slug":"theTransactionOfMySQL","date":"2021-03-05T08:46:14.000Z","updated":"2021-03-05T08:46:14.000Z","comments":true,"path":"2021/03/05/theTransactionOfMySQL/","link":"","permalink":"https://zy68.top/2021/03/05/theTransactionOfMySQL/","excerpt":"🈲🈲Ctrl + z Ctrl + Y🈲🈲 好不容易开开心心撸完这篇博客,一下子Ctrl Z,手忙脚乱,啪,没了😔😔。淦,这是二次回放。第一次的思维已经莫得了。。。谨慎撤销、谨慎撤销、谨慎撤销。","text":"🈲🈲Ctrl + z Ctrl + Y🈲🈲 好不容易开开心心撸完这篇博客,一下子Ctrl Z,手忙脚乱,啪,没了😔😔。淦,这是二次回放。第一次的思维已经莫得了。。。谨慎撤销、谨慎撤销、谨慎撤销。 为什么需要事务?考虑一个场景——转账。账户A有100块钱,给账户B转50。其中就包含着两个有先后顺序的 update 操作。正常情况下,第一个update,账户A 100-50 剩 50。同时账户B update 加50。总的金额还是100,保持不变。如果出现异常,在第一次 update 执行结束后,第二个update 执行失败,那么账户A 100-50 剩 50。但账户B并没有加50。此时金额的总量由100变成了50。这是无法忍受的,那么就需要事务处理机制来解决。 一、事务事务处理(transaction processing)可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。 用事务思维思考上述场景:如果转账的两个操作能够要么完全执行,要么完全不执行,还会出现金额丢失的情况吗?不会,结果要么正常转账,要么转账失败,但金额不变。这两个update就是事务。由此,可以进一步探究事务的特性👇👇。 ACID特性四个特性ACID: **原子性(Atomicity)**:事务的整个过程如原子操作一样,最终要么全部成功,或者全部失败。 **一致性(Consistency)**:一个事务必须使数据库从一个一致性状态变换到另一个一致性状态。即达到期望。 **隔离性(Isolation)**:一个事务的执行不能被其他事务干扰。 **持久性(Durability)**:一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。 初步认识了事务的来源背景和事务特性,再来在看看数据库中怎么用,增强认识。 二、显隐式事务隐式事务MySQL 中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务。 显式事务很明显,显式事务就是需要手动开启、提交或回滚,由开发者自己控制。 三、事务操作1. 操作术语 事务(transaction) 指一组SQL语句; 回退(rollback) 指撤销指定SQL语句的过程; 提交(commit) 指将未存储的SQL语句结果写入数据库表; 保留点(savepoint) 指事务处理中设置的临时占位符(placeholder),你可以对它发布回退(与回退整个事务处理不同)。 否开启隐式事务是由变量autocommit控制的。为ON表示开启了自动提交。语法: 1show variables like 'transaction_isolation'; 2. 开启事务方式1: 1234567//设置不自动提交事务set autocommit=0;//执行事务操作//事务结束:提交或回滚commit|rollback; 方式2: 123456// 开启事务start transaction;// 执行事务操作commit|rollback; 开启事务示例 1234567891011121314151617181920212223242526mysql> show variables like 'transaction_isolation';+-----------------------+-----------------+| Variable_name | Value |+-----------------------+-----------------+| transaction_isolation | REPEATABLE-READ |+-----------------------+-----------------+1 row in set, 1 warning (0.10 sec)mysql> show variables like "autocommit";+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | OFF |+---------------+-------+1 row in set, 1 warning (0.01 sec)mysql> set autocommit = 1;Query OK, 0 rows affected (0.14 sec)mysql> show variables like "autocommit";+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit | ON |+---------------+-------+1 row in set, 1 warning (0.00 sec) 3. 保留点如果发生故障时不需要全部回退,而只选择性的回退一部分,则可以使用保留点,回退到指定的点。 12SAVEPOINT 保留点名;ROLLBACK TO 保留点名; 4. 只读事务1start transaction read only; 开启了之后,执行更改数据的命令会出错。 进一步解析事务执行 12345678// 开启手动操作事务set autocommit = 0;// 事务操作:insert \\ update \\ delete// 执行了事务之后,数据库中的表已经发生了修改了。意味着其他事务可以读取数据来使用。这也就导致问题的出现// 执行提交或回滚,执行完之后事务才算结束。commit | rollback; 可见,在事务中一旦执行更新表操作,表中的数据就会变化。而此时其他事务是可以读取表中的数据来使用的,而一旦该事务不提交而回滚了,那么其他事务读取到的将是错误的数据。由此,说明事务是存在问题的。 四、事务中存在的问题 脏读 一个事务在执行的过程中读取到了其他事务还没有提交的数据。 读已提交 一个事务操作过程中可以读取到其他事务已经提交的数据。事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(相当于当前读) 可重复读 一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。 幻读 幻读发生在可重复读的基础上。事务中后面的操作需要前面的读取操作提供支持,但读取操作却不能支持下面的操作时产生的错误,就像发生了幻觉一样。 比如: 事务A:1.读取某条记录—发现不存在;2.那么事务A进行插入—结果插入失败;3.再次读取该条记录—还是发现不存在——事务A纳闷发生了什么?(幻读-事务A明明没有读到该条记录啊) 事务B:1.在事务A读取之后,插入之前,事务B插入了该条数据——导致事务A插入失败;2.但事务A再次读的时候还是不存在(可重复读) 针对上面这些问题:如何保证事务中数据的正确性——一个事务是否可以看见另一个事务已提交或未提交的数据?——通过事务的隔离级别来解决。 五、隔离级别事务隔离级别主要是解决了上面多个事务之间数据可见性及数据正确性的问题。 隔离级别相当于数据库环境的状态,不同的状态有不同的功能效果。 隔离级别分为4种: 读未提交:READ-UNCOMMITTED 读已提交:READ-COMMITTED 可重复读:REPEATABLE-READ 串行:SERIALIZABLE 4中隔离级别越来越强,会导致数据库的并发性也越来越低。 查看隔离级别:show variables like ‘transaction_isolation’; 设置隔离级别 修改mysql中的my.init文件 123# 隔离级别设置,READ-UNCOMMITTED读未提交, READ-COMMITTED读已提交,# REPEATABLE-READ可重复读, SERIALIZABLE串行transaction-isolation=READ-UNCOMMITTED 重启mysql。 各种隔离级别中会出现的问题 隔离级别 脏读 不可重复读 幻读 READ-UNCOMMITTED 有 有 无 READ-COMMITTED 无 有 无 REPEATABLE-READ 无 无 有 SERIALIZABLE 无 无 无 无 1. 隔离级别为——读未提交场景模拟(空表,两个事务,按序号顺序): 事务A:1. 开启事务,然后读取——空表;4.读取——成功,事务B插入的数据;6.commit; 事务B:2.开启事务,然后插入数据——成功;3.读取——成功,有数据;5. commit; 结论: 读未提交情况下,可以读取到其他事务还未提交的数据,出现了脏读; 多次读取结果不一样,为不可重复读。 2. 隔离级别为——读已提交场景模拟(空表,两个事务,按序号顺序): 事务A:1.开启事务,然后读取——空表;4. 读取数据——还是空表;6. 读取数据——有事务B插入的数据;7.commit; 事务B:2.开启事务,然后插入——成功;3.读取数据——成功;5. commit; 结论: 读已提交情况下,无法读取到其他事务还未提交的数据,未出现脏读; 可以读取到其他事务已经提交的数据,出现了读已提交; 多次读取结果不一样,不可重复读。 3. 隔离级别为——可重复读场景模拟(空表,两个事务,按序号顺序): 事务A:1.开启事务,然后读取——空表;3.读取数据——还是空表;5.读取数据——还是空表;6.commit;7. 读取数据——有事务B插入的数据; 事务B:1.开启事务,插入数据——成功;2.读取数据——成功;4.commit; 结论:• 可重复读的情况下,无法读取到其他事务还未提交的数据,未出现脏读;• 未读取到其他事务已经提交的数据,且多次读取结果一直,为可重复读; 4. 隔离级别为——可重复读——幻读场景模拟(空表,两个事务,按序号顺序): 事务A:1.开启事务,然后读取某条记录——发现不存在;4.进行该记录插入——结果插入失败;5.再次读取该条记录——还是发现不存在啊——事务A纳闷发生了什么?第一次读取是发生了幻觉?(幻读-事务A明明没有读到该条记录啊) 事务B:2.开启事务,插入了该条数据——成功;3.读取该条记录——成功;6.commit; 结论: 事务A第一次读取的时候相当于幻觉,即幻读。明明没这条数据,但插入还是失败,第二次再读取来确认,发现确实是不存在的呀,晕。——第二次读还是不存在,得益于可重复读级别。 5. 隔离级别为——串行串行是针对整个事务而言的。一个事务想要执行,必须等待上一个事务执行结束才可以执行。 结论:一个个事务串行执行,不存在脏读、不可重复读、幻读的问题。但效率较低。 六、关于隔离级别的选择 需要对各种隔离级别产生的现象非常了解,然后选择的时候才能游刃有余 隔离级别越高,并发性也低,比如最高级别SERIALIZABLE 会让事物串行执行,并发操作变成串行了,会导致系统性能直接降低。 具体选择哪种需要结合具体的业务来选择。 读已提交(READ-COMMITTED)通常用的比较多。 吐槽:好好的一篇文章变成了流水账,可惜!!!💔💔写文章确实需要灵感,一件艺术品,总是需要精心雕刻的。 参考 《MySQL必知必会》 玩转Mysql系列 - 第13篇:详解事务","categories":[{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/categories/MySQL/"}],"tags":[{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/tags/MySQL/"},{"name":"database","slug":"database","permalink":"https://zy68.top/tags/database/"}]},{"title":"常用算法系列2一贪心算法及其应用","slug":"greedy","date":"2021-01-12T06:30:14.000Z","updated":"2021-01-12T06:30:14.000Z","comments":true,"path":"2021/01/12/greedy/","link":"","permalink":"https://zy68.top/2021/01/12/greedy/","excerpt":"今天来复习一波贪心算法。贪,就完了~~~","text":"今天来复习一波贪心算法。贪,就完了~~~ 一、贪婪算法 贪婪算法(Greedy Algorithm),又称贪心算法,其主要思想是:在每一步决策中,总是选取当前状态下最好的或最优的选择,从而希望得到的最终结果是最好或最优的。即希望通过实现局部最优来达到全局最优的目的。 ——贪心算法-WIKI 贪心算法具有无后向性,即每一阶段的决策一旦确定,这个决策结果都不会受到后面的决策的影响,且不能回退回到之前的某一状态。这与动态规划有所区别,动态规划会保存之前的运算结果,包括选择或未选择的运算结果,并能够根据以前的结果来对当前的结果进行选择。因此,对于大部分问题,贪心算法并不是一定是能够取得最好或最优结果的算法,只能取得较为接近最好或最优结果,因而它的应用范围有限。 下面来上点典型应用,加深认识和理解👇👇 二、贪婪算法的典型应用先来上点开胃菜,👇👇 1.找零钱问题 有几种固定面额的纸币,比如100块,50块,20块,10块,5块,1块。当需要找数值为n钱额的零钱,问如何找才能使得所找的纸币数量最少? 这很明显的贪心问题。当然每次找最大,以一抵十、以一抵百,这样纸币数才是最少。具体实现思路可以转换为:每次找在n范围内最大面额的纸币,然后n减去所找的纸币,再重新找下一张纸币,直到最后n=0。换一个角度,每次都贪面额最大的纸币,每次都贪面额最大的纸币,每次都贪面额最大的纸币。贪着贪着就找完了,得到的纸币数刚好是最少的,也得到了问题的最优解。 2.背包问题 背包问题是贪心算法和动态规划里最经典之一了。背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。——背包问题-WIKI 考虑物品数量为1的情况下,根据物品是否可分量可以分为一般的背包问题和0-1背包问题。 一般的背包问题中,可以将物品的一部分装入背包,但不能重复装入。 0-1背包问题中,限定每种物品只能选择0个或1个。即要么装完一整个要么不装,与部分装入相对应。 这里,我们分开讨论(空谈太乏,上个例题): 背包问题 给定N个物品和一个背包,背包的容量为W,假设背包容量为15,第i个物品对应的体积和价值分别为W[i]和v[i]。各种物品的价值和重量如下:物品编号12345重量W34789价值V45101113求: 如何选择装入背包的物品,使得装入背包的物品的总价值为最大。实现代码12时间复杂度O()空间复杂度O() 利用贪心算法解决背包问题的关键是如何选定贪心策略,使得物品按照这个策略能够尽可能的装入背包中,最后价值最大。很明显,我们既不能仅着眼于看见价值最大的物品即装入而忽略重量的盲目追求价值的策略,因为这样背包可能会迅速装满;也不能仅着眼于每次选择最轻的物品来使得背包能装更多的物品,这个策略最后的结果价值不一定是最大。而正确的,应该根据性价比来选择物品。 因此,我们的算法可以设计为: 根据给定的物品重量和价值,计算每一个物品的单价; 再根据得到的单价对每一个物品进行降序排列; 根据得到的物品优先级次序来装入背包,这里区分是一般的背包问题还是0-1背包问题。若是前者,可以根据背包剩余的容量来计算装入物品的多少( 0<实际装入的w[i]<1 ),直到背包装满,可以得到最优解。若是后者,则根据背包的容量是否够继续装入下一个物品,够则装入,不够则跳过当前物品去判断下一个物品,直到背包装满或没有适合的物品装入为止,只能尽可能的靠近最优解。 顺便实现一下?😏😏——代码在题目收缩面板里呢!!! 3.最小生成树——Prim为例 最小生成树问题最常见的算法是Prim算法和Kruskal算法,它们都可以在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。 先来简单认识一下这两个算法: Prim算法 Prim算法的基本思想是通过将已访问节点和未访问节点分开,每次从所有已访问节点中的任一节点出发,逐步通过可达边中的最短边将未访问节点纳入已访问节点的阵营中,直到未访问节点阵营全部进入已访问阵营中,得到最小生成树。 具体算法看WIKI: Kruskal算法 Kruskal算法的基本思想是通过将点边分离再组合得到最小生成树,即将所有的边按从小到大排序,每次任意选取最小的一条边,如果这条边连接的两个点至少有一个不在正在建立的连通图中,那么将这条边添加到图中。不断重复,直到所有的点都连接在一起且不构成圈,或者说同在一个连通分量。 具体算法看WIKI: 新建图G,G中拥有原图中相同的节点,但没有边; 将原图中所有的边按权值从小到大排序; 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中; 重复3,直至图G中所有的节点都在同一个连通分量中。 若不理解Prim算法和Kruskal算法,建议前往wiki学习,解释和图例都很棒。 顺便实现一下?😏😏——这里实现Prim算法 Prim 如下图,从A节点开始,求它的最小生成树。基本思路:思路还是Prim算法的思路,实现是利用两个数组来表示已访问节点(selected[])和未访问节点 (left[]),利用二维数组graph[][]的邻接矩阵来存储图。每一次找点,都是从所有已访问节点数组(selected[])出发任选一个点,找到最短的可达边,且对应的点在未访问节点数组(left[])中,避免重复也要求不在已访问节点数组(selected[])中。每次找到都将点从未访问搬到已访问中。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115#include <stdio.h>#include <stdlib.h>#define MAX_L 100 // 假设所有的边权值都小于100// 邻接矩阵表示图,0~5=A~Fint graph[6][6] = { {0, 5, 6, 4, 0, 0}, {5, 0, 1, 2, 0, 0}, {6, 1, 0, 2, 5, 3}, {4, 2, 2, 0, 0, 4}, {0, 0, 5, 0, 0, 4}, {0, 0, 3, 4, 4, 0}};int selected[6] = {-1}; // 存选择了的节点int left[6] = {0, 1, 2, 3, 4, 5}; // 存未选择的节点// 判断某一点是否在待选择集合中int isInLeft(int n){ for (int i = 0; i < 6; i++) { if (left[i] == n) { return 1; } } return 0;}// 判断某一点是否在已选择集合中int isNotInSelected(int n){ for (int i = 0; i < 6; i++) { if (selected[i] == n) { return 0; } } return 1;}// 从Selected内的所有边找最小的边对应的节点,且节点不存在Selected中int getNextNode(){ int min = MAX_L; int index = -1; for (int i = 0; i < 6 && selected[i] != -1; i++) //从已选择的集合中取点 { for (int j = 0; j < 6; j++) //从当前点找最小 { //先判是不是最小且不为0,再判这个节点是不是在待查找中 if (graph[selected[i]][j] < min && graph[selected[i]][j] != 0 && isInLeft(j) && isNotInSelected(j)) { min = graph[selected[i]][j]; index = j; } } } return index;}int main(){ selected[0] = 0; //从第0个节点开始,即A。 left[0] = -1; //0号点已取 //将已经访问的节点记录 for (int i = 1; i < 6; i++) { int nodeIndex = getNextNode(); selected[i] = nodeIndex; //把对应的节点放到已取节点的集合中 left[nodeIndex] = -1; //把已经访问的节点删除 } //打印结果,按顺序打印Selected数组内容,每一个数组对应字母 for (int i = 0; i < 6; i++) { switch (selected[i]) { case 0: printf("A"); break; case 1: printf("B"); break; case 2: printf("C"); break; case 3: printf("D"); break; case 4: printf("E"); break; case 5: printf("F"); break; default: break; } if (i<5) { printf("-"); } } printf("\\n"); system("pause"); return 0;}注:看到别的dalao以及wiki上写的真的是头大,这是自己基于Prim思想写的,在二维数组中各种花里胡哨的操作。时间复杂度嘛,不敢说,only achieved!!!另外,代码还是具有可复用性的嘛。👀🌚 4.多级调度问题 有n个作业,完成作业的耗时分别为T1,T2,T3,...,Tn,一共有m台机器(m<n),每个作业为非抢占式,问如何安排作业才能使得完成所有的作业耗时最少?看个例子: 作业调度 例如n=7,m=3,每个作业完成所需的时间如表所示作业编号1234567完成用时214416653 算法可设计为: 将所有的作业按所用时间大小从大到小排序; 根据作业次序,按M1 ~ Mm的工作量从小到大分配,工作量即已安排的作业的时间叠加,谁的工作量小就把一个作业分配给谁。 不断重复步骤2,直到分配完毕。最后工作量最大的机器的工作量就是完成所有作业的最短时间。 机器与机器之间是并行关系。 贪心算法的应用还有很多,比如哈夫曼编码和旅行商问题等。应用不可能面面俱到,最核心的还是要掌握算法的思想,利用思想去举一反三,解决变化多样的问题。 三、总结一下最后稍微总结一下贪心算法,先再看一波概念,希望有所体会或新的收获。 贪心算法就是在一个大问题中,朝着总目标的最终解前进,每到一个状态选择当前的最优解,不断重复。最后将得到的所有解组合为最终的一个可行解。它适用前提是:局部最优策略能够导致产生全局最优解。否则,不适用。 最后,贪心算法并不是解决最优化问题的最好方法,它只是其中一个可行方法,它得到的解不一定是最优的,且大多数问题都不是最优的。但使用这个算法得到的解可以作为取得最优解的参考。 balabala~~,实现算法太难了😫😫 参考 维基百科 《算法设计与分析》——吕国英 【算法】—-贪心算法(背包问题)","categories":[{"name":"Algorithm","slug":"Algorithm","permalink":"https://zy68.top/categories/Algorithm/"}],"tags":[{"name":"algorithm","slug":"algorithm","permalink":"https://zy68.top/tags/algorithm/"},{"name":"greedy","slug":"greedy","permalink":"https://zy68.top/tags/greedy/"}]},{"title":"常用算法系列1一分治算法及其应用","slug":"divideAndConquer","date":"2021-01-11T05:00:14.000Z","updated":"2021-01-11T05:00:14.000Z","comments":true,"path":"2021/01/11/divideAndConquer/","link":"","permalink":"https://zy68.top/2021/01/11/divideAndConquer/","excerpt":"最近在准备算法设计与分析的期末考试,顺便简单总结记录一下。Let’s go~~~","text":"最近在准备算法设计与分析的期末考试,顺便简单总结记录一下。Let’s go~~~ 前言 在正式开始某一具体算法之前,还是想简单废话一下自己对算法的理解和认识。首先,三大本源问题:算法是什么?为什么会有算法?常用的算法都有哪些且它们都能用来解决什么样的问题? 余以为,算法,就是解决问题时所用的指定的方法和步骤,通过这个步骤和方法能够得到这个问题的答案。我们一直在用算法,我们身边都是算法,只是在这里,我们是从计算机科学的角度去讨论某些常用的算法。 为什么会有算法?因为我们的身边总是存在各种各样的问题需要去解决,每个人都有或没有自己解决问题的思维思想,但自己的思想可能不是最好最优的算法,所有我们要站在巨人的肩膀上,总结和归纳比较好的思想,通过学习优秀的思想,解决对应的问题,也是扩展开发自己的思维,因而存在需要学习的算法。 常用的算法思想主要有:迭代、分治、贪心、动态规划、回溯、分支限界等,每一种算法思想都可以用来解决不同的或相同的问题,因为存在不同特性和优劣的问题,需要根据不同的情况来选择最优的算法。 迭代适合问题规模比较小,能够验证最优解的情况;分治适合规模大且具有相同子问题的情况,将大问题分割为小问题解决;贪心适合问题整体的规模不是由局部最优解组成,且对最优解没有要求的情况;动态规划适合当问题的整体最优解就是由局部最优解组成的情况;回溯适合具有尝试性的问题,利用dfs的思想不能得到则回退;分支限界适合产生多个子结构并从中选择最优而同时排除非最优的子结构的问题,能够加速收敛得到最优解。 大白话,真的是有够抽象的,难以描述。 那么,为了拥有更好的解决问题或得到更好答案的思想,现在从分治算法开始👇👇 一、分而治之算法 **分而治之算法(divide and conquer)**,就是把一个复杂的问题分成两个或多个相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。另外,因为分治的子问题的属性,所以它常常与递归相伴 ——分治算法—WIKI 概念过于空泛,来点典型应用👇👇 二、分治算法的典型应用1. 二分查找 二分查找:说到分治,那必须点到二分查找。二分查找Binary Search,也称“折半查找”“对数搜索”,就是在一个有序的数组中查找某一特定元素的算法,通过比较与中间值的大小,不断缩小查找的范围。这就应用了分治的思想,从大数组逐步变成小数组,最后得到问题的解。——二分查找算法—WIKI 顺便实现下?😏😏 BinarySearch 12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * 递归二分 * @param arr * @param left * @param right * @param target * @return */ int binarySearch(int arr[], int left, int right, int target) { if (left > right) return -1; int mid = left + (right - left) / 2;// 避免溢出不使用直接平均 if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { return binarySearch(arr, mid + 1, right, target); } else { return binarySearch(arr, left, mid - 1, target); } }/** * 非递归二分 * @param arr * @param target * @return */ int UnRecursionBinarySearch(int[] arr, int target) { int left = 0; int right = arr.length; while (left <= right) { int mid = left + (right - left) / 2;// 避免溢出不使用直接平均 if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; }时间复杂度O(logN) :折半,每次少一半,2^x = N ,总次数为x。空间复杂度O(1) :固定大小数组,固定次数的临时变量。 2. 快速排序 快速排序:有查找,怎么能没有排序?当然,主要还是快排确实用到了分治的思想。快速排序Quick Sort,又称分区交换排序(partition-exchange sort),简称快排,快排的主要实现思想是以某一值为标准,比这个值小的放左边,比这个值大的放右边,这样就排序完了一个值,左边的值都比它小,右边的值都比它大。然后再对这两个子集合进行同样的算法排序,直到最后两个子集合也排序完,那么整个排序也就排完了。————快速排序-WIKI 顺便实现下?😏😏 Inplace-QuickSort 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859/** * 快速排序 按照设计的算法思想,先把快排大问题化小问题的大框架搭起来 * * @param arr * @param left * @param right */ void quickSort(int[] arr, int left, int right) { if (left > right) return; // 取中间值,暂时不用管怎么取,就是partition()给的 int mid = partition(arr, left, right); // 同样算法排左边的子集合 quickSort(arr, left, mid-1); // 同样的算法排右边的子集合 quickSort(arr, mid + 1, right); // 左右的子集合都排完之后就排好了,框架搭建完毕。 } /** * 分区,取基准值 * 然后再取基准值,在进行左右大小分区后得到基准值,本方法做的就是分区 * @param arr * @param left * @param right * @return */ int partition(int[] arr, int left, int right) { int mid = arr[left]; // 不断筛选 while (left < right) { // 从右边开始,找一个小的用来替换到左边 while (left < right && arr[right] >= mid) { right--; } if (left < right) { arr[left] = arr[right]; } // 从左边找一个大的用来换到右边 while (left < right && arr[left] <= mid) { left++; } if (left < right) { arr[right] = arr[left]; } } arr[left] = mid; return left; }时间复杂度O(?) : 等一位高人指点,please。空间复杂度O(1) :一个数组原地排序,三个临时变量。 3. 归并排序 归并排序:有快排,当然少不了归并咯。归并排序Merge Sort,指将两个已经排序的序列合并成一个序列的操作,该算法依赖于归并操作。其实它包含分治算法的两个步骤:1.分割——一个大序列分成只有一个或两个元素的小序列;2.集成:保持元素顺序同时将上一步得到的小序列合并到一起。u1s1,归并真是把分治的思想体现得淋漓尽致,先是大化小,再小化大而得到解。————归并排序-WIKI 顺便实现下?😏😏 MergeSort 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667/** * 此方法用来简化方法调用,只需传入要排序的数组即可 * * @param arr */ void faMergeSort(int[] arr) { int[] temp = new int[arr.length];// 临时数组,辅助存储交换的数据 mergeSort(arr, 0, arr.length - 1, temp);// 调用真正的归并方法 } /** * 实现了归并算法的方法——分解 * * @param arr * @param left * @param right * @param temp */ void mergeSort(int[] arr, int left, int right, int[] temp) { if (left >= right) return; int mid = left + (right - left) / 2; mergeSort(arr, left, mid, temp);// 归并左边 mergeSort(arr, mid + 1, right, temp);// 归并右边 mergerSortInOrder(arr, left, mid, right, temp);// 合并左右 } /** * 归并的合并实现:将左右子序列按大小存到temp数组,最后再拷贝temp数组中的值覆盖原数组 * * @param arr * @param left * @param mid * @param right * @param temp */ void mergerSortInOrder(int[] arr, int left, int mid, int right, int[] temp) { // 利用两个指针,一左一右 int lp = left;// 左边子序列 int rp = mid + 1;// 右边子序列 int tp = 0;// 临时数组的指针 // 将左右两个序列的值按大小顺序存到临时数组中 while (lp <= mid && rp <= right) { if (arr[lp] <= arr[rp]) { temp[tp++] = arr[lp];// 存到临时数组 lp++;// 下一个值 } else { temp[tp++] = arr[rp]; rp++; } } // 已经存完了至少一边子序列,看看还有没有剩的数没加进临时数组 while (lp <= mid) { temp[tp++] = arr[lp++]; } while (rp <= right) { temp[tp++] = arr[rp++]; } // 将临时数组中排好序的数组拷贝回原数组 tp = 0; while (left <= right) { arr[left++] = temp[tp++]; } } 4. 斐波那契数列 斐波那契数列:斐波那契数列也蕴含着分治思想嘛——F(n) = F(n-1) + F(n-2)。自顶向下,大问题化为小问题;回溯求和,小问题的解合并为大问题的解。这里可以看一个例子——下楼梯问题或者同理的leetcode70.爬楼梯问题,本质上与斐波那契数列一样。 下楼梯问题 问题描述:有n阶楼梯要下,一次可以下一阶或两阶。问:下n阶楼梯有几种方案?注:该问题与爬楼梯问题一样,这里不再赘述。只是若用递归的自顶向下,时间复杂度爆表;更好的方法应该用迭代的自底向上,借助数组记录每一个层数对应的方法。 5. 整数划分 整数划分:再来看一道典例,整数划分。 三、总结一下经过上面这么多题的磨练,想必对分治的理解多多少少也有些概念了,这里再来稍微总结一波。 1.算法步骤由分治算法的思想,可以很容易想到利用递归过程来表示。分治在每一层递归上都有3个步骤(或2个) 分解:将原问题分解为若干规模较小,相互独立,与原问题形式相同的子问题; 解决:若子问题规模较小而容易被解决则直接解,否则继续分解为更小的子问题,直到容易解决; 合并:将已求解的各个子问题的解,逐步合并为原问题的解。 2.算法框架1234567891011121314151617Divide-and-Conquer(n) //n为问题规模{ if(n <= n0){ //n0为可解子问题的规模 /*解子问题*/ return ("子问题的解"); } for(int i = 0; i <= k; i++){ //分解为较小的k个子问题P1,P2,...,Pk /*分解原问题为更小的子问题Pi*/ yi=Divide-and-Conque(|Pi|); } T=MERGE(y1,y2,y3,...,yk);//合并子问题 return(T);} 参考 维基百科 《算法设计与分析》——吕国英 图解排序算法(四)之归并排序——博客园:图很棒👍👍","categories":[{"name":"Algorithm","slug":"Algorithm","permalink":"https://zy68.top/categories/Algorithm/"}],"tags":[{"name":"algorithm","slug":"algorithm","permalink":"https://zy68.top/tags/algorithm/"},{"name":"divide and conquer","slug":"divide-and-conquer","permalink":"https://zy68.top/tags/divide-and-conquer/"}]},{"title":"白丁的0和1","slug":"summaryof2020","date":"2021-01-01T07:36:35.000Z","updated":"2021-01-01T07:36:35.000Z","comments":true,"path":"2021/01/01/summaryof2020/","link":"","permalink":"https://zy68.top/2021/01/01/summaryof2020/","excerpt":" 嘿!2020年结束了,啪的一下,很快啊,又到了新旧交替的时刻 Happy New Year~~~","text":" 嘿!2020年结束了,啪的一下,很快啊,又到了新旧交替的时刻 Happy New Year~~~ 2020,是不平凡的一年。与我而言,可以说是启蒙之年、转折之年,从无到有,从0到1。 前言开始吐槽>>> 这个博客,真正算起,应该是在2019.12.30开始正式使用,中间波折不堪,也正似2020,也波折不堪。但正是这波折,让我收获良多。 2020年之前,虽然major in CS,但我们是所谓的大类招生,在大二下之前,很少接触到CS。并且大学里的CS课程,基本都是从很老很理论很古板的东西教起,对我这种入门的人来说,是真正的食之无味,弃之可惜。也真是如此,导致了CS思想启蒙的延迟。 思想启蒙,很重要。作为一个“土生土长”的人,对网络的利用和掌握程度很低,不像一些同龄人早已玩得飞起,足迹遍布各大平台,领略各大技术社区的风骚。到目前为止,我所了解到的强者,无一不是早早掌握了网络和平台,增长了自己的见闻,认识到自己真正需要的是什么,自己感兴趣的是什么,如何去追求、去获得自己需要的东西,从而去做得更好。而我的启蒙,不是始于所谓的计算机导论,也不是开始于什么计算机思维的结构,而是始于一个单页web app、hexo 和 technical community。 回首2020,是淡淡微光 2019没到年底的时候,计划参加一个比赛做一个单页app,虽然后面一如既往的被各种考试填满了,没有做出最后的成品,但是自己也是接触、经历了不少。从html、css到各种框架的修修改改,东拼西凑,学到了不少后来才知道可以是属于前端的的东西。在19年底的时候,开始接触和搭建hexo,也开始了更多的最大开源技术平台github之旅。当时只是搭起了博客,并没有使用起来,没错,又是有考试。直到学期开始放假,差不多也是就是2020的元旦,也就是一年前的今天,我才开始有空继续折腾我的博客。新事物,开启了后期连续一周+的啃文档。从二次html、css到git、yaml…… 总的来说,我的2020是从hexo开始的,我的思想启蒙也是从hexo开始的。 后来,逐渐接触到了更多的知识和技术,无论是课程内的还是课程外的,都有了新的认识。从markdown、二次html和css、二次git、scientifically surfing…… 到后来 http、Linux、项目、spring、springmvc、mybatis、springboot……。虽然有些课程在今年也开了,但无一不是我已经提前接触过了,而对于在课上学到了什么,现在看来不过是在浪费时间,即使是没提前学过也是如此。(/(ㄒoㄒ)/~~课内教的应用课技术很老、课程很low)除此之外,今年也拿到了一些校内荣誉,好毕业。最重要的是总算学到了CS核心课程:数据结构与算法、计算机组成原理、数据库、操作系统和计算机网络。不愧是是CS核心,收获巨大,奈何都是初印象,现在对它们的理解程度还不足,并没有能够深入掌握、打通体系,不过初识罢了。(:没错,31号刚跨年考完计网,所以今天才写的总结😁😁。 总而言之,立足自身,2020接触到了很多东西,也算是开了眼👀,总算是对CS体系和软件开发方向有了了解和认识。从现在的角度看,软件开发入门容易,计算机科学入门难;但高级软件开发需要计算机科学的理论支撑。因此,从学习的角度上来看,软件开发是反哺计算机科学的学习。(:√,我现在很想学CS,哪怕是计算机导论、计算思维的结构,真香。 但事情并不总是那么完美,2020也有可惜的地方。现在看来,首当其冲的应该是CET-6吧,但,从未准备过CET的人又怎能期望总裸考过呢?另外,今年接触的知识和技术,说多不多,说少不少,自己并没有真正的深入掌握和理解,并没有能够熟悉的运用自如,甚至完整点的项目都没有写完整。还有就是自己的学习方法和学习方式的问题,毕竟软开的学习和一般的理论学习有很大不同的地方,自己也是走了很多歧路,从不记笔记🧠记不住,不久便归还;到笔记平台的各种切换;再到自己学习方式的问题。归根到底,最可惜的,是我的思维启蒙得太迟,🧠也不咋好使。现在已经大三该爪巴去找实习找工作混饭吃了,然而相比于其他早启蒙同龄人,我只能说差距过大。同时,行业也是卷啊卷,现在的水平跟企业要求的水平真的是毕业即失业。 简单记录一下2020 2020时光线 折腾Hexo 折腾ecs 折腾javase 进入base并做了第一次技术分享——Hexo搭建 折腾ssm 制作投递简历 获评奖评优 比赛获奖 思想的升华 展望2021,愿与星光相伴 2021,希望是满天星的一年。 没错√,从启蒙到去被社会毒打,刚会走就得会飞。当前最大的任务,就是利用好刚刚启蒙的思想和所接触的工具。既然不选择考研,那就得好好准备春秋招。虽然,现在所剩的时间不多,自己的水平也未到预期的水平。因此,2021前期的计划就是扎实基础、打通体系。具体的计划还是小本本见吧😁😁 最后,2021最大的愿望,是能够感受一波技术人之乐,本白丁真正向往的,也是鸿儒之雅。 感恩 感恩是永恒的话题。感谢2020所有帮助过我的人👀🌹🌹 最后 未负2020,2021也会继续努力。愿所有的努力,都能得到应有的回报。 停泊,是为了更好的远航。加油,造梦人🚩🚩","categories":[{"name":"Experience","slug":"Experience","permalink":"https://zy68.top/categories/Experience/"}],"tags":[{"name":"annual summary","slug":"annual-summary","permalink":"https://zy68.top/tags/annual-summary/"}]},{"title":"(译)通过 Git 和 Angular 了解语义化提交信息","slug":"gitMessageStandard","date":"2020-12-23T06:28:14.000Z","updated":"2020-12-23T06:28:14.000Z","comments":true,"path":"2020/12/23/gitMessageStandard/","link":"","permalink":"https://zy68.top/2020/12/23/gitMessageStandard/","excerpt":"受传统提交规范和 Angular 约定的启发,让我们来解释语义化提交术语,并演示提交信息的实际示例。","text":"受传统提交规范和 Angular 约定的启发,让我们来解释语义化提交术语,并演示提交信息的实际示例。 目录动机提交信息的格式 头部(Header) 主体(Body) 尾部(Footer)常见类型 👷build 💚ci 📝docs ✨feat 🐛fix ⚡️perf ♻️refactor 🎨style ✅test好处 浏览历史变更记录 自动发布其它 使用 Emojis CLI 工具 检查器(Linter) VS Code 扩展总结 许多项目决定以某种约定方式来标准化它们的提交信息。这种做法并不是新出现的,但在最近几年中越来越多地得到了应用。而且很可能您已经在某些项目中遇到过这样的提交消息。 最早出现的规范之一来自与 AngularJS 项目。这个项目团队创建了一个详细的文档,其中指定了他们应该提交的目标和方式。这些提交约定非常流行,有些您可能通过 Karma 指南遇到过。但是,还有一些不同的约定,像 jQuery, JSHint, Ember, Angular(一个受AngularJS 提交规范启发的增强版约定),甚至更多: 可以清楚地看到上面各种各样的提交约定,这无疑构成了一个标准化官方规范的正当理由。约定式提交就是这样一种规范,它在实践中简化了 Angular 约定,并简化指出了提交消息规范的要点。 在本文中,我们将介绍“语义化提交”背后的概念,并使用 Git 和 Angular 的提交约定来演示具体的例子。声明一下,我们使用它们只是为了澄清概念——意味着版本控制工具和规范的选择取决于您。 那我们就开始吧!👨🏻🏫 动机让我们从定义开始: 语义化提交是遵循着特定约定并具有人类和机器可读含义的提交消息 这意味着,它只是提交消息的指导方针,因此: 提交消息是语义化的:因为它们被划分为有意义的类型,标识了提交(commit)的意图 提交消息是约定俗成的:对于开发者和工具,它们有着统一的结构和良好的类型标识 此外,当我们通常需要执行以下操作时,语义化提交可能会派上用场: 允许维护人员和贡献者轻松地浏览项目历史并理解提交的意图,同时通过提交消息类型忽略不重要的更改 强制提交信息的结构,鼓励有针对特定目的的小型提交 直接提交信息的主体,不必话大段话去解说 根据提交信息类型自动更新包版本号(Bump the package version) 自动生成日志(CHANGELOGs)和 release 说明 最后,语义化提交致力于实现更好的可读性和自动化,以及速度的提高。 话虽如此,我们中的一些人可能不接受这些消息约定,认为它们是可读的或提供信息的,这显然是有意义的。所以如果我们也不需要这些附带的好处,那在项目中执行这样的规范显然是没有意义的。 好了,是时候了解我们如何实际遵循这些约定了。 免责声明:从这一刻起,我们将引用 Angular 提交信息约定及其好处。 提交信息的格式Angular 规范要求根据以下结构来构造提交消息(Commit Message): 上图向我们说明了提交消息由三个部分组成 —— header、body 和 footer 。 HeaderHeader 是强制要求的一行,它简单地描述了更改的目的(最多100个字符)。更好的是,它本身由三部分组成: 类型(Type):标识更改类型的短前缀 范围(Scope):可选项,表明 Commit 影响的范围 主体(Subject):表示对实际更改的简明描述 实际上,就 Git 而言,它就是提交消息的首行: 1git commit -m "fix(core): remove deprecated and defunct wtf* apis" 我们插入单行消息,并用 : 分隔。当 fix和 core(受影响的包)分别是类型和范围时,我们将左分区假设称为“前缀”。另一方面,右分区显然构成了主体(Subject)。 简而言之,上述消息含义是:“本次更改通过移除不推荐使用(deprecated)和不存在的 wtf * api 修复了来自Core软件包的错误”。 Body主体(Body)是可选行,用于介绍本次更改背后的动机或仅描述一些更详细的信息。 让我们以上述的例子为例,并添加一个主体: 1git commit -m "fix(core): remove deprecated and defunct wtf* apis" -m "These apis have been deprecated in v8, so they should stick around till v10, but since they are defunct we are removing them early so that they don't take up payload size." 现在,我们在消息上附加了几句话,详细说明了此提交(Commit)目的。 请注意以下几点: 我们使用了多个-m来连接段落而不是简单的行 头部和主体应该用空白行分隔(根据这些段落,这显然是正确的) 注意:尽管我们可以使用其他方式将消息分成几行,但为了简单起见,我们将在下一个示例中继续使用多个 -m(展示了一个与shell无关的解决方案)。 Footer尾部(Footer)是可选行,其中提到了由于更改而产生的影响,例如:宣布重大更改、链接关闭已解决的问题(issues)、提及贡献者等等。 这是上述带有尾部(footer)的提交消息: 1git commit -m "fix(core): remove deprecated and defunct wtf* apis" -m "These apis have been deprecated in v8, so they should stick around till v10, but since they are defunct we are removing them early so that they don't take up payload size." -m "PR Close #33949" 在本例中,我们只是简单地添加了对相关拉请求(pull request)的引用,而没有添加其他内容。 最后,让我们查看完整的提交日志: 正如您可能会推断的,此提交实际上是 Angular 存储库中存在的。 常见类型除了定义提交消息格式外,Angular 的提交消息约定还指定了一个有用的类型列表,其中包含了各种各样的更改。 在开始之前,我们应该区分如下两种类型: 开发(Development):一种维护类型,它对变更进行分类,面向开发人员,这些变更实际上并不影响产品代码,而是影响内部的开发环境和工作流程(workflows) 生产(Production):一种增强类型,用于对仅影响产品代码的最终用户(end users)进行更改分类 现在,让我们介绍和解释这些类型。 注意:以下示例直接取自Angular存储库的提交日志。 👷构建构建类型 build(以前称为chore)用于识别与构建系统相关的开发更改(涉及脚本、配置或工具)和包依赖项(dependencies)。 例子: 💚cici 类型用于识别与持续集成和部署系统相关的开发更改——包括脚本、配置或工具。 例子: 📝文档docs文档类型用于识别与项目相关的文档更改——无论是针对最终用户的外部更改(对于库)还是针对开发人员的内部更改。 例子: ✨特性该feat类型用于标识生产环境相关的新的向后兼容能力(backward-compatible)或功能的更改。 例子: 🐛修复fix类型用于标识生产环境相关向后兼容(backward-compatible)的 bug 修复(bug fixes) 例子: ⚡️性能perf类型用于标识生产环境相关向后兼容的性能(performance)改进相关的产品更改。 例子: ♻️重构refactor类型用于识别与修改代码库相关的开发更改,这些更改既没有添加功能,也没有修复 bug —— 例如删除冗余代码、简化代码、重命名变量等等。 例子: 🎨风格style类型用于标识代码样式变动相关的开发更改,而不考虑其含义——例如缩进、分号、引号、结尾逗号等等。 例子: ✅测试test类型用于标识与测试相关的开发更改——例如重构现有测试或添加新测试。 例子: 好处现在我们已经熟悉了这些约定,让我们看看从中收获的两种好处。 浏览历史变更记录Git 为我们提供了浏览存储库提交历史的能力,所以我们就可以知道实际发生了什么,谁做了贡献等等。 让我们看看这些约定是如何简化我们对这些记录的浏览: 1git log --oneline --grep "^feat\\|^fix\\|^perf" 我们使用提交消息类型来过滤,因此只显示生产更改(所有以 feat、fix 或 perf开头的消息)。 另一个例子: 1git log --oneline --grep "^feat" | wc -l 我们只打印 feat 更改的总数。 上述的关键是提交消息格式非常结构化,这使得我们在扫描或过滤提交历史记录时能够有效地依赖于此格式。 即,更加迅速!💪🏻 自动发布提交消息格式对于自动化发布过程的步骤也很有用。 事实上,这可能是因为像Standard Version和Semantic Versioning这样的工具严格遵循语义化的版本规范和特定的信息提交约定(分别是传统的提交约定和 Angular 约定)。它们之间的主要区别在于 approach,但是让我们关注语义化发布(Semantic Release)。 因此,基于提交信息(特别是类型)——语义化发布(Semantic Release)能够给我们提供以下能力: 转到下一个语义化包版本(发生重大变更时-补丁发布、监控到新特性和性能的优化) 创建一个包含生产环境相关发布信息的 CHANGELOG 文件 为新的发布版本创建一个 Git tag 将release artifact发布(Publish)到 npm 注册中心 酷吧? 例如,Ionic 的angular-toolkit项目,集成了语义化发布来自动化发布过程(在此遵循 Angular 的提交约定): 正如我们所注意到的,发布的版本是基于 tag 和注释生成的——但重点是,这是自动完成的。🤖 其它为了充分利用语义化提交(semantic commit),让我们来看一些东西。 使用Emojis将表情符号附加到提交消息可能会进一步提高可读性,这样我们就可以在浏览提交历史时非常快速和容易地识别它们。💯 请参阅以下链接: gitmoji Commit Message Emoji 👋 CLI工具Commitizen 是一个通过命令行强制格式化提交信息的工具: 检查器(Linter)commitlint 是一个保证提交消息格式符合约定的工具: VSCode扩展如果你想使用一个可定制的VScode扩展,那么下面的内容可能会让你感兴趣: 总结我们今天介绍了“语义化提交”这个术语,并通过遵循 Angular 提交消息约定的具体例子,解释了这种消息的结构。 概括要点: 语义化提交是对开发人员和工具都有重要意义的提交信息方式,它们遵循特定的约定 语义化提交(以及基于它的工具)有助于提高可读性、速度和自动化 Conventional Commits 是一个详细描述语义提交的规范,遵循轻量级约定 Angular 的指导原则详细描述了遵循项目约定的语义化提交,包括: 包含 header、body 和 footer 的信息格式 与开发和生产相关的提交更改的类型 我们可以利用信息约定轻松浏览提交历史 我们可以从这些规范收获自动化发布流程(release process)的好处 最后,不管您是否决定采用这些约定,您可能会偶尔遇到它们,所以请记住上面的几点。😉 原文地址:Understanding Semantic Commit Messages Using Git and Angular 原文作者:Nitay Neeman 译文出自:Seven innovation base 译者:MrGo123 校对者:yeshan333","categories":[{"name":"git/github","slug":"git-github","permalink":"https://zy68.top/categories/git-github/"}],"tags":[{"name":"github","slug":"github","permalink":"https://zy68.top/tags/github/"},{"name":"git","slug":"git","permalink":"https://zy68.top/tags/git/"}]},{"title":"CI/CD && Github action自动部署Hexo","slug":"DeployHexoWithGithubAction","date":"2020-12-04T13:25:14.000Z","updated":"2020-12-04T13:25:14.000Z","comments":true,"path":"2020/12/04/DeployHexoWithGithubAction/","link":"","permalink":"https://zy68.top/2020/12/04/DeployHexoWithGithubAction/","excerpt":"使用Github Action实现hexo博客的自动部署,真香。","text":"使用Github Action实现hexo博客的自动部署,真香。 #本地博客的弊端: 写完博客需要generate、deploy; 需要保存博客源码,避免丢失; 当博客量大了之后,generate和deploy需要花费很多时间。 …… #使用Github Action实现hexo博客的自动部署的好处: 本地博客的弊端全解决; 实现CI/CD持续集成; 方便,即使更换电脑也能直接clone恢复以往操作。 更niubility? 减少了又是node.js、hexo版本等的问题,使用github action无需在本地下载按照软件。 总之,香🤭🤭 有个不好的地方——出错了调试错误不太方便。 因为时间的原因,暂不深入研究,暂时码住参考的大佬的文章👉👉Click me。 记录一下遇到的一点问题: 在一切都弄完之后,写博客发布(git push)之后,一直无法push成功,需要登录,且登录失败。这里应该有一个授权问题。solve:既然搭建成功,那么push就可以触发action进行渲染和发布,so,重新clone一份,重复操作,Σ(っ °Д °;)っ 问题解决!!!","categories":[{"name":"Mark","slug":"Mark","permalink":"https://zy68.top/categories/Mark/"}],"tags":[{"name":"blog","slug":"blog","permalink":"https://zy68.top/tags/blog/"},{"name":"CI/CD","slug":"CI-CD","permalink":"https://zy68.top/tags/CI-CD/"},{"name":"Github","slug":"Github","permalink":"https://zy68.top/tags/Github/"}]},{"title":"关于java的深浅拷贝","slug":"theObjectCopyofJava","date":"2020-11-29T06:57:14.000Z","updated":"2020-11-29T06:57:14.000Z","comments":true,"path":"2020/11/29/theObjectCopyofJava/","link":"","permalink":"https://zy68.top/2020/11/29/theObjectCopyofJava/","excerpt":"以前经常会看见java“深拷贝”和“浅拷贝”的字眼,不如现在从创建到拷贝来好好捋一捋,学习一下关于java深浅拷贝的知识。 浅拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用但不复制引用的对象。 深拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用的对象。","text":"以前经常会看见java“深拷贝”和“浅拷贝”的字眼,不如现在从创建到拷贝来好好捋一捋,学习一下关于java深浅拷贝的知识。 浅拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用但不复制引用的对象。 深拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用的对象。 插话:对于很久没有更新博客,谢一波罪。主要是最近在学的东西都更新在了笔记系统上,很久没有写博客作技术分享了。但博客是博客,笔记是笔记,一个是输出,一个是输入,无论如何不能把搭建博客的初心给忘了。🌝🌝待笔记逐渐完善后,我会分享链接至导航栏,敬请关注! 那我们现在开始吧~~👇👇 前言:在面向对象编程中,我们使用最频繁的是创建对象,而比较少用同样是得到一个新对象的对象拷贝的方式,即便需要拷贝,我们也可能是使用有参构造方法来新建一个对象。虽然如此,但是理解对象的拷贝对于理解java世界中对象的创建、参数的传递和复制以及对象在内存中的存在方式等方面有很大的帮助。 从我们最熟悉的创建去认识既熟悉又陌生的拷贝。 回顾:java创建对象的方式在java中创建对象有五种方式: 使用new关键字; 通过Class类的newInstance方法; 通过Constructor类的newInstance方法; 利用Clone方法; 通过反序列化实现。 一、理解对象的拷贝、浅拷贝、深拷贝拷贝:In object-oriented programming, object copying is creating a copy of an existing object, a unit of data in object-oriented programming. 在面向对象编程中,对象是面向对象编程中的数据单元,对象复制是创建现有对象的副本。——Wikipedia对拷贝的定义 个人觉得这个定义很纯粹、很真实。它抛弃了我们关于对象拷贝关于是否是引用还是值传递的相关忧虑,回归拷贝的本质——即复制。 但在java中,它并不那么纯粹。我们进行拷贝操作的目的是为了得到一个现有对象的副本,但由于java涉及内存引用的复杂的实际问题,它给我们提供了两种不同的拷贝方法来得到两种不同的副本————深拷贝和浅拷贝。 (:这里仅讨论深浅拷贝,暂时忽略延迟拷贝等 浅拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用地址。 释义:浅拷贝People对象得到一个副本CopyPeople,由于id是int型,属于基本类型,故CopyPeople直接复制一份。而info对象是Info型,复制其引用地址,最后共用一个Info对象。 深拷贝:以某个对象为基准创建新对象,将其所有非静态属性复制到新对象。如果属性是值类型(基本数据类型),则直接复制该字段;如果属性是引用类型,则复制引用的对象 。 释义:深拷贝People对象得到一个副本CopyPeople,由于id是int型,属于基本类型,故CopyPeople直接复制一份。而info对象是Info型,根据其引用新创建一个对象。 拟人独白 浅拷贝:CopyPerson:Person,我们一起用info吧?Person:好的!深拷贝:CopyPerson:Person,我们一起用info吧?Person:不行,我想自己用!CopyPerson:好吧,那我自己new一个好了。 究其差别:无非是拷贝的是引用对象时的不同——浅拷贝复制对象的引用,大家一起使用这个对象;而深拷贝直接复制一个新的对象不抢占原拷贝的对象,拥有自己专属的一个对象。 二、浅拷贝方法及实例利用Object类的clone方法可以实现拷贝。该方法是创建并返回调用类的一个拷贝。 这里利用原生的clone方法实现上述Person对象的浅拷贝。 Info Info类1234567891011121314151617181920public class Info { String name; int age; public String getName(){ return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public Info(String name, int age){ this.age=age; this.name=name; }} Person Person类123456789101112131415161718192021222324252627282930313233343536public class Person implements Cloneable { int id; // 引用对象 Info info; public Person(int id, String name, int age) { this.id = id; this.info = new Info(name, age); } @Override protected Object clone(){ // 浅拷贝 try { // 调用父类的clone方法 return super.clone(); } catch (CloneNotSupportedException e) { return null; } } // get、set方法 public int getId() { return id; } public Person() { } public void setId(int id) { this.id = id; } public Info getInfo() { return info; }} shadowCopy 1234567891011121314151617181920212223public class shadowCopy { public static void main(String[] args) { // 初始化一个对象 Person person = new Person(1, "Tom", 20); System.out.println("person原始数据:"+person.getId() + "-" + person.getInfo().getName() + "-" + person.getInfo().getAge()); // 拷贝一个对象 Person person2 = (Person) person.clone(); System.out.println("person2原始数据:"+person2.getId()+"-"+person2.getInfo().getName()+"-"+person2.getInfo().getAge()); System.out.println("判断person与person2对象是否一样:"+(person==person2));//不一样成功拷贝。 System.out.println("判断person对象的Info值与person2对象的Info值是否一样:"+(person.info==person2.info));//一样,引用地址相同 // 修改person2的值 person2.setId(2); person2.getInfo().setAge(60); person2.getInfo().setName("Amy"); //查改修改后的对象的信息 System.out.println("person数据:"+person.getId() + "-" + person.getInfo().getName() + "-" + person.getInfo().getAge()); System.out.println("person2修改后的数据:"+person2.getId()+"-"+person2.getInfo().getName()+"-"+person2.getInfo().getAge()); //可以看到除了person的id不同外,其他均相同,person的info值被迫与person2修改的一致。 }} 运行结果 123456person原始数据:1-Tom-20person2原始数据:1-Tom-20判断person与person2对象是否一样:false判断person对象的Info值与person2对象的Info值是否一样:trueperson数据:1-Amy-60person2修改后的数据:2-Amy-60 从输出结果可以看出,一开始拷贝的person2与person的属性值都是一样的,但他们其实是不同的对象(内存中),通过第一个false和修改id可以判断,两个对象的id是分开独立的。而在判断两个对象的Info值是true,以及修改person2的name和age后,person的name和age也跟着改变了,说明两个对象的Info指向同一个对象(内存中)。由此可见,对象的浅拷贝拷贝的是对象的引用地址。 三、深拷贝方法及实例深拷贝可以通过重写clone方法实现,也可以通过序列化实现。这里通过重写clone方法实现。 重写clone() 将上述的Person类的clone方法重写:12345@Overrideprotected Object clone(){ // 深拷贝 return new Person(this.id, this.getInfo().getName(), this.getInfo().getAge());} 运行结果 123456person原始数据:1-Tom-20person2原始数据:1-Tom-20判断person与person2对象是否一样:false判断person与person2对象的Info属性是否一样:falseperson数据:1-Tom-20person2修改后的数据:2-Amy-60 从输出结果可以看出,一开始拷贝的person2与person的属性值都是一样的,但他们是属于不同的对象(内存中),二者之间互不相影响。 四、小结本文分享了关于java深浅拷贝的相关知识,从平常的创建对象到拷贝,并深入认识了深浅拷贝的区别。浅拷贝,复制基本数据类型和对象的引用地址;深拷贝,复制基本数据类型和基于引用创建新的对象。最后通过Object方法的clone方法实例展示深浅拷贝。 认知扩展: java中只是值传递 引用拷贝拷贝的也是地址值。 参考文献 Object copying - Wikipedia Java到底是值传递还是引用传递?——知乎 Java的深拷贝和浅拷贝——YSOcean Java深拷贝和浅拷贝——掘金","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"git忽略文件gitignore","slug":"gitignore","date":"2020-09-25T03:12:26.000Z","updated":"2020-09-25T03:12:26.000Z","comments":true,"path":"2020/09/25/gitignore/","link":"","permalink":"https://zy68.top/2020/09/25/gitignore/","excerpt":"在每一次的开发中,一般总会有一些文件是我们不希望提交、也不希望出现在未跟踪的文件列表里的。这时,我们可以使用 .gitignore 文件,屏蔽或排除掉我们不想添加到git仓库中的文件,git已经跟踪的文件则不受影响。","text":"在每一次的开发中,一般总会有一些文件是我们不希望提交、也不希望出现在未跟踪的文件列表里的。这时,我们可以使用 .gitignore 文件,屏蔽或排除掉我们不想添加到git仓库中的文件,git已经跟踪的文件则不受影响。 实例了然1234567891011121314151617# 忽略所有的 .a 文件(星号*泛指)。*.a# 跟踪所有的 lib.a,即便在前面忽略了 .a 文件!lib.a# 只忽略当前目录下的 TODO 文件,而不忽略子目录下的(./subdir/TODO)/TODO# 忽略任何目录下名为 build 的文件夹build/# 忽略doc/当前目录下的所有.txt,但不忽略 doc/子目录下的.txt(如:doc/app/*.txt)doc/*.txt# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件doc/**/*.pdf gitignore文件中的每一行都指定一个模式。在决定是否忽略路径时,Git通常会gitignore按照从高到低的优先顺序检查来自多个源的模式(从一个优先级,最后一个匹配模式决定结果)。 编写规范文件 .gitignore 的格式规范如下: 所有空行或者以 # 开头的行都会被 Git 忽略,即注释。 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。 匹配模式可以以(/)开头防止递归。 匹配模式可以以(/)结尾指定目录。 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。 所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符; [abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(?)只匹配一个任意字符; 如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。 使用两个星号(**)表示匹配任意中间目录,比如 a/**/z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等。 常用gitignore模板因为忽略文件有极大的共性,因此有时候不需要我们自己编写.gitignore 文件,而可以直接使用模板。 github有一个仓库专门收集了.gitignore模板,一方面是便利,可以直接使用;另一方面是接入行业共识或标准。仓库:gitignore 参考文献 Git-ignore Document Pro Git github-忽略文件","categories":[{"name":"git/github","slug":"git-github","permalink":"https://zy68.top/categories/git-github/"}],"tags":[{"name":"github","slug":"github","permalink":"https://zy68.top/tags/github/"}]},{"title":"初识Spring","slug":"初识Spring","date":"2020-08-07T16:25:28.000Z","updated":"2020-08-07T16:25:28.000Z","comments":true,"path":"2020/08/07/初识Spring/","link":"","permalink":"https://zy68.top/2020/08/07/%E5%88%9D%E8%AF%86Spring/","excerpt":"Part1. Spring是什么?Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。——【IBM简介】","text":"Part1. Spring是什么?Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。——【IBM简介】 Part2. 简单认识IOCSpring的核心主要就是两个概念IOC和AOP,搞定这两个概念是进一步学习Spring开发的基础,这里先认识IOC。 IOC(Inversion of Control,控制反转),是一种开发思想,而DI(dependency injection,依赖注入)是这个思想在Spring中的具体实现。即我们只是学习DI来使用这个思想即可 平时我们需要使用一个对象时,都是new Object(),是人为的自己new一个对象。而使用Spring框架的IOC,是我们借助Spring容器通过DI注入达到new Object()的目的。 简单的说,就是我们把所有的Class都交给了Spring容器,这个容器就是一个存储仓库,当我们需要某个对象的时候,我们就找到这个仓库(Spring容器),问这个仓库要即可。划重点 这个对所需对象的操控的转变由我们人为的自己new变成了问Spring容器要,我们只是需要的时候问它要即可,不需要new的过程(这个过程由Spring容器来做)。这就是IOC控制反转。而问Spring容器要的方式,就是DI依赖注入。 从上述的简单IOC认识,我们可以从应用的角度来认识和学习————假设您现在要使用Spring。一开始就可以发现的问题有:1. 如何开始使用Spring? 2. 如何创建这个Spring仓库? 3. 如何使用这个Spring仓库来获取到我们想要的对象?围绕着这三个问题来简单学习一下Spring。 Part3. Spring环境搭建第一个问题,其实就是Spring框架“安装”的问题,这是开发的基础。 创建一个空的maven项目,在pom.xml中导入Spring框架包,例如下面的配置。导入了包之后,Spring框架就搭建好了。 1234567891011121314151617<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.3.RELEASE</version> </dependency> </dependencies> 到这里,第一个问题就解决了。现在可以开始正常的开发了。就是简单导个包??是的,简单认识。 Part4. Bean和创建Spring容器在上面我们说到,我们把所有的Class都交给了Spring容器,也就是第二个问题——如何创建这个Spring仓库? 到这里,我们引入Bean的概念。bean是什么? Bean是什么??Bean是一套约定或规范。具体的说Bean:1、所有属性为private2、提供默认构造方法3、提供getter和setter4、实现serializable接口 简单的说:由spring容器管理的对象都是Bean对象,也是普通的java对象。 码两篇文章【javaBean上】、【javaBean下】 这里我们不深究bean,就知道有这东西就行。我们需要做的是在maven文件架构下的resources目录下新建一个Spring XML配置文件(如下,文件名为Beans.xml)。在Spring中编辑一个Bean(如下) 1234567891011121314<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <!-- 定义一个bean id:bean的唯一标识,可以通过这个标识从容器中获取这个bean对象,可以自己随便定义; class:这个bean的类型,填入类的完整路径。 --> <bean id="helloWorld" class="demo1.Hello"/> <!-- 这里要知道bean有id和class属性即可 --></beans> 到这里,一个简单的Spring容器就创建好了,第二个问题解决。 Part5. 使用Spring容器第三个问题,如何通过Spring容器获取到我们想要的对象?这里可以使用理解为“模板”。 在新的类中使用: 1234//1.创建ApplicationContext容器,给容器指定需要加载的bean配置文件,它会自动从classpath中查找指定的XML配置文件。基于xml的容器有了,想要什么就get。ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//3.从容器中获取需要的beanHello he = context.getBean("helloWorld",Hello.class); 如注释所述,这里已经使用Spring容器获取了对象he了,其中出现的两个helloWorld要一一对应。SpringIOC部分大概就是这样子了吧。 Part6. 补充回顾这里对上述的流程做一个简单的补充和总结。 Part4 Bean的使用其实不用像规范那么严格; 这里展示的是装配Bean的一种方式——xml显式配置。另外两种方式是1通过注解配置和通过javaconfig配置。每一个方式都需要且值得深入学习。先讲其他配置的真的过分,虽然其他的最为推荐和常用。 Part.5 初始化一个Spring容器,根据装配Bean的方式的不同而有些许差异。首先对象肯定是容器ApplicationContext,差异在于new的对象不同。其他Spring容器的使用方式一致。 这些都是IOC要好好学习的东西。不同的教程教授的深度和广度不同。 Part7.关于学习Spring的一些tuxue感叹不得不说,自学,一如既往,真的是太难了。从寻找教学资源、到环境配置、到运行处处error、学到一半发现教程不合适or教程讲到的比较少-继续找教程、缺少足够的demo、触及知识盲区卡顿补漏、……、每一个都是你阻止前进的一大拦路虎。所以,找到一个适合自己的小白教程真的是太难了😭😭。 但是,这个过程经历下来,你也总会有收获,几乎每一步都会有,只是学习进度有一点慢而已,何止一点😡😡。这个收获是多方面的,比如在要学习的领域上,肯定有了进步;比如在踩坑的问题上,可能下一次就不会再踩了;比如你又学到了某些奇奇怪怪的知识;等。 最后,有一个经验,就是所有的这些“二手教程”,真的是二手。不同的作者有不同的水平、不同的理解、不同的侧重点等,所以写出来的教程也就各具特色,各领风骚。但是经过人家消化的东西,要么不够全、不够官方或者误解……。总之,多找几份教程,对比着看,对比着学,虽然慢,虽然难,虽然麻烦,但至少自己能够理解、学习得更全面。可能这就是学习吧,多花时间多努力吧。💪💪提升自学能力。 Why not official document ?? 功力不够,够也不需要什么入门教程了 这篇博文是Spring学习的从输入到输出的转变。是对前面学习的简单总结输出,如果您发现哪里问题or错误,还请指出,3Q🌹🌹,撒花~~~~★,°:.☆( ̄▽ ̄)/$:.°★ 。 相关推荐 了不起的IOC与DI 参考文献 《Spring实战》 【狂神说Java】Spring5最新完整教程IDEA版通俗易懂——首推 廖雪峰java教程 Java干货铺子 Spring Framework官方文档","categories":[{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/categories/Spring/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/tags/Spring/"}]},{"title":"关于UML","slug":"UML","date":"2020-06-30T06:50:40.000Z","updated":"2020-06-30T06:50:40.000Z","comments":true,"path":"2020/06/30/UML/","link":"","permalink":"https://zy68.top/2020/06/30/UML/","excerpt":"**Unified Modeling Language (UML)**又称统一建模语言或标准建模语言。 使用UML的面向对象图的方式来更明确、清晰的表达项目中的架构思想、项目结构、执行顺序等一些逻辑思维。 UML模型的三部分构成: 事物(Things):UML中最基本的构成要素,是具有代表性的成分的抽象; 关系(Relationships):关系把事物联系在一起; 图(Diagrams):图是事物和关系的可视化表示。","text":"**Unified Modeling Language (UML)**又称统一建模语言或标准建模语言。 使用UML的面向对象图的方式来更明确、清晰的表达项目中的架构思想、项目结构、执行顺序等一些逻辑思维。 UML模型的三部分构成: 事物(Things):UML中最基本的构成要素,是具有代表性的成分的抽象; 关系(Relationships):关系把事物联系在一起; 图(Diagrams):图是事物和关系的可视化表示。 UML构建模块事物事物是是实体抽象化的最终结果,是 UML 构建块最重要的组成部分,事物的分类如下: 结构事物 类 接口 协作 用例 组件 行为事物 交互 状态机 分组事物 包 注释事物 注释 关系关系是另一个最重要的构建块UML,它显示元素是如何彼此相关联,此关联描述的一个应用程序的功能,UML中定义了四种关系: 依赖关系 协作 泛化 实现 UML图UML 图的视觉效果是整个过程中最重要的部分。分为: 类图:类图描述系统所包含的类、类的内部结构及类之间的关系; 对象图:对象图是类图的一个具体实例; 用例图:用例图从用户的角度出发描述系统的功能、需求,展示系统外部的各类角色与系统内部的各种用例之间的关系; 顺序图:顺序图表示对象之间动态合作的关系; 协作图:协作图描述对象之间的协作关系; 活动图:活动图描述系统中各种活动的执行顺序。 状态图:状态图描述一类对象的所有可能的状态以及事件发生时状态的转移条件; 部署关系图:部署关系图定义系统中软硬件的物理体系结构; 组件图:组件图描述代码部件的物理结构以及各部件之间的依赖关系; 根据建模类型划分,可分为: 结构建模 类图 对象图 部署图 包图 复合结构图 组件图 行为建模 活动图 交互图 用例图 架构建模 包图 UML类图类图(Class Diagram)是面向对象系统建模中最常用和最重要的图,是定义其它图的基础。 类图主要是用来显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。 类图不仅用于可视化描述和记录系统的不同方面,也为构建可执行代码的软件应用程序。 类图描述一类的属性和操作,也对系统的约束。被广泛应用于类图的建模的面向对象的系统中,因为它们是唯一的,可以直接映射到面向对象的语言的 UML 图。 类图显示集合的类,接口,关联,协作和约束,它也被称为作为结构图。 一个类图的综合例子 In the example above: We can interpret the meaning of the above class diagram by reading through the points as following. Shape is an abstract class. It is shown in Italics. Shape is a superclass. Circle, Rectangle and Polygon are derived from Shape. In other words, a Circle is-a Shape. This is a generalization / inheritance relationship. There is an association between DialogBox and DataController. Shape is part-of Window. This is an aggregation relationship. Shape can exist without Window. Point is part-of Circle. This is a composition relationship. Point cannot exist without a Circle. Window is dependent on Event. However, Event is not dependent on Window. The attributes of Circle are radius and center. This is an entity class. The method names of Circle are area(), circum(), setCenter() and setRadius(). The parameter radius in Circle is an in parameter of type float. The method area() of class Circle returns a value of type double. The attributes and method names of Rectangle are hidden. Some other classes in the diagram also have their attributes and method names hidden. 参考文献W3CSchool——UML 教程 What is class diagram-visual Paradigm","categories":[{"name":"Design Patterns","slug":"Design-Patterns","permalink":"https://zy68.top/categories/Design-Patterns/"}],"tags":[{"name":"UML","slug":"UML","permalink":"https://zy68.top/tags/UML/"}]},{"title":"(码)Linux C编程一站式学习","slug":"Linux C编程一站式学习","date":"2020-06-23T10:13:40.000Z","updated":"2020-06-23T10:13:40.000Z","comments":true,"path":"2020/06/23/Linux C编程一站式学习/","link":"","permalink":"https://zy68.top/2020/06/23/Linux%20C%E7%BC%96%E7%A8%8B%E4%B8%80%E7%AB%99%E5%BC%8F%E5%AD%A6%E4%B9%A0/","excerpt":"码一本Linux C编程的书——《Linux C编程一站式学习》。","text":"码一本Linux C编程的书——《Linux C编程一站式学习》。 特点 不是孤立地讲C语言,而是和编译原理、操作系统、计算机体系结构结合起来讲。或者说,本书的内容只是以C语言为载体,真正讲的是计算机的原理和程序的原理。 强调基本概念和基本原理,在编排顺序上非常重视概念之间的依赖关系,每次引入一个新的概念,只依赖于前面章节已经讲过的概念,而绝不会依赖后面章节要讲的概念。有些地方为了叙述得完整,也会引用后面要讲的内容,比如说“有关XX我们到XX章再仔细讲解”,凡是这种引用都不是必要的依赖,可以当它不存在,只管继续往下看就行了。 尽量做到每个知识点直到要用的时候才引入。过早引入一个知识点,讲完了又不用它,读者很快就会遗忘,这是不符合认知规律的。 前备要求 一本从零基础开始学习编程的书,不要求读者有任何编程经验,但读者至少需要具备以下素质: 熟悉Linux系统的基本操作。如果不具备这一点,请先参考其它教材学习Linux系统的基本操作,熟练之后再学习本书,《鸟哥的Linux私房菜》据说是Linux系统管理和应用方面比较好的一本书。但学习本书并不需要会很多系统管理技术,只要会用基本命令,会自己安装系统和软件包就足够了。 具有高中毕业的数学水平。本书会用到高中的数学知识,事实上,如果不具有高中毕业的数学水平,也不必考虑做程序员了。但并不是说只要具有高中毕业的数学水平就足够做程序员了,只能说看这本书应该没有问题,数学是程序员最重要的修养,计算机科学其实就是数学的一个分支,如果你的数学功底很差,日后还需恶补一下。 具有高中毕业的英文水平。理由同上。 对计算机的原理和本质深感兴趣,不是为就业而学习,不是为拿高薪而学习,而是真的感兴趣,想把一切来龙去脉搞得清清楚楚而学习。 勤于思考。本书尽最大努力理清概念之间的依赖关系,力求一站式学习,读者不需要为了找一个概念的定义去翻其它书,也不需要为了搞清楚一个概念在本书中前后一通乱翻,只需从前到后按顺序学习即可。但一站式学习并不等于傻瓜式学习,有些章节有一定的难度,需要积极思考才能领会。本书可以替你节省时间,但不能替你思考,不要指望像看小说一样走马观花看一遍就能学会。","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"},{"name":"C","slug":"C","permalink":"https://zy68.top/tags/C/"}]},{"title":"wsl中windows与子系统的交互","slug":"wsl中windows与子系统的交互","date":"2020-06-20T00:08:54.000Z","updated":"2020-06-20T00:08:54.000Z","comments":true,"path":"2020/06/20/wsl中windows与子系统的交互/","link":"","permalink":"https://zy68.top/2020/06/20/wsl%E4%B8%ADwindows%E4%B8%8E%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E4%BA%A4%E4%BA%92/","excerpt":"当我们要在wsl下对Windows系统操作时,需要使用 /mnt/…… 命令。为什么?? /mnt 与Windows有什么关系?? 在Linux系统的文件根目录下,有名为 /mnt 的目录。CD2 ROM、软盘这类可移动介质的挂载点目录一般放在/ mnt 目录下, 通常有cdrom和floppy 两个子目录, 分别是光盘和软盘的挂载安装点。通过挂载光盘或软盘后, 对应进入/ mnt/ cdrom 或/ mnt/ floppy 子目录, 就可访问光盘或软盘中的内容。注意挂载点目录中不要有任何文件, 否则将无法正常挂载。————《Linux服务器的配置与管理-冯昊》 因此,Windows子系统下的Linux系统就是通过 /mnt 目录来连通与Windows的联系。我们可以通过 /mnt 访问Windows下的各个磁盘,如同在Windows下一样。","text":"当我们要在wsl下对Windows系统操作时,需要使用 /mnt/…… 命令。为什么?? /mnt 与Windows有什么关系?? 在Linux系统的文件根目录下,有名为 /mnt 的目录。CD2 ROM、软盘这类可移动介质的挂载点目录一般放在/ mnt 目录下, 通常有cdrom和floppy 两个子目录, 分别是光盘和软盘的挂载安装点。通过挂载光盘或软盘后, 对应进入/ mnt/ cdrom 或/ mnt/ floppy 子目录, 就可访问光盘或软盘中的内容。注意挂载点目录中不要有任何文件, 否则将无法正常挂载。————《Linux服务器的配置与管理-冯昊》 因此,Windows子系统下的Linux系统就是通过 /mnt 目录来连通与Windows的联系。我们可以通过 /mnt 访问Windows下的各个磁盘,如同在Windows下一样。","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"}]},{"title":"Shell","slug":"Shell","date":"2020-06-17T08:58:24.000Z","updated":"2020-06-17T08:58:24.000Z","comments":true,"path":"2020/06/17/Shell/","link":"","permalink":"https://zy68.top/2020/06/17/Shell/","excerpt":"shell简介Shell 诞生于 Unix,是与 Unix/Linux 交互的工具。Shell虽然是Unix的第一个脚本语言,但它是相当优秀的。它结合了延展性与效率,持续保有独具的特色,并不断的被改良,使它多年来能与那些花招很多的脚本语言保持抗衡。 Shell需要依赖其他程序才能完成大部分的工作,这或许是它的缺陷,但它不容置疑的长处是:简洁的脚本语言标记方式,而且比C语言编写的程序执行更快、更有效率。 Shell 是将内核、程序和用户连接了起来的软件。 Shell 本身支持的命令并不多,但是它可以调用其他的程序,每个程序就是一个命令,这使得 Shell 命令的数量可以无限扩展,其结果就是 Shell 的功能非常强大。 shell是一种脚本语言,因此需要编译成二进制的形式才可以被计算机执行。 几种常见的Shell:sh、bash、csh、tcsh、ash。其中默认的是bash,使用 echo $SHELL 查看默认的shell。 SHELL 是 Linux 系统中的环境变量,它指明了当前使用的 Shell 程序的位置,也就是使用的哪个 Shell。","text":"shell简介Shell 诞生于 Unix,是与 Unix/Linux 交互的工具。Shell虽然是Unix的第一个脚本语言,但它是相当优秀的。它结合了延展性与效率,持续保有独具的特色,并不断的被改良,使它多年来能与那些花招很多的脚本语言保持抗衡。 Shell需要依赖其他程序才能完成大部分的工作,这或许是它的缺陷,但它不容置疑的长处是:简洁的脚本语言标记方式,而且比C语言编写的程序执行更快、更有效率。 Shell 是将内核、程序和用户连接了起来的软件。 Shell 本身支持的命令并不多,但是它可以调用其他的程序,每个程序就是一个命令,这使得 Shell 命令的数量可以无限扩展,其结果就是 Shell 的功能非常强大。 shell是一种脚本语言,因此需要编译成二进制的形式才可以被计算机执行。 几种常见的Shell:sh、bash、csh、tcsh、ash。其中默认的是bash,使用 echo $SHELL 查看默认的shell。 SHELL 是 Linux 系统中的环境变量,它指明了当前使用的 Shell 程序的位置,也就是使用的哪个 Shell。 对于普通用户,Base shell 默认的提示符是美元符号$;对于超级用户(root 用户),Bash Shell 默认的提示符是井号# echo 是一个输出命令,可以用来输出数字、变量、字符串等; bash shell中变量都是字符串类型,使用变量在变量名前加 $,变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界 单双引号的区别:单引号’ ‘包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。双引号” “包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。 使用 $(变量名or内容) 读取变量的值or内容。 声明只读变量 readonly 变量名,删除变量 unset 变量名 变量类型运行shell时,会同时存在三种变量: 局部变量局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 环境变量所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。 shell变量shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行 特殊变量列表| 变量 | 含义 || :—: | :——————————————————————————————: || $0 | 当前脚本的文件名 || $n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 || $# | 传递给脚本或函数的参数个数。 || $* | 传递给脚本或函数的所有参数。 || $@ | 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。 || $? | 上个命令的退出状态(上一个命令执行后的返回结果),或函数的返回值。 || $$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 | 命令行参数 命令行参数运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。 请看下面的脚本: 1234567#!/bin/bashecho "File Name: $0"echo "First Parameter : $1"echo "First Parameter : $2"echo "Quoted Values: $@"echo "Quoted Values: $*"echo "Total Number of Parameters : $#" 运行结果: 1234567$./test.sh Zara AliFile Name : ./test.shFirst Parameter : ZaraSecond Parameter : AliQuoted Values: Zara AliQuoted Values: Zara AliTotal Number of Parameters : 2 注:$* 和 $@ 的区别 转义字符 含义 \\ 反斜杠 \\a 警报,响铃 \\b 退格(删除键) \\f 换页(FF),将当前位置移到下页开头 \\n 换行 \\r 回车 \\t 水平制表符(tab键) \\v 垂直制表符 可以使用 echo 命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。 命令替换命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。命令替换的语法:command 将命令执行结果保存在变量中: 1234567#!/bin/bashDATE=`date`echo "Date is $DATE"USERS=`who | wc -l`echo "Logged in user are $USERS"UP=`date ; uptime`echo "Uptime is $UP" 运行结果: 1234Date is Thu Jul 2 03:59:57 MST 2009Logged in user are 1Uptime is Thu Jul 2 03:59:57 MST 200903:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15 变量替换变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值 可以使用的变量替换形式:| 形式 | 说明 || :————-: | :—————————————————————————————————————————————————————: || ${var} | 变量本来的值 || ${var:-word} | 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 || ${var:=word} | 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 || ${var:?message} | 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。 || ${var:+word} | 如果变量 var 被定义,那么返回 word,但不改变 var 的值。 | shell运算符原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。 算数运算符 运算符 说明 举例 + 加法 expr $a + $b 结果为 30。 - 减法 expr $a - $b 结果为 10。 * 乘法 expr $a \\* $b 结果为 200。 / 除法 expr $b / $a 结果为 2。 % 取余 expr $b % $a 结果为 0。 = 赋值 a=$b 将把变量 b 的值赋给 a。 == 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。 != 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。 关系运算符列表 运算符 说明 举例 -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。 -ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。 -ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。 -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。 布尔运算符列表 运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。 -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 字符串运算符列表 运算符 说明 举例 = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。 -n 检测字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。 str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。 文件测试运算符 操作符 说明 举例 -b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。 -c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。 -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。 -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。 -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。 -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。 -p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。 -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。 -r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。 -w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。 -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。 -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。 -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。 字符串 除了单双引号的区别外,还有:拼接字符串 1234your_name="qinjx"greeting="hello, "$your_name" !"greeting_1="hello, ${your_name} !"echo $greeting $greeting_1 获取字符串长度 12string="abcd"echo ${#string} #输出 4 提取子字符串 12string="alibaba is a great company"echo ${string:1:4} #输出liba 查找子字符串 12string="alibaba is a great company"echo `expr index "$string" is` 数组bash支持一维数组(不支持多维数组),并且没有限定数组的大小。 定义数组123456789101112array_name=(value0 value1 value2 value3)# 或者array_name=(value0value1value2value3)# 单独定义array_name[0]=value0array_name[1]=value1array_name[2]=value2 使用数组1234valuen=${array_name[2]}# 使用@ 或 * 可以获取数组中的所有元素,例如:${array_name[*]}${array_name[@]} 获取数组长度123456# 取得数组元素的个数length=${#array_name[@]}# 或者length=${#array_name[*]}# 取得数组单个元素的长度lengthn=${#array_name[n]} 输出语句echo和printf(C语言中的printf,只是没有括号,其他不变),printf是echo的升级版。 条件语句123456789101112131415#!/bin/sha=10b=20if [ $a == $b ]then echo "a is equal to b"elif [ $a -gt $b ]then echo "a is greater than b"elif [ $a -lt $b ]then echo "a is less than b"else echo "None of the condition met"fi test命令shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。 数值测试 12345678num1=100num2=100if test $[num1] -eq $[num2]then echo 'The two numbers are equal!'else echo 'The two numbers are not equal!' # 输出结果fi 比较运算符它不香吗?? 字符串测试 12345678num1=100num2=100if test num1=num2then echo 'The two strings are equal!'else echo 'The two strings are not equal!'fi 文件测试 1234567cd /binif test -e ./bashthen echo 'The file already exists!'else echo 'The file does not exists!'fi case命令123456789101112131415echo 'Input a number between 1 to 4'echo 'Your number is:\\c'read aNumcase $aNum in 1) echo 'You select 1' ;; 2) echo 'You select 2' ;; 3) echo 'You select 3' ;; 4) echo 'You select 4' ;; *) echo 'You do not select a number between 1 to 4' ;;esac 取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。 取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。 for循环格式 1234567for 变量 in 列表do command1 command2 ... commandNdone 列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。 in 列表是可选的,如果不用它,for 循环使用命令行的位置参数。 显示主目录下以 .bash 开头的文件: 12345#!/bin/bashfor FILE in $HOME/.bash*do echo $FILEdone 运行结果: 1234/root/.bash_history/root/.bash_logout/root/.bash_profile/root/.bashrc 参考文献","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"},{"name":"shell","slug":"shell","permalink":"https://zy68.top/tags/shell/"}]},{"title":"javaSE-反射","slug":"javaSE-反射","date":"2020-06-12T14:12:48.000Z","updated":"2020-06-12T14:12:48.000Z","comments":true,"path":"2020/06/12/javaSE-反射/","link":"","permalink":"https://zy68.top/2020/06/12/javaSE-%E5%8F%8D%E5%B0%84/","excerpt":"认识反射和Class类 + 访问对象的字段 + 调用对象的方法 + 调用构造函数 + 获取继承关系 + 动态代理","text":"认识反射和Class类 + 访问对象的字段 + 调用对象的方法 + 调用构造函数 + 获取继承关系 + 动态代理 认识反射和Class类反射(Reflection),Java的反射是指程序在运行期可以拿到一个对象的所有信息。 JVM为每个加载的 class及 interface创建了对应的 Class实例来保存 class及 interface的所有信息;这里的 Class类型是一个名叫 Class的 class。 获取一个 class对应的 Class实例后,就可以获取该 class的所有信息; 通过 Class 实例获取 class 信息的方法称为反射(Reflection); JVM总是动态加载class,可以在运行期根据条件来控制加载class。 访问对象的字段Java的反射API提供的Field类封装了字段的所有信息: 通过Class实例的方法可以获取Field实例: Field getField(name):根据字段名获取某个public的field(包括父类) Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类) Field[] getFields():获取所有public的field(包括父类) Field[] getDeclaredFields():获取当前类的所有field(不包括父类) 通过Field实例可以获取字段信息: getName():返回字段名称,例如,”name”; getType():返回字段类型,也是一个Class实例,例如,String.class; getModifiers():返回字段的修饰符,它是一个int,不同的bit表示不同的含义。 123456789101112131415161718192021222324252627282930313233343536import java.lang.reflect.Field;public class Main { public static void main(String[] args) throws Exception{// 拿到实例的字段 Class std= Student.class; System.out.println(std.getField("score")); System.out.println(std.getField("name")); System.out.println(std.getDeclaredField("grade"));// 拿到实例字段对应的值。 Object p= new Student(45); Class c=p.getClass(); Field f=c.getDeclaredField("score"); Object value =f.get(p); System.out.println(value);// 修改字段值 f.set(p, 50); Student q=(Student)p;//p为Object型,强制转为Student型。 System.out.println(q.getScore()); // "Xiao Hong" }}class Student extends Person{ public int score; private int grade; public Student(int score){ this.score=score; } int getScore(){ return score; }}class Person{ public String name;} 运行结果 12345public int Student.scorepublic java.lang.String Person.nameprivate int Student.grade4550 通过Field实例可以读取或设置某个对象的字段,如果存在访问限制,要首先调用setAccessible(true)来访问非public字段。 通过反射读写字段是一种非常规方法,它会破坏对象的封装。因此多用于底层设计。 调用对象的方法java的反射API提供的 Method对象封装了方法的所有信息: 通过 Class实例的方法可以获取 Method实例: Method getMethod(name, Class…):获取某个public的Method(包括父类) Method getDeclaredMethod(name, Class…):获取当前类的某个Method(不包括父类) Method[] getMethods():获取所有public的Method(包括父类) Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类) 通过 Method 实例可以获取方法信息: getName():返回方法名称,例如:”getScore”; getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class; getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class}; getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。 通过 Method 实例可以调用某个对象的方法:Object invoke(Object instance, Object... parameters); 通过设置 setAccessible(true)来访问非public方法; 通过反射调用方法时,仍然遵循多态原则。 调用构造函数通过Class实例获取Constructor的方法如下: getConstructor(Class…):获取某个public的Constructor; getDeclaredConstructor(Class…):获取某个Constructor; getConstructors():获取所有public的Constructor; getDeclaredConstructors():获取所有Constructor。 123456789101112131415public class Main { public static void main(String[] args) throws Exception { // 获取构造方法Integer(int): Constructor cons1 = Integer.class.getConstructor(int.class); // 调用构造方法: Integer n1 = (Integer) cons1.newInstance(123); System.out.println(n1); // 获取构造方法Integer(String) Constructor cons2 = Integer.class.getConstructor(String.class); Integer n2 = (Integer) cons2.newInstance("456"); System.out.println(n2); }} 获取继承关系通过Class对象可以获取继承关系: Class getSuperclass():获取父类类型; Class[] getInterfaces():获取当前类实现的所有接口。 通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。 动态代理Java标准库提供了动态代理功能,允许在运行期动态创建一个接口的实例; 动态代理是通过Proxy创建代理对象,然后将接口方法“代理”给InvocationHandler完成的。 参考廖雪峰的Java教程——反射","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"Gcc编译和Gdb调试","slug":"Gcc编译C语言","date":"2020-06-10T12:13:40.000Z","updated":"2020-06-10T12:13:40.000Z","comments":true,"path":"2020/06/10/Gcc编译C语言/","link":"","permalink":"https://zy68.top/2020/06/10/Gcc%E7%BC%96%E8%AF%91C%E8%AF%AD%E8%A8%80/","excerpt":"gccgcc简介GNU编译器套装(英语:GNU Compiler Collection,缩写为GCC),指一套编程语言编译器,以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,也是GNU工具链的主要组成部分之一。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。可处理C、C++、Fortran、Pascal、Objective-C、Java、Ada,Go等其他语言。——Wiki","text":"gccgcc简介GNU编译器套装(英语:GNU Compiler Collection,缩写为GCC),指一套编程语言编译器,以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,也是GNU工具链的主要组成部分之一。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。可处理C、C++、Fortran、Pascal、Objective-C、Java、Ada,Go等其他语言。——Wiki gcc编译流程GCC 编译器在编译一个C语言程序时需要经过以下 4 步: (-E)将C语言源程序预处理,生成.i文件。 (-S)预处理后的.i文件编译成为汇编语言,生成.s文件。 (-c)将汇编语言文件经过汇编,生成目标文件.o文件。 将各个模块的.o文件链接起来生成一个可执行程序文件。 注: .i文件、.s文件、.o文件可以认为是中间文件或临时文件,如果使用 GCC 一次性完成C语言程序的编译,那么只能看到最终的可执行文件。中间文件被删除。 每一个步骤生产的文件都可以直接从.c 文件执行对应得命令后直接生成,不必按顺序。(到底还是按顺序,只是系统把它们删了) gcc编译选项 选项的意义 -c 编译、汇编指定的源文件,但是不进行链接 -S 编译指定的源文件,但是不进行汇编 -E 预处理指定的源文件,不进行编译 -o [file1] [file2] 将文件 file2 编译成可执行文件 file1 -I directory 指定 include 包含文件的搜索目录 -g 生成调试信息,该程序可以被调试器调试 直接编译:gcc hello.c -o hello,生成hello可执行文件可直接运行。 gdbgdb简介GNU调试器(英语:GNU Debugger,缩写:GDB),是GNU软件系统中的标准调试器,此外GDB也是个具有移携性的调试器,经过移携需求的调修与重新编译,如今许多的类UNIX操作系统上都可以使用GDB,而现有GDB所能支持调试的编程语言有C、C++、Pascal以及FORTRAN。——Wiki 在用gcc编译时要加上-g选项,生成的可执行文件才能用gdb进行源码级调试 单步执行和跟踪1234567891011121314151617$ gcc -g main.c -o main$ gdb main # 进入gdb调试$ (gdb) list 1 # list命令从第一行开始列出源代码,单纯list或l列出10行$ (gdb) next # next或n——单条执行指令。next 3 运行到当前位置的后三行$ (gdb) start #程序再次启动调试$ (gdb) step #step或s——进入函数内部跟踪执行$ (gdb) backtrace #backtrace或bt查看函数调用的栈帧$ (gdb) frame 1 # 选择1号栈帧$ (gdb) info locals # info或i查看当前栈帧中变量的值$ (gdb) print value # print或p——打印变量value的值,变量也可以是表达式$ (gdb) finish # 让当前程序一直运行到当前函数返回为止$ (gdb) set var sum=0 # 在gdb中给变量sum设值$ (gdb) run # run或r——直接运行程序$ (gdb) quit # quit或q退出gdb -g选项的作用是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。 gdb提供了一个很方便的功能,在提示符下直接敲回车表示重复上一条命令。 参考文献 C语言中文网-GCC","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"},{"name":"C","slug":"C","permalink":"https://zy68.top/tags/C/"}]},{"title":"Linux进程前后台切换","slug":"Linux前后台切换","date":"2020-06-10T11:08:54.000Z","updated":"2020-06-10T11:08:54.000Z","comments":true,"path":"2020/06/10/Linux前后台切换/","link":"","permalink":"https://zy68.top/2020/06/10/Linux%E5%89%8D%E5%90%8E%E5%8F%B0%E5%88%87%E6%8D%A2/","excerpt":"在基础篇 Linux中有说到进程的一点命令:ps、top、kill等,但是跟这次的前后台有点不一样,可以操作学习一下。 认识Linux前后台进程前后台,顾名思义。前台进程:运行在终端(跑在脸上)的,可以直接操控,终端关闭,进程也停止。后台进程:也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要终端的交互。进程的主要战场。","text":"在基础篇 Linux中有说到进程的一点命令:ps、top、kill等,但是跟这次的前后台有点不一样,可以操作学习一下。 认识Linux前后台进程前后台,顾名思义。前台进程:运行在终端(跑在脸上)的,可以直接操控,终端关闭,进程也停止。后台进程:也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要终端的交互。进程的主要战场。 场景实战 下载东西,执行命令后那进度条在脸上哗哗的过,但是还要用终端啊。那咋办? 答:在敲下载命令后,在尾部加 & 符号,eg:sudo apt install gdb &,这一下载进程就会切换到后台进程下载。 如果执行了呢? 答: 使用 jobs 查看后台有哪些进程以及它的jobsnum,如下一个停止了的进程,[1]的1就是jobsnum,使用 fg 1将其调到前台。若只有一个进程,直接fg即可。 12jobs [1]+ Stopped sudo apt install gdb 如果想结束进程呢? 答:jobs -l 查看进程pid,得到pid编号,然后 kill 编号,done。 其他 ctrl+z:把在前台的进程放到后台并暂停。bg+jobsnum:启动jobsnum进程。ctrl+c:在前台使用此命令,取消掉当前进程。 参考 LINUX 杀死、暂停、继续、后台运行进程 Linux进程前后台切换 Linux前后台进程切换","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"}]},{"title":"Linux更换下载源镜像","slug":"Linux更换下载源镜像","date":"2020-06-09T11:57:54.000Z","updated":"2020-06-09T11:57:54.000Z","comments":true,"path":"2020/06/09/Linux更换下载源镜像/","link":"","permalink":"https://zy68.top/2020/06/09/Linux%E6%9B%B4%E6%8D%A2%E4%B8%8B%E8%BD%BD%E6%BA%90%E9%95%9C%E5%83%8F/","excerpt":"更换Ubuntu的下载源镜像,回归正常速度!!这里推阿里云的镜像 用lsb_release -a 查看自己的Linux版本信息。 用cp /etc/apt/sources.list /etc/apt/sources.list.back 备份 sources.list 文件。要是不保存也行 到镜像网里找到自己对应的Linux系统和版本。那里有教,复制对应的配置信息。 sudo权限编辑上述的文件——sources.list,把里面的内容全替换为复制下来的信息。 更新原有配置:sudo apt-get update,sudo依旧。 搞定。","text":"更换Ubuntu的下载源镜像,回归正常速度!!这里推阿里云的镜像 用lsb_release -a 查看自己的Linux版本信息。 用cp /etc/apt/sources.list /etc/apt/sources.list.back 备份 sources.list 文件。要是不保存也行 到镜像网里找到自己对应的Linux系统和版本。那里有教,复制对应的配置信息。 sudo权限编辑上述的文件——sources.list,把里面的内容全替换为复制下来的信息。 更新原有配置:sudo apt-get update,sudo依旧。 搞定。","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"}]},{"title":"重装系统+环境恢复简记","slug":"A-Rebuild-Record","date":"2020-06-03T09:00:42.000Z","updated":"2020-06-03T09:00:42.000Z","comments":true,"path":"2020/06/03/A-Rebuild-Record/","link":"","permalink":"https://zy68.top/2020/06/03/A-Rebuild-Record/","excerpt":"重装Windows + 重装后系统环境的恢复(including office、Hexo and so on)","text":"重装Windows + 重装后系统环境的恢复(including office、Hexo and so on) 重装windows系统的原因:版本太低、不支持新的terminal、office散架、……全程有 ShanSan 指导,丝毫不慌。just do it!!!😄😄😄 一、重装Windows系统此次重装系统使用的是U盘PE辅助重装。 大概步骤 制作启动盘:微PE工具箱——取一个内存大于8G的U盘用来制作工具盘,下载在本地后启动安装至U盘。 下载镜像:镜像——这里随便!推荐良心的【MSDN】。用复制链接可以用迅雷下。–慢就开会员咯–注:1.镜像可以下至上述制作好的微PE启动盘中;2.也可存至另外一个U盘中。 选择进入刷机系统 or BIOS:摁下开机键后狂戳某个键,华硕是 esc进入刷机系统,F2进入BIOS,刷机系统下选择UEFI(选择显示与U盘信息相关的选项);如果是BIOS要修改优先启动选项(boot)。 进入PE系统:使用分盘工具分盘(也可安装系统时再分),找到Windows镜像(若是另外一个U盘则插入到USB接口中),镜像装载。进入Windows安装流程。 这里省略…… finish Windows激活:支持正版。 enjoy yourself!!! 详情参考: Docs——刷机教程 B站video——官方ISO直装与PE两种方法教程 ShanSan——collection 二、office安装windows自带的office Microsoft不给镜像,要到官网登录-绑卡-支付……,具体我也不知道,给钱才能装,支持正版ヾ( ̄▽ ̄)ByeBye 正篇~~~ 依旧是上述MSDN下载office镜像(依旧有镜像流出),解压安装一套走,KMS激活使用(支持正版),enjoy yourself~~。 hexo博客恢复前备 首先环境依旧:Git、Node.js、hexo保存的时候,保存一部分文件:_config.yml、package.json、source、scaffold、themes。够了,其他的说拜拜。 关键 hexo搬迁:直接在Hexo目录下Bash,然后npm install(npm 根据hexo下保留有的package.json安装所需的包),然后npx hexo g,再然后npx hexo s,即可。 三、vscode漏装补全安装vscode时,有些功能如果没勾到,可以直接运行原安装包,再次安装,勾上自己想装的部分功能即可。 四、wsl2安装没太多要说的,看官网 适用于 Linux 的 Windows 子系统安装指南 (Windows 10),真香啊~~~ 五、壁纸推荐如果您喜欢动态壁纸的话,steam那个啥……wall来着,不记得。静态壁纸——彼岸图网可以免费获取4K的壁纸,登录即可,每天可以免费获取一张,还不够嘛?不够再多几个账号注册??什么?还不够?每天领double壁纸。 六、说在最后ShanSan🐂🍺 如果有时间,那就多动手折腾吧。别怂,大不了…………重装。📴📴@ShanSan","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[{"name":"rebuild","slug":"rebuild","permalink":"https://zy68.top/tags/rebuild/"}]},{"title":"Computer English","slug":"Computer-English","date":"2020-06-03T08:58:09.000Z","updated":"2020-06-03T08:58:09.000Z","comments":true,"path":"2020/06/03/Computer-English/","link":"","permalink":"https://zy68.top/2020/06/03/Computer-English/","excerpt":"Some computer term in English and its paraphrase. English makes you go further. computer culture is extensive and profound, there is no gap at different aspect.Just mark down.📕📕。","text":"Some computer term in English and its paraphrase. English makes you go further. computer culture is extensive and profound, there is no gap at different aspect.Just mark down.📕📕。 C/C++——The C/C++ Programming word 编程用义 有道释义 constant 常量 adj. 不变的;恒定的;经常的。n. [数] 常数;恒量 variable 变量 adj. 变量的;可变的;易变的,多变的;变异的,[生物] 畸变的。n. [数] 变量;可变物,可变因素 value 值 n. 值;价值;价格;重要性;确切涵义。vt. 评价;重视;估价 Procedure-Based Programming 基于过程的程序设计 procedure——n. 程序,手续;步骤 data structure 数据结构 pseudo code 伪代码 pseudo——n. 伪君子;假冒的人。adj. 冒充的,假的 constructor 构造函数 n. 构造函数;构造器;建造者。复数constructors 数据库——DataBase word 编程用义 有道释义 wildcard 通配符 search pattern 搜索模式 计组——Principles of Computer Organization word (,acronym ) 编程用义 有道释义 Complex Instruction Set Computer,CISC 复杂指令系统计算机 Reduced Instruction Set Computer,RISC 精简指令系统计算机 备忘录看一本Computer English书籍。了解一哈。 听老师说有这门课,但是我得培养方案没有。问题不大","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[{"name":"English","slug":"English","permalink":"https://zy68.top/tags/English/"}]},{"title":"SQL——Practice","slug":"SQL_Practice","date":"2020-05-30T03:06:58.000Z","updated":"2020-05-30T03:06:58.000Z","comments":true,"path":"2020/05/30/SQL_Practice/","link":"","permalink":"https://zy68.top/2020/05/30/SQL_Practice/","excerpt":"SQL概述SQL(Structured Query Language,SQL) 结构化英语查询语言,非过程性语言。集数据定义语言(DDL)、数据操作语言(DML)、数据控制语言(DCL)三大功能于一体。 SQL的几个动词 SQL 功能 动词 数 据 查 询 SELECT 数 据 定 义 CREATE,DROP,ALTER 数 据 操 纵 INSERT,UPDATE,DELETE 数 据 控 制 GRANT,REVOKE","text":"SQL概述SQL(Structured Query Language,SQL) 结构化英语查询语言,非过程性语言。集数据定义语言(DDL)、数据操作语言(DML)、数据控制语言(DCL)三大功能于一体。 SQL的几个动词 SQL 功能 动词 数 据 查 询 SELECT 数 据 定 义 CREATE,DROP,ALTER 数 据 操 纵 INSERT,UPDATE,DELETE 数 据 控 制 GRANT,REVOKE 检索 select 如非必须,少用通配符 *,影响性能。 输出中行的值重复了:使用 DISTINCT 关键字,必须放在”列“前,且不对部分使用,是对全体列使用。 返回部分行:不同的DBMS语句不同。SQL Server eg:select top 5 score from Course; 1234567891011121314-- MySQL输出前几行,limit输出不超过指定行数。select prod_namefrom Productslimit 3;-- 返回从第几行起的多少行数据-- limit指定返回的行数,offset指定从哪一行开始。第一行从0开始,即第0行。select prod_namefrom productslimit 5 offset 0;-- 上述也可简写为:select prod_namefrom productslimit 0,5; 注释SQL三种注释 12345-- 单行注释# 单行注释/*多行注释*/ 函数 left(属性名,数字x) 表示取属性值的最左边x个字符 right(属性名,数字x) 表示取属性值的最右边边x个字符 lower(属性名) 表示将属性值的字母都变成小写 upper(属性名)表示将属性值的字母都变成大写 substring(属性名,起始位置L,长度x)取属性值起始位置L开始,长度为x的子串 ltrim(属性名)去除属性值最左边的空格 rtrim(属性名)去除属性值最右边的空格 trim(属性名)去除属性值首尾空格 replace(属性名,’目标’,’替代品’)将属性中的目标替换为替代品 len(属性名)取属性值的字符串长度 order by 要使用在句末,否则报错; 多行排序时,要求按多个属性排序,则先按第一个属性排序,再在此基础上按第二个属性,以此类推。eg: order by pro_price,pro_name 先按商品价格排序,价格相同则按商品名称排序。 升降序:DESC(descending)降序、ASC(ascending)升序。默认升序。 where where子句操作符 操作符说 明 = 等于 != 或 < > 不等于 < 小于 <= 或 !> 小于等于 > 大于 >= 或 !< 大于等于 BETWEEN 在指定的两个值之间 IS NULL 为NULL值 通配符 like %通配符123SELECT prod_nameFROM ProductsWHERE prod_name LIKE 'F%y'; 下划线(_)通配符 方括号([])——仅 Access 和 SQL Server 支持 %匹配一个字符及以上;而下划线只能匹配一个字符。 使用通配符技巧 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的。 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。","categories":[{"name":"Database","slug":"Database","permalink":"https://zy68.top/categories/Database/"}],"tags":[{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/tags/MySQL/"},{"name":"SQL","slug":"SQL","permalink":"https://zy68.top/tags/SQL/"}]},{"title":"Spring2_BeanBuilding","slug":"Spring2-BeanBuilding","date":"2020-05-27T15:06:58.000Z","updated":"2020-05-27T15:06:58.000Z","comments":true,"path":"2020/05/27/Spring2-BeanBuilding/","link":"","permalink":"https://zy68.top/2020/05/27/Spring2-BeanBuilding/","excerpt":"使用Spring容器 maven配置; 创建Bean配置文件并定义好所需对象; 创建Spring容器并制定需要装载的Bean配置文件; 通过容器提供的方法获取容器中的对象来使用。 Bean什么是Bean??Bean是一套约定或规范。具体的说Bean:1、所有属性为private2、提供默认构造方法3、提供getter和setter4、实现serializable接口","text":"使用Spring容器 maven配置; 创建Bean配置文件并定义好所需对象; 创建Spring容器并制定需要装载的Bean配置文件; 通过容器提供的方法获取容器中的对象来使用。 Bean什么是Bean??Bean是一套约定或规范。具体的说Bean:1、所有属性为private2、提供默认构造方法3、提供getter和setter4、实现serializable接口 简单的说:由spring容器管理的对象都是Bean对象,也是普通的java对象。 码两篇文章【javaBean上】、【javaBean下】 Bean、EJB、POJO及区别 在java1996年发布,当年12月即发布了java bean1.00-A,有什么用呢?通过统一的规范可以设置对象的值(get,set方法),这是最初的java bean; 在实际企业开发中,需要实现事务、安全、分布式,javabean就不好用了.sun公司就开始往上面堆功能,这里java bean就复杂为EJB; EJB功能强大,但是太重了.此时出现DI(依赖注入),AOP(面向切面)技术,通过简单的java bean也能完成EJB的事情,这里的java bean简化为POJO; Spring诞生了. 区别:先判断是否满足javabean的条件,然后如果再实现一些要求,满足EJB条件就是EJB,否则就是POJO。 Spring支持三种方式配置Bean文件自动装配、java注解和xml配置(三种允许单独使用或混合使用) XML中的Bean配置bean定义 常见bean.xml内容 1234567891011<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> <import resource="引入其他bean xml配置文件" /> <bean id="bean标识" class="玩转类型名称"/> <alias name="bean标识" alias="别名" /></beans> bean命名 1<bean id="bean的唯一标识" name="bean的名称" class="完整类型名称" factory-bean="工厂bean名称" factory-method="工厂方法"/> bean名称别名定义规则名称和别名可以通过bean元素中的id和name来定义,具体定义规则如下:: 当id存在的时候,不管name有没有,取id为bean的名称; 当id不存在,此时需要看name,name的值可以通过,;或者空格分割,最后会按照分隔符得到一个String数组,数组的第一个元素作为bean的名称,其他的作为bean的别名; 当id和name都存在的时候,id为bean名称,name用来定义多个别名; 当id和name都不指定的时候,bean名称自动生成,生成为“完整类名 +#+编号。”eg:com.hello#0; alias元素也可以用来给某个bean定义别名,语法: 1<alias name="需要定义别名的bean" alias="别名" /> import——bean汇总 在一个总的bean xml中对其他bean xml进行汇总,相当于把多个bean xml的内容合并到一个里,可以通过import元素引入其他bean配置文件。 在要汇总的bean.xml下 1<import resource="其他配置文件的位置" /> 容器创建bean实例 通过反射调用构造方法创建bean对象 通过静态工厂方法创建bean对象 通过实例工厂方法创建bean对象 通过FactoryBean创建bean对象 自动装配Spring从两个角度来实现自动化装配 组件扫描:Spring自动发现应用上下文中所创建的Bean 自动装配:Spring自动满足Bean之间的依赖。 通过javaConfig显式配置全程@Bean注解,通过return返回实例或进行DI配置。 实践部分创建一个Maven projects并导入Spring-webmvc所需jar包 在IDEA中创建好基于Maven的project。 在pom.xml中导入依赖信息:12345678910111213<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.17.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.2.17.RELEASE</version> </dependency></dependencies> 注: 直接导入这个包的原因是project项目可能需要的jar包特别多,且包之间还有依赖。直接导入一个集成的jar包,把依赖的包全自动下载了,能减少许多麻烦和问题。 记个坑:由于我的maven源使用的是阿里云的下载源,故有些jar包版本可能未及时更新,所以IDEA会显示 Dependency 'org.springframework:spring-webmvc:5.2.6.RELEASE' not found 。降低版本可能会解决。 参考 Java干货铺子","categories":[{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/categories/Spring/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/tags/Spring/"}]},{"title":"C++(note)","slug":"C++","date":"2020-05-25T04:27:54.000Z","updated":"2020-05-25T04:27:54.000Z","comments":true,"path":"2020/05/25/C++/","link":"","permalink":"https://zy68.top/2020/05/25/C++/","excerpt":"重载函数+函数模板","text":"重载函数+函数模板 目录 一、C++变量的存储期 二、内置函数 三、重载函数 四、指针和引用 五、枚举 六、函数模板 七、文件输入输出流 一、C++变量的存储期存储期,即变量在内存中的存储周期。其又可分为静态存储期和动态存储期。 静态存储方式:在程序运行中分配固定的空间,程序结束后释放。(static)动态存储方式:在程序运行中动态的分配空间。(形参、变量、函数调用的保护和恢复现场等) C++变量的存储类别四个类别:自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。 auto 函数中的局部变量,不用static修饰,默认auto,即动态的分配存储空间。 12345int f(int a){ auto int b,c; ……} static 局部变量定义为 static 时,系统分配静态空间,当变量调用结束时,保留原值而不释放空间,下次调用时该值依旧存在,且可以操作。 与一般的auto变量的区别在于,被调用结束后空间不释放。静态变量仅在编译时赋值一次,以后再调用不再赋值。而auto变量随便赋值,每次都不保留。 注: 变量应该在定义时初始化,否则自动赋0或null。而auto是随机数。 在被一个函数调用结束后,虽然保留了原空间的值,但来自不同函数的调用是互相不可见的。即如果有另外一个函数调用它,又是一个全新的空间分配。 例如: 123456789101112int f(){ static int a=1; //定义静态局部变量 a = a + 1; return a;}int main(){ cout<<f()<<endl; //输出 2; cout<<f()<<endl; //输出 3; //原变量值在上一次调用结束后保持不变。 return 0;} register(了解) 背景:上述的变量都是存放在内存中的,而存取变量需要时间。当需要大量、频繁的调用某一变量时,选择使用CPU寄存器存取会更快(系统对寄存器的存取速度高于内存)。如此可以提高效率。 如今系统有自动选择是否寄存器。 extern 用于声明全局变量,扩展全局变量的作用域。 同一个源文件下,例如:123456789101112int max(int a, int b){ return a>b?a:b;}int main(){ extern int a,b; //(提前)引用全局变量 a,b cout<<max(a,b);}int a=16, b=-7; //定义全局变量 a,b 不同源文件下,两个文件使用同一个变量时,可以在一个文件中使用 extern 引用另一个文件定义好的变量。 注:如果不想被外部文件引用可以使用 static修饰变量。 二、内置函数——inline内置函数,又称内联函数、内嵌函数。 背景:一般的程序执行并调用外部函数时,需要保存当前主调函数跳转去执行外部函数,需要保存现场,执行完后又需要恢复现场(即中断),如此是需要耗费时间的。为了节省时间,提高效率。C++的内置函数,是把函数放在主调函数中,和主调函数一起执行的。 具体实现:与一般的功能函数无异,仅在声明时需在开头加 inline 关键字。例如: 1234inline int max(int a, int b){ return a > b ? a : b;} 注:为了避免主调函数过长,仅建议规模小(很简单的功能函数)而使用频繁的函数作为内置函数。 三、重载函数重载函数,即函数参数个数、参数类型和参数顺序三者中必须至少有一种不同,函数返回值可同可不同的同名函数。例如: 123int max( int a, int b );int max( int a, int b, int c );double max(int a, double b ,float c); 四、带默认参数的函数 实参与形参的结合按从左至右的顺序,即有指定默认值得参数必须放在形参列表得最右端。 12void func(int a, int c=10, double d); //不可void func(int a, double d, int c=10); //可 一个函数不可以同时是重载函数又是有默认参数的函数。 在调用有默认参数函数前必须定义好默认参数。 指针指针只是一个地址,为什么要定义基类型??eg:int *p;char *p;答:不同的数据类型在计算机系统中的存储方式和所占字节数不同,而指针只是一个地址,只是指向某个存储空间,但是读取数据的时候读取多少呢?noone knows。这时,数据类型站出来了,它说它知道 已经知道不同的数据类型占不同大小的空间,所以用数据类型来定义指针,在读取的时候系统就能够知道要读取多少数据。 深入底层它不香吗?就这??好好学微机和计组 函数指针12345678//定义int max(int a, int b);int (*p)(int ,int ); //(*p)的括号不能省略p=max;//使用int a,b,m;cin>>a>>b;m=p(a,b); const指针 指向常量的指针变量 格式:const 类型名 * 指针变量名 用指向常量的指针变量只是限制了通过指针变量改变它指向的对象的值。 指针数组指针数组:即数组每个元素都是用来存指针的。定义:类型名 * 数组名[数组长度] eg:int * p[4]; 合理利用,是个好东西。 小记:p=&array[i] //将数组array第i个元素的地址给p. 指针使用小结简记 变量定义 含义 int *p[4] 指针数组 int (*p)[4] 一般的数组,p是数组首地址的指针变量 int * p() p为函数名,函数返回类型为int型地址 int (*p)() p为指向函数的指针 int **p 指针的指针 int const *p p是常指针,其值固定不变 还有 …… 引用介绍c++引用,即引向一个已存在的对象。俗称“别名”,类似指针,但比指针受到的限制更多。 C++ 引用 vs 指针 不存在空引用。引用必须连接到一块合法的内存。 一旦引用被初始化为一个对象,就不能被指向到另一个对象。而指针可以在任何时候指向到另一个对象。 引用必须在创建时被初始化。指针可以在任何时间被初始化。 使用 引用只有声明,没有定义。即先定义一个变量,然后声明一个引用去指代这个变量。 12345678910111213void swap(int & x, int & y ){ //定义引用 int temp; temp=x; x=y; y=temp;}int main(int argc, char *argv[]) { int a=23,b=45; swap(a,b); cout<<a<<"\\n"<<b <<endl; return 0;} 引用还可作为返回值使用。 枚举1234567//定义enum color{red,yellow,blue,black};//使用```c++color co1,co2;co1=red;co2=co1(2); 使用次数=0 函数模板——template函数模板,即建立一个通用函数,其函数类型和形参类型不具体指定,通过一个虚拟的类型来代表(也可称为泛型)。使用template关键词声明模板例如: 1234567//模板声明,T为类型参数。typename也可改写为 class.//类型参数可以有多个 <typename T1, typename T2>template <typename T> T max(T a, T b){ return a > b ? a : b; } 与重载函数的区别:重载函数是一个函数名多个函数,可以相对地理解为单一功能函数;函数模板是一个函数名一个模板对应多个不同参数类型功能需求的函数,是一个通用函数。 面向对象程序设计在面向对象的程序设计中,除了主函数,其他的函数几乎都是出现在类里,通过类调用函数。程序的基本构成是类,程序面向的是类和对象。面向对象设计更利于开发更大规模的程序。 四个特点:抽象、封装、继承和多态性。 类class 类是对象的抽象,即类是虚的,对象是实的。类是设计图纸上的设计,对象是根据设计做出来的实物。 成员函数的代码不占用对象的存储空间 类的成员函数是公用的,即无论实例化了多少个对象,这些对象使用的函数都是相同的,公用的,并没有生成新的函数。 类的内存大小,取决于类中声明的成员变量,与成员函数无关。 构造函数 同定义的一个类额多个对象之间可以相互赋值。如: Time t1; Time t2=t1; 参数初始化表初始化数据成员 格式:类名::构造函数名([参数表])[:成员初始化表]{} 。 123456789class Box{ private: int height; int width; int length; public: Box(int h, int w, int l):height(h),width(w),length(l){ //使用参数初始化表 }}; 就是直接用成员变量自己赋值 类的默认构造函数只有一个。可以是无参的构造函数或全指定了默认值的构造函数,二者不可同时出现,否则报错。 构造函数同样适用——上述 带默认参数的函数 常对象 和 常对象成员常对象 定义常对象 类名 const 对象名(参数); 将函数定义为常函数 类型名 函数名()const; 常对象只能调用它的常函数,普通函数不可;常对象可以正常调用常函数。 常函数可以访问常对象中的数据成员,但依旧不可以对它们进行修改。 常函数不可以调用非常函数 注:当常对象的某个变量确实需要修改时,可以使用 mutable关键字,则常函数就可以正常的修改它。 在类中定义了常数据成员,则只能直接初始化或使用构造参数(通过参数初始化表)来初始化。 汇总小表 数据成员 非const的普通成员函数 const成员函数 非const数据成员 可以引用,也可以改变值 可以引用但不可以改变值 const数据成员 可以引用,但不可以改变值 可以引用,但不可以改变值 const对象 不允许引用 可以引用但不可以改变值 静态成员被static修饰的成员。静态成员是类层面的一部分。供类的其他函数和类的其他对象使用,是“公共”的。 静态数据成员 静态数据成员可以初始化,但只能在类体外初始化,且不能用参数初始化表。 可以用类名引用静态数据成员,也可以通过对象来引用数据成员。 静态成员函数 在类外调用静态成员函数时要使用 类名::函数名。 静态成员函数没有this指针。即静态成员函数不可以访问非静态成员。 友元关键字 friend 。定义为 friend 的函数或类为友元函数或友元类。友元的作用:突破private的壁垒,访问类的私有成员。 使用:想要使用某一个类的私有成员,在该类中声明用 friend声明一下即可。 例如普通函数声明为友元函数 12345678910111213141516171819class Box{ private: int height; int width; int length; public: Box(int h, int w, int l):height(h),width(w),length(l){ //使用参数初始化表 } friend void display(Box &b);//声明};void display(Box &b){ cout<<b.height<<"\\t"<<b.width<<endl;}int main(){ Box b(1,2,3); display(b);//调用 return 0;} 注:其他如友元成员函数也是如此,只需将类名带上即可。 析构函数析构函数——清场人员,only one。 不反回任何值,没有函数类型,没有函数参数。 使用 12345678class Box{ private: int height; int width; int length; public: ~Box(){};}; 几个对象的构造函数和析构函数调用顺序:先构造的后析构,后构造的先析构。 对象指针对象都可用指针。 对成员函数使用指针,函数返回值类型作为指针的定义类型。 使用格式:&类名::成员函数名,例如: 12345678class Time{……};void Time::getTime(){}int main(){ void(Time:: *p)(); //定义指向Time类的成员函数的指针变量p p=&Time::getTime;//使p指向Time的函数getTime() return 0;} 这部分有点sao,pay attention。 运算符重载运算符重载实质上是函数重载。其函数名就是 operator 运算符。其他与一般的函数一致。 大部分的运算符都能重载,除了这5个:. , * ,:: ,sizeof,?: 。 运算符重载函数作为类的成员函数: 12345678910111213class Complex{ public: //简写 Complex operator + (Complex &c2); Complex(int a, int b):real(a),imag(b){ }; private: int real; int imag; };Complex Complex::operator +(Complex &c2){ return Complex(real+c2.real,imag+c2.imag);} 作为友元函数 12345678910111213class Complex{ public: //简写 friend Complex operator + (Complex &c2); Complex(int a, int b):real(a),imag(b){ }; private: int real; int imag; };Complex operator +(Complex &c1, Complex &c2){ return Complex(c1.real+c2.real,c1.imag+c2.imag);} 虚基类 输入输出流(I/O Stream)输入输出流:指若干个字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。 包括标准I/O、文件I/O和串I/O。 文件流 数据类型 描述 ofstream 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 ifstream 该数据类型表示输入文件流,用于从文件读取信息。 fstream 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 头文件加<fstream>即可。 123456789101112#include "iostream"#include "fstream"// 创建输入文件对象ifstream infile;ofstream outfile;infile.open("myfile1.txt");outfile.open("myfile2.txt");float x,y;infile>>x>>y;outfile<<x<<'\\t'<<y<<endl;infile.close();outfile.close(); 注:本篇作为学习和复习C++课程的笔记和要点,内容不全,有错还请指出。😀😀","categories":[{"name":"C/C++","slug":"C-C","permalink":"https://zy68.top/categories/C-C/"}],"tags":[{"name":"C++","slug":"C","permalink":"https://zy68.top/tags/C/"}]},{"title":"Windows系统相关知识","slug":"Windows系统","date":"2020-05-23T02:24:21.000Z","updated":"2020-05-23T02:24:21.000Z","comments":true,"path":"2020/05/23/Windows系统/","link":"","permalink":"https://zy68.top/2020/05/23/Windows%E7%B3%BB%E7%BB%9F/","excerpt":"Windows系统","text":"Windows系统 因为要清理一下电脑,所以补点Windows下的电脑知识,记录笔记。 系统盘文件夹认识 PerfLogs——系统日志 Program files以及Program File(x86)——软件的安装目录。 Program Data——应用数据文件夹 windows——内含Windows系统运行的文件 用户——保存用户文件。","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[{"name":"CSBasic","slug":"CSBasic","permalink":"https://zy68.top/tags/CSBasic/"}]},{"title":"javaSE-12.部署","slug":"javaSE-12-部署","date":"2020-05-20T08:12:48.000Z","updated":"2020-05-20T08:12:48.000Z","comments":true,"path":"2020/05/20/javaSE-12-部署/","link":"","permalink":"https://zy68.top/2020/05/20/javaSE-12-%E9%83%A8%E7%BD%B2/","excerpt":"认识jar包","text":"认识jar包 JAR文件Java 归档(jar)文件:是压缩格式,文件内可以包含类文件、图像、声音和其他资源,另外包含一个用于描述归档特征的清单文件(manifest)。作用是将应用程序打包,发给使用者。 创建jar文件 jar工具制作JAR文件(在默认的JDK 安装中, 位于jdk/bin 目录下)。 12# 操作命令格式jar options file1 file2 …… jar清单文件(manifest) 清单文件被命名为MANIFEST.MF, 它位于JAR 文件的一个特殊META-INF 子目录中。 可执行jar文件 用户可通过命令启动应用程序 1java -jar filename.jar 注:不同操作系统也可以通过不同方式启动应用程序 资源 不是源代码文件的其他文件都可以广义的成为资源(resource)。 密封 作用:密封可以保证不会有其他的类加入到其中。 创建jar包时,默认包时没有密封的。可在清单文件中设定打包时是否密封。 参考《java核心技术 卷一》","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"IDEA使用","slug":"IDEA使用","date":"2020-05-20T04:27:54.000Z","updated":"2020-05-20T04:27:54.000Z","comments":true,"path":"2020/05/20/IDEA使用/","link":"","permalink":"https://zy68.top/2020/05/20/IDEA%E4%BD%BF%E7%94%A8/","excerpt":"概念解释or介绍IDEA不像Eclipse设置工作空间IDEA不需要设置工作空间,因为每一个Project都具备一个工作空间!!对于每一个IDEA的项目工程(Project)而言,它的每一个子模块(Module)都可以使用独立的JDK和MAVEN配置。每个新项目(Project)都需要设置自己的JDK和MAVEN等相关配置","text":"概念解释or介绍IDEA不像Eclipse设置工作空间IDEA不需要设置工作空间,因为每一个Project都具备一个工作空间!!对于每一个IDEA的项目工程(Project)而言,它的每一个子模块(Module)都可以使用独立的JDK和MAVEN配置。每个新项目(Project)都需要设置自己的JDK和MAVEN等相关配置 Module 模块化的概念,作为聚合工程亦或普通的根目录,它称之为Project,而下面的子工程称为模块,每一个子模块之间可以相关联,也可以没有任何关联。 设置 设置里可以设置整个IDE的东西。主要要关注的是JDK和maven,可以设置全局默认配置,以后每一个project或者module就不用自己麻烦配置了。 注:maven插件给操作maven提供了极大便利。 版本控制Git/Svn(默认配置)具体步骤:顶部工具栏 File ->Other Settings -> Default Settings -> Version Control -> Git 编码常用技巧 解决错误的万能快捷键alt+Enter 具体操作:将光标移动到代码标红处然后按下alt+Enter。 代码格式化Ctrl+alt+l。 调整调整全篇代码的样式格式。 全部重命名shift+f6 写错或要修改:包名、类名、方法名、变量名……且被引用了的时候。另外一个方法:1.光标定位;2.右键-重构-重命名;3.输入新名称后确定。 Intellij IDEA十大快捷键 参考 IntelliJ IDEA 使用教程(2019图文版) – 从入门到上瘾 Intellij IDEA十大快捷键","categories":[{"name":"Tool","slug":"Tool","permalink":"https://zy68.top/categories/Tool/"}],"tags":[{"name":"tool","slug":"tool","permalink":"https://zy68.top/tags/tool/"}]},{"title":"Spring1","slug":"Spring1","date":"2020-05-20T04:27:54.000Z","updated":"2020-05-20T04:27:54.000Z","comments":true,"path":"2020/05/20/Spring1/","link":"","permalink":"https://zy68.top/2020/05/20/Spring1/","excerpt":"Spring容器(框架) 定义:Spring是一个轻量级的、非入侵式的开源框架(容器)。 目标和使命:简化java开发,促进代码的松散耦合。 spring容器的概念,容器可以放很多东西,程序启动的时候会创建spring容器,会给spring容器一个清单,清单中列出了需要创建的对象以及对象依赖关系,spring容器会创建和组装好清单中的对象,然后将这些对象存放在spring容器中,当程序中需要使用的时候,可以到容器中查找获取,然后直接使用。具有依赖注入功能的容器,负责对象的实例化、对象的初始化,对象和对象之间依赖关系配置、对象的销毁、对外提供对象的查找等操作,控制对象的整个生命周期。","text":"Spring容器(框架) 定义:Spring是一个轻量级的、非入侵式的开源框架(容器)。 目标和使命:简化java开发,促进代码的松散耦合。 spring容器的概念,容器可以放很多东西,程序启动的时候会创建spring容器,会给spring容器一个清单,清单中列出了需要创建的对象以及对象依赖关系,spring容器会创建和组装好清单中的对象,然后将这些对象存放在spring容器中,当程序中需要使用的时候,可以到容器中查找获取,然后直接使用。具有依赖注入功能的容器,负责对象的实例化、对象的初始化,对象和对象之间依赖关系配置、对象的销毁、对外提供对象的查找等操作,控制对象的整个生命周期。 Spring核心 AOP(aspect-orientd programming)面向切面编程。 IOC(Inversion of Control):控制反转,是一种设计思想。IOC主要通过DI和DL来具体实现。 DI(Dependency Injection):依赖注入 DL():依赖查找 支持事务的处理,对框架整合的支持。 一句话:Spring是一个控制反转(IOC)和面向切面编程(AOP)的开源框架。 Spring Framework官方文档介绍 IOC和DI的区别??答:IOC是目的,DI是手段。IOC通过DI来实现(DL了解)。IOC是指让生成类的方式由传统方式(new)反过来,即程序员不调用new, 需要类的时候由框架注入(DI),是从不同层面的解读。——来自知乎高分答案 IOC原理等着填:(转载)Spring IOC 知识点总结 IOC控制反转以前,程序员使用对象的时候都需要自己去创建和组装,而现在这些创建和组装都交给spring容器去给完成了,程序员只需要去spring容器中查找需要使用的对象就可以了;这个过程中对象的创建和组装过程被反转了,之前是使用者自己主动去控制的,现在交给spring容器去创建和组装了,对象的构建过程被反转了,所以叫做控制反转; DI 依赖注入依赖注入是spring容器中创建对象时给其设置依赖对象的方式,比如给spring一个清单,清单中列出了需要创建B对象以及其他的一些对象(可能包含了B类型中需要依赖对象),此时spring在创建B对象的时候,会看B对象需要依赖于哪些对象,然后去查找一下清单中有没有包含这些被依赖的对象,如果有就去将其创建好,然后将其传递给B对象;可能B需要依赖于很多对象,B创建之前完全不需要知道其他对象是否存在或者其他对象在哪里以及被他们是如何创建,而spring容器会将B依赖对象主动创建好并将其注入到B中去,比如spring容器创建B的时候,发现B需要依赖于A,那么spring容器在清单中找到A的定义并将其创建好之后,注入到B对象中。 Spring 组成 参考路人甲java——《Spring系列第2篇:控制反转(IoC)与依赖注入(DI)》","categories":[{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/categories/Spring/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/tags/Spring/"}]},{"title":"Tomcat","slug":"Tomcat","date":"2020-05-19T15:22:21.000Z","updated":"2020-05-19T15:22:21.000Z","comments":true,"path":"2020/05/19/Tomcat/","link":"","permalink":"https://zy68.top/2020/05/19/Tomcat/","excerpt":"概述Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器。 一、Tomcat三个功能: Web服务器 jsp容器 Servlet容器。","text":"概述Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器。 一、Tomcat三个功能: Web服务器 jsp容器 Servlet容器。 二、Tomcat文件目录介绍 注,重点说明: conf目录: server.xml 文件用于配置server相关信息; web.xml 文件配置与web应用(一个web应用相当于一个web站点) tomcat-user.xml 配置用户名密码及相关权限。 work目录:用于存放jsp被访问后生成的对应的server文件和.class文件 webapps目录: 存放web应用。 使用:在webapps目录下新建文件夹(内包含.html、WEB-INF、jsp、图片等文件),用于存放web应用 WEB-INF目录用于对web应用做设置、调整等。主要是web.xml配置文件的配置使用。 一个web应用的目录结构: 三、配置虚拟目录虚拟目录:一个映射,把分放在其他磁盘的web应用映射到webapps目录下。即记录指向其他web应用的路径,使得在要访问时,Tomcat能够找到它并运行。 默认只有在webapps目录下的web应用才能被Tomcat自动管理成一个web站点。 法一:在Tomcat的conf/server.xml文件中添加如下代码123# path表示的是访问时输入的web项目名,docBase表示的是站点目录的绝对路径。# 下例的代码背景:名称为 Demo1 的web应用放在D盘下<Context path="/Demo1" docBase="D:\\Demo1"/> 法二:到conf\\Catalina\\localhost文件下,创建一个xml文件,该文件的名字就是站点的名字。.xml文件内容如下12345<?xml version="9.0" encoding="UTF-8"?><Context docBase="D:\\Demo1" reloadable="true"></Context> 四、配置临时域名访问Tomcat服务器的几种方式: 使用localhost域名访问 使用ip地址127.0.0.1访问【该ip地址也是本机】 使用主机名访问【只限于本机上或局域网】#???我还不懂???答:内网DNS解析# 使用本机IP地址访问【在cmd中输入ipconfig可以查询到本机的IP地址】 为机器配置临时域名 配置临时域名 到 C:\\Windows\\System32\\drivers\\etc下,找到hosts文件 添加、保存如下,然后即可通过http://hellozyhost访问本机了。 说到底是使用本机的DNS解析 五、设置虚拟主机虚拟主机:多个不同域名的网站共存在一个Tomcat中。即:一个主机的情况下,一个Tomcat只能运行一个网站。如果我不配置虚拟主机,那么我需要多个电脑中的Tomcat来运行每一个域名的网站。 配置虚拟主机在tomcat的server.xml文件中添加主机名 123<Host name="zy" appBase="D:\\Demo1"> <Context path="/Demo1" docBase="D:\\Demo1"/></Host> ???????我怎么设置虚拟主机呢??????? 六、Tomcat体系结构 七、web访问流程 来源和参考3y——《Tomcat就是这么简单》","categories":[{"name":"JavaWeb","slug":"JavaWeb","permalink":"https://zy68.top/categories/JavaWeb/"}],"tags":[{"name":"javaWeb","slug":"javaWeb","permalink":"https://zy68.top/tags/javaWeb/"}]},{"title":"认识下HTTP","slug":"http","date":"2020-05-19T15:17:13.000Z","updated":"2020-05-19T15:17:13.000Z","comments":true,"path":"2020/05/19/http/","link":"","permalink":"https://zy68.top/2020/05/19/http/","excerpt":"Part1—— Web及网络基础3 项 WWW(简称Web) 构建技术,分别是: 把 SGML(Standard Generalized Markup Language,标准通用标记语言)作为页面的文本标记语言的 HTML(HyperText Markup Language,超文本标记语言); 作为文档传递协议的 HTTP ; 指定文档所在地址的 URL(Uniform Resource Locator,统一资源定位符)。 不同的硬件、操作系统之间的通信,都需要一种规则。这种规则称为协议(protocol)。TCP/IP 是互联网相关的各类协议族的总称。","text":"Part1—— Web及网络基础3 项 WWW(简称Web) 构建技术,分别是: 把 SGML(Standard Generalized Markup Language,标准通用标记语言)作为页面的文本标记语言的 HTML(HyperText Markup Language,超文本标记语言); 作为文档传递协议的 HTTP ; 指定文档所在地址的 URL(Uniform Resource Locator,统一资源定位符)。 不同的硬件、操作系统之间的通信,都需要一种规则。这种规则称为协议(protocol)。TCP/IP 是互联网相关的各类协议族的总称。 TCP/IP的分层四层:应用层、传输层、网络层、和数据链路层。 分层的一些好处:1.分层即把整体部分化,当有某个地方出现问题时不必改一个大整体,可以只改出现问题的一小部分。2.简化设计。 应用层 应用层决定了向用户提供应用服务时通信的活动。 TCP/IP 协议族内预存了各类通用的应用服务。比如,FTP(File Transfer Protocol,文件传输协议)和 DNS(Domain Name System,域名系统)服务就是其中两类。 HTTP 协议处于该层。 传输层 传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。 在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议) 和 UDP(User Data Protocol,用户数据报协议)。 网络层(又名网络互连层) 网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径 (所谓的传输路线)到达对方计算机,并把数据包传送给对方。 与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一 条传输路线。 链路层(又名数据链路层,网络接口层) 用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范 畴均在链路层的作用范围之内。 发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在 层与层传输数据时,每经过一层时会把对应的首部消去。 这种把数据信息包装起来的做法称为封装(encapsulate)。 与http关系密切的协议:IP、TCP、DNS1.负责传输的 IPIP(Internet Protocol) 网际协议,位于网络层,也即TCP/IP 协议族中的 IP。作用是把各种数据包传送给对方。 tips:此IP是一种协议的名称,需要与IP地址区别开。 IP传送条件:IP 地址(指明了节点被分配到的地址),MAC 地址(指网卡所属的固定地址)。 2.负责保障的 TCPTCP 位于传输层,提供可靠的字节流服务。即TCP 协议为了更容易传送大数据才把数据分割,而且 TCP 协议能够确认数据最终是否送达到 对方。 TCP的 三次握手 用 TCP 协议把数据包送出去后,TCP 不会对传送后的情况置之不理,它一定会向对方确认是否成功送达。 握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和 ACK(acknowledgement)。 发送端首先发送一个带 SYN 标志的数据包给对方。(一次) 接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。(两次) 最后,发送端再回传一个带 ACK 标志的数据包,(三次) 代表“握手”结束。 3.负责域名解析的 DNSDNS(Domain Name System),提供域名到 IP 地址之间的解析服务。位于应用层。 DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。 URI和URL URL(Uniform Resource Locator,统一资源定位符) URI(Uniform Resource Identifier,统一资源标识符) Uniform 规定统一的格式可方便处理多种不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。另 外,加入新增的协议方案(如 http: 或 ftp:)也更容易。 Resource 资源的定义是“可标识的任何东西”。除了文档文件、图像或服务(例如当天的天气预报)等能够区别于其 他类型的,全都可作为资源。另外,资源不仅可以是单一的,也可以是多数的集合体。 Identifier 表示可标识的对象。也称为标识符。综上所述,URI 就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。 URL 是 URI 的子集。 Part2—— http协议一 用于客户端和服务器之间的通信。二 通过请求和响应的交换达成通信(报文)。三 不保存状态的协议。四 请求由URI定位的资源。五 告知服务器意图的 HTTP方法。HTTP方法: GET:获取资源GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。 POST:传输实体主体POST 方法用来传输实体的主体。与GET的差别在于POST主要目的不是获取响应的主体内容。 PUT:传输文件PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后 保存到请求 URI 指定的位置。 HEAD:获得报文首部HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时 间等。 DELETE:删除文件DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除指定的资源。 OPTIONS:询问支持的方法OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。 TRACE:追踪路径TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。 CONNECT:要求用隧道协议连接代理CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议 把通信内容加 密后经网络隧道传输。 六 持久连接节省通信量(持久连接、管线化)七 使用 Cookie 的状态管理Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。 1231. 请求报文(没有 Cookie 信息的状态)-> 2. 响应报文(服务器端生成 Cookie 信息)-> 3. 请求报文(自动发送保存着的 Cookie 信息) Part3—— http报文内的http信息http报文用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端 (服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。 HTTP 报文大致可分为报文首部和报文主体两块。通常,并不一定要有报文主体。 报文(message)是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence,其中 octet 为 8 个比 特)组成,通过 HTTP 通信传输。 实体(entity)作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。 其他 请求报文及响应报文的结构 编码提升传输速率 发送多种数据的多部分对象集合 获取部分内容的范围请求 内容协商返回最合适的内容 Part4——返回结果的HTTP状态码HTTP 状态码负责表示客户端 HTTP 请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。比如404。 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。 状态码类别:| 状态码 | 类别 | 原因短语 ||:–:| :–: | :–: ||1XX |Informational(信息性状态码) |接收的请求正在处理||2XX |Success(成功状态码) |请求正常处理完毕 ||3XX |Redirection(重定向状态码) |需要进行附加操作以完成请求 ||4XX |Client Error(客户端错误状态码) |服务器无法处理请求 ||5XX |Server Error(服务器错误状态码) |服务器处理请求出错 | 1) 2XX 成功2XX 的响应结果表明请求被正常处理了。 200 OK:表示从客户端发来的请求在服务器端被正常处理了。 204 No Content:请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。 206 Partial Content:表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。 2) 3XX 重定向3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。 301 Moved Permanently:永久性重定向,表示请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI。 302 Found:临时性重定向,表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。 303 See Other:表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 304 Not Modified:表示客户端发送附带条件的请求 2 时,服务器端允许请求访问资源,但未满足条件的情况。 307 Temporary Redirect:临时重定向。该状态码与 302 Found 有着相同的含义。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。307 会遵照浏览器标准,不会从 POST 变成 GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。 3) 4XX 客户端错误4XX 的响应结果表明客户端是发生错误的原因所在。 400 Bad Request:表示请求报文中存在语法错误。另外,浏览器会像 200 OK 一样对待该状态码。 401 Unauthorized:表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用户认证失败。 403 Forbidden:表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。 404 Not Found:表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。 4) 5XX 服务器错误5XX 的响应结果表明服务器本身发生错误。 500 Internal Server Error:表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的 bug 或某些临时的故障。 503 Service Unavailable:表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 Part5—— 与 HTTP 协作的 Web 服务器一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路径上的中转服务器提升传输效率。 用单台虚拟主机实现多个域名HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点 在互联网上,域名通过 DNS 服务映射到 IP 地址(域名解析)之后访问目标网站。可见,当请求发送到 服务器时,已经是以 IP 地址形式访问了。 所以,如果一台服务器内托管了 www.tricorder.jp 和 www.hackr.jp 这两个域名,当收到请求时就需要 弄清楚究竟要访问哪个域名。 在相同的 IP 地址下,由于虚拟主机可以寄存多个不同主机名和域名的 Web 网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指定主机名或域名的 URI。??? 通信数据转发程序 :代理、网关、隧道代理代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。代理不改变请求 URI,会直接发送给前方持有资源的目标服务器。 持有资源实体的服务器被称为源服务器 代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。 缓存代理代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。 透明代理转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。 网关网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。 利用网关可以由 HTTP 请求转化为其他协议通信利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。 隧道隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。目的是确保客户端能与服务器进行安全的通信。隧道可按要求建立起一条与其他服务器的通信线路,届时使用 SSL 等加密手段进行通信。 缓存缓存是指在代理服务器或客户端本地磁盘内保存的资源副本。 缓存代理服务器能向原服务器确认缓存有效性进而判别缓存内容是否过期。 在客户端(浏览器)缓存称为临时网络文件。过期后也会向代理服务器确认有效性。 Part6——HTTP首部HTTP 协议的请求和响应报文中必定包含 HTTP 首部。首部内容为客户端和服务器分别处理请求和响应提 供所需要的信息。 Part7——确保安全的httpsHTTP 主要有这些不足,例举如下。 通信使用明文(不加密),内容可能会被窃听 HTTP 协议中没有加密机制 加密 通信加密SSL(Secure Socket Layer,安全套接层)或 TLS(Transport Layer Security,安全层传输协议)的组合使用,加密 HTTP 的通信内容。与 SSL 组合使用的 HTTP 被称为 HTTPS(HTTP Secure,超文本传输安全协议)或 HTTP over SSL。 内容加密对 HTTP 协议传输的内容本身加密。即把 HTTP 报文里所含的内容进行加密处理 不验证通信方的身份,因此有可能遭遇伪装 由于不存在确认通信方的处理步骤,任何人都可发起请求,服务器也都会有回应(除非其端口限制)。 无法确定请求发送至目标的 Web 服务器是否是按真实意图返回响应的那台服务器。有> 可能是已伪装的 Web 服务器。 无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端。有可能是已> 伪> 装的客户端。 无法确定正在通信的对方是否具备访问权限。因为某些 Web 服务器上保存着重要的信息,只想发给特定用户通信的权限。 无法判定请求是来自何方、出自谁手。 即使是无意义的请求也会照单全收。无法阻止海量请求下的 DoS 攻击 (Denial of > Service,拒绝服务攻击)。 查明对手的证书 SSL 不仅提供加密处理,而且还使用了一种被称为证书的手段,可用于确定方。 客户端持有证书即可完成个人身份的确认,也可用于对 Web 网站的认证环节。 无法证明报文的完整性,所以有可能已遭篡改 HTTP 协议无法证明通信的报文完整性,没有任何办法确认,发出的请求 / 响应和接收到的请求 / 响应是前后相同的。 即在传输过程中被遭攻击者拦截并篡改内容的攻击称为中间人攻击(Manin-the-Middle attack,MITM)> 但两端通信看上去还是正常的。 HTTP+加密+认证+完整性保护=HTTPS(HTTP Secure)HTTPS并非是应用层的一种新协议。是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替。 HTTP: 应用(HTTP) TCP IP HTTPS: 应用(HTTP) SSL TCP IP SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。可以说 SSL 是当今世界上应用最为广泛的网络安全技术。 公开密钥加密技术 SSL 采用一种叫做公开密钥加密(Public-key cryptography)的加密处理方式。加密和解密都会用到密钥。任何人只要持有密钥就能解密。(共享密钥加密的弊端) 公开密钥加密使用一对非对称的密钥。一把叫做私有密钥(private key),另一把叫做公开密钥(public key)。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。 使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。 HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。 若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。 所以应充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。(即先给安全的给密钥对方,后面的通信就可以安全使用共享加密) 另一个层次:公开密钥可能是假的,亦会造成信息泄露。解决方法:由数字证书机构颁发公开密钥证书(简称数字证书或证书)。 数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。 证书的一个作用是用来证明作为通信一方的服务器是否规范,另外一个作用是可确认对方服务器背后运营的企业是否真实存在。拥有该特性的证书就是 EV SSL 证书(Extended Validation SSL Certificate)。 Part8——确认访问用户身份的认证访问用户身份认证就是要确定访问的人是不是网页指定的允许的人。 HTTP/1.1使用的认证方式: BASIC认证(基本认证) DIGEST认证(摘要认证) SSL客户端认证 FormBase认证(基于表单认证) BASIC认证 可以认为是简单的填写用户名和密码认证。具体实现: 步骤 1: 当请求的资源需要 BASIC 认证时,服务器会随状态码 401 Authorization Required,返回带 WWW-Authenticate 首部字段的响应。该字段内包含认证的方式(BASIC) 及 Request-URI 安全域字 符串(realm)。步骤 2: 接收到状态码 401 的客户端为了通过 BASIC 认证,需要将用户 ID 及密码发送给服务器。发 送的字符串内容是由用户 ID 和密码构成,两者中间以冒号(:)连接后,再经过 Base64 编码处理。 假设用户 ID 为 guest,密码是 guest,连接起来就会形成 guest:guest 这样的字符串。然后经过 Base64 编码,最后的结果即是 Z3Vlc3Q6Z3Vlc3Q=。把这串字符串写入首部字段 Authorization 后,发送请求。 当用户代理为浏览器时,用户仅需输入用户 ID 和密码即可,之后,浏览器会自动完成到 Base64 编码的 转换工作。步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会对认证信息的正确性进行验证。如验证 通过,则返回一条包含 Request-URI 资源的响应。BASIC 认证虽然采用 Base64 编码方式,但这不是加密处理。不需要任何附加信息即可对其解码。换言 之,由于明文解码后就是用户 ID 和密码,在 HTTP 等非加密通信的线路上进行 BASIC 认证的过程中, 如果被人窃听,被盗的可能性极高。另外,除此之外想再进行一次 BASIC 认证时,一般的浏览器却无法实现认证注销操作,这也是问题之 一。BASIC 认证使用上不够便捷灵活,且达不到多数 Web 网站期望的安全性等级,因此它并不常用。 DIDEST认证 扩展阅读or参考一文读懂HTTPS以及SSL单向验证和双向验证","categories":[{"name":"HTTP","slug":"HTTP","permalink":"https://zy68.top/categories/HTTP/"}],"tags":[{"name":"http","slug":"http","permalink":"https://zy68.top/tags/http/"},{"name":"网络","slug":"网络","permalink":"https://zy68.top/tags/%E7%BD%91%E7%BB%9C/"}]},{"title":"Linux基础——笔记","slug":"Linux","date":"2020-05-19T12:13:40.000Z","updated":"2020-05-19T12:13:40.000Z","comments":true,"path":"2020/05/19/Linux/","link":"","permalink":"https://zy68.top/2020/05/19/Linux/","excerpt":"部分Linux基础知识+详细记录部分指令 Linux c 一站式学习","text":"部分Linux基础知识+详细记录部分指令 Linux c 一站式学习 Shell是一个命令行工具。Shell(也称为终端或壳)充当的 是人与内核(硬件)之间的翻译官,用户把一些命令“告诉”终端,它就会调用相应的程序服务去完成某些工作。现在许多主流Linux系统默认使用的终端是Bash(Bourne-Again SHell)解释器。 常用系统工作命令 echo含义:用于在终端输出字符串或变量提取后的值. 12345echo hellohelloecho $SHELL/bin/bash datedate命令用于显示及设置系统的时间或日期,在强大的date命令中输入以“+”号开头的参数,即可按照指定格式来输出系统的时间或日期 123456# date Mon Aug 24 16:11:23 CST 2017 # date "+%Y-%m-%d %H:%M:%S" 2017-08-24 16:29:12 # date "+%j" 244 //显示今天是当年当中的第几天 rebootreboot命令用于重启系统 poweroffpoweroff命令用于关闭系统 wget命令wget命令用于在终端中下载网络文件,格式为“wget [参数] 下载地址”。 12# wget -r -p http://www.linuxprobe.com --2017-08-24 19:31:41-- http://www.linuxprobe.com/ Resolving www.linuxprobe.com... 106.185.25.197 Connecting to www.linuxprobe.com|106.185.25.197|:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: 'www.linuxprobe.com/index.html' psps命令用于查看系统中的进程状态,格式为“ps [参数]”。 top命令top命令用于动态地监视进程活动与系统负载等信息,其格式为top。 pidof命令pidof命令用于查询某个指定服务进程的PID值,格式为“pidof [参数] [服务名称]”。例如,可以使用如下命令来查询本机上sshd服务程序的PID: 12# pidof sshd 2156 kill命令kill命令用于终止某个指定PID的服务进程,格式为“kill [参数] [进程 PID]”。 killall命令killall命令用于终止某个指定名称的服务所对应的全部进程,格式 为:“killall [参数] [进程名称]”。 12345# pidof httpd 13581 13580 13579 13578 13577 13576 # killall httpd # pidof httpd # tip:在系统终端中执行一个命令后想立即停止:Ctrl + C,如果有些命令在执行时不断地在屏幕 上输出信息,影响到后续命令的输入,则可以在执行命令时在末尾添加上一个&符号,这样命令将进入 系统后台来执行。 系统状态监检测命令……部分略…… ifconfigifconfig命令用于获取网卡配置与网络状态等信息,格式为“ifconfig [网络设备] [参数]”。 history命令history命令用于显示历史执行过的命令,格式为“history [-c]”。 能显示最近1000条命令记录。使用-c参数则会清空所有的命令历史记录。 1# history -c 工作目录切换命令 pwd命令pwd命令用于显示用户当前所处的工作目录,格式为“pwd [选项]”。 12# pwd /etc cd命令cd命令用于切换工作路径,格式为“cd [目录名称]”。“cd -”:命令返回到上一次所处的目录,“cd ..”:命令进入上级目录,“cd ~”:命令切换到当前用户的家目录,“cd ~username”:切换到其他用户的家目录。 ls命令ls命令用于显示目录中的文件信息,格式为“ls [选项] [文件] ”。使用ls命 令的“-a”参数看到全部文件(包括隐藏文件),使用“-l”参数可以查看文 件的属性、大小等详细信息。将这两个参数整合之后,再执行ls命令即可 查看当前目录中的所有文件并输出这些文件的属性信息 tips: 隐藏文档一般以 “.” 开头; “.”表示当前路径; “..”表示上一级路径 使用”ls -la”显示的目录:第一列表示文档类型,”d”表示文件夹,”-“表示文件。例如:1234# ls -latotal 2dr-xr-x---, #省略后面部分-rw-------, #省略后面部分 文件文本编辑命令 cat命令cat命令用于查看纯文本文件(内容较少的),格式为“cat [选项] [文件]”。加一个-n参数显示行号 12# cat -n [文件]# cat -n initial-setup-ks.cfg more命令more命令用于查看纯文本文件(内容较多的),格式为“more [选项] [文件]”。 1# more initial-setup-ks.cfg head命令head命令用于查看纯文本文档的前N行,格式为“head [选项] [文件]”。 1# head -n 20 initial-setup-ks.cfg tail命令tail命令用于查看纯文本文档的后N行或持续刷新内容,格式为“tail [选项] [文件]”。tail命令的操作方法与head命令非常相 似,只需要执行“tail -n 20 文件名”命令就可以达到这样的效果。tail命令 最强悍的功能是可以持续刷新一个文件的内容,当想要实时查看最新日志 文件时,这特别有用,此时的命令格式为“tail -f 文件名” 1# tail -f /var/log/messages tr命令tr命令用于替换文本文件中的字符,格式为“tr [原始字符] [目标字符]”。例如,把某个文本内容中的英文全部替 换为大写: 1# cat anaconda-ks.cfg | tr [a-z] [A-Z] wc命令wc命令用于统计指定文本的行数、字数、字节数,格式为“wc [参数] 文本”。 -l 只显示行数-w 只显示单词数-c 只显示字节数 stat命令stat命令用于查看文件的具体存储信息和时间等信息,格式为“stat 文件名称”。 cut命令cut命令用于按“列”提取文本字符,格式为“cut [参数] 文本”。 diff命令diff命令用于比较多个文本文件的差异,格式为“diff [参数] 文件”。使用–brief参数来确认两个文件是否不同,使用-c参数来详细比较出多个文件的差异之处 文件目录管理命令 touch命令touch命令用于创建空白文件或设置文件的时间,格式为“touch [选项] [文件]”。 mkdir命令mkdir命令用于创建空白的目录,格式为“mkdir [选项] 目录”。在Linux系统中,文件夹是最常见的文件类型之一。除了能创建单个空白目录外,mkdir命令还可以结合-p参数来递归创建出具有嵌套叠层关系的文件目录。 123456[root@linuxprobe ~]# mkdir linuxprobe [root@linuxprobe ~]# cd linuxprobe [root@linuxprobe linuxprobe]# mkdir -p a/b/c/d/e [root@linuxprobe linuxprobe]# cd a [root@linuxprobe a]# cd b [root@linuxprobe b]# cp命令cp命令用于复制文件或目录,格式为“cp [选项] 源文件 目标文件”。在Linux系统中,复制操作具体分 为3种情况: 如果目标文件是目录,则会把源文件复制到该目录中; 如果目标文件也是普通文件,则会询问是否要覆盖它; 如果目标文件不存在,则执行正常的复制操作。 4.mv命令mv命令用于剪切文件或将文件重命名,格式为“mv [选项] 源文件 [目标路径|目标文件名]”。 剪切操作不同于复制操作,因为它会默认把源文件删除掉,只保留剪 切后的文件。如果在同一个目录中对一个文件进行剪切操作,其实也就是 对其进行重命名: 123# mv x.log linux.log # ls install.log linux.log rm命令rm命令用于删除文件或目录,格式为“rm [选项] 文件”。在Linux系统中删除文件时,系统会默认向您询问是否要执行删除操作,如果不想总是看到这种反复的确认信息,可在rm命令后跟上-f参数来 强制删除。另外,想要删除一个目录,需要在rm命令后面一个-r参数才可以,否则删除不掉。我们来尝试删除前面创建的install.log和linux.log文件: [root@linuxprobe ~]# rm install.logrm: remove regular empty file ‘install.log’? y[root@linuxprobe ~]# rm -f linux.log[root@linuxprobe ~]# ls[root@linuxprobe ~]# dd命令 dd命令用于按照指定大小和个数的数据块来复制文件或转换文件,格 式为“dd [参数]”。 file命令file命令用于查看文件的类型,格式为“file 文件名”。 在Linux系统中,由于文本、目录、设备等所有这些一切都统称为文件,而我们又不能单凭后缀就知道具体的文件类型,这时就需要使用file命 令来查看文件类型了。 [root@linuxprobe ~]# file anaconda-ks.cfg anaconda-ks.cfg: ASCII text [root@linuxprobe ~]# file /dev/sda /dev/sda: block special 打包压缩与搜索命令 tar命令tar命令用于对文件进行打包压缩或解压,格式为“tar [选项] [文件]”。-c 创建压缩文件 -x 解开压缩文件-t 查看压缩包内有哪些文件-z 用Gzip压缩或解压-j 用bzip2压缩或解压-v 显示压缩或解压的过程-f 目标文件名-p 保留原始的权限与属性-P 使用绝对路径来压缩-C 指定解压到的目录 Vim编辑器 sudo +操作 :使用root权限执行操作 Linux运行有7个级别0-7级。主要3——登录后进入控制台命令行模式;5——登录后进入图形模式; VM下切换图形模式与文字模式:图形下alt+shift+Ctrl+F1~F6切换至命令行模式; man——查看命令使用;查看ls的使用 1man ls vi撤回操作:命令行下 u 和 ctrl+r Linux查询命令帮助 命令是记不完的,但是需要的时候咋办???用查询命令查看 三个命令:man、info、whatis. 使用 man\\info\\whatis 命令 manman 用来查询命令的帮助文档 命令的帮助文件有9个章节: 用户命令 系统调用 C库调用 设备文件及特殊文件 配置文件格式 游戏 杂项 管理类的命令 Linux 内核API man使用 man 命令 man 章节号 命令 whatiswhatis 显示命令的简短描述 whatis 命令 infoLinux软件包管理软件包分为源码包和二进制包(rpm包、系统默认包) 源码包:需经过编译转换为机器语言后系统才能识别和运行。优点:1. 开源;2. 自由选择功能;3. 软件是编译安装的,更适合自己的系统,稳定性和效率更高;4. 卸载方便:直接删除源文件即删除干净,而windows不行。缺点:1. 安装步骤多,容易出错;2. 编译时间长;3. 安装过程报错难以解决。 二进制包:经过了编译的机器语言包,系统能够直接识别和运行——不能看源码、打开是乱码优点:1. 安装包管理简单;2. 安装迅速缺点:1. 不可以看源代码;2. 功能选择不自由;3. 依赖性(装某个应用前提需要另一个应用) RPM包软件安装apt,全称Advanced Packaging Tool,Linux下的一款安装包管理工具,可以在终端方便的进行安装、卸载和更新。 12345678# 1.安装软件$ sudo apt install 软件包# 2.卸载软件$ sudo apt remove# 3.更新软件$ sudo apt upgrade sudo权限使得所有用户都可以使用这个软件。 YUM软件仓库Yum软件仓库便是为了进一步降低软件安装难度和复杂度而设计的技术。Yum软件仓库可以根据用户的要求分析出所需软件包及其相关的依赖关系,然后自动从服务器下载软件包并安装到系统。 命令 作用 yum repolist all 列出所有仓库 yum list all 列出仓库中所有软件包 yum info 软件包名称查看软件包信息 yum install 软件包名称安装软件包 yum reinstall 软件包名称重新安装软件包 yum update 软件包名称升级软件包 yum remove 软件包移除软件包 yum clean all 清除所有仓库缓存 yum check-update 检查可更新的软件包 yum grouplist 查看系统中已经安装的软件包组 yum groupinstall 软件包组安装指定的软件包组 yum groupremove 软件包组移除指定的软件包组 yum groupinfo 软件包组查询指定的软件包组信息 Linux文件系统编程Linux下DIR,dirent,stat等结构体详解","categories":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"}]},{"title":"PC系统的一些概念","slug":"PC系统知识","date":"2020-04-25T08:24:21.000Z","updated":"2020-04-25T08:24:21.000Z","comments":true,"path":"2020/04/25/PC系统知识/","link":"","permalink":"https://zy68.top/2020/04/25/PC%E7%B3%BB%E7%BB%9F%E7%9F%A5%E8%AF%86/","excerpt":"三个程序 Shell 是带有命令提示符(prompt)的用于输入、输出的界面。准确地说,POSIX 桌面底层也运行着一个 Shell,即使这个 Shell 对用户不可见,因为用户会话就是由这个 Shell 启动的。 终端是在图形界面服务器(例如 X11 或 Wayland)中运行的应用程序,其中加载了一个 Shell。只有在终端窗口启动之后,才算是运行了一个终端。终端可以认为是操作 Shell 的一个入口。 控制台(或称“虚拟控制台”)通常表示在桌面环境以外使用的 Shell,你可以通过 Alt+Ctrl+F2 进入控制台,通常情况下从 F3 到 F7 都是不同的控制台,其中桌面环境有可能是 F1 或者 F7,这在不同的发行版中可能会有所不同。","text":"三个程序 Shell 是带有命令提示符(prompt)的用于输入、输出的界面。准确地说,POSIX 桌面底层也运行着一个 Shell,即使这个 Shell 对用户不可见,因为用户会话就是由这个 Shell 启动的。 终端是在图形界面服务器(例如 X11 或 Wayland)中运行的应用程序,其中加载了一个 Shell。只有在终端窗口启动之后,才算是运行了一个终端。终端可以认为是操作 Shell 的一个入口。 控制台(或称“虚拟控制台”)通常表示在桌面环境以外使用的 Shell,你可以通过 Alt+Ctrl+F2 进入控制台,通常情况下从 F3 到 F7 都是不同的控制台,其中桌面环境有可能是 F1 或者 F7,这在不同的发行版中可能会有所不同。 精准搜索①排除关键词(减号+关键词)②精确搜索(给关键词加引号)③指定网站内搜索(site:域名 关键词)④指定文件格式(filetype:文件格式 关键词)⑤指定标题搜索(intitle:关键词)⑥⑦两种指定范围搜索(intext:/allintext:)(inurl:关键词)⑧叠加使用正确提取关键词","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[{"name":"CSBasic","slug":"CSBasic","permalink":"https://zy68.top/tags/CSBasic/"}]},{"title":"字符编码","slug":"字符编码","date":"2020-04-02T03:19:10.000Z","updated":"2020-04-02T03:19:10.000Z","comments":true,"path":"2020/04/02/字符编码/","link":"","permalink":"https://zy68.top/2020/04/02/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81/","excerpt":"几个常见的编码 ASCII 维基百科 来源 || 定义ASCII( /ˈæski/,American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本延伸美国标准信息交换码则可以部分支持其他西欧语言,并等同于国际标准ISO/IEC 646。新名字US-ASCII。 存储实现使用单字节编码,即每个字符占用一个字节(8 bit)的后七位,第一位规定为0。如 字母 ‘A’,在ASCII码中十进制是65,二进制是0100 0001。 把最高位也拿来用之后就称为非ASCII编码,ISO-8859-1编码就是如此。","text":"几个常见的编码 ASCII 维基百科 来源 || 定义ASCII( /ˈæski/,American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本延伸美国标准信息交换码则可以部分支持其他西欧语言,并等同于国际标准ISO/IEC 646。新名字US-ASCII。 存储实现使用单字节编码,即每个字符占用一个字节(8 bit)的后七位,第一位规定为0。如 字母 ‘A’,在ASCII码中十进制是65,二进制是0100 0001。 把最高位也拿来用之后就称为非ASCII编码,ISO-8859-1编码就是如此。 缺点 || 局限ASCII只能显示26个基本的拉丁字符、阿拉伯数字和英式标点符号,共128个字符。仅用于显示现代美国英语。 现大多数系统使用支持更多语言的Unicode。 GB2312 维基百科 来源 || 定义 GB/T 2312,GB/T 2312–80 或 GB/T 2312–1980 是中华人民共和国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,通常简称GB,又称GB0,由中国国家标准总局发布,1981年5月1日实施。GB/T 2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB/T 2312。 GB/T 2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个字符。 存储实现——分区表示 双字节编码 每区含有94个汉字/符号,共计94个区。用所在的区和位来表示字符(实际上就是码位),因此称为区位码(或许叫“区位号”更为恰当)。表示方式也称为区位码。例如“万”字在45区82位,所以“万”字的区位码是:45 82(注意,GB类汉字编码为双字节编码,因此,45相当于高位字节,82相当于低位字节)。 01~09区(682个):特殊符号、数字、英文字符、制表符等,包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母等在内的682个全角字符; 10~15区:空区,留待扩展;在附录3,第10区推荐作为 GB 1988–80 中的94个图形字符区域(即第3区字符之半形版本)。 16~55区(3755个):常用汉字(也称一级汉字),按拼音排序; 56~87区(3008个):非常用汉字(也称二级汉字),按部首/笔画排序; 88~94区:空区,留待扩展。 Unicode 维基百科 来源 || 定义 Unicode是为了解决传统的字符编码方案的局限而产生的。Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。 Unicode 至今仍在不断增修,每个新版本都加入更多新的字符。当前最新的版本为2019年5月公布的12.1.0[2],已经收录超过13万个字符(第十万个字符在2005年获采纳)。Unicode涵盖的数据除了视觉上的字形、编码方法、标准的字符编码外,还包含了字符特性,如大小写字母。 存储实现——分区表示 Unicode是指一张表,里面包含了可能出现的所有字符,每个字符对应一个数字,这个数字称为码点(Code Point),如字符’H’的码点为72(十进制),字符’李’的码点为26446(十进制)。Unicode表包含了1114112个码点,即从000000(十六进制) - 10FFFF(十六进制)。地球上所有字符都可以在Unicode表中找到对应的唯一码点。点击这里,查询字符对应的码点。Unicode将码空间划分为17个平面,从00 - 10(十六进制,最高两位),即从0 - 16(十进制),每个平面有65536个码点(2^16),其中最重要的是第一个Unicode平面(码位从0000 - FFFF),包含了最常用的字符,该平面被称为基本多语言平面(Basic Multilingual Plane),缩写为BMP,其他平面称为辅助平面(Supplementary Planes),在基本多文种平面內, 从D800到DFFF之间的码位区段是永久保留不映射到字符的, 因此UTF-16编码巧妙的利用了这保留下来的码位来对辅助平面内的字符进行编码,这点后面进行讲解。Unicode只是一个符号集,只规定的字符所对应的码点,并没有指定如何存储,如何进行存储出现了不同的编码方案,关于Unicode编码方案主要有两条主线:UCS和UTF。UTF主线由Unicode Consortium进行维护管理,UCS主线由ISO/IEC进行维护管理。 先码一手dalao整理的干货 【字符编码】彻底理解字符编码 对 ASCII、ISO-8859-1、GB2312、BIG5、GBK、Unicode、UCS、UCS-2、UCS-4、UTF、UTF-8、UTF-16进行了整理,并对其中的部分进行了区别比较。 廖雪峰java教程——字符编码","categories":[{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"}],"tags":[]},{"title":"踩坑大杂烩","slug":"踩坑大杂烩","date":"2020-02-23T04:23:20.000Z","updated":"2020-02-23T04:23:20.000Z","comments":true,"path":"2020/02/23/踩坑大杂烩/","link":"","permalink":"https://zy68.top/2020/02/23/%E8%B8%A9%E5%9D%91%E5%A4%A7%E6%9D%82%E7%83%A9/","excerpt":"","text":"坑1————ssh:time out某日夜,想要在github上clone一repo,照常执行 git clone git@……等待片刻: 1234ssh: connect to host github.com port 22: Connection timed outfatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists. 我:😳😳XXX????????继续检查 12ssh -T [email protected]: connect to host github.com port 22: Connection timed out 🌚🌚好吧!找度娘!查博客!解决:在.ssh下有另外三个文件的情况下再建立config文件(文件名无后缀)文件内容: 123456Host github.comUser 'github上的email'Hostname ssh.github.comPreferredAuthentications publickeyIdentityFile ~/.ssh/id_rsaPort 443 完了之后,长这样 再去执行 1ssh -T [email protected] 后面 yes。solved。🍻🍻 坑2–安装MySQL 由于第一次安装MySQL,为了稳定起见,特地找了两篇教程对照着安装。结果…………错错错,都是你的……。(zanghua).没事,我也就一共装了五次🌚🌚,总耗时不下4h罢了.(zanghua)Oh, I am growing right?? Keep calm. 其实最后错误都只是一个:密码错误。 下面按安装顺序记录所有的问题:安装到这一步:finish.successfully finished \\撒花\\撒花。 生活没有那么容易,每个人……🌗🌗 启动某client,闪退 😀😀😀,问题不大,我还能笑。 闪退……闪退……闪退…… 😅😅😅,问题不大,我网上找找。 人家说mysql没在运行,不好意思,我的在跑。 人家说啥啥啥,不好意思,我试了,没用。 😐😐😐………… 修改登录免密码后,启动mysql:本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止 😶😶😶…………(网上教程花里胡哨,不如重装)still……still……still 😣😣😣😖😖😖😡😡😡 access denied for user ‘root‘@’localhost’ (using password:YES) 综合网上解决方案——密码错误………………继续上述第2步……重装。 (崩溃边缘) 重装。 转折来了 既然上述的是密码错误,那我换个密码。 卸载->干净卸载->重装->谨慎重装->输入初始化的root密码->……->finish. 🌚🌚🌚client 启动。 1ENTER PASSWARD:****** done!!!! What happened??? what ?? Thanks god!! Yearh. 总结:不是PC的错,更不是MySQL的错,也不是教程的错,错就错在我输入的密码中有特殊符号,这是我所不能理解的。 教训:特殊条件下,谨慎设密码,越简单越好。 走过,踩过,以后才会少犯错。🌝🌝🌝","categories":[{"name":"Mark","slug":"Mark","permalink":"https://zy68.top/categories/Mark/"}],"tags":[]},{"title":"Github相关","slug":"Github相关","date":"2020-02-21T05:18:58.000Z","updated":"2020-02-21T05:18:58.000Z","comments":true,"path":"2020/02/21/Github相关/","link":"","permalink":"https://zy68.top/2020/02/21/Github%E7%9B%B8%E5%85%B3/","excerpt":"Github上动态浏览历史版本版本控制、版本控制,当我们要浏览历史版本的时候怎么玩才更舒服更香呢?? 这里就有一顿操作——动态可视化看历史版本。 通过更改URL 具体操作:把 URL 中的 https://github.com/ 替换成 https://github-history.netlify.com/,URL的其它部分保持不变。回车即跳转至在酷的版本页面,而且版本转换时支持动态效果。","text":"Github上动态浏览历史版本版本控制、版本控制,当我们要浏览历史版本的时候怎么玩才更舒服更香呢?? 这里就有一顿操作——动态可视化看历史版本。 通过更改URL 具体操作:把 URL 中的 https://github.com/ 替换成 https://github-history.netlify.com/,URL的其它部分保持不变。回车即跳转至在酷的版本页面,而且版本转换时支持动态效果。 通过Chrome插件 上述的操作有Chrome插件:Git History Browser 我还没安排……………… Github上精准搜索如果简单搜索 java ,就会得到一大堆有 java 字眼的项目。 当然或许你可以 Sort 排序一下,emmmm……那必须是个好东西,香~~~,可以根据不同要求排序: 但是那不叫搜索技巧,打扰了~~~ So,look at this >>>>>>>> 1.name:搜索含关键词为名称的项目 不加条件 搜java: in:name java 搜索结果: 可见,结果只是项目名称中包含所搜关键词的,即搜索的中心只在名称上。 添加条件的搜索 in:name java stars:>5000 in:name java forks:>2000 in:name java stars:>5000 forks:>2000 in:name 电商项目 language:java pushed:>YYYY-MM-DD //pushed根据的是最后更新时间 emmmm……图片都一样的捏,都是那几个项目。罢了,重点在文字内容。以此不断细化、减少搜索结果,使得搜索更准确。 2.其他搜索搜索README中含有关键词的项目 in:readme …… 搜索项目描述中含有关键词的项目 in:description …… tips:添加条件操作如同name,No赘述!!!Warning: 禁止用中文输入下的符号 Useless!!! 参考如何在Gihub上面精准搜索开源项目? GitHub 项目徽章的添加和设置————————我还没搞呢。码 Github上动态浏览历史版本参考","categories":[{"name":"git/github","slug":"git-github","permalink":"https://zy68.top/categories/git-github/"}],"tags":[{"name":"github","slug":"github","permalink":"https://zy68.top/tags/github/"}]},{"title":"yaml","slug":"yaml","date":"2020-02-08T06:35:17.000Z","updated":"2020-02-08T06:35:17.000Z","comments":true,"path":"2020/02/08/yaml/","link":"","permalink":"https://zy68.top/2020/02/08/yaml/","excerpt":"简介YAML:全称”Yet Another Markup Language”(仍是一种标记语言)。yaml是以数据中心的标记语言。YAML配置文件的文件后缀是.yml。 基本语法 大小写敏感 使用缩进表示层级关系(只允许使用空格,不允许使用tab) 相同层级左对齐 ‘#’表示注释 数据类型数据类型包括:对象、数组、纯量。","text":"简介YAML:全称”Yet Another Markup Language”(仍是一种标记语言)。yaml是以数据中心的标记语言。YAML配置文件的文件后缀是.yml。 基本语法 大小写敏感 使用缩进表示层级关系(只允许使用空格,不允许使用tab) 相同层级左对齐 ‘#’表示注释 数据类型数据类型包括:对象、数组、纯量。 1. 对象对象:键值对的集合,或称映射。 对象键值对使用冒号结构表示:key: value.冒号后有一个空格,例如: 123key: key1: value1 key2: value2 或者用流式语法表示为key:{key1: value1,key2: value2} 2. 数组yaml以-开头的行表示构成一个数组。例如A、B、C三个数组: 123- A- B- C 多维数组即在一个数组元素下还是一个数组的数组。例如如下二维数组: 1234- - A - B - C 复合结构复合结构即为较为复杂的数组,由对象和数组结合。如C语言等中的结构体数组。例如: 123456789information: - name: Zhangsan age: 20 hight: 175 - name: Lisi age: 21 hight: 170 即information数组有两个元素,每个元素由name、age、hight三个元素组成。亦可以按information: [{name: Zhangsan,age: 20,hight: 175},{name: Lisi,age: 21,hight:170}]表示 3. 纯量纯量是最基本的、不可再分的值。包括: 字符串 字符串默认不用加上单引号或双引号:双引号””:不会转义字符里的特殊字符,长什么样就输出什么样。单引号’’:会转义字符串里的特殊字符。 转义:转换成字符所包含的含义。 布尔值 整数 浮点数 Null 时间 日期 eg: 12345678910111213141516171819202122232425262728String: - 你好 - "hello \\n world" #原样输出 - 'Hello world' #可以使用双引号或者单引号包裹特殊字符 - newline newline2 #字符串可以拆成多行,每一行会被转化成一个空格Boolean: - true #无所谓大小写 - False int: - 123 - 0b1010_0111_0100_1010_1110 #二进制表示float: - 3.14 - 6.8523015e+5 #可以使用科学计数法null: nodeName: 'node' parent: ~ #使用~表示nulldatetime: - 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区date: - 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd 引用通过联合使用下面三个符号实现引用 & :建立锚点 *:引用锚点。 <<:表示合并到当前数据 例如 1234567891011 defaults: &defaults adapter: postgres host: localhostdevelopment: database: myapp_development <<: *defaultstest: database: myapp_test <<: *defaults 相当于: 12345678910111213defaults: adapter: postgres host: localhostdevelopment: database: myapp_development adapter: postgres host: localhosttest: database: myapp_test adapter: postgres host: localhost 特殊符号 ---:表示一个文档的开始,可以用在同一个文件中。亦可用来分割不同内容。如Springboot中的profile定义:123456789101112server: address: 192.168.1.100---spring: profiles: development server: address: 127.0.0.1---spring: profiles: production server: address: 192.168.1.120 参考 菜鸟教程 阮一峰yaml教程 YAML1.2规范.pdf 简书-博文","categories":[{"name":"YAML","slug":"YAML","permalink":"https://zy68.top/categories/YAML/"}],"tags":[{"name":"yaml","slug":"yaml","permalink":"https://zy68.top/tags/yaml/"}]},{"title":"简述博客搭建","slug":"简述博客搭建","date":"2020-01-30T02:51:47.000Z","updated":"2020-01-30T02:51:47.000Z","comments":true,"path":"2020/01/30/简述博客搭建/","link":"","permalink":"https://zy68.top/2020/01/30/%E7%AE%80%E8%BF%B0%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/","excerpt":"","text":"前叙:本博是在Shan San的引路下自己不断摸索整的,主要是有TRHX大佬写的究极详细的小白教程,真的是小白,无脑跟着操作就OK,可先不理解,把东西先做出来,这里安利一下大佬的CSDN专栏 使用 Github Pages 和 Hexo 搭建自己的独立博客【超级详细的小白教程】 Hexo 博客优化之博客美化系列(持续更新) Hexo 博客优化之实用功能添加系列(持续更新) 有了以上大佬的三个专栏,beautiful blog就有了。当然Hexo官方文档是必不可少的。 下面是我自己建博的简要记录:前备知识:HTML + yaml + Git/Github + CSS + JS tips:没有就见啥学啥吧。just like me!didiwanyier。 基础配置要求 Node.js 官网下载 Git 官网下载 Hexo 本地创建 自己新建一个文件夹,用来放博客文件,右键Git Bash here,分别输入如下命令安装 12$ npm install hexo-cli -g $ npm install hexo-deployer-git --save 然后再建个名为Hexo的文件夹,右键Git Bash Here输入$ hexo init进行初始化,接着部署Hexo,执行命令:$ hexo generate然后执行命令$ hexo server运行本地服务器,打开http://localhost:4000/ 打开博客。至此本地博客建好了。 部署到github配置SSH+Git登录个人账户+clone新建的仓库至Hexo文件夹 更换到Hexo官网选一款中意的Hexo主题,阅读Hexo说明书,修改优化主题配置。添加评论系统,我使用的是Valine+它的一个高级扩展。(这里也会有Valine的配置说明要读)到这博客就差不多建好了。更细更个性化可以自己修改主题源代码。 绑定域名+实现https1.运营商买域名 2.域名解析点上图中的解析,然后添加记录,记录的内容按矩形方框所示,然后确定。tips: github的域名即xxx.github.io填的时候io后面还有个 .。 3.建CNAME文件到github博客的source文件夹内创建名为CANME的文件,里面的内容是所购买的域名,不包含前缀。 4.部署发布整完上面博客$ hexo g -d一下。 5.到github上save域名打开github->博客仓->Setting->github page,看图: 6.收获http等一会,几分钟吧!(人家教程都这样说)oh!http://zy68.top,真香!!https不更香??下面就是https踩坑路。 7.整SSL证书回到域名控制台,点击域名列表中购买了的域名,出现该域名的基本信息,点击下面的开启SSL证书,然后出现两个一千多的SSL证书!(打扰了!回去耕田)点击返回证书列表,购买证书oh! free.真香!!!然后那个啥没问题就等签发吧,十分钟不到。 8.github上打钩拿到证书之后到github老位置打√。oh!https,真香!!结束 tips:这里记个坑,如果上述第二步域名解析用了网上其他教程的:还有另外一个解析记录,其中的记录类型为A类型的话,github上的勾勾是不容易√上的,需要做另外的DNS操作。最简单的做法是:把A的解析记录删了,然后去打钩,over。 奉上两篇Shan San整来的official docs: Managing a custom domain for your GitHub Pages site Custom domains on GitHub Pages gain support for HTTPS 其他推荐 从零基于github pages和使用jekyll搭建自己的网站 Creating a Personal Website with Jekyll and GitHub Pages: A Comprehensive Guide","categories":[{"name":"Mark","slug":"Mark","permalink":"https://zy68.top/categories/Mark/"}],"tags":[{"name":"blog","slug":"blog","permalink":"https://zy68.top/tags/blog/"}]},{"title":"didi算法相关知识","slug":"Algorithm","date":"2020-01-28T07:25:10.000Z","updated":"2020-01-28T07:25:10.000Z","comments":true,"path":"2020/01/28/Algorithm/","link":"","permalink":"https://zy68.top/2020/01/28/Algorithm/","excerpt":"数学函数的使用+一些小知识","text":"数学函数的使用+一些小知识 数学函数要使用数学函数首先引入头文件 <math.h> 三角函数 自变量以弧度制,即 度数/180*π,π≈3.1415926. 自变量和返回值均为double型 常用 123456double cos(double x); //返回x的余弦值double sin(double x); //返回x的正弦值double tan(double x); //返回x的正切值int abs(int x); //返回整型数值得绝对值double fabs(double x); //返回双精度double型数值的绝对值pow(3.14,2);//3.14的平方 int都是32位整数,范围是-2147483648~2147483647。 计时函数clock()的使用。该函数返回程序启动到目前为止运行的时间,在程序结束之前调用此函数,便可获得整个程序的运行时间。这个时间除以常数CLOCKS_PER_SEC之后得到的值以“秒”为单位。#include<time.h> 鲁棒性:在算法竞赛中,偶尔会出现输入输出错误的情况。如果程序鲁棒性强,有 时能在数据有瑕疵的情况下仍然给出正确的结果。程序的鲁棒性在工程中也非常重要。 scanf函数有返回值?对,它返回的是成功输入的变量个数,当输入结束时,scanf函数无法再次读取x,将返回0。判断scanf函数的返回值可以增强程序的鲁棒性。 结束输入程序:在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再按Enter键,即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。 当嵌套的两个代码块中有同名变量时,内层的变量会屏蔽外层变量 long long 型 输入输出用 %lld。 .c文件编译后的产生的可执行文件都保存了啥? 编译后的文件与操作系统有关,但都有段的概念,段是指二进制文件内的区域,所有某种特定类型信息被保存在里面。 123D:\\>size a.exetext data bss dec hex filename2756 740 224 3720 e88 a.exe 此结果表示 a.exe由正文段、数据段和 bss 段组成,总大小是3720,用十六进制表示为e88,文件名为 a.exe。其中: 正文段(Text Segment):用于存储指令; 数据段(Data Segment):用于存储已初始化的全局变量; BSS段(BSS Segment):用于存储未赋值的全局变量所需的空间。 对于程序运行中用到的堆栈会在运行时创建,调用栈所在的段称为堆栈段(Stack Segment)。与其他段一样,堆栈段有自己的大小,且不能被越界访问,否则出现段错误(Segmentation Fault)。 参考文档 C语言常用库函数 [经典算法竞赛入门]","categories":[{"name":"Algorithm","slug":"Algorithm","permalink":"https://zy68.top/categories/Algorithm/"}],"tags":[{"name":"C/C++","slug":"C-C","permalink":"https://zy68.top/tags/C-C/"},{"name":"algorithm","slug":"algorithm","permalink":"https://zy68.top/tags/algorithm/"}]},{"title":"javaSE--7.泛型","slug":"javaSE-7-泛型","date":"2020-01-20T11:52:43.000Z","updated":"2020-01-20T11:52:43.000Z","comments":true,"path":"2020/01/20/javaSE-7-泛型/","link":"","permalink":"https://zy68.top/2020/01/20/javaSE-7-%E6%B3%9B%E5%9E%8B/","excerpt":"泛型程序设计意味着编写的代码可以被多中种不同类型的对象所重用。 就是写一个东西,支持好多对象去使用。可简称广泛的类型。 泛型类定义:一个泛型类就是具有一个或多个类型变量的类。","text":"泛型程序设计意味着编写的代码可以被多中种不同类型的对象所重用。 就是写一个东西,支持好多对象去使用。可简称广泛的类型。 泛型类定义:一个泛型类就是具有一个或多个类型变量的类。 例如下面代码 1234567891011121314151617public class Pair<T,U>{ private T first; private U second; public Pair(){ first=null; second= null; } public Pair(T first, U second){ this.first=first; this.second=second; } public T getFirst() {return first;} public U getSecond(){return second;}} Pair类引入了两个类型变量T和U,用尖括号<>括起来,并放在类名后面。泛型类可以有一个或多个类型变量。类型变量名常用短大写形式。 实例化泛型类型:用具体的类型替换类型变量。如上述类:Pair(String,int) ,则所有的T转换为String类型、所有的U转换为int类型。 泛型方法12345class ArrayAlg{ public static <T> T getMiddle(T …a){//注意类型变量所在的位置 return a[a.length/2]; }} 泛型方法可以定义在泛型类中也可以定义在普通类中。调用时在方法名的尖括号内放入具体的类型。也可以不放,编译器自己能够推断出所调用的方法。eg: String middle = ArrayAlg.<String>getMiddle("~",……,"~") 类型变量的限定………… 参考文档 java核心技术 卷1 菜鸟教程","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"Maven","slug":"Maven","date":"2020-01-20T08:13:40.000Z","updated":"2020-01-20T08:13:40.000Z","comments":true,"path":"2020/01/20/Maven/","link":"","permalink":"https://zy68.top/2020/01/20/Maven/","excerpt":"一、简要认识Maven简介:Maven是一个java的项目管理工具,可以对java项目进行构建、依管理。 使用目的:方便添加和更新jar包、解决jar包之间的依赖关系,以及将项目拆分成多个模块。","text":"一、简要认识Maven简介:Maven是一个java的项目管理工具,可以对java项目进行构建、依管理。 使用目的:方便添加和更新jar包、解决jar包之间的依赖关系,以及将项目拆分成多个模块。 二、Maven下载及配置(Windows) 官网下载压缩包 解压压缩包,自定义解压位置,路径尽可能无中文; 配置环境变量a. 新建系统变量命名为MAVEN_HOME;变量值为解压包的路径。eg: F:\\Java\\Maven\\apache-maven-3.6.3b. 编辑系统变量Path,添加变量值: ;%MAVEN_HOME%\\bin 保存退出后到终端运行:mvn -v 命令,显示版本信息则配置成功。 三、了解九个核心概念 POM 坐标 仓库管理 目录结构 生命周期 依赖管理 插件和目标 继承 聚合 tips:maven的各个操作都由各个插件来完成 1.POMProject Object Model:项目对象模型。将 Java 工程的相关 信息* 封装为对象作为便于操作和管理的模型,即包含jar包或jar包的依赖关系的信息。 Maven 工程的核心配置,即在构建过程中所有的相关设置都在这里设置。可以说学习 Maven 就是学习 pom.xml 文件中的配置。 信息是指:jar包等的名称、版本等,即上述概念中的坐标等信息,用于Maven的自动获取并使其参与项目的构建。 2.坐标Maven中的坐标用于确定jar包或jar包的依赖关系的身份(或位置),(如同数学几何中的坐标确定点或物) 使用如下三个向量在 Maven 的仓库中唯一的确定一个jar包。[1]groupid:公司或组织的域名倒序+当前项目名称 //即项目的位置[2]artifactId:当前项目的某一个模块的名称[3]version:当前模块的版本 tips:三坐标简称 “gav” 利用坐标定位jar包位置 例如,我的repository仓库下的一个插件:compile编译插件 123<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version> 组合起来是:"org.apache.maven.plugins" + "maven-compiler-plugin" + "3.8.1"转换为文件路径:org\\apache\\maven\\plugins\\maven-compiler-plugin\\3.8.1 为什么我要用编译插件,因为它花了我一个下午时间,就是编译插件版本太低导致编译出错,关键下了最新版之后还是改不动它,它依旧用的是原版本,先记个仇,后面再解决。 tips:如果是我们自己的Maven工程,则需要执行安装操作才会进入本地仓库:mvn install.?????????? 3.Maven资源(仓)库Maven有三个资源库(或两个:本地和远程) Maven本地资源库:本地存储中项目的依赖库(下载下来的jar包和其他文件)的repository文件夹。默认为C盘用户文件夹下的.m2目录文件里,可自定义保存位置。文件内部如上述定位的例子。 Maven中央存储库:依赖库的来源,即没有的依赖库可到中央存储库下载到本地资源库。默认的仓库是位于国外的Maven仓库,可更换为阿里云的镜像仓库,提高下载速度。中央仓库是远程仓库的特例,或者说常用、资源较多的远程仓库。 镜像仓库用于分担中央仓库的流量,提高用户访问和下载速度。 Maven远程存储库:依赖库的来源,只要能提供所需框架或jar包,都称为远程仓库。在POM.xml文件内自定义中央仓库没有的依赖库的获取路径。 仓库中的文件: Maven的插件 自己开发的项目模块 第三方框架或jar包。 所有的文件按坐标生成的目录结构,以此统一查询或依赖 三者关系:当建立一个Maven项目,Maven会检查pom.xml文件,确定需要哪些依赖库。1. Maven首先从本地资源库寻找,如果本地没有,2. Maven自动到Maven中央存储库去下载,如果中央存储库没有所需依赖,进入第三步。3. 如果pom.xml没有指定依赖库及其获取路径,Maven报错;如果在pom.xml指定了路径,Maven按照路径去到所在的远程仓库下载。 4.目录结构严格的说应该是约定的目录结构,Maven工程的源文件目录,都应该按照Maven的标准设定。 1234567891011项目名||---src //源码目录|---|---main //主程序目录|---|---|---java //主程序下的java源文件目录|---|---|---resources //主程序下的资源文件目录|---|---test //测试程序目录|---|---|---java //测试程序下的java源文件目录|---|---|---resources //测试程序下的资源文件目录| //执行命令后之后会产生不同的文件*|---pom.xml文件 //pom.xml项目配置目录文件 tips:上述的产生不同的文件将在介绍执行命令时解释。 5.Maven的生命周期 1》生命周期之前,先了解一个maven工程构建的几个主要环节:①清理:删除以前的编译结果,为重新编译做好准备。②编译:将 Java 源程序编译为字节码文件。③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。④报告:在每一次测试后以标准的格式记录和展示测试结果。⑤打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应 war 包。⑥安装:在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。⑦部署:将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。tips:环节步步相扣,执行完前一环节才能执行下一环节。 2》再了解自动化构建:即Maven能够自动化执行构建环节从开始到终点。否则是需要人为手动通过命令逐个实现。 3》接下来是生命周期 Maven生命周期:就是定义了各个构建环节的执行顺序,有了这个顺序,Maven才可以自动化执行构建命令。 Maven有三套相互独立的生命周期,分别是:①Clean Lifecycle :在进行真正的构建之前进行一些清理工作。②Default Lifecycle :构建的核心部分,编译,测试,打包,安装,部署等等。③Site Lifecycle :生成项目报告,站点,发布站点。 它们是相互独立的,可以仅仅调用 clean 来清理工作目录,或者仅仅调用 site 来生成站点。当然也可以直接运行 mvn clean install site, 运行所有这三套生命周期。 生命周期是由一组阶段(phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比 如,运行 mvn clean,这个 clean 是 Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段。 Clean 生命周期Clean 生命周期一共包含了三个阶段:①pre-clean 执行一些需要在 clean 之前完成的工作②clean 移除所有上一次构建生成的文件③post-clean 执行一些需要在 clean 之后立刻完成的工作 Site 生命周期①pre-site 执行一些需要在生成站点文档之前完成的工作②site 生成项目的站点文档③post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备④site-deploy 将生成的站点文档部署到特定的服务器上 这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大 的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。 Default 生命周期Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里, 只解释一些比较重要和常用的阶段:validategenerate-sourcesprocess-sourcesgenerate-resourcesprocess-resources 复制并处理资源文件,至目标目录,准备打包。compile 编译项目的源代码。process-classesgenerate-test-sourcesprocess-test-sourcesgenerate-test-resourcesprocess-test-resources 复制并处理资源文件,至目标测试目录。test-compile 编译测试源代码。process-test-classestest 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。 prepare-packagepackage 接受编译好的代码,打包成可发布的格式,如 JAR。 pre-integration-testintegration-testpost-integration-testverifyinstall 将包安装至本地仓库,以让其它项目依赖。deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。 tips:学习了解即可,有maven自动化操作 几个基本的Maven命令mvn install 安装mvn clean 清理mvn compile 编译mvn test 测试mvn package 打包 6.依赖未…………………… 7.插件和目标 Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的 每个插件都能实现多个功能,每个功能就是一个插件目标 Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务。 eg:compile是插件maven-compiler-plugin的一个目标。 未…………………… 8.继承未…………………… 9..聚合将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进 行 clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。 如何配置聚合? 在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可 12345<modules> <module>../Hello</module> <module>../HelloFriend</module> <module>../MakeFriends</module> </modules> 未…………………… 待补:基于IDEA的Maven构建。 参考文档、教程 尚硅谷–Maven教程 视频也就看文档看懵的时候来找找相关的视频,本文档主要根据其讲义总结,侵删!! 易百教程 应该是来源于官方文档,但是翻译有点菜。能看,相对好。 Maven官方","categories":[{"name":"Maven","slug":"Maven","permalink":"https://zy68.top/categories/Maven/"}],"tags":[{"name":"maven","slug":"maven","permalink":"https://zy68.top/tags/maven/"},{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"}]},{"title":"javaSE-4.继承","slug":"javaSE-4-继承","date":"2020-01-17T07:12:21.000Z","updated":"2020-01-17T07:12:21.000Z","comments":true,"path":"2020/01/17/javaSE-4-继承/","link":"","permalink":"https://zy68.top/2020/01/17/javaSE-4-%E7%BB%A7%E6%89%BF/","excerpt":"继承子类 extends 父类 父类的属性和方法子类都有,子类还可增加域、增加方法、覆盖父类的方法,但是不能删除。子类调用父类的方法属性用supper 有些父类私有属性和方法不能够被调用。 有需要可以不断继承,但不可多继承。 不想被继承的类或方法使用final定义。","text":"继承子类 extends 父类 父类的属性和方法子类都有,子类还可增加域、增加方法、覆盖父类的方法,但是不能删除。子类调用父类的方法属性用supper 有些父类私有属性和方法不能够被调用。 有需要可以不断继承,但不可多继承。 不想被继承的类或方法使用final定义。 多态父类变量可以引用其本身的对象或者引用其任何子类的对象。 123Employee e;//Manager类继承了Employe类e= new Employee();//引用其自身的对象e= new Manager();//或者引用子类对象 在对象数组中 1234567class Manager(){ // …… public setBonus(int num){};}Manager boss = new Manager(……);Employee[] staff = new Employee[3];staff[0]=boss; 变量staff[0]与boss引用同一个对象,但编译器将staff[0]看成Employee对象。即使用boss.setBonus(num);可以用,而staff[0].setBonus(num)不可以用。 方法的调用相对底层的机制,………………未完……………… 类的类型转换与一般的数值强制转换相似。 抽象类受保护类 仅对本类可见——private。 对所有类可见——public。 对本包和所有子类可见——protected。 对本包可见——默认(很遗憾),不需要修饰符。 Object类 equals方法equals方法用于检测一个对象是否等于另外一个对象。即判断使用具有相同的引用。 相等测试与继承hashCode方法","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"javaSE--3.面向对象","slug":"javaSE-3.面向对象","date":"2020-01-16T09:16:03.000Z","updated":"2020-01-16T09:16:03.000Z","comments":true,"path":"2020/01/16/javaSE-3.面向对象/","link":"","permalink":"https://zy68.top/2020/01/16/javaSE-3.%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/","excerpt":"前言 Java是完全面向对象的 面向对象的程序是由对象组成的 面向对象:只关注对象(或需求),不关注如何实现。 面向对象与面向过程的差别:","text":"前言 Java是完全面向对象的 面向对象的程序是由对象组成的 面向对象:只关注对象(或需求),不关注如何实现。 面向对象与面向过程的差别: 正文1.类之间的关系 依赖:一个类的方法操控另一个类的对象,称为一个类依赖于另一个类。(即一个类中的对象需要访问另一个类的对象) 聚合:包含关系。即类A的对象包含类B的对象。 继承:一个类B拥有类A方法的基础上还有额外的的功能,称为类B继承类A。 2.构造对象Java中使用构造器(constructor)构造新实例,构造器是一种特殊的方法,用来构造并初始化对象。 例如.构造一个Date对象: 1new Date()// 构造器名为Date(与类名相同),要构造对象,需在构造器前加 new操作符。 另外,可将对象存放在一个变量中,方便多次使用 1Date vari = new Date(); 注: 如例,语句 “Date vari;“, 定义了一个可以引用 Date 类型的对象变量。但变量 vari 不是一个对象,实际上也没有引用对象。即vari只是一个无对象的变量,所以它不能引用任何Date方法。只有在后面构造一个对象或引用一个构造好的Date对象变量才能正常使用。另外,一个对象变量并没有实际包含一个对象,而仅仅是引用一个对象,即对象变量存储的是对某一个对象的引用。 无参构造器: 当类不提供构造器的时候,系统会默认一个构造器。但有构造器时,就必须按照构造器的格式创建对象。 123new ClassName();//类中没有构造器时,由系统默认。————————————分割线————————————new ClassName("张三","20");//类提供了构造器,按构造器格式创建对象。 构造器 重载 调用 下面这个例子很好的解释了:构造器、方法的重载、构造器的调用。 1234567891011121314151617181920212223242526272829303132333435363738394041import static java.lang.System.*; //-导入java.lang.System下全部的静态成员变量--减少代码书写量public class Constructor{ //-定义4个实例变量 public String name; public String color; public double weight; public int age; public static void main(String[] args){ Constructor C=new Constructor("张三","蓝色",65.5,26); out.println(C.name); out.println(C.color); out.println(C.weight); out.println(C.age); } //-创建一个空的构造器 public Constructor(){ } //-创建一个包含2个参数的构造器--构造器重载 public Constructor(String name,String color){ //-部分实例变量赋值 this.name=name; this.color=color; } //-创建一个包含4个参数的构造器--构造器重载 public Constructor(String name,String color,double weight,int age){ //-构造器里面调用其它构造器,格式方法如下: //-1、使用this调用另一个重载构造器,只能在构造器中使用; //-2、必须写在构造器执行体的第一行语句; this(name,color); this.weight=weight; this.age=age; }} 代码源于这里 调用构造器的具体处理步骤 所有数据域被初始化为默认值(0,false,null); 按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块(即包含在单独花括号内的初始化语句); 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体; 执行这个构造器主体。 基础扩展–内存分析 视频文案: 内含Java中栈、堆、方法区的特点。 3.源文件剖析 每一个class类都会生成一个.class源文件,无论在或是不在同一个.java文件中,都会生成,并存放在bin文件夹中。 编写出来的源代码(即.java文件)都保存在src文件夹中。 回顾:javac 命令编译.java文件,生成.class文件。java命令执行.class文件。 4.main方法事实上,每个类都可以有一个main方法,用于对类进行单元测试。 5.包包:介于javac和java之间,用于方便管理源文件的一个文件夹,可以保证类名的唯一性(即即使类名相同但是包不同,类也是不相同)。常用域名的逆序来命名:原序mrgo123.com逆序为com.mrgo123,其源文件位于com/mrgo123文件下。 包(含类、方法、静态方法、静态域)的导入用import。例如上述《构造器 重载 调用》的代码例子。 类路径??? 6.文档注释JDK中javadoc实用程序,能够由源文件生成HTML文件。 注释格式:/** ………… */。注释应放置在所描述特性的前面,每个文档注释在标记后紧跟着自由格式文本,标记由@开始,如@author。javadoc实用程序自动地将这些句子抽出来形成概要页。 在自由格式文本中,可以使用HTML修饰符。 类注释:类注释必须放在import语句之后,类定义之前。 方法注释:放在所描述的方法前。 域注释:对公有域(常指静态常量)建立文档 通用注释。 包注释 ……待研究…… 7.类设计技巧 一定要保证数据私有 一定要对数据初始化 不要在类中使用过多的基本类型(即用其他的类代替多个相关的基本类型的使用) 不是所有的域都需要独立的域访问器和域更改器 将职责过多的类进行分解(例如:一个复杂的类可分解成两个更为简单的类,那就要分解) 类名和方法名要能够体现它们的职责 命名类名的良好习惯是采用一个名词、前面有形容词修饰的名词(RushOrder)或动名词修饰的名词(BillingAddress)。对于方法来说,习惯是访问器方法用小写get开头 (getSalary),更改器方法用小写的set开头(setSalary)。 优先使用不可变的类 参考文献《java核心技术 卷1》","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"javaSE--2.程序结构","slug":"javaSE-2.程序结构","date":"2020-01-14T02:55:39.000Z","updated":"2020-01-14T02:55:39.000Z","comments":true,"path":"2020/01/14/javaSE-2.程序结构/","link":"","permalink":"https://zy68.top/2020/01/14/javaSE-2.%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84/","excerpt":"第二部分 Java的基本程序设计结构 部分特殊字符转义+格式化输出 + 位运算 + 格式化输出 + 命令行参数 + 不规则数组","text":"第二部分 Java的基本程序设计结构 部分特殊字符转义+格式化输出 + 位运算 + 格式化输出 + 命令行参数 + 不规则数组 正文 回车不代表句子结束,即一个句子可以分行写; 1.特殊字符转义特殊字符转义:\\b——退格,\\r——回车 小心注释中的\\u,如果注释中的\\u~是Unicode编码,会在解析代码前得到转义,进而产生语法错误或者改变原来要表达的意思 2.位运算运算时先转换为二进制,再按位运算。 3.格式化输出沿用C语言函数库printf(): System.out.printf(); 格式化输出数值 123System.out.printf("%2f",10000.0/3.0);//输出3333.333333 格式化输出字符 12345System.out.printf("%,.2f",10000.0/3.0);System.out.printf("%,(.2f",10000.0/3.0);//输出3,333.33(3,333.33) 4.命令行参数main方法: 1public static void main(String args){} String args[]参数表明main方法将接收一个字符串数组,也就是命令行参数。 例如. 如果以如下形式运行这个程序 java Message -g cruel world args数组将包含下列内容: 123args[0]:"-g"args[1]:"cruel"args[2]:"world" 结果显示:Goodbye,cruel world! tips:程序名并未储存在args[]中。 5.多维数组中的不规则数组 分配具有所含行数的数组 int[][] adds = new int [NMAX + 1][]; 实际分配的是包含NMAX+1个指针的数组 分配这些行 12for(int n = 0;n <= NMAX; n++) odds[n] = new int[n + 1]; 每个指针单独的创建数组,由此可自定义每行数组的长度 得到不规则数组 由此可见Java只有一维数组,二维数组是由一维数组组合而成。 6.枚举当需要在几个指定的变量中选择时,可以使用枚举类型。 例如,衣服的尺寸有small,medium,large,extraLarge。则可以自定义枚举类型,表示为:enum Size{small,medium,large,extraLarge};然后使用时,声明类型变量:Size s = Size.medium; Size类型变量只能存储这个类型声明中给定的某个枚举值,或者null. 7.大数值运算当基本的数据类型不能满足精度要求时,可以使用java.math包中的两个类:BigInteger:任意精度的整数。BigDecimal:任意精度的浮点数。 将普通的数值转换为大数值,使用静态的valueOf方法 1BigInteger a = BigInteger.valueOf(100); 进行加、减、乘、除时,也不能使用常规的运算符(如+、-、*等),而应该使用add(+)、mutiply (*)、divide(\\)等 ```javaBigInteger c = a.add(c);//c=a+b;BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));//d=c*(b+2); 参考文献《java核心技术 卷1》","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"javaSE--1.环境","slug":"javaSE-1.环境","date":"2020-01-12T13:33:13.000Z","updated":"2020-01-12T13:33:13.000Z","comments":true,"path":"2020/01/12/javaSE-1.环境/","link":"","permalink":"https://zy68.top/2020/01/12/javaSE-1.%E7%8E%AF%E5%A2%83/","excerpt":"","text":"#下载-安装-设置JDK参考网上教程!! #使用命令行运行java文件:HelloWorld.java文件源码: 1234567import java.util.*;public class HelloWorld { public static void main(String[] args) { System.out.print("HelloWorld!!"); }} 打开终端窗口 进入文件所在目录键入: 12javac HelloWorld.java // javac程序是一个java编译器,将.java文件编译成.class文件,可在``HelloWorld.java``前写入路径(用/),eg:javac com/HelloWorld.javajava HelloWorld //java程序启动java虚拟机,虚拟机执行.class文件中的字节码,可在``HelloWorld``前写入路径(用.),eg:java com.HelloWorld 认识一下几个概念: JDK:全称Java Development Kit,编写java程序的软件开发工具包,Java的核心。内含java运行环境、java工具和java基础类库,实现编译和调试功能。 JDK内部包含的基本组件(部分): javac——编译器,将源程序转成字节码,即 .java文件 变 .class文件 java——运行编译后的java程序即运行 .class文件 javadoc——将源文件生成HTML文档 jdb——debugger,查错工具 jar——打包工具,将相关的类文件打包成一个文件 JRE——Java运行环境 ………… 详情见【维基百科——JDK】 JRE:全称Java Running environment,能够提供运行Java程序的环境的一个软件,内含java虚拟机(JVM)和一些标准类库 JVM:全称Java Virtual Machine,Java虚拟机,一种能够运行Java bytecode的虚拟机,能够运行以Java语言编写的软件程序。【维基百科——JVM】 综上 JDK(JRE(JVM)) #使用集成环境 eclipse NetBeans IntelliJ IDEA VScode ——编辑器 tips:备注一下很有意思的java小应用程序applet,用于插入HTML文件中,通过支持java的浏览器浏览。【维基百科——applet】","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"}]},{"title":"简述Java入坑","slug":"简述Java入坑","date":"2020-01-12T13:30:00.000Z","updated":"2020-01-12T13:30:00.000Z","comments":true,"path":"2020/01/12/简述Java入坑/","link":"","permalink":"https://zy68.top/2020/01/12/%E7%AE%80%E8%BF%B0Java%E5%85%A5%E5%9D%91/","excerpt":"记录一下拖了很久的选择开发方向🌚🌚从开始琢磨到找master,然后到最后的确定","text":"记录一下拖了很久的选择开发方向🌚🌚从开始琢磨到找master,然后到最后的确定 #背景事情应该还得从废掉的大一开始,大一的时光,…………啥也不说,也没得说。嗯……直接跳大一下的暑假吧!当时是开始找了master,从他那里找了一些经验,但依旧没能确定下来,因为……菜,仔细的说是对各个开发方向并不了解,所以也没有定下来,然后那个暑假学了点java,因为这点基础,再加上学校上的java水课,我……几乎一个学期也没学多少java,导致后面原以为不错的java才七十多,真不能忍,当然其他的课是真的多。 当时也是没有注意了解各个方向或者说了解得特别少,再加上课多。然后我又成功的忽视了方向的选择,比较庆幸的是没挂,学分绩也稳了一下,现在应该是八十点几吧。(呸!偏题,就是菜) 然后……成功的苟活到了这个寒假,花了十多天搞了blog+Markdown+HTML+Git+github的深入(都是基础),然后寒假十多天后的今天(其实这篇划水文是创建后的第二天写的),经过前面在某乎,还有个掘金吧……摸鱼终于对各个方向有浅薄了解,再结合自身的情况,算法、front-end、……啥的搞不了或者不想搞,终于选了后端。选了后端,然后选一门语言呀,然后再想java or Python,继续搜资料,好像确实java比较香,不过无所谓,然后再去咨询了下master,他直接上来就是java。😲😲那……那就搞呗!就java。然后又去滴滴我助班,毕竟他也是java方向的,估计现在算是全栈吧!华为offer,上来月薪nW,各种福利,不用几年,拥百万,走上人生巅峰,迎取白富美真香!!😍😍。 “学呗”,依旧是他一贯的作风。然后问他写别的自己都不知道是什么的问题!!最后总结就是javaSE(自己加的觉得不够牢固)+javaEE+Spring boot,“够你学的了”,俺继续问……,🔨🔨“你就学弄吧,找个视频教程,老是问解决不了问题”,可不是嘛,问个啥,搞就完了。🌚🌚 然后……还是某乎,真香,我曾…它来着,花里胡哨乱搜:java、java开发经验、java路线、java推荐书籍…………。好了,然后又到gayhub:java、……。最后《java核心技术 卷1》特地找了最新版的(十),还有个《java编程思想》据说圣经,准备入手,贼贵,于我。然后就开撸。 怀着饱满的热情 愉快的心情,开始读,跟着书,一下忘了吃饭,吃了继续搞,new了两篇博文空白页,然后……这是和master在某谷的愉快玩耍。然后it’s time to sleep!! 第二天(0202.01.13),醒来继续刷某乎+gayhub,然后……开始撸现在的blog article。还有一篇是昨天学(不是复习吗😱😱)的一点总结。 #计划然后这里做一个搜集到的花里胡哨的东西的整理吧! Step1.javaSE————《java核心技术 卷1》+《java编程思想》+尚学堂_高淇_JAVA300集最新视频教程+小破站+我的blog+待续………… tips:这一阶段还有《java疯狂讲义》+《Head First Java》。额……都挺多推的,先码着,再说吧!实验楼里的挺想搞一下! 未完待续…… Step2.javaEE+Spring boot 暂定 Tips: 只是做个关于java的简单记录和规划,更细致的还在脑图里。另外还有别的CS基础的,准备分专业,到时候综合看着学吧!然后立个flag:每学一个章节到blog写一次总结 路很长,也艰辛,但,还算享受。⏳⏳ 这里appreciate: Shan San大大😘😘 助班 Others 未完待续……","categories":[{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"}],"tags":[]},{"title":"Git基础","slug":"Git基础","date":"2020-01-10T06:47:10.000Z","updated":"2020-01-10T06:47:10.000Z","comments":true,"path":"2020/01/10/Git基础/","link":"","permalink":"https://zy68.top/2020/01/10/Git%E5%9F%BA%E7%A1%80/","excerpt":"简要记录Git原理及常用操作Git思维导图","text":"简要记录Git原理及常用操作Git思维导图 Background: 经过这几天的摸鱼,以及阅读部分Git文档的相关内容后,Git学习暂时够用了,就暂时不深入学习,所以来做个总结记录mark一下,Let’s go!work more!BB less! #前言copy了一份鹅厂某猿的Git思维导图(含命令)——Git思维导图 概念简介Git:是一个开源的分布式版本控制系统定位:项目管理工具 #各部分内容一、登录下载配置完之后开始使用,首先登录自己的github账户,使github与本地关联。 $ git config –global user.name “用户名” $ git config –global user.email 邮箱 tips:--global的作用相当于在该Git下执行的账户作为默认账户,否则每次得登录。如要更换账户,把--global去掉重新输入要更换的账户即可。 二、查看配置信息 $ git config –list tips:显示账户等信息 三、创建及初始化仓库 法一:本地建仓: #使某一文件夹变为仓库 $ git init 推送还需在github上创建一个新的仓库或使用已有的仓库作为远程仓库,推送时自定义远程仓库 #先远程和本地关联$ git remote add origin [目的仓库url] #再推送$ git push -u origin master tips:在本地初始化一个Git仓库。 法二:直接从远程仓库上clone: $ git clone [目的仓库url] (filename) tips:直接克隆仓库到本地,filename可以自己定义,或者不定义。 四、Git内部工作原理 待续……………… 五、分支管理 首先可以fork + clone自己的仓库 + 修改 然后选择性执行如下命令 1234567891011121314151617181920212223# 1. 查看当前分支命令 (直接clone下来的是 master 主干)$ git branch #查看所有分支命令 (查看改仓库的所有分支,显示分支列表)$ git branch -a# 查看所有分支的详细信息$ git branch -avv# 2. 新建分支命令 (新建一个名为 branchName 的分支)$ git branch branchName#删除分支命令 (删除名为 branchName分支,强制删除-D)$ git branch -d branchName# 3. 切换分支命令 (切换名为 branchName 分支)$ git checkout branchNname# 4. 在某分支上推送更新 (在 branchName分支上推送)$ git push origin branchName# 把A分支合并到当前分支(修改的是指针)$ git merge A 备注更改主分支名:git branch -M main 受种族歧视问题影响,master分支更改为main分支,使用此命令可将master改为main。 tips:若不新建分支将在master分支上操作。但是这样做merge的时候不好。 push之后到自己的仓上点 New pull request 。 六、关于fork之后跟源仓的同步由于fork之后是属于自己的project,所以fork到自己账户上的project并不会随着源仓更新而更新。所以当需要跟源仓同步时: 12345678#1.添加源仓为自己fork后仓库的上游$ git remote add upstream 源仓clone地址#2.同步fetch上游仓库代码$ git checkout master && git fetch upstream#3.将上游代码合并至自己fork后的仓库(master分支)中,保证自己的master分支永远是最新版本$ git merge upstream/master 详细可参考–git 如何更新 fork 的项目到原项目的最新版本 分支策略 fast-forward快速合并:原当前分支内容merge是基于这个分支的最新版本而进行新开发的分支(例如从master分出一个分支dev,dev做了修改,而master没动,然后master又merge bev) 若不使用此策略而要新生成一个版本,可以commit或merge时使用 --no-ff。 三方分支 原分支分出了新分支,两个分支都改了,然后再merge。其结果是再merge的当前分支新增一个二者的合并版本 七、版本控制当你想回退到以前某一个版本的时候,就需要用到Git最核心、最关键的一部分————版本控制。 比如这里初始化了一个仓库,新建一个README.md文件,并进行三次内容编写,每一次内容保存后提交(commit)。 1234567891011121314151617181920212223242526272829# 第三个版本内容ASUS@HZY MINGW64 /f/test (master)$ cat README.mdThe first version.The second version.The third version.# 日志展示——三个版本ASUS@HZY MINGW64 /f/test (master)$ git logcommit d5a1be6b560ac343de2271eed87c9f81e01fe8d9 (HEAD -> master)Author: MrGo123 <250……@qq.com>Date: Tue Mar 3 15:40:40 2020 +0800 rebuild(readme.md):third versioncommit 1843f71797e8ffa2f27e18a7c01a6aa8831ff032Author: MrGo123 <250……@qq.com>Date: Tue Mar 3 15:38:41 2020 +0800 reBuild(readme.md):second versioncommit 0c3671095671c29d64d14321da9980bddff991c9Author: MrGo123 <250……@qq.com>Date: Tue Mar 3 15:36:20 2020 +0800 build(readme.md):Add README.md tips:1.日志内容太多可以用 $ git log --pretty=oneline 来单行显示。 2.commit id(版本号)就是commit后面的十六进制码。 1234# 查看简易日志git log --online # 查看简易日志且显示分支结构图git log --online --graph 可以看到HEAD指向最新版本也就是 third version。 123456789┌────┐│HEAD│└────┘ │ └──> ○ third version │ ○ second version │ ○ Add README.md 开始退回版本,使用到git reset命令。在Git中,用HEAD表示当前版本,也就是最新的提交d5a1be…,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。 1$ git reset --hard HEAD^ 回退到第二个版本。 123456789┌────┐│HEAD│└────┘ │ │ ○ third version │ │ └──> ○ second version │ ○ Add README.md 想要回退到第三个版本,即最新的版本。可以用版本号(commit id)来回退。 1$ git reset --hard d5a1be #id的前部分 回退后结构: 123456789┌────┐│HEAD│└────┘ │ └──> ○ third version │ ○ second version │ ○ Add README.md 若关闭了当前的Bash窗口,commit id不见了怎么办,可以用 git relog 查看所有的版本,用显示的 commit id回退版本。 八、添加SSH关联**SSH(Secure Shell,安全外壳协议)**:是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。——维基 所以,在git和GitHub之间使用SSH关联,可以实现1.免登录git push,2.提高数据传输速度以及安全性。 实现本地Git和Github关联: 终端执行 ssh-keygen 命令按几次回车生成公私钥,公私钥存放在主目录下的隐藏目录 .ssh 中的两个文件中; 1$ ssh-keygen -t rsa -C "your [email protected]" 将公钥的内容复制到剪切板 1$ clip < ~/.ssh/id_rsa.pub 到github的账户信息处进入 Setting ➡ SSH and GPG Keys ➡ New SSH Key ➡ Title随意、Key粘贴 ➡ Add SSH Key。done! 测试,git bash下执行如下命令1$ ssh -T [email protected] 按提示输入yes,显示successful则成功。 九、冲突解决在日常的开发中,两个分支对同一部分内容做了修改并提交时,会发生冲突,导致一方提交不上去。 解决方法是:提交不上去的一方首先pull最新的版本,然后再提交commit,然后根据冲突内容对文件进行修改(选择哪一方的或重新修改作为最后的提交内容),再提交commit。 结合动态图认识一个命令??这里还没消化,先码 用动图展示 10 个 Git 命令 十、stash储藏储藏,顾名思义就是藏起来,在git中就是藏起来,使得在工作区中看不见,即清空工作区,但是是可恢复的。好处就是在“清空”之后我们可以做其他事情,当这个事情做完之后,我们又可以恢复回藏起来时的状态。命令如下: 123456789101112# 储藏git stash# 查看储藏仓情况git stash list# 恢复储藏的内容 方式一:恢复后stash内容不删除git stash apply# 恢复储藏的内容 方式一:(接上一条命令)删除恢复后stash内容git stash drop# 恢复储藏的内容 方式二:恢复后stash内容删除git stash pop# 恢复指定的内容先使用“git stash list”,再指定git stash apply stash@{0} #其他辅助内容一、commit规范@(译)通过 Git 和 Angular 了解语义化提交信息 #参考文档or推荐 《Pro Git》 Git官方Book,Chinese,详细+全面+官方,但就是太详细了,内容挺多的,留着日后再啃吧 git - 简明指南 github上的项目,这个必须强推,常用且全面的操作都有,表层操作的话,够了,日常有需要可以翻翻 阿里云Git 阿里云的Git教程其实是菜鸟的,基础的方面都有,看得更舒服,读着更爽。 github flow github guide,说明指导Git及github上协作的工作流程。 commit规范 整理的commit规范写法。 廖雪峰的Git教程 版本控制部分 使用 Github Pages 和 Hexo 搭建自己的独立博客【超级详细的小白教程】 SSH关联 git-cheatsheet.pdf 精简主要命令pdf","categories":[{"name":"git/github","slug":"git-github","permalink":"https://zy68.top/categories/git-github/"}],"tags":[{"name":"Git","slug":"Git","permalink":"https://zy68.top/tags/Git/"}]},{"title":"HTML划水","slug":"HTML划水","date":"2020-01-06T02:38:03.000Z","updated":"2020-01-06T02:38:03.000Z","comments":true,"path":"2020/01/06/HTML划水/","link":"","permalink":"https://zy68.top/2020/01/06/HTML%E5%88%92%E6%B0%B4/","excerpt":"整理一下HTML的知识要点","text":"整理一下HTML的知识要点 background: 博客新建好了,需要的前端知识也就更多了,所以抽时间重新补一the front-end knowledge。本篇是HTML的部分内容,仅记录部分常见常用稍微重点的标签或知识。下面直接开始吧,敲就完了!!!(奥利给) #前言HTML简介HTML 指的是超文本标记语言 (Hyper Text Markup Language) 简单的说就一对标签加个属性就完了 #正文一、基础1.HTML文档结构12345678910<!DOCTYPE HTML><html><body><h1>第一个一级标题</h1><p>第一个段落</p></body></html> 2.四个基础标签1234567891.标题(<h1>~<h6>) eg:<h6>六级</h6>2.段落(<p>) eg:<p>段落内容</p>3.链接(<a>) eg:<a href="https://mrgo123.github.io" alt="我的博客地址">MrGo123</a>4.图像(<img src="url" width="宽" height="高" />) eg:<img src="url" width="100" height="100" /> tips:<img />是个"自闭"标签😅😅 3.语法(标签+元素+属性)1234标签:开始标签<~>和结束标签</~>元素:处于开始和结束标签之间的内容 <~>我是元素</~>属性:可以理解为自定义标签的样式 <a href="" alt=""></a>—— href和alt就是属性 重点强调:class、id、style 二、其他重点标签介绍1.CSS样式—<style>属性 外部样式() 123<head><link rel="stylesheet" type="text/css" href="mystyle.css"></head> HTML与CSS文档分离样式,可多个HTML文档引用 内部样式 123456<head><style type="text/css">body {background-color: red}p {margin-left: 20px}</style></head> 对单个HTML文件内统一定义样式 内联样式 1<p style="font-family:verdana;color:red">This is a paragraph</p><!--结果是字体是verdana,字体颜色是红色--> This is a paragraph 对单个标签定义样式 2.表格 每个表格由 table 标签开始 每个表头由 th 标签开始 每个表格行由 tr 标签开始 每个表格数据由 td 标签开始 12345678910111213141516171819202122232425262728293031323334<p>一列:</p><table border="0"><tr> <td>100</td></tr></table><p>一行三列:</p><table border="1"><tr> <td>100</td> <td>200</td> <td>300</td></tr></table><p>两行三列:</p><table border="10"><tr><th>Heading1</th><th>Heading2</th><th>Heading3</th></tr><tr> <td>100</td> <td>200</td> <td>300</td></tr><tr> <td>400</td> <td>500</td> <td>600</td></tr></table> 一列: 100 一行三列: 100 200 300 两行三列: Heading1 Heading2 Heading3 100 200 300 400 500 600 border是表格属性,用于定义边框粗细程度 3.列表a. 有序列表 12345<ol><li>one</li><li>two</li><li>three</li></ol> one two three b. 无序列表 123456<ul><li>HTML</li><li>CSS</li><li>JavaScript</li><li>Markdown</li></ul> HTML CSS JavaScript Markdown c. 定义列表 自定义列表以 <dl> 标签开始。 每个自定义列表项以 <dt> 开始。 每个自定义列表项的定义以 <dd> 开始。 123456<dl><dt>项目1</dt><dd>……项目里的内容……</dd><dt>项目2</dt><dd>……项目里的内容……</dd></dl 项目1 ……项目里的内容…… 项目2 ……项目里的内容…… 4.块 块级元素 <div> eg: <h1>, <p>, <ul>, <table>,<div>,…… <div> :是可用于组合其他HTML元素的容器 123<div style="color:#00FF00"> <p>This is a paragraph.</p></div> This is a paragraph. 内联元素 <span> eg: <b>, <td>, <a >, <img >,…… <span> : 可做文本容器 1This is a <span style="font-family:verdana;color:red"> span </span> tag. This is a span tag. 5.类Class类:可以简单理解为对HTML进行分类,使我们能够为元素的类定义不同的CSS样式。直接看例子: 12345678910111213141516<style>.cities { background-color:lightBlue; color:white; margin:00px; padding:10px;} </style><div class="cities"><p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p></div> .cities { background-color:lightBlue; color:white; margin:0px; padding:10px; } London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants. 首先提取结构主要有:<div> 、<style>。再看<div>中的class(这就是div元素的类,其类名为 cities),再看<style>内有 “.cities{……}“ ,“……”号里的就是类为cities的<div>的自定义属性。 <style>即为上述 CSS样式 ,其内部{……}属性详请学习CSS 6.布局HTML布局有三种形式 使用<div>元素布局使用<div>元素,通过CSS对其进行样式(含定位)调整 使用HTML5的网站布局 语义元素 代表属性 header 定义文档或节的页眉 nav 定义导航链接的容器 section 定义文档中的节 article 定义独立的自包含文章 aside 定义内容之外的内容(如侧栏) footer 定义文档或节的页脚 details 定义额外的细节 summary 定义details元素的标题 使用表格布局可以使用<table>表格表格化页面,用CSS样式调整表格样式 7.HTML响应式设计响应式设计:即能够改变网页尺寸(对不同设备有不同的网页显示效果) 创建:1.自己创建;2.使用现成的CSS框架 eg:Bootstrap 8.框架作用:实现在同一个窗口显示多个页面 标签: 框架结构标签<frameset> 框架标签<frame> 设置了一个两列的框架集。第一列被设置为占据浏览器窗口的 25%。第二列被设置为占据浏览器窗口的 75%。HTML 文档 “frame_a.htm” 被置于第一个列中,而 HTML 文档 “frame_b.htm” 被置于第二个列中: 1234<frameset cols="25%,75%"> <frame src="frame_a.htm"> <frame src="frame_b.htm"></frameset> 还有个内联框架<iframe>:在页面中自定义嵌入网页 9.HTML脚本HTML脚本:<script>标签 详学见JavaScript 10.文件路径 路径 描述 <img src=\"picture.jpg\"> picture.jpg 位于与当前网页相同的文件夹 <img src=\"images/picture.jpg\"> picture.jpg 位于当前文件夹的 images 文件夹中 <img src=\"/images/picture.jpg\"> picture.jpg 当前站点根目录的 images 文件夹中 <img src=\"../picture.jpg\"> picture.jpg 位于当前文件夹的上一级文件夹中 绝对路径和相对路径,优先相对路径(表上均为相对路径) 11.字符实体空格——&nbsp; 三、重点标签补充未完待续………… ***2 #参考文档 w3school 菜鸟教程 Tips:本页摘要内容基于以上两个网站的HTML教程,部分案例题材亦取于以上网站,如有侵权,还请联系我删除,thanks!!!","categories":[{"name":"HTML","slug":"HTML","permalink":"https://zy68.top/categories/HTML/"}],"tags":[{"name":"HTML","slug":"HTML","permalink":"https://zy68.top/tags/HTML/"}]},{"title":"Markdown练习","slug":"markdown摘要练习","date":"2019-12-29T16:06:54.000Z","updated":"2019-12-29T16:06:54.000Z","comments":true,"path":"2019/12/29/markdown摘要练习/","link":"","permalink":"https://zy68.top/2019/12/29/markdown%E6%91%98%E8%A6%81%E7%BB%83%E4%B9%A0/","excerpt":"","text":"前言Markdown是一种轻量级标记语言 正文1.标题123456# 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题###### 六级标题 一级标题(有下划线)二级标题三级标题四级标题五级标题六级标题 2.块 块实现 123456> 无嵌套>> 一层嵌套 > >>> 两层嵌套> >>>> 三层嵌套(n层……) 无嵌套 一层嵌套 两层嵌套 三层嵌套(n层……) 块段落换行 123456> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. >> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisseid sem consectetuer libero luctus adipiscing. This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisseid sem consectetuer libero luctus adipiscing. 块中包含其他元素 123> ## 二级标题>> 1. This ***is the first list*** item. 二级标题 This is the first list item. 3.表格|分单元格,-分表头和行 12345格式:| 表头1 | 表头2 || ---- | ---- || 单元格 | 单元格 || 单元格 | 单元格 | 表头1 表头2 单元格 单元格 单元格 单元格 对齐 -: 设置内容和标题栏居右对齐。 :- 设置内容和标题栏居左对齐。 :-: 设置内容和标题栏居中对齐。 12345eg:| 左对齐 | 右对齐 | 居中对齐 || :----- | ----: | :----: || 单元格 | 单元格 | 单元格 || 单元格 | 单元格 | 单元格 | 左对齐 右对齐 居中对齐 单元格 单元格 单元格 单元格 单元格 单元格 4.无序列表(*,+,-)123456789101112*:* 一* 二* 三+:+ a+ b+ c -:- 1- 2- 3 *: 一 二 三 +: a b c -: 1 2 3 段落样式 1234567* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,viverra nec, fringilla in, laoreet vitae, risus.* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. > :包含块>需要缩进四个空格或者一个制表符tab Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 包含块>:需要缩进四个空格或者一个制表符tab 5.有序列表(数字+.)1234567891011121. one8. two78. three``` 1. one2. two3. three ***### 6.代码块 tab这是一块代码tab通常只需每行(或首行)开头一个tab即可(看当前格式而定)tab动手敲敲 12345678910 这是一块代码 通常只需每行(或首行)开头一个tab即可(看当前格式而定) 动手敲敲 ___### 7.转换HTML字符实体 © 2004 Foo Corporation 12345678910<div class="footer"> &copy; 2004 Foo Corporation</div>---### 8.水平线(*,-,_ 三个三个以上均可) *** * * * ************ - - - --- _ _ _ 123456789101112131415**** * * ************- - - ---_ _ _<br />---### 9.链接1. 内联的链接 格式:[显示的信息](链接地址 \"链接标题\") eg: his is [an example](http://example.com/ \"Title\") inline link.(有链接标题) [This link](http://example.net/) has no title attribute. 123456 This is [an example](http://example.com/ "Title") inline link. [This link](http://example.net/) has no title attribute.2. 引用的链接 由两部分构成(两中括号,第二个): This is [an example] [id] reference-style link. (隔行) [id]: http://example.com/ \"Optional Title Here\" 123456789 This is an example [id] reference-style link. [id]: http://example.com/ "Optional Title Here"***### 10.强调用*或_ *星号斜体强调* _下划线斜体强调_ **星号加粗强调** __下划线加粗强调__ 1234567891011121314 *星号斜体强调* _下划线斜体强调_ **星号加粗强调** __下划线加粗强调__***### 11.代码片段 格式:\\```片段 \\``` ```javascript(可指定编程语言) $(document).ready(function () { alert('RUNOOB'); }); 123$(document).ready(function () { alert('RUNOOB');}); 12.图片 链接的格式上加“!” 1234即:![图片名](链接 "链接标题")eg:![Alt text](https://cdn.jsdelivr.net/gh/MrGo123/[email protected]/headPortrait/mybloghp.jpg)![Alt text](https://cdn.jsdelivr.net/gh/MrGo123/[email protected]/headPortrait/mybloghp.jpg "我的头像") 引用图片 12![Alt text][id][id]: url/to/image "Optional title attribute" 13.反斜杠转义123456789101112\\\\ \\` \\* \\_ \\{\\} \\[\\] \\(\\) \\# \\+ \\- \\. \\! \\`*_{}[]()#+-.! 部分写作常用内容插入B站播放外链简略步骤:某视频下点击分享–>copy“嵌入代码”–>copy下面代码并更改src–>插入完成。 12345{% raw %}<div style="position: relative; width: 100%; height: 0; padding-bottom: 75%;"><iframe src="//player.bilibili.com/player.html?aid=43896218&cid=76952146&page=64" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;"></iframe></div>{% endraw %} 参考文档及推荐文档 Mrakdown中文文档 内容翻译于Markdown创始人 John Gruber 的博客 菜鸟教程 能够补充部分Markdown中文文档没有的部分,有编写演示 Markdown中文网 内容跟Markdown中文文档差不多,联合起来瞅瞅,多多参考","categories":[{"name":"markdown","slug":"markdown","permalink":"https://zy68.top/categories/markdown/"}],"tags":[{"name":"markdown","slug":"markdown","permalink":"https://zy68.top/tags/markdown/"}]}],"categories":[{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/categories/Spring/"},{"name":"Experience","slug":"Experience","permalink":"https://zy68.top/categories/Experience/"},{"name":"Cloud Native","slug":"Cloud-Native","permalink":"https://zy68.top/categories/Cloud-Native/"},{"name":"ComputerBasic","slug":"ComputerBasic","permalink":"https://zy68.top/categories/ComputerBasic/"},{"name":"Database","slug":"Database","permalink":"https://zy68.top/categories/Database/"},{"name":"HTTP","slug":"HTTP","permalink":"https://zy68.top/categories/HTTP/"},{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/categories/MySQL/"},{"name":"Algorithm","slug":"Algorithm","permalink":"https://zy68.top/categories/Algorithm/"},{"name":"git/github","slug":"git-github","permalink":"https://zy68.top/categories/git-github/"},{"name":"Mark","slug":"Mark","permalink":"https://zy68.top/categories/Mark/"},{"name":"JavaSE","slug":"JavaSE","permalink":"https://zy68.top/categories/JavaSE/"},{"name":"Design Patterns","slug":"Design-Patterns","permalink":"https://zy68.top/categories/Design-Patterns/"},{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/categories/Linux/"},{"name":"C/C++","slug":"C-C","permalink":"https://zy68.top/categories/C-C/"},{"name":"Tool","slug":"Tool","permalink":"https://zy68.top/categories/Tool/"},{"name":"JavaWeb","slug":"JavaWeb","permalink":"https://zy68.top/categories/JavaWeb/"},{"name":"YAML","slug":"YAML","permalink":"https://zy68.top/categories/YAML/"},{"name":"Maven","slug":"Maven","permalink":"https://zy68.top/categories/Maven/"},{"name":"HTML","slug":"HTML","permalink":"https://zy68.top/categories/HTML/"},{"name":"markdown","slug":"markdown","permalink":"https://zy68.top/categories/markdown/"}],"tags":[{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://zy68.top/tags/SpringBoot/"},{"name":"Email","slug":"Email","permalink":"https://zy68.top/tags/Email/"},{"name":"ComputerNetworks","slug":"ComputerNetworks","permalink":"https://zy68.top/tags/ComputerNetworks/"},{"name":"年终总结","slug":"年终总结","permalink":"https://zy68.top/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"},{"name":"Cloud Computing","slug":"Cloud-Computing","permalink":"https://zy68.top/tags/Cloud-Computing/"},{"name":"Cloud Native","slug":"Cloud-Native","permalink":"https://zy68.top/tags/Cloud-Native/"},{"name":"Springboot","slug":"Springboot","permalink":"https://zy68.top/tags/Springboot/"},{"name":"Ubuntu","slug":"Ubuntu","permalink":"https://zy68.top/tags/Ubuntu/"},{"name":"MySQL","slug":"MySQL","permalink":"https://zy68.top/tags/MySQL/"},{"name":"Database","slug":"Database","permalink":"https://zy68.top/tags/Database/"},{"name":"network","slug":"network","permalink":"https://zy68.top/tags/network/"},{"name":"cors","slug":"cors","permalink":"https://zy68.top/tags/cors/"},{"name":"database","slug":"database","permalink":"https://zy68.top/tags/database/"},{"name":"algorithm","slug":"algorithm","permalink":"https://zy68.top/tags/algorithm/"},{"name":"greedy","slug":"greedy","permalink":"https://zy68.top/tags/greedy/"},{"name":"divide and conquer","slug":"divide-and-conquer","permalink":"https://zy68.top/tags/divide-and-conquer/"},{"name":"annual summary","slug":"annual-summary","permalink":"https://zy68.top/tags/annual-summary/"},{"name":"github","slug":"github","permalink":"https://zy68.top/tags/github/"},{"name":"git","slug":"git","permalink":"https://zy68.top/tags/git/"},{"name":"blog","slug":"blog","permalink":"https://zy68.top/tags/blog/"},{"name":"CI/CD","slug":"CI-CD","permalink":"https://zy68.top/tags/CI-CD/"},{"name":"Github","slug":"Github","permalink":"https://zy68.top/tags/Github/"},{"name":"java","slug":"java","permalink":"https://zy68.top/tags/java/"},{"name":"javaSE","slug":"javaSE","permalink":"https://zy68.top/tags/javaSE/"},{"name":"Spring","slug":"Spring","permalink":"https://zy68.top/tags/Spring/"},{"name":"UML","slug":"UML","permalink":"https://zy68.top/tags/UML/"},{"name":"Linux","slug":"Linux","permalink":"https://zy68.top/tags/Linux/"},{"name":"C","slug":"C","permalink":"https://zy68.top/tags/C/"},{"name":"shell","slug":"shell","permalink":"https://zy68.top/tags/shell/"},{"name":"rebuild","slug":"rebuild","permalink":"https://zy68.top/tags/rebuild/"},{"name":"English","slug":"English","permalink":"https://zy68.top/tags/English/"},{"name":"SQL","slug":"SQL","permalink":"https://zy68.top/tags/SQL/"},{"name":"C++","slug":"C","permalink":"https://zy68.top/tags/C/"},{"name":"CSBasic","slug":"CSBasic","permalink":"https://zy68.top/tags/CSBasic/"},{"name":"tool","slug":"tool","permalink":"https://zy68.top/tags/tool/"},{"name":"javaWeb","slug":"javaWeb","permalink":"https://zy68.top/tags/javaWeb/"},{"name":"http","slug":"http","permalink":"https://zy68.top/tags/http/"},{"name":"网络","slug":"网络","permalink":"https://zy68.top/tags/%E7%BD%91%E7%BB%9C/"},{"name":"yaml","slug":"yaml","permalink":"https://zy68.top/tags/yaml/"},{"name":"C/C++","slug":"C-C","permalink":"https://zy68.top/tags/C-C/"},{"name":"maven","slug":"maven","permalink":"https://zy68.top/tags/maven/"},{"name":"Git","slug":"Git","permalink":"https://zy68.top/tags/Git/"},{"name":"HTML","slug":"HTML","permalink":"https://zy68.top/tags/HTML/"},{"name":"markdown","slug":"markdown","permalink":"https://zy68.top/tags/markdown/"}]}