<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Andy's Blog</title><link>https://andy1202go.github.io</link><description>Tech Experience Learn Think</description><copyright>Andy's Blog</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><image><url>https://avatars.githubusercontent.com/u/11980041</url><title>avatar</title><link>https://andy1202go.github.io</link></image><lastBuildDate>Tue, 24 Mar 2026 07:12:53 +0000</lastBuildDate><managingEditor>Andy's Blog</managingEditor><ttl>60</ttl><webMaster>Andy's Blog</webMaster><item><title>PG核心配置参数_Basic_5_副本</title><link>https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_5_-fu-ben.html</link><description>## max_replication_slots

默认：10

推荐：每个从库默认给一个物理副本，逻辑副本按计划预留，再冗余1-2个

&gt; **max_replication_slots** 是 PostgreSQL 的一个配置参数，它定义了**数据库集群中可以创建的最大复制槽数量**。</description><guid isPermaLink="true">https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_5_-fu-ben.html</guid><pubDate>Tue, 24 Mar 2026 07:12:19 +0000</pubDate></item><item><title>PG核心配置参数_Basic_4_检查点</title><link>https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_4_-jian-cha-dian.html</link><description>## min_wal_size

默认：80MB

建议：大一些，1GB

首先需要理解wal日志，这个是pg的一个核心功能的保障：

&gt; WAL（Write-Ahead Logging）是PostgreSQL的核心机制，它确保**任何数据修改都必须先写入日志，然后才能写入实际数据文件**。</description><guid isPermaLink="true">https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_4_-jian-cha-dian.html</guid><pubDate>Fri, 20 Mar 2026 07:59:30 +0000</pubDate></item><item><title>PG核心配置参数_Basic_3_日志</title><link>https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_3_-ri-zhi.html</link><description>## logging_collector 日志收集器

默认值：off

建议：on

&gt; 一个服务器参数，用于确定是否启用日志收集器。</description><guid isPermaLink="true">https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_3_-ri-zhi.html</guid><pubDate>Thu, 19 Mar 2026 06:44:03 +0000</pubDate></item><item><title>理解Linux的标准流</title><link>https://andy1202go.github.io/post/li-jie-Linux-de-biao-zhun-liu.html</link><description>## 标准流

&gt; 在 Linux 系统中，'标准流'（Standard Streams）是程序与外部环境进行数据交互的核心机制，标准流主要包括以下三种类型：
&gt;
&gt; 1. 标准输入（stdin）：这是程序或shell接收数据的通道。</description><guid isPermaLink="true">https://andy1202go.github.io/post/li-jie-Linux-de-biao-zhun-liu.html</guid><pubDate>Wed, 11 Mar 2026 02:50:17 +0000</pubDate></item><item><title>PG核心配置参数_Basic_2_内存设置</title><link>https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_2_-nei-cun-she-zhi.html</link><description>## shard_buffers 共享缓冲区

默认值：128MB

设置数据库服务使用的共享内存缓冲区数量。</description><guid isPermaLink="true">https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_2_-nei-cun-she-zhi.html</guid><pubDate>Tue, 10 Mar 2026 07:27:38 +0000</pubDate></item><item><title>PG核心配置参数_Basic_1_进程设置</title><link>https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_1_-jin-cheng-she-zhi.html</link><description>## max_connections 最大连接数

默认值：100

确定数据库服务的最大连接数。</description><guid isPermaLink="true">https://andy1202go.github.io/post/PG-he-xin-pei-zhi-can-shu-_Basic_1_-jin-cheng-she-zhi.html</guid><pubDate>Tue, 10 Mar 2026 07:03:10 +0000</pubDate></item><item><title>什么是图灵完备</title><link>https://andy1202go.github.io/post/shen-me-shi-tu-ling-wan-bei.html</link><description>如果一门语言是图灵完备的，那它就能实现所有计算任务。</description><guid isPermaLink="true">https://andy1202go.github.io/post/shen-me-shi-tu-ling-wan-bei.html</guid><pubDate>Tue, 10 Mar 2026 02:57:50 +0000</pubDate></item><item><title>webhook一二事</title><link>https://andy1202go.github.io/post/webhook-yi-er-shi.html</link><description>告警配置通知过程中，使用了企微的群消息通知，获得webhookUrl之后，取其中的key或者整个链接进行了配置。</description><guid isPermaLink="true">https://andy1202go.github.io/post/webhook-yi-er-shi.html</guid><pubDate>Thu, 12 Feb 2026 08:45:04 +0000</pubDate></item><item><title>nohup命令的&amp;</title><link>https://andy1202go.github.io/post/nohup-ming-ling-de-%26.html</link><description>今天配置一个监控服务，在Linux上面使用docker部署后，怎么配置服务连接都是Connection Failure。</description><guid isPermaLink="true">https://andy1202go.github.io/post/nohup-ming-ling-de-%26.html</guid><pubDate>Wed, 11 Feb 2026 06:53:30 +0000</pubDate></item><item><title>Maven依赖的Scope问题</title><link>https://andy1202go.github.io/post/Maven-yi-lai-de-Scope-wen-ti.html</link><description>## 遇到的问题

最近遇到maven使用上的问题。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Maven-yi-lai-de-Scope-wen-ti.html</guid><pubDate>Wed, 04 Feb 2026 07:19:29 +0000</pubDate></item><item><title>CORS心得</title><link>https://andy1202go.github.io/post/CORS-xin-de.html</link><description>多次受到CORS问题困扰，每次都是一知半解的解决了，不如这次来探寻下。</description><guid isPermaLink="true">https://andy1202go.github.io/post/CORS-xin-de.html</guid><pubDate>Wed, 04 Feb 2026 03:32:18 +0000</pubDate></item><item><title>【LLM】入门好文</title><link>https://andy1202go.github.io/post/%E3%80%90LLM%E3%80%91-ru-men-hao-wen.html</link><description>最近一年以来，一直从事LLM相关工程开发工作，但缺少对其原理的了解。</description><guid isPermaLink="true">https://andy1202go.github.io/post/%E3%80%90LLM%E3%80%91-ru-men-hao-wen.html</guid><pubDate>Mon, 02 Feb 2026 03:04:28 +0000</pubDate></item><item><title>使用CattToolkit加速Github</title><link>https://andy1202go.github.io/post/shi-yong-CattToolkit-jia-su-Github.html</link><description>直接在搜索引擎搜索CattToolkit即可，各个平台都有的下载，下载渠道也有多个，个人使用的是百度网盘。</description><guid isPermaLink="true">https://andy1202go.github.io/post/shi-yong-CattToolkit-jia-su-Github.html</guid><pubDate>Sat, 13 Jul 2024 11:49:44 +0000</pubDate></item><item><title>Let's play a game</title><link>https://andy1202go.github.io/post/Let%27s%20play%20a%20game.html</link><description>按照前面职业规格的情况，35w年收入是能接受的。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Let%27s%20play%20a%20game.html</guid><pubDate>Thu, 11 Jul 2024 07:13:25 +0000</pubDate></item><item><title>30岁的职业规划 Part2</title><link>https://andy1202go.github.io/post/30-sui-de-zhi-ye-gui-hua-%20Part2.html</link><description>## 2 职业之思&#13;
&#13;
### 2.0 个人真实情况分析&#13;
&#13;
1. 当前工作情况&#13;
&#13;
   应该是能做也适合做的，但是没那么想做的工作。</description><guid isPermaLink="true">https://andy1202go.github.io/post/30-sui-de-zhi-ye-gui-hua-%20Part2.html</guid><pubDate>Fri, 05 Jul 2024 07:46:05 +0000</pubDate></item><item><title>常用网站收藏（持续更新）</title><link>https://andy1202go.github.io/post/chang-yong-wang-zhan-shou-cang-%EF%BC%88-chi-xu-geng-xin-%EF%BC%89.html</link><description>## 开发工具&#13;
&#13;
### 合集&#13;
&#13;
[开发者武器库](https://devtool.tech/)&#13;
&#13;
[Hutool](https://www.hutool.cn/)&#13;
&#13;
[Jodd-Java工具包](https://jodd.org/)&#13;
&#13;
### 正则表达式&#13;
&#13;
[regex101](https://regex101.com/)&#13;
&#13;
[**Regex Vis**](https://regex-vis.com/)&#13;
&#13;
[AutoRegex](https://www.autoregex.xyz/)&#13;
&#13;
### JSON&#13;
&#13;
[jsont](https://www.jsont.run/)&#13;
&#13;
utools&#13;
&#13;
[Jsoncn](https://www.json.cn/)&#13;
&#13;
### 时间戳&#13;
&#13;
[时间戳](https://tool.lu/timestamp/)&#13;
&#13;
### cron&#13;
&#13;
[在线Cron表达式生成器](https://cron.qqe2.com/)&#13;
&#13;
utools&#13;
&#13;
### Git&#13;
&#13;
[Git Command Explorer](https://gitexplorer.com/)&#13;
&#13;
[写readme](https://readme.so/)&#13;
&#13;
[git-flight-rules](https://github.com/k88hudson/git-flight-rules)&#13;
&#13;
### 代码格式化&#13;
&#13;
[在线代码格式化](https://tool.oschina.net/codeformat/sql)&#13;
&#13;
### 开发文档&#13;
&#13;
[DocLand-轻松查找api文档](https://docland.io/)&#13;
&#13;
[QuickRef](https://quickref.me/)&#13;
&#13;
[Redis](https://redis.io/docs/)&#13;
&#13;
### 架构设计&#13;
&#13;
[程序员练级攻略：软件设计](https://time.geekbang.org/column/article/9369)&#13;
&#13;
#### DDD&#13;
&#13;
[领域驱动设计在互联网业务开发中的实践](https://tech.meituan.com/2017/12/22/ddd-in-practice.html)&#13;
&#13;
[DDD 理论积累](https://www.cnblogs.com/netfocus/category/361987.html)&#13;
&#13;
[DDD实践：如何用DDD重构中台业务模型](https://time.geekbang.org/column/article/163032)&#13;
&#13;
[DDD系列第四讲：领域层设计规范](https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ%3D%3D&amp;chksm=8396d75fb4e15e49341b07022780dcb8dca66a0efb7f129d4de86a5ef5d8a890f6e0d2fd6432&amp;idx=1&amp;mid=2650414919&amp;scene=21&amp;sn=0ad1df1a1b0e2488f7faa21008fdbdd0#wechat_redirect)&#13;
&#13;
### 其他&#13;
&#13;
[explainshell](https://explainshell.com/)&#13;
&#13;
[在线IDE-phcode](https://phcode.dev/)&#13;
&#13;
[spring-initializr](https://start.spring.io/)&#13;
&#13;
## 办公&#13;
&#13;
### 绘图相关&#13;
&#13;
[PlantUML](https://plantuml.com/zh/)&#13;
&#13;
[draw.io](https://app.diagrams.net/)&#13;
&#13;
[*markmap*](https://markmap.js.org/)&#13;
&#13;
[ProcessOn思维导图流程图](https://www.processon.com/)&#13;
&#13;
[在线白板](https://songlh.top/paint-board/)&#13;
&#13;
[在线白板](https://www.tldraw.com/)&#13;
&#13;
[Mermaid](https://mermaid.js.org/)&#13;
&#13;
[SVG Silh](https://svgsilh.com/)&#13;
&#13;
[阿里巴巴矢量图标库](https://www.iconfont.cn/search/index?searchType=icon&amp;q=icon)&#13;
&#13;
[Cloudcraft-绘制部署架构图](https://www.cloudcraft.co/)&#13;
&#13;
[Plectica](https://www.plectica.com/)&#13;
&#13;
[iconbolt](https://www.iconbolt.com/)&#13;
&#13;
[tablerIcon](https://tabler.io/icons)&#13;
&#13;
### PPT&#13;
[Office破解](https://massgrave.dev/)&#13;
&#13;
[**SearchTheDeck**](https://searchthedeck.com/)&#13;
&#13;
[MindShow](https://www.mindshow.fun/#/templates)&#13;
&#13;
### CV&#13;
&#13;
[一纸简历](https://cv.devtool.tech/)&#13;
&#13;
[木及简历](https://www.mujicv.com/index.html)&#13;
&#13;
[OpenResume](https://www.open-resume.com/)&#13;
&#13;
[PPResume-基于Latex](https://ppresume.com/)&#13;
&#13;
[简单简历](https://easycv.cn/)&#13;
&#13;
[LapisCV-基于Markdown](https://github.com/BingyanStudio/LapisCV)&#13;
&#13;
[优雅简历](https://www.elegantresume.pro/)&#13;
&#13;
[Faultier-CV](https://i5heu.github.io/Faultier-CV/dist/index.html)&#13;
&#13;
### 其他&#13;
&#13;
[录屏截图软件](https://www.screentogif.com/)&#13;
&#13;
[salaryfly](https://salaryfly.com/)&#13;
&#13;
[写作猫](https://xiezuocat.com/#/)&#13;
[定积分计算log(x+1)](https://zh.numberempire.com/definiteintegralcalculator.php)&#13;
&#13;
[数学公式绘图](https://www.desmos.com/calculator/nagoahpcmu?lang=zh-CN)&#13;
&#13;
## 开源软件/资源&#13;
&#13;
### 软件或框架&#13;
&#13;
[MEGAEASE-云部署平台](https://megaease.com/zh/)&#13;
&#13;
[创业灵感收集-来源于阮一峰](https://github.com/zhaoolee/ins)&#13;
&#13;
[Solon **Java “纯血国产”应用开发框架：更快、更小、更简单。</description><guid isPermaLink="true">https://andy1202go.github.io/post/chang-yong-wang-zhan-shou-cang-%EF%BC%88-chi-xu-geng-xin-%EF%BC%89.html</guid><pubDate>Tue, 02 Jul 2024 06:48:44 +0000</pubDate></item><item><title>30岁的职业规划 part1</title><link>https://andy1202go.github.io/post/30-sui-de-zhi-ye-gui-hua-%20part1.html</link><description>身处物联网行业+两次面临裁员+日常工作提不起干劲，不禁在头脑中游走：&#13;
&#13;
是不是不应该走程序员道路？&#13;
&#13;
这糟糕的国内互联网环境和不负责的头部企业，真是入错行了么？&#13;
&#13;
我到底适合做什么工作？&#13;
&#13;
我喜欢做什么？&#13;
&#13;
我擅长做什么？&#13;
&#13;
我到底想要的是什么呢？&#13;
&#13;
这些都没有答案....&#13;
&#13;
思来想去，似乎10余年应试教育下来，最合适的解决系统性问题的时候，还是得听课，不如就按照职业规划的课程，来回看一下自己的职业选择，以及未来可能40年的职业之路。</description><guid isPermaLink="true">https://andy1202go.github.io/post/30-sui-de-zhi-ye-gui-hua-%20part1.html</guid><pubDate>Fri, 28 Jun 2024 08:00:01 +0000</pubDate></item><item><title>给爸妈购机攻略</title><link>https://andy1202go.github.io/post/gei-ba-ma-gou-ji-gong-lve.html</link><description>电池容量大	4000毫安以上，能达到5000最好&#13;
充电快	闪充，问一下充满要多久&#13;
内存大	6个G以上最好，越大越好&#13;
存储空间大	256个G以上，越大越好&#13;
好看	看妈喜欢哪个就行，手机壳可以看要不要选&#13;
屏幕护眼	问一下是什么屏幕，LCD是最好的，OLED也行，自己玩一下，体验下刺眼不&#13;
轻便	体验下手感，现在的手机很多比较重，达到200克了（四两），最好轻一点，长时间拿着玩不累手和手腕&#13;
售后方便	推荐oppo，有啥不会的电话或者去店里问下&#13;
购物方式	建议去店里体验下，问下上面这几项内容，就能评估好坏了。</description><guid isPermaLink="true">https://andy1202go.github.io/post/gei-ba-ma-gou-ji-gong-lve.html</guid><pubDate>Thu, 27 Jun 2024 08:36:41 +0000</pubDate></item><item><title>常用CURL指南</title><link>https://andy1202go.github.io/post/chang-yong-CURL-zhi-nan.html</link><description>## 常用命令&#13;
&#13;
```&#13;
curl www.baidu.com get百度&#13;
curl -X POST www.baidu.com&#13;
curl -X POST --data 'shit=happens' www.baidu.com&#13;
curl -X POST --data-urlencode 'shit=happens' www.baidu.com 表单编码，post提交&#13;
curl -i www.baidu.com 显示header信息&#13;
curl -o test.txt www.baidu.com 保存&#13;
curl -v test.txt www.baidu.com 显示通信过程&#13;
curl --user-agent 'Mozilla/5.0' www.baidu.com&#13;
curl --cookie 'name=xxx' www.baidu.com&#13;
curl --header 'Content-Type:applicaiton/json' www.baidu.com&#13;
curl --user name:password www.baidu.com&#13;
```&#13;
&#13;
### 一次curl，多个URL&#13;
&#13;
空格隔开就行；jianshu.com/p/fc0eb6c60816&#13;
&#13;
### GET命令的多个参数问题&#13;
&#13;
会有&amp;在URL中，不同操作系统的写法不同https://blog.csdn.net/sinat_27818621/article/details/104517435&#13;
&#13;
linux：&#13;
&#13;
```shell&#13;
curl localhost:8080/test?a=1\&amp;b=2&#13;
```&#13;
&#13;
windows&#13;
&#13;
```shell&#13;
curl -s 'http://localhost:8080/get?name=zhangsan&amp;age=12&amp;sex=1'&#13;
```&#13;
&#13;
## CookBook&#13;
&#13;
### Make a POST Request (TLDR: Use -X POST argument)&#13;
&#13;
1. [Send an Empty POST Request](https://catonmat.net/cookbooks/curl/make-post-request#send-empty-post-request)&#13;
&#13;
   ```shell&#13;
   curl -X POST https://sth.com&#13;
   ```&#13;
&#13;
   &#13;
&#13;
2. [Send a POST Request with Form Data](https://catonmat.net/cookbooks/curl/make-post-request#post-form-data)&#13;
&#13;
   ```shell&#13;
   curl -d 'a=1&amp;b=2' -X POST https://sth.com&#13;
   ```&#13;
&#13;
   &gt; When using the `-d` argument, curl also sets the `Content-Type` header to `application/x-www-form-urlencoded`.&#13;
   &gt;&#13;
   &gt; Note that the `key=value` data should be URL-escaped.&#13;
&#13;
3. [Skipping the -X Argument](https://catonmat.net/cookbooks/curl/make-post-request#skipping-x-argument)&#13;
&#13;
   ```shell&#13;
   curl -d 'a=1&amp;b=2' https://sht.com&#13;
   ```&#13;
&#13;
   &gt; When `-d` is used, curl implicitly sets the request's type to POST.&#13;
&#13;
4. [A Neater Way to POST Data](https://catonmat.net/cookbooks/curl/make-post-request#neater-way-to-post)&#13;
&#13;
   ```shell&#13;
   curl -d 'a=1' -d 'b=2' https://sth.com&#13;
   ```&#13;
&#13;
   &#13;
&#13;
5. [Send a POST Request and Follow a Redirect](https://catonmat.net/cookbooks/curl/make-post-request#post-with-redirect)&#13;
&#13;
6. [Send a POST Request with JSON Data](https://catonmat.net/cookbooks/curl/make-post-request#post-json-data)&#13;
&#13;
   ```shell&#13;
   curl -d '{'a':2,'b':1}' -H 'Content-Type:application/json' https://sth.com&#13;
   ```&#13;
&#13;
   必须手动声明Content-Type头为application/json&#13;
&#13;
7. [Send a POST Request with XML Data](https://catonmat.net/cookbooks/curl/make-post-request#post-xml-data)&#13;
&#13;
   ```shell&#13;
   curl -d '&lt;user&gt;1&lt;/user&gt;' -H 'Content-Type:text/xml' https://sth.com&#13;
   ```&#13;
&#13;
   注意Content-Type&#13;
&#13;
8. [Send a POST Request with Plain Text Data](https://catonmat.net/cookbooks/curl/make-post-request#post-plain-text-data)&#13;
&#13;
   ```shell&#13;
   curl -d 'hello world' -H 'Content-Type:text/plain' https://sht.com&#13;
   ```&#13;
&#13;
   注意Content-Type&#13;
&#13;
9. [Send a POST Request with Data from a File](https://catonmat.net/cookbooks/curl/make-post-request#post-data-from-file)&#13;
&#13;
10. [URL-encode POST Data](https://catonmat.net/cookbooks/curl/make-post-request#url-encode-post-data)&#13;
&#13;
    &gt; So far, all recipes have been using the `-d` argument to add POST data to requests. This argument assumes that your data is URL-encoded already. If it is not, then there can be some trouble. If your data is not URL-encoded, then replace `-d` with `--data-urlencode`. It works exactly the same way as `-d`, except the data gets URL-encoded by curl before it's sent out on the wire.&#13;
&#13;
    ```shell&#13;
    curl --data-urlencode 'a=1' https://sth.com&#13;
    ```&#13;
&#13;
    -d是假设参数已经url编码好了的，--data-urlencode是对参数执行url编码&#13;
&#13;
11. [POST a Binary File](https://catonmat.net/cookbooks/curl/make-post-request#post-binary-file)&#13;
&#13;
12. [POST a Binary File and Set Its MIME Type](https://catonmat.net/cookbooks/curl/make-post-request#post-binary-file-set-mime)&#13;
&#13;
13. [POST a Binary File and Change Its Filename](https://catonmat.net/cookbooks/curl/make-post-request#post-binary-file-change-filename)&#13;
&#13;
### Add POST Data to a Request (TLDR: Use -d var=val argument)&#13;
&#13;
同上一个&#13;
&#13;
### Construct a Query String (TLDR: Use -G argument)&#13;
&#13;
&gt; This curl recipe shows you how to construct query strings for your GET requests. This is done via the `-G` command line argument in combination with the `-d` or `--data-urlencode` arguments. The `-G` argument will append the data specified in `-d` and `--data-urlencode` arguments at the end of the request URL, joining all data pieces with the `&amp;` character and separating them from the URL with the `?` character.&#13;
&#13;
使用-G和-d或者--data-urlencode，把参数按照?&amp;&amp;的格式拼接到url的后面&#13;
&#13;
1. [Construct Two Query Arguments](https://catonmat.net/cookbooks/curl/construct-query-string#construct-two-query-arguments)&#13;
&#13;
   ```shell&#13;
   curl -G -d 'a=1' -d 'b=2' https://sth.com&#13;
   ```&#13;
&#13;
   &gt; Be careful – if you forget the `-G` argument, then curl will make a POST request instead!&#13;
&#13;
2. [URL-encode a Query Argument](https://catonmat.net/cookbooks/curl/construct-query-string#url-encode-query-argument)&#13;
&#13;
   ```shell&#13;
   curl -G --data-urlencode 'comment=this cookbook is awesome' https://catonmat.net&#13;
   ```&#13;
&#13;
### Add HTTP Headers (TLDR: Use -H 'Header: Value' argument)&#13;
&#13;
1. [Add a Single Header](https://catonmat.net/cookbooks/curl/add-http-headers#add-a-single-header)&#13;
2. [Add Two Headers](https://catonmat.net/cookbooks/curl/add-http-headers#add-two-header)&#13;
3. [Add an Empty Header](https://catonmat.net/cookbooks/curl/add-http-headers#add-an-empty-header)&#13;
&#13;
```shell&#13;
curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com&#13;
curl -H 'Puppies;' https://google.com&#13;
```&#13;
&#13;
### Change the User Agent (TLDR: Use -A 'User Agent' argument)&#13;
&#13;
浏览器啥的设置&#13;
&#13;
### Set Cookies (TLDR: Use -b name=value argument)&#13;
&#13;
1. [Add a Cookie](https://catonmat.net/cookbooks/curl/set-cookies#add-cookie)&#13;
&#13;
   ```shell&#13;
   curl -b 'user_id=abc' https://sth.com&#13;
   ```&#13;
&#13;
   在一个get请求中，添加了一个cookie，Cookie: user_id=abc&#13;
&#13;
2. [Add Two Cookies](https://catonmat.net/cookbooks/curl/set-cookies#add-two-cookies)&#13;
&#13;
   ```shell&#13;
   curl -b 'session=abcdef' -b 'loggedin=true' https://google.com&#13;
   ```&#13;
&#13;
3. [Add an Empty Cookie](https://catonmat.net/cookbooks/curl/set-cookies#add-empty-cookie)&#13;
&#13;
4. [Save Cookies to a File](https://catonmat.net/cookbooks/curl/set-cookies#save-cookies-to-file)&#13;
&#13;
5. [Load Cookies from a File](https://catonmat.net/cookbooks/curl/set-cookies#load-cookies-from-file)&#13;
&#13;
### Add a Referrer (TLDR: Use -e URL argument)&#13;
&#13;
信任来源设置&#13;
&#13;
### Follow a 3XX Redirect (TLDR: Use -L argument)&#13;
&#13;
重定向&#13;
&#13;
### Use the Basic HTTP Authentication (TLDR: Use -u user:pass argument)&#13;
&#13;
基础的HTTP登录，可以传递用户名和密码的&#13;
&#13;
```shell&#13;
curl -u 'bob:12345' https://google.com/login&#13;
```&#13;
&#13;
### Print the Response Headers (TLDR: Use -i argument)&#13;
&#13;
1. [Print the Response Headers and Body (together)](https://catonmat.net/cookbooks/curl/print-response-headers#print-headers-and-response)&#13;
&#13;
   ```shell&#13;
   curl -i https://catonmat.net&#13;
   ```&#13;
&#13;
   注意这里一定是小写的-i，大写的功能是不一样的。</description><guid isPermaLink="true">https://andy1202go.github.io/post/chang-yong-CURL-zhi-nan.html</guid><pubDate>Thu, 27 Jun 2024 08:26:57 +0000</pubDate></item><item><title>Mybatis Mapper生成器-MapperCreator源码分享</title><link>https://andy1202go.github.io/post/Mybatis%20Mapper-sheng-cheng-qi--MapperCreator-yuan-ma-fen-xiang.html</link><description>来源：huzhiyong&#13;
```java&#13;
import java.io.FileWriter;&#13;
import java.io.IOException;&#13;
import java.util.ArrayList;&#13;
import java.util.HashMap;&#13;
import java.util.List;&#13;
&#13;
/**&#13;
 * Created by huzhiyong on 2017/2/7.&#13;
 * 用于生成基本的mapper文件&#13;
 * 输入：SQLyog 导出的建表语句&#13;
 * 输出：1，基本Dao和DO类，2，mapper文件，3,测试代码  全部输出到 output.txt 文件&#13;
 *&#13;
 * sql规范：&#13;
 * 1, 数据库字段名全小写，用下划线隔开&#13;
 * 2，默认每个表都有 id 字段（自增主键） modified_date&#13;
 * 3, 每列都要有注释，列注释当中不包括 英文逗号，数据库注释不包括 英文括号&#13;
 * 4，删除掉索引行，当有联合索引时，会报错&#13;
 */&#13;
public class MapperCreator {&#13;
    private static final HashMap&lt;String,String&gt; sqlJavaTypeMap = new HashMap&lt;&gt;();&#13;
    private static final HashMap&lt;String,String&gt; sqlJdbcTypeMap = new HashMap&lt;&gt;();&#13;
    static{&#13;
        sqlJavaTypeMap.put('bigint', 'Long') ;&#13;
        sqlJavaTypeMap.put('int', 'Integer') ;&#13;
        sqlJavaTypeMap.put('tinyint', 'Integer') ;&#13;
        sqlJavaTypeMap.put('varchar', 'String') ;&#13;
        sqlJavaTypeMap.put('text', 'String') ;&#13;
        sqlJavaTypeMap.put('char', 'String') ;&#13;
        sqlJavaTypeMap.put('datetime', 'Date') ;&#13;
        sqlJavaTypeMap.put('timestamp', 'Date') ;&#13;
        sqlJavaTypeMap.put('mediumtext', 'String') ;&#13;
&#13;
        sqlJdbcTypeMap.put('bigint', 'BIGINT') ;&#13;
        sqlJdbcTypeMap.put('int', 'INTEGER') ;&#13;
        sqlJdbcTypeMap.put('tinyint', 'INTEGER') ;&#13;
        sqlJdbcTypeMap.put('varchar', 'VARCHAR') ;&#13;
        sqlJdbcTypeMap.put('text', 'VARCHAR') ;&#13;
        sqlJdbcTypeMap.put('char', 'CHAR') ;&#13;
        sqlJdbcTypeMap.put('datetime', 'TIMESTAMP') ;// 注意，这里使用这个类型，不能直接使用DATE,mybatis的Date只有年月日&#13;
        sqlJdbcTypeMap.put('timestamp', 'TIMESTAMP') ;&#13;
        sqlJdbcTypeMap.put('mediumtext', 'VARCHAR') ;&#13;
    }&#13;
&#13;
    private static final String DAO_END = 'Dao' ;&#13;
    private static final String DO_END = 'DO' ;&#13;
&#13;
&#13;
&#13;
    // 修改这两个参数&#13;
    private static final String OUTPUT_DIR = 'C:\\Users\\jrliangbo\\Downloads' ;&#13;
    private static final String PACKAGE_NAME = 'com.heytap.mall.comment.core.domain.dao.' ;&#13;
&#13;
&#13;
    public static void main(String[] args) throws Exception{&#13;
&#13;
        // 此处将sql建表语句粘出，注意sql规范&#13;
       String sql = 'CREATE TABLE `t_comment_liking` (\n' +&#13;
               '  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id 自增主键',\n' +&#13;
               '  `comment_id` bigint(20) NOT NULL COMMENT '评论id 评论id',\n' +&#13;
               '  `user_id` varchar(64) DEFAULT NULL COMMENT '用户唯一标识 用户唯一标识',\n' +&#13;
               '  `device_id` varchar(64) DEFAULT NULL COMMENT '设备id',\n' +&#13;
               '  `liking` tinyint(1) DEFAULT NULL COMMENT '点赞 点赞与否，1点赞',\n' +&#13;
               '  `data_status` tinyint(1) DEFAULT NULL COMMENT '数据有效性 数据是否有效，1有效',\n' +&#13;
               '  `create_time` timestamp NOT NULL COMMENT '创建时间',\n' +&#13;
               '  `modify_time` timestamp NOT NULL COMMENT '修改时间',\n' +&#13;
               '  `created` varchar(32) NOT NULL DEFAULT '' COMMENT '创建人',\n' +&#13;
               '  `modified` varchar(32) NOT NULL DEFAULT '' COMMENT '更新人',\n' +&#13;
               '  PRIMARY KEY (`id`)\n' +&#13;
               ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论点赞表 '' ;&#13;
&#13;
&#13;
        sql = sql.replace('\n','') ;&#13;
        process(sql) ;&#13;
        System.out.println('end');&#13;
&#13;
    }&#13;
&#13;
    /**&#13;
     * 生成 java DO类&#13;
     * 生成 Dao类&#13;
     * 生成 mapper文件&#13;
     * 生成 测试类&#13;
     */&#13;
    private static void process(String allData){&#13;
        int begin = allData.indexOf('(');&#13;
        int end = allData.lastIndexOf(')');&#13;
&#13;
        String firstLine = allData.substring(0, begin) ;&#13;
        String columnLine = allData.substring(begin+1,end);&#13;
&#13;
        String tableName = getTableName(firstLine) ;&#13;
&#13;
        List&lt;Item&gt; columnList = getColumnList(columnLine) ;&#13;
&#13;
        String baseName = columnName2JavaName(tableName) ;&#13;
        String doVarName = baseName + DO_END ;&#13;
        String daoVarName = baseName + DAO_END ;&#13;
        String doClassName = doVarName.substring(0,1).toUpperCase() + doVarName.substring(1) ;&#13;
        String daoClassName = daoVarName.substring(0,1).toUpperCase() + daoVarName.substring(1) ;&#13;
        StringBuilder sb = new StringBuilder('') ;&#13;
&#13;
        sb.append(doClassName);&#13;
        sb.append('-----------------------------------------------------------\n\n') ;&#13;
        sb.append(createDoFile(columnList)) ;&#13;
        sb.append('\n\n') ;&#13;
&#13;
&#13;
        sb.append(daoClassName);&#13;
        sb.append('-----------------------------------------------------------\n\n') ;&#13;
        sb.append(createDaoFile(doVarName, doClassName, daoClassName)) ;&#13;
        sb.append('\n\n') ;&#13;
&#13;
&#13;
        sb.append(baseName.substring(0,1).toUpperCase());&#13;
        sb.append(baseName.substring(1));&#13;
        sb.append('Mapper.xml-------------------------------------------------\n\n') ;&#13;
        sb.append(createMapperFile(columnList,daoClassName,doClassName,tableName));&#13;
        sb.append('\n\n');&#13;
&#13;
&#13;
&#13;
        sb.append(daoClassName);&#13;
        sb.append('Test.java');&#13;
        sb.append('-----------------------------------------------------------\n\n') ;&#13;
        sb.append(createTestFile(columnList,doClassName,doVarName,daoClassName,daoVarName)) ;&#13;
        sb.append('\n\n') ;&#13;
&#13;
&#13;
        writeToFile(OUTPUT_DIR, sb.toString()) ;&#13;
&#13;
        return ;&#13;
    }&#13;
&#13;
&#13;
    private static void writeToFile(String dir, String data){&#13;
        String filePath = dir + '\\\\' + 'output.txt' ;&#13;
        FileWriter fos;&#13;
        try {&#13;
            fos = new FileWriter(filePath);&#13;
            fos.write(data);&#13;
            fos.flush();&#13;
            fos.close();&#13;
        } catch (IOException e) {&#13;
            e.printStackTrace();&#13;
        }&#13;
    }&#13;
&#13;
&#13;
&#13;
    private static String createDoFile(List&lt;Item&gt; columnList){&#13;
        StringBuilder sb = new StringBuilder('') ;&#13;
        for(Item item : columnList){&#13;
            sb.append('/**  ');&#13;
            sb.append(item.getComment());&#13;
            sb.append('  */\n');&#13;
&#13;
            sb.append('private ');&#13;
            sb.append(item.getJavaType());&#13;
            sb.append(' ');&#13;
            sb.append(item.getName()) ;&#13;
            sb.append(';\n\n') ;&#13;
        }&#13;
&#13;
        sb.append('\n\n');&#13;
        return sb.toString() ;&#13;
    }&#13;
&#13;
    private static String createDaoFile(String doVarName,String doClassName,String daoClassName){&#13;
        String base  = '@SuperDao\n' +&#13;
                'public interface TMPDAO {\n' +&#13;
                '    int insert(TMPDO tmpdo);\n' +&#13;
                '    int update(TMPDO tmpdo);\n' +&#13;
                '    int delete(Long id);\n' +&#13;
                '    TMPDO getById(Long id);\n' +&#13;
                '}';&#13;
        base = base.replace('TMPDAO',daoClassName);&#13;
        base = base.replace('TMPDO',doClassName);&#13;
        base = base.replace('tmpdo',doVarName);&#13;
        return base ;&#13;
&#13;
    }&#13;
&#13;
    private static String createMapperFile(List&lt;Item&gt; columnList,String daoClassName,String doClassName,String tableName){&#13;
        StringBuilder sb = new StringBuilder('&lt;?xml version=\'1.0\' encoding=\'UTF-8\' ?&gt;\n' +&#13;
                '&lt;!DOCTYPE mapper PUBLIC \'-//mybatis.org//DTD Mapper 3.0//EN\' \'http://mybatis.org/dtd/mybatis-3-mapper.dtd\' &gt;\n' +&#13;
                '&lt;mapper namespace=\'');&#13;
        sb.append(PACKAGE_NAME);&#13;
        sb.append(daoClassName);&#13;
        sb.append('\'&gt;\n');&#13;
&#13;
        sb.append('&lt;resultMap id=\'BaseResultMap\' type=\'');&#13;
        sb.append(doClassName);&#13;
        sb.append('\'&gt;\n') ;&#13;
&#13;
        sb.append('&lt;id column=\'id\' property=\'id\' jdbcType=\'BIGINT\'/&gt;\n') ;&#13;
&#13;
        for(Item item : columnList){&#13;
            if(!item.getName().equals('id')){&#13;
                sb.append('&lt;result column=\'');&#13;
                sb.append(item.getColumn());&#13;
                sb.append('\' property=\'');&#13;
                sb.append(item.getName());&#13;
                sb.append('\' jdbcType=\'');&#13;
                sb.append(item.getJdbcType());&#13;
                sb.append('\'/&gt;\n');&#13;
&#13;
            }&#13;
        }&#13;
&#13;
        sb.append(' &lt;/resultMap&gt;\n') ;&#13;
&#13;
        sb.append('&lt;sql id=\'Base_Column_List\'&gt;\n');&#13;
        sb.append(columnList.get(0).getColumn());&#13;
        for(int i=1; i&lt;columnList.size(); i++){&#13;
            sb.append(',') ;&#13;
            sb.append(columnList.get(i).getColumn()) ;&#13;
        }&#13;
        sb.append('\n');&#13;
        sb.append('&lt;/sql&gt;\n') ;&#13;
&#13;
        // insert&#13;
        sb.append(createInsertSql(columnList, doClassName, tableName)) ;&#13;
        sb.append('\n\n');&#13;
&#13;
        // update&#13;
        sb.append(createUpdateSql(columnList, doClassName, tableName)) ;&#13;
        sb.append('\n\n');&#13;
&#13;
        // getById&#13;
        sb.append(createQuerySql(tableName)) ;&#13;
        sb.append('\n\n');&#13;
&#13;
        // delete&#13;
        sb.append(createDeleteSql(tableName)) ;&#13;
        sb.append('\n\n');&#13;
&#13;
        sb.append('&lt;/mapper&gt;\n');&#13;
        return sb.toString() ;&#13;
&#13;
    }&#13;
&#13;
&#13;
    private static String createInsertSql(List&lt;Item&gt; columnList,String doClassName,String tableName){&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        sb.append('&lt;insert id=\'insert\' useGeneratedKeys=\'true\' keyProperty=\'id\' parameterType=\'');&#13;
        sb.append(doClassName);&#13;
        sb.append('\'&gt;\n');&#13;
        sb.append('INSERT into ');&#13;
        sb.append(tableName) ;&#13;
        sb.append('\n');&#13;
        sb.append('&lt;trim prefix=\'(\' suffix=\')\'&gt;\n');&#13;
        for(Item item : columnList){&#13;
            if(!item.getColumn().equals('id') &amp;&amp; !item.getColumn().equals('modified_date')){&#13;
                if(item.getColumn().equals('created_date')){&#13;
                    sb.append('created_date,\n');&#13;
                }else if(item.isCanEmpty()){&#13;
                    sb.append('&lt;if test=\'');&#13;
                    sb.append(item.getName());&#13;
                    sb.append('!= null\'&gt;\n');&#13;
                    sb.append(item.getColumn());&#13;
                    sb.append(',\n');&#13;
                    sb.append('&lt;/if&gt;\n');&#13;
                }else{&#13;
                    sb.append(item.getColumn());&#13;
                    sb.append(',\n') ;&#13;
                }&#13;
            }&#13;
        }&#13;
        sb.append('modified_date\n');&#13;
        sb.append('&lt;/trim&gt;\n') ;&#13;
&#13;
&#13;
        sb.append('&lt;trim prefix=\'values (\' suffix=\')\'&gt;\n');&#13;
        for(Item item : columnList){&#13;
            if(!item.getColumn().equals('id') &amp;&amp; !item.getColumn().equals('modified_date')){&#13;
                if(item.getColumn().equals('created_date')){&#13;
                    sb.append('current_timestamp,\n');&#13;
                }else if(item.isCanEmpty()){&#13;
                    sb.append('&lt;if test=\'');&#13;
                    sb.append(item.getName());&#13;
                    sb.append(' != null\'&gt;\n');&#13;
                    sb.append('#{');&#13;
                    sb.append(item.getName());&#13;
                    sb.append(',jdbcType=');&#13;
                    sb.append(item.getJdbcType());&#13;
                    sb.append('},\n');&#13;
                    sb.append('&lt;/if&gt;\n');&#13;
                }else{&#13;
                    sb.append('#{');&#13;
                    sb.append(item.getName());&#13;
                    sb.append(',jdbcType=');&#13;
                    sb.append(item.getJdbcType());&#13;
                    sb.append('},\n');&#13;
                }&#13;
            }&#13;
        }&#13;
        sb.append('current_timestamp\n');&#13;
        sb.append('&lt;/trim&gt;\n') ;&#13;
        sb.append('&lt;/insert&gt;\n') ;&#13;
        return sb.toString() ;&#13;
    }&#13;
&#13;
&#13;
    private static String createUpdateSql(List&lt;Item&gt; columnList,String doClassName,String tableName){&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        sb.append('&lt;update id=\'update\' parameterType=\'');&#13;
        sb.append(doClassName);&#13;
        sb.append('\'&gt;\n');&#13;
        sb.append('update ');&#13;
        sb.append(tableName);&#13;
        sb.append('\n');&#13;
        sb.append('&lt;set&gt;\n');&#13;
&#13;
&#13;
        for(Item item : columnList){&#13;
            if(!item.getColumn().equals('id')&#13;
                    &amp;&amp; !item.getColumn().equals('modified_date')&#13;
                    &amp;&amp; !item.getColumn().equals('created_date')){&#13;
&#13;
                sb.append('&lt;if test=\'');&#13;
                sb.append(item.getName());&#13;
                sb.append(' != null\'&gt;\n');&#13;
                sb.append(item.getColumn());&#13;
                sb.append(' = #{');&#13;
                sb.append(item.getName());&#13;
                sb.append(',jdbcType=');&#13;
                sb.append(item.getJdbcType());&#13;
                sb.append('},\n');&#13;
                sb.append('&lt;/if&gt;\n');&#13;
            }&#13;
        }&#13;
        sb.append('modified_date = current_timestamp\n');&#13;
        sb.append('&lt;/set&gt;\n');&#13;
        sb.append('where id = #{id,jdbcType=BIGINT}\n');&#13;
        sb.append('&lt;/update&gt;\n');&#13;
&#13;
&#13;
        return sb.toString() ;&#13;
    }&#13;
&#13;
    private static String createQuerySql(String tableName){&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        sb.append('&lt;select id=\'getById\' resultMap=\'BaseResultMap\' parameterType=\'java.lang.Long\'&gt;\n');&#13;
        sb.append('SELECT\n');&#13;
        sb.append('&lt;include refid=\'Base_Column_List\' /&gt;\n');&#13;
        sb.append('from ');&#13;
        sb.append(tableName);&#13;
        sb.append('\n');&#13;
        sb.append('where id = #{id,jdbcType=BIGINT}\n');&#13;
        sb.append('&lt;/select&gt;\n') ;&#13;
&#13;
        return sb.toString() ;&#13;
    }&#13;
&#13;
    private static String createDeleteSql(String tableName){&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        sb.append('&lt;delete id=\'delete\'  parameterType=\'java.lang.Long\'&gt;\n');&#13;
        sb.append('DELETE\n');&#13;
        sb.append('from ');&#13;
        sb.append(tableName);&#13;
        sb.append('\n');&#13;
        sb.append('where id = #{id,jdbcType=BIGINT}\n');&#13;
        sb.append('&lt;/delete&gt;\n') ;&#13;
&#13;
        return sb.toString() ;&#13;
    }&#13;
&#13;
    private static String createTestFile(List&lt;Item&gt; columnList,String doClassName,String doVarName,String daoClassName, String daoVarName){&#13;
&#13;
        String model = 'public class TMPXXXDaoTest extends TestBase {\n' +&#13;
                '    private static final Logger logger = LoggerFactory.getLogger(TMPXXXDaoTest.class);\n' +&#13;
                '\n' +&#13;
                '    @Resource\n' +&#13;
                '    private TMPXXXDao tmpXXXDao;\n' +&#13;
                '\n' +&#13;
                '    private Long id ;\n' +&#13;
                '\n' +&#13;
                '    @Test\n' +&#13;
                '    public void testInsert(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = create();\n' +&#13;
                '        int result = tmpXXXDao.insert(tmpXXXDO);\n' +&#13;
                '        Assert.assertTrue(result &gt; 0);\n' +&#13;
                '        id = tmpXXXDO.getId() ;\n' +&#13;
                '        Assert.assertNotNull(id);\n' +&#13;
                '        Assert.assertTrue(id &gt; 0);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '    @Test(dependsOnMethods = \'testInsert\')\n' +&#13;
                '    public void testGetById(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n' +&#13;
                '        Assert.assertNotNull(tmpXXXDO);\n' +&#13;
                '        logger.info(\'testGetById获得对象： {}\', tmpXXXDO);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '    @Test(dependsOnMethods = \'testGetById\')\n' +&#13;
                '    public void testUpdate(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = create();\n' +&#13;
                '        tmpXXXDO.setId(id);\n' +&#13;
                '        SET_STRING_PLACEHOLDER\n' +&#13;
                '        int result = tmpXXXDao.update(tmpXXXDO);\n' +&#13;
                '        Assert.assertTrue(result &gt; 0);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '    @Test(dependsOnMethods = \'testUpdate\')\n' +&#13;
                '    public void testGetById2(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n' +&#13;
                '        Assert.assertNotNull(tmpXXXDO);\n' +&#13;
                '        logger.info(\'testGetById2获得对象： {}\', tmpXXXDO);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '    @Test(dependsOnMethods = \'testGetById2\')\n' +&#13;
                '    public void testDelete(){\n' +&#13;
                '        int result = tmpXXXDao.delete(id);\n' +&#13;
                '        Assert.assertTrue(result &gt; 0);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '    @Test(dependsOnMethods = \'testDelete\')\n' +&#13;
                '    public void testGetById3(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = tmpXXXDao.getById(id);\n' +&#13;
                '        Assert.assertNull(tmpXXXDO);\n' +&#13;
                '    }\n' +&#13;
                '\n' +&#13;
                '\n' +&#13;
                '    private TMPXXXDO create(){\n' +&#13;
                '        TMPXXXDO tmpXXXDO = new TMPXXXDO();\n' +&#13;
                '        SET_STRING_PLACEHOLDER\n' +&#13;
                '        return tmpXXXDO ;\n' +&#13;
                '    }\n' +&#13;
                '}' ;&#13;
&#13;
        model = model.replace('TMPXXXDao',daoClassName);&#13;
        model = model.replace('tmpXXXDao',daoVarName);&#13;
        model = model.replace('TMPXXXDO',doClassName);&#13;
        model = model.replace('tmpXXXDO',doVarName);&#13;
        String setString = getSetString(columnList,doVarName);&#13;
        model = model.replace('SET_STRING_PLACEHOLDER', setString);&#13;
        return model ;&#13;
&#13;
    }&#13;
&#13;
    private static String getSetString(List&lt;Item&gt; columnList,String doVarName){&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        for(Item item:columnList){&#13;
            if(!item.getColumn().equals('id')){&#13;
                if(item.isCanEmpty()){&#13;
                    sb.append('//') ;&#13;
                }&#13;
                sb.append(doVarName);&#13;
                sb.append('.set');&#13;
                sb.append(item.getName().substring(0,1).toUpperCase());&#13;
                sb.append(item.getName().substring(1));&#13;
                sb.append('(');&#13;
&#13;
                // 当有新的类型时，需要在此处添加&#13;
                if(item.getJavaType().equals('Integer')){&#13;
                    sb.append('0');&#13;
                }else if(item.getJavaType().equals('Long')){&#13;
                    sb.append('0L');&#13;
                }else if(item.getJavaType().equals('String')){&#13;
                    sb.append('\'hello world 测试\'');&#13;
                }else if(item.getJavaType().equals('Date')){&#13;
                    sb.append('new Date()');&#13;
                }else{&#13;
                    sb.append('');&#13;
                }&#13;
&#13;
                sb.append(');\n');&#13;
            }&#13;
&#13;
        }&#13;
&#13;
        return sb.toString() ;&#13;
&#13;
    }&#13;
&#13;
&#13;
&#13;
    private static List&lt;Item&gt; getColumnList(String data){&#13;
        List&lt;Item&gt; result = new ArrayList&lt;Item&gt;();&#13;
        String[] array = data.split(',') ;&#13;
        for(String line : array){&#13;
            if(!isKeyLine(line)){&#13;
                Item item = new Item();&#13;
                item.setColumn(getColumn(line));&#13;
                item.setComment(getComment(line));&#13;
                item.setSqlType(getType(line));&#13;
                item.setCanEmpty(canEmpty(line));&#13;
                if(!sqlJavaTypeMap.containsKey(item.getSqlType())){&#13;
                    throw new RuntimeException('找不到对应类型') ;&#13;
                }&#13;
                item.setJavaType(sqlJavaTypeMap.get(item.getSqlType()));&#13;
                item.setJdbcType(sqlJdbcTypeMap.get(item.getSqlType()));&#13;
                item.setName(columnName2JavaName(item.getColumn()));&#13;
                result.add(item);&#13;
            }&#13;
&#13;
        }&#13;
        return result ;&#13;
    }&#13;
&#13;
    private static boolean isKeyLine(String line){&#13;
        line = line.trim();&#13;
        line = line.toUpperCase() ;&#13;
        if(line.startsWith('PRIMARY')&#13;
                || line.startsWith('KEY')&#13;
                || line.startsWith('INDEX')&#13;
                || line.startsWith('UNIQUE')&#13;
                ){&#13;
            return true ;&#13;
        }&#13;
        return false ;&#13;
    }&#13;
&#13;
&#13;
&#13;
    private static String removeQuote(String data, int quote){&#13;
        data = data.trim() ;&#13;
        int begin = data.indexOf(quote);&#13;
        if(begin &gt; -1){&#13;
            int end = data.indexOf(quote,begin+1);&#13;
            if(end &gt; -1){&#13;
                return data.substring(begin+1,end) ;&#13;
            }&#13;
        }&#13;
        return data ;&#13;
    }&#13;
&#13;
    private static String getTableName(String firstLine){&#13;
        String[] array = firstLine.split(' ');&#13;
        int length = array.length;&#13;
        return removeQuote(array[length-1],'`');&#13;
    }&#13;
&#13;
    // 获取注释，COMMENT 之后第一个用 引号包起来的内容&#13;
    private static String getComment(String line){&#13;
        String[] array = line.split('COMMENT');&#13;
        return removeQuote(array[1],'\'') ;&#13;
    }&#13;
&#13;
    private static String getColumn(String line){&#13;
        return removeQuote(line,'`');&#13;
    }&#13;
&#13;
    private static boolean canEmpty(String line){&#13;
        // 有默认值的认为插入是可以为空&#13;
        if(line.contains('NOT NULL DEFAULT')){&#13;
            return true ;&#13;
        }&#13;
        return !(line.contains('NOT NULL')) ;&#13;
    }&#13;
&#13;
    private static String getType(String line){&#13;
        line = line.trim() ;&#13;
        String[] array = line.split(' ');&#13;
        String name = array[1];&#13;
        int end = name.indexOf('(');&#13;
        if(end &gt; 1){&#13;
            return name.substring(0,end) ;&#13;
        }&#13;
        return name ;&#13;
    }&#13;
&#13;
&#13;
&#13;
&#13;
    private static String columnName2JavaName(String column){&#13;
        column = column.toLowerCase() ;&#13;
        String[] array = column.split('_') ;&#13;
        StringBuilder sb = new StringBuilder('');&#13;
        sb.append(array[0]);&#13;
        for(int i=1; i&lt;array.length; i++){&#13;
            sb.append(array[i].substring(0,1).toUpperCase()) ;&#13;
            sb.append(array[i].substring(1)) ;&#13;
        }&#13;
&#13;
        return sb.toString() ;&#13;
&#13;
    }&#13;
&#13;
&#13;
}&#13;
&#13;
class Item{&#13;
    private String name; // java字段名&#13;
    private String column ; // 数据库列名&#13;
    private String sqlType ;&#13;
    private String javaType;&#13;
    private String jdbcType ;&#13;
    private boolean canEmpty ;// 是否可为Null&#13;
    private String comment ; //注释&#13;
&#13;
    public String getName() {&#13;
        return name;&#13;
    }&#13;
&#13;
    public void setName(String name) {&#13;
        this.name = name;&#13;
    }&#13;
&#13;
    public String getColumn() {&#13;
        return column;&#13;
    }&#13;
&#13;
    public void setColumn(String column) {&#13;
        this.column = column;&#13;
    }&#13;
&#13;
    public String getSqlType() {&#13;
        return sqlType;&#13;
    }&#13;
&#13;
    public void setSqlType(String sqlType) {&#13;
        this.sqlType = sqlType;&#13;
    }&#13;
&#13;
    public String getJavaType() {&#13;
        return javaType;&#13;
    }&#13;
&#13;
    public void setJavaType(String javaType) {&#13;
        this.javaType = javaType;&#13;
    }&#13;
&#13;
    public String getJdbcType() {&#13;
        return jdbcType;&#13;
    }&#13;
&#13;
    public void setJdbcType(String jdbcType) {&#13;
        this.jdbcType = jdbcType;&#13;
    }&#13;
&#13;
    public boolean isCanEmpty() {&#13;
        return canEmpty;&#13;
    }&#13;
&#13;
    public void setCanEmpty(boolean canEmpty) {&#13;
        this.canEmpty = canEmpty;&#13;
    }&#13;
&#13;
    public String getComment() {&#13;
        return comment;&#13;
    }&#13;
&#13;
    public void setComment(String comment) {&#13;
        this.comment = comment;&#13;
    }&#13;
}&#13;
&#13;
```。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Mybatis%20Mapper-sheng-cheng-qi--MapperCreator-yuan-ma-fen-xiang.html</guid><pubDate>Thu, 27 Jun 2024 08:25:16 +0000</pubDate></item><item><title>好用软件/插件收集（持续更新）</title><link>https://andy1202go.github.io/post/hao-yong-ruan-jian---cha-jian-shou-ji-%EF%BC%88-chi-xu-geng-xin-%EF%BC%89.html</link><description>## 软件&#13;
&#13;
| 软件名称           | 类别             | 备注 |&#13;
| ------------------ | ---------------- | ---- |&#13;
| Picasa             | 图片查看         |      |&#13;
| Fluent Reader      | RSS终端          |      |&#13;
| LocalSend          | 局域网文件传输   |      |&#13;
| BeyondCompare      | 代码对比         |      |&#13;
| Notepad--          | 文本处理         |      |&#13;
| S3 Browser         | S3文件查看终端   |      |&#13;
| 坚果云             | 个人/企业云盘    |      |&#13;
| Docker Desktop     | Docker           |      |&#13;
| RedisInsight       | Redis终端        |      |&#13;
| Visual Studio Code | VsCode           |      |&#13;
| uTools             | 高效率快捷键工具 |      |&#13;
| Git Bash           |                  |      |&#13;
| draw.io            | 绘图软件         |      |&#13;
| ScreenToGif        | 录屏转Gif小软件  |      |&#13;
| SwitchHosts        | Hosts文件切换    |      |&#13;
| DBeaver            | 数据库终端       |      |&#13;
| 欧路词典           | 词典             |      |&#13;
| Typora             | 文本撰写         |      |&#13;
| XMind              | 脑图             |      |&#13;
| PostMan            |                  |      |&#13;
| 7-zip              | 压缩软件         |      |&#13;
| Everything         | 本地搜索软件     |      |&#13;
&#13;
## 浏览器插件&#13;
&#13;
| 插件名称     | 类别                 | 备注 |&#13;
| ------------ | -------------------- | ---- |&#13;
| Monica       | AI                   |      |&#13;
| 沉浸式翻译   | 翻译                 |      |&#13;
| 极客时间     |                      |      |&#13;
| Smart Header | 修改浏览器请求Header |      |&#13;
| WizClipper   | 为知笔记             |      |&#13;
| Listen1      | 跨平台听歌软件       |      |&#13;
&#13;
。</description><guid isPermaLink="true">https://andy1202go.github.io/post/hao-yong-ruan-jian---cha-jian-shou-ji-%EF%BC%88-chi-xu-geng-xin-%EF%BC%89.html</guid><pubDate>Thu, 27 Jun 2024 08:19:36 +0000</pubDate></item><item><title>数据结构与算法之美(2) 复杂度分析</title><link>https://andy1202go.github.io/post/shu-ju-jie-gou-yu-suan-fa-zhi-mei-%282%29%20-fu-za-du-fen-xi.html</link><description># 2 复杂度分析&#13;
&#13;
[TOC]&#13;
&#13;
## 1 定义及必要性&#13;
&#13;
之所以需要复杂度分析，就是需要一个可以量化的指标，来衡量一个算法或者一段代码的执行效率，占用内存的大小。</description><guid isPermaLink="true">https://andy1202go.github.io/post/shu-ju-jie-gou-yu-suan-fa-zhi-mei-%282%29%20-fu-za-du-fen-xi.html</guid><pubDate>Thu, 27 Jun 2024 07:53:48 +0000</pubDate></item><item><title>数据结构与算法之美(1) 开篇</title><link>https://andy1202go.github.io/post/shu-ju-jie-gou-yu-suan-fa-zhi-mei-%281%29%20-kai-pian.html</link><description>## 1 定位&#13;
&#13;
- 基础内容&#13;
- 知道有哪些，是什么，怎么用&#13;
- 分为入门、基础、高级、实战&#13;
&#13;
## 2 期望&#13;
&#13;
- 对数据结构和算法有初步认知&#13;
- 在平时设计和编写代码能用起来&#13;
&#13;
## 3 老生常谈，为什么要学习数据结构和算法&#13;
&#13;
因为要从唯一性原理出发，探查本质。</description><guid isPermaLink="true">https://andy1202go.github.io/post/shu-ju-jie-gou-yu-suan-fa-zhi-mei-%281%29%20-kai-pian.html</guid><pubDate>Thu, 27 Jun 2024 07:52:34 +0000</pubDate></item><item><title>EffectiveJava(6) 类和接口 Part1</title><link>https://andy1202go.github.io/post/EffectiveJava%286%29%20-lei-he-jie-kou-%20Part1.html</link><description>如何使用Java提供的基本元素来合理设计类和接口。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%286%29%20-lei-he-jie-kou-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:45:58 +0000</pubDate></item><item><title>EffectiveJava(5) 对于所有对象都通用的方法 Part2</title><link>https://andy1202go.github.io/post/EffectiveJava%285%29%20-dui-yu-suo-you-dui-xiang-du-tong-yong-de-fang-fa-%20Part2.html</link><description>## 12 始终重写toString方法&#13;
&#13;
### 为什么&#13;
&#13;
- Object提供的toString方法，不好用，是类名@十六进制的展示，看不懂啥意思&#13;
&#13;
  ```java&#13;
  //    * It is recommended that all subclasses override this method.    &#13;
  public String toString() {&#13;
          return getClass().getName() + '@' + Integer.toHexString(hashCode());&#13;
      }&#13;
  ```&#13;
&#13;
- 官方都说，强烈建议，所有类都重写这个方法&#13;
&#13;
- 没有约定，想equals和hashcode那样，但良好的toString方法，对后续的使用大有益处。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%285%29%20-dui-yu-suo-you-dui-xiang-du-tong-yong-de-fang-fa-%20Part2.html</guid><pubDate>Thu, 27 Jun 2024 07:43:30 +0000</pubDate></item><item><title>EffectiveJava(4) 对于所有对象都通用的方法 Part1</title><link>https://andy1202go.github.io/post/EffectiveJava%284%29%20-dui-yu-suo-you-dui-xiang-du-tong-yong-de-fang-fa-%20Part1.html</link><description>&gt; 尽管Object是一个具体的类，但设计它主要是为了拓展。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%284%29%20-dui-yu-suo-you-dui-xiang-du-tong-yong-de-fang-fa-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:41:24 +0000</pubDate></item><item><title>EffectiveJava(3) 创建和销毁对象 Part3</title><link>https://andy1202go.github.io/post/EffectiveJava%283%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part3.html</link><description>## 7 消除过期的对象引用&#13;
&#13;
简单来说，就是对象过期了，但引用还在，就会占用内存不释放。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%283%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part3.html</guid><pubDate>Thu, 27 Jun 2024 07:39:00 +0000</pubDate></item><item><title>EffectiveJava(2) 创建和销毁对象 Part2</title><link>https://andy1202go.github.io/post/EffectiveJava%282%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part2.html</link><description>## 4 使用私有构造方法强化不可实例化&#13;
&#13;
有些类，不可实例化：&#13;
&#13;
- 只包含静态方法和静态字段&#13;
- 比如java.lang.Math java.util.Arrays&#13;
- java.util.Collections还把一些工厂方法放进去了，比如UnmodifiableCollection这种只读类型的类，可以通过Collections.unmodifiableCollection()方法获得实例&#13;
&#13;
这种不可以实例的类，通常是工具类&#13;
&#13;
&gt; 这样的工具类（utility classes）不是设计用来被实例化的，因为实例化对它没有任何意义。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%282%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part2.html</guid><pubDate>Thu, 27 Jun 2024 07:38:20 +0000</pubDate></item><item><title>EffectiveJava(1) 创建和销毁对象 Part1</title><link>https://andy1202go.github.io/post/EffectiveJava%281%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part1.html</link><description>## 1 考虑使用静态工厂方法替代构造方法&#13;
&#13;
静态工厂方法，指的是类中的静态方法，用于创建类的工厂方法；&#13;
&#13;
和设计模式中的工厂方法主要区别在于&#13;
&#13;
- 静态工厂方法创建的是同一个实例，比如Boolean.of()，返回的是TRUE和FALSE两个实例中的一个，没有更多的&#13;
- 工厂方法，永远是new一个&#13;
&#13;
先看下Boolean的静态工厂方法实例吧&#13;
&#13;
```java&#13;
public final class Boolean implements java.io.Serializable,&#13;
                                      Comparable&lt;Boolean&gt;&#13;
{&#13;
    /**&#13;
     * The {@code Boolean} object corresponding to the primitive&#13;
     * value {@code true}.&#13;
     */&#13;
    public static final Boolean TRUE = new Boolean(true);&#13;
&#13;
    /**&#13;
     * The {@code Boolean} object corresponding to the primitive&#13;
     * value {@code false}.&#13;
     */&#13;
    public static final Boolean FALSE = new Boolean(false);&#13;
                                   &#13;
    public static Boolean valueOf(String s) {&#13;
        return parseBoolean(s) ? TRUE : FALSE;&#13;
    }                                      &#13;
  }&#13;
```&#13;
&#13;
工厂方法的简单工厂，抽象工厂就不写了；但是静态工厂方法和静态单例模式还是挺像的，比如&#13;
&#13;
```java&#13;
public class Singleton{&#13;
    //lazy&#13;
    private static Singleton instance = null;&#13;
    &#13;
    //private防止直接构造&#13;
    private Singleton(){}&#13;
    &#13;
    public static Singleton getInstance(){&#13;
        if(instance == null){&#13;
            synchronized (Singleton.class) {&#13;
                if (instance == null) {&#13;
                    instance = new Singleton();&#13;
                }&#13;
            }&#13;
        }&#13;
        return instance;&#13;
    }&#13;
}&#13;
```&#13;
&#13;
静态工厂方法的优点&#13;
&#13;
- 可读性更好：有名字，可以直接表示含义，比如Collections.emptyList()&#13;
- 与构造方法不同，它们不需要每次调用时都创建一个新对象&#13;
- 可以返回该类的任意子类：比如Collections.unmodifiableList();&#13;
- 静态工厂的第四个优点是返回对象的类可以根据输入参数的不同而不同&#13;
- 静态工厂的第五个优点是，在编写包含该方法的类时，返回的对象的类不需要存在&#13;
&#13;
缺点&#13;
&#13;
- 名字用于表示含义了，没有标识是实例化的方法：所以用getInstance，newInstance什么的命名，保留至少一个&#13;
- 如果类不含public或protect的构造方法，将不能被继承：这也是单例模式的问题，分需要使用的情况来决定吧&#13;
&#13;
综上，给出两种较好的实现：一种是单例模式，线程安全的静态方法；一种如下&#13;
&#13;
```java&#13;
public class RandomIntGenerator {&#13;
    /**&#13;
     * 最小值&#13;
     */&#13;
    private int min = Integer.MIN_VALUE;&#13;
    /**&#13;
     * 最大值&#13;
     */&#13;
    private int max = Integer.MAX_VALUE;&#13;
&#13;
    /**&#13;
     * 大于min 小于max&#13;
     * @param min&#13;
     * @param max&#13;
     */&#13;
    public RandomIntGenerator(int min, int max)&#13;
    {&#13;
        this.min = min;&#13;
        this.max = max;&#13;
    }&#13;
    &#13;
    /**&#13;
     * 大于min 小于max&#13;
     * @param min&#13;
     * @param max&#13;
     */&#13;
    public static RandomIntGenerator between(int min, int max)&#13;
    {&#13;
        return new RandomIntGenerator(min, max);&#13;
    }&#13;
    /**&#13;
     * 大于min 小于Integer.MAX_VALUE&#13;
     */&#13;
    public static RandomIntGenerator biggerThan(int min)&#13;
    {&#13;
        return new RandomIntGenerator(min, Integer.MAX_VALUE);&#13;
    }&#13;
&#13;
    /**&#13;
     * 大于Integer.MIN_VALUE 小于max&#13;
     */&#13;
    public static RandomIntGenerator smallerThan(int max)&#13;
    {&#13;
        return new RandomIntGenerator(Integer.MIN_VALUE, max);&#13;
    }&#13;
&#13;
    public static RandomIntGenerator getInstance(){&#13;
        return new RandomIntGenerator(Integer.MIN_VALUE, Integer.MAX_VALUE);&#13;
    }&#13;
}&#13;
```&#13;
&#13;
### 使用体验&#13;
&#13;
- 感觉更多的是工具类可以这么去定义，毕竟都是单例&#13;
- spring本身都是单例了，其实也不需要单独这个了&#13;
&#13;
## 2 当构造方法参数过多时使用builder模式&#13;
&#13;
构造方法比较多的时候，比较几种构造设计&#13;
&#13;
- 伸缩构造方法：就是构造方法中强行塞参数&#13;
- JavaBeans：就是属性都是private，通过setter来构造&#13;
- Builder模式&#13;
&#13;
使用Builder模式的优势&#13;
&#13;
- 可读性好&#13;
- 更安全（相比于JavaBeans，因为JavaBeans的构造方法被割裂为了多次调用，可能导致实例不一致）&#13;
- 可以有多个可变参数，其实就是递归使用builder的某个方法，微小优势，不常用&#13;
&#13;
缺点：&#13;
&#13;
- 代码冗长，因为要单独写builder&#13;
&#13;
综合考虑&#13;
&#13;
- 参数大于等于4个的时候，最好使用builder模式&#13;
- 注意：需要估计类的参数数量，在一开始的时候，而不是从一种构造方法切换到builder模式，代价较大&#13;
&#13;
最佳实践1&#13;
&#13;
- 使用Lombok的@Builder&#13;
&#13;
  ```java&#13;
  import lombok.Builder;&#13;
  &#13;
  @Builder&#13;
  public class SingletonBuilder {&#13;
      private String param1;&#13;
      private String param2;&#13;
      private String param3;&#13;
      private String param4;&#13;
  }&#13;
  ```&#13;
&#13;
- 手写Builder&#13;
&#13;
  ```java&#13;
  // Builder Pattern&#13;
  public class NutritionFacts {&#13;
      private final int servingSize;&#13;
      private final int servings;&#13;
      private final int calories;&#13;
      private final int fat;&#13;
      private final int sodium;&#13;
      private final int carbohydrate;&#13;
      public static class Builder {&#13;
          // Required parameters&#13;
          private final int servingSize;&#13;
          private final int servings;&#13;
          // Optional parameters - initialized to default values&#13;
          private int calories      = 0;&#13;
          private int fat           = 0;&#13;
          private int sodium        = 0;&#13;
          private int carbohydrate  = 0;&#13;
          public Builder(int servingSize, int servings) {&#13;
              this.servingSize = servingSize;&#13;
              this.servings    = servings;&#13;
          }&#13;
          public Builder calories(int val) { &#13;
              calories = val;      &#13;
          }&#13;
          public Builder fat(int val) { &#13;
             fat = val;           &#13;
             return this;&#13;
          }&#13;
          public Builder sodium(int val) { &#13;
             sodium = val;        &#13;
             return this; &#13;
          }&#13;
          public Builder carbohydrate(int val) { &#13;
             carbohydrate = val;  &#13;
             return this; &#13;
          }&#13;
          public NutritionFacts build() {&#13;
              return new NutritionFacts(this);&#13;
          }&#13;
      }&#13;
      private NutritionFacts(Builder builder) {&#13;
          servingSize  = builder.servingSize;&#13;
          servings     = builder.servings;&#13;
          calories     = builder.calories;&#13;
          fat          = builder.fat;&#13;
          sodium       = builder.sodium;&#13;
          carbohydrate = builder.carbohydrate;&#13;
      }&#13;
  }&#13;
  ```&#13;
&#13;
- 抽象基类使用Builder实现可变参数构造&#13;
&#13;
  ```java&#13;
  public abstract class Pizza {&#13;
      public enum Topping {HAM,MUSHROOM,ONION,PEPPER,SAUSAGE}&#13;
      final Set&lt;Topping&gt; toppings;&#13;
  &#13;
      abstract static class Builder&lt;T extends Builder&lt;T&gt;&gt; {&#13;
          EnumSet&lt;Topping&gt; toppings = EnumSet.noneOf(Topping.class);&#13;
          public T addTopping(Topping topping){&#13;
              toppings.add(Objects.requireNonNull(topping));&#13;
              return self();//模拟的self类型&#13;
          }&#13;
          abstract Pizza build();&#13;
  &#13;
          // Subclasses must override this method to return 'this'&#13;
          protected abstract T self();&#13;
      }&#13;
  &#13;
      Pizza(Builder&lt;?&gt; builder) {&#13;
          toppings = builder.toppings.clone();&#13;
      }&#13;
  }&#13;
  ```&#13;
&#13;
### 使用体验&#13;
&#13;
## 3 使用私有构造方法或枚举实现单例模式&#13;
&#13;
讨论了3种实现单例模式的优劣，分别是&#13;
&#13;
- 私有构造方法+公开的实例；&#13;
&#13;
  ```java&#13;
  public class Singleton{&#13;
      private Singleton(){}&#13;
      public static final Singleton INSTANCE = new Singleton();&#13;
  }&#13;
  ```&#13;
&#13;
- 私有构造方法+私有的实例+公开的静态方法获取实例&#13;
&#13;
  ```java&#13;
  public class Singleton{&#13;
      private Singleton(){}&#13;
      private static final Singleton INSTANCE = new Singleton();&#13;
      public static Singleton getInstance(){&#13;
          return INSTANCE;&#13;
      }&#13;
  }&#13;
  ```&#13;
&#13;
- 枚举&#13;
&#13;
  ```java&#13;
  public enum Singleton {&#13;
      INSTANCE;&#13;
  }&#13;
  ```&#13;
&#13;
书中最倾向使用枚举来实现单例，原因如下：&#13;
&#13;
- 最简洁&#13;
&#13;
- 无偿地提供了序列化机制（还不怎么理解..https://www.jianshu.com/p/d3d797c3cd45）&#13;
&#13;
  &gt; 绝对防止多次实例化，即使是在面对复杂的序列化或者反射攻击的时候&#13;
&#13;
其次是静态工厂的模式，优点在于&#13;
&#13;
- 通过API表示这是单例模式&#13;
- 灵活&#13;
  - 需要改变为每个调用该方法的线程返回一个唯一的实例，直接在静态工厂方法中 new instance()，但此时需要去掉单例对象中final修饰的关键字&#13;
  - 如果应用程序需要他，我们可以将它改为一个泛型单例工厂（条目30）&#13;
&#13;
缺点在于，小心序列化问题（第11章有讨论）&#13;
&#13;
&gt; 为了防止单例类变成可序列化的，仅仅将添加 *implements Serializable* 到声明中是不够的。</description><guid isPermaLink="true">https://andy1202go.github.io/post/EffectiveJava%281%29%20-chuang-jian-he-xiao-hui-dui-xiang-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:37:44 +0000</pubDate></item><item><title>JavaScript(8) 浏览器</title><link>https://andy1202go.github.io/post/JavaScript%288%29%20-liu-lan-qi.html</link><description>JavaScript的出现就是为了能在浏览器中运行。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%288%29%20-liu-lan-qi.html</guid><pubDate>Thu, 27 Jun 2024 07:35:11 +0000</pubDate></item><item><title>JavaScript(7) 面向对象编程</title><link>https://andy1202go.github.io/post/JavaScript%287%29%20-mian-xiang-dui-xiang-bian-cheng.html</link><description>JavaScript虽然所有数据都是对象，但不是就能原生实现面向对象编程的。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%287%29%20-mian-xiang-dui-xiang-bian-cheng.html</guid><pubDate>Thu, 27 Jun 2024 07:33:31 +0000</pubDate></item><item><title>JavaScript(6) 标准对象</title><link>https://andy1202go.github.io/post/JavaScript%286%29%20-biao-zhun-dui-xiang.html</link><description>在JavaScript的世界里，一切都是对象。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%286%29%20-biao-zhun-dui-xiang.html</guid><pubDate>Thu, 27 Jun 2024 07:32:09 +0000</pubDate></item><item><title>JavaScript(5) 函数 Part3</title><link>https://andy1202go.github.io/post/JavaScript%285%29%20-han-shu-%20Part3.html</link><description>## 5 闭包&#13;
&#13;
高阶函数除了可以接受函数作为参数外，还可以把函数作为结果返回。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%285%29%20-han-shu-%20Part3.html</guid><pubDate>Thu, 27 Jun 2024 07:29:28 +0000</pubDate></item><item><title>JavaScript(4) 函数 Part2</title><link>https://andy1202go.github.io/post/JavaScript%284%29%20-han-shu-%20Part2.html</link><description>## 3 方法&#13;
&#13;
在一个对象中绑定函数，是这个对象的方法，举例&#13;
&#13;
```javascript&#13;
var xiaoming = {&#13;
    name: '小明',&#13;
    birth: 1990,&#13;
    age: function () {&#13;
        var y = new Date().getFullYear();&#13;
        return y - this.birth;&#13;
    }&#13;
};&#13;
&#13;
xiaoming.age; // function xiaoming.age()&#13;
xiaoming.age(); // 今年调用是25,明年调用就变成26了&#13;
```&#13;
&#13;
#### this和that&#13;
&#13;
- 方法中的this指当前对象&#13;
&#13;
- 当方法中嵌套函数的时候，再使用this会有意想不到的结果...此时的this可能指向全局对象window，或者undefined&#13;
&#13;
- 修复方法是使用一个that在函数一开始就捕获this，后续都使用that，利用嵌套函数变量作用域&#13;
&#13;
  ```javascript&#13;
  'use strict';&#13;
  &#13;
  var xiaoming = {&#13;
      name: '小明',&#13;
      birth: 1990,&#13;
      age: function () {&#13;
          var that = this; // 在方法内部一开始就捕获this&#13;
          function getAgeFromBirth() {&#13;
              var y = new Date().getFullYear();&#13;
              return y - that.birth; // 用that而不是this&#13;
          }&#13;
          return getAgeFromBirth();&#13;
      }&#13;
  };&#13;
  &#13;
  xiaoming.age(); // 25&#13;
  ```&#13;
&#13;
#### apply&#13;
&#13;
函数本身都具有apply方法。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%284%29%20-han-shu-%20Part2.html</guid><pubDate>Thu, 27 Jun 2024 07:28:38 +0000</pubDate></item><item><title>JavaScript(3) 函数 Part1</title><link>https://andy1202go.github.io/post/JavaScript%283%29%20-han-shu-%20Part1.html</link><description>## 1 函数定义和调用&#13;
&#13;
常规定义：&#13;
&#13;
```javascript&#13;
function abs(x){&#13;
    ...&#13;
}&#13;
```&#13;
&#13;
- function指出这是一个函数定义&#13;
- abs是函数名&#13;
- (x)内是函数的参数，多个以逗号分隔&#13;
- {}是函数体&#13;
&#13;
需要注意：&#13;
&#13;
- 一旦执行到return就结束函数&#13;
- 如果没有return，会返回undefined&#13;
&#13;
由于JavaScript的函数也是一个对象，所以有另一种函数定义方法&#13;
&#13;
```javascript&#13;
var abs = function(x){&#13;
    ...&#13;
};&#13;
```&#13;
&#13;
需要注意：&#13;
&#13;
- 这种方式要有分号结尾&#13;
- 使用上完全相同&#13;
&#13;
另外，JavaScript对函数入参比较随意，需要格外注意&#13;
&#13;
```javascript&#13;
abs(10, 'blablabla'); // 多个参数，只用了第一个；返回10&#13;
abs(-9, 'haha', 'hehe', null); // 返回9&#13;
abs(); // 返回NaN&#13;
&#13;
//改良&#13;
function abs(x) {&#13;
    if (typeof x !== 'number') {&#13;
        throw 'Not a number';&#13;
    }&#13;
    if (x &gt;= 0) {&#13;
        return x;&#13;
    } else {&#13;
        return -x;&#13;
    }&#13;
}&#13;
```&#13;
&#13;
### arguments&#13;
&#13;
&gt; JavaScript还有一个免费赠送的关键字`arguments`，它只在函数内部起作用，并且永远指向当前函数的调用者传入的所有参数。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%283%29%20-han-shu-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:27:36 +0000</pubDate></item><item><title>JavaScript(2) 入门 Part2</title><link>https://andy1202go.github.io/post/JavaScript%282%29%20-ru-men-%20Part2.html</link><description>## 6 对象&#13;
&#13;
- 访问属性是通过`.`操作符完成的，但这要求属性名必须是一个有效的变量名。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%282%29%20-ru-men-%20Part2.html</guid><pubDate>Thu, 27 Jun 2024 07:24:46 +0000</pubDate></item><item><title>JavaScript(1) 入门 Part1</title><link>https://andy1202go.github.io/post/JavaScript%281%29%20-ru-men-%20Part1.html</link><description>&gt; 简单地说，JavaScript是一种运行在浏览器中的解释型的编程语言。</description><guid isPermaLink="true">https://andy1202go.github.io/post/JavaScript%281%29%20-ru-men-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:24:03 +0000</pubDate></item><item><title>业务系统要求浅要总结</title><link>https://andy1202go.github.io/post/ye-wu-xi-tong-yao-qiu-qian-yao-zong-jie.html</link><description># 业务系统要求&#13;
&#13;
一句话目标：建立好负责的项目&#13;
&#13;
项目要达到&#13;
&#13;
|              | 性能要求  开发要求    效率要求  质量要求 |&#13;
| ------------ | ---------------------------------------- |&#13;
| **应用视角** | 高并发   开发速度快  并行开发  高可用    |&#13;
| **底层视角** | 云原生    分布式      微服务    k8s      |&#13;
| **抽象视角** | 流量治理  服务治理    资源治理  数据治理 |&#13;
&#13;
## 应用视角&#13;
&#13;
### 高并发系统&#13;
&#13;
#### 什么是高并发？&#13;
&#13;
&gt; 高并发是指特定的系统或应用程序可以同时处理大量的并发处理请求，要求其能够同时应付高流量的访问。</description><guid isPermaLink="true">https://andy1202go.github.io/post/ye-wu-xi-tong-yao-qiu-qian-yao-zong-jie.html</guid><pubDate>Thu, 27 Jun 2024 07:20:02 +0000</pubDate></item><item><title>Python菜鸟入门</title><link>https://andy1202go.github.io/post/Python-cai-niao-ru-men.html</link><description>## [[Python3 教程 | 菜鸟教程](https://www.runoob.com/python/python-tutorial.html)](https://www.runoob.com/python/python-tutorial.html)&#13;
&#13;
**[[Python Tutor: Visualize code](https://pythontutor.com/visualize.html#mode=edit)](https://pythontutor.com/visualize.html#mode=edit)**&#13;
&#13;
### Python 发展历史&#13;
&#13;
Python 是由 Guido van Rossum 在八十年代末和九十年代初，在荷兰国家数学和计算机科学研究所设计出来的。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Python-cai-niao-ru-men.html</guid><pubDate>Thu, 27 Jun 2024 07:16:53 +0000</pubDate></item><item><title>Linux 入门 Part3</title><link>https://andy1202go.github.io/post/Linux%20-ru-men-%20Part3.html</link><description>## 2 Shell语言的知识内容&#13;
&#13;
略&#13;
&#13;
## 3 Linux相关的参考手册&#13;
&#13;
1. [[Linux 命令大全](https://www.w3cschool.cn/linux/linux-command-manual.html)](https://www.w3cschool.cn/linux/linux-command-manual.html)&#13;
2. [[Nginx 安装配置](https://www.w3cschool.cn/linux/u5xv1rha.html)](https://www.w3cschool.cn/linux/u5xv1rha.html)&#13;
3. [[MySQL 安装配置](https://www.w3cschool.cn/linux/z29j1rhv.html)](https://www.w3cschool.cn/linux/z29j1rhv.html)&#13;
4. [[linux删除文件夹命令使用方法](https://www.w3cschool.cn/linux/linux-9yfc2oyy.html)](https://www.w3cschool.cn/linux/linux-9yfc2oyy.html)&#13;
5. [[Linux关机命令和重启命令说明](https://www.w3cschool.cn/linux/linux-are12oz3.html)](https://www.w3cschool.cn/linux/linux-are12oz3.html)&#13;
&#13;
## 参考资料&#13;
&#13;
[[Linux 教程](https://www.w3cschool.cn/linux/)](https://www.w3cschool.cn/linux/)&#13;
&#13;
[[谈谈如何学习Linux操作系统](http://ixdba.blog.51cto.com/2895551/569329/)](http://ixdba.blog.51cto.com/2895551/569329/)&#13;
&#13;
[[Linux官网](http://www.linux.org/)](http://www.linux.org/) （此网站经常显示服务器错误）&#13;
&#13;
[[Linux下载](https://www.linux.org/pages/download/)](https://www.linux.org/pages/download/)&#13;
&#13;
[[Linux API文档](http://download.csdn.net/detail/a7320760/3617981)](http://download.csdn.net/detail/a7320760/3617981)&#13;
&#13;
[[Linux教程](https://www.w3cschool.cn/linux)](https://www.w3cschool.cn/linux)&#13;
&#13;
[[Linux视频课程](https://www.w3cschool.cn/minicourse/play/linux_my)](https://www.w3cschool.cn/minicourse/play/linux_my)&#13;
&#13;
[[Linux问答](https://www.w3cschool.cn/topic/linux)](。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Linux%20-ru-men-%20Part3.html</guid><pubDate>Thu, 27 Jun 2024 07:14:23 +0000</pubDate></item><item><title>Linux 入门 Part2</title><link>https://andy1202go.github.io/post/Linux%20-ru-men-%20Part2.html</link><description>### 1.6 文件与目录管理&#13;
&#13;
- 绝对路径，就是从/根目录开始的&#13;
- 相对路径，相对于当前所在的目录&#13;
&#13;
#### 处理目录的常用命令&#13;
&#13;
接下来我们就来看几个常见的处理目录的命令吧：&#13;
&#13;
- ls: 列出目录&#13;
- cd：切换目录&#13;
- pwd：显示目前的目录&#13;
- mkdir：创建一个新的目录&#13;
- rmdir：删除一个空的目录&#13;
- cp: 复制文件或目录&#13;
- rm: 移除文件或目录&#13;
- mv: 移动文件与目录、文件重命名&#13;
&#13;
你可以使用 *man [命令]* 来查看各个命令的使用文档，如 ：man cp。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Linux%20-ru-men-%20Part2.html</guid><pubDate>Thu, 27 Jun 2024 07:13:48 +0000</pubDate></item><item><title>Linux入门 Part1</title><link>https://andy1202go.github.io/post/Linux-ru-men-%20Part1.html</link><description>&#13;
&gt; 初级阶段：&#13;
&gt; 1． 命令是必须要学的，linux常用的命令大概在80个左右，这些常用命令一定要熟练掌握。</description><guid isPermaLink="true">https://andy1202go.github.io/post/Linux-ru-men-%20Part1.html</guid><pubDate>Thu, 27 Jun 2024 07:12:33 +0000</pubDate></item><item><title>The Key To Accelerating Your Coding Skills-文章读后小结</title><link>https://andy1202go.github.io/post/The%20Key%20To%20Accelerating%20Your%20Coding%20Skills--wen-zhang-du-hou-xiao-jie.html</link><description>### 文章链接：http://blog.thefirehoseproject.com/posts/learn-to-code-and-be-self-reliant/&#13;
&#13;
&gt; 在系统地学习编程技能之前，我希望你能先看一下 ' The Key To Accelerating Your Coding Skills'， 这篇文章会告诉你如何有效地快速提高自己的编程能力。</description><guid isPermaLink="true">https://andy1202go.github.io/post/The%20Key%20To%20Accelerating%20Your%20Coding%20Skills--wen-zhang-du-hou-xiao-jie.html</guid><pubDate>Thu, 27 Jun 2024 03:02:19 +0000</pubDate></item></channel></rss>