<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>远之松的小窝</title><link href="https://zhiyuansong.xyz/" rel="alternate"/><link href="https://zhiyuansong.xyz/feeds/all.atom.xml" rel="self"/><id>https://zhiyuansong.xyz/</id><updated>2026-10-14T10:20:00+08:00</updated><entry><title>传说开始时刻</title><link href="https://zhiyuansong.xyz/chuan-shuo-kai-shi-shi-ke.html" rel="alternate"/><published>2026-10-14T10:20:00+08:00</published><updated>2026-10-14T10:20:00+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2026-10-14:/chuan-shuo-kai-shi-shi-ke.html</id><content type="html">&lt;p&gt;Category: Review&lt;/p&gt;
&lt;p&gt;Following is a review of my favorite mechanical keyboard.&lt;/p&gt;</content><category term="misc"/></entry><entry><title>StarRocks相关知识记录</title><link href="https://zhiyuansong.xyz/starrocksxiang-guan-zhi-shi-ji-lu.html" rel="alternate"/><published>2023-10-23T14:16:04+08:00</published><updated>2023-10-23T14:16:04+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-10-23:/starrocksxiang-guan-zhi-shi-ji-lu.html</id><summary type="html">&lt;p&gt;近来的EIP需求接入了新的数据组件，StarRocks，趁着有时间了解一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;简单看了一下，这个数据存储在数据分析上有长处，在建表的时候就可以直接指定数据 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;近来的EIP需求接入了新的数据组件，StarRocks，趁着有时间了解一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;简单看了一下，这个数据存储在数据分析上有长处，在建表的时候就可以直接指定数据模型的类型，来确定数据入表的时候是直接保存，还是做聚合，还是做更新，还是直接主键索引。语言方便就兼容原生SQL。这个主键模型的数更新逻辑是删掉旧的，再插入新的（笑了）&lt;/p&gt;
&lt;p&gt;说实话不少东西也看不懂究竟有什么用&lt;/p&gt;
&lt;p&gt;可以建一个表结构联合所建立的表及案例联系。&lt;/p&gt;
&lt;p&gt;我还是没太看懂，直接看DML相关的内容罢，先把增删改查之类的东西学完&lt;/p&gt;
&lt;p&gt;GROUP BY 可以直接把多个要分组的内容放在一起，不怕出问题，一个句子顶上好几句的内容（GROUPING SETS）&lt;/p&gt;
&lt;p&gt;感觉看了半天没什么印象，等之后实际使用的时候再看看怎么搞吧&lt;/p&gt;
&lt;p&gt;消息队列：低持久性消息、较小消息可选redis,海量持久性消息选kafka,中等需求可选rebbitmq&lt;/p&gt;
&lt;p&gt;redis适合做很小规模，业务简单的消息队列场景。&lt;/p&gt;
&lt;p&gt;消息队列 异步，微服务 流量削峰填谷(先全塞到队列里，再慢慢处理) 消息分发（直接让应用监听消息对应的队列即可）&lt;/p&gt;
&lt;p&gt;因为redis是直接存储内容在内存里面的，所以如果设备被断电，内容会直接清空，不是持久保存的&lt;/p&gt;
&lt;p&gt;缺点：系统可用性降低，系统的复杂性也提高，一致性问题，没法判断对面到底有没有正确消费内容。&lt;/p&gt;
&lt;p&gt;Redis可以做数据库，缓存和消息队列&lt;/p&gt;
&lt;p&gt;NoSQL 非关系型数据库 方便扩展，数据量大性能高，多样&lt;br /&gt;
存储形式，键值对，文档，列簇，图关系等&lt;/p&gt;
&lt;p&gt;缓存雪崩 大量key失效，访问数据库请求太多崩了&lt;br /&gt;
缓存穿透：缓存和数据库里面都没有的数据，所有请求都落到了数据库上，造成了数据库短时间内承受了大量的请求崩掉&lt;br /&gt;
缓存击穿：缓存中没有但是数据库中有并发太多又跑去数据库里面去查了，数据库撑不住 加互斥锁可以解决，没有过期时间的缓存是不推荐的&lt;/p&gt;
&lt;p&gt;Redis主要就是基于内存，所以相应的速度很快。是不是存在一个命中率的问题，命中就直接取读缓存，没命中就去读数据库，同时回写缓存&lt;/p&gt;</content><category term="学习笔记"/><category term="StarRocks"/><category term="数据库"/><category term="原创"/></entry><entry><title>EIP客服模块Case查询需求流程总结</title><link href="https://zhiyuansong.xyz/eipke-fu-mo-kuai-casecha-xun-xu-qiu-liu-cheng-zong-jie.html" rel="alternate"/><published>2023-10-19T14:43:25+08:00</published><updated>2023-10-19T14:43:25+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-10-19:/eipke-fu-mo-kuai-casecha-xun-xu-qiu-liu-cheng-zong-jie.html</id><summary type="html">&lt;p&gt;EIP在做完了广告管理部分的重构之后，又去做了一些不轻不重的需求，之后接到了这个Case查询的实现需求，个人感觉这个需求是一个完整的数据流搭建，虽然简单但是其中的 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;EIP在做完了广告管理部分的重构之后，又去做了一些不轻不重的需求，之后接到了这个Case查询的实现需求，个人感觉这个需求是一个完整的数据流搭建，虽然简单但是其中的关键步骤值得记录一下，方便之后借鉴。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;简单数据流大概是，数据接收系统向爬虫端派发爬取任务，爬虫端爬取到数据推送到数据接收系统的接口，接收到的数据先推到队列中，然后由挂在守护进程里的脚本做数据保存处理。由此完成数据保存流程。&lt;/p&gt;
&lt;p&gt;然后是在EIP中完成数据显示，参考之前的工作内容还是主要前端页面搭建，搜索实现，数据源配置等内容。&lt;/p&gt;
&lt;p&gt;数据保存部分本次耗时较多，问题主要出现在需求多次变动，最后甚至直接换了个数据保存系统，在另一个系统里重新搭建了一次数据保存流。个人卡住的地方主要是队列的使用，之前没怎么用过，不懂配置流程。主要是在mq等配置文件里做好配置即可，感觉队列在处理数据的过程中是有使用需求的，毕竟一次推送过来的数据过多的话，脚本一次性处理不过来的，放到队列中依次处理是比较好的选择。&lt;/p&gt;
&lt;p&gt;然后是EIP部分的内容，页面搭建部分问题不是很大，页面，控制器参考之前的内容，table配置文件配置显示的字段，配置字段的模板和宽度等，配置查找，本次比较简单，因为数据规模较小，所以数据源直接取mysql，搜索记得加权限控制函数，GraphQL的内容主要是Type文件和Schema文件，其他部分略过。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="工作流程"/><category term="原创"/></entry><entry><title>EIP页面重构内容总结</title><link href="https://zhiyuansong.xyz/eipye-mian-zhong-gou-nei-rong-zong-jie.html" rel="alternate"/><published>2023-09-01T10:18:55+08:00</published><updated>2023-09-01T10:18:55+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-09-01:/eipye-mian-zhong-gou-nei-rong-zong-jie.html</id><summary type="html">&lt;p&gt;回来接手的第一个和数据结合比较紧密的需求，做下总结，主要是数据访问的流程之前接触过也忘得差不多了，需要做下 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;回来接手的第一个和数据结合比较紧密的需求，做下总结，主要是数据访问的流程之前接触过也忘得差不多了，需要做下总结备忘。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;首先做下数据流的描述，整个工作台的数据访问其实是建立在ElasticSearch上的，好处主要是搜索上很快，自己使用的过程中也确实感受到了，查询方面确实要比直接从MySQL查询快多了。因为在Laravel中数据源基本都直接以Model形式访问，所以基本的访问方式其实可以用基本的Model访问数据方式来实现。当然也有某些ES DSL的扩展库，可以实现ES的查询方式，之后有机会再做下记录。&lt;/p&gt;
&lt;p&gt;从ES查询到数据后，会存在这样一种使用情景。在MySQL中反映出来就是一个页面展示多个数据表的数据，那么一般的操作是做表连接查询，当然连接查询会有性能问题，那么另外一种情况就是写一个拼接数据的函数分别访问多个数据表最后完成数据拼装。那么反映在ES中索引的数据又该怎么处理呢？脑测一下其实访问多个索引再拼装数据其实也不是不行。但实际项目中的数据量乃是千万到亿的数量级。性能问题是绝对会存在的。所以实际的使用中在查询完ES后又使用了GraphQL来实现数据拼接。&lt;/p&gt;
&lt;p&gt;说起GraphQL，之前应该做过一点记录，但确实理解不深。其实从个人方面来解释，这个查询语言就是便利了数据的组织返回，相比RESTful API那种情况，每次请求一个复杂结构的数据，都得请求不同的API。GraphQL做的是把整个数据的结构都配置出来，根据后面请求包含的数据格式再组装数据返回。有点一劳永逸的感觉。反映在项目中就是对每一个索引建立一个GraphQL Type，对每个字段进行类型的描述，多个索引间的关系也可以通过对象类型来绑定。&lt;/p&gt;
&lt;p&gt;内容大概就是这些。然后简述一下续作完成过程中涉及的文件。首先是一个配置文件，配置了访问的数据字段和生成字段的显示等内容，个人感觉实际上就是通过这里的配置生成graphQL请求的。然后页面显示的内容实际上应该是分成两个部分的。负责页面的controller实际上不负责返回数据，而负责的是页面组件的返回，和导出之类的配置。实际的数据返回是在TableApiController中完成的，具体细节暂时不详。数据的请求处理和数据组装是在Service文件中完成的。而布局等内容基本上和之前做i过的一致，主要是拆分了不少数据展示方面的模板，需要仇视假案学习一下布局拆分的逻辑。&lt;/p&gt;
&lt;p&gt;大概内容就是这些。比较难的地方主要是数据流那一部分，因为涉及到很多Type的修改，最终走到数据展示的点的过程中试错了很多次，比较艰难，其他内容倒是还好。再就是在完成需求的过程中加了不少重复的页面，最后修改的过程中直接工作量翻倍，后面只好修改成增加参数做区分即可，下次注意一下就好了。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="工作流程"/><category term="原创"/></entry><entry><title>EHR项目总结</title><link href="https://zhiyuansong.xyz/ehrxiang-mu-zong-jie.html" rel="alternate"/><published>2023-07-11T20:22:15+08:00</published><updated>2023-07-11T20:22:15+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-07-11:/ehrxiang-mu-zong-jie.html</id><summary type="html">&lt;p&gt;我从项目组借调出去干EHR项目支援差不多有一年时间了（虽然回来之后那边的需求还是源源不断，让人挺苦恼的😂），终于可以做一下总结了，其实也说不上 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我从项目组借调出去干EHR项目支援差不多有一年时间了（虽然回来之后那边的需求还是源源不断，让人挺苦恼的😂），终于可以做一下总结了，其实也说不上总结，就是把整个做东西过程中接触到的东西简单罗列一下，做个备忘。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;首先，这个项目基于的是一个叫ROCKOA的OA框架做的二次开发，对这框架我才疏学浅不好评价，但不太好用是真的，文档就几页，大量的试错。不过最后做出来的东西还是要比之前老掉牙的旧OA要强不少。&lt;/p&gt;
&lt;p&gt;OA基于的就是流程和程序流，这个框架设定每一个流程为一个模块，一个模块从组成上大概包含以下内容，前端的录入表单，展示页面，列表页面和相应的js调控；后端的涉及到数据检测和替换等功能的Action文件和涉及程序流控制的Model文件。还有就是相关的在框架的配置内容。具体更详细的描述可以去看框架的文档（这东西寿命大概比我的小博客要长吧）。下面依次进行说明。&lt;/p&gt;
&lt;p&gt;录入表单和展示页面：可以通过配置字段，然后框架根据配置的字段的顺序，字段的元素类型等属性自动生成一个页面，大部分情况是先框架配置好字段，然后生成页面后再进行内容的调整，像是处理js实现更复杂的交互逻辑等。展示页面同理，不过展示页面没有交互逻辑只做展示，所以更简单。&lt;/p&gt;
&lt;p&gt;列表页面：列表页面的显示，大概涉及一个页面和列表显示的权限配置，和模块条件等内容，在字段配置好的前提下，系统会默认生成一个列表页面，但此时的列表页面不可见，需要配置列表页面的条件，大概是配置编号，然后再去配置模块的权限，在配置查看权限的情况下是可见页面的。列表页面的相关功能，像是搜索项，字段编辑功能等是在配置字段的时候可以配置的。&lt;/p&gt;
&lt;p&gt;Action文件：可以写对应的函数来控制表单填写数据提交前后的内容处理，像是格式检验，修改数据等，也可以控制列表页数据的搜索和数据显示，做的一些模块自定义内容较多，搜索组件都得自己写的情况下，后端对搜索逻辑的处理基本上是在这个地方搓出来的。&lt;/p&gt;
&lt;p&gt;Model文件：可以说是一个流程的核心文件了，涉及到数据源的自定义，写AJAX异步处理，确定自定义审核步骤的审核人和抄送人等内容，基本上核心的流程处理就是在这里进行的，内容很多，我到现在还没有研究到位。&lt;/p&gt;
&lt;p&gt;框架配置项：首先模块创建，之后创建字段，生成录入页面再进行调整，最后配置审核步骤，模块条件和模块权限。个人感觉配置审核步骤是一个比较复杂的活，因为步骤配置的一些地方使用起来和画逻辑图不太一样，所以需要设置一些过渡节点来解决问题，有些时候会配置的很乱。&lt;/p&gt;
&lt;p&gt;大概就是这些内容，目前感觉项目有的问题没法解决，像是批量导入的问题，目前是没法搞定的，不清楚导入数据的量是在什么地方造成了性能瓶颈。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="工作流程"/><category term="原创"/></entry><entry><title>SQL和接口相关的内容</title><link href="https://zhiyuansong.xyz/sqlhe-jie-kou-xiang-guan-de-nei-rong.html" rel="alternate"/><published>2023-03-20T20:22:28+08:00</published><updated>2023-03-20T20:22:28+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-03-20:/sqlhe-jie-kou-xiang-guan-de-nei-rong.html</id><summary type="html">&lt;p&gt;最近一直在做的内容主要是写流程的前后端内容，然后写接口。整个过程大概就是后端从数据库取数据，前端做显示。接口 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;最近一直在做的内容主要是写流程的前后端内容，然后写接口。整个过程大概就是后端从数据库取数据，前端做显示。接口的内容也是差不多，无非就是读取请求参数，从数据库中取值拼装并返回。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;期间有一些写的很烂的东西，改正之后长了些教训，记录一下。&lt;/p&gt;
&lt;h2 id="_1"&gt;接口速度的提升&lt;/h2&gt;
&lt;p&gt;第一点，要避免没有条件，直接请求一整张表的内容的情况，不止指的是全字段，指的是整张表的全部数据，之前写接口，干的事情大概是首先请求一整张表的数据，然后for循环处理，根据传参的id之类的东西做内容排除，实际用起来，一开始响应的速度还行，但是只要数据一多，响应速度就会变慢，尽量还是在SQL请求的时候就把条件加上，而不是获取全局数据后再去排除。&lt;/p&gt;
&lt;p&gt;第二点，很多张表的数据拼接，适时使用连接查询。自己之前不喜欢用表连接，因为写起来很长，经常使用的是先查一张表的内容，再用这张表的某个字段当条件去另一张表里查询，最后做数据拼接。实际用起来也是，会越来越慢，而且SQL请求的数量会很多。SQL请求越多就越慢，连接查询既减少了请求的数量也变相减少了数据拼接的工作量，唯一不好的点大概是略微有点长。&lt;/p&gt;
&lt;p&gt;第三点，尽量避免在for循环里使用SQL请求，这一点可以联系到上面那条，多个表数据拼接，第一个表请求获得一个数组，然后for循环，去第二张表里面查内容再拼接……如果量少还好，量多的话，真的难以控制访问速度，写起来大概很轻松，但是访问速度会相当慢。&lt;/p&gt;
&lt;p&gt;第四点，limit和offset关键字实现分页，接口大多数情况直接返回整张表的数据都是比较困难的事情，不分页的话响应速度会相当慢，建议还是分页，响应速度会很快，无非就是让请求端多请求几次，但体验会好不少。&lt;/p&gt;
&lt;p&gt;内容目前大概就这些，自己还是得抽点时间去改改之前写的东西，不少内容确实能实际感受到响应的缓慢。&lt;/p&gt;</content><category term="学习笔记"/><category term="SQL"/><category term="原创"/></entry><entry><title>正则表达式相关内容整理</title><link href="https://zhiyuansong.xyz/zheng-ze-biao-da-shi-xiang-guan-nei-rong-zheng-li.html" rel="alternate"/><published>2023-01-09T11:12:45+08:00</published><updated>2023-01-09T11:12:45+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2023-01-09:/zheng-ze-biao-da-shi-xiang-guan-nei-rong-zheng-li.html</id><summary type="html">&lt;p&gt;这部分内容主要是最近有一部分需求涉及到了字段的格式校验，学习应用了一下，本来内容上其实之前已经看过几遍了 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这部分内容主要是最近有一部分需求涉及到了字段的格式校验，学习应用了一下，本来内容上其实之前已经看过几遍了，但是没有应用环境，导致看了也没什么印象，这次好歹照猫画虎写了一些相关的代码，可以总结一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;简述&lt;/h2&gt;
&lt;p&gt;正则表达式就是用一个用特定字符组合成的字符串，它用来表示一组具有对应表示结构的字符串，即符合正则表达式的结构。&lt;/p&gt;
&lt;p&gt;基本的写法是要用双引号包住，里面再包一组正斜杠，如此开始书写内容。&lt;/p&gt;
&lt;h2 id="_2"&gt;举例说明&lt;/h2&gt;
&lt;p&gt;需要举例说明来展示相关符号的功能。&lt;/p&gt;
&lt;p&gt;例如&amp;rdquo;/^[A-Za-z0-9_-]$/&amp;rdquo;，&lt;code&gt;^&lt;/code&gt;代表字符串的开头，&lt;code&gt;$&lt;/code&gt;代表字符串的结尾，中括号中的内容代表一个字符集合，一个中括号代表在这个字符集合中取一个字符。&lt;/p&gt;
&lt;p&gt;再举例&amp;rdquo;/^[A-Za-z0-9_-]+$/&amp;rdquo;，和上面的区别就是多了一个&lt;code&gt;+&lt;/code&gt;号，代表的含义是中括号内集合字符出现1次或多次，如果&lt;code&gt;+&lt;/code&gt;替换成&lt;code&gt;*&lt;/code&gt;代表字符出现0次或多次，替换成&lt;code&gt;?&lt;/code&gt;代表出现0次或1次。其实后两个按平常使用的系统通配符的含义理解就可以了。&lt;/p&gt;
&lt;p&gt;再举例&amp;rdquo;/^[A-Za-z0-9_-]{3,15}$/&amp;rdquo;，大括号中的内容代表中括号内集合字符出现3~15次，这种场景可以出现在密码验证中限制密码的位数这种情况下。&lt;/p&gt;
&lt;p&gt;再举例&amp;rdquo;/^[A-Za-z0-9_-]{3,15}abc$/&amp;rdquo;，代表的内容是在上面的说明基础上，同时以abc做结尾的字符串。&lt;/p&gt;
&lt;p&gt;再举例&amp;rdquo;/^[^A-Z]{3,15}$/&amp;rdquo;，中括号中的&lt;code&gt;^&lt;/code&gt;含义是排除，即除了A-Z之外的字符出现3~15次，起一个除外的作用。&lt;/p&gt;
&lt;p&gt;一个&lt;code&gt;.&lt;/code&gt;可以代表除了回车(&lt;code&gt;\r\n&lt;/code&gt;)外的所有字符。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\w&lt;/code&gt;可以代表[A-Za-z0-9_]这个字符集合，&lt;code&gt;\s&lt;/code&gt;匹配所有的空白符，包括换行；&lt;code&gt;\S&lt;/code&gt;匹配所有的非空白符，不包括换行。&lt;/p&gt;
&lt;p&gt;特殊字符用的时候自行查一下，主要是有些符号在表达式中有意义，实际上要表示这个符号要用反斜杠转义一下。&lt;/p&gt;
&lt;p&gt;修饰符——标记匹配的模式，像是i表示忽视大小写，g表示全局匹配找出所有的满足字符串等。&lt;/p&gt;</content><category term="学习笔记"/><category term="正则表达式"/><category term="原创"/></entry><entry><title>设计模式沙龙内容</title><link href="https://zhiyuansong.xyz/she-ji-mo-shi-sha-long-nei-rong.html" rel="alternate"/><published>2022-10-23T18:28:48+08:00</published><updated>2022-10-23T18:28:48+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-10-23:/she-ji-mo-shi-sha-long-nei-rong.html</id><summary type="html">&lt;p&gt;设计模式提供了一套可复用的设计范式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;设计模式的类型&lt;/h2&gt;
&lt;p&gt;设计模式主要可划分为三种类型：创建型模式主要是针对对象 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;设计模式提供了一套可复用的设计范式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;设计模式的类型&lt;/h2&gt;
&lt;p&gt;设计模式主要可划分为三种类型：创建型模式主要是针对对象是如何实例化的过程进行设计；结构型模式针对类和对象的组合关系进行设计；行为型模式关注的是类和对象的通信，或者说交互问题。&lt;/p&gt;
&lt;p&gt;创建型模式有：工厂方法模式、抽象工厂模式、建造者模式、单例模式和&lt;em&gt;原型模式&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;结构型模式有：适配器模式、装饰器模式、代理模式、门面模式、组合模式、享元模式和&lt;em&gt;桥接模式&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;行为型模式有：策略模式、&lt;em&gt;观察者模式&lt;/em&gt;、责任链模式、&lt;em&gt;解释器模式&lt;/em&gt;、模板方法模式、&lt;em&gt;迭代器模式&lt;/em&gt;、&lt;em&gt;中介者模式&lt;/em&gt;、&lt;em&gt;命令模式&lt;/em&gt;、&lt;em&gt;访问者模式&lt;/em&gt;、&lt;em&gt;备忘录模式&lt;/em&gt;和状态模式。&lt;/p&gt;
&lt;h2 id="_2"&gt;创建型模式&lt;/h2&gt;
&lt;h3 id="_3"&gt;工厂模式相关&lt;/h3&gt;
&lt;p&gt;首先先说简单工厂模式，在不考虑设计模式的情况下，一般类继承接口，类再实例化获得对象，但当规模扩展时，直接调用类的实例化会使对象和类的关系比较耦合（距离产生美），之后可能的修改也会比较困难。简单地说，创建一个工厂类，有工厂类中的创建方法来实现类的实例化，为了方便调用可以直接将这个方法写成工厂类的静态方法，方便调用。如果使用类似switch判断的问题导致项目扩展过程中反复修改工厂类的话，可以考虑使用语言特性来解决，像是Java中的反射。&lt;/p&gt;
&lt;p&gt;再说工厂方法模式，还是上面的问题，不过现在获得对象的步骤变复杂了，例如想要获得预期的对象需要大量的重复代码，在大方向上区别不大但在细节上需要有所区别等。这样的话，在简单工厂的逻辑上进一步提升，所谓专人干专事，同一类对象就交给同一个专用的工厂去生成，具体的类衍生自抽象的类，满足了上面提到的要求。相比简单工厂，可以说是更加细化了工厂的类别。&lt;/p&gt;
&lt;p&gt;最后说抽象工厂模式，问题进一步复杂化，产品有了两个乃至多个维度。举个例子，某个具体品牌的电饭煲，在品牌维度上属于某具体品牌，在电器类型维度上属于电饭煲，那么构建这个具体品牌的电饭煲就需要在这个具体品牌的工厂生产电饭煲（当然，在电饭煲工厂生产属于某个具体品牌的电饭煲就不合逻辑了，需要考虑实际情况）。所以首先获取该具体品牌工厂的实例，即具体工厂的类实例化，再调用该工厂生产具体产品的方法（即在工厂中完成产品的实例化）。&lt;/p&gt;
&lt;p&gt;看到最后，感觉三个工厂模式的复杂度层层递进，处理的维度层数越来越复杂，多数情况人们不关心实例是怎么创建的，工厂模式把实例化的过程封装在了工厂中，提供了获取实例的一个开口罢了。&lt;/p&gt;
&lt;h3 id="_4"&gt;建造者模式&lt;/h3&gt;
&lt;p&gt;使用静态内部类来实现建造者模式，即一个产品类中带有一个建造者的静态类负责产品的组装创建。类似煎饼和煎饼师傅的关系？&lt;/p&gt;
&lt;p&gt;https://blog.csdn.net/weixin_46121939/article/details/119088667&lt;/p&gt;
&lt;p&gt;实例：sql语句的组装就可以用建造者模式来解决。Laravel框架在查询构造器中就是这样处理的。Laravel container&lt;/p&gt;
&lt;h3 id="facade"&gt;门面模式（Facade）&lt;/h3&gt;
&lt;p&gt;设想一个场景，一个功能的实现是基于之前已经完成的各个子功能的拼接，如果不做拼接的步骤，每次都需要考虑子功能间的关系，如果把各个子功能的接口调用过程封装到一个类中，只提供一个调用接口，这样的类就是一个门面。&lt;/p&gt;
&lt;p&gt;其实简单来说就是步骤复杂时做的过程封装，复用时直接调用开放的接口就行了。&lt;/p&gt;
&lt;p&gt;当然步骤的复杂有繁有简。&lt;/p&gt;
&lt;p&gt;实例：在Laravel框架中有一批被称为门面的类，为应用程序的服务容器中可用的类提供了静态接口。相比传统的静态方法调用，Facade提供的语法更简洁，测试性和扩展性更好。&lt;/p&gt;</content><category term="学习笔记"/><category term="设计模式"/><category term="原创"/></entry><entry><title>设计模式相关知识</title><link href="https://zhiyuansong.xyz/she-ji-mo-shi-xiang-guan-zhi-shi.html" rel="alternate"/><published>2022-09-07T16:57:47+08:00</published><updated>2022-09-07T16:57:47+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-09-07:/she-ji-mo-shi-xiang-guan-zhi-shi.html</id><summary type="html">&lt;p&gt;用php来理解几个设计模式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;单例模式&lt;/h2&gt;
&lt;p&gt;$_instance必须声明成静态私有变量&lt;br /&gt;
构造和析构函数必须是私有的，防止外部程序new一个新对象&lt;br /&gt;
getInstance()必须设置为公有的，调用此方法来返回实例的一个引 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;用php来理解几个设计模式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;单例模式&lt;/h2&gt;
&lt;p&gt;$_instance必须声明成静态私有变量&lt;br /&gt;
构造和析构函数必须是私有的，防止外部程序new一个新对象&lt;br /&gt;
getInstance()必须设置为公有的，调用此方法来返回实例的一个引用。使用的时候直接使用获取实例，应该是个静态函数，然后调用构造函数即可。&lt;br /&gt;
::操作符只能访问静态变量和静态函数&lt;br /&gt;
new对象都会消耗内存&lt;br /&gt;
这个模式最常用的地方是数据库连接，生成一个对象后可以被其他对象所使用，私有的_clone()方法防止克隆对象。&lt;/p&gt;
&lt;h2 id="_2"&gt;工厂模式&lt;/h2&gt;
&lt;p&gt;工厂模式，工厂方法或者类生成对象而不是在代码中直接new，可以避免当改变某个类的名字或者方法后在调用这个类的所有的代码中都修改它的名字或者参数。&lt;/p&gt;
&lt;h2 id="gof"&gt;阅读GOF相关知识&lt;/h2&gt;
&lt;p&gt;继承，类的组合，使用模板（讲到的内容没有涉及，主要是只有C++带有泛型编程）&lt;/p&gt;
&lt;p&gt;https://zhuanlan.zhihu.com/p/427324132&lt;/p&gt;</content><category term="学习笔记"/><category term="设计模式"/><category term="原创"/></entry><entry><title>技术讨论——地铁二维码扫码乘车场景</title><link href="https://zhiyuansong.xyz/ji-zhu-tao-lun-di-tie-er-wei-ma-sao-ma-cheng-che-chang-jing.html" rel="alternate"/><published>2022-09-07T11:39:58+08:00</published><updated>2022-09-07T11:39:58+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-09-07:/ji-zhu-tao-lun-di-tie-er-wei-ma-sao-ma-cheng-che-chang-jing.html</id><summary type="html">&lt;p&gt;对于这种实际场景的应用考虑做的比较少，考虑一下这些点。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;1.设计难度，为什么难&lt;br /&gt;
2.金融安全角度的难点&lt;br /&gt;
3.网络通信问 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;对于这种实际场景的应用考虑做的比较少，考虑一下这些点。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;1.设计难度，为什么难&lt;br /&gt;
2.金融安全角度的难点&lt;br /&gt;
3.网络通信问题，不可靠网络场景的处理&lt;br /&gt;
4.信息传递，各项事件的依赖传递怎么实现&lt;br /&gt;
5.二维码的设计和识别问题&lt;br /&gt;
6.面向异常设计，若中间流程出现异常怎么办，出站或进站出现延迟阻塞怎么办&lt;br /&gt;
7.网络交互的框架设计&lt;br /&gt;
8.各种实际场景问题&lt;/p&gt;
&lt;h2 id="_1"&gt;设计难度&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;使用人数考虑&lt;/li&gt;
&lt;li&gt;网络状况不稳定的考虑&lt;/li&gt;
&lt;li&gt;将二维码和其他付款方式结合兼容&lt;/li&gt;
&lt;li&gt;设备布设的问题&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;解决的方法：统计地铁人流量；使用被动扫码，维护扫码设备网络的稳定性；设计特定的设备，联系地铁站设计等相关知识。实际上是一个软硬件结合的问题。&lt;/p&gt;
&lt;h2 id="_2"&gt;金融安全角度的难点&lt;/h2&gt;
&lt;p&gt;是一个软硬件结合的系统，硬件出问题的话需要回复的事件较长，软件的话可能有恶意二维码的情况，如果是主动的扫码的话，可能会有这种情况，被动的话需要做好恶意访问的拦截。&lt;/p&gt;
&lt;h2 id="_3"&gt;网络通信问题，不可靠网络场景处理&lt;/h2&gt;
&lt;p&gt;使用的是先乘车后付费的形式，采用的是自动扣款的方式，所以扣费的行为是可以延迟进行的。扫二维码实际上是一个身份、事件和地点凭证，扫码设备是固定的，保证这部分网络的稳定情况下，要解决的网络问题主要是手机设备的问题，主要是二维码生成的问题，这里使用的是离线支付的方式，二维码是采用令牌可以离线生成的，而且是动态的，如果是静态的会有被盗刷的风险，动态二维码也可以保证信息的一致性。&lt;/p&gt;
&lt;h2 id="_4"&gt;信息传递，各项事件的依赖传递怎么实现&lt;/h2&gt;
&lt;p&gt;扫二维码可以获取账号时间地点信息，只要经过处理就可以计算出票价等相关信息。&lt;/p&gt;
&lt;h2 id="_5"&gt;二维码的设计和识别问题&lt;/h2&gt;
&lt;p&gt;二维码的生成可以离线实现，主要是结合了令牌生成器的原理。这样的话二维码也是动态的，防止盗用情况的出现。&lt;/p&gt;
&lt;p&gt;采用被刷的形式，而不是主动扫码的形式，因为主动扫码可能会被而已篡改二维码而达成某些不法目的，同时网络维护的主体是车站设备而不是手机端，维护的难度和稳定性更高。&lt;/p&gt;
&lt;h2 id="_6"&gt;异常？&lt;/h2&gt;
&lt;h2 id="_7"&gt;框架设计？&lt;/h2&gt;
&lt;h2 id="_8"&gt;实际场景？&lt;/h2&gt;</content><category term="学习笔记"/><category term="实际场景讨论"/><category term="原创"/></entry><entry><title>技术讨论——数据库相关</title><link href="https://zhiyuansong.xyz/ji-zhu-tao-lun-shu-ju-ku-xiang-guan.html" rel="alternate"/><published>2022-08-22T19:19:55+08:00</published><updated>2022-08-22T19:19:55+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-08-22:/ji-zhu-tao-lun-shu-ju-ku-xiang-guan.html</id><summary type="html">&lt;p&gt;本篇主要是简略记录数据库相关的知识。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;定义&lt;/h2&gt;
&lt;p&gt;存储数据、管理数据的仓库，简称数据库。&lt;/p&gt;
&lt;h2 id="_2"&gt;分类&lt;/h2&gt;
&lt;p&gt;可以分为关系型数据库和非关 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;本篇主要是简略记录数据库相关的知识。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;定义&lt;/h2&gt;
&lt;p&gt;存储数据、管理数据的仓库，简称数据库。&lt;/p&gt;
&lt;h2 id="_2"&gt;分类&lt;/h2&gt;
&lt;p&gt;可以分为关系型数据库和非关系型数据库，常见的关系型数据库有MySQL，Oracle，非关系型数据库有Redis，Elasticsearch，MongoDB和HBase等。&lt;/p&gt;
&lt;p&gt;关系型数据库的数据建立在紧密的关系基础上，以数据表为数据的组织形式，优点是易于维护，使用方便和通过SQL可以实现复杂的操作；缺点是读写性能较差，数据组织形式灵活性不够，再就是高并发读写存在瓶颈。&lt;/p&gt;
&lt;p&gt;非关系型数据库指的是一种数据结构化存储方法的集合，像是文档和键值对，优点有格式灵活，速度快（可选的载体多），高扩展性和成本低。缺点是没有sql支持，没有事务处理，复杂查询不太胜任。&lt;/p&gt;
&lt;p&gt;扩展性上关系型依靠提高性能来实现，这样总会有上限。而非关系型通过分布式来扩展自己的性能。&lt;/p&gt;
&lt;h2 id="_3"&gt;数据类型&lt;/h2&gt;
&lt;p&gt;二进制数据，blob，目前使用存储访问路径，将实际的内容放在磁盘上来实现。&lt;/p&gt;
&lt;h2 id="_4"&gt;主键&lt;/h2&gt;
&lt;p&gt;唯一且不能为空。&lt;/p&gt;
&lt;h2 id="_5"&gt;事务&lt;/h2&gt;
&lt;p&gt;类似于原子性操作的一组操作，要么完全执行，要么完全不执行。执行失败会回滚。&lt;/p&gt;
&lt;p&gt;事务的特性，原子性，一致性（数据的完整性没有被破坏），隔离性（多个并发事务同时读写修改），持久性（永久性修改数据，系统故障不丢失）。&lt;/p&gt;
&lt;p&gt;MySQL中使用InnoDB的才支持事务。&lt;br /&gt;
事务隔离级别分为读未提交，读提交，可重复读和串行化。MySQL达到了第三层。&lt;/p&gt;
&lt;h2 id="_6"&gt;约束&lt;/h2&gt;
&lt;p&gt;非空约束，主键约束，唯一约束，外键约束，默认约束&lt;/p&gt;
&lt;p&gt;脏读：事务1更新记录但没提交，事务2读取了更新后的行，事务1回滚了，则2读到的数据不存在了。&lt;br /&gt;
不可重复读:事务1读取记录时，事务2更新了记录并提交，事务1再读取时可以看到事务2修改后的记录。&lt;br /&gt;
幻读：事务1读取记录时事务2新增了记录并提交，事务1再次读取记录时会发现事务2修改后的记录。（行级锁）&lt;/p&gt;
&lt;h2 id="sql"&gt;优化sql的点&lt;/h2&gt;
&lt;p&gt;使用具体字段查找，避免在where中使用or，会使索引有失效的可能。使用varchar而不是char。索引不要太多，不要用在有大量重复的字段上，避免在where中使用表达式。where使用default代替null，distinct使用的字段要少。批量插入与删除，删除用ID批量删，分批，避免删除太多锁表。复合索引的使用（最左特性），先过滤，再分组。连接优先使用inner join，左连接左表要小。&lt;/p&gt;
&lt;p&gt;MySQL优化使用合适的字段，避免使用空字段，使用连接来代替子查询，使用联合（UNION）来代替手动创建的临时表，使用事务和锁定表，使用外键，使用索引，优化相关的查询语句。自动类型转换也会使得索引不起作用。&lt;/p&gt;
&lt;h2 id="dmlcrudddlcreatedclgrantdenyrevokedqlselect"&gt;DML（CRUD），DDL(create)，DCL（grant,deny,revoke），DQL(select)&lt;/h2&gt;
&lt;h2 id="innodb"&gt;InnoDB&lt;/h2&gt;
&lt;h3 id="_7"&gt;特点&lt;/h3&gt;
&lt;p&gt;支持行级锁，支持MVCC，支持外键，提供一致性非锁定读，利用CPU和内存的效率好。&lt;/p&gt;
&lt;h3 id="_8"&gt;结构&lt;/h3&gt;
&lt;p&gt;内存块组成的内存池，和后台线程，后台线程用来刷新内存池的数据，把已修改的数据刷新到磁盘。&lt;/p&gt;
&lt;h3 id="_9"&gt;后台线程&lt;/h3&gt;
&lt;p&gt;主线程：负责将缓冲池中的数据异步刷新到磁盘，保证数据的一致性。&lt;br /&gt;
IO线程：处理IO请求的回调处理。&lt;br /&gt;
Purge Thread:用来回收已经使用并分配的undo页。&lt;br /&gt;
Page Cleaner Thread：将脏页刷新操作放到单独线程中来完成&lt;/p&gt;
&lt;h3 id="_10"&gt;内存&lt;/h3&gt;
&lt;p&gt;读取磁盘数据加了缓冲池做过渡，类似于缓存的作用。以页作为读取单位。控制块对应缓存页。空闲页组成链表，节点对应控制块，控制块对应缓存块，用的时候，取节点，用，添加控制块信息，移除节点。使用LRU来淘汰算法，midpoint,FLUSH链表。空闲链表和LRU链表的关系是相互转化的，脏页链表（FLUSH）是在LRU链表中包含的。&lt;/p&gt;
&lt;h3 id="checkpoint"&gt;checkpoint&lt;/h3&gt;
&lt;p&gt;解决的问题：缩短数据库恢复时间，缓冲池不够用时将脏页刷新到磁盘，重做日志不可用时刷新脏页。每次恢复只要从回复点之后进行就可以了，大大缩短了回复时间。缓冲池不够用时溢出最近最久未使用的页，页为脏页的情况强制执行checkpoint将脏页刷新回磁盘。重做日志循环使用，当恢复时不需要这部分日志可以被覆盖，需要的话，必须执行checkpoint将缓冲池的页至少刷新到当前重做日志的位置。&lt;/p&gt;
&lt;p&gt;checkpoint类型，sharp,全部刷，关机时用；fuzzy，只刷新一部分脏页。&lt;/p&gt;
&lt;h3 id="innodb_1"&gt;InnoDB 特性&lt;/h3&gt;
&lt;p&gt;插入缓冲：物理页的组成部分&lt;/p&gt;
&lt;p&gt;两次写：提高可靠性，先写到两次写缓冲区，再分两次从缓冲区写入磁盘上共享表空间（副本），每次1MB，完成后再将两次写缓冲区写入数据文件&lt;/p&gt;
&lt;p&gt;自适应哈希索引&lt;/p&gt;
&lt;p&gt;异步IO，IO Merge&lt;/p&gt;
&lt;p&gt;刷新邻接页，邻接脏页一起更新&lt;/p&gt;
&lt;h2 id="innodbmyisam"&gt;InnoDB和MyISAM 区别&lt;/h2&gt;
&lt;p&gt;I:支持事务，支持行级锁和外键约束，不存储总行数。&lt;/p&gt;
&lt;p&gt;M:不支持事务，支持表级锁，存储表的总行数，每个表有三个文件，索引文件，表结构文件，数据文件。使用非聚集索引，索引文件的数据域存储指向数据文件的指针。&lt;/p&gt;</content><category term="学习笔记"/><category term="数据库"/><category term="原创"/></entry><entry><title>技术讨论——缓存相关</title><link href="https://zhiyuansong.xyz/ji-zhu-tao-lun-huan-cun-xiang-guan.html" rel="alternate"/><published>2022-08-15T10:02:31+08:00</published><updated>2022-08-15T10:02:31+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-08-15:/ji-zhu-tao-lun-huan-cun-xiang-guan.html</id><summary type="html">&lt;p&gt;主要的内容是计算机组成原理里面的缓存的相关知识。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;一个情况是，随着时间的推移设备逐渐发展，CPU的数据处理速度是超过内存数据的访问速度的，这样的话会出现CPU处理完当前数据 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;主要的内容是计算机组成原理里面的缓存的相关知识。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;一个情况是，随着时间的推移设备逐渐发展，CPU的数据处理速度是超过内存数据的访问速度的，这样的话会出现CPU处理完当前数据“无事可做”的情况，而内存的访问速度越快，内存的单位价格越高，为了解决数据访问速度相比处理速度“脱节”的问题，现代的CPU中引入了高速缓存的机制，通过引入多级小容量、速度快的高速缓存，与大容量，速度相对较慢的内存之间形成了类似“阶梯”的关系。通过某些算法可以预先将可能访问的内容从内存先读取到高速缓存中，CPU优先读取高速缓存中的内容，这里有一个词汇来表示读取到缓存中的数据，即所谓的“命中”，而当出现所谓未命中的情况之时，CPU才会直接读取内存中的内容，同时会将数据写入高速缓存，因为时间局部性原理，访问过的数据有很大可能会被再次访问。&lt;/p&gt;
&lt;p&gt;在实际的结构上和应用程序-&amp;gt;Redis缓存-&amp;gt;数据库类似。&lt;/p&gt;
&lt;p&gt;从上面的描述中可以看出，算法处理数据预先从内存读取到高速缓存中的这个过程对提高CPU读取数据的命中率，从而提高数据的访问速度是十分重要的，以下记录一下几种相关的算法。&lt;/p&gt;
&lt;p&gt;LRU（最近最少使用）：如果数据最近被访问过，将来被访问到的几率也更高。&lt;br /&gt;
LFU（最不经常使用）：一个数据最近一段时间使用次数很少，在将来一段时间内被使用的可能性也很小。&lt;br /&gt;
FIFO（先进先出）：数据最先进入缓存中，则应该最早被淘汰掉。&lt;/p&gt;
&lt;p&gt;浏览器的缓存策略使用的就是LRU。简单来说，将新数据和最近访问的数据优先级提前，当缓存满时将优先级低的数据释放掉。&lt;/p&gt;
&lt;p&gt;LFU和LRU的区别是，LFU是从数据的访问次数上来淘汰数据，LRU是从最近一次访问数据的时间间隔上来淘汰数据。&lt;/p&gt;
&lt;p&gt;Redis缓存淘汰和对键的过期删除策略：前一个是内存使用超过一定值时候使用的淘汰策略，后者是通过定期删除和惰性删除两者结合进行内存淘汰。key设置过期时间的情况下，每次访问都会检测是否过期，过期则删除，但有一些键只访问一次所以需要主动删除，默认情况下Redis每一秒会在设置过期时间的键集合中检测十次，每次检测20个键，过期则删除，维持过期键不超过键集合的四分之一。&lt;/p&gt;
&lt;p&gt;Redis使用24位时间戳的机制来实现LRU，使用16位时间戳加8位计数器来实现LFU，计数器使用了算法维持计数器的增长速度。新加入的数据是不会直接把计数器设置位0的，防止因为访问频率过低被删除。&lt;/p&gt;
&lt;p&gt;CPU如何知道访问的数据在缓存中的位置&lt;/p&gt;
&lt;p&gt;直接映射Cache：采用取模的方法来讲内存块的地址映射到缓存中对应的块，取N个缓存块对应的M个内存块中的数据，可以取二进制M的低N位来对应到缓存块的地址。使用在缓存块中存储组标记来确定对应的确定内存块，简单地就是存储上面的低N位地址外剩余的地址位。&lt;/p&gt;
&lt;p&gt;组标记+数据+有效位（当有效位为0，直接访问内存重新加载数据）&lt;/p&gt;
&lt;p&gt;索引（低位）、有效位、组标记（高位），由此确定数据块，从偏移量确定希望读取到的字。&lt;/p&gt;</content><category term="学习笔记"/><category term="缓存"/><category term="原创"/></entry><entry><title>Nginx的使用</title><link href="https://zhiyuansong.xyz/nginxde-shi-yong.html" rel="alternate"/><published>2022-06-23T09:03:13+08:00</published><updated>2022-06-23T09:03:13+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-23:/nginxde-shi-yong.html</id><summary type="html">&lt;p&gt;Nginx使用这部分内容主要是对其配置文件进行操作。&lt;/p&gt;
&lt;h2 id="nginx"&gt;Nginx的优点&lt;/h2&gt;
&lt;p&gt;高并发：使用了epoll。并发连接可以达到万的数量级。&lt;/p&gt;
&lt;p&gt;内存消耗少。免费使用可以商业化，配置文件简单。&lt;/p&gt;
&lt;h2 id="_1"&gt;安装&lt;/h2&gt;
&lt;p&gt;一般可以用yum进行安装 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Nginx使用这部分内容主要是对其配置文件进行操作。&lt;/p&gt;
&lt;h2 id="nginx"&gt;Nginx的优点&lt;/h2&gt;
&lt;p&gt;高并发：使用了epoll。并发连接可以达到万的数量级。&lt;/p&gt;
&lt;p&gt;内存消耗少。免费使用可以商业化，配置文件简单。&lt;/p&gt;
&lt;h2 id="_1"&gt;安装&lt;/h2&gt;
&lt;p&gt;一般可以用yum进行安装，但经常会出现这种安装的版本太旧的情况，还有去官网下载对应的源码压缩包进行编译安装之类的，这部分内容建议参考网上相关内容。&lt;/p&gt;
&lt;h2 id="_2"&gt;配置文件&lt;/h2&gt;
&lt;p&gt;配置文件的位置一般是在&lt;code&gt;/etc/nginx&lt;/code&gt;里面，是一个名叫&lt;code&gt;nginx.conf&lt;/code&gt;的文件，这个文件包括了nginx的配置项内容和网站相关的配置内容（但这部分也可以写到子配置文件中？）。&lt;/p&gt;
&lt;p&gt;具体内容如下：&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;#运行用户，默认即是nginx，可以不进行设置&lt;/span&gt;
&lt;span class="x"&gt;user  nginx;&lt;/span&gt;
&lt;span class="x"&gt;#Nginx进程，一般设置为和CPU核数一样&lt;/span&gt;
&lt;span class="x"&gt;worker_processes  1;   &lt;/span&gt;
&lt;span class="x"&gt;#错误日志存放目录&lt;/span&gt;
&lt;span class="x"&gt;error_log  /var/log/nginx/error.log warn;&lt;/span&gt;
&lt;span class="x"&gt;#进程pid存放位置&lt;/span&gt;
&lt;span class="x"&gt;pid        /var/run/nginx.pid;&lt;/span&gt;


&lt;span class="x"&gt;events {&lt;/span&gt;
&lt;span class="x"&gt;    worker_connections  1024; # 单个后台进程的最大并发数&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;


&lt;span class="x"&gt;http {&lt;/span&gt;
&lt;span class="x"&gt;    include       /etc/nginx/mime.types;   #文件扩展名与类型映射表&lt;/span&gt;
&lt;span class="x"&gt;    default_type  application/octet-stream;  #默认文件类型&lt;/span&gt;
&lt;span class="x"&gt;    #设置日志模式&lt;/span&gt;
&lt;span class="x"&gt;    log_format  main  &amp;#39;$remote_addr - $remote_user [$time_local] &amp;quot;$request&amp;quot; &amp;#39;&lt;/span&gt;
&lt;span class="x"&gt;                      &amp;#39;$status $body_bytes_sent &amp;quot;$http_referer&amp;quot; &amp;#39;&lt;/span&gt;
&lt;span class="x"&gt;                      &amp;#39;&amp;quot;$http_user_agent&amp;quot; &amp;quot;$http_x_forwarded_for&amp;quot;&amp;#39;;&lt;/span&gt;

&lt;span class="x"&gt;    access_log  /var/log/nginx/access.log  main;   #nginx访问日志存放位置&lt;/span&gt;

&lt;span class="x"&gt;    sendfile        on;   #开启高效传输模式&lt;/span&gt;
&lt;span class="x"&gt;    #tcp_nopush     on;    #减少网络报文段的数量&lt;/span&gt;

&lt;span class="x"&gt;    keepalive_timeout  65;  #保持连接的时间，也叫超时时间&lt;/span&gt;

&lt;span class="x"&gt;    #gzip  on;  #开启gzip压缩&lt;/span&gt;

&lt;span class="x"&gt;    include /etc/nginx/conf.d/*.conf; #包含的子配置项位置和文件&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;相关网站配置的内容。&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;server {&lt;/span&gt;
&lt;span class="x"&gt;    listen       80;   #配置监听端口&lt;/span&gt;
&lt;span class="x"&gt;    server_name  localhost;  //配置域名&lt;/span&gt;

&lt;span class="x"&gt;    #charset koi8-r;     &lt;/span&gt;
&lt;span class="x"&gt;    #access_log  /var/log/nginx/host.access.log  main;&lt;/span&gt;

&lt;span class="x"&gt;    location / {&lt;/span&gt;
&lt;span class="x"&gt;        root   /usr/share/nginx/html;     #服务默认启动目录&lt;/span&gt;
&lt;span class="x"&gt;        index  index.html index.htm;    #默认访问文件&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    #error_page  404              /404.html;   # 配置404页面&lt;/span&gt;

&lt;span class="x"&gt;    # redirect server error pages to the static page /50x.html&lt;/span&gt;
&lt;span class="x"&gt;    #&lt;/span&gt;
&lt;span class="x"&gt;    error_page   500 502 503 504  /50x.html;   #错误状态码的显示页面，配置后需要重启&lt;/span&gt;
&lt;span class="x"&gt;    location = /50x.html {&lt;/span&gt;
&lt;span class="x"&gt;        root   /usr/share/nginx/html;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    # proxy the PHP scripts to Apache listening on 127.0.0.1:80&lt;/span&gt;
&lt;span class="x"&gt;    #&lt;/span&gt;
&lt;span class="x"&gt;    #location ~ \.php$ {&lt;/span&gt;
&lt;span class="x"&gt;    #    proxy_pass   http://127.0.0.1;&lt;/span&gt;
&lt;span class="x"&gt;    #}&lt;/span&gt;

&lt;span class="x"&gt;    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000&lt;/span&gt;
&lt;span class="x"&gt;    #&lt;/span&gt;
&lt;span class="x"&gt;    #location ~ \.php$ {&lt;/span&gt;
&lt;span class="x"&gt;    #    root           html;&lt;/span&gt;
&lt;span class="x"&gt;    #    fastcgi_pass   127.0.0.1:9000;&lt;/span&gt;
&lt;span class="x"&gt;    #    fastcgi_index  index.php;&lt;/span&gt;
&lt;span class="x"&gt;    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;&lt;/span&gt;
&lt;span class="x"&gt;    #    include        fastcgi_params;&lt;/span&gt;
&lt;span class="x"&gt;    #}&lt;/span&gt;

&lt;span class="x"&gt;    # deny access to .htaccess files, if Apache&amp;#39;s document root&lt;/span&gt;
&lt;span class="x"&gt;    # concurs with nginx&amp;#39;s one&lt;/span&gt;
&lt;span class="x"&gt;    #&lt;/span&gt;
&lt;span class="x"&gt;    #location ~ /\.ht {&lt;/span&gt;
&lt;span class="x"&gt;    #    deny  all;&lt;/span&gt;
&lt;span class="x"&gt;    #}&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="nginx_1"&gt;Nginx的启动、停止、重启&lt;/h2&gt;
&lt;p&gt;一般可以用linux提供的systemctl或者service来启动，这部分内容请去查看相关的命令内容。&lt;/p&gt;
&lt;p&gt;重新编写或修改Nginx的配置文件后都需要做重新载入，使用&lt;code&gt;nginx -s reload&lt;/code&gt;来重新载入配置文件。&lt;/p&gt;
&lt;h2 id="_3"&gt;自定义错误页和访问设置&lt;/h2&gt;
&lt;p&gt;配置文件中&lt;code&gt;error_page&lt;/code&gt; 字段用来配置对应的错误页面。&lt;/p&gt;
&lt;p&gt;访问控制在&lt;code&gt;location&lt;/code&gt;字段进行配置，像是&lt;code&gt;deny&lt;/code&gt;，表示禁止访问，后续填写相关的IP；&lt;code&gt;allow&lt;/code&gt;表示允许访问，后续填写相关的IP。&lt;/p&gt;
&lt;h2 id="nginx_2"&gt;Nginx访问权限&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;deny all&lt;/code&gt;拒绝所有IP访问。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;location&lt;/code&gt;还可以对目录访问进行控制，直接在后面接上想要配置的目录即可：&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;  location =/img{&lt;/span&gt;
&lt;span class="x"&gt;        allow all;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    location =/admin{&lt;/span&gt;
&lt;span class="x"&gt;        deny all;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;还可以用正则表达式来配置。&lt;/p&gt;
&lt;h2 id="nginx_3"&gt;Nginx设置虚拟主机&lt;/h2&gt;
&lt;p&gt;这部分说实话挺简单的，就是写配置文件，实现挂载多个网站的功能，可以通过端口，IP和域名进行区分，其他的内容参考上面的配置文件配置相关的字段。&lt;/p&gt;
&lt;h2 id="nginx_4"&gt;Nginx反向代理&lt;/h2&gt;
&lt;p&gt;客户端发送的请求，想要访问server服务器上的内容。发送的内容被发送到代理服务器上，这个代理服务器再把请求发送到自己设置好的内部服务器上，而用户真实想获得的内容就在这些设置好的服务器上。&lt;/p&gt;
&lt;p&gt;反向代理的好处是，安全，遮蔽了服务器的准确位置，同时实现了负载均衡。&lt;/p&gt;
&lt;p&gt;实现的过程：还是设置&lt;code&gt;location&lt;/code&gt;字段：&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;server{
        listen 80;
        server_name nginx2.jspang.com;
        location / {
               proxy_pass http://jspang.com;#这个地方也可以是IP
        }
}
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_4"&gt;配置多平台设备&lt;/h2&gt;
&lt;p&gt;虽然有前端页面网格之类的自动适配多平台的相关内容，但是各自写一份比较好。&lt;/p&gt;
&lt;h2 id="gzip"&gt;配置Gzip压缩配置&lt;/h2&gt;
&lt;p&gt;Gzip把网页压缩，加速访问的时间。&lt;/p&gt;</content><category term="学习笔记"/><category term="Nginx"/><category term="原创"/></entry><entry><title>PHP的垃圾回收机制</title><link href="https://zhiyuansong.xyz/phpde-la-ji-hui-shou-ji-zhi.html" rel="alternate"/><published>2022-06-22T11:42:48+08:00</published><updated>2022-06-22T11:42:48+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-22:/phpde-la-ji-hui-shou-ji-zhi.html</id><summary type="html">&lt;p&gt;php的垃圾回收机制基于的是zval变量容器。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;一般情况&lt;/h2&gt;
&lt;p&gt;一个zval变量容器，除了包含变量的类型和值，还包含两个字节的额外信息，第一个是&lt;code&gt;is_ref&lt;/code&gt;，是个bool值，用来区分变量是否是属于 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;php的垃圾回收机制基于的是zval变量容器。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;一般情况&lt;/h2&gt;
&lt;p&gt;一个zval变量容器，除了包含变量的类型和值，还包含两个字节的额外信息，第一个是&lt;code&gt;is_ref&lt;/code&gt;，是个bool值，用来区分变量是否是属于引用类型；第二个是&lt;code&gt;refcount&lt;/code&gt;，表示指向这个zval变量容器的变量个数。&lt;/p&gt;
&lt;p&gt;当一个变量被赋常量值时，就会生成一个zval变量容器。例如&lt;code&gt;$a = "name";&lt;/code&gt;，生成的变量容器是包括了&lt;code&gt;type&lt;/code&gt;是string，&lt;code&gt;value&lt;/code&gt;是&amp;rdquo;name&amp;rdquo;，&lt;code&gt;is_ref&lt;/code&gt;是false，&lt;code&gt;refcount&lt;/code&gt;是1。&lt;/p&gt;
&lt;p&gt;简单地说，只要定义了，&lt;code&gt;refcount&lt;/code&gt;就是1，当使用unset()或者脚本结束，&lt;code&gt;refcount&lt;/code&gt;就会变成0，当该字段变成0的时候变量就会释放掉了。当出现&lt;code&gt;$b = $a&lt;/code&gt;的时候，&lt;code&gt;$a&lt;/code&gt;的&lt;code&gt;refcount&lt;/code&gt;字段加1。&lt;/p&gt;
&lt;h2 id="_2"&gt;复合类型&lt;/h2&gt;
&lt;p&gt;当遇到复合类型的变量，像是array和object类型，和标量有不同的地方，array和object类型的变量把它们的成员或属性存在自己的符号表中，也就是说本体创建一个容器，成员和属性也要依次创建容器。例如&lt;code&gt;$a = array( 'meaning' =&amp;gt; 'life', 'number' =&amp;gt; 42 );&lt;/code&gt;就会生成3个zval变量容器。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;refcount&lt;/code&gt;字段的变化参考标量类型的变量来做，数组元素存在共用一个容器字段&lt;code&gt;refcount&lt;/code&gt;的情况。&lt;/p&gt;
&lt;h2 id="_3"&gt;清理变量容器的问题&lt;/h2&gt;
&lt;p&gt;因为变量创建的时候会使&lt;code&gt;refcount&lt;/code&gt;字段不为0，只有使用&lt;code&gt;unset()&lt;/code&gt;和脚本结束的时候会销毁，所以当出现大量未销毁的变量时，要注意处理，释放掉。不然会占用大量内存。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="原创"/></entry><entry><title>PHP——PECL扩展库安装</title><link href="https://zhiyuansong.xyz/php-peclkuo-zhan-ku-an-zhuang.html" rel="alternate"/><published>2022-06-22T09:08:10+08:00</published><updated>2022-06-22T09:08:10+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-22:/php-peclkuo-zhan-ku-an-zhuang.html</id><summary type="html">&lt;p&gt;PHP扩展安装这部分参考的是PHP的文档部分内容，个人看来PHP的扩展相比其他有管理器的语言有点麻烦了，比较原始。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="windowsphp"&gt;Windows平台的php扩展安装&lt;/h2&gt;
&lt;p&gt;似乎是最简单的安装方式，因为Win平台的php扩展会在PECL上定期有编译好的dll文件可供下载，可以直接下载对应的文件，放入php目录下的ext目录中，然后在&lt;code&gt;php.ini&lt;/code&gt;中添加&lt;code&gt;extension = extname&lt;/code&gt;这 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;PHP扩展安装这部分参考的是PHP的文档部分内容，个人看来PHP的扩展相比其他有管理器的语言有点麻烦了，比较原始。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="windowsphp"&gt;Windows平台的php扩展安装&lt;/h2&gt;
&lt;p&gt;似乎是最简单的安装方式，因为Win平台的php扩展会在PECL上定期有编译好的dll文件可供下载，可以直接下载对应的文件，放入php目录下的ext目录中，然后在&lt;code&gt;php.ini&lt;/code&gt;中添加&lt;code&gt;extension = extname&lt;/code&gt;这样的内容来开启扩展。&lt;/p&gt;
&lt;h2 id="_1"&gt;其他的平台的扩展安装&lt;/h2&gt;
&lt;p&gt;类似上面的方法，linux平台获得对应的so文件，可能从pecl下载的扩展是源码形式，或者是其他来源的扩展，这样的话，就需要相关的编译工具来对源码进行编译了。但是这部分内容就不在此处阐述了，此处主要是对流程做一下简介，具体怎么做还需要自己下去再行研究。&lt;/p&gt;
&lt;h2 id="php"&gt;扩展库静态编译到PHP&lt;/h2&gt;
&lt;p&gt;大多数情况都是动态链接使用扩展的，静态地将扩展内容编译到PHP中，感觉不太常用。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel邮箱验证的一般步骤</title><link href="https://zhiyuansong.xyz/laravelyou-xiang-yan-zheng-de-yi-ban-bu-zou.html" rel="alternate"/><published>2022-06-21T10:01:24+08:00</published><updated>2022-06-21T10:01:24+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-21:/laravelyou-xiang-yan-zheng-de-yi-ban-bu-zou.html</id><summary type="html">&lt;p&gt;这部分内容主要是参考Laravel文档的内容进行的笔记记录，具体效果还没有使用过，如果之后有使用到，再进行一下记录。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="mustverifyemail"&gt;使用MustVerifyEmail接口&lt;/h2&gt;
&lt;p&gt;首先要在用户Model中引入&lt;code&gt;MustVerifyEmail&lt;/code&gt;这个接 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这部分内容主要是参考Laravel文档的内容进行的笔记记录，具体效果还没有使用过，如果之后有使用到，再进行一下记录。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="mustverifyemail"&gt;使用MustVerifyEmail接口&lt;/h2&gt;
&lt;p&gt;首先要在用户Model中引入&lt;code&gt;MustVerifyEmail&lt;/code&gt;这个接口：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;App\Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Illuminate\Contracts\Auth\MustVerifyEmail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Illuminate\Foundation\Auth\User&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Authenticatable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Illuminate\Notifications\Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Authenticatable&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;MustVerifyEmail&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_1"&gt;手动分发注册事件&lt;/h2&gt;
&lt;p&gt;在EventServiceProvider中的Registered事件中已经附加了SendEmailVerificationNotification监听器，在用户注册成功后需要手动分发&lt;code&gt;Illuminate\Auth\Events\Registered&lt;/code&gt;事件。&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;use Illuminate\Auth\Events\Registered;&lt;/span&gt;

&lt;span class="x"&gt;event(new Registered($user));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_2"&gt;数据库&lt;/h2&gt;
&lt;p&gt;需要在user包含email_verified_at字段，来记录邮箱通过验证的时间。&lt;/p&gt;
&lt;h2 id="_3"&gt;路由&lt;/h2&gt;
&lt;p&gt;需要三个路由，一个向用户发送要求验证邮件的通知，一个处理用户点击验证链接的请求，一个处理没接到邮件点击重发邮件的情况。&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;Route::get(&amp;#39;/email/verify&amp;#39;, function () {&lt;/span&gt;
&lt;span class="x"&gt;    return view(&amp;#39;auth.verify-email&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;})-&amp;gt;middleware(&amp;#39;auth&amp;#39;)-&amp;gt;name(&amp;#39;verification.notice&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;use Illuminate\Foundation\Auth\EmailVerificationRequest;&lt;/span&gt;

&lt;span class="x"&gt;Route::get(&amp;#39;/email/verify/{id}/{hash}&amp;#39;, function (EmailVerificationRequest $request) {&lt;/span&gt;
&lt;span class="x"&gt;    $request-&amp;gt;fulfill();&lt;/span&gt;

&lt;span class="x"&gt;    return redirect(&amp;#39;/home&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;})-&amp;gt;middleware([&amp;#39;auth&amp;#39;, &amp;#39;signed&amp;#39;])-&amp;gt;name(&amp;#39;verification.verify&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;use Illuminate\Http\Request;&lt;/span&gt;

&lt;span class="x"&gt;Route::post(&amp;#39;/email/verification-notification&amp;#39;, function (Request $request) {&lt;/span&gt;
&lt;span class="x"&gt;    $request-&amp;gt;user()-&amp;gt;sendEmailVerificationNotification();&lt;/span&gt;

&lt;span class="x"&gt;    return back()-&amp;gt;with(&amp;#39;message&amp;#39;, &amp;#39;Verification link sent!&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;})-&amp;gt;middleware([&amp;#39;auth&amp;#39;, &amp;#39;throttle:6,1&amp;#39;])-&amp;gt;name(&amp;#39;verification.send&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;verified中间件可以阻止未通过邮箱验证的用户进行访问，未通过验证的用户会被自动重定向到&lt;code&gt;verification.notice&lt;/code&gt;命名路由。&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;Route::get(&amp;#39;/profile&amp;#39;, function () {&lt;/span&gt;
&lt;span class="x"&gt;    // 只有经过验证的用户才能进入...&lt;/span&gt;
&lt;span class="x"&gt;})-&amp;gt;middleware(&amp;#39;verified&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_4"&gt;自定义邮箱和事件&lt;/h2&gt;
&lt;p&gt;&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;use Illuminate\Auth\Notifications\VerifyEmail;&lt;/span&gt;
&lt;span class="x"&gt;use Illuminate\Notifications\Messages\MailMessage;&lt;/span&gt;

&lt;span class="x"&gt;/**&lt;/span&gt;
&lt;span class="x"&gt; * 注册任何身份验证/授权服务&lt;/span&gt;
&lt;span class="x"&gt; *&lt;/span&gt;
&lt;span class="x"&gt; * @return void&lt;/span&gt;
&lt;span class="x"&gt; */&lt;/span&gt;
&lt;span class="x"&gt;public function boot()&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    // ...&lt;/span&gt;

&lt;span class="x"&gt;    VerifyEmail::toMailUsing(function ($notifiable, $url) {&lt;/span&gt;
&lt;span class="x"&gt;        return (new MailMessage)&lt;/span&gt;
&lt;span class="x"&gt;            -&amp;gt;subject(&amp;#39;Verify Email Address&amp;#39;)&lt;/span&gt;
&lt;span class="x"&gt;            -&amp;gt;line(&amp;#39;Click the button below to verify your email address.&amp;#39;)&lt;/span&gt;
&lt;span class="x"&gt;            -&amp;gt;action(&amp;#39;Verify Email Address&amp;#39;, $url);&lt;/span&gt;
&lt;span class="x"&gt;    });&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
自定义发送邮件的格式：把闭包函数发送给toMailUsing方法，闭包将接收可通知模型的实例，以及用户必须访问的包含签名的验证 URL。闭包将返回一个 &lt;code&gt;Illuminate\Notifications\Messages\MailMessage&lt;/code&gt;实例。通常您应该在应用中的&lt;code&gt;App\Providers\AuthServiceProvider&lt;/code&gt;类的&lt;code&gt;boot&lt;/code&gt;方法中调用&lt;code&gt;toMailUsing&lt;/code&gt;方法。&lt;/p&gt;
&lt;p&gt;事件想要接收并且进行手动处理的话，应该在EventServiceProvider中注册监听者。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/**
 * 应用程序的事件监听器
 *
 * @var array
 */
protected $listen = [
    &amp;#39;Illuminate\Auth\Events\Verified&amp;#39; =&amp;gt; [
        &amp;#39;App\Listeners\LogVerifiedUser&amp;#39;,
    ],
];
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="原创"/></entry><entry><title>视图</title><link href="https://zhiyuansong.xyz/shi-tu.html" rel="alternate"/><published>2022-06-17T17:13:59+08:00</published><updated>2022-06-17T17:13:59+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-17:/shi-tu.html</id><summary type="html">&lt;p&gt;blade.php&lt;/p&gt;
&lt;p&gt;用view操作。with添加属性。&lt;/p&gt;
&lt;p&gt;Laravel Mix 是一个拓展包，可以轻松编译和压缩应用程序中的CSS和JS文件，链式调用可以流畅定义资源管道。&lt;/p&gt;
&lt;p&gt;运行Mix，要确保安 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;blade.php&lt;/p&gt;
&lt;p&gt;用view操作。with添加属性。&lt;/p&gt;
&lt;p&gt;Laravel Mix 是一个拓展包，可以轻松编译和压缩应用程序中的CSS和JS文件，链式调用可以流畅定义资源管道。&lt;/p&gt;
&lt;p&gt;运行Mix，要确保安装Node,js和NPM&lt;/p&gt;
&lt;p&gt;安装Laravel Mix，可以找到package.json文件&lt;/p&gt;
&lt;p&gt;npm run dev&lt;/p&gt;
&lt;p&gt;npm run watch&lt;/p&gt;
&lt;p&gt;postCss 转换CSS&lt;/p&gt;
&lt;p&gt;通过NPM安装所需的配件，然后在调用Mix的postCSS方法的时候，把它添加到插件数组中,postCss方法的第一个参数是CSS文件的路径，第二个参数为编译后的文件的位置路径。&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>算法研究</title><link href="https://zhiyuansong.xyz/suan-fa-yan-jiu.html" rel="alternate"/><published>2022-06-17T15:45:05+08:00</published><updated>2022-06-17T15:45:05+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-17:/suan-fa-yan-jiu.html</id><summary type="html">&lt;h2 id="_1"&gt;冒泡排序&lt;/h2&gt;
&lt;p&gt;简单回忆一下，冒泡排序的时间复杂度是O(n^2),可以用泡泡从瓶底向上冒出的流程理解。&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function bubbleSort($array)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    //计算传入的数 …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</summary><content type="html">&lt;h2 id="_1"&gt;冒泡排序&lt;/h2&gt;
&lt;p&gt;简单回忆一下，冒泡排序的时间复杂度是O(n^2),可以用泡泡从瓶底向上冒出的流程理解。&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function bubbleSort($array)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    //计算传入的数组的长度&lt;/span&gt;
&lt;span class="x"&gt;    $length = count($array)&lt;/span&gt;
&lt;span class="x"&gt;    //每一次循环，都会把最大的数据冒出到队尾&lt;/span&gt;
&lt;span class="x"&gt;    for ($i = $length;$i &amp;gt; 0;$i--) {&lt;/span&gt;
&lt;span class="x"&gt;        $swape = true;&lt;/span&gt;
&lt;span class="x"&gt;        for ($j = 0; $j &amp;lt; $i - 1;$j++) {&lt;/span&gt;
&lt;span class="x"&gt;            //相邻的两个做比较，满足条件的话做交换&lt;/span&gt;
&lt;span class="x"&gt;            if ($array[$j]&amp;gt;$array[$j+1]){&lt;/span&gt;
&lt;span class="x"&gt;                $temp=$array[$j];&lt;/span&gt;
&lt;span class="x"&gt;                $array[$j]=$array[$j+1];&lt;/span&gt;
&lt;span class="x"&gt;                $array[$j+1]=$temp;&lt;/span&gt;
&lt;span class="x"&gt;                //当发生了交换，标记设为false&lt;/span&gt;
&lt;span class="x"&gt;                $swape=false;&lt;/span&gt;
&lt;span class="x"&gt;            }&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;        //当标记没有变化时，说明整个序列都有序了，结束循环，&lt;/span&gt;
&lt;span class="x"&gt;        if ($swape) {&lt;/span&gt;
&lt;span class="x"&gt;            break;&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $array;&lt;/span&gt;
&lt;span class="x"&gt;} &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;还有另一种：&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function bubbleSort(array $input)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    if(!isset($input))&lt;/span&gt;
&lt;span class="x"&gt;    {&lt;/span&gt;
&lt;span class="x"&gt;        return [];&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    do {&lt;/span&gt;
&lt;span class="x"&gt;        $swapped = false;&lt;/span&gt;

&lt;span class="x"&gt;        for($i = 0,$count = sizeof($input) - 1;$i &amp;lt; $count;$i++) {&lt;/span&gt;
&lt;span class="x"&gt;            //也是交换&lt;/span&gt;
&lt;span class="x"&gt;            if($input[$i + 1] &amp;lt; $input[$i]) {&lt;/span&gt;
&lt;span class="x"&gt;                list($input[$i + 1],$input[$i]) = [$input[$i],$input[$i + 1]];&lt;/span&gt;
&lt;span class="x"&gt;                $wrapped = true;&lt;/span&gt;
&lt;span class="x"&gt;            }&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    } while($swapped);&lt;/span&gt;

&lt;span class="x"&gt;    return $input;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id="_2"&gt;计数排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;//min和max是数组里的最小值和最大值&lt;/span&gt;
&lt;span class="x"&gt;function countSort($array,$min,$max)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $count = array();&lt;/span&gt;
&lt;span class="x"&gt;    //对count进行标记，对min和max之间的位置进行置0&lt;/span&gt;
&lt;span class="x"&gt;    for($i = $min;$i &amp;lt;= $max;$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        $count[$i] = 0;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    //读取数组，读取一遍，把对应数字下标的count加一&lt;/span&gt;
&lt;span class="x"&gt;    foreach($array as $number) {&lt;/span&gt;
&lt;span class="x"&gt;        $count[$number]++;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    //设置数组的访问下标为0，置0&lt;/span&gt;
&lt;span class="x"&gt;    $z = 0;&lt;/span&gt;
&lt;span class="x"&gt;    //遍历一遍count数组，遇见不为零的情况，则说明该处有数字，把下标存在array&lt;/span&gt;
&lt;span class="x"&gt;    for($i = $min;$i &amp;lt;= $max;$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        while($count[$i] &amp;gt; 0) {&lt;/span&gt;
&lt;span class="x"&gt;            $array[$z++] = $i;&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    //但这样好像把重复的数字抹掉了？&lt;/span&gt;
&lt;span class="x"&gt;    return $array;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_3"&gt;插入排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function insertionSort(array $array)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    for ($i = 1;$i &amp;lt; count($array);$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        $currentVal = $array[$i];&lt;/span&gt;
&lt;span class="x"&gt;        for ($j = $i - 1;$j &amp;gt;= 0&amp;amp;&amp;amp;$array[$j]&amp;gt;$currentVal;$j--) {&lt;/span&gt;
&lt;span class="x"&gt;            $array[$j+1] = $array[$j];&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;        $array[$j+1] = $currentVal;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $array;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_4"&gt;归并排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;//处理两个数组的合并&lt;/span&gt;
&lt;span class="x"&gt;function merge(array $arr1,array $arr2)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $result = [];&lt;/span&gt;
&lt;span class="x"&gt;    $i = 0;&lt;/span&gt;
&lt;span class="x"&gt;    $j = 0;&lt;/span&gt;
&lt;span class="x"&gt;    //用i，j来做arr的比较下标&lt;/span&gt;
&lt;span class="x"&gt;    while($i &amp;lt; count($arr1) &amp;amp;&amp;amp; j &amp;lt; count($arr2)) {&lt;/span&gt;
&lt;span class="x"&gt;        //小的入数组&lt;/span&gt;
&lt;span class="x"&gt;        if ($arr2[$j] &amp;gt; $arr1[$i]) {&lt;/span&gt;
&lt;span class="x"&gt;            $result[] = $arr1[$i];&lt;/span&gt;
&lt;span class="x"&gt;            $i++;&lt;/span&gt;
&lt;span class="x"&gt;        } else {&lt;/span&gt;
&lt;span class="x"&gt;            $result[] = $arr2[$j];&lt;/span&gt;
&lt;span class="x"&gt;            $j++;&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    //arr1还有数据，，不为空&lt;/span&gt;
&lt;span class="x"&gt;    while ($i &amp;lt; count($arr1)) {&lt;/span&gt;
&lt;span class="x"&gt;        $result[] = $arr1[$i];&lt;/span&gt;
&lt;span class="x"&gt;        $i++;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    //arr2还有数据，不为空&lt;/span&gt;
&lt;span class="x"&gt;    while ($j &amp;lt; count($arr2)) {&lt;/span&gt;
&lt;span class="x"&gt;        $result[] = $arr2[$j];&lt;/span&gt;
&lt;span class="x"&gt;        $j++;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $result;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;function mergeSort(array $arr)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    //当数组长度不大于1时，返回数组&lt;/span&gt;
&lt;span class="x"&gt;    if (count($arr) &amp;lt;= 1) {&lt;/span&gt;
&lt;span class="x"&gt;        return $arr;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    //取整&lt;/span&gt;
&lt;span class="x"&gt;    $mid = floor(count($arr)/2);&lt;/span&gt;
&lt;span class="x"&gt;    //还是接着切分数组&lt;/span&gt;
&lt;span class="x"&gt;    $left = mergeSort(array_slice($arr,0,$mid));&lt;/span&gt;
&lt;span class="x"&gt;    $right = mergeSort(array_slice($arr,$mid));&lt;/span&gt;

&lt;span class="x"&gt;    //两个参数都是数组&lt;/span&gt;
&lt;span class="x"&gt;    return merge($left,$right);&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_5"&gt;快速排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function quickSort(array $input)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    if (!isset($input)) {&lt;/span&gt;
&lt;span class="x"&gt;        return [];&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    $lt = [];&lt;/span&gt;
&lt;span class="x"&gt;    $gt = [];&lt;/span&gt;

&lt;span class="x"&gt;    if (sizeof($input) &amp;lt; 2) {&lt;/span&gt;
&lt;span class="x"&gt;        return $input;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    $key = key($input);&lt;/span&gt;
&lt;span class="x"&gt;    $shift = array_shift($input);&lt;/span&gt;

&lt;span class="x"&gt;    foreach($input as $value) {&lt;/span&gt;
&lt;span class="x"&gt;        $value &amp;lt;= $shift ? $lt[] = $value : $gt[] = $value;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;

&lt;span class="x"&gt;    return array_merge(quickSort($lt),[$key =&amp;gt; $shift],quickSort($gt));&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_6"&gt;基数排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function getDigit($num,$i)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    return floor(abs($num)/pow(10,$i)) % 10;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;function digitsCount($num)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    if ($num == 0) {&lt;/span&gt;
&lt;span class="x"&gt;        return 1;&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return floor(log10(abs($num)))+1;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;function maxDigits($arr)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $maxDigits = 0;&lt;/span&gt;
&lt;span class="x"&gt;    for ($i = 0;$i &amp;lt; count($arr);$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        $maxDigits = max($maxDigits,digitsCount($arr[$i]));&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $maxDigits;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;function radixSort($nums)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $maxDigitsCount = maxDigits($nums);&lt;/span&gt;
&lt;span class="x"&gt;    for ($k = 0;$k &amp;lt; $maxDigitsCount;$k++) {&lt;/span&gt;
&lt;span class="x"&gt;        $digitBucket = array_fill(0,10,[]);&lt;/span&gt;

&lt;span class="x"&gt;        for ($i = 0;$i &amp;lt; count($nums);$i++) {&lt;/span&gt;
&lt;span class="x"&gt;            $digitBucket[getDigit($nums[$i],$k)][] $nums[$i];&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;

&lt;span class="x"&gt;        $nums = concat($digitBucket);&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $nums;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;

&lt;span class="x"&gt;function concat(array $array)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $newArray = [];&lt;/span&gt;
&lt;span class="x"&gt;    for ($i = 0;$j &amp;lt; count($count[$i]);$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        for ($j = 0;$j &amp;lt; count($array[$i]);$j++) {&lt;/span&gt;
&lt;span class="x"&gt;            $newArray[] = $array[$i][$j];&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $newArray;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_7"&gt;选择排序&lt;/h2&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function selectionSorting($array)&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    $length = count($array);&lt;/span&gt;
&lt;span class="x"&gt;    for ($i = 0;$i &amp;lt; $length;$i++) {&lt;/span&gt;
&lt;span class="x"&gt;        $lowest = $i;&lt;/span&gt;
&lt;span class="x"&gt;        for ($j = $i + 1;$j &amp;lt; length;$j++) {&lt;/span&gt;
&lt;span class="x"&gt;            if ($array[$j] &amp;lt; $array[$lowest]) {&lt;/span&gt;
&lt;span class="x"&gt;                $lowest = $j;&lt;/span&gt;
&lt;span class="x"&gt;            }&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;        if ($i !== $lowest) {&lt;/span&gt;
&lt;span class="x"&gt;            $temp = $array[$i];&lt;/span&gt;
&lt;span class="x"&gt;            $array[$i] = $array[$lowest];&lt;/span&gt;
&lt;span class="x"&gt;            $array[$lowest] = $temp;&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;    return $array;&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="学习笔记"/></entry><entry><title>Laravel安全相关</title><link href="https://zhiyuansong.xyz/laravelan-quan-xiang-guan.html" rel="alternate"/><published>2022-06-17T10:47:00+08:00</published><updated>2022-06-17T10:47:00+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-17:/laravelan-quan-xiang-guan.html</id><summary type="html">&lt;h2 id="_1"&gt;用户认证&lt;/h2&gt;
&lt;p&gt;通过应用程序进行身份验证和登录的方法，在web应用程序中实现此功能自己写比较困难，Laravel提供了一套脚手架。&lt;/p&gt;
&lt;p&gt;Laravel的核心用户认证机制是由“看守器”和“提供器”，看守器定义如何对每个请求的用户进行 …&lt;/p&gt;</summary><content type="html">&lt;h2 id="_1"&gt;用户认证&lt;/h2&gt;
&lt;p&gt;通过应用程序进行身份验证和登录的方法，在web应用程序中实现此功能自己写比较困难，Laravel提供了一套脚手架。&lt;/p&gt;
&lt;p&gt;Laravel的核心用户认证机制是由“看守器”和“提供器”，看守器定义如何对每个请求的用户进行身份验证。提供器定义如何从持久存储中检索用户，Laravel支持使用Model和数据库查询生成器检索用户，还可以根据应用程序的需要自由定制其他提供程序.&lt;/p&gt;
&lt;p&gt;model目录中有user model，这个模型可以和Eloquent身份验证驱动程序一起使用，当输入用户名和密码且正确的时候，存入session中，cookie中存放了session id。&lt;/p&gt;
&lt;p&gt;脚手架配置还挺麻烦的，手动验证的流程。&lt;/p&gt;
&lt;p&gt;use Auth&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>php代码简洁之道</title><link href="https://zhiyuansong.xyz/phpdai-ma-jian-ji-zhi-dao.html" rel="alternate"/><published>2022-06-15T17:51:09+08:00</published><updated>2022-06-15T17:51:09+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-15:/phpdai-ma-jian-ji-zhi-dao.html</id><summary type="html">&lt;h2 id="_1"&gt;变量&lt;/h2&gt;
&lt;p&gt;使用有意义且可读的变量名&lt;/p&gt;
&lt;p&gt;对同一类型的变量使用相同的词汇&lt;/p&gt;
&lt;p&gt;使用可搜索的名称，例如数字，给它做成赋值形式，这 …&lt;/p&gt;</summary><content type="html">&lt;h2 id="_1"&gt;变量&lt;/h2&gt;
&lt;p&gt;使用有意义且可读的变量名&lt;/p&gt;
&lt;p&gt;对同一类型的变量使用相同的词汇&lt;/p&gt;
&lt;p&gt;使用可搜索的名称，例如数字，给它做成赋值形式，这样变量就能对数字含义做出说明。像是某些变量，也要显示出含义。&lt;/p&gt;
&lt;p&gt;避免嵌套太深，选择结构层数不要太多，不然会很难理解写的是什么。&lt;/p&gt;
&lt;p&gt;命名一定要尽量用显式命名。&lt;/p&gt;
&lt;p&gt;某些名字已经在上面用过了，那么有些地方就要注意不要再重复使用了。&lt;/p&gt;
&lt;p&gt;函数的参数要控制的尽量少，多的话，说明这个参数负责的东西太多了。&lt;/p&gt;
&lt;p&gt;函数的名字也要语义化。函数应该只是一个抽象级别&lt;/p&gt;
&lt;p&gt;不要使用标志作为函数的参数，标志告诉用户这个函数能干的事情不只一件，应该是一个函数负责一件事的&lt;/p&gt;
&lt;p&gt;避免副作用，尽量避免函数产生附加的功能，指的是返回一个值的情况下再去产生另一个功能，像是写入一个文件之类的。&lt;/p&gt;
&lt;p&gt;避免污染全局函数。&lt;/p&gt;
&lt;p&gt;不要使用单例。&lt;/p&gt;
&lt;p&gt;要避免类型检查&lt;/p&gt;
&lt;h2 id="_2"&gt;面向对象和数据结构&lt;/h2&gt;
&lt;p&gt;属性设成私有，写函数接口去操作属性来开放属性的操作。&lt;/p&gt;
&lt;p&gt;类的组合优于继承&lt;/p&gt;
&lt;p&gt;避免流畅的接口&lt;/p&gt;
&lt;h2 id="solid"&gt;SOLID设计原则&lt;/h2&gt;
&lt;p&gt;单一职责原则&lt;br /&gt;
开/关原则：扩展开放，修改关闭&lt;br /&gt;
里氏替换原则&lt;br /&gt;
接口隔离原则&lt;br /&gt;
依赖倒置原则&lt;/p&gt;
&lt;h2 id="dry"&gt;DRY 编程原则&lt;/h2&gt;
&lt;p&gt;避免重复代码&lt;/p&gt;
&lt;p&gt;MVC &lt;/p&gt;
&lt;p&gt;RESTFUL&lt;/p&gt;
&lt;p&gt;静态资源加载尽量用CDN&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>LaravelDatabase</title><link href="https://zhiyuansong.xyz/laraveldatabase.html" rel="alternate"/><published>2022-06-15T15:08:34+08:00</published><updated>2022-06-15T15:08:34+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-15:/laraveldatabase.html</id><summary type="html">&lt;h2 id="eloquent-model"&gt;Eloquent Model&lt;/h2&gt;
&lt;p&gt;定义关联：一个Model中定义一个关联函数，利用这个关联函数去操作另一个Model。&lt;/p&gt;
&lt;p&gt;父模型：模型关系中主动的一方&lt;/p&gt;
&lt;p&gt;子模型：模型关系中被动的一方 …&lt;/p&gt;</summary><content type="html">&lt;h2 id="eloquent-model"&gt;Eloquent Model&lt;/h2&gt;
&lt;p&gt;定义关联：一个Model中定义一个关联函数，利用这个关联函数去操作另一个Model。&lt;/p&gt;
&lt;p&gt;父模型：模型关系中主动的一方&lt;/p&gt;
&lt;p&gt;子模型：模型关系中被动的一方。&lt;/p&gt;
&lt;p&gt;正向定义中被关联的是子模型，反向关联中被关联的是父模型。&lt;/p&gt;
&lt;h2 id="_1"&gt;关联关系&lt;/h2&gt;
&lt;p&gt;一对一：&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;class User extends Model&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    /**&lt;/span&gt;
&lt;span class="x"&gt;     * 获得与用户关联的电话记录。&lt;/span&gt;
&lt;span class="x"&gt;     */&lt;/span&gt;
&lt;span class="x"&gt;    public function phone()&lt;/span&gt;
&lt;span class="x"&gt;    {&lt;/span&gt;
&lt;span class="x"&gt;        $this-&amp;gt;hasOne(&amp;#39;App\Phone&amp;#39;, &amp;#39;user_id&amp;#39;, &amp;#39;id&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
一对多：&lt;/p&gt;
&lt;p&gt;belongsTo：一对一，一对多，反向关联&lt;/p&gt;
&lt;p&gt;如果想从文章反向查找作者用户，可以定义反向关联。&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;public function user()&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    return $this-&amp;gt;belongsTo(&amp;#39;App\User&amp;#39;, &amp;#39;foreign_key&amp;#39;, &amp;#39;other_key&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;belongsMany 多对多&lt;br /&gt;
&lt;code&gt;`php
class User extends Model
{
    /**
     * 获得此用户的角色。
     */
    public function roles()
    {
        return $this-&amp;gt;belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
    }
}&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="laravel"&gt;Laravel 分页&lt;/h2&gt;
&lt;p&gt;laravel的分页用起来非常简单，只需要对query调用paginate函数，再把返回的对象扔给前端blade文件，在blade文件调用render函数或者link函数,就可以获得上一页、下一页的分页特效。&lt;/p&gt;
&lt;p&gt;可以直接把分页服务看作一个前端资源，render函数或者link函数的结果都是分页前端代码。&lt;/p&gt;
&lt;p&gt;paginationserviceprovider是负责注册和启动分页服务的服务提供者。&lt;/p&gt;
&lt;p&gt;获取分页前端代码、设置url地址和当前页数。&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>SQL索引的最左前缀匹配原则</title><link href="https://zhiyuansong.xyz/sqlsuo-yin-de-zui-zuo-qian-zhui-pi-pei-yuan-ze.html" rel="alternate"/><published>2022-06-06T14:30:19+08:00</published><updated>2022-06-06T14:30:19+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-06:/sqlsuo-yin-de-zui-zuo-qian-zhui-pi-pei-yuan-ze.html</id><summary type="html">&lt;p&gt;对索引的最左前缀匹配原则进行一下记录。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;这种情况出现在组合索引的情况，组合索引的字段排列需要考虑字段的排列 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;对索引的最左前缀匹配原则进行一下记录。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;这种情况出现在组合索引的情况，组合索引的字段排列需要考虑字段的排列顺序，靠前的字段可以被精确匹配的话，索引就可以被使用到。所以要考虑以下的情况。&lt;/p&gt;
&lt;p&gt;当按组合索引的所有字段进行查找的时候，查找字段的顺序会被SQL优化成充分利用索引的情况。&lt;/p&gt;
&lt;p&gt;当只用到了部分索引中的字段的时候，只能匹配到索引开头的字段，不是索引开头的字段就不能使用到索引了。&lt;/p&gt;
&lt;p&gt;所以组合索引的字段顺序创建时，要把最常使用的字段，或者说是字段去重个数最多的，放在最前面。&lt;/p&gt;</content><category term="学习笔记"/><category term="SQL"/><category term="原创"/></entry><entry><title>Laravel日志</title><link href="https://zhiyuansong.xyz/laravelri-zhi.html" rel="alternate"/><published>2022-06-02T15:13:40+08:00</published><updated>2022-06-02T15:13:40+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-06-02:/laravelri-zhi.html</id><summary type="html">&lt;p&gt;Laravel日志允许记录日志信息到文件，到系统错误日志。&lt;/p&gt;
&lt;p&gt;Laravel日志基于channel，每个channel代表一个具体的记录日志消息的方式，简单来说，single会把日志记录到单独的文件里，slack通道会发送日志信息到slack，基于重要程度，日志可能会写入到多个通道中。&lt;/p&gt;
&lt;p&gt;Monolog库，为各种强大的日志处理提供 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Laravel日志允许记录日志信息到文件，到系统错误日志。&lt;/p&gt;
&lt;p&gt;Laravel日志基于channel，每个channel代表一个具体的记录日志消息的方式，简单来说，single会把日志记录到单独的文件里，slack通道会发送日志信息到slack，基于重要程度，日志可能会写入到多个通道中。&lt;/p&gt;
&lt;p&gt;Monolog库，为各种强大的日志处理提供支持。允许以混合和匹配的方式，自定义程序日志管理。&lt;/p&gt;
&lt;p&gt;stack 该通道有助于创建多通道的包装器&lt;/p&gt;
&lt;p&gt;single 单个基于文件或路径的记录器通道（StreamHandler）&lt;/p&gt;
&lt;p&gt;daily 一个基于 RotatingFileHandler 的每日循环的Monolog驱动程序&lt;/p&gt;
&lt;p&gt;monolog 可以使用任何支持的Monolog处理程序的Monolog驱动程序&lt;/p&gt;
&lt;p&gt;syslog 基于SyslogHandler的Monolog驱动程序&lt;/p&gt;
&lt;p&gt;errorlog 基于ErrorLogHandler的Monolog驱动程序&lt;/p&gt;
&lt;p&gt;emergency alert critical error warning notice info debug&lt;br /&gt;
记录级别&lt;/p&gt;
&lt;p&gt;会根据使用的信息等级来返回到stack对应的信息等级的channel。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use Illuminate\Support\Facades\Log;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;可以将一组上下文数据传递给日志方法。此上下文数据将被格式化并与日志消息一起显示：&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use Illuminate\Support\Facades\Log;

Log::info(&amp;#39;User failed to login.&amp;#39;, [&amp;#39;id&amp;#39; =&amp;gt; $user-&amp;gt;id]);
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;写入特定频道使用channel，写入的内容是config/logging.php中的channel名字。&lt;/p&gt;
&lt;p&gt;还可以直接现成创建channel，使用build：&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use Illuminate\Support\Facades\Log;

Log::build([
  &amp;#39;driver&amp;#39; =&amp;gt; &amp;#39;single&amp;#39;,
  &amp;#39;path&amp;#39; =&amp;gt; storage_path(&amp;#39;logs/custom.log&amp;#39;),
])-&amp;gt;info(&amp;#39;Something happened!&amp;#39;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>Laravel服务提供者</title><link href="https://zhiyuansong.xyz/laravelfu-wu-ti-gong-zhe.html" rel="alternate"/><published>2022-05-31T18:04:47+08:00</published><updated>2022-05-31T18:04:47+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-05-31:/laravelfu-wu-ti-gong-zhe.html</id><summary type="html">&lt;p&gt;服务提供者是所有Laravel应用程序的引导中心，应用程序，以及通过服务器引导的Laravel核心服务都是通过服务提供器引导。&lt;br /&gt;
所谓的引导，实际上可以理解为注册服务容器绑定，事件监听器 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;服务提供者是所有Laravel应用程序的引导中心，应用程序，以及通过服务器引导的Laravel核心服务都是通过服务提供器引导。&lt;br /&gt;
所谓的引导，实际上可以理解为注册服务容器绑定，事件监听器，中间件，甚至是路由，服务提供者是配置应用程序的中心。&lt;/p&gt;
&lt;p&gt;providers数组是位于&lt;code&gt;config/app.php&lt;/code&gt;配置文件中，用来配置引入的服务提供者的类的。&lt;/p&gt;
&lt;p&gt;每一个服务提供者都会继承&lt;code&gt;Illuminate\Support\ServiceProvider&lt;/code&gt;类，大多数会提供一个register和一个boot方法。register方法是将服务绑定到服务容器的功能。&lt;/p&gt;
&lt;p&gt;使用Artisan命令行，通过make:provider生成一个新的提供者。&lt;/p&gt;
&lt;p&gt;在任何服务提供器方法中，总是通过$app属性来访问服务容器。&lt;/p&gt;
&lt;p&gt;关于服务容器的相关解释；是一个用于管理类依赖以及实现依赖注入的强有力工具，依赖注入指的是通过构造函数或者谋者情况下通过setter方法将类依赖“注入”到类中。&lt;/p&gt;
&lt;p&gt;什么叫自动和零配置依赖注入？&lt;/p&gt;
&lt;p&gt;直接用use引入，就可以使用了。为什么？是因为容器在后台管理吗？&lt;/p&gt;
&lt;p&gt;什么时候需要和容器手动打交道？&lt;/p&gt;
&lt;p&gt;如果编写了一个实现接口的类，并希望在路由或类的构造函数上键入该接口的提示，则必须告诉容器应该怎么解析该接口，其二是&lt;br /&gt;
如果编写的是一个Laravel包计划共享，那么可能需要将包的服务绑定到容器中。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use App\Services\Transistor;
use App\Services\PodcastParser;

//第一个参数是要绑定的类或接口名，第二个参数是一个返回类实例的闭包。
$this-&amp;gt;app-&amp;gt;bind(Transistor::class, function ($app) {
    return new Transistor($app-&amp;gt;make(PodcastParser::class));
});
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;单例的绑定，singleton方法将类或接口绑定到只应该解析一次的容器中，解析单例绑定后续调用容器时将返回相同的对象实例。&lt;/p&gt;
&lt;p&gt;scoped方法将一个类或接口绑定到容器中，该容器只应在给定的Laravel请求/作业生命周期内解析一次，和singleton的区别是当开始新的生命周期时，scope方法注册的实例将会刷新&lt;/p&gt;
&lt;p&gt;绑定接口到实现，第一个参数是接口，第二个参数是实现&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use App\Contracts\EventPusher;
use App\Services\RedisEventPusher;

$this-&amp;gt;app-&amp;gt;bind(EventPusher::class, RedisEventPusher::class);
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;服务提供者的延迟加载&lt;/p&gt;
&lt;p&gt;Facade为应用程序的服务容器中可用的类提供了静态代理，啥玩意？&lt;/p&gt;
&lt;p&gt;实际上就是加载的时候加载的是Facade/Cache，对应的内容是Illuminate\Contracts\Cache\Factory中的内容。也就是卓，facade对应使用的是服务容器中的方法。&lt;/p&gt;
&lt;p&gt;请求周期：&lt;/p&gt;
&lt;p&gt;开始的地方是&lt;code&gt;public/index.php&lt;/code&gt;，所有的请求都由web服务器配置定向到这个文件。之后根据进入应用的请求类型。选择传入的请求是进入Http内核还是Console内核。&lt;br /&gt;
Http内核定义了一个Http中间件列表，这些中间件处理读写Http会话，确定应用程序是否处于维护模式，校验CSRF令牌。Http内核接收Request接口并且返回Response接口。之后是加载服务提供者。&lt;/p&gt;
&lt;p&gt;RouteServiceProvider，返回响应，响应通过路由的中间件返回，从而使应用程序有机会修改或检查传出的响应，一旦响应通过中间件返回，http内核的handle方法将返回响应对象，并且index.php文件在返回的响应上调用send方法。send方法将响应内容发送到用户的web浏览器，至此已经完成了整个Laravel请求生命周期的过程。&lt;br /&gt;
服务提供者重要。&lt;/p&gt;</content><category term="学习笔记"/></entry><entry><title>Laravel源码阅读笔记（一）</title><link href="https://zhiyuansong.xyz/laravelyuan-ma-yue-du-bi-ji-yi.html" rel="alternate"/><published>2022-05-11T14:53:42+08:00</published><updated>2022-05-11T14:53:42+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-05-11:/laravelyuan-ma-yue-du-bi-ji-yi.html</id><summary type="html">&lt;p&gt;参考着Laravel的源码还有github上的源码解读来学习一下源码，提升一下。第一篇看config文件的加载。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;加载配置文件首先是查找配置文件的缓存是否存在，存在的话，就优先加载配置文件的缓 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;参考着Laravel的源码还有github上的源码解读来学习一下源码，提升一下。第一篇看config文件的加载。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;加载配置文件首先是查找配置文件的缓存是否存在，存在的话，就优先加载配置文件的缓存来起到更快的效果；不存在的话，就会遍历配置文件目录里面的所有配置文件来把所有配置信息加载进来，方便在程序的各个地方进行调用。&lt;/p&gt;
&lt;p&gt;加载配置文件有两部分：搜索配置文件，加载配置文件的数组变量值。&lt;/p&gt;
&lt;p&gt;getConfigurationFiles 可以根据配置文件目录搜索所有的 php 为后缀的文件，并将其转化为 files 数组，其 key 为目录名以字符 . 为连接的字符串 ，value 为文件真实路径。就是个数组。&lt;/p&gt;
&lt;p&gt;加载配置文件的数组。&lt;/p&gt;
&lt;p&gt;实际上加载数据就是加载进来的大数组，配置文件的获取和加载也类似，都是把字符串转换为多维数组来进行访问。&lt;/p&gt;
&lt;p&gt;加载配置文件的数值、&lt;/p&gt;
&lt;p&gt;PHP自动加载的功能&lt;/p&gt;
&lt;p&gt;这个功能出现之前：类的加载依靠&lt;code&gt;include/require&lt;/code&gt;，当项目变大时，维护类的加载语句变成了一件非常复杂的事情，经常可能会发生错误。而且require_once的代价不小。&lt;/p&gt;
&lt;p&gt;php5提出了autoload机制，使得程序在有可能使用类的时候才自动包含类文件。也叫延迟加载。&lt;/p&gt;
&lt;p&gt;有一个自己定义的&lt;code&gt;__autoload&lt;/code&gt;函数（有吗？我怎么没写过？）&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;function __autoload($classname) {&lt;/span&gt;
&lt;span class="x"&gt;   require_once ($classname . &amp;quot;.class.php&amp;quot;);&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;这个函数做了三件事，根据类名确定类文件名，确定类文件所在的磁盘路径，将类从磁盘文件中加载到系统中。&lt;/p&gt;
&lt;p&gt;主要是前两件事比较需要考虑一下，要确定一下类和实际的磁盘文件之间的映射关系。&lt;/p&gt;
&lt;p&gt;但是因为&lt;code&gt;__autoload&lt;/code&gt;是全局函数只能定义一次，如果要把所有的类和磁盘文件的映射关系都写进去，会十分的庞杂臃肿。解决的办法是使用一个__autoload调用堆栈，不同的映射关系写到不同的__autoload函数中，然后统一注册管理。所谓的SPL Autoload。&lt;/p&gt;
&lt;p&gt;PSR标准&lt;/p&gt;
&lt;p&gt;一个顶级命名空间，可以有多个子命名空间&lt;br /&gt;
分隔符的变化，命名空间有下划线的话直接映射成一层目录，PSR0解决了上面的问题，PSR4解决了映射层数过深的部分问题&lt;/p&gt;
&lt;p&gt;之所以没写过__autoload函数是因为composer帮你做了，它下载好了你要的版本的库代码，生成了映射函数，你做的就是用use引入而已。&lt;/p&gt;
&lt;p&gt;框架甚至把顶级域名映射也做了，直接用就好。&lt;/p&gt;
&lt;p&gt;Laravel框架下，composer的自动加载是怎么做道德&lt;/p&gt;
&lt;p&gt;入口的index.php第一句就是利用composer来实现自动加载功能&lt;/p&gt;
&lt;p&gt;database &lt;br /&gt;
eloquent model&lt;/p&gt;
&lt;p&gt;定义关联，在一个Model定义一个关联函数，利用关联函数来操作另一个Model,user表是用户表，posts是用户发的文章，用户可以发表多篇文章&lt;br /&gt;
$user-&amp;gt;posts()-&amp;gt;where(&amp;lsquo;active&amp;rsquo;,1)-&amp;gt;get()&lt;br /&gt;
用$user这个用户查询到active为1的所有的所有的文章，posts是关联函数，可以通过这个关联函数去操作另一个与user关联的表。&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel学习记录（九）</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-jiu.html" rel="alternate"/><published>2022-05-04T10:05:46+08:00</published><updated>2022-05-04T10:05:46+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-05-04:/laravelxue-xi-ji-lu-jiu.html</id><summary type="html">&lt;p&gt;登陆注册脚手架&lt;/p&gt;
&lt;p&gt;邮箱认证，第一步，注册成功会给用户发送一个认证邮件；第二步，用户登录状态下，如果邮箱未认证，重定向 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;登陆注册脚手架&lt;/p&gt;
&lt;p&gt;邮箱认证，第一步，注册成功会给用户发送一个认证邮件；第二步，用户登录状态下，如果邮箱未认证，重定向到提醒验证邮箱的页面中。&lt;/p&gt;
&lt;p&gt;中间件是什么，可以解决一部分登录判断相关的问题。&lt;/p&gt;
&lt;p&gt;控制器的构建函数使用了中间件，auth登录，verify和signed绑定&lt;/p&gt;
&lt;p&gt;trait是什么？&lt;/p&gt;
&lt;p&gt;用户认证成功触发了verified事件，&lt;/p&gt;
&lt;p&gt;会话是什么？&lt;/p&gt;
&lt;p&gt;找回密码&lt;/p&gt;
&lt;p&gt;资源控制器，资源路由&lt;/p&gt;
&lt;p&gt;路由对应控制器&lt;/p&gt;
&lt;p&gt;队列允许异步执行消耗时间的任务，比如请求一个API并等待返回的结果，这样就可以有效的降低请求响应的时间。因为API请求的时候可能会发生超时情况，如果发生了不可预知的错误，用户就不能发帖了。&lt;/p&gt;
&lt;p&gt;队列&lt;/p&gt;
&lt;p&gt;经典的MVC架构&lt;/p&gt;
&lt;p&gt;权限和角色&lt;/p&gt;
&lt;p&gt;游客、用户、管理员和站长&lt;/p&gt;
&lt;p&gt;laravel-permission用来扩展权限&lt;/p&gt;
&lt;p&gt;角色的模型表&lt;br /&gt;
权限的模型表&lt;br /&gt;
模型和角色的关联表，用户拥有什么角色在此表中定义，一个用户可以有多个角色&lt;br /&gt;
角色拥有的权限关联表，如管理员拥有查看后台的权限都是在这张表进行定义，一个角色可以拥有多个权限&lt;br /&gt;
模型和权限关联表，一个模型可以有多个权限&lt;/p&gt;
&lt;p&gt;用户只能通过角色来获取权限，用户不单独拥有权限&lt;/p&gt;
&lt;p&gt;权限名字的定义，建议用下划线分隔&lt;/p&gt;
&lt;p&gt;要想在过滤后的查询中进行多次查询，一般会使用query()方法，但是使用了操作之后，就会修改掉query的值，要想重复使用query，就要克隆这个query，用(clone query)来实现。&lt;/p&gt;
&lt;p&gt;检查日期有特定检查时间的where函数&lt;/p&gt;
&lt;p&gt;软删除可以用restore()恢复数据&lt;/p&gt;
&lt;p&gt;用all可以指定返回的列。在查找列的时候，可以用as返回具有不同名称的任何列。&lt;/p&gt;
&lt;p&gt;可以指定时间字段的名字。&lt;/p&gt;
&lt;p&gt;可以用latest和oldest来用时间来排序&lt;/p&gt;
&lt;p&gt;Carbon的now方法可以自动转换成日期无需转换成日期&lt;/p&gt;
&lt;p&gt;find()不止可以查询一条数据，传入多个ID的值会返回这些结果的集合。第二个参数可以指定只返回哪些字段&lt;/p&gt;
&lt;p&gt;数据库事务：&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;DB::transaction(function () {
    DB::table(&amp;#39;users&amp;#39;)-&amp;gt;update([&amp;#39;votes&amp;#39; =&amp;gt; 1]);

    DB::table(&amp;#39;posts&amp;#39;)-&amp;gt;delete();
});
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;如何判断表是空表，可以用exists和count来实现本地的，exists返回的是布尔值，count返回的是条目的数量。&lt;/p&gt;
&lt;p&gt;这个模型之间的对应关系是什么东西？&lt;/p&gt;
&lt;p&gt;Artisan 命令&lt;br /&gt;
confirm() 确认&lt;br /&gt;
perialipate() 预期输入&lt;br /&gt;
choice() 选择&lt;br /&gt;
从任意处启动脚本，使用Artisan::call()&lt;/p&gt;
&lt;p&gt;用Log::info&lt;br /&gt;
dd可以直接接在SQL的语句上面实现&lt;/p&gt;
&lt;p&gt;Log::withContext()将用来区分不同请求之间的日志消息&lt;/p&gt;
&lt;p&gt;路由&lt;/p&gt;
&lt;p&gt;分组中的分组&lt;br /&gt;
在路由中可以在分组中创建分组来实现为 夫分组中的某些路由分配中间件&lt;br /&gt;
快速从路由导航到控制器&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Route::get(&amp;#39;page&amp;#39;, [\App\Http\Controllers\PageController::class, &amp;#39;action&amp;#39;]);
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
这样的写法就可以实现到控制器的跳转，相比XXXconrtoller@xxx要长一点，要想要简洁一点可以引入控制器的类&lt;/p&gt;
&lt;p&gt;没有匹配到任何路由&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;// 一些其他的路由
Route::fallback(function() {
    return &amp;quot;出错了&amp;quot;;
});
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
throttle:60,1&lt;/p&gt;
&lt;p&gt;names 给路由命名&lt;/p&gt;
&lt;p&gt;资源型控制器&lt;/p&gt;
&lt;p&gt;php artisan make:controller PhotoController &amp;ndash;resource&lt;br /&gt;
可以生成资源型控制器，包括每个资源操作的方法。&lt;/p&gt;
&lt;p&gt;index路由，create路由，store路由，show路由，edit路由，update路由，destroy路由&lt;/p&gt;
&lt;p&gt;如果没找到隐式绑定的资源模型，则会生成状态码为404的http响应。&lt;/p&gt;
&lt;p&gt;资源型路由可以用only和except来指定动作的类型。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use App\Http\Controllers\PhotoController;

Route::resource(&amp;#39;photos&amp;#39;, PhotoController::class)-&amp;gt;only([
    &amp;#39;index&amp;#39;, &amp;#39;show&amp;#39;
]);

Route::resource(&amp;#39;photos&amp;#39;, PhotoController::class)-&amp;gt;except([
    &amp;#39;create&amp;#39;, &amp;#39;store&amp;#39;, &amp;#39;update&amp;#39;, &amp;#39;destroy&amp;#39;
]);
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
命名资源路由参数，默认情况下，资源路由会根据资源名称的单数形式创建资源路由的路由参数，可以使用parameters方法来覆盖资源路由名称，传入parameters方法应该是资源名称和参数名称的关联数组。&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Elasticsearch创建索引简单记录</title><link href="https://zhiyuansong.xyz/elasticsearchchuang-jian-suo-yin-jian-dan-ji-lu.html" rel="alternate"/><published>2022-04-28T17:18:34+08:00</published><updated>2022-04-28T17:18:34+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-28:/elasticsearchchuang-jian-suo-yin-jian-dan-ji-lu.html</id><summary type="html">&lt;p&gt;很神秘，我之前没有做过Elasticsearch相关的笔记吗？这次主要是对创建索引过程做下记录，也许以后会整理一份ES相关的内容。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;首先是之前并没有实际创建索 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;很神秘，我之前没有做过Elasticsearch相关的笔记吗？这次主要是对创建索引过程做下记录，也许以后会整理一份ES相关的内容。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;首先是之前并没有实际创建索引的经历，这次是第一次，基本上就是照抄模板，配置一下字段的名称和类型就完事了，有关数据同步的内容，自己并不是很清楚，因为这部分工作交给其他人做了，我做的内容主要是创建MySQL数据表在ElasticSearch中对应的索引，然后把整理的对应字段的映射表交给同步数据的人。下面列一份索引创建的json作为例子参考：&lt;br /&gt;
&lt;div class="highlight" data-language="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wb_cpc_sbv_search_keyword_repor&lt;/span&gt;&lt;span class="kc"&gt;t&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;settings&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;index.mapper.dynamic&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;number_of_shards&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;number_of_replicas&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;analysis&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;normalizer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;my_normalizer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;custom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;char_filter&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;filter&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lowercase&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;asciifolding&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;mappings&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;_doc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;dynamic&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;site&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;_site_account_type_id_search_item&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;search_item&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;target_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;match_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;keyword_text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;group_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;group_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;campaign_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;campaign_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;impressions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;clicks&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;cost&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;float&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;orders&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sales&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;float&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;viewable_impressions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_five_second_views&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_first_quartile_views&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_midpoint_views&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_third_quartile_views&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_complete_views&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;video_unmutes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;updated_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;deleted_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;可以看出来创建索引的内容主要分了两部分，第一部分是设置（settings），主要是配置索引，像是分片等的配置，但是这一部分我主要是按照模板来的，并没有做更改，不太懂。第二部分是映射（mappings），主要是配置字段的名称和数据类型，目前经常用到的数据类型有keyword（用在字符串），integer（用在整数），float（用在浮点数）和date（用在日期和时间）。&lt;/p&gt;
&lt;h2 id="_1"&gt;工作台数据逻辑&lt;/h2&gt;
&lt;p&gt;下面主要记一下当前工作台部分的数据逻辑，首先是以MySQL每日拉数据组成的数据中心以及其他几个数据渠道，大概是以MySQL做存储数据，然后ElasticSearch在其中扮演的角色是同步要使用的数据，大概也是存储的功能，之所以不直接从数据库取数据而是要加一层ES同步数据，目前我还不太懂，不过耳濡目染听到的ES大概是在数据的汇总和搜索方面很快，比较适合工作台的使用场景。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;我个人是不太适应ES这套逻辑的，用json嵌套命令的坏处就是我现在都记不住查找语句咋写来着……学吧老弟，学无止境~&lt;/p&gt;
&lt;h2 id="_3"&gt;助益的点&lt;/h2&gt;
&lt;p&gt;term查询和match查询区别是前者不做分词搜索&lt;br /&gt;
mapping的作用是定义索引中的字段的名称定义字段的数据类型，比如字符串、数字、布尔字段，倒排索引的相关配置，比如设置某个字段为不被索引、记录 position 等在 ES 早期版本，一个索引下是可以有多个 Type ，从 7.0 开始，一个索引只有一个 Type，也可以说一个 Type 有一个 Mapping 定义。&lt;br /&gt;
dynamic定义了这个文档能都被搜索。&lt;br /&gt;
嵌套类型是什么东西&lt;/p&gt;</content><category term="学习笔记"/><category term="Elasticsearch"/><category term="原创"/></entry><entry><title>Laravel学习记录（八）：集合、查询构造器和Model</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-ba-ji-he-cha-xun-gou-zao-qi-he-model.html" rel="alternate"/><published>2022-04-14T14:45:30+08:00</published><updated>2022-04-14T14:45:30+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-14:/laravelxue-xi-ji-lu-ba-ji-he-cha-xun-gou-zao-qi-he-model.html</id><summary type="html">&lt;p&gt;这篇主要是当时看集合和数据库操作方面的记录，内容很散，可能以后还得重写一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;集合&lt;/h2&gt;
&lt;p&gt;这个东西貌似是和数组有关系 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这篇主要是当时看集合和数据库操作方面的记录，内容很散，可能以后还得重写一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;集合&lt;/h2&gt;
&lt;p&gt;这个东西貌似是和数组有关系？&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$collection = collect([1, 2, 3]);
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;目前发现的是查询构造器返回的东西就是集合，查询构造器和ORM有的地方不一样，像是查询构造器更新单条数据只能用update，因为查询构造器没有fill()和save()这两个方法。集合是个对象，所以对于里面的字段元素可以用&lt;code&gt;-&amp;gt;&lt;/code&gt;来指出。&lt;/p&gt;
&lt;h2 id="dborm"&gt;DB，查询构造器，ORM&lt;/h2&gt;
&lt;p&gt;用DB facade可以直接运行原生的SQL语句，使用参数绑定可以有效地防止SQL注入。像是增删改查都有对应的方法，&lt;code&gt;statement()&lt;/code&gt;是没有返回值的，其他的大概都会返回受影响的行数。&lt;/p&gt;
&lt;p&gt;用DB的&lt;code&gt;connection()&lt;/code&gt;来执行数据库之间的切换，数据库的定义是在config/database.php里面。&lt;/p&gt;
&lt;p&gt;数据库的事务可以用transaction来实现，还有手动控制的手段。&lt;/p&gt;
&lt;p&gt;table方法，这东西就叫查询构造器？&lt;/p&gt;
&lt;p&gt;用value()可以获取单个值，用pluck()可以获取一列的值的集合，可以提供第二个参数来指定作为键的列。&lt;/p&gt;
&lt;p&gt;还有count()，max()，min()，avg()和sum()。&lt;/p&gt;
&lt;p&gt;exists()，doesntExist() 存在不存在&lt;/p&gt;
&lt;p&gt;原生SQL的使用务必谨慎，主要是存在SQL注入的可能。&lt;/p&gt;
&lt;p&gt;where()可以用like之类的作为条件。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;可以结合一下第二篇内容，里面有部分的Model相关内容，平时使用的时候用上DB也是可以的，当然能用Model最好。&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel待补充内容整理</title><link href="https://zhiyuansong.xyz/laraveldai-bu-chong-nei-rong-zheng-li.html" rel="alternate"/><published>2022-04-14T11:51:38+08:00</published><updated>2022-04-14T11:51:38+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-14:/laraveldai-bu-chong-nei-rong-zheng-li.html</id><summary type="html">&lt;p&gt;这篇东西主要是做一下Laravel待完成内容的相关记录。主要是暂时读不太懂的文档，可能以后慢慢补，等全部补完就可以删掉这一篇了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;会话&lt;/h2&gt;
&lt;p&gt;会话：可以 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这篇东西主要是做一下Laravel待完成内容的相关记录。主要是暂时读不太懂的文档，可能以后慢慢补，等全部补完就可以删掉这一篇了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;会话&lt;/h2&gt;
&lt;p&gt;会话：可以用来存储信息，因为http是没有状态的。&lt;br /&gt;
数据库做会话存储需要一张表。&lt;br /&gt;
闪存数据在时间到来后失效，flash()&lt;br /&gt;
flush()可以删除所有的会话数据。&lt;/p&gt;
&lt;p&gt;重新生成会话数据。没太看懂。&lt;/p&gt;
&lt;h2 id="_2"&gt;表单验证&lt;/h2&gt;
&lt;p&gt;首先定义路由。定义两个路由。一个GET展示一个供用户创建新博客文章的表单，POST将新的博客文章存放到数据库中。POST暂时留空。使用validate方法来验证。可以验证的内容，像是全景标题，内容之类的。验证内容是怎么做到的呢。规则是怎么定义的，对应的变量是什么。看不懂了&lt;/p&gt;
&lt;h2 id="_3"&gt;错误处理&lt;/h2&gt;
&lt;p&gt;日志，上下文，看不懂&lt;/p&gt;
&lt;h2 id="_4"&gt;日志&lt;/h2&gt;
&lt;p&gt;驱动程序(driver)：custom，daily，errorlog&lt;/p&gt;
&lt;h2 id="_5"&gt;缓存系统&lt;/h2&gt;
&lt;p&gt;也是要借用例如redis之类的东西，关系型数据库也可以。实际上的使用，也就是get,put,forget,has,pull(检索项目并删除),add（缓存存储中不存在的项目添加到缓存中）flush()直接把整个缓存清除。&lt;/p&gt;
&lt;p&gt;缓存的锁，自定义缓存驱动程序，注册驱动程序，看不懂&lt;/p&gt;
&lt;h2 id="urlurl"&gt;url()生成url&lt;/h2&gt;
&lt;p&gt;类似生成路径的&lt;code&gt;path()&lt;/code&gt;，同样在括号中填入路径，就可以拼接成一个完整的路径。&lt;/p&gt;
&lt;p&gt;生成url也可以用指定命名路由的&lt;code&gt;route()&lt;/code&gt;方法来生成。里面指定的变量可以通过数组赋值来确定。&lt;/p&gt;
&lt;p&gt;签名url：在查询字符串后附加了签名哈希，允许laravel验证url自创建以来未被修改过，对于可公开访问但要防止url操作的路由特别有用。&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel学习记录（七）：Command</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-qi-command.html" rel="alternate"/><published>2022-04-14T11:06:05+08:00</published><updated>2022-04-14T11:06:05+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-14:/laravelxue-xi-ji-lu-qi-command.html</id><summary type="html">&lt;p&gt;简单来说，Command命令文件写了已经不少了，从一开始写的拉取报表的触发器（Dispatcher），到监测报表拉取延迟，查找确实站点之类的脚本，都算是Laravel的自定义命令文件，就算抄我也有 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;简单来说，Command命令文件写了已经不少了，从一开始写的拉取报表的触发器（Dispatcher），到监测报表拉取延迟，查找确实站点之类的脚本，都算是Laravel的自定义命令文件，就算抄我也有一点点印象了，稍微总结一下这部分的内容，方便之后。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;简介&lt;/h2&gt;
&lt;p&gt;简单来说，自定义命令就是自定义Laravel的artisan命令，像是自带的创建类型文件的make之类的，我们做的就是自定义相关功能的命令，这样的命令文件也就能直接被artisan识别并且使用了。可是目前我对这种脚本的使用完全是手动调用，至于我写的东西怎么就在线上自动执行了呢？不清楚，之后看看。&lt;/p&gt;
&lt;h2 id="_2"&gt;构成的元素&lt;/h2&gt;
&lt;p&gt;首先一般这类自定义artisan的命令都在App/Console/Commands目录里面。当然Laravel不怎么限制文件出现的位置，写在其他地方似乎也没有影响，但是文件组织还是要有的。&lt;/p&gt;
&lt;p&gt;下面说的这些前提是要继承Command基类，不然基本上是空谈。&lt;/p&gt;
&lt;h3 id="signature"&gt;signature&lt;/h3&gt;
&lt;p&gt;这个protected元素定义了artisan元素的调用句柄，参数和选项之类的东西。类比到定义一个Linux命令切换目录，大概就是&lt;code&gt;cd {path}&lt;/code&gt;这种形式的东西（可能例子不太合适，稍微理解一下）。&lt;/p&gt;
&lt;h3 id="description"&gt;description&lt;/h3&gt;
&lt;p&gt;这个变量是用来对命令的作用进行说明的，在列出命令时搭配这个变量说明命令的作用。&lt;/p&gt;
&lt;h3 id="handle"&gt;handle()&lt;/h3&gt;
&lt;p&gt;这个方法是整个命令脚本的主方法，只要运行命令就一定会运行这个方法，感觉就是个很像C中&lt;code&gt;main()&lt;/code&gt;的东西。&lt;/p&gt;
&lt;h3 id="argumentoption"&gt;argument和option&lt;/h3&gt;
&lt;p&gt;这两个内容是在定义signature时候定义的东西，个人感觉这两个的区别不是很大，很多功能都是互通的，就是写法和获取内容的方法有一点不同。&lt;/p&gt;
&lt;p&gt;在signature中定义的写法是，argument用&lt;code&gt;{arg}&lt;/code&gt;的形式，option用&lt;code&gt;{--opt}&lt;/code&gt;的形式，后者比前者多了两个杠。&lt;/p&gt;
&lt;p&gt;参数后面带&lt;code&gt;?&lt;/code&gt;标识参数可选，也可以用等号来给参数添加默认值；而选项在不带值的情况下使用就是个判断true和false的标志，带上就是true，不带就是false，而带值选项的定义就是加个&lt;code&gt;=&lt;/code&gt;，这样的用法感觉和参数就差不多了，甚至也能在后面写默认值。用&lt;code&gt;|&lt;/code&gt;来标识选项的另一种写法，像是做个简写命令什么的。&lt;/p&gt;
&lt;p&gt;数组参数在参数后面带个&lt;code&gt;*&lt;/code&gt;，这样的话，就会把输入的多个参数值封装成数组参数，选项也可以使用&lt;code&gt;{--opt=*}&lt;/code&gt;来实现选项的多个输入。&lt;/p&gt;
&lt;p&gt;可以使用&lt;code&gt;$this-&amp;gt;argument('arg')&lt;/code&gt;、&lt;code&gt;$this-&amp;gt;arguments()&lt;/code&gt;来获取单个或者是全部参数，用&lt;code&gt;$this-&amp;gt;option('opt')&lt;/code&gt;、&lt;code&gt;$this-&amp;gt;options()&lt;/code&gt;来获取单个或是全部选项。&lt;/p&gt;
&lt;h2 id="_3"&gt;用编程方式执行命令&lt;/h2&gt;
&lt;p&gt;简单来说就是不用命令行而用程序调用命令。可以用Artisan下面的&lt;code&gt;call()&lt;/code&gt;方法来实现，第一个参数是命令的句柄，第二个参数是数组，传入对应的option或者argument。或者直接第一个参数一步到位。选项布尔类型的用&lt;code&gt;true&lt;/code&gt;或&lt;code&gt;false&lt;/code&gt;来实现。&lt;/p&gt;
&lt;p&gt;可以命令排队。前提需要配置好队列。&lt;/p&gt;
&lt;p&gt;从一个命令文件来调用另一个命令文件也可以用&lt;code&gt;call()&lt;/code&gt;方法，属于Command类。调用但禁止所有输出，可以使用&lt;code&gt;callSilenly()&lt;/code&gt;方法。&lt;/p&gt;
&lt;h2 id="_4"&gt;其他内容&lt;/h2&gt;
&lt;p&gt;php artisan make:command xxx 用来生成空白的命令脚本。&lt;/p&gt;
&lt;p&gt;选项可以简写，用&lt;code&gt;--Q|queue&lt;/code&gt;类似的结构实现，实际用的时候也是，改成一道杠就可以了。&lt;/p&gt;
&lt;p&gt;选项或参数的说明可以写在signature中。&lt;/p&gt;
&lt;p&gt;交互式输入，可以用&lt;code&gt;ask()&lt;/code&gt;来实现，&lt;code&gt;secret()&lt;/code&gt;实现的是内容不可见。&lt;code&gt;confirm()&lt;/code&gt;来实现用户的确认，用户用&lt;code&gt;y&lt;/code&gt;或者&lt;code&gt;yes&lt;/code&gt;来返回确认。&lt;code&gt;anticipate&lt;/code&gt;实现的是自动补全，可以在第二个参数写一个可能结果的数组，也可以写一个闭包函数，专门处理返回内容的相关功能。&lt;code&gt;choice()&lt;/code&gt;，预定义选择。最大的尝试次数，是否允许多次选择。&lt;/p&gt;
&lt;p&gt;控制台输出：line,info,comment,question,error,newLine(空白行)&lt;/p&gt;
&lt;p&gt;表格：table([title],[content])&lt;/p&gt;
&lt;p&gt;进度条：&lt;code&gt;withProgressBar(all,item)&lt;/code&gt;，还可以设置推进进度条：&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$users = App\Models\User::all();

$bar = $this-&amp;gt;output-&amp;gt;createProgressBar(count($users));

$bar-&amp;gt;start();

foreach ($users as $user) {
    $this-&amp;gt;performTask($user);

    $bar-&amp;gt;advance();
}

$bar-&amp;gt;finish();
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;确定步数，start-&amp;gt;advance-&amp;gt;finish。&lt;/p&gt;
&lt;p&gt;注册命令是在&lt;code&gt;App\Console\Kernel&lt;/code&gt;类中注册的，只有经过这一步，系统才能检索到添加的命令脚本。简单来说就是在&lt;code&gt;commands&lt;/code&gt;方法里面，用&lt;code&gt;load&lt;/code&gt;方法读取对应脚本所在的目录，理论上只要读到，就可以搜索到命令脚本完成注册。&lt;/p&gt;
&lt;h2 id="_5"&gt;结尾&lt;/h2&gt;
&lt;p&gt;暂时写到这里，可能写的并不详细，只起到了知道有这么个东西的作用，具体用到的时候还是需要去看一下文档。&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>年后到4月中旬做的工作</title><link href="https://zhiyuansong.xyz/nian-hou-dao-4yue-zhong-xun-zuo-de-gong-zuo.html" rel="alternate"/><published>2022-04-13T16:40:09+08:00</published><updated>2022-04-13T16:40:09+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-13:/nian-hou-dao-4yue-zhong-xun-zuo-de-gong-zuo.html</id><summary type="html">&lt;p&gt;年后到现在好像一直在做这一个需求，感觉自己好像写过一点相关的内容……没写的话当我是在做梦。感觉已经变成无情的 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;年后到现在好像一直在做这一个需求，感觉自己好像写过一点相关的内容……没写的话当我是在做梦。感觉已经变成无情的数据搬运工了，每天就是在写数据脚本，建表格拉数据……还是得偷学点能当饭吃的技术，感觉现在干的活找个人来干几个月也就会了。🤔&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;拉取退款数据&lt;/h2&gt;
&lt;p&gt;简单来说就是，通过接口请求数据，再把数据结构整理好，存到对应的表结构里，我每天干的事情无非是这些。需要掌握一些像是字符串处理，字符串和数组互转，还有就是特殊格式的数据处理函数，像是json和XML类型的数据。财务数据这里遇到的难点主要是，首先数据类型很多，整理起来很困难，尤其是完整的数据结构，手动拉了很多数据才基本整理出来，最后主要用到的部分存到了数据库，剩下的部分直接存到了MongoDB里面；其次是数据搞清楚是按照区域还是站点拉取，是我做的少，花了不少时间去解决按照站点拉取结果产生的大量重复数据，还有站点确定的问题要解决，所幸还有一个网址可以用来确定站点；最后是，数据没有能确定的唯一键，最后只能采用直接插入的办法来解决这个问题，要考虑的点，像是每次拉取的时间怎么确定，怎么解决上一次拉取结束时数据的完整性问题等等。不过这些问题解决起来的具体实现其实难度还可以。&lt;/p&gt;
&lt;p&gt;之后又做了把所有的财务数据存储到MongoDB的工作，这期间也是学习了相关环境的配置，MongoDB的使用是要比关系型数据库简单的，不用确定固定的数据表结构，每个文档就像组装数组一样组装好然后扔到一张表里就搞定任务了，上面说退款数据确定数据结构花了很长时间，这全部财务数据因为暂时用不上，就直接扔到了MongoDB里。&lt;/p&gt;
&lt;p&gt;期间，出现了一个问题，当请求传递的速度太快时，服务器会返回429错误，需要降下来请求的频率，目前的解决办法也只有用&lt;code&gt;sleep()&lt;/code&gt;和&lt;code&gt;usleep()&lt;/code&gt;两个函数进行代码的延迟执行，来尽可能避免这种情况的出现。再就是尽量把请求时间片缩小一些，让请求下来完整时间片的数据的可能提高，尽量减少下次插入数据时对数据的删除量，不然删除一个大时间片中的不完整数据浪费的时间和硬件资源还是挺多的。&lt;/p&gt;
&lt;h2 id="_2"&gt;拉取退货数据&lt;/h2&gt;
&lt;p&gt;其实这个逻辑倒是比上面那个简单，唯一的问题是退货数据的接口，稳定性相当差，只要请求的时间长一些，请求的频率高一点，接口基本就会爆炸，没数据，导致每次调试代码，都是一种折磨，巧妇难为无米之炊了属于是。退货数据的唯一键存在，所以可以更新数据，感觉逻辑倒是很简单，但是，FBA数据也是按照区域来拉取的，而且确定站点的数据不像退款数据还有个网址可以利用，最后的解法是根据订单号去订单表里查找对应记录的站点……当然一开始按站点拉的，最后改成按区域拉，那时心态相当炸裂。&lt;/p&gt;
&lt;h2 id="_3"&gt;数据分表&lt;/h2&gt;
&lt;p&gt;我一开始以为数据库分表可以用数据库的机制来做，像是一张表数据大的负担很重，就可以像winrar给压缩包分卷那样给表也做数据切分，然后分表之间自动就有联系……但是结果分表只能用程序自己做，一开始挺麻的，主要没做过，就只知道按时间分表，然后是退款和退货的入库逻辑还不一样，导致得写两套逻辑，而且表的更新、插入也要考虑到问题很多。写到最后，感觉死循环条件跳出这种东西最好少写，因为我好几次都是没考虑到额外的跳出条件，结果还得费老大劲去处理相关的错误数据……&lt;/p&gt;
&lt;p&gt;反正这块不简单，以后做都得注意一点，时间是一个比较重要的区分指标。&lt;/p&gt;
&lt;h2 id="_4"&gt;部署&lt;/h2&gt;
&lt;p&gt;这块内容主要是脚本部署，要配置一些环境，像是线上环境建表的SQL审核，定时脚本用cron解决，还有守护进程的使用之类的。线上跑的定时自动启动脚本用的就是守护进程。一些工具类脚本用的是cron，第一次接触倒是很新鲜。&lt;/p&gt;
&lt;h2 id="_5"&gt;总结&lt;/h2&gt;
&lt;p&gt;感觉很难的东西写成文字竟然只有这么一点……还是得继续积累。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>Laravel学习记录（六）：Blade模板</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-liu-blademo-ban.html" rel="alternate"/><published>2022-04-02T15:15:53+08:00</published><updated>2022-04-02T15:15:53+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-02:/laravelxue-xi-ji-lu-liu-blademo-ban.html</id><summary type="html">&lt;p&gt;简单来说，Laravel的Blade前端模板是一种前端页面的写法，像是模板可以继承，一定程度上使用PHP代码等。说实话我对前端不太懂，基本上写不出来什么漂亮的页面，看来以后还 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;简单来说，Laravel的Blade前端模板是一种前端页面的写法，像是模板可以继承，一定程度上使用PHP代码等。说实话我对前端不太懂，基本上写不出来什么漂亮的页面，看来以后还是得学习学习相关的知识。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;返回页面&lt;/h2&gt;
&lt;p&gt;使用全局函数&lt;code&gt;view()&lt;/code&gt;可以在路由和控制器中返回页面，第二个参数可以向视图中返回参数，用的是一个数组。而在视图中使用双层大括号套上PHP变量就可以让传入的变量获得解析显示。当然这种情况下的内容会被&lt;code&gt;htmlspecialchars()&lt;/code&gt;自动转义以防止XSS攻击，要想直接显示未处理的内容，举个例子：我想直接把返回的网页html内容打到页面上，这个时候的Blade页面就只是当一个空白容器的作用，如果转义了原始内容是显示不出来的，所以可以直接使用&lt;code&gt;{!! $value !!}&lt;/code&gt;来把原始的内容显示出来。&lt;/p&gt;
&lt;p&gt;有些js框架也用到了花括号，这种情况下的可以在括号前面加上&lt;code&gt;@&lt;/code&gt;来保证Blade引擎不会对相关的内容做修改。还有类似逻辑语法之类的，像是&lt;code&gt;@if&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="blade"&gt;Blade指令&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@auth&lt;/code&gt;，&lt;code&gt;@endauth&lt;/code&gt;，&lt;code&gt;@guest&lt;/code&gt;，&lt;code&gt;@endguest&lt;/code&gt;，&lt;code&gt;@production&lt;/code&gt;，&lt;code&gt;@env&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="_2"&gt;视图包含&lt;/h2&gt;
&lt;p&gt;使用&lt;code&gt;@include&lt;/code&gt;可以包含其他视图。&lt;code&gt;@includeWhen&lt;/code&gt;，&lt;code&gt;@includeUnless&lt;/code&gt;&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@includeWhen($boolean, &amp;#39;view.name&amp;#39;, [&amp;#39;status&amp;#39; =&amp;gt; &amp;#39;complete&amp;#39;])

@includeUnless($boolean, &amp;#39;view.name&amp;#39;, [&amp;#39;status&amp;#39; =&amp;gt; &amp;#39;complete&amp;#39;])
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>初步了解graphQL（二）</title><link href="https://zhiyuansong.xyz/chu-bu-liao-jie-graphqler.html" rel="alternate"/><published>2022-04-01T09:25:29+08:00</published><updated>2022-04-01T09:25:29+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-04-01:/chu-bu-liao-jie-graphqler.html</id><summary type="html">&lt;p&gt;上一篇大概只写了最简单的一部分，像是请求结构什么的，这一篇继续写一点相关的东西。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;个人感觉，这套规范如果是从头 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;上一篇大概只写了最简单的一部分，像是请求结构什么的，这一篇继续写一点相关的东西。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;个人感觉，这套规范如果是从头开始使用的话倒还是很好的，相比 REST 请求有很多好处。但是对于不少后端结构已经很成熟的企业，改造过程可能就比较难了——可以说是前端爽了，后端苦了。因为后端要提前为前端把数据格式之类的都配置好，工作量其实不小。&lt;/p&gt;
&lt;p&gt;基本上就是，后端会预先把可能请求的数据结构描述出来，前端访问的时候无非是字段之间的拼接组合，按照自己的需求返回即可。&lt;/p&gt;
&lt;h2 id="schema-language"&gt;类型语言 Schema Language&lt;/h2&gt;
&lt;div class="highlight" data-language="graphql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;appearsIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Episode&lt;/span&gt;&lt;span class="err"&gt;!]!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;感觉有点像 golang 的结构体——先写字段名称，再写字段类型。类型名后加 &lt;code&gt;!&lt;/code&gt; 表示字段非空，用中括号 &lt;code&gt;[]&lt;/code&gt; 表示数组。&lt;/p&gt;
&lt;p&gt;字段也可以带参数：&lt;/p&gt;
&lt;div class="highlight" data-language="graphql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Starship&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;LengthUnit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;METER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="query-mutation"&gt;查询与变更类型（Query / Mutation）&lt;/h2&gt;
&lt;p&gt;GraphQL 中有一些预定义的标量类型，比如 &lt;code&gt;Int&lt;/code&gt;、&lt;code&gt;String&lt;/code&gt;、&lt;code&gt;Float&lt;/code&gt;、&lt;code&gt;Boolean&lt;/code&gt;、&lt;code&gt;ID&lt;/code&gt; 等，也可以自己定义字段类型。&lt;/p&gt;
&lt;p&gt;简单来说，数据的流向是：首先同步到数据库，然后数据库内容同步到 Elasticsearch，之后 GraphQL 会对每个字段进行解析，主要是解析字段的名称和类型。&lt;/p&gt;
&lt;h2 id="_1"&gt;请求方式&lt;/h2&gt;
&lt;p&gt;大致的访问方式和 REST 差不多，但 GraphQL 似乎只有读（query）和写（mutation）两种操作。向 URL 传入的请求就是一个字符串，用大括号之类的符号进行分隔。&lt;/p&gt;
&lt;p&gt;片段的自身引用是不可以的，会造成结果无边界。&lt;/p&gt;
&lt;p&gt;查询字段只能查询类型上已定义的字段，否则会报错。&lt;/p&gt;
&lt;p&gt;如果返回的类型不是标量或枚举类型，也就是说是一个对象，那么需要指明具体需要的字段——返回一个整体的话，必须列出所有字段，不能只返回对象本身。（前端一定要知道自己需要哪些字段，后端一定要提前按需求配好，不存在&amp;rdquo;不确定&amp;rdquo;的情况。）&lt;/p&gt;
&lt;p&gt;如果一个字段是标量，那么它内部就不会再有字段，这种情况下用括号去请求也没有作用。&lt;/p&gt;
&lt;h2 id="fragment"&gt;条件片段（Fragment）&lt;/h2&gt;
&lt;p&gt;在请求中实现可选字段，可以用带成立条件的片段：&lt;/p&gt;
&lt;div class="highlight" data-language="graphql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="err"&gt;hero&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="n"&gt;DroidFields&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fragment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DroidFields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Droid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;primaryFunction&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;上面的片段只有在 &lt;code&gt;Character&lt;/code&gt; 为 &lt;code&gt;Droid&lt;/code&gt; 的时候才会在请求中成立，其他情况下是隐藏的。&lt;/p&gt;
&lt;p&gt;不过这样使用具名字段有些浪费，不如直接使用内联片段：&lt;/p&gt;
&lt;div class="highlight" data-language="graphql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="err"&gt;hero&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Droid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;primaryFunction&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这样只使用一次，避免浪费。&lt;/p&gt;
&lt;h2 id="_2"&gt;字段执行与解析&lt;/h2&gt;
&lt;p&gt;字段执行 → 相应的 resolver 被调用产生一个值。&lt;/p&gt;
&lt;p&gt;如果字段产生的是标量值，执行完成；如果字段产生的是对象，则查询会继续执行该对象对应字段的解析器，直到生成标量值为止。&lt;/p&gt;
&lt;h2 id="introspection"&gt;内省系统（Introspection）&lt;/h2&gt;
&lt;p&gt;可以通过内省系统来查询支持哪些查询。这样一来，即使不是自己写的 schema，也能知道它支持哪些查询：&lt;/p&gt;
&lt;div class="highlight" data-language="graphql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;__schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 查询开始的地方&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;__schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queryType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 查询特定的类型&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;__schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queryType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 查询类型的文档&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;__type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Droid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_3"&gt;其他要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GraphQL 通过单一入口提供完整的 HTTP 服务功能，和 REST API 的多端点不同。&lt;/li&gt;
&lt;li&gt;JSON 用 GZIP 压缩后表现非常好。&lt;/li&gt;
&lt;li&gt;默认每个字段都可以为 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;服务器端可以做批处理（batching）和缓存。&lt;/li&gt;
&lt;li&gt;本质上就是一个图（Graph）结构。&lt;/li&gt;
&lt;li&gt;不要尝试一次性把整个模型都建立出来，应该在测试中逐渐扩展。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="graphiql-rest-api"&gt;GraphiQL 与 REST API&lt;/h2&gt;
&lt;p&gt;GraphiQL 是用来传递请求并且返回结果到页面上的一个组合工具，但一般只在调试和开发过程中使用，生产环境下默认被禁用。&lt;/p&gt;</content><category term="学习笔记"/><category term="graphQL"/><category term="API"/><category term="原创"/></entry><entry><title>过年后至今做的工作总结</title><link href="https://zhiyuansong.xyz/guo-nian-hou-zhi-jin-zuo-de-gong-zuo-zong-jie.html" rel="alternate"/><published>2022-03-21T15:39:05+08:00</published><updated>2022-03-21T15:39:05+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-03-21:/guo-nian-hou-zhi-jin-zuo-de-gong-zuo-zong-jie.html</id><summary type="html">&lt;p&gt;我记得年前的时候自己在大看特看Golang和Docker，然后年后活来了，东西全鸽了……现在感觉东西至少做的七七八八了，可以写点东西总 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我记得年前的时候自己在大看特看Golang和Docker，然后年后活来了，东西全鸽了……现在感觉东西至少做的七七八八了，可以写点东西总结一下。&lt;/p&gt;
&lt;p&gt;但其实也只做了两个东西，惭愧，惭愧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;退款分析的数据端&lt;/h2&gt;
&lt;p&gt;这个需求最简单的理解就是从接口拉数据，然后整理好放到数据表里，其实表面上看逻辑倒不是太难，主要难在处理的过程上了。像是有些情况下的数据格式处理，有的是xml格式的，有的是直接用特定标识符，像是&lt;code&gt;\n&lt;/code&gt;,&lt;code&gt;\t&lt;/code&gt;之类的做分隔，然后处理的时候就需要做一下相关的内容。&lt;br /&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;        $line = strtok($reportResult, PHP_EOL);&lt;/span&gt;
&lt;span class="x"&gt;        $headers = preg_split(&amp;#39;/\t/&amp;#39;, $line);&lt;/span&gt;
&lt;span class="x"&gt;        $n = 0;&lt;/span&gt;
&lt;span class="x"&gt;        $fbaReturns = [];&lt;/span&gt;
&lt;span class="x"&gt;        $groupsKey = [];&lt;/span&gt;
&lt;span class="x"&gt;        while ($line != false) {&lt;/span&gt;
&lt;span class="x"&gt;            $line = strtok(PHP_EOL);&lt;/span&gt;
&lt;span class="x"&gt;            $row = preg_split(&amp;#39;/\t/&amp;#39;, $line);&lt;/span&gt;
&lt;span class="x"&gt;            if (empty($row[2])) {&lt;/span&gt;
&lt;span class="x"&gt;                continue;&lt;/span&gt;
&lt;span class="x"&gt;            }&lt;/span&gt;
&lt;span class="x"&gt;            $list = array_combine($headers, $row);&lt;/span&gt;
&lt;span class="x"&gt;            //对list进行处理……&lt;/span&gt;
&lt;span class="x"&gt;        }&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
这段代码是当时一部分退货原始数据处理的函数。大概是根据&lt;code&gt;\n&lt;/code&gt;来区分每行，&lt;code&gt;\t&lt;/code&gt;来区分字段，用&lt;code&gt;array_combine()&lt;/code&gt;来做键值匹配。&lt;/p&gt;
&lt;p&gt;&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;    $xmlData = simplexml_load_string($reportResult);&lt;/span&gt;
&lt;span class="x"&gt;    $contentArray = json_decode(json_encode($xmlData), true);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
这段代码是时处理原始数据格式是xml类型的数据函数，通过这样就可以将xml类型的数据转化成PHP数组。&lt;/p&gt;
&lt;p&gt;然后就是数据入库的处理，拼装数据，在入库前做关键值查找，有相同的记录做更新然后释放掉，如果最后没有释放完，就说明有新数据，做批量插入就行。（其实这块一开始写的挺恶心的，为啥laravel不提供一个批量插入/更新的方法……&lt;code&gt;updateOrCreate&lt;/code&gt;终究只能一个个访问，好慢。）&lt;/p&gt;
&lt;p&gt;当然我处理的部分数据，还挺恶心的，没有关键值，也就是说，什么账号站点之类平常用来区分数据的字段的都一样，但是数值不一样，还好不用做更新，数据也是死的，最后就采取增量插入的方法，直接读上次插入数据的最后日期，从那个时候开始继续拉就好，当然，遇到了上次的结尾和这次的开头一样的这种情况，主要是时间点重合了，这样的话，我尝试的是在插入这次的数据前把上次的结尾部分数据删掉，这样的话，这次的数据里有上次结尾的数据，不会漏数据，也不会有重复数据。&lt;/p&gt;
&lt;p&gt;然后比较难的地方个人感觉是做数据库分表……我一开始以为分表是后边运维做的，他们可以把大表切割成小表，就像winrar压缩包的时候可以手动分卷……然而想的有点天真，实际情况是写程序去选择分表，然后就可能会出现各种各样的问题，像是数据更新和插入选择分表的问题之类的，有点难。&lt;/p&gt;
&lt;p&gt;一开始我想的是，表的数目不确定，那么就做个死循环，从某个时间点去找表里数据的最后时间之类的，从而确定哪一张是插入数据的表，结果在调试过程中频繁进入死循环……防不胜防，身心俱疲。最后的解决方法是，确定一个时间为起始点，当前时间为结束点，这样就可以保证这个时间范围内的分表都是存在的，然后寻找每张表里的最晚数据，以此来确定最晚数据存在的表，最晚数据的时间就可以确定插入数据的分表。&lt;/p&gt;
&lt;p&gt;再就是存在更新情况的数据分表的问题，一开始也是纠结于更新和插入内容位于两张表的情况，最后想到的解决办法是，直接把数据在组装过程中就按时间分好组，这样的话，可以保证这个时间的数据一定就在这个时间对应的分表中，就不存在这个时间的数据插入到哪一个时间对应的分表中了。&lt;/p&gt;
&lt;p&gt;差不多就是这些东西，其他的，我还研究了一下把时间按月切分之类的函数，结果到最后用不上了……（因为数据组装部分处理了）只能说一开始想的方案到最后不一定能用上。&lt;/p&gt;
&lt;h2 id="_2"&gt;通知任务推送脚本&lt;/h2&gt;
&lt;p&gt;这个简单来说也倒是不难，就是第一步推任务参数去一个系统，第二步处理这个系统后续返回的数据，加工完放到数据库中。其他的内容倒是不怎么见过了。&lt;/p&gt;
&lt;p&gt;主要难的地方是，后面增加的需求，让把返回的body内容也保存下来，然后显示在界面上，当成网页展示。&lt;/p&gt;
&lt;p&gt;简单来说上面那个系统就是个爬虫，它把获得的网页内容保存成了json文件，其中body字段存的就是字符串化的邮件内容html文档，我要怎么处理才能让它显示在页面上呢？&lt;/p&gt;
&lt;p&gt;首先前端显示这里还是和之前一样，需要一个view页面，但是这个时候不需要添加其他内容了，使用&lt;code&gt;{!!$str!!}&lt;/code&gt;可以把原始的&lt;code&gt;$str&lt;/code&gt;内容显示出来。大概就是，如果$str是个html文档，那么它解析的时候就会按html来解析。接下来的就比较简单了，直接把它存到一个文件里面就好了。&lt;/p&gt;
&lt;h2 id="_3"&gt;总结&lt;/h2&gt;
&lt;p&gt;总的来说写的东西还是有一定的难度，可以学到一些东西，我在想，当我学不到什么东西的时候，就跑路。&lt;/p&gt;</content><category term="学习笔记"/><category term="工作流程"/><category term="原创"/></entry><entry><title>初步了解graphQL</title><link href="https://zhiyuansong.xyz/chu-bu-liao-jie-graphql.html" rel="alternate"/><published>2022-02-09T09:45:37+08:00</published><updated>2022-02-09T09:45:37+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-02-09:/chu-bu-liao-jie-graphql.html</id><summary type="html">&lt;p&gt;这块一开始根本不理解，也许现在也还是不理解……毕竟REST的我都不是很理解，但是毕竟看了这么多天了，也该写点东西了，哪怕理解的是错的，之 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这块一开始根本不理解，也许现在也还是不理解……毕竟REST的我都不是很理解，但是毕竟看了这么多天了，也该写点东西了，哪怕理解的是错的，之后回看大概也是有点用的吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="api"&gt;什么是API&lt;/h2&gt;
&lt;p&gt;在大学的时候自己东西没做过多少，对API这东西理解就是一个接口，可以传入和获取数据。其实大差不差吧，但是对这东西究竟是怎么实现的，完全不清楚。&lt;/p&gt;
&lt;p&gt;年前做了一个返回数据的接口，主要是基于Laravel的API形式来做的，初步对API有了一点了解，就像请求网址获取资源一样嘛，你对API的接口传入了请求的内容，像是资源的序号什么的，它返回给你数据，只不过不像请求网站资源那样返回的是HTML文档而返回的是纯数据罢了。&lt;/p&gt;
&lt;p&gt;然后就学到了graphQL，就有点麻了，这是什么东西……为什么还要提前把每个数据字段的类型都定义好，图啥……&lt;/p&gt;
&lt;h2 id="graphql"&gt;graphQL?&lt;/h2&gt;
&lt;p&gt;按教程里的说法，graphQL应该也算是一种API，就是在表现形式上和REST API差距有点大，简单对比一下两者的区别。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;REST是按请求网络资源的形式来定义的，所以关键字有像是&lt;code&gt;GET&lt;/code&gt;，&lt;code&gt;POST&lt;/code&gt;，&lt;code&gt;PATCH&lt;/code&gt;，&lt;code&gt;DELETE&lt;/code&gt;之类的，而graphQL直接就只有读和写两种（不过我感觉用的大多数还是读比较多吧🤔）。&lt;/li&gt;
&lt;li&gt;REST请求一个数据是整个拖出来的，没办法做到请求某个资源的某几个字段这样去请求，可能会浪费资源，而graphQL可以单独请求数据的某几个字段，精准（就是请求可能会看着很晕，有ES的DSL那种感觉）。&lt;/li&gt;
&lt;li&gt;REST请求多个资源需要访问多个URL（我单独写一个能请求多个资源的URL不行吗，你说是那就是吧），graphQL请求多个资源只需要一个描述，在网络资源受限的情况下表现更好。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;大概内容就是这些，还有其他的，如果有用之后再补。&lt;/p&gt;
&lt;h2 id="_1"&gt;请求结构&lt;/h2&gt;
&lt;p&gt;我对这块内容不是很理解，因为这部分请求的结构长得很像ES的DSL请求，但我那块其实也是学的半瓶子醋……凑合写一下。&lt;/p&gt;
&lt;p&gt;简单来说这东西的请求结构是靠大括号分层的，大概举个例子，像是“中国河北省张家口市桥东区xx小区xx栋xx单元的xxx住户”大概可以抽象出来一个“人”（citizen）的模型，写成graphQL的请求形式大概是这个样子：&lt;br /&gt;
&lt;div class="highlight" data-language="graphQL"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;citizen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;province&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;district&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;community&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;building&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
可能有写错的单词，大概理解一下，然后请求到的数据大概是这个样子：&lt;br /&gt;
&lt;div class="highlight" data-language="graphQL"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;citizen&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;中国&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;province&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;河北省&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;张家口市&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;district&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;桥东区&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;community&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;xx小区&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;building&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;xx栋&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;xx单元&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;&lt;span class="n"&gt;xxx&lt;/span&gt;&lt;span class="err"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;所以可以很清楚的看出来，你的请求是和返回的数据的结构是严格对应的，字段有没有，字段排列的顺序，都是和请求相关的，请求有，结果就有，所以不会有冗余（就是请求可能会写的很长……）。&lt;/p&gt;
&lt;h2 id="_2"&gt;结尾&lt;/h2&gt;
&lt;p&gt;这大概就是最基础的理解了，后面还有定义字段类型之类的内容，之后慢慢补充。&lt;/p&gt;</content><category term="学习笔记"/><category term="graphQL"/><category term="API"/><category term="原创"/></entry><entry><title>一月末做的需求总结</title><link href="https://zhiyuansong.xyz/yi-yue-mo-zuo-de-xu-qiu-zong-jie.html" rel="alternate"/><published>2022-01-24T17:03:38+08:00</published><updated>2022-01-24T17:03:38+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-24:/yi-yue-mo-zuo-de-xu-qiu-zong-jie.html</id><summary type="html">&lt;p&gt;其实没做什么，上周和上上周是大学特学docker和golang了。然后上周四开始做产品经理需求的一个数据接口，主要是方便他分析数据字 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;其实没做什么，上周和上上周是大学特学docker和golang了。然后上周四开始做产品经理需求的一个数据接口，主要是方便他分析数据字段。今天应该是做的差不多了。我也熟悉了一下接口的相关写法和内容什么的。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="api"&gt;Api&lt;/h2&gt;
&lt;p&gt;这个词听着挺吓人，其实就是个开放在外的网址，你访问它，它做做反应，像是返回一些数据什么的，照这样理解，其实web访问就是个api，只不过是返回页面内容罢了。这么做也不难理解Laravel的web路由和api路由是放在一起的这件事了。甚至流程都差不多，配配路由，写写控制器什么的。&lt;/p&gt;
&lt;p&gt;好像没什么可讲的了，差不多就这样。&lt;/p&gt;
&lt;h2 id="_1"&gt;代码&lt;/h2&gt;
&lt;p&gt;这次用的代码主要是SP-API的接口，之前说实话也封装过几次底层代码了，封装这块其实问题不大，照猫画虎就行。问题主要出在自己是第一次做相关的内容，读文档都读不太懂的那种，第二个问题就是文档有问题了。这次碰到最多的问题主要是传入时间参数的格式问题，经常是文档要求的是ISO8601，但实际上不是，自己配了半天就是报错，还是靠github上的讨论贴文才解决的，只能庆幸自己没有跳到坑里起不来吧。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;其实没什么了，另外是自己被要求做了个保存文件并下载的功能，主要是fopen、fwrite、fclose还有&lt;code&gt;return response()-&amp;gt;download('path/name','name')&lt;/code&gt;这类的语句，见多了自然就会了。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>偷学golang（四）</title><link href="https://zhiyuansong.xyz/tou-xue-golangsi.html" rel="alternate"/><published>2022-01-19T11:44:21+08:00</published><updated>2022-01-19T11:44:21+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-19:/tou-xue-golangsi.html</id><summary type="html">&lt;p&gt;最近手头没什么活，代码翻来覆去就那点东西，也没什么可做的。既然没得做，那就接着偷学吧。这次学的是网络编程。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;网络分 …&lt;/h2&gt;</summary><content type="html">&lt;p&gt;最近手头没什么活，代码翻来覆去就那点东西，也没什么可做的。既然没得做，那就接着偷学吧。这次学的是网络编程。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;网络分层&lt;/h2&gt;
&lt;p&gt;首先记一下网络通信的层数。课本里讲的是五层模型，而国际标准（OSI）是七层，大概了解一下就行。Socket 位于应用层和传输层之间。&lt;/p&gt;
&lt;h2 id="goroutine"&gt;goroutine 与通道&lt;/h2&gt;
&lt;p&gt;golang 的并发使用 goroutine 这种东西，它和实际的系统线程是多对多的关系。&lt;/p&gt;
&lt;p&gt;通道（channel）是一种通信用的数据结构，遵循先进先出（FIFO）的原则，类似于一个队列。通道关闭后只能发送、不能接收。&lt;/p&gt;
&lt;p&gt;无缓冲通道必须有接收才能有发送，否则执行的时候会报错。&lt;/p&gt;</content><category term="学习笔记"/><category term="golang"/><category term="原创"/></entry><entry><title>Docker学习笔记（三）</title><link href="https://zhiyuansong.xyz/dockerxue-xi-bi-ji-san.html" rel="alternate"/><published>2022-01-17T14:50:26+08:00</published><updated>2022-01-17T14:50:26+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-17:/dockerxue-xi-bi-ji-san.html</id><summary type="html">&lt;p&gt;这章的内容不多，就是端口映射（第一篇讲过），docker-compose使用和docker的网络模式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;端口映射&lt;/h2&gt;
&lt;p&gt;具体内容可以参见第一章容器端口的相关内容。补充一个命令&lt;code&gt;docker …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;这章的内容不多，就是端口映射（第一篇讲过），docker-compose使用和docker的网络模式。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;端口映射&lt;/h2&gt;
&lt;p&gt;具体内容可以参见第一章容器端口的相关内容。补充一个命令&lt;code&gt;docker container inspect xxid&lt;/code&gt;可以查看容器提供的端口之类的信息，当然还有一些其他的信息，有时间可以看看。总之端口映射就是运行容器的时候设定一下，很简单的。&lt;/p&gt;
&lt;h2 id="docker-compose"&gt;docker-compose&lt;/h2&gt;
&lt;p&gt;大概是个打包多条Docker命令成shell脚本的工具。下载建议去翻官方文档，linux平台有安装教程，大概是三条命令。但是github由于访问有问题可能下不下来。可以试试道客的国内镜像，再就是可以试试用pip安装（就是Python的那个包管理器）,不过我没试。windows平台因为安装的直接是Docker Desktop所以直接自带。&lt;/p&gt;
&lt;p&gt;因为写这个文件感觉纯粹就是多写就会了，基本上就是把命令转个说法，所以下面举个例子：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker container run -d -p 5001:80 wordpress&lt;/code&gt;转成docker-compose.yaml大概是这样的：&lt;/p&gt;
&lt;div class="highlight" data-language="yaml"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;3.8&amp;quot;&lt;/span&gt;

&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;my-wordpress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;wordpress:latest&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;5001:80&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;版本号version对应的是Docker的版本号，具体的对应关系可以上网查。&lt;/p&gt;
&lt;p&gt;yaml写的时候有几个坑，首先是，每一个键值之间的冒号后边必须有一个空格，哪怕值是空的也必须要有,但是Docker命令内容里的冒号不用这样处理；其次，缩进不能用制表符，只能用空格。（一开始直接照抄的我是各种报错……）最后，docker-compose的脚本必须命名成&lt;code&gt;docker-compose.yml&lt;/code&gt;或者是&lt;code&gt;docker-compose.yaml&lt;/code&gt;，其他情况会报错，跑不了命令。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;命令相关&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;写完上面的内容然后保存，在终端中运行&lt;code&gt;docker-compose up (-d)&lt;/code&gt;就可以运行写的脚本了。&lt;code&gt;-d&lt;/code&gt;是后台运行。当然这样并不能显示出脚本的优越之处，因为文档中描述这种方式是为了多容器的应用开发的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose ps&lt;/code&gt;，查看容器的运行情况。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose stop&lt;/code&gt;，停止service。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose rm&lt;/code&gt;，清理service，会直接把docker-compose生成的容器删除。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;生成的容器名字是对应所在的文件夹的名字，再和yaml文件夹种起的名字拼接在一起，最后还有一个阿拉伯数字的后缀生成的。想修改前缀可以在启动时添加&lt;code&gt;-p&lt;/code&gt;参数命名一个新的名字。整个容器名字也可以在yaml文件里用container_name来命名，但是这样前缀后缀就没了。可以起好文件夹的名字，再启动容器。&lt;/p&gt;
&lt;p&gt;自定义镜像的构建，给自定义镜像命名，启动镜像前拉取镜像。&lt;/p&gt;
&lt;h2 id="docker"&gt;Docker的网络模式&lt;/h2&gt;
&lt;p&gt;容器之间，容器和宿主机之间建立的网络关系进行一下了解是很重要的，这是进一步了解集群之类知识的基础。&lt;/p&gt;
&lt;p&gt;docker inspect &lt;Container ID &gt; 查看容器信息&lt;/p&gt;
&lt;p&gt;默认情况下，启动容器获得的IP是自动分配的，也就是说，每次启动获得的IP不固定，对于某些任务使用时，不固定IP并不方便。用&lt;code&gt;--name NAME&lt;/code&gt;来指定容器的名字为NAME。&lt;/p&gt;
&lt;p&gt;docker network ls 查看主机上已有的网络配置列表&lt;/p&gt;
&lt;p&gt;桥接模式：为每个容器分配IP，默认连到docker0虚拟网桥。再由网桥和主机端口进行连接。默认的连接模式。&lt;/p&gt;
&lt;p&gt;主机模式：用的是宿主机的IP和端口，不生成自己的虚拟网卡，不配置自己的IP。使用&lt;code&gt;--network host&lt;/code&gt;或&lt;code&gt;--net host&lt;/code&gt;来指定启动时按主机模式启动。这之后访问主机IP就会看到对应的容器页面了。&lt;/p&gt;
&lt;p&gt;none：禁用网络功能，只有127.0.0.1本地环回接口，创建时通过&lt;code&gt;--net none&lt;/code&gt;或者&lt;code&gt;--network none&lt;/code&gt;来指定。&lt;/p&gt;
&lt;p&gt;container：和另一个容器共享对面的IP和端口，自己不生成自己的虚拟网卡和IP。启动时通过&lt;code&gt;--net container: 已运行的网络名称|ID&lt;/code&gt;或&lt;code&gt;--network container: 已运行的容器名称|ID&lt;/code&gt;指定，两个容器除了网络方面相同之外，其他的像是文件系统和进程列表还是隔离的。主容器退出了，副容器是没办法连网的，因为副容器的网络访问依赖于主容器。&lt;/p&gt;</content><category term="学习笔记"/><category term="容器"/><category term="原创"/></entry><entry><title>偷学golang（三）</title><link href="https://zhiyuansong.xyz/tou-xue-golangsan.html" rel="alternate"/><published>2022-01-13T17:06:31+08:00</published><updated>2022-01-13T17:06:31+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-13:/tou-xue-golangsan.html</id><summary type="html">&lt;p&gt;继续偷学，该面向对象了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;golang有面向对象，但是没有类，是通过把方法绑到结构体上实现的。&lt;/p&gt;
&lt;p&gt;当时学C和C++的时候，就知道其实结构体加上函数 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;继续偷学，该面向对象了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;golang有面向对象，但是没有类，是通过把方法绑到结构体上实现的。&lt;/p&gt;
&lt;p&gt;当时学C和C++的时候，就知道其实结构体加上函数其实就和类差不多了。但是真的做成这个样子还是挺稀奇的，感觉这门语言真是为了减少关键字数量无所不用其极。&lt;/p&gt;
&lt;h2 id="_1"&gt;方法&lt;/h2&gt;
&lt;p&gt;方法就是一类带有特殊的接收者参数的函数，这个接收者是结构体类型的实例。位置在&lt;code&gt;func&lt;/code&gt;关键字和方法名之间，用小括号括起来。&lt;/p&gt;
&lt;p&gt;教程里甚至强调了方法就是函数，加了个接收者参数感觉也就是用来引用接收者的属性比较好使，把它直接扔到参数列表里感觉都可以。&lt;/p&gt;
&lt;p&gt;可以为除了结构体外的其他类型定义方法，接收者的类型定义和方法声明需要在同一个包里。不能为内建类型声明方法。但看着好像可以用&lt;code&gt;type&lt;/code&gt;关键字改个名字来用？&lt;/p&gt;
&lt;p&gt;方法所绑定的接收者结构体要是被别的结构体包含了，那么就有点像继承的意思，方法也就被继承了。当然内层结构体里的字段也可以使用。匿名字段在golang中大概就是这么使用的。之所以叫匿名字段，因为在包含的过程中，只写了结构体类型名称，没有把详细的字段列出来。&lt;/p&gt;
&lt;p&gt;方法集大概只是一种概念，大概就是两条准则，第一条是，如果接收者实例是T，那么它可以使用所有接收者是T的方法。第二条是，如果接收者实例是*T，那么它可以使用所有接收者是T和*T的方法。你可以根据上面的匿名字段继承那块的知识进一步推论出另外两条结论：当包含T，可以用接收者是T的方法，包含*T，可以用接收者是T和*T的方法。&lt;/p&gt;
&lt;p&gt;表达式：啥玩意儿？&lt;/p&gt;
&lt;p&gt;接口：这个概念和其他的一样，都是要求实现的一组规范。定义了应该有什么功能，至于到底怎么实现这些功能它是不关心的，只要有就好。首先要记住接口是一个类型，相当于是一组方法定义的集合。规定了方法的参数列表和返回值，具体的实现内容并没有涉及。举个例子：&lt;/p&gt;
&lt;div class="highlight" data-language="golang"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;writer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;一般接口的名字结尾都要加上er。&lt;/p&gt;
&lt;p&gt;接口的实现很简单，不用有什么引入的步骤，只要结构体能够把接口中列出的方法全部都实现了，就说明接口被实现了。（那么强制性显示在哪里？像是我代码只实现了一部分接口方法，会报错吗）&lt;/p&gt;
&lt;p&gt;实现了接口的对象能够被存放在接口里面。先跳了，这块没太看懂。&lt;/p&gt;</content><category term="学习笔记"/><category term="golang"/><category term="原创"/></entry><entry><title>偷学golang（二）</title><link href="https://zhiyuansong.xyz/tou-xue-golanger.html" rel="alternate"/><published>2022-01-13T13:51:43+08:00</published><updated>2022-01-13T13:51:43+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-13:/tou-xue-golanger.html</id><summary type="html">&lt;p&gt;今天还没事，继续偷学了，好爽。&lt;/p&gt;
&lt;p&gt;今天主要总结一下golang的基础部分，大概就是面向对象之前的内容。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;上一章其实内容和形式已经介绍不少 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;今天还没事，继续偷学了，好爽。&lt;/p&gt;
&lt;p&gt;今天主要总结一下golang的基础部分，大概就是面向对象之前的内容。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;上一章其实内容和形式已经介绍不少了，这点东西其实大多数点到为止就行。&lt;/p&gt;
&lt;h2 id="_1"&gt;包和函数&lt;/h2&gt;
&lt;p&gt;包的导入用&lt;code&gt;import&lt;/code&gt;关键字，包名以包名的最后一个单词为准，像是&lt;code&gt;math/rand&lt;/code&gt;实际的包就是&lt;code&gt;package rand&lt;/code&gt;，所有的方法都是以它为开头。引入一个包可能会有&lt;code&gt;import _ "xxx"&lt;/code&gt;的写法，这样的写法主要是用了这个包的&lt;code&gt;init()&lt;/code&gt;函数。&lt;/p&gt;
&lt;p&gt;golang的包里没有什么&lt;code&gt;public&lt;/code&gt;和&lt;code&gt;private&lt;/code&gt;的概念，有的只有方法和属性的首字母是否大写形成的是否可以导出的概念。如果是大写，就相当于允许外部使用，反之就不行。所以调用其他包的方法会发现首字母全是大写的，不新鲜。说实话这样还挺方便的，比C++那三种关键字好理解多了。但是函数使用上有的点，像是重载和默认参数是不支持的。&lt;/p&gt;
&lt;p&gt;形参和返回值的类型声明会有点不适应，因为是名称在前，类型在后的形式。但是按照开发者博客上的说法说这样写是有好处的，像是C语言中的&lt;code&gt;int *p&lt;/code&gt;，有的人还可能理解错p的类型，但是在golang中&lt;code&gt;p *int&lt;/code&gt;，基本上辨识度就很高，类似的还有数组写成&lt;code&gt;arr [5]int&lt;/code&gt;的情况，总之理解上还是比较好的。&lt;/p&gt;
&lt;p&gt;写法上语言格式要求大括号左半边必须出现在语句的末尾，看了一下说是因为不用写标点符号，所以如果不这样写，编译器在编译代码时候就会自动在句子结尾加分号，就会导致发生错误。所以在这方面语言格式要求很高，不过感觉问题也不大。&lt;/p&gt;
&lt;p&gt;多值返回就很正常了，感觉用着很自然，写交换这类函数反向返回一下就行了，爽到。&lt;/p&gt;
&lt;h3 id="_2"&gt;函数的闭包&lt;/h3&gt;
&lt;p&gt;说是闭包就是函数加上引用函数，不太能理解这个闭包是什么意思。&lt;/p&gt;
&lt;p&gt;看了个例子，大概是函数里面又定义了个内部函数，可以调用外层函数的变量，最后返回的结果是内层函数的流程……函数外的变量c引用了函数a内的函数b。函数a执行完成后因为垃圾回收的原因不会被回收自身的资源。因为函数a内的函数b需要函数a的数据资源……&lt;/p&gt;
&lt;p&gt;闭包可以完成信息隐藏。&lt;/p&gt;
&lt;p&gt;闭包的使用要注意引用环境，前一次和后一次引用的情况是不一样的。但是这个量不丢的话，应该就没问题。&lt;/p&gt;
&lt;p&gt;总之就是因为引用的函数用了外部函数的数据，但是因为闭包的原因值还在使用，不会被垃圾清理释放掉，从而把这个值保留了下来，方便实现了一些功能。&lt;/p&gt;
&lt;p&gt;注意外部引用的值指向的内部的东西是不一样的，所以返回的值不会一致。&lt;/p&gt;
&lt;h3 id="_3"&gt;函数的递归&lt;/h3&gt;
&lt;p&gt;简单来说，就是我调用我自己，最常见的例子就是斐波那契数列的写法。&lt;/p&gt;
&lt;h2 id="_4"&gt;流程控制语句&lt;/h2&gt;
&lt;h3 id="_5"&gt;循环和选择&lt;/h3&gt;
&lt;p&gt;循环语句只有一个&lt;code&gt;for&lt;/code&gt;关键字，具有for和while两个功能，总之把平常语言中的while换成for，再把条件的小括号和多余的标点去掉，用就是了。无限循环直接写&lt;code&gt;for {}&lt;/code&gt;就行。🤔&lt;/p&gt;
&lt;p&gt;选择语句&lt;code&gt;if&lt;/code&gt;关键字也是一样的，不带小括号，语句块必须带大括号就行了，也没什么可说的。&lt;code&gt;switch&lt;/code&gt;关键字也差不多，不像其它语言，golang的switch的每个case都自带了break，也就是每次匹配到的case运行完后就直接跳出了。要想继续运行需要用到&lt;code&gt;fallthrough&lt;/code&gt;语句。其他的点就是case的条件不需要是常量，也不需要是整数，在使用上更方便了。甚至可以用不带条件的switch语句来实现一个多判断的if语句，显得更有条理。&lt;/p&gt;
&lt;h3 id="defer"&gt;&lt;code&gt;defer&lt;/code&gt;关键字&lt;/h3&gt;
&lt;p&gt;这个defer关键字的作用是把正常流程中运行的语句结果塞到一个栈里，等到外层函数返回值的时候再返回值，因为是栈，所以会有后进先出的特性。这样的话你就可以用一个递增的循环输出一个递减的序列，只要在正常递增的输出语句前面加上&lt;code&gt;defer&lt;/code&gt;关键字就好。&lt;/p&gt;
&lt;h2 id="_6"&gt;重点的数据结构&lt;/h2&gt;
&lt;p&gt;结构体不难，指针简单了太多。难的大概就是数组、切片和映射这三个东西。反正代码写多了都知道，无非是和数组还有字符串打交道，务必需要掌握相关的内容。&lt;/p&gt;
&lt;h3 id="_7"&gt;指针和结构体&lt;/h3&gt;
&lt;p&gt;指针的用法，其实和C的差不多，把指针运算去掉，好像指针也不是很难的东西了，golang的指针大概就一个取地址解地址的用法，在操作某些值的修改比较方便外，其他没什么好讲的。&lt;/p&gt;
&lt;p&gt;结构体就是一组字段，注意结构的写法：&lt;/p&gt;
&lt;div class="highlight" data-language="golang"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Vertex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;X&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;Y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;感觉和C的没什么区别。使用上用大括号赋值，大概类似于&lt;code&gt;v := Vertex{1,2}&lt;/code&gt;这种形式。用&lt;code&gt;v := Vertex{X:1}&lt;/code&gt;这种写法可以只列出部分值，其余值按默认的来取。结构体指针访问元素可以直接用&lt;code&gt;p.X&lt;/code&gt;这种写法，不用解地址，编译器很智能。&lt;/p&gt;
&lt;h3 id="_8"&gt;数组和切片&lt;/h3&gt;
&lt;p&gt;数组就和正常的C语言的数组一样，大小固定不能扩展，所以切片相比数组更常用。&lt;/p&gt;
&lt;p&gt;切片用&lt;code&gt;[]int&lt;/code&gt;这样的类型声明这是一个元素类型是int的切片，切片单从字面理解上会认为是数组的一部分，事实上确实有这个功能，像是&lt;code&gt;var slice []int = group[1:4]&lt;/code&gt;就是表示slice是group数组的下标1到3的数据。遵循左闭右开的情况。&lt;/p&gt;
&lt;p&gt;切片像数组的引用，也就是说对切片元素的修改实际上就是对基于的数组元素的修改。&lt;/p&gt;
&lt;p&gt;切片的直接定义，像是&lt;code&gt;slice := []int {1,2,3,4,5}&lt;/code&gt;，实际上是先创建了一个基底的数组，再在数组基础上申请的一个包含全部元素的切片。&lt;/p&gt;
&lt;p&gt;切片的上下界不写的情况下默认下界为0，上界为切片的长度。&lt;/p&gt;
&lt;p&gt;切片的长度和容量，说实话，看着很麻，什么长度，什么容量，不是一个东西吗？&lt;/p&gt;
&lt;p&gt;仔细研究了一下，长度理解很简单，就是当前切片的元素数量；容量理解起来，就是切片的第一个元素，到基底的数组的最后一个元素的元素数量。&lt;/p&gt;
&lt;p&gt;所以，有一种情况就比较有趣，切片切自己的话，最好是上界确定，这样下界默认就保持为0，以后扩展和缩小还有的救，但是下界确定的话，好像只能缩，想再扩大就难了，因为这样的操作直接把切片的容量给缩小了。🤔使用&lt;code&gt;len(s)&lt;/code&gt;和&lt;code&gt;cap(s)&lt;/code&gt;来获取切片的长度和容量。其实感觉还挺怪的，说是可扩展，结果还是得看基底的大小。&lt;/p&gt;
&lt;p&gt;切片的0值是nil，长度和容量都是0，并且没有基底数组。&lt;/p&gt;
&lt;p&gt;可以用&lt;code&gt;make()&lt;/code&gt;来申请切片，包括切片的长度，容量都可以自己定义：&lt;/p&gt;
&lt;div class="highlight" data-language="golang"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//长度0，容量5&lt;/span&gt;
&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;向切片追加元素，使用&lt;code&gt;append()&lt;/code&gt;函数，第一个参数是一个切片，之后的参数类型要和切片类型一致，就可以传入，而且切片的容量不会影响插入，会自动扩容。（上面提的基底数组影响容量当我没说……🙃）&lt;/p&gt;
&lt;h3 id="range"&gt;range&lt;/h3&gt;
&lt;p&gt;for循环中的range可以用来遍历切片或映射，每次返回两个值，一个键一个值，可以用&lt;code&gt;_&lt;/code&gt;忽略部分数据：&lt;/p&gt;
&lt;div class="highlight" data-language="golang"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="_9"&gt;映射&lt;/h3&gt;
&lt;p&gt;映射将键映射到值，空映射为nil，什么都干不了。用&lt;code&gt;make()&lt;/code&gt;来创建一个映射&lt;code&gt;make(map[string]string)&lt;/code&gt;。文法和结构体类似，但是键一定要有，用冒号链接。&lt;/p&gt;
&lt;h3 id="_10"&gt;函数当值&lt;/h3&gt;
&lt;p&gt;函数也是值，所以可以拿函数当参数和返回值。&lt;/p&gt;
&lt;h3 id="_11"&gt;函数的闭包&lt;/h3&gt;
&lt;p&gt;整不来，啥意思？&lt;/p&gt;
&lt;h2 id="_12"&gt;总结&lt;/h2&gt;
&lt;p&gt;基本内容串了一遍，下一部分该面向对象了，孩子还是看不懂函数闭包是个啥玩意，太难了。&lt;/p&gt;</content><category term="学习笔记"/><category term="golang"/><category term="原创"/></entry><entry><title>偷学golang（一）</title><link href="https://zhiyuansong.xyz/tou-xue-golangyi.html" rel="alternate"/><published>2022-01-12T14:26:13+08:00</published><updated>2022-01-12T14:26:13+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-12:/tou-xue-golangyi.html</id><summary type="html">&lt;p&gt;不写东西，没有记忆，好几次读文档了，基本上就是看着看着然后人就不会了，还是得记点东西。看了看之前的记录，应该是没 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;不写东西，没有记忆，好几次读文档了，基本上就是看着看着然后人就不会了，还是得记点东西。看了看之前的记录，应该是没有golang的。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;这个偷学主要是公司没事偷学的，主要没活，那就得自己学东西了。&lt;/p&gt;
&lt;p&gt;参考的学习内容主要是官方网站的英文文档，感觉这门语言其实挺简单的，甚至有种处在C和C++之间的那种感觉，简约的感觉很好。但是网上很多教程就一股脑塞给你，尤其是切片，看的人麻了，反而是官方教程讲的很实用。&lt;/p&gt;
&lt;h2 id="_1"&gt;安装&lt;/h2&gt;
&lt;p&gt;从linux和windows两个平台来看的话，linux就是解压压缩包到某个路径然后export Go目录下bin文件夹的路径到profile文件。至于windows平台就更简单了，直接下载官方的安装包一路安装就行。连配置路径都省了。（我不太清楚为什么早期的教程好多还要配置什么GOPATH还有GOROOT，目前看env的话应该都是配置好的）&lt;/p&gt;
&lt;h2 id="_2"&gt;编辑器&lt;/h2&gt;
&lt;p&gt;已经不是学生了，没法白嫖jetBrain家的Goland了😭。学习版试用了一下，主要是太大了，感觉大多数情况下也用不上，甚至它这种特别智能的IDE对于教程学习有很多不方便的地方，像是敲命令行什么的……试了试发现还是VS Code爽，只要安装好官方的Go插件就可以使用了（可能因为网络问题，在安装好基础插件的情况下会有一堆依赖下不下来，网上一堆离线教程看的头大，结果还是常备魔法😂）。&lt;/p&gt;
&lt;h2 id="_3"&gt;基础内容&lt;/h2&gt;
&lt;p&gt;前几篇教程主要是讲了Go代码文件的基础内容，像是文件的结构，基本的语法（package-import-func），还有引用外部模块什么的。主要感觉没见过的点一是代码格式要求，就是一种风格，因为其他的写法都会报错，直接用&lt;code&gt;go fmt&lt;/code&gt;对代码进行格式处理就好。然后是没用的代码必须删掉不然会报错，再就是用mod文件来管理项目中用到的package之类的，说实话挺好的，免去了管理依赖项的各种乱七八糟的问题。引用外部模块有个类似于github的&lt;code&gt;pkg.go.dev&lt;/code&gt;来找各种未在标准库中包含的官方和第三方包，给人Docker Hub的感觉。&lt;/p&gt;
&lt;p&gt;几条命令：&lt;code&gt;go run xxx.go&lt;/code&gt;不生成可执行文件跑代码文件，&lt;code&gt;go build xxx.go&lt;/code&gt;生成可执行文件，&lt;code&gt;go mod init packagename&lt;/code&gt;生成mod文件来跟踪项目的依赖，&lt;code&gt;go mod tidy&lt;/code&gt;用来对代码引入的package进行处理，像是本地没有的去下载之类的，&lt;code&gt;go mod edit -replace packagename=disname&lt;/code&gt;可以通过这种方式让本地的第三方包被识别到路径而不是上网去找🤔，&lt;code&gt;go fmt xxx.go&lt;/code&gt;格式化代码，可能在命令行下比较好使，现在IDE都自带保存调整格式了。&lt;/p&gt;
&lt;h2 id="_4"&gt;错误及其处理&lt;/h2&gt;
&lt;p&gt;Golang的函数一次可以返回多个值，所以可以在返回值里面直接返回一个error类型的值来实现返回异常情况，像是一个函数如果需要传入的实参不为空，可以用一个判断外加返回errors模块的New方法生成的error值来实现。如果正常的话返回的error类型的值是nil就行。在实际调用这个带有error返回类型的函数，当然要赋一个值来作为判断了，可以用log模块对这个err进行处理。&lt;/p&gt;
&lt;p&gt;用到的函数：&lt;code&gt;errors.New()&lt;/code&gt;产生一个error，参数用string类型；&lt;code&gt;log.SetPrefix("greetings：")&lt;/code&gt;设置日志的前缀内容，&lt;code&gt;log.SetFlags()&lt;/code&gt;设置标准输出的输出标志，&lt;code&gt;log.Fatal()&lt;/code&gt;相当于打印函数，同时结束程序(&lt;code&gt;os.Exit(1)&lt;/code&gt;)。&lt;/p&gt;
&lt;h2 id="init"&gt;切片、时间、&lt;code&gt;init()&lt;/code&gt;和随机数&lt;/h2&gt;
&lt;p&gt;切片可以说是Golang里面相当灵活的数据结构了，说白了很像Python里面的列表，就是有扩展性的数组。类型的写法有点怪，举个例子，&lt;code&gt;[]string&lt;/code&gt;，需要熟悉一下，其他的写法，目前先注意使用大括号做赋值就好。&lt;/p&gt;
&lt;p&gt;时间要用time模块，要用的函数&lt;code&gt;time.Now()&lt;/code&gt;返回现在的时间，后面可以接&lt;code&gt;UnixNana()&lt;/code&gt;来转成Unix时间戳一类的东西。这里介绍时间主要是为了生成可变化的随机数种子。毕竟时间时刻都在变化，拿来做种子就很好。&lt;/p&gt;
&lt;p&gt;随机数就和其他语言用的一样，先设置一个随机数种子然后就可以调用对应的函数来生成范围内的随机数了。这里介绍&lt;code&gt;init()&lt;/code&gt;函数，这个函数主要是对模块内方法调用前做的一些操作，在一切调用函数的行为发生前执行，像是设置随机数种子就可以交给&lt;code&gt;init()&lt;/code&gt;来执行。用到的函数有&lt;code&gt;rand.Seed()&lt;/code&gt;，传入一个值来生成随机数种子，之后可使用&lt;code&gt;rand.Intn()&lt;/code&gt;来生成一定范围的随机整数，倘若传入3，则生成的随机数为0，1，2其中之一。&lt;/p&gt;
&lt;h2 id="_5"&gt;参数和返回值是数组或映射的情况&lt;/h2&gt;
&lt;p&gt;其实数组理解起来没什么难度，映射无非可以理解成下标不是数字的数组，有点像PHP&lt;code&gt;[key =&amp;gt; val]&lt;/code&gt;这种数组罢了。注意下写法，申请一个映射要写清楚键值的类型，像是&lt;code&gt;messages := make(map[string]string)&lt;/code&gt;这种东西，申请的就是一个键和值都是string类型的映射。&lt;/p&gt;
&lt;p&gt;注意映射的类型写法是类似于&lt;code&gt;map[string][string]&lt;/code&gt;这种形式。其他的用法其实和数组也没什么区别，像是一个一个赋值完全可以用类似于&lt;code&gt;messages[key] = value&lt;/code&gt;的写法。&lt;/p&gt;
&lt;p&gt;for循环有一个&lt;code&gt;_&lt;/code&gt;可以对切片或者是映射的一部分数据进行忽略处理，因为golang要求引入的数据必须都处理，那我忽略掉其实也是处理了。😮&lt;/p&gt;
&lt;h2 id="_6"&gt;单元测试&lt;/h2&gt;
&lt;p&gt;简单来说，写一个单元测试文件，运行测试来验证函数是否安全可靠。大概步骤是写单元测试文件-&amp;gt;跑&lt;code&gt;go test (-v)&lt;/code&gt;命令，差不多就是这么简单，主要是了解单元测试文件怎么写就好了。&lt;/p&gt;
&lt;p&gt;但是，看不太懂，寄了。&lt;/p&gt;
&lt;h2 id="_7"&gt;编译和安装程序&lt;/h2&gt;
&lt;p&gt;使用&lt;code&gt;go build&lt;/code&gt;可以编译生成程序的可执行文件。但这个时候的可执行程序运行需要一个完整的路径。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;go install&lt;/code&gt;安装前需要配置相关的对应路径，有点像配置Java安装包的JAVA_HOME。但是也有点看不懂，而且感觉没什么用途。&lt;/p&gt;
&lt;h2 id="_8"&gt;总结&lt;/h2&gt;
&lt;p&gt;这一篇小文档基本就算是golang的小入门了，虽然面向对象的一大部分知识没有讲到，但是其实因为golang的面向对象依附在结构体上，所以和写函数差不多。问题其实不是很大，其他的像是网络并发之类的知识之后再进行总结。&lt;/p&gt;</content><category term="学习笔记"/><category term="golang"/><category term="原创"/></entry><entry><title>Docker学习笔记（二）</title><link href="https://zhiyuansong.xyz/dockerxue-xi-bi-ji-er.html" rel="alternate"/><published>2022-01-12T10:49:24+08:00</published><updated>2022-01-12T10:49:24+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-12:/dockerxue-xi-bi-ji-er.html</id><summary type="html">&lt;p&gt;这次要学习的主要是Dockerfile，感觉就是很像命令行似的东西。这东西单看起来就有点像是构建命令，基本上在大写关键字后跟 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这次要学习的主要是Dockerfile，感觉就是很像命令行似的东西。这东西单看起来就有点像是构建命令，基本上在大写关键字后跟的东西就是系统命令行。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;div class="highlight" data-language="Dockerfile"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ubuntu:latest&lt;/span&gt;
&lt;span class="k"&gt;RUN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noninteractive&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;--no-install-recommends&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;python3.9&lt;span class="w"&gt; &lt;/span&gt;python3-pip&lt;span class="w"&gt; &lt;/span&gt;python3.9-dev
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;test.py&lt;span class="w"&gt;  &lt;/span&gt;/
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;python3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;test.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;上面所示的就是一段最简单的Dockerfile，首先是找一个基础镜像，再安装Python3，最后运行一个python脚本。然后运行&lt;code&gt;docker image build -t xxx&lt;/code&gt;就可以运行Dockerfile，生成一个名为xxx的镜像。可以看到在关键字后面跟的就是在基础镜像里面可以运行的命令。所以理解起来也不是很难，所谓的Dockerfile就是可以对基础镜像进行自己的自定义打包，生成新的镜像的命令文件。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;命令补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker image tag old new&lt;/code&gt; 镜像改名&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker login&lt;/code&gt; 登录Dockerhub（需要事先申请Dockerhub的账号）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker image push xxx&lt;/code&gt; 镜像上传到Dockerhub&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="_1"&gt;关键字解析和注意事项&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FROM引入的原则&lt;/strong&gt;：1.优先官方镜像 2.tag要标清楚 3.功能满足的情况下镜像尽量小&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RUN的功能&lt;/strong&gt;：运行shell命令。要注意的是，运行多个命令，最好不要每条命令都RUN一下，因为每RUN一次，容器都会进行一次分层。这样的话，容器的体量就会很大。要连接多条命令，可以用&lt;code&gt;&amp;amp;&amp;amp; \&lt;/code&gt;来连接。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;命令补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker image history &amp;lt;Image ID&amp;gt;&lt;/code&gt;查看image的封装历史（层数）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker image build -f dockerfile.good -t ipinfo-good .&lt;/code&gt;构建镜像 &lt;/p&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt;主要是因为Dockerfile命名不是默认的&lt;code&gt;Dockerfile&lt;/code&gt;，需要指明具体的文件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;文件操作命令&lt;/strong&gt;：使用COPY或ADD命令来添加本地的文件到镜像中，像是上面举过的例子，添加当前目录中的文件到镜像中路径，当路径不存在就会自动创建。&lt;/p&gt;
&lt;p&gt;COPY和ADD使用的时候其实没有什么区别，就是ADD添加的gzip压缩文件到镜像会自动解压，这样的话多文件上传就会很方便。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;切换目录命令&lt;/strong&gt;：WORKDIR命令会切换在镜像中的路径，相当于在镜像中运行&lt;code&gt;cd&lt;/code&gt;命令。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定义变量&lt;/strong&gt;：ARG和ENV命令，这两个命令都是可以用来定义变量的，但是在使用细节上有一点区别。变量的使用主要是命令中可能存在的诸如版本号修改一类的东西，使用变量引入的话会方便修改。&lt;code&gt;ENV VERSION=2.0.1&lt;/code&gt;就是像这样的定义格式。用&lt;code&gt;$(VERSION)&lt;/code&gt;在命令中引入变量。&lt;/p&gt;
&lt;p&gt;ARG的声明变量结构和上面ENV的例子类似。&lt;/p&gt;
&lt;p&gt;ARG和ENV的区别一是声明变量的作用域不同，ENV的变量是可以直接带入到镜像中的，用&lt;code&gt;env&lt;/code&gt;命令可以直接查看到定义的变量。二是ARG声明后可以在构建时修改变量。在build镜像时，用&lt;code&gt;--build-arg xxx=xx&lt;/code&gt;来直接修改版本号，方便了生成其他版本的镜像。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;默认执行命令&lt;/strong&gt;：CMD可以用来设置容器启动时候默认会执行的命令。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;命令补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker system prune -f&lt;/code&gt;批量删除已经退出的容器&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker image prune -a&lt;/code&gt;删除没有使用的所有镜像&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;若&lt;code&gt;docker container run&lt;/code&gt;启动容器时指定了其他命令，则CMD命令会被忽略，定义了多个CMD则只有最后一个CMD会执行。&lt;/p&gt;
&lt;p&gt;上面说了，可以直接在启动容器的时候指定容器开启时执行的命令，举个例子：&lt;code&gt;docker container run -it ipinfo-base ipinfo version&lt;/code&gt;就是在开启后运行&lt;code&gt;ipinfo version&lt;/code&gt;这条命令。在Dockerfile中写成CMD形式&lt;code&gt;CMD ["ipinfo","version"]&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;ENTRYPOINT命令同样也可以设置容器启动时候要执行的命令，但和CMD有一点区别。CMD执行的命令可以在运行容器时通过传入命令覆盖掉，但是ENTRYPOINT的命令一定会执行。这两个命令可以同时使用。ENTRYPOINT设置命令，CMD设置参数。就像下面的例子：&lt;/p&gt;
&lt;div class="highlight" data-language="Dockerfile"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ubuntu:21.04&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;echo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这样的话，CMD实际决定了输出的内容是什么。可以通过运行容器时候输入的内容在界面上进行相应的输出。&lt;/p&gt;
&lt;h2 id="_2"&gt;数据持久化&lt;/h2&gt;
&lt;p&gt;所谓的数据持久化，指的就是在容器中的数据在容器被删除之后，依旧可以被之后创建的新容器使用，从而不会丢失。&lt;/p&gt;
&lt;p&gt;在Dockerfile中添加VOLUME可以将数据持久化，这样即使容器被删除了，数据依旧存在。开启的新的容器依然可以使用。&lt;/p&gt;
&lt;h3 id="_3"&gt;一般的用法&lt;/h3&gt;
&lt;p&gt;用VOLUME可以设置容器中持久化的目录。举例，在Dockerfile中使用&lt;code&gt;VOLUME ["/app"]&lt;/code&gt;来固定&lt;code&gt;/app&lt;/code&gt;目录。在开启的容器中创建app目录并且添加文件，这些文件在容器删除后就不会丢失掉了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;命令补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker volume ls&lt;/code&gt;列出所有的持久化空间，其中会列出诸如持节话空间的名字，还有所处的路径（挂载点）。&lt;/p&gt;
&lt;p&gt;想让新容器利用旧容器的持久化空间？在启动容器的时候给空间起个名字，用&lt;code&gt;-v&lt;/code&gt;来命名。&lt;code&gt;docker container run -d -v my-data:/app my-image&lt;/code&gt;，&lt;code&gt;-v&lt;/code&gt;后面接的是命名和空间的路径。这样的话，生成的空间就可以被继承了。用列出命令获得的路径名称也就不会是生成的一串随机码。&lt;/p&gt;
&lt;h3 id="bind-mount"&gt;Bind Mount数据持久化&lt;/h3&gt;
&lt;p&gt;这种方式叫做挂载绑定，可以把容器中持久化的数据绑定到本机的自定义位置。Data Volume在Windows环境中使用很不方便，因为想想就知道这种用法对应的路径只有在Linux下比较好用，对应到Windows环境就会非常奇怪。而且Bind Mount的设置更简单，可以和开发环境更好的融合。所以建议多使用Bind Mount来实现数据持久化。这种方法也是要用&lt;code&gt;-v&lt;/code&gt;参数，像是&lt;code&gt;docker container run -it -v ${pwd}:/app node&lt;/code&gt;就是将容器中的&lt;code&gt;/app&lt;/code&gt;目录和本机的当前目录绑定到了一起。这样的话就可以在本机当前目录添加和操作内容，在容器中运行。&lt;/p&gt;
&lt;p&gt;这样的话，其实就是很像现在开发中用的在本地环境创建一个网络共享文件夹，可以本地编辑代码，在容器中看效果，或者说容器中做一些操作，本地中也会有反映。感觉很方便开发。&lt;/p&gt;
&lt;h2 id="_4"&gt;总结&lt;/h2&gt;
&lt;p&gt;这章主要是把Dockerfile的用法学了一下，还有数据持久化的相关了解，总体来说都是为了生成镜像。说实话让我自己去搭一个镜像，像是Laravel开发这种镜像，感觉要死，要求的东西太多了。目前还是以拿来用作为目的就好了。&lt;/p&gt;</content><category term="学习笔记"/><category term="容器"/><category term="原创"/></entry><entry><title>12月底至今参加的工作内容</title><link href="https://zhiyuansong.xyz/12yue-di-zhi-jin-can-jia-de-gong-zuo-nei-rong.html" rel="alternate"/><published>2022-01-11T17:15:34+08:00</published><updated>2022-01-11T17:15:34+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2022-01-11:/12yue-di-zhi-jin-can-jia-de-gong-zuo-nei-rong.html</id><summary type="html">&lt;p&gt;我大概记得这个需求做之前我是很无聊的，都说没活，找组长，找经理，都说让先看看工作台代码熟悉一下。然后我在12月底接触到了工作台的第一个需求，总之 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我大概记得这个需求做之前我是很无聊的，都说没活，找组长，找经理，都说让先看看工作台代码熟悉一下。然后我在12月底接触到了工作台的第一个需求，总之一趟做下来感觉就是各种不会和不适应。所幸熬了过来，有点收获赶快记下来免得忘掉。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;首先说明一下需求是干什么，大概就是从另一个系统里同步到工作台的数据完成页面显示和搜索以及导出等相关工作，其实搜索和导出因为已经有相对成熟的内容了，也就是配置一下就好，不用纠结什么同步异步的问题。其实感觉整个需求的大部分时间都是在走一个配置的流程。配置完了，也就通了，不过这也导致我其实对于功能是怎么实现的半懂不懂，只是对大概在哪个文件里做个操作有点印象……（完了，要变成熟练工了😱）算了，总结一下干了什么也好，以后有相似工作可以抄抄作业。&lt;/p&gt;
&lt;p&gt;首先是前端页面，作为Laravel框架的一部分使用，这个内容是逃不掉的，然后采用的方式主要是把相似结构的页面粘贴过来然后去掉没用的地方，对有用的组件进行一下复制和修改……反正自己手打一个页面对我目前来说很难，想做出风格相对统一的页面只能这样。页面上一开始就是一个搜索框的样式和一个装模作样的表头。至于表格数据的填充，我一开始以为是会像之前做的通知系统那样，写个控制器方法把数据传到页面上，然后在页面上写长长的控制内容显示代码……但是没有，是写一堆配置文件，我目前还是没有理解究竟是哪里在解析这些配置文件，感觉就是把该写的东西写完了然后就自然而然完成了。😵&lt;/p&gt;
&lt;p&gt;然后是路由和控制器什么的，这个倒没什么可说的，甚至控制器方法简单了太多，就返回了一些配置参数和配置里写死的一些内容给页面，另外还有个TableApiController的控制器用来控制所有表格对Service，即数据组装层的访问，从这个角度感觉这个控制器反而比单独页面的控制器要重要的多。&lt;/p&gt;
&lt;p&gt;配置文件大概包括的内容是table.php，配置了表头，和workbench.php，记录了相关的具体文件的相关配置内容。像是type的配置位置，schema的配置位置等等配置的相关名字。&lt;/p&gt;
&lt;p&gt;再就是Repository类文件，这类文件在之前做过的需求里主要是用来写Model之类的访问函数的，但是在这个项目里似乎除了这部分之外，还承载着处理请求的功能，其实就是把请求转成搜索语句，再把搜索到的结果返回给上一层。感觉似乎把我之前写的那种把请求处理逻辑放在控制器方法里的想法改变了一点。&lt;/p&gt;
&lt;p&gt;然后是Service文件，这类文件目前看来的作用主要是数据组装，像是处理数据为空的情况下数据的值之类的东西，其实就是把数据传递到页面上。具体的数据显示可以在table.php中进行处理，像是一个字段内显示两个数据，Service只是返回了两个数据给显示层，但是处理显示的格式需要在前端定义个局部的模板来处理。&lt;/p&gt;
&lt;p&gt;之后进展到GraphQL和EsModel部分，其实我不懂，这部分也不是我做的，但是为了能之后有点印象，还是写一下。EsModel其实就是数据源是Es的Model，其实实际绑定好之后用法和MySQL的一样（目前我是没发现哪里有不同的地方）。GraphQL就有点迷惑了，感觉像是某种绑定Es数据的东西，可以用这种方法把要用的字段都进行一个绑定，然后有些关联在其他表的字段也可以在这里直接处理掉，方便之后的直接使用。到时候Service直接访问对应的GraphQL模块就可以（但是Schema，Type里Search类文件的配置我是没有看懂究竟是什么意思的，大概是某种主键的确定什么的？）。总之这部分没懂，自己也没做这部分，只能后面看看。&lt;/p&gt;
&lt;p&gt;还要配置个数据库什么的，有个表，主要内容是声明表格字段的名字和来源系统什么的，虽然不写好像照样可以跑……这个目前也不懂怎么写。&lt;/p&gt;
&lt;p&gt;下面是整理的需求的简单目录结构，也不知道有没有用：&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/workbench.png" /&gt;&lt;/p&gt;
&lt;p&gt;大概就这么多东西，下次至少应该碰见相似的东西可以写的顺利一点点。&lt;/p&gt;</content><category term="学习笔记"/><category term="工作流程"/><category term="原创"/></entry><entry><title>Docker学习笔记（一）</title><link href="https://zhiyuansong.xyz/dockerxue-xi-bi-ji-yi.html" rel="alternate"/><published>2021-12-29T18:53:28+08:00</published><updated>2021-12-29T18:53:28+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-12-29:/dockerxue-xi-bi-ji-yi.html</id><summary type="html">&lt;p&gt;我目前知道Docker是用Golang写的，然后有点类似于封装好的开箱即用的各种环境，简单有点说就是像一台手机上的各种APP。&lt;br /&gt;
现在就慢慢学一 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我目前知道Docker是用Golang写的，然后有点类似于封装好的开箱即用的各种环境，简单有点说就是像一台手机上的各种APP。&lt;br /&gt;
现在就慢慢学一下，至少感觉要比装个虚拟机强一点。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;安装&lt;/h2&gt;
&lt;p&gt;Windows平台看了一下，需要开启hyper-v和虚拟化，但是我用的电脑是家庭版，不支持这部分功能，所以直接没戏了。直接看Linux系统的安装了。&lt;br /&gt;
Linux安装很方便，直接下载get.docker.com的内容保存为shell脚本，然后运行即可。运行命令&lt;code&gt;curl -fsSL get.docker.com -o get-docker.sh&lt;/code&gt;就可以保存内容为脚本。之后运行shell脚本。&lt;br /&gt;
用docker version来查看安装是否成功，这时候只有客户端启动了，可以用&lt;code&gt;systemctl start docker&lt;/code&gt;来启动服务端。&lt;/p&gt;
&lt;h2 id="_2"&gt;容器和镜像&lt;/h2&gt;
&lt;p&gt;容器可以读写，镜像只能读。Docker Hub是封装好的容器的市场。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;docker container run xxx&lt;/code&gt;运行对应的含有关键词的容器，默认本地搜索，找不到的话会到Docker hub下载并运行对应的容器。&lt;/p&gt;
&lt;p&gt;用&lt;code&gt;docker container ls&lt;/code&gt;查看运行的容器，加&lt;code&gt;-a&lt;/code&gt;查看所有容器。&lt;/p&gt;
&lt;p&gt;用&lt;code&gt;docker container stop&lt;/code&gt;停止运行的容器，后面接ID的一部分就好。&lt;/p&gt;
&lt;p&gt;用&lt;code&gt;docker container rm&lt;/code&gt;删除容器，和上面一样接部分ID。&lt;/p&gt;
&lt;p&gt;管理多个容器：可以用&lt;code&gt;docker container ps -aq&lt;/code&gt;查看所有的ID，用&lt;code&gt;docker container stop $(docker container ps -aq)&lt;/code&gt;批量关闭所有的容器，同理也可以一口气把所有的容器都删除掉。组合命令的用法大概就是这样。&lt;/p&gt;
&lt;p&gt;运行的容器删除是删不掉的，会报错，可以加&lt;code&gt;-f&lt;/code&gt;后缀强制删除。&lt;/p&gt;
&lt;p&gt;容器端口的映射：使用&lt;code&gt;docker run (--detach/-d) -p local:container xxx&lt;/code&gt;来将容器的端口映射到本地主机的端口。tached模式是前台运行，加上&lt;code&gt;--detach&lt;/code&gt;是detached模式，是后台运行。后台切前台，用&lt;code&gt;docker attach id&lt;/code&gt;来实现。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker container logs (-f) id/imageid&lt;/code&gt;对后台的日志进行查看，&lt;code&gt;-f&lt;/code&gt;实现日志跟踪。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker run -it container sh&lt;/code&gt;以shell和容器进行交互模式。exit退出。可以用后台启动，再用&lt;code&gt;docker exec -it id sh&lt;/code&gt;来访问，这样就不会退出后关闭容器了。&lt;/p&gt;
&lt;h2 id="_3"&gt;获取和制作镜像&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;pull from registry hub.docker.com quay.io(没有官方认证)&lt;/li&gt;
&lt;li&gt;dockerfile (online)&lt;/li&gt;
&lt;li&gt;自有文件导入(offline)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一种方法获取镜像可以先在hub上搜索相关的内容，然后复制上面的命令，&lt;code&gt;docker image pull xxx&lt;/code&gt;可以下载对应的镜像，想要下载不同版本的镜像可以点击tag页面进行相关内容的查找。使用&lt;code&gt;docker image ls&lt;/code&gt;来查看本地存在的镜像。像是之前安装过容器，这时候就会有对应容器的镜像存在。使用&lt;code&gt;docker image inspect id&lt;/code&gt;来查看镜像的相关信息。用&lt;code&gt;docker image rm id&lt;/code&gt;来删除镜像。&lt;/p&gt;
&lt;p&gt;第二种方法，镜像的导入导出：使用&lt;code&gt;docker image save xximage:tag -o xxx.image&lt;/code&gt;在特定位置导出一个镜像，使用&lt;code&gt;docker image load -i ./xxx.image&lt;/code&gt;导入某一位置的镜像。这样可以离线进行镜像的分享，挺好。&lt;/p&gt;
&lt;p&gt;第三种方法，Dockerfile。是一种命令打包镜像的方法，需要一定时间的学习。&lt;/p&gt;
&lt;h2 id="_4"&gt;总结&lt;/h2&gt;
&lt;p&gt;时间拖的比较长，总之Dockfile的内容放在下一篇再说。&lt;/p&gt;</content><category term="学习笔记"/><category term="容器"/><category term="原创"/></entry><entry><title>报警脚本知识总结</title><link href="https://zhiyuansong.xyz/bao-jing-jiao-ben-zhi-shi-zong-jie.html" rel="alternate"/><published>2021-12-16T17:53:19+08:00</published><updated>2021-12-16T17:53:19+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-12-16:/bao-jing-jiao-ben-zhi-shi-zong-jie.html</id><summary type="html">&lt;p&gt;上篇文章说了自己最近事情比较少，基本上就是一个做报警脚本的工作，外加给他们拉点店铺数据打下手，倒也算乐的清 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;上篇文章说了自己最近事情比较少，基本上就是一个做报警脚本的工作，外加给他们拉点店铺数据打下手，倒也算乐的清闲，当然报警脚本这种东西之前是完全没有写过的，所以又陷入了两眼一抹黑的状态，还好有之前的代码，虽然完全没有注释（麻了，为什么大家写代码懒得写注释）。但是靠着问导师，至少磕磕绊绊两礼拜把东西做出来了，还挺好。稍微总结一下用到的知识，至少还是有点之前没接触到的东西的。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;流程&lt;/h2&gt;
&lt;p&gt;简单叙述一下思路，线上的脚本都是配置了对应的任务间隔的，大概是固定几小时更新一次，要做的就是监控脚本有多长时间没有做拉取报表的工作了，一旦超出对应的间隔一定倍数，就发送消息到一个通知容器里，会有机器人读取通知内容在群里进行通知。&lt;/p&gt;
&lt;p&gt;报告的成功时间是记录在日志表里的，直接读取对应的表就行，所以还是比较容易的，然后比较难获取的是时间间隔，这个东西配置在触发器里，一个类型一个，如果改成直接从触发器里读，就会异常的多，而且需要建立一个通知类型对应对应的触发器的表，以后如果要添加新的类型的话，难免会要反复对报警脚本的代码进行修修改改，头大。最后请教了一下，直接把任务间隔提到了一个配置文件里，让触发器和报警脚本都去读配置文件，这个问题就解决了。&lt;/p&gt;
&lt;p&gt;上面的内容已经基本解决了基本的报警逻辑，然后就是通知部分的写法了，如果每次运行脚本都会发送通知的话，恐怕通知就会异常的多，而且问题出现的话会相当频繁地进行通知，没有必要。之前代码解决这个问题是用缓存传入一个标志来完成的。大概就是一个过一段时间就会释放的值，每次访问的时候都会检测这个值是否存在，如果不存在了，才进行通知，通知后再填入一个缓存标志。如此循环。用这样的方式来避免过于频繁的通知消息发送。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;基本只是说了一下思路，具体怎么写就不做介绍了，毕竟其实也没什么难点，大概缓存那里的几个方法，像是put，has和get，看看就好。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="缓存"/><category term="原创"/></entry><entry><title>关于多选下拉列表的使用</title><link href="https://zhiyuansong.xyz/guan-yu-duo-xuan-xia-la-lie-biao-de-shi-yong.html" rel="alternate"/><published>2021-12-07T16:15:24+08:00</published><updated>2021-12-07T16:15:24+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-12-07:/guan-yu-duo-xuan-xia-la-lie-biao-de-shi-yong.html</id><summary type="html">&lt;p&gt;这周一开始没什么活可以给我，让我去给之前的亚马逊消息订阅系统添加了个增加订阅的功能，简单来说就是在通知类 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这周一开始没什么活可以给我，让我去给之前的亚马逊消息订阅系统添加了个增加订阅的功能，简单来说就是在通知类型页面上针对某个类型可以进行单个店铺区域的指定订阅，说起来其实不难。但是有个条件，它下拉列表要做成多选的，人麻了，完全不知道怎么写的那种，总之在九牛二虎之力下，这个问题算是勉强解决到了能用的程度。在这里总结一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;简述&lt;/h2&gt;
&lt;p&gt;只能说公司的东西过于老掉牙，框架也用不上，就只能拿jQuery来实现了。用的是Select2的插件，在我用的adminlte里面是有集成这个，所以怎么集成我倒是没有研究。&lt;/p&gt;
&lt;p&gt;这东西似乎和Bootstrap关系很大，得按照Bootstrap表单那一套来写，但是光说我也说不清楚，还是得上图。&lt;br /&gt;
&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20211207162436.png" /&gt;&lt;/p&gt;
&lt;p&gt;大概是个这么个形式，但是还没完，需要做的还有添加相关的js语句。虽然目前我并不理解只是添加了两句话就会让显示发生这么大变化的原理。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$('#account').select2().val({!! json_encode(request()-&amp;gt;get('account')) !!}).trigger('change');
        $('#area').select2().val({!! json_encode(request()-&amp;gt;get('area')) !!}).trigger('change');
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;这一步做完了，做出的效果大概是下面这个样子：

![](https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20211207162925.png)

简单来说就是点击显示下拉列表然后可以点击多选，重复点击取消选中。

最难的部分其实是取到框中有比较正常格式的值……我之前试着用text()来请求，然后就发现多选的各个值粘连成了一个字符串（可能用字符串解析的方法也能识别出来，但是很费脑子）。然后又试过用val()请求，但这样只能读到第一个值，之后多选的没了。只能说是痛苦。所幸在网上翻了很长时间发现了相关的请求方法，记录一下：
&lt;/pre&gt;&lt;/div&gt;
 javascript
function addSubscription() {
            let typeId = $(&amp;quot;#typeid2&amp;quot;).attr(&amp;quot;value&amp;quot;);
            let account = [];
            $(&amp;quot;#account option:selected&amp;quot;).each(function () {
                account.push($(this).val());
            });
            let area = [];
            $(&amp;quot;#area option:selected&amp;quot;).each(function () {
                area.push($(this).val());
            });
            let data = {
                '_token': &amp;quot;{{csrf_token()}}&amp;quot;,
                'account': account,
                'area': area
            };
            $.ajax({
                url: '/notification/notification_type/add_sub/' + typeId,
                type: 'GET',
                data: data,
                success: function (result) {
                    if (result.code == 'SUCCESS') {
                        alertify.success(&amp;quot;添加订阅成功,请稍侯&amp;quot;);
                    } else {
                        alertify.error(&amp;quot;添加订阅失败&amp;quot;);
                    }
                }
            });
            return false;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;主要是获取account和area的数据，这一部分我是通过把选中的元素推到一个空数组里面实现的，可能会有更好的方法，但是目前我也就只想到了这种。&lt;/p&gt;
&lt;p&gt;至于送到后端的事，就是做了一个组合，然后表内查找，存在推送队列云云……以下内容就不说了。&lt;/p&gt;
&lt;p&gt;下次大概能好用一点？感觉写原生前端就是在坐牢。麻呀。&lt;/p&gt;</content><category term="学习笔记"/><category term="前端"/><category term="原创"/></entry><entry><title>最近完成工作总结</title><link href="https://zhiyuansong.xyz/zui-jin-wan-cheng-gong-zuo-zong-jie.html" rel="alternate"/><published>2021-12-03T14:51:54+08:00</published><updated>2021-12-03T14:51:54+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-12-03:/zui-jin-wan-cheng-gong-zuo-zong-jie.html</id><summary type="html">&lt;p&gt;说是完成的工作其实这周也是回到了之前的拉数据环节中，没什么难的，就是整理要拉的字段和各种拉数据吃瘪上比较 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;说是完成的工作其实这周也是回到了之前的拉数据环节中，没什么难的，就是整理要拉的字段和各种拉数据吃瘪上比较难受罢了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;过程&lt;/h2&gt;
&lt;p&gt;说起来上次写的那点总结还是有点用的，至少我在差不多两个月没做这块业务的情况下能通过自己写的那点东西比较快的理清楚思路。比较常规的东西就做的很快。但这次还是有点不一样的地方的。&lt;/p&gt;
&lt;p&gt;首先是有的拉取过程缩短成一步了，之前大概是三步，请求，处理，下载；现在就变成了一步获取数据，接口的变化其实没什么，数据的组装也没什么，主要是让写的代码去适应之前的那套框架就比较难，没写过，也就参考了好久。&lt;/p&gt;
&lt;p&gt;第二个就是没接口了，这个东西不少得自己写，大概就是对一个网址进行请求，进行一个网址的拼接，说白了就是字符串，还行吧。&lt;/p&gt;
&lt;p&gt;第三个就是，不知道他要用哪些字段，产品经理整理的表格字段语焉不详，搞得我只能尽量全拉了，用不用以后再说，少拉了麻烦。&lt;/p&gt;
&lt;p&gt;差不多就是这么个情况，最近在看Golang的一点东西，还挺喜欢这种特别标准化的语言的，至少代码不会显得很乱，但是VS Code配置语言环境的时候有的插件根本下载不下来，就很气，但是暂时也没什么好办法。服了。&lt;/p&gt;
&lt;p&gt;以后还是得想个法子把这个问题解决一下。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>十月中旬到十一月下旬完成工作总结</title><link href="https://zhiyuansong.xyz/shi-yue-zhong-xun-dao-shi-yi-yue-xia-xun-wan-cheng-gong-zuo-zong-jie.html" rel="alternate"/><published>2021-11-25T18:22:08+08:00</published><updated>2021-11-25T18:22:08+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-11-25:/shi-yue-zhong-xun-dao-shi-yi-yue-xia-xun-wan-cheng-gong-zuo-zong-jie.html</id><summary type="html">&lt;p&gt;这段时间主要完成的是一个系统，大概是数据类型订阅再分发的相关系统，这个系统基本上自己从前端到后端都做了工 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这段时间主要完成的是一个系统，大概是数据类型订阅再分发的相关系统，这个系统基本上自己从前端到后端都做了工作，虽然各种不会，但也算是比较艰难的完成了工作，也算是学到了很多知识，大概再做一遍的话就不会这么狼狈了。&lt;/p&gt;
&lt;p&gt;还是得感谢导师了，自己写的这么慢，还能忍下来……😀&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;前端&lt;/h2&gt;
&lt;p&gt;我之前没写过前端，所以只能搭出那种最丑的界面，所以这段时间看了点Bootstrap，至少拯救了一下自己的界面，只能说还行，但是那一堆css美化标签看了着实想吐，果然前端大佬都是牛人，我是看见美化就头大。像模态框这种东西原生根本写不出来，只能靠BS了。&lt;/p&gt;
&lt;p&gt;然后让人头大的就是js做异步了，只能说没做过，之前学的也就是直接界面上action一个路由，把东西传过去，那这样肯定就是同步的了啊……然后去学习了jQuery和AJAX，怎么说呢，学着还行，反正异步只是换了种方法把参数传到控制器函数中，后端基本变化不大。主要是blade模板数据怎么让js去使用研究了好半天，令人头大。&lt;/p&gt;
&lt;p&gt;说起来感觉Laravel写界面真的难受，php夹杂着前端代码一锅乱炖，看的人眼花缭乱，做的实在是痛苦不堪，我被忽悠着搞不清什么同步什么异步已经够难受了，然后还要面对碎成一团的前端……&lt;/p&gt;
&lt;h2 id="_2"&gt;后端&lt;/h2&gt;
&lt;p&gt;主要是知道了代码要按功能逻辑分层，像是专门访问数据库表模型，Laravel方法要放在一个文件里，方便复用，我第一次就直接在控制器函数里边用了……总之控制器函数只是完成了流程，具体的功能要拆分到各个文件中。&lt;/p&gt;
&lt;p&gt;然后就是数据库表的使用，基本上算是把东西搞的可以看着写了，像是主键可以直接在路由访问对应的对象，还有就是各种增删改查……感觉后端就是各种查表，组装数据，然后送到前端视图去。至于前端怎么处理，大概就是夹杂着php的前端代码，所以啊，老痛苦了，这前后端不分离，php终究只能做点小家子气的东西，写的不好还痛苦。&lt;/p&gt;
&lt;h2 id="_3"&gt;总结&lt;/h2&gt;
&lt;p&gt;算了，学还是要学的，明明自己菜的要死还要装的很会。不装了，我摊牌了，这不会的还有太多了！&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>近期需求完成整理</title><link href="https://zhiyuansong.xyz/jin-qi-xu-qiu-wan-cheng-zheng-li.html" rel="alternate"/><published>2021-10-12T16:07:29+08:00</published><updated>2021-10-12T16:07:29+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-10-12:/jin-qi-xu-qiu-wan-cheng-zheng-li.html</id><summary type="html">&lt;p&gt;这段时间应该是完成了两个需求，一个账号字段的转换，另一个是调试一个触发式的代码，大概第二个需求比较恶心，我得 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这段时间应该是完成了两个需求，一个账号字段的转换，另一个是调试一个触发式的代码，大概第二个需求比较恶心，我得算是从国庆前就开始调试了，这十几天都过去了……还行吧不过，至少我记得上个月月末在复习，然后又是五天的假，那么看来大概是花了一周多的时间去调试代码。&lt;/p&gt;
&lt;p&gt;大概就是这么多，东西还是学到了一些的。总结总结。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="listing"&gt;某店铺的Listing数据报告拉取不到……&lt;/h2&gt;
&lt;p&gt;简单来说需要先把数据拿下来看一下结构，之前用dump但是不好使，一条数据的量就已经很长了，而且有类似表格的结构，单纯用命令行不太好使，需要把内容写到文件里。这里使用的是Laravel的path函数。用来读取特定文件的路径，再加上文件写入函数之类的就够了。&lt;/p&gt;
&lt;p&gt;这个时候查看会发现有乱码，发现这个店铺的字段用的是德语，而且编码使用的不是utf-8，所以和数据库的英文字段对不上。&lt;/p&gt;
&lt;p&gt;最后是根据是否存在的德语字段和特定店铺账号做了一下编码转换和字段名转换处理，目前因为是只有一个店铺存在这个问题，所以就直接写死在代码里了。&lt;/p&gt;
&lt;p&gt;这次的需求和上次拉数据的需求是差不多的结构，问题倒不是很大。&lt;/p&gt;
&lt;h2 id="_1"&gt;代码调试&lt;/h2&gt;
&lt;p&gt;本次调试的代码是大概根据一个商品的站点和商品编码数据来抓取星级和排名两个数据再写回到elasticsearch和数据库里面。其实逻辑上不难，但是数据上，脚本上是用了不少elasticsearch的相关查找方法，自己一开始不太熟，然后抓数据也不是什么时候都能抓到的。就调试很困难，再加上拉上数据后回写这一部分函数感觉基本上和前面拉取是没什么关系的，回写函数是触发式的，也没法确定什么时候会触发，那就没法用dd和dump来导出数据了。&lt;/p&gt;
&lt;p&gt;其实可以参照上面的需求来做的，直接用文件写入函数写进去，不过这里用的是日志，感觉日志使用也比较简单，在配置文件里配置logging.php里的通道，然后就可以在对应通道写入相关的内容即可。这样在模拟数据对接口写入的时候也算是比较方便可以查看数据的内容。&lt;/p&gt;
&lt;p&gt;然后是对接口推数据的相关内容，这里主要是使用postman来推模拟数据，感觉使用比较简单，选择方法，输入url，之后就贴相关的内容就可以了。主要是读json数据，填到字段里组装一下就行了。&lt;/p&gt;
&lt;p&gt;其他的，感觉调试拉取数据那部分，我现在还是有点不太懂，因为没有数据，没办法，只能看一下相关的逻辑结构就完事了。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;可能就是学习了一下调试代码的相关知识，其他的就多看就会了。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>MongoDB学习笔记</title><link href="https://zhiyuansong.xyz/mongodbxue-xi-bi-ji.html" rel="alternate"/><published>2021-09-28T15:55:06+08:00</published><updated>2021-09-28T15:55:06+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-28:/mongodbxue-xi-bi-ji.html</id><summary type="html">&lt;p&gt;说起来MongoDB是和Redis相类似的NoSQL数据库，但是你让我说他们之间有什么不同，我还真的说不出来，感觉一个更强调键值组织成的json格式数据组成的所谓“文档”，另一个单纯就是 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;说起来MongoDB是和Redis相类似的NoSQL数据库，但是你让我说他们之间有什么不同，我还真的说不出来，感觉一个更强调键值组织成的json格式数据组成的所谓“文档”，另一个单纯就是存放个键值对、列表这种数据结构吧。&lt;/p&gt;
&lt;p&gt;安装的版本是windows版本，安装这部分内容就不提了，百度即可。本着能把语句学到就是胜利的原则，先学再说。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;创建和删除数据库&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;db&lt;/code&gt;这两个字母就可以显示出当前使用的数据库，&lt;code&gt;show dbs&lt;/code&gt;就可以查看当前所有的数据库名字，而&lt;code&gt;use 数据库名&lt;/code&gt;可以切换/创建数据库，所谓有就切换，没有就创建，就这么简单。&lt;/p&gt;
&lt;p&gt;删除当前所在数据库使用&lt;code&gt;db.dropDatabase()&lt;/code&gt;，务必看清楚当前所在的数据库，免得误删。&lt;/p&gt;
&lt;h2 id="_2"&gt;创建和删除集合&lt;/h2&gt;
&lt;p&gt;集合是在数据库中的，算是文档的集合，很像关系型数据库的一张表吧。文档简单解释就是一串json数据，差不多存放了一个对象的数据，所以文档差不多就是一群有相似特征的对象的集合。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;db.createCollection(name,options)&lt;/code&gt;来创建一个集合。&lt;code&gt;name&lt;/code&gt;其实没什么说的，就是&lt;code&gt;options&lt;/code&gt;几个参数，像是限制了集合的大小&lt;code&gt;cappped&lt;/code&gt;和&lt;code&gt;size&lt;/code&gt;、限制了包含文档的最大数量&lt;code&gt;max&lt;/code&gt;等。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;show collections/tables&lt;/code&gt;来查看已存在的集合名。使用&lt;code&gt;db.xxx.find()&lt;/code&gt;列出所有xxx集合的文档。&lt;/p&gt;
&lt;p&gt;甚至不用自己创建集合，当你使用&lt;code&gt;db.xxx.insert()&lt;/code&gt;插数据时，直接就会建一个xxx集合。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;db.xxx.drop()&lt;/code&gt;删除xxx这张集合表。&lt;/p&gt;
&lt;h2 id="_3"&gt;插入、删除和修改文档&lt;/h2&gt;
&lt;p&gt;简单来说文档对应的就是关系型数据库的表里的一个条目。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;db.xxx.insert/insertOne()&lt;/code&gt;向xxx集合插入一条文档，使用&lt;code&gt;db.xxx.insertMany()&lt;/code&gt;向集合插入多条文档。&lt;/p&gt;
&lt;p&gt;修改使用&lt;code&gt;db.xxx.update()&lt;/code&gt;，主要是两个参数大括号，一个是要修改的字段，另一个是修改后的字段。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;db.xxx.deleteOne/deleteMany()&lt;/code&gt;可以删除一条/多条文档。&lt;/p&gt;
&lt;p&gt;查找上面说过了。&lt;/p&gt;
&lt;h2 id="_4"&gt;创建和删除索引&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;db.xxx.createIndex()&lt;/code&gt;创建集合的索引，参数基本上以列名：1/-1的格式来写，标识升序还是降序创建索引，可选参数暂时略过，下次再说。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;db.xxx.dropIndex()&lt;/code&gt;来删除集合的索引。&lt;/p&gt;
&lt;h2 id="_5"&gt;关系判断符&lt;/h2&gt;
&lt;p&gt;gt、lt、gte、lte，说实话这些判断符和elasticsearch的判断符基本一样，没什么变化的。&lt;/p&gt;
&lt;h2 id="_6"&gt;总结&lt;/h2&gt;
&lt;p&gt;这种实操类的写再多也可能有没写到的地方。只能靠时间去慢慢积累了。&lt;/p&gt;</content><category term="学习笔记"/><category term="MongoDB"/><category term="NoSQL"/><category term="原创"/></entry><entry><title>PHP几个概念辨析</title><link href="https://zhiyuansong.xyz/phpji-ge-gai-nian-bian-xi.html" rel="alternate"/><published>2021-09-27T11:03:07+08:00</published><updated>2021-09-27T11:03:07+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-27:/phpji-ge-gai-nian-bian-xi.html</id><summary type="html">&lt;p&gt;做了点测试题，复习几个概念，写一下理解，免得再去看别人写的东西。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="globalstatic"&gt;global和static&lt;/h2&gt;
&lt;p&gt;global是函数内访问全局变量的前缀。全局变量就是在所有的括号外边定义的变量，全 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;做了点测试题，复习几个概念，写一下理解，免得再去看别人写的东西。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="globalstatic"&gt;global和static&lt;/h2&gt;
&lt;p&gt;global是函数内访问全局变量的前缀。全局变量就是在所有的括号外边定义的变量，全局可访问。&lt;/p&gt;
&lt;p&gt;全局变量的访问有这么两种情况，第一是在函数内部的变量名前加上global关键字，像是&lt;code&gt;global $x&lt;/code&gt;和&lt;code&gt;$x&lt;/code&gt;很明显就不是一个东西，第二是可以通过访问$GLOBALS数组来访问全局变量，PHP所有的全局变量都放在了这里，以关联数组的方式来访问即可。&lt;/p&gt;
&lt;p&gt;static是生存期在整个文件跑完销毁之前，里面的数据不会被抹掉。但是不是局部变量，总之全局变量和静态变量没有共同的地方，根本就是两个东西。&lt;/p&gt;
&lt;h2 id="define"&gt;define 常量&lt;/h2&gt;
&lt;p&gt;简单来说define不是一个关键字，而是一个函数，定义了常量的名字和内容。常量的前面不能加$符号。&lt;/p&gt;
&lt;h2 id="_1"&gt;数值数组和关联数组的排序函数&lt;/h2&gt;
&lt;p&gt;sort()、rsort()、arsort()、krsort()、asort()、ksort()&lt;/p&gt;
&lt;p&gt;简单来说带r的就是降序排序，带k的是对关联数组的键排序，带a的是对关联数组的值排序。&lt;/p&gt;
&lt;h2 id="_2"&gt;超级全局变量&lt;/h2&gt;
&lt;p&gt;这个最典型的就是$GLOBALS，还有其他的可能用的时候需要查一下&lt;/p&gt;
&lt;h2 id="foreach"&gt;foreach&lt;/h2&gt;
&lt;p&gt;这个东西是只能拿来遍历数组的。&lt;/p&gt;
&lt;p&gt;这个东西用数据模板，大概定义就是&lt;code&gt;$array as $arrayKey=&amp;gt;$arrayName&lt;/code&gt;的格式，自己定义，然后再按照定义的模板访问访问，有时候不是关联数组，就不用键值格式的模板。&lt;/p&gt;
&lt;h2 id="_3"&gt;魔术常量&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;__FILE__&lt;/code&gt;、&lt;code&gt;__LINE__&lt;/code&gt;、&lt;code&gt;__DIR__&lt;/code&gt;、&lt;code&gt;__FUNCTION__&lt;/code&gt;、&lt;code&gt;__CLASS__&lt;/code&gt;、&lt;code&gt;__TRAIT__&lt;/code&gt;、&lt;code&gt;__METHOD__&lt;/code&gt;、&lt;code&gt;__NAMESPACE__&lt;/code&gt;这几个量依据自己出现的位置不同而值不同，有的时候编程会比较方便，主要还是记一下功能。&lt;/p&gt;
&lt;h2 id="oop"&gt;OOP&lt;/h2&gt;
&lt;p&gt;特点是封装、继承、多态。&lt;/p&gt;
&lt;p&gt;大多数面向对象的东西基本上感觉和Java是差不多的，像是只支持单继承，有接口等等。&lt;/p&gt;
&lt;p&gt;但是PHP多了一个trait的继承。trait不能实例化，用use关键字引入，会覆盖基类的继承方法或属性，以及可以多继承等等。感觉像个变了个样子的interface，但是PHP本身就有interface，就很乱。&lt;/p&gt;
&lt;p&gt;final关键字也是有的，功能差不多，不接受函数/类的重写之类的。&lt;/p&gt;
&lt;p&gt;调用父类的构造方法基本上也是&lt;code&gt;parent::__construct()&lt;/code&gt;这个样子。&lt;/p&gt;
&lt;h2 id="_4"&gt;做题学到的知识&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;自己定义的函数名字PHP对大小不敏感，定义成&lt;code&gt;FUNCTION FUN()&lt;/code&gt;这种鬼样子照样可以用&lt;code&gt;fun()&lt;/code&gt;来调用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PHP除了可以用C++的两种注释方式外，shell的#注释也是可以使用的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;关联数组因为可以直接插值又可以指定下标插值，所以经常会出问下标这种题恶心人，最后一个直接插值的找前面的指定下标插值的最大下标，肯定是比这个值大的，具体大几就要看最后直接插值插了几个了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;空数组会转化成null，在一些判断结构里老是坑人。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;三元运算符&lt;code&gt;?:&lt;/code&gt;别被绕晕了，就是从左向右运算，&lt;code&gt;?&lt;/code&gt;前的一定是个bool运算式，别看见了一脸蒙就行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;数值字符串比较按整数处理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有时候一些奇奇怪怪的东西会当关联数组的下标，像是null，true，false等，null等价成&amp;rsquo;&amp;lsquo;，true等价成1，false等价成0，有的题很坏，拿这些混淆视听，问你有几个下标，其心可诛。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;个人测试，单引号字符串不能识别&lt;code&gt;\n&lt;/code&gt;标识，只会当字符显示出来，但是&lt;code&gt;\\&lt;/code&gt;却能识别成一个反斜杠，太离谱了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;关于&lt;code&gt;headers_list()&lt;/code&gt;和&lt;code&gt;headers_sent()&lt;/code&gt;的区别，请看下图：&lt;br /&gt;
&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20210927155148.png" /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;include引入文件好几次也不会报错的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;upload_max_file_size默认2M&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;其他零零碎碎的东西：&lt;/p&gt;
&lt;p&gt;trim()移除字符串两侧字符&lt;/p&gt;
&lt;p&gt;rand()&lt;/p&gt;
&lt;p&gt;array_slice()&lt;/p&gt;
&lt;p&gt;isset()检查变量&lt;/p&gt;
&lt;p&gt;fread()文件读取&lt;/p&gt;
&lt;p&gt;is_a()对象类型判断&lt;/p&gt;
&lt;p&gt;get_parent_class()&lt;/p&gt;
&lt;p&gt;prev()&lt;/p&gt;
&lt;p&gt;header()向客户端发送原始的HTTP报头&lt;/p&gt;
&lt;p&gt;eregi()搜索指定模式字符串，不分大小写&lt;/p&gt;
&lt;p&gt;glob()返回匹配指定模式的文件名或目录&lt;/p&gt;
&lt;p&gt;memory_get_usage&lt;/p&gt;
&lt;p&gt;gzcompress()&lt;/p&gt;
&lt;p&gt;strtoupper()&lt;/p&gt;
&lt;p&gt;session() 1440s&lt;/p&gt;
&lt;p&gt;使用父方法调用方法时应该使用对静态方法的静态引用&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_5"&gt;结语&lt;/h2&gt;
&lt;p&gt;东西有太多零碎的东西了，最后一部分等我抽时间补完，主要是有些自带函数平时用的少。难顶。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="原创"/></entry><entry><title>MySQL学习笔记</title><link href="https://zhiyuansong.xyz/mysqlxue-xi-bi-ji.html" rel="alternate"/><published>2021-09-25T11:00:27+08:00</published><updated>2021-09-25T11:00:27+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-25:/mysqlxue-xi-bi-ji.html</id><summary type="html">&lt;p&gt;上次整理了一篇SQL基础知识，我记得基本上是把增删改查这类知识总结了一下，基本的语句问题倒是少了，可能是连接查询和其他 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;上次整理了一篇SQL基础知识，我记得基本上是把增删改查这类知识总结了一下，基本的语句问题倒是少了，可能是连接查询和其他的方面有点弱，可以抽时间再练一练。&lt;/p&gt;
&lt;p&gt;这次要解决的主要是数据库主从复制、MySQL索引和SQL优化、锁和事务这些平常的基础教程里讲的比较少的东西。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;数据库主从复制&lt;/h2&gt;
&lt;p&gt;解决单点故障问题和提高整体服务性能。最粗略的说法是，其实大概就是异步备份吧。&lt;/p&gt;
&lt;h2 id="_2"&gt;索引&lt;/h2&gt;
&lt;p&gt;索引快，是因为数据库额外为索引字段存储建了结构，像是B+树，这样的查询效率要比遍历查找块，接近二分查找的速度。极端情况下（更新少、请求频繁、实时性低）可以建一个单项有序序列，用二分法最快。&lt;/p&gt;
&lt;p&gt;索引分普通索引、唯一索引（保证元素在列中的唯一性）、主键（主键默认创建了索引）、单列索引、多列索引（满足最左前缀原则，即部分使用多列索引，优先用最左边的部分，若是用的部分在右边索引的效果就不是太好）。&lt;/p&gt;
&lt;h2 id="sql"&gt;SQL的优化&lt;/h2&gt;
&lt;p&gt;可以对某些较大的数据库进行拆库，或者拆表。&lt;/p&gt;
&lt;p&gt;拆表使用的方法有两种，水平拆分和垂直拆分，水平拆分其实就是限制表的规模,再建一张副表。垂直拆分就是把字段拆出来，像是不常用的字段，可以单独拆出来，这样就可以减轻查找时候的负担了。&lt;/p&gt;
&lt;p&gt;少用*查找，最好只指定自己需要的字段。关联查询用小表驱动大表。名字太长的字段名和表名用别名替换。字符串加引号。不要设置字段为NULL，用空字符串都能减轻SQL的负担。&lt;/p&gt;
&lt;p&gt;参考explain的过程说明来优化SQL的执行过程。&lt;/p&gt;
&lt;h2 id="_3"&gt;锁&lt;/h2&gt;
&lt;p&gt;从个人角度理解，锁就是对资源访问的限制吧，若是没有限制，资源访问就会出现各种问题。&lt;/p&gt;
&lt;p&gt;锁分悲观锁和乐观锁。&lt;/p&gt;
&lt;p&gt;悲观锁和乐观锁是一种概念。不是指实际的实现。像是悲观锁，针对的大多针对的时写多读少的情景，他就假设每次一个进程修改数据时都会被另一个进程访问到，为了防止这种情况的发生，每次修改数据前，进程都会对内存加锁，禁止掉其他进程读写权限。乐观锁针对的一般是写少读多的情况，所以假设数据一般不会发生被修改，所以只有在提交的时候才会对数据进行查验。可以设置一个version，每次修改都会对version加1，这样通过核对version的值，很容易就知道了数据有没有被修改了。&lt;/p&gt;
&lt;p&gt;悲观锁还分共享锁和互斥锁。共享锁是只对读这个权限进行共享，但是写还是不行的。互斥锁简言之就是不管读写每次都会先把进程锁了。当然并发度就会差不少。&lt;/p&gt;
&lt;p&gt;针对数据库的锁的分类，大概分表级锁、页级锁和行级锁。表级锁开销小，速度快、粒度大，但是很明显并发度不够，经常会发生冲突。行级锁是针对表中的一行进行的锁，开销大，速度慢，但是冲突概率低，并发度高。页级锁的性能基本上介于表级锁和行级锁之间。现在的MySQL，使用的InnoDB默认使用的就是行级锁。主要是并发的效果好一些。&lt;/p&gt;
&lt;p&gt;死锁处理目前有这几个方法，一是超时结束任务，二是死锁检测，发生死锁后回滚事务。&lt;/p&gt;
&lt;h2 id="_4"&gt;事务&lt;/h2&gt;
&lt;p&gt;事务其实就是一组连续的数据库操作。这一组操作必须要么全执行完，要么全部不执行，不存在执行到一半了突然出了问题不执行的情况。&lt;/p&gt;
&lt;p&gt;事务的四个特点、原子性（一个事务就是一个整体，要么成功要么全不执行）、隔离性（多事事务之间操作互相独立，不能发生干涉）、一致性（执行事务只是从一个一致状态到另一个一致状态）、持久性（事务一旦提交，造成的影响是持久存在的，数据库故障也不会丢失提交事务的操作）。&lt;/p&gt;
&lt;p&gt;事务隔离级别基本存在四种情况，读未提交，读提交，可重复读、串行化。&lt;/p&gt;
&lt;p&gt;先介绍三个概念。脏读、不可重复读和幻读。&lt;/p&gt;
&lt;p&gt;脏读指一个事务修改了事务但还没提交的时候另一个事务却已经能从事务上读到这个还没提交的数据了。&lt;/p&gt;
&lt;p&gt;不可重复读，一个事务读取同一条记录两次，但是得到的内容不一样。&lt;/p&gt;
&lt;p&gt;幻读是一个事务读两次，但是记录的条目数量不一样。无中生有或者不翼而飞了属于是。&lt;/p&gt;
&lt;p&gt;上面事务隔离程度依照从左往右依次变高。&lt;/p&gt;
&lt;p&gt;读未提交不能阻止上面的问题，最不安全。读提交制止了脏读操作，但是共享操作的存在违反了事务的隔离性，每次修改的新值都能读到。可重复读是制止了脏读和不可重复读，每次只会显示第一次读取的值。串行化问题是写不能读，读不能写，不能并发。&lt;/p&gt;
&lt;h2 id="_5"&gt;总结&lt;/h2&gt;
&lt;p&gt;理解概念，记在脑子里。&lt;/p&gt;</content><category term="学习笔记"/><category term="SQL"/><category term="MySQL"/><category term="原创"/></entry><entry><title>PHP学习笔记（二）</title><link href="https://zhiyuansong.xyz/phpxue-xi-bi-ji-er.html" rel="alternate"/><published>2021-09-22T15:59:28+08:00</published><updated>2021-09-22T15:59:28+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-22:/phpxue-xi-bi-ji-er.html</id><summary type="html">&lt;p&gt;看了下上一篇PHP学习笔记写的好像没有什么营养，只能说时间过的好快，转眼之间就到9月底了，说是29号有这方面知识的考试。孩子战战兢兢。只能早早整理相关知识。目前看大概有三块 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;看了下上一篇PHP学习笔记写的好像没有什么营养，只能说时间过的好快，转眼之间就到9月底了，说是29号有这方面知识的考试。孩子战战兢兢。只能早早整理相关知识。目前看大概有三块内容，我尽快在本周内复习完成。&lt;/p&gt;
&lt;p&gt;这块内容主要是PHP的相关知识，就算在相关学习笔记了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;开发环境和工具&lt;/h2&gt;
&lt;p&gt;上一篇提到过了，基本上是LNMP或者LAMP，我最近做Laravel相关的东西甚至直接有官方配好的Homestead环境，所以这块基本上就是配着玩的。自己在云主机上装过一遍了，挺好的。还是难在PHP的编译安装上了，上一篇没有记录，个人感觉基本上拿着对应版本号的包去网上搜，然后照着做，基本问题不大。至于编辑器IDE什么的，自己看着弄吧，VS Code我是心累了，如今也就是拿来写写博客。&lt;/p&gt;
&lt;h2 id="_2"&gt;编程工具和扩展安装&lt;/h2&gt;
&lt;p&gt;略，主要是针对VS Code的。&lt;/p&gt;
&lt;h2 id="php"&gt;PHP基础和动静结合&lt;/h2&gt;
&lt;p&gt;一个面向对象编程语言的基本组成部分大概就是一堆关键词，三种逻辑结构，还有自带函数、面向对象内容等等。感觉主要是后边两个部分有点需要看看，前面部分实在没什么可说的。&lt;/p&gt;
&lt;p&gt;动静结合指的就是网页和PHP搭配处理请求吧，我印象中这块也没什么，毕竟动态请求处理自然而然就这样了。&lt;/p&gt;
&lt;h2 id="php_1"&gt;PHP语法简介、异常处理和垃圾回收机制&lt;/h2&gt;
&lt;p&gt;异常处理可以用&lt;code&gt;die()&lt;/code&gt;，直接输出一个字符串结束程序。&lt;/p&gt;
&lt;p&gt;try正常的代码，catch处理相关的异常，throw抛出异常。简单来说就是函数抛出的一场有catch负责处理。&lt;/p&gt;
&lt;p&gt;以上就是异常处理部分的相关内容。&lt;/p&gt;
&lt;p&gt;垃圾回收机制主要是基于变量存储容器（zval）上的访问记录数，数为零，自然就会被释放掉。垃圾回收使用一个轮询删除函数来实现的。&lt;/p&gt;
&lt;h2 id="_3"&gt;函数式编程、面向对象编程、类加载、命名空间&lt;/h2&gt;
&lt;p&gt;函数式编程和面向对象编程，难度不高，主要是有个继承调用等等的关键字，这个部分的内容需要看，像是trait、final无法被重写和继承&lt;br /&gt;
命名空间主要是限制变量的名称重复这种现象，同时，可以用use关键字来给类或命名空间取别名。&lt;/p&gt;
&lt;h2 id="psr"&gt;编程规范、psr、编程范式&lt;/h2&gt;
&lt;p&gt;多读几遍PSR编程规范就行，没多少东西。&lt;/p&gt;
&lt;h2 id="php_2"&gt;PHP执行原理、依赖扩展的加载和安装&lt;/h2&gt;
&lt;p&gt;执行原理方面，其实基本上是分成三层的，最底层的是Zend Engine，是一个用C语言写成的PHP核心，Zend Engine负责把PHP代码翻译成类似于Java在虚拟机中跑的那种东西，叫所谓的opcode。PHP其实最下层调用的还是C语言的相关函数，所以可以把PHP看成是在C语言上层的一个软件实现。&lt;/p&gt;
&lt;p&gt;SAPI指的是实现了PHP和最上层应用程序的结构分离的相关结构，像是上面提过的CGI和Fast-CGI等，其实我也说不太清楚它究竟是干什么的，大概是个桥梁？&lt;/p&gt;
&lt;p&gt;最上层就是编写的应用程序了，通过SAPI获得各种各样的调用方式。&lt;/p&gt;
&lt;p&gt;依赖扩展的加载和安装部分略，这部分之后还会继续强调的。&lt;/p&gt;
&lt;h2 id="php_3"&gt;PHP设计模式&lt;/h2&gt;
&lt;p&gt;课上主要讲了四种设计模式：简单工厂、工厂方法、单例和策略。&lt;/p&gt;
&lt;p&gt;说实话之前完全没有接触过这块知识，只知道它有本黑皮书，写的很牛逼。尝试把这点东西啃下来。&lt;/p&gt;
&lt;h3 id="_4"&gt;简单工厂模式（静态工厂方法）&lt;/h3&gt;
&lt;p&gt;简单来说，这个模式一共有三种类，第一个是个抽象类，定义了产品的基本属性；第二个是具体产品类，继承了第一个抽象类，实现了具体功能；第三个是工厂类，这个类大概只有一个方法，还是静态的，它专门负责具体产品的实例化，简单来说就是写一个if或者switch判断，根据传入的参数来实例化对应的产品。&lt;/p&gt;
&lt;p&gt;简单来看，它把类的功能逻辑和类的实例化部分分割开了，耦合度降低，同时，实例的构建者并不需要知道实例对应类的全名，只需要知道对应这个类的参数就行了，只要设计合理的参数（像是针对第四次和第五次圣杯战争里的阿尔托莉雅可以直接指代成Saber这个东西😂，懂的都懂），就可以十分便利地完成实例化工作。&lt;/p&gt;
&lt;p&gt;但是缺点还是有的，首先，工厂类太重要了，负责了全部的实例化工作，一旦它崩了，整个系统就完蛋了；其次，每次增添新的产品实例化功能，都要修改工厂类的实例化方法，而且一旦产品多了，整个系统的类的数量和工厂类的实例化方法都会变得庞大，难以理解；最后，工厂类的静态工厂方法难以形成基于继承的体系结构，工厂就这么大，没法进一步扩展了。&lt;/p&gt;
&lt;h3 id="_5"&gt;工厂方法模式&lt;/h3&gt;
&lt;p&gt;这个模式是简单工厂模式的改进型，主要是对工厂类进行了改造，建了一个抽象工厂基类，规定了必须实现的接口，再针对具体的产品实例化构建相对应的工厂类，由实际的工厂类实现负责产品的实例化。&lt;/p&gt;
&lt;p&gt;刚开始看完我还有点蒙，上一步好歹有判断语句来判断调用哪个产品类完成实例化，这个可是没有判断语句了啊，我怎么知道要用哪个产品类实例化啊？对，构建者确实不知道该用哪个实例化，但他知道该去哪个对应的工厂，这就足够了，毕竟现在一个工厂负责一种产品，那么只要去了工厂，就一定能拿到产品（有点类似于把上一步中的创建阿尔托莉雅变成去Saber工厂提货就行了😂）。&lt;/p&gt;
&lt;p&gt;好处是，扩展性很好，想要扩展新产品，不需要改代码了，直接继承写对应的具体产品类和工厂类就行，把具体实例化的细节完全封在了工厂类里，创建者不需要知道产品的细节，只要知道去哪个工厂类完成实例化就行。&lt;/p&gt;
&lt;p&gt;坏处是，可能类的个数要比上一个翻一番了，毕竟每次都是成对增加内容的，开销是有的；其次，抽象类的使用可能增加了理解难度，还可能用到一些比较不好理解的编程技术，实现变难了。&lt;/p&gt;
&lt;p&gt;扩展向：① 抽象工厂类可以定义多个工厂方法，这样针对多种产品类可以有多种选择 ② 创建过的产品可以存在数组或列表中，若后续请求直接有创建过的产品，就可以直接给出，没有的话可以创建后塞到数组中，再给出。&lt;/p&gt;
&lt;h3 id="_6"&gt;单例模式&lt;/h3&gt;
&lt;p&gt;简单来说，有的类有只实例化出一个对象的需求，这种模式就应运而生了。&lt;/p&gt;
&lt;p&gt;简单来说，要满足三点要求，第一，只有一个实例；第二，自动创建实例；第三，提供全局访问实例的方法。&lt;/p&gt;
&lt;p&gt;注意的点是：首先单例类的构造函数是私有的，只有访问函数那一步，里面判断实例为空的情况才会调用构造函数。这样也防止了非法构建重复实例。其次访问实例的方法应该是公有的静态方法。最后实例化标志是一个静态私有成员变量，类型其实是个单例指针类型？默认是NULL。&lt;/p&gt;
&lt;p&gt;优点是受控访问，节约系统资源，更可以进一步扩展到限定实例化数量的类的相关实现。&lt;/p&gt;
&lt;p&gt;缺点是扩展性差，任务太重，GC容易被杀和乱用程序崩掉。&lt;/p&gt;
&lt;p&gt;应用：唯一序列号生成器，防止生成的序号重复。&lt;/p&gt;
&lt;h3 id="_7"&gt;策略模式&lt;/h3&gt;
&lt;p&gt;总的来说，像是从A到B，有好多条道路，那么就可以把这好多条道路依次列出来，只要能完成从A到B的任务就好了。选择的权力完全交给使用方，系统本身不做推荐。像是一组排序算法、一组查找算法……都可以这么组织。&lt;/p&gt;
&lt;p&gt;基本上就是先建一个类似接口的东西说明一下要实现的功能，再去具体继承接口完成相关功能即可。&lt;/p&gt;
&lt;p&gt;优点是，算法可自由切换，不用使用判断语句，扩展也方便。&lt;/p&gt;
&lt;p&gt;缺点是，策略类多了的话体积会很庞大，同时每个具体的策略都要对外开放调用权限。&lt;/p&gt;
&lt;h2 id="phpcomposer"&gt;PHP开源社区和开源包的管理，composer的使用&lt;/h2&gt;
&lt;p&gt;基本上就是几个网站上找动态链接库，composer目前大概掌握require和install命令就行，可能之后补充一个composer操作什么的？&lt;/p&gt;
&lt;h2 id="_8"&gt;结语&lt;/h2&gt;
&lt;p&gt;东西说多也不多，还是要注重基础。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="原创"/></entry><entry><title>6日到11日工作内容总结</title><link href="https://zhiyuansong.xyz/6ri-dao-11ri-gong-zuo-nei-rong-zong-jie.html" rel="alternate"/><published>2021-09-11T14:49:03+08:00</published><updated>2021-09-11T14:49:03+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-11:/6ri-dao-11ri-gong-zuo-nei-rong-zong-jie.html</id><summary type="html">&lt;p&gt;这周开始做了上周导师布置的需求任务，做到今天上午才算是基本没有问题了，从对流程一无所知到现在有了一点模模 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这周开始做了上周导师布置的需求任务，做到今天上午才算是基本没有问题了，从对流程一无所知到现在有了一点模模糊糊的印象，我得记一下。免得以后做相似东西的时候出事情，这样也能提升我下次的开发速度吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;这次做的东西应该只能算是一个拉取数据的功能的一部分吧。我完成的是拉取亚马逊店铺的SD数据到对应的数据表的这项工作。至于什么是SD数据，我并不清楚。只能说不知道做的是什么确实很头疼，照着人家之前写的代码做些调整加些内容上去能跑通就算成功……&lt;/p&gt;
&lt;p&gt;简单总结一下流程，首先是整个模块分成两个部分，数据库部分和代码部分，代码是基于Laravel框架的，所以数据库中的表和Laravel框架交互基于的是App\Models里建的对应模型。还记得之前敲代码的时候完全不知道拉到的数据是怎么传到对应的表里的，这下了解了。&lt;/p&gt;
&lt;p&gt;代码部分增加文件的部分除了上面提到的Models外，还有Dispatchers和Jobs文件夹，一个Dispatcher对应一个Job，调用的开始就是基于DisPatcher的，里面给我影响比较深的就是要配置一个工作类型的字符串，这个字符串的工作流程直接反映在数据库的一个工作配置表中，由一个json字符串来控制流程的细节等等，像是缓存、队列等等。Job应该是承接了上面的Dispatcher发布的任务，同时呢Job应该要在报告类型的Job中进行对应类型和Job的注册。最基本的类型Job继承了对应的基本Job,这里规定了工作的主要流程，这个基本Job继承了大类的Job，这里对相关的任务类型和类型Job进行记录。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20210911152313.png" /&gt;&lt;/p&gt;
&lt;p&gt;说的可能有点乱，上图，最左边的是最低层，最右边的是最上层。&lt;/p&gt;
&lt;p&gt;最底层没干什么，就是绑定关系，最上层也没干什么，就是声明了一下任务类型和返回报告类型，最大的增添内容主要是在中间这层，因为多加了一层类型，要重写好几个方法，添加报告类型，请求函数、状态函数重写……这部分还调用了接口函数完成了相关的报告内容拉取，来交给下一步处理后存到数据库。接口函数应该是在对应Service继承的基类中。目前来说应该不用我操心去写，导师大概会解决的。&lt;/p&gt;
&lt;p&gt;上面说到了基本把报告拉下来了，之后的job方法会调用相关方法来处理函数。这块代码主要是在Services文件夹中，首先是一个判断，依据报告类型来选取对应的同步函数，然后同步函数会负责对应字段的处理组装等。这解答了如何保证拉到的数据能够按表中字段插入的问题。但是数据库操作相关的内容没有怎么能操作表呢？这部分代码在Repositories文件夹中，主要是相关的Laravel模型操作表的代码。包括查找和插入数据等。到这个地步基本上流程就算完成了，大功告成。&lt;/p&gt;
&lt;p&gt;还早呢……调试代码的过程才是最恶心的。只能说，多做就有经验吧。感觉至少这几天dump和dd用的挺好的……还是要多测试，像是之前只跑一个测试账号，数据没问题，但是第二次换了个账号就崩了，结果发现有个字段是可选的……还好修改时间充裕，能抽时间改出来，不然后果不知道会是什么样的。😡&lt;/p&gt;
&lt;p&gt;大概就是这样了。下周大概还是相似的工作，要是接口函数调好了写的应该会比这周快一点。&lt;/p&gt;</content><category term="学习笔记"/><category term="业务流程"/><category term="原创"/></entry><entry><title>Redis学习记录</title><link href="https://zhiyuansong.xyz/redisxue-xi-ji-lu.html" rel="alternate"/><published>2021-09-01T16:09:22+08:00</published><updated>2021-09-01T16:09:22+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-09-01:/redisxue-xi-ji-lu.html</id><summary type="html">&lt;p&gt;进入九月，学习内容进一步加深，要进一步加强框架的学习，还有诸如Redis和Elasticsearch之类的，之后可能就得做东西了。&lt;br /&gt;
今天看了一下Redis的相关知识，感觉就是 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;进入九月，学习内容进一步加深，要进一步加强框架的学习，还有诸如Redis和Elasticsearch之类的，之后可能就得做东西了。&lt;br /&gt;
今天看了一下Redis的相关知识，感觉就是个能放数据的碗，学了半天就是会了个怎么放，怎么取，没了。其他的知识感觉不出有什么用，估计这东西的作用只有在项目中才能体现吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;简介&lt;/h2&gt;
&lt;p&gt;Redis是一个非关系型数据库，在处理字符串、散列、集合、有序集合和列表等数据结构方面效果优越，它速度块的同时还可以将内容固定在磁盘中，保证持久化。它的每个操作都是原子化操作，保证不会发生进行到一半的情况。所以个人看了它的事务部分感觉不明所以，失去了原子性的事务有什么用呢？疑惑。&lt;/p&gt;
&lt;h2 id="_2"&gt;五种数据类型&lt;/h2&gt;
&lt;p&gt;感觉用的最多的还是字符串、列表、散列、集合和有序集合。每一类都有一堆命令，看了半天就记住了插入数据和输出数据，其他的抽时间慢慢用吧。&lt;/p&gt;
&lt;h3 id="_3"&gt;字符串&lt;/h3&gt;
&lt;p&gt;说是字符串实际上指的是键值对，因为是二进制安全的，所以放图片这一类的也可以，况且最大可以放512MB的内容，所以还真的可以放字符之外的二进制数据。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;SET 键名 值
GET 键名
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id="_4"&gt;散列&lt;/h3&gt;
&lt;p&gt;其实是一张映射表，存放了一堆键值对，很像面向对象的实例。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;HMSET 表名 属性名1 属性值1 属性名2 属性值2
HGET 表名 属性名
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id="_5"&gt;列表&lt;/h3&gt;
&lt;p&gt;一个表，里面一堆值，按照推入的顺序来排序，最后推入的最先输出。下标就是从0开始的数字。&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;LPUSH 表名 值1
LPUSH 表名 值2
...
LRANGE 表名 起始下标 结束下标
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="_6"&gt;集合&lt;/h3&gt;
&lt;p&gt;集合的特点就是无序，所以塞就完事了。&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;SADD 集合名 值1
SADD 集合名 值2
...
SMEMBERS 集合名 
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="_7"&gt;有序集合&lt;/h3&gt;
&lt;p&gt;相比集合多了个序号，输进去的时候直接按照这个序号的大小排序了。&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ZADD 集合名 序号 值
...
ZRANGEBYSCORE 集合名 最小序号 最大序号
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="_8"&gt;补充&lt;/h3&gt;
&lt;p&gt;DEL 可以删除对应键名的结构，EXISTS 可以判断对应键名的结构是否存在，TYPE 可以返回对应键名的结构的类型。&lt;/p&gt;
&lt;h2 id="_9"&gt;其他&lt;/h2&gt;
&lt;p&gt;订阅看了，说实话不知道有什么用，我就打开了四个命令框，两个SUBSCRIBE一个channel，另外两个在这个channel上面PUBLISH消息，然后订阅的就都能看到发送的消息，很有聊天的感觉，但是有什么用呢？&lt;/p&gt;
&lt;p&gt;脚本也很迷，EVAL 后面引号写Lua脚本，但是很怪，引号里边写语句，后面还要标上有几个key，还有arg之类的，搞不懂什么作用。&lt;/p&gt;
&lt;p&gt;事务也说了，没有原子性的事务有什么用？&lt;/p&gt;
&lt;p&gt;其他的性能测试客户端连接感觉暂时用不上，我先放放，之后肯定会继续补充内容的嘛。&lt;/p&gt;</content><category term="学习笔记"/><category term="Redis"/><category term="NoSQL"/><category term="原创"/></entry><entry><title>AJAX简单记录</title><link href="https://zhiyuansong.xyz/ajaxjian-dan-ji-lu.html" rel="alternate"/><published>2021-08-24T10:11:21+08:00</published><updated>2021-08-24T10:11:21+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-24:/ajaxjian-dan-ji-lu.html</id><summary type="html">&lt;p&gt;这段时间在看前端知识，对于js的相关内容又看了一遍，说实话，之前也就是个会写函数的程度，现在至少能整点花活了。像是JQuery什么的也是看了一遍，以后有时间写一写 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这段时间在看前端知识，对于js的相关内容又看了一遍，说实话，之前也就是个会写函数的程度，现在至少能整点花活了。像是JQuery什么的也是看了一遍，以后有时间写一写。&lt;/p&gt;
&lt;p&gt;这篇主要是对AJAX写一点内容，因为内容确实很少，但是确实很有意思，比起单纯的网页表单提交又高出了一个层次，比较好使。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;简介&lt;/h2&gt;
&lt;p&gt;所谓AJAX，就是异步的Javascript和XML，是一种可以在不重新加载整个页面的情况下可以和服务器交换数据并更新部分网页内容的技术。&lt;/p&gt;
&lt;p&gt;传统的网页更新内容必须要重新加载整个网页。而AJAX借用XMLHttpRequest对象用来在后台和服务器交换数据，就是借此完成了异步更新网页。&lt;/p&gt;
&lt;h2 id="_2"&gt;相关方法和属性&lt;/h2&gt;
&lt;h3 id="_3"&gt;基本&lt;/h3&gt;
&lt;p&gt;XMLHttpRequest对象有两个方法用来处理请求，open()和send()，open()有三个参数，第一个，规定访问方式是GET还是POST，第二个规定文件在服务器的路径，第三个规定异步性。建议一直使用true，不然就显示不出异步的优势了。send()用来发送请求。&lt;/p&gt;
&lt;p&gt;响应方面XMLHttpRequest对象有两个属性，responseText和responseXML，分别用来获取字符串和XML形式的响应数据。&lt;/p&gt;
&lt;h3 id="_4"&gt;重要事件和相关属性&lt;/h3&gt;
&lt;p&gt;事件触发方面，有一个重要的事件，onreadystatechange事件，这个事件必然要接一个处理函数，提供了两个属性状态符，readystate和status，都是以数字形式来确定状态的。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;readystate对应值&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;请求未初始化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;服务器连接已建立&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;请求已接收&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;请求处理中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;请求已完成，且响应已就绪&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;readystate对应的值和相应的含义如上所述，而status的状态其实就是网络访问状态码，像是200对应OK，404对应NOT FOUND等。&lt;/p&gt;
&lt;p&gt;很明显当readystate为4且status为200时表示相应已经就绪，对应的获取文件内容的属性标识符已经读到了内容，可以进行处理了。&lt;/p&gt;
&lt;h2 id="_5"&gt;更进一步&lt;/h2&gt;
&lt;p&gt;AJAX可以通过PHP文件完成更加动态的访问操作，像是根据文本框输入来直接拉取对应的数据库数据，这比单纯的网页用表单来提交请求再获取响应体验更好。&lt;/p&gt;</content><category term="学习笔记"/><category term="Javascript"/><category term="AJAX"/><category term="原创"/></entry><entry><title>Laravel学习记录（五）：CSRF保护和控制器</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-wu-csrfbao-hu-he-kong-zhi-qi.html" rel="alternate"/><published>2021-08-23T17:43:23+08:00</published><updated>2021-08-23T17:43:23+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-23:/laravelxue-xi-ji-lu-wu-csrfbao-hu-he-kong-zhi-qi.html</id><summary type="html">&lt;p&gt;这一篇主要是对CSRF保护和控制器写的，主要是控制器的内容比较多。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="csrf"&gt;CSRF保护&lt;/h2&gt;
&lt;h3 id="_1"&gt;简述&lt;/h3&gt;
&lt;p&gt;提交表单都要在表单内容里加一个&lt;code&gt;@csrf&lt;/code&gt;来保证安全性，防止CSRF（跨站 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这一篇主要是对CSRF保护和控制器写的，主要是控制器的内容比较多。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="csrf"&gt;CSRF保护&lt;/h2&gt;
&lt;h3 id="_1"&gt;简述&lt;/h3&gt;
&lt;p&gt;提交表单都要在表单内容里加一个&lt;code&gt;@csrf&lt;/code&gt;来保证安全性，防止CSRF（跨站请求伪造攻击）发生，它借助已验证的用户身份来运行未经过授权的命令。&lt;/p&gt;
&lt;p&gt;加上之后，默认使用的CSRF防护中间件会自动验证请求里的令牌是否和存储在会话里的令牌匹配。&lt;/p&gt;
&lt;h3 id="csrf_1"&gt;添加CSRF白名单&lt;/h3&gt;
&lt;p&gt;部分URL不需要CSRF保护，像是集成第三方收费管理API，对方的网址也没有办法发送CSRF令牌，可以在中间件文件里配置&lt;code&gt;$except&lt;/code&gt;来忽略掉相关的URL。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20210823165336.png" /&gt;&lt;/p&gt;
&lt;h2 id="_2"&gt;控制器&lt;/h2&gt;
&lt;p&gt;用来替代在路由文件中以闭包形式定义的所有请求处理逻辑，简单来说就是对URI的处理函数，将这些控制逻辑组织成控制类，就是控制器。&lt;/p&gt;
&lt;p&gt;定义一个指向控制器行为的路由是这样的：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;use App\Http\Controllers\UserController;&lt;/span&gt;

&lt;span class="x"&gt;Route::get(&amp;#39;user/{id}&amp;#39;, [UserController::class, &amp;#39;show&amp;#39;]);&lt;/span&gt;

&lt;span class="x"&gt;//还有另一种写法&lt;/span&gt;

&lt;span class="x"&gt;Route::get(&amp;#39;user/{id}&amp;#39;,&amp;#39;UserController@show&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;一般来说控制器可以直接生成，生成的框架是继承&lt;code&gt;Controller&lt;/code&gt;基类的，当然不继承也行，但是少了基类的像是中间件和验证等方法的使用。&lt;/p&gt;
&lt;p&gt;只处理单个行为的控制器，因为只有一个方法，所以可以直接指明方法叫&lt;code&gt;__invoke&lt;/code&gt;，路由调用的时候也不需要指名方法，直接写控制器类名就行。&lt;/p&gt;
&lt;h3 id="_3"&gt;控制器中间件&lt;/h3&gt;
&lt;p&gt;上面说过可以在路由界面指定中间件，但是更方便的方法是在控制器的构造方法里指定中间件，这样还可以使用指定范围，像是只对某几个方法生效，除去几个方法生效等：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;class UserController extends Controller&lt;/span&gt;
&lt;span class="x"&gt;{&lt;/span&gt;
&lt;span class="x"&gt;    /**&lt;/span&gt;
&lt;span class="x"&gt;     * 实例化一个新的控制器实例&lt;/span&gt;
&lt;span class="x"&gt;     *&lt;/span&gt;
&lt;span class="x"&gt;     * @return void&lt;/span&gt;
&lt;span class="x"&gt;     */&lt;/span&gt;
&lt;span class="x"&gt;    public function __construct()&lt;/span&gt;
&lt;span class="x"&gt;    {&lt;/span&gt;
&lt;span class="x"&gt;        $this-&amp;gt;middleware(&amp;#39;auth&amp;#39;);&lt;/span&gt;

&lt;span class="x"&gt;        $this-&amp;gt;middleware(&amp;#39;log&amp;#39;)-&amp;gt;only(&amp;#39;index&amp;#39;);&lt;/span&gt;

&lt;span class="x"&gt;        $this-&amp;gt;middleware(&amp;#39;subscribed&amp;#39;)-&amp;gt;except(&amp;#39;store&amp;#39;);&lt;/span&gt;
&lt;span class="x"&gt;    }&lt;/span&gt;
&lt;span class="x"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这样的话甚至可以直接写一个闭包函数来注册中间件，虽然感觉不规整。&lt;/p&gt;
&lt;h3 id="_4"&gt;资源型控制器&lt;/h3&gt;
&lt;p&gt;资源路由只要一行代码就可以把常用的CRUD（增删改查）路由交给控制器。生成资源型控制器的命令是&lt;code&gt;php artisan make:controller PhotoController --resource&lt;/code&gt;。这样生成的控制器会有上面提到的方法。&lt;/p&gt;
&lt;p&gt;再使用命令来给控制器注册一个对应的方法的路由：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;Route::resource(&amp;#39;photos&amp;#39;, PhotoController::class);&lt;/span&gt;
&lt;span class="x"&gt;//还可以写成这样&lt;/span&gt;
&lt;span class="x"&gt;Route::resource(&amp;#39;photos&amp;#39;,&amp;#39;PhotoController&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;甚至可以一次给资源型路由传入多个键值对来注册多个资源控制器。&lt;/p&gt;
&lt;p&gt;可以使用&lt;code&gt;only()&lt;/code&gt;、&lt;code&gt;except()&lt;/code&gt;来限定生成的路由，毕竟不是每个路由都要用。&lt;/p&gt;
&lt;p&gt;自己针对模型要自定义的路由要放在资源型路由的前边，顺序决定优先级。&lt;/p&gt;
&lt;h3 id="_5"&gt;路由缓存&lt;/h3&gt;
&lt;p&gt;在只使用了基于路由的控制器下，进行路由缓存可以提高路由访问速度，应用也会更快。&lt;/p&gt;
&lt;div class="highlight" data-language="shell"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;php&lt;span class="w"&gt; &lt;/span&gt;artisan&lt;span class="w"&gt; &lt;/span&gt;route:cache
php&lt;span class="w"&gt; &lt;/span&gt;artisan&lt;span class="w"&gt; &lt;/span&gt;route:clear
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;上一句进行缓存，下一句清理缓存，每次添加新路由记得重新生成缓存。&lt;/p&gt;
&lt;h2 id="_6"&gt;总结&lt;/h2&gt;
&lt;p&gt;CSRF部分比较少，但是控制器部分有个依赖注入和方法注入，看不懂。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="Laravel"/><category term="原创"/></entry><entry><title>Laravel学习记录（四）：中间件</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-si-zhong-jian-jian.html" rel="alternate"/><published>2021-08-23T14:43:55+08:00</published><updated>2021-08-23T14:43:55+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-23:/laravelxue-xi-ji-lu-si-zhong-jian-jian.html</id><summary type="html">&lt;p&gt;说实话自己在做项目的时候对中间件的印象不是很深，我对中间件这个词也不太理解。&lt;/p&gt;
&lt;p&gt;文档记载，中间件是用来提供一种 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;说实话自己在做项目的时候对中间件的印象不是很深，我对中间件这个词也不太理解。&lt;/p&gt;
&lt;p&gt;文档记载，中间件是用来提供一种机制来对HTTP请求进行过滤的，参考上周使用throttle中间件来对网页进行访问流量控制的相关例子，大概对这个东西有了一点理解。但是还是边做边看吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;中间件提供了一种方便的机制来检查和过滤进入应用程序的HTTP请求。例如判断用户是否经过身份验证，如果没有通过身份验证，那就重定义到之前的登录页面，不然就顺利登入程序。&lt;/p&gt;
&lt;h2 id="_1"&gt;定义中间件&lt;/h2&gt;
&lt;p&gt;使用&lt;code&gt;php artisan make:middleware Xxx&lt;/code&gt;类似的语句在项目中添加一个中间件。&lt;/p&gt;
&lt;p&gt;基本上类中定义的方法是用来处理请求的，像是请求中的参数满足条件可以正常访问，不满足重新定义到首页等。&lt;/p&gt;
&lt;p&gt;还有前置和后置中间件之分。&lt;/p&gt;
&lt;h2 id="_2"&gt;包含和使用中间件&lt;/h2&gt;
&lt;p&gt;全局中间件需要在&lt;code&gt;app\Http\Kernel.php&lt;/code&gt;中的&lt;code&gt;$middleware&lt;/code&gt;属性下包含该中间件。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20210823142252.png" /&gt;&lt;/p&gt;
&lt;p&gt;差不多是这个样子。&lt;/p&gt;
&lt;p&gt;而给路由分配中间件，是在&lt;code&gt;$routeMiddleware&lt;/code&gt;中添加，需要构建类似&lt;code&gt;功能=&amp;gt;middleware&lt;/code&gt;的键值对。&lt;/p&gt;
&lt;p&gt;然后用&lt;code&gt;middleware()&lt;/code&gt;方法分配。&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;Route::get(&amp;#39;admin/profile&amp;#39;, function () {&lt;/span&gt;
&lt;span class="x"&gt;    //&lt;/span&gt;
&lt;span class="x"&gt;})-&amp;gt;middleware(&amp;#39;auth&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;还可以给路由分配多个中间件。&lt;/p&gt;
&lt;p&gt;给一组中间件绑定一个键值，就是一个中间件组，可以按照上面讲的方法给路由分配中间件。&lt;/p&gt;
&lt;p&gt;中间件执行任务可以在实际执行完之前，也可以在之后。&lt;/p&gt;
&lt;p&gt;排除中间件，用withoutMiddleware,用的场景主要是，一组路由赋予了一个中间件，有一个路由用不到的情况。&lt;/p&gt;
&lt;p&gt;可以在整个组路由中定义排除一组给定的中间件：&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;use App\Http\Middleware\EnsureTokenIsValid;

Route::withoutMiddleware([EnsureTokenIsValid::class])-&amp;gt;group(function () {
    Route::get(&amp;#39;/profile&amp;#39;, function () {
        //
    });
});
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;中间件组，有时候希望可以将多个中间件组合在一个键下，使得更容易分配给路由，可以使用middlewareGroup属性来完成操作。大概就是用建立数组的方法。&lt;br /&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/**
 * 应用程序的路由中间件组。
 *
 * @var array
 */
protected $middlewareGroups = [
    &amp;#39;web&amp;#39; =&amp;gt; [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    &amp;#39;api&amp;#39; =&amp;gt; [
        &amp;#39;throttle:api&amp;#39;,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;如何确定中间件的优先级，可以使用middlewarePriority属性来控制优先级。&lt;/p&gt;
&lt;h2 id="_3"&gt;总结&lt;/h2&gt;
&lt;p&gt;东西不多，主要是做一个请求处理的中间层。有些东西暂时用不上。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="Laravel"/><category term="原创"/></entry><entry><title>Laravel学习记录（三）：路由</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-san-lu-you.html" rel="alternate"/><published>2021-08-23T11:32:35+08:00</published><updated>2021-08-23T11:32:35+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-23:/laravelxue-xi-ji-lu-san-lu-you.html</id><summary type="html">&lt;p&gt;这篇是对路由的基本介绍，内容基本上来自于文档阅读，少部分来自于自己项目中的写法，简单来说路由目前还是web路由居多，对相 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这篇是对路由的基本介绍，内容基本上来自于文档阅读，少部分来自于自己项目中的写法，简单来说路由目前还是web路由居多，对相关资源的访问，以及对处理方法的声明（当然你定义也可以，就是项目不太整洁了）。内容比较简单，因为是边看边写的，所以格式上比较乱，没有章法，见谅。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;基本结构&lt;/h2&gt;
&lt;p&gt;路由的基本结构就是一个URI加一个闭包函数：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;/*&lt;/span&gt;
&lt;span class="x"&gt;*这是一个web路由，访问的是foo页面，控制函数就是后边的function，&lt;/span&gt;
&lt;span class="x"&gt;*因为网址肯定是在配置文件里面配好了，&lt;/span&gt;
&lt;span class="x"&gt;*所以访问页面的路径写的这么短可以理解&lt;/span&gt;
&lt;span class="x"&gt;*/&lt;/span&gt;
&lt;span class="x"&gt;Route::get(&amp;#39;foo&amp;#39;,function()&lt;/span&gt;
&lt;span class="x"&gt;           {&lt;/span&gt;
&lt;span class="x"&gt;              //相关函数内容 &lt;/span&gt;
&lt;span class="x"&gt;           });&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;在我最近完成的项目里，大概还有这样一种写法，感觉更满足一个项目的管理写法：&lt;/p&gt;
&lt;div class="highlight" data-language="php"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;/*&lt;/span&gt;
&lt;span class="x"&gt;*实际上不同在控制函数的写法上，&lt;/span&gt;
&lt;span class="x"&gt;*控制函数是UsersController里的show方法，&lt;/span&gt;
&lt;span class="x"&gt;*同时路由被重命名为show，方便了在视图之类的文件里使用&lt;/span&gt;
&lt;span class="x"&gt;*使用$url = route(&amp;#39;show&amp;#39;)类似的语句来获取链接&lt;/span&gt;
&lt;span class="x"&gt;*或者用redirect()-&amp;gt;route(&amp;#39;show&amp;#39;)来重定向&lt;/span&gt;
&lt;span class="x"&gt;*/&lt;/span&gt;
&lt;span class="x"&gt;Route::get(&amp;#39;foo&amp;#39;,&amp;#39;UsersController@show&amp;#39;)-&amp;gt;name(&amp;#39;show&amp;#39;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_2"&gt;类别&lt;/h2&gt;
&lt;p&gt;可以相应HTTP请求的Web路由有get、post、put、patch、delete和options，match路由可以相应多个请求，any可以响应所有HTTP请求。&lt;/p&gt;
&lt;p&gt;所有指向Web路由中post，put，patch和delete的表单都要有CSRF令牌，否则请求会被拒绝：&lt;/p&gt;
&lt;div class="highlight" data-language="php+HTML"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;nethod=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/profile&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;@csrf
&lt;span class="w"&gt;    &lt;/span&gt;//相关表单内容
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;重定向路由直接用redirect即可，参数就是两个页面路径，省的再次定义很费事。第三个参数可以自定义状态码。&lt;/p&gt;
&lt;p&gt;视图路由可以用view，接受URI做第一个参数，视图路径做第二个路径，第三个参顺可以传一个数据数组给视图。但是目前我用的好像没有相关的方法，都是用普通的web路由加上相关的返回视图方法来用的。&lt;/p&gt;
&lt;h2 id="_3"&gt;参数&lt;/h2&gt;
&lt;p&gt;获取URL中的变量做参数，就和PHP变量一样，框个大括号。可选有默认，加个“？”来实现。&lt;/p&gt;
&lt;p&gt;后接where方法可以对参数的格式用正则表达式做约束。模板化的要去路由的提供者boot中定义pattern路由方法。&lt;/p&gt;
&lt;p&gt;有参数的命名路由，插入参数直接在第二个参数上按数组的格式去插就好。&lt;/p&gt;
&lt;h2 id="_4"&gt;约定关系和表单方法伪造&lt;/h2&gt;
&lt;p&gt;URI和方法其实是有隐性的绑定关系的，基本上是约定的名字上有相同的部分，这是一种约定，所以基本上可以按照这种方法来添加文件。&lt;/p&gt;
&lt;p&gt;表单方法伪造：因为HTML表单也就有个get、post和require三个方法，不支持put、patch和delete请求，所以当调用方式是这些的时候，需要在表单里面添加一个&lt;code&gt;_mothod&lt;/code&gt;隐藏域，它的值会作为请求的方法。&lt;/p&gt;
&lt;div class="highlight" data-language="html"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/foo/bar&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;_method&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;PUT&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;_token&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{{ csrf_token() }}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;或者用&lt;code&gt;@method&lt;/code&gt;生成指定的隐藏域：&lt;/p&gt;
&lt;div class="highlight" data-language="html"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/foo/bar&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    @method(&amp;#39;PUT&amp;#39;)
    @csrf
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel学习记录（二）</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-er.html" rel="alternate"/><published>2021-08-17T10:49:56+08:00</published><updated>2021-08-17T10:49:56+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-17:/laravelxue-xi-ji-lu-er.html</id><summary type="html">&lt;p&gt;这篇梳理一下文件夹结构还有目前接触过的一些约定的格式，主要是写一写就记得牢。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;文件结构&lt;/h2&gt;
&lt;p&gt;关于Laravel的文件结构，其实感觉有点像 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这篇梳理一下文件夹结构还有目前接触过的一些约定的格式，主要是写一写就记得牢。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;文件结构&lt;/h2&gt;
&lt;p&gt;关于Laravel的文件结构，其实感觉有点像MVC，各种文件按照约定组织放在不同的文件夹里面。按照当前个人的理解，画出下面的这张图。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20210817142424.png" /&gt;&lt;/p&gt;
&lt;p&gt;没有做标注的，是当前我接触比较少的，下面按照主要的几个挨个分析，主要是理解，毕竟像是“路由”、“迁移”之类的词语，整的实在是过于抽象，其实也就是个说法罢了。&lt;/p&gt;
&lt;h3 id="composerjson"&gt;composer.json&lt;/h3&gt;
&lt;p&gt;这个文件是用来管理项目的依赖的，composer是php项目的依赖管理器，可以全局安装也可以给单个项目安装，不过从我这几天做项目的理解来看，composer应该是全局安装的，这样的话，就可以直接生成Laravel项目，感觉比较方便，具体怎么做之后再说。&lt;/p&gt;
&lt;h3 id="vendor"&gt;vendor&lt;/h3&gt;
&lt;p&gt;这个文件夹就是存放composer配置文件中下载的各种依赖和第三方库的，需要的话直接调用即可。&lt;/p&gt;
&lt;h3 id="resources"&gt;resources&lt;/h3&gt;
&lt;p&gt;存放视图和未编译的资源文件，像是SASS这种编译后可以生成样式表的文件。大概可以理解成前端部分的设计了。&lt;/p&gt;
&lt;h3 id="packagejson"&gt;package.json&lt;/h3&gt;
&lt;p&gt;这个是npm管理依赖的配置文件，这个是因为目前前端部分资源文件的编译要用到一系列前端工作流。像是Sass，NPM，Yarn，Laravel Mix之类的东西，需要一定的配置，当然这是后话了。&lt;/p&gt;
&lt;h3 id="public"&gt;public&lt;/h3&gt;
&lt;p&gt;入口文件夹，程序启动的地方，在服务器上挂载的时候，用的也是这个文件夹。&lt;/p&gt;
&lt;h3 id="routes"&gt;routes&lt;/h3&gt;
&lt;p&gt;存放的是路由定义，这一部分目前接触到的主要是web界面的路由。这个部分，我简单理解，就是，一个界面有一个路由，增删改查四个功能对应route的四个句柄，再加上界面的路径和处理对应视图的方法，大概就构成了一个访问的过程。&lt;/p&gt;
&lt;p&gt;粗浅理解起来像是个定义，至于怎么做，还需要控制器。&lt;/p&gt;
&lt;h3 id="database"&gt;database&lt;/h3&gt;
&lt;p&gt;目前用到的只有一个数据库迁移，感觉就是像php写的通用建表语句。到不同的数据库里面，只需要在配置文件相关数据库完成的情况下直接迁移就能生成对应的数据表结构，感觉很方便。&lt;/p&gt;
&lt;h3 id="appmodels"&gt;app.Models&lt;/h3&gt;
&lt;p&gt;数据模型嘛，这个生成的话还会生成一堆路由，到时候还需要建相关的控制器去实现这些方法。我看代码，似乎Laravel 5这部分内容还在app.Http文件夹里边的，到了8代搬出来了？&lt;/p&gt;
&lt;h3 id="apphttpcontrollers"&gt;app.Http.Controllers&lt;/h3&gt;
&lt;p&gt;定义了视图和模型的处理方法。视图方面对应的是路由对页面的请求，模型方面我个人感觉主要是增删改查之类的方法定义。&lt;/p&gt;
&lt;h2 id="_2"&gt;总结&lt;/h2&gt;
&lt;p&gt;感觉上，就是MVC架构的味道，有数据模型，有控制器，有视图，就是感觉更细分了一点，像是路由只管定义，控制器负责实现等等。&lt;/p&gt;
&lt;p&gt;下一个暂时还没想好怎么写，毕竟，都是细节，做过一遍也记不住。😂&lt;/p&gt;</content><category term="学习笔记"/><category term="Laravel"/><category term="PHP"/><category term="原创"/></entry><entry><title>Laravel学习记录（一）</title><link href="https://zhiyuansong.xyz/laravelxue-xi-ji-lu-yi.html" rel="alternate"/><published>2021-08-16T15:03:54+08:00</published><updated>2021-08-16T15:03:54+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-16:/laravelxue-xi-ji-lu-yi.html</id><summary type="html">&lt;p&gt;今天是周一，说实话上周学了很多东西，但是上周小周只有一天休息再加上那天还停电……😡什么也没整理，这周学习的时候感 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;今天是周一，说实话上周学了很多东西，但是上周小周只有一天休息再加上那天还停电……😡什么也没整理，这周学习的时候感觉有点懵。整理一下Laravel的内容。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;上周主要就是数据库吧，另外就是HTML，CSS自己没性子看下去，等着之后慢慢磨。js倒是还行，就是DOM部分自己当时也是没性子看下去，就一个字，磨。&lt;/p&gt;
&lt;p&gt;最难的还是Laravel框架吧，主要是没接触的框架，看文档看不懂，配环境也难受.痛苦。&lt;/p&gt;
&lt;p&gt;那就得自己整理，免得以后再受苦了。😀&lt;/p&gt;
&lt;h2 id="_1"&gt;简述&lt;/h2&gt;
&lt;p&gt;Laravel就是个PHP做项目的框架，可以直接生成一套项目框架，只要你按照它的约定去组织项目文件，其实感觉难度是不高的，难就难在开头对什么都不熟，难顶。&lt;/p&gt;
&lt;h2 id="_2"&gt;配置环境&lt;/h2&gt;
&lt;p&gt;按文档的说法有两种，一个是容器开发环境，另一个是虚拟机开发环境，我个人是参照&lt;a href='https://learnku.com/docs/laravel-development-environment/8.x'&gt;构建Laravel开发环境&lt;/a&gt;这个文档搭建的Homestead环境，整体来说没有难度，就连我这天生和虚拟机相悖的公司电脑都能装上，还是比较顺利的，但是其中问题也确实有一些。&lt;/p&gt;
&lt;p&gt;virtual box 版本问题，vagrant 在安装的时候报错了，结果报的错是不支持当前最新的6.1版本vritual box。只能降版本。我碰到的问题目前就这一个。&lt;/p&gt;
&lt;h2 id="_3"&gt;第一个项目遇见的坑&lt;/h2&gt;
&lt;p&gt;其实总共就做了两个……第二个还在做，但是坑已经是不少了。&lt;/p&gt;
&lt;p&gt;坑的地方大概就在部署上线那一部分吧，首先是存在这么一个问题，部署的Heroku网站是外网，在公司比较差的网络环境下，首先登录heroku就是一个问题。另一个就是，创建的Procfile文件千万不要写错，不然真的无法部署成功，即使在Heroku上吧创建的应用删掉重新部署，也会出现之前创建的远程git地址和新生成的应用的远程git地址不一样的情况，导致还需要改动这个地址才能成功。一番下来自己干脆删了本地代码重新生成，世界从此清净了……🙃&lt;br /&gt;
&lt;div class="highlight" data-language="git"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//查看当前的url和生成的是否一致&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;heroku&lt;/span&gt;
&lt;span class="c1"&gt;//查看应用的url在seting-&amp;gt;info-&amp;gt;Heroku Git URL&lt;/span&gt;
&lt;span class="c1"&gt;//修改为自己的heroku地址即可&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;heroku&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//git.heroku.com/xxx.git&lt;/span&gt;
&lt;span class="c1"&gt;//再push不上去可以执行heroku git:remote -a myapp来试试（虽然我直接删代码重配了……）&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id="_4"&gt;第二个项目遇见的坑&lt;/h2&gt;
&lt;p&gt;然后第二个做的是一个类微博app，这个主要是卡在了前端渲染组件的安装配置问题。&lt;/p&gt;
&lt;p&gt;因为这一部分是要安装web-pack的，而laravel 8似乎在初始化的配置文件上就存在一些问题，windows环境根本无法生成需要的软链接，根本安装不成，还报错。结果参照的是别人的一篇经验。解决了这个问题。&lt;/p&gt;
&lt;p&gt;首先是&lt;code&gt;package.json&lt;/code&gt;文件默认生成的文件是不行的，得替换成laravel 7的（你问我为啥我也不知道啊）：&lt;/p&gt;
&lt;p&gt;&lt;div class="highlight" data-language="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;scripts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;dev&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;npm run development&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;development&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;watch&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;npm run development -- --watch&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;watch-poll&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;npm run watch -- --watch-options-poll=1000&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hot&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;prod&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;npm run production&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;production&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
安装包的版本部分倒是没什么问题，可以不用管，就是&lt;code&gt;scripts&lt;/code&gt;这一部分，默认生成的甚至会带&lt;code&gt;cross-env&lt;/code&gt;这个字段，但是带上之后根本安不了，看见之后记得速速删掉。&lt;/p&gt;
&lt;p&gt;接下来输入以下命令&lt;br /&gt;
&lt;div class="highlight" data-language="bash"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;SASS_BINARY_SITE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://npm.taobao.org/mirrors/node-sass&lt;span class="w"&gt; &lt;/span&gt;yarn&lt;span class="w"&gt; &lt;/span&gt;--no-bin-links
yarn&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;cross-env&lt;span class="w"&gt; &lt;/span&gt;--no-bin-links
//这句会报错，不用管
npm&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;webpack.mix.js&lt;span class="w"&gt; &lt;/span&gt;
yarn&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;resolve-url-loader@3.1.0&lt;span class="w"&gt; &lt;/span&gt;--dev&lt;span class="w"&gt; &lt;/span&gt;--no-bin-links
npm&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;dev
//或者
npm&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;watch-poll
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/image-webpack.png" /&gt;&lt;/p&gt;
&lt;p&gt;成功的配置大概见上图，在修改前端渲染文件（就是sass那一块时）记得始终打开，因为每次修改保存都会重新编译生成样式表。不要忘了。&lt;/p&gt;
&lt;h2 id="_5"&gt;完结&lt;/h2&gt;
&lt;p&gt;暂时解决了目前遇到的各种问题，下一个开始梳理一下Laravel相关的结构内容，像是文件夹结构之类的东西……就先这样吧。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="Laravel"/><category term="原创"/></entry><entry><title>SQL基本知识整理</title><link href="https://zhiyuansong.xyz/sqlji-ben-zhi-shi-zheng-li.html" rel="alternate"/><published>2021-08-09T10:44:44+08:00</published><updated>2021-08-09T10:44:44+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-08-09:/sqlji-ben-zhi-shi-zheng-li.html</id><summary type="html">&lt;p&gt;我看了一下自己之前应该是没有写过SQL相关的东西，以后打算把各种关系型数据库学习的东西也都扔进去，因为其实感觉区别不大 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我看了一下自己之前应该是没有写过SQL相关的东西，以后打算把各种关系型数据库学习的东西也都扔进去，因为其实感觉区别不大，也就是各个数据库的数据类型和扩展函数不太一样。&lt;br /&gt;
这次主要整理的是上周五（8月9日）的SQL学习内容，大概是把SQL自带函数之前的基础知识看完了。但是不整理它就永远是一坨零碎的笔记，于是整理一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;简介&lt;/h2&gt;
&lt;p&gt;SQL的全称是结构化查询语言（Structed Query Language,SQL），实际上只是一个语言标准，当前的各种关系型数据库都会在支持SQL的基础上增加了各种可能没什么用的内容。&lt;/p&gt;
&lt;p&gt;SQL对大小写不敏感，我全部小写主要是因为敲大写太累了，没必要。反正命令部分有需要的话大写即可。&lt;/p&gt;
&lt;p&gt;那天实际上的操作是在Oracle上完成的，因为当时没有装好MySQL，但其实大多数东西差不多可以通用，如果以后还有什么不同的地方我会在相应位置补全。&lt;/p&gt;
&lt;h2 id="oraclemysql"&gt;Oracle和MySQL的区别（个人感到的）&lt;/h2&gt;
&lt;p&gt;目前可以感到的就是“database”这个概念大概Oracle是没有的，因为它的表是直接放在用户下边，一个用户负责一套表的管理，这样说实话我还比较喜欢，不太理解MySQL用户下边还要再塞一堆数据库做什么，那么新建用户说实话就没有什么意义了，全交给dba不就行了？反正普通用户去搞建表这套操作搞不好是要丢饭碗的。&lt;/p&gt;
&lt;h2 id="_2"&gt;增删改查&lt;/h2&gt;
&lt;p&gt;这里的增删改查针对的是数据库里的表的内容进行的操作，不是对表这个对象的操作。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*单纯的查找功能，*部分可以替换成每一列中的项，这些项还可以空格后取别名，where主要是加筛选条件的，order by进行排序，在前面的属性优先排列，desc表示从大到小排列，distinct可以把不重复的内容拿出来*/&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="k"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*更改数据项的值，where确定位置，务必不能丢，不然可能会发生全部数据都被改掉的惨剧*/&lt;/span&gt;
&lt;span class="k"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...;&lt;/span&gt;
&lt;span class="cm"&gt;/*删除一行数据，where确定位置，大多数情况不能丢，丢了就把整个表清空了，当然你要真的想清空表也算是一种方法大概*/&lt;/span&gt;
&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...;&lt;/span&gt;
&lt;span class="cm"&gt;/*插入一行数据，第一个括号，是每一项的名字，第二个括号，是每一项要插入的值*/&lt;/span&gt;
&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这几句大概是没有建表权限的人用的最多的话，估计前期大部分时间都在干这个事情。因为建表毕竟还是需要一定设计的，暂时不会。&lt;/p&gt;
&lt;p&gt;另外提一句，MySQL引号没有特殊要求，但Oracle应该是只能用单引号。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select top&lt;/code&gt;操作，这个操作的意思是从一张表里取出前几个元素，但是MySQL实际用的是LIMIT关键字，Oracle实际用的是ROWNUM来控制。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- MySQL取出表中前5个数据&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Oracle取出表中前5个数据&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ROWNUM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_3"&gt;模式匹配&lt;/h2&gt;
&lt;p&gt;实际上就是模糊查找，就我看的这点内容，好像在正则表达式上的支持实际上数据库可能不是太好，如果有变动我再后边补充，之际上大概也就用了一个&lt;code&gt;LIKE&lt;/code&gt;关键字和&lt;code&gt;%&lt;/code&gt;和&lt;code&gt;_&lt;/code&gt;两个通配符。其中&lt;code&gt;%&lt;/code&gt;代表了一个到多个字符&lt;code&gt;_&lt;/code&gt;只代表一个字符。似乎支持一点正则表达式的内容，用&lt;code&gt;^[]&lt;/code&gt;在中括号填写，但是使用起来似乎不太方便，也可能是我本人对正则表达式不太熟悉。模式匹配用在&lt;code&gt;WHERE&lt;/code&gt;关键字后边。&lt;/p&gt;
&lt;h2 id="in-between"&gt;IN 和 BETWEEN&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;IN&lt;/code&gt;用在&lt;code&gt;WHERE&lt;/code&gt;中来规定属性在多个值之中，可以加&lt;code&gt;NOT&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BETWEEN A AND B&lt;/code&gt; 用来&lt;code&gt;WHERE&lt;/code&gt;中来规定属性在&lt;code&gt;A&lt;/code&gt;和&lt;code&gt;B&lt;/code&gt;之间，可以加&lt;code&gt;NOT&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="_4"&gt;连接&lt;/h2&gt;
&lt;p&gt;我感觉这个部分有点难，等我之后细细研究一下，现在就先把格式列一下。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;access_log&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;aid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;site_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 站点ID，对应websitesID&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;access_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;site_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;values&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;to_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2016-05-17&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yyyy-mm-dd&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*连接有4种，内(INNER)连接，全（FULL）连接，左(LEFT)连接，右(RIGHT)连接*/&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;websites&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;inner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;access_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;说实话感觉也就内连接用的多，其他的，感觉用的比较少啊。&lt;/p&gt;
&lt;h2 id="_5"&gt;表的创建和、删除和修改&lt;/h2&gt;
&lt;p&gt;下面展示的是Oracle数据库下的建表和删除表语句，主要是在数据类型上各个数据库有所不同，其他的东西基本一致，像是添加约束，在建表的时候都可以添加。无非就是格式上有所区别，这个在约束部分会具体展开。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;websites&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 编号&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;varchar2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 名称&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;varchar2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 网址&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;alexa&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;varchar2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 国家&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- 删除整个表的结构，结构都没了，自然数据更保存不了了&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;truncate table table_name;&lt;/code&gt;用来清除表里的内容，其实我感觉用不带&lt;code&gt;where&lt;/code&gt;的删除语句应该也可以。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;alter table table_name add/drop/modify column clolumn_name datatype&lt;/code&gt;用来给表的结构进行修改，像是加列、减列和修改列的数据类型。&lt;/p&gt;
&lt;h2 id="_6"&gt;索引&lt;/h2&gt;
&lt;p&gt;创建索引可以加快访问的速度，但是索引过多表的更新耗费时间也会变长，所以对于经常访问的数据创建索引即可。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*创建索引，带unique表示唯一索引，两行的索引值不能一样*/&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;index_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xxx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- MySQL删除索引，Oracle的直接drop就行&lt;/span&gt;
&lt;span class="k"&gt;alter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;index_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_7"&gt;约束&lt;/h2&gt;
&lt;p&gt;约束大概是有这么几种，非空约束（NOT NULL），主键约束（PRIVATE KEY），外键约束（FOREIGN KEY），唯一性约束（UNIQUE），检查元素（CHECK）和默认值(DEFAULT)。&lt;/p&gt;
&lt;p&gt;约束可以在建表时就定义，也可以对建好的表用ALTER语句修改添加约束。&lt;/p&gt;
&lt;p&gt;主键约束和唯一性约束的区别是，主键约束一表只有一个，唯一性约束没有这个要求。&lt;/p&gt;
&lt;p&gt;外键指向另一个表的唯一性约束。&lt;/p&gt;
&lt;p&gt;具体内容可以之后再整理一篇。&lt;/p&gt;
&lt;h2 id="_8"&gt;视图&lt;/h2&gt;
&lt;p&gt;简单来说视图是通过定义的语句直接从各个实体表中生成的表，这张表同样可以进行查找，加函数,做连接.这样做的好处是掩盖了实际的表结构，只提供必要的数据可视化。&lt;/p&gt;
&lt;div class="highlight" data-language="sql"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- 创建视图的语句&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;view&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xx_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;xx_2&lt;/span&gt;&lt;span class="p"&gt;,...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...;&lt;/span&gt;
&lt;span class="c1"&gt;-- 修改视图可以用create,也可以用replace&lt;/span&gt;
&lt;span class="c1"&gt;-- 删除视图&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;view&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="_9"&gt;难点总结&lt;/h2&gt;
&lt;p&gt;总的来说,难点在连接部分，约束部分和分组部分，分组上面没提到，实际上就是&lt;code&gt;GROUP BY&lt;/code&gt;语句，这三个部分需要下去再做总结，不断巩固，总感觉不会就不踏实。&lt;/p&gt;</content><category term="学习笔记"/><category term="SQL"/><category term="原创"/></entry><entry><title>PHP学习笔记（一）</title><link href="https://zhiyuansong.xyz/phpxue-xi-bi-ji-yi.html" rel="alternate"/><published>2021-07-31T22:30:59+08:00</published><updated>2021-07-31T22:30:59+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-07-31:/phpxue-xi-bi-ji-yi.html</id><summary type="html">&lt;p&gt;结果招来还是要写PHP的，也不是说不愿意，但是确实大学学的，和实际做的，有点落差，但是既然来了，那就干吧，反正殊途同归，只 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;结果招来还是要写PHP的，也不是说不愿意，但是确实大学学的，和实际做的，有点落差，但是既然来了，那就干吧，反正殊途同归，只要能把东西做好就是好样的。&lt;/p&gt;
&lt;p&gt;主要整理的是29号和30号的学习笔记，这段时间主要是把环境问题和基本语法这些问题搞的差不多了，其他的还在搞，下周能搞完这部分？&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;环境安装&lt;/h2&gt;
&lt;p&gt;总的来说算是简单的，单用PHP的话装个PHP解释器就行，甚至不到50M。环境变量配置个路径就行。其他的，其实可以装个集成的开发框架，像是PHPStudy什么的，好用。&lt;/p&gt;
&lt;p&gt;当然提倡你一个一个单独在Linux上以命令行形式一个一个安装，坑倒是真的挺多的，甚至自己给自己挖坑……🙃&lt;/p&gt;
&lt;p&gt;IDE目前最好的还是PhpStorm，但是要花钱。本来想的是拿VSCode配一个轻量级的编辑调试环境，但是按照网上的法子不太行……等我问问高人之后再弄一弄。&lt;/p&gt;
&lt;h2 id="_2"&gt;知识&lt;/h2&gt;
&lt;p&gt;说实话，这门语言的知识要说有新的东西，还真的没有。我从来没觉得一门语言怎么会一点特立独行的东西都没有，大概是之前接触过什么C系语言，Java，Python的缘故，我没感觉有什么新玩意儿，无非就是细枝末节的东西，“.”要用&amp;rdquo;-&amp;gt;&amp;rdquo;代替什么的，引入文件建议用“require”什么的，其他的感觉和接触过的弱类型语言差不多。想找乐子大概是没有的。&lt;/p&gt;
&lt;p&gt;要学的知识目前一是会配环境，按目前的说法是，会LNMP就行，所谓LNMP，就是在Linux环境下的Nginx，MySQL和PHP组合环境，这个主要是其实难度我感觉主要是在PHP的编译安装上了，其他的我之前参照CodeSheep的安装手册都装过好几次了，问题倒是不大，主要是记得远程连接的时候，MySQL默认的是只能本地访问，所以要修改配置文件同时给账户添加远程访问授权才可以正常用数据库客户端来访问。PHP我至今都没有装，主要是要编译，头疼了起来。二是PHP基础语法知识，上面说了，其实没什么东西；三是MySQL基础知识，这个8月6号看了一遍SQL，基本把语句过了一遍，另一部分就是PHP的MySQL接口，这个倒是需要看一看。最后一部分就是前端知识了，本着内部软件能用就行的原则，听说前端只用j-Query这种老掉牙的东西，框架都是不鸟的，那没事了。反正能跑就行。大概熟悉一下即可。&lt;/p&gt;
&lt;p&gt;其他的内容暂时没有了，今天完稿时间是8月9日，说实话31号开的坑到现在才填了一点，万分羞愧。感觉自己还是什么都不会。也不知道什么时候才能感觉自己真的能行呢。&lt;/p&gt;
&lt;p&gt;下一篇想的是整理一下MySQL相关语句的东西。大概就先这样吧。&lt;/p&gt;</content><category term="学习笔记"/><category term="PHP"/><category term="原创"/></entry><entry><title>新的开始，迈向工作</title><link href="https://zhiyuansong.xyz/xin-de-kai-shi-mai-xiang-gong-zuo.html" rel="alternate"/><published>2021-07-27T22:51:54+08:00</published><updated>2021-07-27T22:51:54+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-07-27:/xin-de-kai-shi-mai-xiang-gong-zuo.html</id><summary type="html">&lt;p&gt;还是很感谢四年以来的一切，我终究还是度过了比较充实的四年，掌握了一定的学习意识，比较圆满地完成了毕设（能拿90多分我也没想到 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;还是很感谢四年以来的一切，我终究还是度过了比较充实的四年，掌握了一定的学习意识，比较圆满地完成了毕设（能拿90多分我也没想到）拿到了毕业证书，大概也算是一个皆大欢喜的结果。&lt;/p&gt;
&lt;p&gt;22号来了深圳，新的生活开始了。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;热~&lt;/h2&gt;
&lt;p&gt;深圳的天气，大概是那种蒸笼的感觉。西安是热锅，那深圳就是在“蒸”一个人，下雨也感觉不到凉意，每天从公司到酒店短短不到20分钟路程，走一趟就是一身汗，我从来没这么爱洗澡过……&lt;/p&gt;
&lt;h2 id="_2"&gt;培训&lt;/h2&gt;
&lt;p&gt;有种大学新生教育的感觉，确实，每天还是要打卡，按时上下班，不过目前学的是什么工资核算方法、有各种事情该去找谁什么的，竟然还有考试……算术题是算工资🤣孩子笑了，确实，钱怎么能少给呢。&lt;/p&gt;
&lt;h2 id="_3"&gt;人&lt;/h2&gt;
&lt;p&gt;有同班同学、同校同学、同样来自西安的兄弟，甚至还有都是来自大口子的老乡……震惊，我大口子不入流城市，竟也能在深圳遇见老乡，只是碍于面子，没怎么聊过。公司里的人也挺好的，目前看来都很负责至少，这个比较满意，值得好评。&lt;/p&gt;
&lt;h2 id="_4"&gt;公司&lt;/h2&gt;
&lt;p&gt;一栋商用建筑的高层竟然是公司……说实话之前没机会见识过，还大多数都是做跨境电商的，女性居多，这悬殊的男女比例让我这种工科学校出身的深感震撼。这一批来的校招生也好多都是做销售的，敲代码的我们这批还算多的。其他的话，看到有的工作的兄弟抓住午间的一个半小时打开折叠床睡觉，感到了社畜未来的受苦预感……加油，打工人……&lt;/p&gt;
&lt;h2 id="_5"&gt;结尾&lt;/h2&gt;
&lt;p&gt;明天开工，下周二有个日常知识的考试，希望能够顺利度过这三个月的磨合期。&lt;/p&gt;
&lt;p&gt;说实话我之前没想过招来是做php的，那来都来了，那就学吧，反正我是一点都没学过，靠自己，靠师傅了！💪&lt;/p&gt;</content><category term="随便聊聊"/><category term="原创"/></entry><entry><title>暂时的终点：上汽零束HR面总结暨目前一个阶段的完结</title><link href="https://zhiyuansong.xyz/zan-shi-de-zhong-dian-shang-qi-ling-shu-hrmian-zong-jie-ji-mu-qian-yi-ge-jie-duan-de-wan-jie.html" rel="alternate"/><published>2021-05-01T16:36:57+08:00</published><updated>2021-05-01T16:36:57+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-05-01:/zan-shi-de-zhong-dian-shang-qi-ling-shu-hrmian-zong-jie-ji-mu-qian-yi-ge-jie-duan-de-wan-jie.html</id><summary type="html">&lt;p&gt;结果：上汽零束完全按学历刷人，普通211拿不到，只能说自己不够入人家法眼。&lt;/p&gt;
&lt;p&gt;和赛维网络签约了，自己也没有时间再耗下去了。结果 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;结果：上汽零束完全按学历刷人，普通211拿不到，只能说自己不够入人家法眼。&lt;/p&gt;
&lt;p&gt;和赛维网络签约了，自己也没有时间再耗下去了。结果也算挺好了，毕竟当时的目标是能有地方收留就可以。&lt;/p&gt;
&lt;p&gt;以上，新的阶段就要开始了，祝自己在新的阶段取得新的成就，不因为一时的失败而郁郁寡欢。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="hr"&gt;零束HR面&lt;/h2&gt;
&lt;p&gt;总的来说这是我少有的几家到HR面阶段的公司，主要是不少公司都把HR面扔在前面，招人全看眼缘，咱也不是那能说会道的人，被早早刷掉很正常，所以说零束专业面自己过了还是很高兴的。但是自己也知道HR面估计要坑掉一大批人，那当然自己也就没啥把握了呗。&lt;/p&gt;
&lt;p&gt;结果果然如此，总的来说，根据牛客网的数据，基本收的以海外硕士和985本硕为主，加上一些985本科，211除了几个通信专精的学校，其他的就是给人家刷KPI的。😅&lt;/p&gt;
&lt;p&gt;那没事了，虽然我也挺向往上海的，但去不了那也没办法啊，算了。&lt;/p&gt;
&lt;p&gt;主要就是总结以下他问的几个问题罢了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. 校内活动什么的，像是加入的社团活动，班长担任时间
2. 问了问offer薪资，详细到了问公司名字……我搪塞了过去，说实话这个地方有点不舒服，问这么细，活脱脱像是怕自己把薪资定高了似的
3. 去做通信，去吗？我本人没有做通信的想法，还是想做软件开发。
4. 问了问考研什么的
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;没了，差不多就是这些，面试官像是在赶时间，问了也就十七八分钟，提问环节问他问题回答的也比较水，估计也是自己提问没水平吧。&lt;/p&gt;
&lt;p&gt;大概情况就是如此，然后等了几天没有音信后，我就和赛维网络签订了三方协议。&lt;/p&gt;
&lt;h2 id="_1"&gt;总结&lt;/h2&gt;
&lt;p&gt;我求职准备时间可能比较长，大概是从清明假之后才开始投递的，现在回想一下，大概是浪费了一个月的机会，总的来说，实现了自己一开始定的卑微小目标，有个地方收留就不错了，总的来说工资给的还可以，描述总的来说也不是996，当然加班也是免不了的，还有就是还有同班同学在一个公司，还算是比较安心的。&lt;/p&gt;
&lt;p&gt;未来规划是把golang作为第二语言，这几天看了一点，觉得这门语言有点像C语言混加了python的不少东西的样子，但是有的东西真的很怪，像是把数据类型摆在后边，语句设计的似乎就是为了所有人写出来几乎一样的代码来服务的，代码格式卡的死死的。总的来说有一定的适应时间。&lt;/p&gt;
&lt;p&gt;总的来说，人要向前看，向上走。&lt;/p&gt;
&lt;p&gt;不想做课设，但是时间不多了，只能一天啃一点。&lt;/p&gt;
&lt;p&gt;怠惰了。&lt;/p&gt;</content><category term="求职"/><category term="原创"/></entry><entry><title>中联航专业一面总结</title><link href="https://zhiyuansong.xyz/zhong-lian-hang-zhuan-ye-yi-mian-zong-jie.html" rel="alternate"/><published>2021-04-21T15:40:53+08:00</published><updated>2021-04-21T15:40:53+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-04-21:/zhong-lian-hang-zhuan-ye-yi-mian-zong-jie.html</id><summary type="html">&lt;p&gt;我也不知道他问了个啥，就很迷，三个人坐在那里问的问题还不如前几天面的两家一个人问的问题多，而且还在说悄悄话 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我也不知道他问了个啥，就很迷，三个人坐在那里问的问题还不如前几天面的两家一个人问的问题多，而且还在说悄悄话！😡能不能至少尊重一下人啊，服了。&lt;/p&gt;
&lt;p&gt;很麻，那我也总结一下，反正也有答不出来的问题，那总结一下吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;介绍一下自己&lt;/h2&gt;
&lt;p&gt;没啥好说的。&lt;/p&gt;
&lt;h2 id="_2"&gt;服务器&lt;/h2&gt;
&lt;p&gt;问了一下项目是个什么东西，我甚至感觉她是不是不清楚服务器是个啥，问我作用。我内心直打“？”，这是搞什么？然后就回答一下解析HTTP的GET和POST请求，然后返回一个图片和网页内容什么的。然后旁边一男的问我GET和POST有什么区别，我回答一个获取网页内容一个提交表单，然后问我这两个后面有没有参数什么的，还有表单是什么东西……啊这，告辞，不会。&lt;/p&gt;
&lt;h2 id="_3"&gt;扯淡时间&lt;/h2&gt;
&lt;p&gt;然后呢，就是说你专业不对口，说你学网络工程的，转软件开发可能要学很多东西，已经不是“学以致用”了。啊这，我这大学四年除了实习的时候做过网络割接的项目其他时间一直都是在写代码啊，咋到了你这里就好像只能干网络工程师了呢？而且四年学下来我感觉计算机类学的东西都差不多，区别很大吗？&lt;/p&gt;
&lt;p&gt;神秘，太神秘了。&lt;/p&gt;
&lt;h2 id="_4"&gt;社团&lt;/h2&gt;
&lt;p&gt;问了问社团干了什么，还有负责了什么工作。&lt;/p&gt;
&lt;h2 id="_5"&gt;提问时间&lt;/h2&gt;
&lt;p&gt;问了问他们业务方向，主要是做交通运输的软件方向，技术栈主要是后端Java，前端用框架，还有一点数据库的东西（啊这，数据库除了少量数据外不都是要用的吗？）。&lt;/p&gt;
&lt;h2 id="end"&gt;END&lt;/h2&gt;
&lt;p&gt;不明所以，就算技术栈不一样，你服务器根上的东西总能问到吧，结果就是感觉啥都没问到，GET和POST确实是我没看到，我服气了。&lt;/p&gt;
&lt;p&gt;但是体验真心不佳，唉，太难了。&lt;/p&gt;</content><category term="求职"/><category term="原创"/></entry><entry><title>赛维网络专业面试总结</title><link href="https://zhiyuansong.xyz/sai-wei-wang-luo-zhuan-ye-mian-shi-zong-jie.html" rel="alternate"/><published>2021-04-20T20:10:01+08:00</published><updated>2021-04-20T20:10:01+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-04-20:/sai-wei-wang-luo-zhuan-ye-mian-shi-zong-jie.html</id><summary type="html">&lt;p&gt;昨天鬼使神差地新开了一个求职栏，想着毕竟工作也算是一个人身大事，值得写一写，面试不管怎么说总还是有一点收获 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;昨天鬼使神差地新开了一个求职栏，想着毕竟工作也算是一个人身大事，值得写一写，面试不管怎么说总还是有一点收获的。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;先汇报一下情况，昨天看了一下多益网络的游戏策划校招，果然不出意外在第一场面试挂掉了，游戏行业毕竟还是一个赢家通吃的情况，国内目前除了那三家之外其他也就一般，月薪9000块的广州游戏策划，算了。&lt;/p&gt;
&lt;p&gt;然后编程猫没消息估计也挂掉了，半个月过去了都。&lt;/p&gt;
&lt;p&gt;然后是今天，本来以为有一汽丰田的专业面试的，结果呢，它推到明天去了不说，然后说计算机类没有合适岗位了，之后有消息会在群里反馈。啊这，已经四月下旬了，春招马上要结束了，我offer为0真的等不起……&lt;/p&gt;
&lt;p&gt;然后就是面试蒲亨存所在的公司了，人家3天的Java，就进了公司，我也没准备Java，然后就拿着C/C++的简历去投了他家的研发向管培生，结果人家HR反馈说，这部分管培生不包括IT方向，我只能死皮赖脸求HR姐姐给我推到IT方向，说自己有转golang的意愿（确实有啊，golang目前看风评做后端猛的一批啊），那然后就面试了。&lt;/p&gt;
&lt;p&gt;面试是在微信视频上，持续了大概30分钟，总的来说我个人感觉比较尴尬，可能面试官也不用C/C++好久了，根本不问C/C++相关的知识，纯问简历上东西。我简历上项目总的来说也不多，就各种扯，连自己Android项目和毕设项目都扯出来了。&lt;/p&gt;
&lt;h2 id="_1"&gt;自我介绍&lt;/h2&gt;
&lt;p&gt;总的来说没啥东西，就把为啥投他家公司说了一下，有同学嘛，然后他也笑了，表示理解。&lt;/p&gt;
&lt;h2 id="io"&gt;IO复用&lt;/h2&gt;
&lt;p&gt;自己的项目是C/C++开发的epoll并发服务器，问了一下什么时候做的，参考是什么，然后问了下epoll相比其他两个IO复用模型优势在哪里，什么时候都要用epoll吗。然后问了一下使用epoll的著名产品之类的，那我只知道Nginx。有一个问题没答上来，epoll是怎么识别出就绪的线程的，说实话有点蒙，不就是那三个函数吗？问我原理我可记不起来……&lt;/p&gt;
&lt;p&gt;总的来说，这部分准备了挺长时间的，虽然说的磕磕巴巴，但是至少知道不少。&lt;/p&gt;
&lt;h2 id="_2"&gt;数据库&lt;/h2&gt;
&lt;p&gt;问了一下用过什么数据库，我答Mysql和Oracle，然后也就是个知道SQL语句的水平，数据库函数调用都是用封装好的……大概就这样。&lt;/p&gt;
&lt;h2 id="_3"&gt;计算机网络&lt;/h2&gt;
&lt;p&gt;问了TCP协议一个包从一台主机到另一台主机是经过了什么流程。我当时脑子一片混乱，基本语无伦次，然后就讲了个三次握手连接，包的分组传递，四次挥手结束连接，然后他问我包是怎么在网络中传递的，我答依靠路由器查路由表，然后我想不起来如果没查到广播查找IP单播返回结果的协议叫什么来着了（现在想想，CSMA-CD协议？）。然后又问我IP协议起了什么作用，我对照着传输层协议说IP协议是IP对应的主机进行的交流，传输层协议是端口号对应的进程之间的交流……内容大概是这些。&lt;/p&gt;
&lt;p&gt;乱成一锅粥，我感觉答的最不好的地方。&lt;/p&gt;
&lt;h2 id="_4"&gt;数据结构&lt;/h2&gt;
&lt;p&gt;讲一下快排的原理。&lt;/p&gt;
&lt;p&gt;因为不用手写代码，所以还算很快乐，就讲一下划分一次的方法就行。&lt;/p&gt;
&lt;p&gt;还好之前背过快排的模板，深入理解了一下，救我一条狗命。😀&lt;/p&gt;
&lt;h2 id="_5"&gt;其他&lt;/h2&gt;
&lt;p&gt;我也很疑惑他似乎没问操作系统相关的问题，然后对着我几个项目接着问，但是真的没项目了，像是网络割接，也讲不出什么花来，Android实现的“2048”游戏，逻辑实现讲明白也挺难的，就讲了下分工和实现，最后就扯到毕设上了，这训练模型之类的东西他也不懂，我也半懂不懂，大概讲了一下干了什么事，用了什么语言，难度和代码量之类的东西。&lt;/p&gt;
&lt;p&gt;是谁说的计算机语言差别不大的，你看看这和昨天问的根本不是一个路数。&lt;/p&gt;
&lt;h2 id="end"&gt;END&lt;/h2&gt;
&lt;p&gt;问了下熟悉他家公司业务吗，我怎么说也是做过前期调研的，知道他家做海外电商运营这一块，还有自建的电商平台。之后问了一下他家招后端是做自家平台吗，他说主要是做仓储管理这一类的东西，自家平台目前流量太小用不到。&lt;/p&gt;
&lt;p&gt;然后说他家技术栈主要是PHP和Java，问我转PHP可行，我也很疑惑你家不是招golang吗，但也不好说不行，可以考虑，可以考虑。😐&lt;/p&gt;
&lt;p&gt;然后就结束了。大概还行，他也没说不行，还问我技术栈的更换问题，那就是还有的商量。&lt;/p&gt;
&lt;p&gt;明天还有一场联合航空的面试，不知又是什么妖魔鬼怪。🤔&lt;/p&gt;
&lt;p&gt;只求能快点拿到一个offer，我现在根本没时间准备算法，大厂压根不指望。😔&lt;/p&gt;</content><category term="求职"/><category term="C"/><category term="原创"/></entry><entry><title>上汽零束专业面试总结</title><link href="https://zhiyuansong.xyz/shang-qi-ling-shu-zhuan-ye-mian-shi-zong-jie.html" rel="alternate"/><published>2021-04-19T20:39:25+08:00</published><updated>2021-04-19T20:39:25+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-04-19:/shang-qi-ling-shu-zhuan-ye-mian-shi-zong-jie.html</id><summary type="html">&lt;p&gt;今天又收到了上汽零束的电话面试，其实上周五就收到了，但是当时和兄弟们走在北站回学校的隧道里，就约在了周末晚 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;今天又收到了上汽零束的电话面试，其实上周五就收到了，但是当时和兄弟们走在北站回学校的隧道里，就约在了周末晚上，结果自己战战兢兢等了两个晚上也没给来电话，反而是今天下午5点多来电话了。躲是躲不过的，那就上了，然后问题感觉就是C语言基础，感觉还行？&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;下面总结一下他问的问题，总的来说我感觉不难，但是我答得不好，有的点没看到。&lt;/p&gt;
&lt;h2 id="static"&gt;讲讲static的用法&lt;/h2&gt;
&lt;p&gt;我当时思路比较凌乱，就单从C语言的用法上，它就是个静态变量的作用，在程序运行的全局状态都不会释放掉，但是只有当前文件可以访问这一点我紧张没答上来，他提醒了一句我答上来了；然后C++面向对象上我就比较语无伦次地说出了标了static的成员变量或函数是属于类的这么大概个意思，他大概懂了，表示还不错。😂&lt;/p&gt;
&lt;p&gt;总的来说还行，就是我太紧张了。&lt;/p&gt;
&lt;h2 id="sizeof"&gt;sizeof是个函数还是关键字，它必须带括号吗，它获取变量的大小是在编译时还是运行时&lt;/h2&gt;
&lt;p&gt;sizeof当然不是函数是关键字，用途就是获取变量名或数据类型的大小，他唬了我一下说必须要带括号吗，我有点蒙了说不用啊，然后他说他唬我的……自己回去翻了一下，单纯的数据类型是要加括号的，但是变量名可以不加，但是大部分人也不没事找事了，基本上都加了。然后问我获取大小的时间，那我虽然没研究过，但还是觉得是编译时，他说对了。&lt;/p&gt;
&lt;p&gt;总之还是不难，是我紧张外加菜。&lt;/p&gt;
&lt;h2 id="void"&gt;void*指针大小&lt;/h2&gt;
&lt;p&gt;指针的大小不就是和系统有关吗，64位的8字节，32位的砍一半。&lt;/p&gt;
&lt;p&gt;这个问题基本上是和上一个问题连着的，也没啥。&lt;/p&gt;
&lt;h2 id="freenull"&gt;有几种申请内存的方法，申请内存在哪里申请，然后free为啥不用传内存大小就能释放，收到NULL咋办&lt;/h2&gt;
&lt;p&gt;这个题我很麻。因为我就知道一个malloc，没了然后我还傻了吧唧的答memset，还好他耳误听成了malloc，然后我们就这个函数扯了起来，然后就提出了free()为啥不用传内存大小就能释放，收到NULL，free()会做什么。&lt;/p&gt;
&lt;p&gt;首先我扯了个memset上去，那当然不对了，memset撑死了就是给内存设定内容的，只不过大多数情况下填个0当置空来用。申请内存以我的眼界只知道动态申请内存都是在堆上申请的，他说不对，也有不是的。然后别的我也答不上来，很麻。就那个free()为啥不用传大小，那不用传啊，它不是参数就是内存的指针吗？然后传个NULL进去，free()什么都不做。当然这些都是我下来自己man了一下学到的。他说这块算是进阶内容了，你不懂可以理解。😂&lt;/p&gt;
&lt;p&gt;申请内存的函数总结：&lt;br /&gt;
&lt;div class="highlight" data-language="c"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//来自stdlib.h&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//填入一个单位是字节的参数即可，返回一个指向申请内存的指针，内存不会初始化，置空得自己干&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//申请一段a个×b字节的大小的连续内存，返回值同上，内存会初始化为0&lt;/span&gt;

&lt;span class="c1"&gt;//上边两个函数在参数结果是0的时候返回NULL或者一个特定的指针，能让free()顺利处理掉&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//给一个已经存在的指针内存扩展或者缩小内存，ptr原来内存有的东西不动，t的大小比之前大的话，大的部分也不会初始化。ptr必须是之前函数返回过的一个指向内存的指针，为NULL的话，函数等价于malloc，t为0且ptr不为空的话，函数等价于free()&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//释放ptr指向的内存，NULL的话什么都不做&lt;/span&gt;

&lt;span class="c1"&gt;//来自alloca.h&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;alloca&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//在栈上申请内存，内存会自动释放，所以不用担心内存泄漏&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;总的来说，没研究过，压根不懂，溜了溜了。&lt;/p&gt;
&lt;h2 id="atoiatoi"&gt;了解atoi函数吗，然后设计一个atoi函数&lt;/h2&gt;
&lt;p&gt;atoi不就是字符串转数字吗，这个我倒是写过，当时是直接用ASCII码做一下加减运算然后输出这么做的，然后他问我你还记得数字的ASCII码吗？抱歉，忘了。然后呢，我又掏出了我C++的知识（之前看y总算法基础课的时候处理过string类型的单个元素转int，直接减个&amp;lsquo;0&amp;rsquo;），但是我脑抽了。说减个&amp;rsquo;\0&amp;rsquo;，反正他也理解了，说在C语言里这么做也可以。就是我&amp;rsquo;\0&amp;rsquo;大概记错了，下来好好查查。&lt;/p&gt;
&lt;p&gt;48：对应0&lt;br /&gt;
65：对应&amp;rsquo;A&amp;rsquo;&lt;br /&gt;
97：对应&amp;rsquo;a&amp;rsquo;&lt;/p&gt;
&lt;p&gt;忘了，尴尬。&lt;/p&gt;
&lt;h2 id="end"&gt;END&lt;/h2&gt;
&lt;p&gt;最后问了问我有offer吗，我说都在走流程，然后又说了说自己考研没上的情况，然后聊了聊学校和初试没过。他说专业面过了让我等HR通知，说实话比较梦幻，感觉和我想象中差别略大。但是只要offer没到手，我就永远都是没有着落，战战兢兢地情况。总的来说有个地方能收我，工资过得去，能养活自己就可以了，我一定会深钻技术，当个技术人的……&lt;/p&gt;
&lt;p&gt;卑微，太卑微了……明天还有两个面试，只能说尽人事，听天命了……&lt;/p&gt;</content><category term="求职"/><category term="C"/><category term="原创"/></entry><entry><title>服务器两种事件处理模式的理解</title><link href="https://zhiyuansong.xyz/fu-wu-qi-liang-chong-shi-jian-chu-li-mo-shi-de-li-jie.html" rel="alternate"/><published>2021-04-08T21:26:46+08:00</published><updated>2021-04-08T21:26:46+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-04-08:/fu-wu-qi-liang-chong-shi-jian-chu-li-mo-shi-de-li-jie.html</id><summary type="html">&lt;p&gt;这是我在做服务器的时候一直难以理解的问题——什么是 Reactor，什么又是 Proactor。项目可以照着做，但理解却难上天。毕竟大学编程课 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这是我在做服务器的时候一直难以理解的问题——什么是 Reactor，什么又是 Proactor。项目可以照着做，但理解却难上天。毕竟大学编程课连多进程、多线程都不教，更别说同步异步了。操作系统那门课倒是讲了进程线程，但完全就是念 PPT，服了。😂&lt;/p&gt;
&lt;p&gt;下面大概要磨磨唧唧写点东西，也不知道对不对，反正写就是了，估计未来的我回看会笑掉大牙吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;同步与异步&lt;/h2&gt;
&lt;p&gt;说起同步异步：同步就是事情要做了，那就一定要做完才给你结果。中间可能存在阻塞这类事情，返回一个结果可能要相当长的一段时间。而异步，就是事情要做了，我先告诉你会做的、结果会给你的，不用等了，之后处理完了，你过来拿。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;备注&lt;/strong&gt;：这篇先鸽掉了，之后会补齐 Reactor 和 Proactor 的内容。&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="学习笔记"/><category term="服务器"/><category term="原创"/></entry><entry><title>算法基础课笔记（二）：高精度、前缀和和差分</title><link href="https://zhiyuansong.xyz/suan-fa-ji-chu-ke-bi-ji-er-gao-jing-du-qian-zhui-he-he-chai-fen.html" rel="alternate"/><published>2021-04-01T10:44:31+08:00</published><updated>2021-04-01T10:44:31+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-04-01:/suan-fa-ji-chu-ke-bi-ji-er-gao-jing-du-qian-zhui-he-he-chai-fen.html</id><summary type="html">&lt;p&gt;这是第二节课，单纯从高精度也就是大数运算的角度来说，我记得之前做课设时候的数字加密器，用Java做直接就有BigDecimal类，可以做大数运算，相 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这是第二节课，单纯从高精度也就是大数运算的角度来说，我记得之前做课设时候的数字加密器，用Java做直接就有BigDecimal类，可以做大数运算，相对而言c/c++就没这么便利了。前缀和和差分我好像是闻所未闻，大概就是这么个情况。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;高精度&lt;/h2&gt;
&lt;p&gt;一般来说，超大数字用的不多，long在平时场景处理数据时候已经够用了，但是一旦用到了，c/c++没有相关处理机制，就很难受。目前的处理思路是把数字按位塞进数组里，然后再设计算法进行运算。涉及的有两个大数相加、相减，大数和一个较小的数相乘，大数除以一个较小的数。&lt;/p&gt;
&lt;h3 id="_2"&gt;加法&lt;/h3&gt;
&lt;p&gt;先上模板：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//判断一下两个数的长度，用长的加上短的&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//进位的存储&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//A[i] + B[i] + t，和10取余是当前位，除以10得到的是进位&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;//很明显若B短，之后就变成了A[i] + t&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//最后若t不为0，说明还有进位，要塞进去&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;算法实现比较简单，记得最后判断t的值来确定最后还用不用进位，处理数据的部分也是要注意的点，要把高位放进下标大的位置，从平常来看就是把数字倒着放入数组里。&lt;/p&gt;
&lt;p&gt;容器的使用相比数组的好处就是可以直接用&lt;code&gt;size()&lt;/code&gt;成员函数来判断长度也不用担心数组固定大小带来的各种问题，string的元素减&lt;code&gt;'0'&lt;/code&gt;可以变成数字倒是之前没见过的，之前用c做主要语言时候基本是用&lt;code&gt;c_str()&lt;/code&gt;成员函数把string类型转成c类型的字符串（就是字符数组），然后再用&lt;code&gt;atoi()&lt;/code&gt;函数转成数字，学到了。&lt;/p&gt;
&lt;h3 id="_3"&gt;减法&lt;/h3&gt;
&lt;p&gt;先上模板：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//当两个数字不等长的时候，肯定是长的大&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//等长的时候，比较的时候，从高位开始比较，高位大的就大&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;trimZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop_back&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;//保证A的长度大于等于B的长度，且两个数字都不小于0&lt;/span&gt;
&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//当数字的是高位有0的时候，把0删掉&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;trimZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//如果数据合法那么去0这一步完全可以去掉&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//trimZero(A), trimZero(B);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;主要注意的问题是，对应位数相减，如果从最高位开始有0，那么就要把0去掉，不然输出结果就会很奇怪。模板解决的只有大的减小的，且两个数都非负的情况，如果是其他情况可以通过结合加法的模板来计算，像是负数-正数可以转化成-(正数+正数)，完全可以用加法模板来做。&lt;/p&gt;
&lt;p&gt;做这个题的时候，我的模板还是没有背熟，竟然在&lt;code&gt;main()&lt;/code&gt;函数处理数据的部分都能写错，导致出现了段错误，每次出现段错误都只能自己慢慢查找老半天，丢人了。&lt;/p&gt;
&lt;h3 id="_4"&gt;乘法&lt;/h3&gt;
&lt;p&gt;这里的乘法指的是大数乘以一个较小的数字，单纯来说&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;//进位&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//当t不为0，说明进行到最后还有进位，要直接放入&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//其实如果上一步执行了，这一步基本不会执行了，这一步是为了除去从高位开始出现的0的&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop_back&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;整个算法不少内容都和前两个算法的思想差不多，可以参考。&lt;/p&gt;
&lt;h3 id="_5"&gt;除法&lt;/h3&gt;
&lt;p&gt;一个大数除以一个较小的数字：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//A / b = C ... r,A &amp;gt;= 0,b &amp;gt; 0&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//除法的处理是从高位开始的所以要倒着处理&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//存放的顺序颠倒了，要反转一下&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//去掉高位可能存在的0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop_back&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//r用来存储余数&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;具体处理，&lt;code&gt;main()&lt;/code&gt;的部分基本和乘法的差别不大，函数部分要注意的地方就是除法是从高位开始处理的，其他的问题不是太大。&lt;/p&gt;
&lt;h2 id="_6"&gt;前缀和&lt;/h2&gt;
&lt;p&gt;前缀和简单的来说就是一个数列的前n项和作为一个新的数列S来存储的话，举例：S[5]就是数列的前五个项的和，此处特殊定义S[0] = 0，前缀和可以处理一些数组中的连续的数字之和这类的问题，例如要求一个数列第3到第5个数字的和，可以用前缀和表示成S[5] - S[2],特殊地，可以用S[5] - S[0]解决第1个到第5个数字和的问题。&lt;/p&gt;
&lt;p&gt;前缀和的实现可以用递归来做，基于S[i] = S[i - 1] + a[i]:&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//计算前缀和&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;calcS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calcS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;递归做法在处理大量数据的时候总会遇见各种超时，空间不够的问题，这个只能改写成栈的方式解决。&lt;/p&gt;
&lt;h2 id="_7"&gt;差分&lt;/h2&gt;
&lt;p&gt;差分可以说是前缀和的逆运算，试想一下，假设一个数列A，可以获得一个前缀和数列B；反过来说，数列B的差分数列就是数列A。&lt;/p&gt;
&lt;p&gt;差分数列A的特点就是B[i] = A[1] + &amp;hellip; + A[i]，如果要构造的话，可以令A[1] = B[1],A[2] = B[2] - B[1],A[3] = B[3] - B[2]&amp;hellip;但是实际应用中，构造差分数列并不重要，重要的是应用这个差分的性质来解题。&lt;/p&gt;
&lt;p&gt;假定一种情况：对于数组B的从下标l到下标r的所有的数字都加上一个c，如果是通常暴力做法，遍历一遍数组然后挨个往上加，那么就是O(n)的时间复杂度。但是还有另外一种方法：假设数组B有一个差分数组A，那么差分数组的前n项和等于B对应下标n的元素，那么，对A[l]加上一个c，那么根据性质B[l]往后的每个数都加上了一个c，但是要使B[r + 1]开始的值不要再加c了，那么就要对A[r + 1]加上一个c来抵消掉之前加上的c带来的影响。这样只修改了两个数字，时间复杂度是O(1)。&lt;/p&gt;
&lt;p&gt;以下是上面提出问题的代码实现：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="c1"&gt;//group2是group的差分数列&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//怎么构造出差分数列呢？&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d%d%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;//计算一遍group2的前缀和&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;group2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;二重差分的操作类似，若要对B的子矩阵都加上一个c，实际上操作就是对差分矩阵A的对应子矩阵的四角元素进行操作，左上和右下是加，左下和右上是减。&lt;/p&gt;</content><category term="学习笔记"/><category term="算法"/><category term="原创"/></entry><entry><title>算法基础课笔记（一）：快排，归并以及二分查找</title><link href="https://zhiyuansong.xyz/suan-fa-ji-chu-ke-bi-ji-yi-kuai-pai-gui-bing-yi-ji-er-fen-cha-zhao.html" rel="alternate"/><published>2021-03-31T11:11:55+08:00</published><updated>2021-03-31T11:11:55+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-03-31:/suan-fa-ji-chu-ke-bi-ji-yi-kuai-pai-gui-bing-yi-ji-er-fen-cha-zhao.html</id><summary type="html">&lt;p&gt;看看自己博客这竟然是第一篇算法相关的文章……我学东西一向是有用的才学，有时候算法这东西用的时候理解上网搜一 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;看看自己博客这竟然是第一篇算法相关的文章……我学东西一向是有用的才学，有时候算法这东西用的时候理解上网搜一搜，但是为了准备工作，还是得系统学学，刷刷题目，背背模板之类的。感谢欧翔曦给我指了条明路，先看y总的算法基础课，总的来说第一讲效果挺好，几个模板吃透了感觉要比准备考研时候学习数据结构还清晰。反正之前无脑乱刷是真的痛苦😔。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;快速排序&lt;/h2&gt;
&lt;p&gt;快排属于分治思想的一种，简单来说，就是每一趟，找一个基准点（当时考研的时候复习叫枢轴），把大于枢轴的放在一边，小于等于枢轴的放在另一边，如此再对两边进行找枢轴划分的操作……如此递归，最终得到一个有序的数列，当时复习的时候，记得快排算是不稳定的算法，时间复杂度是O(nlogn)。&lt;/p&gt;
&lt;p&gt;快排的思想很简单，但是难点就在划分这一步怎么实现上。&lt;/p&gt;
&lt;p&gt;这一步要是暴力来做，可以开两个额外数组，小于枢轴的扔到一个里，大于枢轴的扔到另外一个里，然后再按顺序扔回原来的数组里，完成一次划分。但是额外空间太浪费了。&lt;/p&gt;
&lt;p&gt;课上所讲的划分方法，是指定指向数组有左右两个指针，左侧指针在保证指向数字小于枢轴的情况下向右移动，右侧指针在保证指向数字大于枢轴的情况下向左移动；两个都移不动的时候，说明左指针指向的数大于枢轴而右指针指的小于枢轴，这样一来，对两个数字进行一次交换即可，如此循环直到两个指针相遇完成一次划分。&lt;/p&gt;
&lt;p&gt;模板如下：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;quick_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;quick_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;quick_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;quick_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;本来在之前的模板里，枢轴选取是选的&lt;code&gt;q[l]&lt;/code&gt;的，但是我试了一下会报段错误，有边界问题，保险起见选中间的，不会有问题。&lt;/p&gt;
&lt;h2 id="_2"&gt;归并排序&lt;/h2&gt;
&lt;p&gt;归并排序也是分治思想的一种体现，先找中间位置的点，分成两片，然后递归左右两边，再归并，把小的合并成大的。归并排序时间复杂度是O(nlogn)，稳定。&lt;/p&gt;
&lt;p&gt;归并排序的难点在归并这一步，其实这一步完成了排序的操作，因为归并是一个由小合大的过程，当区间小到长度为1时，这时的小区间就是有序的，那么归并的过程就要保证小区间合成后的大区间有序性。&lt;/p&gt;
&lt;p&gt;提出的想法是，申请一个额外数组，对归并的两个数组头部加上指针，比较两个指针指向的数字大小，数字小的加入额外数组且指针右移。如此循环直到一个数组为空，将另一个数组的余下值放入额外数组中。再将额外数组的值放回原来的数组，完成一次归并。&lt;/p&gt;
&lt;p&gt;模板如下：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;merge_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merge_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merge_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merge_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;单纯的归并排序还能扩展出新的题目，像是这么一道题，求一个数列逆序数对的个数，就可以用归并的方法做，只需要在上面的模板修改以下的部分：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//最后返回count即可&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;关于&lt;code&gt;count&lt;/code&gt;的理解：因为归并的两部分都是有序的，用模板来说是由小到大的，那么只要左边数组里的下标为&lt;code&gt;i&lt;/code&gt;的值大于右边的一个值的话，那么对于右边的这个值，左边从&lt;code&gt;i&lt;/code&gt;到&lt;code&gt;mid&lt;/code&gt;的所有值都比它大，即可组成&lt;code&gt;mid - i + 1&lt;/code&gt;个逆序对。&lt;/p&gt;
&lt;h2 id="_3"&gt;二分查找（整数/浮点数）&lt;/h2&gt;
&lt;p&gt;二分查找在我印象中应该是在初中还是高中数学书中介绍的一种解方程的方法，思想很简单，确定问题的解在一个确定的区间中，找到这个区间的中间值mid，带入到问题中做判断，如此来判断解是在mid的左边还是mid的右边，这样区间就缩小了，如此重复这个过程，区间的长度越来越小，小到满足精度要求时候，就可以认为区间左右任一个断点可作为问题的解。&lt;/p&gt;
&lt;p&gt;其实二分的应用场景不是有单调性的排列，可以说是具有某种阶段变化的序列都可以用二分来判断。所以单调序列都可以二分，但是可以二分的问题不一定是单调的。&lt;/p&gt;
&lt;p&gt;这么理解下来，其实问题很简单，二分查找的模板可以很轻松地写一个出来：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;bsearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//check(double)是一个判断函数，具体怎么实现要看实际情况&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;对于浮点数的情况来说，二分查找比较简单，因为不会产生边界问题，数字都是连续的，不会存在边界问题。&lt;/p&gt;
&lt;p&gt;但是对于整数的二分，根据问题的不同，由于C/C++的整数除法是下取整的，在某些情况下会发生边界问题。所以有两个模板：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//区间被划分成[l,mid]和[mid + 1,r]时使用&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;bsearch_1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//区间被划分成[l,mid - 1]和[mid,r]时使用&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;bsearch_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这里一个难以理解的点就是在划分为[l,mid - 1]和[mid,r]的情况下为什么mid等于(l + r + 1) / 2,可以这么想，不加1的情况下，若[l,r]的长度为1，此时的(l + r) / 2即(l + l + 1) / 2，由于c/c++整数除法向下取整的特性，此时mid等于l，那么在&lt;code&gt;check(mid)&lt;/code&gt;为true的情况下，l会等于自身，整个while循环会进入死循环的状态，所以为了避免这种情况，要加1，防止l等于自身。&lt;/p&gt;
&lt;p&gt;其实写到这里还是有点摸不到头脑，似乎说不太清楚这两种情况究竟是什么样的，下面看这么一道题。&lt;/p&gt;
&lt;p&gt;题目名字叫做&lt;a href="https://www.acwing.com/problem/content/791/"&gt;数的范围&lt;/a&gt;，这道题是一个整数二分查找问题，目标数列是一个单调有序数列，要求对于输入的查询元素在数列中找到数的起始下标和终止下标。本题实现的代码如下：&lt;/p&gt;
&lt;div class="highlight" data-language="c++"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d %d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;//先找起始下标&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid_1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-1 -1&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;//再找终止下标&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid_2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid_2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这道题处理一个数的起始和终止位置，其实就是用了两次二分，正好用了两次上面介绍的模板。记住模板后，设计判断函数的部分决定了要用哪一个模板，一开始写可能会有点蒙，但是只要记住不同的划分情况用的模板就行了。&lt;/p&gt;
&lt;p&gt;后记：就上面那道题我写的挺快的，结果报了半天的超时错误跑不过，结果查了半天发现是把mid写在了每个while的上面……而且设计判断函数的过程也比较痛苦，那个大于等于号和小于等于号分别归属于哪个情况，转了半天弯。还是功力太浅。&lt;/p&gt;
&lt;h2 id="_4"&gt;总结&lt;/h2&gt;
&lt;p&gt;这节课学了两种排序和一种查找方法，借助固定的模板，自己感觉能比较快的写出来，理解上也相比考研时候更清楚了，当时看王道的数据结构课，说实话就是过课本，写代码的能力倒是真的没有什么提高，y总的课总体来说还是不错的，让我在做算法题上有了个思路。&lt;/p&gt;
&lt;p&gt;这是第一节课的总结，加油。&lt;/p&gt;</content><category term="学习笔记"/><category term="算法"/><category term="排序"/><category term="查找"/><category term="原创"/></entry><entry><title>完结篇？网站的上线解析和备案完成</title><link href="https://zhiyuansong.xyz/wan-jie-pian-wang-zhan-de-shang-xian-jie-xi-he-bei-an-wan-cheng.html" rel="alternate"/><published>2021-03-20T19:41:57+08:00</published><updated>2021-03-20T19:41:57+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-03-20:/wan-jie-pian-wang-zhan-de-shang-xian-jie-xi-he-bei-an-wan-cheng.html</id><summary type="html">&lt;p&gt;上一篇写到了还差网站地址解析和备案完成这两步，今天终于完成了两个备案，可以放心的把网站挂出来了，以下简单记 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;上一篇写到了还差网站地址解析和备案完成这两步，今天终于完成了两个备案，可以放心的把网站挂出来了，以下简单记录一下流程。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id="_1"&gt;域名的解析&lt;/h2&gt;
&lt;p&gt;首先在上一篇做的事情是已经把网站挂在了Nginx上，可以直接通过服务器ip直接访问网站了。这一步要做的是把网站的域名解析到服务器ip上，从计算机网络的角度来说就是dns这一步。&lt;/p&gt;
&lt;p&gt;这一步其实相当简单了，现在云服务器提供商基本我用过的阿里云和腾讯云都免费提供域名的解析。基本上就是在域名控制台下就能完成域名的解析配置工作。就我目前的配置经验来说，A类型的解析记录配置一条，其他的直接写CNAME类型指向A类型的域名就行了。举个例子，把域名记录都指向“www”的域名，那么就A记录配置“www”域名，将不带“www”的域名CNAME类型指向“www”类型即可。这样就不会搞得域名一会儿带“www”一会儿不带，显得不协调了。&lt;/p&gt;
&lt;h2 id="_2"&gt;给域名配置安全证书&lt;/h2&gt;
&lt;p&gt;配置安全证书好处是网站访问加强为https访问，浏览器访问也不会显示不安全的标签。虽然来说我一个博客网站装不装没两样，但是，有就是好。别的就不说了。&lt;/p&gt;
&lt;p&gt;免费证书的申请腾讯云就有，有效期一年，暂时不知道怎么续期，配置的方法腾讯云的文档针对各个主流后台服务端程序都有说明，基本就是把证书解压然后把其中的两个文件放到对应的后台服务器文件夹下然后进服务器里面配置文件的对应位置。要强调的是，一个域名一个证书就够了，不需要搞什么“www”的申请一个，不带的再申请一个，没必要，上一步反正都直接指向唯一的一个域名了。那只配置那一个域名即可。&lt;/p&gt;
&lt;p&gt;配置强制转向https访问的功能也简单，在此略过。&lt;/p&gt;
&lt;h2 id="_3"&gt;网站备案&lt;/h2&gt;
&lt;p&gt;走到这一步了，恭喜你，最后一步只是合规合法的问题了。老老实实走流程即可。&lt;/p&gt;
&lt;p&gt;管局备案，这一步直接腾讯云就能做，腾讯云内部审核后会提交管局审核，反正感谢腾讯云客服，我填的不合适的地方，她们直接电话联系帮我修改了，免去了很多事情。就经验来说，网站名字不要有名字，昵称、网名也不要有（大概是因为我网名和名字有一个字一样？），不要出现博客这类字眼，似乎是因为带交互内容的网站内容审核会卡的很严。管局备案下来大概花了一周多的时间。&lt;/p&gt;
&lt;p&gt;之后会有通知提醒做公安报备，这一步相对上一步来说好像严了一点，要你对网站的内容进行描述，有了管局审核的经验，我这次就是把网站名字相关的敏感关键词去掉，然后去掉网站的交互式内容（好像造个评论区都不行的样子……），总之整个网站就是个类似公开日志的东西，网站内容也没有选什么交互式内容，博客也没选，只选了最基本的http（还是www来着？忘了）服务。过审大概花了半个月时间。虽然有点慢吧，但是过审了就是好事。&lt;/p&gt;
&lt;p&gt;个人不太清楚如果我现在网站内容增增减减警察叔叔会不会来定期检查，其实网站名字，别人能不能评论也不重要，只要我自己有个写东西的地方就好了。&lt;/p&gt;
&lt;h2 id="end"&gt;END&lt;/h2&gt;
&lt;p&gt;最近一直在准备找工作，我真的不知道自己找得到找不到，学校还一直催催催。反正我是不会啃老的，大不了从代码民工干起，我庆幸自己还是个年轻人。&lt;/p&gt;
&lt;p&gt;网站过审是个好消息，希望到时候也能有个好企业收留孩子😂&lt;/p&gt;</content><category term="实用小文章"/><category term="网站"/><category term="博客"/><category term="服务器"/><category term="原创"/></entry><entry><title>博客迁移至服务器的相关工作</title><link href="https://zhiyuansong.xyz/bo-ke-qian-yi-zhi-fu-wu-qi-de-xiang-guan-gong-zuo.html" rel="alternate"/><published>2021-03-04T22:39:56+08:00</published><updated>2021-03-04T22:39:56+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2021-03-04:/bo-ke-qian-yi-zhi-fu-wu-qi-de-xiang-guan-gong-zuo.html</id><summary type="html">&lt;p&gt;在假期学习C/C++相关知识的途中又在腾讯云购置了一台云服务器，在学习云服务使用的同时也想把自己放在github上的博客网站部署到服务器上，难度还 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;在假期学习C/C++相关知识的途中又在腾讯云购置了一台云服务器，在学习云服务使用的同时也想把自己放在github上的博客网站部署到服务器上，难度还好，大概一天就能弄完，目前备案号还没有下来。待到备案号下来后填上，把域名解析到自己这台服务器便可大功告成。以下简述过程。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;备案&lt;/h2&gt;
&lt;p&gt;备案包括服务器和域名的备案。域名的备案我在之前就做过了，服务器备案是这次新做的，之前也没有经验，总的来说没有难度，域名备案只要上传个人实名信息，服务器备案主要是时间长一点，要过省级管理部门之手，但是只要跟着网上备案系统的提示走，挺方便的。腾讯云的客服也很有耐心，各种填的不合理的地方都能指出，感谢感谢。&lt;/p&gt;
&lt;h2 id="_2"&gt;部署&lt;/h2&gt;
&lt;p&gt;分两步，前台和后台。&lt;br /&gt;
前台还是老样子，拿Hexo做，NexT的主题，之前做博客的时候写过相关的内容了，只不过是重新在服务器上做一遍，首先，用yum安装的nodejs版本太低了，直接自行安装最新版本的吧，然后记住用cnpm的镜像，相对快一点，其他浪费时间的地方就是从github上克隆主题太浪费时间以及主题配崩了只能重下（谁会给这东西备个份啊……），总的来说参照之前的博客和相关文档都能配的七七八八，难也不难，然后把之前写的markdown文件都传到对应的文件夹里，基本就成了。当然你&lt;code&gt;hexo s&lt;/code&gt;跑本地测试不开4000端口也看不见啥东西。至于挂github，和之前差不多，注意配ssh公钥和hexo配置就行了，做到这一步，无非就是把之前的操作机从我本地电脑搬到了了服务器上,还是和之前差不多挂着github page。&lt;br /&gt;
后台就是找个服务器程序，这东西目前我还写不出来，未来估计可以，我用的是Nginx，网上参考资料挺多的，总的来说就是安好后配置系统服务开机启动之类的，然后配置nginx.conf文件，挂上hexo工程里的public文件夹。这个文件夹里在每次输入&lt;code&gt;hexo g&lt;/code&gt;生成网站页面的变化都会显示出来。然后访问在开着80端口的情况下直接从ip访问效果就成。这么一来，每次写完直接&lt;code&gt;hexo g&lt;/code&gt;就完成了网页更新，github page要再&lt;code&gt;hexo d&lt;/code&gt;一下。如此基本大功告成。&lt;/p&gt;
&lt;h2 id="_3"&gt;总结&lt;/h2&gt;
&lt;p&gt;这次部署其实有点脱离自己之前的预想，之前想的是在本地计算机完成编写然后分别上传到服务器和github上，实际上却是在服务器上部署了工程，以后每次写博客都要远程连接到服务器，生成、编写、构建网页、上传github一条龙。优点是有的，不占我本地计算机空间了；不便的就是写博客要连到服务器，没网要命。而且就目前来说，只能用vscode来获得相对比较好的编辑环境了，typora用起来不是那么方便，不能远程连接。图床倒是还可以接着用之前的，问题不大。&lt;br /&gt;
自己也没研究过怎么能把自己的这一套工程配置保存下来，省的以后搬家还得再重新搭，费事，大概直接传一份到github仓库上就行？之后研究研究看看怎么办吧。&lt;br /&gt;
还差域名解析和备案完成这些内容，过两天弄好了之后再写一篇。&lt;br /&gt;
以上。&lt;/p&gt;</content><category term="实用小文章"/><category term="博客"/><category term="网站"/><category term="服务器"/><category term="原创"/></entry><entry><title>考研后有感</title><link href="https://zhiyuansong.xyz/kao-yan-hou-you-gan.html" rel="alternate"/><published>2020-12-31T22:14:37+08:00</published><updated>2020-12-31T22:14:37+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-12-31:/kao-yan-hou-you-gan.html</id><summary type="html">&lt;p&gt;今天是12月31日，2021年的研究生招生考试开始于12月26日，结束于12月27日。考完之后，个人知道自己的数学怕是不能远远不能满足华科网络空间安全学院的要求了。长达快一 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;今天是12月31日，2021年的研究生招生考试开始于12月26日，结束于12月27日。考完之后，个人知道自己的数学怕是不能远远不能满足华科网络空间安全学院的要求了。长达快一年的马拉松式复习终究还是结束了，伴随着一种不知说是痛苦，还是说随着人的成长而演化成的强装镇定，一种说不出来的心情。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;个人反思，自己的原因在于首先不够专心，被手机分散精力太多。其次是自己选择专业犹豫再三，是基于自己的复习状况来实时确定自己的方向，目标一降再降，最终定在了软件专硕，但是由于客观原因考试科目发生了改变，自己本就复习的千疮百孔的数学终究还是崩溃了，最后一百天基本就是在迷茫中度过，概率论看了记不住，线代越看越忘。唯有一半的高数还记得，大概就是整张卷子上的二三十分有把握拿到，其他的就是一片稀烂。说出去丢人。相当于数学考试是硬着头皮上的。结果可想而知。&lt;/p&gt;
&lt;p&gt;我在复习的时候甚至产生了疑问，我考研究竟是为了什么，从内心最卑劣的欲望谈起我就是想要有一个看的过去的的学历，计算机专业相关的高大上的术语我并不喜欢，反而感觉很做作。或许是年少轻狂，我还记得当时选择这个专业的想法是做自己想要做的，喜欢的软件，目前看来大概就是游戏这类他人眼中歪门邪道的东西把。但是嘴上口口声声说着，却不肯动，四年了，都是这样混日子过来的。如果考上研大概就又是两年多时间的混日子吧。那看来没考上还是好事。让我至少动了起来。&lt;/p&gt;
&lt;p&gt;最后悔的事情大概是自己没有在有时间时候出去找个实习岗干干，到了大四才发现自己会的企业也并不需要，一张白板进，一张白板出。&lt;/p&gt;
&lt;p&gt;人如果不能进步，就只能被淘汰，我不想做一个沉底的人，不求人前显贵，只求自己从事的职业，自己喜欢，自己值得骄傲，自己有能力做的更好。&lt;/p&gt;
&lt;p&gt;我的价值可以被他人认可吗？&lt;/p&gt;</content><category term="随便聊聊"/></entry><entry><title>基于tomcat疫情地图的部署学习</title><link href="https://zhiyuansong.xyz/ji-yu-tomcatyi-qing-di-tu-de-bu-shu-xue-xi.html" rel="alternate"/><published>2020-08-07T15:40:47+08:00</published><updated>2020-08-07T15:40:47+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-08-07:/ji-yu-tomcatyi-qing-di-tu-de-bu-shu-xue-xi.html</id><summary type="html">&lt;h2 id="_1"&gt;前言&lt;/h2&gt;
&lt;p&gt;老实说这根本算不上是个项目吧。就是自己看见小甲鱼的某个开课吧恰饭广告突然心血来潮想着就算参加了也不 …&lt;/p&gt;</summary><content type="html">&lt;h2 id="_1"&gt;前言&lt;/h2&gt;
&lt;p&gt;老实说这根本算不上是个项目吧。就是自己看见小甲鱼的某个开课吧恰饭广告突然心血来潮想着就算参加了也不会掉块肉，然后就加了进去看看。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;总的来说东西非常简单，因为是面向0基础同学的，所以估计大部分人也就是看看，自己也算是科班出身那就更是没啥难度了。就是不求甚解地在阿里云服务器上部署一个tomcat服务，然后把前端jsp扔到容器里边，写上不到10行代码，再申请一个微信订阅号，整一个自动回复，就完成了。我上午磨磨叽叽边复习政治边做，走上正轨后也就是花了个大概一个多小时就完事了。&lt;/p&gt;
&lt;h2 id="_2"&gt;具体步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;整一台服务器，我用的是2月份从阿里云白嫖的服务器，还有二十来天可用，然后自己一开始想用自己的虚拟机来做，不过期间问题不少。就放弃了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;装JDK和tomcat，这个部分我之前参考着程序羊的手册在虚拟机上做了一遍，这个部分不难。照做就行，昨天踩的坑都总结了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置访问端口，tomcat默认页面是8080端口访问，改成80主要是为了用http访问。修改tomcat目录conf文件夹里面server.xml的connector项，打开一眼就能看到&amp;rdquo;8080&amp;rdquo;，改了就行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;云服务器相比虚拟机好的一点就是配置出入规则太方便了，想打开哪个端口也不用敲命令。打开80端口的访问权限后http访问，tomcat打开的情况下直接就会显示默认页面。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把前端提供的脚本和页面添加到webapps文件夹里面去，脚本直接丢进去，页面就是复制然后替换index.jsp文件，保留编码规定的那一行。现在访问无法获取数据，要想动态获取数据就是给index.jsp添加java控制代码：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;```html&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
         &lt;%
           //获取疫情数据的网址
           URL url = new URL("https://zaixianke.com/yq/all");
             URLConnection conn = url.openConnection();
             //获取输入流
             InputStream in = conn.getInputStream();
             //包装输入流为字符流进一步包装为缓冲字符流
             BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
             //读取一行内容
             String str = reader.readLine();
          //这句没用
             System.out.println(str);
         %&gt;
           var data = &lt;%=str%&gt;;
       &lt;/script&gt;&lt;/p&gt;
&lt;p&gt;```&lt;/p&gt;
&lt;p&gt;这个部分把Java代码嵌入到页面完成了个数据读取的功能，说实话现在前端还用JSP这东西吗？Java代码当然包还是要导入的，导入的部分也在index.jsp里实现：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;html
   //就是上面要求保留的编码规定的那一行
   &amp;lt;%@ page session="false"
   import="java.io.BufferedReader,java.io.IOException,java.io.InputStream,java.io.InputStreamReader,java.net.URL,java.net.URLConnection,java.nio.charset.StandardCharsets"
   pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;现在再访问，结果就是动态的了。&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;申请个微信订阅号，做个自动留言。这个太简单了，只不过是个表现形式而已，申请一遍就无师自通了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200807163428.png"  /&gt;&lt;br /&gt;
&lt;img src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200807163450.png"  /&gt;&lt;/p&gt;
&lt;h2 id="_3"&gt;总结&lt;/h2&gt;
&lt;p&gt;基本没讲什么的水课，唯一的用处大概就是让我用了用云服务器的服务部署，了解了一下tomcat和JSP，其他的感觉就和你在bilibili上找个网课看效果差不多，编程这个行当确实就是得多练多学多敲多输出，不是你整一个网课学过了就以为学到了。&lt;/p&gt;
&lt;p&gt;个人竟然被这个动摇了考研的心志……惭愧。考研还是为了见识更广，二十多岁正是学习的好时机，为什么要忙着去赚钱呢？&lt;/p&gt;
&lt;p&gt;材料扔到网盘里了，这只是个部署，也没必要扔到github上。&lt;/p&gt;
&lt;p&gt;进步一点点。&lt;/p&gt;</content><category term="项目实践"/><category term="tomcat"/></entry><entry><title>初探tomcat的两个坑</title><link href="https://zhiyuansong.xyz/chu-tan-tomcatde-liang-ge-keng.html" rel="alternate"/><published>2020-08-06T22:07:17+08:00</published><updated>2020-08-06T22:07:17+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-08-06:/chu-tan-tomcatde-liang-ge-keng.html</id><summary type="html">&lt;p&gt;自从上次风风火火装完了java的一套后端系统，我也没仔细研究过，然后今日想试一试，然后就踩坑了……&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;首先第一个坑，上次配置过的tomcat启动和关闭命令在运行时会报找不到JAVA_HOME和JRE_HOME的错误，然后我 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;自从上次风风火火装完了java的一套后端系统，我也没仔细研究过，然后今日想试一试，然后就踩坑了……&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;首先第一个坑，上次配置过的tomcat启动和关闭命令在运行时会报找不到JAVA_HOME和JRE_HOME的错误，然后我遍寻网络，各种说法都有，最后在tomcat的bin目录下的catalina.sh中添加了一个&lt;code&gt;export JAVA_HOME="JDK的路径"&lt;/code&gt;才解决了这个问题。&lt;/p&gt;
&lt;p&gt;第二个坑，这是上次留下的，上次配好之后我没有细究，就是无法访问IP地址下的8080端口，然后一开始以为是8080被其他程序占用了，查询情况无果。最后通过解决防火墙的端口打开才把问题解决……（也是一个教训，之前总是想着宿主机的防火墙，没想到还有一个虚拟机的防火墙）&lt;/p&gt;
&lt;p&gt;代码如下（系统是CentOS 8）:&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;第一句就是在public作用域上添加8080端口运行TCP协议，永久生效；第二句是重启防火墙。&lt;/p&gt;
&lt;p&gt;深感自己所学的浅薄，目前粗浅地只能理解tomcat就是个装前端的容器。🤔&lt;/p&gt;</content><category term="学习笔记"/><category term="tomcat"/><category term="防火墙"/></entry><entry><title>暑期线上实习总结</title><link href="https://zhiyuansong.xyz/shu-qi-xian-shang-shi-xi-zong-jie.html" rel="alternate"/><published>2020-08-05T20:34:41+08:00</published><updated>2020-08-05T20:34:41+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-08-05:/shu-qi-xian-shang-shi-xi-zong-jie.html</id><summary type="html">&lt;p&gt;这次学校组织的线上实习总的来说还是有所收获的，我怀着内心还没有复习高数第二遍完成的沉重心情来总结一下还 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这次学校组织的线上实习总的来说还是有所收获的，我怀着内心还没有复习高数第二遍完成的沉重心情来总结一下还是为了能够有所收获，不至于什么都不剩下。&lt;/p&gt;
&lt;p&gt;这次实习持续了三周，第一周是大概复习了一下计算机网络相关协议的内容，第二周是一点点Linux相关的知识还有利用华为的eNSP来学习相关协议在机器上的实现，第三周是进一步学习还有外加用两天时间完成了一个单核心网络的模拟割接项目，由思科的设备替换为华为的设备。&lt;/p&gt;
&lt;p&gt;老师说这次实习的价值还是有的，和实际项目差的只有一个去现场连线。既然他都这么说了，我当然心里还是比较舒服的啊😂。&lt;/p&gt;
&lt;p&gt;我会把相关的东西打个包扔到网盘里，总的来说，按照协议来完成连接还是相对简单的，主要是配置命令。大概如果能有一本相关设备的命令手册会好一点。&lt;/p&gt;
&lt;p&gt;缺省路由的实现其实是有点不太懂的，今后大概得深入学习一下。&lt;/p&gt;
&lt;p&gt;自己确实认识到了，学校有的课讲的是真的太过偏向理论没有实践了，培训机构的培训虽然为一些大学内老师所不齿，但是如果能够两相结合，其实效果感觉是不错的。&lt;/p&gt;
&lt;p&gt;自己也确实感觉在实践方面有很多的问题，希望能够在今后的学习中加以补足。&lt;/p&gt;</content><category term="项目实践"/></entry><entry><title>Python的numpy包学习</title><link href="https://zhiyuansong.xyz/pythonde-numpybao-xue-xi.html" rel="alternate"/><published>2020-06-08T15:04:21+08:00</published><updated>2020-06-08T15:04:21+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-06-08:/pythonde-numpybao-xue-xi.html</id><summary type="html">&lt;h2 id="_1"&gt;综述&lt;/h2&gt;
&lt;p&gt;Numpy是一个Python的数学库，支持很强大的数组运算，本次数据学习建模比赛里要用，记录一下学习经验。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="ndarray"&gt;Ndarray对象&lt;/h2&gt;
&lt;p&gt;这是Numpy包提供的一个n维数组对象，可以通过构造函数构造一个 …&lt;/p&gt;</summary><content type="html">&lt;h2 id="_1"&gt;综述&lt;/h2&gt;
&lt;p&gt;Numpy是一个Python的数学库，支持很强大的数组运算，本次数据学习建模比赛里要用，记录一下学习经验。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="ndarray"&gt;Ndarray对象&lt;/h2&gt;
&lt;p&gt;这是Numpy包提供的一个n维数组对象，可以通过构造函数构造一个数组。&lt;/p&gt;
&lt;div class="highlight" data-language="python"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;numpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ndmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;object&lt;/code&gt;部分是一个数组或者说是嵌套的数列，如[1,2,3,4,5,]，[[1,2],[3,4]]等都可以；&lt;code&gt;dtype&lt;/code&gt;可选，表示数据类型；&lt;code&gt;copy&lt;/code&gt;可选，表示对象是否需要复制；&lt;code&gt;order&lt;/code&gt;表示创建数组的样式，C为行F为列默认为A表示任意方向；&lt;code&gt;subook&lt;/code&gt;可选，返回一个与基类类型一致的数组，&lt;code&gt;ndmin&lt;/code&gt;指定生成数组的最小维度。&lt;/p&gt;
&lt;p&gt;个人感觉，&lt;code&gt;object&lt;/code&gt;部分是最主要的，&lt;code&gt;dtype&lt;/code&gt;指定数据类型，&lt;code&gt;ndmin&lt;/code&gt;指定生成的维度。其他的相对用的不多。&lt;/p&gt;
&lt;h2 id="_2"&gt;数据类型（待补充）&lt;/h2&gt;
&lt;h2 id="_3"&gt;数组属性&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.ndim&lt;/code&gt;：秩，就是数组的维度的数量，矩阵的表示用的一般都是多维数组来表示（等于ndmin）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.shape&lt;/code&gt;：输出的是几行几列之类的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.size&lt;/code&gt;：输出元素总个数，大概可以看成长*宽之类的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.dtype&lt;/code&gt;：输出数据类型&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.itemsize&lt;/code&gt;：输出每个元素的大小，以字节为单位&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;xxx.flags&lt;/code&gt;：输出对象的内存信息（说实话看不懂）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200608222747.png" /&gt;&lt;/p&gt;
&lt;ol start="7"&gt;
&lt;li&gt;&lt;code&gt;xxx.real/imag&lt;/code&gt;：输出实部/虚部&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_4"&gt;创建数组&lt;/h2&gt;
&lt;p&gt;除了&lt;code&gt;ndarray&lt;/code&gt;以外，还可以有以下的三种方法创建一个数组。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;numpy.empty(shape,dtype,order='C')&lt;/code&gt;：建立一个用&lt;code&gt;shape&lt;/code&gt;描述行列数的未初始化数组，&lt;code&gt;dtype&lt;/code&gt;可选，&lt;code&gt;order&lt;/code&gt;用C与F指定行还是列优先。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;numpy.zeros(shape,dtype,order='C')&lt;/code&gt;：建立一个用0初始化的用&lt;code&gt;shape&lt;/code&gt;描述行列数的数组，其他同上。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;numpy.ones(shape,dtype,order='C')&lt;/code&gt;：建立一个用1初始化的数组，其他同上。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_5"&gt;从已有数组创建数组&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;numpy.asarray(a,dtype,order)&lt;/code&gt;：和&lt;code&gt;ndarray&lt;/code&gt;差不多，就是少了几个参数，可以根据a的输入完成像是根据列表或元组转换成ndarray类型等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;numpy.frombuffer(buffer,dtype,count,offset)&lt;/code&gt;：实现动态数组，&lt;code&gt;buffer&lt;/code&gt;可任意对象以流形式读入，&lt;code&gt;count&lt;/code&gt;默认为-1，表示读入全部数据，&lt;code&gt;offset&lt;/code&gt;表示读取起始位置，默认为0。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;python
   import numpy as np
   s = b'Hello World'
   a = np.frombuffer(s, dtype='S1')
   print(a)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;结果是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python
   [b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这里string必须转成bytestring，加个b&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;code&gt;numpy.fromiter(iterable,dtype,count=-1)&lt;/code&gt;：由可迭代对象建立ndarray对象，&lt;code&gt;iterable&lt;/code&gt;是可迭代对象（啥？）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_6"&gt;从数值范围创建数组&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;numpy.arange(start,stop,step,dtype)&lt;/code&gt;：创建一个[start,stop)的数组。&lt;code&gt;start&lt;/code&gt;是开始点，默认为0；&lt;code&gt;stop&lt;/code&gt;是结束点（不包括&lt;code&gt;stop&lt;/code&gt;），&lt;code&gt;step&lt;/code&gt;是步长，默认为1；&lt;code&gt;dtype&lt;/code&gt;同上。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;python
   x = np.arange(5)
   print(x)
   # 结果是[0,1,2,3,4]，很明显，唯一一定要有的参数是stop&lt;/code&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;code&gt;numpy.linspace(start,stop,num=50,endpooint=True,retstep=False,dtype=None)&lt;/code&gt;：生成一个知道首尾元素，知道元素个数的等差数组。&lt;code&gt;start&lt;/code&gt;是起始，&lt;code&gt;stop&lt;/code&gt;是终止，是否包含取决于&lt;code&gt;endpoint&lt;/code&gt;，默认为True，包含，反之不包含；&lt;code&gt;num&lt;/code&gt;是整个数组的元素个数，默认是50；&lt;code&gt;retstep&lt;/code&gt;是输出步长，默认False。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;python
   import numpy as np
   a = np.linspace(1, 10, 10, retstep=True)
   print(a)
   #(array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]), 1.0)&lt;/code&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;code&gt;numpy.logspace(start,stop,num=50,endpoint=True,base=10.0,dtype=None)&lt;/code&gt;：生成一个等比数列，和生成等差数列的方法区别就在&lt;code&gt;base&lt;/code&gt;上，默认为10，为对数log的底数，起始值是&lt;code&gt;base**start&lt;/code&gt;，结束值是&lt;code&gt;base**stop&lt;/code&gt;。 &lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_7"&gt;切片、索引&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;切片方法是使用&lt;code&gt;slice(start,stop,step)&lt;/code&gt;来给一个量赋值，再将这个值传给ndarray对象的索引里：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;python
   a=slice(2,7,2)
   print(arr[a])
   # 输出的是索引2~6的步长为2的元素数组&lt;/code&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;使用更多的是用冒号间隔开的一种方式，使用便利的多：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;python
   b=a[a:b:c]
   print(b)
   # 使用冒号隔开的三个元素分别代表起始端，结束端（不包括），步长
   # [a:]这种形式代表从索引a之后的全要，[:b]代表到索引b-1之前的全要
   # 多维数组同样适用，以数组内的元素为准
   # 还有加省略号的切片形式暂时没看懂&lt;/code&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;高级索引部分：整数数组索引和花式索引。暂时有点难。参见https://www.runoob.com/numpy/numpy-advanced-indexing.html&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_8"&gt;广播&lt;/h2&gt;
&lt;p&gt;广播是Numpy针对形状不同的数组进行数值运算处理的方式。在形状相同（指的是内部元素类型一致而且数组的维数也一样的这种）的情况下，运算基本都是对应位置的元素进行运算即可。&lt;/p&gt;
&lt;p&gt;但是遇到形状不同的数组，会自动触发广播机制。&lt;/p&gt;
&lt;p&gt;草，没看懂……https://www.runoob.com/numpy/numpy-broadcast.html&lt;/p&gt;</content><category term="学习笔记"/><category term="Python"/><category term="Numpy"/></entry><entry><title>VS Code在C/C++调试上的配置</title><link href="https://zhiyuansong.xyz/vs-codezai-ccdiao-shi-shang-de-pei-zhi.html" rel="alternate"/><published>2020-05-31T15:57:55+08:00</published><updated>2020-05-31T15:57:55+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-31:/vs-codezai-ccdiao-shi-shang-de-pei-zhi.html</id><summary type="html">&lt;p&gt;实际上目前确实在用VS Code上比较多，毕竟VS实在是太大，有时候敲一小段代码完全用不上这个，而VS Code因为在美观度和插件丰富度上比较高，之前用MinGW的编译调试环境搭了个C/C++的环境，这两天用的时候却发 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;实际上目前确实在用VS Code上比较多，毕竟VS实在是太大，有时候敲一小段代码完全用不上这个，而VS Code因为在美观度和插件丰富度上比较高，之前用MinGW的编译调试环境搭了个C/C++的环境，这两天用的时候却发现自己之前没配好调试环境……那就记录一下吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="vs-codeccmingw"&gt;安装VS Code、安装C、C++插件、安装MinGW并配置路径……（略）&lt;/h2&gt;
&lt;p&gt;安装VS Code，装插件极为无脑，不难（毕竟只要打开一个.cpp文件必然会推荐安装插件……）安装MinGW也是不难，只要记得把三件套gcc、g++、gdb在管理里下载安装好就行。唯一难得一点就是记得在Path环境变量里把MinGW的bin路径加上，只要能在命令行里能全局识别出来三件套的命令即可。&lt;/p&gt;
&lt;h2 id="_1"&gt;配置调试环境&lt;/h2&gt;
&lt;p&gt;经过上面一通操作后，其实已经可以运行C/C++代码了，只是按F5调试会发现蹦出一堆选项，但是自己点了也没什么反应……&lt;/p&gt;
&lt;p&gt;首先是要说明VSC的调试是要在文件夹里进行的，单个的c或cpp文件是没法调试的，请务必当成个小项目，给它套个文件夹。注意整个路径里不能有中文（气抖冷，中文何时才能站起来😂），不然调试是会报找不到文件路径的错误。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200531162626870" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200531162634.png" /&gt;&lt;/p&gt;
&lt;p&gt;如上图所示，先敲好程序，点击那个感觉就很有debug味道的运行图标，然后点击&lt;strong&gt;创建launch.json文件&lt;/strong&gt;，相继就是会弹出一堆调试选项，当然先选GNU再根据调试文件类型选择是要用gcc还是g++，之后会自动跳转到项目文件夹新生成的.vscode文件夹里的launch.json中。&lt;/p&gt;
&lt;p&gt;主要注意的是以下几个点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;externalConsole&lt;/code&gt;项记得把&lt;code&gt;false&lt;/code&gt;改成&lt;code&gt;true&lt;/code&gt;,只有这样才能在命令行里输入，内置控制台没办法输入数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;launch.json修改完按F5，会出现以下图片：&lt;img alt="image-20200531165836228" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200531165836.png" /&gt;点击配置任务选择相应的任务类型（gcc还是g++），又会在.vscode里生成tasks.json，这个时候，点F5依旧显示上图的找不到服务。对tasks.json修改，令&lt;code&gt;label&lt;/code&gt;和launch.json里的&lt;code&gt;preLaunchTask&lt;/code&gt;内容一摸一样即可（为什么不直接生成相同的名字，理解不能）。至此所有的配置就完成了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按F5运行VSC调试必须打断点，不打断点相当于程序只会在有输入等操作或者系统pause命令处才会停下来，基本上就是命令行一闪而过，自己一开始也不懂，以为是没配好……&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个.vscode文件夹只能配置当前父文件夹内的所有代码，图省事可以把这个文件夹直接在常用的文件夹中加到最上层，就可以让当前文件夹下的所有项目文件夹享受到调试配置效果了（我是没找见有什么可以全局配置的方法……）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="image-20200531171309707" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200531171309.png" /&gt;&lt;/p&gt;</content><category term="实用小文章"/><category term="VS Code"/></entry><entry><title>用Typora外加PicGo搭配完成更舒心的博客环境</title><link href="https://zhiyuansong.xyz/yong-typorawai-jia-picgoda-pei-wan-cheng-geng-shu-xin-de-bo-ke-huan-jing.html" rel="alternate"/><published>2020-05-31T12:10:43+08:00</published><updated>2020-05-31T12:10:43+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-31:/yong-typorawai-jia-picgoda-pei-wan-cheng-geng-shu-xin-de-bo-ke-huan-jing.html</id><summary type="html">&lt;p&gt;在之前的博客文章书写时，自己并没有部署图床，所以在之前的文章里都没有图片插入，这次主要是部署Github图床，搭配上Typora和PicGo，可以 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;在之前的博客文章书写时，自己并没有部署图床，所以在之前的文章里都没有图片插入，这次主要是部署Github图床，搭配上Typora和PicGo，可以实现直接在书写中粘贴图片同时上传图床，无脑又好用。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="github"&gt;Github图床的部署&lt;/h2&gt;
&lt;p&gt;这里所谓的图床，就是在Github里建一个仓库专门上传照片，原理很简单。当然首先应该要有一个自己的Github账户，创建一个新的仓库，名字任意。注意要把仓库设置成公开（Public）。&lt;/p&gt;
&lt;p&gt;创建完成后点击自己的账户头像，选择设置（Settings），再转到Developer settings，点击Personal access tokens中的Generate new token按钮，description可以自行填写，勾选repo项点击最下方的Generate token即可。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200531123047.png" /&gt;&lt;/p&gt;
&lt;p&gt;会出现一串字符，只出现一次，记得保存好。&lt;/p&gt;
&lt;h2 id="picgogithub"&gt;PicGo的安装和连接Github图床&lt;/h2&gt;
&lt;p&gt;PicGo(2.2.2版本)是一个开源图床工具，只要把图片拖入上传区，就可以实现向连接的图床上传图片的功能。&lt;/p&gt;
&lt;p&gt;PicGo可以在Github上进行项目搜索并下载。&lt;/p&gt;
&lt;p&gt;安装过程很简单，不再赘述。主要部分是图床的连接设置。在PicGo的图床设置界面中找到Github图床，进行设置：&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200601145312914" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200601145313.png" /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;仓库名是Github账户名字/仓库名字&lt;/p&gt;
&lt;p&gt;分支名默认master即可&lt;/p&gt;
&lt;p&gt;Token填写之前生成的token&lt;/p&gt;
&lt;p&gt;存储路径可以按默认提示来即可&lt;/p&gt;
&lt;p&gt;设置自定义域名：因为Github访问的速度偏慢，可以考虑用CDN加速，使用&lt;code&gt;https://cdn.jsdelivr.net/gh/[账户名]/[仓库名]@master&lt;/code&gt;来进行加速，jsdelivr可以提供对Github内容的分发，具体原理可以自行了解&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;经过这些配置，目前PicGo已经可以完成将图片通过上传区上传到Github图床上了。但是使用还是不便，大多数情况，要先上传图片，再复制生成的对应链接，粘贴到.md文件里。要想更省力，还得装一个Typora。&lt;/p&gt;
&lt;h2 id="typorapicgo"&gt;安装Typora和PicGo进行联动&lt;/h2&gt;
&lt;p&gt;Typora确实是我目前用过的最好的Markdown编辑器了，之前一直都在用VS Code的我流下了泪水……（当然VS Code也不错）Typora支持实时预览，预览界面和编辑界面是一体的，感觉很奇妙，毕竟写Markdown不是敲代码，稍微舒心一点怎么都好，同时最近版本（0.9.88beta win版）是支持和PicGo联动完成插入图片即完成上传的功能的，体验突然飞起。&lt;/p&gt;
&lt;p&gt;Typora的安装包去官网下载，唯一的难点大概是，下载非常慢……安装即可。然后去菜单里的偏好设置里选择图像进行配置：&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200601151704251" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200601151704.png" /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;下拉项选择上传图片，勾选对本地和网络位置图片应用规则&lt;/p&gt;
&lt;p&gt;上传服务设定，上传服务选择PicGo(app)，配置PicGo路径&lt;/p&gt;
&lt;p&gt;验证图片上传选项稍后进行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="image-20200601152254152" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200601152254.png" /&gt;&lt;/p&gt;
&lt;p&gt;打开PicGo，在PicGo配置里选择设置server，将监听端口设置为上面所示的36677（因为Typora只用这个端口传输🙁希望之后能出个自行设置端口的选项）。&lt;/p&gt;
&lt;p&gt;此时运行Typora中的验证图片上传选项，显示为:&lt;img alt="image-20200601152735860" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200601152735.png" /&gt;说明连接成功了，之后的图片可以直接插入，直接就会上传到图床。&lt;/p&gt;
&lt;h2 id="_1"&gt;问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;显示&amp;rdquo;Failed to fetch&amp;rdquo;：上传不了图片，可以检查以下端口设置，有时打开了多个PicGo，端口冲突，就会自动把原先的端口改了，可以改回来，再关掉所有PicGo，重新上传。&lt;/li&gt;
&lt;li&gt;显示{&amp;ldquo;success&amp;rdquo;,false}：上传了重名的图片，可以在PicGo设置里将时间戳重命名打开即可。&lt;/li&gt;
&lt;li&gt;更多问题可以看PicGo的日志文件找办法。&lt;/li&gt;
&lt;/ol&gt;</content><category term="实用小文章"/></entry><entry><title>参加某机器学习比赛的随记（随时可能弃坑）</title><link href="https://zhiyuansong.xyz/can-jia-mou-ji-qi-xue-xi-bi-sai-de-sui-ji-sui-shi-ke-neng-qi-keng.html" rel="alternate"/><published>2020-05-26T22:28:03+08:00</published><updated>2020-05-26T22:28:03+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-26:/can-jia-mou-ji-qi-xue-xi-bi-sai-de-sui-ji-sui-shi-ke-neng-qi-keng.html</id><summary type="html">&lt;p&gt;有头无尾的比赛参加了一届又一届，希望这次至少能学到点知识，能获得点成果吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="525"&gt;5月25日&lt;/h2&gt;
&lt;p&gt;首先是自己完全没想过参加这种比 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;有头无尾的比赛参加了一届又一届，希望这次至少能学到点知识，能获得点成果吧。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="525"&gt;5月25日&lt;/h2&gt;
&lt;p&gt;首先是自己完全没想过参加这种比赛，对于啥是机器学习对于当前的我的知识面来说完全是一窍不通。只是老师发了通知，我会一点Python，我在火车上很无聊，我想更多地了解一点关于这方面的知识。就这么战战兢兢地加了老师的微信，算是报了名。然后老师的热情有点让人出乎意料，我就是表了表努力去学的心情，然后老师就把他研究生的论文发给了我，然后还拉了个群，还拉了自己的研究生入群，对我和班里大佬可谓是“无微不至”，说实话自己有点被惊到了。然后就是难顶的地方了，一个月拿出一个机器学习的模型初稿……虽然可以在老师研究生成果的基础上学习，但感觉还是很难，毕竟，自己会的Python，真的就只是基础……&lt;/p&gt;
&lt;h2 id="526"&gt;5月26日&lt;/h2&gt;
&lt;p&gt;到了学校，日常学习完了之后报了名，下了个数据集，八百多MB，说实话是第一次见这么大的数据集，然后呢就是看那个所谓的基线系统。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200526230004791" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/image-20200526230004791.png" /&gt;&lt;/p&gt;
&lt;p&gt;说实话，汉字还能看懂，代码……大概能看出来是把一些指令封装成了模块，除了解压数据整理数据之外核心应该是训练部分，但是吧，这部分完全看不懂。泪目，只能先去学习一下怎么使用这个平台，哦对了还有一篇七十多页的论文要看……还不一定能看懂，太惨了。&lt;/p&gt;
&lt;p&gt;希望明天能好过一点。🙏&lt;/p&gt;
&lt;h2 id="527"&gt;5月27日&lt;/h2&gt;
&lt;p&gt;复习了一点数学和数据结构，开始搞这个比赛，目前正在学习平台的功能，总的来说，似乎是把代码文件分割成了一个个所谓的&amp;rdquo;cell&amp;rdquo;，这些cell功能是相互独立的，但是在顺序上又是紧密联系的。操作上没有太大障碍，举的例子还挺简单的，但是实际项目的阅读难度确实不小。&lt;/p&gt;
&lt;p&gt;做一点笔记，要使用Linux命令需要在命令前打！号来使平台识别，还有主要用于测试的magic命令：&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200527185114.png" /&gt;&lt;/p&gt;
&lt;p&gt;试着跑了一下那个基线系统，训练的过程仿佛没有尽头……&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200527185836365" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/image-20200527185836365.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200527185915394" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/image-20200527185915394.png" /&gt;&lt;/p&gt;
&lt;p&gt;差不多就这样，感觉该去看那个七十多页的论文了，现在唯一的感觉就是，论文的话说的永远令人看不懂。&lt;/p&gt;
&lt;h2 id="528"&gt;5月28日&lt;/h2&gt;
&lt;p&gt;今日没有无线网络，张宇的线代视频没看成，把线性方程组那一章的书看了一遍，例题做了做；下午复习了顺序表，说实话虽然代码比较简单，但是还是得记住套路，我一不刷算法题，二不常用C++，相对地这些知识有点遗忘了，难顶，得多看两遍。晚上用思维导图把操作系统的第一章复习了一遍，说实话，这课程也不知何时考试，无奈。&lt;/p&gt;
&lt;p&gt;闲话少说，看论文走起！&lt;/p&gt;
&lt;p&gt;今天就看了一个时间序列，一个集成学习的概念，看了一个Bagging算法，明天大概可以把大部分集成学习算法看完。说实话还是感觉很像白开水，也没代码实例，半懂不懂。&lt;/p&gt;
&lt;p&gt;思维导图用的挺来劲的，那种不用费劲就能构架关系的感觉挺好。&lt;/p&gt;
&lt;p&gt;晚安。&lt;/p&gt;
&lt;h2 id="529"&gt;5月29日&lt;/h2&gt;
&lt;p&gt;太难了，Boosting算法数学公式一大堆，LightGBM又是讲了一堆什么浮点数离散化成k个整数之类的东西，再图像化……&lt;/p&gt;
&lt;p&gt;为啥要这样啊！突然感觉数据结构里面的算法一下子就变得亲切了起来😂&lt;/p&gt;
&lt;p&gt;神经网络就是对生物的仿真，然后卷积神经网络里面用了卷积……我就记得学信号与系统的时候用了卷积，但是只是处于皮毛，好像是积分之类的……忘了啊&lt;/p&gt;
&lt;p&gt;又是难顶的一天呢。&lt;/p&gt;
&lt;h2 id="68"&gt;6月8日&lt;/h2&gt;
&lt;p&gt;磨磨蹭蹭地看完了论文第三章TPFF方法，后面两个是例子，说实话还是没看懂说的是什么，论文这东西似乎并不太讲求再现性，总之就是看了还是什么都不会。&lt;/p&gt;
&lt;p&gt;今天群里那个负责的学姐加了我，我和她聊了聊自己的进度，总之就是举步维艰，她还了解了一下我的Python学习情况，总之就是最多掌握了Python的标准语法，至于那些数据和图像相关的库基本没学过……（大概也就是用过几次matplotlib画统计图😅）我想学姐大概也是一脸黑线吧，她让我下去把numpy，pandas和matplotlib再学习一下。那就这样呗。&lt;/p&gt;
&lt;p&gt;貌似又要开新坑写一下这些包的学习过程了……这周还有考试啊……&lt;/p&gt;
&lt;h2 id="85"&gt;8月5日&lt;/h2&gt;
&lt;p&gt;鸽了，好像那之后赶上了几个课设外加考试，然后非常遗憾地没有做，因为是真的就只会一点python基础……&lt;img alt="" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200805223617.png" /&gt;&lt;/p&gt;
&lt;p&gt;就很惨，虽然在师兄的鼓励下还是稍微有了一点勇气，但是真的感觉自己会的这么少，将来可怎么去找工作啊……&lt;/p&gt;</content><category term="学习笔记"/><category term="机器学习"/></entry><entry><title>git的学习与简单使用</title><link href="https://zhiyuansong.xyz/gitde-xue-xi-yu-jian-dan-shi-yong.html" rel="alternate"/><published>2020-05-22T23:00:38+08:00</published><updated>2020-05-22T23:00:38+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-22:/gitde-xue-xi-yu-jian-dan-shi-yong.html</id><summary type="html">&lt;p&gt;计划在这两天完成一下对 git 的初步学习，本来也不是很难的一个东西，自己的电脑上很早就装了但是基本上就是摆设……决 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;计划在这两天完成一下对 git 的初步学习，本来也不是很难的一个东西，自己的电脑上很早就装了但是基本上就是摆设……决定还是学一下，毕竟自己的项目永远都是放养状态，有几次改崩了就真的崩了，是该好好利用一下。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;简介&lt;/h2&gt;
&lt;p&gt;git 是 Linus 在编写 linux 时花两个星期用 C 写的一个版本控制系统，方便管理 linux 的内核代码。git 的很大的特点就是它的弱中央服务器，每一个电脑地位都是等同的，不像 SVN 有一个中心的代码服务器，代码总是要提交到中央，中央的服务器崩掉了就会出很大的问题。&lt;/p&gt;
&lt;h2 id="_2"&gt;安装&lt;/h2&gt;
&lt;p&gt;具体的安装过程就不介绍了，在三种系统上安装基本都很简单，也并不用配置路径。&lt;/p&gt;
&lt;p&gt;要注意的是配置 git 所安装计算机的名字和 email 地址，可以在 git bash 里设置，也可以直接在 cmd 中设置：&lt;/p&gt;
&lt;div class="highlight" data-language="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ git config --global user.name &amp;quot;Your Name&amp;quot;
$ git config --global user.email &amp;quot;email@example.com&amp;quot;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;因为 git 是分布式版本控制系统，要识别每一台在在系统中的计算机，需要配置名字。当然只是一个标志，只要能识别就行。&lt;/p&gt;
&lt;h2 id="_3"&gt;最基础的几条指令&lt;/h2&gt;
&lt;p&gt;首先要明确，版本控制系统只能追踪文本文件的改变，如增减了几个字符等，像是图片和视频这类二进制文件，是追踪不了的，word 文档也是二进制的文件，所以追踪不了。&lt;/p&gt;
&lt;p&gt;下面介绍一下基础的几条指令：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;将一个目录初始化一个 git 仓库：在该目录下运行&lt;code&gt;git init&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加文件到提交流上：&lt;code&gt;git add 文件名&lt;/code&gt;，添加所有文件将文件名写成&amp;rsquo;*&amp;lsquo;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进行文件的提交：&lt;code&gt;git commit -m "提交的记录"&lt;/code&gt;，记录部分可写一个提交的说明，提交是把之前在提交流上的所有文件进行一次提交，即 add 操作可以分批多次进行，commit 进行总的一次提交。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;追踪仓库中未被 commit 的改变（具体哪个文件出现了变化，变化是否已被 add）：&lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看文件具体出现了哪些变化：&lt;code&gt;git diff "文件名"&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看commit的版本：&lt;code&gt;git log&lt;/code&gt;，按提交时间最近在前排列&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="image-20200603180531458" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200603180539.png" /&gt;&lt;/p&gt;
&lt;p&gt;加上参数，&lt;code&gt;git log --pretty=oneline&lt;/code&gt;，信息显示在一行&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200603181056627" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200603181056.png" /&gt;&lt;/p&gt;
&lt;ol start="7"&gt;
&lt;li&gt;要切换commit的提交版本，使用&lt;code&gt;git reset --hard XXX&lt;/code&gt;，在这里，XXX可以是当前的指针HEAD指向当前版本之前的版本，例如上一个版本表示为HEAD^，上两个版本就再加一个^，多了当然不好表示，可以用HEAD~N（N为阿拉伯数字）表示前N个版本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当然，能往前切版本，也就能往后切版本，后面的版本在log命令下查不到，但是可以在XXX处填写版本号（就是那一串字符，不用填全，几位就够了）实现版本切换&lt;/p&gt;
&lt;ol start="8"&gt;
&lt;li&gt;当然，切换版本的关键，是要知道版本号，但是有的时候，命令行关了没记住，再想切回去，怎么办？使用&lt;code&gt;git reflog&lt;/code&gt;可以查看之前的命令历史，包含版本号&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="image-20200603182937532" src="https://cdn.jsdelivr.net/gh/meloveayu/blog_img@master/img/20200603182937.png" /&gt;&lt;/p&gt;
&lt;ol start="9"&gt;
&lt;li&gt;
&lt;p&gt;解决修改撤销的几个情景：当你在工作区做了修改，但没add，那么直接&lt;code&gt;git checkout --file&lt;/code&gt;就可以回到上一次commit或add的记录；当你做了add操作，可以&lt;code&gt;git reset HEAD &amp;lt;file&amp;gt;&lt;/code&gt;实现将暂存区的修改回退到工作区，然后用&lt;code&gt;git checkout --file&lt;/code&gt;就可以；如果commit了，可以用上面讲过的版本回退，但是推到远端仓库就没有办法了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;删除在版本库里的文件，普通的删除，在git的记录里是会保留下来的，如果真的想把这个记录也删除了，那么运行&lt;code&gt;git rm file&lt;/code&gt;进行记录删除，再commit，则完全删除；反之之前删错了想恢复，用&lt;code&gt;git checkout --file&lt;/code&gt;进行还原（用版本库版本替换工作区版本）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;远程仓库：目前用的最多的还是github，关于连接github账户与本机的连接要用ssh密钥，这里就不写了。主要是两种方式使用，一种方式是先建立远程空仓库，再将本地的仓库和空仓库绑定，把仓库里的内容推上去；另一种是先建好空仓库，再把仓库克隆下来，进行项目的编写。前一种用&lt;code&gt;git remote add origin git@github.com:账户名/仓库名.git&lt;/code&gt;连接，用&lt;code&gt;git push -u origin master&lt;/code&gt;进行第一次推送，用&lt;code&gt;git push origin master&lt;/code&gt;进行之后的推送。后一种用&lt;code&gt;git clone 仓库网址&lt;/code&gt;即可（这个用的很多了吧……时常扒人项目有感）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;好像写的篇幅已经很长了，先停一下，之后的内容放在下一篇继续。&lt;/p&gt;</content><category term="学习笔记"/><category term="git"/><category term="版本控制"/></entry><entry><title>关于java中重载，多态，向上和向下转型的概念</title><link href="https://zhiyuansong.xyz/guan-yu-javazhong-zhong-zai-duo-tai-xiang-shang-he-xiang-xia-zhuan-xing-de-gai-nian.html" rel="alternate"/><published>2020-05-21T22:21:28+08:00</published><updated>2020-05-21T22:21:28+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-21:/guan-yu-javazhong-zhong-zai-duo-tai-xiang-shang-he-xiang-xia-zhuan-xing-de-gai-nian.html</id><summary type="html">&lt;p&gt;之前在学习各种语言的时候，自己总是对一些基础的概念辨析不清，像是面向对象之中的重载和多态，对象的向上和向下 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;之前在学习各种语言的时候，自己总是对一些基础的概念辨析不清，像是面向对象之中的重载和多态，对象的向上和向下转型等等。这里简单记录一下这几个概念的辨析，方便之后的回忆使用。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;重载：重载方法的实现基本上是在类中实现的，在类中有的时候会碰上函数处理一组多情况的输入，或者说，这一组函数针对多情况实现的功能基本就是一致的，那么这个时候，当然是函数名起成相同的最具有一致性了。那么不同的重载函数之间的区别就在&lt;strong&gt;参数&lt;/strong&gt;，参数在个数和类型上都可以有所不同，具体实现的函数语句当然也可以就此有所区别。要注意的是返回值类型也是相同的。举一个例子就是在类中定义的重载构造函数。很明显，可以有诸如无参数构造和有参数构造，但它们解决的就是生成对象这一个问题，无非就是分了分情况。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多态：这一部分看的比较粗略，主要是看了最常用的方法覆写实现多态。覆写的实现要求方法签名部分，即返回类型，函数名和参数列表都一样，所变的只有方法实现。这里举个例子，像是类的继承过程中，子类可以对从父类所继承的方法进行改写，实现自己想要的功能。&lt;br /&gt;
&lt;strong&gt;注意&lt;/strong&gt;：对于函数名相同，参数相同但是返回值不同的方法也是不同的方法，而且这种情况下会报错，是不允许出现的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;向上转型：首先是这么一个问题，一个继承了父类的子类生成的对象，类型还是属于父类的吗？答案当然是肯定的。一切的类的父类都是 Object 类，自然一切的对象类型也可以追溯到 Object 上。那么在对象的创建时，对父类的对象构建使用子类的构造函数，这就是将一个子类的对象类型向上转型为更抽象的父类类型。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;向下转型：这里就要针对向上转型来说了，一个父类的对象构建使用子类的构造参数，当前的类型当然是父类类型，但是还可以转型成子类的类型吗？要看情况，上面说的当然可以。而如果一个父类对象的构建不是向上转型来的，那就不能向下转型，因为子类的功能是要比父类多的，没有的功能也变不出来。能否向下转型的判断可以用&lt;code&gt;对象名 instance of 类名&lt;/code&gt;（这是 java 14 的功能），来进行判断，结果为 true 可进行强制类型转换来进行向下转型。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：java 的实例方法执行是基于运行时的实际类型。&lt;/p&gt;</content><category term="学习笔记"/><category term="Java"/></entry><entry><title>CentOS 8虚拟机的网络配置相关</title><link href="https://zhiyuansong.xyz/centos-8xu-ni-ji-de-wang-luo-pei-zhi-xiang-guan.html" rel="alternate"/><published>2020-05-14T15:31:58+08:00</published><updated>2020-05-14T15:31:58+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-05-14:/centos-8xu-ni-ji-de-wang-luo-pei-zhi-xiang-guan.html</id><summary type="html">&lt;p&gt;这部分只解决在 VMWare Workstation 上安装完 CentOS 8 后的网络问题，即第一无法访问外界网络，第二无法与宿主机联通。这部分可以自行用 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这部分只解决在 VMWare Workstation 上安装完 CentOS 8 后的网络问题，即第一无法访问外界网络，第二无法与宿主机联通。这部分可以自行用&lt;code&gt;ping&lt;/code&gt;判断是否有这两个问题。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;ol&gt;
&lt;li&gt;首先要把虚拟机的网络连接模式设置成桥接模式，然后用&lt;code&gt;ifconfig&lt;/code&gt;命令查看一下虚拟机是否有配置 IP 地址以及掩码设置等（以下的操作均在 root 下进行），大概率没有配置。&lt;/li&gt;
&lt;li&gt;在 VMWare 的工具栏里的编辑中选择虚拟网络编辑器，设定连接的哪一张网卡，这一部分要把 VMnet0 项选择为桥接模式连接到自己的宿主机的可用网卡上，参考网上文章，可选自动使用。个人是绑到了常用的无线网卡上。&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;dhclient&lt;/code&gt;为虚拟机分配可用的 IP 地址与掩码，可以用&lt;code&gt;ifconfig&lt;/code&gt;查看后记下来，一会儿要用。&lt;/li&gt;
&lt;li&gt;修改&lt;code&gt;/etc/sysconfig/network-scripts/ifcfg-ens33&lt;/code&gt;文件，修改以下的几项：（基于本人的操作，其他人或者有所不同）&lt;blockquote&gt;
&lt;p&gt;将 BOOTPOROTO 的之后修改为 static&lt;br /&gt;
ONBOOT 的之后修改为 yes&lt;br /&gt;
添加 IPADDR=x.x.x.x 此处添加的即为之前分配的 IP 地址&lt;br /&gt;
添加 NETMASK=x.x.x.x 此处添加的是之前的掩码&lt;br /&gt;
添加 GATEWAY=x.x.x.x 此处添加的是网关，应和宿主机一致，可使用相关指令在宿主机查找&lt;br /&gt;
添加 DNS1=x.x.x.x 此处添加 DNS 服务器地址，也和宿主机一致（这里本人的宿主机没有 DNS 的相关信息，似乎填上常用的即可，存疑）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;重启网络设置，相比之前版本 CentOS 8 修改了网络管理的相关指令，使用&lt;code&gt;nmcli c reload&lt;/code&gt;重启网络服务即可。可用&lt;code&gt;ping&lt;/code&gt;指令检查是否能够联通外界网络与宿主机。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;遗留的问题：个人测试虚拟机连接宿主机无法 ping 通，但是宿主机可以 ping 通虚拟机，宿主机也可以使用 SSH 访问到虚拟机界面，似乎并没有什么问题……&lt;/p&gt;
&lt;p&gt;上面问题的回答（补充于8月5日）：是Windows 10 防火墙的问题，最直接的方式就是把防火墙关了，稍微高级的方法是防火墙高级规则配置入站规则允许虚拟机IPv4可进入，但是这个问题似乎是在桥接模式下存在的，之后改成NAT连接后，把防火墙配置改回去也没有问题了。&lt;/p&gt;
&lt;p&gt;多节点的配置可以直接克隆再重新配置网络即可，问题不大。&lt;/p&gt;
&lt;p&gt;补充：按照上面的配置方法，桥接模式加静态IP的弊端就是当宿主机的网络环境变了之后，就不能网络访问虚拟机了，可以改成NAT连接模式。我参考了https://www.cnblogs.com/Stephen-Qin/p/12889358.html这篇文章里的方法进行了配置，最后效果很好。感谢博主。&lt;/p&gt;</content><category term="学习笔记"/><category term="linux"/><category term="虚拟机"/></entry><entry><title>Java——终结和垃圾回收</title><link href="https://zhiyuansong.xyz/java-zhong-jie-he-la-ji-hui-shou.html" rel="alternate"/><published>2020-03-26T18:34:20+08:00</published><updated>2020-03-26T18:34:20+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-26:/java-zhong-jie-he-la-ji-hui-shou.html</id><summary type="html">&lt;p&gt;这还是一个搭积木的过程，看《Java 编程思想》这本书，看到了垃圾回收相关的章节，半懂不懂地记下一点东西，可能现在写的之 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;这还是一个搭积木的过程，看《Java 编程思想》这本书，看到了垃圾回收相关的章节，半懂不懂地记下一点东西，可能现在写的之后看会有很多错误的地方，但是先写下来再说。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;关于清除、终结和垃圾回收&lt;/h2&gt;
&lt;p&gt;在 C 与 C++这两门语言（或者说就是一门语言，毕竟后者就是前者加入了面向对象特性的升级版）中，最难为人的地方无非就是指针的使用和内存的分配与管理。Java 在这一方面减轻了许多程序员的负担，其一是 Java 没有指针这个东西，其二内存的分配与管理上引入了垃圾回收（garbage collection）的概念，使得程序编写过程中可以相对轻松地不用管内存何时释放这个问题，由程序自动回收不再使用的内存，如此云云。&lt;br /&gt;
今天看了相关的内容，产生了几个问题，第一，自己还是不太明白这个内存回收的具体机理，它是怎么知道程序不会再使用已经使用过的内存了呢？其二，既然已经有了这个机制，那是不是就可以当一个甩手掌柜，什么事都交给它了呢？既然如此那为什么还会有一个终结（&lt;code&gt;finalize()&lt;/code&gt;）函数存在呢？&lt;br /&gt;
首先说明以下这个问题，第一，Java 作为一门面向对象语言，类的构造函数是有的，对象的初始化借助构造函数完成，大部分情况下对象占用的内存释放借助垃圾回收机制完成。第二，&lt;code&gt;finalize()&lt;/code&gt;绝对不等于 C++类里的析构函数。需要明确的点是，C++里的对象一定会被析构函数销毁，但是 Java 里的对象并不一定总是会被垃圾回收掉。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;对象可能不被回收&lt;/li&gt;
&lt;li&gt;垃圾回收不等于“析构”&lt;/li&gt;
&lt;li&gt;垃圾回收只与内存有关&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;说实话有点蒙：什么时候对象不会被回收？垃圾回收不等于析构，那么它又是什么?&lt;br /&gt;
第一个问题，垃圾回收只会回收通过 new 关键字申请的对象所占用的内存，对于不用这种方式获得的特殊内存，应该定义一个&lt;code&gt;finalize()&lt;/code&gt;函数，通过在垃圾回收准备回收内存时先调用&lt;code&gt;finalize()&lt;/code&gt;来进行一些清除操作，使得在下一次垃圾回收时使得真正回收对象的内存。&lt;br /&gt;
由此产生的新的问题，除了 new 以外申请内存的方式是什么？&lt;code&gt;finalize()&lt;/code&gt;具体的操作过程是什么？&lt;br /&gt;
**只要程序没有濒临存储空间用完的那一刻，对象占用的空间就总也得不到释放。如果程序执行结束，并且垃圾回收器一直都没有释放你创建的任何对象的存储空间，则随着程序的退出，那些资源会全部交还给操作系统。这个策略是恰当的，因为垃圾回收本身也有开销，要是不使用它，那就不用支付这部分开销了。**也就是说，只要内存够用，垃圾回收机制是不会调动的。&lt;br /&gt;
&lt;code&gt;finalize()&lt;/code&gt;的真正用途：垃圾回收器存在的唯一原因就是回收程序不再使用的内存，而只要是与垃圾回收相关的行为（包括&lt;code&gt;finalize()&lt;/code&gt;），也必须要和内存及其回收有关。&lt;br /&gt;
也就是说，内存的回收最后一步一定是垃圾回收，但是在少部分情况下需要使用&lt;code&gt;finalize()&lt;/code&gt;来进行部分清除工作，之后由垃圾回收来完成内存回收。&lt;br /&gt;
&lt;code&gt;finalize()&lt;/code&gt;的使用场景是在 Java 中可能调用了 C/C++代码，由于这两种语言内存空间不会自动释放，需要在&lt;code&gt;finalize()&lt;/code&gt;中调用释放内存空间的对应函数。&lt;br /&gt;
所以&lt;code&gt;finalize()&lt;/code&gt;不是一个很常用的清除工作的执行方法，只有在存在不能自动释放内存的时候会使用一下。&lt;br /&gt;
&lt;code&gt;finalize()&lt;/code&gt;的调用是自动进行的，发生在垃圾回收执行之前，可以在&lt;code&gt;finalize()&lt;/code&gt;里面加入一些动作，通过动作找 bug。（所谓“终结条件的验证”）当然垃圾回收只有内存空间不够才会执行，可以通过&lt;code&gt;System.gc()&lt;/code&gt;强制执行垃圾回收以达到执行&lt;code&gt;finalize()&lt;/code&gt;的目的。&lt;br /&gt;
在大部分情况下，垃圾回收都是不用担心的，因为垃圾回收器的存在，基本上代替了析构函数的作用，但是当你想进行回收存储空间以外的清楚工作，你就得明确定义一个相关功能的函数，不能是&lt;code&gt;finalize()&lt;/code&gt;，因为它不能手动调用。相比之下反而没有析构好。虽然这种情况很少很少。&lt;/p&gt;
&lt;h2 id="_2"&gt;垃圾回收器究竟是如何工作的？&lt;/h2&gt;
&lt;p&gt;Java 除了基本类型之外的对象都是创建在堆上的，回忆一下 C/C++的堆内存申请与释放过程，不难理解相比代价高昂的使用堆内存的两种语言，Java 的垃圾回收机制十分高效快速。&lt;br /&gt;
&lt;strong&gt;内存空间的释放竟然会影响内存的分配……&lt;/strong&gt;&lt;/p&gt;</content><category term="学习笔记"/><category term="Java"/><category term="垃圾回收"/></entry><entry><title>随便扯皮</title><link href="https://zhiyuansong.xyz/sui-bian-che-pi.html" rel="alternate"/><published>2020-03-18T22:44:57+08:00</published><updated>2020-03-18T22:44:57+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-18:/sui-bian-che-pi.html</id><summary type="html">&lt;p&gt;考研真的好难啊。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;最近复习数学，越复习越感慨，明明自己高中数学不是很好，为什么还要来趟计算机这潭深水……你去学个医 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;考研真的好难啊。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;最近复习数学，越复习越感慨，明明自己高中数学不是很好，为什么还要来趟计算机这潭深水……你去学个医科不就避免了这个问题了嘛，况且高中生物学的还可以……&lt;br /&gt;
还是当年太年轻，没有看清未来的现实境遇。&lt;br /&gt;
说实话，到现在学的也是很迷茫，倒不是有没有爱了好不好学的问题，爱，绝对是有的，学是不好学但不是一直在前进嘛，关键是学了知识，我能干什么，我当时想的和现在做的差距还是有的，那么该怎么达到我当时所想的呢？说实话，网上没有，自己只能摸着石头过河。&lt;br /&gt;
目前倒是有几个喜欢的方面，但是我不知道该拿它去做点啥。&lt;br /&gt;
其实解决点现实问题就挺好的。&lt;br /&gt;
总感觉学的和工作的东西是脱离的，学的是积木，工作就成用砖石了，我会用积木搭房子，不一定会用砖石啊。&lt;br /&gt;
参加的比赛，经常谈着谈着，就……没消息了……emm&lt;br /&gt;
睡了睡了，饭得一口一口吃，学习也得一点一点学，毕竟我还是有爱的，只是我做的没有想象中好，而别人眼里做的好的也不是我觉得好的方向，大概是这样才导致了我产生的挫败感吧。&lt;br /&gt;
如果有人能给我一点爱……😂&lt;/p&gt;</content><category term="随便聊聊"/></entry><entry><title>软件工程笔记：结构化分析方法</title><link href="https://zhiyuansong.xyz/ruan-jian-gong-cheng-bi-ji-jie-gou-hua-fen-xi-fang-fa.html" rel="alternate"/><published>2020-03-18T14:59:14+08:00</published><updated>2020-03-18T14:59:14+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-18:/ruan-jian-gong-cheng-bi-ji-jie-gou-hua-fen-xi-fang-fa.html</id><summary type="html">&lt;p&gt;软件工程分析方法的一套框架&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;结构化设计方法的概念&lt;/h2&gt;
&lt;h3 id="1"&gt;① 软件开发方法学&lt;/h3&gt;
&lt;p&gt;软件开发过程所遵循的办法和步骤。&lt;br /&gt;
&lt;strong&gt;软件开发 …&lt;/strong&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;软件工程分析方法的一套框架&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;结构化设计方法的概念&lt;/h2&gt;
&lt;h3 id="1"&gt;① 软件开发方法学&lt;/h3&gt;
&lt;p&gt;软件开发过程所遵循的办法和步骤。&lt;br /&gt;
&lt;strong&gt;软件开发方法学指的是规则、方法和工具的集成。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="2"&gt;② 结构化方法的组成&lt;/h3&gt;
&lt;p&gt;一套系统化的软件开发方法，包括结构化分析方法，结构化设计方法，结构化程序设计方法。&lt;/p&gt;
&lt;h3 id="3"&gt;③ 结构化分析&lt;/h3&gt;
&lt;p&gt;系统使用问题域术语，给出问题模型。（系统做什么的一个估算）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;需求分析的目标 2.实现软件需求分析的目标对方法学的需求&lt;br /&gt;
   1）提供一组术语&lt;br /&gt;
   2）给出模型表达工具&lt;br /&gt;
   3）给出过程指导&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_2"&gt;结构化分析模型&lt;/h2&gt;
&lt;h3 id="_3"&gt;基本术语&lt;/h3&gt;
&lt;p&gt;数据流：数据的流动，箭头表示流向。数据抽象&lt;br /&gt;
加工：对数据进行变换的单元，椭圆。功能支持过程抽象&lt;br /&gt;
数据存储：数据的静态结构，双线。数据抽象&lt;br /&gt;
数据源：数据的起点，系统之外的实体，长方框。系统边界抽象&lt;br /&gt;
数据潭：数据流的终点，系统之外的实体，同上。同上&lt;/p&gt;
&lt;h3 id="_4"&gt;模型表达工具（在数据库里用过）&lt;/h3&gt;
&lt;p&gt;1）数据流图：描述系统功能&lt;br /&gt;
2）数据字典：定义数据流与数据存储&lt;br /&gt;
= ：等价于（定义为）+ ：与（顺序结构）{}：重复（循环结构）|||：或（选择结构）（）：任选 m..n：界域&lt;br /&gt;
3）加工小说明：描述加工做什么，就是加工逻辑，可以用结构化自然语言描述，判定表，判定树也可以。&lt;/p&gt;
&lt;h2 id="_5"&gt;结构化分析过程&lt;/h2&gt;
&lt;h3 id="_6"&gt;过程指导&lt;/h3&gt;
&lt;p&gt;1.1 顶层数据流图&lt;br /&gt;
1.2 自顶向下，逐层分解:对父图元素分解细化（功能分解）&lt;br /&gt;
2 建立数据字典：数据流图里的数据流和数据存储&lt;br /&gt;
3 写出加工小说明：数据流图的加工&lt;br /&gt;
&lt;strong&gt;需要注意的问题：不是每个加工都需要在加工小说明里写上，数据流与数据存储需要每一个都进行说明，加工的输入流与输出流都应该说清楚，图元个数应该是 5 到 9 个&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="_7"&gt;需求规格说明书&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;引言&lt;br /&gt;
   1.1 编写目的&lt;br /&gt;
   1.2 背景说明&lt;br /&gt;
   1）软件产品的名称&lt;br /&gt;
   2）产品的提出者，开发者，用户&lt;br /&gt;
   3）产品将做什么，不做什么&lt;br /&gt;
   1.3 术语定义&lt;br /&gt;
   1.4 参考文献&lt;/li&gt;
&lt;li&gt;概述&lt;br /&gt;
   2.1 功能概述&lt;br /&gt;
   2.2 约束&lt;/li&gt;
&lt;li&gt;数据流图与数据字典还有加工说明&lt;br /&gt;
   3.1 数据流图&lt;br /&gt;
   3.1.1 数据流图 1&lt;br /&gt;
   1）画图&lt;br /&gt;
   2）加工说明&lt;br /&gt;
   3）数据流说明&lt;br /&gt;
   3.1.2 数据流图 2&lt;br /&gt;
   3.2 数据字典&lt;br /&gt;
   3.2.1 文件说明&lt;br /&gt;
   3.2.2 数据项说明&lt;/li&gt;
&lt;li&gt;接口&lt;br /&gt;
   4.1 用户接口&lt;br /&gt;
   4.2 硬件接口&lt;br /&gt;
   4.3 软件接口&lt;/li&gt;
&lt;li&gt;性能需求&lt;br /&gt;
   5.1 精度（数据的）&lt;br /&gt;
   5.2 时间特征（各个过程的时间耗费）&lt;br /&gt;
   5.3 灵活性（环境变化时能否进行调整与适应）&lt;/li&gt;
&lt;li&gt;属性&lt;br /&gt;
   6.1 可使用性&lt;br /&gt;
   6.2 保密性&lt;br /&gt;
   6.3 可维护性&lt;br /&gt;
   6.4 可移植性&lt;/li&gt;
&lt;li&gt;其他需求的补充&lt;/li&gt;
&lt;/ol&gt;</content><category term="学习笔记"/><category term="软件工程"/><category term="笔记"/></entry><entry><title>针对博客的访问方面的改动</title><link href="https://zhiyuansong.xyz/zhen-dui-bo-ke-de-fang-wen-fang-mian-de-gai-dong.html" rel="alternate"/><published>2020-03-17T11:03:28+08:00</published><updated>2020-03-17T11:03:28+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-17:/zhen-dui-bo-ke-de-fang-wen-fang-mian-de-gai-dong.html</id><summary type="html">&lt;p&gt;前天晚上和昨天晚上，为自己的博客配置了自己的域名，使用了 cloudflare 的免费 CDN 服务加速网站访问，还大费周章的调整了访问 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;前天晚上和昨天晚上，为自己的博客配置了自己的域名，使用了 cloudflare 的免费 CDN 服务加速网站访问，还大费周章的调整了访问节点，速度快了不少，但是也不能期望太高。 😂&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;今天上午看点数学，越看越困，干脆先放一放，总结一下做的事。&lt;br /&gt;
首先是配置域名的事，这个简单，要是有国外支付手段的话可以去买国外的域名，国内的也就是多了个上传个人身份信息备案的步骤，价格上只要你不买什么特牛逼的域名，也挺便宜的，像 xyz 这种新顶级域名，只要 6 块钱注册费，以后每年续费大概也就是 60 多块，自己看着买就行了。&lt;br /&gt;
关于域名解析的问题，简单来说就是把域名指向你的网站，在你买域名的注册商那里配置就行，解析规则配置也挺简单的，像是 A 策略就是把域名指向服务器的 ipv4 地址，CNAME 就是把域名指向另一个域名什么的……因为我博客仅仅是一个 Github Page，配置 CNAME 即可，二级域名就设了 www 和@两个。在你的网页仓库里同时也要在设置里添加自己的域名，这时会在根目录下生成 CNAME 文件，里面正是你的域名。做完这些大概等一段时间生效就可以用自己的域名访问到博客页面了。&lt;br /&gt;
&lt;strong&gt;补充：这篇文章发上去之后，发现自己访问绑定的域名直接 404，访问原域名倒还行，一看是&lt;code&gt;hexo d&lt;/code&gt;命令在上传生成的 public 文件夹时候直接把 CNAME 文件给覆盖没了……解决方法是在工程里的 source 文件夹里写 CNAME 文件，这样生成 public 文件夹时就会把它原封不动搬过去，不会丢了。&lt;/strong&gt;&lt;br /&gt;
做完这些其实我已经很满意了，但是想起之前把博客地址发给朋友看，朋友死活打不开的问题……😳 我还是上网搜了搜怎么加速页面访问速度，结果看到了 CDN，而且有免费的，可以白嫖，令人内心无比感激。😀&lt;br /&gt;
&lt;strong&gt;CDN 指内容分发网络，指的是服务提供商把你的网站文件定期拷贝就近放在他家服务器里，访问者访问时可以就近访问，以此加快访问速度。&lt;/strong&gt;&lt;br /&gt;
首先国内免费的 CDN 不少,目前看看，感觉又拍云的不错，挂上他家 logo，还可以每年送你流量包，还支持 https……（太好了，穷学生感激落泪……就是我域名备案太晚，死活不给过……）结果选了 cloudflare，一家美国的全球 CDN 提供商。&lt;br /&gt;
总的来说 cloudflare 的服务很好，即使你不用他的 CDN 服务，他免费版提供的安全保护也是很强的（虽然我这小网站确实是没啥可保护的，但是有总比没有好啊），但是这么说的另一方面就是说他家的 CDN 服务在中国境内有点平庸，在国外倒是非常好……😅 不过白嫖的瓜你还要说不甜着实是过分了点，先配置起来再说。&lt;br /&gt;
总的来说非常简单，去 cloudflare 注册账户，然后输入你想开启 CDN 服务的域名，选上免费版服务，然后按他的要求将你的域名 dns 服务器改成他家的（说实话这家 CDN 修改 DNS 服务器有点别具一格的特色，但在国内还是不太行，之后解决这个问题），就这么简单，然后你就得重新在 cloudflare 再配置一遍域名解析。然后就成了。👌 感觉好的地方是首先你开 https 服务，SSL 证书不用像国内那样去申请，直接就有了，你还可以在安全配置里各种有用的安全配置拉满，连页面规则都可以设置三个（虽然完全不懂怎么设置），感觉巨贴心。&lt;br /&gt;
测试一下当然速度还是有一点点提升的，从完全超时到可以勉强上去，稍微强了一点。&lt;br /&gt;
但是不能满意，cloudflare 的 dns 解析总是绕开中国跑去美国的节点访问……所以该慢还是慢，需要采取措施来将节点调整到最近的香港节点。简单来说，中国有 cloudflare 的联营伙伴，可以绑定 cloudflare 的账号，更加细化地选择节点。&lt;br /&gt;
我选择的是笨牛网这家联营平台，个人感觉就是个 cloudflare 的中国版控制台，安全策略都可以在上面直接改动。你绑定了 cloudflare 的账号也可以管理上面的服务。这里的话就直接把接入方式改成笨牛网的 CNAME 接入，这个时候你就需要在笨牛网配置解析规则了，照抄 cloudflare 上的，之后可以把域名的 dns 服务器换回先前的了……（得，又回去了）再在域名的解析规则里，条数不变，类型不变，指向的是笨牛网配置完解析规则后提供的以&lt;code&gt;cdn.cloudflare.net&lt;/code&gt;结尾的回源地址，然后就完成了。个人理解是访问的过程中加了一层中间层，跳转了两个 dns，大概吧。🤔&lt;br /&gt;
测试了一下，速度不错，200ms 左右延时，比较满意了。&lt;br /&gt;
这一通操作下来，感觉还学了不少嘛！😄&lt;/p&gt;</content><category term="实用小文章"/><category term="Hexo"/><category term="CDN"/></entry><entry><title>软件工程学习笔记：需求和需求规约</title><link href="https://zhiyuansong.xyz/ruan-jian-gong-cheng-xue-xi-bi-ji-xu-qiu-he-xu-qiu-gui-yue.html" rel="alternate"/><published>2020-03-15T11:28:04+08:00</published><updated>2020-03-15T11:28:04+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-15:/ruan-jian-gong-cheng-xue-xi-bi-ji-xu-qiu-he-xu-qiu-gui-yue.html</id><summary type="html">&lt;p&gt;无论是哪种开发方式，软件需求都是软件开发的基础。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;需求&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;定义：一个有关“要予构造”的陈述，描述了待开发产品/系统（或项）功 …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;无论是哪种开发方式，软件需求都是软件开发的基础。&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;需求&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;定义：一个有关“要予构造”的陈述，描述了待开发产品/系统（或项）功能上的&lt;strong&gt;能力、性能参数或者其他性质（像是约束什么的）&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;基本性质：① 必要性 ② 无歧义性 ③ 可测性 ④ 可跟踪性 ⑤ 可测量性&lt;/li&gt;
&lt;li&gt;分类：功能，性能，外部接口，设计约束，质量属性（产品质量的量化值）。&lt;/li&gt;
&lt;li&gt;发现需求的方式：自悟（自己从用户出发），交谈（谈话的艺术），观察（眼见为实），小组会，提炼（复审需求文档），综合运用。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_2"&gt;需求规约&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;概念：一个产品所有需求陈述的正式文档，是一个软件产品/系统的概念模型。&lt;/li&gt;
&lt;li&gt;基本性质：① 重要性和稳定性程度（需求分层次） ② 可修改的（容易修改单个需求） ③ 完整的（不漏） ④ 一致的（不抵触）&lt;/li&gt;
&lt;li&gt;格式：&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;引言&lt;br /&gt;
   1.1 目的&lt;br /&gt;
   1.2 范围&lt;br /&gt;
   1.3 定义，略缩语&lt;br /&gt;
   1.4 参考文献&lt;br /&gt;
   1.5 概述（项目范围）&lt;/li&gt;
&lt;li&gt;总体描述&lt;br /&gt;
   2.1 产品概述&lt;br /&gt;
   2.2 产品功能&lt;br /&gt;
   2.3 用户特性&lt;br /&gt;
   2.4 约束&lt;br /&gt;
   2.5 假设与依赖&lt;/li&gt;
&lt;li&gt;特定需求(技术核心,非功能性刻画)&lt;br /&gt;
   附录&lt;br /&gt;
   索引&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;作用:① 开发者与用户间的技术合同,体现产品功能 ② 项目的管理控制基础 ③ 产品设计的起始点 ④ 测试计划(早期修改错误的代价低)与用户指南(用户角度的功能描述)的生成基础&lt;br /&gt;
   &lt;u&gt;但是需求规约不是设计文档,也不是进度或规划文档,开发进度,成本,开发方法不应该包含在内&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="_3"&gt;项目的需求和需求规约&lt;/h2&gt;
&lt;p&gt;软件的需求:我要交个啥样的产品&lt;br /&gt;
项目的需求:开发组要做啥&lt;/p&gt;</content><category term="学习笔记"/><category term="软件工程"/><category term="笔记"/></entry><entry><title>对NexT主题进行的第一次美化工作</title><link href="https://zhiyuansong.xyz/dui-nextzhu-ti-jin-xing-de-di-yi-ci-mei-hua-gong-zuo.html" rel="alternate"/><published>2020-03-14T18:27:08+08:00</published><updated>2020-03-14T18:27:08+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-14:/dui-nextzhu-ti-jin-xing-de-di-yi-ci-mei-hua-gong-zuo.html</id><summary type="html">&lt;p&gt;我还是选择让界面好看一点而不是快速打开……大概这就是人的劣根性吧。 😓&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;第一次美化工作完成了以下几个目标，在网站的 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;我还是选择让界面好看一点而不是快速打开……大概这就是人的劣根性吧。 😓&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;第一次美化工作完成了以下几个目标，在网站的左下角插入了一个 aplayer 播放器，可以放最爱听的《Ninelie》，然后解决了切换网页就会使播放器刷新的问题，这大概是今天最难的问题了。其他的小修小补，像是边栏换个位置啊，加上我那几年不换的头像啊，开启背景动画啊，基本上照着 NexT 主题的文档就可以改的差不多了。然而像什么评论栏啊，什么简介啊，什么字数统计和访问热度啊，暂时不太想开，没啥意思，自己写着爽就完事了，这些工程等我啥时候兴致起了再说吧。&lt;/p&gt;
&lt;p&gt;aplayer 这个东西，坑还是很多的，首先第一个坑，存在 aplayer 和 hexo-tag-aplayer 两个包，而用处又不一样，第一个包，你可以在网页结构里用，修改你的博客模板就可以插入播放器，第二个包，你可以在写文章时直接插一首歌进去，但它最吸引我的点还是直接支持读取歌单内容，不用自己累的要死去找歌曲的网址、封面的网址、歌词的网址然后去写一个 json……（但是实在鸡肋，谁累的要死还去查半天歌曲 ID 就为插首歌？浪费时间 🙁）网上的东西很乱，一开始看的很蒙，最后才确定用 aplayer。&lt;/p&gt;
&lt;p&gt;第二个坑，就是怎么用了，网上大概就是把源码下下来塞到主题 source 文件里然后加个调用文件，再在布局文件里插入一个标签容器……看着巨 low，可是我更 low，看不太懂各路大神的操作，本着先跑起来再说的实际精神，我就这么用了。😶&lt;/p&gt;
&lt;p&gt;第三个坑，由于部署到 Github 上，访问很慢，自己找到的资源网址要加载半天……歌是半天放不出来，最后只能把资源文件都拎出来放到本地环境，稍微快了一丢丢但还是慢，挂梯子才能好些。（像这种网站上的都这么艰辛，感慨 🙄）&lt;/p&gt;
&lt;p&gt;第四个坑，调用文件里要写歌词的调用方式，aplayer 里的 lrcType 属性，竟然用的是 1，2，3……（3 对应的是读取 lrc 文件）&lt;br /&gt;
不写的话是不会显示歌词的，文档上没有说，完全是自己试出来的。&lt;/p&gt;
&lt;p&gt;最后一个坑，切换网页导致的播放器刷新，用了 pjax 插件来解决，首先是主题里有这个配置项，但是依赖包得自己下载，然后这个包似乎会引发一些 hexo-tag-aplayer 的问题，但是我目前没有用这个包的打算，这个问题目前算是搁置了下来。&lt;/p&gt;
&lt;p&gt;一个很大的问题，在这番改动之后，手机访问不了博客了，不知是什么原因，迷惑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;今天的感悟是：不要动不动给一个东西定性，你永远都没办法把一个东西看全面，动不动定性很没意思的。&lt;/strong&gt;&lt;/p&gt;</content><category term="实用小文章"/><category term="Hexo"/></entry><entry><title>软件生存周期学习笔记</title><link href="https://zhiyuansong.xyz/ruan-jian-sheng-cun-zhou-qi-xue-xi-bi-ji.html" rel="alternate"/><published>2020-03-11T14:21:37+08:00</published><updated>2020-03-11T14:21:37+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-11:/ruan-jian-sheng-cun-zhou-qi-xue-xi-bi-ji.html</id><summary type="html">&lt;blockquote&gt;
&lt;p&gt;很明显软件工程不是所谓的“开发完了就完事了”的事情，以下就是要介绍一下软件产生到消亡的过程，就是所谓的软件生 …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;很明显软件工程不是所谓的“开发完了就完事了”的事情，以下就是要介绍一下软件产生到消亡的过程，就是所谓的软件生存周期。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;h2 id="_1"&gt;软件生存周期&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;概念：软件产品或系统的一系列活动全周期，从产生概念，到开发，交付，使用中的修订演化到最后被淘汰的过程。&lt;br /&gt;
   &lt;u&gt;过程是活动的集合，活动是任务的集合，任务是 input 转成 output 的操作。&lt;/u&gt;&lt;br /&gt;
&lt;strong&gt;很明显是过程最大，活动第二，任务最小嘛！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;分类：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基本过程：软件生产直接相关活动集合，&lt;strong&gt;还能细分成获取（需方）-供应（供方）-&lt;u&gt;开发（供方）&lt;/u&gt;-运行（需方）-维护（供方）小过程&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;支持过程：有关各方按目标从事的支持活动集合（分工合作支持开发各方……）&lt;strong&gt;还有文档-配置管理-质量保证（QA？）-验证-确认-联合评审-审计-问题解决的小细分……&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;组织过程：软件生产组织相关活动集合（管理什么的）&lt;strong&gt;细分为管理-基础设施-人力资源-改进-资产管理-复用程序管理-领域软件工程的小过程……&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;总的来说你得把基本过程，支持过程，组织过程记住是个啥。关系的分析从供需（承担软件开发的主体）方面分析 🆗&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="_2"&gt;软件生存周期模型&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;概念：软件过程、活动、任务的组织框架（就是软件开发模型）&lt;/li&gt;
&lt;li&gt;常见的模型：&lt;/li&gt;
&lt;li&gt;瀑布模型（一条线，可返工）&lt;br /&gt;
      &amp;gt; 优点：有规约，有设计，有双方参与，画了控制线&lt;br /&gt;
      &amp;gt; 缺点：需求不明确，做不出好的东西，文档类的前期写没有太多意义，功能完全体现太迟了&lt;/li&gt;
&lt;li&gt;增量模型（分段完成需求，分段增删）&lt;br /&gt;
      &amp;gt; 优点：在以上优点之上，第一版开发快，小版本更新风险小，防止客户不断变化需求，可以增量投资（先强化一两个突出点）&lt;br /&gt;
      &amp;gt; 缺点：如果不对客户需求进行规划，第一版需求不稳定对于之后就很成问题，如果早期就不稳，那么就得重新开始，成本，进度和配置的复杂性可能承担不了。&lt;/li&gt;
&lt;li&gt;演化模型（EA 版本迭代，可能最后结果和第一版需求都不一样的那种，需求一开始不确定，需要用户的版本不断反馈）&lt;/li&gt;
&lt;li&gt;喷泉模型（迭代，无缝，层层叠叠，面向对象）&lt;/li&gt;
&lt;/ol&gt;</content><category term="学习笔记"/><category term="软件工程"/><category term="笔记"/></entry><entry><title>用Hexo在Github上搭建博客</title><link href="https://zhiyuansong.xyz/yong-hexozai-githubshang-da-jian-bo-ke.html" rel="alternate"/><published>2020-03-10T11:24:26+08:00</published><updated>2020-03-10T11:24:26+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-10:/yong-hexozai-githubshang-da-jian-bo-ke.html</id><summary type="html">&lt;p&gt;其实很久以前就想搭建一个属于自己的博客了，之前甚至发疯了去买了一年的阿里云轻量应用服务器，结果就是自己只 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;其实很久以前就想搭建一个属于自己的博客了，之前甚至发疯了去买了一年的阿里云轻量应用服务器，结果就是自己只在上面敲了敲 linux 指令……白瞎了一百来块钱，现在想来，在服务器上搭建确实好，但是确实还是有一定的开销的，而且在中国，建个个人博客都要备案，时间成本也是有的。那么不妨借用 Github 的静态网页托管来搭一个，省去了服务器与域名的钱，虽然速度有点慢但是无伤大雅。好 👍&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;

&lt;p&gt;前置条件：自己的电脑上请安装 nodejs，安装 git，同时要去 Github 申请一个账号（&lt;strong&gt;起用户名的时候要认真一点，不要瞎写&lt;/strong&gt;），这里的安装和确认安装成功的流程就略掉了，自行百度 💪&lt;/p&gt;
&lt;p&gt;那么就正式开始安装的流程吧:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;通过 &lt;code&gt;npm/cnpm install -g hexo-cli&lt;/code&gt; 安装 Hexo 框架。npm 是指 nodejs 的包管理器，由于 node 服务器在国外访问慢，建议安装淘宝镜像的 node 源 cnpm。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在自己选定的盘符下新建一个文件夹，在文件夹里用 &lt;code&gt;hexo init&lt;/code&gt; 命令初始化一个 hexo 的模板网站，这个过程有点像 Django 在初始化时在文件夹里展开的过程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这个时候要记住几条命令：&lt;code&gt;hexo clean&lt;/code&gt;是清理缓存，&lt;code&gt;hexo g&lt;/code&gt;是生成将 markdown 文件转成 html 的命令，&lt;code&gt;hexo n "xxx"&lt;/code&gt;是生成一个名字为 xxx 的 markdown 文件，这个文件位置是在当前目录下的&lt;code&gt;source/_posts&lt;/code&gt;文件夹里，就是你写博客时要编辑的文件；&lt;code&gt;hexo s&lt;/code&gt;是在本地电脑上预览自己的博客页面，默认是 4000 端口；&lt;code&gt;hexo d&lt;/code&gt;是将自己的网站页面推送到 Github 上,一般来说还需要装插件 hexo-deployer-git 才可以保证没有问题，用&lt;code&gt;cnpm install --save hexo-deployer-git&lt;/code&gt;命令来安装。以上基本就是常用的命令，具体用法向后看吧。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;给自己的 Github 账户首先装好 ssh 密钥，具体方法百度，主要是为了防止以后每次推送内容到服务器上都要一遍一遍地输密码。在这之后，新建仓库，仓库名格式必须是&lt;code&gt;用户名.github.io&lt;/code&gt;格式，只有这样才能保证你可以以&lt;code&gt;https://用户名.github.io&lt;/code&gt;的域名来访问到你的博客页面。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改项目目录下的&lt;code&gt;_config.yml&lt;/code&gt;文件配置选项，这里是配置 Hexo 框架的各种可选项，具体的内容可以去看 Hexo 的文档进行自定义,但如果想要把你的博客页面传到 Github 仓库里，最重要的是修改&lt;code&gt;deploy&lt;/code&gt;这一块的内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    deploy:
        type: git
        repo: https://github.com/meloveayu/meloveayu.github.io
        branch: master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;code&gt;repo&lt;/code&gt;修改成你的仓库的网址，其他照抄即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;目前已经是万事俱备了，你可以现在现在自己的本地预览一下模板页面是啥样的，直接用&lt;code&gt;hexo g&lt;/code&gt;编译页面然后再用&lt;code&gt;hexo s&lt;/code&gt;开一个本地页面来预览，没有问题就可以用&lt;code&gt;hexo d&lt;/code&gt;将自己的页面上传到 Github 的仓库去了，第一次上传要输入 github 的账号密码，之后就免了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;每次要写博客时，用&lt;code&gt;hexo n "xxx"&lt;/code&gt;来新建页面，写完这个页面，遵循“编译页面——预览页面——推送页面”的流程。然后你就可以访问自己的博客网址来看到自己的网页了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;至于更改主题，可以上 Hexo 主题页去看看有没有喜欢的，当前自己选的 NexT 主题感觉不错，用的人多，可扩展，初始页就很棒了，这部分已经算是个性化了，该去自己百度了 🤭&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当然不止 Github，像是码云什么的也能部署博客页，还快，但是码云不开 pro 版就不能自动更新网页，你得自己去网页里点一下……&lt;strong&gt;~~我是不知道为啥要有这么傻的设计，还浪费了我半天思索为啥我页面没有变化/(ㄒ o ㄒ)/~~&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;大概就是这样了吧，以后就可以爽写了 😀&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="实用小文章"/><category term="Hexo"/></entry><entry><title>终于安顿下来了</title><link href="https://zhiyuansong.xyz/zhong-yu-an-dun-xia-lai-liao.html" rel="alternate"/><published>2020-03-10T11:01:42+08:00</published><updated>2020-03-10T11:01:42+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-10:/zhong-yu-an-dun-xia-lai-liao.html</id><summary type="html">&lt;p&gt;天哪，兜兜转转，感觉自己终于算是安顿了下来，搭好了一个能写东西的地方，也选了一个很素的主题，虽然它现在看来只有 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;天哪，兜兜转转，感觉自己终于算是安顿了下来，搭好了一个能写东西的地方，也选了一个很素的主题，虽然它现在看来只有写东西一个功能，但是，这还不够吗？😂&lt;/p&gt;
&lt;p&gt;今天，务必要把这一连串下来的安装过程写下来，这真的是一件很神奇的事情。虽然懒得要死，但我还是搭起来了！&lt;/p&gt;</content><category term="随便聊聊"/></entry><entry><title>能成吗？</title><link href="https://zhiyuansong.xyz/neng-cheng-ma.html" rel="alternate"/><published>2020-03-09T14:07:44+08:00</published><updated>2020-03-09T14:07:44+08:00</updated><author><name>远之松</name></author><id>tag:zhiyuansong.xyz,2020-03-09:/neng-cheng-ma.html</id><summary type="html">&lt;h2 id="_1"&gt;这是一个测试&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;gitee 不行，自动更新网页还要升级到 pro 版&lt;/li&gt;
&lt;li&gt;本来还想在 gitee 上建博客，看来是不行了，太不方便了&lt;/li&gt;
&lt;li&gt;虽然 github 的访问有 …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;h2 id="_1"&gt;这是一个测试&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;gitee 不行，自动更新网页还要升级到 pro 版&lt;/li&gt;
&lt;li&gt;本来还想在 gitee 上建博客，看来是不行了，太不方便了&lt;/li&gt;
&lt;li&gt;虽然 github 的访问有点慢，但是也只能这样了&lt;/li&gt;
&lt;/ol&gt;</content><category term="misc"/><category term="test"/></entry></feed>