diff options
29 files changed, 1453 insertions, 779 deletions
diff --git a/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/index.html b/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/index.html index 0078f582..cd2af748 100644 --- a/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/index.html +++ b/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/index.html @@ -215,7 +215,7 @@ <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">type</span> <span class="title class_">Safe</span><T> = </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">true</span>; </span><br><span class="line"> <span class="attr">data</span>: T; </span><br><span class="line"> } </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">false</span>; </span><br><span class="line"> <span class="attr">error</span>: <span class="built_in">string</span>; </span><br><span class="line"> };</span><br></pre></td></tr></table></figure> <p>we do need a few try/catches. The good thing is we only need about two, not 100,000:</p> -<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">promise</span>: <span class="title class_">Promise</span><T>, err?: <span class="built_in">string</span>): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">func</span>: <span class="function">() =></span> T, err?: <span class="built_in">string</span>): <span class="title class_">Safe</span><T>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(</span><br><span class="line"> <span class="attr">promiseOrFunc</span>: <span class="title class_">Promise</span><T> | (<span class="function">() =></span> T),</span><br><span class="line"> err?: <span class="built_in">string</span>,</span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> | <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">if</span> (promiseOrFunc <span class="keyword">instanceof</span> <span class="title class_">Promise</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeAsync</span>(promiseOrFunc, err);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeSync</span>(promiseOrFunc, err);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> safeAsync<T>(</span><br><span class="line"> <span class="attr">promise</span>: <span class="title class_">Promise</span><T>, </span><br><span class="line"> err?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> promise;</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> safeSync<T>(</span><br><span class="line"> <span class="attr">func</span>: <span class="function">() =></span> T, </span><br><span class="line"> err?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="title function_">func</span>();</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">promise</span>: <span class="title class_">Promise</span><T>, <span class="attr">err</span>?: <span class="built_in">string</span>): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">func</span>: <span class="function">() =></span> T, <span class="attr">err</span>?: <span class="built_in">string</span>): <span class="title class_">Safe</span><T>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(</span><br><span class="line"> <span class="attr">promiseOrFunc</span>: <span class="title class_">Promise</span><T> | (<span class="function">() =></span> T),</span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span>,</span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> | <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">if</span> (promiseOrFunc <span class="keyword">instanceof</span> <span class="title class_">Promise</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeAsync</span>(promiseOrFunc, err);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeSync</span>(promiseOrFunc, err);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> safeAsync<T>(</span><br><span class="line"> <span class="attr">promise</span>: <span class="title class_">Promise</span><T>, </span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> promise;</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> safeSync<T>(</span><br><span class="line"> <span class="attr">func</span>: <span class="function">() =></span> T, </span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="title function_">func</span>();</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <p>This is just a wrapper with our <code>Safe</code> type as the return one. But sometimes simple things are all you need. Let’s combine them with the example from above.</p> <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> request = { <span class="attr">name</span>: “test”, <span class="attr">value</span>: <span class="number">2n</span> }; </span><br><span class="line"><span class="keyword">const</span> body = <span class="title function_">safe</span>( </span><br><span class="line"> <span class="function">() =></span> <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(request), </span><br><span class="line"> “<span class="title class_">Failed</span> to serialize request”, </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!body.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (body.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">safe</span>( </span><br><span class="line"> <span class="title function_">fetch</span>(<span class="string">"https://example.com"</span>, { </span><br><span class="line"> <span class="attr">method</span>: “<span class="variable constant_">POST</span>”, </span><br><span class="line"> <span class="attr">body</span>: body.<span class="property">data</span>, </span><br><span class="line"> }), </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (response.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">data</span>.<span class="property">ok</span>) { </span><br><span class="line"> <span class="comment">// handle network error </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="comment">// handle response (body.data)</span></span><br></pre></td></tr></table></figure> diff --git a/2025/02/18/Prisma-关系型数据库的-Self-relations/index.html b/2025/02/18/Prisma-关系型数据库的-Self-relations/index.html index fda4a344..b69d4397 100644 --- a/2025/02/18/Prisma-关系型数据库的-Self-relations/index.html +++ b/2025/02/18/Prisma-关系型数据库的-Self-relations/index.html @@ -213,7 +213,7 @@ <p>一对一的 self-relation 需要两个端点,即使这两个端点是同一条数据。</p> </blockquote> <p>而在关系型数据库中,一对一的 self-relation 可以用如下 SQL 描述:</p> -<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "successorId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> fk_successor_user <span class="keyword">FOREIGN</span> KEY ("successorId") <span class="keyword">REFERENCES</span> "User" (id);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> successor_unique <span class="keyword">UNIQUE</span> ("successorId");</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "successorId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> fk_successor_user <span class="keyword">FOREIGN KEY</span> ("successorId") <span class="keyword">REFERENCES</span> "User" (id);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> successor_unique <span class="keyword">UNIQUE</span> ("successorId");</span><br></pre></td></tr></table></figure> <h2 id="一对多"><a href="#一对多" class="headerlink" title="一对多"></a>一对多</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> teacherId Int?</span><br><span class="line"> teacher User? @relation("TeacherStudents", fields: [teacherId], references: [id])</span><br><span class="line"> students User[] @relation("TeacherStudents")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> @@ -226,7 +226,7 @@ <p>可以通过将 <code>teacher</code> 字段设<a target="_blank" rel="noopener" href="https://www.prisma.io/docs/orm/prisma-schema/data-model/models#optional-and-mandatory-fields">为 required</a> 来要求每个 User 都有一名 teacher。</p> </blockquote> <p>用 SQL 描述 User model:</p> -<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "teacherId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> fk_teacherid_user <span class="keyword">FOREIGN</span> KEY ("teacherId") <span class="keyword">REFERENCES</span> "User" (id);</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "teacherId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> fk_teacherid_user <span class="keyword">FOREIGN KEY</span> ("teacherId") <span class="keyword">REFERENCES</span> "User" (id);</span><br></pre></td></tr></table></figure> <p><code>teacherId</code> 没有使用 <code>UNIQUE</code> 约束,这代表着多个 students 可以有同一个 teacher</p> <h2 id="多对多"><a href="#多对多" class="headerlink" title="多对多"></a>多对多</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> followedBy User[] @relation("UserFollows")</span><br><span class="line"> following User[] @relation("UserFollows")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> @@ -243,7 +243,7 @@ <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> followedBy Follows[] @relation("followedBy")</span><br><span class="line"> following Follows[] @relation("following")</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">model Follows {</span><br><span class="line"> followedBy User @relation("followedBy", fields: [followedById], references: [id])</span><br><span class="line"> followedById Int</span><br><span class="line"> following User @relation("following", fields: [followingId], references: [id])</span><br><span class="line"> followingId Int</span><br><span class="line"></span><br><span class="line"> @@id([followingId, followedById])</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <p>在关系型数据库中,可以用如下 SQL 描述:</p> -<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id <span class="type">integer</span> <span class="keyword">DEFAULT</span> nextval(<span class="string">'"User_id_seq"'</span>::regclass) <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> name text</span><br><span class="line">);</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "_UserFollows" (</span><br><span class="line"> "A" <span class="type">integer</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE,</span><br><span class="line"> "B" <span class="type">integer</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE</span><br><span class="line">);</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id <span class="type">integer</span> <span class="keyword">DEFAULT</span> nextval(<span class="string">'"User_id_seq"'</span>::regclass) <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> name text</span><br><span class="line">);</span><br><span class="line"><span class="keyword">CREATE TABLE</span> "_UserFollows" (</span><br><span class="line"> "A" <span class="type">integer</span> <span class="keyword">NOT NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE,</span><br><span class="line"> "B" <span class="type">integer</span> <span class="keyword">NOT NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE</span><br><span class="line">);</span><br></pre></td></tr></table></figure> <h2 id="在同一模型上建立多个-self-relations"><a href="#在同一模型上建立多个-self-relations" class="headerlink" title="在同一模型上建立多个 self-relations"></a>在同一模型上建立多个 self-relations</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> teacherId Int?</span><br><span class="line"> teacher User? @relation("TeacherStudents", fields: [teacherId], references: [id])</span><br><span class="line"> students User[] @relation("TeacherStudents")</span><br><span class="line"> followedBy User[] @relation("UserFollows")</span><br><span class="line"> following User[] @relation("UserFollows")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> diff --git a/2025/02/19/Repository-pattern-in-Typescript/index.html b/2025/02/19/Repository-pattern-in-Typescript/index.html index bdd29669..d5509d8e 100644 --- a/2025/02/19/Repository-pattern-in-Typescript/index.html +++ b/2025/02/19/Repository-pattern-in-Typescript/index.html @@ -217,10 +217,10 @@ <li><code>IGenericRepository</code> 中定义的函数是每个 <em>Repository</em> 公开的通用存储函数。</li> </ul> <p>以上这些就是对业务中的实体的 <em>Repository</em> 抽象,这样就隔离开了业务和存储逻辑,例如使用 MongoDB,可以实现一个 <code>MongoGenericRepository</code>:</p> -<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IGenericRepository</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoGenericRepository</span><T> <span class="keyword">implements</span> <span class="title class_">IGenericRepository</span><T> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_repository</span>: <span class="title class_">Model</span><T>;</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_populateOnFind</span>: <span class="built_in">string</span>[];</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">repository: Model<T>, populateOnFind: <span class="built_in">string</span>[] = []</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_repository</span> = repository;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_populateOnFind</span> = populateOnFind;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">getAll</span>(): <span class="title class_">Promise</span><T[]> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">find</span>().<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">get</span>(<span class="attr">id</span>: <span class="built_in">any</span>): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findById</span>(id).<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">create</span>(<span class="attr">item</span>: T): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">create</span>(item);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">update</span>(<span class="params">id: <span class="built_in">string</span>, item: T</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findByIdAndUpdate</span>(id, item);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IGenericRepository</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoGenericRepository</span><T> <span class="keyword">implements</span> <span class="title class_">IGenericRepository</span><T> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_repository</span>: <span class="title class_">Model</span><T>;</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_populateOnFind</span>: <span class="built_in">string</span>[];</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"><span class="attr">repository</span>: <span class="title class_">Model</span><T>, <span class="attr">populateOnFind</span>: <span class="built_in">string</span>[] = []</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_repository</span> = repository;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_populateOnFind</span> = populateOnFind;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">getAll</span>(): <span class="title class_">Promise</span><T[]> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">find</span>().<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">get</span>(<span class="attr">id</span>: <span class="built_in">any</span>): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findById</span>(id).<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">create</span>(<span class="attr">item</span>: T): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">create</span>(item);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">update</span>(<span class="params"><span class="attr">id</span>: <span class="built_in">string</span>, <span class="attr">item</span>: T</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findByIdAndUpdate</span>(id, item);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <p>然后实现一个 <code>MongoDataServices</code>:</p> -<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Injectable</span>, <span class="title class_">OnApplicationBootstrap</span> } <span class="keyword">from</span> <span class="string">'@nestjs/common'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">InjectModel</span> } <span class="keyword">from</span> <span class="string">'@nestjs/mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IDataServices</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">MongoGenericRepository</span> } <span class="keyword">from</span> <span class="string">'./mongo-generic-repository'</span>;</span><br><span class="line"><span class="keyword">import</span> {</span><br><span class="line"> <span class="title class_">Author</span>,</span><br><span class="line"> <span class="title class_">AuthorDocument</span>,</span><br><span class="line"> <span class="title class_">Book</span>,</span><br><span class="line"> <span class="title class_">BookDocument</span>,</span><br><span class="line"> <span class="title class_">Genre</span>,</span><br><span class="line"> <span class="title class_">GenreDocument</span>,</span><br><span class="line">} <span class="keyword">from</span> <span class="string">'./model'</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Injectable</span>()</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoDataServices</span></span><br><span class="line"> <span class="keyword">implements</span> <span class="title class_">IDataServices</span>, <span class="title class_">OnApplicationBootstrap</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">authors</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>;</span><br><span class="line"> <span class="attr">books</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>;</span><br><span class="line"> <span class="attr">genres</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Author.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> AuthorRepository: Model<AuthorDocument>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Book.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> BookRepository: Model<BookDocument>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Genre.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> GenreRepository: Model<GenreDocument>,</span></span><br><span class="line"><span class="params"> </span>) {}</span><br><span class="line"></span><br><span class="line"> <span class="title function_">onApplicationBootstrap</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">authors</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>(<span class="variable language_">this</span>.<span class="property">AuthorRepository</span>);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">books</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>(<span class="variable language_">this</span>.<span class="property">BookRepository</span>, [</span><br><span class="line"> <span class="string">'author'</span>,</span><br><span class="line"> <span class="string">'genre'</span>,</span><br><span class="line"> ]);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">genres</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>(<span class="variable language_">this</span>.<span class="property">GenreRepository</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Injectable</span>, <span class="title class_">OnApplicationBootstrap</span> } <span class="keyword">from</span> <span class="string">'@nestjs/common'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">InjectModel</span> } <span class="keyword">from</span> <span class="string">'@nestjs/mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IDataServices</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">MongoGenericRepository</span> } <span class="keyword">from</span> <span class="string">'./mongo-generic-repository'</span>;</span><br><span class="line"><span class="keyword">import</span> {</span><br><span class="line"> <span class="title class_">Author</span>,</span><br><span class="line"> <span class="title class_">AuthorDocument</span>,</span><br><span class="line"> <span class="title class_">Book</span>,</span><br><span class="line"> <span class="title class_">BookDocument</span>,</span><br><span class="line"> <span class="title class_">Genre</span>,</span><br><span class="line"> <span class="title class_">GenreDocument</span>,</span><br><span class="line">} <span class="keyword">from</span> <span class="string">'./model'</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Injectable</span>()</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoDataServices</span></span><br><span class="line"> <span class="keyword">implements</span> <span class="title class_">IDataServices</span>, <span class="title class_">OnApplicationBootstrap</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">authors</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>;</span><br><span class="line"> <span class="attr">books</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>;</span><br><span class="line"> <span class="attr">genres</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Author.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">AuthorRepository</span>: <span class="title class_">Model</span><<span class="title class_">AuthorDocument</span>>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Book.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">BookRepository</span>: <span class="title class_">Model</span><<span class="title class_">BookDocument</span>>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Genre.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">GenreRepository</span>: <span class="title class_">Model</span><<span class="title class_">GenreDocument</span>>,</span></span><br><span class="line"><span class="params"> </span>) {}</span><br><span class="line"></span><br><span class="line"> <span class="title function_">onApplicationBootstrap</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">authors</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>(<span class="variable language_">this</span>.<span class="property">AuthorRepository</span>);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">books</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>(<span class="variable language_">this</span>.<span class="property">BookRepository</span>, [</span><br><span class="line"> <span class="string">'author'</span>,</span><br><span class="line"> <span class="string">'genre'</span>,</span><br><span class="line"> ]);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">genres</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>(<span class="variable language_">this</span>.<span class="property">GenreRepository</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <hr> <p>Sunday, March 30, 2025 7:58 PM:</p> diff --git a/2025/04/02/N-1-selects-problem-与-Prisma-ORM/index.html b/2025/04/02/N-1-selects-problem-与-Prisma-ORM/index.html index 2df41efe..ac98e832 100644 --- a/2025/04/02/N-1-selects-problem-与-Prisma-ORM/index.html +++ b/2025/04/02/N-1-selects-problem-与-Prisma-ORM/index.html @@ -211,7 +211,7 @@ </ol> <p>Prisma ORM 在设计上就考虑了 N+1 问题,并提供了一种既方便开发者又高效的解决方案。当使用 Prisma Client 查询数据并需要包含关联模型时,Prisma 会自动优化查询,<strong>避免产生 N+1 查询</strong>,主要通过<strong>关系查询(Relation Queries)</strong>中的 <code>include</code> 选项或嵌套读取(nested reads)来实现这一点:</p> <p>假设想获取所有用户及其发布的帖子,使用 Prisma Client,可以这样写:</p> -<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">PrismaClient</span> } <span class="keyword">from</span> <span class="string">'@prisma/client'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> prisma = <span class="keyword">new</span> <span class="title class_">PrismaClient</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getUsersWithPosts</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> usersWithPosts = <span class="keyword">await</span> prisma.<span class="property">user</span>.<span class="title function_">findMany</span>({</span><br><span class="line"> <span class="attr">include</span>: {</span><br><span class="line"> <span class="attr">posts</span>: <span class="literal">true</span>, <span class="comment">// 指示 Prisma 加载关联的 posts</span></span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line"> <span class="comment">// usersWithPosts 包含了用户列表,每个用户对象中都有一个 posts 数组</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(usersWithPosts)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getUsersWithPosts</span>()</span><br><span class="line"> .<span class="title function_">catch</span>(<span class="function">(<span class="params">e</span>) =></span> {</span><br><span class="line"> <span class="keyword">throw</span> e</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">finally</span>(<span class="keyword">async</span> () => {</span><br><span class="line"> <span class="keyword">await</span> prisma.$disconnect()</span><br><span class="line"> })</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">PrismaClient</span> } <span class="keyword">from</span> <span class="string">'@prisma/client'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> prisma = <span class="keyword">new</span> <span class="title class_">PrismaClient</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getUsersWithPosts</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> usersWithPosts = <span class="keyword">await</span> prisma.<span class="property">user</span>.<span class="title function_">findMany</span>({</span><br><span class="line"> <span class="attr">include</span>: {</span><br><span class="line"> <span class="attr">posts</span>: <span class="literal">true</span>, <span class="comment">// 指示 Prisma 加载关联的 posts</span></span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line"> <span class="comment">// usersWithPosts 包含了用户列表,每个用户对象中都有一个 posts 数组</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(usersWithPosts)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getUsersWithPosts</span>()</span><br><span class="line"> .<span class="title function_">catch</span>(<span class="function">(<span class="params">e</span>) =></span> {</span><br><span class="line"> <span class="keyword">throw</span> e</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">finally</span>(<span class="title function_">async</span> () => {</span><br><span class="line"> <span class="keyword">await</span> prisma.$disconnect()</span><br><span class="line"> })</span><br></pre></td></tr></table></figure> <p>当执行上述查询时,Prisma <strong>不会</strong> 生成 N+1 个 SQL 查询。而是首先会分析请求,并将其转化为数量非常有限的高效 SQL 查询。对于上面这个一对多关系的 <code>include</code> 查询,Prisma 通常会执行以下<strong>两步</strong>(类似于批量加载策略):</p> <ol> @@ -234,6 +234,11 @@ <nav class="post-nav"> <div class="prev-item"> + <div class="icon arrow-left"></div> + <div class="post-link"> + <a href="/2025/04/13/uuidv7-rdbms/">Prev</a> + </div> + </div> <div class="next-item"> diff --git a/2025/04/13/uuidv7-rdbms/index.html b/2025/04/13/uuidv7-rdbms/index.html new file mode 100644 index 00000000..1a8b513a --- /dev/null +++ b/2025/04/13/uuidv7-rdbms/index.html @@ -0,0 +1,308 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> +<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> +<meta http-equiv="X-UA-Compatible" content="ie=edge"> + + <meta name="author" content="韩暮秋"> + + + <meta name="subtitle" content="暮秋小屋"> + + + <meta name="description" content="这里是暮秋小屋,思念和灵感的寄存处"> + + + <meta name="keywords" content="韩暮秋,MuqiuHan,'Muqiu Han', 'muqiu han', muqiuhan"> + + + + + <title> + + UUID v7 是如何加快 RDBMS 索引速度的 | + 暮秋小屋 + </title> + + + + <link rel="icon" href="/favicon.ico"> + + + <style> + @font-face { + font-family: CarroisSong; + src: url('/fonts/CarroisSong.ttf'); + } + </style> + + + + <!-- stylesheets list from _config.yml --> + + <link rel="stylesheet" href="/css/style.css"> + + + + + + <!-- scripts list from _config.yml --> + + <script + src="/js/menu.js"></script> + + + + + + <script + src="https://polyfill.alicdn.com/polyfill.js?features=es6"></script> + <script + id="MathJax-script" + async + src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/mathjax/3.2.0/es5/tex-mml-chtml.js"></script> + + + + + <meta name="generator" content="Hexo 6.3.0"></head> + <body> + <div class="mask-border"> + </div> + + <div class="wrapper"> + + <div class="header"> + <div class="flex-container"> + <div class="header-inner"> + <div class="site-brand-container"> + <a href="/"> + + 暮秋小屋 + + </a> + </div> + <div id="menu-btn" class="menu-btn" onclick="toggleMenu()"> + Menu + </div> + <nav class="site-nav"> + <ul class="menu-list"> + + + <li class="menu-item"> + <a href="/"> + 主页 + </a> + </li> + + + + <li class="menu-item"> + <a href="/categories/gallery/"> + 日记本 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Medicine/"> + 医学 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Technique/"> + 计算机/互联网 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Life/"> + 生活 + </a> + </li> + + + + <li class="menu-item"> + <a href="/archives"> + 全部 + </a> + </li> + + + + <li class="menu-item"> + <a href="/about"> + 关于 + </a> + </li> + + + + <li class="menu-item search-btn"> + <a href="#">Search</a> + </li> + + </ul> + </nav> + </div> + </div> +</div> + + <div class="main"> + <div class="flex-container"> + <article id="post"> + + + <div class="post-head"> + <div class="post-info"> + <div class="tag-list"> + + + <span class="post-tag"> + <a href="/tags/Technique/"> + Technique + </a> + </span> + + + </div> + <div class="post-title"> + + + UUID v7 是如何加快 RDBMS 索引速度的 + + + </div> + <span class="post-date"> + Apr 13, 2025 + </span> + </div> + <div class="post-img"> + + <div class="h-line-primary"></div> + + </div> +</div> + <div class="post-content"> + <p>UUID v7 之所以能显著提升关系型数据库(尤其是采用聚集索引的 MySQL InnoDB)在插入和查询速度,主要归功于它在 ID 中引入了“可排序的时间戳前缀”,从而大幅减少了 B-Tree 索引页分裂(page split)和数据碎片化。这里分几点来说:</p> +<p>一、 聚集索引(Clustered Index)的插入机制 </p> +<p>在 InnoDB 中,聚集索引的叶子节点同时存储了行数据,且按照索引键(主键)顺序物理排序。</p> +<p>当新记录的主键完全随机(如 UUID v4)时,每次插入都会随机落在 B-Tree 的不同叶子页,导致频繁的页分裂和指针重排,而页分裂和随机 I/O 会带来大量的磁盘写放大和缓存抖动(cache churn),削弱吞吐并拉高延迟。</p> +<p>二、UUID v7 的时间排序特性 </p> +<p>UUID v7 在高位(前 48 位)嵌入了以毫秒级精度的 Unix 时间戳,剩下的位用于随机数或序列号,这样生成的 ID 保持全局唯一性的同时,随着时间自然递增(即“近似单调递增”),新插入的记录几乎总是追加到 B-Tree 的最右端叶子节点。 </p> +<p>参见 dbaplus.cn 的分析: </p> +<blockquote> +<p>“UUID v7 的创新之处在于其时间排序特性,它在前 48 位中嵌入了以毫秒为单位的 Unix 时间戳……可能在插入和查询操作上提供更好的性能”【1】。</p> +</blockquote> +<p>三、降低页分裂与碎片化 </p> +<p>顺序或近似顺序的主键能使叶子节点连续增长,极少触发页分裂,并且更少的页分裂意味着更低的写放大(write amplification)和更稳定的插入延迟,同时,减少了空洞和链表重排,提高了磁盘和内存缓存的命中率。</p> +<p>四、提升查询局部性与缓存命中 </p> +<p>因为数据物理上是按时间顺序紧凑写入,时间范围查询(如 “最近 1 小时的日志”)可以快速定位连续的叶子页,I/O 更聚集,内存缓冲池(buffer pool)或操作系统页缓存能更有效地缓存最近热数据,进一步加速查询。</p> +<hr> +<p>Rimon Tawadrous 在其 GitHub repo 中的测试,对比 100 万条逐条插入实验,UUID v7 相较 UUID v4 在单线程插入上速度快约 3.24%,多线程下更可观【1】。 </p> +<hr> +<p><strong>参考链接</strong><br>[1] “为什么 UUID 7 比 UUID 4 更适合作为 RDBMS 的聚集索引?” dbaplus.cn<br> <a target="_blank" rel="noopener" href="https://dbaplus.cn/news-160-6313-1.html">https://dbaplus.cn/news-160-6313-1.html</a><br>[2] “PostgreSQL and UUID as primary key” maciejwalkowiak<br> <a target="_blank" rel="noopener" href="https://maciejwalkowiak.com/blog/postgres-uuid-primary-key/">https://maciejwalkowiak.com/blog/postgres-uuid-primary-key/</a><br>[3] “Optimised UUIDs in mysql” stitcher<br> <a target="_blank" rel="noopener" href="https://stitcher.io/blog/optimised-uuids-in-mysql">https://stitcher.io/blog/optimised-uuids-in-mysql</a><br>[3] “Storing UUID Values in MySQL” percona<br> <a target="_blank" rel="noopener" href="https://www.percona.com/blog/store-uuid-optimized-way/">https://www.percona.com/blog/store-uuid-optimized-way/</a></p> + +</div> + +<script> + window.onload = detectors(); +</script> + <div class="post-footer"> + <div class="h-line-primary"></div> + <nav class="post-nav"> + <div class="prev-item"> + + <div class="icon arrow-left"></div> + <div class="post-link"> + <a href="/2025/04/20/linux-amd-screen-boom/">Prev</a> + </div> + + </div> + <div class="next-item"> + + <div class="icon arrow-right"></div> + <div class="post-link"> + <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/">Next</a> + </div> + + </div> + </nav> +</div> + + + <div class="post-comment"> + + + + + + + +</div> + + +</article> + </div> + </div> + + <div class="footer"> + <div class="flex-container"> + <div class="footer-text"> + + + 韩暮秋 | + + + 希望路过的人可以添点柴火让这里暖和点 + + </div> + </div> +</div> + + </div> + + + <div class="search-popup"> + <div class="search-popup-overlay"> + </div> + <div class="search-popup-window" > + <div class="search-header"> + <div class="search-input-container"> + <input autocomplete="off" autocapitalize="off" maxlength="80" + placeholder="Search Anything" spellcheck="false" + type="search" class="search-input"> + </div> + <div class="search-close-btn"> + <div class="icon close-btn"></div> + </div> + </div> + <div class="search-result-container"> + </div> + </div> +</div> + +<script> + const searchConfig = { + path : "/search.xml", + top_n_per_article: "1", + unescape : "false", + trigger: "auto", + preload: "false" + } +</script> +<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/search.js"></script> +<script src="/js/search.js"></script> + + + + </body> +</html> diff --git a/2025/04/20/linux-amd-screen-boom/index.html b/2025/04/20/linux-amd-screen-boom/index.html new file mode 100644 index 00000000..f47c1744 --- /dev/null +++ b/2025/04/20/linux-amd-screen-boom/index.html @@ -0,0 +1,290 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> +<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> +<meta http-equiv="X-UA-Compatible" content="ie=edge"> + + <meta name="author" content="韩暮秋"> + + + <meta name="subtitle" content="暮秋小屋"> + + + <meta name="description" content="这里是暮秋小屋,思念和灵感的寄存处"> + + + <meta name="keywords" content="韩暮秋,MuqiuHan,'Muqiu Han', 'muqiu han', muqiuhan"> + + + + + <title> + + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 | + 暮秋小屋 + </title> + + + + <link rel="icon" href="/favicon.ico"> + + + <style> + @font-face { + font-family: CarroisSong; + src: url('/fonts/CarroisSong.ttf'); + } + </style> + + + + <!-- stylesheets list from _config.yml --> + + <link rel="stylesheet" href="/css/style.css"> + + + + + + <!-- scripts list from _config.yml --> + + <script + src="/js/menu.js"></script> + + + + + + <script + src="https://polyfill.alicdn.com/polyfill.js?features=es6"></script> + <script + id="MathJax-script" + async + src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/mathjax/3.2.0/es5/tex-mml-chtml.js"></script> + + + + + <meta name="generator" content="Hexo 6.3.0"></head> + <body> + <div class="mask-border"> + </div> + + <div class="wrapper"> + + <div class="header"> + <div class="flex-container"> + <div class="header-inner"> + <div class="site-brand-container"> + <a href="/"> + + 暮秋小屋 + + </a> + </div> + <div id="menu-btn" class="menu-btn" onclick="toggleMenu()"> + Menu + </div> + <nav class="site-nav"> + <ul class="menu-list"> + + + <li class="menu-item"> + <a href="/"> + 主页 + </a> + </li> + + + + <li class="menu-item"> + <a href="/categories/gallery/"> + 日记本 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Medicine/"> + 医学 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Technique/"> + 计算机/互联网 + </a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Life/"> + 生活 + </a> + </li> + + + + <li class="menu-item"> + <a href="/archives"> + 全部 + </a> + </li> + + + + <li class="menu-item"> + <a href="/about"> + 关于 + </a> + </li> + + + + <li class="menu-item search-btn"> + <a href="#">Search</a> + </li> + + </ul> + </nav> + </div> + </div> +</div> + + <div class="main"> + <div class="flex-container"> + <article id="post"> + + + <div class="post-head"> + <div class="post-info"> + <div class="tag-list"> + + + <span class="post-tag"> + <a href="/tags/Technique/"> + Technique + </a> + </span> + + + </div> + <div class="post-title"> + + + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 + + + </div> + <span class="post-date"> + Apr 20, 2025 + </span> + </div> + <div class="post-img"> + + <div class="h-line-primary"></div> + + </div> +</div> + <div class="post-content"> + <p>不知道我们所说的闪烁是不是一个东西,在我的笔记本上,闪烁是指偶发的屏幕中出现部分彩色雪花。</p> +<p>我使用 Pop!_OS,此发行版使用 EFI 启动,故而可以在 <code>/boot/efi/loader/loader.conf</code> 中加上:</p> +<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">options quiet splash amdgpu.dcdebugmask=0x10 amdgpu.sg_display=0</span><br></pre></td></tr></table></figure> + +<p>对于其他使用 EFI 或 GRUB 启动的发行版也可以添加类似的参数尝试尝试。</p> + +</div> + +<script> + window.onload = detectors(); +</script> + <div class="post-footer"> + <div class="h-line-primary"></div> + <nav class="post-nav"> + <div class="prev-item"> + + </div> + <div class="next-item"> + + <div class="icon arrow-right"></div> + <div class="post-link"> + <a href="/2025/04/13/uuidv7-rdbms/">Next</a> + </div> + + </div> + </nav> +</div> + + + <div class="post-comment"> + + + + + + + +</div> + + +</article> + </div> + </div> + + <div class="footer"> + <div class="flex-container"> + <div class="footer-text"> + + + 韩暮秋 | + + + 希望路过的人可以添点柴火让这里暖和点 + + </div> + </div> +</div> + + </div> + + + <div class="search-popup"> + <div class="search-popup-overlay"> + </div> + <div class="search-popup-window" > + <div class="search-header"> + <div class="search-input-container"> + <input autocomplete="off" autocapitalize="off" maxlength="80" + placeholder="Search Anything" spellcheck="false" + type="search" class="search-input"> + </div> + <div class="search-close-btn"> + <div class="icon close-btn"></div> + </div> + </div> + <div class="search-result-container"> + </div> + </div> +</div> + +<script> + const searchConfig = { + path : "/search.xml", + top_n_per_article: "1", + unescape : "false", + trigger: "auto", + preload: "false" + } +</script> +<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/search.js"></script> +<script src="/js/search.js"></script> + + + + </body> +</html> diff --git a/archives/2025/04/index.html b/archives/2025/04/index.html index dbf7518d..293893ea 100644 --- a/archives/2025/04/index.html +++ b/archives/2025/04/index.html @@ -170,6 +170,42 @@ <div class="post-list-item"> <div class="post-title"> + <a href="/2025/04/20/linux-amd-screen-boom/"> + + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 + + </a> + </div> + + <span class="post-date">Apr 20, 2025</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> + <a href="/2025/04/13/uuidv7-rdbms/"> + + UUID v7 是如何加快 RDBMS 索引速度的 + + </a> + </div> + + <span class="post-date">Apr 13, 2025</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> N+1 selects problem 与 Prisma ORM diff --git a/archives/2025/index.html b/archives/2025/index.html index 0a2062db..256a991f 100644 --- a/archives/2025/index.html +++ b/archives/2025/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> + <a href="/2025/04/20/linux-amd-screen-boom/"> - N+1 selects problem 与 Prisma ORM + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 </a> </div> - <span class="post-date">Apr 2, 2025</span> + <span class="post-date">Apr 20, 2025</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> + <a href="/2025/04/13/uuidv7-rdbms/"> - 在F#中处理复杂依赖注入的实践指南 + UUID v7 是如何加快 RDBMS 索引速度的 </a> </div> - <span class="post-date">Mar 31, 2025</span> + <span class="post-date">Apr 13, 2025</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> + <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> - F# 重载解析问题 + N+1 selects problem 与 Prisma ORM </a> </div> - <span class="post-date">Mar 30, 2025</span> + <span class="post-date">Apr 2, 2025</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/25/Scala-3-Capture-Checking/"> + <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> - Scala 3 (Capture Checking) + 在F#中处理复杂依赖注入的实践指南 </a> </div> - <span class="post-date">Mar 25, 2025</span> + <span class="post-date">Mar 31, 2025</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> + <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> - TDD 和 DDD 的一些小想法 + F# 重载解析问题 </a> </div> - <span class="post-date">Mar 20, 2025</span> + <span class="post-date">Mar 30, 2025</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/20/%E8%82%BA%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E6%95%B0%E5%80%BC/"> + <a href="/2025/03/25/Scala-3-Capture-Checking/"> - 肺功能检查数值 + Scala 3 (Capture Checking) </a> </div> - <span class="post-date">Mar 20, 2025</span> + <span class="post-date">Mar 25, 2025</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> + <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> - 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 + TDD 和 DDD 的一些小想法 </a> </div> - <span class="post-date">Mar 19, 2025</span> + <span class="post-date">Mar 20, 2025</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2025/03/20/%E8%82%BA%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E6%95%B0%E5%80%BC/"> - 二〇二五年三月十七日 + 肺功能检查数值 </a> </div> - <span class="post-date">Mar 17, 2025</span> + <span class="post-date">Mar 20, 2025</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> + <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> - DDD 中的 Ubiquitous Language + 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 </a> </div> - <span class="post-date">Mar 14, 2025</span> + <span class="post-date">Mar 19, 2025</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> + <a href="/2025/03/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> - 领域驱动设计中的“聚合根” + 二〇二五年三月十七日 </a> </div> - <span class="post-date">Mar 13, 2025</span> + <span class="post-date">Mar 17, 2025</span> </div> diff --git a/archives/2025/page/2/index.html b/archives/2025/page/2/index.html index 74eb9cdd..cd8d22fd 100644 --- a/archives/2025/page/2/index.html +++ b/archives/2025/page/2/index.html @@ -170,6 +170,42 @@ <div class="post-list-item"> <div class="post-title"> + <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> + + DDD 中的 Ubiquitous Language + + </a> + </div> + + <span class="post-date">Mar 14, 2025</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> + <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> + + 领域驱动设计中的“聚合根” + + </a> + </div> + + <span class="post-date">Mar 13, 2025</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> <a href="/2025/02/24/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%9B%9B%E6%97%A5/"> 二〇二五年二月二十四日 diff --git a/archives/index.html b/archives/index.html index 7ed7d818..b4a4a007 100644 --- a/archives/index.html +++ b/archives/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> + <a href="/2025/04/20/linux-amd-screen-boom/"> - N+1 selects problem 与 Prisma ORM + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 </a> </div> - <span class="post-date">Apr 2, 2025</span> + <span class="post-date">Apr 20, 2025</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> + <a href="/2025/04/13/uuidv7-rdbms/"> - 在F#中处理复杂依赖注入的实践指南 + UUID v7 是如何加快 RDBMS 索引速度的 </a> </div> - <span class="post-date">Mar 31, 2025</span> + <span class="post-date">Apr 13, 2025</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> + <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> - F# 重载解析问题 + N+1 selects problem 与 Prisma ORM </a> </div> - <span class="post-date">Mar 30, 2025</span> + <span class="post-date">Apr 2, 2025</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/25/Scala-3-Capture-Checking/"> + <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> - Scala 3 (Capture Checking) + 在F#中处理复杂依赖注入的实践指南 </a> </div> - <span class="post-date">Mar 25, 2025</span> + <span class="post-date">Mar 31, 2025</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> + <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> - TDD 和 DDD 的一些小想法 + F# 重载解析问题 </a> </div> - <span class="post-date">Mar 20, 2025</span> + <span class="post-date">Mar 30, 2025</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/20/%E8%82%BA%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E6%95%B0%E5%80%BC/"> + <a href="/2025/03/25/Scala-3-Capture-Checking/"> - 肺功能检查数值 + Scala 3 (Capture Checking) </a> </div> - <span class="post-date">Mar 20, 2025</span> + <span class="post-date">Mar 25, 2025</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> + <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> - 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 + TDD 和 DDD 的一些小想法 </a> </div> - <span class="post-date">Mar 19, 2025</span> + <span class="post-date">Mar 20, 2025</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2025/03/20/%E8%82%BA%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E6%95%B0%E5%80%BC/"> - 二〇二五年三月十七日 + 肺功能检查数值 </a> </div> - <span class="post-date">Mar 17, 2025</span> + <span class="post-date">Mar 20, 2025</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> + <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> - DDD 中的 Ubiquitous Language + 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 </a> </div> - <span class="post-date">Mar 14, 2025</span> + <span class="post-date">Mar 19, 2025</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> + <a href="/2025/03/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> - 领域驱动设计中的“聚合根” + 二〇二五年三月十七日 </a> </div> - <span class="post-date">Mar 13, 2025</span> + <span class="post-date">Mar 17, 2025</span> </div> diff --git a/archives/page/10/index.html b/archives/page/10/index.html index b08d7d6a..65a2eb9d 100644 --- a/archives/page/10/index.html +++ b/archives/page/10/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/05/02/Rust-Partial-%E8%AF%AD%E4%B9%89/"> + <a href="/2023/05/24/Rust-%E9%97%AD%E5%8C%85-lifetime-may-not-live-long-enough-%E9%97%AE%E9%A2%98/"> - Rust Partial 语义 + Rust 闭包 lifetime may not live long enough 问题 </a> </div> - <span class="post-date">May 2, 2023</span> + <span class="post-date">May 24, 2023</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/05/01/Rust-%E8%99%9A%E8%A1%A8%E5%B8%83%E5%B1%80%E8%A7%84%E5%88%99%E4%BB%8B%E7%BB%8D/"> + <a href="/2023/05/03/Rust-NewType-%E6%A8%A1%E5%BC%8F/"> - Rust 虚表布局规则介绍 + Rust NewType 模式 </a> </div> - <span class="post-date">May 1, 2023</span> + <span class="post-date">May 3, 2023</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/"> + <a href="/2023/05/02/Rust-Partial-%E8%AF%AD%E4%B9%89/"> - TypeScript With Rust Errors, No Try Catch, Heresy + Rust Partial 语义 </a> </div> - <span class="post-date">Apr 30, 2023</span> + <span class="post-date">May 2, 2023</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/04/25/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%9B%9B%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%94%E6%97%A5/"> + <a href="/2023/05/01/Rust-%E8%99%9A%E8%A1%A8%E5%B8%83%E5%B1%80%E8%A7%84%E5%88%99%E4%BB%8B%E7%BB%8D/"> - 二零二三年四月二十五日 + Rust 虚表布局规则介绍 </a> </div> - <span class="post-date">Apr 25, 2023</span> + <span class="post-date">May 1, 2023</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/04/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%9B%9B%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> + <a href="/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/"> - 二零二三年四月二十二日 + TypeScript With Rust Errors, No Try Catch, Heresy </a> </div> - <span class="post-date">Apr 22, 2023</span> + <span class="post-date">Apr 30, 2023</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/14/%E8%9E%BA%E5%86%85%E9%85%AF%E7%89%87/"> + <a href="/2023/04/25/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%9B%9B%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%94%E6%97%A5/"> - 螺内酯片 + 二零二三年四月二十五日 </a> </div> - <span class="post-date">Mar 14, 2023</span> + <span class="post-date">Apr 25, 2023</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/14/%E5%91%8B%E5%A1%9E%E7%B1%B3/"> + <a href="/2023/04/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%9B%9B%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> - 呋塞米 + 二零二三年四月二十二日 </a> </div> - <span class="post-date">Mar 14, 2023</span> + <span class="post-date">Apr 22, 2023</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/13/%E6%9B%BF%E7%B1%B3%E6%B2%99%E5%9D%A6/"> + <a href="/2023/03/14/%E8%9E%BA%E5%86%85%E9%85%AF%E7%89%87/"> - 替米沙坦 + 螺内酯片 </a> </div> - <span class="post-date">Mar 13, 2023</span> + <span class="post-date">Mar 14, 2023</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/05/%E5%A5%A5%E5%8F%B8%E4%BB%96%E9%9F%A6/"> + <a href="/2023/03/14/%E5%91%8B%E5%A1%9E%E7%B1%B3/"> - 奥司他韦 + 呋塞米 </a> </div> - <span class="post-date">Mar 5, 2023</span> + <span class="post-date">Mar 14, 2023</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/04/%E9%87%91%E5%8C%AE%E8%A6%81%E7%95%A5/"> + <a href="/2023/03/13/%E6%9B%BF%E7%B1%B3%E6%B2%99%E5%9D%A6/"> - 金匮要略 + 替米沙坦 </a> </div> - <span class="post-date">Mar 4, 2023</span> + <span class="post-date">Mar 13, 2023</span> </div> diff --git a/archives/page/11/index.html b/archives/page/11/index.html index c61e91d5..80f77a73 100644 --- a/archives/page/11/index.html +++ b/archives/page/11/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/01/%E6%B0%94%E8%83%B8/"> + <a href="/2023/03/05/%E5%A5%A5%E5%8F%B8%E4%BB%96%E9%9F%A6/"> - 气胸 + 奥司他韦 </a> </div> - <span class="post-date">Mar 1, 2023</span> + <span class="post-date">Mar 5, 2023</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/03/01/%E7%BA%AF%E7%89%9B%E5%A5%B6%E5%8F%AF%E4%BB%A5%E5%8A%A0%E7%82%B9%E5%95%A5/"> + <a href="/2023/03/04/%E9%87%91%E5%8C%AE%E8%A6%81%E7%95%A5/"> - 纯牛奶可以加点啥 + 金匮要略 </a> </div> - <span class="post-date">Mar 1, 2023</span> + <span class="post-date">Mar 4, 2023</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/26/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%85%AD%E6%97%A5/"> + <a href="/2023/03/01/%E6%B0%94%E8%83%B8/"> - 二零二三年二月二十六日 + 气胸 </a> </div> - <span class="post-date">Feb 26, 2023</span> + <span class="post-date">Mar 1, 2023</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/25/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%94%E6%97%A5/"> + <a href="/2023/03/01/%E7%BA%AF%E7%89%9B%E5%A5%B6%E5%8F%AF%E4%BB%A5%E5%8A%A0%E7%82%B9%E5%95%A5/"> - 二零二三年二月二十五日 + 纯牛奶可以加点啥 </a> </div> - <span class="post-date">Feb 25, 2023</span> + <span class="post-date">Mar 1, 2023</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/24/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%9B%9B%E6%97%A5/"> + <a href="/2023/02/26/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%85%AD%E6%97%A5/"> - 二零二三年二月二十四日 + 二零二三年二月二十六日 </a> </div> - <span class="post-date">Feb 24, 2023</span> + <span class="post-date">Feb 26, 2023</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> + <a href="/2023/02/25/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%94%E6%97%A5/"> - 二零二三年二月二十二日 + 二零二三年二月二十五日 </a> </div> - <span class="post-date">Feb 22, 2023</span> + <span class="post-date">Feb 25, 2023</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/02/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/"> + <a href="/2023/02/24/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%9B%9B%E6%97%A5/"> - 二零二三年二月二日 + 二零二三年二月二十四日 </a> </div> - <span class="post-date">Feb 2, 2023</span> + <span class="post-date">Feb 24, 2023</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/02/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2023/02/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> - 二零二三年二月一日 + 二零二三年二月二十二日 </a> </div> - <span class="post-date">Feb 1, 2023</span> + <span class="post-date">Feb 22, 2023</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/01/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> + <a href="/2023/02/02/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/"> - 二零二三年一月二十一日 + 二零二三年二月二日 </a> </div> - <span class="post-date">Jan 21, 2023</span> + <span class="post-date">Feb 2, 2023</span> </div> @@ -329,19 +329,17 @@ - <div class="year-title">2022</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2022/12/31/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%B8%89%E5%8D%81%E4%B8%80%E6%97%A5/"> + <a href="/2023/02/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%B8%80%E6%97%A5/"> - 二零二二年十二月三十一日 + 二零二三年二月一日 </a> </div> - <span class="post-date">Dec 31, 2022</span> + <span class="post-date">Feb 1, 2023</span> </div> diff --git a/archives/page/12/index.html b/archives/page/12/index.html index 9d8b1585..68a529e3 100644 --- a/archives/page/12/index.html +++ b/archives/page/12/index.html @@ -165,19 +165,19 @@ - <div class="year-title">2022</div> + <div class="year-title">2023</div> <div class="post-list-item"> <div class="post-title"> - <a href="/2022/11/03/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E6%9C%88%E4%B8%89%E6%97%A5/"> + <a href="/2023/01/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> - 二零二二年十一月月三日 + 二零二三年一月二十一日 </a> </div> - <span class="post-date">Nov 3, 2022</span> + <span class="post-date">Jan 21, 2023</span> </div> @@ -185,17 +185,19 @@ + <div class="year-title">2022</div> + <div class="post-list-item"> <div class="post-title"> - <a href="/2022/10/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2022/12/31/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%B8%89%E5%8D%81%E4%B8%80%E6%97%A5/"> - 二零二二年十月一日 + 二零二二年十二月三十一日 </a> </div> - <span class="post-date">Oct 1, 2022</span> + <span class="post-date">Dec 31, 2022</span> </div> @@ -206,14 +208,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2022/09/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B9%9D%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> + <a href="/2022/11/03/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E6%9C%88%E4%B8%89%E6%97%A5/"> - 二零二二年九月二十二日 + 二零二二年十一月月三日 </a> </div> - <span class="post-date">Sep 22, 2022</span> + <span class="post-date">Nov 3, 2022</span> </div> @@ -224,14 +226,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2022/08/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> + <a href="/2022/10/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%8D%81%E6%9C%88%E4%B8%80%E6%97%A5/"> - 二零二二年八月二十一日 + 二零二二年十月一日 </a> </div> - <span class="post-date">Aug 21, 2022</span> + <span class="post-date">Oct 1, 2022</span> </div> @@ -242,14 +244,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2022/03/14/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E5%9B%9B%E6%97%A5/"> + <a href="/2022/09/22/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B9%9D%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> - 二零二二年三月十四日 + 二零二二年九月二十二日 </a> </div> - <span class="post-date">Mar 14, 2022</span> + <span class="post-date">Sep 22, 2022</span> </div> @@ -260,14 +262,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2022/01/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%80%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2022/08/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> - 二零二二年一月一日 + 二零二二年八月二十一日 </a> </div> - <span class="post-date">Jan 1, 2022</span> + <span class="post-date">Aug 21, 2022</span> </div> @@ -275,19 +277,17 @@ - <div class="year-title">2021</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2021/03/27/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%B8%89%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2022/03/14/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E5%9B%9B%E6%97%A5/"> - 二零二一年三月二十七日 + 二零二二年三月十四日 </a> </div> - <span class="post-date">Mar 27, 2021</span> + <span class="post-date">Mar 14, 2022</span> </div> @@ -298,14 +298,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2021/03/15/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%BA%94%E6%97%A5/"> + <a href="/2022/01/01/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%80%E6%9C%88%E4%B8%80%E6%97%A5/"> - 二零二一年三月十五日 + 二零二二年一月一日 </a> </div> - <span class="post-date">Mar 15, 2021</span> + <span class="post-date">Jan 1, 2022</span> </div> @@ -313,17 +313,19 @@ + <div class="year-title">2021</div> + <div class="post-list-item"> <div class="post-title"> - <a href="/2021/02/16/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%BA%8C%E6%9C%88%E5%8D%81%E5%85%AD%E6%97%A5/"> + <a href="/2021/03/27/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%B8%89%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> - 二零二一年二月十六日 + 二零二一年三月二十七日 </a> </div> - <span class="post-date">Feb 16, 2021</span> + <span class="post-date">Mar 27, 2021</span> </div> @@ -334,14 +336,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2021/02/14/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%BA%8C%E6%9C%88%E5%8D%81%E5%9B%9B%E6%97%A5/"> + <a href="/2021/03/15/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%BA%94%E6%97%A5/"> - 二零二一年二月十四日 + 二零二一年三月十五日 </a> </div> - <span class="post-date">Feb 14, 2021</span> + <span class="post-date">Mar 15, 2021</span> </div> diff --git a/archives/page/13/index.html b/archives/page/13/index.html index 9ef36846..95bd1e55 100644 --- a/archives/page/13/index.html +++ b/archives/page/13/index.html @@ -165,6 +165,44 @@ + <div class="year-title">2021</div> + + + <div class="post-list-item"> + <div class="post-title"> + <a href="/2021/02/16/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%BA%8C%E6%9C%88%E5%8D%81%E5%85%AD%E6%97%A5/"> + + 二零二一年二月十六日 + + </a> + </div> + + <span class="post-date">Feb 16, 2021</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> + <a href="/2021/02/14/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%80%E5%B9%B4%E4%BA%8C%E6%9C%88%E5%8D%81%E5%9B%9B%E6%97%A5/"> + + 二零二一年二月十四日 + + </a> + </div> + + <span class="post-date">Feb 14, 2021</span> + </div> + + + + + + <div class="year-title">2020</div> diff --git a/archives/page/2/index.html b/archives/page/2/index.html index 3a712ed5..be97260c 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/24/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%9B%9B%E6%97%A5/"> + <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> - 二〇二五年二月二十四日 + DDD 中的 Ubiquitous Language </a> </div> - <span class="post-date">Feb 24, 2025</span> + <span class="post-date">Mar 14, 2025</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/19/Repository-pattern-in-Typescript/"> + <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> - Repository pattern in Typescript + 领域驱动设计中的“聚合根” </a> </div> - <span class="post-date">Feb 19, 2025</span> + <span class="post-date">Mar 13, 2025</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/18/Prisma-%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84-Self-relations/"> + <a href="/2025/02/24/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%BA%8C%E5%8D%81%E5%9B%9B%E6%97%A5/"> - Prisma 关系型数据库的 Self-relations + 二〇二五年二月二十四日 </a> </div> - <span class="post-date">Feb 18, 2025</span> + <span class="post-date">Feb 24, 2025</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/11/%E4%BB%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E7%9C%8B%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/"> + <a href="/2025/02/19/Repository-pattern-in-Typescript/"> - 从事件风暴看领域驱动设计 + Repository pattern in Typescript </a> </div> - <span class="post-date">Feb 11, 2025</span> + <span class="post-date">Feb 19, 2025</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/10/%E5%AE%9E%E6%97%B6%E6%90%9C%E7%B4%A2%E4%B8%AD%E7%9A%84%E9%98%B2%E6%8A%96%E5%87%BD%E6%95%B0/"> + <a href="/2025/02/18/Prisma-%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84-Self-relations/"> - 实时搜索中的防抖函数 + Prisma 关系型数据库的 Self-relations </a> </div> - <span class="post-date">Feb 10, 2025</span> + <span class="post-date">Feb 18, 2025</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/01/19/%E8%BA%AB%E4%BD%93%E5%BE%80%E5%89%8D%E5%80%BE%EF%BC%8C%E7%81%B5%E9%AD%82%E5%90%91%E5%90%8E%E6%91%87/"> + <a href="/2025/02/11/%E4%BB%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E7%9C%8B%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/"> - 身体往前倾,灵魂向后摇 + 从事件风暴看领域驱动设计 </a> </div> - <span class="post-date">Jan 19, 2025</span> + <span class="post-date">Feb 11, 2025</span> </div> @@ -275,19 +275,17 @@ - <div class="year-title">2024</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2024/12/18/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E5%8D%81%E5%85%AB%E6%97%A5/"> + <a href="/2025/02/10/%E5%AE%9E%E6%97%B6%E6%90%9C%E7%B4%A2%E4%B8%AD%E7%9A%84%E9%98%B2%E6%8A%96%E5%87%BD%E6%95%B0/"> - 二〇二四年十二月十八日 + 实时搜索中的防抖函数 </a> </div> - <span class="post-date">Dec 18, 2024</span> + <span class="post-date">Feb 10, 2025</span> </div> @@ -298,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/12/15/OCaml-News-2024-7/"> + <a href="/2025/01/19/%E8%BA%AB%E4%BD%93%E5%BE%80%E5%89%8D%E5%80%BE%EF%BC%8C%E7%81%B5%E9%AD%82%E5%90%91%E5%90%8E%E6%91%87/"> - OCaml News 2024-7 + 身体往前倾,灵魂向后摇 </a> </div> - <span class="post-date">Dec 15, 2024</span> + <span class="post-date">Jan 19, 2025</span> </div> @@ -313,17 +311,19 @@ + <div class="year-title">2024</div> + <div class="post-list-item"> <div class="post-title"> - <a href="/2024/11/26/%E5%A6%82%E4%BD%95%E7%AE%A1%E7%90%86%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E4%B8%AD%E7%9A%84%E5%8D%B1%E9%99%A9%E6%93%8D%E4%BD%9C/"> + <a href="/2024/12/18/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E5%8D%81%E5%85%AB%E6%97%A5/"> - 如何管理用户界面中的危险操作 + 二〇二四年十二月十八日 </a> </div> - <span class="post-date">Nov 26, 2024</span> + <span class="post-date">Dec 18, 2024</span> </div> @@ -334,14 +334,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/11/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2024/12/15/OCaml-News-2024-7/"> - 二〇二四年十一月十七日 + OCaml News 2024-7 </a> </div> - <span class="post-date">Nov 17, 2024</span> + <span class="post-date">Dec 15, 2024</span> </div> diff --git a/archives/page/3/index.html b/archives/page/3/index.html index 5ff89594..21724a78 100644 --- a/archives/page/3/index.html +++ b/archives/page/3/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/11/15/%E8%A5%BF%E6%9F%9A%E5%AF%B9%E8%8D%AF%E7%89%A9%E7%9A%84%E5%BD%B1%E5%93%8D/"> + <a href="/2024/11/26/%E5%A6%82%E4%BD%95%E7%AE%A1%E7%90%86%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E4%B8%AD%E7%9A%84%E5%8D%B1%E9%99%A9%E6%93%8D%E4%BD%9C/"> - 西柚对药物的影响 + 如何管理用户界面中的危险操作 </a> </div> - <span class="post-date">Nov 15, 2024</span> + <span class="post-date">Nov 26, 2024</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/10-Tips-for-Productive-FSharp-Scripting/"> + <a href="/2024/11/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/"> - 10 Tips for Productive FSharp Scripting + 二〇二四年十一月十七日 </a> </div> - <span class="post-date">Oct 18, 2024</span> + <span class="post-date">Nov 17, 2024</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/Building-custom-fibers-library-in-FSharp/"> + <a href="/2024/11/15/%E8%A5%BF%E6%9F%9A%E5%AF%B9%E8%8D%AF%E7%89%A9%E7%9A%84%E5%BD%B1%E5%93%8D/"> - Building custom fibers library in FSharp + 西柚对药物的影响 </a> </div> - <span class="post-date">Oct 18, 2024</span> + <span class="post-date">Nov 15, 2024</span> </div> @@ -224,9 +224,9 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/Dealing-with-complex-dependency-injection-in-FSharp/"> + <a href="/2024/10/18/10-Tips-for-Productive-FSharp-Scripting/"> - Dealing with complex dependency injection in FSharp + 10 Tips for Productive FSharp Scripting </a> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/06/Obsidian-Vault-%E7%9A%84-obsidian-%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%90%84%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8/"> + <a href="/2024/10/18/Building-custom-fibers-library-in-FSharp/"> - Obsidian Vault 的 .obsidian 目录中的各文件作用 + Building custom fibers library in FSharp </a> </div> - <span class="post-date">Oct 6, 2024</span> + <span class="post-date">Oct 18, 2024</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/27/Turborepo-%E7%AE%80%E8%BF%B0/"> + <a href="/2024/10/18/Dealing-with-complex-dependency-injection-in-FSharp/"> - Turborepo 简述 + Dealing with complex dependency injection in FSharp </a> </div> - <span class="post-date">Sep 27, 2024</span> + <span class="post-date">Oct 18, 2024</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/15/%E8%82%A9%E5%91%A8%E7%82%8E%E5%92%8C%E8%82%A9%E8%A2%96%E6%8D%9F%E4%BC%A4%E7%9A%84%E5%8C%BA%E5%88%AB/"> + <a href="/2024/10/06/Obsidian-Vault-%E7%9A%84-obsidian-%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%90%84%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8/"> - 肩周炎和肩袖损伤的区别 + Obsidian Vault 的 .obsidian 目录中的各文件作用 </a> </div> - <span class="post-date">Sep 15, 2024</span> + <span class="post-date">Oct 6, 2024</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/15/Advanced-C-binding-using-ocaml-ctypes-and-dune/"> + <a href="/2024/09/27/Turborepo-%E7%AE%80%E8%BF%B0/"> - Advanced C binding using ocaml-ctypes and dune + Turborepo 简述 </a> </div> - <span class="post-date">Sep 15, 2024</span> + <span class="post-date">Sep 27, 2024</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/12/Functional-Reactive-Programming-in-F/"> + <a href="/2024/09/15/%E8%82%A9%E5%91%A8%E7%82%8E%E5%92%8C%E8%82%A9%E8%A2%96%E6%8D%9F%E4%BC%A4%E7%9A%84%E5%8C%BA%E5%88%AB/"> - Functional Reactive Programming in F# + 肩周炎和肩袖损伤的区别 </a> </div> - <span class="post-date">Sep 12, 2024</span> + <span class="post-date">Sep 15, 2024</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/12/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B9%9D%E6%9C%88%E5%8D%81%E4%BA%8C%E6%97%A5/"> + <a href="/2024/09/15/Advanced-C-binding-using-ocaml-ctypes-and-dune/"> - 二〇二四年九月十二日 + Advanced C binding using ocaml-ctypes and dune </a> </div> - <span class="post-date">Sep 12, 2024</span> + <span class="post-date">Sep 15, 2024</span> </div> diff --git a/archives/page/4/index.html b/archives/page/4/index.html index 60020a2e..a808bec6 100644 --- a/archives/page/4/index.html +++ b/archives/page/4/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/08/%E4%B8%AD%E8%80%81%E5%B9%B4%E4%BA%BA%E6%B2%89%E8%BF%B7%E6%89%8B%E6%9C%BA%E7%9A%84%E9%97%AE%E9%A2%98/"> + <a href="/2024/09/12/Functional-Reactive-Programming-in-F/"> - 中老年人沉迷手机的问题 + Functional Reactive Programming in F# </a> </div> - <span class="post-date">Sep 8, 2024</span> + <span class="post-date">Sep 12, 2024</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/07/%E7%BB%99%E5%AD%A9%E5%AD%90%E4%BB%AC%E7%9A%84%E8%AF%9D/"> + <a href="/2024/09/12/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B9%9D%E6%9C%88%E5%8D%81%E4%BA%8C%E6%97%A5/"> - 什么玩意儿都是 + 二〇二四年九月十二日 </a> </div> - <span class="post-date">Sep 7, 2024</span> + <span class="post-date">Sep 12, 2024</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B9%9D%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2024/09/08/%E4%B8%AD%E8%80%81%E5%B9%B4%E4%BA%BA%E6%B2%89%E8%BF%B7%E6%89%8B%E6%9C%BA%E7%9A%84%E9%97%AE%E9%A2%98/"> - 二〇二四年九月一日 + 中老年人沉迷手机的问题 </a> </div> - <span class="post-date">Sep 1, 2024</span> + <span class="post-date">Sep 8, 2024</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/01/%E8%97%BF%E9%A6%99%E6%AD%A3%E6%B0%94%E6%B0%B4%E5%92%8C%E8%97%BF%E9%A6%99%E6%AD%A3%E6%B0%94%E5%8F%A3%E6%9C%8D%E6%B6%B2%E7%9A%84%E5%8C%BA%E5%88%AB/"> + <a href="/2024/09/07/%E7%BB%99%E5%AD%A9%E5%AD%90%E4%BB%AC%E7%9A%84%E8%AF%9D/"> - 藿香正气水和藿香正气口服液的区别 + 什么玩意儿都是 </a> </div> - <span class="post-date">Sep 1, 2024</span> + <span class="post-date">Sep 7, 2024</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/08/12/%E7%9B%B4%E7%B3%BB%E8%A1%80%E4%BA%B2%E4%B9%8B%E9%97%B4%E4%B8%8D%E8%83%BD%E7%9B%B4%E6%8E%A5%E8%BE%93%E8%A1%80/"> + <a href="/2024/09/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B9%9D%E6%9C%88%E4%B8%80%E6%97%A5/"> - 直系血亲之间不能直接输血 + 二〇二四年九月一日 </a> </div> - <span class="post-date">Aug 12, 2024</span> + <span class="post-date">Sep 1, 2024</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/08/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%85%AB%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2024/09/01/%E8%97%BF%E9%A6%99%E6%AD%A3%E6%B0%94%E6%B0%B4%E5%92%8C%E8%97%BF%E9%A6%99%E6%AD%A3%E6%B0%94%E5%8F%A3%E6%9C%8D%E6%B6%B2%E7%9A%84%E5%8C%BA%E5%88%AB/"> - 二〇二四年八月一日 + 藿香正气水和藿香正气口服液的区别 </a> </div> - <span class="post-date">Aug 2, 2024</span> + <span class="post-date">Sep 1, 2024</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/07/23/OCaml-News-2024-6/"> + <a href="/2024/08/12/%E7%9B%B4%E7%B3%BB%E8%A1%80%E4%BA%B2%E4%B9%8B%E9%97%B4%E4%B8%8D%E8%83%BD%E7%9B%B4%E6%8E%A5%E8%BE%93%E8%A1%80/"> - OCaml News 2024-6 + 直系血亲之间不能直接输血 </a> </div> - <span class="post-date">Jul 23, 2024</span> + <span class="post-date">Aug 12, 2024</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/07/09/%E7%A5%9E%E7%BB%8F%E7%B3%BB%E7%BB%9F%E9%87%8D%E7%82%B9/"> + <a href="/2024/08/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%85%AB%E6%9C%88%E4%B8%80%E6%97%A5/"> - 内护神经系统重点考点 + 二〇二四年八月一日 </a> </div> - <span class="post-date">Jul 9, 2024</span> + <span class="post-date">Aug 2, 2024</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/07/01/OCaml-News-2024-4/"> + <a href="/2024/07/23/OCaml-News-2024-6/"> - OCaml News 2024-4 + OCaml News 2024-6 </a> </div> - <span class="post-date">Jul 1, 2024</span> + <span class="post-date">Jul 23, 2024</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/06/27/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%85%AD%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2024/07/09/%E7%A5%9E%E7%BB%8F%E7%B3%BB%E7%BB%9F%E9%87%8D%E7%82%B9/"> - 二〇二四年六月二十七日 + 内护神经系统重点考点 </a> </div> - <span class="post-date">Jun 27, 2024</span> + <span class="post-date">Jul 9, 2024</span> </div> diff --git a/archives/page/5/index.html b/archives/page/5/index.html index 7b09639b..8cf35b16 100644 --- a/archives/page/5/index.html +++ b/archives/page/5/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/06/27/OCaml-News-2024-5/"> + <a href="/2024/07/01/OCaml-News-2024-4/"> - OCaml News 2024-5 + OCaml News 2024-4 </a> </div> - <span class="post-date">Jun 27, 2024</span> + <span class="post-date">Jul 1, 2024</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/06/06/NET-AOT-%E4%B8%8B%E7%9A%84-F-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90%E5%BA%93%E9%80%89%E6%8B%A9/"> + <a href="/2024/06/27/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%85%AD%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> - .NET AOT 下的 F# 命令行参数解析库选择 + 二〇二四年六月二十七日 </a> </div> - <span class="post-date">Jun 6, 2024</span> + <span class="post-date">Jun 27, 2024</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/05/20/Rescript-genType-import-%E9%97%AE%E9%A2%98/"> + <a href="/2024/06/27/OCaml-News-2024-5/"> - Rescript @genType import 问题 + OCaml News 2024-5 </a> </div> - <span class="post-date">May 20, 2024</span> + <span class="post-date">Jun 27, 2024</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/05/16/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%94%E6%9C%88%E5%8D%81%E5%85%AD%E6%97%A5/"> + <a href="/2024/06/06/NET-AOT-%E4%B8%8B%E7%9A%84-F-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90%E5%BA%93%E9%80%89%E6%8B%A9/"> - 二〇二四年五月十六日 + .NET AOT 下的 F# 命令行参数解析库选择 </a> </div> - <span class="post-date">May 16, 2024</span> + <span class="post-date">Jun 6, 2024</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/05/13/%E7%BB%99%E5%B0%B8%E4%BD%93%E4%B8%8A-ECMO-%E5%B9%B6%E7%BB%B4%E6%8C%81%E5%BF%83%E8%B7%B3/"> + <a href="/2024/05/20/Rescript-genType-import-%E9%97%AE%E9%A2%98/"> - 给尸体上 ECMO 并维持心跳 + Rescript @genType import 问题 </a> </div> - <span class="post-date">May 13, 2024</span> + <span class="post-date">May 20, 2024</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/05/07/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%94%E6%9C%88%E4%B8%83%E6%97%A5/"> + <a href="/2024/05/16/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%94%E6%9C%88%E5%8D%81%E5%85%AD%E6%97%A5/"> - 二〇二四年五月七日 + 二〇二四年五月十六日 </a> </div> - <span class="post-date">May 7, 2024</span> + <span class="post-date">May 16, 2024</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/04/08/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%9B%9B%E6%9C%88%E5%85%AB%E6%97%A5/"> + <a href="/2024/05/13/%E7%BB%99%E5%B0%B8%E4%BD%93%E4%B8%8A-ECMO-%E5%B9%B6%E7%BB%B4%E6%8C%81%E5%BF%83%E8%B7%B3/"> - 二〇二四年四月八日 + 给尸体上 ECMO 并维持心跳 </a> </div> - <span class="post-date">Apr 8, 2024</span> + <span class="post-date">May 13, 2024</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/04/03/shadow-cljs-proxy/"> + <a href="/2024/05/07/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%94%E6%9C%88%E4%B8%83%E6%97%A5/"> - shadow-cljs 怎么设置代理 + 二〇二四年五月七日 </a> </div> - <span class="post-date">Apr 3, 2024</span> + <span class="post-date">May 7, 2024</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/03/22/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B8%89%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> + <a href="/2024/04/08/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E5%9B%9B%E6%9C%88%E5%85%AB%E6%97%A5/"> - 二〇二四年三月二十二日 + 二〇二四年四月八日 </a> </div> - <span class="post-date">Mar 22, 2024</span> + <span class="post-date">Apr 8, 2024</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/02/26/OCaml-News-2024-3/"> + <a href="/2024/04/03/shadow-cljs-proxy/"> - OCaml News 2024-3 + shadow-cljs 怎么设置代理 </a> </div> - <span class="post-date">Feb 26, 2024</span> + <span class="post-date">Apr 3, 2024</span> </div> diff --git a/archives/page/6/index.html b/archives/page/6/index.html index 66dcc1d7..2fa3ee05 100644 --- a/archives/page/6/index.html +++ b/archives/page/6/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/02/07/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%B8%83%E6%97%A5/"> + <a href="/2024/03/22/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B8%89%E6%9C%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E6%97%A5/"> - 二〇二四年二月七日 + 二〇二四年三月二十二日 </a> </div> - <span class="post-date">Feb 7, 2024</span> + <span class="post-date">Mar 22, 2024</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/25/%E6%80%A5%E8%AF%8A%E4%B8%8E%E7%81%BE%E9%9A%BE%E5%8C%BB%E5%AD%A6-%E7%83%A7%E4%BC%A4/"> + <a href="/2024/02/26/OCaml-News-2024-3/"> - 急诊与灾难医学--烧伤 + OCaml News 2024-3 </a> </div> - <span class="post-date">Jan 25, 2024</span> + <span class="post-date">Feb 26, 2024</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/23/G-Machine/"> + <a href="/2024/02/07/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%BA%8C%E6%9C%88%E4%B8%83%E6%97%A5/"> - G-Machine + 二〇二四年二月七日 </a> </div> - <span class="post-date">Jan 23, 2024</span> + <span class="post-date">Feb 7, 2024</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/23/%E6%85%A2%E6%80%A7%E8%82%BA%E6%BA%90%E6%80%A7%E5%BF%83%E8%84%8F%E7%97%85/"> + <a href="/2024/01/25/%E6%80%A5%E8%AF%8A%E4%B8%8E%E7%81%BE%E9%9A%BE%E5%8C%BB%E5%AD%A6-%E7%83%A7%E4%BC%A4/"> - 慢性肺源性心脏病 + 急诊与灾难医学--烧伤 </a> </div> - <span class="post-date">Jan 23, 2024</span> + <span class="post-date">Jan 25, 2024</span> </div> @@ -242,9 +242,9 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/23/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%89%E6%97%A5/"> + <a href="/2024/01/23/G-Machine/"> - 二〇二四年一月二十三日 + G-Machine </a> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/22/Rescript-React-Native/"> + <a href="/2024/01/23/%E6%85%A2%E6%80%A7%E8%82%BA%E6%BA%90%E6%80%A7%E5%BF%83%E8%84%8F%E7%97%85/"> - Rescript and React Native + 慢性肺源性心脏病 </a> </div> - <span class="post-date">Jan 22, 2024</span> + <span class="post-date">Jan 23, 2024</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/18/OCaml-News-2024-2/"> + <a href="/2024/01/23/%E4%BA%8C%E3%80%87%E4%BA%8C%E5%9B%9B%E5%B9%B4%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%89%E6%97%A5/"> - OCaml News 2024-2 + 二〇二四年一月二十三日 </a> </div> - <span class="post-date">Jan 18, 2024</span> + <span class="post-date">Jan 23, 2024</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/08/OCaml-News-2024-1/"> + <a href="/2024/01/22/Rescript-React-Native/"> - OCaml News 2024-1 + Rescript and React Native </a> </div> - <span class="post-date">Jan 8, 2024</span> + <span class="post-date">Jan 22, 2024</span> </div> @@ -311,19 +311,17 @@ - <div class="year-title">2023</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2023/12/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/"> + <a href="/2024/01/18/OCaml-News-2024-2/"> - 二〇二三年十二月二日 + OCaml News 2024-2 </a> </div> - <span class="post-date">Dec 2, 2023</span> + <span class="post-date">Jan 18, 2024</span> </div> @@ -334,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/12/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2024/01/08/OCaml-News-2024-1/"> - 二〇二三年十二月一日 + OCaml News 2024-1 </a> </div> - <span class="post-date">Dec 1, 2023</span> + <span class="post-date">Jan 8, 2024</span> </div> diff --git a/archives/page/7/index.html b/archives/page/7/index.html index 3cbaf362..c6d3fb20 100644 --- a/archives/page/7/index.html +++ b/archives/page/7/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/11/29/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B9%9D%E6%97%A5/"> + <a href="/2023/12/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/"> - 二〇二三年十一月二十九日 + 二〇二三年十二月二日 </a> </div> - <span class="post-date">Nov 29, 2023</span> + <span class="post-date">Dec 2, 2023</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/11/21/Adolescent-Onset-of-Acute-Heart-Failure/"> + <a href="/2023/12/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%B8%80%E6%97%A5/"> - Adolescent Onset of Acute Heart Failure + 二〇二三年十二月一日 </a> </div> - <span class="post-date">Nov 21, 2023</span> + <span class="post-date">Dec 1, 2023</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/11/16/Fever-of-Unknown-Origin/"> + <a href="/2023/11/29/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B9%9D%E6%97%A5/"> - Fever of Unknown Origin + 二〇二三年十一月二十九日 </a> </div> - <span class="post-date">Nov 16, 2023</span> + <span class="post-date">Nov 29, 2023</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/11/06/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E5%85%AD%E6%97%A5/"> + <a href="/2023/11/21/Adolescent-Onset-of-Acute-Heart-Failure/"> - 二零二三年十一月六日 + Adolescent Onset of Acute Heart Failure </a> </div> - <span class="post-date">Nov 6, 2023</span> + <span class="post-date">Nov 21, 2023</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/25/%E5%84%BF%E7%AB%A5%E6%96%B0%E5%9E%8B%E5%86%A0%E7%8A%B6%E7%97%85%E6%AF%92Omicron%E6%A0%AA%E5%92%8C%E8%82%BA%E7%82%8E%E6%94%AF%E5%8E%9F%E4%BD%93%E6%B7%B7%E5%90%88%E6%84%9F%E6%9F%93%E9%87%8D%E7%97%87%E8%82%BA%E7%82%8E1%E4%BE%8B/"> + <a href="/2023/11/16/Fever-of-Unknown-Origin/"> - 儿童新型冠状病毒Omicron株和肺炎支原体混合感染重症肺炎1例 + Fever of Unknown Origin </a> </div> - <span class="post-date">Oct 25, 2023</span> + <span class="post-date">Nov 16, 2023</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/25/Radiographic-Absence-of-the-Left-Humeral-Head/"> + <a href="/2023/11/06/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%B8%80%E6%9C%88%E5%85%AD%E6%97%A5/"> - Radiographic Absence of the Left Humeral Head + 二零二三年十一月六日 </a> </div> - <span class="post-date">Oct 25, 2023</span> + <span class="post-date">Nov 6, 2023</span> </div> @@ -278,9 +278,9 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/25/%E8%82%BA%E7%82%8E%E6%94%AF%E5%8E%9F%E4%BD%93%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/"> + <a href="/2023/10/25/%E5%84%BF%E7%AB%A5%E6%96%B0%E5%9E%8B%E5%86%A0%E7%8A%B6%E7%97%85%E6%AF%92Omicron%E6%A0%AA%E5%92%8C%E8%82%BA%E7%82%8E%E6%94%AF%E5%8E%9F%E4%BD%93%E6%B7%B7%E5%90%88%E6%84%9F%E6%9F%93%E9%87%8D%E7%97%87%E8%82%BA%E7%82%8E1%E4%BE%8B/"> - 肺炎支原体注意事项 + 儿童新型冠状病毒Omicron株和肺炎支原体混合感染重症肺炎1例 </a> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/22/%E5%86%AC%E5%AD%A3%E5%92%B3%E5%97%BD%E8%BE%A8%E5%88%AB%E6%8C%87%E5%8D%97/"> + <a href="/2023/10/25/Radiographic-Absence-of-the-Left-Humeral-Head/"> - 冬季咳嗽辨别指南 + Radiographic Absence of the Left Humeral Head </a> </div> - <span class="post-date">Oct 22, 2023</span> + <span class="post-date">Oct 25, 2023</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/21/OCaml-Core-Int-pow-%E7%9A%84%E5%AE%9E%E7%8E%B0/"> + <a href="/2023/10/25/%E8%82%BA%E7%82%8E%E6%94%AF%E5%8E%9F%E4%BD%93%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/"> - OCaml Core.Int.pow 的实现 + 肺炎支原体注意事项 </a> </div> - <span class="post-date">Oct 21, 2023</span> + <span class="post-date">Oct 25, 2023</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/13/%E8%82%9D%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E5%8C%96%E9%AA%8C%E5%8D%95/"> + <a href="/2023/10/22/%E5%86%AC%E5%AD%A3%E5%92%B3%E5%97%BD%E8%BE%A8%E5%88%AB%E6%8C%87%E5%8D%97/"> - 肝功能检查化验单阅读指南 + 冬季咳嗽辨别指南 </a> </div> - <span class="post-date">Oct 13, 2023</span> + <span class="post-date">Oct 22, 2023</span> </div> diff --git a/archives/page/8/index.html b/archives/page/8/index.html index e0f1916d..7516bfcf 100644 --- a/archives/page/8/index.html +++ b/archives/page/8/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/12/%E8%A1%80%E5%B8%B8%E8%A7%84%E5%8C%96%E9%AA%8C%E7%BB%93%E6%9E%9C%E9%98%85%E8%AF%BB%E6%8C%87%E5%8D%97/"> + <a href="/2023/10/21/OCaml-Core-Int-pow-%E7%9A%84%E5%AE%9E%E7%8E%B0/"> - 血常规化验结果阅读指南 + OCaml Core.Int.pow 的实现 </a> </div> - <span class="post-date">Oct 12, 2023</span> + <span class="post-date">Oct 21, 2023</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/12/%E8%BF%87%E5%BA%A6%E7%96%B2%E5%8A%B3%E7%9A%84%E5%85%AD%E7%A7%8D%E8%A1%A8%E7%8E%B0/"> + <a href="/2023/10/13/%E8%82%9D%E5%8A%9F%E8%83%BD%E6%A3%80%E6%9F%A5%E5%8C%96%E9%AA%8C%E5%8D%95/"> - 过度疲劳的六种表现 + 肝功能检查化验单阅读指南 </a> </div> - <span class="post-date">Oct 12, 2023</span> + <span class="post-date">Oct 13, 2023</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/05/v8%E4%B8%AD%E7%9A%84Number-toString/"> + <a href="/2023/10/12/%E8%A1%80%E5%B8%B8%E8%A7%84%E5%8C%96%E9%AA%8C%E7%BB%93%E6%9E%9C%E9%98%85%E8%AF%BB%E6%8C%87%E5%8D%97/"> - v8中的Number.toString() + 血常规化验结果阅读指南 </a> </div> - <span class="post-date">Oct 5, 2023</span> + <span class="post-date">Oct 12, 2023</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/09/28/A-Brief-History-of-Just-In-Time/"> + <a href="/2023/10/12/%E8%BF%87%E5%BA%A6%E7%96%B2%E5%8A%B3%E7%9A%84%E5%85%AD%E7%A7%8D%E8%A1%A8%E7%8E%B0/"> - A Brief History of Just-In-Time + 过度疲劳的六种表现 </a> </div> - <span class="post-date">Sep 28, 2023</span> + <span class="post-date">Oct 12, 2023</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/09/13/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B9%9D%E6%9C%88%E5%8D%81%E4%B8%89%E6%97%A5/"> + <a href="/2023/10/05/v8%E4%B8%AD%E7%9A%84Number-toString/"> - 二零二三年九月十三日 + v8中的Number.toString() </a> </div> - <span class="post-date">Sep 13, 2023</span> + <span class="post-date">Oct 5, 2023</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/27/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> + <a href="/2023/09/28/A-Brief-History-of-Just-In-Time/"> - 二零二三年八月二十七日 + A Brief History of Just-In-Time </a> </div> - <span class="post-date">Aug 27, 2023</span> + <span class="post-date">Sep 28, 2023</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> + <a href="/2023/09/13/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B9%9D%E6%9C%88%E5%8D%81%E4%B8%89%E6%97%A5/"> - 二零二三年八月二十一日 + 二零二三年九月十三日 </a> </div> - <span class="post-date">Aug 21, 2023</span> + <span class="post-date">Sep 13, 2023</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/15/tick-thread%E5%9C%A8Multicore-OCaml%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8/"> + <a href="/2023/08/27/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%83%E6%97%A5/"> - tick thread在Multicore OCaml中的作用 + 二零二三年八月二十七日 </a> </div> - <span class="post-date">Aug 15, 2023</span> + <span class="post-date">Aug 27, 2023</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/15/poll-error-attribute-in-OCaml/"> + <a href="/2023/08/21/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B8%80%E6%97%A5/"> - 使用 [@poll error] 实现线程安全的数据结构 + 二零二三年八月二十一日 </a> </div> - <span class="post-date">Aug 15, 2023</span> + <span class="post-date">Aug 21, 2023</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%B8%80%E6%97%A5/"> + <a href="/2023/08/15/tick-thread%E5%9C%A8Multicore-OCaml%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8/"> - 二〇二三年八月一日 + tick thread在Multicore OCaml中的作用 </a> </div> - <span class="post-date">Aug 1, 2023</span> + <span class="post-date">Aug 15, 2023</span> </div> diff --git a/archives/page/9/index.html b/archives/page/9/index.html index 4b0be2ec..ae97f1a2 100644 --- a/archives/page/9/index.html +++ b/archives/page/9/index.html @@ -170,14 +170,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/07/30/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B8%83%E6%9C%88%E4%B8%89%E5%8D%81%E6%97%A5/"> + <a href="/2023/08/15/poll-error-attribute-in-OCaml/"> - 二零二三年七月三十日 + 使用 [@poll error] 实现线程安全的数据结构 </a> </div> - <span class="post-date">Jul 30, 2023</span> + <span class="post-date">Aug 15, 2023</span> </div> @@ -188,14 +188,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/07/21/WiscKey-Separating-Keys-from-Values-in-SSD-conscious-Storage/"> + <a href="/2023/08/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AB%E6%9C%88%E4%B8%80%E6%97%A5/"> - WiscKey: Separating Keys from Values in SSD-conscious Storage + 二〇二三年八月一日 </a> </div> - <span class="post-date">Jul 21, 2023</span> + <span class="post-date">Aug 1, 2023</span> </div> @@ -206,14 +206,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/29/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AD%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B9%9D%E6%97%A5/"> + <a href="/2023/07/30/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E4%B8%83%E6%9C%88%E4%B8%89%E5%8D%81%E6%97%A5/"> - 二〇二三年六月二十九日 + 二零二三年七月三十日 </a> </div> - <span class="post-date">Jun 29, 2023</span> + <span class="post-date">Jul 30, 2023</span> </div> @@ -224,14 +224,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/28/%E9%9A%90%E8%97%8F%E4%B8%80%E4%BA%9BOCaml-Effect%E7%9A%84%E6%9C%BA%E5%88%B6%EF%BC%8C%E8%AE%A9%E5%85%B6%E8%AF%AD%E6%B3%95%E5%9C%A8%E7%B2%BE%E7%A5%9E%E4%B8%8A%E6%9B%B4%E6%8E%A5%E8%BF%91delimcc/"> + <a href="/2023/07/21/WiscKey-Separating-Keys-from-Values-in-SSD-conscious-Storage/"> - 隐藏一些OCaml Effect的机制,让其语法在精神上更接近delimcc + WiscKey: Separating Keys from Values in SSD-conscious Storage </a> </div> - <span class="post-date">Jun 28, 2023</span> + <span class="post-date">Jul 21, 2023</span> </div> @@ -242,14 +242,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/28/caml-release-runtime-system%E5%AF%BC%E8%87%B4%E7%9A%84%E6%AD%BB%E9%94%81%E9%97%AE%E9%A2%98/"> + <a href="/2023/06/29/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AD%E6%9C%88%E4%BA%8C%E5%8D%81%E4%B9%9D%E6%97%A5/"> - caml_release_runtime_system导致的死锁问题 + 二〇二三年六月二十九日 </a> </div> - <span class="post-date">Jun 28, 2023</span> + <span class="post-date">Jun 29, 2023</span> </div> @@ -260,14 +260,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/22/%E7%81%AF%E7%AC%BC%E8%8D%89/"> + <a href="/2023/06/28/%E9%9A%90%E8%97%8F%E4%B8%80%E4%BA%9BOCaml-Effect%E7%9A%84%E6%9C%BA%E5%88%B6%EF%BC%8C%E8%AE%A9%E5%85%B6%E8%AF%AD%E6%B3%95%E5%9C%A8%E7%B2%BE%E7%A5%9E%E4%B8%8A%E6%9B%B4%E6%8E%A5%E8%BF%91delimcc/"> - 灯笼草 + 隐藏一些OCaml Effect的机制,让其语法在精神上更接近delimcc </a> </div> - <span class="post-date">Jun 22, 2023</span> + <span class="post-date">Jun 28, 2023</span> </div> @@ -278,14 +278,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/17/%E5%8F%91%E7%83%AD%E5%8F%8A%E8%B6%85%E9%AB%98%E7%83%AD%E5%8D%B1%E8%B1%A1/"> + <a href="/2023/06/28/caml-release-runtime-system%E5%AF%BC%E8%87%B4%E7%9A%84%E6%AD%BB%E9%94%81%E9%97%AE%E9%A2%98/"> - 发热及超高热危象 + caml_release_runtime_system导致的死锁问题 </a> </div> - <span class="post-date">Jun 17, 2023</span> + <span class="post-date">Jun 28, 2023</span> </div> @@ -296,14 +296,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/10/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AD%E6%9C%88%E5%8D%81%E6%97%A5/"> + <a href="/2023/06/22/%E7%81%AF%E7%AC%BC%E8%8D%89/"> - 二零二三年六月十日 + 灯笼草 </a> </div> - <span class="post-date">Jun 10, 2023</span> + <span class="post-date">Jun 22, 2023</span> </div> @@ -314,14 +314,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/05/24/Rust-%E9%97%AD%E5%8C%85-lifetime-may-not-live-long-enough-%E9%97%AE%E9%A2%98/"> + <a href="/2023/06/17/%E5%8F%91%E7%83%AD%E5%8F%8A%E8%B6%85%E9%AB%98%E7%83%AD%E5%8D%B1%E8%B1%A1/"> - Rust 闭包 lifetime may not live long enough 问题 + 发热及超高热危象 </a> </div> - <span class="post-date">May 24, 2023</span> + <span class="post-date">Jun 17, 2023</span> </div> @@ -332,14 +332,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/05/03/Rust-NewType-%E6%A8%A1%E5%BC%8F/"> + <a href="/2023/06/10/%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%85%AD%E6%9C%88%E5%8D%81%E6%97%A5/"> - Rust NewType 模式 + 二零二三年六月十日 </a> </div> - <span class="post-date">May 3, 2023</span> + <span class="post-date">Jun 10, 2023</span> </div> diff --git a/page/7/index.html b/page/7/index.html index 35a18644..4d9193cb 100644 --- a/page/7/index.html +++ b/page/7/index.html @@ -65,119 +65,7 @@ - <meta name="generator" content="Hexo 6.3.0"><style>mjx-container[jax="SVG"] { - direction: ltr; -} - -mjx-container[jax="SVG"] > svg { - overflow: visible; -} - -mjx-container[jax="SVG"][display="true"] { - display: block; - text-align: center; - margin: 1em 0; -} - -mjx-container[jax="SVG"][justify="left"] { - text-align: left; -} - -mjx-container[jax="SVG"][justify="right"] { - text-align: right; -} - -g[data-mml-node="merror"] > g { - fill: red; - stroke: red; -} - -g[data-mml-node="merror"] > rect[data-background] { - fill: yellow; - stroke: none; -} - -g[data-mml-node="mtable"] > line[data-line] { - stroke-width: 70px; - fill: none; -} - -g[data-mml-node="mtable"] > rect[data-frame] { - stroke-width: 70px; - fill: none; -} - -g[data-mml-node="mtable"] > .mjx-dashed { - stroke-dasharray: 140; -} - -g[data-mml-node="mtable"] > .mjx-dotted { - stroke-linecap: round; - stroke-dasharray: 0,140; -} - -g[data-mml-node="mtable"] > svg { - overflow: visible; -} - -[jax="SVG"] mjx-tool { - display: inline-block; - position: relative; - width: 0; - height: 0; -} - -[jax="SVG"] mjx-tool > mjx-tip { - position: absolute; - top: 0; - left: 0; -} - -mjx-tool > mjx-tip { - display: inline-block; - padding: .2em; - border: 1px solid #888; - font-size: 70%; - background-color: #F8F8F8; - color: black; - box-shadow: 2px 2px 5px #AAAAAA; -} - -g[data-mml-node="maction"][data-toggle] { - cursor: pointer; -} - -mjx-status { - display: block; - position: fixed; - left: 1em; - bottom: 1em; - min-width: 25%; - padding: .2em .4em; - border: 1px solid #888; - font-size: 90%; - background-color: #F8F8F8; - color: black; -} - -foreignObject[data-mjx-xml] { - font-family: initial; - line-height: normal; - overflow: visible; -} - -.MathJax path { - stroke-width: 3; -} - -mjx-container[display="true"] { - overflow: auto hidden; -} - -mjx-container[display="true"] + br { - display: none; -} -</style></head> + <meta name="generator" content="Hexo 6.3.0"></head> <body> <div class="mask-border"> </div> @@ -845,7 +845,7 @@ </ol> <p>Prisma ORM 在设计上就考虑了 N+1 问题,并提供了一种既方便开发者又高效的解决方案。当使用 Prisma Client 查询数据并需要包含关联模型时,Prisma 会自动优化查询,<strong>避免产生 N+1 查询</strong>,主要通过<strong>关系查询(Relation Queries)</strong>中的 <code>include</code> 选项或嵌套读取(nested reads)来实现这一点:</p> <p>假设想获取所有用户及其发布的帖子,使用 Prisma Client,可以这样写:</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">PrismaClient</span> } <span class="keyword">from</span> <span class="string">'@prisma/client'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> prisma = <span class="keyword">new</span> <span class="title class_">PrismaClient</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getUsersWithPosts</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> usersWithPosts = <span class="keyword">await</span> prisma.<span class="property">user</span>.<span class="title function_">findMany</span>({</span><br><span class="line"> <span class="attr">include</span>: {</span><br><span class="line"> <span class="attr">posts</span>: <span class="literal">true</span>, <span class="comment">// 指示 Prisma 加载关联的 posts</span></span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line"> <span class="comment">// usersWithPosts 包含了用户列表,每个用户对象中都有一个 posts 数组</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(usersWithPosts)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getUsersWithPosts</span>()</span><br><span class="line"> .<span class="title function_">catch</span>(<span class="function">(<span class="params">e</span>) =></span> {</span><br><span class="line"> <span class="keyword">throw</span> e</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">finally</span>(<span class="keyword">async</span> () => {</span><br><span class="line"> <span class="keyword">await</span> prisma.$disconnect()</span><br><span class="line"> })</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">PrismaClient</span> } <span class="keyword">from</span> <span class="string">'@prisma/client'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> prisma = <span class="keyword">new</span> <span class="title class_">PrismaClient</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getUsersWithPosts</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> usersWithPosts = <span class="keyword">await</span> prisma.<span class="property">user</span>.<span class="title function_">findMany</span>({</span><br><span class="line"> <span class="attr">include</span>: {</span><br><span class="line"> <span class="attr">posts</span>: <span class="literal">true</span>, <span class="comment">// 指示 Prisma 加载关联的 posts</span></span><br><span class="line"> },</span><br><span class="line"> })</span><br><span class="line"> <span class="comment">// usersWithPosts 包含了用户列表,每个用户对象中都有一个 posts 数组</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(usersWithPosts)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getUsersWithPosts</span>()</span><br><span class="line"> .<span class="title function_">catch</span>(<span class="function">(<span class="params">e</span>) =></span> {</span><br><span class="line"> <span class="keyword">throw</span> e</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">finally</span>(<span class="title function_">async</span> () => {</span><br><span class="line"> <span class="keyword">await</span> prisma.$disconnect()</span><br><span class="line"> })</span><br></pre></td></tr></table></figure> <p>当执行上述查询时,Prisma <strong>不会</strong> 生成 N+1 个 SQL 查询。而是首先会分析请求,并将其转化为数量非常有限的高效 SQL 查询。对于上面这个一对多关系的 <code>include</code> 查询,Prisma 通常会执行以下<strong>两步</strong>(类似于批量加载策略):</p> <ol> @@ -1139,67 +1139,6 @@ </tags> </entry> <entry> - <title>OCaml News 2024-5</title> - <url>/2024/06/27/OCaml-News-2024-5/</url> - <content><![CDATA[<h2 id="语言的发展"><a href="#语言的发展" class="headerlink" title="语言的发展"></a>语言的发展</h2><ul> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13097">Immutable arrays #13097: This PR proposes to add immutable arrays to OCaml.</a></li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13199">Support running native debuggers in ocamltest #13199</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13152">The Pattern-Matching Bug: fix totality information by gasche · Pull Request #13152 · ocaml/ocaml</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/11974%23discussion_r1621832545">Add loongarch architecture support #11974</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13101">Add Stdlib.todo #13101</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-26-enhancing-the-ocaml-org-community-page-boosting-ux-and-ui-based-on-user-research/">Enhancing the OCaml.org Community Page: Boosting UX and UI Based on User Research.</a></li> -<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-05-22-launching-the-first-class-windows-project/">Launching the First-Class Windows Project</a>.</li> -</ul> -<h2 id="新消息"><a href="#新消息" class="headerlink" title="新消息"></a>新消息</h2><ul> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-project-wide-occurrences-in-merlin-and-lsp/14847">[ANN] Project wide occurrences in Merlin and LSP</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-opam-2-2-0-rc1-release/14842">[ANN] opam 2.2.0 rc1 release</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-first-release-of-baby/14840">[ANN] First release of baby</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://github.com/fpottier/baby">baby</a> is an OCaml library that offers several implementations of balanced binary search trees.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-preview-of-stripe-client-and-mock-server-dkstdrestapis/14841">[ANN] Preview of Stripe client and mock server - DkStdRestApis</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-caisar-release-2-0-a-platform-for-characterizing-ai-safety-and-robustness/14831">[ANN] CAISAR release 2.0, a platform for characterizing AI safety and robustness</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-forester-4-1/14800">[ANN] Forester 4.1</a>.</p> -</li> -<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-dream-html-pure-html-3-5-2/14808">[ANN] dream-html & pure-html 3.5.2</a></p> -</li> -</ul> -<h2 id="有价值的文章"><a href="#有价值的文章" class="headerlink" title="有价值的文章"></a>有价值的文章</h2><ul> -<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-19-keeping-up-with-the-compiler-how-we-help-maintain-the-ocaml-language/">Keeping Up With the Compiler: How we Help Maintain the OCaml Language</a></li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/10995">Explain mapping between OCaml memory model and C.</a></li> -<li><a href="https://link.zhihu.com/?target=https://xavierleroy.org/CdF/2023-2024/index.html">Control structures – Xavier Leroy</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://dev.to/chshersh/8-months-of-ocaml-after-8-years-of-haskell-in-production-h96">8 months of OCaml after 8 years of Haskell in production</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://hypirion.com/musings/getting-ocaml-through-the-eye-of-a-needle">Getting OCaml Through the Eye of a Needle</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-05-secure-from-the-ground-up-introducing-the-fides-project-combining-risc-v-and-mirageos/">Secure From the Ground Up: Introducing the FIDES Project Combining RISC-V and MirageOS.</a></li> -<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-05-29-effective-ml-through-merlin-s-destruct-command/">Effective ML Through Merlin’s Destruct Command.</a></li> -<li><a href="https://link.zhihu.com/?target=https://blog.osau.re/articles/reproducible.html">Dinosaure’s website - Reproducibility!</a></li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/experiments-in-jitting/14853">Experiments in JITting</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/how-to-write-an-efficient-cp-r-clone-with-eio/14848">How to write an efficient ‘cp -R’ clone with Eio?</a></li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/generating-infix-extension-nodes-with-ppxlib/14833">Generating infix extension nodes with Ppxlib</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/this-made-my-day-float-to-string-and-string-of-float-without-loss-of-precision/14825">This made my day (float to string and string of float without loss of precision)</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/help-with-cryptic-dependency-cycle-compile-errors-using-dune-build/14864">Help with cryptic dependency cycle compile errors using <code>dune build</code></a>.</li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/why-does-relaxed-value-restriction-treat-function-types-differently/14802">Why does relaxed value restriction treat function types differently?</a></li> -<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/binding-existentials-in-a-non-uniform-gadt/14809">Binding existentials in a non-uniform GADT</a>.</li> -</ul> -<h2 id="有趣的项目"><a href="#有趣的项目" class="headerlink" title="有趣的项目"></a>有趣的项目</h2><ul> -<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/ocaml-index/latest">ocaml-index 1.0 (latest) · OCaml Package: A tool that indexes value usages from cmt files</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/fileutils/latest">fileutils 0.6.4 (latest) · OCaml Package: API to manipulate files (POSIX like) and filenames.</a></li> -<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/pure-html/latest">pure-html 3.5.2 (latest) · OCaml Package</a></li> -<li><a href="https://link.zhihu.com/?target=https://github.com/fpottier/baby">GitHub - fpottier/baby: A balanced binary search tree library for OCaml</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://github.com/akabe/ocaml-jupyter">GitHub - akabe/ocaml-jupyter: An OCaml kernel for Jupyter (IPython) notebook</a>.</li> -<li><a href="https://link.zhihu.com/?target=https://github.com/robur-coop/orb">Github - robur-coop/orb: check opam package reproductibility.</a></li> -<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml-multicore/dscheck%23motivation">Github - ocaml-multicore/dscheck: Experimental model checker for testing concurrent algorithms.</a></li> -</ul> -]]></content> - <tags> - <tag>Technique</tag> - </tags> - </entry> - <entry> <title>OCaml News 2024-4</title> <url>/2024/07/01/OCaml-News-2024-4/</url> <content><![CDATA[<h2 id="那么接下来"><a href="#那么接下来" class="headerlink" title="那么接下来"></a>那么接下来</h2><ul> @@ -1319,6 +1258,67 @@ </tags> </entry> <entry> + <title>OCaml News 2024-5</title> + <url>/2024/06/27/OCaml-News-2024-5/</url> + <content><![CDATA[<h2 id="语言的发展"><a href="#语言的发展" class="headerlink" title="语言的发展"></a>语言的发展</h2><ul> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13097">Immutable arrays #13097: This PR proposes to add immutable arrays to OCaml.</a></li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13199">Support running native debuggers in ocamltest #13199</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13152">The Pattern-Matching Bug: fix totality information by gasche · Pull Request #13152 · ocaml/ocaml</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/11974%23discussion_r1621832545">Add loongarch architecture support #11974</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/13101">Add Stdlib.todo #13101</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-26-enhancing-the-ocaml-org-community-page-boosting-ux-and-ui-based-on-user-research/">Enhancing the OCaml.org Community Page: Boosting UX and UI Based on User Research.</a></li> +<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-05-22-launching-the-first-class-windows-project/">Launching the First-Class Windows Project</a>.</li> +</ul> +<h2 id="新消息"><a href="#新消息" class="headerlink" title="新消息"></a>新消息</h2><ul> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-project-wide-occurrences-in-merlin-and-lsp/14847">[ANN] Project wide occurrences in Merlin and LSP</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-opam-2-2-0-rc1-release/14842">[ANN] opam 2.2.0 rc1 release</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-first-release-of-baby/14840">[ANN] First release of baby</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://github.com/fpottier/baby">baby</a> is an OCaml library that offers several implementations of balanced binary search trees.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-preview-of-stripe-client-and-mock-server-dkstdrestapis/14841">[ANN] Preview of Stripe client and mock server - DkStdRestApis</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-caisar-release-2-0-a-platform-for-characterizing-ai-safety-and-robustness/14831">[ANN] CAISAR release 2.0, a platform for characterizing AI safety and robustness</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-forester-4-1/14800">[ANN] Forester 4.1</a>.</p> +</li> +<li><p><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/ann-dream-html-pure-html-3-5-2/14808">[ANN] dream-html & pure-html 3.5.2</a></p> +</li> +</ul> +<h2 id="有价值的文章"><a href="#有价值的文章" class="headerlink" title="有价值的文章"></a>有价值的文章</h2><ul> +<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-19-keeping-up-with-the-compiler-how-we-help-maintain-the-ocaml-language/">Keeping Up With the Compiler: How we Help Maintain the OCaml Language</a></li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml/ocaml/pull/10995">Explain mapping between OCaml memory model and C.</a></li> +<li><a href="https://link.zhihu.com/?target=https://xavierleroy.org/CdF/2023-2024/index.html">Control structures – Xavier Leroy</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://dev.to/chshersh/8-months-of-ocaml-after-8-years-of-haskell-in-production-h96">8 months of OCaml after 8 years of Haskell in production</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://hypirion.com/musings/getting-ocaml-through-the-eye-of-a-needle">Getting OCaml Through the Eye of a Needle</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-06-05-secure-from-the-ground-up-introducing-the-fides-project-combining-risc-v-and-mirageos/">Secure From the Ground Up: Introducing the FIDES Project Combining RISC-V and MirageOS.</a></li> +<li><a href="https://link.zhihu.com/?target=https://tarides.com/blog/2024-05-29-effective-ml-through-merlin-s-destruct-command/">Effective ML Through Merlin’s Destruct Command.</a></li> +<li><a href="https://link.zhihu.com/?target=https://blog.osau.re/articles/reproducible.html">Dinosaure’s website - Reproducibility!</a></li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/experiments-in-jitting/14853">Experiments in JITting</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/how-to-write-an-efficient-cp-r-clone-with-eio/14848">How to write an efficient ‘cp -R’ clone with Eio?</a></li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/generating-infix-extension-nodes-with-ppxlib/14833">Generating infix extension nodes with Ppxlib</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/this-made-my-day-float-to-string-and-string-of-float-without-loss-of-precision/14825">This made my day (float to string and string of float without loss of precision)</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/help-with-cryptic-dependency-cycle-compile-errors-using-dune-build/14864">Help with cryptic dependency cycle compile errors using <code>dune build</code></a>.</li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/why-does-relaxed-value-restriction-treat-function-types-differently/14802">Why does relaxed value restriction treat function types differently?</a></li> +<li><a href="https://link.zhihu.com/?target=https://discuss.ocaml.org/t/binding-existentials-in-a-non-uniform-gadt/14809">Binding existentials in a non-uniform GADT</a>.</li> +</ul> +<h2 id="有趣的项目"><a href="#有趣的项目" class="headerlink" title="有趣的项目"></a>有趣的项目</h2><ul> +<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/ocaml-index/latest">ocaml-index 1.0 (latest) · OCaml Package: A tool that indexes value usages from cmt files</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/fileutils/latest">fileutils 0.6.4 (latest) · OCaml Package: API to manipulate files (POSIX like) and filenames.</a></li> +<li><a href="https://link.zhihu.com/?target=https://ocaml.org/p/pure-html/latest">pure-html 3.5.2 (latest) · OCaml Package</a></li> +<li><a href="https://link.zhihu.com/?target=https://github.com/fpottier/baby">GitHub - fpottier/baby: A balanced binary search tree library for OCaml</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://github.com/akabe/ocaml-jupyter">GitHub - akabe/ocaml-jupyter: An OCaml kernel for Jupyter (IPython) notebook</a>.</li> +<li><a href="https://link.zhihu.com/?target=https://github.com/robur-coop/orb">Github - robur-coop/orb: check opam package reproductibility.</a></li> +<li><a href="https://link.zhihu.com/?target=https://github.com/ocaml-multicore/dscheck%23motivation">Github - ocaml-multicore/dscheck: Experimental model checker for testing concurrent algorithms.</a></li> +</ul> +]]></content> + <tags> + <tag>Technique</tag> + </tags> + </entry> + <entry> <title>OCaml News 2024-6</title> <url>/2024/07/23/OCaml-News-2024-6/</url> <content><![CDATA[<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"> ^o3</span><br><span class="line">~/\_/\_|)</span><br><span class="line">|/=_=\|</span><br><span class="line">" "</span><br></pre></td></tr></table></figure> @@ -1618,7 +1618,7 @@ <p>一对一的 self-relation 需要两个端点,即使这两个端点是同一条数据。</p> </blockquote> <p>而在关系型数据库中,一对一的 self-relation 可以用如下 SQL 描述:</p> -<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "successorId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> fk_successor_user <span class="keyword">FOREIGN</span> KEY ("successorId") <span class="keyword">REFERENCES</span> "User" (id);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> successor_unique <span class="keyword">UNIQUE</span> ("successorId");</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "successorId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> fk_successor_user <span class="keyword">FOREIGN KEY</span> ("successorId") <span class="keyword">REFERENCES</span> "User" (id);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> successor_unique <span class="keyword">UNIQUE</span> ("successorId");</span><br></pre></td></tr></table></figure> <h2 id="一对多"><a href="#一对多" class="headerlink" title="一对多"></a>一对多</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> teacherId Int?</span><br><span class="line"> teacher User? @relation("TeacherStudents", fields: [teacherId], references: [id])</span><br><span class="line"> students User[] @relation("TeacherStudents")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> @@ -1631,7 +1631,7 @@ <p>可以通过将 <code>teacher</code> 字段设<a href="https://www.prisma.io/docs/orm/prisma-schema/data-model/models#optional-and-mandatory-fields">为 required</a> 来要求每个 User 都有一名 teacher。</p> </blockquote> <p>用 SQL 描述 User model:</p> -<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "teacherId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> "User" <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> fk_teacherid_user <span class="keyword">FOREIGN</span> KEY ("teacherId") <span class="keyword">REFERENCES</span> "User" (id);</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id SERIAL <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> "name" TEXT,</span><br><span class="line"> "teacherId" <span class="type">INTEGER</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER TABLE</span> "User" <span class="keyword">ADD CONSTRAINT</span> fk_teacherid_user <span class="keyword">FOREIGN KEY</span> ("teacherId") <span class="keyword">REFERENCES</span> "User" (id);</span><br></pre></td></tr></table></figure> <p><code>teacherId</code> 没有使用 <code>UNIQUE</code> 约束,这代表着多个 students 可以有同一个 teacher</p> <h2 id="多对多"><a href="#多对多" class="headerlink" title="多对多"></a>多对多</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> followedBy User[] @relation("UserFollows")</span><br><span class="line"> following User[] @relation("UserFollows")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> @@ -1648,7 +1648,7 @@ <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> followedBy Follows[] @relation("followedBy")</span><br><span class="line"> following Follows[] @relation("following")</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">model Follows {</span><br><span class="line"> followedBy User @relation("followedBy", fields: [followedById], references: [id])</span><br><span class="line"> followedById Int</span><br><span class="line"> following User @relation("following", fields: [followingId], references: [id])</span><br><span class="line"> followingId Int</span><br><span class="line"></span><br><span class="line"> @@id([followingId, followedById])</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <p>在关系型数据库中,可以用如下 SQL 描述:</p> -<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "User" (</span><br><span class="line"> id <span class="type">integer</span> <span class="keyword">DEFAULT</span> nextval(<span class="string">'"User_id_seq"'</span>::regclass) <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line"> name text</span><br><span class="line">);</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> "_UserFollows" (</span><br><span class="line"> "A" <span class="type">integer</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE,</span><br><span class="line"> "B" <span class="type">integer</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE</span><br><span class="line">);</span><br></pre></td></tr></table></figure> +<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE TABLE</span> "User" (</span><br><span class="line"> id <span class="type">integer</span> <span class="keyword">DEFAULT</span> nextval(<span class="string">'"User_id_seq"'</span>::regclass) <span class="keyword">PRIMARY KEY</span>,</span><br><span class="line"> name text</span><br><span class="line">);</span><br><span class="line"><span class="keyword">CREATE TABLE</span> "_UserFollows" (</span><br><span class="line"> "A" <span class="type">integer</span> <span class="keyword">NOT NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE,</span><br><span class="line"> "B" <span class="type">integer</span> <span class="keyword">NOT NULL</span> <span class="keyword">REFERENCES</span> "User"(id) <span class="keyword">ON</span> <span class="keyword">DELETE</span> CASCADE <span class="keyword">ON</span> <span class="keyword">UPDATE</span> CASCADE</span><br><span class="line">);</span><br></pre></td></tr></table></figure> <h2 id="在同一模型上建立多个-self-relations"><a href="#在同一模型上建立多个-self-relations" class="headerlink" title="在同一模型上建立多个 self-relations"></a>在同一模型上建立多个 self-relations</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">model User {</span><br><span class="line"> id Int @id @default(autoincrement())</span><br><span class="line"> name String?</span><br><span class="line"> teacherId Int?</span><br><span class="line"> teacher User? @relation("TeacherStudents", fields: [teacherId], references: [id])</span><br><span class="line"> students User[] @relation("TeacherStudents")</span><br><span class="line"> followedBy User[] @relation("UserFollows")</span><br><span class="line"> following User[] @relation("UserFollows")</span><br><span class="line">}</span><br></pre></td></tr></table></figure> @@ -1713,10 +1713,10 @@ <li><code>IGenericRepository</code> 中定义的函数是每个 <em>Repository</em> 公开的通用存储函数。</li> </ul> <p>以上这些就是对业务中的实体的 <em>Repository</em> 抽象,这样就隔离开了业务和存储逻辑,例如使用 MongoDB,可以实现一个 <code>MongoGenericRepository</code>:</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IGenericRepository</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoGenericRepository</span><T> <span class="keyword">implements</span> <span class="title class_">IGenericRepository</span><T> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_repository</span>: <span class="title class_">Model</span><T>;</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_populateOnFind</span>: <span class="built_in">string</span>[];</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">repository: Model<T>, populateOnFind: <span class="built_in">string</span>[] = []</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_repository</span> = repository;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_populateOnFind</span> = populateOnFind;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">getAll</span>(): <span class="title class_">Promise</span><T[]> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">find</span>().<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">get</span>(<span class="attr">id</span>: <span class="built_in">any</span>): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findById</span>(id).<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">create</span>(<span class="attr">item</span>: T): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">create</span>(item);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">update</span>(<span class="params">id: <span class="built_in">string</span>, item: T</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findByIdAndUpdate</span>(id, item);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IGenericRepository</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoGenericRepository</span><T> <span class="keyword">implements</span> <span class="title class_">IGenericRepository</span><T> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_repository</span>: <span class="title class_">Model</span><T>;</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">_populateOnFind</span>: <span class="built_in">string</span>[];</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"><span class="attr">repository</span>: <span class="title class_">Model</span><T>, <span class="attr">populateOnFind</span>: <span class="built_in">string</span>[] = []</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_repository</span> = repository;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">_populateOnFind</span> = populateOnFind;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">getAll</span>(): <span class="title class_">Promise</span><T[]> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">find</span>().<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">get</span>(<span class="attr">id</span>: <span class="built_in">any</span>): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findById</span>(id).<span class="title function_">populate</span>(<span class="variable language_">this</span>.<span class="property">_populateOnFind</span>).<span class="title function_">exec</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">create</span>(<span class="attr">item</span>: T): <span class="title class_">Promise</span><T> {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">create</span>(item);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">update</span>(<span class="params"><span class="attr">id</span>: <span class="built_in">string</span>, <span class="attr">item</span>: T</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_repository</span>.<span class="title function_">findByIdAndUpdate</span>(id, item);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <p>然后实现一个 <code>MongoDataServices</code>:</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Injectable</span>, <span class="title class_">OnApplicationBootstrap</span> } <span class="keyword">from</span> <span class="string">'@nestjs/common'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">InjectModel</span> } <span class="keyword">from</span> <span class="string">'@nestjs/mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IDataServices</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">MongoGenericRepository</span> } <span class="keyword">from</span> <span class="string">'./mongo-generic-repository'</span>;</span><br><span class="line"><span class="keyword">import</span> {</span><br><span class="line"> <span class="title class_">Author</span>,</span><br><span class="line"> <span class="title class_">AuthorDocument</span>,</span><br><span class="line"> <span class="title class_">Book</span>,</span><br><span class="line"> <span class="title class_">BookDocument</span>,</span><br><span class="line"> <span class="title class_">Genre</span>,</span><br><span class="line"> <span class="title class_">GenreDocument</span>,</span><br><span class="line">} <span class="keyword">from</span> <span class="string">'./model'</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Injectable</span>()</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoDataServices</span></span><br><span class="line"> <span class="keyword">implements</span> <span class="title class_">IDataServices</span>, <span class="title class_">OnApplicationBootstrap</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">authors</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>;</span><br><span class="line"> <span class="attr">books</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>;</span><br><span class="line"> <span class="attr">genres</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Author.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> AuthorRepository: Model<AuthorDocument>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Book.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> BookRepository: Model<BookDocument>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Genre.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> GenreRepository: Model<GenreDocument>,</span></span><br><span class="line"><span class="params"> </span>) {}</span><br><span class="line"></span><br><span class="line"> <span class="title function_">onApplicationBootstrap</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">authors</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>(<span class="variable language_">this</span>.<span class="property">AuthorRepository</span>);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">books</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>(<span class="variable language_">this</span>.<span class="property">BookRepository</span>, [</span><br><span class="line"> <span class="string">'author'</span>,</span><br><span class="line"> <span class="string">'genre'</span>,</span><br><span class="line"> ]);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">genres</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>(<span class="variable language_">this</span>.<span class="property">GenreRepository</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Injectable</span>, <span class="title class_">OnApplicationBootstrap</span> } <span class="keyword">from</span> <span class="string">'@nestjs/common'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">InjectModel</span> } <span class="keyword">from</span> <span class="string">'@nestjs/mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Model</span> } <span class="keyword">from</span> <span class="string">'mongoose'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">IDataServices</span> } <span class="keyword">from</span> <span class="string">'../../../core'</span>;</span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">MongoGenericRepository</span> } <span class="keyword">from</span> <span class="string">'./mongo-generic-repository'</span>;</span><br><span class="line"><span class="keyword">import</span> {</span><br><span class="line"> <span class="title class_">Author</span>,</span><br><span class="line"> <span class="title class_">AuthorDocument</span>,</span><br><span class="line"> <span class="title class_">Book</span>,</span><br><span class="line"> <span class="title class_">BookDocument</span>,</span><br><span class="line"> <span class="title class_">Genre</span>,</span><br><span class="line"> <span class="title class_">GenreDocument</span>,</span><br><span class="line">} <span class="keyword">from</span> <span class="string">'./model'</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Injectable</span>()</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">MongoDataServices</span></span><br><span class="line"> <span class="keyword">implements</span> <span class="title class_">IDataServices</span>, <span class="title class_">OnApplicationBootstrap</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">authors</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>;</span><br><span class="line"> <span class="attr">books</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>;</span><br><span class="line"> <span class="attr">genres</span>: <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Author.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">AuthorRepository</span>: <span class="title class_">Model</span><<span class="title class_">AuthorDocument</span>>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Book.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">BookRepository</span>: <span class="title class_">Model</span><<span class="title class_">BookDocument</span>>,</span></span><br><span class="line"><span class="params"> <span class="meta">@InjectModel</span>(Genre.name)</span></span><br><span class="line"><span class="params"> <span class="keyword">private</span> <span class="title class_">GenreRepository</span>: <span class="title class_">Model</span><<span class="title class_">GenreDocument</span>>,</span></span><br><span class="line"><span class="params"> </span>) {}</span><br><span class="line"></span><br><span class="line"> <span class="title function_">onApplicationBootstrap</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">authors</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Author</span>>(<span class="variable language_">this</span>.<span class="property">AuthorRepository</span>);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">books</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Book</span>>(<span class="variable language_">this</span>.<span class="property">BookRepository</span>, [</span><br><span class="line"> <span class="string">'author'</span>,</span><br><span class="line"> <span class="string">'genre'</span>,</span><br><span class="line"> ]);</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">genres</span> = <span class="keyword">new</span> <span class="title class_">MongoGenericRepository</span><<span class="title class_">Genre</span>>(<span class="variable language_">this</span>.<span class="property">GenreRepository</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> <hr> <p>Sunday, March 30, 2025 7:58 PM:</p> @@ -2091,49 +2091,6 @@ </tags> </entry> <entry> - <title>TypeScript With Rust Errors, No Try Catch, Heresy</title> - <url>/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/</url> - <content><![CDATA[<blockquote> -<p>It’s hard to miss things when you don’t know different things exist</p> -</blockquote> -<p>The first problem is, and personally, I believe it’s the biggest JavaScript problem ever: we don’t know what can throw an error. From a JavaScript error perspective, it’s the same as the following:</p> -<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">let</span> data = “<span class="title class_">Hello</span>”;</span><br><span class="line">} <span class="keyword">catch</span> (err) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(err);</span><br><span class="line">}</span><br></pre></td></tr></table></figure> - -<p>JavaScript doesn’t know; JavaScript doesn’t care. You should know.</p> -<p>Second thing, this is perfectly viable code:</p> -<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> request = { <span class="attr">name</span>: “test”, <span class="attr">value</span>: <span class="number">2n</span> };</span><br><span class="line"><span class="keyword">const</span> body = <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(request);</span><br><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">"https://example.com"</span>, {</span><br><span class="line"> <span class="attr">method</span>: “<span class="variable constant_">POST</span>”,</span><br><span class="line"> body,</span><br><span class="line">});</span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">ok</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure> - -<p>No errors, no linters, even though this can break your app.</p> -<p>Right now, in my head, I can hear, “What’s the problem, just use try/catch everywhere.” Here comes the third problem: we don’t know which one is thrown. Of course, we can somehow guess by the error message, but what about bigger services/functions with many places where errors can happen? Are you sure you are handling all of them properly with one try/catch?</p> -<hr> -<figure class="highlight rust"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">greeting_file_result</span> = File::<span class="title function_ invoke__">open</span>(“hello.txt”); </span><br><span class="line"><span class="keyword">let</span> <span class="variable">greeting_file</span> = <span class="keyword">match</span> greeting_file_result { </span><br><span class="line"> <span class="title function_ invoke__">Ok</span>(file) => file, </span><br><span class="line"> <span class="title function_ invoke__">Err</span>(error) => <span class="built_in">panic!</span>(<span class="string">"Problem opening the file: {:?}"</span>, error), </span><br><span class="line">};</span><br></pre></td></tr></table></figure> - -<p>The most verbose of the three shown here and, ironically, the best one. So, first of all, Rust handles the errors using its amazing enums (they are not the same as TypeScript enums!). Without going into detail, what is important here is that it uses an enum called <code>Result</code> with two variants: <code>Ok</code> and <code>Err</code>. As you might guess, <code>Ok</code> holds a value and <code>Err</code> holds…surprise, an error :D.</p> -<p>The summary here is that Rust always know where there might be an error. And it force you to deal with it right where it appears (mostly). No hidden ones, no guessing, no breaking app with a surprise face.</p> -<p>And this approach is just better. By A MILE.</p> -<p>We cannot make TypeScript errors work like the Rust. The limiting factor here is the language itself; it doesn’t have the proper tools to do that.</p> -<p>But what we can do is try to make it similar. And make it simple:</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">type</span> <span class="title class_">Safe</span><T> = </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">true</span>; </span><br><span class="line"> <span class="attr">data</span>: T; </span><br><span class="line"> } </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">false</span>; </span><br><span class="line"> <span class="attr">error</span>: <span class="built_in">string</span>; </span><br><span class="line"> };</span><br></pre></td></tr></table></figure> - -<p>we do need a few try/catches. The good thing is we only need about two, not 100,000:</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">promise</span>: <span class="title class_">Promise</span><T>, err?: <span class="built_in">string</span>): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">func</span>: <span class="function">() =></span> T, err?: <span class="built_in">string</span>): <span class="title class_">Safe</span><T>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(</span><br><span class="line"> <span class="attr">promiseOrFunc</span>: <span class="title class_">Promise</span><T> | (<span class="function">() =></span> T),</span><br><span class="line"> err?: <span class="built_in">string</span>,</span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> | <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">if</span> (promiseOrFunc <span class="keyword">instanceof</span> <span class="title class_">Promise</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeAsync</span>(promiseOrFunc, err);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeSync</span>(promiseOrFunc, err);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> safeAsync<T>(</span><br><span class="line"> <span class="attr">promise</span>: <span class="title class_">Promise</span><T>, </span><br><span class="line"> err?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> promise;</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> safeSync<T>(</span><br><span class="line"> <span class="attr">func</span>: <span class="function">() =></span> T, </span><br><span class="line"> err?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="title function_">func</span>();</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> - -<p>This is just a wrapper with our <code>Safe</code> type as the return one. But sometimes simple things are all you need. Let’s combine them with the example from above.</p> -<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> request = { <span class="attr">name</span>: “test”, <span class="attr">value</span>: <span class="number">2n</span> }; </span><br><span class="line"><span class="keyword">const</span> body = <span class="title function_">safe</span>( </span><br><span class="line"> <span class="function">() =></span> <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(request), </span><br><span class="line"> “<span class="title class_">Failed</span> to serialize request”, </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!body.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (body.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">safe</span>( </span><br><span class="line"> <span class="title function_">fetch</span>(<span class="string">"https://example.com"</span>, { </span><br><span class="line"> <span class="attr">method</span>: “<span class="variable constant_">POST</span>”, </span><br><span class="line"> <span class="attr">body</span>: body.<span class="property">data</span>, </span><br><span class="line"> }), </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (response.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">data</span>.<span class="property">ok</span>) { </span><br><span class="line"> <span class="comment">// handle network error </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="comment">// handle response (body.data)</span></span><br></pre></td></tr></table></figure> - -<p>New solution is longer, but it performs better because of the following reasons:</p> -<ul> -<li>no try/catch</li> -<li>we handle each error where it occurs</li> -<li>we can specify an error message for a specific function</li> -<li>we have a nice top-to-bottom logic, all errors on top, then only the response at the bottom</li> -</ul> -]]></content> - <tags> - <tag>Technique</tag> - </tags> - </entry> - <entry> <title>Turborepo 简述</title> <url>/2024/09/27/Turborepo-%E7%AE%80%E8%BF%B0/</url> <content><![CDATA[<h2 id="Turborepo-简介"><a href="#Turborepo-简介" class="headerlink" title="Turborepo 简介"></a>Turborepo 简介</h2><p>Monorepos 有很多优势,但它们难以扩展。每个工作区都有自己的测试套件、自己的 linting 和构建过程。单个 monorepo 可能有数千个任务要执行。</p> @@ -2353,6 +2310,49 @@ </tags> </entry> <entry> + <title>TypeScript With Rust Errors, No Try Catch, Heresy</title> + <url>/2023/04/30/TypeScript-With-Rust-Errors-No-Try-Catch-Heresy/</url> + <content><![CDATA[<blockquote> +<p>It’s hard to miss things when you don’t know different things exist</p> +</blockquote> +<p>The first problem is, and personally, I believe it’s the biggest JavaScript problem ever: we don’t know what can throw an error. From a JavaScript error perspective, it’s the same as the following:</p> +<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">let</span> data = “<span class="title class_">Hello</span>”;</span><br><span class="line">} <span class="keyword">catch</span> (err) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(err);</span><br><span class="line">}</span><br></pre></td></tr></table></figure> + +<p>JavaScript doesn’t know; JavaScript doesn’t care. You should know.</p> +<p>Second thing, this is perfectly viable code:</p> +<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> request = { <span class="attr">name</span>: “test”, <span class="attr">value</span>: <span class="number">2n</span> };</span><br><span class="line"><span class="keyword">const</span> body = <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(request);</span><br><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">"https://example.com"</span>, {</span><br><span class="line"> <span class="attr">method</span>: “<span class="variable constant_">POST</span>”,</span><br><span class="line"> body,</span><br><span class="line">});</span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">ok</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure> + +<p>No errors, no linters, even though this can break your app.</p> +<p>Right now, in my head, I can hear, “What’s the problem, just use try/catch everywhere.” Here comes the third problem: we don’t know which one is thrown. Of course, we can somehow guess by the error message, but what about bigger services/functions with many places where errors can happen? Are you sure you are handling all of them properly with one try/catch?</p> +<hr> +<figure class="highlight rust"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">greeting_file_result</span> = File::<span class="title function_ invoke__">open</span>(“hello.txt”); </span><br><span class="line"><span class="keyword">let</span> <span class="variable">greeting_file</span> = <span class="keyword">match</span> greeting_file_result { </span><br><span class="line"> <span class="title function_ invoke__">Ok</span>(file) => file, </span><br><span class="line"> <span class="title function_ invoke__">Err</span>(error) => <span class="built_in">panic!</span>(<span class="string">"Problem opening the file: {:?}"</span>, error), </span><br><span class="line">};</span><br></pre></td></tr></table></figure> + +<p>The most verbose of the three shown here and, ironically, the best one. So, first of all, Rust handles the errors using its amazing enums (they are not the same as TypeScript enums!). Without going into detail, what is important here is that it uses an enum called <code>Result</code> with two variants: <code>Ok</code> and <code>Err</code>. As you might guess, <code>Ok</code> holds a value and <code>Err</code> holds…surprise, an error :D.</p> +<p>The summary here is that Rust always know where there might be an error. And it force you to deal with it right where it appears (mostly). No hidden ones, no guessing, no breaking app with a surprise face.</p> +<p>And this approach is just better. By A MILE.</p> +<p>We cannot make TypeScript errors work like the Rust. The limiting factor here is the language itself; it doesn’t have the proper tools to do that.</p> +<p>But what we can do is try to make it similar. And make it simple:</p> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">type</span> <span class="title class_">Safe</span><T> = </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">true</span>; </span><br><span class="line"> <span class="attr">data</span>: T; </span><br><span class="line"> } </span><br><span class="line"> | { </span><br><span class="line"> <span class="attr">success</span>: <span class="literal">false</span>; </span><br><span class="line"> <span class="attr">error</span>: <span class="built_in">string</span>; </span><br><span class="line"> };</span><br></pre></td></tr></table></figure> + +<p>we do need a few try/catches. The good thing is we only need about two, not 100,000:</p> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">promise</span>: <span class="title class_">Promise</span><T>, <span class="attr">err</span>?: <span class="built_in">string</span>): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(<span class="attr">func</span>: <span class="function">() =></span> T, <span class="attr">err</span>?: <span class="built_in">string</span>): <span class="title class_">Safe</span><T>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> safe<T>(</span><br><span class="line"> <span class="attr">promiseOrFunc</span>: <span class="title class_">Promise</span><T> | (<span class="function">() =></span> T),</span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span>,</span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> | <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">if</span> (promiseOrFunc <span class="keyword">instanceof</span> <span class="title class_">Promise</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeAsync</span>(promiseOrFunc, err);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">safeSync</span>(promiseOrFunc, err);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> safeAsync<T>(</span><br><span class="line"> <span class="attr">promise</span>: <span class="title class_">Promise</span><T>, </span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Promise</span><<span class="title class_">Safe</span><T>> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="keyword">await</span> promise;</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> safeSync<T>(</span><br><span class="line"> <span class="attr">func</span>: <span class="function">() =></span> T, </span><br><span class="line"> <span class="attr">err</span>?: <span class="built_in">string</span></span><br><span class="line">): <span class="title class_">Safe</span><T> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> data = <span class="title function_">func</span>();</span><br><span class="line"> <span class="keyword">return</span> { data, <span class="attr">success</span>: <span class="literal">true</span> };</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(e);</span><br><span class="line"> <span class="keyword">if</span> (err !== <span class="literal">undefined</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: err };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: e.<span class="property">message</span> };</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> { <span class="attr">success</span>: <span class="literal">false</span>, <span class="attr">error</span>: <span class="string">"Something went wrong"</span> };</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> + +<p>This is just a wrapper with our <code>Safe</code> type as the return one. But sometimes simple things are all you need. Let’s combine them with the example from above.</p> +<figure class="highlight typescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> request = { <span class="attr">name</span>: “test”, <span class="attr">value</span>: <span class="number">2n</span> }; </span><br><span class="line"><span class="keyword">const</span> body = <span class="title function_">safe</span>( </span><br><span class="line"> <span class="function">() =></span> <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(request), </span><br><span class="line"> “<span class="title class_">Failed</span> to serialize request”, </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!body.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (body.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">safe</span>( </span><br><span class="line"> <span class="title function_">fetch</span>(<span class="string">"https://example.com"</span>, { </span><br><span class="line"> <span class="attr">method</span>: “<span class="variable constant_">POST</span>”, </span><br><span class="line"> <span class="attr">body</span>: body.<span class="property">data</span>, </span><br><span class="line"> }), </span><br><span class="line">); </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">success</span>) { </span><br><span class="line"> <span class="comment">// handle error (response.error) </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">if</span> (!response.<span class="property">data</span>.<span class="property">ok</span>) { </span><br><span class="line"> <span class="comment">// handle network error </span></span><br><span class="line"> <span class="keyword">return</span>; </span><br><span class="line">} </span><br><span class="line"><span class="comment">// handle response (body.data)</span></span><br></pre></td></tr></table></figure> + +<p>New solution is longer, but it performs better because of the following reasons:</p> +<ul> +<li>no try/catch</li> +<li>we handle each error where it occurs</li> +<li>we can specify an error message for a specific function</li> +<li>we have a nice top-to-bottom logic, all errors on top, then only the response at the bottom</li> +</ul> +]]></content> + <tags> + <tag>Technique</tag> + </tags> + </entry> + <entry> <title>WiscKey: Separating Keys from Values in SSD-conscious Storage</title> <url>/2023/07/21/WiscKey-Separating-Keys-from-Values-in-SSD-conscious-Storage/</url> <content><![CDATA[<p>We present WiscKey, a persistent LSM-tree-based key-value store with a performance-oriented data layoutthat separates keys from values to minimize I/O amplifi-cation. The design of WiscKey is highly SSD optimized, leveraging both the sequential and random performance characteristics of the device.</p> @@ -2415,6 +2415,19 @@ </tags> </entry> <entry> + <title>Linux 下 AMD 显卡屏幕画面闪烁问题修复方案</title> + <url>/2025/04/20/linux-amd-screen-boom/</url> + <content><![CDATA[<p>不知道我们所说的闪烁是不是一个东西,在我的笔记本上,闪烁是指偶发的屏幕中出现部分彩色雪花。</p> +<p>我使用 Pop!_OS,此发行版使用 EFI 启动,故而可以在 <code>/boot/efi/loader/loader.conf</code> 中加上:</p> +<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">options quiet splash amdgpu.dcdebugmask=0x10 amdgpu.sg_display=0</span><br></pre></td></tr></table></figure> + +<p>对于其他使用 EFI 或 GRUB 启动的发行版也可以添加类似的参数尝试尝试。</p> +]]></content> + <tags> + <tag>Technique</tag> + </tags> + </entry> + <entry> <title>使用 [@poll error] 实现线程安全的数据结构</title> <url>/2023/08/15/poll-error-attribute-in-OCaml/</url> <content><![CDATA[<p>OCaml的标准库提供了许多mutable的数据结构,比如Hashtbl, Queue, Stack之类的,但是这些数据结构都不是线程安全的。在 OCaml 4 和 OCaml 5 中,单个Domain中一次只能运行一个线程。换句话说,单个Domain中的线程仍然不会并行运行,除非在不同所的Domain中。</p> @@ -2453,6 +2466,32 @@ </tags> </entry> <entry> + <title>UUID v7 是如何加快 RDBMS 索引速度的</title> + <url>/2025/04/13/uuidv7-rdbms/</url> + <content><![CDATA[<p>UUID v7 之所以能显著提升关系型数据库(尤其是采用聚集索引的 MySQL InnoDB)在插入和查询速度,主要归功于它在 ID 中引入了“可排序的时间戳前缀”,从而大幅减少了 B-Tree 索引页分裂(page split)和数据碎片化。这里分几点来说:</p> +<p>一、 聚集索引(Clustered Index)的插入机制 </p> +<p>在 InnoDB 中,聚集索引的叶子节点同时存储了行数据,且按照索引键(主键)顺序物理排序。</p> +<p>当新记录的主键完全随机(如 UUID v4)时,每次插入都会随机落在 B-Tree 的不同叶子页,导致频繁的页分裂和指针重排,而页分裂和随机 I/O 会带来大量的磁盘写放大和缓存抖动(cache churn),削弱吞吐并拉高延迟。</p> +<p>二、UUID v7 的时间排序特性 </p> +<p>UUID v7 在高位(前 48 位)嵌入了以毫秒级精度的 Unix 时间戳,剩下的位用于随机数或序列号,这样生成的 ID 保持全局唯一性的同时,随着时间自然递增(即“近似单调递增”),新插入的记录几乎总是追加到 B-Tree 的最右端叶子节点。 </p> +<p>参见 dbaplus.cn 的分析: </p> +<blockquote> +<p>“UUID v7 的创新之处在于其时间排序特性,它在前 48 位中嵌入了以毫秒为单位的 Unix 时间戳……可能在插入和查询操作上提供更好的性能”【1】。</p> +</blockquote> +<p>三、降低页分裂与碎片化 </p> +<p>顺序或近似顺序的主键能使叶子节点连续增长,极少触发页分裂,并且更少的页分裂意味着更低的写放大(write amplification)和更稳定的插入延迟,同时,减少了空洞和链表重排,提高了磁盘和内存缓存的命中率。</p> +<p>四、提升查询局部性与缓存命中 </p> +<p>因为数据物理上是按时间顺序紧凑写入,时间范围查询(如 “最近 1 小时的日志”)可以快速定位连续的叶子页,I/O 更聚集,内存缓冲池(buffer pool)或操作系统页缓存能更有效地缓存最近热数据,进一步加速查询。</p> +<hr> +<p>Rimon Tawadrous 在其 GitHub repo 中的测试,对比 100 万条逐条插入实验,UUID v7 相较 UUID v4 在单线程插入上速度快约 3.24%,多线程下更可观【1】。 </p> +<hr> +<p><strong>参考链接</strong><br>[1] “为什么 UUID 7 比 UUID 4 更适合作为 RDBMS 的聚集索引?” dbaplus.cn<br> <a href="https://dbaplus.cn/news-160-6313-1.html">https://dbaplus.cn/news-160-6313-1.html</a><br>[2] “PostgreSQL and UUID as primary key” maciejwalkowiak<br> <a href="https://maciejwalkowiak.com/blog/postgres-uuid-primary-key/">https://maciejwalkowiak.com/blog/postgres-uuid-primary-key/</a><br>[3] “Optimised UUIDs in mysql” stitcher<br> <a href="https://stitcher.io/blog/optimised-uuids-in-mysql">https://stitcher.io/blog/optimised-uuids-in-mysql</a><br>[3] “Storing UUID Values in MySQL” percona<br> <a href="https://www.percona.com/blog/store-uuid-optimized-way/">https://www.percona.com/blog/store-uuid-optimized-way/</a></p> +]]></content> + <tags> + <tag>Technique</tag> + </tags> + </entry> + <entry> <title>v8中的Number.toString()</title> <url>/2023/10/05/v8%E4%B8%AD%E7%9A%84Number-toString/</url> <content><![CDATA[<p>这里讲一下JavaScript中<code>Number.toString()</code>的实现, 以V8为例。</p> @@ -2542,36 +2581,6 @@ </categories> </entry> <entry> - <title>二〇二三年十二月二日</title> - <url>/2023/12/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/</url> - <content><![CDATA[<p>夏日凌晨的海风,裹挟着季风带的温热的潮气不远万里奔赴而来,搅碎了一汪流动的星星。</p> -<p>天空泛起一丝鱼肚白,那是每年夏至,凌晨四点多就会早起的日出。</p> -<p>而身后那栋为我而建的世界上独一无二的小屋子,正通宵达旦地亮着灯火,里面是我的痕迹,我的热爱,我的温暖和祝福。</p> -<p>身前,我的山林和小狗,正笨拙地试图从自然的馈赠里找到那份属于它们的礼物。</p> -<p>它们那样爱着我,那样忠诚于我。</p> -<p>那一刻,我突然就想起了曾经在书上看过的一句很喜欢的话——“世界先爱了我,我不能不爱他.”</p> -<p>曾经在冬季日出的时候,我见过海岸线浮满碎冰的模样,那是连太阳都会显得寂寥和落寞的冷清。</p> -<p>可是太阳始终当着太阳,守着一个恒星的职责,不知疲倦地用自己炽热的温度和光芒试图唤醒沉睡的冬日。</p> -<p>直到终于有一天,有人在冬夜里复苏,爱上了那个比夏天更炽烈的温度,然后海浪成了新娘白色的花环,我成了太阳一生的爱人。</p> -<p>所以我始终愿意相信,是这个世界先温柔地爱了我。</p> -<p>哪怕世界给予我的这份爱,在最初的时候,来得并不那么明显,也并不那么浓烈,我也曾因此孤独过,无助过,迷茫过,放弃过。</p> -<p>可是那份爱最终还是随着冰雪消融,春暖花开,随着夏天剧烈摇晃过后的气泡水,滋滋地冒了出来,连盖上盖子,也没有办法捂住。</p> -<p>所以我拥有了世界上最好的义无反顾的爱。</p> -<p>看着前方,轻轻叫了一声:“毛毛”</p> -<p>狗狗立马回了头,和乍出的日光,和突然转动的风力发电机,和突然被风吹动的山林,同步发生。好像只要我一声令下,这个世界就愿意为我而生动。</p> -<p>可这世间哪里会在乎茫茫人海中这不值一提的爱</p> -<p>我们都只不过是平凡世界里平凡生活着的人们,如果非要说有什么不同,那就是我只爱着这个世界而已。</p> -<p>于是我看着那只大笨狗,看着并没有被虚化成背景的世界,温柔地弯起了唇角:“有句话今天我一直忘记告诉你了。”</p> -<p>狗狗叼起一根树枝,歪头不解地看着我。</p> -<p>然后我就在山峰浮现出第一缕阳光时,笑着对这个世界说:“我爱你,会永远爱你,永远最爱你。”</p> -<p>我爱这个因为有我而变得温柔的世界。</p> -<p>这将是我与周遭的一切,热爱一生,共度一生的地方。</p> -]]></content> - <categories> - <category>gallery</category> - </categories> - </entry> - <entry> <title>二〇二三年十二月一日</title> <url>/2023/12/01/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%B8%80%E6%97%A5/</url> <content><![CDATA[<p>他说:“路挺远的,你慢走啊。”</p> @@ -2623,6 +2632,36 @@ </categories> </entry> <entry> + <title>二〇二三年十二月二日</title> + <url>/2023/12/02/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%B8%89%E5%B9%B4%E5%8D%81%E4%BA%8C%E6%9C%88%E4%BA%8C%E6%97%A5/</url> + <content><![CDATA[<p>夏日凌晨的海风,裹挟着季风带的温热的潮气不远万里奔赴而来,搅碎了一汪流动的星星。</p> +<p>天空泛起一丝鱼肚白,那是每年夏至,凌晨四点多就会早起的日出。</p> +<p>而身后那栋为我而建的世界上独一无二的小屋子,正通宵达旦地亮着灯火,里面是我的痕迹,我的热爱,我的温暖和祝福。</p> +<p>身前,我的山林和小狗,正笨拙地试图从自然的馈赠里找到那份属于它们的礼物。</p> +<p>它们那样爱着我,那样忠诚于我。</p> +<p>那一刻,我突然就想起了曾经在书上看过的一句很喜欢的话——“世界先爱了我,我不能不爱他.”</p> +<p>曾经在冬季日出的时候,我见过海岸线浮满碎冰的模样,那是连太阳都会显得寂寥和落寞的冷清。</p> +<p>可是太阳始终当着太阳,守着一个恒星的职责,不知疲倦地用自己炽热的温度和光芒试图唤醒沉睡的冬日。</p> +<p>直到终于有一天,有人在冬夜里复苏,爱上了那个比夏天更炽烈的温度,然后海浪成了新娘白色的花环,我成了太阳一生的爱人。</p> +<p>所以我始终愿意相信,是这个世界先温柔地爱了我。</p> +<p>哪怕世界给予我的这份爱,在最初的时候,来得并不那么明显,也并不那么浓烈,我也曾因此孤独过,无助过,迷茫过,放弃过。</p> +<p>可是那份爱最终还是随着冰雪消融,春暖花开,随着夏天剧烈摇晃过后的气泡水,滋滋地冒了出来,连盖上盖子,也没有办法捂住。</p> +<p>所以我拥有了世界上最好的义无反顾的爱。</p> +<p>看着前方,轻轻叫了一声:“毛毛”</p> +<p>狗狗立马回了头,和乍出的日光,和突然转动的风力发电机,和突然被风吹动的山林,同步发生。好像只要我一声令下,这个世界就愿意为我而生动。</p> +<p>可这世间哪里会在乎茫茫人海中这不值一提的爱</p> +<p>我们都只不过是平凡世界里平凡生活着的人们,如果非要说有什么不同,那就是我只爱着这个世界而已。</p> +<p>于是我看着那只大笨狗,看着并没有被虚化成背景的世界,温柔地弯起了唇角:“有句话今天我一直忘记告诉你了。”</p> +<p>狗狗叼起一根树枝,歪头不解地看着我。</p> +<p>然后我就在山峰浮现出第一缕阳光时,笑着对这个世界说:“我爱你,会永远爱你,永远最爱你。”</p> +<p>我爱这个因为有我而变得温柔的世界。</p> +<p>这将是我与周遭的一切,热爱一生,共度一生的地方。</p> +]]></content> + <categories> + <category>gallery</category> + </categories> + </entry> + <entry> <title>二〇二五年三月十七日</title> <url>/2025/03/17/%E4%BA%8C%E3%80%87%E4%BA%8C%E4%BA%94%E5%B9%B4%E4%B8%89%E6%9C%88%E5%8D%81%E4%B8%83%E6%97%A5/</url> <content><![CDATA[<p>人类其实根本无法同时拥有对死亡的坦然和对生活的眷恋。</p> diff --git a/tags/Technique/index.html b/tags/Technique/index.html index 5169c320..aba6f836 100644 --- a/tags/Technique/index.html +++ b/tags/Technique/index.html @@ -177,14 +177,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> + <a href="/2025/04/20/linux-amd-screen-boom/"> - N+1 selects problem 与 Prisma ORM + Linux 下 AMD 显卡屏幕画面闪烁问题修复方案 </a> </div> - <span class="post-date">Apr 2, 2025</span> + <span class="post-date">Apr 20, 2025</span> </div> @@ -195,14 +195,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> + <a href="/2025/04/13/uuidv7-rdbms/"> - 在F#中处理复杂依赖注入的实践指南 + UUID v7 是如何加快 RDBMS 索引速度的 </a> </div> - <span class="post-date">Mar 31, 2025</span> + <span class="post-date">Apr 13, 2025</span> </div> @@ -213,14 +213,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> + <a href="/2025/04/02/N-1-selects-problem-%E4%B8%8E-Prisma-ORM/"> - F# 重载解析问题 + N+1 selects problem 与 Prisma ORM </a> </div> - <span class="post-date">Mar 30, 2025</span> + <span class="post-date">Apr 2, 2025</span> </div> @@ -231,14 +231,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/25/Scala-3-Capture-Checking/"> + <a href="/2025/03/31/%E5%9C%A8F-%E4%B8%AD%E5%A4%84%E7%90%86%E5%A4%8D%E6%9D%82%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/"> - Scala 3 (Capture Checking) + 在F#中处理复杂依赖注入的实践指南 </a> </div> - <span class="post-date">Mar 25, 2025</span> + <span class="post-date">Mar 31, 2025</span> </div> @@ -249,14 +249,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> + <a href="/2025/03/30/F-%E9%87%8D%E8%BD%BD%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98/"> - TDD 和 DDD 的一些小想法 + F# 重载解析问题 </a> </div> - <span class="post-date">Mar 20, 2025</span> + <span class="post-date">Mar 30, 2025</span> </div> @@ -267,14 +267,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> + <a href="/2025/03/25/Scala-3-Capture-Checking/"> - 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 + Scala 3 (Capture Checking) </a> </div> - <span class="post-date">Mar 19, 2025</span> + <span class="post-date">Mar 25, 2025</span> </div> @@ -285,14 +285,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> + <a href="/2025/03/20/TDD-%E5%92%8C-DDD-%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/"> - DDD 中的 Ubiquitous Language + TDD 和 DDD 的一些小想法 </a> </div> - <span class="post-date">Mar 14, 2025</span> + <span class="post-date">Mar 20, 2025</span> </div> @@ -303,14 +303,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> + <a href="/2025/03/19/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E8%81%9A%E5%90%88%E6%A0%B9%E6%8C%81%E4%B9%85%E5%8C%96%E5%92%8C%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E9%97%AE%E9%A2%98/"> - 领域驱动设计中的“聚合根” + 领域驱动设计中聚合根持久化和事件发布可能导致数据不一致问题 </a> </div> - <span class="post-date">Mar 13, 2025</span> + <span class="post-date">Mar 19, 2025</span> </div> @@ -321,14 +321,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/19/Repository-pattern-in-Typescript/"> + <a href="/2025/03/14/DDD-%E4%B8%AD%E7%9A%84-Ubiquitous-Languages/"> - Repository pattern in Typescript + DDD 中的 Ubiquitous Language </a> </div> - <span class="post-date">Feb 19, 2025</span> + <span class="post-date">Mar 14, 2025</span> </div> @@ -339,14 +339,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/18/Prisma-%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84-Self-relations/"> + <a href="/2025/03/13/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%9A%84%E2%80%9C%E8%81%9A%E5%90%88%E6%A0%B9%E2%80%9D/"> - Prisma 关系型数据库的 Self-relations + 领域驱动设计中的“聚合根” </a> </div> - <span class="post-date">Feb 18, 2025</span> + <span class="post-date">Mar 13, 2025</span> </div> diff --git a/tags/Technique/page/2/index.html b/tags/Technique/page/2/index.html index 0bedfb56..0ba29ac7 100644 --- a/tags/Technique/page/2/index.html +++ b/tags/Technique/page/2/index.html @@ -177,14 +177,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/11/%E4%BB%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E7%9C%8B%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/"> + <a href="/2025/02/19/Repository-pattern-in-Typescript/"> - 从事件风暴看领域驱动设计 + Repository pattern in Typescript </a> </div> - <span class="post-date">Feb 11, 2025</span> + <span class="post-date">Feb 19, 2025</span> </div> @@ -195,14 +195,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2025/02/10/%E5%AE%9E%E6%97%B6%E6%90%9C%E7%B4%A2%E4%B8%AD%E7%9A%84%E9%98%B2%E6%8A%96%E5%87%BD%E6%95%B0/"> + <a href="/2025/02/18/Prisma-%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84-Self-relations/"> - 实时搜索中的防抖函数 + Prisma 关系型数据库的 Self-relations </a> </div> - <span class="post-date">Feb 10, 2025</span> + <span class="post-date">Feb 18, 2025</span> </div> @@ -210,19 +210,17 @@ - <div class="year-title">2024</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2024/12/15/OCaml-News-2024-7/"> + <a href="/2025/02/11/%E4%BB%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E7%9C%8B%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/"> - OCaml News 2024-7 + 从事件风暴看领域驱动设计 </a> </div> - <span class="post-date">Dec 15, 2024</span> + <span class="post-date">Feb 11, 2025</span> </div> @@ -233,14 +231,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/10-Tips-for-Productive-FSharp-Scripting/"> + <a href="/2025/02/10/%E5%AE%9E%E6%97%B6%E6%90%9C%E7%B4%A2%E4%B8%AD%E7%9A%84%E9%98%B2%E6%8A%96%E5%87%BD%E6%95%B0/"> - 10 Tips for Productive FSharp Scripting + 实时搜索中的防抖函数 </a> </div> - <span class="post-date">Oct 18, 2024</span> + <span class="post-date">Feb 10, 2025</span> </div> @@ -248,17 +246,19 @@ + <div class="year-title">2024</div> + <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/Building-custom-fibers-library-in-FSharp/"> + <a href="/2024/12/15/OCaml-News-2024-7/"> - Building custom fibers library in FSharp + OCaml News 2024-7 </a> </div> - <span class="post-date">Oct 18, 2024</span> + <span class="post-date">Dec 15, 2024</span> </div> @@ -269,9 +269,9 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/18/Dealing-with-complex-dependency-injection-in-FSharp/"> + <a href="/2024/10/18/10-Tips-for-Productive-FSharp-Scripting/"> - Dealing with complex dependency injection in FSharp + 10 Tips for Productive FSharp Scripting </a> </div> @@ -287,14 +287,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/10/06/Obsidian-Vault-%E7%9A%84-obsidian-%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%90%84%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8/"> + <a href="/2024/10/18/Building-custom-fibers-library-in-FSharp/"> - Obsidian Vault 的 .obsidian 目录中的各文件作用 + Building custom fibers library in FSharp </a> </div> - <span class="post-date">Oct 6, 2024</span> + <span class="post-date">Oct 18, 2024</span> </div> @@ -305,14 +305,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/27/Turborepo-%E7%AE%80%E8%BF%B0/"> + <a href="/2024/10/18/Dealing-with-complex-dependency-injection-in-FSharp/"> - Turborepo 简述 + Dealing with complex dependency injection in FSharp </a> </div> - <span class="post-date">Sep 27, 2024</span> + <span class="post-date">Oct 18, 2024</span> </div> @@ -323,14 +323,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/15/Advanced-C-binding-using-ocaml-ctypes-and-dune/"> + <a href="/2024/10/06/Obsidian-Vault-%E7%9A%84-obsidian-%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%90%84%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8/"> - Advanced C binding using ocaml-ctypes and dune + Obsidian Vault 的 .obsidian 目录中的各文件作用 </a> </div> - <span class="post-date">Sep 15, 2024</span> + <span class="post-date">Oct 6, 2024</span> </div> @@ -341,14 +341,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/09/12/Functional-Reactive-Programming-in-F/"> + <a href="/2024/09/27/Turborepo-%E7%AE%80%E8%BF%B0/"> - Functional Reactive Programming in F# + Turborepo 简述 </a> </div> - <span class="post-date">Sep 12, 2024</span> + <span class="post-date">Sep 27, 2024</span> </div> diff --git a/tags/Technique/page/3/index.html b/tags/Technique/page/3/index.html index e7543f31..6a633673 100644 --- a/tags/Technique/page/3/index.html +++ b/tags/Technique/page/3/index.html @@ -177,14 +177,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/07/23/OCaml-News-2024-6/"> + <a href="/2024/09/15/Advanced-C-binding-using-ocaml-ctypes-and-dune/"> - OCaml News 2024-6 + Advanced C binding using ocaml-ctypes and dune </a> </div> - <span class="post-date">Jul 23, 2024</span> + <span class="post-date">Sep 15, 2024</span> </div> @@ -195,14 +195,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/07/01/OCaml-News-2024-4/"> + <a href="/2024/09/12/Functional-Reactive-Programming-in-F/"> - OCaml News 2024-4 + Functional Reactive Programming in F# </a> </div> - <span class="post-date">Jul 1, 2024</span> + <span class="post-date">Sep 12, 2024</span> </div> @@ -213,14 +213,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/06/27/OCaml-News-2024-5/"> + <a href="/2024/07/23/OCaml-News-2024-6/"> - OCaml News 2024-5 + OCaml News 2024-6 </a> </div> - <span class="post-date">Jun 27, 2024</span> + <span class="post-date">Jul 23, 2024</span> </div> @@ -231,14 +231,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/06/06/NET-AOT-%E4%B8%8B%E7%9A%84-F-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90%E5%BA%93%E9%80%89%E6%8B%A9/"> + <a href="/2024/07/01/OCaml-News-2024-4/"> - .NET AOT 下的 F# 命令行参数解析库选择 + OCaml News 2024-4 </a> </div> - <span class="post-date">Jun 6, 2024</span> + <span class="post-date">Jul 1, 2024</span> </div> @@ -249,14 +249,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/05/20/Rescript-genType-import-%E9%97%AE%E9%A2%98/"> + <a href="/2024/06/27/OCaml-News-2024-5/"> - Rescript @genType import 问题 + OCaml News 2024-5 </a> </div> - <span class="post-date">May 20, 2024</span> + <span class="post-date">Jun 27, 2024</span> </div> @@ -267,14 +267,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/04/03/shadow-cljs-proxy/"> + <a href="/2024/06/06/NET-AOT-%E4%B8%8B%E7%9A%84-F-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90%E5%BA%93%E9%80%89%E6%8B%A9/"> - shadow-cljs 怎么设置代理 + .NET AOT 下的 F# 命令行参数解析库选择 </a> </div> - <span class="post-date">Apr 3, 2024</span> + <span class="post-date">Jun 6, 2024</span> </div> @@ -285,14 +285,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/02/26/OCaml-News-2024-3/"> + <a href="/2024/05/20/Rescript-genType-import-%E9%97%AE%E9%A2%98/"> - OCaml News 2024-3 + Rescript @genType import 问题 </a> </div> - <span class="post-date">Feb 26, 2024</span> + <span class="post-date">May 20, 2024</span> </div> @@ -303,14 +303,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/23/G-Machine/"> + <a href="/2024/04/03/shadow-cljs-proxy/"> - G-Machine + shadow-cljs 怎么设置代理 </a> </div> - <span class="post-date">Jan 23, 2024</span> + <span class="post-date">Apr 3, 2024</span> </div> @@ -321,14 +321,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/22/Rescript-React-Native/"> + <a href="/2024/02/26/OCaml-News-2024-3/"> - Rescript and React Native + OCaml News 2024-3 </a> </div> - <span class="post-date">Jan 22, 2024</span> + <span class="post-date">Feb 26, 2024</span> </div> @@ -339,14 +339,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/18/OCaml-News-2024-2/"> + <a href="/2024/01/23/G-Machine/"> - OCaml News 2024-2 + G-Machine </a> </div> - <span class="post-date">Jan 18, 2024</span> + <span class="post-date">Jan 23, 2024</span> </div> diff --git a/tags/Technique/page/4/index.html b/tags/Technique/page/4/index.html index d1d86b90..60e892de 100644 --- a/tags/Technique/page/4/index.html +++ b/tags/Technique/page/4/index.html @@ -177,14 +177,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2024/01/08/OCaml-News-2024-1/"> + <a href="/2024/01/22/Rescript-React-Native/"> - OCaml News 2024-1 + Rescript and React Native </a> </div> - <span class="post-date">Jan 8, 2024</span> + <span class="post-date">Jan 22, 2024</span> </div> @@ -192,19 +192,17 @@ - <div class="year-title">2023</div> - <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/21/OCaml-Core-Int-pow-%E7%9A%84%E5%AE%9E%E7%8E%B0/"> + <a href="/2024/01/18/OCaml-News-2024-2/"> - OCaml Core.Int.pow 的实现 + OCaml News 2024-2 </a> </div> - <span class="post-date">Oct 21, 2023</span> + <span class="post-date">Jan 18, 2024</span> </div> @@ -215,14 +213,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/10/05/v8%E4%B8%AD%E7%9A%84Number-toString/"> + <a href="/2024/01/08/OCaml-News-2024-1/"> - v8中的Number.toString() + OCaml News 2024-1 </a> </div> - <span class="post-date">Oct 5, 2023</span> + <span class="post-date">Jan 8, 2024</span> </div> @@ -230,17 +228,19 @@ + <div class="year-title">2023</div> + <div class="post-list-item"> <div class="post-title"> - <a href="/2023/09/28/A-Brief-History-of-Just-In-Time/"> + <a href="/2023/10/21/OCaml-Core-Int-pow-%E7%9A%84%E5%AE%9E%E7%8E%B0/"> - A Brief History of Just-In-Time + OCaml Core.Int.pow 的实现 </a> </div> - <span class="post-date">Sep 28, 2023</span> + <span class="post-date">Oct 21, 2023</span> </div> @@ -251,14 +251,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/15/tick-thread%E5%9C%A8Multicore-OCaml%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8/"> + <a href="/2023/10/05/v8%E4%B8%AD%E7%9A%84Number-toString/"> - tick thread在Multicore OCaml中的作用 + v8中的Number.toString() </a> </div> - <span class="post-date">Aug 15, 2023</span> + <span class="post-date">Oct 5, 2023</span> </div> @@ -269,14 +269,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/08/15/poll-error-attribute-in-OCaml/"> + <a href="/2023/09/28/A-Brief-History-of-Just-In-Time/"> - 使用 [@poll error] 实现线程安全的数据结构 + A Brief History of Just-In-Time </a> </div> - <span class="post-date">Aug 15, 2023</span> + <span class="post-date">Sep 28, 2023</span> </div> @@ -287,14 +287,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/07/21/WiscKey-Separating-Keys-from-Values-in-SSD-conscious-Storage/"> + <a href="/2023/08/15/tick-thread%E5%9C%A8Multicore-OCaml%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8/"> - WiscKey: Separating Keys from Values in SSD-conscious Storage + tick thread在Multicore OCaml中的作用 </a> </div> - <span class="post-date">Jul 21, 2023</span> + <span class="post-date">Aug 15, 2023</span> </div> @@ -305,14 +305,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/28/%E9%9A%90%E8%97%8F%E4%B8%80%E4%BA%9BOCaml-Effect%E7%9A%84%E6%9C%BA%E5%88%B6%EF%BC%8C%E8%AE%A9%E5%85%B6%E8%AF%AD%E6%B3%95%E5%9C%A8%E7%B2%BE%E7%A5%9E%E4%B8%8A%E6%9B%B4%E6%8E%A5%E8%BF%91delimcc/"> + <a href="/2023/08/15/poll-error-attribute-in-OCaml/"> - 隐藏一些OCaml Effect的机制,让其语法在精神上更接近delimcc + 使用 [@poll error] 实现线程安全的数据结构 </a> </div> - <span class="post-date">Jun 28, 2023</span> + <span class="post-date">Aug 15, 2023</span> </div> @@ -323,14 +323,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/06/28/caml-release-runtime-system%E5%AF%BC%E8%87%B4%E7%9A%84%E6%AD%BB%E9%94%81%E9%97%AE%E9%A2%98/"> + <a href="/2023/07/21/WiscKey-Separating-Keys-from-Values-in-SSD-conscious-Storage/"> - caml_release_runtime_system导致的死锁问题 + WiscKey: Separating Keys from Values in SSD-conscious Storage </a> </div> - <span class="post-date">Jun 28, 2023</span> + <span class="post-date">Jul 21, 2023</span> </div> @@ -341,14 +341,14 @@ <div class="post-list-item"> <div class="post-title"> - <a href="/2023/05/24/Rust-%E9%97%AD%E5%8C%85-lifetime-may-not-live-long-enough-%E9%97%AE%E9%A2%98/"> + <a href="/2023/06/28/%E9%9A%90%E8%97%8F%E4%B8%80%E4%BA%9BOCaml-Effect%E7%9A%84%E6%9C%BA%E5%88%B6%EF%BC%8C%E8%AE%A9%E5%85%B6%E8%AF%AD%E6%B3%95%E5%9C%A8%E7%B2%BE%E7%A5%9E%E4%B8%8A%E6%9B%B4%E6%8E%A5%E8%BF%91delimcc/"> - Rust 闭包 lifetime may not live long enough 问题 + 隐藏一些OCaml Effect的机制,让其语法在精神上更接近delimcc </a> </div> - <span class="post-date">May 24, 2023</span> + <span class="post-date">Jun 28, 2023</span> </div> diff --git a/tags/Technique/page/5/index.html b/tags/Technique/page/5/index.html index fcce60ca..4208b1f9 100644 --- a/tags/Technique/page/5/index.html +++ b/tags/Technique/page/5/index.html @@ -177,6 +177,42 @@ <div class="post-list-item"> <div class="post-title"> + <a href="/2023/06/28/caml-release-runtime-system%E5%AF%BC%E8%87%B4%E7%9A%84%E6%AD%BB%E9%94%81%E9%97%AE%E9%A2%98/"> + + caml_release_runtime_system导致的死锁问题 + + </a> + </div> + + <span class="post-date">Jun 28, 2023</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> + <a href="/2023/05/24/Rust-%E9%97%AD%E5%8C%85-lifetime-may-not-live-long-enough-%E9%97%AE%E9%A2%98/"> + + Rust 闭包 lifetime may not live long enough 问题 + + </a> + </div> + + <span class="post-date">May 24, 2023</span> + </div> + + + + + + + + <div class="post-list-item"> + <div class="post-title"> <a href="/2023/05/03/Rust-NewType-%E6%A8%A1%E5%BC%8F/"> Rust NewType 模式 |
