<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>首页 on Ruoke Zhang</title>
    <link>https://ruokezhang.github.io/zh-cn/</link>
    <description>Recent content in 首页 on Ruoke Zhang</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 29 Oct 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://ruokezhang.github.io/zh-cn/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Kubernetes 基础</title>
      <link>https://ruokezhang.github.io/zh-cn/post/k8s/</link>
      <pubDate>Thu, 29 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/k8s/</guid>
      <description>&lt;p&gt;Kubernetes（K8s）用于编排容器化应用。一个集群由 Control Plane 和多个 Worker Node 组成：Control Plane 维护集群的期望状态，Worker Node 负责运行实际工作负载。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reinforcement Learning</title>
      <link>https://ruokezhang.github.io/zh-cn/ai/rl/</link>
      <pubDate>Thu, 29 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/rl/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;AI 整理笔记：&lt;/strong&gt; 本文由 AI 根据学习过程中的问题辅助整理，并非作者逐字手写。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Optimal Policy 与 Optimal Q-function&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Let $\pi^*$ denote an optimal policy, i.e. any policy $\pi^*$ s.t.&lt;/p&gt;&#xA;$$&#xA;Q^{\pi^*}(s,a) \ge Q^\pi(s,a)&#xA;$$&lt;p&gt;for every $s \in S$, $a \in A$, and any policy $\pi$.&lt;/p&gt;&#xA;&lt;p&gt;All optimal policies have the same Q-function, which is called the optimal Q-function and denoted $Q^*$.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hindsight Experience Replay (HER)</title>
      <link>https://ruokezhang.github.io/zh-cn/research/papers/rl/hindsight-experience-replay/</link>
      <pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/research/papers/rl/hindsight-experience-replay/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;AI 整理笔记：&lt;/strong&gt; 本文由 AI 根据学习过程中的问题辅助整理，并非作者逐字手写。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;30-秒结论&#34;&gt;30 秒结论&lt;/h2&gt;&#xA;&lt;p&gt;HER 的核心不是修改已经执行过的动作，而是修改观察这段轨迹时所使用的目标：即使 Agent 没有完成原目标，也可以把它实际达到的状态当作替代目标，重新计算奖励，从失败轨迹中构造出有学习信号的经验。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Learning from Hindsight for VLA Reinforcement Learning</title>
      <link>https://ruokezhang.github.io/zh-cn/research/papers/rl/learning-from-hindsight-vla-rl/</link>
      <pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/research/papers/rl/learning-from-hindsight-vla-rl/</guid>
      <description>&lt;h2 id=&#34;研究问题&#34;&gt;研究问题&lt;/h2&gt;&#xA;&lt;h2 id=&#34;learning-from-hindsight&#34;&gt;Learning from Hindsight&lt;/h2&gt;&#xA;&lt;h3 id=&#34;rollout-relabeling&#34;&gt;Rollout Relabeling&lt;/h3&gt;&#xA;&lt;p&gt;每轮训练开始时，初始化原始数据 Batch、Hindsight Batch 和旧策略：&lt;/p&gt;&#xA;$$&#xA;\mathcal B\leftarrow\varnothing,&#xA;\qquad&#xA;\widetilde{\mathcal B}\leftarrow\varnothing,&#xA;\qquad&#xA;\pi_{\theta_{\mathrm{old}}}\leftarrow\pi_\theta.&#xA;$$&lt;p&gt;之后按以下流程收集并重标记数据：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;从任务分布中采样指令 $g$，使用旧策略采集包含 $K$ 条轨迹的 Group：&lt;/p&gt;</description>
    </item>
    <item>
      <title>文生图系统设计</title>
      <link>https://ruokezhang.github.io/zh-cn/post/system_design/text_to_image/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/system_design/text_to_image/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://medium.com/pinterest-engineering/building-pinterest-canvas-a-text-to-image-foundation-model-aa34965e84d9&#34;&gt;https://medium.com/pinterest-engineering/building-pinterest-canvas-a-text-to-image-foundation-model-aa34965e84d9&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://arxiv.org/abs/2603.06453?utm_source=chatgpt.com&#34;&gt;https://arxiv.org/abs/2603.06453?utm_source=chatgpt.com&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/junfanz1/Awesome-AI-Review/blob/main/System%20Design/GenAI%20System%20Design.md#5-text-to-image&#34;&gt;https://github.com/junfanz1/Awesome-AI-Review/blob/main/System%20Design/GenAI%20System%20Design.md#5-text-to-image&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;pinterest-canvas&#34;&gt;Pinterest Canvas&lt;/h2&gt;&#xA;&lt;h3 id=&#34;text-to-image&#34;&gt;Text-To-Image&lt;/h3&gt;&#xA;&lt;p&gt;generate images conditioned on both &lt;strong&gt;text prompts&lt;/strong&gt; and &lt;strong&gt;reference images&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;1-text-to-image&#34;&gt;1. text-to-image&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Inference&#xA;&lt;ol&gt;&#xA;&lt;li&gt;对Text prompt做embedding, 得到text embedding&lt;/li&gt;&#xA;&lt;li&gt;noisy target latent和text embedding一起送进DiT，得到clean target latent&lt;/li&gt;&#xA;&lt;li&gt;clean target latent经过VAE decoder得到图片&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Training&#xA;&lt;ul&gt;&#xA;&lt;li&gt;训练数据(text prompt, real image)&lt;/li&gt;&#xA;&lt;li&gt;只训DiT。text encoder和VAE都用pretrained, 然后freeze&lt;/li&gt;&#xA;&lt;li&gt;real image经过VAE encoder得到real latent。训练时根据real latent去生成x_t&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4 id=&#34;2-multimodal-image-editing-tasks&#34;&gt;2. multimodal image editing tasks&lt;/h4&gt;&#xA;&lt;p&gt;Stage 2 starts from the trained Stage 1 text-to-image model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Visual Search</title>
      <link>https://ruokezhang.github.io/zh-cn/post/system_design/visual_search/</link>
      <pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/system_design/visual_search/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://bytebytego.com/courses/machine-learning-system-design-interview/visual-search-system&#34;&gt;bytebytego tutorial&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;dataset&#34;&gt;dataset&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;一个query image&lt;/li&gt;&#xA;&lt;li&gt;(n-1)个negative images&lt;/li&gt;&#xA;&lt;li&gt;一个positive image, 即和query image最像的image.&lt;/li&gt;&#xA;&lt;li&gt;positive image在所有images中的index label.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;build-dataset&#34;&gt;build dataset&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;human judgement: 人去annotate最像的image&lt;/li&gt;&#xA;&lt;li&gt;user interaction&#xA;&lt;ul&gt;&#xA;&lt;li&gt;noisy&lt;/li&gt;&#xA;&lt;li&gt;sparse: may not have click data available for lots of the images&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;generate similar images&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;offline-metrics&#34;&gt;Offline metrics&lt;/h2&gt;&#xA;&lt;h3 id=&#34;mean-reciprocal-rank-mrr&#34;&gt;Mean reciprocal rank (MRR)&lt;/h3&gt;&#xA;&lt;p&gt;MRR=1/m * sum(1/rank_i)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deep Learning</title>
      <link>https://ruokezhang.github.io/zh-cn/ai/deep_learning/</link>
      <pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/deep_learning/</guid>
      <description>&lt;h2 id=&#34;neural-network&#34;&gt;Neural Network&lt;/h2&gt;&#xA;&lt;h3 id=&#34;terminology&#34;&gt;terminology&lt;/h3&gt;&#xA;&lt;p&gt;比如有10000个sample，batch size为100&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;epoch: 10000个sample全部经过forward+back prop。每次epoch之后，都要进行shuffle，来确保每次选的batch由不同的sample组成&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI 模型</title>
      <link>https://ruokezhang.github.io/zh-cn/ai/models/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/models/</guid>
      <description>&lt;h2 id=&#34;clip&#34;&gt;CLIP&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://arxiv.org/pdf/2103.00020&#34;&gt;paper&lt;/a&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# image_encoder - ResNet or Vision Transformer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# text_encoder - CBOW or Text Transformer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# I[n, h, w, c] - minibatch of aligned images&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# T[n, l] - minibatch of aligned texts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# W_i[d_i, d_e] - learned proj of image to embed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# W_t[d_t, d_e] - learned proj of text to embed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# t - learned temperature parameter&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# extract feature representations of each modality&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I_f &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; image_encoder(I) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#[n, d_i]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;T_f &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; text_encoder(T) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#[n, d_t]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# joint multimodal embedding [n, d_e]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I_e &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; l2_normalize(np&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dot(I_f, W_i), axis&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#[n, d_e]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;T_e &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; l2_normalize(np&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dot(T_f, W_t), axis&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#[n, n]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# scaled pairwise cosine similarities [n, n]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;logits &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dot(I_e, T_e&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;T) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; np&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;exp(t)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# symmetric loss function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;labels &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;arange(n)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;loss_i &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; cross_entropy_loss(logits, labels, axis&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# image-to-text loss&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;loss_t &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; cross_entropy_loss(logits, labels, axis&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;) &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;loss &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; (loss_i &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; loss_t)&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;architecture&#34;&gt;architecture&lt;/h3&gt;&#xA;&lt;h4 id=&#34;image-encoder&#34;&gt;image encoder&lt;/h4&gt;&#xA;&lt;h5 id=&#34;visiontransformer&#34;&gt;VisionTransformer&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;输入：[B,3,H,W]&lt;/li&gt;&#xA;&lt;li&gt;输出：[B,output_dim]&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;23&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;24&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;25&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;26&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;27&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;28&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;29&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;30&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;31&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;32&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;33&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;34&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;35&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;36&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;VisionTransformer&lt;/span&gt;(nn&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Module):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;__init__&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, input_resolution: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, patch_size: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, width: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, layers: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, heads: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, output_dim: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;super&lt;/span&gt;()&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1e66f5&#34;&gt;__init__&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;input_resolution &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; input_resolution&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;output_dim &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; output_dim&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;conv1 &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Conv2d(in_channels&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;3&lt;/span&gt;, out_channels&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;width, kernel_size&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;patch_size, stride&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;patch_size, bias&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;False&lt;/span&gt;) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#width表示Transformer 里每个 token 的隐藏维度。&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# grid=input_resolution/patch_size&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# 经过conv1变成[B, width, grid, grid]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        scale &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; width &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;0.5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;class_embedding &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Parameter(scale &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;randn(width)) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#class token, 一个专门负责“收集整张图信息”的特殊 token&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;positional_embedding &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Parameter(scale &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;randn((input_resolution &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;//&lt;/span&gt; patch_size) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;, width)) &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# [(input_resolution//patch_size)2+1, width]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;ln_pre &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; LayerNorm(width)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;transformer &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; Transformer(width, layers, heads)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;ln_post &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; LayerNorm(width)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;proj &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Parameter(scale &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;randn(width, output_dim))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;forward&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, x: torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;Tensor):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;conv1(x)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# shape = [*, width, grid, grid]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;reshape(x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;shape[&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;], x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;shape[&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;], &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# shape = [*, width, grid ** 2]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;permute(&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# shape = [*, grid ** 2, width]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;cat([&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;class_embedding&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;to(x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dtype) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; torch&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;zeros(x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;shape[&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;], &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;, x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;shape[&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;], dtype&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dtype, device&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;device), x], dim&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# shape = [*, grid ** 2 + 1, width]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;positional_embedding&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;to(x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;dtype)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;ln_pre(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;permute(&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# NLD -&amp;gt; LND&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;transformer(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;permute(&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;)  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# LND -&amp;gt; NLD&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;ln_post(x[:, &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;, :])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;proj &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;None&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;@&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;proj&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; x&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;text-encoder&#34;&gt;text encoder&lt;/h4&gt;&#xA;&lt;h4 id=&#34;embedding-space&#34;&gt;embedding space&lt;/h4&gt;</description>
    </item>
    <item>
      <title>Computer Vision</title>
      <link>https://ruokezhang.github.io/zh-cn/ai/computer_vision/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/computer_vision/</guid>
      <description>&lt;h2 id=&#34;vit&#34;&gt;ViT&lt;/h2&gt;&#xA;&lt;h3 id=&#34;funnel-vit&#34;&gt;Funnel ViT&lt;/h3&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://proceedings.neurips.cc/paper_files/paper/2020/file/2cd2915e69546904e4e5d4a2ac9e1652-Paper.pdf&#34;&gt;paper&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;object-detection&#34;&gt;Object Detection&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://cs231n.stanford.edu/slides/2026/lecture_9.pdf&#34;&gt;slides&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;single-object&#34;&gt;Single Object&lt;/h3&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/zh-cn/AI/single_object.png&#34; alt=&#34;alt text&#34;&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;label是：Cat + (x&amp;rsquo;, y&amp;rsquo;, w&amp;rsquo;, h&#39;)&lt;/li&gt;&#xA;&lt;li&gt;x, y = box 左上角的位置，w = box 宽度，h = box 高度，这些是人工标注的&lt;/li&gt;&#xA;&lt;li&gt;CNN把图片变成4096维向量&#xA;&lt;ul&gt;&#xA;&lt;li&gt;classification head：Fully connected，4096 -&amp;gt; 1000，输出1000个类别的分数, 做softmax&lt;/li&gt;&#xA;&lt;li&gt;localization head：Fully connected: 4096 -&amp;gt; 4，输出predicted box = (x, y, w, h)，这些是&lt;strong&gt;连续值&lt;/strong&gt;，用&lt;strong&gt;L2 loss&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Total Loss = Softmax Loss + L2 Loss&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;r-cnn&#34;&gt;R-CNN&lt;/h3&gt;&#xA;&lt;p&gt;R-CNN uses &lt;strong&gt;Selective Search&lt;/strong&gt; to generate around 2000 &lt;strong&gt;region proposals&lt;/strong&gt;, warps each proposal to a fixed 224×224 image, then runs a CNN on each region to classify it and later refine the box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ML Basic</title>
      <link>https://ruokezhang.github.io/zh-cn/ai/ml_basic/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/ml_basic/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/andrewekhalel/MLQuestions&#34;&gt;https://github.com/andrewekhalel/MLQuestions&lt;/a&gt;&#xA;&lt;a href=&#34;https://www.1point3acres.com/bbs/forum.php?mod=viewthread&amp;amp;tid=998257&amp;amp;page=1&amp;amp;extra=&#34;&gt;https://www.1point3acres.com/bbs/forum.php?mod=viewthread&amp;tid=998257&amp;page=1&amp;extra=&lt;/a&gt;&#xA;&lt;a href=&#34;https://longxingtan.gitbook.io/mle-interview/02_ml&#34;&gt;https://longxingtan.gitbook.io/mle-interview/02_ml&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;supervised-learning&#34;&gt;supervised learning&lt;/h2&gt;&#xA;&lt;p&gt;training data includes both the input features and corresponding target labels&lt;/p&gt;&#xA;&lt;h3 id=&#34;classification&#34;&gt;classification&lt;/h3&gt;&#xA;&lt;h4 id=&#34;logistic-regression&#34;&gt;Logistic Regression&lt;/h4&gt;&#xA;&lt;p&gt;linear classification， 二分&lt;br&gt;&#xA;loss function: Binary Cross-Entropy Loss&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/zh-cn/post/interview/images/logistic_regression.png&#34; alt=&#34;alt text&#34;&gt;&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/zh-cn/post/interview/images/logistic_regression_loss.png&#34; alt=&#34;alt text&#34;&gt;&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;logistic regression有closed form 解嘛？&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;没有闭式解。虽然loss function 是convex的，但求导后得到的是含指数项的&lt;strong&gt;非线性方程&lt;/strong&gt;，无法通过求导令其等于 0，解出 w 和 b 的解析表达式，所以只能用gradient decesent&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dynamo</title>
      <link>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems_blog/</link>
      <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems_blog/</guid>
      <description>&lt;h2 id=&#34;dynamo&#34;&gt;Dynamo&lt;/h2&gt;&#xA;&lt;h3 id=&#34;virtual-nodes&#34;&gt;virtual nodes&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;compared to basic consistent hashing, each node is assigned to multiple points on the ring&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;advantages&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;If a node becomes unavailable, the load handled by this node is evenly dispersed across the remaining available nodes.&lt;/li&gt;&#xA;&lt;li&gt;When a new node is added to the system, the new node accepts a roughly equivalent amount of load from each of the other available nodes.&lt;/li&gt;&#xA;&lt;li&gt;The number of virtual nodes that a node is responsible for can be decided based on its capacity, accounting for heterogeneity in the physical infrastructure.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;solved consistent hashing&amp;rsquo;s problems&lt;/p&gt;</description>
    </item>
    <item>
      <title>Distributed Systems</title>
      <link>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems/</guid>
      <description>&lt;h2 id=&#34;rpc-basic&#34;&gt;RPC Basic&lt;/h2&gt;&#xA;&lt;p&gt;protobuf IDL&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;define .proto file，定义Request, Response格式，函数签名&lt;/li&gt;&#xA;&lt;li&gt;protobuf自动生成CalculatorStub&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;channel &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; grpc.&lt;span style=&#34;color:#1e66f5&#34;&gt;insecure_channel&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;服务端IP:端口&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;#&lt;/span&gt; 客户端Stub&lt;span style=&#34;color:#d20f39&#34;&gt;（&lt;/span&gt;服务端函数的&lt;span style=&#34;color:#d20f39&#34;&gt;“&lt;/span&gt;本地替身&lt;span style=&#34;color:#d20f39&#34;&gt;”）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;stub &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; CalculatorStub(channel)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;#&lt;/span&gt; 调用Stub的Add方法&lt;span style=&#34;color:#d20f39&#34;&gt;（&lt;/span&gt;感觉和调用本地函数一样&lt;span style=&#34;color:#d20f39&#34;&gt;）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;request &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; AddRequest(num1&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;2, num2&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;3)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;response &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; stub.&lt;span style=&#34;color:#1e66f5&#34;&gt;Add&lt;/span&gt;(request)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;server side实现add的具体逻辑&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;semantics&#34;&gt;Semantics&lt;/h3&gt;&#xA;&lt;p&gt;At most once&lt;/p&gt;</description>
    </item>
    <item>
      <title>File System</title>
      <link>https://ruokezhang.github.io/zh-cn/post/os/file_system/</link>
      <pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/os/file_system/</guid>
      <description>&lt;h2 id=&#34;文件系统&#34;&gt;文件系统&lt;/h2&gt;&#xA;&lt;h3 id=&#34;inode&#34;&gt;inode&lt;/h3&gt;&#xA;&lt;p&gt;每个文件都有唯一的 inode, &lt;strong&gt;只在当前文件系统唯一&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;存放的信息有&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;文件权限（File Permissions）：读（r=read）、写（w=write）、执行（x=execute），示例：rw-r&amp;ndash;r&amp;ndash;（所有者可读可写，所属组和其他用户仅可读）&lt;/li&gt;&#xA;&lt;li&gt;文件所有者和所属组（File Owner &amp;amp; Group）：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;所有者 UID（User ID）&lt;/li&gt;&#xA;&lt;li&gt;所属组 GID（Group ID）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;文件大小（File Size）：单位字节（Byte），区分普通文件（存储内容大小）和目录文件（存储目录项的大小）&lt;/li&gt;&#xA;&lt;li&gt;时间戳（Timestamps）：3 个核心时间属性&#xA;&lt;ul&gt;&#xA;&lt;li&gt;ctime（Change Time）：inode 元数据修改时间（如权限、所有者变更）&lt;/li&gt;&#xA;&lt;li&gt;mtime（Modify Time）：文件内容修改时间&lt;/li&gt;&#xA;&lt;li&gt;atime（Access Time）：文件内容最后访问时间&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;数据块指针（Data Block Pointers）：最核心字段，直接或间接指向存储文件内容的数据块物理地址&lt;/li&gt;&#xA;&lt;li&gt;链接数（Link Count）：指向该 inode 的硬链接数量，默认新建文件时 link count = 1&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;读取普通文件的流程&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java RPC</title>
      <link>https://ruokezhang.github.io/zh-cn/post/personal_projects/java_rpc/</link>
      <pubDate>Tue, 30 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/personal_projects/java_rpc/</guid>
      <description>&lt;h2 id=&#34;rpc和http的区别&#34;&gt;RPC和HTTP的区别&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;RPC has small header overhead, 能灵活定制传输格式&lt;/li&gt;&#xA;&lt;li&gt;服务发现：服务提供者启动时自动注册，消费者通过注册中心动态发现服务地址&lt;/li&gt;&#xA;&lt;li&gt;负载均衡：RPC 在客户端实现负载均衡&lt;/li&gt;&#xA;&lt;li&gt;容错机制：我的项目实现了重试（Retry）、熔断（Circuit Breaker）和限流（Rate Limiting）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;serialization&#34;&gt;Serialization&lt;/h2&gt;&#xA;&lt;h3 id=&#34;kyro&#34;&gt;Kyro&lt;/h3&gt;&#xA;&lt;p&gt;速度快，体积小，只支持序列化和反序列化Java对象，线程不安全&lt;/p&gt;</description>
    </item>
    <item>
      <title>读写分离&amp;分表分库</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/performance/</link>
      <pubDate>Wed, 17 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/performance/</guid>
      <description>&lt;h2 id=&#34;读写分离&#34;&gt;读写分离&lt;/h2&gt;&#xA;&lt;h3 id=&#34;常见架构&#34;&gt;常见架构&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;一主多从&lt;/li&gt;&#xA;&lt;li&gt;主主互备 + 多从：两个主库互为主从，解决主库单点故障，读请求仍走从库&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;实现&#34;&gt;实现&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在业务和数据库之间加一层代理（MySQL Router），由它把读写请求分发给不同节点&lt;/li&gt;&#xA;&lt;li&gt;第三方组件（sharding-jdbc）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;分库分表&#34;&gt;分库分表&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;单表的数据达到千万级别以上-&amp;gt;分表&lt;/li&gt;&#xA;&lt;li&gt;单库的 CPU/IO/ 连接数达到上限-&amp;gt;分库&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;路由规则&#34;&gt;路由规则&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;哈希路由（取模）&lt;/li&gt;&#xA;&lt;li&gt;范围路由 （user_id 1&lt;del&gt;100 万→库 0，101&lt;/del&gt;200 万→库 1）&lt;/li&gt;&#xA;&lt;li&gt;一致性哈希（把 key 和节点映射到同一个哈希环上，key 顺时针找到第一个节点作为归属节点）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;数据迁移&#34;&gt;数据迁移&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;停机迁移：在半夜做&lt;/li&gt;&#xA;&lt;li&gt;双写：所有写操作同时写入旧存储和新存储，后台异步迁移旧存储中双写前的历史数据到新存储，对比新旧存储的数据，修正不一致的数据&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;分布式事务&#34;&gt;分布式事务&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;分布式ID（订单ID）。比如“订单库写订单 + 库存库扣库存 + 用户库减余额”涉及到三个库，&lt;/li&gt;&#xA;&lt;li&gt;本地消息表 + 消息队列&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在一个 MySQL 单机事务里，同时完成两件事：创建订单+扣库存。一是往order表里面添加order，二是在msg_table里添加“扣库存消息”&lt;/li&gt;&#xA;&lt;li&gt;异步线程扫一遍msg_table，把消息都发给message queue&lt;/li&gt;&#xA;&lt;li&gt;消费者执行跨库操作。如果不成功，MQ会自动重试&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Kafka</title>
      <link>https://ruokezhang.github.io/zh-cn/post/kafka/</link>
      <pubDate>Sat, 06 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/kafka/</guid>
      <description>&lt;h2 id=&#34;architecture&#34;&gt;architecture&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;同一个topic的partition不会跨cluster&lt;/li&gt;&#xA;&lt;li&gt;一个broker里面可能含有不同topic的partition&lt;/li&gt;&#xA;&lt;li&gt;partition在存储上可以被看作为一个可追加的日志文件，每条消息加进去的时候带有一个offset&lt;/li&gt;&#xA;&lt;li&gt;fault-tolerant: 多个节点故障时，集群仍能持续提供服务且数据不丢失。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;同一个partition会有多个replica,每个replica要么是leader（只有一个）, 要么是follower&lt;/li&gt;&#xA;&lt;li&gt;同一个broker里面不会有同一个partition的多个replica&lt;/li&gt;&#xA;&lt;li&gt;同一个broker里面会有同一个topic的不同的partition&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;一群broker中有一个是controller,它不负责消息的传递，只负责选举partition的新leader&lt;/li&gt;&#xA;&lt;li&gt;Zookeeper: 管理broker的状态&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;partiton&#34;&gt;partiton&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;高并发：多个producer可以向多个partition同时写入&lt;/li&gt;&#xA;&lt;li&gt;Kafka 只保证在单个 Partition 内消息的顺序性&lt;/li&gt;&#xA;&lt;li&gt;高可用：多个replica&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;leader&#34;&gt;leader&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;负责读写&lt;/li&gt;&#xA;&lt;li&gt;Leader 负责管理 In-Sync Replicas（同步副本集）。它要确保 Follower 能跟上自己的进度，将落后的 Follower 踢出 ISR。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;ISR：如果一个 Follower 在replica.lag.time.max.ms时间内没有发送pull request,它就会被踢出ISR&lt;/li&gt;&#xA;&lt;li&gt;ISR存放在zookeeper中，controller broker会查看ISR中的信息，以方便知道每个partition的follwer是否跟上了它们的leader&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;follower&#34;&gt;follower&lt;/h3&gt;&#xA;&lt;p&gt;定期向leader发送&lt;strong&gt;pull&lt;/strong&gt;请求&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于</title>
      <link>https://ruokezhang.github.io/zh-cn/about/</link>
      <pubDate>Sun, 07 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/about/</guid>
      <description>&lt;h1 id=&#34;关于我&#34;&gt;关于我&lt;/h1&gt;&#xA;&lt;p&gt;我正在从软件工程转向机器学习。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;目前感兴趣的方向：&lt;/strong&gt; Agentic AI&lt;/li&gt;&#xA;&lt;li&gt;喜欢自学，也喜欢探索新工具。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;2025-2027: 华盛顿大学，电子与计算机工程，硕士&lt;/p&gt;&#xA;&lt;p&gt;2021-2024: 俄亥俄州立大学，数学&amp;amp;计算机，双学位学士&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bit Manipulation</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/bit_manipulation/</link>
      <pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/bit_manipulation/</guid>
      <description>&lt;h2 id=&#34;常见操作&#34;&gt;常见操作&lt;/h2&gt;&#xA;&lt;p&gt;x.bit_count()：返回x的二进制表示中，有几个1。也可以理解为，x最少需要用几个2的幂次之和来表示。&lt;/p&gt;&#xA;&lt;h2 id=&#34;脑筋急转弯&#34;&gt;脑筋急转弯&lt;/h2&gt;&#xA;&lt;h4 id=&#34;2749-得到整数零需要执行的最少操作数&#34;&gt;2749. 得到整数零需要执行的最少操作数&lt;/h4&gt;&#xA;&lt;p&gt;设x = num1 - k * num2，则问题转化为：能否用k个2的幂次（允许重复）表示x？&lt;/p&gt;</description>
    </item>
    <item>
      <title>Math</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/math/</link>
      <pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/math/</guid>
      <description>&lt;h2 id=&#34;运算规则&#34;&gt;运算规则&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;//：向下取zheng&lt;/li&gt;&#xA;&lt;li&gt;int(): 向0取整&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;质数&#34;&gt;质数&lt;/h2&gt;&#xA;&lt;h3 id=&#34;埃氏筛&#34;&gt;埃氏筛&lt;/h3&gt;&#xA;&lt;p&gt;比如想找到[2, right]中的所有质数&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# 时间复杂度 O(right * log log right)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;is_prime &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#fe640b&#34;&gt;True&lt;/span&gt;]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt;(right&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;is_prime[&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;is_prime[&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;False&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;range&lt;/span&gt;(&lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;, isqrt(right)&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; is_prime[i]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; j &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;range&lt;/span&gt;(i &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; i, right&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt; i):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            is_prime[j] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;False&lt;/span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;204-计数质数&#34;&gt;204. 计数质数&lt;/h4&gt;&#xA;&lt;p&gt;p[i]表示小于等于i的质数数量。从i=2开始，p[i]==0 &amp;lt;=&amp;gt; i是质数。则从i&lt;em&gt;i开始，标记i的倍数为合数（通过令p[i&lt;/em&gt;k]=-1来实现）。并且，p[i]被赋值为p[i-1]+1&lt;/p&gt;</description>
    </item>
    <item>
      <title>string</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/string/</link>
      <pubDate>Mon, 18 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/string/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/3144832/fen-xiang-gun-ti-dan-zi-fu-chuan-kmpzhan-ugt4/&#34;&gt;题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;kmp&#34;&gt;KMP&lt;/h3&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.zhihu.com/question/21923021/answer/37475572&#34;&gt;https://www.zhihu.com/question/21923021/answer/37475572&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;28-找出字符串中第一个匹配项的下标&#34;&gt;28. 找出字符串中第一个匹配项的下标&lt;/h4&gt;&#xA;&lt;p&gt;模式串：abababzababab&lt;/p&gt;&#xA;&lt;p&gt;第一步：一边遍历模式串，一边构造next数组。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;next[i]表示字符串s[0:i+1]的前缀和后缀&lt;strong&gt;最大的&lt;/strong&gt;公共长度&lt;/li&gt;&#xA;&lt;li&gt;初始化j=0，i从1遍历到n-1。j的位置表示，此时s[:j]是公共前后缀&lt;/li&gt;&#xA;&lt;li&gt;遍历时，如果&lt;strong&gt;此时有公共前后缀&lt;/strong&gt;，不断比较s[i]和s[j]，一旦发现他们不同，则&lt;strong&gt;在循环中回退j，直到s[:j]成为公共前后缀&lt;/strong&gt;。回退到此时的&lt;strong&gt;次长公共前后缀&lt;/strong&gt;，将j移动到next[j-1]即可&lt;/li&gt;&#xA;&lt;li&gt;再次比较s[i]和s[j]，如果相同，则移动j，并且为next[i]赋值&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;第二步：比较两个字符串&lt;br&gt;&#xA;abeababeabf&lt;br&gt;&#xA;abeabf&lt;/p&gt;</description>
    </item>
    <item>
      <title>网络</title>
      <link>https://ruokezhang.github.io/zh-cn/post/network/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/network/</guid>
      <description>&lt;h2 id=&#34;tcp-可靠传输&#34;&gt;TCP 可靠传输&lt;/h2&gt;&#xA;&lt;h3 id=&#34;tcp-重传&#34;&gt;TCP 重传&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;超时重传：设置一个计时器，时间应略长于RTT。如果超时了还没有收到ACK，则立即重传&lt;/li&gt;&#xA;&lt;li&gt;快速重传：当连续收到三个相同的 ACK 时，立即重传&lt;/li&gt;&#xA;&lt;li&gt;SACK（选择性确认）：接收方可以告诉发送方接收到了哪几个消息，还缺哪个消息&lt;/li&gt;&#xA;&lt;li&gt;DSACK（重复确认）：接收方收到两个2，就会用DSACK告诉发送方，它有两个 2，别重传了。只是因为网络延迟问题。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;流量控制--拥塞控制&#34;&gt;流量控制 &amp;amp; 拥塞控制&lt;/h3&gt;&#xA;&lt;h4 id=&#34;流量控制&#34;&gt;流量控制&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;核心机制：&lt;strong&gt;滑动窗口（接收窗口 rwnd）&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;实现逻辑：接收方通过 ACK 报文通告当前可用缓冲区大小（rwnd），发送方实际发送窗口 = min(拥塞窗口 cwnd, 接收窗口 rwnd)&lt;/li&gt;&#xA;&lt;li&gt;目的：防止发送方速率超过接收方处理能力，避免接收缓冲区溢出&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4 id=&#34;拥塞控制基于拥塞窗口-cwnd单位mss&#34;&gt;拥塞控制（基于拥塞窗口 cwnd，单位：MSS）&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;慢启动阶段&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>系统设计</title>
      <link>https://ruokezhang.github.io/zh-cn/post/system_deigsn/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/system_deigsn/</guid>
      <description>&lt;h2 id=&#34;cap&#34;&gt;CAP&lt;/h2&gt;&#xA;&lt;p&gt;Consistency：所有节点同时看到相同的数据（强一致性）。&lt;/p&gt;&#xA;&lt;p&gt;Availability: 99.999%的成功率，一年之内只有5分钟系统不可用&lt;/p&gt;&#xA;&lt;p&gt;Partition Tolerance：系统在网络分区时仍能继续工作。&lt;/p&gt;</description>
    </item>
    <item>
      <title>贪心</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/greedy/</link>
      <pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/greedy/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/g6KTKL/&#34;&gt;灵神题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;300-最长递增子序列&#34;&gt;300. 最长递增子序列&lt;/h4&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1ub411Q7sB/?vd_source=3417d90294dd8bcb1cc2b3dc8bc1ef3c&#34;&gt;灵神视频&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;定义 g[i] 表示长为 i+1 的上升子序列的末尾元素的最小值。&lt;/p&gt;&#xA;&lt;p&gt;反证法可证明：g是一个严格递增的数组&lt;/p&gt;&#xA;&lt;h4 id=&#34;659-分割数组为连续子序列&#34;&gt;659. 分割数组为连续子序列&lt;/h4&gt;&#xA;&lt;p&gt;tail[i]用来表示，以i结尾的子序列个数。这样在遇到i+1时，就可以放进去了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL日志</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/log/</link>
      <pubDate>Wed, 26 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/log/</guid>
      <description>&lt;p&gt;所有DML操作（INSERT/UPDATE/DELETE）都先在Buffer Pool中完成&lt;/p&gt;&#xA;&lt;h2 id=&#34;redo-log&#34;&gt;redo log&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1Dr4y197ai/?spm_id_from=333.1391.0.0&amp;amp;vd_source=3417d90294dd8bcb1cc2b3dc8bc1ef3c&#34;&gt;视频讲解&lt;/a&gt;&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/redoLog.png&#34; alt=&#34;Alt text&#34;&gt;&#xA;实现事务的持久性。redo log先刷盘，脏页再刷盘&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis面试题整理</title>
      <link>https://ruokezhang.github.io/zh-cn/post/redis/redis_interview/</link>
      <pubDate>Tue, 25 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/redis/redis_interview/</guid>
      <description>&lt;h2 id=&#34;zset&#34;&gt;Zset&lt;/h2&gt;&#xA;&lt;h3 id=&#34;压缩列表&#34;&gt;压缩列表&lt;/h3&gt;&#xA;&lt;p&gt;当元素数量 ≤ zset-max-ziplist-entries（默认128）且所有元素长度 ≤ zset-max-ziplist-value（默认64字节）时使用，内存紧凑。&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL常见面试题</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/mysql_interview/</link>
      <pubDate>Mon, 24 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/mysql_interview/</guid>
      <description>&lt;h2 id=&#34;存储引擎对比&#34;&gt;存储引擎对比&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;InnoDB中主键索引和数据放在一起，主键索引的B+树里放完整的数据行；MyISAM中索引和数据分开放，B树里存索引值和该行的物理地址&lt;/li&gt;&#xA;&lt;li&gt;InnoDB 支持 ACID 事务，MyISAM 不支持&lt;/li&gt;&#xA;&lt;li&gt;InnoDB支持行级锁，MyISAM 不支持&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;innodb的可重复读隔离级别下解决幻读&#34;&gt;InnoDB的可重复读隔离级别下解决幻读&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;对于快照读(普通SELECT)：通过MVCC，可重复读隔离级别，在&lt;strong&gt;事务第一次查询&lt;/strong&gt;时创建ReadView&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java后端面试</title>
      <link>https://ruokezhang.github.io/zh-cn/post/interview/</link>
      <pubDate>Wed, 19 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/interview/</guid>
      <description>&lt;h2 id=&#34;面经&#34;&gt;面经&lt;/h2&gt;&#xA;&lt;h3 id=&#34;20250319-小红书日常一面&#34;&gt;2025.03.19 小红书日常一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;IO和NIO的区别&lt;/li&gt;&#xA;&lt;li&gt;JVM内存模型，堆里面具体有哪些东西&lt;/li&gt;&#xA;&lt;li&gt;手写监听者模式/单例模式&lt;/li&gt;&#xA;&lt;li&gt;ThreadLocal实现原理，并发安全吗，map里面放什么东西，内存泄露如何排查&lt;/li&gt;&#xA;&lt;li&gt;get请求里面放什么，参数如何区分&lt;/li&gt;&#xA;&lt;li&gt;讲一下泛型，泛型类的字节码文件是怎样的。&lt;/li&gt;&#xA;&lt;li&gt;Spring 注解，RequestBody什么用处&lt;/li&gt;&#xA;&lt;li&gt;ArrayList如何扩容&lt;/li&gt;&#xA;&lt;li&gt;虚拟机栈有多大？一个栈帧有多大？&lt;/li&gt;&#xA;&lt;li&gt;SQL的UPDATE语句的准确写法&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250320-sap日常二面&#34;&gt;2025.03.20 SAP日常二面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;two sum, three sum&lt;/li&gt;&#xA;&lt;li&gt;缓存空值有问题，应选择布隆过滤器&lt;/li&gt;&#xA;&lt;li&gt;限流&lt;/li&gt;&#xA;&lt;li&gt;Zookeeper 了解吗（因为我讲 Redisson 的时候提到了）&lt;/li&gt;&#xA;&lt;li&gt;如果用户名+密码登录，如何保证数据安全。如何加密？RSA？&lt;/li&gt;&#xA;&lt;li&gt;点评项目中，点赞数量太多怎么办。（大 key问题）&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250320-阿里云暑期一面&#34;&gt;2025.03.20 阿里云暑期一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;前缀树：输入法提示&lt;/li&gt;&#xA;&lt;li&gt;Redis内部有锁吗&lt;/li&gt;&#xA;&lt;li&gt;讲讲SETNX&lt;/li&gt;&#xA;&lt;li&gt;sorted set的底层实现&lt;/li&gt;&#xA;&lt;li&gt;RDB，AOF的优缺点&lt;/li&gt;&#xA;&lt;li&gt;分布式锁&lt;/li&gt;&#xA;&lt;li&gt;登录验证，为什么要把token存在redis里面，还有更好的方法吗？了解Oauth2吗？&lt;/li&gt;&#xA;&lt;li&gt;ThreadLocal 使用的时候需要注意什么问题？&lt;/li&gt;&#xA;&lt;li&gt;是先拿锁，再判断库存；还是先在 lua 脚本里面判断库存，再拿锁&lt;/li&gt;&#xA;&lt;li&gt;有对商户列表做缓存吗？如何解决按照不同的条件排序还能做到缓存？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250321-paypal上海-full-stack-暑期实习一面&#34;&gt;2025.03.21 PayPal上海 full stack 暑期实习一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;合并排序数组&lt;/li&gt;&#xA;&lt;li&gt;数字符串里面一共有多少个 palindrome&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250322-月之暗面搜推实习一面&#34;&gt;2025.03.22 月之暗面搜推实习一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;协程&lt;/li&gt;&#xA;&lt;li&gt;讲讲go reduce这个项目的细节&lt;/li&gt;&#xA;&lt;li&gt;手写单例模式，除了双重检验锁，还有什么别的方法可以实现吗？懒汉/饿汉。为什么加 volatile，禁止指令重排序，开辟空间，（实例化，分配给该对象）。&lt;/li&gt;&#xA;&lt;li&gt;Redis的数据结构，为什么不用string而是用hash，我说少一步序列化操作&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250324-sap日常二面&#34;&gt;2025.03.24 SAP日常二面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;为什么用Kafka？优点；用的是Confluent Kafka吗？&lt;/li&gt;&#xA;&lt;li&gt;讲讲对分布式锁的理解，项目代码里面如何实现？我回答MultiLock.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250325-字节暑期一面&#34;&gt;2025.03.25 字节暑期一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;如果某条 SQL 执行太慢，怎么排查，用过什么工具。联表查询：小表驱动大表。&lt;/li&gt;&#xA;&lt;li&gt;EXPLAIN 会出现一个表格，表格最后有一个 extra column，请介绍&lt;/li&gt;&#xA;&lt;li&gt;方法区里面有什么？&lt;/li&gt;&#xA;&lt;li&gt;讲一讲 G1&lt;/li&gt;&#xA;&lt;li&gt;为什么需要四次挥手？client 最后为什么要 wait？&lt;/li&gt;&#xA;&lt;li&gt;讲一讲建立HTTPS连接的过程&lt;/li&gt;&#xA;&lt;li&gt;手撕 48 和 3&lt;/li&gt;&#xA;&lt;li&gt;MySQL主从复制讲一下&lt;/li&gt;&#xA;&lt;li&gt;讲一下Spring的AOP，并且除了动态代理的实现，还有什么实现方法？ASM 字节码操作。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250326-paypal暑期二面&#34;&gt;2025.03.26 PayPal暑期二面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;手写快排&lt;/li&gt;&#xA;&lt;li&gt;为啥要把用户信息存到ThreadLocal里面去&lt;/li&gt;&#xA;&lt;li&gt;filter和interceptor的区别&lt;/li&gt;&#xA;&lt;li&gt;interceptor 和 AOP的区别&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250327-字节暑期二面&#34;&gt;2025.03.27 字节暑期二面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;合并 k个有序数组&lt;/li&gt;&#xA;&lt;li&gt;讲讲 redo log&lt;/li&gt;&#xA;&lt;li&gt;讲讲MySQL锁&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250327-初创团队实习&#34;&gt;2025.03.27 初创团队实习&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;有用过AWS实现多个服务之间通信吗？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;20250401-淘天暑期一面&#34;&gt;2025.04.01 淘天暑期一面&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;讲SpringMVC如何处理请求&lt;/li&gt;&#xA;&lt;li&gt;联合索引最左匹配&lt;/li&gt;&#xA;&lt;li&gt;线程池&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;202512-tt-一面&#34;&gt;2025.12 TT 一面&lt;/h3&gt;&#xA;&lt;p&gt;拓扑排序：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java反射&amp;动态代理</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/javabasic/reflection/</link>
      <pubDate>Tue, 18 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/javabasic/reflection/</guid>
      <description>&lt;h2 id=&#34;反射&#34;&gt;反射&lt;/h2&gt;&#xA;&lt;p&gt;反射是Java在&lt;strong&gt;运行时&lt;/strong&gt;动态&lt;strong&gt;获取类的信息&lt;/strong&gt;（如类名、方法、属性、构造方法等）并&lt;strong&gt;操作类&lt;/strong&gt;的能力&lt;/p&gt;&#xA;&lt;h3 id=&#34;api&#34;&gt;API&lt;/h3&gt;&#xA;&lt;h4 id=&#34;获取class对象&#34;&gt;获取Class对象&lt;/h4&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;String str&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Class&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; clazz &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; String.&lt;span style=&#34;color:#1e66f5&#34;&gt;class&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;String str &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Class&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; clazz &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; str.&lt;span style=&#34;color:#1e66f5&#34;&gt;getClass&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Class&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; clazz &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; Class.&lt;span style=&#34;color:#1e66f5&#34;&gt;forName&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;java.lang.String&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;通过反射创建对象&#34;&gt;通过反射创建对象&lt;/h4&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Class&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; clazz &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; Class.&lt;span style=&#34;color:#1e66f5&#34;&gt;forName&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;com.example.User&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Object obj &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; clazz.&lt;span style=&#34;color:#1e66f5&#34;&gt;getDeclaredConstructor&lt;/span&gt;().&lt;span style=&#34;color:#1e66f5&#34;&gt;newInstance&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Constructor&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; constructor &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; clazz.&lt;span style=&#34;color:#1e66f5&#34;&gt;getConstructor&lt;/span&gt;(String.&lt;span style=&#34;color:#1e66f5&#34;&gt;class&lt;/span&gt;, &lt;span style=&#34;color:#d20f39&#34;&gt;int&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;class&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Object obj &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; constructor.&lt;span style=&#34;color:#1e66f5&#34;&gt;newInstance&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;, 25);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;获取字段&#34;&gt;获取字段&lt;/h4&gt;&#xA;&lt;p&gt;getDeclaredField(&amp;ldquo;字段名&amp;rdquo;)&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL锁</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/lock/</link>
      <pubDate>Mon, 17 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/lock/</guid>
      <description>&lt;h2 id=&#34;全局锁&#34;&gt;全局锁&lt;/h2&gt;&#xA;&lt;p&gt;一般在做&lt;strong&gt;全库备份&lt;/strong&gt;的时候用到。会阻塞写操作，只允许读请求。因此一般选在业务低峰期去做全库备份。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flush tables &lt;span style=&#34;color:#8839ef&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;read&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;lock&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;表级锁&#34;&gt;表级锁&lt;/h2&gt;&#xA;&lt;h3 id=&#34;表锁&#34;&gt;表锁&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;表共享读锁。多个线程能同时获取这个锁，获取锁的线程可以读这个表，但不能写这个表。MyISAM 处理读请求时，会获取该表的表共享读锁。而 InnoDB 默认是&lt;strong&gt;行锁&lt;/strong&gt;，通过 MVCC 来处理读请求。&lt;/li&gt;&#xA;&lt;li&gt;表独占写锁。只有一个线程能获取这个锁，它可以对表进行写操作。其它任何线程都不可以读这张表。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;lock&lt;/span&gt; tables t_student &lt;span style=&#34;color:#8839ef&#34;&gt;read&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;触发表锁：ALTER/DROP/TRUNCATE TABLE&lt;/p&gt;</description>
    </item>
    <item>
      <title>高可用</title>
      <link>https://ruokezhang.github.io/zh-cn/post/redis/highavailability/</link>
      <pubDate>Sat, 15 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/redis/highavailability/</guid>
      <description>&lt;h2 id=&#34;主从复制master---slave-replication&#34;&gt;主从复制(master - slave replication)&lt;/h2&gt;&#xA;&lt;p&gt;主要优点：数据备份、读写分离，通常和&lt;strong&gt;哨兵模式&lt;/strong&gt;结合使用。&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/availability.png&#34; alt=&#34;Alt text&#34;&gt;&#xA;主服务器负责&lt;strong&gt;读写请求&lt;/strong&gt;，从服务器&lt;strong&gt;默认只负责读请求&lt;/strong&gt;。&lt;br&gt;&#xA;主节点在执行完写请求之后，将写命令同步到从节点，然后从节点再执行这条命令，保证和主节点的数据一致。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Binary Search</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/binarysearch/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/binarysearch/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/3579164/ti-dan-er-fen-suan-fa-er-fen-da-an-zui-x-3rqn/&#34;&gt;https://leetcode.cn/discuss/post/3579164/ti-dan-er-fen-suan-fa-er-fen-da-an-zui-x-3rqn/&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;闭区间写法&#34;&gt;闭区间写法&lt;/h2&gt;&#xA;&lt;h3 id=&#34;找该数&#34;&gt;找该数&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;Solution&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# 标准的二分搜索框架，搜索目标元素的索引，若不存在则返回 -1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;search&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, nums: List[&lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;], target: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;len&lt;/span&gt;(nums) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;while&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;=&lt;/span&gt; right:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; (right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; left) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;//&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;==&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; mid&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;找左边界&#34;&gt;找左边界&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;search&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, nums: List[&lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;], target: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;len&lt;/span&gt;(nums) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;while&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;=&lt;/span&gt; right:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; (right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; left) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;//&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;==&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            right&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;mid&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; left&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;左闭右开&#34;&gt;左闭右开&lt;/h2&gt;&#xA;&lt;h3 id=&#34;找左边界-1&#34;&gt;找左边界&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;left_bound&lt;/span&gt;(nums: List[&lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;], target: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;len&lt;/span&gt;(nums)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;while&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt; right:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; (right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; left) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;//&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;==&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            left &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;elif&lt;/span&gt; nums[mid] &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; target:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            right &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; mid&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; left&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;如果 target 不存在，搜索左侧边界的二分搜索返回的索引是大于 target 的最小索引。&lt;/p&gt;</description>
    </item>
    <item>
      <title>黑马点评登录设计</title>
      <link>https://ruokezhang.github.io/zh-cn/post/blackhorserating/login/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/blackhorserating/login/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/login.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;短信验证码登录&#34;&gt;短信验证码登录&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;登录界面输入手机号，然后点获取验证码。此时后端首先校验手机号格式是否正确，接着生成一个验证码。把手机号和对应的验证码存入 Redis，设置过期时间为 2 分钟。&lt;/li&gt;&#xA;&lt;li&gt;登录界面填写验证码，然后点击登录。此时后端对比传过来的手机号和验证码。如果一致，则进行下一步。&lt;/li&gt;&#xA;&lt;li&gt;如果该用户不存在，则创建用户并且保存用户到数据库。&lt;/li&gt;&#xA;&lt;li&gt;随机生成token，作为登录令牌；并将 User 对象转成 Hash，以 token 为 key，以 hash为 value，存入 Redis。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;校验登录状态&#34;&gt;校验登录状态&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;前端携带的请求会带有 token，所有请求都会被RefreshTokenInterceptor拦截。如果没有token直接放行&lt;/li&gt;&#xA;&lt;li&gt;首先获取请求头中的 token，然后基于token获取redis中存储的用户（一个 Map对象）。&lt;/li&gt;&#xA;&lt;li&gt;如果用户存在，则将Map对象转换为UserDTO，并且把它存储在ThreadLocal中，并且刷新 token 的有效期。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;第二个Interceptor：除了指定的（不需要用户登陆的）路径之外，其它请求路径都会被 LoginInterceptor 拦截，如果此时没有登录，（UserHolder里为空—），则无法处理请求。&lt;/p&gt;</description>
    </item>
    <item>
      <title>图</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/dfs_bfs/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/dfs_bfs/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/3581143/fen-xiang-gun-ti-dan-tu-lun-suan-fa-dfsb-qyux/&#34;&gt;图题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/3580195/fen-xiang-gun-ti-dan-wang-ge-tu-dfsbfszo-l3pa/&#34;&gt;网格图题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;notes&#34;&gt;Notes&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;能记忆化搜索-&amp;gt;一定是有向无环图&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;邻接表空间复杂度&#34;&gt;邻接表空间复杂度&lt;/h2&gt;&#xA;&lt;p&gt;空间由两部分构成：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;每个节点对应一个邻接列表：$O(V)$&lt;/li&gt;&#xA;&lt;li&gt;邻接列表中保存边的端点：无向图的每条边存两次，因此是 $O(2E) = O(E)$&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;总空间复杂度为 $O(V + E)$。&lt;/p&gt;</description>
    </item>
    <item>
      <title>异常、泛型</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/javabasic/exception_r/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/javabasic/exception_r/</guid>
      <description>&lt;h2 id=&#34;异常&#34;&gt;异常&lt;/h2&gt;&#xA;&lt;h3 id=&#34;throwable&#34;&gt;Throwable&lt;/h3&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/Exception_R/image.png&#34; alt=&#34;Alt text&#34;&gt;&#xA;Throwable具有 Exception和 Error 两个子类&lt;/p&gt;&#xA;&lt;p&gt;Error 类代表严重错误，往往不建议我们在程序中用 catch捕获的，我们只能通过优化代码来优化 Error。当出现 Error 时，&lt;strong&gt;JVM 一般会选择终止线程&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java集合</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/javabasic/collection/</link>
      <pubDate>Tue, 11 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/javabasic/collection/</guid>
      <description>&lt;h2 id=&#34;collection接口&#34;&gt;Collection接口&lt;/h2&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/hierarchy-of-collection-framework.jpg&#34; alt=&#34;collection&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;list&#34;&gt;List&lt;/h2&gt;&#xA;&lt;h3 id=&#34;arraylist&#34;&gt;ArrayList&lt;/h3&gt;&#xA;&lt;h4 id=&#34;基本内容&#34;&gt;基本内容&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;可以允许null值&lt;/li&gt;&#xA;&lt;li&gt;内存是连续的，节省内存空间。&lt;/li&gt;&#xA;&lt;li&gt;插入时间复杂度：插在队头O(n)因为要把后面的元素都往后移动一位；插在队尾，如果不需要扩容，则是 O（1），如果需要扩容则先需要 O(n)把原来的 ArryList复制一遍，再执行O（1）的插入操作。&#xA;插在队中间，O(n).&lt;/li&gt;&#xA;&lt;li&gt;删除时间复杂度：与插入的时间复杂度相对应。&lt;/li&gt;&#xA;&lt;li&gt;并非线程安全。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4 id=&#34;底层实现&#34;&gt;底层实现&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;由动态数组实现，随机访问某个节点，只需要计算它的地址值，因此随机访问O(1). 实现了RandomAccess这一个标识借口。&lt;/li&gt;&#xA;&lt;li&gt;如果没有指定初始容量，那么默认初始容量为0，第一次添加元素时，容量变成10. &lt;strong&gt;每次动态扩容，容量变成原来的1.5倍。&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4 id=&#34;arraylist与-array-的区别&#34;&gt;ArrayList与 Array 的区别&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;ArrayList可以动态扩容；Array则不行，它的长度是固定的，并且需要在初始化数组的时候就指定长度&lt;/li&gt;&#xA;&lt;li&gt;ArrayList支持泛型&lt;/li&gt;&#xA;&lt;li&gt;ArrayList只支持对象，对于基本数据类型则需要使用它们的包装类如Integer, Double。Array支持基本数据类型和对象。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;linkedlist&#34;&gt;LinkedList&lt;/h3&gt;&#xA;&lt;h4 id=&#34;底层实现-1&#34;&gt;底层实现&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;双向链表实现。在头部/尾部进行插入/删除的时间复杂度均为O(1)&lt;/li&gt;&#xA;&lt;li&gt;不支持随机访问。每次访问指定元素的时间复杂度为O(n)&lt;/li&gt;&#xA;&lt;li&gt;性能不如ArrayList, 在实际开发中基本不会用到。&lt;/li&gt;&#xA;&lt;li&gt;线程不安全。&lt;/li&gt;&#xA;&lt;li&gt;允许null值&lt;/li&gt;&#xA;&lt;li&gt;除了数据之外还要存指针，所以占用空间比LinkedList大。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;hashmap&#34;&gt;HashMap&lt;/h2&gt;&#xA;&lt;h3 id=&#34;实现原理&#34;&gt;实现原理&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;哈希表+链表/红黑树实现。解决哈希冲突的方法有 chaining/probing，一般使用chaining.&lt;/li&gt;&#xA;&lt;li&gt;哈希值如何计算？拿到key的hashcode()。将&lt;strong&gt;原 hashcode和hashcode右移16位的值进行异或运算&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;int&lt;/span&gt; hash &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; (key &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;?&lt;/span&gt; 0 : (key.&lt;span style=&#34;color:#1e66f5&#34;&gt;hashCode&lt;/span&gt;()) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;^&lt;/span&gt; ((key.&lt;span style=&#34;color:#1e66f5&#34;&gt;hashCode&lt;/span&gt;()) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 16);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;计算数组下标。&lt;strong&gt;hash&amp;amp;(length-1)&lt;/strong&gt;，相当于hash%length. 二进制运算比取模运算更快。&lt;/li&gt;&#xA;&lt;li&gt;如果遇到碰撞，就在链表或红黑树中找是否存在该key，如果存在则直接替换值，如果不存在，就加到里面去。链表长度为 8，并且哈希表长度大于64时，升级成红黑树。&lt;/li&gt;&#xA;&lt;li&gt;红黑树节点数少于6时，变回链表。&lt;/li&gt;&#xA;&lt;li&gt;初始容量16，负载因子0.75，扩容至原来的两倍。&lt;/li&gt;&#xA;&lt;li&gt;并非线程安全。扩容的时候可能会造成链表成环。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;时间复杂度&#34;&gt;时间复杂度&lt;/h3&gt;&#xA;&lt;p&gt;理想情况下，HashMap 的插入、删除和查找操作平均时间复杂度都是 O (1)。&lt;br&gt;&#xA;如果转成红黑树，操作的时间复杂度会稳定在 O (log n)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Process</title>
      <link>https://ruokezhang.github.io/zh-cn/post/os/process/</link>
      <pubDate>Fri, 07 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/os/process/</guid>
      <description>&lt;h2 id=&#34;进程和线程的区别&#34;&gt;进程和线程的区别&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;进程：操作系统资源分配的最小单位，拥有独立的地址空间、文件描述符等。&lt;/li&gt;&#xA;&lt;li&gt;线程：CPU 调度的最小单位，共享进程的资源，包括代码段、数据段、堆等。线程&lt;strong&gt;不共享栈空间&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;pcb&#34;&gt;PCB&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;操作系统每创建一个进程，都会创建一个 process control block，里面存储进程的 PID 和信息&lt;/li&gt;&#xA;&lt;li&gt;process name&lt;/li&gt;&#xA;&lt;li&gt;procee status(ready/blocked/running)&lt;/li&gt;&#xA;&lt;li&gt;pc, stack pointer, file descriptors&lt;/li&gt;&#xA;&lt;li&gt;process对资源(CPU 时间、内存空间）的需求情况&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;线程模型&#34;&gt;线程模型&lt;/h2&gt;&#xA;&lt;p&gt;UT：用户线程&lt;br&gt;&#xA;KT：内核线程&lt;/p&gt;</description>
    </item>
    <item>
      <title>持久化</title>
      <link>https://ruokezhang.github.io/zh-cn/post/redis/aofrdb/</link>
      <pubDate>Fri, 07 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/redis/aofrdb/</guid>
      <description>&lt;p&gt;参考：小林 coding&lt;br&gt;&#xA;&lt;a href=&#34;https://www.bilibili.com/video/BV1sK421i7B8/?spm_id_from=333.337.search-card.all.click&amp;amp;vd_source=512bb0b359ea7a5e16733b06bbe10478&#34;&gt;参考视频&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;aof&#34;&gt;AOF&lt;/h2&gt;&#xA;&lt;p&gt;Append Ony File，是一个&lt;strong&gt;文本文件&lt;/strong&gt;，因此较大。 当客户端发起一个写请求时，Redis 主线程首先在内存中执行写操作，接着将这个写命令同步到&lt;strong&gt;磁盘中的 AOF 日志&lt;/strong&gt;中。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Virtualization</title>
      <link>https://ruokezhang.github.io/zh-cn/post/os/virtualization/</link>
      <pubDate>Wed, 05 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/os/virtualization/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://notes.yxy.ninja/OS/Process/Address-Space&#34;&gt;参考的技术博客&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/Educators-Slides/Tyler/sep17/paging.pdf&#34;&gt;OSTEP slides&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://os.phil-opp.com/paging-introduction/&#34;&gt;参考&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;虚拟内存&#34;&gt;虚拟内存&lt;/h2&gt;&#xA;&lt;p&gt;虚拟化：每个进程都认为，自己有自己的地址空间，多个进程的地址空间是分开的。&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/address_space.png&#34; alt=&#34;地址空间&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;实际上，CPU 拿到这些虚拟的地址，会让它内部的 &lt;strong&gt;MMU 把虚拟地址翻译成物理地址，也就是内存中的地址&lt;/strong&gt;。内存里，每个地址可以存放一个字节。&lt;/p&gt;</description>
    </item>
    <item>
      <title>问题排查</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/jvm/oom/</link>
      <pubDate>Mon, 03 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/jvm/oom/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1Lb4y1j7uc/?spm_id_from=333.337.search-card.all.click&amp;amp;vd_source=3417d90294dd8bcb1cc2b3dc8bc1ef3c&#34;&gt;参考视频&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;内存溢出的原因&#34;&gt;内存溢出的原因&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;一次性申请太多对象-&amp;gt;分页查询&lt;/li&gt;&#xA;&lt;li&gt;内存泄漏：可达但不再使用的对象仍然占用内存-&amp;gt;找到并释放这些对象&lt;/li&gt;&#xA;&lt;li&gt;本身资源不够-&amp;gt;jmap -heap [process id]查看堆信息&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;jmap是一个JDK命令行工具，用来生成heap dump。&lt;strong&gt;heap dump叫做堆转储快照，是一个binary file，记录了堆里面所有对象的信息&lt;/strong&gt;。&lt;br&gt;&#xA;或者，添加JVM参数-XX:+HeapDumpOnOutOfMemoryError，当程序发生OOM时，JVM会自动生成heap dump。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Transaction</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/transactionmysql/</link>
      <pubDate>Sun, 02 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/transactionmysql/</guid>
      <description>&lt;p&gt;参考：小林 coding&lt;/p&gt;&#xA;&lt;h2 id=&#34;事务的特性&#34;&gt;事务的特性&lt;/h2&gt;&#xA;&lt;p&gt;atomicity:  undo log&lt;/p&gt;&#xA;&lt;p&gt;consistency: 由其他三个特性实现.事务在执行前后，数据库从一个一致性状态转变到另一个一致性状态。&lt;/p&gt;&#xA;&lt;p&gt;isolation: MVCC/lock.一个事物的执行不影响其它事务的执行&lt;/p&gt;</description>
    </item>
    <item>
      <title>索引</title>
      <link>https://ruokezhang.github.io/zh-cn/post/mysql/sqlindex/</link>
      <pubDate>Fri, 28 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/mysql/sqlindex/</guid>
      <description>&lt;h2 id=&#34;聚簇索引二级索引&#34;&gt;聚簇索引、二级索引&lt;/h2&gt;&#xA;&lt;h3 id=&#34;聚簇索引&#34;&gt;聚簇索引&lt;/h3&gt;&#xA;&lt;p&gt;InnoDB中，每个表都有一个聚簇索引，它决定着数据在磁盘上存储的物理顺序。&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;如果有 primary key, 即为聚簇索引&lt;/li&gt;&#xA;&lt;li&gt;如果没有 primary key, 选择一个唯一的非空索引作为聚簇索引&lt;/li&gt;&#xA;&lt;li&gt;如果还是没有，InnoDB隐式地创建一个自增列作为聚簇索引&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;b-tree&#34;&gt;B+ Tree&lt;/h3&gt;&#xA;&lt;p&gt;InnoDB在默认情况下，聚簇索引和二级索引都使用 B+ Tree存储。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ThreadLocal&amp;线程池</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/juc/threadlocal/</link>
      <pubDate>Thu, 27 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/juc/threadlocal/</guid>
      <description>&lt;p&gt;参考：JavaGuide&lt;/p&gt;&#xA;&lt;h2 id=&#34;threadlocal&#34;&gt;ThreadLocal&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Thread类&lt;/strong&gt;里面有一个变量threadLocals，可以视为一个 HashMap，用来存放线程私有的内容。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;/* ThreadLocal values pertaining to this thread. This map is maintained&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;    * by the ThreadLocal class. */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ThreadLocal.&lt;span style=&#34;color:#1e66f5&#34;&gt;ThreadLocalMap&lt;/span&gt; threadLocals &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;ThreadLocal类里面有一个instance 方法 set,实际上是把内容存在threadLocals里面。key是&lt;strong&gt;该ThreadLocal对象自己&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
    <item>
      <title>技巧题</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/skill/</link>
      <pubDate>Wed, 26 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/skill/</guid>
      <description>&lt;h4 id=&#34;31-next-permutation&#34;&gt;31. Next Permutation&lt;/h4&gt;&#xA;&lt;p&gt;考虑最后一个permutation：5-4-3-2-1，全部降序。&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;从后往前，找第一组升序的nums[i]和nums[i+1], 比如129&lt;strong&gt;47&lt;/strong&gt;653，找到了nums[4]=4.&lt;/li&gt;&#xA;&lt;li&gt;从后往前，找第一个比nums[i]大的数nums[j]，也就是 5&lt;/li&gt;&#xA;&lt;li&gt;交换nums[i]和nums[j], 得到 129&lt;strong&gt;5&lt;/strong&gt;76&lt;strong&gt;4&lt;/strong&gt;3，此时nums[i]后面的数字全都是降序排列&lt;/li&gt;&#xA;&lt;li&gt;把nums[i]后面的数字按升序排列，得到 1295&lt;strong&gt;3467&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4 id=&#34;128-longest-consecutive-sequence&#34;&gt;128. Longest Consecutive Sequence&lt;/h4&gt;&#xA;&lt;p&gt;[100,4,200,1,3,2]&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stack&amp;Queue&amp;Heap</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/stackqueue/</link>
      <pubDate>Tue, 25 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/stackqueue/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/circle/discuss/mOr1u6/&#34;&gt;灵神题单&lt;/a&gt;&#xA;&lt;a href=&#34;https://leetcode.cn/discuss/post/9oZFK9/&#34;&gt;单调栈&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h1 id=&#34;栈&#34;&gt;栈&lt;/h1&gt;&#xA;&lt;h2 id=&#34;普通栈&#34;&gt;普通栈&lt;/h2&gt;&#xA;&lt;h4 id=&#34;636-函数的独占时间&#34;&gt;636. 函数的独占时间&lt;/h4&gt;&#xA;&lt;p&gt;自己构造调用栈即可。不管当前的 operation 是 start还是end，栈顶都代表当前正在执行的函数&lt;/p&gt;&#xA;&lt;h2 id=&#34;合法括号字符串&#34;&gt;合法括号字符串&lt;/h2&gt;&#xA;&lt;h4 id=&#34;32-最长有效括号&#34;&gt;32 最长有效括号&lt;/h4&gt;&#xA;&lt;p&gt;&amp;ldquo;()(())&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;用一个&lt;strong&gt;数组tmp&lt;/strong&gt;记录匹配成功的index。遇到(时，把它的 index 加入栈。遇到）时，从栈里pop出一个(，它们两个匹配成功，于是把tmp中它们两个的index上都标记为1.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Array</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/array/</link>
      <pubDate>Sat, 22 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/array/</guid>
      <description>&lt;h3 id=&#34;lc-188&#34;&gt;LC 188&lt;/h3&gt;&#xA;&lt;p&gt;输入: nums = [1,2,3,4,5,6,7], k = 3&#xA;输出: [5,6,7,1,2,3,4]&lt;/p&gt;&#xA;&lt;p&gt;方法一：切片操作；取数组里的后k个元素：nums[-k%n:]&lt;/p&gt;&#xA;&lt;p&gt;方法二：先反转整体，再反转局部. 反转过程单独实现，不要用切片，因为可能会产生额外空间。&lt;/p&gt;</description>
    </item>
    <item>
      <title>JMM</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/juc/jmm/</link>
      <pubDate>Fri, 21 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/juc/jmm/</guid>
      <description>&lt;p&gt;参考：JavaGuide&lt;/p&gt;&#xA;&lt;h2 id=&#34;并发问题&#34;&gt;并发问题&lt;/h2&gt;&#xA;&lt;h3 id=&#34;cpu-cache&#34;&gt;CPU Cache&lt;/h3&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/CPUCache.png&#34; alt=&#34;Alt text&#34;&gt;&#xA;Cahce中某个变量的值可能与 Main memory中的值不一致，导致计算出错。&lt;/p&gt;&#xA;&lt;h3 id=&#34;指令级重排&#34;&gt;指令级重排&lt;/h3&gt;&#xA;&lt;h3 id=&#34;编译器优化重排&#34;&gt;编译器优化重排&lt;/h3&gt;&#xA;&lt;p&gt;JVM, JIT做这件事。对于Java程序，在不改变它的语义的情况下，编译时进行指令重排序，类似g1, g2 optimization的重排。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sorting</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/sort/</link>
      <pubDate>Fri, 21 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/sort/</guid>
      <description>&lt;h2 id=&#34;merge-sort&#34;&gt;merge sort&lt;/h2&gt;&#xA;&lt;h3 id=&#34;lc-148-sort-a-linked-list&#34;&gt;LC 148: sort a linked list&lt;/h3&gt;&#xA;&lt;p&gt;快慢指针分成两半，断开中间，分别递归排序，最后升序合并两个链表。边界条件：head==None or head.next==None&lt;/p&gt;&#xA;&lt;h3 id=&#34;lc-23-merge-k-sorted-lists&#34;&gt;LC 23. Merge k Sorted Lists&lt;/h3&gt;&#xA;&lt;p&gt;注意边界情况&lt;/p&gt;&#xA;&lt;h2 id=&#34;quick-sort&#34;&gt;quick sort&lt;/h2&gt;&#xA;&lt;p&gt;以数组某个元素（一般选取首元素）为基准数，将所有小于基准数的元素移动至其左边，大于基准数的元素移动至其右边。&#xA;&lt;a href=&#34;https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/821137/ji-yu-kuai-pai-de-suo-you-topkwen-ti-jia-ylsd/&#34;&gt;python模版&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java线程</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/juc/thread/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/juc/thread/</guid>
      <description>&lt;p&gt;参考：JavaGuide&lt;/p&gt;&#xA;&lt;h2 id=&#34;线程&#34;&gt;线程&lt;/h2&gt;&#xA;&lt;h3 id=&#34;线程的实现&#34;&gt;线程的实现&lt;/h3&gt;&#xA;&lt;p&gt;一个Java程序作为一个进程，运行时实际上是多线程并发的, main函数就是主线程。每个调用过start()方法，并且还未结束的java.lang.Thread类的实例就是一个线程。Java线程是Java程序的并发执行单位。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Python一些常用操作</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/pythonskill/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/pythonskill/</guid>
      <description>&lt;p&gt;intervals.sort(key=lambda p: p[0])&lt;/p&gt;&#xA;&lt;p&gt;LC 189 [:]切片操作&lt;/p&gt;&#xA;&lt;h2 id=&#34;dict&#34;&gt;dict&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# 包含初始键值对的字典&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;filled_dict &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;value1&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;value2&amp;#39;&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# 使用 dict() 构造函数&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;constructed_dict &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;dict&lt;/span&gt;(key1&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;value1&amp;#39;&lt;/span&gt;, key2&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;value2&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;valueList&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#04a5e5&#34;&gt;list&lt;/span&gt;(filled_dict&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;values())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;my_dict &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;apple&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;banana&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#39;cherry&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#fe640b&#34;&gt;3&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; key &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; my_dict&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;keys():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#04a5e5&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#d20f39&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;Key: &lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;{&lt;/span&gt;key&lt;span style=&#34;color:#40a02b&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;LC 49&lt;/p&gt;</description>
    </item>
    <item>
      <title>滑动窗口</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/slidingwindow/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/slidingwindow/</guid>
      <description>&lt;p&gt;reference：灵茶山艾府&lt;/p&gt;&#xA;&lt;h2 id=&#34;定长滑窗&#34;&gt;定长滑窗&lt;/h2&gt;&#xA;&lt;p&gt;入：下标为i的元素进入窗口，更新相关统计量。如果i&amp;lt;k−1则重复第一步。&lt;/p&gt;&#xA;&lt;p&gt;更新：更新答案。一般是更新最大值/最小值。&lt;/p&gt;</description>
    </item>
    <item>
      <title>前缀和</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/presum/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/presum/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/discuss/post/3583665/fen-xiang-gun-ti-dan-chang-yong-shu-ju-j-bvmv/&#34;&gt;前缀和题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;一维前缀和&#34;&gt;一维前缀和&lt;/h2&gt;&#xA;&lt;h4 id=&#34;lc-1749&#34;&gt;LC 1749&lt;/h4&gt;&#xA;&lt;p&gt;任意子数组和的绝对值的最大值: 在前缀和数组里面找最小值和最大值，他们的差的绝对值就是答案。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;maxAbsoluteSum&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, nums: List[&lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;]) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    s &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;list&lt;/span&gt;(accumulate(nums, initial&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;))  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# nums 的前缀和&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;max&lt;/span&gt;(s) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;min&lt;/span&gt;(s)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;2055-蜡烛之间的盘子&#34;&gt;2055. 蜡烛之间的盘子&lt;/h4&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;找a或其右边第一个蜡烛&lt;/li&gt;&#xA;&lt;li&gt;找b或其左边第一个蜡烛&lt;/li&gt;&#xA;&lt;li&gt;用前缀和，算他们之间的盘子数量&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;步骤1，2可以用二分，但是会超时&lt;br&gt;&#xA;最好是预处理，记录每个位置左边/右边的第一个蜡烛位置&lt;/p&gt;</description>
    </item>
    <item>
      <title>垃圾回收</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/jvm/gc/</link>
      <pubDate>Mon, 17 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/jvm/gc/</guid>
      <description>&lt;p&gt;参考：&lt;a href=&#34;https://github.com/RongleXie/java-books-collections/blob/master/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%9AJVM%E9%AB%98%E7%BA%A7%E7%89%B9%E6%80%A7%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5%EF%BC%88%E7%AC%AC3%E7%89%88%EF%BC%89%E5%91%A8%E5%BF%97%E6%98%8E.pdf&#34;&gt;深入理解Java虚拟机&lt;/a&gt;，&lt;a href=&#34;%E6%9E%81%E8%87%B4%E5%85%AB%E8%82%A1%E6%96%87%E4%B9%8BJVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E5%99%A8G1&amp;amp;ZGC%E8%AF%A6%E8%A7%A3&#34;&gt;极致八股文之JVM垃圾回收器G1&amp;amp;ZGC详解&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;对象已死&#34;&gt;对象已死？&lt;/h2&gt;&#xA;&lt;h3 id=&#34;引用计数算法&#34;&gt;引用计数算法&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;/**&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;* testGC()方法执行后，objA和objB会不会被GC呢？&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;* @author zzm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;*/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;ReferenceCountingGC&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; Object instance &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;int&lt;/span&gt; _1MB &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; 1024 &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; 1024;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;/**&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;    * 这个成员属性的唯一意义就是占点内存，以便能在GC日志中看清楚是否有回收过&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;    */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;byte&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;[]&lt;/span&gt; bigSize &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;byte&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;[&lt;/span&gt;2 &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt; _1MB&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;]&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;testGC&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ReferenceCountingGC objA &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;new&lt;/span&gt; ReferenceCountingGC();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ReferenceCountingGC objB &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;new&lt;/span&gt; ReferenceCountingGC();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    objA.&lt;span style=&#34;color:#1e66f5&#34;&gt;instance&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; objB;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    objB.&lt;span style=&#34;color:#1e66f5&#34;&gt;instance&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; objA;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    objA &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    objB &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 假设在这行发生GC，objA和objB是否能被回收？&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    System.&lt;span style=&#34;color:#1e66f5&#34;&gt;gc&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;缺点：这两个对象互相引用，导致他们的 reference counting 始终不能为 0，无法被回收。&lt;/p&gt;</description>
    </item>
    <item>
      <title>动态规划</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/dp/</link>
      <pubDate>Wed, 12 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/dp/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/circle/discuss/tXLS3i/&#34;&gt;灵神题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;线性dp&#34;&gt;线性dp&lt;/h2&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/zh-cn/post/leetcode/dfs_dp.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;排列型&#34;&gt;排列型&lt;/h3&gt;&#xA;&lt;p&gt;外层遍历target，内层遍历可用的数字&lt;/p&gt;&#xA;&lt;h4 id=&#34;70-爬楼梯&#34;&gt;70. 爬楼梯&lt;/h4&gt;&#xA;&lt;p&gt;这里的1和2也可以无数次被用，并且不同顺序算为不同的答案&lt;/p&gt;&#xA;&lt;h4 id=&#34;lc-377&#34;&gt;lc 377:&lt;/h4&gt;&#xA;&lt;p&gt;排列型：外层target，内层nums&lt;/p&gt;</description>
    </item>
    <item>
      <title>二叉树</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/binarytree/binarytree/</link>
      <pubDate>Wed, 12 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/binarytree/binarytree/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/circle/discuss/K0n2gO/&#34;&gt;灵神题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;自底向上dfs-后序遍历&#34;&gt;自底向上dfs: 后序遍历&lt;/h2&gt;&#xA;&lt;p&gt;对于当前节点root做什么，需要它的子树的信息。&lt;/p&gt;&#xA;&lt;h4 id=&#34;lc-1110-删点成林&#34;&gt;LC 1110， 删点成林&lt;/h4&gt;&#xA;&lt;h4 id=&#34;lc-1123-公共祖先&#34;&gt;LC 1123 公共祖先&lt;/h4&gt;&#xA;&lt;p&gt;dfs函数返回：以root为根的子树的所有叶子的最近公共祖先，还有从叶子结点往上数，到root的深度&lt;/p&gt;</description>
    </item>
    <item>
      <title>回溯</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/backtrack/backtracking/</link>
      <pubDate>Mon, 10 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/backtrack/backtracking/</guid>
      <description>&lt;h2 id=&#34;子集型回溯&#34;&gt;子集型回溯&lt;/h2&gt;&#xA;&lt;p&gt;在一次 dfs函数里面，如果 path 是 mutable 类型, 一定保证path进入函数和出函数时 &lt;strong&gt;状态一定不变&lt;/strong&gt;。不管有多少个分支，每个分支都要考虑这个问题。&lt;/p&gt;&#xA;&lt;p&gt;如果 path是immutable，如string，它作为参数传递给dfs，这种情况下&lt;strong&gt;根本没有在修改它的状态&lt;/strong&gt;，而是每次新建一个string，传给子节点。因而不需要恢复状态。LC 257.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linked List</title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/linkedlist/</link>
      <pubDate>Sun, 09 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/linkedlist/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/circle/discuss/K0n2gO/&#34;&gt;灵神题单&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;反转链表&#34;&gt;反转链表&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;reverseBetween&lt;/span&gt;(&lt;span style=&#34;color:#04a5e5&#34;&gt;self&lt;/span&gt;, head: Optional[ListNode], left: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;, right: &lt;span style=&#34;color:#04a5e5&#34;&gt;int&lt;/span&gt;) &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; Optional[ListNode]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#因为答案的头节点可能会改，所以搞一个dummy&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    dummy&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;ListNode(&lt;span style=&#34;color:#04a5e5&#34;&gt;next&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;head)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pre&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;dummy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#移动pre, cur到1和2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;range&lt;/span&gt;(left&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pre&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;pre&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cur&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;pre&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#记录一下此时pre&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p0&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;pre&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#开始反转2到4这一段, 其实就是分别把2到4的next改了&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;range&lt;/span&gt;(right&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;left&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nxt&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;cur&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cur&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;pre&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pre&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;cur&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cur&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;nxt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#新的pre,cur分别是4，5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#连接 2 和 5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p0&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;cur&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#连接1和4&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p0&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;pre&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; dummy&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;next&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;反转链表关注 pre和cur在开始前和结束后的位置，在这一题中，旧pre的next为新的pre，旧cur的 next为新的cur.&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/static/reverse.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java 8的新特性</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/javabasic/java8/</link>
      <pubDate>Fri, 07 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/javabasic/java8/</guid>
      <description>&lt;h2 id=&#34;functional-interface&#34;&gt;Functional Interface&lt;/h2&gt;&#xA;&lt;p&gt;函数式接口的定义是，必须只含有一个abstract method，它可以拥有许多static或default method(包含实现), 但是 abstract method必须只有一个。&lt;/p&gt;</description>
    </item>
    <item>
      <title>达人探店</title>
      <link>https://ruokezhang.github.io/zh-cn/post/blackhorserating/post/</link>
      <pubDate>Fri, 07 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/blackhorserating/post/</guid>
      <description>&lt;h2 id=&#34;点赞设计&#34;&gt;点赞设计&lt;/h2&gt;&#xA;&lt;p&gt;用Redis的 sorted set, key是当前 post的ID，set里面存点赞用户的 ID，score 为点赞的时间戳。&lt;/p&gt;&#xA;&lt;p&gt;前端在看帖子详情的时候，后端不仅需要根据帖子id去数据库里拿内容，还要通过redis判断帖子是否被当前用户点过赞。在 Blog里面加一个liked字段，作为结果一并返回给前端。&lt;/p&gt;</description>
    </item>
    <item>
      <title>接口和抽象类</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/javabasic/interfaceabstractclass/</link>
      <pubDate>Fri, 07 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/javabasic/interfaceabstractclass/</guid>
      <description>&lt;h2 id=&#34;interface&#34;&gt;Interface&lt;/h2&gt;&#xA;&lt;p&gt;接口是对行为的抽象。&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;abstract method, Java 8以前接口只能有抽象方法&lt;/li&gt;&#xA;&lt;li&gt;default method，提供方法体，Java 8 以后有&lt;/li&gt;&#xA;&lt;li&gt;static method, 提供方法体，Java 8 以后有，可以通过Interface.method()调用&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;23&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;24&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;25&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;26&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;27&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;28&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;29&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;30&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;31&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;32&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;33&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;34&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;35&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;36&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;37&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;38&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;39&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;40&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;41&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;42&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;43&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;44&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;45&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;46&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;47&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;48&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;49&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;MyInterface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 抽象方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;abstractMethod&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 默认方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;default&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;defaultMethod&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;这是接口的默认方法&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        privateHelperMethod();  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 调用私有辅助方法（注意：私有方法是Java 9的特性，这里仅为示例）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 静态方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;staticMethod&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;这是接口的静态方法&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 私有辅助方法（Java 9 特性，但为了完整性展示，包含在此）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;privateHelperMethod&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;这是接口的私有辅助方法&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;MyClass&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;implements&lt;/span&gt; MyInterface {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@Override&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;abstractMethod&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;实现接口的抽象方法&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 可以选择覆盖默认方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@Override&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;defaultMethod&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;覆盖接口的默认方法&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MyInterface.&lt;span style=&#34;color:#1e66f5&#34;&gt;super&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;defaultMethod&lt;/span&gt;();  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 调用接口的默认方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#df8e1d&#34;&gt;Main&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;main&lt;/span&gt;(String&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;[]&lt;/span&gt; args) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MyClass myClass &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;new&lt;/span&gt; MyClass();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 调用实现的抽象方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        myClass.&lt;span style=&#34;color:#1e66f5&#34;&gt;abstractMethod&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 调用默认方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        myClass.&lt;span style=&#34;color:#1e66f5&#34;&gt;defaultMethod&lt;/span&gt;();  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 注意这里调用的是覆盖后的版本&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 调用接口的静态方法&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MyInterface.&lt;span style=&#34;color:#1e66f5&#34;&gt;staticMethod&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;abstract-class&#34;&gt;Abstract Class&lt;/h2&gt;&#xA;&lt;p&gt;抽象类通常作为基类，比如 Person，Animal。因为不同子类的某种方法的 body可能不一样，所以把这些方法作为abstract method放在抽象类中。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Concurrency</title>
      <link>https://ruokezhang.github.io/zh-cn/post/os/concurrency/</link>
      <pubDate>Wed, 05 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/os/concurrency/</guid>
      <description>&lt;h2 id=&#34;目标&#34;&gt;目标&lt;/h2&gt;&#xA;&lt;p&gt;Mutual exclusion (e.g., A and B don’t run at same time)，进程的互斥&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;solved with locks&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Ordering (e.g., B runs after A does something)，进程的同步&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;solved with condition variables OR semaphores&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/Classes/537/Fall2021/Discussion/videos.html&#34;&gt;CS 537 Videos&lt;/a&gt;&#xA;&lt;a href=&#34;https://xiaolincoding.com/os/4_process/multithread_sync.html#%E4%BF%A1%E5%8F%B7%E9%87%8F&#34;&gt;小林coding&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;锁&#34;&gt;锁&lt;/h2&gt;&#xA;&lt;p&gt;可以理解为 Mutex. 它只是一个变量，只有 available/acquired 两种状态，每个线程可以获取/释放它。&#xA;&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf&#34;&gt;Reference: OSTEP-Locks&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>黑马点评商户缓存</title>
      <link>https://ruokezhang.github.io/zh-cn/post/blackhorserating/shopcache/</link>
      <pubDate>Mon, 03 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/blackhorserating/shopcache/</guid>
      <description>&lt;h2 id=&#34;一致性&#34;&gt;一致性&lt;/h2&gt;&#xA;&lt;h3 id=&#34;缓存更新策略&#34;&gt;缓存更新策略&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;内存淘汰：Redis 内存不足时自动淘汰部分数据，下次请求时更新缓存&lt;/li&gt;&#xA;&lt;li&gt;超时剔除：给缓存数据添加 TTL 时间，到期后自动删除缓存。下次请求时更新缓存。&lt;/li&gt;&#xA;&lt;li&gt;主动更新：在修改数据库的同时更新缓存。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;缓存数据库一致性&#34;&gt;缓存数据库一致性&lt;/h3&gt;&#xA;&lt;p&gt;有请求并发到来时，不管是先更新缓存后更新数据库，还是先更新数据库后更新缓存，都可能出现缓存不一致问题。&lt;/p&gt;</description>
    </item>
    <item>
      <title>优惠券秒杀</title>
      <link>https://ruokezhang.github.io/zh-cn/post/blackhorserating/voucher/</link>
      <pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/blackhorserating/voucher/</guid>
      <description>&lt;h2 id=&#34;全局id生成器-redis自增&#34;&gt;全局ID生成器: Redis自增&lt;/h2&gt;&#xA;&lt;p&gt;使用数据库自增ID的缺点：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;可能会暴露给用户一些信息：用户可能会根据此推断，一天之内销售出了多少张优惠券。&lt;/li&gt;&#xA;&lt;li&gt;当优惠券太多时，会导致数据库ID过大。但如果为优惠券分表，又会出现许多优惠券共用同一个ID的情况。&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/uniqueID.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;//符号位0+时间戳31bit+序列号32bit&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;long&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;nextId&lt;/span&gt;(String keyPrefix){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;//生成时间戳&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    LocalDateTime now&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;LocalDateTime.&lt;span style=&#34;color:#1e66f5&#34;&gt;now&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;long&lt;/span&gt; nowSecond&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;now.&lt;span style=&#34;color:#1e66f5&#34;&gt;toEpochSecond&lt;/span&gt;(ZoneOffset.&lt;span style=&#34;color:#1e66f5&#34;&gt;UTC&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;long&lt;/span&gt; timestamp&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;nowSecond&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;BEGIN_TIMESTAMP;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;//生成序列号. 每一天下的单使用同一个Key&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    String date&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;now.&lt;span style=&#34;color:#1e66f5&#34;&gt;format&lt;/span&gt;(DateTimeFormatter.&lt;span style=&#34;color:#1e66f5&#34;&gt;ofPattern&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;yyyy:MM:dd&amp;#34;&lt;/span&gt;));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;long&lt;/span&gt; count&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;  stringRedisTemplate.&lt;span style=&#34;color:#1e66f5&#34;&gt;opsForValue&lt;/span&gt;().&lt;span style=&#34;color:#1e66f5&#34;&gt;increment&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;icr:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;keyPrefix&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;+&lt;/span&gt;date);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;//拼接并返回&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; timestamp&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;COUNT_BITS&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;|&lt;/span&gt;count;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;这里的 keyPrefix表示一种object,比如优惠券订单&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis缓存</title>
      <link>https://ruokezhang.github.io/zh-cn/post/redis/caching_patterns/</link>
      <pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/redis/caching_patterns/</guid>
      <description>&lt;h2 id=&#34;caching-patterns&#34;&gt;Caching Patterns&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://redis.io/learn/howtos/solutions/microservices/caching&#34;&gt; Redis Doc: How to use Redis for Query Caching&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://hazelcast.com/blog/a-hitchhikers-guide-to-caching-patterns/&#34;&gt;这里有图片！&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;cache-aside-lazy-loading&#34;&gt;Cache-Aside (Lazy Loading)&lt;/h2&gt;&#xA;&lt;p&gt;只有我们想查看数据的时候，Redis Cache才有可能被更新。当我们发出一个Query,后端先判断数据是否在Redis Cache里面。如果不在，则查数据库，并且把查到的数据放到Redis Cache里。&lt;/p&gt;</description>
    </item>
    <item>
      <title>JVM Basic</title>
      <link>https://ruokezhang.github.io/zh-cn/post/java/jvm/basic/</link>
      <pubDate>Thu, 30 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/java/jvm/basic/</guid>
      <description>&lt;h2 id=&#34;classfile&#34;&gt;ClassFile&lt;/h2&gt;&#xA;&lt;p&gt;Java文件经过javac编译后，得到.class字节码文件，再放在JVM上面跑。ClassFile是一种结构规范，所有.class文件都应该符合这样的格式。&#xA;&lt;img src=&#34;https://blog-ruoke.oss-cn-hongkong.aliyuncs.com/blog/images/classFile.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nginx</title>
      <link>https://ruokezhang.github.io/zh-cn/post/nginx/</link>
      <pubDate>Thu, 30 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/nginx/</guid>
      <description>&lt;h2 id=&#34;cli&#34;&gt;CLI&lt;/h2&gt;&#xA;&lt;p&gt;nginx -V 查看 Nginx配置文件的位置：/opt/homebrew/etc/nginx/nginx.conf&lt;/p&gt;&#xA;&lt;p&gt;nginx命令启动master进程，nginx分为master进程和worker进程。&#xA;master进程负责读取配置文件、管理worker进程；worker进程实际处理HTTP请求。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Session登录</title>
      <link>https://ruokezhang.github.io/zh-cn/post/session/</link>
      <pubDate>Thu, 30 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/session/</guid>
      <description>&lt;h2 id=&#34;黑马点评登录&#34;&gt;黑马点评登录&lt;/h2&gt;&#xA;&lt;h3 id=&#34;第一次请求获取验证码&#34;&gt;第一次请求：获取验证码&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@PostMapping&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;/login&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; Result &lt;span style=&#34;color:#1e66f5&#34;&gt;login&lt;/span&gt;(&lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@RequestBody&lt;/span&gt; LoginFormDTO loginFormDTO, HttpSession session){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; userService.&lt;span style=&#34;color:#1e66f5&#34;&gt;login&lt;/span&gt;(loginFormDTO, session);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;后端为其生成随机验证码，并且存入 session&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session.&lt;span style=&#34;color:#1e66f5&#34;&gt;setAttribute&lt;/span&gt;(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;, code);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;后端接着把Session ID通过 set cookie返回给前端浏览器。浏览器保存这个 Session ID, 把它存在 cookie 里面。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java IO</title>
      <link>https://ruokezhang.github.io/zh-cn/post/javaio/</link>
      <pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/javaio/</guid>
      <description>&lt;h2 id=&#34;file&#34;&gt;File&lt;/h2&gt;&#xA;&lt;h3 id=&#34;public-static-fields&#34;&gt;Public Static Fields&lt;/h3&gt;&#xA;&lt;p&gt;To let the code run on every system, use these variables.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// depends on the system. On Mac, it is &amp;#34;/&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(File.&lt;span style=&#34;color:#1e66f5&#34;&gt;separator&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// On Mac, it&amp;#39;s &amp;#34;:&amp;#34;, used to separate filenames in a sequence of files given as a path list&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#1e66f5&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;println&lt;/span&gt;(File.&lt;span style=&#34;color:#1e66f5&#34;&gt;pathSeparator&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;For example, if we want to get a path like &amp;ldquo;Users/ruoke&amp;rdquo;, we can create it using&lt;/p&gt;</description>
    </item>
    <item>
      <title>Maven</title>
      <link>https://ruokezhang.github.io/zh-cn/post/maven/</link>
      <pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/maven/</guid>
      <description>&lt;h2 id=&#34;basic&#34;&gt;Basic&lt;/h2&gt;&#xA;&lt;h3 id=&#34;java-version&#34;&gt;Java Version&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ruoke@Ruokes-MacBook-Pro ~ % mvn -v&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Apache Maven 3.9.6 &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;bc0240f3c744dd6b6ec2920b3cd08dcc295161ae&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Maven home: /Users/ruoke/Documents/devTools/apache-maven-3.9.6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java version: 21.0.3, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;这个 Java 版本是 Maven 本身运行时使用的 Java 版本&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;1.8&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;我项目里的 pom指定该项目的Java编译时版本，会影响maven-compiler-plugin去找哪个版本的JDK；但这里并不指定该项目的运行时版本。&#xA;可以在Project Structure里面规定哪个版本JDK用来编译文件&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/ai/parallact_bind/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/ai/parallact_bind/</guid>
      <description>&lt;p&gt;视觉/文本/音频，每个模态都产出semantic_emb和spatial_emb&lt;/p&gt;&#xA;&lt;h2 id=&#34;visualencoder&#34;&gt;VisualEncoder&lt;/h2&gt;&#xA;&lt;h3 id=&#34;离线特征&#34;&gt;离线特征&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;用 SigLIP2 自带的 preprocess 把图片 resize / crop / normalize&lt;/li&gt;&#xA;&lt;li&gt;输入分辨率 256，patch size 16。所以一张图会被切成 16 × 16 = 256 个 patch&lt;/li&gt;&#xA;&lt;li&gt;每个 patch 变成向量&lt;/li&gt;&#xA;&lt;li&gt;过 Transformer trunk, 得到[B,256,1152]，也就是一张图片有256个patch，每个patch有1152维&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;在线部分&#34;&gt;在线部分&lt;/h3&gt;&#xA;&lt;h4 id=&#34;semantic_emb&#34;&gt;semantic_emb&lt;/h4&gt;&#xA;&lt;h5 id=&#34;attentionpool&#34;&gt;AttentionPool&lt;/h5&gt;&#xA;&lt;p&gt;query是一个单独学出来的向量，它去看所有patch tokens, 压缩成每张图片一个1152维度的向量&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/bq/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/bq/</guid>
      <description>&lt;h2 id=&#34;failure&#34;&gt;failure&lt;/h2&gt;&#xA;&lt;p&gt;During a big promotion our model’s TPM (500,000 tokens/min) was exhausted and many highlight requests started failing. My goal was to stabilize the service quickly without just dropping requests. I added a worker-side token bucket (Redis) so a task only calls the model if tokens are available, otherwise it gets delayed and retried later. I also tied autoscaling to token usage and queue length so we automatically add capacity when pressure rises. Within minutes the failure rate fell below 1% and the task queue stopped growing.&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems_labs/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/course_notes/distributed_systems_labs/</guid>
      <description>&lt;h1 id=&#34;lab-0&#34;&gt;Lab 0&lt;/h1&gt;&#xA;&lt;h2 id=&#34;node&#34;&gt;Node&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;一个Node可以有parent和多个child node&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;field&#34;&gt;field&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@VizIgnore&lt;/span&gt; &lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@NonNull&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;final&lt;/span&gt; Address address;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;transient&lt;/span&gt; Consumer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Triple&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Address, Address, Message&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; messageAdder;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;//模拟网络通信行为&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;transient&lt;/span&gt; Consumer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Triple&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Address, Address&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;[]&lt;/span&gt;, Message&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; batchMessageAdder;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;transient&lt;/span&gt; Consumer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Triple&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Address, Timer, Pair&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Integer, Integer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; timerAdder;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#d20f39&#34;&gt;transient&lt;/span&gt; Consumer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Throwable&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; throwableCatcher;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20f39&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;Address&lt;/span&gt;(String identifier) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;identifier&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; identifier;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;parentAddress&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;subIdentifier&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#1e66f5&#34;&gt;fullAddressString&lt;/span&gt; &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; identifier; &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 完整地址就是核心标识&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;function&#34;&gt;function&lt;/h3&gt;&#xA;&lt;h4 id=&#34;init&#34;&gt;init():&lt;/h4&gt;&#xA;&lt;p&gt;这是节点的入口。如果你需要在节点启动时就发消息（比如 Client 一上来就要 Ping），写在这里。不要在构造函数里发消息。&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/course_notes/llm/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/course_notes/llm/</guid>
      <description>&lt;h1 id=&#34;lecture&#34;&gt;Lecture&lt;/h1&gt;&#xA;&lt;h2 id=&#34;线性&#34;&gt;线性&lt;/h2&gt;&#xA;&lt;h3 id=&#34;二分类&#34;&gt;二分类&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Perceptron&#xA;&lt;ul&gt;&#xA;&lt;li&gt;weighted sum+activate function: 简单线性决策，可以解决OR/AND&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Logistic Regression&#xA;&lt;ul&gt;&#xA;&lt;li&gt;概率化的线性分类器&lt;/li&gt;&#xA;&lt;li&gt;p(y=1|x)=sigmoid(z), z:weighted sum&lt;/li&gt;&#xA;&lt;li&gt;loss function: binary cross-entropy&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Linear SVM&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;多分类&#34;&gt;多分类&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Softmax Regression&#xA;&lt;ul&gt;&#xA;&lt;li&gt;输出层：softmax. 前面的输出，会给每个样本一堆logits,代表它在相应分类的得分，softmax吧这组logits转换为在每个分类的概率&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;非线性&#34;&gt;非线性&lt;/h2&gt;&#xA;&lt;h3 id=&#34;multi-layer-perceptron-mlp&#34;&gt;Multi-layer perceptron (MLP)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;multiple linear layers + non-linear activations&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;non-parametric--classical-ml&#34;&gt;Non-parametric / Classical ML&lt;/h2&gt;&#xA;&lt;h3 id=&#34;knn&#34;&gt;kNN&lt;/h3&gt;&#xA;&lt;h3 id=&#34;naive-bayes&#34;&gt;Naive Bayes&lt;/h3&gt;&#xA;&lt;h2 id=&#34;tree-based-models&#34;&gt;Tree-based Models&lt;/h2&gt;&#xA;&lt;h3 id=&#34;decision-tree&#34;&gt;Decision Tree&lt;/h3&gt;&#xA;&lt;h3 id=&#34;random-forest&#34;&gt;Random Forest&lt;/h3&gt;&#xA;&lt;h3 id=&#34;gradient-boosted-trees-eg-xgboost&#34;&gt;Gradient Boosted Trees (e.g., XGBoost)&lt;/h3&gt;&#xA;&lt;h1 id=&#34;lecture-6&#34;&gt;Lecture 6&lt;/h1&gt;&#xA;&lt;h2 id=&#34;word-embeddings--x2vec&#34;&gt;Word Embeddings &amp;amp; X2Vec&lt;/h2&gt;&#xA;&lt;h3 id=&#34;word2vec&#34;&gt;Word2Vec&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Skip-Gram， semi-supervised&lt;/li&gt;&#xA;&lt;li&gt;生成训练数据：通过移动窗口扫描句子，生成 (输入词, 目标词) 对&lt;/li&gt;&#xA;&lt;li&gt;架构：input(one-hot), 1 hidden layer, softmax classifier&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;product2vec-x2vec&#34;&gt;Product2Vec (X2Vec)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;View Similarity：学习 Substitutability（可替代性/严格相似）&lt;/li&gt;&#xA;&lt;li&gt;Purchase Similarity：学习 Complementarity（互补性/搭配关系）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;bert&#34;&gt;BERT&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;bert base: 12 layers of encoder&lt;/li&gt;&#xA;&lt;li&gt;[CLS]：放在句首，用于整个句子的分类表示。&lt;/li&gt;&#xA;&lt;li&gt;[SEP]：放在句尾或两句之间，作为分隔符。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;normalization： all lower case&lt;/li&gt;&#xA;&lt;li&gt;WordPiece Tokenization&lt;/li&gt;&#xA;&lt;li&gt;add special tokens: [CLS]/[SEP]&lt;/li&gt;&#xA;&lt;li&gt;Token IDs(BERT vocab)&lt;/li&gt;&#xA;&lt;li&gt;each token got 3 embeddings，sum them up&#xA;&lt;ul&gt;&#xA;&lt;li&gt;token embedding(get from a huge matrix, size of [Vocab_Size, 768])&lt;/li&gt;&#xA;&lt;li&gt;position embedding(get from a matrix, size of [Max_Len, 768])&lt;/li&gt;&#xA;&lt;li&gt;segment embedding&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;got a matrix[token_size*768]&lt;/li&gt;&#xA;&lt;li&gt;pass the matrix through a 12 Encoder Layers. After that, [CLS] would gather information from the entire sentence&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;usage&#34;&gt;usage&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;get tokenizer&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tokenizer &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; BertTokenizer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;from_pretrained(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;bert-base-uncased&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;get tokens and token_ids&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tokens &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; tokenizer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;tokenize(text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;input_ids &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; tokenizer&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;convert_tokens_to_ids(tokens)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;get embedding&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;outputs &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; bert_model(input_ids&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;input_ids, attention_mask&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;attention_mask)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;对应第5,6,7步&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/company_wise/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/company_wise/</guid>
      <description>&lt;h2 id=&#34;heap&#34;&gt;heap&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;767&#34;&gt;&#xA;&lt;li&gt;重构字符串(Roblox)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;621&#34;&gt;&#xA;&lt;li&gt;任务调度器(Roblox, Snowflake)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;692&#34;&gt;&#xA;&lt;li&gt;前K个高频单词(Adobe)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;347&#34;&gt;&#xA;&lt;li&gt;前 K 个高频元素(Adobe, Bloomberg)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1353&#34;&gt;&#xA;&lt;li&gt;最多可以参加的会议数目(Snowflake)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;373&#34;&gt;&#xA;&lt;li&gt;查找和最小的 K 对数字(Linkedin, Google)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1046&#34;&gt;&#xA;&lt;li&gt;最后一块石头的重量(Nvidia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;295&#34;&gt;&#xA;&lt;li&gt;数据流的中位数(Snowflake)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Merge k Sorted Lists(Bloomberg, Snowflake, Nvidia, Microsoft)&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2034&#34;&gt;&#xA;&lt;li&gt;股票价格波动(Google)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2402&#34;&gt;&#xA;&lt;li&gt;会议室 III&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;prefix-sum&#34;&gt;prefix sum&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;713&#34;&gt;&#xA;&lt;li&gt;乘积小于 K 的子数组(Airbnb)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1004&#34;&gt;&#xA;&lt;li&gt;最大连续1的个数 III(Microsoft, Expedia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;974&#34;&gt;&#xA;&lt;li&gt;和可被 K 整除的子数组(Expedia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;304&#34;&gt;&#xA;&lt;li&gt;二维区域和检索 - 矩阵不可变(Snowflake)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Subarray Sum Equals K(Bloomberg)&lt;/li&gt;&#xA;&lt;li&gt;Product of Array Except Self(Bloomberg, Microsoft)&lt;/li&gt;&#xA;&lt;li&gt;Meeting Rooms II(Microsoft)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;trie&#34;&gt;trie&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;211&#34;&gt;&#xA;&lt;li&gt;添加与搜索单词 - 数据结构设计(Docusign, LinkedIn, Snowflake, Rubrik, Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;14&#34;&gt;&#xA;&lt;li&gt;最长公共前缀(Bloomberg)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3043&#34;&gt;&#xA;&lt;li&gt;最长公共前缀的长度(Databricks)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Implement Trie (Prefix Tree)(Snowflake)&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;588&#34;&gt;&#xA;&lt;li&gt;设计内存文件系统(Snowflake)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1233&#34;&gt;&#xA;&lt;li&gt;删除子文件夹(Snowflake, Google)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1268&#34;&gt;&#xA;&lt;li&gt;搜索推荐系统(Docusign, Amazon)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;212&#34;&gt;&#xA;&lt;li&gt;单词搜索 II(Microsoft, Google, Airbnb)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;stack&#34;&gt;stack&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Basic Calculator II(Tesla)&lt;/li&gt;&#xA;&lt;li&gt;Max Stack(Linkedin)&lt;/li&gt;&#xA;&lt;li&gt;Nested List Weight Sum II(Linkedin)&lt;/li&gt;&#xA;&lt;li&gt;Valid Parentheses(Nvidia, Expedia)&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;150&#34;&gt;&#xA;&lt;li&gt;逆波兰表达式求值(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;224&#34;&gt;&#xA;&lt;li&gt;基本计算器(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;20&#34;&gt;&#xA;&lt;li&gt;有效的括号(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;32&#34;&gt;&#xA;&lt;li&gt;最长有效括号(Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;85&#34;&gt;&#xA;&lt;li&gt;最大矩形(Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;84&#34;&gt;&#xA;&lt;li&gt;柱状图中最大的矩形(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;71&#34;&gt;&#xA;&lt;li&gt;简化路径(Snowflake, Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;316&#34;&gt;&#xA;&lt;li&gt;去除重复字母(Expedia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1944&#34;&gt;&#xA;&lt;li&gt;队列中可以看到的人数(Expedia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1963&#34;&gt;&#xA;&lt;li&gt;使字符串平衡的最小交换次数(Expedia)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2104&#34;&gt;&#xA;&lt;li&gt;子数组范围和(Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;queue&#34;&gt;queue&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;622&#34;&gt;&#xA;&lt;li&gt;设计循环队列(Tesla, Cloudflare)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;362&#34;&gt;&#xA;&lt;li&gt;敲击计数器(Snowflake, Cloudflare, Databricks)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1438&#34;&gt;&#xA;&lt;li&gt;绝对差不超过限制的最长连续子数组(Google)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;错题集&#34;&gt;错题集&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;622&#34;&gt;&#xA;&lt;li&gt;设计循环队列(Tesla, Cloudflare)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;hash&#34;&gt;hash&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;41&#34;&gt;&#xA;&lt;li&gt;缺失的第一个正数(Tesla)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;268&#34;&gt;&#xA;&lt;li&gt;丢失的数字(Meta, Microsoft, Bloomberg)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;sort&#34;&gt;sort&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;215&#34;&gt;&#xA;&lt;li&gt;数组中的第K个最大元素(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;sliding-window&#34;&gt;sliding window&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1004&#34;&gt;&#xA;&lt;li&gt;最大连续1的个数 III(SAP, Salesforce, LinkedIn, Meta, Google)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;424&#34;&gt;&#xA;&lt;li&gt;替换后的最长重复字符(Adobe, Amazon, Bytedance, Bloomberg)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1297&#34;&gt;&#xA;&lt;li&gt;子串的最大出现次数(Hubspot, Salesforce)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;159&#34;&gt;&#xA;&lt;li&gt;至多包含两个不同字符的最长子串(Ebay, Google, Tiktok)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;340&#34;&gt;&#xA;&lt;li&gt;至多包含 K 个不同字符的最长子串(Microsoft)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;713&#34;&gt;&#xA;&lt;li&gt;乘积小于 K 的子数组(Paypal, Oracle, Salesforce)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;632&#34;&gt;&#xA;&lt;li&gt;最小区间(Lyft, Databricks)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;1343&#34;&gt;&#xA;&lt;li&gt;大小为 K 且平均值大于等于阈值的子数组数目(LinkedIn)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/leetcode/followup/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/leetcode/followup/</guid>
      <description>&lt;h3 id=&#34;300-最长递增子序列&#34;&gt;300. 最长递增子序列&lt;/h3&gt;&#xA;&lt;h4 id=&#34;输出子序列&#34;&gt;输出子序列&lt;/h4&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;23&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;24&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nums &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#fe640b&#34;&gt;10&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;9&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;5&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;7&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;101&lt;/span&gt;,&lt;span style=&#34;color:#fe640b&#34;&gt;18&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#179299&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;bisect&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;sol&lt;/span&gt;(nums):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    g&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;[]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    g_idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;[]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    n&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#04a5e5&#34;&gt;len&lt;/span&gt;(nums)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    parent&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;[&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;*&lt;/span&gt;n &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;#记录nums[i]在最终答案里的上一个数字的index&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;for&lt;/span&gt; i, x &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#04a5e5&#34;&gt;enumerate&lt;/span&gt;(nums):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;bisect&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;bisect_left(g, x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;0&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;# its has a preceding number&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            parent[i]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;g_idx[idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5&#34;&gt;len&lt;/span&gt;(g):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            g[idx]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;x&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            g_idx[idx]&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;i&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8839ef&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            g&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;append(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            g_idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;append(i)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cur_idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;g_idx[&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;[]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;while&lt;/span&gt; cur_idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;!=-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        res&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;.&lt;/span&gt;append(nums[cur_idx])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cur_idx&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt;parent[cur_idx]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;return&lt;/span&gt; res[::&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#fe640b&#34;&gt;1&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;162-寻找峰值&#34;&gt;162. 寻找峰值&lt;/h3&gt;&#xA;&lt;p&gt;DoorDash面经&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/post/message_queue/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/post/message_queue/</guid>
      <description>&lt;h2 id=&#34;消息可靠性&#34;&gt;消息可靠性&lt;/h2&gt;&#xA;&lt;h3 id=&#34;生产者-mq&#34;&gt;生产者-&amp;gt;MQ&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;生产者开启 confirm 模式&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;channel.&lt;span style=&#34;color:#1e66f5&#34;&gt;confirmSelect&lt;/span&gt;(); &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 开启Confirm模式&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;channel.&lt;span style=&#34;color:#1e66f5&#34;&gt;basicPublish&lt;/span&gt;(exchange, routingKey, MessageProperties.&lt;span style=&#34;color:#1e66f5&#34;&gt;PERSISTENT_TEXT_PLAIN&lt;/span&gt;, message.&lt;span style=&#34;color:#1e66f5&#34;&gt;getBytes&lt;/span&gt;());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;!&lt;/span&gt;channel.&lt;span style=&#34;color:#1e66f5&#34;&gt;waitForConfirms&lt;/span&gt;(5000)) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// 消息未确认，重试或记录日志&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;异步确认：发送消息后不阻塞等待 MQ 的 ACK，而是通过回调函数接收 ACK 通知；若回调中发现未确认（如 ACK 失败、超时），将未确认的消息存入本地缓存，定期触发重试，直到收到 ACK 或达到最大重试次数；&lt;/li&gt;&#xA;&lt;li&gt;同步确认：发送消息后阻塞等待 ACK&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;mq&#34;&gt;MQ&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;持久化（必做）：设置消息和队列为「持久化模式」（RocketMQ 默认开启），MQ 会将消息和队列信息写入磁盘，即使 MQ 进程宕机、重启，也能从磁盘恢复消息，避免内存中的消息丢失；&lt;/li&gt;&#xA;&lt;li&gt;集群多副本（进阶，提升可靠性）：搭建 RocketMQ 集群，配置多副本（类似镜像队列），将队列数据同步到集群多个节点，设置节点同步模式（如同步复制）；&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;mq-消费者&#34;&gt;MQ-&amp;gt;消费者&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;手动 ACK&#xA;&lt;ul&gt;&#xA;&lt;li&gt;自动 ACK 的确定：会存在消费者收到，确认之后没消费，消费者挂了，数据丢失&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;死信队列： 当消息多次重试（如3次）仍处理失败（如系统异常），将消息转入「死信队列」，由人工介入排查处理，避免消息无限重试或被丢弃&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;幂等性&#34;&gt;幂等性&lt;/h2&gt;&#xA;&lt;h3 id=&#34;为什么会有重复的消息&#34;&gt;为什么会有重复的消息&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;生产者没收到 MQ 的 ACK，又发了一次&lt;/li&gt;&#xA;&lt;li&gt;MQ 没收到消费者的 ACK，又发了一次&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;解决&#34;&gt;解决&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;数据库唯一索引&lt;/li&gt;&#xA;&lt;li&gt;Redis SETNX /Lua 脚本查状态改状态&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;对比kafka的优势&#34;&gt;对比Kafka的优势&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Consumer 端自带重试机制，当消费消息失败时，RocketMQ 会自动将消息放入重试队列。&lt;/li&gt;&#xA;&lt;li&gt;当消费消息失败时，RocketMQ 会自动将消息放入重试队列&lt;/li&gt;&#xA;&lt;/ol&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ruokezhang.github.io/zh-cn/research/papers/autoresearch/benchmark/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://ruokezhang.github.io/zh-cn/research/papers/autoresearch/benchmark/</guid>
      <description>&lt;h1 id=&#34;mle-dojo-benchmark&#34;&gt;MLE-Dojo Benchmark&lt;/h1&gt;&#xA;&lt;h2 id=&#34;这是什么&#34;&gt;这是什么&lt;/h2&gt;&#xA;&lt;p&gt;MLE-Dojo 是一个面向 LLM machine learning engineering（MLE）agent 的交互式 benchmark / Gym-style 环境。它把真实 Kaggle 竞赛整理成可执行任务，让 agent 不只是回答问题，而是要反复读数据、写代码、运行实验、根据反馈调试，并提交预测结果。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
