This repository has been archived on 2025-06-28. You can view files and clone it, but cannot push or open issues or pull requests.
Files
vitepress-theme-blog-charle…/categories/fragments/2023/01/06/CodeReview方法论与实践总结.html

301 lines
171 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>阿里巴巴的Code Review方法论与实践总结 | 查尔斯的知识库</title>
<meta name="description" content="个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。">
<meta name="generator" content="VitePress v1.0.0-rc.31">
<link rel="preload stylesheet" href="/assets/style.-TyODVlN.css" as="style">
<script type="module" src="/assets/app.wVULdALl.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.bvIUbFQP.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.FVQzxbLi.js">
<link rel="modulepreload" href="/assets/chunks/theme.H88Ua6lx.js">
<link rel="modulepreload" href="/assets/chunks/md5.RtphNWHi.js">
<link rel="modulepreload" href="/assets/chunks/use-popup-manager.-j2MED7j.js">
<link rel="modulepreload" href="/assets/chunks/ArticleMetadata.Sb1DYAHo.js">
<link rel="modulepreload" href="/assets/categories_fragments_2023_01_06_CodeReview方法论与实践总结.md.viSW2KC_.lean.js">
<link rel="icon" href="/favicon.ico">
<meta name="author" content="Charles7c">
<meta name="keywords" content="查尔斯的知识库, 知识库, 博客, Charles7c">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="theme-color" content="#3c8772">
<meta property="og:type" content="website">
<meta property="og:locale" content="zh_CN">
<meta property="og:title" content="查尔斯的知识库">
<meta property="og:description" content="个人技术知识库,记录 &amp; 分享个人碎片化、结构化、体系化的技术知识内容。">
<meta property="og:site" content="https://blog.charles7c.top">
<meta property="og:site_name" content="查尔斯的知识库">
<meta property="og:image" content="https://blog.charles7c.top/logo.jpg">
<script>var _hmt=_hmt||[];(function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?53af4b1a12fbe40810ca7ad39f8db9c7";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();</script>
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-03322d68><!--[--><!--]--><!--[--><span tabindex="-1" data-v-c4918e4e></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-c4918e4e> Skip to content </a><!--]--><!----><header class="VPNav" data-v-03322d68 data-v-629c70bd><div class="VPNavBar has-sidebar" data-v-629c70bd data-v-1d72176a><div class="container" data-v-1d72176a><div class="title" data-v-1d72176a><div class="VPNavBarTitle has-sidebar" data-v-1d72176a data-v-21327bbd><a class="title" href="/" data-v-21327bbd><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.png" alt data-v-d7b35c78><!--]--><!--[-->查尔斯的知识库<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-1d72176a><div class="curtain" data-v-1d72176a></div><div class="content-body" data-v-1d72176a><!--[--><!--]--><div class="VPNavBarSearch search" data-v-1d72176a><!--[--><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="搜索文档"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">搜索文档</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-1d72176a data-v-a12edbe3><span id="main-nav-aria-label" class="visually-hidden" data-v-a12edbe3>Main Navigation</span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup active" data-v-a12edbe3 data-v-f18e2dbf><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-f18e2dbf><span class="text" data-v-f18e2dbf><!----><span data-v-f18e2dbf>我的分类</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-f18e2dbf><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-f18e2dbf><div class="VPMenu" data-v-f18e2dbf data-v-8a7fe2f1><div class="items" data-v-8a7fe2f1><!--[--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/categories/issues/index" data-v-cf652a9b><!--[-->Bug万象集<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link active" href="/categories/fragments/index" data-v-cf652a9b><!--[-->&quot;杂碎&quot;逆袭史<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/categories/tools/index" data-v-cf652a9b><!--[-->工具四海谈<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/categories/solutions/index" data-v-cf652a9b><!--[-->方案春秋志<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-a12edbe3 data-v-f18e2dbf><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-f18e2dbf><span class="text" data-v-f18e2dbf><!----><span data-v-f18e2dbf>我的小册</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-f18e2dbf><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-f18e2dbf><div class="VPMenu" data-v-f18e2dbf data-v-8a7fe2f1><div class="items" data-v-8a7fe2f1><!--[--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/courses/java/index" data-v-cf652a9b><!--[-->Java基础快速入门<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/courses/mysql/index" data-v-cf652a9b><!--[-->MySQL快速入门<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/courses/mybatis/index" data-v-cf652a9b><!--[-->MyBatis快速入门<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/tags" tabindex="0" data-v-a12edbe3 data-v-bc587c79><!--[--><span data-v-bc587c79>我的标签</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/archives" tabindex="0" data-v-a12edbe3 data-v-bc587c79><!--[--><span data-v-bc587c79>我的归档</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-a12edbe3 data-v-f18e2dbf><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-f18e2dbf><span class="text" data-v-f18e2dbf><!----><span data-v-f18e2dbf>关于</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-f18e2dbf><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-f18e2dbf><div class="VPMenu" data-v-f18e2dbf data-v-8a7fe2f1><div class="items" data-v-8a7fe2f1><!--[--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/about/index" data-v-cf652a9b><!--[-->关于知识库<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-8a7fe2f1 data-v-cf652a9b><a class="VPLink link" href="/about/me" data-v-cf652a9b><!--[-->关于我<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-1d72176a data-v-c2c90abb><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="Switch to dark theme" aria-checked="false" data-v-c2c90abb data-v-1502017d data-v-54e1997a><span class="check" data-v-54e1997a><span class="icon" data-v-54e1997a><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-1502017d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-1502017d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-1d72176a data-v-804ae77e data-v-f57dd261><!--[--><a class="VPSocialLink no-icon" href="https://github.com/Charles7c/charles7c.github.io" aria-label="github" target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://gitee.com/Charles7c/charles7c" aria-label target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>码云</title><path d="M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z"/></svg></a><a class="VPSocialLink no-icon" href="https://cnadmin.charles7c.top/" aria-label target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg width="33" height="33" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 174.8 204">
<title>ContiNew Admin</title>
<path fill="#307AF2" d="M86.7,0l88,51v.2l-16.3,9.4v-.2L86.7,18.9Zm71.8,143.5,16.3,9.4v.2L86.8,204h0l-16.3-9.4,16.3-9.4h0l71.7-41.5v-.2Z"/>
<path fill="#12D2AC" d="M16.3,143.5v.2L58,167.8l-16.3,9.4L0,153.1v-.2Z"/>
<path fill="#12D2AC" d="M104.1,93,15.9,143.8l-.2-.1V124.9l.2.1L87.7,83.6,104.1,93Z"/>
<path fill="#0057FE" d="M88.1,0,.1,51v.2l16.3,9.4v-.2L88.1,18.9Z"/>
<path fill="#307AF2" d="M.1,50.9.2,152.6l.2.1,16.3-9.4-.2-.1-.1-82.9L.1,50.9Z"/>
<path fill="#0057FE" d="M174.7,50.9l-.1,101.7-.2.1-16.3-9.4.2-.1.1-82.9Z"/>
<path fill="#12D2AC" d="M41.7,158.5l16.1,9.4,100.6-58.7V90.4Z"/>
</svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-1d72176a data-v-3893c6ae data-v-f18e2dbf><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-f18e2dbf><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-f18e2dbf><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-f18e2dbf><div class="VPMenu" data-v-f18e2dbf data-v-8a7fe2f1><!----><!--[--><!--[--><!----><div class="group" data-v-3893c6ae><div class="item appearance" data-v-3893c6ae><p class="label" data-v-3893c6ae>切换日光/暗黑模式</p><div class="appearance-action" data-v-3893c6ae><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="Switch to dark theme" aria-checked="false" data-v-3893c6ae data-v-1502017d data-v-54e1997a><span class="check" data-v-54e1997a><span class="icon" data-v-54e1997a><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-1502017d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-1502017d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-3893c6ae><div class="item social-links" data-v-3893c6ae><div class="VPSocialLinks social-links-list" data-v-3893c6ae data-v-f57dd261><!--[--><a class="VPSocialLink no-icon" href="https://github.com/Charles7c/charles7c.github.io" aria-label="github" target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://gitee.com/Charles7c/charles7c" aria-label target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>码云</title><path d="M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z"/></svg></a><a class="VPSocialLink no-icon" href="https://cnadmin.charles7c.top/" aria-label target="_blank" rel="noopener" data-v-f57dd261 data-v-19217157><svg width="33" height="33" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 174.8 204">
<title>ContiNew Admin</title>
<path fill="#307AF2" d="M86.7,0l88,51v.2l-16.3,9.4v-.2L86.7,18.9Zm71.8,143.5,16.3,9.4v.2L86.8,204h0l-16.3-9.4,16.3-9.4h0l71.7-41.5v-.2Z"/>
<path fill="#12D2AC" d="M16.3,143.5v.2L58,167.8l-16.3,9.4L0,153.1v-.2Z"/>
<path fill="#12D2AC" d="M104.1,93,15.9,143.8l-.2-.1V124.9l.2.1L87.7,83.6,104.1,93Z"/>
<path fill="#0057FE" d="M88.1,0,.1,51v.2l16.3,9.4v-.2L88.1,18.9Z"/>
<path fill="#307AF2" d="M.1,50.9.2,152.6l.2.1,16.3-9.4-.2-.1-.1-82.9L.1,50.9Z"/>
<path fill="#0057FE" d="M174.7,50.9l-.1,101.7-.2.1-16.3-9.4.2-.1.1-82.9Z"/>
<path fill="#12D2AC" d="M41.7,158.5l16.1,9.4,100.6-58.7V90.4Z"/>
</svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-1d72176a data-v-a6ca9ab6><span class="container" data-v-a6ca9ab6><span class="top" data-v-a6ca9ab6></span><span class="middle" data-v-a6ca9ab6></span><span class="bottom" data-v-a6ca9ab6></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-03322d68 data-v-b9e3214b><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-b9e3214b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-b9e3214b><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-b9e3214b>文章</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-b9e3214b data-v-06057024><button data-v-06057024>返回顶部</button><!----></div></div><aside class="VPSidebar" data-v-03322d68 data-v-802ad7d8><div class="curtain" data-v-802ad7d8></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-802ad7d8><span class="visually-hidden" id="sidebar-aria-label" data-v-802ad7d8> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-802ad7d8><section class="VPSidebarItem level-0 collapsible" data-v-802ad7d8 data-v-95d837d1><div class="item" role="button" tabindex="0" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><h2 class="text" data-v-95d837d1><svg style="display: inline-block; vertical-align: middle; padding-bottom: 3px;" viewBox="0 0 1920 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="30" height="30"><path d="M367.488 667.904h423.744v47.232H367.488v-47.232zM320.256 204.352h137.28v68.992h-137.28v-68.992zM367.488 754.112h423.744v48H367.488v-48zM693.76 204.352h137.984v68.992H693.76v-68.992zM507.008 204.352h137.28v68.992h-137.28v-68.992z" p-id="10749" fill="#d81e06"></path><path d="M1792.512 0H127.488C57.472 0 0 57.152 0 127.616v768.768C0 966.72 57.088 1024 127.488 1024h1665.088c69.952 0 127.424-57.152 127.424-127.616V127.616C1920 57.216 1862.912 0 1792.512 0z m-528 175.104h446.976v54.016H1494.72l-24 101.248h206.976V689.6h-57.728V384.32h-289.472v308.224h-57.728v-362.24h140.224l20.992-101.248h-169.472v-53.952z m-996.032-11.2h614.272v167.232h-51.008v-17.28H320.256v17.28H268.48V163.904z m678.784 681.728h-744v-43.52h111.744V454.848h229.504v-48.704H221.248v-42.048h323.264v-39.744h54.016v39.744h331.52v41.984h-331.52v48.768h245.248v347.264h103.488v43.52z m203.264-94.528c0 59.52-30.72 89.28-92.224 89.28-25.472 0-46.016-0.512-61.504-1.472-2.496-22.976-6.528-45.248-12.032-66.752 22.976 5.504 46.72 8.256 71.232 8.256 24 0 35.968-11.52 35.968-34.496V247.872H971.2v-54.72h278.976v54.72H1150.4v503.232z m521.216 121.536c-67.008-55.488-137.28-108.032-210.752-157.504-4.992 9.984-10.496 19.008-16.512 27.008-41.472 57.024-113.28 101.504-215.232 133.504-9.472-16.512-21.504-34.496-35.968-54.016 94.528-27.008 161.28-64.512 200.256-112.512 34.496-44.992 51.776-113.024 51.776-204.032V421.12h57.728v82.496c0 62.528-6.72 115.776-20.224 159.744 84.48 54.016 161.472 107.008 230.976 158.976l-42.048 50.304z" p-id="10750" fill="#d81e06"></path><path d="M367.488 495.36h423.744v47.232H367.488V495.36zM367.488 581.632h423.744v47.232H367.488v-47.232z" p-id="10751" fill="#d81e06"></path></svg>
我的置顶 (8篇)</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-95d837d1><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-95d837d1><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-95d837d1><!--[--><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/06/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>个人常用快捷键</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/05/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Git%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-orange mr-[6px]" style="font-weight: 550; display: inline-block;">2</div>个人常用 Git 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/01/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Docker%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-yellow mr-[6px]" style="font-weight: 550; display: inline-block;">3</div>个人常用 Docker 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/02/16/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8SQL%E5%87%BD%E6%95%B0" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">4</div>个人常用 SQL 函数</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/31/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Linux%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">5</div>个人常用 Linux 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/30/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Hutool%E5%B7%A5%E5%85%B7%E7%B1%BB" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">6</div>个人常用 Hutool 工具类</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/29/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Stream%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">7</div>个人常用 Stream 使用技巧</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/28/%E4%B8%AA%E4%BA%BASQL%E4%BC%98%E5%8C%96%E6%8A%80%E5%B7%A7" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">8</div>个人 SQL 优化技巧</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-802ad7d8><section class="VPSidebarItem level-0 collapsible has-active" data-v-802ad7d8 data-v-95d837d1><div class="item" role="button" tabindex="0" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><h2 class="text" data-v-95d837d1><img class="chinese-zodiac" style="position: static; vertical-align: middle; padding-bottom: 3px;" src="/img/svg/chinese-zodiac/rabbit.svg" title="兔年" alt="生肖">
2023年 (2篇)</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-95d837d1><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-95d837d1><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-95d837d1><!--[--><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2023/12/21/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3%E9%99%90%E6%B5%81%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>一文详解限流接口实现</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2023/01/06/CodeReview%E6%96%B9%E6%B3%95%E8%AE%BA%E4%B8%8E%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-orange mr-[6px]" style="font-weight: 550; display: inline-block;">2</div>阿里巴巴的Code Review方法论与实践总结</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-802ad7d8><section class="VPSidebarItem level-0 collapsible collapsed" data-v-802ad7d8 data-v-95d837d1><div class="item" role="button" tabindex="0" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><h2 class="text" data-v-95d837d1><img class="chinese-zodiac" style="position: static; vertical-align: middle; padding-bottom: 3px;" src="/img/svg/chinese-zodiac/tiger.svg" title="虎年" alt="生肖">
2022年 (15篇)</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-95d837d1><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-95d837d1><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-95d837d1><!--[--><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/12/07/%E7%BD%91%E7%AB%99%E5%BC%80%E5%90%AF%E7%81%B0%E8%89%B2%E6%98%BE%E7%A4%BA" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>简单聊聊如何让网站开启灰色显示</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/11/01/%E4%BD%BF%E7%94%A8IDEA%E8%BF%9B%E8%A1%8C%E8%BF%9C%E7%A8%8B%E7%A8%8B%E5%BA%8F%E8%B0%83%E8%AF%95" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-orange mr-[6px]" style="font-weight: 550; display: inline-block;">2</div>使用 IntelliJ IDEA 进行远程程序调试</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/31/CentOS%E5%AE%89%E8%A3%85Docker" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-yellow mr-[6px]" style="font-weight: 550; display: inline-block;">3</div>CentOS 安装 Docker、Docker Compose</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/28/Docker%E5%AE%89%E8%A3%85MinIO" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">4</div>Docker 安装 MinIO 详细步骤</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/27/Docker%E5%AE%89%E8%A3%85Consul" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">5</div>Docker 安装 Consul 详细步骤</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/26/Docker%E5%AE%89%E8%A3%85OpenLDAP" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">6</div>Docker 安装 OpenLDAP 详细步骤</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/06/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">7</div>个人常用快捷键</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/05/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Git%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">8</div>个人常用 Git 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/10/01/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Docker%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">9</div>个人常用 Docker 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/08/29/%E5%86%85%E7%BD%91CentOS%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%BE%E7%BD%AE%E7%BD%91%E7%BB%9C%E4%BB%A3%E7%90%86" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">10</div>内网CentOS服务器设置网络代理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/03/28/%E4%B8%BA%E6%8C%87%E5%AE%9AGit%E4%BB%93%E5%BA%93%E5%8D%95%E7%8B%AC%E9%85%8D%E7%BD%AE%E7%94%A8%E6%88%B7%E5%90%8D%E5%92%8C%E9%82%AE%E7%AE%B1" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">11</div>为指定Git仓库单独配置用户名和邮箱</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/03/27/%E4%BF%AE%E6%94%B9Git%E6%89%80%E6%9C%89%E6%8F%90%E4%BA%A4%E8%AE%B0%E5%BD%95%E4%B8%AD%E7%9A%84%E4%BD%9C%E8%80%85%E5%92%8C%E9%82%AE%E7%AE%B1" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">12</div>修改Git所有提交记录中的作者和邮箱</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/03/26/%E4%BF%AE%E6%94%B9Git%E6%9C%80%E5%90%8E%E4%B8%80%E6%AC%A1%E6%8F%90%E4%BA%A4%E8%AE%B0%E5%BD%95%E7%9A%84%E4%BD%9C%E8%80%85%E5%92%8C%E9%82%AE%E7%AE%B1" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">13</div>修改Git最后一次提交记录的作者和邮箱</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/03/25/%E5%90%88%E5%B9%B6%E4%B8%A4%E4%B8%AAGit%E4%BB%93%E5%BA%93%E7%9A%84%E5%8E%86%E5%8F%B2%E6%8F%90%E4%BA%A4%E8%AE%B0%E5%BD%95" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">14</div>合并两个Git仓库的历史提交记录</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2022/02/16/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8SQL%E5%87%BD%E6%95%B0" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">15</div>个人常用 SQL 函数</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-802ad7d8><section class="VPSidebarItem level-0 collapsible collapsed" data-v-802ad7d8 data-v-95d837d1><div class="item" role="button" tabindex="0" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><h2 class="text" data-v-95d837d1><img class="chinese-zodiac" style="position: static; vertical-align: middle; padding-bottom: 3px;" src="/img/svg/chinese-zodiac/ox.svg" title="牛年" alt="生肖">
2021年 (2篇)</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-95d837d1><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-95d837d1><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-95d837d1><!--[--><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2021/05/29/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>设计模式之单例模式</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2021/03/12/%E7%B2%BE%E5%AF%86%E8%AE%A1%E7%AE%97%E5%B7%A5%E5%85%B7%E7%B1%BB-BigDecimal" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-orange mr-[6px]" style="font-weight: 550; display: inline-block;">2</div>精密计算工具类-BigDecimal</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-802ad7d8><section class="VPSidebarItem level-0 collapsible collapsed" data-v-802ad7d8 data-v-95d837d1><div class="item" role="button" tabindex="0" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><h2 class="text" data-v-95d837d1><img class="chinese-zodiac" style="position: static; vertical-align: middle; padding-bottom: 3px;" src="/img/svg/chinese-zodiac/pig.svg" title="猪年" alt="生肖">
2019年 (4篇)</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-95d837d1><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-95d837d1><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-95d837d1><!--[--><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/31/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Linux%E5%91%BD%E4%BB%A4" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>个人常用 Linux 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/30/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Hutool%E5%B7%A5%E5%85%B7%E7%B1%BB" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-orange mr-[6px]" style="font-weight: 550; display: inline-block;">2</div>个人常用 Hutool 工具类</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/29/%E4%B8%AA%E4%BA%BA%E5%B8%B8%E7%94%A8Stream%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-yellow mr-[6px]" style="font-weight: 550; display: inline-block;">3</div>个人常用 Stream 使用技巧</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-95d837d1 data-v-95d837d1><div class="item" data-v-95d837d1><div class="indicator" data-v-95d837d1></div><a class="VPLink link link" href="/categories/fragments/2019/12/28/%E4%B8%AA%E4%BA%BASQL%E4%BC%98%E5%8C%96%E6%8A%80%E5%B7%A7" data-v-95d837d1><!--[--><p class="text" data-v-95d837d1><div class="text-color-gray mr-[6px]" style="font-weight: 550; display: inline-block;">4</div>个人 SQL 优化技巧</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-03322d68 data-v-2c336b25><div class="VPDoc has-sidebar has-aside" data-v-2c336b25 data-v-53ed897c><!--[--><!--]--><div class="container" data-v-53ed897c><div class="aside" data-v-53ed897c><div class="aside-curtain" data-v-53ed897c></div><div class="aside-container" data-v-53ed897c><div class="aside-content" data-v-53ed897c><div class="VPDocAside" data-v-53ed897c data-v-3d450548><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-3d450548 data-v-70b38f01><div class="content" data-v-70b38f01><div class="outline-marker" data-v-70b38f01></div><div class="outline-title" role="heading" aria-level="2" data-v-70b38f01>目录</div><nav aria-labelledby="doc-outline-aria-label" data-v-70b38f01><span class="visually-hidden" id="doc-outline-aria-label" data-v-70b38f01> Table of Contents for current page </span><ul class="root" data-v-70b38f01 data-v-e10534d6><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-3d450548></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-53ed897c><div class="content-container" data-v-53ed897c><!--[--><!--]--><!----><main class="main" data-v-53ed897c><div style="position:relative;" class="vp-doc _categories_fragments_2023_01_06_CodeReview%E6%96%B9%E6%B3%95%E8%AE%BA%E4%B8%8E%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93" data-v-53ed897c><div><h1 id="阿里巴巴的code-review方法论与实践总结" tabindex="-1">阿里巴巴的Code Review方法论与实践总结 <a class="header-anchor" href="#阿里巴巴的code-review方法论与实践总结" aria-label="Permalink to &quot;阿里巴巴的Code Review方法论与实践总结&quot;"></a></h1><!----><p>作为卓越工程文化的一部分Code Review 其实一直在进行中,只是各团队根据自身情况张驰有度,松紧可能也不一,这里简单梳理一下 CR 的方法和团队实践。</p><h2 id="为什么要cr" tabindex="-1">为什么要CR <a class="header-anchor" href="#为什么要cr" aria-label="Permalink to &quot;为什么要CR&quot;"></a></h2><ul><li><strong>提前发现缺陷</strong> 在CodeReview阶段发现的逻辑错误、业务理解偏差、性能隐患等时有发生CR可以提前发现问题。</li><li><strong>提高代码质量</strong> 主要体现在代码健壮性、设计合理性、代码优雅性等方面持续CodeReview可以提升团队整体代码质量。</li><li><strong>统一规范和风格</strong> 集团编码规范自不必说,对于代码风格要不要统一,可能会有不同的看法,个人观点对于风格也不强求。但代码其实不是写给自己看的,是写给下一任看的,就像经常被调侃的“程序员不喜欢写注释,更不喜欢别人不写注释”,代码风格的统一更有助于代码的可读性及继任者的快速上手。</li><li><strong>防止架构腐烂</strong> 架构的维护者是谁仅靠架构师或应用Owner是远远不够的需要所有成员的努力所谓人人都是架构师。架构防腐最好前置在设计阶段但CodeReview作为对最终产出代码的检查也算是最后一道关键工序。</li><li><strong>知识分享</strong> 每一次CodeReview都是一次知识的分享磨合一定时间后团队成员间会你中有我、我中有你集百家之所长融百家之所思。同时业务逻辑都在代码中团队CodeReview也是一种新人业务细节学习的途径。</li><li><strong>团队共识</strong> 通过多次讨论与交流,逐步达成团队共识,特别是对架构理解和设计原则的认知,在共识的基础上团队也会更有凝聚力,特别是在较多新人加入时尤为重要。</li></ul><h2 id="他山之石" tabindex="-1">他山之石 <a class="header-anchor" href="#他山之石" aria-label="Permalink to &quot;他山之石&quot;"></a></h2><h3 id="某大厂a" tabindex="-1">某大厂A <a class="header-anchor" href="#某大厂a" aria-label="Permalink to &quot;某大厂A&quot;"></a></h3><p>非常重视 Code Review基本上代码需要至少有两位以上 Reviewer 审核通过后,才会让你 Check In。</p><h4 id="代码评审规则" tabindex="-1">代码评审规则 <a class="header-anchor" href="#代码评审规则" aria-label="Permalink to &quot;代码评审规则&quot;"></a></h4><ul><li>如果变更达到可以提升系统整体代码质量的程度,就可以让它们通过,即使它们可能还不完美。这是所有代码评审准则的最高原则。</li><li>世界上没有“完美”的代码,只有更好的代码。<strong>评审者不应该要求代码提交者在每个细节都写得很完美。评审者应该做好修改时间与修改重要性之间的权衡。</strong></li></ul><h4 id="代码评审原则" tabindex="-1">代码评审原则 <a class="header-anchor" href="#代码评审原则" aria-label="Permalink to &quot;代码评审原则&quot;"></a></h4><ul><li>以客观的技术因素与数据为准,而非个人偏好。</li><li>在代码样式上,遵从代码样式指南,所有代码都应与其保持一致,任何与代码样式指南不一致的观点都是个人偏好。但如果某项代码样式在指南中未提及,那就接受作者的样式。</li><li>任务涉及软件设计的问题,都应取决于基本设计原则,而不应由个人喜好来决定。当同时有多种可行方案时,如果作者能证明(以数据或公认的软件工程原理为依据)这些方案基本差不多,那就接受作者的选项;否则,应由标准的软件设计原则为准。</li><li>如果没有可用的规则,那么审核者应该让作者与当前代码库保持一致,至少不会恶化代码系统的质量。(一旦恶化代码质量,就会带来<strong>破窗效应</strong>,导致系统的代码质量逐渐下降)</li></ul><h4 id="代码审核者应该看什么" tabindex="-1">代码审核者应该看什么 <a class="header-anchor" href="#代码审核者应该看什么" aria-label="Permalink to &quot;代码审核者应该看什么&quot;"></a></h4><ul><li><strong>设计</strong>:代码是否设计良好?这种设计是否适合当前系统?</li><li><strong>功能</strong>:代码实现的行为与作者的期望是否相符?代码实现的交互界面是否对用户友好?</li><li><strong>复杂性</strong>:代码可以更简单吗?如果将来有其他开发者使用这段代码,他能很快理解吗?</li><li><strong>测试</strong>:这段代码是否有正确的、设计良好的自动化测试?</li><li><strong>命名</strong>:在为变量、类名、方法等命名时,开发者使用的名称是否清晰易懂?</li><li><strong>注释</strong>:所有的注释是否都一目了然?</li><li><strong>代码样式</strong>:所有的代码是否都遵循代码样式?</li><li><strong>文档</strong>:开发者是否同时更新了相关文档?</li></ul><h3 id="某大厂b" tabindex="-1">某大厂B <a class="header-anchor" href="#某大厂b" aria-label="Permalink to &quot;某大厂B&quot;"></a></h3><ul><li>在开发流程上专门有这个环节,排期会明确排进日程,比如 5 天开发会排 2 天来做代码审核,分为代码自审、交叉审核、集中审核。</li><li>有明确的量化指标,如 8 人时审核/每千行代码8 个以上非提示性有效问题/每千行代码。</li></ul><h3 id="某大厂c" tabindex="-1">某大厂C <a class="header-anchor" href="#某大厂c" aria-label="Permalink to &quot;某大厂C&quot;"></a></h3><ul><li>推行 Code Owner 机制,每个代码变更必须有 Code Owner 审核通过才可以提交。</li><li>所有的一线工程师,无论职级高低,最重要的工程输出原则是 “show me the code”而 Code Review 是最能够反应这个客观输出的。</li><li>尽量让每个人的 Code Review 参与状况都公开透明,每个变更发送给项目合作者,及转发到小组内成员,小组内任何人都可以去 Review 其他人的代码。</li><li>明确每个人的考评和 Code Review 表现相关,包括 Code Review 输出状况及提交代码的质量等。</li></ul><h2 id="我们怎么做cr" tabindex="-1">我们怎么做CR <a class="header-anchor" href="#我们怎么做cr" aria-label="Permalink to &quot;我们怎么做CR&quot;"></a></h2><h3 id="作为代码提交者" tabindex="-1">作为代码提交者 <a class="header-anchor" href="#作为代码提交者" aria-label="Permalink to &quot;作为代码提交者&quot;"></a></h3><ul><li><p><strong>发起时机</strong>:发起 Code Review 尽量提前,开发过程小步快跑</p><p><img src="/assets/202301062024211.XSdkEyRK.png" alt="202301062024211"></p></li><li><p><strong>代码行数</strong>:提交 Code Review 的代码行数最好在 400 行以下。根据数据分析发现,从代码行数来看,超过 400 行的 CR缺陷发现率会急剧下降从CR速度来看超过 500 行/小时后Review 质量也会大大降低,一个高质量的 CR 最好控制在一个小时以内。</p></li><li><p><strong>明确意图</strong>:编写语义明确的<strong>标题</strong>(必填)和<strong>描述</strong>(选填,可以包括背景、思路、改造点和影响面、风险等)</p></li><li><p><strong>善用工具</strong>IDEA 打开编码规约实时检测,减少代码样式、编码规约等基础性问题 (阿里编码规约插件:<a href="https://github.com/alibaba/p3c/tree/master/idea-plugin%EF%BC%89" target="_blank" rel="noreferrer">https://github.com/alibaba/p3c/tree/master/idea-plugin</a></p></li></ul><h3 id="作为代码评审者" tabindex="-1">作为代码评审者 <a class="header-anchor" href="#作为代码评审者" aria-label="Permalink to &quot;作为代码评审者&quot;"></a></h3><h4 id="评审范围" tabindex="-1">评审范围 <a class="header-anchor" href="#评审范围" aria-label="Permalink to &quot;评审范围&quot;"></a></h4><p>主要从两方面来评审:</p><ul><li>代码逻辑 <ul><li><strong>功能完整</strong>:代码实现是否满足功能需求,实现上有没有需求的理解偏差,对用户是否友好;</li><li><strong>逻辑设计</strong>:是否考虑了全局设计和兼容现有业务细节,是否考虑边界条件和并发控制;</li><li><strong>安全隐患</strong>是否存在数据安全隐患及敏感信息泄漏如越权、SQL 注入、CSRF、敏感信息未脱敏等</li><li><strong>性能隐患</strong>是否存在损害性能的隐患如死锁、死循环、FullGC、慢 SQL、缓存数据热点等</li><li><strong>测试用例</strong>:单元测试用例的验证逻辑是否有效,测试用例的代码行覆盖率和分支覆盖率;</li></ul></li><li>代码质量 <ul><li><strong>编码规范</strong>:命名、注释、领域术语、架构分层、日志打印、代码样式等是否符合规范</li><li><strong>可读性</strong>:是否逻辑清晰、易理解,避免使用奇淫巧技,避免过度拆分</li><li><strong>简洁性</strong>:是否有重复可简化的复杂逻辑,代码复杂度是否过高,符合 KISS 和 DRY 原则</li><li><strong>可维护性</strong>:在可读性和简洁性基础上,是否分层清晰、模块化合理、高内聚低耦合、遵从基本设计原则</li><li><strong>可扩展性</strong>:是否仅仅是满足一次性需求的代码,是否有必要的前瞻性扩展设计</li><li><strong>可测试性</strong>:代码是否方便写单元测试及分支覆盖,是否便于自动化测试</li></ul></li></ul><h4 id="评审注意事项" tabindex="-1">评审注意事项 <a class="header-anchor" href="#评审注意事项" aria-label="Permalink to &quot;评审注意事项&quot;"></a></h4><ul><li>尽快完成评审</li><li>避免过度追求完美</li><li>明确评论是否要解决</li><li>避免使用反问句来评价</li></ul><p>我们主要是通过交叉 CR、集中 CR 相结合的方式,由应用 Owner + SM + 架构师 + TL 完成。</p><h2 id="cr怎么避免流于形式" tabindex="-1">CR怎么避免流于形式 <a class="header-anchor" href="#cr怎么避免流于形式" aria-label="Permalink to &quot;CR怎么避免流于形式&quot;"></a></h2><p>CR 流于形式的因素很多,大概如下:</p><ul><li><p><strong>不认同 CodeReview</strong></p><ul><li>评审者的姿态?有没有带来好处?有没有从中收获?这些都会直观影响团队成员的认可度</li><li>每个 Review 建议的提出都是一次思想交流,评论要友好、中肯、具体,避免教条式及负面词汇,在遵守评审原则下,同时尊重个性展现</li><li>团队集中 CodeReview 尽量不要太正式和严肃,轻松的气氛下更有助于互相理解,来点水果,聊聊业务聊聊代码</li><li>在 Review 过程有时候会陷入谁对谁错的争论,只要是为了寻求真理辩证的去看问题,哪怕是讨论再激烈也是有收获的,注意只对事不对人。</li></ul></li><li><p><strong>CodeReview 后改动太大</strong></p><ul><li>发布前发现问题多,改动太大,影响项目计划</li><li>大项目要求编码前设计评审,小需求可以事先 Review 设计思路,避免最后的惊喜</li><li>每次 Review 的代码行数最好控制在数百行以内</li></ul></li><li><p><strong>评审者没有足够时间</strong></p><ul><li>评审者在任务安排上尽量预留好时间</li><li>尽快评审,代码在百行以内及时响应,在千行以内当日完结</li></ul></li><li><p><strong>评审者不了解业务和代码</strong></p><ul><li>代码提交人编写清晰的标题和描述</li><li>有必要的情况下评审者需要了解 PRD</li><li>评审者需要提前了解系统和代码</li></ul></li><li><p><strong>Review 建议未修改</strong></p><ul><li>这一点极为重要,需要对修改后的代码再次 Review确保理解一致以及预防带问题上线</li><li>应用可以设置 Review 建议需全部解决的卡点,同时对于非必需修改的建议可以进行打标或说明</li></ul></li></ul><h2 id="cr实践中发现的几个常见代码问题" tabindex="-1">CR实践中发现的几个常见代码问题 <a class="header-anchor" href="#cr实践中发现的几个常见代码问题" aria-label="Permalink to &quot;CR实践中发现的几个常见代码问题&quot;"></a></h2><p>笔者对个人 CR 评论问题做了个大概统计Bug 发现数占比约 4%(直接或潜在 Bug重复代码数占比约 5%,其他还有规范、安全、性能、设计等问题。在 CR 代码质量时,可以参考《重构:改善既有代码的设计》,书中所列的 22 种坏味道在 CR 中基本都会遇到。而此处我们主要聚焦以下几个常见问题:</p><h3 id="dry" tabindex="-1">DRY <a class="header-anchor" href="#dry" aria-label="Permalink to &quot;DRY&quot;"></a></h3><p>DRY 是 Don&#39;t Repeat Yourself 的缩写DRY 是 Andy Hunt 和 Dave Thomas&#39;s 在《 The Pragmatic Programmer 》一书中提出的核心原则。DRY 原则描述的重复是知识和意图的重复,包含代码重复、文档重复、数据重复、表征重复,我们这里重点讲讲<strong>代码重复</strong></p><h4 id="代码重复" tabindex="-1">代码重复 <a class="header-anchor" href="#代码重复" aria-label="Permalink to &quot;代码重复&quot;"></a></h4><blockquote><p>《重构》中对 “Duplicated Code重复代码” 的描述:</p><p>坏味道行列中首当其冲的就是 Duplicated Code。如果你在一个以上的地点看到相同的程序结构那么可以肯定设法将它们合而为一程序会变得更好。</p><p>最单纯的 Duplicated Code 就是“同一个类的两个函数含有相同的表达式”。这时候你需要做的就是采用 Extract Method (110) 提炼出重复的代码,然后让这两个地点都调用被提炼出来的那一段代码。</p><p>另一种常见情况就是“两个互为兄弟的子类内含相同表达式”。要避免这种情况,只需对两个类都使用 Extract Method (110),然后再对被提炼出来的代码使用 Pull Up Method (332),将它推入超类内。如果代码之间只是类似,并非完全相同,那么就得运用 Extract Method (110) 将相似部分和差异部分割开,构成单独一个函数。然后你可能发现可以运用 Form Template Method (345) 获得一个Template Method 设计模式。如果有些函数以不同的算法做相同的事,你可以选择其中较清晰的一个,并使用 Substitute Algorithm (139) 将其他函数的算法替换掉。</p><p>如果两个毫不相关的类出现 Duplicated Code你应该考虑对其中一个使用 Extract Class (149),将重复代码提炼到一个独立类中,然后在另一个类内使用这个新类。但是,重复代码所在的函数也可能的确只应该属于某个类,另一个类只能调用它,抑或这个函数可能属于第三个类,而另两个类应该引用这第三个类。你必须决定这个函数放在哪儿最合适,并确保它被安置后就不会再在其他任何地方出现。</p></blockquote><p>代码重复的几种场景:</p><ul><li>一个类中重复代码抽象为一个方法</li><li>两个子类间重复代码抽象到父类</li><li>两个不相关类间重复代码抽象到第三个类</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-j1KtI" id="tab-DMM-Vz0" checked="checked"><label for="tab-DMM-Vz0">反例</label><input type="radio" name="group-j1KtI" id="tab-Wzsb_r8"><label for="tab-Wzsb_r8">正例</label></div><div class="blocks"><div class="language-java vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> BillVO </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">convertBillDTO2BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(BillDTO billDTO) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (billDTO </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Money</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> cost</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCost</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (cost </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> &amp;&amp;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> cost.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setCostDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;%s %s&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, cost.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCurrency</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(), cost.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Money</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> sale</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getSale</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (sale </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> &amp;&amp;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> sale.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setSaleDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;%s %s&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, sale.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCurrency</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(), sale.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Money</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> grossProfit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getGrossProfit</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (grossProfit </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> &amp;&amp;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> grossProfit.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setGrossProfitDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;%s %s&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, grossProfit.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCurrency</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(), grossProfit.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> final</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> MONEY_DISPLAY_TEXT_PATTERN</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;"> &quot;%s %s&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> BillVO </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">convertBillDTO2BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(BillDTO billDTO) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (billDTO </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> BillVO</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setCostDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildMoneyDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCost</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setSaleDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildMoneyDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getSale</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setGrossProfitDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildMoneyDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(billDTO.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getGrossProfit</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">()));</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> billVO;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildMoneyDisplayText</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(Money money) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (money </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> money.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> StringUtils.EMPTY;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">format</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(MONEY_DISPLAY_TEXT_PATTERN, money.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getCurrency</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(), money.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getAmount</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">toPlainString</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">());</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div></div></div><h4 id="dyr实践忠告" tabindex="-1">DYR实践忠告 <a class="header-anchor" href="#dyr实践忠告" aria-label="Permalink to &quot;DYR实践忠告&quot;"></a></h4><ul><li>不要借用 DRY 之名,过度提前抽象,请遵循 <strong>Rule of three 原则</strong></li><li>不要过度追求 DRY破坏了内聚性实践中需要<strong>平衡复用与内聚</strong></li></ul><h3 id="primitive-obsession" tabindex="-1">Primitive Obsession <a class="header-anchor" href="#primitive-obsession" aria-label="Permalink to &quot;Primitive Obsession&quot;"></a></h3><blockquote><p>《重构》中对 “Primitive Obsession基本类型偏执” 的描述:</p><p>大多数编程环境都有两种数据:结构类型允许你将数据组织成有意义的形式;基本类型则是构成结构类型的积木块。结构总是会带来一定的额外开销。它们可能代表着数据库中的表,如果只为做一两件事而创建结构类型也可能显得太麻烦。</p><p>对象的一个极大的价值在于它们模糊甚至打破了横亘于基本数据和体积较大的类之间的界限。你可以轻松编写出一些与语言内置基本类型无异的小型类。例如Java 就以基本类型表示数值,而以类表示字符串和日期——这两个类型在其他许多编程环境中都以基本类型表现。</p><p>对象技术的新手通常不愿意在小任务上运用小对象——像是结合数值和币种的 money 类、由一个起始值和一个结束值组成的 range 类、电话号码或邮政编码ZIP)等的特殊字符串。你可以运用 Replace Data Valuewith Object (175) 将原本单独存在的数据值替换为对象,从而走出传统的洞窟,进入炙手可热的对象世界。如果想要替换的数据值是类型码,而它并不影响行为,则可以运用 Replace Type Code with Class (218) 将它换掉。如果你有与类型码相关的条件表达式,可运用 Replace Type Codewith Subclass (213) 或 Replace Type Code with State/Strategy (227) 加以处理。</p><p>如果你有一组应该总是被放在一起的字段,可运用 Extract Class(149)。如果你在参数列中看到基本型数据,不妨试试 IntroduceParameter Object (295)。如果你发现自己正从数组中挑选数据,可运用 Replace Array with Object (186)。</p></blockquote><p>给我们的启示主要有两点:</p><ul><li>大部分业务场景和语言环境下,结构化类型导致的开销基本可以忽略</li><li>结构化类型带来更清晰的语义和复用</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-17Pay" id="tab-RDlOgiv" checked="checked"><label for="tab-RDlOgiv">反例</label><input type="radio" name="group-17Pay" id="tab-rlUv9mN"><label for="tab-rlUv9mN">正例</label></div><div class="blocks"><div class="language-java vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">Data</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#F69D50;"> XxxConfigDTO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> implements</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> Serializable</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> final</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> serialVersionUID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> 8018480763009740953L</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 租户ID</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> tenantId;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 工商税务企业类型</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyType;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 企业名称</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyName;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 企业纳税人识别号</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyTaxNo;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 审单员工工号</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> auditEmpNo;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 审单员工姓名</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> auditEmpName;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 跟单员工工号</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> trackEmpNo;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 跟单员工姓名</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> trackEmpName;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">Data</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#F69D50;"> XxxConfigDTO2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> implements</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> Serializable</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> final</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> serialVersionUID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> 8018480763009740953L</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 租户ID</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> tenantId;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 企业信息</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Company</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> company;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 审单员工信息</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Employee</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> auditEmployee;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 跟单员工信息</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Employee</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> trackEmployee;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">Data</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#F69D50;"> Company</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 工商税务企业类型</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyType;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 企业名称</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyName;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 企业纳税人识别号</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> companyTaxNo;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">Data</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#F69D50;"> Employee</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 员工工号</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> empNo;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> /**</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> * 员工姓名</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> String</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> empName;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div></div></div><p>其实就是怎么去抽象,对于特定领域的对象可以参考 DDD 里面的 Domain PrimitiveDP</p><h3 id="分布式锁" tabindex="-1">分布式锁 <a class="header-anchor" href="#分布式锁" aria-label="Permalink to &quot;分布式锁&quot;"></a></h3><h4 id="未处理锁失败" tabindex="-1">未处理锁失败 <a class="header-anchor" href="#未处理锁失败" aria-label="Permalink to &quot;未处理锁失败&quot;"></a></h4><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> process</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String orderId) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do validate</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockSuccess</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">tryLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType.ORDER, orderId);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">lockSuccess) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // TODO 此处需要处理锁失败,重试或抛出异常</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do something</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">finally</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">unlock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType.ORDER, orderId);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><p>分布式锁的目的是为了防止并发冲突和保证数据一致性,锁失败时未处理直接返回,会带来非预期结果的影响,除非明确失败可放弃。</p><h4 id="手写解锁容易遗漏" tabindex="-1">手写解锁容易遗漏 <a class="header-anchor" href="#手写解锁容易遗漏" aria-label="Permalink to &quot;手写解锁容易遗漏&quot;"></a></h4><p>上面的加锁和解锁都是手动编写,而这两个动作一般是成对出现的,在手动编写时容易发生遗漏解锁而导致线上问题,推荐封装一个加解锁的方法来实现,会更加安全和便利。</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> procoess</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String orderId) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do validate</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> processSuccess</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">executeWithLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType.ORDER, orderId, () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">-&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> doProcess</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(orderId));</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do something</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Boolean </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">doProcess</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String orderId) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do something</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Boolean.TRUE;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;">// LockService</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> &lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> T </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">executeWithLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType bizType, String bizId, Supplier</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> supplier) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> executeWithLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(bizType, bizId, </span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">60</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">3</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, supplier);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> &lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> T </span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">execteWithLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType bizType, String bizId, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">int</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> expireSeconds, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">int</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> retryTimes, Supplier</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> supplier) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // 尝试加锁</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockTimes</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lock</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> tryLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(bizType, bizId, expireSeconds);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> while</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(lockTimes </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> retryTimes </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&amp;&amp;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">lock) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Thread.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">sleep</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">10</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (Exception </span><span style="--shiki-light:#E36209;--shiki-dark:#F69D50;">e</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do something</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lock </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> tryLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(bizType, bizId, expireSeconds);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockTimes</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // 锁失败抛异常</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">lock) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> LockException</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;try lock fail&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // 解锁</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> supplier.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">finally</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> unlock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(bizType, bizId);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><h4 id="加锁key无效" tabindex="-1">加锁KEY无效 <a class="header-anchor" href="#加锁key无效" aria-label="Permalink to &quot;加锁KEY无效&quot;"></a></h4><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> process</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(String orderId) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do validate</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // 此处加锁类型与加锁KEY不匹配</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockSuccess</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">tryLock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType.PRODUCT, orderId);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">lockSuccess) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // TODO 重试或抛出异常</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // do something</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">finally</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> lockService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">unlock</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(LockBizType.PRODUCT, orderId);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><p>注意加锁类型与加锁 KEY 在同一个维度,否则加锁会失效。</p><h3 id="分页查询" tabindex="-1">分页查询 <a class="header-anchor" href="#分页查询" aria-label="Permalink to &quot;分页查询&quot;"></a></h3><h4 id="完全没有分页" tabindex="-1">完全没有分页 <a class="header-anchor" href="#完全没有分页" aria-label="Permalink to &quot;完全没有分页&quot;"></a></h4><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-lr3ch" id="tab-iCxbeED" checked="checked"><label for="tab-iCxbeED">反例</label><input type="radio" name="group-lr3ch" id="tab-t8jm6fu"><label for="tab-t8jm6fu">正例</label></div><div class="blocks"><div class="language-java vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">OrderDTO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> queryOrderList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(Long customerId) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (customerId </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Lists.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">newArrayList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">OrderDO</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&gt; </span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">orderDOList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderMapper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">list</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(customerId);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderConverter.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">doList2dtoList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(orderDOList);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Page</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">OrderDTO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> queryOrderList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(OrderPageQuery query) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Preconditions.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">checkNotNull</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, </span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;查询条件不能为空&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Preconditions.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">checkArgument</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">getPageSize</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;=</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> MAX_PAGE_SIZE, </span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;分页size不能大于&quot;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> MAX_PAGE_SIZE);</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // 分页size一般由前端传入</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;"> // query.setPageSize(20);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> cnt</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderMapper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">count</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (cnt </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> PageQueryUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildPageData</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, </span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, cnt);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">OrderDO</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&gt; </span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">orderDOList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderMapper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">list</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">OrderDTO</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&gt; </span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">orderDTOList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderConverter.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">doList2dtoList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(orderDOList);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> PageQueryUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildPageData</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, orderDTOList, cnt);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div></div></div><p>没有分页的列表查询对DB性能影响非常大特别是在项目初期因为数据量非常小问题不明显而导致没有及时发现会给未来留坑。</p><h4 id="分页size太大" tabindex="-1">分页size太大 <a class="header-anchor" href="#分页size太大" aria-label="Permalink to &quot;分页size太大&quot;"></a></h4><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-i5Pcm" id="tab-MNo9J8V" checked="checked"><label for="tab-MNo9J8V">反例</label></div><div class="blocks"><div class="language-java vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">private</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Page</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">OrderDTO</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;"> queryOrderList2</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(OrderPageQuery query) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> Preconditions.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">checkNotNull</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, </span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;查询条件不能为空&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> query.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">setPageSize</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">10000</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> long</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> cnt</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderMapper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">count</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> (cnt </span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> PageQueryUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildPageData</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, </span><span style="--shiki-light:#005CC5;--shiki-dark:#6CB6FF;">null</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">, cnt);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">OrderDO</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&gt; </span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">orderDOList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderMapper.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">list</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> List</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&lt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;">OrderDTO</span><span style="--shiki-light:#24292E;--shiki-dark:#F69D50;">&gt; </span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">orderDTOList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> orderConverter.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">doList2dtoList</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(orderDOList);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F47067;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> PageQueryUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#DCBDFB;">buildPageData</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">(query, orderDTOList, cnt);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">}</span></span></code></pre></div></div></div><p>分页 size 的大小并没有一个固定的标准,取决于业务需求、数据量及数据库等,但动辄几千上万的分页 size会带来性能瓶颈而大量的慢 SQL 不但影响客户体验,对系统稳定性也是极大的隐患。</p><h4 id="超多分页慢sql" tabindex="-1">超多分页慢SQL <a class="header-anchor" href="#超多分页慢sql" aria-label="Permalink to &quot;超多分页慢SQL&quot;"></a></h4><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-7RKcA" id="tab-_gfP3Eo" checked="checked"><label for="tab-_gfP3Eo">反例</label><input type="radio" name="group-7RKcA" id="tab-LT6mXLb"><label for="tab-LT6mXLb">正例</label></div><div class="blocks"><div class="language-xml vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;">&lt;!-- 分页查询订单列表 --&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">select</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> id</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;list&quot;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> parameterType</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;com.xxx.OrderPageQuery&quot;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> resultType</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;com.xxx.OrderDO&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> SELECT</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">include</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> refid</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;all_columns&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">/&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> FROM t_order</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">include</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> refid</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;listConditions&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">/&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> ORDER BY id DESC</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> LIMIT #{offset},#{pageSize}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">select</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&gt;</span></span></code></pre></div><div class="language-xml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">xml</span><pre class="shiki shiki-themes github-light github-dark-dimmed vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#768390;">&lt;!-- 分页查询订单列表 --&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">select</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> id</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;list&quot;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> parameterType</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;com.xxx.OrderPageQuery&quot;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> resultType</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;com.xxx.OrderDO&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> SELECT</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">include</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> refid</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;all_columns&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">/&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> FROM t_order a</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> INNER JOIN (</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> SELECT id AS bid</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> FROM t_order</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">include</span><span style="--shiki-light:#6F42C1;--shiki-dark:#6CB6FF;"> refid</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#96D0FF;">&quot;listConditions&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">/&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> ORDER BY id DESC</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> LIMIT #{offset},#{pageSize}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;"> ) b ON a.id = b.bid</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#8DDB8C;">select</span><span style="--shiki-light:#24292E;--shiki-dark:#ADBAC7;">&gt;</span></span></code></pre></div></div></div><p>以上 bad case 的 SQL 在超多页分页查询时性能极其低下,存在多次回表甚至 Using Filesort 的问题,在阿里巴巴编码规范中也有明确的规避方案,此处不展开。</p><p><img src="/assets/202301062027985.qIIuam8H.png" alt="202301062027985"></p><p>最后,我们工程师的智慧结晶都尽在代码之中,而 Code Review 可以促进结晶更加清莹通透、纯洁无瑕、精致完美,值得大家一起持续精进!</p></div></div></main><footer class="VPDocFooter" data-v-53ed897c data-v-f3af8004><!--[--><!--[--><!--[--><!--[--><!----><!--]--><!--]--><!--]--><!--]--><div class="edit-info" data-v-f3af8004><div class="edit-link" data-v-f3af8004><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/Charles7c/charles7c.github.io/edit/main/docs/categories/fragments/2023/01/06/CodeReview方法论与实践总结.md" target="_blank" rel="noreferrer" data-v-f3af8004><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" aria-label="edit icon" data-v-f3af8004><path d="M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"></path><path d="M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"></path></svg> 不妥之处,敬请雅正<!--]--></a></div><div class="last-updated" data-v-f3af8004><p class="VPLastUpdated" data-v-f3af8004 data-v-a25eb6f3>最后更新: <time datetime="2023-01-06T13:01:12.000Z" data-v-a25eb6f3></time></p></div></div><nav class="prev-next" data-v-f3af8004><div class="pager" data-v-f3af8004><a class="VPLink link pager-link prev" href="/categories/fragments/2023/12/21/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3%E9%99%90%E6%B5%81%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0" data-v-f3af8004><!--[--><span class="desc" data-v-f3af8004>上一篇</span><span class="title" data-v-f3af8004><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>一文详解限流接口实现</span><!--]--></a></div><div class="pager" data-v-f3af8004><a class="VPLink link pager-link next" href="/categories/fragments/2022/12/07/%E7%BD%91%E7%AB%99%E5%BC%80%E5%90%AF%E7%81%B0%E8%89%B2%E6%98%BE%E7%A4%BA" data-v-f3af8004><!--[--><span class="desc" data-v-f3af8004>下一篇</span><span class="title" data-v-f3af8004><div class="text-color-red mr-[6px]" style="font-weight: 550; display: inline-block;">1</div>简单聊聊如何让网站开启灰色显示</span><!--]--></a></div></nav></footer><!--[--><!--[--><!--[--><div id="comment-container"></div><!--]--><!--]--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"categories_fragments_2019_12_31_个人常用linux命令.md\":\"lx3qwmph\",\"categories_fragments_2021_03_12_精密计算工具类-bigdecimal.md\":\"zBMJQ_Bo\",\"categories_fragments_2019_12_30_个人常用hutool工具类.md\":\"8YjnAagp\",\"categories_fragments_2022_03_27_修改git所有提交记录中的作者和邮箱.md\":\"OvDDBZd4\",\"categories_fragments_2022_10_06_个人常用快捷键.md\":\"7DmE2Sdn\",\"categories_fragments_2022_10_27_docker安装consul.md\":\"LIu1Q7_o\",\"categories_fragments_2022_11_01_使用idea进行远程程序调试.md\":\"0r_fvBId\",\"categories_fragments_2022_10_28_docker安装minio.md\":\"pOrH5sCo\",\"categories_fragments_2019_12_28_个人sql优化技巧.md\":\"fmoswBLx\",\"categories_fragments_2022_03_28_为指定git仓库单独配置用户名和邮箱.md\":\"qMYHQNJe\",\"categories_fragments_2022_03_26_修改git最后一次提交记录的作者和邮箱.md\":\"hSvi24NU\",\"categories_fragments_2022_10_26_docker安装openldap.md\":\"mcPLxA8n\",\"categories_fragments_2021_05_29_设计模式之单例模式.md\":\"Q_Kk2HQh\",\"categories_fragments_2022_03_25_合并两个git仓库的历史提交记录.md\":\"e24riSJ9\",\"courses_java_01-java语法入门_02-第一个java程序.md\":\"b9EylDVG\",\"archives.md\":\"hEvO1jAg\",\"categories_fragments_2022_10_05_个人常用git命令.md\":\"H2ehuVi6\",\"courses_java_01-java语法入门_12-程序调试入门.md\":\"1LT3Uu5K\",\"categories_issues_2022_10_25_解决centos8执行yum安装报错.md\":\"vWOngd9g\",\"courses_mybatis_01-mybatis基础_03-核心配置文件.md\":\"pjBK9LfV\",\"categories_solutions_2021_11_18_用java8获取近n天日期.md\":\"r9mp3BOr\",\"categories_issues_2021_12_01_f盘上的回收站已损坏。是否清空该驱动器上的回收站.md\":\"dANDLbnx\",\"categories_fragments_2022_08_29_内网centos服务器设置网络代理.md\":\"Wz9Gyo3N\",\"categories_issues_2022_11_04_解决docker安装prometheus启动报错的问题.md\":\"wlwkdFKi\",\"courses_java_01-java语法入门_13-一维数组.md\":\"tyF-2IM9\",\"categories_issues_2021_12_08_for循环中删除集合元素隐藏的陷阱.md\":\"HaXmdlA5\",\"categories_issues_2021_12_10_command line is too long. shorten command line for xxx or also for spring boot default configuration.md\":\"PXnmw2TY\",\"categories_issues_2021_12_11_sql 注入攻击风险.md\":\"rljfD_Fi\",\"categories_issues_2022_11_23_解决maven传递依赖污染的问题.md\":\"GY3psqIs\",\"categories_issues_2021_12_13_无法访问f盘。文件或目录损坏且无法读取.md\":\"ly-jJhLg\",\"categories_issues_2022_01_26_javascript 无法存储 java long 类型数据问题.md\":\"IO54X60W\",\"categories_issues_2022_08_11_执行shell脚本报java command not found.md\":\"M4ZLKe1m\",\"categories_issues_2022_08_31_springboot项目引入openfeign后无法启动.md\":\"ChRCkQV5\",\"categories_issues_2022_09_05_nginx转发请求报13permission denied错误.md\":\"PClZAC2K\",\"categories_solutions_2021_11_22_一条sql查询今年每月统计信息.md\":\"2pLzv9Tp\",\"categories_fragments_2022_02_16_个人常用sql函数.md\":\"3XF3Onqb\",\"categories_fragments_2022_10_31_centos安装docker.md\":\"aS1qV9Oq\",\"categories_issues_2022_10_29_docker设置网络代理.md\":\"5gbvC2uf\",\"categories_tools_2021_02_22_rdm快速入门.md\":\"-N1bZYLN\",\"about_me.md\":\"yl4MsNR1\",\"categories_issues_index.md\":\"Yzlc8cBS\",\"categories_issues_2022_10_15_解决windows桌面部分快捷方式图标变为空白的问题.md\":\"Zuxd2KdY\",\"categories_fragments_2023_12_21_一文详解限流接口实现.md\":\"HHXYHaRJ\",\"categories_issues_2022_11_06_解决dotnet安装后报错的问题.md\":\"skCbcShV\",\"categories_issues_2022_03_24_创建一个自身类的静态对象变量究竟会如何执行.md\":\"_sjVm5kR\",\"categories_fragments_index.md\":\"lRTNURvo\",\"categories_fragments_2022_12_07_网站开启灰色显示.md\":\"ALiJge8d\",\"categories_fragments_2019_12_29_个人常用stream使用技巧.md\":\"CuDwLpDP\",\"about_index.md\":\"aZfz3sjq\",\"courses_java_01-java语法入门_01-开发环境搭建.md\":\"JchJHevH\",\"courses_mybatis_01-mybatis基础_04-sql映射文件之查询元素.md\":\"UYQRCMvg\",\"courses_mybatis_index.md\":\"7LMzFTpl\",\"categories_solutions_index.md\":\"JPFJaff4\",\"categories_tools_2021_01_14_初识lombok.md\":\"DDRTdFdf\",\"courses_mybatis_02-mybatis-plus基础_01-快速入门.md\":\"2M92eqRH\",\"courses_mybatis_01-mybatis基础_07-sql映射文件之缓存元素.md\":\"9orUXUze\",\"categories_fragments_2023_01_06_codereview方法论与实践总结.md\":\"viSW2KC_\",\"courses_mybatis_01-mybatis基础_05-sql映射文件之增删改元素.md\":\"Q1bwfP8k\",\"courses_mybatis_02-mybatis-plus基础_05-代码生成器.md\":\"hjpH5d8x\",\"courses_mybatis_02-mybatis-plus基础_03-简单查询操作.md\":\"OO_paHtp\",\"courses_mysql_index.md\":\"6rziEA5O\",\"categories_solutions_2022_09_07_递归查询树型结构数据的性能优化方案.md\":\"zWro2Zfo\",\"categories_tools_2021_03_06_postman快速入门.md\":\"7P3rh4Zw\",\"courses_mysql_03-附录_02-docker安装mysql.md\":\"Qay1Rxzf\",\"courses_java_01-java语法入门_04-程序和计算机的那点事儿.md\":\"i4Xi0Jl0\",\"courses_java_index.md\":\"Vd-Tt2Gz\",\"courses_java_01-java语法入门_14-多维数组.md\":\"C3Jtu4yX\",\"courses_java_01-java语法入门_09-switch选择结构.md\":\"p1ZypRLa\",\"courses_mybatis_01-mybatis基础_02-核心对象.md\":\"J2u3OyyP\",\"courses_java_04-附录_01-centos安装jdk.md\":\"mrm2xLeJ\",\"categories_tools_2021_03_04_ardm快速入门.md\":\"zbxPd0TS\",\"courses_java_03-java高级特性_01-集合与泛型-1.md\":\"3f19_0FV\",\"courses_mybatis_01-mybatis基础_08-动态sql.md\":\"EiHlJ807\",\"courses_mybatis_01-mybatis基础_01-快速入门.md\":\"KXcjGx0w\",\"categories_tools_2021_03_10_quartz快速入门.md\":\"yXxsG68Z\",\"categories_tools_index.md\":\"qDqYFV-P\",\"courses_java_01-java语法入门_07-控制语句和流程图.md\":\"t61wREmj\",\"courses_java_01-java语法入门_11-多重循环.md\":\"79go9ddo\",\"courses_java_01-java语法入门_03-初识eclipse.md\":\"VIICcUYm\",\"courses_mysql_01-mysql基础_01-mysql安装与配置.md\":\"bXq0pYDh\",\"index.md\":\"rpby8rrg\",\"courses_mybatis_02-mybatis-plus基础_02-增删改操作.md\":\"0wJpZsHd\",\"courses_java_02-java面向对象_01-类和对象.md\":\"A4c0BkF0\",\"courses_mysql_03-附录_01-centos安装mysql.md\":\"ZEGR5OmN\",\"courses_java_01-java语法入门_06-常用的运算符.md\":\"ERU0p3Fx\",\"courses_mybatis_02-mybatis-plus基础_04-条件构造器.md\":\"v-MWEs-l\",\"categories_issues_2022_09_23_解决无法重复读取请求体和响应体的问题.md\":\"QBFvmfGv\",\"categories_fragments_2022_10_01_个人常用docker命令.md\":\"tQHhdswU\",\"courses_java_01-java语法入门_10-循环结构.md\":\"z73Bcwe8\",\"courses_mybatis_01-mybatis基础_06-sql映射文件之自定义映射元素.md\":\"yafOyEf1\",\"courses_java_01-java语法入门_05-变量和常量.md\":\"wVbb047E\",\"courses_java_01-java语法入门_08-if选择结构.md\":\"GylQ89V9\",\"tags.md\":\"TML_Ecph\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"查尔斯的知识库\",\"description\":\"个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"我的分类\",\"items\":[{\"text\":\"Bug万象集\",\"link\":\"/categories/issues/index\",\"activeMatch\":\"/categories/issues/\"},{\"text\":\"\\\"杂碎\\\"逆袭史\",\"link\":\"/categories/fragments/index\",\"activeMatch\":\"/categories/fragments/\"},{\"text\":\"工具四海谈\",\"link\":\"/categories/tools/index\",\"activeMatch\":\"/categories/tools/\"},{\"text\":\"方案春秋志\",\"link\":\"/categories/solutions/index\",\"activeMatch\":\"/categories/solutions/\"}],\"activeMatch\":\"/categories/\"},{\"text\":\"我的小册\",\"items\":[{\"text\":\"Java基础快速入门\",\"link\":\"/courses/java/index\",\"activeMatch\":\"/courses/java/\"},{\"text\":\"MySQL快速入门\",\"link\":\"/courses/mysql/index\",\"activeMatch\":\"/courses/mysql/\"},{\"text\":\"MyBatis快速入门\",\"link\":\"/courses/mybatis/index\",\"activeMatch\":\"/courses/mybatis/\"}],\"activeMatch\":\"/courses/\"},{\"text\":\"我的标签\",\"link\":\"/tags\",\"activeMatch\":\"/tags\"},{\"text\":\"我的归档\",\"link\":\"/archives\",\"activeMatch\":\"/archives\"},{\"text\":\"关于\",\"items\":[{\"text\":\"关于知识库\",\"link\":\"/about/index\",\"activeMatch\":\"/about/index\"},{\"text\":\"关于我\",\"link\":\"/about/me\",\"activeMatch\":\"/about/me\"}],\"activeMatch\":\"/about/\"}],\"sidebar\":{\"/categories/issues/\":[{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/tiger.svg\\\" title=\\\"虎年\\\" alt=\\\"生肖\\\">\\n 2022年 (12篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>解决 Maven 传递依赖污染的问题\",\"link\":\"/categories/issues/2022/11/23/解决Maven传递依赖污染的问题\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>解决 DotNet 安装完报错Couldn't find a valid ICU package installed on the system. Please install libicu using your package manager and try again\",\"link\":\"/categories/issues/2022/11/06/解决DotNET安装后报错的问题\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>解决 Docker 安装 Prometheus 启动报 permission denied 的问题\",\"link\":\"/categories/issues/2022/11/04/解决Docker安装Prometheus启动报错的问题\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>Docker 设置网络代理\",\"link\":\"/categories/issues/2022/10/29/Docker设置网络代理\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>解决 CentOS 8 执行 yum install 报 Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist 的问题\",\"link\":\"/categories/issues/2022/10/25/解决CentOS8执行yum安装报错\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">6</div>解决 Windows 桌面部分快捷方式图标变为空白的问题\",\"link\":\"/categories/issues/2022/10/15/解决Windows桌面部分快捷方式图标变为空白的问题\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">7</div>解决无法重复读取请求体和响应体的问题\",\"link\":\"/categories/issues/2022/09/23/解决无法重复读取请求体和响应体的问题\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">8</div>Nginx转发请求报13Permission denied错误\",\"link\":\"/categories/issues/2022/09/05/Nginx转发请求报13Permission denied错误\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">9</div>SpringBoot项目引入OpenFeign后无法启动\",\"link\":\"/categories/issues/2022/08/31/SpringBoot项目引入OpenFeign后无法启动\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">10</div>执行Shell脚本报java: command not found\",\"link\":\"/categories/issues/2022/08/11/执行Shell脚本报java command not found\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">11</div>创建一个自身类的静态对象变量,究竟会如何执行?\",\"link\":\"/categories/issues/2022/03/24/创建一个自身类的静态对象变量,究竟会如何执行?\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">12</div>JavaScript 无法存储 Java Long 类型数据问题\",\"link\":\"/categories/issues/2022/01/26/JavaScript 无法存储 Java Long 类型数据问题\"}],\"collapsed\":false},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/ox.svg\\\" title=\\\"牛年\\\" alt=\\\"生肖\\\">\\n 2021年 (5篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>无法访问 F:\\\\。文件或目录损坏且无法读取。\",\"link\":\"/categories/issues/2021/12/13/无法访问F盘。文件或目录损坏且无法读取\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>SQL 注入攻击风险\",\"link\":\"/categories/issues/2021/12/11/SQL 注入攻击风险\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>Command line is too long. Shorten command line for XXX or also for Spring Boot default configuration\",\"link\":\"/categories/issues/2021/12/10/Command line is too long. Shorten command line for XXX or also for Spring Boot default configuration\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>for循环中删除集合元素隐藏的陷阱\",\"link\":\"/categories/issues/2021/12/08/for循环中删除集合元素隐藏的陷阱\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>F:\\\\ 上的回收站已损坏。是否清空该驱动器上的\\\"回收站\\\"?\",\"link\":\"/categories/issues/2021/12/01/F盘上的回收站已损坏。是否清空该驱动器上的回收站\"}],\"collapsed\":true}],\"/categories/fragments/\":[{\"text\":\"<svg style=\\\"display: inline-block; vertical-align: middle; padding-bottom: 3px;\\\" viewBox=\\\"0 0 1920 1024\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"30\\\" height=\\\"30\\\"><path d=\\\"M367.488 667.904h423.744v47.232H367.488v-47.232zM320.256 204.352h137.28v68.992h-137.28v-68.992zM367.488 754.112h423.744v48H367.488v-48zM693.76 204.352h137.984v68.992H693.76v-68.992zM507.008 204.352h137.28v68.992h-137.28v-68.992z\\\" p-id=\\\"10749\\\" fill=\\\"#d81e06\\\"></path><path d=\\\"M1792.512 0H127.488C57.472 0 0 57.152 0 127.616v768.768C0 966.72 57.088 1024 127.488 1024h1665.088c69.952 0 127.424-57.152 127.424-127.616V127.616C1920 57.216 1862.912 0 1792.512 0z m-528 175.104h446.976v54.016H1494.72l-24 101.248h206.976V689.6h-57.728V384.32h-289.472v308.224h-57.728v-362.24h140.224l20.992-101.248h-169.472v-53.952z m-996.032-11.2h614.272v167.232h-51.008v-17.28H320.256v17.28H268.48V163.904z m678.784 681.728h-744v-43.52h111.744V454.848h229.504v-48.704H221.248v-42.048h323.264v-39.744h54.016v39.744h331.52v41.984h-331.52v48.768h245.248v347.264h103.488v43.52z m203.264-94.528c0 59.52-30.72 89.28-92.224 89.28-25.472 0-46.016-0.512-61.504-1.472-2.496-22.976-6.528-45.248-12.032-66.752 22.976 5.504 46.72 8.256 71.232 8.256 24 0 35.968-11.52 35.968-34.496V247.872H971.2v-54.72h278.976v54.72H1150.4v503.232z m521.216 121.536c-67.008-55.488-137.28-108.032-210.752-157.504-4.992 9.984-10.496 19.008-16.512 27.008-41.472 57.024-113.28 101.504-215.232 133.504-9.472-16.512-21.504-34.496-35.968-54.016 94.528-27.008 161.28-64.512 200.256-112.512 34.496-44.992 51.776-113.024 51.776-204.032V421.12h57.728v82.496c0 62.528-6.72 115.776-20.224 159.744 84.48 54.016 161.472 107.008 230.976 158.976l-42.048 50.304z\\\" p-id=\\\"10750\\\" fill=\\\"#d81e06\\\"></path><path d=\\\"M367.488 495.36h423.744v47.232H367.488V495.36zM367.488 581.632h423.744v47.232H367.488v-47.232z\\\" p-id=\\\"10751\\\" fill=\\\"#d81e06\\\"></path></svg>\\n 我的置顶 (8篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>个人常用快捷键\",\"link\":\"/categories/fragments/2022/10/06/个人常用快捷键\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>个人常用 Git 命令\",\"link\":\"/categories/fragments/2022/10/05/个人常用Git命令\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>个人常用 Docker 命令\",\"link\":\"/categories/fragments/2022/10/01/个人常用Docker命令\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>个人常用 SQL 函数\",\"link\":\"/categories/fragments/2022/02/16/个人常用SQL函数\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>个人常用 Linux 命令\",\"link\":\"/categories/fragments/2019/12/31/个人常用Linux命令\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">6</div>个人常用 Hutool 工具类\",\"link\":\"/categories/fragments/2019/12/30/个人常用Hutool工具类\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">7</div>个人常用 Stream 使用技巧\",\"link\":\"/categories/fragments/2019/12/29/个人常用Stream使用技巧\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">8</div>个人 SQL 优化技巧\",\"link\":\"/categories/fragments/2019/12/28/个人SQL优化技巧\"}],\"collapsed\":false},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/rabbit.svg\\\" title=\\\"兔年\\\" alt=\\\"生肖\\\">\\n 2023年 (2篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>一文详解限流接口实现\",\"link\":\"/categories/fragments/2023/12/21/一文详解限流接口实现\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>阿里巴巴的Code Review方法论与实践总结\",\"link\":\"/categories/fragments/2023/01/06/CodeReview方法论与实践总结\"}],\"collapsed\":false},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/tiger.svg\\\" title=\\\"虎年\\\" alt=\\\"生肖\\\">\\n 2022年 (15篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>简单聊聊如何让网站开启灰色显示\",\"link\":\"/categories/fragments/2022/12/07/网站开启灰色显示\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>使用 IntelliJ IDEA 进行远程程序调试\",\"link\":\"/categories/fragments/2022/11/01/使用IDEA进行远程程序调试\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>CentOS 安装 Docker、Docker Compose\",\"link\":\"/categories/fragments/2022/10/31/CentOS安装Docker\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>Docker 安装 MinIO 详细步骤\",\"link\":\"/categories/fragments/2022/10/28/Docker安装MinIO\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>Docker 安装 Consul 详细步骤\",\"link\":\"/categories/fragments/2022/10/27/Docker安装Consul\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">6</div>Docker 安装 OpenLDAP 详细步骤\",\"link\":\"/categories/fragments/2022/10/26/Docker安装OpenLDAP\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">7</div>个人常用快捷键\",\"link\":\"/categories/fragments/2022/10/06/个人常用快捷键\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">8</div>个人常用 Git 命令\",\"link\":\"/categories/fragments/2022/10/05/个人常用Git命令\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">9</div>个人常用 Docker 命令\",\"link\":\"/categories/fragments/2022/10/01/个人常用Docker命令\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">10</div>内网CentOS服务器设置网络代理\",\"link\":\"/categories/fragments/2022/08/29/内网CentOS服务器设置网络代理\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">11</div>为指定Git仓库单独配置用户名和邮箱\",\"link\":\"/categories/fragments/2022/03/28/为指定Git仓库单独配置用户名和邮箱\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">12</div>修改Git所有提交记录中的作者和邮箱\",\"link\":\"/categories/fragments/2022/03/27/修改Git所有提交记录中的作者和邮箱\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">13</div>修改Git最后一次提交记录的作者和邮箱\",\"link\":\"/categories/fragments/2022/03/26/修改Git最后一次提交记录的作者和邮箱\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">14</div>合并两个Git仓库的历史提交记录\",\"link\":\"/categories/fragments/2022/03/25/合并两个Git仓库的历史提交记录\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">15</div>个人常用 SQL 函数\",\"link\":\"/categories/fragments/2022/02/16/个人常用SQL函数\"}],\"collapsed\":true},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/ox.svg\\\" title=\\\"牛年\\\" alt=\\\"生肖\\\">\\n 2021年 (2篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>设计模式之单例模式\",\"link\":\"/categories/fragments/2021/05/29/设计模式之单例模式\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>精密计算工具类-BigDecimal\",\"link\":\"/categories/fragments/2021/03/12/精密计算工具类-BigDecimal\"}],\"collapsed\":true},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/pig.svg\\\" title=\\\"猪年\\\" alt=\\\"生肖\\\">\\n 2019年 (4篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>个人常用 Linux 命令\",\"link\":\"/categories/fragments/2019/12/31/个人常用Linux命令\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>个人常用 Hutool 工具类\",\"link\":\"/categories/fragments/2019/12/30/个人常用Hutool工具类\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>个人常用 Stream 使用技巧\",\"link\":\"/categories/fragments/2019/12/29/个人常用Stream使用技巧\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>个人 SQL 优化技巧\",\"link\":\"/categories/fragments/2019/12/28/个人SQL优化技巧\"}],\"collapsed\":true}],\"/categories/solutions/\":[{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/tiger.svg\\\" title=\\\"虎年\\\" alt=\\\"生肖\\\">\\n 2022年 (1篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>递归查询树型结构数据的性能优化方案\",\"link\":\"/categories/solutions/2022/09/07/递归查询树型结构数据的性能优化方案\"}],\"collapsed\":false},{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/ox.svg\\\" title=\\\"牛年\\\" alt=\\\"生肖\\\">\\n 2021年 (2篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>一条SQL查询今年每月统计信息\",\"link\":\"/categories/solutions/2021/11/22/一条SQL查询今年每月统计信息\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>用Java8获取近N天日期\",\"link\":\"/categories/solutions/2021/11/18/用Java8获取近N天日期\"}],\"collapsed\":true}],\"/categories/tools/\":[{\"text\":\"<img class=\\\"chinese-zodiac\\\" style=\\\"position: static; vertical-align: middle; padding-bottom: 3px;\\\" src=\\\"/img/svg/chinese-zodiac/ox.svg\\\" title=\\\"牛年\\\" alt=\\\"生肖\\\">\\n 2021年 (5篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>Quartz 快速入门\",\"link\":\"/categories/tools/2021/03/10/Quartz快速入门\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>Postman 快速入门\",\"link\":\"/categories/tools/2021/03/06/Postman快速入门\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>Another Redis Desktop Manager 快速入门\",\"link\":\"/categories/tools/2021/03/04/ARDM快速入门\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>Redis Desktop Manager 快速入门\",\"link\":\"/categories/tools/2021/02/22/RDM快速入门\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>初识 Lombok\",\"link\":\"/categories/tools/2021/01/14/初识Lombok\"}],\"collapsed\":false}],\"/courses/java/\":[{\"text\":\"Java语法入门 (14篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>开发环境搭建\",\"link\":\"/courses/java/01-Java语法入门/01-开发环境搭建\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>第一个Java程序\",\"link\":\"/courses/java/01-Java语法入门/02-第一个Java程序\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>初识Eclipse\",\"link\":\"/courses/java/01-Java语法入门/03-初识Eclipse\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>程序和计算机的那点事儿\",\"link\":\"/courses/java/01-Java语法入门/04-程序和计算机的那点事儿\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>变量和常量\",\"link\":\"/courses/java/01-Java语法入门/05-变量和常量\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">6</div>常用的运算符\",\"link\":\"/courses/java/01-Java语法入门/06-常用的运算符\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">7</div>控制语句和流程图\",\"link\":\"/courses/java/01-Java语法入门/07-控制语句和流程图\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">8</div>if选择结构\",\"link\":\"/courses/java/01-Java语法入门/08-if选择结构\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">9</div>switch选择结构\",\"link\":\"/courses/java/01-Java语法入门/09-switch选择结构\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">10</div>循环结构\",\"link\":\"/courses/java/01-Java语法入门/10-循环结构\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">11</div>多重循环\",\"link\":\"/courses/java/01-Java语法入门/11-多重循环\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">12</div>程序调试入门\",\"link\":\"/courses/java/01-Java语法入门/12-程序调试入门\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">13</div>一维数组\",\"link\":\"/courses/java/01-Java语法入门/13-一维数组\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">14</div>多维数组\",\"link\":\"/courses/java/01-Java语法入门/14-多维数组\"}],\"collapsed\":false},{\"text\":\"Java面向对象 (1篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>类和对象\",\"link\":\"/courses/java/02-Java面向对象/01-类和对象\"}],\"collapsed\":true},{\"text\":\"Java高级特性 (1篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>集合与泛型-1\",\"link\":\"/courses/java/03-Java高级特性/01-集合与泛型-1\"}],\"collapsed\":true},{\"text\":\"附录 (1篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>CentOS 8.2 安装 JDK 1.8.0_202\",\"link\":\"/courses/java/04-附录/01-CentOS安装JDK\"}],\"collapsed\":true}],\"/courses/mysql/\":[{\"text\":\"MySQL基础 (1篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>MySQL安装与配置\",\"link\":\"/courses/mysql/01-MySQL基础/01-MySQL安装与配置\"}],\"collapsed\":true},{\"text\":\"附录 (2篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>CentOS 8.2 安装 MySQL 5.7.39\",\"link\":\"/courses/mysql/03-附录/01-CentOS安装MySQL\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>Docker 安装 MySQL 详细步骤\",\"link\":\"/courses/mysql/03-附录/02-Docker安装MySQL\"}],\"collapsed\":false}],\"/courses/mybatis/\":[{\"text\":\"MyBatis基础 (8篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>快速入门\",\"link\":\"/courses/mybatis/01-MyBatis基础/01-快速入门\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>核心对象\",\"link\":\"/courses/mybatis/01-MyBatis基础/02-核心对象\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>核心配置文件\",\"link\":\"/courses/mybatis/01-MyBatis基础/03-核心配置文件\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>SQL映射文件之查询元素\",\"link\":\"/courses/mybatis/01-MyBatis基础/04-SQL映射文件之查询元素\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>SQL映射文件之增删改元素\",\"link\":\"/courses/mybatis/01-MyBatis基础/05-SQL映射文件之增删改元素\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">6</div>SQL映射文件之自定义映射元素\",\"link\":\"/courses/mybatis/01-MyBatis基础/06-SQL映射文件之自定义映射元素\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">7</div>SQL映射文件之缓存元素\",\"link\":\"/courses/mybatis/01-MyBatis基础/07-SQL映射文件之缓存元素\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">8</div>动态SQL\",\"link\":\"/courses/mybatis/01-MyBatis基础/08-动态SQL\"}],\"collapsed\":false},{\"text\":\"MyBatis-Plus基础 (5篇)\",\"items\":[{\"text\":\"<div class=\\\"text-color-red mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">1</div>快速入门\",\"link\":\"/courses/mybatis/02-MyBatis-Plus基础/01-快速入门\"},{\"text\":\"<div class=\\\"text-color-orange mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">2</div>增删改操作\",\"link\":\"/courses/mybatis/02-MyBatis-Plus基础/02-增删改操作\"},{\"text\":\"<div class=\\\"text-color-yellow mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">3</div>简单查询操作\",\"link\":\"/courses/mybatis/02-MyBatis-Plus基础/03-简单查询操作\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">4</div>条件构造器\",\"link\":\"/courses/mybatis/02-MyBatis-Plus基础/04-条件构造器\"},{\"text\":\"<div class=\\\"text-color-gray mr-[6px]\\\" style=\\\"font-weight: 550; display: inline-block;\\\">5</div>代码生成器\",\"link\":\"/courses/mybatis/02-MyBatis-Plus基础/05-代码生成器\"}],\"collapsed\":false}]},\"logo\":\"/logo.png\",\"outline\":{\"level\":\"deep\",\"label\":\"目录\"},\"darkModeSwitchLabel\":\"切换日光/暗黑模式\",\"sidebarMenuLabel\":\"文章\",\"returnToTopLabel\":\"返回顶部\",\"lastUpdatedText\":\"最后更新\",\"docFooter\":{\"prev\":\"上一篇\",\"next\":\"下一篇\"},\"editLink\":{\"pattern\":\"https://github.com/Charles7c/charles7c.github.io/edit/main/docs/:path\",\"text\":\"不妥之处,敬请雅正\"},\"search\":{\"provider\":\"algolia\",\"options\":{\"appId\":\"DBZ0G9HBUY\",\"apiKey\":\"00cef480a543003d05d9808110ea5f65\",\"indexName\":\"charles7c\",\"locales\":{\"root\":{\"placeholder\":\"搜索文档\",\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"searchBox\":{\"resetButtonTitle\":\"清除查询条件\",\"resetButtonAriaLabel\":\"清除查询条件\",\"cancelButtonText\":\"取消\",\"cancelButtonAriaLabel\":\"取消\"},\"startScreen\":{\"recentSearchesTitle\":\"搜索历史\",\"noRecentSearchesText\":\"没有搜索历史\",\"saveRecentSearchButtonTitle\":\"保存至搜索历史\",\"removeRecentSearchButtonTitle\":\"从搜索历史中移除\",\"favoriteSearchesTitle\":\"收藏\",\"removeFavoriteSearchButtonTitle\":\"从收藏中移除\"},\"errorScreen\":{\"titleText\":\"无法获取结果\",\"helpText\":\"你可能需要检查你的网络连接\"},\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\",\"searchByText\":\"搜索提供者\"},\"noResultsScreen\":{\"noResultsText\":\"无法找到相关结果\",\"suggestedQueryText\":\"你可以尝试查询\",\"reportMissingResultsText\":\"你认为该查询应该有结果?\",\"reportMissingResultsLinkText\":\"点击反馈\"}}}}}}},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/Charles7c/charles7c.github.io\"},{\"icon\":{\"svg\":\"<svg role=\\\"img\\\" viewBox=\\\"0 0 24 24\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><title>码云</title><path d=\\\"M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z\\\"/></svg>\"},\"link\":\"https://gitee.com/Charles7c/charles7c\"},{\"icon\":{\"svg\":\"<svg width=\\\"33\\\" height=\\\"33\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 174.8 204\\\">\\n <title>ContiNew Admin</title>\\n <path fill=\\\"#307AF2\\\" d=\\\"M86.7,0l88,51v.2l-16.3,9.4v-.2L86.7,18.9Zm71.8,143.5,16.3,9.4v.2L86.8,204h0l-16.3-9.4,16.3-9.4h0l71.7-41.5v-.2Z\\\"/>\\n <path fill=\\\"#12D2AC\\\" d=\\\"M16.3,143.5v.2L58,167.8l-16.3,9.4L0,153.1v-.2Z\\\"/>\\n <path fill=\\\"#12D2AC\\\" d=\\\"M104.1,93,15.9,143.8l-.2-.1V124.9l.2.1L87.7,83.6,104.1,93Z\\\"/>\\n <path fill=\\\"#0057FE\\\" d=\\\"M88.1,0,.1,51v.2l16.3,9.4v-.2L88.1,18.9Z\\\"/>\\n <path fill=\\\"#307AF2\\\" d=\\\"M.1,50.9.2,152.6l.2.1,16.3-9.4-.2-.1-.1-82.9L.1,50.9Z\\\"/>\\n <path fill=\\\"#0057FE\\\" d=\\\"M174.7,50.9l-.1,101.7-.2.1-16.3-9.4.2-.1.1-82.9Z\\\"/>\\n <path fill=\\\"#12D2AC\\\" d=\\\"M41.7,158.5l16.1,9.4,100.6-58.7V90.4Z\\\"/>\\n </svg>\"},\"link\":\"https://cnadmin.charles7c.top/\"}],\"articleMetadataConfig\":{\"author\":\"查尔斯\",\"authorLink\":\"/about/me\",\"showViewCount\":false},\"copyrightConfig\":{\"license\":\"署名-相同方式共享 4.0 国际 (CC BY-SA 4.0)\",\"licenseLink\":\"http://creativecommons.org/licenses/by-sa/4.0/\"},\"commentConfig\":{\"type\":\"gitalk\",\"showComment\":true},\"footerConfig\":{\"showFooter\":true,\"icpRecordCode\":\"津ICP备2022005864号-2\",\"publicSecurityRecordCode\":\"津公网安备12011202000677号\",\"copyright\":\"Copyright © 2019-2024 Charles7c\"}},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":true}");</script>
</body>
</html>