<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ggball's blog</title><link>https://www.ggball.top/</link><description>Recent content on ggball's blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 00:36:55 +0800</lastBuildDate><atom:link href="https://www.ggball.top/index.xml" rel="self" type="application/rss+xml"/><item><title>Redis 6.0的新特性：多线程、客户端缓存与安全</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis-6-0%E7%9A%84%E6%96%B0%E7%89%B9%E6%80%A7%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%BC%93%E5%AD%98%E4%B8%8E%E5%AE%89%E5%85%A8/</link><pubDate>Mon, 18 May 2026 00:36:55 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis-6-0%E7%9A%84%E6%96%B0%E7%89%B9%E6%80%A7%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%BC%93%E5%AD%98%E4%B8%8E%E5%AE%89%E5%85%A8/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis 官方在今年 5 月份正式推出了 6.0 版本，这个版本中有很多的新特性。所以，6.0 刚刚推出，就受到了业界的广泛关注。&lt;/p&gt;
&lt;p&gt;所以，在课程的最后，我特意安排了这节课，想来和你聊聊 Redis 6.0 中的几个关键新特性，分别是面向网络处理的多 IO 线程、客户端缓存、细粒度的权限控制，以及 RESP 3 协议的使用。&lt;/p&gt;</description></item><item><title>关于</title><link>https://www.ggball.top/about/</link><pubDate>Mon, 18 May 2026 00:00:00 +0800</pubDate><guid>https://www.ggball.top/about/</guid><description>关于我和这个站点</description></item><item><title>AIIDE</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/aiide/</link><pubDate>Fri, 07 Mar 2025 17:15:08 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/aiide/</guid><description>&lt;h1 id="ai-ide工具"&gt;ai ide工具&lt;/h1&gt;
&lt;h2 id="cursor"&gt;cursor&lt;/h2&gt;
&lt;p&gt;是一款集成了人工智能辅助功能的代码编辑器，旨在为程序员提供更便捷、高效的编程体验。 它利用先进的人工智能技术，能够帮助开发者快速生成代码、修改代码、查找错误以及回答各种与代码相关的问题，极大地提升了开发效率和质量&lt;/p&gt;</description></item><item><title>githubActionCICD实战</title><link>https://www.ggball.top/posts/git/githubactioncicd%E5%AE%9E%E6%88%98/</link><pubDate>Fri, 07 Mar 2025 15:12:54 +0800</pubDate><guid>https://www.ggball.top/posts/git/githubactioncicd%E5%AE%9E%E6%88%98/</guid><description>&lt;h1 id="github-action-cicd-实战"&gt;github action CI/CD 实战&lt;/h1&gt;
&lt;p&gt;&lt;img alt="ci/cd" loading="lazy" src="https://blog.opsmx.com/wp-content/uploads/2022/03/Standard-DevOps-CICD.png"&gt;&lt;/p&gt;
&lt;h2 id="什么是ci"&gt;什么是ci&lt;/h2&gt;
&lt;p&gt;持续集成，需要用户主动提交代码，触发代码集成、自动化构建、自动化测试流程&lt;/p&gt;
&lt;h2 id="什么是cd"&gt;什么是cd&lt;/h2&gt;
&lt;p&gt;持续交付、持续部署，不需要用户干预，自动将ci准备好的构建文件发布到生产环境&lt;/p&gt;</description></item><item><title>windows安装Deep-Live-Cam教程</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/windows%E5%AE%89%E8%A3%85deep-live-cam%E6%95%99%E7%A8%8B/</link><pubDate>Sun, 11 Aug 2024 13:24:23 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/windows%E5%AE%89%E8%A3%85deep-live-cam%E6%95%99%E7%A8%8B/</guid><description>&lt;h2 id="windows10配合1650显卡安装deep-live-cam教程实现实时换脸效果流畅"&gt;windows10配合1650显卡安装Deep-Live-Cam教程，实现实时换脸，效果流畅！&lt;/h2&gt;
&lt;h3 id="官方实例"&gt;官方实例&lt;/h3&gt;
&lt;p&gt;&lt;img alt="demo" loading="lazy" src="https://img.ggball.top/picGo/demo.gif"&gt;&lt;/p&gt;
&lt;h4 id="1环境配置"&gt;1.环境配置&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;python (3.10 recommended)&lt;/li&gt;
&lt;li&gt;pip&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=OlNWCpFdVMA"&gt;ffmpeg&lt;/a&gt; 需要配置环境变量&lt;/li&gt;
&lt;li&gt;&lt;a href="https://visualstudio.microsoft.com/visual-cpp-build-tools/"&gt;visual studio 2022 runtimes (windows)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2-克隆仓库"&gt;2. 克隆仓库&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;https://github.com/hacksider/Deep-Live-Cam.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="3-下载模型"&gt;3. 下载模型&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/hacksider/deep-live-cam/resolve/main/GFPGANv1.4.pth"&gt;GFPGANv1.4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/hacksider/deep-live-cam/resolve/main/inswapper_128_fp16.onnx"&gt;inswapper_128_fp16.onnx&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下载好之后，将模型放到&lt;code&gt;models&lt;/code&gt;文件夹下
&lt;img alt="20240811131835" loading="lazy" src="https://img.ggball.top/picGo/20240811131835.png"&gt;&lt;/p&gt;
&lt;h4 id="4-安装依赖"&gt;4. 安装依赖&lt;/h4&gt;
&lt;p&gt;强烈推荐使用venv虚拟环境&lt;/p&gt;</description></item><item><title>2023-12</title><link>https://www.ggball.top/monthly/2023-12/</link><pubDate>Mon, 01 Jan 2024 15:49:51 +0800</pubDate><guid>https://www.ggball.top/monthly/2023-12/</guid><description>&lt;blockquote&gt;
&lt;p&gt;其实我自己是不太喜欢记录的，但是觉得自己工作的枯燥、时间愈发觉得过得快，所以还是想记录一下自己的生活，也算是给自己的生活做一个总结吧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="2023回顾"&gt;2023回顾&lt;/h2&gt;
&lt;h3 id="一月"&gt;一月&lt;/h3&gt;
&lt;p&gt;制定了很多计划，因为受够了公司的领导不公平的待遇以及技术上的瓶颈发展，所及决定后面离职，准备面试资料，看消息队列、分布式、微服务等相关知识。过年的时候又放弃准备面试，当时看到了一个直播推流技术，转而对自媒体进行直播推流，当时也是一时兴起，过年那几天搞推流直播，短视频发布，虽然不是自己擅长的领域，但是乐在其中，也算是对自己的一种放松吧。现在想起来既可笑，又浪费时间。
&lt;img alt="20240101160422" loading="lazy" src="https://img.ggball.top/picGo/20240101160422.png"&gt;
&lt;a href="https://blog.csdn.net/ZHUXIUQINGIT/article/details/128758938"&gt;推流教程&lt;/a&gt;&lt;/p&gt;</description></item><item><title>prompt的设计</title><link>https://www.ggball.top/posts/chatgpt/prompt%E7%9A%84%E8%AE%BE%E8%AE%A1/</link><pubDate>Thu, 17 Aug 2023 12:09:49 +0800</pubDate><guid>https://www.ggball.top/posts/chatgpt/prompt%E7%9A%84%E8%AE%BE%E8%AE%A1/</guid><description>&lt;p&gt;前几天刚入职，领导给我派了个活。&lt;/p&gt;
&lt;p&gt;叫我给一堆医疗诊断结果和医学界结论材料，叫我写个prompt，输入材料信息和医学结论，逆向推断出检查结果。&lt;/p&gt;
&lt;p&gt;虽然不是什么技术活，但是也是耗费了我一天时间 。&lt;/p&gt;</description></item><item><title>spring的三级缓存如何解决循环依赖</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96/</link><pubDate>Thu, 17 Aug 2023 12:09:49 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96/</guid><description>&lt;h2 id="什么是循环依赖"&gt;什么是循环依赖？&lt;/h2&gt;
&lt;h3 id="官方解释"&gt;官方解释&lt;/h3&gt;
&lt;p&gt;&lt;img alt="spring官方提倡使用构造方法来依赖注入" loading="lazy" src="https://img.ggball.top/picGo/20230815215348.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="官方解释" loading="lazy" src="https://img.ggball.top/picGo/20230815215504.png"&gt;&lt;/p&gt;
&lt;p&gt;虽然官方提倡使用构造方法来依赖注入，但是构造方法解决不了循环依赖，可以使用setter方法来解决。&lt;/p&gt;
&lt;h3 id="个人理解"&gt;个人理解&lt;/h3&gt;
&lt;p&gt;a对象持有b对象的引用，b对象持有a对象的引用。这样说好像察觉不到问题，可以试想下当我们自己创建a对象时,是不是先要调用a对象的构造方法，然后再进行属性的填充，这才是一个完整的a对象,但是当调用对象a的构造方法后，发现需要先拿到完整的b对象，则需要先完成b对象的创建，然后调用b对象的构造方法，b对象进行属性填充时，发现需要a对象，然后无限的循环下去。。。&lt;/p&gt;</description></item><item><title>动态代理</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%AB%98%E7%BA%A7/%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</link><pubDate>Thu, 17 Aug 2023 12:09:49 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%AB%98%E7%BA%A7/%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</guid><description>&lt;h2 id="cglib动态代理使用介绍"&gt;CGLIB动态代理使用介绍&lt;/h2&gt;
&lt;h4 id="一前言"&gt;一、前言&lt;/h4&gt;
&lt;p&gt;  说到动态代理，开发者们第一时间想到的就是&lt;a href="https://blog.csdn.net/Bronze5/article/details/106968019"&gt;JDK动态代理&lt;/a&gt;和cglib动态代理。了解Spring的同学应该知道，&lt;code&gt;Spring AOP功能&lt;/code&gt;的底层实现，就是使用的这两种动态代理。&lt;/p&gt;
&lt;h5 id="两者区别"&gt;两者区别&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;JDK的动态代理机制只能代理实现了接口的类，而没有实现接口的类就不能实现JDK的动态代理；&lt;/li&gt;
&lt;li&gt;cglib动态代理是针对类来实现代理的，它的原理是对指定的目标类生成一个子类，并覆盖其中方法实现增强。使用cglib实现动态代理，完全不受代理类必须实现接口的限制。&lt;/li&gt;
&lt;li&gt;cglib底层采用ASM字节码生成框架，使用字节码技术生成代理类，比使用Java反射效率要高。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;因为cglib动态代理采用的是继承，所以不能对final修饰的类进行代理。&lt;/p&gt;</description></item><item><title>esxi创建虚拟机,安装centos7</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/esxi%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AE%89%E8%A3%85centos7/</link><pubDate>Wed, 19 Jul 2023 09:16:23 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/esxi%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AE%89%E8%A3%85centos7/</guid><description>&lt;p&gt;1.首页点击创建/注册虚拟机&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20230719090048818" loading="lazy" src="https://img.ggball.top/img/image-20230719090048818.png?picGo"&gt;2.点击创建新虚拟机&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20230719090149770" loading="lazy" src="https://img.ggball.top/img/image-20230719090149770.png?picGo"&gt;&lt;/p&gt;
&lt;p&gt;3.填写虚拟机名称，选择客户机操作系统系列 linux，客户机操作系统版本 centos7&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20230719090321271" loading="lazy" src="https://img.ggball.top/img/image-20230719090321271.png?picGo"&gt;&lt;/p&gt;
&lt;p&gt;4.储存选择 标准-datastore1&lt;/p&gt;</description></item><item><title>分布式事务概览</title><link>https://www.ggball.top/notes/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E6%A6%82%E8%A7%88/</link><pubDate>Wed, 19 Jul 2023 09:15:28 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E6%A6%82%E8%A7%88/</guid><description>&lt;h1 id="分布式事务概览"&gt;分布式事务概览&lt;/h1&gt;
&lt;h2 id="分布式理论"&gt;分布式理论&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前置理论知识：
&lt;ul&gt;
&lt;li&gt;CAP
&lt;ul&gt;
&lt;li&gt;C 强一致性 主节点写入新的数据，必须能从从节点读到最新数据，否则错误&lt;/li&gt;
&lt;li&gt;A 可用性 保证每个服务尽可能都能响应结果&lt;/li&gt;
&lt;li&gt;P 分区容忍性 正常情况下，服务节点之间通信是正常的，可能因为网络原因，节点之间通信失败，将整个服务分成了多个区，仍然可以保证整个服务的运行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;BASE
&lt;ul&gt;
&lt;li&gt;basically Available 基本可用 系统出现故障，保证核心功能可用&lt;/li&gt;
&lt;li&gt;Soft state 软状态 出现一个中间状态，表示动作进行中&lt;/li&gt;
&lt;li&gt;eventually consistent 最终一致性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2pc-两阶段提交协议"&gt;2pc 两阶段提交（协议）&lt;/h2&gt;
&lt;h3 id="主要角色"&gt;主要角色&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;事务管理器（协调者 tm）&lt;/p&gt;</description></item><item><title>我的简历</title><link>https://www.ggball.top/projects/%E6%88%91%E7%9A%84%E7%AE%80%E5%8E%86/</link><pubDate>Wed, 19 Jul 2023 09:15:28 +0800</pubDate><guid>https://www.ggball.top/projects/%E6%88%91%E7%9A%84%E7%AE%80%E5%8E%86/</guid><description>&lt;h1 id="java工程师"&gt;java工程师&lt;/h1&gt;
&lt;p&gt;::: left
朱秀清/男/1998.02&lt;/p&gt;
&lt;p&gt;江西应用科技学院/物联网工程&lt;/p&gt;
&lt;p&gt;本科/2020年毕业&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;::: right
&lt;a href="https://ggball.top"&gt;icon:blog https://ggball.top&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/hua1995116"&gt;icon:github https://github.com/a1667834841&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="%5B1667834841@qq.com%5D(mailto:1667834841@qq.com)"&gt;icon:email 1667834841@qq.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;icon:weixin a1667834841
icon:phone 13217913287&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2 id="技能"&gt;技能&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;掌握java语言，熟悉JUC、io、多线程等java高级特性；&lt;/p&gt;</description></item><item><title>个人网站实现微信扫码登录</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99%E5%AE%9E%E7%8E%B0%E5%BE%AE%E4%BF%A1%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95/</link><pubDate>Thu, 25 May 2023 20:26:03 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99%E5%AE%9E%E7%8E%B0%E5%BE%AE%E4%BF%A1%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95/</guid><description>&lt;h1 id="个人网站实现微信扫码登录"&gt;⭐个人网站实现微信扫码登录&lt;/h1&gt;
&lt;h2 id="效果图"&gt;🥈效果图&lt;/h2&gt;
&lt;p&gt;&lt;img alt="效果图" loading="lazy" src="https://img.ggball.top/picGo/%E5%8A%A8%E7%94%BB.gif"&gt;&lt;/p&gt;
&lt;h2 id="开发背景"&gt;📗开发背景&lt;/h2&gt;
&lt;p&gt;为什么想用微信扫码登录呢？&lt;/p&gt;
&lt;p&gt;起因是自己开发了一个&lt;a href="https://tiku.toolkit.show/"&gt;搜题网站&lt;/a&gt;，内容很简单，但是没有登陆，所以游客可以随便使用，当然也不是不让游客访问，只是没有登陆的话，不能很好的统计使用的用户，也能减少些一些滥用的用户。&lt;/p&gt;
&lt;p&gt;起初，我是想设计成账号密码登录网站的，但是想了下，我自己平常碰到一些需要注册的网站，我往往会直接跳过，就不会对这个网站感兴趣了，能让我感兴趣的网站一般都是支持直接扫码登录或者可以以第三方账号直接注册登录，所以能吸引更多的用户，必须要把这个门槛给打下来，提高用户体验！&lt;/p&gt;</description></item><item><title>websocket网络协议</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/websocket%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/</link><pubDate>Mon, 22 May 2023 22:22:49 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/websocket%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/</guid><description>&lt;p&gt;WebSocket是一种在单个TCP连接上进行全双工通信的网络协议。它提供了一种在客户端和服务器之间进行实时、双向通信的方式，允许服务器主动向客户端推送数据，而不需要客户端发起请求。&lt;/p&gt;</description></item><item><title>python安装</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/python%E5%AE%89%E8%A3%85/</link><pubDate>Mon, 01 May 2023 15:31:49 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/python%E5%AE%89%E8%A3%85/</guid><description>&lt;h1 id="python安装37"&gt;python安装3.7&lt;/h1&gt;
&lt;h2 id="linux下python2x升级python37"&gt;Linux下Python2.x升级Python3.7&lt;/h2&gt;
&lt;h3 id="一查看当前python版本"&gt;一、查看当前Python版本&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@localhost ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# python -V&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Python 2.7.5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="二下载新的python包并安装"&gt;二、下载新的python包并安装&lt;/h3&gt;
&lt;p&gt;进入Python官网（https://www.python.org），选择需要的版本。此处我选择Python3.7.3版本&lt;/p&gt;</description></item><item><title>利用chatgpt做一款题库小程序</title><link>https://www.ggball.top/posts/chatgpt/%E5%88%A9%E7%94%A8chatgpt%E5%81%9A%E4%B8%80%E6%AC%BE%E9%A2%98%E5%BA%93%E5%B0%8F%E7%A8%8B%E5%BA%8F/</link><pubDate>Sun, 30 Apr 2023 10:54:16 +0800</pubDate><guid>https://www.ggball.top/posts/chatgpt/%E5%88%A9%E7%94%A8chatgpt%E5%81%9A%E4%B8%80%E6%AC%BE%E9%A2%98%E5%BA%93%E5%B0%8F%E7%A8%8B%E5%BA%8F/</guid><description>&lt;h1 id="前端小白是如何利用chatgt用一周时间从0做一款微信小程序的"&gt;前端小白是如何利用chatgt用一周时间从0做一款微信小程序的&lt;/h1&gt;
&lt;p&gt;随着&lt;code&gt;chatgpt&lt;/code&gt;的大火，真的是在工作上给各行各业的人带来了极大的便利，本人是一个&lt;code&gt;java&lt;/code&gt;程序员，其实我自己是一直想开发一款属于自己的小程序的，但是迫于对前端知识的贫瘠，考虑到要学的前端开发知识有很多，比如&lt;code&gt;js&lt;/code&gt;,&lt;code&gt;ts&lt;/code&gt;,前端框架&lt;code&gt;vue&lt;/code&gt;,&lt;code&gt;react&lt;/code&gt;&amp;hellip;,最难受的是&lt;code&gt;css&lt;/code&gt;样式，最简单的效果都要弄好久，每次想一想就放弃了。最近出来的&lt;code&gt;chatgpt&lt;/code&gt;，让我对这个想法重新有了信心，然后就是直接开干！&lt;/p&gt;</description></item><item><title>JVM大纲</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%A4%A7%E7%BA%B2/</link><pubDate>Tue, 14 Mar 2023 23:21:20 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%A4%A7%E7%BA%B2/</guid><description>&lt;p&gt;&lt;img alt="20230315000656" loading="lazy" src="https://img.ggball.top/picGo/20230315000656.png"&gt;&lt;/p&gt;
&lt;h1 id="jvm重点"&gt;JVM重点&lt;/h1&gt;
&lt;h2 id="自动内存管理"&gt;自动内存管理&lt;/h2&gt;
&lt;h3 id="java内存区域"&gt;java内存区域&lt;/h3&gt;
&lt;h3 id="垃圾收集器和内存分配策略"&gt;垃圾收集器和内存分配策略&lt;/h3&gt;
&lt;h3 id="虚拟机性能监控和故障处理工具"&gt;虚拟机性能监控和故障处理工具&lt;/h3&gt;
&lt;h3 id="调优案例"&gt;调优案例&lt;/h3&gt;
&lt;h2 id="虚拟机执行子系统"&gt;虚拟机执行子系统&lt;/h2&gt;
&lt;h3 id="类文件结构"&gt;类文件结构&lt;/h3&gt;
&lt;h3 id="虚拟机类加载机制"&gt;虚拟机类加载机制&lt;/h3&gt;
&lt;h3 id="虚拟机字节码执行引擎"&gt;虚拟机字节码执行引擎&lt;/h3&gt;
&lt;h3 id="类加载及执行子系统的案例与实战"&gt;类加载及执行子系统的案例与实战&lt;/h3&gt;
&lt;p&gt;&lt;img alt="大纲" loading="lazy" src="https://img.ggball.top/picGo/20230314232515.png"&gt;&lt;/p&gt;</description></item><item><title>chatGpt调教教程</title><link>https://www.ggball.top/projects/chatgpt%E8%B0%83%E6%95%99%E6%95%99%E7%A8%8B/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/projects/chatgpt%E8%B0%83%E6%95%99%E6%95%99%E7%A8%8B/</guid><description>&lt;p&gt;&lt;img alt="images" loading="lazy" src="https://img.ggball.top/picGo/images.png"&gt;&lt;/p&gt;
&lt;h2 id="它能干什么-直接问它"&gt;它能干什么? 直接问它&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我是一个训练有素的大型语言模型，可以帮助你回答各种问题，比如关于政治、历史、科学、技术、艺术等方面的问题。我可以帮助你理解一些概念，并为你提供有价值的信息和见解。你可以尝试提出一些问题，看看我能不能帮到你。&lt;/p&gt;</description></item><item><title>MeterSphere-Jenkins插件实现测试计划触发执行</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/metersphere-jenkins%E6%8F%92%E4%BB%B6%E5%AE%9E%E7%8E%B0%E6%B5%8B%E8%AF%95%E8%AE%A1%E5%88%92%E8%A7%A6%E5%8F%91%E6%89%A7%E8%A1%8C/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/metersphere-jenkins%E6%8F%92%E4%BB%B6%E5%AE%9E%E7%8E%B0%E6%B5%8B%E8%AF%95%E8%AE%A1%E5%88%92%E8%A7%A6%E5%8F%91%E6%89%A7%E8%A1%8C/</guid><description>&lt;p&gt;MeterSphere 是一站式开源持续测试平台，涵盖测试跟踪、接口测试、性能测试、团队协作等功能，兼容JMeter 等开源标准，有效助力开发和测试团队充分利用云弹性进行高度可扩展的自动化测试，加速高质量软件的交付。&lt;/p&gt;</description></item><item><title>undo log了解</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/undo-log%E4%BA%86%E8%A7%A3/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/undo-log%E4%BA%86%E8%A7%A3/</guid><description>&lt;p&gt;undo log&lt;/p&gt;
&lt;p&gt;用来保证原子性&lt;/p&gt;
&lt;p&gt;1.redo log通常是物理日志，记录的是数据页的物理修改，而不是某一行或某几行修改成怎样怎样，它用来恢复提交后的物理数据页(恢复数据页，且只能恢复到最后一次提交的位置)。
2.undo用来回滚行记录到某个版本。undo log一般是逻辑日志，根据每行记录进行记录。&lt;/p&gt;</description></item><item><title>xxqg</title><link>https://www.ggball.top/projects/xxqg/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/projects/xxqg/</guid><description>&lt;h1 id="学习强国平台"&gt;学习强国平台&lt;/h1&gt;
&lt;h2 id="10"&gt;1.0&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实现学习 视频 试听 专项 每周 读文章 （29~45分）&lt;/li&gt;
&lt;li&gt;添加用户&lt;/li&gt;
&lt;li&gt;支付&lt;/li&gt;
&lt;li&gt;订单管理&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="20"&gt;2.0&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;利用模拟器 实现挑战 登录 评论 本地 （+8分）&lt;/li&gt;
&lt;li&gt;微信推送&lt;/li&gt;
&lt;li&gt;用户查询优化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="模拟器操作"&gt;模拟器操作&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;设备绑定&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;用户下发绑定指令，&lt;/li&gt;
&lt;li&gt;查询空闲设备，主要获得ip，&lt;/li&gt;
&lt;li&gt;获得登录脚本，&lt;/li&gt;
&lt;li&gt;将ip和用户账号密码作为参数，&lt;/li&gt;
&lt;li&gt;调用执行脚本&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>利用vercel一键部署自己的chatgpt网站</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E5%88%A9%E7%94%A8vercel%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2%E8%87%AA%E5%B7%B1%E7%9A%84chatgpt%E7%BD%91%E7%AB%99/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E5%88%A9%E7%94%A8vercel%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2%E8%87%AA%E5%B7%B1%E7%9A%84chatgpt%E7%BD%91%E7%AB%99/</guid><description>&lt;p&gt;利用vercel一键部署自己的chatgpt网站&lt;/p&gt;
&lt;p&gt;🌟嘿，小伙伴们！今天小编要和大家分享一个超实用的技巧，那就是利用vercel一键部署自己的chatgpt网站！👏&lt;/p&gt;</description></item><item><title>网页调试技巧</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E7%BD%91%E9%A1%B5%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E7%BD%91%E9%A1%B5%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</guid><description>&lt;h5 id="html页面强制刷新清缓存"&gt;html页面强制刷新，清缓存&lt;/h5&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;在html页面头部添加
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http-equiv&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Pragma&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;no-cache&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http-equiv&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;no-cache&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http-equiv&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Expires&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;EventSource 本地调试成功，线上环境不响应&lt;/p&gt;
&lt;p&gt;原因是nginx默认开启的buffer机制缓存了服务器推送的片段信息，缓存达到一定的量才会返回响应内容。只要关闭proxy_buffering即可。配置如下所示：&lt;/p&gt;</description></item><item><title>项目计划</title><link>https://www.ggball.top/projects/%E9%A1%B9%E7%9B%AE%E8%AE%A1%E5%88%92/</link><pubDate>Sun, 12 Mar 2023 01:49:51 +0800</pubDate><guid>https://www.ggball.top/projects/%E9%A1%B9%E7%9B%AE%E8%AE%A1%E5%88%92/</guid><description>&lt;ol&gt;
&lt;li&gt;xxqg 程序&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;input checked="" disabled="" type="checkbox"&gt; 目前先把功能完善，尽量长时间不掉线，过期机制加上（2022-12-8 2022-12-11）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;input disabled="" type="checkbox"&gt; 续费功能&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;input disabled="" type="checkbox"&gt; sql框架由 database/sql 换成 gorm ,替换user表 新增admin表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;input checked="" disabled="" type="checkbox"&gt; 强国二维码 半分钟刷新一次，防止二维码过期&lt;/p&gt;</description></item><item><title>io模型</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/io%E6%A8%A1%E5%9E%8B/</link><pubDate>Sat, 11 Mar 2023 15:14:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/io%E6%A8%A1%E5%9E%8B/</guid><description>&lt;h2 id="单线程模型"&gt;单线程模型&lt;/h2&gt;
&lt;p&gt;&lt;img alt="20230312004513" loading="lazy" src="https://img.ggball.top/picGo/20230312004513.png"&gt;
accept函数如果没有事件，则会阻塞，影响其他请求
。。。。。&lt;/p&gt;
&lt;h2 id="多进程模型"&gt;多进程模型&lt;/h2&gt;
&lt;p&gt;。。。。。&lt;/p&gt;
&lt;p&gt;套接字
用网络地址和端口来唯一标识一个实体。那么，用来唯一标识通信两端的数据结构就叫做套接字&lt;/p&gt;</description></item><item><title>jvm垃圾收集器和内存分配策略</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E5%92%8C%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5/</link><pubDate>Thu, 09 Mar 2023 21:38:54 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E5%92%8C%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5/</guid><description>&lt;p&gt;&lt;img alt="20230315001155" loading="lazy" src="https://img.ggball.top/picGo/20230315001155.png"&gt;&lt;/p&gt;
&lt;h2 id="序言"&gt;序言&lt;/h2&gt;
&lt;p&gt;&lt;img alt="20230314234149" loading="lazy" src="https://img.ggball.top/picGo/20230314234149.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="20230315000112" loading="lazy" src="https://img.ggball.top/picGo/20230315000112.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;今天讲的是jvm垃圾收集器是如何回收垃圾的，现在我们的生产环境动不动就是几十G，每时每刻产生的垃圾对象也会很多，所以回收他们也是JVM重中之重的任务。&lt;/p&gt;</description></item><item><title>锁升级过程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E9%94%81%E5%8D%87%E7%BA%A7%E8%BF%87%E7%A8%8B/</link><pubDate>Wed, 08 Feb 2023 20:51:50 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E9%94%81%E5%8D%87%E7%BA%A7%E8%BF%87%E7%A8%8B/</guid><description>&lt;h1 id="java锁升级过程"&gt;java锁升级过程&lt;/h1&gt;
&lt;p&gt;前置知识：对象头中的markword（32字节）的最后两个字节用来表示锁的状态&lt;/p&gt;
&lt;p&gt;无锁 -&amp;gt; 偏向锁 -&amp;gt; 轻量级锁 -&amp;gt; 重量级锁 （无法退化）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;无锁状态 会被标志无锁状态，jvm启动4秒后会变为偏向锁状态（&lt;code&gt;BiasedLockingStartupDelay&lt;/code&gt; jvm参数 默认4秒）&lt;/li&gt;
&lt;li&gt;偏向锁，最后两个字节会标志为偏向锁，且还会有块内存区域标志着线程id的信息，下次线程过来时，直接将锁交出，当有竞争时，偏向锁会升级为轻量级锁&lt;/li&gt;
&lt;li&gt;轻量级锁，采用的是cas操作，cas成功的线程获取到锁，其他的线程会自旋，等待锁释放，轻量级锁实现的过程是：线程的虚拟机栈中会创建一个lock record内存块用来保存对象头markword副本，对象头会记录lock record的地址，如果自旋线程数量超过一个，那么就会升级为重量级锁&lt;/li&gt;
&lt;li&gt;重量级锁 jvm层面，使用monitor enter 和 monitor exist命令加锁，其他线程挂起&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>hashMap解读</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/hashmap%E8%A7%A3%E8%AF%BB/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/hashmap%E8%A7%A3%E8%AF%BB/</guid><description>&lt;p&gt;每次面试都会看一遍别人的博客，还不如直接记下，补充自己的笔记&lt;/p&gt;
&lt;p&gt;主要是对jdk1.7和jdk1.8的分析&lt;/p&gt;
&lt;h2 id="jdk17-hashmap结构图"&gt;JDK1.7 hashMap结构图&lt;/h2&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://img.ggball.top/img/5cd1d2be77958.jpg?picGo"&gt;&lt;/p&gt;
&lt;h3 id="17-hashmap变量"&gt;1.7 hashMap变量&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;初始容量16&lt;/p&gt;</description></item><item><title>redis概览</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%A6%82%E8%A7%88/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%A6%82%E8%A7%88/</guid><description>&lt;h1 id="redis学习路径"&gt;Redis学习路径&lt;/h1&gt;
&lt;h2 id="掌握数据结构"&gt;掌握数据结构&lt;/h2&gt;
&lt;h3 id="学会基本数据结构用法"&gt;&lt;a href="https://ggball.top/pages/0d1608/"&gt;学会基本数据结构用法&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="string"&gt;string&lt;/h4&gt;
&lt;h4 id="list"&gt;list&lt;/h4&gt;
&lt;h4 id="hash"&gt;hash&lt;/h4&gt;
&lt;h4 id="set"&gt;set&lt;/h4&gt;
&lt;h4 id="zset"&gt;zset&lt;/h4&gt;
&lt;h4 id="思考对应的使用场景"&gt;思考对应的使用场景&lt;/h4&gt;
&lt;h3 id="特殊数据结构用法"&gt;&lt;a href="https://pdai.tech/md/db/nosql-redis/db-redis-data-type-special.html"&gt;特殊数据结构用法&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="hyperloglog"&gt;HyperLogLog&lt;/h4&gt;
&lt;h4 id="bitmap"&gt;Bitmap&lt;/h4&gt;
&lt;h4 id="geo"&gt;GEO&lt;/h4&gt;
&lt;h4 id="思考对应的使用场景-1"&gt;思考对应的使用场景&lt;/h4&gt;
&lt;h2 id="使用场景"&gt;使用场景&lt;/h2&gt;
&lt;h3 id="分布式锁"&gt;分布式锁&lt;/h3&gt;
&lt;h2 id="掌握支撑redis实现高可靠高性能的技术"&gt;掌握支撑redis实现高可靠，高性能的技术&lt;/h2&gt;
&lt;h3 id="持久化机制"&gt;&lt;a href="https://ggball.top/pages/039a2c/#aof%E6%9C%BA%E5%88%B6"&gt;持久化机制&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="aof"&gt;aof&lt;/h4&gt;
&lt;h4 id="rdb"&gt;rdb&lt;/h4&gt;
&lt;h4 id="aof和rdb的比较以及如何实际应用"&gt;aof和rdb的比较，以及如何实际应用&lt;/h4&gt;
&lt;h3 id="主从复制机制"&gt;&lt;a href="https://ggball.top/pages/331160/"&gt;主从复制机制&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="同步"&gt;同步&lt;/h4&gt;
&lt;h4 id="命令传播"&gt;命令传播&lt;/h4&gt;
&lt;h4 id="主从复制搭建"&gt;&lt;a href="https://ggball.top/pages/222607/"&gt;主从复制搭建&lt;/a&gt;&lt;/h4&gt;
&lt;h3 id="哨兵机制"&gt;&lt;a href="https://ggball.top/pages/238765/"&gt;哨兵机制&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id="监控"&gt;监控&lt;/h4&gt;
&lt;h4 id="决策"&gt;决策&lt;/h4&gt;
&lt;h4 id="通知"&gt;通知&lt;/h4&gt;
&lt;h3 id="切片集群解决单台服务器数据量过多的方案"&gt;&lt;a href="https://ggball.top/pages/27393e/"&gt;切片集群&lt;/a&gt;（解决单台服务器数据量过多的方案）&lt;/h3&gt;
&lt;h4 id="什么是切片集群"&gt;什么是切片集群&lt;/h4&gt;
&lt;h4 id="数据如何分配到实例"&gt;数据如何分配到实例&lt;/h4&gt;
&lt;h4 id="客户端发送消息的机制"&gt;客户端发送消息的机制&lt;/h4&gt;
&lt;h2 id="精通底层实现原理"&gt;精通底层实现原理&lt;/h2&gt;
&lt;h3 id="事件机制"&gt;事件机制&lt;/h3&gt;
&lt;h3 id="数据结构实现原理"&gt;数据结构实现原理&lt;/h3&gt;
&lt;h3 id="高可靠高性能的原理"&gt;高可靠，高性能的原理&lt;/h3&gt;
&lt;h4 id="哨兵集群分布式系统选举和共识问题"&gt;哨兵集群：分布式系统选举和共识问题&lt;/h4&gt;
&lt;h4 id="切片集群分布式系统问题"&gt;切片集群：分布式系统问题&lt;/h4&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://kaito-blog-1253469779.cos.ap-beijing.myqcloud.com/2020/09/15996549004998.jpg"&gt;&lt;/p&gt;</description></item><item><title>redis淘汰策略机制</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%B7%98%E6%B1%B0%E7%AD%96%E7%95%A5%E6%9C%BA%E5%88%B6/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%B7%98%E6%B1%B0%E7%AD%96%E7%95%A5%E6%9C%BA%E5%88%B6/</guid><description>&lt;h1 id="redis-淘汰策略"&gt;redis 淘汰策略&lt;/h1&gt;
&lt;p&gt;分类角度：会进行淘汰的和不进行淘汰的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不会进行淘汰的 noeviction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;会进行淘汰的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;过期内淘汰的 volatile-random、volatile-ttl、volatile-lru、volatile-lfu&lt;/li&gt;
&lt;li&gt;全部数据淘汰的 allkeys-lru、allkeys-random、allkeys-lfu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" src="https://static001.geekbang.org/resource/image/04/f6/04bdd13b760016ec3b30f4b02e133df6.jpg"&gt;&lt;/p&gt;</description></item><item><title>redis消息队列方案</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E6%96%B9%E6%A1%88/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E6%96%B9%E6%A1%88/</guid><description>&lt;h1 id="redis-消息队列方案"&gt;redis 消息队列方案&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;观察角度：消息有序，重复消息处理，消息可靠性保证&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="pubsub-发布订阅机制"&gt;pub/sub 发布订阅机制&lt;/h2&gt;
&lt;h2 id="list集合"&gt;list集合&lt;/h2&gt;
&lt;p&gt;消息有序：lpush和rpop可以保证消息顺序的被消费&lt;/p&gt;
&lt;p&gt;重复消息处理：list没有为消息提供唯一标识，需要生产者提供唯一标识，消费程序自行判断消息是否重复&lt;/p&gt;</description></item><item><title>缓存雪崩，缓存穿透和缓存击穿</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F%E5%92%8C%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F%E5%92%8C%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF/</guid><description>&lt;h1 id="数据不一致的原因"&gt;数据不一致的原因&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;缓存或数据库只有一个操作失败&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;先删数据库数据 再删除缓存数据&lt;/li&gt;
&lt;li&gt;先删除缓存数据 再删除数据库数据&lt;/li&gt;
&lt;li&gt;多线程（先删缓存，再删数据库） 线程a先删除缓存数据，此时线程b查询数据库，并把旧数据放入缓存，a线程再插入数据库，之后的线程可能只会读到缓存上的旧数据&lt;/li&gt;
&lt;li&gt;多线程（先删除数据库，再删除缓存）a线程删除完数据库旧数据到删除缓存这段时间，如果有读操作，那么会读到旧数据，等到a线程更新完缓存，缓存就为新的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="数据不一致的解决方案"&gt;数据不一致的解决方案&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;重试机制&lt;/li&gt;
&lt;li&gt;针对第三点 可以让a线程sleep 一小段时间 目的是为了 让像b线程这些查询操作 完成将旧数据放入缓存的操作，之后a线程再更新下缓存，sleep时间需要实测，比较难界定。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="图片" loading="lazy" src="https://static001.geekbang.org/resource/image/11/6f/11ae5e620c63de76448bc658fe6a496f.jpg"&gt;&lt;/p&gt;</description></item><item><title>针对支付宝-当面付实现的个人支付</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E9%92%88%E5%AF%B9%E6%94%AF%E4%BB%98%E5%AE%9D-%E5%BD%93%E9%9D%A2%E4%BB%98%E5%AE%9E%E7%8E%B0%E7%9A%84%E4%B8%AA%E4%BA%BA%E6%94%AF%E4%BB%98/</link><pubDate>Sun, 05 Feb 2023 15:38:19 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E9%92%88%E5%AF%B9%E6%94%AF%E4%BB%98%E5%AE%9D-%E5%BD%93%E9%9D%A2%E4%BB%98%E5%AE%9E%E7%8E%B0%E7%9A%84%E4%B8%AA%E4%BA%BA%E6%94%AF%E4%BB%98/</guid><description>&lt;h1 id="针对支付宝-当面付实现的个人支付"&gt;针对支付宝-当面付实现的个人支付&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://test.ggball.top:9002/view/index.html"&gt;测试地址&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="项目背景"&gt;项目背景&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么想做这个 一是工作中也接触到了支付宝，微信支付方面，二是自己也想弄个收费服务，比如之后做的程序想收费可以直接让用户扫码支付，而不用微信交流了。&lt;/p&gt;</description></item><item><title>redis集群机制</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E9%9B%86%E7%BE%A4%E6%9C%BA%E5%88%B6/</link><pubDate>Sat, 05 Nov 2022 17:02:30 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E9%9B%86%E7%BE%A4%E6%9C%BA%E5%88%B6/</guid><description>&lt;h1 id="redis-集群"&gt;redis 集群&lt;/h1&gt;
&lt;p&gt;为了解决保存大量数据，有两种方案&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;纵向扩展（直接加大服务器的内存）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缺点：内存扩展会存在成本或硬件的限制&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;横向扩展（增加服务器的个数）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缺点：部署复杂，会产生新的集群问题&lt;/li&gt;
&lt;li&gt;优点：节约成本，扩展容易&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="redis集群产生的问题"&gt;redis集群产生的问题？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;客户端发送的数据如何分布？&lt;/p&gt;</description></item><item><title>redis哨兵机制原理</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E5%93%A8%E5%85%B5%E6%9C%BA%E5%88%B6%E5%8E%9F%E7%90%86/</link><pubDate>Wed, 02 Nov 2022 19:42:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E5%93%A8%E5%85%B5%E6%9C%BA%E5%88%B6%E5%8E%9F%E7%90%86/</guid><description>&lt;h1 id="哨兵机制"&gt;哨兵机制&lt;/h1&gt;
&lt;p&gt;无论是写服务中断，还是从库无法进行数据同步，都是不能接受的。所以，如果主库挂了，我们就需要运行一个新主库，比如说把一个从库切换为主库，把它当成主库。这就涉及到三个问题：&lt;/p&gt;</description></item><item><title>redis主从复制搭建</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E6%90%AD%E5%BB%BA/</link><pubDate>Mon, 31 Oct 2022 16:31:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E6%90%AD%E5%BB%BA/</guid><description>&lt;h3 id="redis安装"&gt;Redis安装&lt;/h3&gt;
&lt;p&gt;3台服务器安装Redis6.2.6
&lt;a href="https://redis.io/"&gt;官网&lt;/a&gt;
&lt;a href="http://redis.cn/"&gt;中文&lt;/a&gt;
Redis安装包解压完成后，详细安装目录可以查看README.md&lt;/p&gt;
&lt;p&gt;bash&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. 安装gcc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install gcc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. 下载安装包&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://download.redis.io/releases/redis-6.2.6.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar -xf redis-6.2.6.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. 编译 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd redis-6.2.6 &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd src &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make install PREFIX&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/redis
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. 配置环境变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 添加环境变量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export REDIS_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/redis
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$PATH:$REDIS_HOME/bin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 5. 根据Redis官方提供的脚本一键安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ../../redis-6.2.6/utils
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./install_server.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行第5步报错，错误信息如下：
&lt;a href="https://img2022.cnblogs.com/blog/907818/202202/907818-20220226170104527-1242488579.jpg?watermark/2/text/aHR0cHM6Ly93d3cuZHZvbXUuY29t/font/5a6L5L2T/fontsize/25/fill/I0ZGMDAwMA==/dissolve/50/gravity/SouthEast"&gt;&lt;img alt="img" loading="lazy" src="https://img2022.cnblogs.com/blog/907818/202202/907818-20220226170104527-1242488579.jpg?watermark/2/text/aHR0cHM6Ly93d3cuZHZvbXUuY29t/font/5a6L5L2T/fontsize/25/fill/I0ZGMDAwMA==/dissolve/50/gravity/SouthEast"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>redis主从复制原理</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E5%8E%9F%E7%90%86/</link><pubDate>Sun, 30 Oct 2022 14:59:36 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E5%8E%9F%E7%90%86/</guid><description>&lt;blockquote&gt;
&lt;p&gt;为什么要有主从复制，使redis具有高可用性！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="多机情况下主从复制"&gt;多机情况下主从复制&lt;/h1&gt;
&lt;h2 id="同步和命令传播"&gt;同步和命令传播&lt;/h2&gt;
&lt;h3 id="同步二进制文件和同步命令区别"&gt;同步二进制文件和同步命令区别&lt;/h3&gt;
&lt;h4 id="同步文件"&gt;同步文件&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;首先需要指定从服务器，发送命令 &lt;code&gt;replicaof 主服务器ip 主服务器端口&lt;/code&gt; （5.0之前使用slaveof）
&lt;ul&gt;
&lt;li&gt;例如，现在有实例 1（ip：172.16.19.3）和实例 2（ip：172.16.19.5），我们在实例 2 上执行以下这个命令后，实例 2 就变成了实例 1 的从库，并从实例 1 上复制数据：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;replicaof 172.16.19.3 &lt;span style="color:#ae81ff"&gt;6379&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;从服务器发送 sync 命令给主服务器，主服务器收到以后，会执行bgsave命令 生成rdb文件，同时会使用缓冲区保存从现在开始执行的所有命令&lt;/li&gt;
&lt;li&gt;主服务器发送rdb文件给从服务器，从服务器同步状态，主服务器还会同步缓存区内的执行命令给从服务器&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="命令传播"&gt;命令传播&lt;/h4&gt;
&lt;p&gt;当主从首次同步完全量数据后，此时主从数据是一致的，但是主服务器是可以一直接受命令的，所以主服务器执行完自己的命令，也需要发送相同的命令给从服务器的，来保证主从服务器的数据一致。&lt;/p&gt;</description></item><item><title>redis持久化机制</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%8C%81%E4%B9%85%E5%8C%96%E6%9C%BA%E5%88%B6/</link><pubDate>Sun, 23 Oct 2022 20:19:45 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E6%8C%81%E4%B9%85%E5%8C%96%E6%9C%BA%E5%88%B6/</guid><description>&lt;h1 id="为什么有持久化机制背景"&gt;为什么有持久化机制背景&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;通过 redis操作数据时，更多的时候是通过内存和cpu打交道，所以会特别快，但是内存有个缺点就是，一断电内存中的数据就没有了，那redis作者还是想尽可能的不丢失内存中的数据，所以redis也有自己的持久化机制。&lt;/p&gt;</description></item><item><title>redis基本数据结构使用与场景</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%9C%BA%E6%99%AF/</link><pubDate>Thu, 20 Oct 2022 22:25:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/redis%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%9C%BA%E6%99%AF/</guid><description>&lt;h2 id="string字符串"&gt;string（字符串）&lt;/h2&gt;
&lt;h3 id="用法"&gt;用法&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 给key设置value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;value&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 根据key 获取 value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;get &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 根据key删除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;del &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 判断是否存在指定key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;exists &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 批量存取键值对&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mset &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;value1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key2&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;value2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 根据key批量获取value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mget &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 给key设置对应的过期时间 单位：秒&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;expire &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;time&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 等价于 set + expire 命令组合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;setex &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;time&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;value&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 如果key不存在则set 创建，否则返回0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;setnx &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;value&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 如果value为整数 可用 incr命令每次自增1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;incr &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 使用incrby命令对整数值 进行增加 number&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;incrby &lt;span style="color:#f92672"&gt;[&lt;/span&gt;key&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;number&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="使用场景"&gt;使用场景&lt;/h3&gt;
&lt;p&gt;存储key-value键值对，可以用做缓存
使用setnx 实现分布式锁
使用 incr 命令 用作计数器
分布式系统全局序列号&lt;/p&gt;</description></item><item><title>“万金油”的String，为什么不好用了？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%B8%87%E9%87%91%E6%B2%B9-%E7%9A%84string%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%A5%BD%E7%94%A8%E4%BA%86/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%B8%87%E9%87%91%E6%B2%B9-%E7%9A%84string%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%A5%BD%E7%94%A8%E4%BA%86/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;从今天开始，我们就要进入“实践篇”了。接下来，我们会用 5 节课的时间学习“数据结构”。我会介绍节省内存开销以及保存和统计海量数据的数据类型及其底层数据结构，还会围绕典型的应用场景（例如地址位置查询、时间序列数据库读写和消息队列存取），跟你分享使用 Redis 的数据类型和 module 扩展功能来满足需求的具体方案。&lt;/p&gt;</description></item><item><title>38 _ 通信开销：限制Redis Cluster规模的关键因素</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/38-%E9%80%9A%E4%BF%A1%E5%BC%80%E9%94%80%E9%99%90%E5%88%B6redis-cluster%E8%A7%84%E6%A8%A1%E7%9A%84%E5%85%B3%E9%94%AE%E5%9B%A0%E7%B4%A0/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/38-%E9%80%9A%E4%BF%A1%E5%BC%80%E9%94%80%E9%99%90%E5%88%B6redis-cluster%E8%A7%84%E6%A8%A1%E7%9A%84%E5%85%B3%E9%94%AE%E5%9B%A0%E7%B4%A0/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis Cluster 能保存的数据量以及支撑的吞吐量，跟集群的实例规模密切相关。Redis 官方给出了 Redis Cluster 的规模上限，就是一个集群运行 1000 个实例。&lt;/p&gt;
&lt;p&gt;那么，你可能会问，为什么要限定集群规模呢？其实，这里的一个关键因素就是，实例间的通信开销会随着实例规模增加而增大，在集群超过一定规模时（比如 800 节点），集群吞吐量反而会下降。所以，集群的实际规模会受到限制。&lt;/p&gt;</description></item><item><title>40 _ Redis的下一步：基于NVM内存的实践</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/40-redis%E7%9A%84%E4%B8%8B%E4%B8%80%E6%AD%A5%E5%9F%BA%E4%BA%8Envm%E5%86%85%E5%AD%98%E7%9A%84%E5%AE%9E%E8%B7%B5/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/40-redis%E7%9A%84%E4%B8%8B%E4%B8%80%E6%AD%A5%E5%9F%BA%E4%BA%8Envm%E5%86%85%E5%AD%98%E7%9A%84%E5%AE%9E%E8%B7%B5/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天这节课是咱们课程的最后一节课了，我们来聊聊 Redis 的下一步发展。&lt;/p&gt;
&lt;p&gt;这几年呢，新型非易失存储（Non-Volatile Memory，NVM）器件发展得非常快。NVM 器件具有容量大、性能快、能持久化保存数据的特性，这些刚好就是 Redis 追求的目标。同时，NVM 器件像 DRAM 一样，可以让软件以字节粒度进行寻址访问，所以，在实际应用中，NVM 可以作为内存来使用，我们称为 NVM 内存。&lt;/p&gt;</description></item><item><title>41 _ 第35～40讲课后思考题答案及常见问题答疑</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/41-%E7%AC%AC35-40%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/41-%E7%AC%AC35-40%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天是我们最后一节答疑课，我会带你一起分析一下第 35～40 讲的课后思考题。同时，我还会讲解两个典型问题，分别是原子操作使用问题，以及 Redis 和其他键值数据库的对比情况。&lt;/p&gt;</description></item><item><title>AOF日志：宕机了，Redis如何避免数据丢失？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/aof%E6%97%A5%E5%BF%97%E5%AE%95%E6%9C%BA%E4%BA%86redis%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/aof%E6%97%A5%E5%BF%97%E5%AE%95%E6%9C%BA%E4%BA%86redis%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;如果有人问你：“你会把 Redis 用在什么业务场景下？”我想你大概率会说：“我会把它当作缓存使用，因为它把后端数据库中的数据存储在内存中，然后直接从内存中读取数据，响应速度会非常快。”没错，这确实是 Redis 的一个普遍使用场景，但是，这里也有一个绝对不能忽略的问题：一旦服务器宕机，内存中的数据将全部丢失。&lt;/p&gt;</description></item><item><title>Codis VS Redis Cluster：我该选择哪一个集群方案？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/codis-vs-redis-cluster%E6%88%91%E8%AF%A5%E9%80%89%E6%8B%A9%E5%93%AA%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4%E6%96%B9%E6%A1%88/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/codis-vs-redis-cluster%E6%88%91%E8%AF%A5%E9%80%89%E6%8B%A9%E5%93%AA%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4%E6%96%B9%E6%A1%88/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis 的切片集群使用多个实例保存数据，能够很好地应对大数据量的场景。在&lt;!-- raw HTML omitted --&gt;第 8 讲&lt;!-- raw HTML omitted --&gt;中，我们学习了 Redis 官方提供的切片集群方案 Redis Cluster，这为你掌握切片集群打下了基础。今天，我再来带你进阶一下，我们来学习下 Redis Cluster 方案正式发布前，业界已经广泛使用的 Codis。&lt;/p&gt;</description></item><item><title>GEO是什么？还可以定义新的数据类型吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/geo%E6%98%AF%E4%BB%80%E4%B9%88%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%AE%9A%E4%B9%89%E6%96%B0%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%90%97/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/geo%E6%98%AF%E4%BB%80%E4%B9%88%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%AE%9A%E4%B9%89%E6%96%B0%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%90%97/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在&lt;!-- raw HTML omitted --&gt;第 2 讲&lt;!-- raw HTML omitted --&gt;中，我们学习了 Redis 的 5 大基本数据类型：String、List、Hash、Set 和 Sorted Set，它们可以满足大多数的数据存储需求，但是在面对海量数据统计时，它们的内存开销很大，而且对于一些特殊的场景，它们是无法支持的。所以，Redis 还提供了 3 种扩展数据类型，分别是 Bitmap、HyperLogLog 和 GEO。前两种我在上节课已经重点介绍过了，今天，我再具体讲一讲 GEO。&lt;/p&gt;</description></item><item><title>Pika如何基于SSD实现大容量Redis？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/pika%E5%A6%82%E4%BD%95%E5%9F%BA%E4%BA%8Essd%E5%AE%9E%E7%8E%B0%E5%A4%A7%E5%AE%B9%E9%87%8Fredis/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/pika%E5%A6%82%E4%BD%95%E5%9F%BA%E4%BA%8Essd%E5%AE%9E%E7%8E%B0%E5%A4%A7%E5%AE%B9%E9%87%8Fredis/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们在应用 Redis 时，随着业务数据的增加（比如说电商业务中，随着用户规模和商品数量的增加），就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群，把数据分散保存到多个实例上。但是这样做的话，会有一个问题，如果要保存的数据总量很大，但是每个实例保存的数据量较小的话，就会导致集群的实例规模增加，这会让集群的运维管理变得复杂，增加开销。&lt;/p&gt;</description></item><item><title>Redis支撑秒杀场景的关键技术和实践都有哪些？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis%E6%94%AF%E6%92%91%E7%A7%92%E6%9D%80%E5%9C%BA%E6%99%AF%E7%9A%84%E5%85%B3%E9%94%AE%E6%8A%80%E6%9C%AF%E5%92%8C%E5%AE%9E%E8%B7%B5%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis%E6%94%AF%E6%92%91%E7%A7%92%E6%9D%80%E5%9C%BA%E6%99%AF%E7%9A%84%E5%85%B3%E9%94%AE%E6%8A%80%E6%9C%AF%E5%92%8C%E5%AE%9E%E8%B7%B5%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;秒杀是一个非常典型的活动场景，比如，在双 11、618 等电商促销活动中，都会有秒杀场景。秒杀场景的业务特点是限时限量，业务系统要处理瞬时的大量高并发请求，而 Redis 就经常被用来支撑秒杀活动。&lt;/p&gt;</description></item><item><title>Redis主从同步与故障切换，有哪些坑？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5%E4%B8%8E%E6%95%85%E9%9A%9C%E5%88%87%E6%8D%A2%E6%9C%89%E5%93%AA%E4%BA%9B%E5%9D%91/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/redis%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5%E4%B8%8E%E6%95%85%E9%9A%9C%E5%88%87%E6%8D%A2%E6%9C%89%E5%93%AA%E4%BA%9B%E5%9D%91/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis 的主从同步机制不仅可以让从库服务更多的读请求，分担主库的压力，而且还能在主库发生故障时，进行主从库切换，提供高可靠服务。&lt;/p&gt;
&lt;p&gt;不过，在实际使用主从机制的时候，我们很容易踩到一些坑。这节课，我就向你介绍 3 个坑，分别是主从数据不一致、读到过期数据，以及配置项设置得不合理从而导致服务挂掉。&lt;/p&gt;</description></item><item><title>波动的响应延迟：如何应对变慢的Redis？（上）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B3%A2%E5%8A%A8%E7%9A%84%E5%93%8D%E5%BA%94%E5%BB%B6%E8%BF%9F%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%8F%98%E6%85%A2%E7%9A%84redis%E4%B8%8A/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B3%A2%E5%8A%A8%E7%9A%84%E5%93%8D%E5%BA%94%E5%BB%B6%E8%BF%9F%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%8F%98%E6%85%A2%E7%9A%84redis%E4%B8%8A/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在 Redis 的实际部署应用中，有一个非常严重的问题，那就是 Redis 突然变慢了。一旦出现这个问题，不仅会直接影响用户的使用体验，还可能会影响到“旁人”，也就是和 Redis 在同一个业务系统中的其他系统，比如说数据库。&lt;/p&gt;</description></item><item><title>波动的响应延迟：如何应对变慢的Redis？（下）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B3%A2%E5%8A%A8%E7%9A%84%E5%93%8D%E5%BA%94%E5%BB%B6%E8%BF%9F%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%8F%98%E6%85%A2%E7%9A%84redis%E4%B8%8B/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B3%A2%E5%8A%A8%E7%9A%84%E5%93%8D%E5%BA%94%E5%BB%B6%E8%BF%9F%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%8F%98%E6%85%A2%E7%9A%84redis%E4%B8%8B/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我介绍了判断 Redis 变慢的两种方法，分别是响应延迟和基线性能。除此之外，我还给你分享了从 Redis 的自身命令操作层面排查和解决问题的两种方案。&lt;/p&gt;</description></item><item><title>第1～9讲课后思考题答案及常见问题答疑</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC1-9%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC1-9%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;咱们的课程已经更新 9 讲了，这段时间，我收到了很多留言。很多同学都认真地回答了课后思考题，有些回答甚至可以说是标准答案。另外，还有很多同学针对 Redis 的基本原理和关键机制，提出了非常好的问题，值得好好讨论一下。&lt;/p&gt;</description></item><item><title>第11～21讲课后思考题答案及常见问题答疑</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC11-21%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC11-21%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;咱们的课程已经更新到第 21 讲了，今天，我们来进行一场答疑。&lt;/p&gt;
&lt;p&gt;前半部分，我会给你讲解第 11～21 讲的课后思考题。在学习这部分内容时，可以和你的答案进行对照，看看还有哪里没有考虑到。当然，有些问题不一定有标准答案，我们还可以继续讨论。&lt;/p&gt;</description></item><item><title>第23~33讲课后思考题答案及常见问题答疑</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC23-33%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%AC%AC23-33%E8%AE%B2%E8%AF%BE%E5%90%8E%E6%80%9D%E8%80%83%E9%A2%98%E7%AD%94%E6%A1%88%E5%8F%8A%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天，又到了我们的答疑时间，我们一起来学习下第 23～33 讲的课后思考题。同时，我还会给你讲解两道典型问题。&lt;/p&gt;
&lt;h2 id="课后思考题答案"&gt;课后思考题答案&lt;/h2&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;p&gt;问题：Redis 的只读缓存和使用直写策略的读写缓存，都会把数据同步写到后端数据库中，你觉得它们有什么区别吗？&lt;/p&gt;</description></item><item><title>高性能IO模型：为什么单线程Redis能那么快？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E9%AB%98%E6%80%A7%E8%83%BDio%E6%A8%A1%E5%9E%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8D%95%E7%BA%BF%E7%A8%8Bredis%E8%83%BD%E9%82%A3%E4%B9%88%E5%BF%AB/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E9%AB%98%E6%80%A7%E8%83%BDio%E6%A8%A1%E5%9E%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8D%95%E7%BA%BF%E7%A8%8Bredis%E8%83%BD%E9%82%A3%E4%B9%88%E5%BF%AB/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天，我们来探讨一个很多人都很关心的问题：“为什么单线程的 Redis 能那么快？”&lt;/p&gt;
&lt;p&gt;首先，我要和你厘清一个事实，我们通常说，Redis 是单线程，主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的，这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能，比如持久化、异步删除、集群数据同步等，其实是由额外的线程执行的。&lt;/p&gt;</description></item><item><title>缓冲区：一个可能引发“惨案”的地方</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%86%B2%E5%8C%BA%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%83%BD%E5%BC%95%E5%8F%91-%E6%83%A8%E6%A1%88-%E7%9A%84%E5%9C%B0%E6%96%B9/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%86%B2%E5%8C%BA%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%83%BD%E5%BC%95%E5%8F%91-%E6%83%A8%E6%A1%88-%E7%9A%84%E5%9C%B0%E6%96%B9/</guid><description>&lt;p&gt;你好，我是蒋德钧。今天，我们一起来学习下 Redis 中缓冲区的用法。&lt;/p&gt;
&lt;p&gt;缓冲区的功能其实很简单，主要就是用一块内存空间来暂时存放命令数据，以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。但因为缓冲区的内存空间有限，如果往里面写入数据的速度持续地大于从里面读取数据的速度，就会导致缓冲区需要越来越多的内存来暂存数据。当缓冲区占用的内存超出了设定的上限阈值时，就会出现缓冲区溢出。&lt;/p&gt;</description></item><item><title>缓存被污染了，该怎么办？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E8%A2%AB%E6%B1%A1%E6%9F%93%E4%BA%86%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E8%A2%AB%E6%B1%A1%E6%9F%93%E4%BA%86%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们应用 Redis 缓存时，如果能缓存会被反复访问的数据，那就能加速业务应用的访问。但是，如果发生了缓存污染，那么，缓存对业务应用的加速作用就减少了。&lt;/p&gt;</description></item><item><title>缓存异常（上）：如何解决缓存和数据库的数据不一致问题？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E5%BC%82%E5%B8%B8%E4%B8%8A%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E5%92%8C%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E5%BC%82%E5%B8%B8%E4%B8%8A%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E5%92%8C%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在实际应用 Redis 缓存时，我们经常会遇到一些异常问题，概括来说有 4 个方面：缓存中的数据和数据库中的不一致；缓存雪崩；缓存击穿和缓存穿透。&lt;/p&gt;</description></item><item><title>缓存异常（下）：如何解决缓存雪崩、击穿、穿透难题？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E5%BC%82%E5%B8%B8%E4%B8%8B%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9-%E5%87%BB%E7%A9%BF-%E7%A9%BF%E9%80%8F%E9%9A%BE%E9%A2%98/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BC%93%E5%AD%98%E5%BC%82%E5%B8%B8%E4%B8%8B%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9-%E5%87%BB%E7%A9%BF-%E7%A9%BF%E9%80%8F%E9%9A%BE%E9%A2%98/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我们学习了缓存和数据库的数据不一致问题和应对方法。除了数据不一致问题，我们常常还会面临缓存异常的三个问题，分别是缓存雪崩、缓存击穿和缓存穿透。这三个问题一旦发生，会导致大量的请求积压到数据库层。如果请求的并发量很大，就会导致数据库宕机或是故障，这就是很严重的生产事故了。&lt;/p&gt;</description></item><item><title>基本架构：一个键值数据库包含什么？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%9E%84%E4%B8%80%E4%B8%AA%E9%94%AE%E5%80%BC%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8C%85%E5%90%AB%E4%BB%80%E4%B9%88/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%9E%84%E4%B8%80%E4%B8%AA%E9%94%AE%E5%80%BC%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8C%85%E5%90%AB%E4%BB%80%E4%B9%88/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们知道，Redis 是典型的键值数据库，所以今天，我准备手把手地带你构建一个简单的键值数据库。为啥要这么做呢？&lt;/p&gt;
&lt;p&gt;还记得我在开篇词说过吗？Redis 本身比较复杂，如果我们一上来就直接研究一个个具体的技术点，比如“单线程”“缓存”等，虽然可以直接学习到具体的内容，甚至立马就能解决一些小问题，但是这样学，很容易迷失在细枝末节里。&lt;/p&gt;</description></item><item><title>加餐（二）_ Kaito：我是如何学习Redis的？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%BA%8C-kaito%E6%88%91%E6%98%AF%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0redis%E7%9A%84/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%BA%8C-kaito%E6%88%91%E6%98%AF%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0redis%E7%9A%84/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在看课程留言的时候，我发现，Kaito 同学的总结常常特别精彩，所以就请编辑帮我联系了 Kaito，想请他来聊一聊具体是怎么学习 Redis 的。&lt;/p&gt;</description></item><item><title>加餐（六）_ Redis的使用规范小建议</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E5%85%AD-redis%E7%9A%84%E4%BD%BF%E7%94%A8%E8%A7%84%E8%8C%83%E5%B0%8F%E5%BB%BA%E8%AE%AE/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E5%85%AD-redis%E7%9A%84%E4%BD%BF%E7%94%A8%E8%A7%84%E8%8C%83%E5%B0%8F%E5%BB%BA%E8%AE%AE/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天的加餐，我们来聊一个轻松点儿的话题，我来给你介绍一下 Redis 的使用规范，包括键值对使用、业务数据保存和命令使用规范。&lt;/p&gt;
&lt;p&gt;毕竟，高性能和节省内存，是我们的两个目标，只有规范地使用 Redis，才能真正实现这两个目标。如果说之前的内容教会了你怎么用，那么今天的内容，就是帮助你用好 Redis，尽量不出错。&lt;/p&gt;</description></item><item><title>加餐（七） _ 从微博的Redis实践中，我们可以学到哪些经验？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%83-%E4%BB%8E%E5%BE%AE%E5%8D%9A%E7%9A%84redis%E5%AE%9E%E8%B7%B5%E4%B8%AD%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E5%AD%A6%E5%88%B0%E5%93%AA%E4%BA%9B%E7%BB%8F%E9%AA%8C/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%83-%E4%BB%8E%E5%BE%AE%E5%8D%9A%E7%9A%84redis%E5%AE%9E%E8%B7%B5%E4%B8%AD%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E5%AD%A6%E5%88%B0%E5%93%AA%E4%BA%9B%E7%BB%8F%E9%AA%8C/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们知道，微博内部的业务场景中广泛使用了 Redis，积累了大量的应用和优化经验。微博有位专家曾有过一个&lt;!-- raw HTML omitted --&gt;分享&lt;!-- raw HTML omitted --&gt;，介绍了 Redis 在微博的优化之路，其中有很多的优秀经验。&lt;/p&gt;</description></item><item><title>加餐（三）-Kaito：我希望成为在压力中成长的人</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%89-kaito%E6%88%91%E5%B8%8C%E6%9C%9B%E6%88%90%E4%B8%BA%E5%9C%A8%E5%8E%8B%E5%8A%9B%E4%B8%AD%E6%88%90%E9%95%BF%E7%9A%84%E4%BA%BA/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%89-kaito%E6%88%91%E5%B8%8C%E6%9C%9B%E6%88%90%E4%B8%BA%E5%9C%A8%E5%8E%8B%E5%8A%9B%E4%B8%AD%E6%88%90%E9%95%BF%E7%9A%84%E4%BA%BA/</guid><description>&lt;p&gt;你好，我是 Kaito。&lt;/p&gt;
&lt;p&gt;上一次，我分享了我总结的 Redis 学习路径，在留言区的交流和互动中，我有了很多新的收获。今天，我想再分享一下我对学习这件事儿的认识以及我的学习方法，包括领先一步的心理建设、事半功倍的学习方法以及提升效率的小技巧。&lt;/p&gt;</description></item><item><title>加餐（四）-Redis客户端如何与服务器端交换命令和数据？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E5%9B%9B-redis%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%A6%82%E4%BD%95%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E4%BA%A4%E6%8D%A2%E5%91%BD%E4%BB%A4%E5%92%8C%E6%95%B0%E6%8D%AE/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E5%9B%9B-redis%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%A6%82%E4%BD%95%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E4%BA%A4%E6%8D%A2%E5%91%BD%E4%BB%A4%E5%92%8C%E6%95%B0%E6%8D%AE/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在前面的课程中，我们主要学习了 Redis 服务器端的机制和关键技术，很少涉及到客户端的问题。但是，Redis 采用的是典型的 client-server（服务器端 - 客户端）架构，客户端会发送请求给服务器端，服务器端会返回响应给客户端。&lt;/p&gt;</description></item><item><title>加餐（五）- Redis有哪些好用的运维工具？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%BA%94-redis%E6%9C%89%E5%93%AA%E4%BA%9B%E5%A5%BD%E7%94%A8%E7%9A%84%E8%BF%90%E7%BB%B4%E5%B7%A5%E5%85%B7/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%BA%94-redis%E6%9C%89%E5%93%AA%E4%BA%9B%E5%A5%BD%E7%94%A8%E7%9A%84%E8%BF%90%E7%BB%B4%E5%B7%A5%E5%85%B7/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;今天的加餐，我来给你分享一些好用的 Redis 运维工具。&lt;/p&gt;
&lt;p&gt;我们在应用 Redis 时，经常会面临的运维工作，包括 Redis 的运行状态监控，数据迁移，主从集群、切片集群的部署和运维。接下来，我就从这三个方面，给你介绍一些工具。我们先来学习下监控 Redis 实时运行状态的工具，这些工具都用到了 Redis 提供的一个监控命令：INFO。&lt;/p&gt;</description></item><item><title>加餐（一）_ 经典的Redis学习资料有哪些？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%80-%E7%BB%8F%E5%85%B8%E7%9A%84redis%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%9C%89%E5%93%AA%E4%BA%9B/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%8A%A0%E9%A4%90%E4%B8%80-%E7%BB%8F%E5%85%B8%E7%9A%84redis%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%9C%89%E5%93%AA%E4%BA%9B/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;咱们课程的“基础篇”已经结束了。在这个模块，我们学习了 Redis 的系统架构、数据结构、线程模型、持久化、主从复制和切片集群这些核心知识点，相信你已经初步构建了自己的一套基础知识框架。&lt;/p&gt;</description></item><item><title>结束语 _ 从学习Redis到向Redis学习</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BB%93%E6%9D%9F%E8%AF%AD-%E4%BB%8E%E5%AD%A6%E4%B9%A0redis%E5%88%B0%E5%90%91redis%E5%AD%A6%E4%B9%A0/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E7%BB%93%E6%9D%9F%E8%AF%AD-%E4%BB%8E%E5%AD%A6%E4%B9%A0redis%E5%88%B0%E5%90%91redis%E5%AD%A6%E4%B9%A0/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;这么快就到课程的尾声了，到了和你说再见的时候了。&lt;/p&gt;
&lt;p&gt;在过去的 4 个多月时间里，我们掌握了 Redis 的各种关键技术和核心知识。在课程的最后，我想带你切换一个视角：如果说我们之前一直在学习 Redis 本身，那么今天，我们来看看能向 Redis 学到什么。&lt;/p&gt;</description></item><item><title>开篇词丨这样学Redis，才能技高一筹</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%BC%80%E7%AF%87%E8%AF%8D%E4%B8%A8%E8%BF%99%E6%A0%B7%E5%AD%A6redis%E6%89%8D%E8%83%BD%E6%8A%80%E9%AB%98%E4%B8%80%E7%AD%B9/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%BC%80%E7%AF%87%E8%AF%8D%E4%B8%A8%E8%BF%99%E6%A0%B7%E5%AD%A6redis%E6%89%8D%E8%83%BD%E6%8A%80%E9%AB%98%E4%B8%80%E7%AD%B9/</guid><description>&lt;p&gt;你好，我是蒋德钧，欢迎和我一起学习 Redis。&lt;/p&gt;
&lt;p&gt;我博士毕业后，就一直在中科院计算所工作，现在的职位是副研究员。在过去的 14 年时间里，我一直从事互联网底层基础设施方面的研究工作，主要的研究方向为新型存储介质、键值数据库、存储系统和操作系统。&lt;/p&gt;</description></item><item><title>脑裂：一次奇怪的数据丢失</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E8%84%91%E8%A3%82%E4%B8%80%E6%AC%A1%E5%A5%87%E6%80%AA%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E8%84%91%E8%A3%82%E4%B8%80%E6%AC%A1%E5%A5%87%E6%80%AA%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在使用主从集群时，我曾遇到过这样一个问题：我们的主从集群有 1 个主库、5 个从库和 3 个哨兵实例，在使用的过程中，我们发现客户端发送的一些数据丢失了，这直接影响到了业务层的数据可靠性。&lt;/p&gt;</description></item><item><title>内存快照：宕机后，Redis如何实现快速恢复？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%86%85%E5%AD%98%E5%BF%AB%E7%85%A7%E5%AE%95%E6%9C%BA%E5%90%8Eredis%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%BF%AB%E9%80%9F%E6%81%A2%E5%A4%8D/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%86%85%E5%AD%98%E5%BF%AB%E7%85%A7%E5%AE%95%E6%9C%BA%E5%90%8Eredis%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%BF%AB%E9%80%9F%E6%81%A2%E5%A4%8D/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我们学习了 Redis 避免数据丢失的 AOF 方法。这个方法的好处，是每次执行只需要记录操作命令，需要持久化的数据量不大。一般而言，只要你采用的不是 always 的持久化策略，就不会对性能造成太大影响。&lt;/p&gt;</description></item><item><title>旁路缓存：Redis是如何工作的？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%97%81%E8%B7%AF%E7%BC%93%E5%AD%98redis%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%97%81%E8%B7%AF%E7%BC%93%E5%AD%98redis%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们知道，Redis 提供了高性能的数据存取功能，所以广泛应用在缓存场景中，既能有效地提升业务应用的响应速度，还可以避免把高并发大压力的请求发送到数据库层。&lt;/p&gt;</description></item><item><title>期中测试题-一套习题，测出你的掌握程度</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%9F%E4%B8%AD%E6%B5%8B%E8%AF%95%E9%A2%98-%E4%B8%80%E5%A5%97%E4%B9%A0%E9%A2%98%E6%B5%8B%E5%87%BA%E4%BD%A0%E7%9A%84%E6%8E%8C%E6%8F%A1%E7%A8%8B%E5%BA%A6/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%9F%E4%B8%AD%E6%B5%8B%E8%AF%95%E9%A2%98-%E4%B8%80%E5%A5%97%E4%B9%A0%E9%A2%98%E6%B5%8B%E5%87%BA%E4%BD%A0%E7%9A%84%E6%8E%8C%E6%8F%A1%E7%A8%8B%E5%BA%A6/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;咱们的课程已经更新过半了，我看到很多同学一直在坚持学习，课程每次更新后，都会认真回答课后题，而且还会分享自己的思考和经验。但是，我也发现，最近有不少同学都掉队了，积累了很多节课都没有学习过。&lt;/p&gt;</description></item><item><title>期中测试题答案-这些问题，你都答对了吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%9F%E4%B8%AD%E6%B5%8B%E8%AF%95%E9%A2%98%E7%AD%94%E6%A1%88-%E8%BF%99%E4%BA%9B%E9%97%AE%E9%A2%98%E4%BD%A0%E9%83%BD%E7%AD%94%E5%AF%B9%E4%BA%86%E5%90%97/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%9F%E4%B8%AD%E6%B5%8B%E8%AF%95%E9%A2%98%E7%AD%94%E6%A1%88-%E8%BF%99%E4%BA%9B%E9%97%AE%E9%A2%98%E4%BD%A0%E9%83%BD%E7%AD%94%E5%AF%B9%E4%BA%86%E5%90%97/</guid><description>&lt;p&gt;你好，我是蒋德钧。今天，我来公布一下主观题的答案。&lt;/p&gt;
&lt;h3 id="第一题"&gt;第一题&lt;/h3&gt;
&lt;p&gt;Redis 在接收多个网络客户端发送的请求操作时，如果有一个客户端和 Redis 的网络连接断开了，Redis 会一直等待该客户端恢复连接吗？为什么？&lt;/p&gt;</description></item><item><title>切片集群：数据增多了，是该加内存还是加实例？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%88%87%E7%89%87%E9%9B%86%E7%BE%A4%E6%95%B0%E6%8D%AE%E5%A2%9E%E5%A4%9A%E4%BA%86%E6%98%AF%E8%AF%A5%E5%8A%A0%E5%86%85%E5%AD%98%E8%BF%98%E6%98%AF%E5%8A%A0%E5%AE%9E%E4%BE%8B/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%88%87%E7%89%87%E9%9B%86%E7%BE%A4%E6%95%B0%E6%8D%AE%E5%A2%9E%E5%A4%9A%E4%BA%86%E6%98%AF%E8%AF%A5%E5%8A%A0%E5%86%85%E5%AD%98%E8%BF%98%E6%98%AF%E5%8A%A0%E5%AE%9E%E4%BE%8B/</guid><description>&lt;p&gt;你好，我是蒋德钧。今天我们来学习切片集群。&lt;/p&gt;
&lt;p&gt;我曾遇到过这么一个需求：要用 Redis 保存 5000 万个键值对，每个键值对大约是 512B，为了能快速部署并对外提供服务，我们采用云主机来运行 Redis 实例，那么，该如何选择云主机的内存容量呢？&lt;/p&gt;</description></item><item><title>如何使用Redis实现分布式锁？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8redis%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8redis%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我提到，在应对并发问题时，除了原子操作，Redis 客户端还可以通过加锁的方式，来控制并发写操作对共享数据的修改，从而保证数据的正确性。&lt;/p&gt;</description></item><item><title>如何在Redis中保存时间序列数据？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%A6%82%E4%BD%95%E5%9C%A8redis%E4%B8%AD%E4%BF%9D%E5%AD%98%E6%97%B6%E9%97%B4%E5%BA%8F%E5%88%97%E6%95%B0%E6%8D%AE/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%A6%82%E4%BD%95%E5%9C%A8redis%E4%B8%AD%E4%BF%9D%E5%AD%98%E6%97%B6%E9%97%B4%E5%BA%8F%E5%88%97%E6%95%B0%E6%8D%AE/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们现在做互联网产品的时候，都有这么一个需求：记录用户在网站或者 App 上的点击行为数据，来分析用户行为。这里的数据一般包括用户 ID、行为类型（例如浏览、登录、下单等）、行为发生的时间戳：&lt;/p&gt;</description></item><item><title>删除数据后，为什么内存占用率还是很高？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE%E5%90%8E%E4%B8%BA%E4%BB%80%E4%B9%88%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E7%8E%87%E8%BF%98%E6%98%AF%E5%BE%88%E9%AB%98/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE%E5%90%8E%E4%B8%BA%E4%BB%80%E4%B9%88%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E7%8E%87%E8%BF%98%E6%98%AF%E5%BE%88%E9%AB%98/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在使用 Redis 时，我们经常会遇到这样一个问题：明明做了数据删除，数据量已经不大了，为什么使用 top 命令查看时，还会发现 Redis 占用了很多内存呢？&lt;/p&gt;</description></item><item><title>哨兵机制：主库挂了，如何不间断服务？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%93%A8%E5%85%B5%E6%9C%BA%E5%88%B6%E4%B8%BB%E5%BA%93%E6%8C%82%E4%BA%86%E5%A6%82%E4%BD%95%E4%B8%8D%E9%97%B4%E6%96%AD%E6%9C%8D%E5%8A%A1/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%93%A8%E5%85%B5%E6%9C%BA%E5%88%B6%E4%B8%BB%E5%BA%93%E6%8C%82%E4%BA%86%E5%A6%82%E4%BD%95%E4%B8%8D%E9%97%B4%E6%96%AD%E6%9C%8D%E5%8A%A1/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我们学习了主从库集群模式。在这个模式下，如果从库发生故障了，客户端可以继续向主库或其他从库发送请求，进行相关的操作，但是如果主库发生故障了，那就直接会影响到从库的同步，因为从库没有相应的主库可以进行数据复制操作了。&lt;/p&gt;</description></item><item><title>哨兵集群：哨兵挂了，主从库还能切换吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%93%A8%E5%85%B5%E9%9B%86%E7%BE%A4%E5%93%A8%E5%85%B5%E6%8C%82%E4%BA%86%E4%B8%BB%E4%BB%8E%E5%BA%93%E8%BF%98%E8%83%BD%E5%88%87%E6%8D%A2%E5%90%97/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%93%A8%E5%85%B5%E9%9B%86%E7%BE%A4%E5%93%A8%E5%85%B5%E6%8C%82%E4%BA%86%E4%B8%BB%E4%BB%8E%E5%BA%93%E8%BF%98%E8%83%BD%E5%88%87%E6%8D%A2%E5%90%97/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;上节课，我们学习了哨兵机制，它可以实现主从库的自动切换。通过部署多个实例，就形成了一个哨兵集群。哨兵集群中的多个实例共同判断，可以降低对主库下线的误判率。&lt;/p&gt;</description></item><item><title>事务机制：Redis能实现ACID属性吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%BA%8B%E5%8A%A1%E6%9C%BA%E5%88%B6redis%E8%83%BD%E5%AE%9E%E7%8E%B0acid%E5%B1%9E%E6%80%A7%E5%90%97/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%BA%8B%E5%8A%A1%E6%9C%BA%E5%88%B6redis%E8%83%BD%E5%AE%9E%E7%8E%B0acid%E5%B1%9E%E6%80%A7%E5%90%97/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;事务是数据库的一个重要功能。所谓的事务，就是指对数据进行读写的一系列操作。事务在执行时，会提供专门的属性保证，包括原子性（Atomicity）、一致性（Consistency）、隔离性（Isolation）和持久性（Durability），也就是 ACID 属性。这些属性既包括了对事务执行结果的要求，也有对数据库在事务执行前后的数据状态变化的要求。&lt;/p&gt;</description></item><item><title>数据分布优化：如何应对数据倾斜？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E5%88%86%E5%B8%83%E4%BC%98%E5%8C%96%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E6%95%B0%E6%8D%AE%E5%80%BE%E6%96%9C/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E5%88%86%E5%B8%83%E4%BC%98%E5%8C%96%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E6%95%B0%E6%8D%AE%E5%80%BE%E6%96%9C/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在切片集群中，数据会按照一定的分布规则分散到不同的实例上保存。比如，在使用 Redis Cluster 或 Codis 时，数据都会先按照 CRC 算法的计算值对 Slot（逻辑槽）取模，同时，所有的 Slot 又会由运维管理员分配到不同的实例上。这样，数据就被保存到相应的实例上了。&lt;/p&gt;</description></item><item><title>数据结构：快速的Redis有哪些慢操作？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BF%AB%E9%80%9F%E7%9A%84redis%E6%9C%89%E5%93%AA%E4%BA%9B%E6%85%A2%E6%93%8D%E4%BD%9C/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BF%AB%E9%80%9F%E7%9A%84redis%E6%9C%89%E5%93%AA%E4%BA%9B%E6%85%A2%E6%93%8D%E4%BD%9C/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;一提到 Redis，我们的脑子里马上就会出现一个词：“快。”但是你有没有想过，Redis 的快，到底是快在哪里呢？实际上，这里有一个重要的表现：它接收到一个键值对操作后，能以微秒级别的速度找到数据，并快速完成操作。&lt;/p&gt;</description></item><item><title>数据同步：主从库如何实现数据一致？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5%E4%B8%BB%E4%BB%8E%E5%BA%93%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E4%B8%80%E8%87%B4/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5%E4%B8%BB%E4%BB%8E%E5%BA%93%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E4%B8%80%E8%87%B4/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;前两节课，我们学习了 AOF 和 RDB，如果 Redis 发生了宕机，它们可以分别通过回放日志和重新读入 RDB 文件的方式恢复数据，从而保证尽量少丢失数据，提升可靠性。&lt;/p&gt;</description></item><item><title>替换策略：缓存满了怎么办？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9B%BF%E6%8D%A2%E7%AD%96%E7%95%A5%E7%BC%93%E5%AD%98%E6%BB%A1%E4%BA%86%E6%80%8E%E4%B9%88%E5%8A%9E/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9B%BF%E6%8D%A2%E7%AD%96%E7%95%A5%E7%BC%93%E5%AD%98%E6%BB%A1%E4%BA%86%E6%80%8E%E4%B9%88%E5%8A%9E/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis 缓存使用内存来保存数据，避免业务应用从后端数据库中读取数据，可以提升应用的响应速度。那么，如果我们把所有要访问的数据都放入缓存，是不是一个很好的设计选择呢？其实，这样做的性价比反而不高。&lt;/p&gt;</description></item><item><title>为什么CPU结构也会影响Redis的性能？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%B8%BA%E4%BB%80%E4%B9%88cpu%E7%BB%93%E6%9E%84%E4%B9%9F%E4%BC%9A%E5%BD%B1%E5%93%8Dredis%E7%9A%84%E6%80%A7%E8%83%BD/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E4%B8%BA%E4%BB%80%E4%B9%88cpu%E7%BB%93%E6%9E%84%E4%B9%9F%E4%BC%9A%E5%BD%B1%E5%93%8Dredis%E7%9A%84%E6%80%A7%E8%83%BD/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;很多人都认为 Redis 和 CPU 的关系很简单，就是 Redis 的线程在 CPU 上运行，CPU 快，Redis 处理请求的速度也很快。&lt;/p&gt;
&lt;p&gt;这种认知其实是片面的。CPU 的多核架构以及多 CPU 架构，也会影响到 Redis 的性能。如果不了解 CPU 对 Redis 的影响，在对 Redis 的性能进行调优时，就可能会遗漏一些调优方法，不能把 Redis 的性能发挥到极限。&lt;/p&gt;</description></item><item><title>无锁的原子操作：Redis如何应对并发访问？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%97%A0%E9%94%81%E7%9A%84%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9Credis%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%B9%B6%E5%8F%91%E8%AE%BF%E9%97%AE/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%97%A0%E9%94%81%E7%9A%84%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9Credis%E5%A6%82%E4%BD%95%E5%BA%94%E5%AF%B9%E5%B9%B6%E5%8F%91%E8%AE%BF%E9%97%AE/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;我们在使用 Redis 时，不可避免地会遇到并发访问的问题，比如说如果多个用户同时下单，就会对缓存在 Redis 中的商品库存并发更新。一旦有了并发写操作，数据就会被修改，如果我们没有对并发写请求做好控制，就可能导致数据被改错，影响到业务的正常使用（例如库存数据错误，导致下单异常）。&lt;/p&gt;</description></item><item><title>消息队列的考验：Redis有哪些解决方案？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E7%9A%84%E8%80%83%E9%AA%8Credis%E6%9C%89%E5%93%AA%E4%BA%9B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E7%9A%84%E8%80%83%E9%AA%8Credis%E6%9C%89%E5%93%AA%E4%BA%9B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;现在的互联网应用基本上都是采用分布式系统架构进行设计的，而很多分布式系统必备的一个基础软件就是消息队列。&lt;/p&gt;
&lt;p&gt;消息队列要能支持组件通信消息的快速读写，而 Redis 本身支持数据的高速访问，正好可以满足消息队列的读写性能需求。不过，除了性能，消息队列还有其他的要求，所以，很多人都很关心一个问题：“Redis 适合做消息队列吗？”&lt;/p&gt;</description></item><item><title>异步机制：如何避免单线程模型的阻塞？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%BC%82%E6%AD%A5%E6%9C%BA%E5%88%B6%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%8D%95%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E7%9A%84%E9%98%BB%E5%A1%9E/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E5%BC%82%E6%AD%A5%E6%9C%BA%E5%88%B6%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%8D%95%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E7%9A%84%E9%98%BB%E5%A1%9E/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;Redis 之所以被广泛应用，很重要的一个原因就是它支持高性能访问。也正因为这样，我们必须要重视所有可能影响 Redis 性能的因素（例如命令操作、系统配置、关键机制、硬件配置等），不仅要知道具体的机制，尽可能避免性能异常的情况出现，还要提前准备好应对异常的方案。&lt;/p&gt;</description></item><item><title>有一亿个keys要统计，应该用哪种集合？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%89%E4%B8%80%E4%BA%BF%E4%B8%AAkeys%E8%A6%81%E7%BB%9F%E8%AE%A1%E5%BA%94%E8%AF%A5%E7%94%A8%E5%93%AA%E7%A7%8D%E9%9B%86%E5%90%88/</link><pubDate>Tue, 18 Oct 2022 11:09:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/redis%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E4%B8%8E%E5%AE%9E%E6%88%98/%E6%9C%89%E4%B8%80%E4%BA%BF%E4%B8%AAkeys%E8%A6%81%E7%BB%9F%E8%AE%A1%E5%BA%94%E8%AF%A5%E7%94%A8%E5%93%AA%E7%A7%8D%E9%9B%86%E5%90%88/</guid><description>&lt;p&gt;你好，我是蒋德钧。&lt;/p&gt;
&lt;p&gt;在 Web 和移动应用的业务场景中，我们经常需要保存这样一种信息：一个 key 对应了一个数据集合。我举几个例子。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;手机 App 中的每天的用户登录信息：一天对应一系列用户 ID 或移动设备 ID；&lt;/p&gt;</description></item><item><title>指针</title><link>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%8C%87%E9%92%88/</link><pubDate>Tue, 18 Oct 2022 11:07:26 +0800</pubDate><guid>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%8C%87%E9%92%88/</guid><description>&lt;h2 id="指针"&gt;指针&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Wallet&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;Deposit&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;amount&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;address of balance in Deposit is&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;balance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;balance&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;amount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的示例，声明一个&lt;code&gt;Deposit&lt;/code&gt;方法，接受者是&lt;code&gt;w&lt;/code&gt;，如果方法被调用，接受者会被复制返回一个副本，方法体内使用的接受者的副本，所以在方法体内无论如何怎么修改接受者副本的属性，都不会影响到原接受者。&lt;/p&gt;</description></item><item><title>打包环境配置</title><link>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E7%BC%96%E8%AF%91%E4%B8%8E%E6%89%93%E5%8C%85/%E6%89%93%E5%8C%85%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</link><pubDate>Tue, 18 Oct 2022 11:05:43 +0800</pubDate><guid>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E7%BC%96%E8%AF%91%E4%B8%8E%E6%89%93%E5%8C%85/%E6%89%93%E5%8C%85%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</guid><description>&lt;p&gt;在windows下编译Mac可执行程序&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CGO_ENABLED&lt;/span&gt;=&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GOOS&lt;/span&gt;=&lt;span style="color:#a6e22e"&gt;darwin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GOARCH&lt;/span&gt;=&lt;span style="color:#a6e22e"&gt;amd64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;build&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在windows下发编译linux可执行程序&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CGO_ENABLED&lt;/span&gt;=&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GOOS&lt;/span&gt;=&lt;span style="color:#a6e22e"&gt;linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GOARCH&lt;/span&gt;=&lt;span style="color:#a6e22e"&gt;amd64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;build&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;o&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;study_xxqg&lt;/span&gt; .&lt;span style="color:#f92672"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;nohup&lt;/span&gt; .&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;study_xxqg&lt;/span&gt; &amp;gt; .&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;study_xxqg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&amp;gt;&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echo&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;!&amp;gt;&lt;span style="color:#a6e22e"&gt;pid&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;恢复windows默认值&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CGO_ENABLED&lt;/span&gt;=&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;env&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GOOS&lt;/span&gt;=&lt;span style="color:#a6e22e"&gt;windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>appium环境搭建教程（一）</title><link>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/appium%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B%E4%B8%80/</link><pubDate>Fri, 14 Oct 2022 15:01:17 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/appium%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B%E4%B8%80/</guid><description>&lt;p&gt;Appium 是一个开源工具，用于自动化 iOS 手机、 Android 手机。专业话就不多介绍，想要做移动端app自动化，就是它了。下面详细介绍环境搭建过程，并且实现一个简单的自动化。&lt;/p&gt;</description></item><item><title>appium实现微信小程序自动化操作（二）</title><link>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/appium%E5%AE%9E%E7%8E%B0%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%87%AA%E5%8A%A8%E5%8C%96%E6%93%8D%E4%BD%9C%E4%BA%8C/</link><pubDate>Fri, 14 Oct 2022 15:01:15 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/appium%E5%AE%9E%E7%8E%B0%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%87%AA%E5%8A%A8%E5%8C%96%E6%93%8D%E4%BD%9C%E4%BA%8C/</guid><description>&lt;h2 id="准备环境"&gt;准备环境&lt;/h2&gt;
&lt;p&gt;准备运行环境&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;appium server端&lt;/li&gt;
&lt;li&gt;Android sdk&lt;/li&gt;
&lt;li&gt;jdk&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;查看元素需要的环境&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;appium desktop 可以查看手机内的元素&lt;/li&gt;
&lt;li&gt;谷歌浏览器 输入&lt;code&gt;chrome://inspect/#devices&lt;/code&gt;（需要翻墙）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我本人操作的时候是 appium desktop 和谷歌浏览器都是用的，appium desktop 本来是可以切换context的但是 我的不知道是哪里没有配置对，所以看小程序的页面元素就转战 谷歌浏览器啦。&lt;/p&gt;</description></item><item><title>javaAgent初探</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/javaagent/javaagent%E5%88%9D%E6%8E%A2/</link><pubDate>Wed, 28 Sep 2022 20:13:39 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/javaagent/javaagent%E5%88%9D%E6%8E%A2/</guid><description>&lt;h1 id="agent-初探"&gt;agent 初探&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;premain 命令式 在main方法之前执行&lt;/li&gt;
&lt;li&gt;agentmain 以Attach的方式载入，在Java程序启动后执行，1.6提供&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="img.png" loading="lazy" src="https://img.ggball.top/img/img.png?picGo"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Instrumentation&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 添加Transformer(转换器)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * ClassFileTransformer类是一个接口，通常用户只需实现这个接口的 byte[] transform()方法即可；
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * transform这个方法会返回一个已经转换过的对象的byte[]数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param transformer 拦截器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return canRetransform 是否能重新转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;addTransformer&lt;/span&gt;(ClassFileTransformer transformer, &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; canRetransform);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 重新触发类加载，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 该方法可以修改方法体、常量池和属性值，但不能新增、删除、重命名属性或方法，也不能修改方法的签名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param classes Class对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @throws UnmodifiableClassException 异常
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;retransformClasses&lt;/span&gt;(Class&lt;span style="color:#f92672"&gt;&amp;lt;?&amp;gt;&lt;/span&gt;... classes) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; UnmodifiableClassException;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 直接替换类的定义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 重新转换某个对象,并已一个新的class格式，进行转化。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 该方法可以修改方法体、常量池和属性值，但不能新增、删除、重命名属性或方法，也不能修改方法的签名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param definitions ClassDefinition对象[Class定义对象]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @throws ClassNotFoundException,UnmodifiableClassException 异常
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;redefineClasses&lt;/span&gt;(ClassDefinition... definitions)&lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; ClassNotFoundException, UnmodifiableClassException;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 获取当前被JVM加载的所有类对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return Class[] class数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getAllLoadedClasses&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="premain方法介绍"&gt;premain方法介绍&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AgentWithTransFormer&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;premain&lt;/span&gt;(String agentOps, Instrumentation instrumentation) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;premian start 。。&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;agentOps = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; agentOps);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; instrumentation.&lt;span style="color:#a6e22e"&gt;addTransformer&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DefineTransformer(),&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DefineTransformer&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; ClassFileTransformer {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;transform&lt;/span&gt;(ClassLoader loader, String className, Class&lt;span style="color:#f92672"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; classBeingRedefined, ProtectionDomain protectionDomain, &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; classfileBuffer) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IllegalClassFormatException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;premain load class :&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; className);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; classfileBuffer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;premain方法会拦截大部分类（不包含有些系统类），实现类&lt;code&gt;DefineTransformer&lt;/code&gt;需要实现&lt;code&gt;transform&lt;/code&gt;方法，比如我们可以拦截某个类，将某个类的class文件修改，可以整个文件替换或者利用javassist自定义添加或者删除方法。&lt;/p&gt;</description></item><item><title>观察者模式</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="观察者模式"&gt;观察者模式&lt;/h1&gt;
&lt;h2 id="概念"&gt;概念&lt;/h2&gt;
&lt;p&gt;一个动作的发生可以让其他观察者知道&lt;/p&gt;
&lt;h2 id="应用"&gt;应用&lt;/h2&gt;
&lt;h3 id="jdk的observer和-observable"&gt;jdk的observer和 Observable&lt;/h3&gt;
&lt;p&gt;观察者（observer）注册（addObserver()）在被观察者（observable）上，通过方法&lt;code&gt;notifyObservers&lt;/code&gt;来执行每个观察者的update方法，有意思的是，为了防止在循环执行每个观察者的update方法时，可能存在删除或者添加观察者，引起结果的不正确，执行&lt;code&gt;notifyObservers&lt;/code&gt;方法时，都会先生成一个观察者集合快照，并给他加上了锁，使用快照来循环，就不会出现意外。&lt;/p&gt;</description></item><item><title>缓存一致性问题</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BC%93%E5%AD%98%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BC%93%E5%AD%98%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/</guid><description>&lt;h1 id="缓存一致性问题"&gt;缓存一致性问题&lt;/h1&gt;
&lt;h2 id="什么是缓存一致性问题"&gt;什么是缓存一致性问题？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;在JMM中，每个线程都拥有自己的工作内存（逻辑概念，也叫缓存），通过bus总线与内存交互，也就是说每个线程都有自己的工作内存，可以进行读，写操作。不同线程对同一数据进行读写，就会使工作内存之间和主内存的数据不一致的情况。这时候就需要操作系统制定相关规则来维持工作内存之间和主内存的数据的一致性。&lt;/p&gt;</description></item><item><title>继续教育刷课软件</title><link>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E7%8E%A9%E5%85%B7/%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E5%88%B7%E8%AF%BE%E8%BD%AF%E4%BB%B6/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E7%8E%A9%E5%85%B7/%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E5%88%B7%E8%AF%BE%E8%BD%AF%E4%BB%B6/</guid><description>&lt;h2 id="功能说明"&gt;功能说明&lt;/h2&gt;
&lt;p&gt;适合网站&lt;a href="http://plat.xzjxjy.com/"&gt;徐州市专业技术人员继续教育网&lt;/a&gt;,&lt;a href="http://hlbe.chinahrt.cn/area.asp"&gt;呼伦贝尔市专业技术人员继续教育在线学习平台&lt;/a&gt;，指定多个账号，指定年份一键多线程刷课，速度控制在一分钟左右&lt;/p&gt;
&lt;h2 id="使用说明"&gt;使用说明&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载文件后，首先在settings excel文件填入需要的信息，填写好之后请检查是否有误，确保账号密码正确，还有年份格式正确，保存excel 。&lt;/p&gt;</description></item><item><title>设计模式大纲</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%A4%A7%E7%BA%B2/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%A4%A7%E7%BA%B2/</guid><description>&lt;h1 id="设计原则与思想"&gt;设计原则与思想&lt;/h1&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h2 id="八大设计原则"&gt;八大设计原则&lt;/h2&gt;
&lt;h3 id="solid原则"&gt;solid原则&lt;/h3&gt;
&lt;h4 id="单一职责原则--single-responsibility-principle"&gt;单一职责原则 Single Responsibility Principle&lt;/h4&gt;
&lt;h4 id="开闭原则-open-closed-principle"&gt;开闭原则 Open Closed Principle&lt;/h4&gt;
&lt;h4 id="里氏替换原则-liskov-substitution-principle"&gt;里氏替换原则 Liskov Substitution Principle&lt;/h4&gt;
&lt;h4 id="接口隔离原则-interface-segregation-principle"&gt;接口隔离原则 Interface Segregation Principle&lt;/h4&gt;
&lt;h4 id="依赖反转原则-dependency-inversion-principle"&gt;依赖反转原则 Dependency Inversion Principle&lt;/h4&gt;
&lt;h2 id="设计模式需要从实现方式使用场景两方面看"&gt;设计模式（需要从实现方式，使用场景两方面看）&lt;/h2&gt;
&lt;h3 id="创建型"&gt;创建型&lt;/h3&gt;
&lt;h4 id="单例模式"&gt;单例模式&lt;/h4&gt;
&lt;h5 id="使用场景"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;重点对资源的共享，避免了资源的重复创建&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="实现方式"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;饿汉式&lt;/li&gt;
&lt;li&gt;懒汉式&lt;/li&gt;
&lt;li&gt;双重检测&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="工厂模式"&gt;工厂模式&lt;/h4&gt;
&lt;h5 id="实现方式-1"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;简单工厂&lt;/li&gt;
&lt;li&gt;方法工厂&lt;/li&gt;
&lt;li&gt;抽象工厂&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-1"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;封装创建过程，方便创建对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="建造者模式"&gt;建造者模式&lt;/h4&gt;
&lt;h5 id="实现方式-2"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;创建builder,使用builder来校验参数，创建对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-2"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;一般用来创建同一类型的复杂对象（比如构造参数复杂），或者不想对外暴露set方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="原型模式"&gt;原型模式&lt;/h4&gt;
&lt;h5 id="实现方式-3"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;浅拷贝&lt;/li&gt;
&lt;li&gt;深拷贝&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-3"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;当创建对象的成本比较大，需要的对象和已知对象的差别不大，可以拷贝已知对象来创建新的对象。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="结构型-对象与对象之间组合成新的结构"&gt;结构型-对象与对象之间组合成新的结构&lt;/h3&gt;
&lt;h4 id="代理模式"&gt;代理模式&lt;/h4&gt;
&lt;h5 id="实现方式-4"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;静态代理&lt;/li&gt;
&lt;li&gt;动态代理&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="使用场景-4"&gt;使用场景&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;利用已知对象对它增强，mybatis的拦截器，spring的AOP&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="桥接模式"&gt;桥接模式&lt;/h4&gt;
&lt;h5 id="概念"&gt;概念&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;一个类存在两个（或多个）独立变化的维度，我们通过组合的方式，让这两个（或多个）维度可以独立进行扩展。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="装饰者模式"&gt;装饰者模式&lt;/h4&gt;
&lt;h5 id="概念-1"&gt;概念&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;装饰器模式主要解决继承关系过于复杂的问题，通过组合来替代继承。它主要的作用是给原始类添加增强功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="特点"&gt;特点&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;可以对原始类嵌套使用多个装饰器&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="适配器模式"&gt;适配器模式&lt;/h4&gt;
&lt;h5 id="实现方式-5"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;类适配器&lt;/li&gt;
&lt;li&gt;对象适配器&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-5"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;是用来做适配，它将不兼容的接口转换为可兼容的接口&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="门面模式"&gt;门面模式&lt;/h4&gt;
&lt;h5 id="概念-2"&gt;概念&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;门面模式为子系统提供一组统一的接口，定义一组高层接口让子系统更易用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="组合模式"&gt;组合模式&lt;/h4&gt;
&lt;h4 id="享元模式"&gt;享元模式&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;顾名思义就是被共享的单元。享元模式的意图是复用对象，节省内存，前提是享元对象是不可变对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="行为型"&gt;行为型&lt;/h3&gt;
&lt;h4 id="观察者模式"&gt;观察者模式&lt;/h4&gt;
&lt;h5 id="实现方式-6"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;发布-订阅型 1:N&lt;/li&gt;
&lt;li&gt;生产-消费型 N:N&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-6"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;解耦数据的产生和数据的消费&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="模板模式"&gt;模板模式&lt;/h4&gt;
&lt;h5 id="实现方式-7"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;定义好模板框架，暴露接口给子类实现&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-7"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;主要是用来扩展和复用代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="策略模式"&gt;策略模式&lt;/h4&gt;
&lt;h5 id="实现方式-8"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;可以使用工厂类来创建策略，动态选择策略（if else,或者反射）&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-8"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;将对象的创建和使用解耦&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="责任链模式"&gt;责任链模式&lt;/h4&gt;
&lt;h5 id="实现方式-9"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;将流程拆分成一个一个的步骤，交给handler处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-9"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;适合业务复杂，多变的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="状态模式"&gt;状态模式&lt;/h4&gt;
&lt;h5 id="实现方式-10"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;分支逻辑法&lt;/li&gt;
&lt;li&gt;查表法&lt;/li&gt;
&lt;li&gt;态模式&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-10"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;游戏人物，审批流场景&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="迭代模式"&gt;迭代模式&lt;/h4&gt;
&lt;h5 id="实现方式-11"&gt;实现方式&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;创建迭代器，遍历数据，不影响集合对象&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="使用场景-11"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;遍历数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="访问者模式"&gt;访问者模式&lt;/h4&gt;
&lt;h4 id="备忘录模式"&gt;备忘录模式&lt;/h4&gt;
&lt;h5 id="使用场景-12"&gt;使用场景&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;数据备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="命令模式"&gt;命令模式&lt;/h4&gt;
&lt;h4 id="解释器模式"&gt;解释器模式&lt;/h4&gt;
&lt;h4 id="中介模式"&gt;中介模式&lt;/h4&gt;</description></item><item><title>实践-创建多少线程合适</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%AE%9E%E8%B7%B5-%E5%88%9B%E5%BB%BA%E5%A4%9A%E5%B0%91%E7%BA%BF%E7%A8%8B%E5%90%88%E9%80%82/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%AE%9E%E8%B7%B5-%E5%88%9B%E5%BB%BA%E5%A4%9A%E5%B0%91%E7%BA%BF%E7%A8%8B%E5%90%88%E9%80%82/</guid><description>&lt;h1 id="创建多少线程合适"&gt;创建多少线程合适？&lt;/h1&gt;
&lt;p&gt;根据文章&lt;a href="https://ggball.top/pages/824790/#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8%E5%A4%9A%E7%BA%BF%E7%A8%8B"&gt;Java线程（中）：创建多少线程才是合适的？&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="我总结了"&gt;我总结了&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;为什么要使用多线程？&lt;/p&gt;
&lt;p&gt;因为程序执行多任务时，可以执行的更快，快 取决于 &lt;strong&gt;延迟&lt;/strong&gt; ，&lt;strong&gt;吞吐量&lt;/strong&gt; 。降低延迟，提高吞吐量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多线程的应用场景有哪些？
io密集型：磁盘和内存打交道之类的操作
cpu密集型：复杂计算，几乎不操作磁盘，就是一个劲的计算&lt;/p&gt;</description></item><item><title>线程通信——通知与等待</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E9%80%9A%E4%BF%A1-%E9%80%9A%E7%9F%A5%E4%B8%8E%E7%AD%89%E5%BE%85/</link><pubDate>Thu, 04 Aug 2022 19:22:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E9%80%9A%E4%BF%A1-%E9%80%9A%E7%9F%A5%E4%B8%8E%E7%AD%89%E5%BE%85/</guid><description>&lt;h1 id="线程通信-通知与等待"&gt;线程通信-通知与等待&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;我们知道 在java中 线程的状态 有6种，初始（NEW），运行（runnable），阻塞(bloked)，等待(waiting)，超时等待(timed_waiting)，终止(terminated)
Object.wait() 使线程等待，释放锁，Object.notify(),Object.notifyAll() 唤醒等待的线程&lt;/p&gt;</description></item><item><title>LongAdder，LongAccumulator类了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/longadderlongaccumulator%E7%B1%BB%E4%BA%86%E8%A7%A3/</link><pubDate>Mon, 23 May 2022 19:02:47 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/longadderlongaccumulator%E7%B1%BB%E4%BA%86%E8%A7%A3/</guid><description>&lt;p&gt;AtomicLong 通过cas提供了非阻塞的api，但是并发量高的时候，cas会导致大量线程自旋从而浪费cpu资源，所以开发者发明了&lt;code&gt;LongAdder&lt;/code&gt;来减少自旋&lt;/p&gt;</description></item><item><title>备忘录模式：对于大对象的备份和恢复，如何优化内存和时间的消耗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F%E5%AF%B9%E4%BA%8E%E5%A4%A7%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%A4%87%E4%BB%BD%E5%92%8C%E6%81%A2%E5%A4%8D%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96%E5%86%85%E5%AD%98%E5%92%8C%E6%97%B6%E9%97%B4%E7%9A%84%E6%B6%88%E8%80%97/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F%E5%AF%B9%E4%BA%8E%E5%A4%A7%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%A4%87%E4%BB%BD%E5%92%8C%E6%81%A2%E5%A4%8D%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96%E5%86%85%E5%AD%98%E5%92%8C%E6%97%B6%E9%97%B4%E7%9A%84%E6%B6%88%E8%80%97/</guid><description>&lt;h1 id="70--备忘录模式对于大对象的备份和恢复如何优化内存和时间的消耗"&gt;70 | 备忘录模式：对于大对象的备份和恢复，如何优化内存和时间的消耗？&lt;/h1&gt;
&lt;p&gt;上两节课，我们学习了访问者模式。在23种设计模式中，访问者模式的原理和实现可以说是最难理解的了，特别是它的代码实现。其中，用SingleDispatch来模拟DoubleDispatch的实现思路尤其不好理解。不知道你有没有将它拿下呢？如果还没有弄得很清楚，那就要多看几遍、多自己动脑经琢磨一下。&lt;/p&gt;</description></item><item><title>策略模式（上）：如何避免冗长的if-else-switch分支判断代码？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%86%97%E9%95%BF%E7%9A%84if-else-switch%E5%88%86%E6%94%AF%E5%88%A4%E6%96%AD%E4%BB%A3%E7%A0%81/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%86%97%E9%95%BF%E7%9A%84if-else-switch%E5%88%86%E6%94%AF%E5%88%A4%E6%96%AD%E4%BB%A3%E7%A0%81/</guid><description>&lt;h1 id="60--策略模式上如何避免冗长的if-elseswitch分支判断代码"&gt;60 | 策略模式（上）：如何避免冗长的if-else/switch分支判断代码？&lt;/h1&gt;
&lt;p&gt;上两节课中，我们学习了模板模式。模板模式主要起到代码复用和扩展的作用。除此之外，我们还讲到了回调，它跟模板模式的作用类似，但使用起来更加灵活。它们之间的主要区别在于代码实现，模板模式基于继承来实现，回调基于组合来实现。&lt;/p&gt;</description></item><item><title>策略模式（下）：如何实现一个支持给不同大小文件排序的小程序？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E7%BB%99%E4%B8%8D%E5%90%8C%E5%A4%A7%E5%B0%8F%E6%96%87%E4%BB%B6%E6%8E%92%E5%BA%8F%E7%9A%84%E5%B0%8F%E7%A8%8B%E5%BA%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E7%BB%99%E4%B8%8D%E5%90%8C%E5%A4%A7%E5%B0%8F%E6%96%87%E4%BB%B6%E6%8E%92%E5%BA%8F%E7%9A%84%E5%B0%8F%E7%A8%8B%E5%BA%8F/</guid><description>&lt;h1 id="61--策略模式下如何实现一个支持给不同大小文件排序的小程序"&gt;61 | 策略模式（下）：如何实现一个支持给不同大小文件排序的小程序？&lt;/h1&gt;
&lt;p&gt;上一节课，我们主要介绍了策略模式的原理和实现，以及如何利用策略模式来移除if-else或者switch-case分支判断逻辑。今天，我们结合“给文件排序”这样一个具体的例子，来详细讲一讲策略模式的设计意图和应用场景。&lt;/p&gt;</description></item><item><title>程序员怎么才能让自己走得更高、更远？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%85%AB-%E7%A8%8B%E5%BA%8F%E5%91%98%E6%80%8E%E4%B9%88%E6%89%8D%E8%83%BD%E8%AE%A9%E8%87%AA%E5%B7%B1%E8%B5%B0%E5%BE%97%E6%9B%B4%E9%AB%98-%E6%9B%B4%E8%BF%9C/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%85%AB-%E7%A8%8B%E5%BA%8F%E5%91%98%E6%80%8E%E4%B9%88%E6%89%8D%E8%83%BD%E8%AE%A9%E8%87%AA%E5%B7%B1%E8%B5%B0%E5%BE%97%E6%9B%B4%E9%AB%98-%E6%9B%B4%E8%BF%9C/</guid><description>&lt;p&gt;大学就像一个笼子，跑得快的人拖着笼子跑，跑得慢的人被笼子拖着跑，他们之间最大的差距，顶多只有笼子的长度那么大。但等到一毕业，笼门一打开，跑得快的人很快就把跑得慢的远远甩在后面。有人不到30岁就升到了阿里P8，有人35岁了还为拿个P7Offer在拼命。&lt;/p&gt;</description></item><item><title>从哪些维度评判代码质量的好坏？如何具备写出高质量代码的能力？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E4%BB%8E%E5%93%AA%E4%BA%9B%E7%BB%B4%E5%BA%A6%E8%AF%84%E5%88%A4%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%84%E5%A5%BD%E5%9D%8F%E5%A6%82%E4%BD%95%E5%85%B7%E5%A4%87%E5%86%99%E5%87%BA%E9%AB%98%E8%B4%A8%E9%87%8F%E4%BB%A3%E7%A0%81%E7%9A%84%E8%83%BD%E5%8A%9B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E4%BB%8E%E5%93%AA%E4%BA%9B%E7%BB%B4%E5%BA%A6%E8%AF%84%E5%88%A4%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%84%E5%A5%BD%E5%9D%8F%E5%A6%82%E4%BD%95%E5%85%B7%E5%A4%87%E5%86%99%E5%87%BA%E9%AB%98%E8%B4%A8%E9%87%8F%E4%BB%A3%E7%A0%81%E7%9A%84%E8%83%BD%E5%8A%9B/</guid><description>&lt;h1 id="02--从哪些维度评判代码质量的好坏如何具备写出高质量代码的能力"&gt;02 | 从哪些维度评判代码质量的好坏？如何具备写出高质量代码的能力？&lt;/h1&gt;
&lt;p&gt;在我的工作经历中，每当同事评论起项目代码质量的时候，听到的最多的评语就是：“代码写得很烂”或者“代码写得很好”。用“好”“烂”这样的字眼来描述，非常地笼统。当我具体问到底如何烂、如何好的时候，尽管大部分同事都能简单地罗列上几个点，但往往都不够全面、非常零碎，也切不中要害。&lt;/p&gt;</description></item><item><title>代理模式：代理在RPC、缓存、监控等场景中的应用</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E4%BB%A3%E7%90%86%E5%9C%A8rpc-%E7%BC%93%E5%AD%98-%E7%9B%91%E6%8E%A7%E7%AD%89%E5%9C%BA%E6%99%AF%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E4%BB%A3%E7%90%86%E5%9C%A8rpc-%E7%BC%93%E5%AD%98-%E7%9B%91%E6%8E%A7%E7%AD%89%E5%9C%BA%E6%99%AF%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</guid><description>&lt;h1 id="48--代理模式代理在rpc缓存监控等场景中的应用"&gt;48 | 代理模式：代理在RPC、缓存、监控等场景中的应用&lt;/h1&gt;
&lt;p&gt;前面几节，我们学习了设计模式中的创建型模式。创建型模式主要解决对象的创建问题，封装复杂的创建过程，解耦对象的创建代码和使用代码。&lt;/p&gt;</description></item><item><title>单例模式（上）：为什么说支持懒加载的双重检测不比饿汉式更优？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%8A%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%94%AF%E6%8C%81%E6%87%92%E5%8A%A0%E8%BD%BD%E7%9A%84%E5%8F%8C%E9%87%8D%E6%A3%80%E6%B5%8B%E4%B8%8D%E6%AF%94%E9%A5%BF%E6%B1%89%E5%BC%8F%E6%9B%B4%E4%BC%98/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%8A%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%94%AF%E6%8C%81%E6%87%92%E5%8A%A0%E8%BD%BD%E7%9A%84%E5%8F%8C%E9%87%8D%E6%A3%80%E6%B5%8B%E4%B8%8D%E6%AF%94%E9%A5%BF%E6%B1%89%E5%BC%8F%E6%9B%B4%E4%BC%98/</guid><description>&lt;h1 id="41--单例模式上为什么说支持懒加载的双重检测不比饿汉式更优"&gt;41 | 单例模式（上）：为什么说支持懒加载的双重检测不比饿汉式更优？&lt;/h1&gt;
&lt;p&gt;从今天开始，我们正式进入到设计模式的学习。我们知道，经典的设计模式有23种。其中，常用的并不是很多。据我的工作经验来看，常用的可能都不到一半。如果随便抓一个程序员，让他说一说最熟悉的3种设计模式，那其中肯定会包含今天要讲的单例模式。&lt;/p&gt;</description></item><item><title>单例模式（下）：如何设计实现一个集群环境下的分布式单例模式？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83%E4%B8%8B%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83%E4%B8%8B%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="43--单例模式下如何设计实现一个集群环境下的分布式单例模式"&gt;43 | 单例模式（下）：如何设计实现一个集群环境下的分布式单例模式？&lt;/h1&gt;
&lt;p&gt;上两节课中，我们针对单例模式，讲解了单例的应用场景、几种常见的代码实现和存在的问题，并粗略给出了替换单例模式的方法，比如工厂模式、IOC容器。今天，我们再进一步扩展延伸一下，一块讨论一下下面这几个问题：&lt;/p&gt;</description></item><item><title>单例模式（中）：我为什么不推荐使用单例模式？又有何替代方案？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%AD%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E5%8F%88%E6%9C%89%E4%BD%95%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E4%B8%AD%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E5%8F%88%E6%9C%89%E4%BD%95%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88/</guid><description>&lt;h1 id="42--单例模式中我为什么不推荐使用单例模式又有何替代方案"&gt;42 | 单例模式（中）：我为什么不推荐使用单例模式？又有何替代方案？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们通过两个实战案例，讲解了单例模式的一些应用场景，比如，避免资源访问冲突、表示业务概念上的全局唯一类。除此之外，我们还学习了Java语言中，单例模式的几种实现方法。如果你熟悉的是其他编程语言，不知道你课后有没有自己去对照着实现一下呢？&lt;/p&gt;</description></item><item><title>迭代器模式（上）：相比直接遍历集合数据，使用迭代器有哪些优势？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8A%E7%9B%B8%E6%AF%94%E7%9B%B4%E6%8E%A5%E9%81%8D%E5%8E%86%E9%9B%86%E5%90%88%E6%95%B0%E6%8D%AE%E4%BD%BF%E7%94%A8%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8A%E7%9B%B8%E6%AF%94%E7%9B%B4%E6%8E%A5%E9%81%8D%E5%8E%86%E9%9B%86%E5%90%88%E6%95%B0%E6%8D%AE%E4%BD%BF%E7%94%A8%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF/</guid><description>&lt;h1 id="65--迭代器模式上相比直接遍历集合数据使用迭代器有哪些优势"&gt;65 | 迭代器模式（上）：相比直接遍历集合数据，使用迭代器有哪些优势？&lt;/h1&gt;
&lt;p&gt;上一节课，我们学习了状态模式。状态模式是状态机的一种实现方法。它通过将事件触发的状态转移和动作执行，拆分到不同的状态类中，以此来避免状态机类中的分支判断逻辑，应对状态机类代码的复杂性。&lt;/p&gt;</description></item><item><title>迭代器模式（下）：如何设计实现一个支持“快照”功能的iterator？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81-%E5%BF%AB%E7%85%A7-%E5%8A%9F%E8%83%BD%E7%9A%84iterator/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81-%E5%BF%AB%E7%85%A7-%E5%8A%9F%E8%83%BD%E7%9A%84iterator/</guid><description>&lt;h1 id="67--迭代器模式下如何设计实现一个支持快照功能的iterator"&gt;67 | 迭代器模式（下）：如何设计实现一个支持“快照”功能的iterator？&lt;/h1&gt;
&lt;p&gt;上两节课，我们学习了迭代器模式的原理、实现，并且分析了在遍历集合的同时增删集合元素，产生不可预期结果的原因以及应对策略。&lt;/p&gt;</description></item><item><title>迭代器模式（中）：遍历集合的同时，为什么不能增删集合元素？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%AD%E9%81%8D%E5%8E%86%E9%9B%86%E5%90%88%E7%9A%84%E5%90%8C%E6%97%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E8%83%BD%E5%A2%9E%E5%88%A0%E9%9B%86%E5%90%88%E5%85%83%E7%B4%A0/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%AD%E9%81%8D%E5%8E%86%E9%9B%86%E5%90%88%E7%9A%84%E5%90%8C%E6%97%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E8%83%BD%E5%A2%9E%E5%88%A0%E9%9B%86%E5%90%88%E5%85%83%E7%B4%A0/</guid><description>&lt;h1 id="66--迭代器模式中遍历集合的同时为什么不能增删集合元素"&gt;66 | 迭代器模式（中）：遍历集合的同时，为什么不能增删集合元素？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们通过给ArrayList、LinkedList容器实现迭代器，学习了迭代器模式的原理、实现和设计意图。迭代器模式主要作用是解耦容器代码和遍历代码，这也印证了我们前面多次讲过的应用设计模式的主要目的是解耦。&lt;/p&gt;</description></item><item><title>访问者模式（上）：手把手带你还原访问者模式诞生的思维过程</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8A%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E8%BF%98%E5%8E%9F%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E8%AF%9E%E7%94%9F%E7%9A%84%E6%80%9D%E7%BB%B4%E8%BF%87%E7%A8%8B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8A%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E8%BF%98%E5%8E%9F%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E8%AF%9E%E7%94%9F%E7%9A%84%E6%80%9D%E7%BB%B4%E8%BF%87%E7%A8%8B/</guid><description>&lt;h1 id="68--访问者模式上手把手带你还原访问者模式诞生的思维过程"&gt;68 | 访问者模式（上）：手把手带你还原访问者模式诞生的思维过程&lt;/h1&gt;
&lt;p&gt;前面我们讲到，大部分设计模式的原理和实现都很简单，不过也有例外，比如今天要讲的访问者模式。它可以算是23种经典设计模式中最难理解的几个之一。因为它难理解、难实现，应用它会导致代码的可读性、可维护性变差，所以，访问者模式在实际的软件开发中很少被用到，在没有特别必要的情况下，建议你不要使用访问者模式。&lt;/p&gt;</description></item><item><title>访问者模式（下）：为什么支持双分派的语言不需要访问者模式？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E6%94%AF%E6%8C%81%E5%8F%8C%E5%88%86%E6%B4%BE%E7%9A%84%E8%AF%AD%E8%A8%80%E4%B8%8D%E9%9C%80%E8%A6%81%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E6%94%AF%E6%8C%81%E5%8F%8C%E5%88%86%E6%B4%BE%E7%9A%84%E8%AF%AD%E8%A8%80%E4%B8%8D%E9%9C%80%E8%A6%81%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="69--访问者模式下为什么支持双分派的语言不需要访问者模式"&gt;69 | 访问者模式（下）：为什么支持双分派的语言不需要访问者模式？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们学习了访问者模式的原理和实现，并且还原了访问者模式诞生的思维过程。总体上来讲，这个模式的代码实现比较难，所以应用场景并不多。从应用开发的角度来说，它的确不是我们学习的重点。&lt;/p&gt;</description></item><item><title>工厂模式（上）：我为什么说没事不要随便用工厂模式创建对象？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E4%B8%8A%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%B2%A1%E4%BA%8B%E4%B8%8D%E8%A6%81%E9%9A%8F%E4%BE%BF%E7%94%A8%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E4%B8%8A%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%B2%A1%E4%BA%8B%E4%B8%8D%E8%A6%81%E9%9A%8F%E4%BE%BF%E7%94%A8%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1/</guid><description>&lt;h1 id="44--工厂模式上我为什么说没事不要随便用工厂模式创建对象"&gt;44 | 工厂模式（上）：我为什么说没事不要随便用工厂模式创建对象？&lt;/h1&gt;
&lt;p&gt;上几节课我们讲了单例模式，今天我们再来讲另外一个比较常用的创建型模式：工厂模式（FactoryDesignPattern）。&lt;/p&gt;</description></item><item><title>工厂模式（下）：如何设计实现一个DependencyInjection框架？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AAdependencyinjection%E6%A1%86%E6%9E%B6/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AAdependencyinjection%E6%A1%86%E6%9E%B6/</guid><description>&lt;h1 id="45--工厂模式下如何设计实现一个dependency-injection框架"&gt;45 | 工厂模式（下）：如何设计实现一个Dependency Injection框架？&lt;/h1&gt;
&lt;p&gt;在上一节课我们讲到，当创建对象是一个“大工程”的时候，我们一般会选择使用工厂模式，来封装对象复杂的创建过程，将对象的创建和使用分离，让代码更加清晰。那何为“大工程”呢？上一节课中我们讲了两种情况，一种是创建过程涉及复杂的if-else分支判断，另一种是对象创建需要组装多个其他类对象或者需要复杂的初始化过程。&lt;/p&gt;</description></item><item><title>观察者模式（上）：详解各种应用场景下观察者模式的不同实现方式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8A%E8%AF%A6%E8%A7%A3%E5%90%84%E7%A7%8D%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E4%B8%8B%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E7%9A%84%E4%B8%8D%E5%90%8C%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8A%E8%AF%A6%E8%A7%A3%E5%90%84%E7%A7%8D%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E4%B8%8B%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E7%9A%84%E4%B8%8D%E5%90%8C%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/</guid><description>&lt;h1 id="56--观察者模式上详解各种应用场景下观察者模式的不同实现方式"&gt;56 | 观察者模式（上）：详解各种应用场景下观察者模式的不同实现方式&lt;/h1&gt;
&lt;p&gt;我们常把23种经典的设计模式分为三类：创建型、结构型、行为型。前面我们已经学习了创建型和结构型，从今天起，我们开始学习行为型设计模式。我们知道，创建型设计模式主要解决“对象的创建”问题，结构型设计模式主要解决“类或对象的组合或组装”问题，那行为型设计模式主要解决的就是“类或对象之间的交互”问题。&lt;/p&gt;</description></item><item><title>观察者模式（下）：如何实现一个异步非阻塞的EventBus框架？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%BC%82%E6%AD%A5%E9%9D%9E%E9%98%BB%E5%A1%9E%E7%9A%84eventbus%E6%A1%86%E6%9E%B6/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%BC%82%E6%AD%A5%E9%9D%9E%E9%98%BB%E5%A1%9E%E7%9A%84eventbus%E6%A1%86%E6%9E%B6/</guid><description>&lt;h1 id="57--观察者模式下如何实现一个异步非阻塞的eventbus框架"&gt;57 | 观察者模式（下）：如何实现一个异步非阻塞的EventBus框架？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们学习了观察者模式的原理、实现、应用场景，重点介绍了不同应用场景下，几种不同的实现方式，包括：同步阻塞、异步非阻塞、进程内、进程间的实现方式。&lt;/p&gt;</description></item><item><title>基础学科的知识如何转化成实际的技术生产力？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%83-%E5%9F%BA%E7%A1%80%E5%AD%A6%E7%A7%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%A6%82%E4%BD%95%E8%BD%AC%E5%8C%96%E6%88%90%E5%AE%9E%E9%99%85%E7%9A%84%E6%8A%80%E6%9C%AF%E7%94%9F%E4%BA%A7%E5%8A%9B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%83-%E5%9F%BA%E7%A1%80%E5%AD%A6%E7%A7%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%A6%82%E4%BD%95%E8%BD%AC%E5%8C%96%E6%88%90%E5%AE%9E%E9%99%85%E7%9A%84%E6%8A%80%E6%9C%AF%E7%94%9F%E4%BA%A7%E5%8A%9B/</guid><description>&lt;p&gt;我相信，很多程序员都已经意识到基础知识的重要性，觉得要夯实基础，才能走得更远，但同时对于如何将基础知识转化成开发“生产力”仍然有些疑惑。所以，你可能看了很多基础的书籍，比如操作系统、组成原理、编译原理等，但还是觉得很迷茫，觉得在开发中用不上，起码在平时的CRUD业务开发中用不上。&lt;/p&gt;</description></item><item><title>建造者模式：详解构造函数、set方法、建造者模式三种对象创建方式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0-set%E6%96%B9%E6%B3%95-%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%89%E7%A7%8D%E5%AF%B9%E8%B1%A1%E5%88%9B%E5%BB%BA%E6%96%B9%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0-set%E6%96%B9%E6%B3%95-%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%89%E7%A7%8D%E5%AF%B9%E8%B1%A1%E5%88%9B%E5%BB%BA%E6%96%B9%E5%BC%8F/</guid><description>&lt;h1 id="46--建造者模式详解构造函数set方法建造者模式三种对象创建方式"&gt;46 | 建造者模式：详解构造函数、set方法、建造者模式三种对象创建方式&lt;/h1&gt;
&lt;p&gt;上两节课中，我们学习了工厂模式，讲了工厂模式的应用场景，并带你实现了一个简单的DI容器。今天，我们再来学习另外一个比较常用的创建型设计模式，Builder模式，中文翻译为建造者模式或者构建者模式，也有人叫它生成器模式。&lt;/p&gt;</description></item><item><title>解释器模式：如何设计实现一个自定义接口告警规则功能？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%A3%E9%87%8A%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%91%8A%E8%AD%A6%E8%A7%84%E5%88%99%E5%8A%9F%E8%83%BD/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%A7%A3%E9%87%8A%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%91%8A%E8%AD%A6%E8%A7%84%E5%88%99%E5%8A%9F%E8%83%BD/</guid><description>&lt;h1 id="72--解释器模式如何设计实现一个自定义接口告警规则功能"&gt;72 | 解释器模式：如何设计实现一个自定义接口告警规则功能？&lt;/h1&gt;
&lt;p&gt;上一节课，我们学习了命令模式。命令模式将请求封装成对象，方便作为函数参数传递和赋值给变量。它主要的应用场景是给命令的执行附加功能，换句话说，就是控制命令的执行，比如，排队、异步、延迟执行命令、给命令执行记录日志、撤销重做命令等等。总体上来讲，命令模式的应用范围并不广。&lt;/p&gt;</description></item><item><title>开篇词丨一对一的设计与编码集训，让你告别没有成长的烂代码！</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E7%AF%87%E8%AF%8D-1%E8%AE%B2/%E5%BC%80%E7%AF%87%E8%AF%8D%E4%B8%A8%E4%B8%80%E5%AF%B9%E4%B8%80%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E7%BC%96%E7%A0%81%E9%9B%86%E8%AE%AD%E8%AE%A9%E4%BD%A0%E5%91%8A%E5%88%AB%E6%B2%A1%E6%9C%89%E6%88%90%E9%95%BF%E7%9A%84%E7%83%82%E4%BB%A3%E7%A0%81/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E7%AF%87%E8%AF%8D-1%E8%AE%B2/%E5%BC%80%E7%AF%87%E8%AF%8D%E4%B8%A8%E4%B8%80%E5%AF%B9%E4%B8%80%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E7%BC%96%E7%A0%81%E9%9B%86%E8%AE%AD%E8%AE%A9%E4%BD%A0%E5%91%8A%E5%88%AB%E6%B2%A1%E6%9C%89%E6%88%90%E9%95%BF%E7%9A%84%E7%83%82%E4%BB%A3%E7%A0%81/</guid><description>&lt;h1 id="开篇词--一对一的设计与编码集训让你告别没有成长的烂代码"&gt;开篇词 | 一对一的设计与编码集训，让你告别没有成长的烂代码！&lt;/h1&gt;
&lt;p&gt;你好，我是王争，是“”专栏的作者。“数据结构与算法之美”专栏在今年2月底全部更新完毕。时隔8个月，我又给你带来了一个新的专栏“设计模式之美”。如果说“数据结构与算法之美”是教你写出高效的代码，那这个设计模式专栏就是教你写出高质量的代码。&lt;/p&gt;</description></item><item><title>开源实战二（上）：从Unix开源开发学习应对大型复杂项目开发</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</guid><description>&lt;h1 id="78--开源实战二上从unix开源开发学习应对大型复杂项目开发"&gt;78 | 开源实战二（上）：从Unix开源开发学习应对大型复杂项目开发&lt;/h1&gt;
&lt;p&gt;软件开发的难度无外乎两点，一是技术难，意思是说，代码量不一定多，但要解决的问题比较难，需要用到一些比较深的技术解决方案或者算法，不是靠“堆人”就能搞定的，比如自动驾驶、图像识别、高性能消息队列等；二是复杂度，意思是说，技术不难，但项目很庞大，业务复杂，代码量多，参与开发的人多，比如物流系统、财务系统等。第一点涉及细分专业的领域知识，跟我们专栏要讲的设计、编码无关，所以我们重点来讲第二点，如何应对软件开发的复杂度。&lt;/p&gt;</description></item><item><title>开源实战二（下）：从Unix开源开发学习应对大型复杂项目开发</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</guid><description>&lt;h1 id="80--开源实战二下从unix开源开发学习应对大型复杂项目开发"&gt;80 | 开源实战二（下）：从Unix开源开发学习应对大型复杂项目开发&lt;/h1&gt;
&lt;p&gt;上两节课，我们分别从代码编写、研发管理的角度，学习了如何应对大型复杂软件开发。在研发管理这一部分，我们又讲到比较重要的几点，它们分别是编码规范、单元测试、持续重构和CodeReview。其中，前三点在专栏的理论部分都有比较详细的讲解，而唯独CodeReview我们还没有讲过，所以，今天我就借机会和你补充一下这一部分的内容。&lt;/p&gt;</description></item><item><title>开源实战二（中）：从Unix开源开发学习应对大型复杂项目开发</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%AD%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%AD%E4%BB%8Eunix%E5%BC%80%E6%BA%90%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E5%BA%94%E5%AF%B9%E5%A4%A7%E5%9E%8B%E5%A4%8D%E6%9D%82%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91/</guid><description>&lt;h1 id="79--开源实战二中从unix开源开发学习应对大型复杂项目开发"&gt;79 | 开源实战二（中）：从Unix开源开发学习应对大型复杂项目开发&lt;/h1&gt;
&lt;p&gt;我们知道，项目越复杂、代码量越多、参与开发人员越多、开发维护时间越长，我们就越是要重视代码质量。代码质量下降会导致项目研发困难重重，比如：开发效率低，招了很多人，天天加班，出活却不多；线上bug频发，查找bug困难，领导发飙，中层束手无策，工程师抱怨不断。&lt;/p&gt;</description></item><item><title>开源实战三（上）：借GoogleGuava学习发现和开发通用功能模块</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%8A%E5%80%9Fgoogleguava%E5%AD%A6%E4%B9%A0%E5%8F%91%E7%8E%B0%E5%92%8C%E5%BC%80%E5%8F%91%E9%80%9A%E7%94%A8%E5%8A%9F%E8%83%BD%E6%A8%A1%E5%9D%97/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%8A%E5%80%9Fgoogleguava%E5%AD%A6%E4%B9%A0%E5%8F%91%E7%8E%B0%E5%92%8C%E5%BC%80%E5%8F%91%E9%80%9A%E7%94%A8%E5%8A%9F%E8%83%BD%E6%A8%A1%E5%9D%97/</guid><description>&lt;h1 id="81--开源实战三上借google-guava学习发现和开发通用功能模块"&gt;81 | 开源实战三（上）：借Google Guava学习发现和开发通用功能模块&lt;/h1&gt;
&lt;p&gt;上几节课，我们拿Unix这个超级大型开源软件的开发作为引子，从代码设计编写和研发管理两个角度，讲了如何应对大型复杂项目的开发。接下来，我们再讲一下Google开源的Java开发库GoogleGuava。&lt;/p&gt;</description></item><item><title>开源实战三（下）：借GoogleGuava学习三大编程范式中的函数式编程</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%8B%E5%80%9Fgoogleguava%E5%AD%A6%E4%B9%A0%E4%B8%89%E5%A4%A7%E7%BC%96%E7%A8%8B%E8%8C%83%E5%BC%8F%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%8B%E5%80%9Fgoogleguava%E5%AD%A6%E4%B9%A0%E4%B8%89%E5%A4%A7%E7%BC%96%E7%A8%8B%E8%8C%83%E5%BC%8F%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/</guid><description>&lt;h1 id="83--开源实战三下借google-guava学习三大编程范式中的函数式编程"&gt;83 | 开源实战三（下）：借Google Guava学习三大编程范式中的函数式编程&lt;/h1&gt;
&lt;p&gt;现在主流的编程范式主要有三种，面向过程、面向对象和函数式编程。在理论部分，我们已经详细讲过前两种了。今天，我们再借机会讲讲剩下的一种，函数式编程。&lt;/p&gt;</description></item><item><title>开源实战三（中）：剖析GoogleGuava中用到的几种设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%AD%E5%89%96%E6%9E%90googleguava%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%84%E5%87%A0%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%89%E4%B8%AD%E5%89%96%E6%9E%90googleguava%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%84%E5%87%A0%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="82--开源实战三中剖析google-guava中用到的几种设计模式"&gt;82 | 开源实战三（中）：剖析Google Guava中用到的几种设计模式&lt;/h1&gt;
&lt;p&gt;上一节课，我们通过GoogleGuava这样一个优秀的开源类库，讲解了如何在业务开发中，发现跟业务无关、可以复用的通用功能模块，并将它们从业务代码中抽离出来，设计开发成独立的类库、框架或功能组件。&lt;/p&gt;</description></item><item><title>开源实战四（上）：剖析Spring框架中蕴含的经典设计思想或原则</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%8A%E5%89%96%E6%9E%90spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E8%95%B4%E5%90%AB%E7%9A%84%E7%BB%8F%E5%85%B8%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3%E6%88%96%E5%8E%9F%E5%88%99/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%8A%E5%89%96%E6%9E%90spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E8%95%B4%E5%90%AB%E7%9A%84%E7%BB%8F%E5%85%B8%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3%E6%88%96%E5%8E%9F%E5%88%99/</guid><description>&lt;h1 id="84--开源实战四上剖析spring框架中蕴含的经典设计思想或原则"&gt;84 | 开源实战四（上）：剖析Spring框架中蕴含的经典设计思想或原则&lt;/h1&gt;
&lt;p&gt;在Java世界里，Spring框架已经几乎成为项目开发的必备框架。作为如此优秀和受欢迎的开源项目，它是我们源码阅读的首选材料之一，不管是设计思想，还是代码实现，都有很多值得我们学习的地方。接下来，我们就详细讲讲Spring框架中蕴含的设计思想、原则和模式。因为内容比较多，我分三部分来讲解。&lt;/p&gt;</description></item><item><title>开源实战四（下）：总结Spring框架用到的11种设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%8B%E6%80%BB%E7%BB%93spring%E6%A1%86%E6%9E%B6%E7%94%A8%E5%88%B0%E7%9A%8411%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%8B%E6%80%BB%E7%BB%93spring%E6%A1%86%E6%9E%B6%E7%94%A8%E5%88%B0%E7%9A%8411%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="86--开源实战四下总结spring框架用到的11种设计模式"&gt;86 | 开源实战四（下）：总结Spring框架用到的11种设计模式&lt;/h1&gt;
&lt;p&gt;上一节课，我们讲解了Spring中支持扩展功能的两种设计模式：观察者模式和模板模式。这两种模式能够帮助我们创建扩展点，让框架的使用者在不修改源码的情况下，基于扩展点定制化框架功能。&lt;/p&gt;</description></item><item><title>开源实战四（中）：剖析Spring框架中用来支持扩展的两种设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%AD%E5%89%96%E6%9E%90spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E7%94%A8%E6%9D%A5%E6%94%AF%E6%8C%81%E6%89%A9%E5%B1%95%E7%9A%84%E4%B8%A4%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E5%9B%9B%E4%B8%AD%E5%89%96%E6%9E%90spring%E6%A1%86%E6%9E%B6%E4%B8%AD%E7%94%A8%E6%9D%A5%E6%94%AF%E6%8C%81%E6%89%A9%E5%B1%95%E7%9A%84%E4%B8%A4%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="85--开源实战四中剖析spring框架中用来支持扩展的两种设计模式"&gt;85 | 开源实战四（中）：剖析Spring框架中用来支持扩展的两种设计模式&lt;/h1&gt;
&lt;p&gt;上一节课中，我们学习了Spring框架背后蕴藏的一些经典设计思想，比如约定优于配置、低侵入松耦合、模块化轻量级等等。我们可以将这些设计思想借鉴到其他框架开发中，在大的设计层面提高框架的代码质量。这也是我们在专栏中讲解这部分内容的原因。&lt;/p&gt;</description></item><item><title>开源实战五（上）：MyBatis如何权衡易用性、性能和灵活性？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%8Amybatis%E5%A6%82%E4%BD%95%E6%9D%83%E8%A1%A1%E6%98%93%E7%94%A8%E6%80%A7-%E6%80%A7%E8%83%BD%E5%92%8C%E7%81%B5%E6%B4%BB%E6%80%A7/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%8Amybatis%E5%A6%82%E4%BD%95%E6%9D%83%E8%A1%A1%E6%98%93%E7%94%A8%E6%80%A7-%E6%80%A7%E8%83%BD%E5%92%8C%E7%81%B5%E6%B4%BB%E6%80%A7/</guid><description>&lt;h1 id="87--开源实战五上mybatis如何权衡易用性性能和灵活性"&gt;87 | 开源实战五（上）：MyBatis如何权衡易用性、性能和灵活性？&lt;/h1&gt;
&lt;p&gt;上几节课我们讲到了Spring框架，剖析了背后蕴含的一些通用设计思想，以及用到的十几种设计模式。从今天开始，我们再剖析另外一个Java项目开发中经常用到的框架：MyBatis。因为内容比较多，同样，我们也分三节课来讲解。&lt;/p&gt;</description></item><item><title>开源实战五（下）：总结MyBatis框架中用到的10种设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%8B%E6%80%BB%E7%BB%93mybatis%E6%A1%86%E6%9E%B6%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%8410%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%8B%E6%80%BB%E7%BB%93mybatis%E6%A1%86%E6%9E%B6%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%8410%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="89--开源实战五下总结mybatis框架中用到的10种设计模式"&gt;89 | 开源实战五（下）：总结MyBatis框架中用到的10种设计模式&lt;/h1&gt;
&lt;p&gt;上节课，我带你剖析了利用职责链模式和动态代理模式实现MyBatisPlugin。至此，我们已经学习了三种职责链常用的应用场景：过滤器（ServletFilter）、拦截器（SpringInterceptor）、插件（MyBatisPlugin）。&lt;/p&gt;</description></item><item><title>开源实战五（中）：如何利用职责链与代理模式实现MyBatisPlugin？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%AD%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E8%81%8C%E8%B4%A3%E9%93%BE%E4%B8%8E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E5%AE%9E%E7%8E%B0mybatisplugin/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%BA%94%E4%B8%AD%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E8%81%8C%E8%B4%A3%E9%93%BE%E4%B8%8E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E5%AE%9E%E7%8E%B0mybatisplugin/</guid><description>&lt;h1 id="88--开源实战五中如何利用职责链与代理模式实现mybatis-plugin"&gt;88 | 开源实战五（中）：如何利用职责链与代理模式实现MyBatis Plugin？&lt;/h1&gt;
&lt;p&gt;上节课，我们对MyBatis框架做了简单的背景介绍，并且通过对比各种ORM框架，学习了代码的易用性、性能、灵活性之间的关系。一般来讲，框架提供的高级功能越多，那性能损耗就会越大；框架用起来越简单，提供越简化的使用方式，那灵活性也就越低。&lt;/p&gt;</description></item><item><title>开源实战一（上）：通过剖析JavaJDK源码学习灵活应用设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javajdk%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E7%81%B5%E6%B4%BB%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javajdk%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E7%81%B5%E6%B4%BB%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="76---开源实战一上通过剖析java-jdk源码学习灵活应用设计模式"&gt;76 | 开源实战一（上）：通过剖析Java JDK源码学习灵活应用设计模式&lt;/h1&gt;
&lt;p&gt;从今天开始，我们就正式地进入到实战环节。实战环节包括两部分，一部分是开源项目实战，另一部分是项目实战。&lt;/p&gt;</description></item><item><title>开源实战一（下）：通过剖析JavaJDK源码学习灵活应用设计模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javajdk%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E7%81%B5%E6%B4%BB%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98-14%E8%AE%B2/%E5%BC%80%E6%BA%90%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javajdk%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E7%81%B5%E6%B4%BB%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="77--开源实战一下通过剖析java-jdk源码学习灵活应用设计模式"&gt;77 | 开源实战一（下）：通过剖析Java JDK源码学习灵活应用设计模式&lt;/h1&gt;
&lt;p&gt;上一节课，我们讲解了工厂模式、建造者模式、装饰器模式、适配器模式在JavaJDK中的应用，其中，Calendar类用到了工厂模式和建造者模式，Collections类用到了装饰器模式、适配器模式。学习的重点是让你了解，在真实的项目中模式的实现和应用更加灵活、多变，会根据具体的场景做实现或者设计上的调整。&lt;/p&gt;</description></item><item><title>理论八：如何用迪米特法则（LOD）实现“高内聚、松耦合”？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AB%E5%A6%82%E4%BD%95%E7%94%A8%E8%BF%AA%E7%B1%B3%E7%89%B9%E6%B3%95%E5%88%99lod%E5%AE%9E%E7%8E%B0-%E9%AB%98%E5%86%85%E8%81%9A-%E6%9D%BE%E8%80%A6%E5%90%88/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AB%E5%A6%82%E4%BD%95%E7%94%A8%E8%BF%AA%E7%B1%B3%E7%89%B9%E6%B3%95%E5%88%99lod%E5%AE%9E%E7%8E%B0-%E9%AB%98%E5%86%85%E8%81%9A-%E6%9D%BE%E8%80%A6%E5%90%88/</guid><description>&lt;h1 id="22--理论八如何用迪米特法则lod实现高内聚松耦合"&gt;22 | 理论八：如何用迪米特法则（LOD）实现“高内聚、松耦合”？&lt;/h1&gt;
&lt;p&gt;今天，我们讲最后一个设计原则：迪米特法则。尽管它不像SOLID、KISS、DRY原则那样，人尽皆知，但它却非常实用。利用这个原则，能够帮我们实现代码的“高内聚、松耦合”。今天，我们就围绕下面几个问题，并结合两个代码实战案例，来深入地学习这个法则。&lt;/p&gt;</description></item><item><title>理论二：封装、抽象、继承、多态分别可以解决哪些编程问题？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E5%B0%81%E8%A3%85-%E6%8A%BD%E8%B1%A1-%E7%BB%A7%E6%89%BF-%E5%A4%9A%E6%80%81%E5%88%86%E5%88%AB%E5%8F%AF%E4%BB%A5%E8%A7%A3%E5%86%B3%E5%93%AA%E4%BA%9B%E7%BC%96%E7%A8%8B%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E5%B0%81%E8%A3%85-%E6%8A%BD%E8%B1%A1-%E7%BB%A7%E6%89%BF-%E5%A4%9A%E6%80%81%E5%88%86%E5%88%AB%E5%8F%AF%E4%BB%A5%E8%A7%A3%E5%86%B3%E5%93%AA%E4%BA%9B%E7%BC%96%E7%A8%8B%E9%97%AE%E9%A2%98/</guid><description>&lt;h1 id="05--理论二封装抽象继承多态分别可以解决哪些编程问题"&gt;05 | 理论二：封装、抽象、继承、多态分别可以解决哪些编程问题？&lt;/h1&gt;
&lt;p&gt;上一节课，我简单介绍了面向对象的一些基本概念和知识点，比如，什么是面向对象编程，什么是面向对象编程语言等等。其中，我们还提到，理解面向对象编程及面向对象编程语言的关键就是理解其四大特性：封装、抽象、继承、多态。不过，对于这四大特性，光知道它们的定义是不够的，我们还要知道每个特性存在的意义和目的，以及它们能解决哪些编程问题。所以，今天我就花一节课的时间，针对每种特性，结合实际的代码，带你将这些问题搞清楚。&lt;/p&gt;</description></item><item><title>理论二：如何做到“对扩展开放、修改关闭”？扩展和修改各指什么？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E5%A6%82%E4%BD%95%E5%81%9A%E5%88%B0-%E5%AF%B9%E6%89%A9%E5%B1%95%E5%BC%80%E6%94%BE-%E4%BF%AE%E6%94%B9%E5%85%B3%E9%97%AD-%E6%89%A9%E5%B1%95%E5%92%8C%E4%BF%AE%E6%94%B9%E5%90%84%E6%8C%87%E4%BB%80%E4%B9%88/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E5%A6%82%E4%BD%95%E5%81%9A%E5%88%B0-%E5%AF%B9%E6%89%A9%E5%B1%95%E5%BC%80%E6%94%BE-%E4%BF%AE%E6%94%B9%E5%85%B3%E9%97%AD-%E6%89%A9%E5%B1%95%E5%92%8C%E4%BF%AE%E6%94%B9%E5%90%84%E6%8C%87%E4%BB%80%E4%B9%88/</guid><description>&lt;h1 id="16--理论二如何做到对扩展开放修改关闭扩展和修改各指什么"&gt;16 | 理论二：如何做到“对扩展开放、修改关闭”？扩展和修改各指什么？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们学习了单一职责原则。今天，我们来学习SOLID中的第二个原则：开闭原则。我个人觉得，开闭原则是SOLID中最难理解、最难掌握，同时也是最有用的一条原则。&lt;/p&gt;</description></item><item><title>理论二：为了保证重构不出错，有哪些非常能落地的技术手段？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E4%B8%BA%E4%BA%86%E4%BF%9D%E8%AF%81%E9%87%8D%E6%9E%84%E4%B8%8D%E5%87%BA%E9%94%99%E6%9C%89%E5%93%AA%E4%BA%9B%E9%9D%9E%E5%B8%B8%E8%83%BD%E8%90%BD%E5%9C%B0%E7%9A%84%E6%8A%80%E6%9C%AF%E6%89%8B%E6%AE%B5/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%8C%E4%B8%BA%E4%BA%86%E4%BF%9D%E8%AF%81%E9%87%8D%E6%9E%84%E4%B8%8D%E5%87%BA%E9%94%99%E6%9C%89%E5%93%AA%E4%BA%9B%E9%9D%9E%E5%B8%B8%E8%83%BD%E8%90%BD%E5%9C%B0%E7%9A%84%E6%8A%80%E6%9C%AF%E6%89%8B%E6%AE%B5/</guid><description>&lt;h1 id="28--理论二为了保证重构不出错有哪些非常能落地的技术手段"&gt;28 | 理论二：为了保证重构不出错，有哪些非常能落地的技术手段？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们对“为什么要重构、到底重构什么、什么时候重构、该如何重构”，做了概括性介绍，强调了重构的重要性，希望你建立持续重构意识，将重构作为开发的一部分来执行。&lt;/p&gt;</description></item><item><title>理论六：为什么基于接口而非实现编程？有必要为每个类都定义接口吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AD%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9F%BA%E4%BA%8E%E6%8E%A5%E5%8F%A3%E8%80%8C%E9%9D%9E%E5%AE%9E%E7%8E%B0%E7%BC%96%E7%A8%8B%E6%9C%89%E5%BF%85%E8%A6%81%E4%B8%BA%E6%AF%8F%E4%B8%AA%E7%B1%BB%E9%83%BD%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%90%97/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AD%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9F%BA%E4%BA%8E%E6%8E%A5%E5%8F%A3%E8%80%8C%E9%9D%9E%E5%AE%9E%E7%8E%B0%E7%BC%96%E7%A8%8B%E6%9C%89%E5%BF%85%E8%A6%81%E4%B8%BA%E6%AF%8F%E4%B8%AA%E7%B1%BB%E9%83%BD%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%90%97/</guid><description>&lt;h1 id="09--理论六为什么基于接口而非实现编程有必要为每个类都定义接口吗"&gt;09 | 理论六：为什么基于接口而非实现编程？有必要为每个类都定义接口吗？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们讲了接口和抽象类，以及各种编程语言是如何支持、实现这两个语法概念的。今天，我们继续讲一个跟“接口”相关的知识点：基于接口而非实现编程。这个原则非常重要，是一种非常有效的提高代码质量的手段，在平时的开发中特别经常被用到。&lt;/p&gt;</description></item><item><title>理论六：我为何说KISS、YAGNI原则看似简单，却经常被用错？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AD%E6%88%91%E4%B8%BA%E4%BD%95%E8%AF%B4kiss-yagni%E5%8E%9F%E5%88%99%E7%9C%8B%E4%BC%BC%E7%AE%80%E5%8D%95%E5%8D%B4%E7%BB%8F%E5%B8%B8%E8%A2%AB%E7%94%A8%E9%94%99/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%85%AD%E6%88%91%E4%B8%BA%E4%BD%95%E8%AF%B4kiss-yagni%E5%8E%9F%E5%88%99%E7%9C%8B%E4%BC%BC%E7%AE%80%E5%8D%95%E5%8D%B4%E7%BB%8F%E5%B8%B8%E8%A2%AB%E7%94%A8%E9%94%99/</guid><description>&lt;h1 id="20--理论六我为何说kissyagni原则看似简单却经常被用错"&gt;20 | 理论六：我为何说KISS、YAGNI原则看似简单，却经常被用错？&lt;/h1&gt;
&lt;p&gt;上几节课中，我们学习了经典的SOLID原则。今天，我们讲两个设计原则：KISS原则和YAGNI原则。其中，KISS原则比较经典，耳熟能详，但YAGNI你可能没怎么听过，不过它理解起来也不难。&lt;/p&gt;</description></item><item><title>理论七：为何说要多用组合少用继承？如何决定该用组合还是继承？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%83%E4%B8%BA%E4%BD%95%E8%AF%B4%E8%A6%81%E5%A4%9A%E7%94%A8%E7%BB%84%E5%90%88%E5%B0%91%E7%94%A8%E7%BB%A7%E6%89%BF%E5%A6%82%E4%BD%95%E5%86%B3%E5%AE%9A%E8%AF%A5%E7%94%A8%E7%BB%84%E5%90%88%E8%BF%98%E6%98%AF%E7%BB%A7%E6%89%BF/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%83%E4%B8%BA%E4%BD%95%E8%AF%B4%E8%A6%81%E5%A4%9A%E7%94%A8%E7%BB%84%E5%90%88%E5%B0%91%E7%94%A8%E7%BB%A7%E6%89%BF%E5%A6%82%E4%BD%95%E5%86%B3%E5%AE%9A%E8%AF%A5%E7%94%A8%E7%BB%84%E5%90%88%E8%BF%98%E6%98%AF%E7%BB%A7%E6%89%BF/</guid><description>&lt;h1 id="10--理论七为何说要多用组合少用继承如何决定该用组合还是继承"&gt;10 | 理论七：为何说要多用组合少用继承？如何决定该用组合还是继承？&lt;/h1&gt;
&lt;p&gt;在面向对象编程中，有一条非常经典的设计原则，那就是：组合优于继承，多用组合少用继承。为什么不推荐使用继承？组合相比继承有哪些优势？如何判断该用组合还是继承？今天，我们就围绕着这三个问题，来详细讲解一下这条设计原则。&lt;/p&gt;</description></item><item><title>理论七：重复的代码就一定违背DRY吗？如何提高代码的复用性？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%83%E9%87%8D%E5%A4%8D%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%B1%E4%B8%80%E5%AE%9A%E8%BF%9D%E8%83%8Cdry%E5%90%97%E5%A6%82%E4%BD%95%E6%8F%90%E9%AB%98%E4%BB%A3%E7%A0%81%E7%9A%84%E5%A4%8D%E7%94%A8%E6%80%A7/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%83%E9%87%8D%E5%A4%8D%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%B1%E4%B8%80%E5%AE%9A%E8%BF%9D%E8%83%8Cdry%E5%90%97%E5%A6%82%E4%BD%95%E6%8F%90%E9%AB%98%E4%BB%A3%E7%A0%81%E7%9A%84%E5%A4%8D%E7%94%A8%E6%80%A7/</guid><description>&lt;h1 id="21--理论七重复的代码就一定违背dry吗如何提高代码的复用性"&gt;21 | 理论七：重复的代码就一定违背DRY吗？如何提高代码的复用性？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们讲了KISS原则和YAGNI原则，KISS原则可以说是人尽皆知。今天，我们再学习一个你肯定听过的原则，那就是DRY原则。它的英文描述为：Don’tRepeatYourself。中文直译为：不要重复自己。将它应用在编程中，可以理解为：不要写重复的代码。&lt;/p&gt;</description></item><item><title>理论三：里式替换（LSP）跟多态有何区别？哪些代码违背了LSP？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E9%87%8C%E5%BC%8F%E6%9B%BF%E6%8D%A2lsp%E8%B7%9F%E5%A4%9A%E6%80%81%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%93%AA%E4%BA%9B%E4%BB%A3%E7%A0%81%E8%BF%9D%E8%83%8C%E4%BA%86lsp/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E9%87%8C%E5%BC%8F%E6%9B%BF%E6%8D%A2lsp%E8%B7%9F%E5%A4%9A%E6%80%81%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%93%AA%E4%BA%9B%E4%BB%A3%E7%A0%81%E8%BF%9D%E8%83%8C%E4%BA%86lsp/</guid><description>&lt;h1 id="17--理论三里式替换lsp跟多态有何区别哪些代码违背了lsp"&gt;17 | 理论三：里式替换（LSP）跟多态有何区别？哪些代码违背了LSP？&lt;/h1&gt;
&lt;p&gt;在上两节课中，我们学习了SOLID原则中的单一职责原则和开闭原则，这两个原则都比较重要，想要灵活应用也比较难，需要你在实践中多加练习、多加体会。今天，我们再来学习SOLID中的“L”对应的原则：里式替换原则。&lt;/p&gt;</description></item><item><title>理论三：面向对象相比面向过程有哪些优势？面向过程真的过时了吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9B%B8%E6%AF%94%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E7%9C%9F%E7%9A%84%E8%BF%87%E6%97%B6%E4%BA%86%E5%90%97/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9B%B8%E6%AF%94%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E7%9C%9F%E7%9A%84%E8%BF%87%E6%97%B6%E4%BA%86%E5%90%97/</guid><description>&lt;h1 id="06--理论三面向对象相比面向过程有哪些优势面向过程真的过时了吗"&gt;06 | 理论三：面向对象相比面向过程有哪些优势？面向过程真的过时了吗？&lt;/h1&gt;
&lt;p&gt;在上两节课中，我们讲了面向对象这种现在非常流行的编程范式，或者说编程风格。实际上，除了面向对象之外，被大家熟知的编程范式还有另外两种，面向过程编程和函数式编程。面向过程这种编程范式随着面向对象的出现，已经慢慢退出了舞台，而函数式编程目前还没有被广泛接受。&lt;/p&gt;</description></item><item><title>理论三：什么是代码的可测试性？如何写出可测试性好的代码？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E4%BB%80%E4%B9%88%E6%98%AF%E4%BB%A3%E7%A0%81%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7%E5%A6%82%E4%BD%95%E5%86%99%E5%87%BA%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%89%E4%BB%80%E4%B9%88%E6%98%AF%E4%BB%A3%E7%A0%81%E7%9A%84%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7%E5%A6%82%E4%BD%95%E5%86%99%E5%87%BA%E5%8F%AF%E6%B5%8B%E8%AF%95%E6%80%A7%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81/</guid><description>&lt;h1 id="29--理论三什么是代码的可测试性如何写出可测试性好的代码"&gt;29 | 理论三：什么是代码的可测试性？如何写出可测试性好的代码？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们对单元测试做了介绍，讲了“什么是单元测试？为什么要编写单元测试？如何编写单元测试？实践中单元测试为什么难贯彻执行？”这样几个问题。&lt;/p&gt;</description></item><item><title>理论四：接口隔离原则有哪三种应用？原则中的“接口”该如何理解？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E6%8E%A5%E5%8F%A3%E9%9A%94%E7%A6%BB%E5%8E%9F%E5%88%99%E6%9C%89%E5%93%AA%E4%B8%89%E7%A7%8D%E5%BA%94%E7%94%A8%E5%8E%9F%E5%88%99%E4%B8%AD%E7%9A%84-%E6%8E%A5%E5%8F%A3-%E8%AF%A5%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E6%8E%A5%E5%8F%A3%E9%9A%94%E7%A6%BB%E5%8E%9F%E5%88%99%E6%9C%89%E5%93%AA%E4%B8%89%E7%A7%8D%E5%BA%94%E7%94%A8%E5%8E%9F%E5%88%99%E4%B8%AD%E7%9A%84-%E6%8E%A5%E5%8F%A3-%E8%AF%A5%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3/</guid><description>&lt;h1 id="18--理论四接口隔离原则有哪三种应用原则中的接口该如何理解"&gt;18 | 理论四：接口隔离原则有哪三种应用？原则中的“接口”该如何理解？&lt;/h1&gt;
&lt;p&gt;上几节课中，我们学习了SOLID原则中的单一职责原则、开闭原则和里式替换原则，今天我们学习第四个原则，接口隔离原则。它对应SOLID中的英文字母“I”。对于这个原则，最关键就是理解其中“接口”的含义。那针对“接口”，不同的理解方式，对应在原则上也有不同的解读方式。除此之外，接口隔离原则跟我们之前讲到的单一职责原则还有点儿类似，所以今天我也会具体讲一下它们之间的区别和联系。&lt;/p&gt;</description></item><item><title>理论四：哪些代码设计看似是面向对象，实际是面向过程的？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E5%93%AA%E4%BA%9B%E4%BB%A3%E7%A0%81%E8%AE%BE%E8%AE%A1%E7%9C%8B%E4%BC%BC%E6%98%AF%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%AE%9E%E9%99%85%E6%98%AF%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E7%9A%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E5%93%AA%E4%BA%9B%E4%BB%A3%E7%A0%81%E8%AE%BE%E8%AE%A1%E7%9C%8B%E4%BC%BC%E6%98%AF%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%AE%9E%E9%99%85%E6%98%AF%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E7%9A%84/</guid><description>&lt;h1 id="07--理论四哪些代码设计看似是面向对象实际是面向过程的"&gt;07 | 理论四：哪些代码设计看似是面向对象，实际是面向过程的？&lt;/h1&gt;
&lt;p&gt;上一节课，我们提到，常见的编程范式或者说编程风格有三种，面向过程编程、面向对象编程、函数式编程，而面向对象编程又是这其中最主流的编程范式。现如今，大部分编程语言都是面向对象编程语言，大部分软件都是基于面向对象编程这种编程范式来开发的。&lt;/p&gt;</description></item><item><title>理论四：如何通过封装、抽象、模块化、中间层等解耦代码？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E5%B0%81%E8%A3%85-%E6%8A%BD%E8%B1%A1-%E6%A8%A1%E5%9D%97%E5%8C%96-%E4%B8%AD%E9%97%B4%E5%B1%82%E7%AD%89%E8%A7%A3%E8%80%A6%E4%BB%A3%E7%A0%81/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E5%9B%9B%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E5%B0%81%E8%A3%85-%E6%8A%BD%E8%B1%A1-%E6%A8%A1%E5%9D%97%E5%8C%96-%E4%B8%AD%E9%97%B4%E5%B1%82%E7%AD%89%E8%A7%A3%E8%80%A6%E4%BB%A3%E7%A0%81/</guid><description>&lt;h1 id="30--理论四如何通过封装抽象模块化中间层等解耦代码"&gt;30 | 理论四：如何通过封装、抽象、模块化、中间层等解耦代码？&lt;/h1&gt;
&lt;p&gt;前面我们讲到，重构可以分为大规模高层重构（简称“大型重构”）和小规模低层次重构（简称“小型重构”）。大型重构是对系统、模块、代码结构、类之间关系等顶层代码设计进行的重构。对于大型重构来说，今天我们重点讲解最有效的一个手段，那就是“解耦”。解耦的目的是实现代码高内聚、松耦合。关于解耦，我准备分下面三个部分来给你讲解。&lt;/p&gt;</description></item><item><title>理论五：接口vs抽象类的区别？如何用普通的类模拟抽象类和接口？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E6%8E%A5%E5%8F%A3vs%E6%8A%BD%E8%B1%A1%E7%B1%BB%E7%9A%84%E5%8C%BA%E5%88%AB%E5%A6%82%E4%BD%95%E7%94%A8%E6%99%AE%E9%80%9A%E7%9A%84%E7%B1%BB%E6%A8%A1%E6%8B%9F%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E6%8E%A5%E5%8F%A3vs%E6%8A%BD%E8%B1%A1%E7%B1%BB%E7%9A%84%E5%8C%BA%E5%88%AB%E5%A6%82%E4%BD%95%E7%94%A8%E6%99%AE%E9%80%9A%E7%9A%84%E7%B1%BB%E6%A8%A1%E6%8B%9F%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3/</guid><description>&lt;h1 id="08--理论五接口vs抽象类的区别如何用普通的类模拟抽象类和接口"&gt;08 | 理论五：接口vs抽象类的区别？如何用普通的类模拟抽象类和接口？&lt;/h1&gt;
&lt;p&gt;在面向对象编程中，抽象类和接口是两个经常被用到的语法概念，是面向对象四大特性，以及很多设计模式、设计思想、设计原则编程实现的基础。比如，我们可以使用接口来实现面向对象的抽象特性、多态特性和基于接口而非实现的设计原则，使用抽象类来实现面向对象的继承特性和模板设计模式等等。&lt;/p&gt;</description></item><item><title>理论五：控制反转、依赖反转、依赖注入，这三者有何区别和联系？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC-%E4%BE%9D%E8%B5%96%E5%8F%8D%E8%BD%AC-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E8%BF%99%E4%B8%89%E8%80%85%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC-%E4%BE%9D%E8%B5%96%E5%8F%8D%E8%BD%AC-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E8%BF%99%E4%B8%89%E8%80%85%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB/</guid><description>&lt;h1 id="19--理论五控制反转依赖反转依赖注入这三者有何区别和联系"&gt;19 | 理论五：控制反转、依赖反转、依赖注入，这三者有何区别和联系？&lt;/h1&gt;
&lt;p&gt;关于SOLID原则，我们已经学过单一职责、开闭、里式替换、接口隔离这四个原则。今天，我们再来学习最后一个原则：依赖反转原则。在前面几节课中，我们讲到，单一职责原则和开闭原则的原理比较简单，但是，想要在实践中用好却比较难。而今天我们要讲到的依赖反转原则正好相反。这个原则用起来比较简单，但概念理解起来比较难。比如，下面这几个问题，你看看能否清晰地回答出来：&lt;/p&gt;</description></item><item><title>理论五：让你最快速地改善代码质量的20条编程规范（上）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%8A/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%8A/</guid><description>&lt;h1 id="31--理论五让你最快速地改善代码质量的20条编程规范上"&gt;31 | 理论五：让你最快速地改善代码质量的20条编程规范（上）&lt;/h1&gt;
&lt;p&gt;前面我们讲了很多设计原则，后面还会讲到很多设计模式，利用好它们可以有效地改善代码质量。但是，这些知识的合理应用非常依赖个人经验，用不好有时候会适得其反。而我们接下来要讲的编码规范正好相反。编码规范大部分都简单明了，在代码细节方面，能立竿见影地改善质量。除此之外，我们前面也讲到，持续低层次、小规模重构依赖的基本上都是编码规范，这也是改善代码可读性的有效手段。&lt;/p&gt;</description></item><item><title>理论五：让你最快速地改善代码质量的20条编程规范（下）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%8B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%8B/</guid><description>&lt;h1 id="33--理论五让你最快速地改善代码质量的20条编程规范下"&gt;33 | 理论五：让你最快速地改善代码质量的20条编程规范（下）&lt;/h1&gt;
&lt;p&gt;上两节课，我们讲了命名和注释、代码风格，今天我们来讲一些比较实用的编程技巧，帮你切实地提高代码可读性。这部分技巧比较琐碎，也很难罗列全面，我仅仅总结了一些我认为比较关键的，更多的技巧需要你在实践中自己慢慢总结、积累。&lt;/p&gt;</description></item><item><title>理论五：让你最快速地改善代码质量的20条编程规范（中）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%AD/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%BA%94%E8%AE%A9%E4%BD%A0%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0%E6%94%B9%E5%96%84%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E7%9A%8420%E6%9D%A1%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E4%B8%AD/</guid><description>&lt;h1 id="32--理论五让你最快速地改善代码质量的20条编程规范中"&gt;32 | 理论五：让你最快速地改善代码质量的20条编程规范（中）&lt;/h1&gt;
&lt;p&gt;上一节课中我们讲了命名和注释，这一节课我们来讲一下代码风格（CodeStyle）。说起代码风格，我们其实很难说哪种风格更好。最重要的，也是最需要我们做到的，是在团队、项目中保持风格统一，让代码像同一个人写出来的，整齐划一。这样能减少阅读干扰，提高代码的可读性。这才是我们在实际工作中想要实现的目标。&lt;/p&gt;</description></item><item><title>理论一：当谈论面向对象的时候，我们到底在谈论什么？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E5%BD%93%E8%B0%88%E8%AE%BA%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%97%B6%E5%80%99%E6%88%91%E4%BB%AC%E5%88%B0%E5%BA%95%E5%9C%A8%E8%B0%88%E8%AE%BA%E4%BB%80%E4%B9%88/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E5%BD%93%E8%B0%88%E8%AE%BA%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%97%B6%E5%80%99%E6%88%91%E4%BB%AC%E5%88%B0%E5%BA%95%E5%9C%A8%E8%B0%88%E8%AE%BA%E4%BB%80%E4%B9%88/</guid><description>&lt;h1 id="04--理论一当谈论面向对象的时候我们到底在谈论什么"&gt;04 | 理论一：当谈论面向对象的时候，我们到底在谈论什么？&lt;/h1&gt;
&lt;p&gt;考虑到各个水平层次的同学，并且保证专栏内容的系统性、全面性，我会循序渐进地讲解跟设计模式相关的所有内容。所以，专栏正文的第一个模块，我会讲一些设计原则、设计思想，比如，面向对象设计思想、经典设计原则以及重构相关的知识，为之后学习设计模式做铺垫。&lt;/p&gt;</description></item><item><title>理论一：对于单一职责原则，如何判定某个类的职责是否够“单一”？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E5%AF%B9%E4%BA%8E%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%8E%9F%E5%88%99%E5%A6%82%E4%BD%95%E5%88%A4%E5%AE%9A%E6%9F%90%E4%B8%AA%E7%B1%BB%E7%9A%84%E8%81%8C%E8%B4%A3%E6%98%AF%E5%90%A6%E5%A4%9F-%E5%8D%95%E4%B8%80/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E5%AF%B9%E4%BA%8E%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%8E%9F%E5%88%99%E5%A6%82%E4%BD%95%E5%88%A4%E5%AE%9A%E6%9F%90%E4%B8%AA%E7%B1%BB%E7%9A%84%E8%81%8C%E8%B4%A3%E6%98%AF%E5%90%A6%E5%A4%9F-%E5%8D%95%E4%B8%80/</guid><description>&lt;h1 id="15--理论一对于单一职责原则如何判定某个类的职责是否够单一"&gt;15 | 理论一：对于单一职责原则，如何判定某个类的职责是否够“单一”？&lt;/h1&gt;
&lt;p&gt;上几节课中，我们介绍了面向对象相关的知识。从今天起，我们开始学习一些经典的设计原则，其中包括，SOLID、KISS、YAGNI、DRY、LOD等。&lt;/p&gt;</description></item><item><title>理论一：什么情况下要重构？到底重构什么？又该如何重构？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E4%BB%80%E4%B9%88%E6%83%85%E5%86%B5%E4%B8%8B%E8%A6%81%E9%87%8D%E6%9E%84%E5%88%B0%E5%BA%95%E9%87%8D%E6%9E%84%E4%BB%80%E4%B9%88%E5%8F%88%E8%AF%A5%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E7%90%86%E8%AE%BA%E4%B8%80%E4%BB%80%E4%B9%88%E6%83%85%E5%86%B5%E4%B8%8B%E8%A6%81%E9%87%8D%E6%9E%84%E5%88%B0%E5%BA%95%E9%87%8D%E6%9E%84%E4%BB%80%E4%B9%88%E5%8F%88%E8%AF%A5%E5%A6%82%E4%BD%95%E9%87%8D%E6%9E%84/</guid><description>&lt;h1 id="27--理论一什么情况下要重构到底重构什么又该如何重构"&gt;27 | 理论一：什么情况下要重构？到底重构什么？又该如何重构？&lt;/h1&gt;
&lt;p&gt;“重构”这个词对于大部分工程师来说都不陌生。不过，据我了解，大部分人都只是“听得多做得少”，真正进行过代码重构的人不多，而把持续重构作为开发的一部分的人，就更是少之又少了。&lt;/p&gt;</description></item><item><title>聊一聊Google那些让我快速成长的地方</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%9B%9B-%E8%81%8A%E4%B8%80%E8%81%8Agoogle%E9%82%A3%E4%BA%9B%E8%AE%A9%E6%88%91%E5%BF%AB%E9%80%9F%E6%88%90%E9%95%BF%E7%9A%84%E5%9C%B0%E6%96%B9/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%9B%9B-%E8%81%8A%E4%B8%80%E8%81%8Agoogle%E9%82%A3%E4%BA%9B%E8%AE%A9%E6%88%91%E5%BF%AB%E9%80%9F%E6%88%90%E9%95%BF%E7%9A%84%E5%9C%B0%E6%96%B9/</guid><description>&lt;p&gt;我一直强调，在项目中实践、由点及面的学习，是提高技术最有效的途径。但是，好的技术氛围、培养机制，也能打破通过项目单一成长的限制，获得更多项目之外的收获。很多公司，特别是一些大公司，在关注员工工作效率、工作产出的同时，也十分关注员工的个人成长、职场发展。今天，我就和你聊一聊Google有哪些让我快速成长的地方。&lt;/p&gt;</description></item><item><title>聊一聊Google是如何做CodeReview的</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%89-%E8%81%8A%E4%B8%80%E8%81%8Agoogle%E6%98%AF%E5%A6%82%E4%BD%95%E5%81%9Acodereview%E7%9A%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%89-%E8%81%8A%E4%B8%80%E8%81%8Agoogle%E6%98%AF%E5%A6%82%E4%BD%95%E5%81%9Acodereview%E7%9A%84/</guid><description>&lt;p&gt;100篇的正文已经全部结束了，估计你学得也有点累了吧？时隔这么久，正文终于结束了，从今天起，我们继续加餐内容。&lt;/p&gt;
&lt;p&gt;跟正文内容相比，加餐内容我希望尽量轻松有趣，帮你拓展知识面，主要是课后的一些小分享，有的会以讲故事为主，但我也希望它能给你带来收获。如果能够引发你的思考和共鸣那就更好了。所以，我也希望你在留言区，多说说自己的感受和看法，多多与我互动。&lt;/p&gt;</description></item><item><title>聊一聊机遇、方向、能力、努力！</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E7%BB%93%E6%9D%9F%E8%AF%AD-1%E8%AE%B2/%E7%BB%93%E6%9D%9F%E8%AF%AD-%E8%81%8A%E4%B8%80%E8%81%8A%E6%9C%BA%E9%81%87-%E6%96%B9%E5%90%91-%E8%83%BD%E5%8A%9B-%E5%8A%AA%E5%8A%9B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E7%BB%93%E6%9D%9F%E8%AF%AD-1%E8%AE%B2/%E7%BB%93%E6%9D%9F%E8%AF%AD-%E8%81%8A%E4%B8%80%E8%81%8A%E6%9C%BA%E9%81%87-%E6%96%B9%E5%90%91-%E8%83%BD%E5%8A%9B-%E5%8A%AA%E5%8A%9B/</guid><description>&lt;p&gt;你好，我是王争。从专栏上线到今天，足足有8个月的时间了。在这8个月里，我陪你一块完成了100篇正文和11篇加餐的学习。今天，我要正式地跟你说声再见了。&lt;/p&gt;</description></item><item><title>门面模式：如何设计合理的接口粒度以兼顾接口的易用性和通用性？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E9%97%A8%E9%9D%A2%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%90%88%E7%90%86%E7%9A%84%E6%8E%A5%E5%8F%A3%E7%B2%92%E5%BA%A6%E4%BB%A5%E5%85%BC%E9%A1%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E6%98%93%E7%94%A8%E6%80%A7%E5%92%8C%E9%80%9A%E7%94%A8%E6%80%A7/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E9%97%A8%E9%9D%A2%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%90%88%E7%90%86%E7%9A%84%E6%8E%A5%E5%8F%A3%E7%B2%92%E5%BA%A6%E4%BB%A5%E5%85%BC%E9%A1%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E6%98%93%E7%94%A8%E6%80%A7%E5%92%8C%E9%80%9A%E7%94%A8%E6%80%A7/</guid><description>&lt;h1 id="52--门面模式如何设计合理的接口粒度以兼顾接口的易用性和通用性"&gt;52 | 门面模式：如何设计合理的接口粒度以兼顾接口的易用性和通用性？&lt;/h1&gt;
&lt;p&gt;前面我们已经学习了代理模式、桥接模式、装饰器模式、适配器模式，这4种结构型设计模式。今天，我们再来学习一种新的结构型模式：门面模式。门面模式原理和实现都特别简单，应用场景也比较明确，主要在接口设计方面使用。&lt;/p&gt;</description></item><item><title>面向对象、设计原则、设计模式、编程规范、重构，这五者有何关系？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83-%E9%87%8D%E6%9E%84%E8%BF%99%E4%BA%94%E8%80%85%E6%9C%89%E4%BD%95%E5%85%B3%E7%B3%BB/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83-%E9%87%8D%E6%9E%84%E8%BF%99%E4%BA%94%E8%80%85%E6%9C%89%E4%BD%95%E5%85%B3%E7%B3%BB/</guid><description>&lt;h1 id="03--面向对象设计原则设计模式编程规范重构这五者有何关系"&gt;03 | 面向对象、设计原则、设计模式、编程规范、重构，这五者有何关系？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们讲到，要具备编写高质量代码的能力，你需要学习一些编程方法论，其中就包含面向对象（我们可以把它看成一种设计思想）、设计原则、设计模式、编程规范、重构技巧等。而我们整个专栏的内容也是围绕着这几块展开讲解的。所以，今天我就先来简单介绍一下这几个概念，并且说一说它们之间的联系。&lt;/p&gt;</description></item><item><title>命令模式：如何利用命令模式实现一个手游后端架构？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%89%8B%E6%B8%B8%E5%90%8E%E7%AB%AF%E6%9E%B6%E6%9E%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%89%8B%E6%B8%B8%E5%90%8E%E7%AB%AF%E6%9E%B6%E6%9E%84/</guid><description>&lt;h1 id="71--命令模式如何利用命令模式实现一个手游后端架构"&gt;71 | 命令模式：如何利用命令模式实现一个手游后端架构？&lt;/h1&gt;
&lt;p&gt;设计模式模块已经接近尾声了，现在我们只剩下3个模式还没有学习，它们分别是：命令模式、解释器模式、中介模式。这3个模式使用频率低、理解难度大，只在非常特定的应用场景下才会用到，所以，不是我们学习的重点，你只需要稍微了解，见了能认识就可以了。&lt;/p&gt;</description></item><item><title>模板模式（上）：剖析模板模式在JDK、Servlet、JUnit等中的应用</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%89%96%E6%9E%90%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E5%9C%A8jdk-servlet-junit%E7%AD%89%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%89%96%E6%9E%90%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E5%9C%A8jdk-servlet-junit%E7%AD%89%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</guid><description>&lt;h1 id="58--模板模式上剖析模板模式在jdkservletjunit等中的应用"&gt;58 | 模板模式（上）：剖析模板模式在JDK、Servlet、JUnit等中的应用&lt;/h1&gt;
&lt;p&gt;上两节课我们学习了第一个行为型设计模式，观察者模式。针对不同的应用场景，我们讲解了不同的实现方式，有同步阻塞、异步非阻塞的实现方式，也有进程内、进程间的实现方式。除此之外，我还带你手把手实现了一个简单的EventBus框架。&lt;/p&gt;</description></item><item><title>模板模式（下）：模板模式与Callback回调函数有何区别和联系？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8Ecallback%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E4%B8%8Ecallback%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB/</guid><description>&lt;h1 id="59--模板模式下模板模式与callback回调函数有何区别和联系"&gt;59 | 模板模式（下）：模板模式与Callback回调函数有何区别和联系？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们学习了模板模式的原理、实现和应用。它常用在框架开发中，通过提供功能扩展点，让框架用户在不修改框架源码的情况下，基于扩展点定制化框架的功能。除此之外，模板模式还可以起到代码复用的作用。&lt;/p&gt;</description></item><item><title>桥接模式：如何实现支持不同类型和渠道的消息推送系统？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%94%AF%E6%8C%81%E4%B8%8D%E5%90%8C%E7%B1%BB%E5%9E%8B%E5%92%8C%E6%B8%A0%E9%81%93%E7%9A%84%E6%B6%88%E6%81%AF%E6%8E%A8%E9%80%81%E7%B3%BB%E7%BB%9F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%94%AF%E6%8C%81%E4%B8%8D%E5%90%8C%E7%B1%BB%E5%9E%8B%E5%92%8C%E6%B8%A0%E9%81%93%E7%9A%84%E6%B6%88%E6%81%AF%E6%8E%A8%E9%80%81%E7%B3%BB%E7%BB%9F/</guid><description>&lt;h1 id="49--桥接模式如何实现支持不同类型和渠道的消息推送系统"&gt;49 | 桥接模式：如何实现支持不同类型和渠道的消息推送系统？&lt;/h1&gt;
&lt;p&gt;上一节课我们学习了第一种结构型模式：代理模式。它在不改变原始类（或者叫被代理类）代码的情况下，通过引入代理类来给原始类附加功能。代理模式在平时的开发经常被用到，常用在业务系统中开发一些非功能性需求，比如：监控、统计、鉴权、限流、事务、幂等、日志。&lt;/p&gt;</description></item><item><title>如何将设计思想、原则、模式等理论知识应用到项目中？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E5%A6%82%E4%BD%95%E5%B0%86%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3-%E5%8E%9F%E5%88%99-%E6%A8%A1%E5%BC%8F%E7%AD%89%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86%E5%BA%94%E7%94%A8%E5%88%B0%E9%A1%B9%E7%9B%AE%E4%B8%AD/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E5%A6%82%E4%BD%95%E5%B0%86%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3-%E5%8E%9F%E5%88%99-%E6%A8%A1%E5%BC%8F%E7%AD%89%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86%E5%BA%94%E7%94%A8%E5%88%B0%E9%A1%B9%E7%9B%AE%E4%B8%AD/</guid><description>&lt;p&gt;上一节课，我们对整个专栏的理论知识点做了串讲复习，不知道你掌握得如何？对于上节课总结的重点内容，我希望你能多花点时间搞透彻，对于一些不那么重要的内容，我建议你把专栏当作工具资料，用到的时候随手查阅，再深入学习研究。&lt;/p&gt;</description></item><item><title>如何接手一坨烂业务代码？如何在烂业务代码中成长？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%8D%81-%E5%A6%82%E4%BD%95%E6%8E%A5%E6%89%8B%E4%B8%80%E5%9D%A8%E7%83%82%E4%B8%9A%E5%8A%A1%E4%BB%A3%E7%A0%81%E5%A6%82%E4%BD%95%E5%9C%A8%E7%83%82%E4%B8%9A%E5%8A%A1%E4%BB%A3%E7%A0%81%E4%B8%AD%E6%88%90%E9%95%BF/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%8D%81-%E5%A6%82%E4%BD%95%E6%8E%A5%E6%89%8B%E4%B8%80%E5%9D%A8%E7%83%82%E4%B8%9A%E5%8A%A1%E4%BB%A3%E7%A0%81%E5%A6%82%E4%BD%95%E5%9C%A8%E7%83%82%E4%B8%9A%E5%8A%A1%E4%BB%A3%E7%A0%81%E4%B8%AD%E6%88%90%E9%95%BF/</guid><description>&lt;p&gt;在我们的职业生涯中，很少有机会可以从零开发一个项目，大部分都是接手别人的代码继续开发，或者做些维护性开发。而且，对于大部分业务系统来说，因为业务导向，需求倒逼，开发工期紧，团队往往都不是很重视代码质量，快速上线是第一要务。所以，很多团队的代码质量一般都不怎么高。埋坑无数、没有文档、也没有注释，代码读不懂、也不敢改，这对于新人来说，会非常苦恼。今天，我们就聊一聊，如何接手一坨烂业务代码，以及如在烂业务代码中的成长？&lt;/p&gt;</description></item><item><title>设计模式、重构、编程规范等相关书籍推荐</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%BA%8C-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E9%87%8D%E6%9E%84-%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E7%AD%89%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D%E6%8E%A8%E8%8D%90/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%BA%8C-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E9%87%8D%E6%9E%84-%E7%BC%96%E7%A8%8B%E8%A7%84%E8%8C%83%E7%AD%89%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D%E6%8E%A8%E8%8D%90/</guid><description>&lt;h1 id="加餐二--设计模式重构编程规范等相关书籍推荐"&gt;加餐二 | 设计模式、重构、编程规范等相关书籍推荐&lt;/h1&gt;
&lt;p&gt;有关设计模式、重构、编程规范等的经典书籍很多，有很多你应该已经听说过、甚至看过。今天，我就结合我的经验，对这些书籍进行一个整理和点评。你可以据此来选择适合你的书籍，结合着专栏一块儿来学习，这样学习效果会更好。&lt;/p&gt;</description></item><item><title>什么才是所谓的编程能力？如何考察一个人的编程能力？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%85%AD-%E4%BB%80%E4%B9%88%E6%89%8D%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84%E7%BC%96%E7%A8%8B%E8%83%BD%E5%8A%9B%E5%A6%82%E4%BD%95%E8%80%83%E5%AF%9F%E4%B8%80%E4%B8%AA%E4%BA%BA%E7%9A%84%E7%BC%96%E7%A8%8B%E8%83%BD%E5%8A%9B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E5%85%AD-%E4%BB%80%E4%B9%88%E6%89%8D%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84%E7%BC%96%E7%A8%8B%E8%83%BD%E5%8A%9B%E5%A6%82%E4%BD%95%E8%80%83%E5%AF%9F%E4%B8%80%E4%B8%AA%E4%BA%BA%E7%9A%84%E7%BC%96%E7%A8%8B%E8%83%BD%E5%8A%9B/</guid><description>&lt;p&gt;在招聘要求里，我们经常看到“要求候选人有扎实的编程能力”。在面试反馈中，我们也经常看到面试官用“编程能力很强”来评价候选人。那到底什么是编程能力呢？如何考察一个人的编程能力呢？又如何提高编程能力呢？今天，我们就编程能力这个话题展开聊一聊。&lt;/p&gt;</description></item><item><title>实战二（上）：程序出错该返回啥？NULL、异常、错误码、空对象？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E7%A8%8B%E5%BA%8F%E5%87%BA%E9%94%99%E8%AF%A5%E8%BF%94%E5%9B%9E%E5%95%A5null-%E5%BC%82%E5%B8%B8-%E9%94%99%E8%AF%AF%E7%A0%81-%E7%A9%BA%E5%AF%B9%E8%B1%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E7%A8%8B%E5%BA%8F%E5%87%BA%E9%94%99%E8%AF%A5%E8%BF%94%E5%9B%9E%E5%95%A5null-%E5%BC%82%E5%B8%B8-%E9%94%99%E8%AF%AF%E7%A0%81-%E7%A9%BA%E5%AF%B9%E8%B1%A1/</guid><description>&lt;h1 id="36--实战二上程序出错该返回啥null异常错误码空对象"&gt;36 | 实战二（上）：程序出错该返回啥？NULL、异常、错误码、空对象？&lt;/h1&gt;
&lt;p&gt;我们可以把函数的运行结果分为两类。一类是预期的结果，也就是函数在正常情况下输出的结果。一类是非预期的结果，也就是函数在异常（或叫出错）情况下输出的结果。比如，在上一节课中，获取本机名的函数，在正常情况下，函数返回字符串格式的本机名；在异常情况下，获取本机名失败，函数返回UnknownHostException异常对象。&lt;/p&gt;</description></item><item><title>实战二（上）：如何对接口鉴权这样一个功能开发做面向对象分析？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E5%A6%82%E4%BD%95%E5%AF%B9%E6%8E%A5%E5%8F%A3%E9%89%B4%E6%9D%83%E8%BF%99%E6%A0%B7%E4%B8%80%E4%B8%AA%E5%8A%9F%E8%83%BD%E5%BC%80%E5%8F%91%E5%81%9A%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%88%86%E6%9E%90/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E5%A6%82%E4%BD%95%E5%AF%B9%E6%8E%A5%E5%8F%A3%E9%89%B4%E6%9D%83%E8%BF%99%E6%A0%B7%E4%B8%80%E4%B8%AA%E5%8A%9F%E8%83%BD%E5%BC%80%E5%8F%91%E5%81%9A%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%88%86%E6%9E%90/</guid><description>&lt;h1 id="13--实战二上如何对接口鉴权这样一个功能开发做面向对象分析"&gt;13 | 实战二（上）：如何对接口鉴权这样一个功能开发做面向对象分析？&lt;/h1&gt;
&lt;p&gt;面向对象分析（OOA）、面向对象设计（OOD）、面向对象编程（OOP），是面向对象开发的三个主要环节。在前面的章节中，我对三者的讲解比较偏理论、偏概括性，目的是让你先有一个宏观的了解，知道什么是OOA、OOD、OOP。不过，光知道“是什么”是不够的，我们更重要的还是要知道“如何做”，也就是，如何进行面向对象分析、设计与编程。&lt;/p&gt;</description></item><item><title>实战二（上）：针对非业务的通用框架开发，如何做需求分析和设计？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E9%92%88%E5%AF%B9%E9%9D%9E%E4%B8%9A%E5%8A%A1%E7%9A%84%E9%80%9A%E7%94%A8%E6%A1%86%E6%9E%B6%E5%BC%80%E5%8F%91%E5%A6%82%E4%BD%95%E5%81%9A%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E5%92%8C%E8%AE%BE%E8%AE%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8A%E9%92%88%E5%AF%B9%E9%9D%9E%E4%B8%9A%E5%8A%A1%E7%9A%84%E9%80%9A%E7%94%A8%E6%A1%86%E6%9E%B6%E5%BC%80%E5%8F%91%E5%A6%82%E4%BD%95%E5%81%9A%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E5%92%8C%E8%AE%BE%E8%AE%A1/</guid><description>&lt;h1 id="25--实战二上针对非业务的通用框架开发如何做需求分析和设计"&gt;25 | 实战二（上）：针对非业务的通用框架开发，如何做需求分析和设计？&lt;/h1&gt;
&lt;p&gt;上两节课中，我们讲了如何针对一个业务系统做需求分析、设计和实现，并且通过一个积分兑换系统的开发，实践了之前学过的一些设计原则。接下来的两节课，我们再结合一个支持各种统计规则的性能计数器项目，学习针对一个非业务的通用框架开发，如何来做需求分析、设计和实现，同时学习如何灵活应用各种设计原则。&lt;/p&gt;</description></item><item><title>实战二（下）：如何利用面向对象设计和编程开发接口鉴权功能？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1%E5%92%8C%E7%BC%96%E7%A8%8B%E5%BC%80%E5%8F%91%E6%8E%A5%E5%8F%A3%E9%89%B4%E6%9D%83%E5%8A%9F%E8%83%BD/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1%E5%92%8C%E7%BC%96%E7%A8%8B%E5%BC%80%E5%8F%91%E6%8E%A5%E5%8F%A3%E9%89%B4%E6%9D%83%E5%8A%9F%E8%83%BD/</guid><description>&lt;h1 id="14--实战二下如何利用面向对象设计和编程开发接口鉴权功能"&gt;14 | 实战二（下）：如何利用面向对象设计和编程开发接口鉴权功能？&lt;/h1&gt;
&lt;p&gt;在上一节课中，针对接口鉴权功能的开发，我们讲了如何进行面向对象分析（OOA），也就是需求分析。实际上，需求定义清楚之后，这个问题就已经解决了一大半，这也是为什么我花了那么多篇幅来讲解需求分析。今天，我们再来看一下，针对面向对象分析产出的需求，如何来进行面向对象设计（OOD）和面向对象编程（OOP）。&lt;/p&gt;</description></item><item><title>实战二（下）：如何实现一个支持各种统计规则的性能计数器？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%BB%9F%E8%AE%A1%E8%A7%84%E5%88%99%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%BB%9F%E8%AE%A1%E8%A7%84%E5%88%99%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8/</guid><description>&lt;h1 id="26--实战二下如何实现一个支持各种统计规则的性能计数器"&gt;26 | 实战二（下）：如何实现一个支持各种统计规则的性能计数器？&lt;/h1&gt;
&lt;p&gt;在上一节课中，我们对计数器框架做了需求分析和粗略的模块划分。今天这节课，我们利用面向对象设计、实现方法，并结合之前学过的设计思想、设计原则来看一下，如何编写灵活、可扩展的、高质量的代码实现。&lt;/p&gt;</description></item><item><title>实战二（下）：重构ID生成器项目中各函数的异常处理代码</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E9%87%8D%E6%9E%84id%E7%94%9F%E6%88%90%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%90%84%E5%87%BD%E6%95%B0%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E4%BB%A3%E7%A0%81/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%BA%8C%E4%B8%8B%E9%87%8D%E6%9E%84id%E7%94%9F%E6%88%90%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%90%84%E5%87%BD%E6%95%B0%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E4%BB%A3%E7%A0%81/</guid><description>&lt;h1 id="37--实战二下重构id生成器项目中各函数的异常处理代码"&gt;37 | 实战二（下）：重构ID生成器项目中各函数的异常处理代码&lt;/h1&gt;
&lt;p&gt;平时进行软件设计开发的时候，我们除了要保证正常情况下的逻辑运行正确之外，还需要编写大量额外的代码，来处理有可能出现的异常情况，以保证代码在任何情况下，都在我们的掌控之内，不会出现非预期的运行结果。程序的bug往往都出现在一些边界条件和异常情况下，所以说，异常处理得好坏直接影响了代码的健壮性。全面、合理地处理各种异常能有效减少代码bug，也是保证代码质量的一个重要手段。&lt;/p&gt;</description></item><item><title>实战一（上）：通过一段ID生成器代码，学习如何发现代码质量问题</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%80%9A%E8%BF%87%E4%B8%80%E6%AE%B5id%E7%94%9F%E6%88%90%E5%99%A8%E4%BB%A3%E7%A0%81%E5%AD%A6%E4%B9%A0%E5%A6%82%E4%BD%95%E5%8F%91%E7%8E%B0%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%80%9A%E8%BF%87%E4%B8%80%E6%AE%B5id%E7%94%9F%E6%88%90%E5%99%A8%E4%BB%A3%E7%A0%81%E5%AD%A6%E4%B9%A0%E5%A6%82%E4%BD%95%E5%8F%91%E7%8E%B0%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F%E9%97%AE%E9%A2%98/</guid><description>&lt;h1 id="34--实战一上通过一段id生成器代码学习如何发现代码质量问题"&gt;34 | 实战一（上）：通过一段ID生成器代码，学习如何发现代码质量问题&lt;/h1&gt;
&lt;p&gt;在前面几节课中，我们讲了一些跟重构相关的理论知识，比如：持续重构、单元测试、代码的可测试性、解耦、编码规范。用一句话总结一下，重构就是发现代码质量问题，并且对其进行优化的过程。&lt;/p&gt;</description></item><item><title>实战一（上）：业务开发常用的基于贫血模型的MVC架构违背OOP吗？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E4%B8%9A%E5%8A%A1%E5%BC%80%E5%8F%91%E5%B8%B8%E7%94%A8%E7%9A%84%E5%9F%BA%E4%BA%8E%E8%B4%AB%E8%A1%80%E6%A8%A1%E5%9E%8B%E7%9A%84mvc%E6%9E%B6%E6%9E%84%E8%BF%9D%E8%83%8Coop%E5%90%97/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E4%B8%9A%E5%8A%A1%E5%BC%80%E5%8F%91%E5%B8%B8%E7%94%A8%E7%9A%84%E5%9F%BA%E4%BA%8E%E8%B4%AB%E8%A1%80%E6%A8%A1%E5%9E%8B%E7%9A%84mvc%E6%9E%B6%E6%9E%84%E8%BF%9D%E8%83%8Coop%E5%90%97/</guid><description>&lt;h1 id="11--实战一上业务开发常用的基于贫血模型的mvc架构违背oop吗"&gt;11 | 实战一（上）：业务开发常用的基于贫血模型的MVC架构违背OOP吗？&lt;/h1&gt;
&lt;p&gt;在前面几节课中，我们学习了面向对象的一些理论知识，比如，面向对象四大特性、接口和抽象类、面向对象和面向过程编程风格、基于接口而非实现编程和多用组合少用继承设计思想等等。接下来，我们再用四节课的时间，通过两个更加贴近实战的项目来进一步学习，如何将这些理论应用到实际的软件开发中。&lt;/p&gt;</description></item><item><title>实战一（上）：针对业务系统的开发，如何做需求分析和设计？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%92%88%E5%AF%B9%E4%B8%9A%E5%8A%A1%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%BC%80%E5%8F%91%E5%A6%82%E4%BD%95%E5%81%9A%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E5%92%8C%E8%AE%BE%E8%AE%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8A%E9%92%88%E5%AF%B9%E4%B8%9A%E5%8A%A1%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%BC%80%E5%8F%91%E5%A6%82%E4%BD%95%E5%81%9A%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E5%92%8C%E8%AE%BE%E8%AE%A1/</guid><description>&lt;h1 id="23--实战一上针对业务系统的开发如何做需求分析和设计"&gt;23 | 实战一（上）：针对业务系统的开发，如何做需求分析和设计？&lt;/h1&gt;
&lt;p&gt;对于一个工程师来说，如果要追求长远发展，你就不能一直只把自己放在执行者的角色，不能只是一个代码实现者，你还要有独立负责一个系统的能力，能端到端（endtoend）开发一个完整的系统。这其中的工作就包括：前期的需求沟通分析、中期的代码设计实现、后期的系统上线维护等。&lt;/p&gt;</description></item><item><title>实战一（下）：如何利用基于充血模型的DDD开发一个虚拟钱包系统？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E5%9F%BA%E4%BA%8E%E5%85%85%E8%A1%80%E6%A8%A1%E5%9E%8B%E7%9A%84ddd%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E8%99%9A%E6%8B%9F%E9%92%B1%E5%8C%85%E7%B3%BB%E7%BB%9F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E5%9F%BA%E4%BA%8E%E5%85%85%E8%A1%80%E6%A8%A1%E5%9E%8B%E7%9A%84ddd%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E8%99%9A%E6%8B%9F%E9%92%B1%E5%8C%85%E7%B3%BB%E7%BB%9F/</guid><description>&lt;h1 id="12--实战一下如何利用基于充血模型的ddd开发一个虚拟钱包系统"&gt;12 | 实战一（下）：如何利用基于充血模型的DDD开发一个虚拟钱包系统？&lt;/h1&gt;
&lt;p&gt;上一节课，我们做了一些理论知识的铺垫性讲解，讲到了两种开发模式，基于贫血模型的传统开发模式，以及基于充血模型的DDD开发模式。今天，我们正式进入实战环节，看如何分别用这两种开发模式，设计实现一个钱包系统。&lt;/p&gt;</description></item><item><title>实战一（下）：如何实现一个遵从设计原则的积分兑换系统？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%81%B5%E4%BB%8E%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E7%9A%84%E7%A7%AF%E5%88%86%E5%85%91%E6%8D%A2%E7%B3%BB%E7%BB%9F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-12%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%81%B5%E4%BB%8E%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E7%9A%84%E7%A7%AF%E5%88%86%E5%85%91%E6%8D%A2%E7%B3%BB%E7%BB%9F/</guid><description>&lt;h1 id="24--实战一下如何实现一个遵从设计原则的积分兑换系统"&gt;24 | 实战一（下）：如何实现一个遵从设计原则的积分兑换系统？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们讲了积分系统的需求分析和系统设计。今天，我们来讲它的代码实现。&lt;/p&gt;
&lt;p&gt;上一节课中，我们把积分赚取和消费的渠道和规则的管理维护工作，划分到了上层系统中，所以，积分系统的功能变得非常简单。相应地，代码实现也比较简单。如果你有一定的项目开发经验，那实现这样一个系统，对你来说并不是件难事。&lt;/p&gt;</description></item><item><title>实战一（下）：手把手带你将ID生成器代码从“能用”重构为“好用”</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%B0%86id%E7%94%9F%E6%88%90%E5%99%A8%E4%BB%A3%E7%A0%81%E4%BB%8E-%E8%83%BD%E7%94%A8-%E9%87%8D%E6%9E%84%E4%B8%BA-%E5%A5%BD%E7%94%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84-11%E8%AE%B2/%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%B0%86id%E7%94%9F%E6%88%90%E5%99%A8%E4%BB%A3%E7%A0%81%E4%BB%8E-%E8%83%BD%E7%94%A8-%E9%87%8D%E6%9E%84%E4%B8%BA-%E5%A5%BD%E7%94%A8/</guid><description>&lt;h1 id="35--实战一下手把手带你将id生成器代码从能用重构为好用"&gt;35 | 实战一（下）：手把手带你将ID生成器代码从“能用”重构为“好用”&lt;/h1&gt;
&lt;p&gt;上一节课中，我们结合ID生成器代码讲解了如何发现代码质量问题。虽然ID生成器的需求非常简单，代码行数也不多，但看似非常简单的代码，实际上还是有很多优化的空间。综合评价一下的话，小王的代码也只能算是“能用”、勉强及格。我们大部分人写出来的代码都能达到这个程度。如果想要在团队中脱颖而出，我们就不能只满足于这个60分及格，大家都能做的事情，我们要做得更好才行。&lt;/p&gt;</description></item><item><title>适配器模式：代理、适配器、桥接、装饰，这四个模式有何区别？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%BB%A3%E7%90%86-%E9%80%82%E9%85%8D%E5%99%A8-%E6%A1%A5%E6%8E%A5-%E8%A3%85%E9%A5%B0%E8%BF%99%E5%9B%9B%E4%B8%AA%E6%A8%A1%E5%BC%8F%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%BB%A3%E7%90%86-%E9%80%82%E9%85%8D%E5%99%A8-%E6%A1%A5%E6%8E%A5-%E8%A3%85%E9%A5%B0%E8%BF%99%E5%9B%9B%E4%B8%AA%E6%A8%A1%E5%BC%8F%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB/</guid><description>&lt;h1 id="51--适配器模式代理适配器桥接装饰这四个模式有何区别"&gt;51 | 适配器模式：代理、适配器、桥接、装饰，这四个模式有何区别？&lt;/h1&gt;
&lt;p&gt;前面几节课我们学习了代理模式、桥接模式、装饰器模式，今天，我们再来学习一个比较常用的结构型模式：适配器模式。这个模式相对来说还是比较简单、好理解的，应用场景也很具体，总体上来讲比较好掌握。&lt;/p&gt;</description></item><item><title>听一听小争哥对Google工程师文化的解读</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%BA%94-%E5%90%AC%E4%B8%80%E5%90%AC%E5%B0%8F%E4%BA%89%E5%93%A5%E5%AF%B9google%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%96%87%E5%8C%96%E7%9A%84%E8%A7%A3%E8%AF%BB/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%BA%94-%E5%90%AC%E4%B8%80%E5%90%AC%E5%B0%8F%E4%BA%89%E5%93%A5%E5%AF%B9google%E5%B7%A5%E7%A8%8B%E5%B8%88%E6%96%87%E5%8C%96%E7%9A%84%E8%A7%A3%E8%AF%BB/</guid><description>&lt;p&gt;在技术圈里，我们经常听到“工程师文化”这个词。很多公司的HR、管理层都热衷于研究Google、Facebook、Netflix等大公司的文化，希望能打造成和它们一样优秀的工程师文化。&lt;/p&gt;</description></item><item><title>王争：如何学习《设计模式之美》专栏？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E6%98%A5%E8%8A%82%E7%89%B9%E5%88%AB%E5%8A%A0%E9%A4%90-%E7%8E%8B%E4%BA%89%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E-%E4%B8%93%E6%A0%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E6%98%A5%E8%8A%82%E7%89%B9%E5%88%AB%E5%8A%A0%E9%A4%90-%E7%8E%8B%E4%BA%89%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E-%E4%B8%93%E6%A0%8F/</guid><description>&lt;h1 id="春节特别加餐--王争如何学习设计模式之美专栏"&gt;春节特别加餐 | 王争：如何学习《设计模式之美》专栏？&lt;/h1&gt;
&lt;p&gt;你好，我是王争。今天是春节，首先祝你在新的一年，学业进步，工作顺利。放假期间，也不要忘记学习啊！&lt;/p&gt;
&lt;p&gt;到此为止，咱们的《设计模式之美》快要更新过半了。很多小伙伴反馈的问题我都看到了。这里我也来讲一下，到底该如何学习《设计模式之美》专栏，才能做到事半功倍、有的放矢？&lt;/p&gt;</description></item><item><title>为什么说每个程序员都要尽早地学习并掌握设计模式相关知识？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E8%A6%81%E5%B0%BD%E6%97%A9%E5%9C%B0%E5%AD%A6%E4%B9%A0%E5%B9%B6%E6%8E%8C%E6%8F%A1%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%AF%BB-3%E8%AE%B2/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E8%A6%81%E5%B0%BD%E6%97%A9%E5%9C%B0%E5%AD%A6%E4%B9%A0%E5%B9%B6%E6%8E%8C%E6%8F%A1%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/</guid><description>&lt;h1 id="01--为什么说每个程序员都要尽早地学习并掌握设计模式相关知识"&gt;01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识？&lt;/h1&gt;
&lt;p&gt;我相信，很多程序员都已经意识到基础知识的重要性，觉得要夯实基础，才能走得更远，但同时对于如何将基础知识转化成开发“生产力”仍然有些疑惑。所以，你可能看了很多基础的书籍，比如操作系统、组成原理、编译原理等，但还是觉得很迷茫，觉得在开发中用不上，起码在平时的CRUD业务开发中用不上。实际上，这些基础的知识确实很难直接转化成开发“生产力”。但是，它能潜移默化地、间接地提高你对技术的理解。&lt;/p&gt;</description></item><item><title>享元模式（上）：如何利用享元模式优化文本编辑器的内存占用？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%BC%98%E5%8C%96%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E7%9A%84%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%BC%98%E5%8C%96%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E7%9A%84%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8/</guid><description>&lt;h1 id="54--享元模式上如何利用享元模式优化文本编辑器的内存占用"&gt;54 | 享元模式（上）：如何利用享元模式优化文本编辑器的内存占用？&lt;/h1&gt;
&lt;p&gt;上一节课中，我们讲了组合模式。组合模式并不常用，主要用在数据能表示成树形结构、能通过树的遍历算法来解决的场景中。今天，我们再来学习一个不那么常用的模式，享元模式（FlyweightDesignPattern）。这也是我们要学习的最后一个结构型模式。&lt;/p&gt;</description></item><item><title>享元模式（下）：剖析享元模式在JavaInteger、String中的应用</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%89%96%E6%9E%90%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E5%9C%A8javainteger-string%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E4%B8%8B%E5%89%96%E6%9E%90%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E5%9C%A8javainteger-string%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/</guid><description>&lt;h1 id="55--享元模式下剖析享元模式在java-integerstring中的应用"&gt;55 | 享元模式（下）：剖析享元模式在Java Integer、String中的应用&lt;/h1&gt;
&lt;p&gt;上一节课，我们通过棋牌游戏和文本编辑器这样两个实际的例子，学习了享元模式的原理、实现以及应用场景。用一句话总结一下，享元模式中的“享元”指被共享的单元。享元模式通过复用对象，以达到节省内存的目的。&lt;/p&gt;</description></item><item><title>项目实战二：设计实现一个通用的接口幂等框架（分析）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E5%88%86%E6%9E%90/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E5%88%86%E6%9E%90/</guid><description>&lt;p&gt;上三节课，我带你分析、设计、实现了一个接口限流框架。在分析阶段，我们讲到需求分析的两大方面，功能性需求分析和非功能性需求分析。在设计阶段，我们讲了如何通过合理的设计，在实功能性需求的前提下，满足易用、易扩展、灵活、高性能、高容错等非功能性需求。在实现阶段，我们讲了如何利用设计思想、原则、模式、编码规范等，编写可读、可扩展等高质量的代码实现。&lt;/p&gt;</description></item><item><title>项目实战二：设计实现一个通用的接口幂等框架（设计）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E8%AE%BE%E8%AE%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E8%AE%BE%E8%AE%A1/</guid><description>&lt;p&gt;上一节课，我们介绍了幂等框架的一个重要需求场景，接口超时重试。为了避免同一业务被多次重复执行，接口需要支持幂等特性。同时，我们还对功能性需求和非功能性需求做了梳理。今天，我们来讲解幂等框架的设计思路。&lt;/p&gt;</description></item><item><title>项目实战二：设计实现一个通用的接口幂等框架（实现）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%BA%8C%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%80%9A%E7%94%A8%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%B9%82%E7%AD%89%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0/</guid><description>&lt;p&gt;上一节课，我们讲解了幂等框架的设计思路。在正常情况下，幂等框架的处理流程是比较简单的。调用方生成幂等号，传递给实现方，实现方记录幂等号或者用幂等号判重。但是，幂等框架要处理的异常情况很多，这也是设计的复杂之处和难点之处。比如，代码运行异常、业务系统宕机、幂等框架异常。&lt;/p&gt;</description></item><item><title>项目实战三：设计实现一个支持自定义规则的灰度发布组件（分析）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E5%88%86%E6%9E%90/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E5%88%86%E6%9E%90/</guid><description>&lt;p&gt;到现在为止，我已经带你学习了接口限流框架和接口幂等框架两个实战项目。接下来，我再带你实战一个新的项目：灰度发布组件。这也是我们专栏的最后一个实战项目。还是老套路，我们把它分为分析、设计、实现三个部分、对应三节课来讲解。今天，我们对灰度发布组件进行需求分析，搞清楚这个组件应该具有哪些功能性和非功能性需求。&lt;/p&gt;</description></item><item><title>项目实战三：设计实现一个支持自定义规则的灰度发布组件（设计）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1/</guid><description>&lt;p&gt;上一节课，我们介绍了灰度组件的一个需求场景，将公共服务平台的RPC接口，灰度替换为新的RESTful接口，通过灰度逐步放量，支持快速回滚等手段，来规避代码质量问题带来的不确定性风险。&lt;/p&gt;</description></item><item><title>项目实战三：设计实现一个支持自定义规则的灰度发布组件（实现）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E5%AE%9E%E7%8E%B0/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%89%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E7%81%B0%E5%BA%A6%E5%8F%91%E5%B8%83%E7%BB%84%E4%BB%B6%E5%AE%9E%E7%8E%B0/</guid><description>&lt;p&gt;上两节课，我们讲解了灰度组件的需求和设计思路。不管是之前讲过的限流、幂等框架，还是现在正在讲的灰度组件，这些框架、组件、类库的功能性需求都不复杂，相反，非功能性需求是开发的重点、难点。&lt;/p&gt;</description></item><item><title>项目实战一：设计实现一个支持各种算法的限流框架（分析）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E5%88%86%E6%9E%90/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E5%88%86%E6%9E%90/</guid><description>&lt;h1 id="90--项目实战一设计实现一个支持各种算法的限流框架分析"&gt;90 | 项目实战一：设计实现一个支持各种算法的限流框架（分析）&lt;/h1&gt;
&lt;p&gt;结束了开源实战，从今天开始我们正式进入项目实战模块。在开源实战中，我带你一块剖析了几个著名的开源项目，比如Spring、MyBatis、GoogleGuava等，剖析了它们背后蕴含的设计思想、原则和模式。&lt;/p&gt;</description></item><item><title>项目实战一：设计实现一个支持各种算法的限流框架（设计）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E8%AE%BE%E8%AE%A1/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E8%AE%BE%E8%AE%A1/</guid><description>&lt;p&gt;上一节课，我们介绍了限流框架产生的项目背景，并且对需求做了分析，这其中包括功能性需求和非功能性需求，算是在正式开始设计之前的一个铺垫。&lt;/p&gt;
&lt;p&gt;前面提到，我们把项目实战分为分析、设计、实现三部分来讲解。其中，分析环节跟之前讲过的面向对象分析很相似，都是做需求的梳理。但是，项目实战中的设计和实现，跟面向对象设计和实现就不是一回事儿了。这里的“设计”指的是系统设计，主要是划分模块，对模块进行设计。这里的“实现”实际上等于面向对象设计加实现。因为我们前面讲到，面向对象设计与实现是聚焦在代码层面的，主要产出的是类的设计和实现。&lt;/p&gt;</description></item><item><title>项目实战一：设计实现一个支持各种算法的限流框架（实现）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-9%E8%AE%B2/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E4%B8%80%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E7%AE%97%E6%B3%95%E7%9A%84%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0/</guid><description>&lt;p&gt;上一节课，我们介绍了如何通过合理的设计，来实现功能性需求的同时，满足易用、易扩展、灵活、低延迟、高容错等非功能性需求。在设计的过程中，我们也借鉴了之前讲过的一些开源项目的设计思想。比如，我们借鉴了Spring的低侵入松耦合、约定优于配置等设计思想，还借鉴了MyBatis通过MyBatis-Spring类库将框架的易用性做到极致等设计思路。&lt;/p&gt;</description></item><item><title>用一篇文章带你了解专栏中用到的所有Java语法</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%80-%E7%94%A8%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B8%A6%E4%BD%A0%E4%BA%86%E8%A7%A3%E4%B8%93%E6%A0%8F%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%84%E6%89%80%E6%9C%89java%E8%AF%AD%E6%B3%95/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B8%80-%E7%94%A8%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B8%A6%E4%BD%A0%E4%BA%86%E8%A7%A3%E4%B8%93%E6%A0%8F%E4%B8%AD%E7%94%A8%E5%88%B0%E7%9A%84%E6%89%80%E6%9C%89java%E8%AF%AD%E6%B3%95/</guid><description>&lt;h1 id="加餐一--用一篇文章带你了解专栏中用到的所有java语法"&gt;加餐一 | 用一篇文章带你了解专栏中用到的所有Java语法&lt;/h1&gt;
&lt;p&gt;尽管说设计模式跟编程语言没有直接关系，但是，我们也无法完全脱离代码来讲设计模式。我本人熟悉的是Java语言，所以专栏中的代码示例我都是用Java语言来写的。考虑到有些同学并不熟悉Java语言，我今天用一篇文章介绍一下专栏中用到的Java语法。&lt;/p&gt;</description></item><item><title>原型模式：如何最快速地clone一个HashMap散列表？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0clone%E4%B8%80%E4%B8%AAhashmap%E6%95%A3%E5%88%97%E8%A1%A8/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E5%88%9B%E5%BB%BA%E5%9E%8B-7%E8%AE%B2/%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E6%9C%80%E5%BF%AB%E9%80%9F%E5%9C%B0clone%E4%B8%80%E4%B8%AAhashmap%E6%95%A3%E5%88%97%E8%A1%A8/</guid><description>&lt;h1 id="47--原型模式如何最快速地clone一个hashmap散列表"&gt;47 | 原型模式：如何最快速地clone一个HashMap散列表？&lt;/h1&gt;
&lt;p&gt;对于创建型模式，前面我们已经讲了单例模式、工厂模式、建造者模式，今天我们来讲最后一个：原型模式。&lt;/p&gt;</description></item><item><title>运用学过的设计原则和思想完善之前讲的性能计数器项目（上）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E6%80%BB%E7%BB%93%E8%AF%BE-3%E8%AE%B2/%E8%BF%90%E7%94%A8%E5%AD%A6%E8%BF%87%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E5%92%8C%E6%80%9D%E6%83%B3%E5%AE%8C%E5%96%84%E4%B9%8B%E5%89%8D%E8%AE%B2%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%8A/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E6%80%BB%E7%BB%93%E8%AF%BE-3%E8%AE%B2/%E8%BF%90%E7%94%A8%E5%AD%A6%E8%BF%87%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E5%92%8C%E6%80%9D%E6%83%B3%E5%AE%8C%E5%96%84%E4%B9%8B%E5%89%8D%E8%AE%B2%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%8A/</guid><description>&lt;h1 id="39--运用学过的设计原则和思想完善之前讲的性能计数器项目上"&gt;39 | 运用学过的设计原则和思想完善之前讲的性能计数器项目（上）&lt;/h1&gt;
&lt;p&gt;在、中，我们讲了如何对一个性能计数器框架进行分析、设计与实现，并且实践了之前学过的一些设计原则和设计思想。当时我们提到，小步快跑、逐步迭代是一种非常实用的开发模式。所以，针对这个框架的开发，我们分多个版本来逐步完善。&lt;/p&gt;</description></item><item><title>运用学过的设计原则和思想完善之前讲的性能计数器项目（下）</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E6%80%BB%E7%BB%93%E8%AF%BE-3%E8%AE%B2/%E8%BF%90%E7%94%A8%E5%AD%A6%E8%BF%87%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E5%92%8C%E6%80%9D%E6%83%B3%E5%AE%8C%E5%96%84%E4%B9%8B%E5%89%8D%E8%AE%B2%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%8B/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E4%B8%8E%E6%80%9D%E6%83%B3%E6%80%BB%E7%BB%93%E8%AF%BE-3%E8%AE%B2/%E8%BF%90%E7%94%A8%E5%AD%A6%E8%BF%87%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%E5%92%8C%E6%80%9D%E6%83%B3%E5%AE%8C%E5%96%84%E4%B9%8B%E5%89%8D%E8%AE%B2%E7%9A%84%E6%80%A7%E8%83%BD%E8%AE%A1%E6%95%B0%E5%99%A8%E9%A1%B9%E7%9B%AE%E4%B8%8B/</guid><description>&lt;h1 id="40--运用学过的设计原则和思想完善之前讲的性能计数器项目下"&gt;40 | 运用学过的设计原则和思想完善之前讲的性能计数器项目（下）&lt;/h1&gt;
&lt;p&gt;上一节课中，我们针对版本1存在的问题（特别是Aggregator类、ConsoleReporter和EmailReporter类）进行了重构优化。经过重构之后，代码结构更加清晰、合理、有逻辑性。不过，在细节方面还是存在一些问题，比如ConsoleReporter、EmailReporter类仍然存在代码重复、可测试性差的问题。今天，我们就在版本3中持续重构这部分代码。&lt;/p&gt;</description></item><item><title>在实际的项目开发中，如何避免过度设计？又如何避免设计不足？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E5%9C%A8%E5%AE%9E%E9%99%85%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E4%B8%AD%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E8%BF%87%E5%BA%A6%E8%AE%BE%E8%AE%A1%E5%8F%88%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E8%AE%BE%E8%AE%A1%E4%B8%8D%E8%B6%B3/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E5%9C%A8%E5%AE%9E%E9%99%85%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E4%B8%AD%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E8%BF%87%E5%BA%A6%E8%AE%BE%E8%AE%A1%E5%8F%88%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E8%AE%BE%E8%AE%A1%E4%B8%8D%E8%B6%B3/</guid><description>&lt;h1 id="75--在实际的项目开发中如何避免过度设计又如何避免设计不足"&gt;75 | 在实际的项目开发中，如何避免过度设计？又如何避免设计不足？&lt;/h1&gt;
&lt;p&gt;设计模式的理论部分已经全部学习完了。现在，你可能已经蠢蠢欲动，想要赶紧实践一把，把这些理论应用到自己的项目中。不过，这里我要给你提个醒了，千万别手里拿着锤子就看什么都是钉子啊。&lt;/p&gt;</description></item><item><title>职责链模式（上）：如何实现可灵活扩展算法的敏感信息过滤框架？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%81%8C%E8%B4%A3%E9%93%BE%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8F%AF%E7%81%B5%E6%B4%BB%E6%89%A9%E5%B1%95%E7%AE%97%E6%B3%95%E7%9A%84%E6%95%8F%E6%84%9F%E4%BF%A1%E6%81%AF%E8%BF%87%E6%BB%A4%E6%A1%86%E6%9E%B6/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%81%8C%E8%B4%A3%E9%93%BE%E6%A8%A1%E5%BC%8F%E4%B8%8A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8F%AF%E7%81%B5%E6%B4%BB%E6%89%A9%E5%B1%95%E7%AE%97%E6%B3%95%E7%9A%84%E6%95%8F%E6%84%9F%E4%BF%A1%E6%81%AF%E8%BF%87%E6%BB%A4%E6%A1%86%E6%9E%B6/</guid><description>&lt;h1 id="62--职责链模式上如何实现可灵活扩展算法的敏感信息过滤框架"&gt;62 | 职责链模式（上）：如何实现可灵活扩展算法的敏感信息过滤框架？&lt;/h1&gt;
&lt;p&gt;前几节课中，我们学习了模板模式、策略模式，今天，我们来学习职责链模式。这三种模式具有相同的作用：复用和扩展，在实际的项目开发中比较常用，特别是框架开发中，我们可以利用它们来提供框架的扩展点，能够让框架的使用者在不修改框架源码的情况下，基于扩展点定制化框架的功能。&lt;/p&gt;</description></item><item><title>职责链模式（下）：框架中常用的过滤器、拦截器是如何实现的？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%81%8C%E8%B4%A3%E9%93%BE%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%A1%86%E6%9E%B6%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E8%BF%87%E6%BB%A4%E5%99%A8-%E6%8B%A6%E6%88%AA%E5%99%A8%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E8%81%8C%E8%B4%A3%E9%93%BE%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%A1%86%E6%9E%B6%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E8%BF%87%E6%BB%A4%E5%99%A8-%E6%8B%A6%E6%88%AA%E5%99%A8%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</guid><description>&lt;h1 id="63--职责链模式下框架中常用的过滤器拦截器是如何实现的"&gt;63 | 职责链模式（下）：框架中常用的过滤器、拦截器是如何实现的？&lt;/h1&gt;
&lt;p&gt;上一节课，我们学习职责链模式的原理与实现，并且通过一个敏感词过滤框架的例子，展示了职责链模式的设计意图。本质上来说，它跟大部分设计模式一样，都是为了解耦代码，应对代码的复杂性，让代码满足开闭原则，提高代码的可扩展性。&lt;/p&gt;</description></item><item><title>中介模式：什么时候用中介模式？什么时候用观察者模式？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E4%B8%AD%E4%BB%8B%E6%A8%A1%E5%BC%8F%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%94%A8%E4%B8%AD%E4%BB%8B%E6%A8%A1%E5%BC%8F%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%94%A8%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E4%B8%AD%E4%BB%8B%E6%A8%A1%E5%BC%8F%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%94%A8%E4%B8%AD%E4%BB%8B%E6%A8%A1%E5%BC%8F%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%94%A8%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="73--中介模式什么时候用中介模式什么时候用观察者模式"&gt;73 | 中介模式：什么时候用中介模式？什么时候用观察者模式？&lt;/h1&gt;
&lt;p&gt;今天，我们来学习23种经典设计模式中的最后一个，中介模式。跟前面刚刚讲过的命令模式、解释器模式类似，中介模式也属于不怎么常用的模式，应用场景比较特殊、有限，但是，跟它俩不同的是，中介模式理解起来并不难，代码实现也非常简单，学习难度要小很多。&lt;/p&gt;</description></item><item><title>装饰器模式：通过剖析JavaIO类库源码学习装饰器模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javaio%E7%B1%BB%E5%BA%93%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E9%80%9A%E8%BF%87%E5%89%96%E6%9E%90javaio%E7%B1%BB%E5%BA%93%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="50--装饰器模式通过剖析java-io类库源码学习装饰器模式"&gt;50 | 装饰器模式：通过剖析Java IO类库源码学习装饰器模式&lt;/h1&gt;
&lt;p&gt;上一节课我们学习了桥接模式，桥接模式有两种理解方式。第一种理解方式是“将抽象和实现解耦，让它们能独立开发”。这种理解方式比较特别，应用场景也不多。另一种理解方式更加简单，类似“组合优于继承”设计原则，这种理解方式更加通用，应用场景比较多。不管是哪种理解方式，它们的代码结构都是相同的，都是一种类之间的组合关系。&lt;/p&gt;</description></item><item><title>状态模式：游戏、工作流引擎中常用的状态机是如何实现的？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E6%B8%B8%E6%88%8F-%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%BC%95%E6%93%8E%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E7%8A%B6%E6%80%81%E6%9C%BA%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E8%A1%8C%E4%B8%BA%E5%9E%8B-18%E8%AE%B2/%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E6%B8%B8%E6%88%8F-%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%BC%95%E6%93%8E%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E7%8A%B6%E6%80%81%E6%9C%BA%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</guid><description>&lt;h1 id="64--状态模式游戏工作流引擎中常用的状态机是如何实现的"&gt;64 | 状态模式：游戏、工作流引擎中常用的状态机是如何实现的？&lt;/h1&gt;
&lt;p&gt;从今天起，我们开始学习状态模式。在实际的软件开发中，状态模式并不是很常用，但是在能够用到的场景里，它可以发挥很大的作用。从这一点上来看，它有点像我们之前讲到的组合模式。&lt;/p&gt;</description></item><item><title>总结回顾：在实际软件开发中常用的设计思想、原则和模式</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E6%80%BB%E7%BB%93%E5%9B%9E%E9%A1%BE%E5%9C%A8%E5%AE%9E%E9%99%85%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3-%E5%8E%9F%E5%88%99%E5%92%8C%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E5%BC%80%E6%BA%90%E4%B8%8E%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E6%80%BB%E7%BB%93%E5%9B%9E%E9%A1%BE%E5%9C%A8%E5%AE%9E%E9%99%85%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3-%E5%8E%9F%E5%88%99%E5%92%8C%E6%A8%A1%E5%BC%8F/</guid><description>&lt;p&gt;到今天为止，理论部分和实战部分都已经讲完了，整个专栏也接近尾声了。我这里用两节课的时间，带你一块复习一下前面学到的知识点。跟前面的讲解相对应，这两节课分别是针对理论部分和实战部分进行回顾总结。&lt;/p&gt;</description></item><item><title>总结回顾23种经典设计模式的原理、背后的思想、应用场景等</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E6%80%BB%E7%BB%93%E5%9B%9E%E9%A1%BE23%E7%A7%8D%E7%BB%8F%E5%85%B8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8E%9F%E7%90%86-%E8%83%8C%E5%90%8E%E7%9A%84%E6%80%9D%E6%83%B3-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E7%AD%89/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E6%80%BB%E7%BB%93%E8%AF%BE-2%E8%AE%B2/%E6%80%BB%E7%BB%93%E5%9B%9E%E9%A1%BE23%E7%A7%8D%E7%BB%8F%E5%85%B8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8E%9F%E7%90%86-%E8%83%8C%E5%90%8E%E7%9A%84%E6%80%9D%E6%83%B3-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E7%AD%89/</guid><description>&lt;h1 id="74--总结回顾23种经典设计模式的原理背后的思想应用场景等"&gt;74 | 总结回顾23种经典设计模式的原理、背后的思想、应用场景等&lt;/h1&gt;
&lt;p&gt;到今天为止，23种经典的设计模式已经全部讲完了。咱们整个专栏也完成了3/4，马上就要进入实战环节了。在进入新模块的学习之前，我照例带你做一下总结回顾。23种经典设计模式共分为3种类型，分别是创建型、结构型和行为型。今天，我们把这3种类型分成3个对应的小模块，逐一带你回顾一下每一种设计模式的原理、实现、设计意图和应用场景。&lt;/p&gt;</description></item><item><title>组合模式：如何设计实现支持递归遍历的文件系统目录树结构？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E6%94%AF%E6%8C%81%E9%80%92%E5%BD%92%E9%81%8D%E5%8E%86%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9B%AE%E5%BD%95%E6%A0%91%E7%BB%93%E6%9E%84/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E8%8C%83%E5%BC%8F%E7%BB%93%E6%9E%84%E5%9E%8B-8%E8%AE%B2/%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E6%94%AF%E6%8C%81%E9%80%92%E5%BD%92%E9%81%8D%E5%8E%86%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9B%AE%E5%BD%95%E6%A0%91%E7%BB%93%E6%9E%84/</guid><description>&lt;h1 id="53--组合模式如何设计实现支持递归遍历的文件系统目录树结构"&gt;53 | 组合模式：如何设计实现支持递归遍历的文件系统目录树结构？&lt;/h1&gt;
&lt;p&gt;结构型设计模式就快要讲完了，还剩下两个不那么常用的：组合模式和享元模式。今天，我们来讲一下组合模式（CompositeDesignPattern）。&lt;/p&gt;</description></item><item><title>作为面试官或候选人，如何面试或回答设计模式问题？</title><link>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B9%9D-%E4%BD%9C%E4%B8%BA%E9%9D%A2%E8%AF%95%E5%AE%98%E6%88%96%E5%80%99%E9%80%89%E4%BA%BA%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%88%96%E5%9B%9E%E7%AD%94%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 21 May 2022 17:35:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%9E%81%E5%AE%A2%E6%97%B6%E9%97%B4/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BE%8E/%E4%B8%8D%E5%AE%9A%E6%9C%9F%E5%8A%A0%E9%A4%90-11%E8%AE%B2/%E5%8A%A0%E9%A4%90%E4%B9%9D-%E4%BD%9C%E4%B8%BA%E9%9D%A2%E8%AF%95%E5%AE%98%E6%88%96%E5%80%99%E9%80%89%E4%BA%BA%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%88%96%E5%9B%9E%E7%AD%94%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;在中，我们讲到，对于程序员的编程能力，我们一般从数据结构和算法、设计模式这两个方面来考察。加餐六重点讲到了如何考察数据结构和算法，今天，我们重点讲讲，如何考察设计模式。&lt;/p&gt;</description></item><item><title>ThreadLocalRandom原理解析</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/threadlocalrandom%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/</link><pubDate>Fri, 13 May 2022 09:36:39 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/threadlocalrandom%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/</guid><description>&lt;h1 id="threadlocalrandom原理解析"&gt;ThreadLocalRandom原理解析&lt;/h1&gt;
&lt;h2 id="了解random类"&gt;了解Random类&lt;/h2&gt;
&lt;h3 id="作用"&gt;作用&lt;/h3&gt;
&lt;p&gt;用来获取随机数，提供nextInt(),nextLong()&amp;hellip;api获取随机数&lt;/p&gt;
&lt;p&gt;&lt;img alt="20220513094102" loading="lazy" src="https://img.ggball.top/picGo/20220513094102.png"&gt;&lt;/p&gt;
&lt;h3 id="方法解析"&gt;方法解析&lt;/h3&gt;
&lt;p&gt;先看一段代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Random random &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Random();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 10; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 输出0~5的数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;random = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; random.&lt;span style="color:#a6e22e"&gt;nextInt&lt;/span&gt;(5));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的意思就是循环10次，每次都是调用&lt;code&gt;random&lt;/code&gt;对象的&lt;code&gt;nextInt(5)&lt;/code&gt; 来获取[0,5)之间的数。
再来看下&lt;code&gt;nextInt()&lt;/code&gt;方法&lt;/p&gt;</description></item><item><title>规范与重构</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84/</link><pubDate>Mon, 09 May 2022 09:01:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A7%84%E8%8C%83%E4%B8%8E%E9%87%8D%E6%9E%84/</guid><description>&lt;h1 id="规范与重构"&gt;规范与重构&lt;/h1&gt;
&lt;h2 id="了解重构"&gt;了解重构&lt;/h2&gt;
&lt;h3 id="重构的目的为什么要重构why"&gt;重构的目的：为什么要重构（why）？&lt;/h3&gt;
&lt;p&gt;重构的含义&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;重构是一种对软件内部结构的改善，目的是在不改变软件的可见行为的情况下，使其更易理解，修改成本更低&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;重构的意义&lt;/p&gt;
&lt;p&gt;首先，重构是时刻保证代码质量的一个极其有效的手段，不至于让代码腐化到无可救药的地步。&lt;/p&gt;</description></item><item><title>锁的了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E9%94%81%E7%9A%84%E4%BA%86%E8%A7%A3/</link><pubDate>Thu, 05 May 2022 18:28:36 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E9%94%81%E7%9A%84%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="并发编程中的锁"&gt;并发编程中的锁&lt;/h1&gt;
&lt;h2 id="乐观锁与悲观锁"&gt;乐观锁与悲观锁&lt;/h2&gt;
&lt;h2 id="公平锁与非公平锁"&gt;公平锁与非公平锁&lt;/h2&gt;
&lt;h2 id="独占锁与共享锁"&gt;独占锁与共享锁&lt;/h2&gt;
&lt;h2 id="什么是可重入锁"&gt;什么是可重入锁&lt;/h2&gt;
&lt;h2 id="自旋锁"&gt;自旋锁&lt;/h2&gt;</description></item><item><title>伪共享</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E4%BC%AA%E5%85%B1%E4%BA%AB/</link><pubDate>Thu, 05 May 2022 17:35:36 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E4%BC%AA%E5%85%B1%E4%BA%AB/</guid><description>&lt;h1 id="伪共享"&gt;伪共享&lt;/h1&gt;
&lt;p&gt;从字面意思，我一开始理解的有点迷糊，一开始以为在内存中的变量是不可靠的呢，但是不是！它带来的影响是，会造成多线程操作同一个缓存行的变量性能下降，因为同一个缓存行的修改，只能能同时被一个线程修改，这样就失去了多线程的意义&lt;/p&gt;</description></item><item><title>unsafe类了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/unsafe%E7%B1%BB%E4%BA%86%E8%A7%A3/</link><pubDate>Thu, 05 May 2022 16:58:24 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/unsafe%E7%B1%BB%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="unsafe类"&gt;unsafe类&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;JDK 的此jar包中 的 Unsafe 类提供了硬件级别的原子性操作 ，Unsafe 类中的方法都是native 方法 ，它们使用JNI的方式访问本地 C＋＋实现库。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="使用unsafe类-完成copareandswap"&gt;使用unsafe类 完成copareAndSwap&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @author ggBall
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @version 1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @ClassName UnsafeSateTest.java
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description 获取不到unsafe app类加载器加载不到 unsafe 因为unsafe只允许bootstrap类加载器获取，Unsafe.getUnsafe()里面也做了判断只允许bootstrap类加载器加载
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @createTime 2022年04月30日 16:44:00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UnsafeSateTest&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Unsafe unSafe &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Unsafe.&lt;span style="color:#a6e22e"&gt;getUnsafe&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; stateOffset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;volatile&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 拿到 属性state在类UnsafeSateTest的偏移量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stateOffset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unSafe.&lt;span style="color:#a6e22e"&gt;objectFieldOffset&lt;/span&gt;(UnsafeSateTest.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;state&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (NoSuchFieldException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UnsafeSateTest unsafeSateTest &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UnsafeSateTest();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unSafe.&lt;span style="color:#a6e22e"&gt;compareAndSwapLong&lt;/span&gt;(unsafeSateTest, stateOffset, 0, 1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;result = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; result);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @author ggBall
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @version 1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @ClassName UnsafeSateTest.java
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description 利用反射获取unsafe
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @createTime 2022年04月30日 16:44:00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UnsafeSateTest2&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; Unsafe unSafe;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; stateOffset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;volatile&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Field theUnsafe &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Unsafe.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;theUnsafe&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; theUnsafe.&lt;span style="color:#a6e22e"&gt;setAccessible&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 获取该变量的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; unSafe &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Unsafe)theUnsafe.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 拿到 属性state在类UnsafeSateTest的偏移量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stateOffset &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unSafe.&lt;span style="color:#a6e22e"&gt;objectFieldOffset&lt;/span&gt;(UnsafeSateTest2.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;state&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (NoSuchFieldException &lt;span style="color:#f92672"&gt;|&lt;/span&gt; IllegalAccessException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UnsafeSateTest2 unsafeSateTest &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UnsafeSateTest2();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unSafe.&lt;span style="color:#a6e22e"&gt;compareAndSwapLong&lt;/span&gt;(unsafeSateTest, stateOffset, 0, 1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;result = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; result);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>贫血模型与充血模型</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%B4%AB%E8%A1%80%E6%A8%A1%E5%9E%8B%E4%B8%8E%E5%85%85%E8%A1%80%E6%A8%A1%E5%9E%8B/</link><pubDate>Wed, 04 May 2022 21:13:23 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%B4%AB%E8%A1%80%E6%A8%A1%E5%9E%8B%E4%B8%8E%E5%85%85%E8%A1%80%E6%A8%A1%E5%9E%8B/</guid><description>&lt;h3 id="实战一下如何利用基于充血模型的ddd开发一个虚拟钱包系统"&gt;实战一（下）：如何利用基于充血模型的DDD开发一个虚拟钱包系统？&lt;/h3&gt;
&lt;h4 id="1-什么是贫血模型什么是充血模型"&gt;1. 什么是贫血模型？什么是充血模型？&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;贫血模型：只包含数据，不包含业务逻辑的类&lt;/p&gt;
&lt;p&gt;充血模型：既包含数据，也包含业务逻辑的类&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="2-为什么说基于贫血模型的传统开发模式违反-oop"&gt;2. 为什么说基于贫血模型的传统开发模式违反 OOP?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;这种贫血模型将数据与操作分离，破坏了面向对象的封装特性，是一种典型的面向过程的编程风格。&lt;/p&gt;</description></item><item><title>设计原则</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99/</link><pubDate>Wed, 04 May 2022 21:10:24 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99/</guid><description>&lt;h1 id="solid原则"&gt;solid原则&lt;/h1&gt;
&lt;p&gt;单一职责原则、开闭原则、里式替换原则、接口隔离原则和依赖反转原则，依次对应 SOLID 中的 S、O、L、I、D 这 5 个英文字母。&lt;/p&gt;
&lt;h2 id="单一职责"&gt;单一职责&lt;/h2&gt;
&lt;p&gt;单一职责原则的英文是 Single Responsibility Principle，缩写为 SRP。这个原则的英文描述是这样的：A class or module should have a single reponsibility。如果我们把它翻译成中文，那就是：一个类或者模块只负责完成一个职责（或者功能）。&lt;/p&gt;</description></item><item><title>什么是多线程并发编程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E4%BB%80%E4%B9%88%E6%98%AF%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/</link><pubDate>Wed, 27 Apr 2022 15:17:55 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E4%BB%80%E4%B9%88%E6%98%AF%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/</guid><description>&lt;h1 id="什么是多线程并发编程"&gt;什么是多线程并发编程&lt;/h1&gt;
&lt;h2 id="了解什么是并发什么是并行"&gt;了解什么是并发，什么是并行？&lt;/h2&gt;
&lt;p&gt;并发：一段时间内，执行多个没有结束的任务。
并行：单位时间内，同时执行多个任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：并发任务强调在一个时间段内同时执行，而一个时间段由多个单位时间累积而成，所以说并发的多个任务在单位时间内不一定同时在执行&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>ThreadLocal了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/threadlocal%E4%BA%86%E8%A7%A3/</link><pubDate>Tue, 26 Apr 2022 20:12:28 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/threadlocal%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="threadlocal了解"&gt;ThreadLocal了解&lt;/h1&gt;
&lt;h2 id="原理解析"&gt;原理解析&lt;/h2&gt;
&lt;p&gt;&lt;img alt="20220426201457" loading="lazy" src="https://img.ggball.top/picGo/20220426201457.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通过ThreadLocal获取当前线程保存的值的流程：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先得到当前线程对象&lt;/li&gt;
&lt;li&gt;再从当前线程获取ThreadLocalMap&lt;/li&gt;
&lt;li&gt;最后传入this(即ThreadLocal)获取对应的值&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;创建ThreadLocal时，里面的属性并未初始化，只有当第一次set时才会创建容器，且装数据的容器也不是放在ThreadLocal里面的，而是在Thread里面，一个是threadLocals，一个是inheritableThreadLocals，（数据结构都是hashMap）ThreaLocal只负责操作数据，并不负责储存&lt;/p&gt;</description></item><item><title>守护线程与用户线程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%AE%88%E6%8A%A4%E7%BA%BF%E7%A8%8B%E4%B8%8E%E7%94%A8%E6%88%B7%E7%BA%BF%E7%A8%8B/</link><pubDate>Tue, 26 Apr 2022 19:52:08 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%AE%88%E6%8A%A4%E7%BA%BF%E7%A8%8B%E4%B8%8E%E7%94%A8%E6%88%B7%E7%BA%BF%E7%A8%8B/</guid><description>&lt;h2 id="概念"&gt;概念&lt;/h2&gt;
&lt;p&gt;守护线程：jvm不关心守护线程是否执行完成，如果用户线程全都执行结束，那么jvm就会退出
用户线程：jvm会等待所有用户线程全都执行结束，jvm才会退出&lt;/p&gt;</description></item><item><title>线程死锁</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%AD%BB%E9%94%81/</link><pubDate>Tue, 26 Apr 2022 16:48:21 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%AD%BB%E9%94%81/</guid><description>&lt;h2 id="线程死锁"&gt;线程死锁&lt;/h2&gt;
&lt;p&gt;死锁是指&lt;strong&gt;两个或两个以上的线程&lt;/strong&gt;在执行过程中，&lt;strong&gt;因争夺资源而造成的互相等待的现象&lt;/strong&gt;，在无外力作用的情况下，这些线程会一直相互等待而无法继续运行下去&lt;/p&gt;
&lt;p&gt;&lt;img alt="死锁" loading="lazy" src="https://img.ggball.top/picGo/20220426165050.png"&gt;&lt;/p&gt;</description></item><item><title>多线程的方法介绍与使用</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%9A%84%E6%96%B9%E6%B3%95%E4%BB%8B%E7%BB%8D%E4%B8%8E%E4%BD%BF%E7%94%A8/</link><pubDate>Tue, 26 Apr 2022 15:06:22 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%9A%84%E6%96%B9%E6%B3%95%E4%BB%8B%E7%BB%8D%E4%B8%8E%E4%BD%BF%E7%94%A8/</guid><description>&lt;p&gt;&lt;img alt="20230614004537" loading="lazy" src="https://img.ggball.top/picGo/20230614004537.png"&gt;&lt;/p&gt;
&lt;h2 id="wait函数"&gt;wait函数&lt;/h2&gt;
&lt;p&gt;wait函数会使得到监视器锁的共享对象从&lt;strong&gt;运行状态&lt;/strong&gt;变为&lt;strong&gt;挂起&lt;/strong&gt;，同时会&lt;strong&gt;释放这把锁&lt;/strong&gt;，&lt;strong&gt;但是不会释放当前线程其他共享对象上的锁&lt;/strong&gt;。
以下几个事件可以打断被wait阻塞挂起的状态&lt;/p&gt;</description></item><item><title>进程与线程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E8%BF%9B%E7%A8%8B%E4%B8%8E%E7%BA%BF%E7%A8%8B/</link><pubDate>Tue, 26 Apr 2022 13:48:12 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E8%BF%9B%E7%A8%8B%E4%B8%8E%E7%BA%BF%E7%A8%8B/</guid><description>&lt;h2 id="进程与线程的含义"&gt;进程与线程的含义&lt;/h2&gt;
&lt;h3 id="进程"&gt;进程：&lt;/h3&gt;
&lt;p&gt;进程是代码在数据集合上的一次运行活动 ，是系统进行资源分配和调度的基本单位,一个进程可以有多个线程。&lt;/p&gt;
&lt;h3 id="线程"&gt;线程：&lt;/h3&gt;
&lt;p&gt;进程中的一个执行任务（控制单元），负责当前进程中程序的执行。一个进程至少有一个线程，一个进程可以运行多个线程，多个线程可共享数据。&lt;/p&gt;</description></item><item><title>springBean了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springbean%E4%BA%86%E8%A7%A3/</link><pubDate>Tue, 19 Apr 2022 15:35:40 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springbean%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="springbean了解"&gt;springBean了解&lt;/h1&gt;
&lt;h2 id="1-定义springbean"&gt;1. 定义springBean&lt;/h2&gt;
&lt;h2 id="2-beandefinition-元信息"&gt;2. Beandefinition 元信息&lt;/h2&gt;
&lt;h2 id="3-命名spring-bean"&gt;3. 命名spring bean&lt;/h2&gt;
&lt;h2 id="4-spring-bean的别名"&gt;4. spring bean的别名&lt;/h2&gt;
&lt;h2 id="5-注册spring-beandefinition"&gt;5. 注册spring Beandefinition&lt;/h2&gt;
&lt;h3 id="注册beandefinition-方式"&gt;注册BeanDefinition 方式&lt;/h3&gt;
&lt;h4 id="1-xml"&gt;1. xml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Xml" data-lang="Xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;ggBall的bean工厂&lt;span style="color:#f92672"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resource=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;textBean.xml&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;alias&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;veryComplexDomain&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alias=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;vcd&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;user&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.zhu.entity.User&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;ref&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bean=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;son&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/constructor-arg&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;son&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.zhu.entity.Son&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;小名&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-注解-beancomponentimport"&gt;2. 注解 （@Bean,@Component,@Import）&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Import&lt;/span&gt;(User.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Bean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; User &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Bean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Son &lt;span style="color:#a6e22e"&gt;son&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Son();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="3-java-api"&gt;3. java Api&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;BeanDefinitionRegistry#registerBeanDefinition&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 命名方式 注册BeanDefinition
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * registry.registerBeanDefinition(beanName,beanDefinition);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param registry
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param beanName
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param classBean
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerBeanDefinition&lt;/span&gt;(BeanDefinitionRegistry registry,String beanName,Class classBean) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BeanDefinitionBuilder definitionBuilder &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BeanDefinitionBuilder.&lt;span style="color:#a6e22e"&gt;genericBeanDefinition&lt;/span&gt;(classBean);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; definitionBuilder.&lt;span style="color:#a6e22e"&gt;addPropertyValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;addPropertyValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AbstractBeanDefinition beanDefinition &lt;span style="color:#f92672"&gt;=&lt;/span&gt; definitionBuilder.&lt;span style="color:#a6e22e"&gt;getBeanDefinition&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; registry.&lt;span style="color:#a6e22e"&gt;registerBeanDefinition&lt;/span&gt;(beanName,beanDefinition);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;BeanDefinitionReaderUtils#registerWithGeneratedName&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 非命名方式 注册BeanDefinition
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition,registry);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param registry
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param classBean
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerBeanDefinition&lt;/span&gt;(BeanDefinitionRegistry registry,Class classBean) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BeanDefinitionBuilder definitionBuilder &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BeanDefinitionBuilder.&lt;span style="color:#a6e22e"&gt;genericBeanDefinition&lt;/span&gt;(classBean);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; definitionBuilder.&lt;span style="color:#a6e22e"&gt;addPropertyValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;xxx_1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;addPropertyValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AbstractBeanDefinition beanDefinition &lt;span style="color:#f92672"&gt;=&lt;/span&gt; definitionBuilder.&lt;span style="color:#a6e22e"&gt;getBeanDefinition&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BeanDefinitionReaderUtils.&lt;span style="color:#a6e22e"&gt;registerWithGeneratedName&lt;/span&gt;(beanDefinition,registry);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="6-实例化spring-bean"&gt;6. 实例化spring bean&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我个人理解bean的元信息是Bean初始化时所需要的配置参数。&lt;/p&gt;</description></item><item><title>spring的配置信息</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF/</link><pubDate>Thu, 14 Apr 2022 20:03:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF/</guid><description>&lt;p&gt;spring的配置信息&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当bean注入BeanFactory和ApplicationContext，分析依赖对象的来源，是否是ioc容器内的Bean?&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>面向对象设计</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1/</link><pubDate>Thu, 14 Apr 2022 20:00:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1/</guid><description>&lt;p&gt;编写高质量代码的要素&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20220414185730919" loading="lazy" src="d:%5Cproject%5Cvscode%5Cblog%5Cblogs%5C%E6%AF%8F%E6%97%A5%E9%9A%8F%E7%AC%94%5C2022-04-14_note.assets%5Cimage-20220414185730919.png"&gt;&lt;/p&gt;
&lt;h2 id="谈面向对象"&gt;谈面向对象&lt;/h2&gt;
&lt;h3 id="什么是面向对象编程和面向对象编程语言"&gt;什么是面向对象编程和面向对象编程语言？&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;面向对象编程的英文缩写是 OOP，全称是 Object Oriented Programming。&lt;/p&gt;
&lt;p&gt;对应地，面向对象编程语言的英文缩写是 OOPL，全称是 Object Oriented Programming Language。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元，并将封装、抽象、继承、多态四个特性，作为代码设计和实现的基石 。&lt;/p&gt;</description></item><item><title>为什么学习设计模式</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AD%A6%E4%B9%A0%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><pubDate>Thu, 14 Apr 2022 19:58:38 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AD%A6%E4%B9%A0%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid><description>&lt;h1 id="为什么要学习设计模式"&gt;为什么要学习设计模式&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;应对面试中的设计模式相关问题&lt;/li&gt;
&lt;li&gt;告别写被人吐槽的烂代码&lt;/li&gt;
&lt;li&gt;提高复杂代码的设计和开发能力&lt;/li&gt;
&lt;li&gt;让读源码、学框架事半功倍&lt;/li&gt;
&lt;li&gt;为你的职场发展做铺垫&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;自己是为了第2，4点来学设计模式的&lt;/p&gt;</description></item><item><title>数组与切片</title><link>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%95%B0%E7%BB%84%E4%B8%8E%E5%88%87%E7%89%87/</link><pubDate>Wed, 06 Apr 2022 06:39:22 +0800</pubDate><guid>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%95%B0%E7%BB%84%E4%B8%8E%E5%88%87%E7%89%87/</guid><description>&lt;h1 id="数组与切片"&gt;数组与切片&lt;/h1&gt;
&lt;h2 id="数组"&gt;数组&lt;/h2&gt;
&lt;h3 id="初始化数组"&gt;初始化数组&lt;/h3&gt;
&lt;h4 id="申明长度"&gt;申明长度&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;{&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="不申明长度"&gt;不申明长度&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; [&lt;span style="color:#f92672"&gt;...&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;{&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="切片长度可变"&gt;切片（长度可变）&lt;/h2&gt;
&lt;h3 id="概念"&gt;概念&lt;/h3&gt;
&lt;h4 id="不储存数据只是对底层数组的描述切片是数组的引用"&gt;不储存数据，只是对底层数组的描述，切片是数组的引用&lt;/h4&gt;</description></item><item><title>流程控制语句</title><link>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6%E8%AF%AD%E5%8F%A5/</link><pubDate>Fri, 01 Apr 2022 07:02:03 +0800</pubDate><guid>https://www.ggball.top/notes/go%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%97%85/%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6%E8%AF%AD%E5%8F%A5/</guid><description>&lt;h1 id="go的流程控制语句"&gt;&lt;a href="https://studygolang.gitbook.io/learn-go-with-tests/"&gt;go的流程控制语句&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="for"&gt;for&lt;/h2&gt;
&lt;h3 id="简单for"&gt;简单for&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &amp;lt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="for-是-go-中的-while"&gt;for 是 Go 中的 “while”&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &amp;lt; &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="无限循环"&gt;无限循环&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="if"&gt;if&lt;/h2&gt;
&lt;h3 id="正常if"&gt;正常if&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &amp;lt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sqrt&lt;/span&gt;(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;i&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="简短if"&gt;简短if&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;--&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;同&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;一样&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;语句可以在条件表达式前执行一个简单的语句&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;math&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Pow&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt;); &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; &amp;lt; &lt;span style="color:#a6e22e"&gt;lim&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="switch默认每个case自带break"&gt;switch(默认每个case自带break)&lt;/h2&gt;
&lt;h3 id="有条件的"&gt;有条件的&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;today&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;Weekday&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;switch&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Saturday&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;today&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Today.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;today&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Tomorrow.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Too far away.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="无条件的"&gt;无条件的&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;switch&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Hour&lt;/span&gt;() &amp;lt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Good morning!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Hour&lt;/span&gt;() &amp;lt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Good afternoon.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Good evening.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="defer"&gt;defer&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;语句会将函数推迟到外层函数返回之后执行&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;有点像java的finally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;推迟的函数调用会被压入一个栈中&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;当外层函数返回时&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;被推迟的函数会按照后进先出的顺序调用&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>spring管理bean之间的协同方式</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/spring%E7%AE%A1%E7%90%86bean%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8D%8F%E5%90%8C%E6%96%B9%E5%BC%8F/</link><pubDate>Wed, 30 Mar 2022 17:06:46 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/spring%E7%AE%A1%E7%90%86bean%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8D%8F%E5%90%8C%E6%96%B9%E5%BC%8F/</guid><description>&lt;!-- raw HTML omitted --&gt;
&lt;h1 id="spring管理bean互相协同的方式"&gt;spring管理bean互相协同的方式&lt;/h1&gt;
&lt;h2 id="dependency-injection依赖注入"&gt;Dependency Injection（依赖注入）&lt;/h2&gt;
&lt;h3 id="constructor-based-dependency-injection构造方法注入"&gt;Constructor-based Dependency Injection（构造方法注入）&lt;/h3&gt;
&lt;h4 id="autowired注入"&gt;Autowired注入&lt;/h4&gt;
&lt;h4 id="xml配置"&gt;xml配置&lt;/h4&gt;
&lt;h3 id="setter-based-dependency-injectionset方法注入"&gt;Setter-based Dependency Injection（set方法注入）&lt;/h3&gt;
&lt;h4 id="autowired注入-1"&gt;Autowired注入&lt;/h4&gt;
&lt;h4 id="xml配置-1"&gt;xml配置&lt;/h4&gt;
&lt;h2 id="method-injection方法注入通过代理方式注入"&gt;Method Injection（方法注入，通过代理方式注入）&lt;/h2&gt;
&lt;h3 id="通过applcationcontext容器获取bean注入"&gt;通过applcationContext容器获取bean注入&lt;/h3&gt;
&lt;h3 id="lookup-method-injection通过lookup注解注入"&gt;Lookup Method Injection（通过@LookUp注解注入）&lt;/h3&gt;
&lt;h3 id="arbitrary-method-replacementxml配置replace-method"&gt;Arbitrary Method Replacement（xml配置replace method）&lt;/h3&gt;</description></item><item><title>MVCC并发管理控制</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mvcc%E5%B9%B6%E5%8F%91%E7%AE%A1%E7%90%86%E6%8E%A7%E5%88%B6/</link><pubDate>Tue, 29 Mar 2022 09:19:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mvcc%E5%B9%B6%E5%8F%91%E7%AE%A1%E7%90%86%E6%8E%A7%E5%88%B6/</guid><description>&lt;h1 id="mvcc并发管理控制"&gt;MVCC并发管理控制&lt;/h1&gt;
&lt;h2 id="并发带来的读写问题"&gt;并发带来的读写问题&lt;/h2&gt;
&lt;p&gt;因为mysql是cs结构，一台服务端可以对接多个客户端，那必然就会存在多个线程对同一资源（同一条记录之类的）进行&lt;strong&gt;读读，读写，写写&lt;/strong&gt;操作。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;脏写：一个事务修改了其他事务未提交的数据。&lt;!-- raw HTML omitted --&gt;
&lt;img alt="20220329195612" loading="lazy" src="https://img.ggball.top/picGo/20220329195612.png"&gt;&lt;/p&gt;</description></item><item><title>幂等性解决方案</title><link>https://www.ggball.top/notes/%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87/%E5%B9%82%E7%AD%89%E6%80%A7%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link><pubDate>Mon, 28 Mar 2022 14:39:22 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87/%E5%B9%82%E7%AD%89%E6%80%A7%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</guid><description>&lt;h2 id="一什么是幂等性"&gt;一、什么是幂等性&lt;/h2&gt;
&lt;p&gt;幂等是一个数学与计算机学概念，在数学中某一元运算为幂等时，&lt;strong&gt;其作用在任一元素两次后会和其作用一次的结果相同&lt;/strong&gt;。在计算机中编程中，一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂等方法是指可以使用相同参数重复执行，并能获得相同结果的函数。这些函数不会影响系统状态，也不用担心重复执行会对系统造成改变。&lt;/p&gt;</description></item><item><title>Bean的生命周期</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/bean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/</link><pubDate>Mon, 28 Mar 2022 09:07:33 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/bean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/</guid><description>&lt;p&gt;Bean的生命周期的完全实现需要两个阶段&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;容器的启动&lt;/li&gt;
&lt;li&gt;bean的实例化过程（涵盖了bean生命周期的大部分）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="容器的完全实现" loading="lazy" src="https://img.ggball.top/picGo/image-20220328091203748.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="bean实例化过程" loading="lazy" src="https://img.ggball.top/picGo/20230225164339.png"&gt;&lt;/p&gt;
&lt;h2 id="容器启动阶段"&gt;容器启动阶段&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;重点是收集到元信息配置信息，即创建bean需要的信息（beanDefinition）
通过&lt;code&gt;BeanDefinitionReader&lt;/code&gt;,读取到&lt;code&gt;beanDefinition&lt;/code&gt;信息，再通过&lt;code&gt;beanDefinitionRegistry&lt;/code&gt;,将BeanDefinition注册到其里面&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 这是 PropertiesBeanDefinitionReader 把从properties文件读取到的配置信息，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 通过 BeanDefinitionRegistry 注册 BeanDefinition的过程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AbstractBeanDefinition bd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; BeanDefinitionReaderUtils.&lt;span style="color:#a6e22e"&gt;createBeanDefinition&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parent, className, getBeanClassLoader());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bd.&lt;span style="color:#a6e22e"&gt;setScope&lt;/span&gt;(scope); &lt;span style="color:#75715e"&gt;// 作用域 默认singleton&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bd.&lt;span style="color:#a6e22e"&gt;setAbstract&lt;/span&gt;(isAbstract); &lt;span style="color:#75715e"&gt;// 是否是抽象 默认false 如果是抽象的，容器不会实例化bean，而是将beanDefinition信息作为其子类使用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bd.&lt;span style="color:#a6e22e"&gt;setLazyInit&lt;/span&gt;(lazyInit); &lt;span style="color:#75715e"&gt;// 懒加载 默认false 如果是false,容器一启动就会加载bean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bd.&lt;span style="color:#a6e22e"&gt;setConstructorArgumentValues&lt;/span&gt;(cas); &lt;span style="color:#75715e"&gt;// 构造参数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bd.&lt;span style="color:#a6e22e"&gt;setPropertyValues&lt;/span&gt;(pvs); &lt;span style="color:#75715e"&gt;// 属性信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; getRegistry().&lt;span style="color:#a6e22e"&gt;registerBeanDefinition&lt;/span&gt;(beanName, bd); &lt;span style="color:#75715e"&gt;// 注册Beandefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;BeanDefinitionReader 有多种,包括:&lt;/p&gt;</description></item><item><title>设计模式概览</title><link>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%A7%88/</link><pubDate>Thu, 17 Mar 2022 13:35:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%AE%97%E6%B3%95%E4%B8%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%A7%88/</guid><description>&lt;p&gt;&lt;strong&gt;简单工厂&lt;/strong&gt;
实际不能算作一种设计模式，它引入了创建者的概念，将实例化的代码从应用代码中抽离，在创建者类的静态方法中只处理创建对象的细节，后续创建的实例如需改变，只需改造创建者类即可，&lt;/p&gt;</description></item><item><title>mysql主从复制</title><link>https://www.ggball.top/posts/%E9%83%A8%E7%BD%B2/mysql/mysql%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/</link><pubDate>Wed, 16 Mar 2022 20:25:42 +0800</pubDate><guid>https://www.ggball.top/posts/%E9%83%A8%E7%BD%B2/mysql/mysql%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/</guid><description>&lt;h3 id="1创建用户"&gt;（1）创建用户&lt;/h3&gt;
&lt;p&gt;启动主MySQL服务器，登入主MySQL客户端，在主服务器上创建复制数据的账号并授权：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;#&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;登录主&lt;/span&gt;mysql客户端
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; mysql &lt;span style="color:#f92672"&gt;-&lt;/span&gt;S &lt;span style="color:#f92672"&gt;/&lt;/span&gt;opt&lt;span style="color:#f92672"&gt;/&lt;/span&gt;software&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3306&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;tmp&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql_3306.sock &lt;span style="color:#f92672"&gt;-&lt;/span&gt;p
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;grant&lt;/span&gt; replication slave &lt;span style="color:#66d9ef"&gt;on&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;to&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;slave&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt; identified &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;mysql@123&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;创建一个MySQL用户，该用户是主服务器专门给从服务器拷贝数据用的&lt;/p&gt;</description></item><item><title>一台linux服务器安装多个mysql服务</title><link>https://www.ggball.top/posts/%E9%83%A8%E7%BD%B2/mysql/%E4%B8%80%E5%8F%B0linux%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%89%E8%A3%85%E5%A4%9A%E4%B8%AAmysql%E6%9C%8D%E5%8A%A1/</link><pubDate>Wed, 16 Mar 2022 20:22:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E9%83%A8%E7%BD%B2/mysql/%E4%B8%80%E5%8F%B0linux%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%89%E8%A3%85%E5%A4%9A%E4%B8%AAmysql%E6%9C%8D%E5%8A%A1/</guid><description>&lt;p&gt;&lt;strong&gt;实验环境&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;操作系统 ：CentOS Linux release 7.9.2009 (Core)&lt;/p&gt;
&lt;p&gt;数据库版本：5.7.36-log&lt;/p&gt;
&lt;p&gt;预计划安装3个MySQL实例，规划信息为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;实例一&lt;/th&gt;
&lt;th style="text-align: left"&gt;实例二&lt;/th&gt;
&lt;th&gt;实例三&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;port=3306&lt;!-- raw HTML omitted --&gt;socket=/opt/software/mysql/3306/tmp/mysql_3306.sock&lt;!-- raw HTML omitted --&gt;datadir=/opt/software/mysql/3306/data&lt;!-- raw HTML omitted --&gt;log-error =/opt/software/mysql/3306/error_3306.log&lt;!-- raw HTML omitted --&gt;pid-file=/opt/software/mysql/3306/mysql.pid&lt;/td&gt;
&lt;td style="text-align: left"&gt;port=3307&lt;!-- raw HTML omitted --&gt;socket=/opt/software/mysql/3307/tmp/mysql_3307.sock&lt;!-- raw HTML omitted --&gt;datadir=/opt/software/mysql/3307/data&lt;!-- raw HTML omitted --&gt;log-error =/opt/software/mysql/3307/error_3307.log&lt;!-- raw HTML omitted --&gt;pid-file=/opt/software/mysql/3307/mysql.pid&lt;/td&gt;
&lt;td&gt;port=3308&lt;!-- raw HTML omitted --&gt;socket=/opt/software/mysql/3308/tmp/mysql_3308.sock&lt;!-- raw HTML omitted --&gt;datadir=/opt/software/mysql/3308/data&lt;!-- raw HTML omitted --&gt;log-error =/opt/software/mysql/3308/error_3308.log&lt;!-- raw HTML omitted --&gt;pid-file=/opt/software/mysql/3308/mysql.pid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href="https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.36-linux-glibc2.12-x86_64.tar"&gt;解压包地址&lt;/a&gt;&lt;/p&gt;</description></item><item><title>redo日志（下）</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/redo%E6%97%A5%E5%BF%97%E4%B8%8B/</link><pubDate>Fri, 04 Mar 2022 09:11:24 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/redo%E6%97%A5%E5%BF%97%E4%B8%8B/</guid><description>&lt;h2 id="redo-log的刷盘时机"&gt;redo log的刷盘时机&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;log buffer 空间不足时（大概一半左右）&lt;/li&gt;
&lt;li&gt;事务提交时&lt;/li&gt;
&lt;li&gt;后台线程不停的刷刷刷（大概每秒刷一次）&lt;/li&gt;
&lt;li&gt;正常关闭服务器时&lt;/li&gt;
&lt;li&gt;做所谓的 checkpoint&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="redo日志文件组"&gt;redo日志文件组&lt;/h2&gt;
&lt;p&gt;磁盘上的 redo 日志文件不只一个，而是以一个 日志文件组 的形式出现的&lt;/p&gt;</description></item><item><title>redo日志（上）</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/redo%E6%97%A5%E5%BF%97%E4%B8%8A/</link><pubDate>Fri, 04 Mar 2022 09:04:55 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/redo%E6%97%A5%E5%BF%97%E4%B8%8A/</guid><description>&lt;h2 id="redo日志"&gt;redo日志&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;背景：&lt;/strong&gt; 因为事务提交后，数据不会立刻刷入磁盘（1.刷新一个完整的数据页太浪费了2.随机IO刷起来比较慢），而是在合适的时机刷入磁盘，但是为了不让宕机等因素将缓存数据清空，所以需要记录一份事务提交的数据，方便以后还原。&lt;/p&gt;</description></item><item><title>mysql思维导图</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/</link><pubDate>Sun, 27 Feb 2022 16:20:58 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/</guid><description>&lt;!-- raw HTML omitted --&gt;
&lt;h1 id="mysql"&gt;mysql&lt;/h1&gt;
&lt;h2 id="1-基础知识"&gt;1. 基础知识&lt;/h2&gt;
&lt;h3 id="1-cs架构"&gt;1. cs架构&lt;/h3&gt;
&lt;h3 id="2-安装与启动"&gt;2. 安装与启动&lt;/h3&gt;
&lt;h3 id="3-连接过程"&gt;3. 连接过程&lt;/h3&gt;
&lt;h4 id="1-客户端发起连接3种tcp命名通道与共享内存socket"&gt;1. 客户端发起连接（3种，tcp,命名通道与共享内存，socket）&lt;/h4&gt;
&lt;h4 id="2-服务端接受连接"&gt;2. &lt;a href="https://img.ggball.top/picGo/image-20220208173328925.png"&gt;服务端接受连接&lt;/a&gt;&lt;/h4&gt;
&lt;h5 id="1-处理连接"&gt;1. 处理连接&lt;/h5&gt;
&lt;h5 id="2-解析与优化1查询缓存2语法解析3查询优化"&gt;2. 解析与优化（1.查询缓存，2.语法解析，3.查询优化）&lt;/h5&gt;
&lt;h5 id="3-存储引擎"&gt;3. 存储引擎&lt;/h5&gt;
&lt;h3 id="4-常用引擎"&gt;4. 常用引擎&lt;/h3&gt;
&lt;h4 id="1-innodb"&gt;1. InnoDB&lt;/h4&gt;
&lt;h4 id="2-myisam"&gt;2. MyISAM&lt;/h4&gt;
&lt;h2 id="2-启动选项与变量"&gt;2. 启动选项与变量&lt;/h2&gt;
&lt;h3 id="1-设置mysql启动参数就近原则"&gt;1. 设置mysql启动参数（就近原则）&lt;/h3&gt;
&lt;h4 id="1-命令行和配置文件"&gt;1. 命令行和配置文件&lt;/h4&gt;
&lt;h4 id="2-配置文件"&gt;2. 配置文件&lt;/h4&gt;
&lt;h3 id="1-系统变量"&gt;1. 系统变量&lt;/h3&gt;
&lt;h3 id="2-状态变量"&gt;2. 状态变量&lt;/h3&gt;
&lt;h2 id="3-字符串比较规则"&gt;3. 字符串比较规则&lt;/h2&gt;
&lt;h3 id="1-什么是字符集"&gt;1. 什么是字符集&lt;/h3&gt;
&lt;h4 id="使用二进制的一组数据代表现实世界的字符串"&gt;使用二进制的一组数据代表现实世界的字符串。&lt;/h4&gt;
&lt;h4 id="常用字符集-gbk最多2字节uft8最多3字节utf8mb4最多4字节"&gt;常用字符集 GBK(最多2字节),uft8（最多3字节）,utf8mb4（最多4字节）&lt;/h4&gt;
&lt;h3 id="2-字符集比较规则"&gt;2. 字符集比较规则&lt;/h3&gt;
&lt;h4 id="用来比较同一种字符集的字符大小"&gt;用来比较同一种字符集的字符大小&lt;/h4&gt;
&lt;h3 id="3-字符集应用"&gt;3. 字符集应用&lt;/h3&gt;
&lt;h4 id="注意对于同一个字符串如果编码和解码采用的不同字符集那么结果可能会不同"&gt;注意：对于同一个字符串，如果编码和解码采用的不同字符集，那么结果可能会不同。&lt;/h4&gt;
&lt;h3 id="4-四个级别的字符集和比较规则"&gt;4. 四个级别的字符集和比较规则&lt;/h3&gt;
&lt;h4 id="服务器级别"&gt;服务器级别&lt;/h4&gt;
&lt;h4 id="数据库级别"&gt;数据库级别&lt;/h4&gt;
&lt;h4 id="表级别"&gt;表级别&lt;/h4&gt;
&lt;h4 id="列级别"&gt;列级别&lt;/h4&gt;
&lt;h2 id="4-innodb记录结构"&gt;4. InnoDB记录结构&lt;/h2&gt;
&lt;h3 id="1-innodb页简介"&gt;1. InnoDB页简介&lt;/h3&gt;
&lt;h4 id="磁盘和内存数据交互的最小单位一页16kb"&gt;磁盘和内存数据交互的最小单位，一页=16kb。&lt;/h4&gt;
&lt;h3 id="2-innodb行格式"&gt;2. InnoDB行格式&lt;/h3&gt;
&lt;h4 id="1-简介"&gt;1. 简介&lt;/h4&gt;
&lt;h5 id="记录存放在磁盘上的方式成为行格式"&gt;记录存放在磁盘上的方式成为&lt;code&gt;行格式&lt;/code&gt;&lt;/h5&gt;
&lt;h3 id="3-行格式分类"&gt;3. 行格式分类&lt;/h3&gt;
&lt;h4 id="1-compact类型行格式"&gt;1. compact类型行格式&lt;/h4&gt;
&lt;h5 id="1-组成"&gt;1. &lt;a href="https://img.ggball.top/picGo/image-20220211144936545.png"&gt;组成&lt;/a&gt;&lt;/h5&gt;
&lt;h6 id="额外信息变长字段长度列表null值列表记录头信息"&gt;额外信息（变长字段长度列表，null值列表，记录头信息）&lt;/h6&gt;
&lt;h6 id="真实数据"&gt;真实数据&lt;/h6&gt;
&lt;h4 id="2-redundant行格式"&gt;2. redundant行格式&lt;/h4&gt;
&lt;h4 id="3-dynamic行格式"&gt;3. Dynamic行格式&lt;/h4&gt;
&lt;h5 id="这两种行格式类似于-compact行格式-只不过在处理行溢出数据时有点儿分歧它们不会在记录的真实数据处存储字符串的前768个字节而是把所有的字节都存储到其他页面中只在记录的真实数据处存储其他页面的地址"&gt;这两种行格式类似于 COMPACT行格式 ，只不过在处理行溢出数据时有点儿分歧，它们不会在记录的真实数据处存储字符串的前768个字节，而是把所有的字节都存储到其他页面中，只在记录的真实数据处存储其他页面的地址。&lt;/h5&gt;
&lt;h4 id="3-compressed行格式"&gt;3. Compressed行格式&lt;/h4&gt;
&lt;h5 id="compressed-行格式会采用压缩算法对页面进行压缩"&gt;Compressed 行格式会采用压缩算法对页面进行压缩。&lt;/h5&gt;
&lt;h3 id="4-行溢出"&gt;4. 行溢出&lt;/h3&gt;
&lt;h4 id="1-什么是行溢出"&gt;1. 什么是行溢出&lt;/h4&gt;
&lt;h5 id="当一页的容量满了这是如果记录的数据仍然存不下记录的真实数据的溢出部分会存在另外的页中此时记录的真实数据会腾出20个字节存放剩余数据在其他页的地址"&gt;当一页的容量满了，这是如果记录的数据仍然存不下，记录的真实数据的溢出部分会存在另外的页中，此时记录的真实数据会腾出20个字节存放剩余数据在其他页的地址。&lt;/h5&gt;
&lt;h4 id="2-行溢出的临界值"&gt;2. 行溢出的临界值&lt;/h4&gt;
&lt;h5 id="记住一页最大容量16348byte"&gt;记住一页最大容量=16348byte&lt;/h5&gt;
&lt;h2 id="5-innodb数据页结构"&gt;5. InnoDB数据页结构&lt;/h2&gt;
&lt;h4 id="1-概念存储数据的页"&gt;1. 概念：存储数据的页&lt;/h4&gt;
&lt;h4 id="2-数据页结构"&gt;2. &lt;a href="https://img.ggball.top/picGo/image-20220213170828841.png"&gt;数据页结构&lt;/a&gt;&lt;/h4&gt;
&lt;h5 id="1-file-header-表示页的一些通用信息占固定的38字节"&gt;1. File Header 表示页的一些通用信息，占固定的38字节。&lt;/h5&gt;
&lt;h5 id="2-page-header-表示数据页专有的一些信息占固定的56个字节"&gt;2. Page Header 表示数据页专有的一些信息，占固定的56个字节。&lt;/h5&gt;
&lt;h5 id="3-infimum--supremum-两个虚拟的伪记录分别表示页中的最小和最大记录占固定的-26-个字节"&gt;3. Infimum + Supremum 两个虚拟的伪记录，分别表示页中的最小和最大记录，占固定的 26 个字节。&lt;/h5&gt;
&lt;h5 id="4-user-records-真实存储我们插入的记录的部分大小不固定"&gt;4. User Records 真实存储我们插入的记录的部分，大小不固定。&lt;/h5&gt;
&lt;h5 id="5-free-space-页中尚未使用的部分大小不确定"&gt;5. Free Space 页中尚未使用的部分，大小不确定。&lt;/h5&gt;
&lt;h5 id="6-page-directory-将一页里面的记录分为多组记录每组最大记录的物理地址和主键这个称为槽页目录就是由槽组成"&gt;6. &lt;a href="https://img.ggball.top/picGo/image-20220213184021833.png"&gt;Page Directory&lt;/a&gt; 将一页里面的记录分为多组，记录每组最大记录的物理地址和主键，这个称为&lt;code&gt;槽&lt;/code&gt;，页目录就是由&lt;code&gt;槽&lt;/code&gt;组成。&lt;/h5&gt;
&lt;h5 id="7-file-trailer-用于检验页是否完整的部分占用固定的8个字节"&gt;7. File Trailer 用于检验页是否完整的部分，占用固定的8个字节。&lt;/h5&gt;
&lt;h4 id="3-记录在数据页的数据结构"&gt;3. 记录在数据页的数据结构&lt;/h4&gt;
&lt;h5 id="每个记录的头信息中都有一个-next_record-属性从而使页中的所有记录串联成一个-单链表-"&gt;每个记录的头信息中都有一个 next_record 属性，从而使页中的所有记录串联成一个 单链表 。&lt;/h5&gt;
&lt;h4 id="4-根据主键在页中查找过程"&gt;4. 根据主键在页中查找过程&lt;/h4&gt;
&lt;h5 id="1-利用二分法查找槽"&gt;1. 利用二分法查找槽&lt;/h5&gt;
&lt;h5 id="2-通过记录的记录头信息中的next_record依次寻找主键相同的记录"&gt;2. 通过记录的&lt;code&gt;记录头信息&lt;/code&gt;中的next_record,依次寻找主键相同的记录。&lt;/h5&gt;
&lt;h4 id="5-页与页之间的数据结构"&gt;5. 页与页之间的数据结构&lt;/h4&gt;
&lt;h5 id="利用file-header的-前指针和后指针形成双向链表"&gt;利用File Header的 前指针和后指针形成双向链表。&lt;/h5&gt;
&lt;h2 id="6-mysql索引"&gt;6. mysql索引&lt;/h2&gt;
&lt;h3 id="1-innodb索引方案"&gt;1. InnoDB索引方案&lt;/h3&gt;
&lt;h4 id="1-页分裂"&gt;1. 页分裂&lt;/h4&gt;
&lt;h4 id="1-前提条件下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值"&gt;1. 前提条件：&lt;strong&gt;下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。&lt;/strong&gt;&lt;/h4&gt;
&lt;h4 id="2-索引-给数据页做目录"&gt;2. 索引 （给数据页做目录）&lt;/h4&gt;
&lt;h5 id="1-目录页"&gt;1. 目录页&lt;/h5&gt;
&lt;h5 id="2-目录项记录"&gt;2. 目录项记录&lt;/h5&gt;
&lt;h5 id="3-b数据结构"&gt;3. B+数据结构&lt;/h5&gt;
&lt;h4 id="3-索引类型"&gt;3. 索引类型&lt;/h4&gt;
&lt;h5 id="1-聚簇索引"&gt;1. 聚簇索引&lt;/h5&gt;
&lt;h5 id="2-二级索引"&gt;2. 二级索引&lt;/h5&gt;
&lt;h5 id="3-联合索引"&gt;3. 联合索引&lt;/h5&gt;
&lt;h3 id="2-myisam索引方案"&gt;2. MyISAM索引方案&lt;/h3&gt;
&lt;h4 id="和innodb索引区别myisam的索引的子节点不存数据只存数据的行号和索引列而innodb索引的子节点是保存了索引列和主键如果是聚簇索引保存整行数据和主键"&gt;和InnoDB索引区别：MyISAM的索引的子节点不存数据，只存数据的&lt;code&gt;行号和索引列&lt;/code&gt;，而InnoDB索引的子节点是保存了索引列和主键（如果是聚簇索引保存整行数据和主键）&lt;/h4&gt;
&lt;h2 id="7-mysql日志"&gt;7. mysql日志&lt;/h2&gt;
&lt;h2 id="8-mysql锁"&gt;8. mysql锁&lt;/h2&gt;</description></item><item><title>mysql之事务</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8B%E4%BA%8B%E5%8A%A1/</link><pubDate>Fri, 25 Feb 2022 09:13:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8B%E4%BA%8B%E5%8A%A1/</guid><description>&lt;h2 id="事务"&gt;事务&lt;/h2&gt;
&lt;p&gt;需要保证 原子性 、 隔离性 、 一致性 和 持久性 的一个或多个数据库操作称之为一个 事务&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原子性（Atomicity）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一致性（Consistency）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;​ 保证一致性的努力：&lt;/p&gt;</description></item><item><title>mysql之InnoDB的BufferPool</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Binnodb%E7%9A%84bufferpool/</link><pubDate>Thu, 24 Feb 2022 09:01:19 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Binnodb%E7%9A%84bufferpool/</guid><description>&lt;h1 id="innodb的bufferpool"&gt;InnoDB的BufferPool&lt;/h1&gt;
&lt;h2 id="为什么需要缓存"&gt;为什么需要缓存？&lt;/h2&gt;
&lt;p&gt;因为存储引擎需要访问某一条记录时，是通过页作为基本单位读取到内存的，但是如果每次就因为一两条数据而把一页的数据从磁盘读取到内存有点耗费性能了，这样就多了&lt;code&gt;缓存&lt;/code&gt;的概念，在进行完读写访问之后并不着急把该页对应的内存空间释放掉，而是将其 &lt;code&gt;缓存 &lt;/code&gt;起来，这样将来有请求再次访问该页面时，就可以省去磁盘 IO 的开销了。&lt;/p&gt;</description></item><item><title>EXPLAIN 语句输出的各个列解释</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/explain-%E8%AF%AD%E5%8F%A5%E8%BE%93%E5%87%BA%E7%9A%84%E5%90%84%E4%B8%AA%E5%88%97%E8%A7%A3%E9%87%8A/</link><pubDate>Wed, 23 Feb 2022 09:14:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/explain-%E8%AF%AD%E5%8F%A5%E8%BE%93%E5%87%BA%E7%9A%84%E5%90%84%E4%B8%AA%E5%88%97%E8%A7%A3%E9%87%8A/</guid><description>&lt;h1 id="explain-语句输出的各个列解释"&gt;EXPLAIN 语句输出的各个列解释&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;列名&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;在一个大的查询语句中每个 SELECT 关键字都对应一个唯一的 id&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select_type&lt;/td&gt;
&lt;td&gt;SELECT 关键字对应的那个查询的类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;table&lt;/td&gt;
&lt;td&gt;表名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;partitions&lt;/td&gt;
&lt;td&gt;匹配的分区信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;针对单表的访问方法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;possible_keys&lt;/td&gt;
&lt;td&gt;可能用到的索引&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;key&lt;/td&gt;
&lt;td&gt;实际上使用的索引&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;key_len&lt;/td&gt;
&lt;td&gt;实际使用到的索引长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ref&lt;/td&gt;
&lt;td&gt;当使用索引列等值查询时，与索引列进行等值匹配的对象信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rows&lt;/td&gt;
&lt;td&gt;预估的需要读取的记录条数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;filtered&lt;/td&gt;
&lt;td&gt;某个表经过搜索条件过滤后剩余记录条数的百分比&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extra&lt;/td&gt;
&lt;td&gt;一些额外的信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="select_type"&gt;select_type&lt;/h2&gt;
&lt;p&gt;每一个 SELECT 关键字代表的小查询都定义了一个称之为 select_type 的属性，意思是我们
只要知道了某个小查询的 &lt;code&gt;select_type&lt;/code&gt; 属性，就知道了这个小查询在整个大查询中扮演了一个什么角色&lt;/p&gt;</description></item><item><title>explain之访问方法</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/explain%E4%B9%8B%E8%AE%BF%E9%97%AE%E6%96%B9%E6%B3%95/</link><pubDate>Tue, 22 Feb 2022 09:30:10 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/explain%E4%B9%8B%E8%AE%BF%E9%97%AE%E6%96%B9%E6%B3%95/</guid><description>&lt;blockquote&gt;
&lt;p&gt;MySQL 执行查询语句的方式称之为 &lt;code&gt;访问方法&lt;/code&gt; 或者 &lt;code&gt;访问类型&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="访问方法"&gt;访问方法&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;const&lt;/strong&gt;：通&lt;strong&gt;过主键或者唯一二级索引列与常数的等值&lt;/strong&gt;比较来&lt;strong&gt;定位一条记录&lt;/strong&gt;。意思是常数级别的，代价是可以忽略不计的。不过这种 const 访问方法只能在主键&lt;/p&gt;</description></item><item><title>mysql之InnoDB数据目录结构</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Binnodb%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84/</link><pubDate>Mon, 21 Feb 2022 09:07:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Binnodb%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84/</guid><description>&lt;h2 id="innodb数据目录"&gt;innoDB数据目录&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;表目录&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;表名.frm文件（描述表结构的文件）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;.表名ibd文件（表数据和索引文件）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;视图名.frm文件（描述视图）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mylsam数据目录"&gt;mylSAM数据目录&lt;/h2&gt;
&lt;p&gt;表数据都存放到对应的数据库子目录下。假如 test 表使用 MyISAM 存储引擎的话，那么在它所在数据库对应的 xiaohaizi 目录下会为 test 表创建这三个文件：&lt;/p&gt;</description></item><item><title>多线程下的事务数据问题</title><link>https://www.ggball.top/notes/%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%8B%E7%9A%84%E4%BA%8B%E5%8A%A1%E6%95%B0%E6%8D%AE%E9%97%AE%E9%A2%98/</link><pubDate>Fri, 18 Feb 2022 00:33:22 +0800</pubDate><guid>https://www.ggball.top/notes/%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%8B%E7%9A%84%E4%BA%8B%E5%8A%A1%E6%95%B0%E6%8D%AE%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;前几天遇到的线上问题，防止以后犯这样的错误，特别写下来记录下!:s&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;现场问题：一个业务流程的接口，包含五个左右的操作步骤（a,b,c,d,e，每个步骤都是原子性）,第三方调用这个接口，其中有两次请求(两次请求间隔几十毫秒)，A请求没问题，B请求的d步骤没有执行！&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>B+树索引的由来</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/b-%E6%A0%91%E7%B4%A2%E5%BC%95%E7%9A%84%E7%94%B1%E6%9D%A5/</link><pubDate>Tue, 15 Feb 2022 00:52:09 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/b-%E6%A0%91%E7%B4%A2%E5%BC%95%E7%9A%84%E7%94%B1%E6%9D%A5/</guid><description>&lt;h1 id="b树索引的由来"&gt;B+树索引的由来&lt;/h1&gt;
&lt;p&gt;从前面讲的InnoDB数据页结构，特别是&lt;code&gt;页目录&lt;/code&gt;，我们可以了解到，&lt;code&gt;记录&lt;/code&gt;在&lt;code&gt;页&lt;/code&gt;里面是以单链表的形式存在，而页与页之间构成了双向链表。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20220215000137133" loading="lazy" src="https://img.ggball.top/picGo/image-20220215000137133.png"&gt;&lt;/p&gt;
&lt;p&gt;那么我们应该采取什么样的方式来更高效查询数据呢？&lt;/p&gt;</description></item><item><title>InnoDB数据页结构</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/innodb%E6%95%B0%E6%8D%AE%E9%A1%B5%E7%BB%93%E6%9E%84/</link><pubDate>Sun, 13 Feb 2022 18:50:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/innodb%E6%95%B0%E6%8D%AE%E9%A1%B5%E7%BB%93%E6%9E%84/</guid><description>&lt;h1 id="innodb数据页结构"&gt;InnoDB数据页结构&lt;/h1&gt;
&lt;h2 id="不同类型页"&gt;不同类型页&lt;/h2&gt;
&lt;p&gt;InnoDB存储引擎为了出于不同的存储目的设计多种类型的页，比如&lt;/p&gt;
&lt;p&gt;存放表空间头部信息的页，存放 Insert Buffer信息的页，存放 INODE 信息的页，存放 undo 日志信息的页等等等等&lt;/p&gt;</description></item><item><title>InnoDB记录结构</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/innodb%E8%AE%B0%E5%BD%95%E7%BB%93%E6%9E%84/</link><pubDate>Sat, 12 Feb 2022 17:23:24 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/innodb%E8%AE%B0%E5%BD%95%E7%BB%93%E6%9E%84/</guid><description>&lt;h1 id="innodb记录结构"&gt;InnoDB记录结构&lt;/h1&gt;
&lt;h2 id="innodb存储引擎介绍"&gt;innoDB存储引擎介绍&lt;/h2&gt;
&lt;p&gt;存储引擎的作用就是内存和磁盘打交道，负责将数据在他两之间传输，为了提高传输效率，提出了“页”的概念，也就是在一般情况下，为了减少io次数，一次最少从磁盘中读取16KB的内容到内存中，一次最少把内存中的16KB内容刷新到磁盘中。&lt;/p&gt;</description></item><item><title>字符集和比较规则</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E5%AD%97%E7%AC%A6%E9%9B%86%E5%92%8C%E6%AF%94%E8%BE%83%E8%A7%84%E5%88%99/</link><pubDate>Thu, 10 Feb 2022 21:29:29 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E5%AD%97%E7%AC%A6%E9%9B%86%E5%92%8C%E6%AF%94%E8%BE%83%E8%A7%84%E5%88%99/</guid><description>&lt;h1 id="字符集和比较规则"&gt;字符集和比较规则&lt;/h1&gt;
&lt;h2 id="字符集简介"&gt;字符集简介&lt;/h2&gt;
&lt;p&gt;作用：为了让数据在人和计算机都能被”看的懂“。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们知道在计算机中只能存储二进制数据，那该怎么存储字符串呢？当然是建立字符与二进制数据的映射关系了，建立这个关系最起码要搞清楚两件事儿：&lt;/p&gt;</description></item><item><title>mysql系统配置与启动选项</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E4%B8%8E%E5%90%AF%E5%8A%A8%E9%80%89%E9%A1%B9/</link><pubDate>Thu, 10 Feb 2022 21:18:21 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E4%B8%8E%E5%90%AF%E5%8A%A8%E9%80%89%E9%A1%B9/</guid><description>&lt;h1 id="启动选项与系统变量"&gt;启动选项与系统变量&lt;/h1&gt;
&lt;h2 id="启动选项"&gt;启动选项&lt;/h2&gt;
&lt;h3 id="长格式与短格式"&gt;长格式与短格式&lt;/h3&gt;
&lt;p&gt;在执行启动脚本时，后面可以跟启动选项，其中有长格式和短格式两种形式&lt;/p&gt;
&lt;p&gt;​ 短格式：选项名前只加一个短划线 -&lt;/p&gt;
&lt;p&gt;​ 长格式：选项名前加两个短划线 &amp;ndash;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20220210210832550" loading="lazy" src="https://img.ggball.top/picGo/image-20220210210832550.png"&gt;&lt;/p&gt;
&lt;h2 id="配置选项"&gt;配置选项&lt;/h2&gt;
&lt;h3 id="内容格式"&gt;内容格式&lt;/h3&gt;
&lt;p&gt;与在命令行中指定启动选项不同的是，配置文件中的启动选项被划分为若干个组，每个组有一个组名，用中括号[] 扩起来，像这样：&lt;/p&gt;</description></item><item><title>reactor模型了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/reactor%E6%A8%A1%E5%9E%8B%E4%BA%86%E8%A7%A3/</link><pubDate>Thu, 10 Feb 2022 10:04:01 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/reactor%E6%A8%A1%E5%9E%8B%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="reactor模型"&gt;reactor模型&lt;/h1&gt;
&lt;p&gt;特点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;事件驱动&lt;/li&gt;
&lt;li&gt;可以处理一个或多个输入源&lt;/li&gt;
&lt;li&gt;通过多路复用将请求的事件分发给对应的处理器处理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;根据大神Doug Lea 在 《Scalable IO in Java 》中的介绍，Reacotr模型主要分为三个角色&lt;/p&gt;</description></item><item><title>netty利用websocket协议开发服务端</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/netty%E5%88%A9%E7%94%A8websocket%E5%8D%8F%E8%AE%AE%E5%BC%80%E5%8F%91%E6%9C%8D%E5%8A%A1%E7%AB%AF/</link><pubDate>Wed, 09 Feb 2022 17:53:11 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/netty%E5%88%A9%E7%94%A8websocket%E5%8D%8F%E8%AE%AE%E5%BC%80%E5%8F%91%E6%9C%8D%E5%8A%A1%E7%AB%AF/</guid><description>&lt;h2 id="介绍websocket协议"&gt;介绍websocket协议&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通信的网络技术，WebSocket通信协议于2011年被IETF定为&lt;/p&gt;
&lt;p&gt;标准RFC6455，WebSocket API被W3C定为标准。&lt;/p&gt;</description></item><item><title>重新认识mysql</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E9%87%8D%E6%96%B0%E8%AE%A4%E8%AF%86mysql/</link><pubDate>Wed, 09 Feb 2022 13:19:10 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E9%87%8D%E6%96%B0%E8%AE%A4%E8%AF%86mysql/</guid><description>&lt;h2 id="mysql-的客户端和服务端结构"&gt;mysql 的客户端和服务端结构&lt;/h2&gt;
&lt;p&gt;客户端负责接收用户的命令，并且发送给服务端&lt;/p&gt;
&lt;p&gt;服务端负责接收客户端的命令，并进行处理，返回给客户端&lt;/p&gt;
&lt;h2 id="bin目录下的可执行文件"&gt;bin目录下的可执行文件&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20220208163519036" loading="lazy" src="https://img.ggball.top/picGo/image-20220208163519036.png"&gt;&lt;/p&gt;
&lt;h2 id="unix环境下启动mysql-server"&gt;unix环境下启动mysql server&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;mysqld&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;mysqld 这个可执行文件就代表着 MySQL 服务器程序，运行这个可执行文件就可以&lt;strong&gt;直接启动一个服务器进程&lt;/strong&gt;。但这个命令不常用，我们继续往下看更牛逼的启动命令。&lt;/p&gt;</description></item><item><title>使用netty作为http文件服务</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/%E4%BD%BF%E7%94%A8netty%E4%BD%9C%E4%B8%BAhttp%E6%96%87%E4%BB%B6%E6%9C%8D%E5%8A%A1/</link><pubDate>Tue, 08 Feb 2022 16:16:52 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/%E4%BD%BF%E7%94%A8netty%E4%BD%9C%E4%B8%BAhttp%E6%96%87%E4%BB%B6%E6%9C%8D%E5%8A%A1/</guid><description>&lt;p&gt;代码&lt;/p&gt;
&lt;p&gt;HttpFileServer&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; http;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; echo.server.EchoServer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.bootstrap.ServerBootstrap;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.ChannelFuture;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.ChannelInitializer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.EventLoopGroup;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.nio.NioEventLoopGroup;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.socket.SocketChannel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.socket.nio.NioServerSocketChannel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.channel.socket.nio.NioSocketChannel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.handler.codec.http.*;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; io.netty.handler.stream.ChunkedWriteHandler;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @author ggBall
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @version 1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @ClassName HttpFileServer.java
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description TODO
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @createTime 2022年02月08日 09:41:00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HttpFileServer&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; String default_url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/src/main/java/http/file/netty/&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; port , &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; String url) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; InterruptedException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EventLoopGroup boss &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; NioEventLoopGroup();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EventLoopGroup worker &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; NioEventLoopGroup();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ServerBootstrap bootstrap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ServerBootstrap();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bootstrap.&lt;span style="color:#a6e22e"&gt;group&lt;/span&gt;(boss,worker)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;channel&lt;/span&gt;(NioServerSocketChannel.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;childHandler&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ChannelInitializer&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;SocketChannel&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * This method will be called once the {@link Channel} was registered. After the method returns this instance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * will be removed from the {@link ChannelPipeline} of the {@link Channel}.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param ch the {@link Channel} which was registered.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @throws Exception is thrown if an error occurs. In that case the {@link Channel} will be closed.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initChannel&lt;/span&gt;(SocketChannel ch) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ch.&lt;span style="color:#a6e22e"&gt;pipeline&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http-decoder&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpRequestDecoder()); &lt;span style="color:#75715e"&gt;// 请求消息解码器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ch.&lt;span style="color:#a6e22e"&gt;pipeline&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http-aggregator&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpObjectAggregator(65536));&lt;span style="color:#75715e"&gt;// 目的是将多个消息转换为单一的request或者response对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ch.&lt;span style="color:#a6e22e"&gt;pipeline&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http-encoder&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpResponseEncoder());&lt;span style="color:#75715e"&gt;//响应解码器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ch.&lt;span style="color:#a6e22e"&gt;pipeline&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http-chunked&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ChunkedWriteHandler());&lt;span style="color:#75715e"&gt;//目的是支持异步大文件传输（）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ch.&lt;span style="color:#a6e22e"&gt;pipeline&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;fileServerHandler&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpFileServerHandler(url));&lt;span style="color:#75715e"&gt;// 业务逻辑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ChannelFuture future &lt;span style="color:#f92672"&gt;=&lt;/span&gt; bootstrap.&lt;span style="color:#a6e22e"&gt;bind&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;, port).&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http文件服务器，地址：http://127.0.0.1:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; port &lt;span style="color:#f92672"&gt;+&lt;/span&gt; url);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; future.&lt;span style="color:#a6e22e"&gt;channel&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;closeFuture&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;finally&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; boss.&lt;span style="color:#a6e22e"&gt;shutdownGracefully&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; worker.&lt;span style="color:#a6e22e"&gt;shutdownGracefully&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 8080;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (args.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(args&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (NumberFormatException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; e.&lt;span style="color:#a6e22e"&gt;printStackTrace&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; default_url;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (args.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; args&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpFileServer().&lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;(port, url);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HttpFileServerHandler&lt;/p&gt;</description></item><item><title>elasticsearch</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/elasticsearch/elasticsearch/</link><pubDate>Tue, 18 Jan 2022 13:16:51 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/elasticsearch/elasticsearch/</guid><description>&lt;h2 id="第一部分初识-elasticsearch"&gt;第一部分：初识 Elasticsearch&lt;/h2&gt;
&lt;h3 id="第-1-章概述"&gt;第 1 章：概述&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;课程介绍&lt;/li&gt;
&lt;li&gt;课程综述及学习建议&lt;/li&gt;
&lt;li&gt;Elasticsearch 简介及其发展历史&lt;/li&gt;
&lt;li&gt;Elastic Stack 家族成员及其应用场景&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-2-章安装上手"&gt;第 2 章：安装上手&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Elasticsearch 的安装与简单配置&lt;/li&gt;
&lt;li&gt;Kibana 的安装与界面快速浏览&lt;/li&gt;
&lt;li&gt;在 Docker 容器中运行 Elasticsearch，Kibana 和 Cerebro&lt;/li&gt;
&lt;li&gt;Logstash 安装与导入数据&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-3-章elasticsearch-入门"&gt;第 3 章：Elasticsearch 入门&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;基本概念（1）：索引，文档和 REST API&lt;/li&gt;
&lt;li&gt;基本概念（2）：节点，集群，分片及副本&lt;/li&gt;
&lt;li&gt;文档的基本 CRUD 与批量操作&lt;/li&gt;
&lt;li&gt;倒排索引入门&lt;/li&gt;
&lt;li&gt;通过分析器进行分词&lt;/li&gt;
&lt;li&gt;Search API 概览&lt;/li&gt;
&lt;li&gt;URI Search 详解&lt;/li&gt;
&lt;li&gt;Request Body 与 Query DSL 简介&lt;/li&gt;
&lt;li&gt;Query String &amp;amp; Simple Query String 查询&lt;/li&gt;
&lt;li&gt;Dynamic Mapping 和常见字段类型&lt;/li&gt;
&lt;li&gt;显式 Mapping 设置与常见参数介绍&lt;/li&gt;
&lt;li&gt;多字段特性及 Mapping 中配置自定义 Analyzer&lt;/li&gt;
&lt;li&gt;Index Template 和 Dynamic Template&lt;/li&gt;
&lt;li&gt;Elasticsearch 聚合分析简介&lt;/li&gt;
&lt;li&gt;第一部分总结&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="第二部分深入了解-elasticsearch"&gt;第二部分：深入了解 Elasticsearch&lt;/h2&gt;
&lt;h3 id="第-4-章深入搜索"&gt;第 4 章：深入搜索&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;基于词项和基于全文的搜索&lt;/li&gt;
&lt;li&gt;结构化搜索&lt;/li&gt;
&lt;li&gt;搜索的相关性算分&lt;/li&gt;
&lt;li&gt;Query &amp;amp; Filtering 与多字符串多字段查询&lt;/li&gt;
&lt;li&gt;单字符串多字段查询：Dis Max Query&lt;/li&gt;
&lt;li&gt;单字符串多字段查询：Multi Match&lt;/li&gt;
&lt;li&gt;多语言及中文分词与检索&lt;/li&gt;
&lt;li&gt;Space Jam，一次全文搜索的实例&lt;/li&gt;
&lt;li&gt;使用 Search Template 和 Index Alias 查询&lt;/li&gt;
&lt;li&gt;综合排序：Function Score Query 优化算分&lt;/li&gt;
&lt;li&gt;Term &amp;amp; Phrase Suggester&lt;/li&gt;
&lt;li&gt;自动补全与基于上下文的提示&lt;/li&gt;
&lt;li&gt;配置跨集群搜索&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-5-章分布式特性及分布式搜索的机制"&gt;第 5 章：分布式特性及分布式搜索的机制&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;集群分布式模型及选主与脑裂问题&lt;/li&gt;
&lt;li&gt;分片与集群的故障转移&lt;/li&gt;
&lt;li&gt;文档分布式存储&lt;/li&gt;
&lt;li&gt;分片及其生命周期&lt;/li&gt;
&lt;li&gt;剖析分布式查询及相关性算分&lt;/li&gt;
&lt;li&gt;排序及 Doc Values &amp;amp; Fielddata&lt;/li&gt;
&lt;li&gt;分页与遍历：From, Size, Search After &amp;amp; Scroll API&lt;/li&gt;
&lt;li&gt;处理并发读写操作&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-6-章深入聚合分析"&gt;第 6 章：深入聚合分析&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Bucket &amp;amp; Metric 聚合分析及嵌套聚合&lt;/li&gt;
&lt;li&gt;Pipeline 聚合分析&lt;/li&gt;
&lt;li&gt;作用范围与排序&lt;/li&gt;
&lt;li&gt;聚合分析的原理及精准度问题&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-7-章数据建模"&gt;第 7 章：数据建模&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;对象及 Nested 对象&lt;/li&gt;
&lt;li&gt;文档的父子关系&lt;/li&gt;
&lt;li&gt;Update By Query &amp;amp; Reindex API&lt;/li&gt;
&lt;li&gt;Ingest Pipeline &amp;amp; Painless Script&lt;/li&gt;
&lt;li&gt;Elasticsearch 数据建模实例&lt;/li&gt;
&lt;li&gt;Elasticsearch 数据建模最佳实践&lt;/li&gt;
&lt;li&gt;第二部分总结回顾&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="第三部分管理-elasticsearch-集群"&gt;第三部分：管理 Elasticsearch 集群&lt;/h2&gt;
&lt;h3 id="第-8-章保护你的数据"&gt;第 8 章：保护你的数据&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;集群身份认证与用户鉴权&lt;/li&gt;
&lt;li&gt;集群内部安全通信&lt;/li&gt;
&lt;li&gt;集群与外部间的安全通信&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-9-章水平扩展-elasticsearch-集群"&gt;第 9 章：水平扩展 Elasticsearch 集群&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;常见的集群部署方式&lt;/li&gt;
&lt;li&gt;Hot &amp;amp; Warm 架构与 Shard Filtering&lt;/li&gt;
&lt;li&gt;如何对集群进行容量规划&lt;/li&gt;
&lt;li&gt;分片设计及管理&lt;/li&gt;
&lt;li&gt;在私有云上管理 Elasticsearch 集群的一些方法&lt;/li&gt;
&lt;li&gt;在公有云上管理与部署 Elasticsearch 集群&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-10-章生产环境中的集群运维"&gt;第 10 章：生产环境中的集群运维&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;生产环境常用配置与上线清单&lt;/li&gt;
&lt;li&gt;监控 Elasticsearch 集群&lt;/li&gt;
&lt;li&gt;诊断集群的潜在问题&lt;/li&gt;
&lt;li&gt;解决集群 Yellow 与 Red 的问题&lt;/li&gt;
&lt;li&gt;提升集群写性能&lt;/li&gt;
&lt;li&gt;提升进群读性能&lt;/li&gt;
&lt;li&gt;集群压力测试&lt;/li&gt;
&lt;li&gt;段合并优化及注意事项&lt;/li&gt;
&lt;li&gt;缓存及使用 Breaker 限制内存使用&lt;/li&gt;
&lt;li&gt;一些运维的相关建议&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-11-章索引生命周期管理"&gt;第 11 章：索引生命周期管理&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用 Shrink 与 Rollover API 有效管理时间序列索引&lt;/li&gt;
&lt;li&gt;索引全生命周期管理及工具介绍&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="第四部分利用-elk-做大数据分析"&gt;第四部分：利用 ELK 做大数据分析&lt;/h2&gt;
&lt;h3 id="第-12-章用-logstash-和-beats-构建数据管道"&gt;第 12 章：用 Logstash 和 Beats 构建数据管道&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Logstash 入门及架构介绍&lt;/li&gt;
&lt;li&gt;Beats 介绍&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="第-13-章用-kibana-进行数据可视化分析"&gt;第 13 章：用 Kibana 进行数据可视化分析&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用 Index Pattern 配置数据&lt;/li&gt;
&lt;li&gt;使用 Kibana Discover 探索数据&lt;/li&gt;
&lt;li&gt;基本可视化组件介绍&lt;/li&gt;
&lt;li&gt;构建 Dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="第-14-章探索-x-pack-套件"&gt;第 14 章：探索 X-Pack 套件&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;用 Monitoring 和 Alerting 监控 Elasticsearch 集群&lt;/li&gt;
&lt;li&gt;用 APM 进行程序性能监控&lt;/li&gt;
&lt;li&gt;用机器学习实现时序数据的异常检测（上）&lt;/li&gt;
&lt;li&gt;用机器学习实现时序数据的异常检测(下）&lt;/li&gt;
&lt;li&gt;用 ELK 进行日志管理&lt;/li&gt;
&lt;li&gt;用 Canvas 做数据演示&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="第五部分应用实战工作坊"&gt;第五部分：应用实战工作坊&lt;/h2&gt;
&lt;h3 id="实战-1电影搜索服务"&gt;实战 1：电影搜索服务&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;项目需求分析及架构设计&lt;/li&gt;
&lt;li&gt;将音乐数据导入 Elasticsearch&lt;/li&gt;
&lt;li&gt;搭建你的电影搜索服务&lt;/li&gt;
&lt;li&gt;基于 Java 和 Elasticsearch 构建应用&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="实战-2stackoverflow-用户调查问卷分析"&gt;实战 2：Stackoverflow 用户调查问卷分析&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;需求分析及架构设计&lt;/li&gt;
&lt;li&gt;数据 Extract &amp;amp; Enrichment&lt;/li&gt;
&lt;li&gt;构建 Insights Dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="备战elastic-认证"&gt;备战：Elastic 认证&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Elastic 认证介绍&lt;/li&gt;
&lt;li&gt;考点梳理&lt;/li&gt;
&lt;li&gt;集群的数据备份&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>git指令</title><link>https://www.ggball.top/posts/git/git%E6%8C%87%E4%BB%A4/</link><pubDate>Tue, 18 Jan 2022 10:09:41 +0800</pubDate><guid>https://www.ggball.top/posts/git/git%E6%8C%87%E4%BB%A4/</guid><description>&lt;p&gt;我每天使用 Git ，但是很多命令记不住。&lt;/p&gt;
&lt;p&gt;一般来说，日常使用只要记住下图6个命令，就可以了。但是熟练使用，恐怕要记住60～100个命令。&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://www.ruanyifeng.com/blogimg/asset/2015/bg2015120901.png"&gt;&lt;/p&gt;
&lt;p&gt;下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。&lt;/p&gt;</description></item><item><title>io入门了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/io%E5%85%A5%E9%97%A8%E4%BA%86%E8%A7%A3/</link><pubDate>Sat, 15 Jan 2022 21:04:02 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/io%E5%85%A5%E9%97%A8%E4%BA%86%E8%A7%A3/</guid><description>&lt;p&gt;Java1.4之前的早期版本，Java对I/O的支持并不完善，开发人员在开发高性能I/O程序的时候，会面临一些巨大的挑战和困难，主要问题如下:&lt;/p&gt;</description></item><item><title>javaNIO了解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/javanio%E4%BA%86%E8%A7%A3/</link><pubDate>Sat, 15 Jan 2022 21:02:06 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/javanio%E4%BA%86%E8%A7%A3/</guid><description>&lt;h1 id="流与块"&gt;流与块&lt;/h1&gt;
&lt;p&gt;I/O 与 NIO 最重要的区别是数据打包和传输的方式，&lt;strong&gt;I/O 以流的方式处理数据&lt;/strong&gt;，而 &lt;strong&gt;NIO 以块的方式处理数据&lt;/strong&gt;。 面向流的 I/O 一次处理一个字节数据: 一个输入流产生一个字节数据，一个输出流消费一个字节数据。为流式数据创建过滤器非常容易，链接几个过滤器，以便每个过滤器只负责复杂处理机制的一部分。不利的一面是，面向流的 I/O 通常相当慢。 面向块的 I/O 一次处理一个数据块，按块处理数据比按流处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。 I/O 包和 NIO 已经很好地集成了，java.io.* 已经以 NIO 为基础重新实现了，所以现在它可以利用 NIO 的一些特性。例如，java.io.* 包中的一些类包含以块的形式读写数据的方法，这使得即使在面向流的系统中，处理速度也会更快。&lt;/p&gt;</description></item><item><title>TCP粘包，拆包的原因和解决办法</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/tcp%E7%B2%98%E5%8C%85%E6%8B%86%E5%8C%85%E7%9A%84%E5%8E%9F%E5%9B%A0%E5%92%8C%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</link><pubDate>Sat, 15 Jan 2022 20:55:39 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty/tcp%E7%B2%98%E5%8C%85%E6%8B%86%E5%8C%85%E7%9A%84%E5%8E%9F%E5%9B%A0%E5%92%8C%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</guid><description>&lt;blockquote&gt;
&lt;p&gt;由于TCP会出现粘包，拆包的情况，为了更好的了解netty是如何解决的，所以有必要了解粘包，拆包的原因！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="拆包问题说明"&gt;拆包问题说明&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20220115192707759" loading="lazy" src="https://img.ggball.top/picGo/image-20220115192707759.png"&gt;&lt;/p&gt;
&lt;p&gt;假设客户端分别发送了两个数据包D1和D2给服务端，由于服务端一次读取到的字节数是不确定的，故可能存在以下4种情况。&lt;/p&gt;</description></item><item><title>github action学习总结</title><link>https://www.ggball.top/posts/git/github-action%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/</link><pubDate>Thu, 13 Jan 2022 17:57:26 +0800</pubDate><guid>https://www.ggball.top/posts/git/github-action%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/</guid><description>&lt;h1 id="github-actions总结"&gt;github actions总结&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://lab.github.com/githubtraining/github-actions:-writing-javascript-actions"&gt;github actions实验室&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Github在2019年底开放了内置的CI/CD工具&lt;code&gt;GithubActions&lt;/code&gt;.这样使用Github托管的代码终于有了不借助外部服务自动化测试打包部署的能力. 同时由于后发优势,&lt;code&gt;GithubActions&lt;/code&gt;几乎是目前最易用的CI/CD工具.
GithubActions类似于传统的CI/CD工具,都是使用代码配置脚本,执行器执行脚本,页面管理执行过程的结构.&lt;/p&gt;</description></item><item><title>解决github提交问题集合</title><link>https://www.ggball.top/posts/git/%E8%A7%A3%E5%86%B3github%E6%8F%90%E4%BA%A4%E9%97%AE%E9%A2%98%E9%9B%86%E5%90%88/</link><pubDate>Thu, 13 Jan 2022 16:19:47 +0800</pubDate><guid>https://www.ggball.top/posts/git/%E8%A7%A3%E5%86%B3github%E6%8F%90%E4%BA%A4%E9%97%AE%E9%A2%98%E9%9B%86%E5%90%88/</guid><description>&lt;h2 id="git提交github超时问题"&gt;git提交github超时问题&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 设置代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global http.proxy 127.0.0.1:44444
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global http.proxy 127.0.0.1:44444
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 取消设置代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global --unset http.proxy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global --unset https.proxy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img alt="image-20220113162128872" loading="lazy" src="https://img.ggball.top/picGo/image-20220113162128872.png"&gt;&lt;/p&gt;
&lt;h2 id="git报错解决openssl-ssl_read-connection-was-reset-errno-10054-错误解决"&gt;Git报错解决：OpenSSL SSL_read: Connection was reset, errno 10054 错误解决&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global http.sslVerify &lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="解决fatal-unable-to-access-xxxx-openssl-ssl_connect-ssl_error_syscall-in-connection-to-githubcom443"&gt;解决fatal: unable to access &amp;lsquo;XXXX&amp;rsquo;: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global --add remote.origin.proxy &lt;span style="color:#e6db74"&gt;&amp;#34;ip:port&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>build配置</title><link>https://www.ggball.top/posts/maven/build%E9%85%8D%E7%BD%AE/</link><pubDate>Wed, 12 Jan 2022 10:16:22 +0800</pubDate><guid>https://www.ggball.top/posts/maven/build%E9%85%8D%E7%BD%AE/</guid><description>&lt;p&gt;在阅读详细文档之前我们先来谈谈我自己对maven的一些个人理解，以助于从整体大局上了解maven。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;maven是什么，用通俗的话来将，maven能帮你构建工程，管理jar包，编译代码，还能帮你自动运行单元测试，打包，生成报表，甚至能帮你部署项目&lt;/li&gt;
&lt;li&gt;使用maven构建的项目均可以直接使用maven build完成项目的编译测试打包，无需额外配置&lt;/li&gt;
&lt;li&gt;Maven是通过pom.xml来执行任务的，其中的build标签描述了如何来编译及打包项目，而具体的编译和打包工作是通过build中配置的 plugin 来完成。当然plugin配置不是必须的，默认情况下，Maven 会绑定以下几个插件来完成基本操作。&lt;/li&gt;
&lt;li&gt;&lt;img alt="img" loading="lazy" src="https://img-blog.csdn.net/20180328145612540"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即在没有配置的情况下，执行mvn clean install时，maven会调用默认的plugin来完成编译打包操作，具体来讲，执行mvn clean install时会执行&lt;/p&gt;</description></item><item><title>java8总结思维导图</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/java8%E6%80%BB%E7%BB%93%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/</link><pubDate>Mon, 10 Jan 2022 22:04:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/java8%E6%80%BB%E7%BB%93%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/</guid><description>&lt;p&gt;由于本人对java8的新特性还没有什么了解和学习，而工作中时常会用到，希望学习能对未来的编码工作起到一些帮助，特此总结。&lt;/p&gt;
&lt;h3 id="java8总结思维导图"&gt;java8总结思维导图&lt;/h3&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://cdn.nlark.com/yuque/0/2020/png/1089013/1598713774605-92677562-59af-4484-8082-df7fb21445e2.png"&gt;&lt;/p&gt;</description></item><item><title>lambda表达式详解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%A6%E8%A7%A3/</link><pubDate>Mon, 10 Jan 2022 22:04:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%A6%E8%A7%A3/</guid><description>&lt;h2 id="lambda表达式含义"&gt;lambda表达式含义&lt;/h2&gt;
&lt;p&gt;lambda表达式是对&lt;strong&gt;某些接口的简单实现&lt;/strong&gt;，Lambda 规定接口中&lt;strong&gt;只能有一个需要被实现的方法&lt;/strong&gt;，不是规定接口中只能有一个方法，&lt;strong&gt;这就是函数式接口。&lt;/strong&gt;
**
lambda表达式引入“-&amp;gt;” 左侧代表&lt;strong&gt;参数列表&lt;/strong&gt;，右侧代表&lt;strong&gt;需要的功能，逻辑&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Stream API 详解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/stream-api-%E8%AF%A6%E8%A7%A3/</link><pubDate>Mon, 10 Jan 2022 22:04:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/stream-api-%E8%AF%A6%E8%A7%A3/</guid><description>&lt;h2 id="为什么需要-stream"&gt;为什么需要 Stream&lt;/h2&gt;
&lt;p&gt;Stream 作为 Java 8 的一大亮点，它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream，也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 Stream 是对集合（Collection）对象功能的增强，它专注于对集合对象进行各种非常便利、高效的聚合操作（aggregate operation），或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式，极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作，并发模式能够充分利用多核处理器的优势，使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码，就可以很方便地写出高性能的并发程序。所以说，Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。&lt;/p&gt;</description></item><item><title>记录JAVA8中Optional的使用</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/%E8%AE%B0%E5%BD%95java8%E4%B8%ADoptional%E7%9A%84%E4%BD%BF%E7%94%A8/</link><pubDate>Mon, 10 Jan 2022 22:04:53 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java8%E6%96%B0%E7%89%B9%E6%80%A7/%E8%AE%B0%E5%BD%95java8%E4%B8%ADoptional%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>&lt;h2 id="为什么推出optional"&gt;为什么推出Optional&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;**空指针异常（NullPointerException）**空指针异常特别容易在调用对象的某个方法上，我们平常判空时，可能是以下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (user &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Address address &lt;span style="color:#f92672"&gt;=&lt;/span&gt; user.&lt;span style="color:#a6e22e"&gt;getAddress&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (address &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Country country &lt;span style="color:#f92672"&gt;=&lt;/span&gt; address.&lt;span style="color:#a6e22e"&gt;getCountry&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (country &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String isocode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; country.&lt;span style="color:#a6e22e"&gt;getIsocode&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (isocode &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; isocode &lt;span style="color:#f92672"&gt;=&lt;/span&gt; isocode.&lt;span style="color:#a6e22e"&gt;toUpperCase&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是这样会显得特别杂乱无章&lt;/p&gt;</description></item><item><title>开机自启docker后 开启或关闭自启容器</title><link>https://www.ggball.top/posts/docker/%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AFdocker%E5%90%8E-%E5%BC%80%E5%90%AF%E6%88%96%E5%85%B3%E9%97%AD%E8%87%AA%E5%90%AF%E5%AE%B9%E5%99%A8/</link><pubDate>Sun, 09 Jan 2022 17:39:05 +0800</pubDate><guid>https://www.ggball.top/posts/docker/%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AFdocker%E5%90%8E-%E5%BC%80%E5%90%AF%E6%88%96%E5%85%B3%E9%97%AD%E8%87%AA%E5%90%AF%E5%AE%B9%E5%99%A8/</guid><description>&lt;p&gt;在docker启动容器可以增加参数来达到,当docker 服务重启之后 自动启动容器.&lt;/p&gt;
&lt;p&gt;命令如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-docker" data-lang="docker"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run --restart&lt;span style="color:#f92672"&gt;=&lt;/span&gt;always&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当然如果你的容器已经启动,可以通过update命令进行修改.
命令如下：&lt;/p&gt;</description></item><item><title>后端知识图谱</title><link>https://www.ggball.top/notes/%E5%90%8E%E7%AB%AF%E7%9F%A5%E8%AF%86%E5%9B%BE%E8%B0%B1/</link><pubDate>Mon, 03 Jan 2022 16:13:20 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%90%8E%E7%AB%AF%E7%9F%A5%E8%AF%86%E5%9B%BE%E8%B0%B1/</guid><description>&lt;h1 id="后端知识图谱"&gt;后端知识图谱&lt;/h1&gt;
&lt;h2 id="基础知识"&gt;基础知识&lt;/h2&gt;
&lt;h3 id="java集合"&gt;java集合&lt;/h3&gt;
&lt;h4 id="list"&gt;list&lt;/h4&gt;
&lt;h4 id="map"&gt;map&lt;/h4&gt;
&lt;h3 id="java并发"&gt;Java并发&lt;/h3&gt;
&lt;h3 id="jvm调优"&gt;jvm调优&lt;/h3&gt;
&lt;h3 id="网络编程"&gt;网络编程&lt;/h3&gt;
&lt;h2 id="基础组件"&gt;基础组件&lt;/h2&gt;
&lt;h3 id="spring"&gt;spring&lt;/h3&gt;
&lt;h3 id="mybatis"&gt;mybatis&lt;/h3&gt;
&lt;h3 id="springmvc"&gt;springMvc&lt;/h3&gt;
&lt;h3 id="springboot"&gt;springboot&lt;/h3&gt;
&lt;h3 id="netty"&gt;netty&lt;/h3&gt;
&lt;h3 id="redis"&gt;redis&lt;/h3&gt;
&lt;h2 id="微服务"&gt;微服务&lt;/h2&gt;
&lt;h3 id="服务描述"&gt;服务描述&lt;/h3&gt;
&lt;h3 id="注册中心"&gt;注册中心&lt;/h3&gt;
&lt;h3 id="服务框架"&gt;服务框架&lt;/h3&gt;
&lt;h3 id="服务监控"&gt;服务监控&lt;/h3&gt;
&lt;h3 id="服务追踪"&gt;服务追踪&lt;/h3&gt;
&lt;h3 id="服务治理"&gt;服务治理&lt;/h3&gt;
&lt;h2 id="算法设计与设计模式"&gt;算法设计与设计模式&lt;/h2&gt;
&lt;h3 id="算法"&gt;算法&lt;/h3&gt;
&lt;h4 id="数据结构"&gt;数据结构&lt;/h4&gt;
&lt;h3 id="设计模式"&gt;设计模式&lt;/h3&gt;
&lt;h2 id="架构与分布式"&gt;架构与分布式&lt;/h2&gt;
&lt;h3 id="架构理论"&gt;架构理论&lt;/h3&gt;
&lt;h3 id="分布式方案"&gt;分布式方案&lt;/h3&gt;
&lt;h3 id="分布式组件"&gt;分布式组件&lt;/h3&gt;
&lt;h2 id="数据库"&gt;数据库&lt;/h2&gt;
&lt;h3 id="mysql"&gt;mysql&lt;/h3&gt;
&lt;h3 id="oracle"&gt;oracle&lt;/h3&gt;
&lt;h2 id="linux基础"&gt;Linux基础&lt;/h2&gt;
&lt;h3 id="基本命令"&gt;基本命令&lt;/h3&gt;
&lt;h2 id="工具与部署"&gt;工具与部署&lt;/h2&gt;
&lt;h3 id="maven"&gt;maven&lt;/h3&gt;
&lt;h3 id="git"&gt;git&lt;/h3&gt;</description></item><item><title>项目集合</title><link>https://www.ggball.top/projects/%E9%A1%B9%E7%9B%AE%E9%9B%86%E5%90%88/</link><pubDate>Mon, 03 Jan 2022 15:05:41 +0800</pubDate><guid>https://www.ggball.top/projects/%E9%A1%B9%E7%9B%AE%E9%9B%86%E5%90%88/</guid><description>&lt;p&gt;::: cardImgList&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;img&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://img.ggball.top/picGo/image-20220103153123392.png&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;link&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://github.com/a1667834841/Onemanager-java&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;OneManager-Java&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;desc&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;OneManager-java是基于OneManager-php 的原型上二次开发的一款基于SpringBoot的Java网盘程序&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 描述，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;author&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ggball&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 作者，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;avatar&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://img.ggball.top/picGo/image-20220103152247487.png&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 头像，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;img&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://github.com/rongbo-j/mybatis-book/raw/master/img/mybatis-book.png&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;link&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://github.com/a1667834841/mybatis-book&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;mybatis-book&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;desc&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;本书主要分为两个篇章，第一篇章为Mybatis3源码篇，从第1章至11章，主要介绍Mybatis框架各个特性的实现原理。第二篇章为Mybatis Spring源码篇，主要介绍Mybatis框架与Spring框架整合原理。&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 描述，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;author&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ggball&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 作者，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;avatar&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://img.ggball.top/picGo/image-20220103152247487.png&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 头像，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;img&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://www.preface.ai/blog/wp-content/uploads/2023/01/2023-article-resize-1-1024x576.jpg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;link&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://talk.toolkit.show/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bullet-chatgpt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;desc&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;可以发弹幕的chatgpt。&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 描述，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;author&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ggball&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 作者，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;avatar&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://img.ggball.top/picGo/image-20220103152247487.png&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 头像，可选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;:::
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>总览</title><link>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E6%80%BB%E8%A7%88/</link><pubDate>Mon, 06 Dec 2021 17:15:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E6%80%BB%E8%A7%88/</guid><description>&lt;h1 id="面试总览"&gt;面试总览&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ggball.top/pages/2ace5b"&gt;河狸家【2021-4-13】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ggball.top/pages/0f0bde"&gt;篱笆墙网络科技公司面试【2021-7-6】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ggball.top/pages/4483b5"&gt;卓锐科技视频面试【2021-4-2】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ggball.top/pages/ec740e"&gt;绿城信息科技有限公司【2021-4-7】&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>篱笆墙网络科技公司面试-2021-7-6</title><link>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E7%AF%B1%E7%AC%86%E5%A2%99%E7%BD%91%E7%BB%9C%E7%A7%91%E6%8A%80%E5%85%AC%E5%8F%B8%E9%9D%A2%E8%AF%95-2021-7-6/</link><pubDate>Mon, 06 Dec 2021 17:01:28 +0800</pubDate><guid>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E7%AF%B1%E7%AC%86%E5%A2%99%E7%BD%91%E7%BB%9C%E7%A7%91%E6%8A%80%E5%85%AC%E5%8F%B8%E9%9D%A2%E8%AF%95-2021-7-6/</guid><description>&lt;h2 id="java中如何保证线程安全性"&gt;Java中如何保证线程安全性&lt;/h2&gt;
&lt;p&gt; 
什么是线程安全：
当多个线程访问某个方法时，不管你通过怎样的调用方式、或者说这些线程如何交替地执行，我们在主程序中不需要去做任何的同步，这个类的结果行为都是我们设想的正确行为，那么我们就可以说这个类是线程安全的。  
 
 &lt;/p&gt;</description></item><item><title>绿城信息科技有限公司-2021-4-7</title><link>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E7%BB%BF%E5%9F%8E%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8-2021-4-7/</link><pubDate>Mon, 06 Dec 2021 17:01:28 +0800</pubDate><guid>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E7%BB%BF%E5%9F%8E%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8-2021-4-7/</guid><description>&lt;h2 id="技术面"&gt;技术面&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;简单介绍下自己和目前做的项目&lt;/li&gt;
&lt;li&gt;static的作用，以及静态类初始化的过程？&lt;/li&gt;
&lt;li&gt;i++是原子操作吗&lt;/li&gt;
&lt;li&gt;spring的IOC和AOP&lt;/li&gt;
&lt;li&gt;聊项目&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="hr面"&gt;hr面&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;聊公司业务，福利&lt;/li&gt;
&lt;li&gt;聊工资&lt;/li&gt;
&lt;li&gt;等通知&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>卓锐科技视频面试-2021-4-2</title><link>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E5%8D%93%E9%94%90%E7%A7%91%E6%8A%80%E8%A7%86%E9%A2%91%E9%9D%A2%E8%AF%95-2021-4-2/</link><pubDate>Mon, 06 Dec 2021 17:01:28 +0800</pubDate><guid>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E5%8D%93%E9%94%90%E7%A7%91%E6%8A%80%E8%A7%86%E9%A2%91%E9%9D%A2%E8%AF%95-2021-4-2/</guid><description>&lt;h2 id="线程核心数-如何设置"&gt;线程核心数 如何设置&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;首先考虑到CPU核心数 Java 中如何获取核心线程数 &lt;code&gt;Runtime.getRuntime().availableProcessors();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;考虑任务是 CPU 密集型任务还是 IO 密集型任务
&lt;strong&gt;cpu密集&lt;/strong&gt;（&lt;strong&gt;比如像加解密，压缩、计算等一系列需要大量耗费 CPU 资源的任务&lt;/strong&gt;）：理论上线程的数量 = CPU 核数就是最合适的，不过通常把线程的数量设置为CPU 核数 +1，会实现最优的利用率。
IO密集型任务：线程数 = CPU 核心数 / (1 - 阻塞系数)
&lt;strong&gt;其中计算密集型阻塞系数为 0，IO 密集型阻塞系数接近 1，一般认为在 0.8 ~ 0.9 之间。比如 8 核 CPU，按照公式就是 2 / ( 1 - 0.9 ) = 20 个线程数&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="5个线程如何判断线程结束"&gt;5个线程如何判断线程结束&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;线程池做的话，线程池有一个termiated终止状态，调用isTermiated可以查看线程池中的线程有没有完全结束&lt;/li&gt;
&lt;li&gt;atomicInteger 初始化5，完成一个减一&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="redis-做缓存-还能做啥-消息队列-分布式锁"&gt;redis 做缓存 还能做啥 消息队列 分布式锁&lt;/h2&gt;
&lt;p&gt;使用redis分布式锁（主要使用了redis中的setnx和getset方法，这两个方法在redisTemplate分别是setIfAbsent和getAndSet方法）实现线程安全，因为redis是单线程，能保证线程的安全性，而且redis强大的读写能力能提高效率。&lt;/p&gt;</description></item><item><title>mybatis拦截器执行原理</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%8B%A6%E6%88%AA%E5%99%A8%E6%89%A7%E8%A1%8C%E5%8E%9F%E7%90%86/</link><pubDate>Mon, 06 Dec 2021 16:57:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%8B%A6%E6%88%AA%E5%99%A8%E6%89%A7%E8%A1%8C%E5%8E%9F%E7%90%86/</guid><description>&lt;p&gt;mybatis的拦截器本人平时也很少用到，没了解之前，也只是知道运用到了动态代理用来增强方法的功能，但是不了解其中的原理。为了更好的使用mybatis，这次，我记录下我所了解的mybatis的原理，本文不一定完全正确，可能有理解不到位的地方。&lt;/p&gt;</description></item><item><title>mybatis日志体系</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%97%A5%E5%BF%97%E4%BD%93%E7%B3%BB/</link><pubDate>Sun, 28 Nov 2021 18:08:20 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%97%A5%E5%BF%97%E4%BD%93%E7%B3%BB/</guid><description>&lt;h2 id="java日志体系"&gt;java日志体系&lt;/h2&gt;
&lt;p&gt;常用日志框架&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Log4j：Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的，现在则是Apache软件基金会的一个项目。&lt;/li&gt;
&lt;li&gt;Log4j 2：Apache Log4j 2是Apache开发的一款Log4j的升级产品。&lt;/li&gt;
&lt;li&gt;Commons Logging：Apache基金会所属的项目，是一套Java日志接口，之前叫Jakarta Commons Logging，后更名为Commons Logging。Apache推出了JCL（Jakarta Commons Logging），它只是定义了一套日志接口（其内部也提供一个Simple Log的简单实现），JCL也是一套接口规范，支持运行时动态加载日志组件的实现。也就是说，在应用程序代码中，只需调用Commons Logging的接口，底层实现可以是Log4j，也可以是JUL&lt;/li&gt;
&lt;li&gt;SLF4J：全称为Simple Logging Facade for Java，类似于Commons Logging，是一套简易Java日志门面，本身并无日志的实现。&lt;/li&gt;
&lt;li&gt;Logback：是一套日志组件的实现，属于SLF4J阵营。&lt;/li&gt;
&lt;li&gt;JUL：全称是Java Util Logging，是JDK1.4以后提供的日志实现。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image-20211122122647417" loading="lazy" src="https://img.ggball.top/picGo/image-20211122122647417.png"&gt;&lt;/p&gt;</description></item><item><title>mybatis缓存解析</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E7%BC%93%E5%AD%98%E8%A7%A3%E6%9E%90/</link><pubDate>Wed, 17 Nov 2021 00:07:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E7%BC%93%E5%AD%98%E8%A7%A3%E6%9E%90/</guid><description>&lt;h2 id="mybatis的缓存"&gt;mybatis的缓存&lt;/h2&gt;
&lt;p&gt;首先来看下mybatis对缓存的规范，规范嘛就是定义的接口啦。&lt;/p&gt;
&lt;h3 id="缓存接口"&gt;缓存接口&lt;/h3&gt;
&lt;p&gt;​ Cache接口 定义了缓存的方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Cache&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**获取缓存的id
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return The identifier of this cache
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String &lt;span style="color:#a6e22e"&gt;getId&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**添加缓存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param key Can be any object but usually it is a {@link CacheKey}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param value The result of a select.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;putObject&lt;/span&gt;(Object key, Object value);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**根据缓存键获取缓存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param key The key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return The object stored in the cache.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object &lt;span style="color:#a6e22e"&gt;getObject&lt;/span&gt;(Object key);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**移除缓存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * As of 3.3.0 this method is only called during a rollback
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * for any previous value that was missing in the cache.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * This lets any blocking cache to release the lock that
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * may have previously put on the key.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * A blocking cache puts a lock when a value is null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * and releases it when the value is back again.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * This way other threads will wait for the value to be
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * available instead of hitting the database.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param key The key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return Not used
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object &lt;span style="color:#a6e22e"&gt;removeObject&lt;/span&gt;(Object key);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Clears this cache instance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Optional. This method is not called by the core.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return The number of elements stored in the cache (not its capacity).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getSize&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Optional. As of 3.2.6 this method is no longer called by the core.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Any locking needed by the cache must be provided internally by the cache provider.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return A ReadWriteLock
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ReadWriteLock &lt;span style="color:#a6e22e"&gt;getReadWriteLock&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="实现"&gt;实现&lt;/h3&gt;
&lt;p&gt;&lt;img alt="image-20211116203147375" loading="lazy" src="https://img.ggball.top/picGo/image-20211116203147375.png"&gt;&lt;/p&gt;</description></item><item><title>mybatis的mapper执行过程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E7%9A%84mapper%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B/</link><pubDate>Wed, 10 Nov 2021 00:07:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E7%9A%84mapper%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B/</guid><description>&lt;p&gt;&lt;img alt="image-20211107161121595" loading="lazy" src="https://img.ggball.top/picGo/image-20211107161121595.png"&gt;&lt;/p&gt;</description></item><item><title>mybatis核心组件</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6/</link><pubDate>Wed, 10 Nov 2021 00:07:13 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6/</guid><description>&lt;p&gt;&lt;img alt="image-20211031125517372" loading="lazy" src="https://img.ggball.top/picGo/image-20211031125517372.png"&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;sequenceDiagram
participant SqlSession
participant Excutor
participant StatementHandler
participant parameterHandler
participant ResultSetHandler
participant TypeHandler
participant ResultSet
participant JDBC
SqlSession-&amp;gt;&amp;gt;Excutor:
Excutor-&amp;gt;&amp;gt;StatementHandler:
StatementHandler--&amp;gt;&amp;gt;parameterHandler:
StatementHandler--&amp;gt;&amp;gt;JDBC:
parameterHandler--&amp;gt;&amp;gt;TypeHandler:
parameterHandler-&amp;gt;&amp;gt;JDBC:
JDBC-&amp;gt;&amp;gt;ResultSet:
ResultSet--&amp;gt;&amp;gt;TypeHandler:
ResultSet--&amp;gt;&amp;gt;ResultSetHandler:
TypeHandler--&amp;gt;&amp;gt;ResultSetHandler:
ResultSetHandler-&amp;gt;&amp;gt;StatementHandler:
StatementHandler-&amp;gt;&amp;gt;Excutor:
Excutor-&amp;gt;&amp;gt;SqlSession:
Note left of SqlSession: asa
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt; flowchart TD
subgraph configuration
mappedStatement1 --&amp;gt; mappedStatement2
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;configuration:&lt;/p&gt;
&lt;p&gt;MyBatis框架的配置信息有两种，一种是配置MyBatis框架属性的主配置文件；另一种是配置执行SQL语句的Mapper配置文件。Configuration的作用是描述MyBatis主配置文件的信息&lt;/p&gt;</description></item><item><title>7全文索引</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql57%E5%85%A8%E6%96%87%E7%B4%A2%E5%BC%95/</link><pubDate>Fri, 08 Oct 2021 19:46:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql57%E5%85%A8%E6%96%87%E7%B4%A2%E5%BC%95/</guid><description>&lt;h1 id="mysql-57-中文全文检索"&gt;MySQL 5.7 中文全文检索&lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;在 MySQL 5.7.6 之前，全文索引只支持英文全文索引，不支持中文全文索引，需要利用分词器把中文段落预处理拆分成单词，然后存入数据库。
从 &lt;strong&gt;MySQL 5.7.6&lt;/strong&gt; 开始，MySQL内置了ngram全文解析器，用来&lt;strong&gt;支持中文&lt;/strong&gt;、日文、韩文分词。
本文使用的MySQL 版本是 &lt;strong&gt;5.7.24&lt;/strong&gt;，&lt;strong&gt;InnoDB&lt;/strong&gt;数据库引擎。&lt;/p&gt;</description></item><item><title>mysql基本语句</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E5%9F%BA%E6%9C%AC%E8%AF%AD%E5%8F%A5/</link><pubDate>Fri, 08 Oct 2021 19:46:05 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E5%9F%BA%E6%9C%AC%E8%AF%AD%E5%8F%A5/</guid><description>&lt;h2 id="唯一键"&gt;唯一键&lt;/h2&gt;
&lt;p&gt;mysql 5.6 及以下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;alter ignore table xy_member_game_count add UNIQUE unique_name (uid,time);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;mysql 5.7 以上&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;1.删除表中重复数据，只保留重复中的一条
delete from member
where (uid,time) in
(select uid,time from ( select uid,time from member group by uid,time having count()&amp;gt;1) a)
and id not in
( select min(id) from (select min(id) as id from member group by uid,time having count()&amp;gt;1 ) b)
2. 新增唯一键
alter table member add UNIQUE unique_name (uid,time);
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="sqlmysqlon和where区别on后可跟多个条件"&gt;sql：mysql：on和where区别，on后可跟多个条件&lt;/h1&gt;
&lt;p&gt;数据库在通过连接两张或多张表来返回记录时，都会生成一张中间的临时表，然后再将这张临时表返回给用户。&lt;/p&gt;</description></item><item><title>支付宝支付环境搭建</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/</link><pubDate>Fri, 08 Oct 2021 19:46:05 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/</guid><description>&lt;h1 id="支付宝测试环境开发的前期准备"&gt;支付宝测试环境开发的前期准备&lt;/h1&gt;
&lt;h2 id="1下载java支付的demo"&gt;1.下载Java支付的demo&lt;/h2&gt;
&lt;p&gt;　　demo下载地址：https://docs.open.alipay.com/270/106291/&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://img2018.cnblogs.com/blog/1467925/201903/1467925-20190311134113387-78400923.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.下载解压导入idea&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;img alt="img" loading="lazy" src="https://img.ggball.top/picGo/1467925-20190311135004130-723907218.png"&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;主要是拿到AlipayConfig.java文件&lt;/p&gt;</description></item><item><title>05_GC and Tuning</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/05-gc-and-tuning/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/05-gc-and-tuning/</guid><description>&lt;h1 id="gc和gc-tuning"&gt;GC和GC Tuning&lt;/h1&gt;
&lt;h3 id="gc的基础知识"&gt;GC的基础知识&lt;/h3&gt;
&lt;h4 id="1什么是垃圾"&gt;1.什么是垃圾&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;C语言申请内存：malloc free&lt;/p&gt;
&lt;p&gt;C++： new delete&lt;/p&gt;
&lt;p&gt;c/C++ 手动回收内存&lt;/p&gt;
&lt;p&gt;Java: new ？&lt;/p&gt;
&lt;p&gt;自动内存回收，编程上简单，系统不容易出错，手动释放内存，容易出两种类型的问题：&lt;/p&gt;</description></item><item><title>centos安装jdk9</title><link>https://www.ggball.top/notes/linux/centos%E5%AE%89%E8%A3%85jdk9/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/linux/centos%E5%AE%89%E8%A3%85jdk9/</guid><description>&lt;h2 id="heading"&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*1.先下载jdk9的包**&lt;/em&gt;*&lt;/em&gt;*&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
wget --no-check-certificate --no-cookies --header &amp;#34;Cookie: oraclelicense=accept-securebackup-cookie&amp;#34; http://download.oracle.com/otn-pub/java/jdk/9.0.4+11/c2514751926b4512b076cc82f959763f/jdk-9.0.4_linux-x64_bin.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="heading-1"&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*2.下载完成后解压**&lt;/em&gt;*&lt;/em&gt;*&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下载的文件直接解压在/usr/local/jdk中&lt;/p&gt;
&lt;p&gt;tar -zxvf jdk-9.0.4_linux-x64_bin.tar.gz -C /usr/local/jdk9/&lt;/p&gt;
&lt;h2 id="heading-2"&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*3.编辑配置文件，配置环境变量**&lt;/em&gt;*&lt;/em&gt;*&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
vim /etc/profile
添加如下内容：JAVA_HOME根据实际目录来
#set java environment
JAVA_HOME=/usr/local/jdk9/jdk-9.0.4
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*4.重启机器或执行命令：**&lt;/em&gt;*&lt;/em&gt;*&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;source /etc/profile
或者sudo shutdown -r now
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*5.查看安装情况**&lt;/em&gt;*&lt;/em&gt;*&lt;/p&gt;</description></item><item><title>dns解析过程</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/dns%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/dns%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B/</guid><description>&lt;h1 id="域名的结构"&gt;域名的结构&lt;/h1&gt;
&lt;p&gt;&lt;img alt="image-20210815170504414" loading="lazy" src="https://img.ggball.top/picGo/image-20210815170504414.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210815170634101" loading="lazy" src="https://img.ggball.top/picGo/image-20210815170634101.png"&gt;&lt;/p&gt;
&lt;p&gt;从右向左的解析域名，而且完整的域名是如下所示（有后缀.root）&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210815170731813" loading="lazy" src="https://img.ggball.top/picGo/image-20210815170731813.png"&gt;&lt;/p&gt;
&lt;h2 id="域名的层级"&gt;域名的层级&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20210815171113358" loading="lazy" src="https://img.ggball.top/picGo/image-20210815171113358.png"&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;域名层级&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;根域名&lt;/td&gt;
&lt;td&gt;.root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;顶级域名&lt;/td&gt;
&lt;td&gt;例如：.com、.edu、.org&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;次级域名&lt;/td&gt;
&lt;td&gt;例如：.google，.mit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主机名&lt;/td&gt;
&lt;td&gt;www&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;优势：这样的层级结构，会有提高查询域名的效率，节省DNS解析时间，就像二叉树，多叉树结构，利用树的特性（左子树值比右子树小等等），查询效率会大大提高&lt;/p&gt;</description></item><item><title>easyExcel自定义合并单元格</title><link>https://www.ggball.top/posts/%E5%B7%A5%E5%85%B7%E5%8C%85/easyexcel%E8%87%AA%E5%AE%9A%E4%B9%89%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/posts/%E5%B7%A5%E5%85%B7%E5%8C%85/easyexcel%E8%87%AA%E5%AE%9A%E4%B9%89%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC/</guid><description>&lt;p&gt;easyExcel本身支持简单的单元格合并，一共有两种合并策略:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一次性的合并策略（OnceAbsoluteMergeStrategy）&lt;/li&gt;
&lt;li&gt;循环的合并策略（LoopMergeStrategy）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 合并单元格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * &amp;lt;p&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 1. 创建excel对应的实体对象 参照{@link DemoData} {@link DemoMergeData}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * &amp;lt;p&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 2. 创建一个merge策略 并注册
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * &amp;lt;p&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 3. 直接写即可
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @since 2.2.0-beta1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mergeWrite&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 方法1 注解&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String fileName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; TestFileUtil.&lt;span style="color:#a6e22e"&gt;getPath&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;mergeWrite&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;.xlsx&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 在DemoStyleData里面加上ContentLoopMerge注解&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EasyExcel.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(fileName, DemoMergeData.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;sheet&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;模板&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;doWrite&lt;/span&gt;(data());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 方法2 自定义合并单元格策略&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fileName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; TestFileUtil.&lt;span style="color:#a6e22e"&gt;getPath&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;mergeWrite&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;.xlsx&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 每隔2行会合并 把eachColumn 设置成 3 也就是我们数据的长度，所以就第一列会合并。当然其他合并策略也可以自己写&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LoopMergeStrategy loopMergeStrategy &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; LoopMergeStrategy(2, 0);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EasyExcel.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(fileName, DemoData.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;registerWriteHandler&lt;/span&gt;(loopMergeStrategy).&lt;span style="color:#a6e22e"&gt;sheet&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;模板&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;doWrite&lt;/span&gt;(data());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是往往实际应用中，我们并不能立马指定合并的单元格，就比如我这次需要根据订单id相同的合并单元格，但是数据还没查询出来时，我是不知道哪些要合并的，而我只知道两个要求：&lt;/p&gt;</description></item><item><title>git本地上传项目</title><link>https://www.ggball.top/posts/git/git%E6%9C%AC%E5%9C%B0%E4%B8%8A%E4%BC%A0%E9%A1%B9%E7%9B%AE/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/posts/git/git%E6%9C%AC%E5%9C%B0%E4%B8%8A%E4%BC%A0%E9%A1%B9%E7%9B%AE/</guid><description>&lt;h1 id="使用git将本地项目上传至git仓库"&gt;&lt;a href="https://www.cnblogs.com/fanwenhao/p/10841133.html"&gt;使用git将本地项目上传至git仓库&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="介绍"&gt;介绍&lt;/h2&gt;
&lt;p&gt;一般来说开发过程中都是先在git创建远程仓库，然后fetch到本地仓库，再进行commit push等操作，但是有时候也需要将本地已经开发的项目上传至一个空的远程仓库中，期间也是遇到不少问题，特此总结一下&lt;/p&gt;</description></item><item><title>IOC</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/ioc/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/ioc/</guid><description>&lt;p&gt;这里IoC容器就解决了这个问题。&lt;strong&gt;这个容器可以自动对你的代码进行初始化，你只需要维护一个Configuration（可以是xml可以是一段代码），而不用每次初始化一辆车都要亲手去写那一大段初始化的代码&lt;/strong&gt;。这是引入IoC Container的第一个好处。&lt;/p&gt;</description></item><item><title>java对象内存布局</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80/</guid><description>&lt;h1 id="使用javaagent测试object的大小"&gt;使用JavaAgent测试Object的大小&lt;/h1&gt;
&lt;h2 id="对象大小64位机"&gt;对象大小（64位机）&lt;/h2&gt;
&lt;h3 id="观察虚拟机配置"&gt;观察虚拟机配置&lt;/h3&gt;
&lt;p&gt;java -XX:+PrintCommandLineFlags -version&lt;/p&gt;
&lt;h3 id="普通对象"&gt;普通对象&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;对象头：markword 8&lt;/li&gt;
&lt;li&gt;ClassPointer指针：-XX:+UseCompressedClassPointers 为4字节 不开启为8字节&lt;/li&gt;
&lt;li&gt;实例数据
&lt;ol&gt;
&lt;li&gt;引用类型：-XX:+UseCompressedOops 为4字节 不开启为8字节
Oops Ordinary Object Pointers&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Padding对齐，8的倍数&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="数组对象"&gt;数组对象&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;对象头：markword 8&lt;/li&gt;
&lt;li&gt;ClassPointer指针同上&lt;/li&gt;
&lt;li&gt;数组长度：4字节&lt;/li&gt;
&lt;li&gt;数组数据&lt;/li&gt;
&lt;li&gt;对齐 8的倍数&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="实验"&gt;实验&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;新建项目ObjectSize （1.8）&lt;/p&gt;</description></item><item><title>java内存模型</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</guid><description>&lt;p&gt;自动内存管理&lt;/p&gt;
&lt;p&gt;相关概念&lt;/p&gt;
&lt;p&gt;野指针：比较野的指针，指向内存被释放的内存或者没有访问权限的内存的指针。
原因：野指针主要是因为这些疏忽而出现的删除或申请访问受限内存区域的指针。&lt;/p&gt;</description></item><item><title>java内存模型JMM</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8Bjmm/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8Bjmm/</guid><description>&lt;h1 id="什么是jmm模型"&gt;什么是JMM模型&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;JMM是一组抽象的概念，并不真实存在，他描述的是一组规则或规范，通过这组规范定义了程序中各个变量（包括实例字段，静态字段 和构成数组对象的元素）的访问方式。&lt;strong&gt;JMM是围绕原子性，有序性、可见性展开的&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>java运行时数据区</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E8%BF%90%E8%A1%8C%E6%97%B6%E6%95%B0%E6%8D%AE%E5%8C%BA/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/java%E8%BF%90%E8%A1%8C%E6%97%B6%E6%95%B0%E6%8D%AE%E5%8C%BA/</guid><description>&lt;h1 id="runtime-data-area-and-instruction-set"&gt;Runtime Data Area and Instruction Set&lt;/h1&gt;
&lt;p&gt;jvms 2.4 2.5&lt;/p&gt;
&lt;h2 id="指令集分类"&gt;指令集分类&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;基于寄存器的指令集&lt;/li&gt;
&lt;li&gt;基于栈的指令集
Hotspot中的Local Variable Table = JVM中的寄存器&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="runtime-data-area"&gt;Runtime Data Area&lt;/h2&gt;
&lt;p&gt;PC 程序计数器&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;存放指令位置&lt;/p&gt;
&lt;p&gt;虚拟机的运行，类似于这样的循环：&lt;/p&gt;</description></item><item><title>JVM入门</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%85%A5%E9%97%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/jvm%E5%85%A5%E9%97%A8/</guid><description>&lt;h2 id="jvm-体系结构"&gt;jvm 体系结构&lt;/h2&gt;
&lt;p&gt;&lt;img alt="jvm 体系结构 " loading="lazy" src="https://img.ggball.top/picGo/20230503001206.png"&gt;&lt;/p&gt;
&lt;h3 id="jvm内存分布运行时数据区"&gt;jvm内存分布（运行时数据区）&lt;/h3&gt;
&lt;p&gt;&lt;img alt="jvm内存分布" loading="lazy" src="https://img.ggball.top/picGo/20230507230203.png"&gt;&lt;/p&gt;
&lt;h4 id="程序计数器线程隔离"&gt;程序计数器（线程隔离）&lt;/h4&gt;
&lt;p&gt;每个线程都有，记录着线程下一刻运行到哪里。如果执行的是方法，这里记录的是虚拟机字节码指令的地址。当执行的是Native方法的时候为空（Undefined）。&lt;/p&gt;</description></item><item><title>linux小笔记</title><link>https://www.ggball.top/notes/linux/linux%E5%B0%8F%E7%AC%94%E8%AE%B0/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/linux/linux%E5%B0%8F%E7%AC%94%E8%AE%B0/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;ps -eo pmem,pcpu,rss,vsize,args | sort -k 1 -r | less
执行以上命令可查看各个程序进程内存使用的内存情况，如下图所示，第一列为进程占用的内存百分比，可以看到哪些应用程序占的内存比较多，用于排查问题：
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://img2018.cnblogs.com/blog/1158674/201903/1158674-20190319134154605-495483923.png"&gt;&lt;/p&gt;</description></item><item><title>MQ本质</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/mq%E6%9C%AC%E8%B4%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/mq%E6%9C%AC%E8%B4%A8/</guid><description>&lt;h1 id="mq"&gt;MQ&lt;/h1&gt;
&lt;h2 id="本质"&gt;本质&lt;/h2&gt;
&lt;h3 id="一发一存一消费"&gt;一发一存一消费&lt;/h3&gt;
&lt;p&gt;生产者先将消息投递一个叫做「队列」的容器中，然后再从这个容器中取出消息，最后再转发给消费者，仅此而已&lt;/p&gt;
&lt;h2 id="模型进化"&gt;模型进化&lt;/h2&gt;
&lt;h3 id="队列模型"&gt;队列模型&lt;/h3&gt;
&lt;p&gt;这便是&lt;strong&gt;队列模型&lt;/strong&gt;：它允许多个生产者往同一个队列发送消息。但是，如果有多个消费者，实际上是竞争的关系，也就是一条消息只能被其中一个消费者接收到，读完即被删除。&lt;/p&gt;</description></item><item><title>mvnw简介</title><link>https://www.ggball.top/posts/maven/mvnw%E7%AE%80%E4%BB%8B/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/posts/maven/mvnw%E7%AE%80%E4%BB%8B/</guid><description>&lt;h1 id="mvnw简介"&gt;MVNW简介&lt;/h1&gt;
&lt;p&gt;maven是一款非常流行的java项目构建软件，它集项目的依赖管理、测试用例运行、打包、构件管理于一身，是我们工作的好帮手，maven飞速发展，它的发行版本也越来越多，如果我们的项目是基于maven构件的，那么如何保证拿到我们项目源码的同事的maven版本和我们开发时的版本一致呢，可能你认为很简单，一个公司嘛，规定所有的同事都用一maven版本不就万事大吉了吗？一个组织内部这是可行的，要是你开源了一个项目呢？如何保证你使用的maven的版本和下载你源码的人的maven的版本一致呢，这时候mvnw就大显身手了。
mvnw 全名是maven wrapper,它的原理是在maven-wrapper.properties文件中记录你要使用的maven版本，当用户执行mvnw clean 命令时，发现当前用户的maven版本和期望的版本不一致，那么就下载期望的版本，然后用期望的版本来执行mvn命令，比如刚才的mvn clean。&lt;/p&gt;</description></item><item><title>mybatis-执行器</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis-%E6%89%A7%E8%A1%8C%E5%99%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis-%E6%89%A7%E8%A1%8C%E5%99%A8/</guid><description>&lt;h2 id="mytatis的执行器是什么"&gt;mytatis的执行器是什么&lt;/h2&gt;
&lt;h2 id="执行器结构"&gt;执行器结构&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20210318230608196" loading="lazy" src="https://img.ggball.top/image-20210318230608196.png"&gt;&lt;/p&gt;</description></item><item><title>mybatis概览</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%A6%82%E8%A7%88/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/mybatis/mybatis%E6%A6%82%E8%A7%88/</guid><description>&lt;h1 id="mybatis-概念"&gt;mybatis 概念：&lt;/h1&gt;
&lt;p&gt;一个半自动orm（&lt;strong&gt;Object Relational Mapping&lt;/strong&gt; 对象关系映射）框架&lt;/p&gt;
&lt;h1 id="整体框架"&gt;整体框架&lt;/h1&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://img.ggball.top/3003028eacbd93763c628c4b1bc64b7b4a058068.jpg@1320w_1154h.webp"&gt;&lt;/p&gt;
&lt;h2 id="接口层"&gt;接口层&lt;/h2&gt;
&lt;h2 id="数据处理层"&gt;数据处理层&lt;/h2&gt;
&lt;h2 id="扩展支撑层"&gt;扩展支撑层&lt;/h2&gt;
&lt;h1 id="学习路线"&gt;学习路线&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;执行流程&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;映射配置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;扩展支撑&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;执行流程&lt;/p&gt;
&lt;p&gt;sql执行流程&lt;/p&gt;
&lt;p&gt;映射配置&lt;/p&gt;</description></item><item><title>openFeign超时配置</title><link>https://www.ggball.top/notes/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8/openfeign%E8%B6%85%E6%97%B6%E9%85%8D%E7%BD%AE/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8/openfeign%E8%B6%85%E6%97%B6%E9%85%8D%E7%BD%AE/</guid><description>&lt;h1 id="openfeign超时时间配置"&gt;openFeign超时时间配置&lt;/h1&gt;
&lt;p&gt;一开始我把 feign和openFeign搞混了，所以还是先记录下下面三种feign的区别吧&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-maven" data-lang="maven"&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.netflix.feign/feign-core --&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;com.netflix.feign&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;feign-core&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;8.18.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;22.MVCC0.5.1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign --&amp;gt;
&amp;lt;!-- https://spring.io/projects/spring-cloud-openfeign --&amp;gt;
&amp;lt;!-- https://github.com/spring-cloud/spring-cloud-openfeign --&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;spring-cloud-starter-openfeign&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;2.1.2.RELEASE&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;com.netflix.feign&lt;/code&gt;是Netflix 公司开源产品，2018年宣布停止维护。 改由开源社区进行维护，修改了组织归属为OpenFeign，并调整代码仓库到&lt;a href="https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FOpenFeign%2Ffeign"&gt;OpenFeign/feign&lt;/a&gt;（可以简单理解为换了个仓库地址，换了一批人继续更新维护）。&lt;/p&gt;</description></item><item><title>RabbitMQ</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/rabbitmq/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/rabbitmq/</guid><description>&lt;h2 id="rabbitmq的应用场景以及基本原理介绍"&gt;&lt;a href="https://blog.csdn.net/whoamiyang/article/details/54954780?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&amp;amp;amp;depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase"&gt;RabbitMQ的应用场景以及基本原理介绍&lt;/a&gt;&lt;/h2&gt;
&lt;h2 id="概念"&gt;概念&lt;/h2&gt;
&lt;p&gt;RabbitMQ 是一个由 erlang 开发的 AMQP (Advanced Message Queuing Protocol) 的开源实现。&lt;/p&gt;
&lt;p&gt;AMQP ：高级消息队列协议，是应用层协议的一个开放标准，为面向消息的中间件设计。消息中间件主要用于组件之间的解耦，消息的发送者无需知道消息使用者的存在，反之亦然。 AMQP 的主要特征是面向消息、队列、路由（包括点对点和发布 / 订阅）、可靠性、安全。 RabbitMQ 是一个开源的 AMQP 实现，服务器端用 Erlang 语言编写，支持多种客户端，如：Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等，支持 AJAX。用于在分布式系统中存储转发消息，在易用性、扩展性、高可用性等方面表现不俗。&lt;/p&gt;</description></item><item><title>spring bean的配置方式</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring-bean%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring-bean%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F/</guid><description>&lt;h1 id="xml-配置bean方式"&gt;xml 配置bean方式&lt;/h1&gt;
&lt;h1 id="注解式配置bean方式"&gt;注解式配置bean方式&lt;/h1&gt;
&lt;h2 id="1-component-声明"&gt;1. @Component 声明&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/**
* @program: springboot
* @description:
* @author: ggBall
* @create: 2021-02-20 17:11
**/
@Component
@Data
public class Dog {
private String name;
private Integer age;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;结果&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210220174447838" loading="lazy" src="https://img.ggball.top/picGo/image-20210220174447838.png"&gt;&lt;/p&gt;
&lt;h2 id="2-在配置类中使用-bean注解"&gt;2. 在配置类中使用 @Bean注解&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20210220175048812" loading="lazy" src="https://img.ggball.top/picGo/image-20210220175048812.png"&gt;&lt;/p&gt;
&lt;p&gt;结果&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210220175112752" loading="lazy" src="https://img.ggball.top/picGo/image-20210220175112752.png"&gt;&lt;/p&gt;
&lt;h2 id="3-继承-factorybean"&gt;3. 继承 FactoryBean&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20210220175608997" loading="lazy" src="https://img.ggball.top/picGo/image-20210220175608997.png"&gt;&lt;/p&gt;
&lt;p&gt;结果&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210220175631984" loading="lazy" src="https://img.ggball.top/picGo/image-20210220175631984.png"&gt;&lt;/p&gt;
&lt;h2 id="4-继承beandefinitionregistrypostprocessor"&gt;4. 继承BeanDefinitionRegistryPostprocessor&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image-20210220182750446" loading="lazy" src="https://img.ggball.top/picGo/image-20210220182750446.png"&gt;&lt;/p&gt;</description></item><item><title>springIOC</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springioc/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springioc/</guid><description/></item><item><title>spring的refresh方法解析</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84refresh%E6%96%B9%E6%B3%95%E8%A7%A3%E6%9E%90/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E7%9A%84refresh%E6%96%B9%E6%B3%95%E8%A7%A3%E6%9E%90/</guid><description>&lt;p&gt;refresh方法会刷新spring的上下文&lt;/p&gt;
&lt;p&gt;里面有多达13种方法，一一解析&lt;/p&gt;
&lt;h2 id="preparerefresh方法"&gt;prepareRefresh方法&lt;/h2&gt;
&lt;p&gt;表示在真正做refresh操作之前需要准备做的事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置Spring容器的启动时间，&lt;/li&gt;
&lt;li&gt;开启活跃状态，撤销关闭状态，。&lt;/li&gt;
&lt;li&gt;初始化context environment（上下文环境）中的占位符属性来源。&lt;/li&gt;
&lt;li&gt;验证环境信息里一些必须存在的属性&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * Prepare this context for refreshing, setting its startup date and
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * active flag as well as performing any initialization of property sources.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prepareRefresh&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Switch to active.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 记录刷新开始时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startupDate&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 上下文活动状态设置为开启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;closed&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;active&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (logger.&lt;span style="color:#a6e22e"&gt;isDebugEnabled&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (logger.&lt;span style="color:#a6e22e"&gt;isTraceEnabled&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; logger.&lt;span style="color:#a6e22e"&gt;trace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Refreshing &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; logger.&lt;span style="color:#a6e22e"&gt;debug&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Refreshing &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; getDisplayName());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Initialize any placeholder property sources in the context environment.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 初始化上下文中占位符资源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initPropertySources();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Validate that all properties marked as required are resolvable:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//验证所有标记为必需的属性都是可解析的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// see ConfigurablePropertyResolver#setRequiredProperties&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; getEnvironment().&lt;span style="color:#a6e22e"&gt;validateRequiredProperties&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Store pre-refresh ApplicationListeners...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 准备预存的监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;earlyApplicationListeners&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;earlyApplicationListeners&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; LinkedHashSet&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;applicationListeners&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Reset local application listeners to pre-refresh state.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 不为空 则监听器重置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;applicationListeners&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;applicationListeners&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;addAll&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;earlyApplicationListeners&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Allow for the collection of early ApplicationEvents,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 为applicaion事件准备的集合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// to be published once the multicaster is available...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 一旦广播器可用，application事件就会被push进去&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;earlyApplicationEvents&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; LinkedHashSet&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>spring声明式事务失效原因</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E5%A3%B0%E6%98%8E%E5%BC%8F%E4%BA%8B%E5%8A%A1%E5%A4%B1%E6%95%88%E5%8E%9F%E5%9B%A0/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E5%A3%B0%E6%98%8E%E5%BC%8F%E4%BA%8B%E5%8A%A1%E5%A4%B1%E6%95%88%E5%8E%9F%E5%9B%A0/</guid><description>&lt;h1 id="事务失效的原因"&gt;事务失效的原因&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2 id="数据库引擎不支持事务"&gt;数据库引擎不支持事务&lt;/h2&gt;
&lt;p&gt;（这里以 MySQL 为例，其 MyISAM 引擎是不支持事务操作的，InnoDB 才是支持事务的引擎，一般要支持事务都会使用 InnoDB）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id="没有被-spring-管理"&gt;没有被 Spring 管理&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id="方法不是-public的--该异常一般情况都会被编译器帮忙识别"&gt;方法不是 public的 &amp;ndash; 该异常一般情况都会被编译器帮忙识别&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.&lt;/p&gt;</description></item><item><title>spring事务实战</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E4%BA%8B%E5%8A%A1%E5%AE%9E%E6%88%98/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E4%BA%8B%E5%8A%A1%E5%AE%9E%E6%88%98/</guid><description>&lt;h2 id="事务隔离级别"&gt;事务隔离级别&lt;/h2&gt;
&lt;p&gt;PROPAGATION_REQUIRED&lt;/p&gt;
&lt;p&gt;如果当前没有事务，就创建一个新事务，如果当前存在事务，就加入该事务，这是最常见的选择，也是Spring默认的事务传播行为。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个service内，方法A和方法B事务隔离级别都是REQUIRED，insertAAndB方法无事务&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(propagation &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Propagation.&lt;span style="color:#a6e22e"&gt;REQUIRED&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertA&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; User user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user.&lt;span style="color:#a6e22e"&gt;setAge&lt;/span&gt;(1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user.&lt;span style="color:#a6e22e"&gt;setName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; userDao.&lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(user);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// A方法抛异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1&lt;span style="color:#f92672"&gt;/&lt;/span&gt;0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(propagation &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Propagation.&lt;span style="color:#a6e22e"&gt;REQUIRED&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertB&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TUser user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TUser();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user.&lt;span style="color:#a6e22e"&gt;setAge&lt;/span&gt;(1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user.&lt;span style="color:#a6e22e"&gt;setName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tUserDao.&lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(user);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertAAndB&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; insertA();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; insertB();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;------------------&lt;/span&gt;分界线&lt;span style="color:#f92672"&gt;---------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertAAndB&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 一个service内 事务传播行为都是required 测试方法A有异常 方法A成功执行，方法B因为异常未执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; transactionTestAService.&lt;span style="color:#a6e22e"&gt;insertAAndB&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;分析：方法A声明了事务，但是因为一个service内，方法 insertAAndB 调用了 方法A和方法B，属于自身调用，事务失效，所以方法A抛异常未回滚。&lt;/p&gt;</description></item><item><title>tensorflow知识点</title><link>https://www.ggball.top/notes/tensorflow/tensorflow%E7%9F%A5%E8%AF%86%E7%82%B9/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/tensorflow/tensorflow%E7%9F%A5%E8%AF%86%E7%82%B9/</guid><description>&lt;h1 id="模块与架构"&gt;模块与架构&lt;/h1&gt;
&lt;p&gt;&lt;img alt="image-20210801010006446" loading="lazy" src="https://img.ggball.top/picGo/image-20210801010006446.png"&gt;&lt;/p&gt;
&lt;h1 id="数据流图"&gt;数据流图&lt;/h1&gt;
&lt;p&gt;·&lt;/p&gt;</description></item><item><title>window10防止c盘镜像存放</title><link>https://www.ggball.top/posts/docker/window10%E9%98%B2%E6%AD%A2c%E7%9B%98%E9%95%9C%E5%83%8F%E5%AD%98%E6%94%BE/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/posts/docker/window10%E9%98%B2%E6%AD%A2c%E7%9B%98%E9%95%9C%E5%83%8F%E5%AD%98%E6%94%BE/</guid><description/></item><item><title>搭建tensorFlow环境</title><link>https://www.ggball.top/notes/tensorflow/%E6%90%AD%E5%BB%BAtensorflow%E7%8E%AF%E5%A2%83/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/tensorflow/%E6%90%AD%E5%BB%BAtensorflow%E7%8E%AF%E5%A2%83/</guid><description>&lt;p&gt;docker安装带有jupyter notebook的版本&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker pull tensorflow/tensorflow:latest-py3-jupyter
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启动&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-- 2.0
docker run -it --name tensorflow2.0 -v D:\project\py\tensorFlow\notebooks\data:/tf/notebooks -p 8888:8888 tensorflow/tensorflow:nightly-jupyter
-- 1.0
docker run -it --name tensorflow1.0 -p 8888:8888 tensorflow/tensorflow:1.13.0rc1-py3-jupyter
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注意：这里映射容器里的路径必须为 &lt;code&gt;/tf/&lt;/code&gt; 下面的，否则notebooke 打开会找不到对应宿主机的路径。&lt;/p&gt;</description></item><item><title>防火墙操作</title><link>https://www.ggball.top/notes/linux/%E9%98%B2%E7%81%AB%E5%A2%99%E6%93%8D%E4%BD%9C/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/linux/%E9%98%B2%E7%81%AB%E5%A2%99%E6%93%8D%E4%BD%9C/</guid><description>&lt;h2 id="一下面是red-hatcentos7关闭防火墙的命令"&gt;一、&lt;strong&gt;下面是red hat/CentOs7关闭防火墙的命令!&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1:查看防火状态&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;systemctl status firewalld&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;service iptables status&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2:暂时关闭防火墙&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;systemctl stop firewalld&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;*service iptables stop*&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3:永久关闭防火墙&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;systemctl disable firewalld&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;*chkconfig iptables off*&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4:重启防火墙&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>河狸家-2021-4-13</title><link>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E6%B2%B3%E7%8B%B8%E5%AE%B6-2021-4-13/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E9%9D%A2%E8%AF%95/%E6%B2%B3%E7%8B%B8%E5%AE%B6-2021-4-13/</guid><description>&lt;h1 id="面试过程"&gt;面试过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;先自我介绍&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;先聊项目&lt;/p&gt;
&lt;p&gt;谈谈你项目里负责的模块&lt;/p&gt;
&lt;p&gt;开始追着项目模块细问&lt;/p&gt;
&lt;p&gt;谈到多线程更新缓存数据时，被问到会不会有并发的问题，怎么解决（主要是redis更新操作不是原子性的，可能存在并发操作）&lt;/p&gt;</description></item><item><title>简单实现web服务器</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/tomcat%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C/%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0web%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/tomcat%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C/%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0web%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>&lt;h1 id="实现简单的web服务器"&gt;实现简单的web服务器&lt;/h1&gt;
&lt;p&gt;既然需要手动实现一个web服务器，那么先要了解什么是web服务器?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;web服务器&lt;/strong&gt;：严格意义上Web服务器&lt;strong&gt;只负责处理HTTP协议&lt;/strong&gt;，只能发送静态页面的内容。而JSP，ASP，PHP等动态内容需要通过CGI、FastCGI、ISAPI等接口交给其他程序去处理。这个&lt;strong&gt;其他程序&lt;/strong&gt;就是应用服务器。比如Web服务器包括&lt;strong&gt;Nginx&lt;/strong&gt;，&lt;strong&gt;Apache&lt;/strong&gt;，&lt;strong&gt;IIS&lt;/strong&gt;等。而应用服务器包括&lt;strong&gt;WebLogic&lt;/strong&gt;，&lt;strong&gt;JBoss&lt;/strong&gt;等。应用服务器一般也支持HTTP协议，因此界限没这么清晰。但是应用服务器的HTTP协议部分仅仅是支持，一般不会做特别优化，所以很少有见Tomcat直接暴露给外面，而是和Nginx、Apache等配合，只让Tomcat处理JSP和Servlet部分&lt;/p&gt;</description></item><item><title>建立servlet容器</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/tomcat%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C/%E5%BB%BA%E7%AB%8Bservlet%E5%AE%B9%E5%99%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/tomcat%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C/%E5%BB%BA%E7%AB%8Bservlet%E5%AE%B9%E5%99%A8/</guid><description>&lt;p&gt;上一节&lt;a href="./%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0web%E6%9C%8D%E5%8A%A1%E5%99%A8.md"&gt;实现简单的web容器&lt;/a&gt;，我们已经实现了一个简单的web服务器，客户端可以请求服务器上的静态文件，然后响应给客户端。&lt;/p&gt;
&lt;p&gt;现在，我们需要再加一个功能，就是去请求一个操作，借助逻辑操作，帮我们完成一些事情，这时候就要使用servlet啦&lt;/p&gt;
&lt;h2 id="什么是servlet"&gt;什么是servlet&lt;/h2&gt;
&lt;p&gt;官方解释：&lt;/p&gt;
&lt;p&gt;Servlet是sun公司提供的一门用于开发动态web资源的技术。
　　Sun公司在其API中提供了一个servlet接口，用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据)，需要完成以下2个步骤：
　　1、编写一个Java类，实现servlet接口。
　　2、把开发好的Java类部署到web服务器中。
　　按照一种约定俗成的称呼习惯，通常我们也把实现了servlet接口的java程序，称之为Servlet&lt;/p&gt;</description></item><item><title>类加载器</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/jvm%E8%B0%83%E4%BC%98/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8/</guid><description>&lt;p&gt;&lt;img alt="20230531010103" loading="lazy" src="https://img.ggball.top/picGo/20230531010103.png"&gt;&lt;/p&gt;
&lt;h1 id="jvm类加载器"&gt;jvm类加载器&lt;/h1&gt;
&lt;h2 id="什么是类加载器"&gt;什么是类加载器&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;JVM（Java虚拟机）类加载器（ClassLoader）是Java运行时环境中的一个重要组件，负责加载Java类和资源文件。它的主要功能是根据类的全限定名（Fully Qualified Name）查找并加载对应的字节码，并将其转换为可执行的Java类。&lt;/p&gt;</description></item><item><title>数据库小笔记</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%B0%8F%E7%AC%94%E8%AE%B0/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%B0%8F%E7%AC%94%E8%AE%B0/</guid><description>&lt;p&gt;控制台报错如下&lt;/p&gt;
&lt;p&gt;Wed Apr 10 17:59:18 CST 2019 WARN: Establishing SSL connection without server&amp;rsquo;s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn&amp;rsquo;t set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to &amp;lsquo;false&amp;rsquo;. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.&lt;/p&gt;</description></item><item><title>网络协议扫盲</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E6%89%AB%E7%9B%B2/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E6%89%AB%E7%9B%B2/</guid><description>&lt;h1 id="七层模型"&gt;七层模型&lt;/h1&gt;
&lt;p&gt;七层模型，也称为OSI（Open System Interconnection）参考模型，是国际标准化组织（ISO）制定的一个用于计算机或通讯系统间互联的标准体系。它是一个七层的、抽象的模型体，不仅包括一系列抽象的术语或概念，也包括具体的协议。
ISO 就是 Internationalization Standard Organization（国际标准组织）&lt;/p&gt;</description></item><item><title>线程池</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%B1%A0/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%B1%A0/</guid><description>&lt;h2 id="线程池是如何创建的"&gt;线程池是如何创建的？&lt;/h2&gt;
&lt;p&gt;JAVA中创建线程池主要有两类方法，一类是&lt;code&gt;通过Executors工厂类提供的方法&lt;/code&gt;，该类提供了4种不同的线程池可供使用。另一类是通过&lt;code&gt;ThreadPoolExecutor类&lt;/code&gt;进行自定义创建。&lt;/p&gt;</description></item><item><title>线程池操作数据库造成死锁</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%B1%A0%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%E9%80%A0%E6%88%90%E6%AD%BB%E9%94%81/</link><pubDate>Fri, 08 Oct 2021 19:46:04 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%BA%BF%E7%A8%8B%E6%B1%A0%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%E9%80%A0%E6%88%90%E6%AD%BB%E9%94%81/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;一次遇到一个很有意思的现象，当我狂点分页的时候，因为一个接口返回超时了，过了一会系统崩了，任何请求都不会进来？？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我就想当好奇了，每个请求都是一个线程，怎么会影响到其他的任务呢？于是我就抱着好奇的心理开始了查bug的旅程&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>mysql导入导出</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA/</link><pubDate>Mon, 30 Aug 2021 19:15:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA/</guid><description>&lt;h2 id="mysqldump-导入导出"&gt;mysqldump 导入导出&lt;/h2&gt;
&lt;h3 id="到出"&gt;到出&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mysqldump --column-statistics=0 -uroot -hmsite-server.wonderlandnet.cn -psckj123456 prj_shangye_new_test &amp;gt; C:\Users\DELL\Desktop\md\db\test.sql
-- 线上
mysqldump --column-statistics=0 -usysa -hrm-bp11j9r390x32c307o.mysql.rds.aliyuncs.com -pSckj@123456 prj_shangye_new &amp;gt; C:\Users\DELL\Desktop\md\db\test_online.sql
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;解释：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;--column-statistics=0 因为新版的mysqldump默认启用了一个新标志，通过- -column-statistics=0来禁用他
-u用户名
-h 地址
-p 密码
数据库
&amp;gt; 目标地址
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="导入"&gt;导入&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mysql -uroot -proot -h127.0.0.1 -P3306 表名&amp;lt;C:\Users\DELL\Desktop\md\db\test.sql
-- 线上
mysql -uroot -proot -h127.0.0.1 -P3306 shangye_test&amp;lt;C:\Users\DELL\Desktop\md\db\test_online.sql
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;mysql -uroot -psckj123456 -hmsite-server.wonderlandnet.cn -P3306 prj_shangye_new_dev&amp;lt;C:\Users\DELL\Desktop\md\db\test.sql、&lt;/p&gt;</description></item><item><title>mysql服务</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E6%9C%8D%E5%8A%A1/</link><pubDate>Mon, 30 Aug 2021 19:15:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E6%9C%8D%E5%8A%A1/</guid><description>&lt;p&gt;windows下服务启动&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;net start mysql
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>mysql之sql_mode</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Bsql-mode/</link><pubDate>Mon, 30 Aug 2021 19:15:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mysql%E4%B9%8Bsql-mode/</guid><description>&lt;h1 id="msql的sql_mode修改"&gt;Msql的sql_mode修改&lt;/h1&gt;
&lt;h3 id="问题复现"&gt;问题复现&lt;/h3&gt;
&lt;p&gt;今天突然发现MySQL服务器升级之后&lt;code&gt;sql_mode&lt;/code&gt;变成宽松摸索了，危害如下：
&lt;img alt="img" loading="lazy" src="https://img2018.cnblogs.com/blog/1127869/201902/1127869-20190214132637606-1534393261.png"&gt;&lt;/p&gt;
&lt;h3 id="临时解决"&gt;临时解决&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;set global sql_mode='strict_trans_tables'&lt;/code&gt;（阿里服务器默认是：&lt;code&gt;strict_trans_tables&lt;/code&gt;）
&lt;img alt="img" loading="lazy" src="https://img2018.cnblogs.com/blog/1127869/201902/1127869-20190214132648116-477656439.png"&gt;&lt;/p&gt;</description></item><item><title>sql函数</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/sql%E5%87%BD%E6%95%B0/</link><pubDate>Mon, 30 Aug 2021 19:15:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/sql%E5%87%BD%E6%95%B0/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 查询字节，字符长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;length&lt;/span&gt;(orderBillId),&lt;span style="color:#66d9ef"&gt;char_length&lt;/span&gt;(orderBillId) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; tb_order_nc_history &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;108&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>每年，每季，每月，每周的最后一天</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E6%AF%8F%E5%B9%B4%E6%AF%8F%E5%AD%A3%E6%AF%8F%E6%9C%88%E6%AF%8F%E5%91%A8%E7%9A%84%E6%9C%80%E5%90%8E%E4%B8%80%E5%A4%A9/</link><pubDate>Mon, 30 Aug 2021 19:15:17 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/%E6%AF%8F%E5%B9%B4%E6%AF%8F%E5%AD%A3%E6%AF%8F%E6%9C%88%E6%AF%8F%E5%91%A8%E7%9A%84%E6%9C%80%E5%90%8E%E4%B8%80%E5%A4%A9/</guid><description>&lt;p&gt;当年第一天：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT DATE_SUB(CURDATE(),INTERVAL dayofyear(now())-1 DAY);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当年最后一天：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT concat(YEAR(now()),&amp;#39;-12-31&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当前week的第一天：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 1 DAY);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当前week的最后一天：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) - 5 DAY);
SELECT SUBDATE(CURDATE(),DATE_FORMAT(CURDATE(),&amp;#39;%w&amp;#39;)-7) -- 有效
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;前一week的第一天：&lt;/p&gt;
&lt;p&gt;前一week的第一天：&lt;/p&gt;</description></item><item><title>7</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/centos7%E6%90%AD%E5%BB%BAmysql57/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/centos7%E6%90%AD%E5%BB%BAmysql57/</guid><description>&lt;h3 id="搭建教程"&gt;搭建教程&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.jianshu.com/p/1dab9a4d0d5f"&gt;https://www.jianshu.com/p/1dab9a4d0d5f&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="mysql-server下载过慢问题解决"&gt;mysql-server下载过慢问题解决&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://blog.csdn.net/downmoon/article/details/103159231"&gt;https://blog.csdn.net/downmoon/article/details/103159231&lt;/a&gt;&lt;/p&gt;</description></item><item><title>es640安装</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/es640%E5%AE%89%E8%A3%85/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/es640%E5%AE%89%E8%A3%85/</guid><description>&lt;h2 id="es搭建"&gt;es搭建&lt;/h2&gt;
&lt;h2 id="创建目录"&gt;创建目录&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir /opt/software/skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="上传文件"&gt;上传文件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;es版本 elasticsearch-6.4.0.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-4-0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;skyWalking版本 apache-skywalking-apm-6.5.0.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https://archive.apache.org/dist/skywalking/6.5.0/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="添加es用户"&gt;添加es用户&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@localhost ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# useradd es&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@localhost ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# passwd es&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;更改用户 es 的密码 。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;新的 密码：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;重新输入新的 密码：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;passwd：所有的身份验证令牌已经成功更新。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 修改es目录的拥有者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chown -R es elasticsearch-6.4.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="上传文件-1"&gt;上传文件&lt;/h2&gt;
&lt;p&gt;上传文件至/opt/software/skywalking&lt;/p&gt;</description></item><item><title>frp</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/frp/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/frp/</guid><description>&lt;h1 id="服务端简易版配置"&gt;服务端简易版配置&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bind_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# http和https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vhost_http_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8090&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vhost_https_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 连接认证token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#token = 12345678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 子域名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#subdomain_host = frp.ggball.top&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 自定义404 页面，要用绝对路径哦！&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;custom_404_page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; /usr/local/frp_0.34.2_linux_amd64/404.html
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# dashboard图形管理页面&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dashboard_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;81&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dashboard_user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; admin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dashboard_pwd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; admin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;~
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="客户端简易版配置"&gt;客户端简易版配置&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;common&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server_addr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1.15.141.114
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 配置ssh服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;ssh&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_ip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;remote_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;23&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#skywalking&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;skywalking&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_ip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9010&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;remote_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;common&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server_addr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1.15.141.114
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 如果服务端设置了token，这里也要加上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#token = 1234568&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 内网穿透名称&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;gitlab_8090&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_ip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8090&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;remote_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8090&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;ssh_24&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_ip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;remote_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;code_server_8083&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_ip &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8083&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;remote_port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8083&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="利用systemctl-自启动"&gt;利用systemctl 自启动&lt;/h1&gt;
&lt;h2 id="服务端"&gt;服务端&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建后台启动模版&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /etc/systemd/system/frps.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 内容如下：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Unit&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;frps
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;After&lt;span style="color:#f92672"&gt;=&lt;/span&gt;network.target
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Service&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /usr/local/src/frp_0.34.2_linux_amd64 frp所在位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ExecStart&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/src/frp_0.34.2_linux_amd64/frps -c /usr/local/src/frp_0.34.2_linux_amd64/frps.ini
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Install&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WantedBy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 启动测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl start frps.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查看启动状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status frps.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开机自启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl enable frps.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="客户端"&gt;客户端&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建后台启动模版&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /etc/systemd/system/frpc.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 内容如下：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Unit&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;frpc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;After&lt;span style="color:#f92672"&gt;=&lt;/span&gt;network.target
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Service&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /opt/frp/frp_0.34.2_linux_amd64 frp所在位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ExecStart&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/software/frp_0.34.2_linux_amd64/frpc -c /opt/software/frp_0.34.2_linux_amd64/frpc.ini
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;Install&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WantedBy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 启动测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl start frpc.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查看启动状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status frpc.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开机自启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl enable frpc.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl restart frpc.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;demo&lt;/p&gt;</description></item><item><title>gitlab_docker安装</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/gitlab-docker%E5%AE%89%E8%A3%85/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/gitlab-docker%E5%AE%89%E8%A3%85/</guid><description>&lt;h2 id="一安装gitlab"&gt;一、安装Gitlab&lt;/h2&gt;
&lt;h3 id="1拉取镜像并启动"&gt;1、拉取镜像并启动&lt;/h3&gt;
&lt;p&gt;由于服务器的&lt;code&gt;80&lt;/code&gt;端口可能被占用，所以这里我们改成了其他端口来启动&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -d -p 2443:443 -p 8090:80 -p 2222:22 --name gitlab --restart always \
-v/opt/gitlab/config:/etc/gitlab \
-v /opt/gitlab/logs:/var/log/gitlab \
-v /opt/gitlab/data:/var/opt/gitlab \
beginor/gitlab-ce
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2修改配置文件"&gt;2、修改配置文件&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;提示&lt;/strong&gt;：等待docker运行gitlab一小段时间后在操作，否则可能出现文件找不到&lt;/p&gt;</description></item><item><title>nginx</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/nginx/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/nginx/</guid><description>&lt;h1 id="nginx基本概念"&gt;nginx基本概念&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;什么是nginx&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Nginx是一款&lt;a href="https://baike.baidu.com/item/%E8%BD%BB%E9%87%8F%E7%BA%A7/10002835"&gt;轻量级&lt;/a&gt;的&lt;a href="https://baike.baidu.com/item/Web/150564"&gt;Web&lt;/a&gt; 服务器/&lt;a href="https://baike.baidu.com/item/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/7793488"&gt;反向代理&lt;/a&gt;服务器及&lt;a href="https://baike.baidu.com/item/%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6/111106"&gt;电子邮件&lt;/a&gt;（IMAP/POP3）代理服务器，在BSD-like 协议下发行。其特点是占有内存少，&lt;a href="https://baike.baidu.com/item/%E5%B9%B6%E5%8F%91/11024806"&gt;并发&lt;/a&gt;能力强，事实上nginx的并发能力在同类型的网页服务器中表现较好，中国大陆使用nginx网站用户有：百度、&lt;a href="https://baike.baidu.com/item/%E4%BA%AC%E4%B8%9C/210931"&gt;京东&lt;/a&gt;、&lt;a href="https://baike.baidu.com/item/%E6%96%B0%E6%B5%AA/125692"&gt;新浪&lt;/a&gt;、&lt;a href="https://baike.baidu.com/item/%E7%BD%91%E6%98%93/185754"&gt;网易&lt;/a&gt;、&lt;a href="https://baike.baidu.com/item/%E8%85%BE%E8%AE%AF/112204"&gt;腾讯&lt;/a&gt;、&lt;a href="https://baike.baidu.com/item/%E6%B7%98%E5%AE%9D/145661"&gt;淘宝&lt;/a&gt;等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;反向代理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;先来说&lt;strong&gt;正向代理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;概念：客户端（浏览器） 通过代理服务器 访问 目标 服务器（隐藏客户端）&lt;/p&gt;</description></item><item><title>ngrok搭建</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/ngrok%E6%90%AD%E5%BB%BA/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/ngrok%E6%90%AD%E5%BB%BA/</guid><description>&lt;p&gt;/usr/local/src/ngrok&lt;/p&gt;
&lt;p&gt;/usr/local/src/ngrok/bin/ngrokd -tlsKey=&amp;ldquo;assets/server/tls/snakeoil.key&amp;rdquo; -tlsCrt=&amp;ldquo;assets/server/tls/snakeoil.crt&amp;rdquo; -domain=&amp;quot;$NGROK_DOMAIN&amp;quot; -httpAddr=&amp;quot;:80&amp;quot; -httpsAddr=&amp;quot;:443&amp;quot; -tunnelAddr=&amp;quot;:4443&amp;quot;&lt;/p&gt;
&lt;p&gt;/usr/local/src/ngrok/bin/ngrokd -domain=&amp;ldquo;ngrok.kioye.cn&amp;rdquo; -httpAddr=&amp;quot;:80&amp;quot; -httpsAddr=&amp;quot;:443&amp;quot; -tunnelAddr=&amp;quot;:4443&amp;quot;&lt;/p&gt;
&lt;h1 id="go换国内源解决go-get--u-问题"&gt;Go换国内源解决go get -u 问题&lt;/h1&gt;
&lt;p&gt;Go版本1.13及以上：
Windows在编译器终端执行以下操作：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;MacOS或Linux&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;export GO111MODULE=off
export GOPROXY=https://goproxy.cn
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者&lt;/p&gt;</description></item><item><title>Onedrive云盘同步本地文件夹（适用于Windows）</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/onedrive%E4%BA%91%E7%9B%98%E5%90%8C%E6%AD%A5%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E5%A4%B9%E9%80%82%E7%94%A8%E4%BA%8Ewindows/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/onedrive%E4%BA%91%E7%9B%98%E5%90%8C%E6%AD%A5%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E5%A4%B9%E9%80%82%E7%94%A8%E4%BA%8Ewindows/</guid><description>&lt;p&gt;0 前言
购买了Office365家庭版之后试用了一下订阅自带的云盘，充分体会到了Onedrive的潜力。办公文档上云，妈妈再也不用担心系统崩溃文件丢失啦~&lt;/p&gt;</description></item><item><title>oneUploader搭建</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/oneuploader%E6%90%AD%E5%BB%BA/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/oneuploader%E6%90%AD%E5%BB%BA/</guid><description>&lt;p&gt;&lt;strong&gt;一、OneDriveUploader介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;支持上传文件和文件夹到指定目录,并保持上传前的目录结构.
支持命令参数使用, 方便外部程序调用.
支持自定义上传分块大小.
支持多线程上传(多文件同时上传).
支持根据文件大小动态调整重试次数&lt;/p&gt;</description></item><item><title>redis</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/redis/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/redis/</guid><description>&lt;h1 id="redis"&gt;redis&lt;/h1&gt;
&lt;h2 id="什么是redis"&gt;什么是redis？&lt;/h2&gt;
&lt;p&gt;Redis是一个内存中数据结构存储，用作数据库，缓存和消息代理&lt;/p&gt;
&lt;h2 id="redis的特点"&gt;redis的特点&lt;/h2&gt;
&lt;p&gt;异常快
支持丰富的数据类型
操作都是原子性操作
多实用工具&lt;/p&gt;
&lt;h2 id="redis的五个数据结构"&gt;redis的五个数据结构&lt;/h2&gt;
&lt;p&gt;String&lt;/p&gt;
&lt;p&gt;list 双向链表&lt;/p&gt;
&lt;p&gt;hash 数组+链表&lt;/p&gt;
&lt;p&gt;set&lt;/p&gt;</description></item><item><title>skyWalking搭建</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/skywalking%E6%90%AD%E5%BB%BA/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/skywalking%E6%90%AD%E5%BB%BA/</guid><description>&lt;h1 id="基于-docker-部署-skywalking-并实现-springboot-全链路监控"&gt;基于 docker 部署 skywalking 并实现 SpringBoot 全链路监控&lt;/h1&gt;
&lt;h1 id="一安装环境部署"&gt;一、安装环境部署&lt;/h1&gt;
&lt;p&gt;下载镜像：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ docker pull docker pull elasticsearch:7.10.1
$ docker pull apache/skywalking-oap-server:8.3.0-es7
$ docker pull apache/skywalking-ui:8.3.0
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="11-docker-中安装-elasticsearch762方式一"&gt;1.1 Docker 中安装 Elasticsearch7.6.2（方式一）&lt;/h2&gt;
&lt;p&gt;安装 Elasticsearch&lt;/p&gt;
&lt;p&gt;注意：使用版本为 7.6.2，你可以选择其他版本
拉取镜像&lt;/p&gt;</description></item><item><title>skyWalking搭配springboot应用</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/skywalking%E6%90%AD%E9%85%8Dspringboot%E5%BA%94%E7%94%A8/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/skywalking%E6%90%AD%E9%85%8Dspringboot%E5%BA%94%E7%94%A8/</guid><description>&lt;h2 id="上传springboot的jar包"&gt;上传springboot的jar包&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /opt/jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;![image-20210616225104486](skyWalking搭配springboot应用 .assets/image-20210616225104486.png)&lt;/p&gt;
&lt;h2 id="修改agent配置"&gt;修改agent配置&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /opt/software/skywalking/apache-skywalking-apm-bin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir /opt/software/skywalking/apache-skywalking-apm-bin/agent-mysql-boot
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp /opt/software/skywalking/apache-skywalking-apm-bin/agent/* /opt/software/skywalking/apache-skywalking-apm-bin/agent-mysql-boot
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 修改应用名称&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vim /opt/software/skywalking/apache-skywalking-apm-bin/agent-mysql-boot/config/agent.config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;![image-20210616230243851](skyWalking搭配springboot应用 .assets/image-20210616230243851.png)&lt;/p&gt;</description></item><item><title>sublime操作</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/sublime%E6%93%8D%E4%BD%9C/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/sublime%E6%93%8D%E4%BD%9C/</guid><description>&lt;h2 id="sublime-text行首行尾批量编辑"&gt;Sublime text!行首,行尾,批量编辑!&lt;/h2&gt;
&lt;p&gt;Ctrl + H&lt;/p&gt;
&lt;p&gt;打开左下角 &lt;code&gt;.*&lt;/code&gt;正则匹配&lt;/p&gt;
&lt;p&gt;输入^，然后Find All，查找所有的行首&lt;/p&gt;
&lt;p&gt;输入$，然后Find All，查找所有的行尾&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20210526102439694" loading="lazy" src="https://img.ggball.top/picGo/image-20210526102439694.png"&gt;&lt;/p&gt;</description></item><item><title>unblockMusic</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/unblockmusic/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/unblockmusic/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nohup node ***.js &amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;nohup node /usr/local/unblockmusic/UnblockNeteaseMusic/app.js -p 4567 -f 59.111.181.60 &amp;amp;&lt;/p&gt;</description></item><item><title>win10右键新建md文件</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/win10%E5%8F%B3%E9%94%AE%E6%96%B0%E5%BB%BAmd%E6%96%87%E4%BB%B6/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/win10%E5%8F%B3%E9%94%AE%E6%96%B0%E5%BB%BAmd%E6%96%87%E4%BB%B6/</guid><description>&lt;h2 id="windows下右键新建md文件教程"&gt;Windows下右键新建.md文件教程&lt;/h2&gt;
&lt;p&gt;发表于 2018-12-29 | 更新于: 2019-09-03 | 分类于 &lt;a href="https://stepneverstop.github.io/categories/%E5%B0%8F%E7%9F%A5%E8%AF%86/"&gt;小知识&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;字数统计: 443 | 阅读时长 ≈ 1&lt;/p&gt;
&lt;p&gt;原本创建.md文件需要首先打开markdown文本编辑器，如Typora，或者新建.txt文件然后修改后缀名，本文介绍了如何在Windows操作系统中添加右键创建.md文件的方法。&lt;/p&gt;</description></item><item><title>yarn安装</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/yarn%E5%AE%89%E8%A3%85/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/yarn%E5%AE%89%E8%A3%85/</guid><description>&lt;h1 id="yarn的简介"&gt;yarn的简介：&lt;/h1&gt;
&lt;p&gt;Yarn是facebook发布的一款取代npm的包管理工具。&lt;/p&gt;
&lt;h1 id="yarn的特点"&gt;yarn的特点：&lt;/h1&gt;
&lt;p&gt;速度超快。
Yarn 缓存了每个下载过的包，所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率，因此安装速度更快。
超级安全。
在执行代码之前，Yarn 会通过算法校验每个安装包的完整性。
超级可靠。
使用详细、简洁的锁文件格式和明确的安装算法，Yarn 能够保证在不同系统上无差异的工作。&lt;/p&gt;</description></item><item><title>搭建cloudreve并选择onedrive作为加载策略</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%90%AD%E5%BB%BAcloudreve%E5%B9%B6%E9%80%89%E6%8B%A9onedrive%E4%BD%9C%E4%B8%BA%E5%8A%A0%E8%BD%BD%E7%AD%96%E7%95%A5/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%90%AD%E5%BB%BAcloudreve%E5%B9%B6%E9%80%89%E6%8B%A9onedrive%E4%BD%9C%E4%B8%BA%E5%8A%A0%E8%BD%BD%E7%AD%96%E7%95%A5/</guid><description>&lt;h1 id="cloudreve-是什么"&gt;&lt;strong&gt;Cloudreve 是什么？&lt;/strong&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Cloudreve 可以让您快速搭建起公私兼备的网盘系统。Cloudreve 在底层支持不同的云存储平台，用户在实际使用时无须关心物理存储方式。你可以使用 Cloudreve 搭建个人用网盘、文件分享系统，亦或是针对大小团体的公有云系统。&lt;/p&gt;</description></item><item><title>服务器管理</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AE%A1%E7%90%86/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AE%A1%E7%90%86/</guid><description>&lt;p&gt;腾讯云&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;redis&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#安装目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/redis
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#启动命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>网盘</title><link>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E7%BD%91%E7%9B%98/</link><pubDate>Mon, 30 Aug 2021 19:15:16 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/%E7%BD%91%E7%9B%98/</guid><description>&lt;h1 id="oneindex"&gt;oneindex&lt;/h1&gt;
&lt;p&gt;也可以支持Docker安装：&lt;/p&gt;
&lt;p&gt;从docker仓库获取镜像：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;docker pull yinaoxiong/oneindex&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;或者从源码构建镜像：&lt;/p&gt;
&lt;p&gt;git clone &lt;a href="https://github.com/donwa/oneindex.git"&gt;https://github.com/donwa/oneindex.git&lt;/a&gt;
cd oneindex/
docker build -t your-image-name .&lt;/p&gt;
&lt;p&gt;运行：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;docker run -d -p {open port}:80 &amp;ndash;name {container name} &amp;ndash;restart=always {image name}&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;停止删除容器：&lt;/p&gt;</description></item><item><title>AQS解析</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/aqs%E8%A7%A3%E6%9E%90/</link><pubDate>Thu, 03 Jun 2021 13:42:07 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/aqs%E8%A7%A3%E6%9E%90/</guid><description>&lt;blockquote&gt;
&lt;p&gt;AQS一直是我多线程上不可逾越的鸿沟，每当拿起《Java并发编程艺术》看到这里就会呼呼大睡😢,这次专门做个记录，后面复习用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="概览" loading="lazy" src="https://img.ggball.top/picGo/20230604173417.png"&gt;&lt;/p&gt;
&lt;h2 id="什么是aqs"&gt;什么是AQS&lt;/h2&gt;
&lt;p&gt;AQS（AbstractQueuedSynchronizer）是Java并发包（java.util.concurrent）中提供的一个抽象类，它提供了一种实现同步器（Synchronizer）的框架。&lt;/p&gt;</description></item><item><title>关键字介绍</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%85%B3%E9%94%AE%E5%AD%97%E4%BB%8B%E7%BB%8D/</link><pubDate>Tue, 01 Jun 2021 13:59:21 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%85%B3%E9%94%AE%E5%AD%97%E4%BB%8B%E7%BB%8D/</guid><description>&lt;p&gt;&lt;img alt="20230601232756" loading="lazy" src="https://img.ggball.top/picGo/20230601232756.png"&gt;&lt;/p&gt;
&lt;h1 id="java多线程关键字解析"&gt;java多线程关键字解析&lt;/h1&gt;
&lt;h2 id="synchronized-关键字"&gt;synchronized 关键字&lt;/h2&gt;
&lt;p&gt;&lt;img alt="对象头" loading="lazy" src="https://img.ggball.top/picGo/20230601151743.png"&gt;&lt;/p&gt;
&lt;h3 id="synchronized关键字介绍"&gt;synchronized关键字介绍&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Synchronized关键字是Java中用于实现线程同步的重要特性之一。它可以应用于方法或代码块，用于确保在多线程环境下对共享资源的安全访问。&lt;/p&gt;</description></item><item><title>concurrentHashMap解读</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/concurrenthashmap%E8%A7%A3%E8%AF%BB/</link><pubDate>Mon, 31 May 2021 21:52:41 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/concurrenthashmap%E8%A7%A3%E8%AF%BB/</guid><description>&lt;h2 id="jdk17"&gt;JDK1.7&lt;/h2&gt;
&lt;p&gt;具有分段锁机制，提高并发执行效率，每个段中使用可重入锁进行加锁，&lt;/p&gt;
&lt;p&gt;&lt;img alt="20230531224520" loading="lazy" src="https://img.ggball.top/picGo/20230531224520.png"&gt;
put流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据key的hash值求得segment的位置，trylock()或者scanAndLockForPut()获得segment的锁，再利用hash值，求得桶的下标位置&lt;/li&gt;
&lt;li&gt;如果桶位置首个节点为空，则直接复值，如果不为空，则继续遍历&lt;/li&gt;
&lt;li&gt;比较key和hash值，如果相等，则替换，遍历到最后都不相等，直接添加到链表头部&lt;/li&gt;
&lt;li&gt;查看是否满足扩容条件，满足则扩容，不满足则结束&lt;/li&gt;
&lt;li&gt;释放segment锁&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;scanAndLockForPut 作用就是获取segment的锁，先利用cas，再用lock()（阻塞的），知道获取到锁。&lt;/p&gt;</description></item><item><title>概览</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/%E6%A6%82%E8%A7%88/</link><pubDate>Mon, 31 May 2021 14:11:36 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E9%9B%86%E5%90%88/%E6%A6%82%E8%A7%88/</guid><description>&lt;h1 id="java集合"&gt;java集合&lt;/h1&gt;
&lt;h2 id="set"&gt;Set&lt;/h2&gt;
&lt;h3 id="treeset"&gt;TreeSet&lt;/h3&gt;
&lt;p&gt;基于红黑树实现，支持有序性操作，例如根据一个范围查找元素的操作。但是查找效率不如 HashSet&lt;/p&gt;
&lt;h3 id="hashset"&gt;HashSet&lt;/h3&gt;
&lt;p&gt;HashSet 查找的时间复杂度为 O(1)TreeSet 则为 O(logN)。HashSet 基于哈希表实现，支持快速查找，但不支持有序性操作。并且失去了元素的插入顺序信息，也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。&lt;/p&gt;</description></item><item><title>Java 浅拷贝和深拷贝的理解和实现方式</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/java-%E6%B5%85%E6%8B%B7%E8%B4%9D%E5%92%8C%E6%B7%B1%E6%8B%B7%E8%B4%9D%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/</link><pubDate>Sun, 28 Feb 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/java-%E6%B5%85%E6%8B%B7%E8%B4%9D%E5%92%8C%E6%B7%B1%E6%8B%B7%E8%B4%9D%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/</guid><description>&lt;blockquote&gt;
&lt;p&gt;铺垫知识：Java中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型，在进行赋值操作、用作方法参数或返回值时，会有值传递和引用（地址）传递的差别。&lt;/p&gt;</description></item><item><title>spring模块介绍</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E6%A8%A1%E5%9D%97%E4%BB%8B%E7%BB%8D/</link><pubDate>Sun, 28 Feb 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E6%A8%A1%E5%9D%97%E4%BB%8B%E7%BB%8D/</guid><description>&lt;p&gt;&lt;img alt="spring模块" loading="lazy" src="https://img-blog.csdn.net/20180806221835285?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNzczODYz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70"&gt;&lt;/p&gt;
&lt;h2 id="spring-aop"&gt;spring-aop&lt;/h2&gt;
&lt;p&gt;面向窃密室内编程&lt;/p&gt;
&lt;h2 id="spring-aspects"&gt;spring-aspects&lt;/h2&gt;
&lt;p&gt;Spring提供的对AspectJ框架的整合&lt;/p&gt;
&lt;h2 id="spring-beans"&gt;spring-beans&lt;/h2&gt;
&lt;p&gt;Spring IOC的基础实现，包含访问配置文件、创建和管理bean等。&lt;/p&gt;
&lt;h2 id="spring-context-indexer"&gt;spring-context-indexer&lt;/h2&gt;
&lt;h2 id="spring-context-support"&gt;spring-context-support&lt;/h2&gt;
&lt;p&gt;Spring context的扩展支持，用于MVC方面。&lt;/p&gt;</description></item><item><title>spring语法变化</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E8%AF%AD%E6%B3%95%E5%8F%98%E5%8C%96/</link><pubDate>Sun, 28 Feb 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/spring%E8%AF%AD%E6%B3%95%E5%8F%98%E5%8C%96/</guid><description>&lt;p&gt;&lt;img alt="image-20210228181845604" loading="lazy" src="https://img.ggball.top/image-20210228181845604.png"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java5&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2004&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;枚举&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;泛型&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;注解&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;封箱&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;解箱&lt;span style="color:#960050;background-color:#1e0010"&gt;）…&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java6&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2006&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Override接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java7&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2011&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Diamond语法&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;多Catch&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;Try&lt;span style="color:#960050;background-color:#1e0010"&gt;…&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java8&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2014&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Lambda语法&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;可重复注解&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;类型注解&lt;span style="color:#960050;background-color:#1e0010"&gt;…&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java9&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2017&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;模块化&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;接口私有方法&lt;span style="color:#960050;background-color:#1e0010"&gt;…&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Java10&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;2018&lt;span style="color:#960050;background-color:#1e0010"&gt;）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;局部变量类型推断
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>pg小操作</title><link>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/pg/pg%E5%B0%8F%E6%93%8D%E4%BD%9C/</link><pubDate>Thu, 25 Feb 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E6%95%B0%E6%8D%AE%E5%BA%93/pg/pg%E5%B0%8F%E6%93%8D%E4%BD%9C/</guid><description>&lt;h2 id="pg小操作"&gt;pg小操作&lt;/h2&gt;
&lt;h2 id="postgresql之日期字段统一加一天"&gt;PostgreSQL之日期字段统一加一天&lt;/h2&gt;
&lt;h3 id="提出问题"&gt;&lt;strong&gt;提出问题&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;如何对数据库某一日期字段这一列统一加一天？已经日期操作的复习？？？？&lt;/p&gt;
&lt;h3 id="解决问题"&gt;&lt;strong&gt;解决问题&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;pm_milestone_sign_in是一张数据库表，有个日期字段sign_in_time&lt;/p&gt;</description></item><item><title>npm介绍</title><link>https://www.ggball.top/notes/node/npm%E4%BB%8B%E7%BB%8D/</link><pubDate>Sun, 21 Feb 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/node/npm%E4%BB%8B%E7%BB%8D/</guid><description>&lt;h1 id="npm"&gt;npm&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;nodejs 的包管理工具&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;cnpm 安装&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install -g cnpm -registry=https://registry.npm.taobao.org
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>springboot 深入解析 监听器</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot-%E6%B7%B1%E5%85%A5%E8%A7%A3%E6%9E%90%E7%9B%91%E5%90%AC%E5%99%A8/</link><pubDate>Sun, 31 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot-%E6%B7%B1%E5%85%A5%E8%A7%A3%E6%9E%90%E7%9B%91%E5%90%AC%E5%99%A8/</guid><description>&lt;h1 id="springboot-深入解析-监听器"&gt;springboot 深入解析 监听器&lt;/h1&gt;
&lt;h3 id="文章目录"&gt;文章目录&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#_1"&gt;监听器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#_2"&gt;一、监听器模式介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#_189"&gt;二、系统监听器介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#_282"&gt;三：监听事件触发机制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#_483"&gt;四：自定义监听器&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="监听器"&gt;监听器&lt;/h1&gt;
&lt;h2 id="一监听器模式介绍"&gt;一、监听器模式介绍&lt;/h2&gt;
&lt;p&gt;监听器模式可以用下图来体现：&lt;br&gt;
&lt;img loading="lazy" src="https://img.ggball.top/20200329152324549.png"&gt;&lt;/p&gt;
&lt;p&gt;当运行到关键节点的时候，系统会通过广播器发布相应的事件，而我们系统中存在一些监听器，它们会订阅一些 “感兴趣”（实际是人为设定）的事件。&lt;/p&gt;</description></item><item><title>Conditional 注解</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/conditional%E6%B3%A8%E8%A7%A3/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/conditional%E6%B3%A8%E8%A7%A3/</guid><description>&lt;p&gt;Spring条件注解@Conditional
@Conditional是Spring4新提供的注解，它的作用是根据某个条件创建特定的Bean，通过实现Condition接口，并重写matches接口来构造判断条件。总的来说，就是根据特定条件来控制Bean的创建行为，这样我们可以利用这个特性进行一些自动的配置。&lt;/p&gt;</description></item><item><title>docker 安装相关操作</title><link>https://www.ggball.top/posts/docker/docker%E7%9B%B8%E5%85%B3%E8%BD%AF%E4%BB%B6%E5%AE%89%E8%A3%85/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/posts/docker/docker%E7%9B%B8%E5%85%B3%E8%BD%AF%E4%BB%B6%E5%AE%89%E8%A3%85/</guid><description>&lt;h1 id="安装docker-ce"&gt;安装Docker CE&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://www.cnblogs.com/zlnp/p/15384728.html"&gt;https://www.cnblogs.com/zlnp/p/15384728.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;镜像加速地址&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https://3zne2w5t.mirror.aliyuncs.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="安装centos"&gt;安装centos&lt;/h1&gt;
&lt;h2 id="修改centos的时区手动"&gt;修改centos的时区【手动】&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.进入容器
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 没有新建容器，启动并进入容器内部&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -it 【容器名】 /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 容器正在运行，进入容器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker exec -it 【容器名】/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2.设置时区
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 1、CentOS6、Ubuntu16（有效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 2、CentOS7、RHEL7、Scientific Linux 7、Oracle Linux 7 最好的方法是使用timedatectl命令（未成功）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timedatectl list-timezones |grep Shanghai &lt;span style="color:#75715e"&gt;#查找中国时区的完整名称&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Asia/Shanghai
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timedatectl set-timezone Asia/Shanghai &lt;span style="color:#75715e"&gt;#其他时区以此类推&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 3、直接手动创建软链接（有效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="修改centos的时区-自动版"&gt;修改centos的时区 【自动版】&lt;/h2&gt;
&lt;h3 id="1编写docker-file"&gt;1.编写docker file&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;centos&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 修改为上海时区&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;RUN&lt;/span&gt; /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CMD&lt;/span&gt; echo finish&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;： &lt;code&gt;cmd&lt;/code&gt; 一般放在末尾，只是用一次，因为 &lt;code&gt;cmd&lt;/code&gt; 会被覆盖前面的 &lt;code&gt;run&lt;/code&gt; ， &lt;code&gt;cmd&lt;/code&gt; , &lt;code&gt;envPoint&lt;/code&gt; 命令所覆盖&lt;/p&gt;</description></item><item><title>docker使服务器硬盘挤满</title><link>https://www.ggball.top/posts/docker/docker%E4%BD%BF%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%A1%AC%E7%9B%98%E6%8C%A4%E6%BB%A1/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/posts/docker/docker%E4%BD%BF%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%A1%AC%E7%9B%98%E6%8C%A4%E6%BB%A1/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;使用 命令
df -ik 查看 内存占用情况
后面发现 是 退出容器后 很多容器都没有删除 导致overlay 占用100%
-- 容器和镜像 存在 overlay 这里
// 删除状态为Exited的容器
docker ps -a | grep &amp;#34;Exited&amp;#34; | awk &amp;#39;{print $1 }&amp;#39;|xargs docker rm
// 删除镜像tag为null的镜像
docker rmi -f $(docker images | grep &amp;#34;none&amp;#34; | awk &amp;#39;{print $3}&amp;#39;)
解决！
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="docker-空间使用分析与清理"&gt;&lt;a href="https://developer.aliyun.com/article/272173"&gt;Docker 空间使用分析与清理&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;简介：&lt;/strong&gt; 用户在使用 Docker 部署业务一段时间后，可能会发现宿主节点的磁盘容量持续增长，甚至将磁盘空间耗尽进而引发宿主机异常，进而对业务造成影响。 本文先对 Docker 的空间分析与清理进行说明，然后对容器的磁盘容量限制与使用建议做简要说明。&lt;/p&gt;</description></item><item><title>git问题总结</title><link>https://www.ggball.top/posts/git/git%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/posts/git/git%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93/</guid><description>&lt;h1 id="git问题总结"&gt;git问题总结&lt;/h1&gt;
&lt;h2 id="1-vscode-git-pull-本地代码被覆盖"&gt;1. vscode git pull 本地代码被覆盖&lt;/h2&gt;
&lt;p&gt;今天git pull 本地代码内覆盖问题，因为git pull 之后本地写的代码没了，写了一天的代码 这一下就没了，快哭了。&lt;/p&gt;
&lt;p&gt;我说别急 我帮你查查 ，什么编译器历史啥的都找了 给大家来一个亲测的最好解决的办法。&lt;/p&gt;</description></item><item><title>linux操作命令</title><link>https://www.ggball.top/notes/linux/linux%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/linux/linux%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4/</guid><description>&lt;h1 id="liunx端口c操作"&gt;liunx端口c操作&lt;/h1&gt;
&lt;p&gt;1、开启防火墙&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; systemctl start firewalld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2、开放指定端口&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;5601/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;命令含义：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--zone &lt;span style="color:#75715e"&gt;#作用域&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1935/tcp &lt;span style="color:#75715e"&gt;#添加端口，格式为：端口/通讯协议&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--permanent &lt;span style="color:#75715e"&gt;#永久生效，没有此参数重启后失效&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3、重启防火墙&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;4、查看端口号&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;netstat -ntlp //查看当前所有tcp端口·
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;netstat -ntulp |grep &lt;span style="color:#ae81ff"&gt;9200&lt;/span&gt; //查看所有1935端口使用情况·
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;5、查看开放的端口号&lt;/p&gt;</description></item><item><title>MockMvc介绍</title><link>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/mockmvc%E4%BB%8B%E7%BB%8D/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/posts/%E6%B5%8B%E8%AF%95/mockmvc%E4%BB%8B%E7%BB%8D/</guid><description>&lt;h2 id="mockmvc"&gt;MockMvc&lt;/h2&gt;
&lt;h2 id="1-简介"&gt;1. 简介&lt;/h2&gt;
&lt;p&gt;为何使用MockMvc？&lt;/p&gt;
&lt;p&gt;对模块进行集成测试时，希望能够通过输入URL对Controller进行测试，如果通过启动服务器，建立http client进行测试，这样会使得测试变得很麻烦，比如，启动速度慢，测试验证不方便，依赖网络环境等，所以为了可以对Controller进行测试，我们引入了MockMVC。&lt;/p&gt;</description></item><item><title>SpringBoot 在IDEA中实现热部署 (JRebel实用版)</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot-%E5%9C%A8idea%E4%B8%AD%E5%AE%9E%E7%8E%B0%E7%83%AD%E9%83%A8%E7%BD%B2-jrebel%E5%AE%9E%E7%94%A8%E7%89%88/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot-%E5%9C%A8idea%E4%B8%AD%E5%AE%9E%E7%8E%B0%E7%83%AD%E9%83%A8%E7%BD%B2-jrebel%E5%AE%9E%E7%94%A8%E7%89%88/</guid><description>&lt;h1 id="springboot-在idea中实现热部署-jrebel实用版"&gt;SpringBoot 在IDEA中实现热部署 (JRebel实用版)&lt;/h1&gt;
&lt;h2 id="jrebel插件安装步骤"&gt;JRebel插件安装步骤:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在&lt;code&gt;setting&lt;/code&gt; - &lt;code&gt;Plugins&lt;/code&gt; 里面搜索 &lt;code&gt;JReble&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="20200508144912520" loading="lazy" src="https://img.ggball.top/20200508144912520.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;激活链接&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;https://jrebel.qekang.com/6f540b75-a1f5-4ccc-ae32-d00e12eda632&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xyqierkang@163.com&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="准备条件"&gt;准备条件&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;File–&amp;gt;Serrings–&amp;gt;Compiler–&amp;gt;找到Build project automatically&lt;/strong&gt;勾选上，代表自动编译&lt;/p&gt;</description></item><item><title>springboot三种系统初始化方式解析</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot%E4%B8%89%E7%A7%8D%E7%B3%BB%E7%BB%9F%E5%88%9D%E5%A7%8B%E5%8C%96%E6%96%B9%E5%BC%8F%E8%A7%A3%E6%9E%90/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/springboot/springboot%E4%B8%89%E7%A7%8D%E7%B3%BB%E7%BB%9F%E5%88%9D%E5%A7%8B%E5%8C%96%E6%96%B9%E5%BC%8F%E8%A7%A3%E6%9E%90/</guid><description>&lt;h1 id="springboot三种系统初始化方式解析"&gt;springboot三种系统初始化方式解析&lt;/h1&gt;
&lt;h2 id="1-第一种-利用-springfactories"&gt;1. 第一种 利用 spring.factories&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;在资源文件目录建立 spring.factories 文件 存入key-value信息&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-properties" data-lang="properties"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;org.springframework.context.ApplicationContextInitializer&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;com.zhu.ggball.springboot.initializer.FirstInitializer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="image-20210118213956051" loading="lazy" src="https://img.ggball.top/picGo/image-20210118213956051.png"&gt;&lt;/p&gt;
&lt;p&gt;实现 ApplicationContextInitializer 类&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @program: springboot
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @description: 第一种初始化方式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @author: ggBall
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @create: 2021-01-13 09:16
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; **/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Order&lt;/span&gt;(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FirstInitializer&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; ApplicationContextInitializer&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;ConfigurableApplicationContext&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initialize&lt;/span&gt;(ConfigurableApplicationContext applicationContext) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 获取环境&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ConfigurableEnvironment environment &lt;span style="color:#f92672"&gt;=&lt;/span&gt; applicationContext.&lt;span style="color:#a6e22e"&gt;getEnvironment&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 构建自己的属性&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; map.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;key1&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MapPropertySource source &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; MapPropertySource(&lt;span style="color:#e6db74"&gt;&amp;#34;firstInitializer&amp;#34;&lt;/span&gt;, map);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 3. 加入环境属性集中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment.&lt;span style="color:#a6e22e"&gt;getPropertySources&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;addLast&lt;/span&gt;(source);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;firstInitializer start... &amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;原理：&lt;/p&gt;</description></item><item><title>springCache配合redis做缓存</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springcache%E9%85%8D%E5%90%88redis%E5%81%9A%E7%BC%93%E5%AD%98/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6/spring/springcache%E9%85%8D%E5%90%88redis%E5%81%9A%E7%BC%93%E5%AD%98/</guid><description>&lt;h1 id="springcache配合redis做缓存"&gt;springCache配合redis做缓存&lt;/h1&gt;
&lt;h2 id="redis的优势"&gt;redis的优势&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我们都知道redis可以作为缓存，是因为它具有&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;大内存作为缓存&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;redis的缓存可以被持久化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;redis可以实现分布式缓存&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redis可以处理每秒百万级的并发，是专业的绶存服务&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;redis对缓存有过期时间机制&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redis不仅仅支持简单的k/v类型的数据，同时还提供list，set，zset，hash等数据结构的存储。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="什么是springcache"&gt;什么是springCache&lt;/h2&gt;
&lt;h3 id="概述"&gt;概述&lt;/h3&gt;
&lt;p&gt;Spring 3.1 引入了激动人心的基于凝视（annotation）的缓存（cache）技术，它本质上不是一个具体的缓存实现方案（比如EHCache 或者 OSCache），而是一个对缓存使用的抽象，通过在既有代码中加入少量它定义的各种 annotation，即能够达到缓存方法的返回对象的效果。&lt;/p&gt;</description></item><item><title>利用Excutors异步执行任务</title><link>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%88%A9%E7%94%A8excutors%E5%BC%82%E6%AD%A5%E6%89%A7%E8%A1%8C%E4%BB%BB%E5%8A%A1/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0800</pubDate><guid>https://www.ggball.top/notes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%88%A9%E7%94%A8excutors%E5%BC%82%E6%AD%A5%E6%89%A7%E8%A1%8C%E4%BB%BB%E5%8A%A1/</guid><description>&lt;h1 id="利用excutors异步执行任务"&gt;利用Excutors异步执行任务&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;起因是项目中，有一个接口是查询数据库，for循环查询了10次，特别|消耗时间，当时数据有100万条时，查询时间需要6,7秒 ,所以想异步查询数据库，然后得到自己想要的结果。&lt;/p&gt;</description></item></channel></rss>