<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2023-01-31T11:56:11+00:00</updated><id>/feed.xml</id><title type="html">班启的备忘录</title><subtitle>轻则失根，躁则失君。</subtitle><author><name>班启</name></author><entry><title type="html">Git 的 diff 算法</title><link href="/algorithm/2021-09-23-git-diff-myers" rel="alternate" type="text/html" title="Git 的 diff 算法" /><published>2021-09-23T00:00:00+00:00</published><updated>2021-09-23T00:00:00+00:00</updated><id>/algorithm/git-diff-myers</id><content type="html" xml:base="/algorithm/2021-09-23-git-diff-myers">&lt;h3 id=&quot;参考链接&quot;&gt;参考链接&lt;/h3&gt;

&lt;p&gt;https://segmentfault.com/p/1210000009610313/read
https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">参考链接</summary></entry><entry><title type="html">DNS 解析过程</title><link href="/network/2021-09-16-DNS-resolving" rel="alternate" type="text/html" title="DNS 解析过程" /><published>2021-09-16T00:00:00+00:00</published><updated>2021-09-16T00:00:00+00:00</updated><id>/network/DNS-resolving</id><content type="html" xml:base="/network/2021-09-16-DNS-resolving">&lt;p&gt;&lt;a href=&quot;/assets/images/DNS解析过程.jpg&quot;&gt;DNS解析过程&lt;/a&gt;&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">DNS解析过程</summary></entry><entry><title type="html">三次握手，四次挥手</title><link href="/network/2021-09-16-TCP-resolving" rel="alternate" type="text/html" title="三次握手，四次挥手" /><published>2021-09-16T00:00:00+00:00</published><updated>2021-09-16T00:00:00+00:00</updated><id>/network/TCP-resolving</id><content type="html" xml:base="/network/2021-09-16-TCP-resolving">&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;p&gt;https://zhuanlan.zhihu.com/p/53374516&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">参考链接</summary></entry><entry><title type="html">动态规划解题思维</title><link href="/algorithm/2021-09-15-dynamic-programming" rel="alternate" type="text/html" title="动态规划解题思维" /><published>2021-09-15T00:00:00+00:00</published><updated>2021-09-15T00:00:00+00:00</updated><id>/algorithm/dynamic-programming</id><content type="html" xml:base="/algorithm/2021-09-15-dynamic-programming">&lt;p&gt;一句话总结：动态规划问题的一般形式就是求&lt;strong&gt;最值&lt;/strong&gt;，而求最值必须要&lt;strong&gt;穷举&lt;/strong&gt;，所以求解过程中最大的问题是如何穷举；动态规划的穷举有个特点，会存在&lt;strong&gt;重叠子问题&lt;/strong&gt;，并且一定具备&lt;strong&gt;最优子结构&lt;/strong&gt;；但是题目千变万化，只有列出正确的&lt;strong&gt;状态转移方程&lt;/strong&gt;才能正确地穷举&lt;/p&gt;

&lt;h3 id=&quot;辅助思考状态转移方程的思维框架&quot;&gt;辅助思考状态转移方程的思维框架&lt;/h3&gt;
&lt;p&gt;明确状态 -&amp;gt; 定义 dp 数组/函数的含义 -&amp;gt; 明确选择 -&amp;gt; 明确 base case&lt;/p&gt;

&lt;p&gt;明确变量 -&amp;gt; 定义 dp 函数 -&amp;gt; 明确子问题 -&amp;gt; 明确退出边界&lt;/p&gt;

&lt;h3 id=&quot;解法要点&quot;&gt;解法要点&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;备忘录&lt;/li&gt;
  &lt;li&gt;dp 数组&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;例子1斐波那契数列&quot;&gt;例子1：斐波那契数列&lt;/h3&gt;

&lt;h3 id=&quot;参考链接&quot;&gt;参考链接&lt;/h3&gt;

&lt;p&gt;https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&amp;amp;mid=2247484731&amp;amp;idx=1&amp;amp;sn=f1db6dee2c8e70c42240aead9fd224e6&amp;amp;chksm=9bd7fb33aca07225bee0b23a911c30295e0b90f393af75eca377caa4598ffb203549e1768336&amp;amp;scene=21#wechat_redirect&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">一句话总结：动态规划问题的一般形式就是求最值，而求最值必须要穷举，所以求解过程中最大的问题是如何穷举；动态规划的穷举有个特点，会存在重叠子问题，并且一定具备最优子结构；但是题目千变万化，只有列出正确的状态转移方程才能正确地穷举</summary></entry><entry><title type="html">浏览器缓存策略</title><link href="/front-end/browser/2021-09-15-browser-cache" rel="alternate" type="text/html" title="浏览器缓存策略" /><published>2021-09-15T00:00:00+00:00</published><updated>2021-09-15T00:00:00+00:00</updated><id>/front-end/browser/browser-cache</id><content type="html" xml:base="/front-end/browser/2021-09-15-browser-cache">&lt;p&gt;一句话总结：使用 header 中的字段来控制缓存的使用；老字段是 Expires 记录绝对时间，新字段 Cache-Control 配合各种选项，记录的是相对值；协商缓存是本地缓存文件没有过期就用缓存的，缓存过期了就带着缓存标识询问服务器有没有过期，过期了就重新请求，没过期就用缓存的&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/HTTP缓存流程图.png&quot;&gt;HTTP缓存流程图&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;p&gt;https://juejin.cn/post/6844903593275817998
https://segmentfault.com/a/1190000021716418&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">一句话总结：使用 header 中的字段来控制缓存的使用；老字段是 Expires 记录绝对时间，新字段 Cache-Control 配合各种选项，记录的是相对值；协商缓存是本地缓存文件没有过期就用缓存的，缓存过期了就带着缓存标识询问服务器有没有过期，过期了就重新请求，没过期就用缓存的</summary></entry><entry><title type="html">网站性能优化</title><link href="/front-end/performance/2021-09-15-web-site-performance" rel="alternate" type="text/html" title="网站性能优化" /><published>2021-09-15T00:00:00+00:00</published><updated>2021-09-15T00:00:00+00:00</updated><id>/front-end/performance/web-site-performance</id><content type="html" xml:base="/front-end/performance/2021-09-15-web-site-performance">&lt;h2 id=&quot;一些基础优化&quot;&gt;一些基础优化&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;图片的压缩和合并&lt;/li&gt;
  &lt;li&gt;代码压缩（混淆、去掉调试代码）&lt;/li&gt;
  &lt;li&gt;减少 HTTP 请求&lt;/li&gt;
  &lt;li&gt;样式表放页头、脚本放底部&lt;/li&gt;
  &lt;li&gt;避免过大 DOM&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;进阶优化&quot;&gt;进阶优化&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;静态资源存 CDN&lt;/li&gt;
  &lt;li&gt;TTL 优化&lt;/li&gt;
  &lt;li&gt;异步脚本&lt;/li&gt;
  &lt;li&gt;css 预加载&lt;/li&gt;
  &lt;li&gt;TTFB 优化&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;p&gt;https://segmentfault.com/a/1190000021098540
https://csspod.com/frontend-performance-best-practices/#javascript-bottom&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">一些基础优化 图片的压缩和合并 代码压缩（混淆、去掉调试代码） 减少 HTTP 请求 样式表放页头、脚本放底部 避免过大 DOM</summary></entry><entry><title type="html">公平洗牌算法（Knuth-Shuffle）</title><link href="/algorithm/2021-09-14-knuth-shuffle" rel="alternate" type="text/html" title="公平洗牌算法（Knuth-Shuffle）" /><published>2021-09-14T00:00:00+00:00</published><updated>2021-09-14T00:00:00+00:00</updated><id>/algorithm/knuth-shuffle</id><content type="html" xml:base="/algorithm/2021-09-14-knuth-shuffle">&lt;h1 id=&quot;问设计一个公平的洗牌算法&quot;&gt;问：设计一个公平的洗牌算法&lt;/h1&gt;

&lt;h2 id=&quot;一洗牌&quot;&gt;一、洗牌&lt;/h2&gt;
&lt;p&gt;随机抽取数组中的一个元素，放入另一个数组即可&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function shuffle (arr) {
    const ret = []
    while (arr.length &amp;gt; 0) {
        const r = parseInt(Math.random() * arr.length)
        ret.push(arr.splice(r, 1)[0])
    }
    return ret
}

shuffle([1, 2, 3])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;二sort-洗牌&quot;&gt;二、Sort 洗牌&lt;/h2&gt;
&lt;p&gt;利用 Array 的 sort 方法，对交换函数进行改造，每次有 1/2 的机会交换位置，来实现随机&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const shuffle = arr =&amp;gt; arr.sort(() =&amp;gt; 0.5 - Math.random())

shuffle([1, 2, 3, 4, 5]) // [1, 2, 5, 3, 4]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;三公平洗牌knuth-shuffle&quot;&gt;三、公平洗牌（Knuth-Shuffle）&lt;/h2&gt;
&lt;p&gt;从数组最后一位向第一位循环，每次随机取一个当前位置及之前的项，与当前位置的项替换&lt;/p&gt;

&lt;p&gt;这样相当于每个项被放到每个位置上的概率都为 1/n ，以实现公平&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var shuffle = function(arr) {
    var n = arr.length;
    for (let i = n-1; i &amp;gt; 0; i--) {
        var r = parseInt(Math.random() * (i + 1));
        [arr[r], arr[i]] = [arr[i], arr[r]];
    }
    return arr;
}
shuffle([1, 2, 3, 4, 6])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;https://cloud.tencent.com/developer/article/1462951&lt;/li&gt;
  &lt;li&gt;http://www.xiongdalin.com/2021/01/25/array-shuffle/&lt;/li&gt;
&lt;/ol&gt;</content><author><name>班启</name></author><summary type="html">问：设计一个公平的洗牌算法</summary></entry><entry><title type="html">函数防抖与节流（debounce and throttle）</title><link href="/front-end/javascript/2021-09-14-debounce-and-throttle" rel="alternate" type="text/html" title="函数防抖与节流（debounce and throttle）" /><published>2021-09-14T00:00:00+00:00</published><updated>2021-09-14T00:00:00+00:00</updated><id>/front-end/javascript/debounce-and-throttle</id><content type="html" xml:base="/front-end/javascript/2021-09-14-debounce-and-throttle">&lt;h2 id=&quot;debounce-特点&quot;&gt;debounce 特点&lt;/h2&gt;
&lt;p&gt;函数多次发起执行，只接受执行最后一次发起&lt;/p&gt;

&lt;h2 id=&quot;throttle-特点&quot;&gt;throttle 特点&lt;/h2&gt;
&lt;p&gt;函数多次发起执行，只在第一次执行完成后才接受再次发起执行&lt;/p&gt;

&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;p&gt;https://www.jianshu.com/p/c9fe37cdf200&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">debounce 特点 函数多次发起执行，只接受执行最后一次发起</summary></entry><entry><title type="html">for…in 和 for…of 的用法与区别</title><link href="/front-end/javascript/2021-09-14-for-in-for-of" rel="alternate" type="text/html" title="for…in 和 for…of 的用法与区别" /><published>2021-09-14T00:00:00+00:00</published><updated>2021-09-14T00:00:00+00:00</updated><id>/front-end/javascript/for-in-for-of</id><content type="html" xml:base="/front-end/javascript/2021-09-14-for-in-for-of">&lt;p&gt;一句话总结：for…in 循环对象的 key，for…of 调用对象的迭代器方法循环对象的 value&lt;/p&gt;

&lt;h2 id=&quot;原理&quot;&gt;原理&lt;/h2&gt;</content><author><name>班启</name></author><summary type="html">一句话总结：for…in 循环对象的 key，for…of 调用对象的迭代器方法循环对象的 value</summary></entry><entry><title type="html">JS 中 new 的原理以及实现</title><link href="/front-end/javascript/2021-09-14-new-implement" rel="alternate" type="text/html" title="JS 中 new 的原理以及实现" /><published>2021-09-14T00:00:00+00:00</published><updated>2021-09-14T00:00:00+00:00</updated><id>/front-end/javascript/new-implement</id><content type="html" xml:base="/front-end/javascript/2021-09-14-new-implement">&lt;p&gt;一句话总结：执行 new 关键词后，总是返回一个对象，要么是构造函数加空对象原型生成的对象，要么是构造函数 return 的对象&lt;/p&gt;

&lt;h2 id=&quot;原理&quot;&gt;原理&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;在内存中创建一个新对象&lt;/li&gt;
  &lt;li&gt;这个新对象内部的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[Prototype]]&lt;/code&gt;特性被赋值为构造函数的 prototype 属性。&lt;/li&gt;
  &lt;li&gt;构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)&lt;/li&gt;
  &lt;li&gt;执行构造函数内部的代码(给新对象添加属性)&lt;/li&gt;
  &lt;li&gt;如果构造函数返回非空对象，则返回该对象;否则，返回刚创建的新对象&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;实现&quot;&gt;实现&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const _new = function (fn, ...regs) {
  const o = {};
  o.__proto__ - fn.prototype
  fn = fn.bind(o)
  const res fn(...regs)
  return (typeof res === 'object') ? res : o
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;简便实现&quot;&gt;简便实现&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const _new = function (fn, ...regs) {
  const o = Object.create(fn.prototype);
  const res = fn.call(obj, ...regs);
  return (typeof res === 'object') ? res : o;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;参考链接&quot;&gt;参考链接&lt;/h2&gt;

&lt;p&gt;https://cloud.tencent.com/developer/article/1526901
https://juejin.cn/post/7006232342398238733
https://juejin.cn/post/6844904082310692872&lt;/p&gt;</content><author><name>班启</name></author><summary type="html">一句话总结：执行 new 关键词后，总是返回一个对象，要么是构造函数加空对象原型生成的对象，要么是构造函数 return 的对象</summary></entry></feed>