<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>未分类 &#8211; Bubblog</title>
	<atom:link href="https://blog.yangyuanping.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.yangyuanping.com</link>
	<description>nullable reference types</description>
	<lastBuildDate>Tue, 17 Feb 2026 15:16:11 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://blog.yangyuanping.com/wp-content/uploads/2025/11/cropped-patrick_log_logo_251121-2-32x32.png</url>
	<title>未分类 &#8211; Bubblog</title>
	<link>https://blog.yangyuanping.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>CSS Grid 与 Flexbox 深度对比：何时使用哪个布局方案？</title>
		<link>https://blog.yangyuanping.com/css-grid-%e4%b8%8e-flexbox-%e6%b7%b1%e5%ba%a6%e5%af%b9%e6%af%94%ef%bc%9a%e4%bd%95%e6%97%b6%e4%bd%bf%e7%94%a8%e5%93%aa%e4%b8%aa%e5%b8%83%e5%b1%80%e6%96%b9%e6%a1%88%ef%bc%9f/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Tue, 17 Feb 2026 15:16:11 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1124</guid>

					<description><![CDATA[在现代前端开发中，CSS Grid 和 Flexbox 是两个最强大的布局工具。很多开发者知道它们的基本用法， [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>在现代前端开发中，CSS Grid 和 Flexbox 是两个最强大的布局工具。很多开发者知道它们的基本用法，但在实际项目中常常纠结：这个场景该用 Grid 还是 Flexbox？本文将通过实战案例深入解析两者的适用场景和组合使用技巧。</p>
<h2>核心区别：一维 vs 二维</h2>
<p>最本质的区别在于：</p>
<ul>
<li><strong>Flexbox</strong>：一维布局系统，适合处理<strong>行或列</strong>方向的排列</li>
<li><strong>Grid</strong>：二维布局系统，同时控制<strong>行和列</strong>的精确定位</li>
</ul>
<p>这不是说 Flexbox 不能做二维布局，而是 Grid 在二维场景下更加优雅和高效。</p>
<h2>实战案例 1：导航栏布局</h2>
<p>导航栏是典型的<strong>一维布局</strong>场景，Flexbox 是最佳选择：</p>
<pre><code>.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
  list-style: none;
}

.nav-links li {
  white-space: nowrap;
}

/* 响应式：小屏幕垂直排列 */
@media (max-width: 768px) {
  .navbar {
    flex-direction: column;
    gap: 1rem;
  }
}</code></pre>
<p><strong>为什么用 Flexbox？</strong></p>
<ul>
<li>导航项按<strong>单一方向</strong>排列</li>
<li><code>gap</code> 属性自动处理间距</li>
<li><code>flex-direction</code> 轻松切换横竖布局</li>
</ul>
<h2>实战案例 2：卡片网格布局</h2>
<p>产品列表、图片墙等<strong>网格场景</strong>，Grid 完胜：</p>
<pre><code>.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

.card {
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}</code></pre>
<p><strong>Grid 的优势：</strong></p>
<ul>
<li><code>auto-fit + minmax</code> 实现<strong>完美自适应</strong>，无需媒体查询</li>
<li>自动填充空间，每个卡片宽度一致</li>
<li>比 Flexbox 的 <code>flex-wrap</code> 方案更可控</li>
</ul>
<h2>实战案例 3：复杂页面布局</h2>
<p>圣杯布局（Header + Sidebar + Main + Footer）是 Grid 的杀手级应用：</p>
<pre><code>.app-layout {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }

/* 响应式：小屏幕单列布局 */
@media (max-width: 1024px) {
  .app-layout {
    grid-template-areas:
      "header"
      "main"
      "aside"
      "footer";
    grid-template-columns: 1fr;
  }
}</code></pre>
<p><strong>Grid 的语义化优势：</strong></p>
<ul>
<li><code>grid-template-areas</code> 让布局结构<strong>一目了然</strong></li>
<li>调整布局只需改变 <code>areas</code> 定义，无需修改 HTML</li>
<li>轻松实现复杂的<strong>跨行跨列</strong>效果</li>
</ul>
<h2>高级技巧：Grid + Flexbox 组合</h2>
<p>真正的高手懂得<strong>组合使用</strong>两者。典型场景：Grid 定义整体框架，Flexbox 处理内部细节。</p>
<pre><code>/* Grid 控制整体布局 */
.dashboard {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

/* Flexbox 处理卡片内部对齐 */
.widget {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: white;
  border-radius: 8px;
}

.widget-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.widget-content {
  flex: 1; /* 占据剩余空间 */
}

.widget-footer {
  margin-top: auto; /* 推到底部 */
  padding-top: 1rem;
  border-top: 1px solid #eee;
}</code></pre>
<h2>性能考量</h2>
<p>两者的渲染性能相当，但有细微差异：</p>
<table>
<tr>
<th>场景</th>
<th>推荐方案</th>
<th>原因</th>
</tr>
<tr>
<td>动态添加元素</td>
<td>Flexbox</td>
<td>Grid 需要重新计算整个网格</td>
</tr>
<tr>
<td>固定结构</td>
<td>Grid</td>
<td>浏览器可预先优化布局计算</td>
</tr>
<tr>
<td>大量嵌套</td>
<td>避免过度嵌套</td>
<td>两者都会增加计算成本</td>
</tr>
</table>
<h2>决策树：如何选择？</h2>
<pre><code>需要二维精确定位？
├─ 是 CSS Grid
└─ 否
   |
   需要内容自适应宽度？
   ├─ 是 Flexbox (justify-content)
   └─ 否
      |
      需要复杂的对齐控制？
      ├─ 是 Flexbox (align-items/self)
      └─ 否 看具体需求，两者皆可</code></pre>
<h2>浏览器兼容性</h2>
<ul>
<li><strong>Flexbox</strong>：IE 10+ （需要前缀）</li>
<li><strong>Grid</strong>：IE 11+（部分支持，需要旧语法）、现代浏览器完全支持</li>
<li>生产环境建议使用 <strong>Autoprefixer</strong> 自动处理兼容性</li>
</ul>
<h2>总结</h2>
<p>掌握 Grid 和 Flexbox 的核心原则：</p>
<ul>
<li><strong>Flexbox</strong>：内容驱动布局，适合<strong>组件内部</strong>细节排列</li>
<li><strong>Grid</strong>：结构驱动布局，适合<strong>页面级</strong>框架搭建</li>
<li><strong>组合使用</strong>：Grid 定框架，Flexbox 调细节</li>
</ul>
<p>不要陷入&#8221;只用其一&#8221;的误区，根据场景灵活选择才是专业开发者的标志。实际项目中，80% 的布局问题都可以用这两个工具优雅解决，无需依赖第三方框架。</p>
<p><em>（本文基于 CSS3 最新规范和现代浏览器最佳实践整理，适合有一定 CSS 基础的开发者深入学习）</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>C# 异步编程：从入门到精通的最佳实践</title>
		<link>https://blog.yangyuanping.com/c-%e5%bc%82%e6%ad%a5%e7%bc%96%e7%a8%8b%ef%bc%9a%e4%bb%8e%e5%85%a5%e9%97%a8%e5%88%b0%e7%b2%be%e9%80%9a%e7%9a%84%e6%9c%80%e4%bd%b3%e5%ae%9e%e8%b7%b5/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 16:38:21 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1121</guid>

					<description><![CDATA[C# 的 async/await 关键字让异步编程变得前所未有的简单，但这种简洁性有时会隐藏底层的复杂性。本文 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>C# 的 async/await 关键字让异步编程变得前所未有的简单，但这种简洁性有时会隐藏底层的复杂性。本文将深入探讨异步编程的最佳实践，帮助你写出更高效、更可靠的异步代码。</p>
<h2>async/await 基础回顾</h2>
<p>async 和 await 是语法糖，编译器会将它们转换为状态机。关键点在于：</p>
<ul>
<li><strong>async 方法</strong>：返回 Task 或 Task&lt;T&gt;，调用时不会阻塞线程</li>
<li><strong>await 表达式</strong>：等待任务完成，期间释放线程</li>
<li><strong>ConfigureAwait(false)</strong>：跨线程上下文优化性能</li>
</ul>
<pre><code>// 基础异步方法
public async Task&lt;User&gt; GetUserAsync(int id)
{
    var user = await _userRepository.FindByIdAsync(id);
    return user;
}

// 库代码中的最佳实践
public async Task&lt;IEnumerable&lt;User&gt;&gt; GetAllUsersAsync()
{
    var users = await _userRepository.GetAllAsync()
        .ConfigureAwait(false); // 不需要同步上下文
    return users;
}
</code></pre>
<h2>常见陷阱与解决方案</h2>
<h3>1. 死锁问题</h3>
<pre><code>// &#x274c; 危险：在 UI 线程或 ASP.NET 同步上下文中调用
var user = GetUserAsync(id).Result; // 可能死锁！

// &#x2705; 安全：始终使用 await
var user = await GetUserAsync(id);
</code></pre>
<h3>2. 异常处理</h3>
<pre><code>// &#x274c; 错误：异常被吞掉
try
{
    await Task.Run(() => { throw new Exception("Oops"); });
}
finally
{
    // 这里捕获不到异常
}

// &#x2705; 正确：多个任务并行，统一处理异常
var tasks = new List&lt;Task&gt;
{
    Task1Async(),
    Task2Async(),
    Task3Async()
};

try
{
    await Task.WhenAll(tasks);
}
catch (Exception ex)
{
    // 只能看到第一个异常
    Console.WriteLine($"Exception: {ex.Message}");
}
</code></pre>
<h3>3. void 返回类型</h3>
<pre><code>// &#x274c; 避免：async void 方法
public async void BadMethod()
{
    await Task.Delay(1000);
    // 异常无法被外部捕获！
}

// &#x2705; 推荐：使用 Task 返回类型
public async Task GoodMethod()
{
    await Task.Delay(1000);
    // 异常可以被 await 或 .Result 捕获
}
</code></pre>
<h2>性能优化技巧</h2>
<h3>1. 避免不必要的 async</h3>
<pre><code>// &#x274c; 浪费：不需要 async
public async Task&lt;int&gt; GetValueAsync()
{
    return await ComputeValueAsync(); // 不必要的 await
}

// &#x2705; 高效：直接返回 Task
public Task&lt;int&gt; GetValueAsync()
{
    return ComputeValueAsync();
}
</code></pre>
<h3>2. ValueTask 优化</h3>
<pre><code>// 高频缓存场景：使用 ValueTask 减少内存分配
public async ValueTask&lt;User&gt; GetUserAsync(int id)
{
    // 快速路径：缓存命中，无需分配 Task 对象
    if (_cache.TryGetValue(id, out var user))
        return user;
    
    // 慢速路径：需要异步查询
    user = await _repository.FindByIdAsync(id);
    _cache[id] = user;
    return user;
}
</code></pre>
<h3>3. 并行处理</h3>
<pre><code>// &#x274c; 串行：慢
var user = await GetUserAsync(id);
var orders = await GetOrdersAsync(id);
var payments = await GetPaymentsAsync(id);

// &#x2705; 并行：快 3 倍
var userTask = GetUserAsync(id);
var ordersTask = GetOrdersAsync(id);
var paymentsTask = GetPaymentsAsync(id);

await Task.WhenAll(userTask, ordersTask, paymentsTask);

var user = await userTask;
var orders = await ordersTask;
var payments = await paymentsTask;
</code></pre>
<h2>取消支持</h2>
<p>长时间运行的操作应该支持取消：</p>
<pre><code>public async Task&lt;IEnumerable&lt;User&gt;&gt; GetUsersAsync(
    CancellationToken cancellationToken = default)
{
    var users = new List&lt;User&gt;();
    
    await foreach (var user in _repository.StreamUsersAsync(cancellationToken))
    {
        cancellationToken.ThrowIfCancellationRequested();
        users.Add(user);
    }
    
    return users;
}

// 使用示例
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

try
{
    var users = await GetUsersAsync(cts.Token);
}
catch (OperationCanceledException)
{
    Console.WriteLine("操作被取消");
}
</code></pre>
<h2>实战案例：异步 HTTP 请求</h2>
<pre><code>public class HttpClientWrapper
{
    private readonly HttpClient _httpClient;
    private readonly ILogger&lt;HttpClientWrapper&gt; _logger;

    public HttpClientWrapper(
        HttpClient httpClient,
        ILogger&lt;HttpClientWrapper&gt; logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    public async Task&lt;T&gt; GetAsync&lt;T&gt;(
        string url,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var response = await _httpClient
                .GetAsync(url, cancellationToken)
                .ConfigureAwait(false);

            response.EnsureSuccessStatusCode();

            var content = await response
                .Content
                .ReadAsStringAsync(cancellationToken)
                .ConfigureAwait(false);

            return JsonSerializer.Deserialize&lt;T&gt;(content);
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "HTTP 请求失败: {Url}", url);
            throw;
        }
        catch (JsonException ex)
        {
            _logger.LogError(ex, "JSON 反序列化失败: {Url}", url);
            throw;
        }
    }
}
</code></pre>
<h2>总结</h2>
<p>C# 异步编程的核心原则：</p>
<ul>
<li><strong>始终使用 await</strong>：避免 .Result 或 .Wait() 导致的死锁</li>
<li><strong>避免 async void</strong>：使用 Task 返回类型以便异常处理</li>
<li><strong>优化性能</strong>：使用 ConfigureAwait(false)、ValueTask、并行处理</li>
<li><strong>支持取消</strong>：长时间运行的操作应该接受 CancellationToken</li>
<li><strong>正确处理异常</strong>：使用 try/catch 捕获异步异常</li>
</ul>
<p>掌握这些技巧，你就能写出高效、可靠的异步代码，充分发挥 .NET 平台的并发处理能力。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>pmset 命令速查</title>
		<link>https://blog.yangyuanping.com/pmset-%e5%91%bd%e4%bb%a4%e9%80%9f%e6%9f%a5/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Fri, 13 Feb 2026 06:10:59 +0000</pubDate>
				<category><![CDATA[Linux Nibbles]]></category>
		<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1104</guid>

					<description><![CDATA[查看当前电源设置 常用设置 关闭显示器（分钟） 电脑休眠（分钟） 硬盘休眠（分钟） 待机延迟（秒） 混合休眠模 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="查看当前电源设置">查看当前电源设置</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>pmset -g</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span></span></code></pre></div>



<h4 class="wp-block-heading" id="常用设置">常用设置</h4>



<h6 class="wp-block-heading" id="关闭显示器（分钟）">关闭显示器（分钟）</h6>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset displaysleep 15</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displaysleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">15</span></span></code></pre></div>



<h3 class="wp-block-heading" id="电脑休眠（分钟）">电脑休眠（分钟）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset sleep 30</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">30</span></span></code></pre></div>



<h3 class="wp-block-heading" id="硬盘休眠（分钟）">硬盘休眠（分钟）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset disksleep 10</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disksleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span></span></code></pre></div>



<h3 class="wp-block-heading" id="待机延迟（秒）">待机延迟（秒）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset standbydelay 10800
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">standbydelay</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10800</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading" id="混合休眠模式">混合休眠模式</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset standby 1 # 启用待机
sudo pmset hibernatemode 25 # 混合休眠</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">standby</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">启用待机</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hibernatemode</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">25</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">混合休眠</span></span></code></pre></div>



<h2 class="wp-block-heading" id="常用组合">常用组合</h2>



<h3 class="wp-block-heading" id="永不休眠（接电源）">永不休眠（接电源）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset -c sleep 0 displaysleep 0 disksleep 0</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">c</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displaysleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disksleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span></code></pre></div>



<h3 class="wp-block-heading" id="电池省电模式">电池省电模式</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset -b sleep 15 displaysleep 5 disksleep 10</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">15</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displaysleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disksleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span></span></code></pre></div>



<h2 class="wp-block-heading" id="字段说明">字段说明</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>字段</th><th>值</th><th>说明</th></tr></thead><tbody><tr><td><strong>lidwake</strong></td><td>1</td><td>开盖唤醒</td></tr><tr><td><strong>autopoweroff</strong></td><td>0</td><td>自动关机（省电关机）</td></tr><tr><td><strong>lowpowermode</strong></td><td>1</td><td>低电量模式</td></tr><tr><td><strong>standbydelayhigh</strong></td><td>86400</td><td>高电量待机延迟（秒，24小时）</td></tr><tr><td><strong>autopoweroffdelay</strong></td><td>259200</td><td>自动关机延迟（秒，3天）</td></tr><tr><td><strong>proximitywake</strong></td><td>0</td><td>proximity 唤醒</td></tr><tr><td><strong>standby</strong></td><td>0</td><td>待机模式</td></tr><tr><td><strong>standbydelaylow</strong></td><td>10800</td><td>低电量待机延迟（秒，3小时）</td></tr><tr><td><strong>ttyskeepawake</strong></td><td>1</td><td>TTY 保持唤醒</td></tr><tr><td><strong>hibernatemode</strong></td><td>0</td><td>休眠模式（0=禁用）</td></tr><tr><td><strong>powernap</strong></td><td>0</td><td>电源nap</td></tr><tr><td><strong>gpuswitch</strong></td><td>2</td><td>GPU 自动切换</td></tr><tr><td><strong>hibernatefile</strong></td><td>/var/vm/sleepimage</td><td>休眠文件路径</td></tr><tr><td><strong>highstandbythreshold</strong></td><td>50</td><td>高电量待机阈值</td></tr><tr><td><strong>displaysleep</strong></td><td>5</td><td>显示器休眠（分钟）</td></tr><tr><td><strong>womp</strong></td><td>0</td><td>网络唤醒</td></tr><tr><td><strong>networkoversleep</strong></td><td>0</td><td>网络过载休眠</td></tr><tr><td><strong>sleep</strong></td><td>10</td><td>电脑休眠（分钟）</td></tr><tr><td><strong>lessbright</strong></td><td>1</td><td>暗屏时降低亮度</td></tr><tr><td><strong>halfdim</strong></td><td>1</td><td>半亮度休眠</td></tr><tr><td><strong>tcpkeepalive</strong></td><td>1</td><td>TCP 保持连接</td></tr><tr><td><strong>acwake</strong></td><td>0</td><td>电源适配器唤醒</td></tr><tr><td><strong>disksleep</strong></td><td>10</td><td>硬盘休眠（分钟）</td></tr></tbody></table></figure>



<h2 class="wp-block-heading" id="查看所有设置详情">查看所有设置详情</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>pmset -g custom</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">custom</span></span></code></pre></div>



<h2 class="wp-block-heading" id="恢复默认设置">恢复默认设置</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset -a sleep 10 displaysleep 10 disksleep 10</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displaysleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disksleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span></span></code></pre></div>



<h3 class="wp-block-heading" id="禁用休眠（适合常开机）">禁用休眠（适合常开机）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo pmset -a sleep 0 disksleep 0
udo pmset -a hibernatemode 0</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disksleep</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9">udo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hibernatemode</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span></code></pre></div>



<h3 class="wp-block-heading" id="查看唤醒原因">查看唤醒原因</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># 查看当前阻止系统 / 显示器睡眠的所有电源断言（Power Assertions），快速定位 Mac 无法自动休眠的原因。
pmset -g assertions 

# 查看唤醒原因
pmset -g | grep wake</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">查看当前阻止系统</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">显示器睡眠的所有电源断言</span><span style="color: #D8DEE9FF">（</span><span style="color: #D8DEE9">Power</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Assertions</span><span style="color: #D8DEE9FF">），</span><span style="color: #D8DEE9">快速定位</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Mac</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">无法自动休眠的原因</span><span style="color: #D8DEE9FF">。</span></span>
<span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">assertions</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">查看唤醒原因</span></span>
<span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">grep</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">wake</span></span></code></pre></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>需求</th><th>命令</th><th></th></tr></thead><tbody><tr><td>看唤醒设置</td><td><code>pmset -g</code></td><td>`grep wake`</td></tr><tr><td>看最近唤醒原因</td><td><code>pmset -g log</code></td><td>`grep -i &#8220;wake reason&#8221;`</td></tr><tr><td>看定时唤醒</td><td><code>pmset -g sched</code></td><td></td></tr><tr><td>查阻止睡眠的进程</td><td><code>pmset -g assertions</code></td><td></td></tr></tbody></table></figure>



<h2 class="wp-block-heading" id="参数说明">参数说明</h2>



<ul class="wp-block-list">
<li><code>-a</code> 所有电源模式</li>



<li><code>-c</code> 电源适配器（接充电器）</li>



<li><code>-b</code> 电池模式</li>



<li><code>-u</code> UPS 模式</li>
</ul>



<h2 class="wp-block-heading" id="hibernatemode-取值">hibernatemode 取值</h2>



<ul class="wp-block-list">
<li><code>0</code> &#8211; 内存休眠，唤醒快</li>



<li><code>1</code> &#8211; 安全休眠到磁盘</li>



<li><code>3</code> &#8211; 内存+磁盘混合（默认）</li>



<li><code>25</code> &#8211; 强制休眠到磁盘</li>
</ul>



<h2 class="wp-block-heading" id="相关命令">相关命令</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="复制" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># 立即锁屏
pmset displaysleepnow

# 查看电池状态
pmset -g batt

# 查看唤醒原因
pmset -g wake</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">立即锁屏</span></span>
<span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">displaysleepnow</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">查看电池状态</span></span>
<span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">batt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">查看唤醒原因</span></span>
<span class="line"><span style="color: #D8DEE9">pmset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">g</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">wake</span></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>来源</strong>: macOS 系统命令</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>OpenRTB 协议实战：程序化广告的通信语言</title>
		<link>https://blog.yangyuanping.com/openrtb-%e5%8d%8f%e8%ae%ae%e5%ae%9e%e6%88%98%ef%bc%9a%e7%a8%8b%e5%ba%8f%e5%8c%96%e5%b9%bf%e5%91%8a%e7%9a%84%e9%80%9a%e4%bf%a1%e8%af%ad%e8%a8%80/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Thu, 12 Feb 2026 15:38:32 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1079</guid>

					<description><![CDATA[OpenRTB 协议实战：程序化广告的通信语言 在程序化广告生态中，DSP（需求方平台）、ADX（广告交易平台 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>OpenRTB 协议实战：程序化广告的通信语言</h1>
<p>在程序化广告生态中，<strong>DSP（需求方平台）</strong>、<strong>ADX（广告交易平台）</strong> 与 <strong>SSP（供应方平台）</strong> 之间的实时通信是整个竞价链路的核心。而这套通信机制的基础，正是 <strong>OpenRTB 协议</strong>。</p>
<p>本文将从协议结构、关键字段、实际案例三个维度，帮你快速掌握 OpenRTB 的核心要点。</p>
<h2>一、为什么需要 OpenRTB？</h2>
<p>传统广告投放依赖人工操作，效率低、粒度粗。而程序化广告追求 <strong>毫秒级响应</strong>、<strong>实时竞价</strong>、<strong>精准定向</strong>，必须有一套标准化的数据交换格式。</p>
<p>OpenRTB（Real-Time Bidding）由 <strong>IAB（Interactive Advertising Bureau）</strong> 主导制定，目前主流版本是 <strong>OpenRTB 2.5</strong>。</p>
<p><strong>核心价值：</strong></p>
<ul>
<li>统一数据格式，降低对接成本</li>
<li>支持实时竞价，毫秒级响应</li>
<li>丰富的扩展字段，满足业务定制化需求</li>
</ul>
<h2>二、协议结构一览</h2>
<p>一次完整的竞价流程涉及两个核心请求：</p>
<h3>1. Bid Request（出价请求）— ADX → DSP</h3>
<p>这是 ADX 向 DSP 发送的&quot;竞价邀请&quot;，包含广告位信息、用户特征、投放限制等。</p>
<pre><code class="language-json">{
  "id": "abc123-uuid",
  "tmax": 120,
  "device": {
    "ua": "Mozilla/5.0...",
    "ip": "203.0.113.42",
    "geo": {
      "country": "CHN",
      "city": "Dalian"
    }
  },
  "user": {
    "id": "user_xyz789",
    "data": [{
      "segment": [{"id": "interest_tech"}]
    }]
  },
  "imp": [{
    "id": "1",
    "bidfloor": 0.5,
    "banner": {
      "w": 300,
      "h": 250,
      "mimes": ["image/jpeg", "image/png"]
    }
  }],
  "site": {
    "id": "site_001",
    "name": "News Portal",
    "publisher": {"id": "pub_123"}
  }
}</code></pre>
<p><strong>关键字段解读：</strong></p>
<ul>
<li>&lt;code&gt;id&lt;/code&gt;: 唯一请求标识，用于关联后续响应</li>
<li>&lt;code&gt;tmax&lt;/code&gt;: 超时时间（毫秒），DSP 必须在此时限内返回响应</li>
<li>&lt;code&gt;device&lt;/code&gt;: 设备信息（UA、IP、地理位置），用于用户定向</li>
<li>&lt;code&gt;imp&lt;/code&gt;: 广告展示请求列表，每个 &lt;code&gt;imp&lt;/code&gt; 代表一个广告位</li>
<li>&lt;code&gt;bidfloor&lt;/code&gt;: 最低出价（CPM）</li>
</ul>
<h3>2. Bid Response（出价响应）— DSP → ADX</h3>
<p>DSP 收到请求后，经过竞价决策，返回出价结果。</p>
<pre><code class="language-json">{
  "id": "abc123-uuid",
  "seatbid": [{
    "bid": [{
      "id": "bid_001",
      "impid": "1",
      "price": 1.25,
      "adm": "&lt;html&gt;&lt;img src=https://ad.example.com/creative.jpg/&gt;&lt;/html&gt;",
      "crid": "creative_888",
      "nurl": "https://dsp.example.com/win?price=${AUCTION_PRICE}"
    }]
  }],
  "bidid": "bid_response_001"
}</code></pre>
<p><strong>关键字段解读：</strong></p>
<ul>
<li>&lt;code&gt;seatbid&lt;/code&gt;: 出价席位列表</li>
<li>&lt;code&gt;price&lt;/code&gt;: 出价金额（CPM）</li>
<li>&lt;code&gt;adm&lt;/code&gt;: 广告物料（HTML、图片、VAST 等）</li>
<li>&lt;code&gt;crid&lt;/code&gt;: 创意 ID，用于素材追踪</li>
<li>&lt;code&gt;nurl&lt;/code&gt;: 竞价获胜通知地址，&lt;code&gt;${AUCTION_PRICE}&lt;/code&gt; 会被替换为实际成交价</li>
</ul>
<h2>三、实战：竞价超时处理</h2>
<p>在 RTB 项目中，<strong>超时控制</strong>是性能优化的关键。</p>
<p>根据行业实践和 MEMORY.md 中记录的约束要求：</p>
<ul>
<li><strong>Bid Request 处理 &lt; 30ms</strong></li>
<li><strong>Redis 读写 &lt; 5ms</strong></li>
</ul>
<p><strong>超时处理代码示例（C#）：</strong></p>
<pre><code class="language-csharp">public async Task&lt;BidResponse&gt; HandleBidRequestAsync(BidRequest request, CancellationToken ct)
{
    // 创建超时任务
    var timeoutTask = Task.Delay(25, ct); // 预留 5ms 余量

    // 并行执行竞价逻辑
    var biddingTask = ExecuteBiddingAsync(request, ct);

    // 任一任务完成即返回
    var completedTask = await Task.WhenAny(biddingTask, timeoutTask);

    if (completedTask == timeoutTask)
    {
        // 超时，返回默认响应或空响应
        _logger.LogWarning("Bid request {RequestId} timed out", request.Id);
        return CreateDefaultResponse(request.Id);
    }

    return await biddingTask;
}</code></pre>
<p><strong>Redis 缓存优化策略：</strong></p>
<pre><code class="language-csharp">public async Task&lt;UserProfile&gt; GetUserProfileAsync(string userId)
{
    var cacheKey = $"user:{userId}";

    // 先查 Redis（目标 &lt; 5ms）
    var cached = await _redisDatabase.StringGetAsync(cacheKey);
    if (cached.HasValue)
    {
        return JsonSerializer.Deserialize&lt;UserProfile&gt;(cached);
    }

    // 缓存未命中，查 DB 后回填
    var profile = await _repository.GetUserProfileAsync(userId);

    // 异步回写缓存
    _ = _redisDatabase.StringSetAsync(cacheKey, 
        JsonSerializer.Serialize(profile), 
        TimeSpan.FromMinutes(5));

    return profile;
}</code></pre>
<h2>四、注意事项</h2>
<ol>
<li><strong>协议版本兼容性</strong>：不同 ADX 可能使用不同版本的 OpenRTB，需做好版本适配层</li>
<li><strong>安全传输</strong>：生产环境必须使用 HTTPS/TLS，防止请求被篡改</li>
<li><strong>日志脱敏</strong>：用户 IP、设备 ID 等敏感信息在日志中需脱敏处理</li>
<li><strong>幂等性</strong>：ID 生成和请求处理需保证幂等，避免重复计费</li>
</ol>
<h2>五、总结</h2>
<p>OpenRTB 是程序化广告的&quot;通用语言&quot;，掌握其协议结构和实战用法，是开发 DSP/ADX 系统的基础。建议结合实际项目（如 Google Authorized Buyers、OpenRTB 规范文档）深入学习。</p>
<hr />
<p><strong>参考来源：</strong></p>
<ul>
<li>IAB OpenRTB 2.5 Specification</li>
<li>Google Authorized Buyers API Documentation</li>
</ul>
<blockquote>
<p>关注我，获取更多 RTB 实战经验与 .NET 性能优化技巧。</p>
</blockquote>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mac 中使用 VSCode 开发 Framework 项目指南</title>
		<link>https://blog.yangyuanping.com/mac-%e4%b8%ad%e4%bd%bf%e7%94%a8-vscode-%e5%bc%80%e5%8f%91-framework-%e9%a1%b9%e7%9b%ae%e6%8c%87%e5%8d%97/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Tue, 23 Dec 2025 14:19:57 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[VSCode]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1072</guid>

					<description><![CDATA[前置要求 对于 .NET Framework 4.5.2 项目，在 macOS 上需要使用 Mono 来运行。 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>前置要求</h2>
<p>对于 .NET Framework 4.5.2 项目，在 macOS 上需要使用 Mono 来运行。</p>
<h2>第一步：安装必需工具</h2>
<h3>1. 安装 Mono</h3>
<pre><code class="language-bash">brew install mono</code></pre>
<p>验证安装：</p>
<pre><code class="language-bash">mono --version</code></pre>
<h3>2. 安装 NuGet</h3>
<pre><code class="language-bash">brew install nuget</code></pre>
<h3>3. 安装 MSBuild (包含在 Mono 中)</h3>
<p>验证安装：</p>
<pre><code class="language-bash">msbuild -version</code></pre>
<h3>4. 安装 XSP (Mono 的 Web 服务器)</h3>
<pre><code class="language-bash">brew install xsp</code></pre>
<h2>第二步：安装 VSCode 扩展</h2>
<p>在 VSCode 中安装以下扩展（已在 &lt;code&gt;.vscode/extensions.json&lt;/code&gt; 中推荐）：</p>
<ol>
<li><strong>C# Dev Kit</strong> &#8211; 微软官方 C# 支持</li>
<li><strong>C#</strong> &#8211; OmniSharp 语言服务</li>
<li><strong>.NET Test Explorer</strong> &#8211; 测试资源管理器</li>
</ol>
<p>重启 VSCode 以激活扩展。</p>
<h2>第三步：构建项目</h2>
<h3>方法 1：使用 VSCode 任务（推荐）</h3>
<ol>
<li>按 &lt;code&gt;Cmd+Shift+P&lt;/code&gt; 打开命令面板</li>
<li>选择 &lt;code&gt;Tasks: Run Task&lt;/code&gt;</li>
<li>选择 &lt;code&gt;构建解决方案 (Debug)&lt;/code&gt;</li>
</ol>
<h3>方法 2：使用终端命令</h3>
<pre><code class="language-bash"># 恢复 NuGet 包
nuget restore &lt;Solution-Name&gt;.sln

# 构建项目
msbuild &lt;Solution-Name&gt;.sln /p:Configuration=Debug</code></pre>
<h2>第四步：运行和调试</h2>
<h3>运行 WebAPI 项目</h3>
<h4>方法 1：使用 XSP（Mono Web 服务器）</h4>
<pre><code class="language-bash"># 在终端中运行
xsp4 --port=&lt;PORT&gt; --path=&lt;ProjectName&gt;</code></pre>
<p>然后访问：<a href="http://localhost:23985/api/message">http://localhost:23985/api/message</a></p>
<h4>方法 2：使用 VSCode 任务</h4>
<ol>
<li>按 &lt;code&gt;Cmd+Shift+P&lt;/code&gt;</li>
<li>选择 &lt;code&gt;Tasks: Run Task&lt;/code&gt;</li>
<li>选择 &lt;code&gt;运行 WebAPI (XSP)&lt;/code&gt;</li>
</ol>
<h3>调试代码</h3>
<ol>
<li>在代码中设置断点（点击行号左侧）</li>
<li>按 &lt;code&gt;F5&lt;/code&gt; 或点击调试面板的&quot;开始调试&quot;</li>
<li>选择配置：&lt;code&gt;调试 WebAPI (Mono)&lt;/code&gt;</li>
</ol>
<h3>运行单元测试</h3>
<h4>使用 VSCode 任务：</h4>
<ol>
<li>按 &lt;code&gt;Cmd+Shift+P&lt;/code&gt;</li>
<li>选择 &lt;code&gt;Tasks: Run Task&lt;/code&gt;</li>
<li>选择 &lt;code&gt;运行单元测试&lt;/code&gt;</li>
</ol>
<h4>使用命令行：</h4>
<pre><code class="language-bash"># 首先需要安装 NUnit Console Runner（如果还没有）
nuget install NUnit.ConsoleRunner -Version 3.15.0 -OutputDirectory packages

# 运行测试
mono packages/NUnit.ConsoleRunner.3.15.0/tools/nunit3-console.exe \
  &lt;TestProjectName&gt;/bin/Debug/&lt;TestProjectName&gt;.dll</code></pre>
<h2>常用 VSCode 快捷键</h2>
<ul>
<li>&lt;code&gt;Cmd+Shift+B&lt;/code&gt; &#8211; 运行默认构建任务</li>
<li>&lt;code&gt;F5&lt;/code&gt; &#8211; 开始调试</li>
<li>&lt;code&gt;Shift+F5&lt;/code&gt; &#8211; 停止调试</li>
<li>&lt;code&gt;F9&lt;/code&gt; &#8211; 切换断点</li>
<li>&lt;code&gt;F10&lt;/code&gt; &#8211; 单步跳过</li>
<li>&lt;code&gt;F11&lt;/code&gt; &#8211; 单步进入</li>
<li>&lt;code&gt;Cmd+K Cmd+D&lt;/code&gt; &#8211; 格式化文档</li>
</ul>
<h2>常见问题</h2>
<h3>1. Mono 找不到程序集</h3>
<p>确保已运行 &lt;code&gt;nuget restore&lt;/code&gt; 来恢复所有依赖包。</p>
<h3>2. MSBuild 失败</h3>
<p>检查 Mono 版本是否支持 .NET Framework 4.5.2：</p>
<pre><code class="language-bash">mono --version</code></pre>
<p>需要 Mono 5.0 或更高版本。</p>
<h3>3. XSP 无法启动</h3>
<p>确保端口 23985 未被占用：</p>
<pre><code class="language-bash">lsof -i :23985</code></pre>
<h3>4. OmniSharp 无法加载项目</h3>
<p>在 VSCode 设置中确保：</p>
<ul>
<li>&lt;code&gt;omnisharp.useModernNet&lt;/code&gt; 设置为 &lt;code&gt;false&lt;/code&gt;</li>
<li>&lt;code&gt;omnisharp.monoPath&lt;/code&gt; 指向正确的 Mono 安装路径</li>
</ul>
<h2>已知限制</h2>
<ol>
<li><strong>调试功能受限</strong>：Mono 的调试体验不如 Windows 上的 Visual Studio</li>
<li><strong>性能差异</strong>：Mono 运行性能可能低于 Windows .NET Framework</li>
<li><strong>某些 API 不可用</strong>：部分 Windows 特定的 API 在 Mono 上不支持</li>
</ol>
<h2>建议</h2>
<p>对于生产环境部署，建议：</p>
<ol>
<li>在 Windows Server 上使用 IIS 托管</li>
<li>或考虑将项目迁移到 .NET 6/8 以获得跨平台支持</li>
</ol>
<h2>迁移到现代 .NET 的好处</h2>
<p>如果你计划长期维护此项目，可以考虑迁移到 .NET 8：</p>
<ul>
<li>原生跨平台支持（无需 Mono）</li>
<li>更好的性能</li>
<li>现代化的工具链</li>
<li>长期支持（LTS）</li>
</ul>
<p>迁移步骤请参考：<a href="https://docs.microsoft.com/zh-cn/aspnet/core/migration/">https://docs.microsoft.com/zh-cn/aspnet/core/migration/</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>本地开发环境的自签名 HTTPS 证书不被信任(net::ERR_CERT_AUTHORITY_INVALID)</title>
		<link>https://blog.yangyuanping.com/%e6%9c%ac%e5%9c%b0%e5%bc%80%e5%8f%91%e7%8e%af%e5%a2%83%e7%9a%84%e8%87%aa%e7%ad%be%e5%90%8d-https-%e8%af%81%e4%b9%a6%e4%b8%8d%e8%a2%ab%e4%bf%a1%e4%bb%bbneterr_cert_authority_invalid/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Fri, 19 Dec 2025 05:02:49 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[ERR_CERT_AUTHORITY_INVALID]]></category>
		<category><![CDATA[https]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1053</guid>

					<description><![CDATA[问题描述 本地运行后端项目后，通过浏览器调用 API 时提示： POST https://&#60;ip&#62; [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>问题描述</h2>
<p>本地运行后端项目后，通过浏览器调用 API 时提示：</p>
<pre><code> POST https://&lt;ip&gt;:&lt;port&gt;/path net::ERR_CERT_AUTHORITY_INVALID</code></pre>
<p><strong>原因</strong>：本地开发环境使用的是 .NET 自签名 HTTPS 证书，浏览器默认不信任该证书。</p>
<h2>解决方案</h2>
<h3>方案 1：信任 .NET 开发证书（推荐）</h3>
<pre><code class="language-bash"> dotnet dev-certs https --trust</code></pre>
<p>如果提示证书已存在但不信任，先清理再重新生成：</p>
<pre><code class="language-bash"> dotnet dev-certs https --clean
 dotnet dev-certs https --trust</code></pre>
<blockquote>
<p>一次性解决，之后所有 .NET 本地开发项目都会自动信任。</p>
</blockquote>
<h3>方案 2：使用 HTTP 端口</h3>
<p>修改前端 SDK 的开发环境端点，使用 HTTP 端口 &lt;code&gt;5085&lt;/code&gt; 而非 HTTPS 端口 &lt;code&gt;7218&lt;/code&gt;：</p>
<pre><code class="language-javascript"> // webpack.config.js 或 sdk.js 中
 resolveEndpoint: 'http://&lt;ip&gt;:&lt;port&gt;/path'</code></pre>
<h3>方案 3：浏览器手动信任</h3>
<ol>
<li>直接访问 &lt;code&gt;https://&lt;ip&gt;:&lt;port&gt;/swagger&lt;/code&gt;</li>
<li>浏览器会提示&quot;不安全&quot;，点击&quot;高级&quot; → &quot;继续访问&quot;</li>
<li>
<p>之后该证书在当前浏览器会话中被临时信任</p>
<h3>方案 4：Chrome 启动参数（临时）</h3>
<pre><code class="language-bash"># macOS
open -a "Google Chrome" --args --ignore-certificate-errors --ignore-urlfetcher-cert-requests

# Windows
chrome.exe --ignore-certificate-errors --ignore-urlfetcher-cert-requests</code></pre>
<blockquote>
<p>注意：此方式会忽略所有证书错误，仅用于开发调试。</p>
</blockquote>
</li>
</ol>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>从 Git 历史中删除敏感数据</title>
		<link>https://blog.yangyuanping.com/%e4%bb%8e-git-%e5%8e%86%e5%8f%b2%e4%b8%ad%e5%88%a0%e9%99%a4%e6%95%8f%e6%84%9f%e6%95%b0%e6%8d%ae/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Wed, 26 Nov 2025 18:01:34 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[git]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1041</guid>

					<description><![CDATA[当敏感信息（如密码、密钥、私人域名等）被提交到 Git 仓库后，即使后续提交中删除了这些内容，它们仍然存在于  [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>当敏感信息（如密码、密钥、私人域名等）被提交到 Git 仓库后，即使后续提交中删除了这些内容，它们仍然存在于 Git 历史记录中。本文介绍如何彻底清除这些敏感数据。</p>
<h2>问题场景</h2>
<ul>
<li>不小心提交了 API 密钥、密码</li>
<li>配置文件中包含真实域名或个人信息</li>
<li>已推送到 GitHub 等公开仓库</li>
</ul>
<h2>解决方案&#8217;&quot;</h2>
<h3>方法一：使用 git filter-branch（内置工具）</h3>
<p>适用于替换历史中所有提交的某个文件内容。</p>
<pre><code class="language-bash"># 1. 暂存当前未提交的更改
git stash'"

# 2. 替换历史中所有 README.md 文件里的敏感内容
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --force --tree-filter \
  "find . -name 'README.md' -exec sed -i '' 's/敏感内容/替换内容/g' {} \;" \
  -- --all

# 3. 恢复暂存的更改
git stash pop

# 4. 强制推送到远程仓库（覆盖历史）
git push origin main --force</code></pre>
<h4>参数说明</h4>
<table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>&lt;code&gt;&#8211;force&lt;/code&gt;</td>
<td>强制执行，即使已有备份</td>
</tr>
<tr>
<td>&lt;code&gt;&#8211;tree-filter&lt;/code&gt;</td>
<td>对每个提交的文件树执行命令</td>
</tr>
<tr>
<td>&lt;code&gt;&#8211; &#8211;all&lt;/code&gt;</td>
<td>处理所有分支</td>
</tr>
<tr>
<td>&lt;code&gt;sed -i &#039;&#039;&lt;/code&gt;</td>
<td>macOS 下的原地替换（Linux 用 &lt;code&gt;sed -i&lt;/code&gt;）</td>
</tr>
</tbody>
</table>
<h3>方法二：使用 BFG Repo-Cleaner（推荐，更快）</h3>
<p>适用于删除大文件或敏感文件。</p>
<pre><code class="language-bash"># 安装 BFG
brew install bfg

# 删除某个文件的所有历史
bfg --delete-files 敏感文件.txt

# 或替换敏感文本
bfg --replace-text passwords.txt

# 清理并强制推送
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push origin main --force</code></pre>
<h3>方法三：使用 git filter-repo（官方推荐）</h3>
<pre><code class="language-bash"># 安装
brew install git-filter-repo

# 替换敏感内容
git filter-repo --replace-text &lt;(echo '敏感内容==&gt;替换内容')

# 重新添加远程并推送
git remote add origin https://github.com/user/repo.git
git push origin main --force</code></pre>
<h2>注意事项</h2>
<ol>
<li><strong>强制推送有风险</strong>：会覆盖远程历史，协作者需要重新克隆仓库</li>
<li><strong>轮换密钥</strong>：敏感信息一旦泄露，应立即轮换（如重新生成 API Key）</li>
<li><strong>GitHub 缓存</strong>：GitHub 可能会缓存提交，联系 GitHub 支持可请求清除</li>
<li><strong>本地备份</strong>：操作前建议备份仓库 &lt;code&gt;cp -r .git .git.backup&lt;/code&gt;</li>
</ol>
<h2>预防措施</h2>
<ul>
<li>使用 &lt;code&gt;.gitignore&lt;/code&gt; 忽略敏感文件</li>
<li>使用环境变量存储敏感配置</li>
<li>提交前检查 &lt;code&gt;git diff &#8211;staged&lt;/code&gt;</li>
<li>启用 GitHub 的 Secret Scanning 功能</li>
</ul>
<h2>总结</h2>
<ol>
<li>git stash &#8211; 暂存当前未提交的更改</li>
<li>git filter-branch &#8211;tree-filter &#8211; 遍历所有历史提交，用 sed 替换敏感内容</li>
<li>git stash pop &#8211; 恢复暂存的更改</li>
<li>git push &#8211;force &#8211; 强制推送覆盖远程历史</li>
</ol>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mac OS X uninstall script for packaged install of node.js</title>
		<link>https://blog.yangyuanping.com/mac-os-x-uninstall-script-for-packaged-install-of-node-js/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Mon, 24 Nov 2025 18:49:24 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Node.js]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1033</guid>

					<description><![CDATA[To run this, you can try: curl -ksO https://gist.github [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>To run this, you can try:</p>
<pre><code class="language-bash">curl -ksO https://gist.githubusercontent.com/nicerobot/2697848/raw/uninstall-node.sh
chmod +x ./uninstall-node.sh
./uninstall-node.sh
rm uninstall-node.sh</code></pre>
<p><a href="https://gist.github.com/nicerobot/2697848#file-uninstall-node-sh" title="uninstall-node.sh">uninstall-node.sh</a></p>
<pre><code class="language-bash">#!/bin/sh
(( ${#} &gt; 0 )) || {
  echo 'DISCLAIMER: USE THIS SCRIPT AT YOUR OWN RISK!'
  echo 'THE AUTHOR TAKES NO RESPONSIBILITY FOR THE RESULTS OF THIS SCRIPT.'
  echo "Disclaimer aside, this worked for the author, for what that's worth."
  echo 'Press Control-C to quit now.'
  read
  echo 'Re-running the script with sudo.'
  echo 'You may be prompted for a password.'
  sudo ${0} sudo
  exit $?
}
# This will need to be executed as an Admin (maybe just use sudo).

for bom in org.nodejs.node.pkg.bom org.nodejs.pkg.bom; do

  receipt=/var/db/receipts/${bom}
  [ -e ${receipt} ] &amp;&amp; {
    # Loop through all the files in the bom.
    lsbom -f -l -s -pf ${receipt} \
    | while read i; do
      # Remove each file listed in the bom.
      rm -v /usr/local/${i#/usr/local/}
    done
  }

done

# Remove directories related to node.js.
rm -vrf /usr/local/lib/node \
  /usr/local/lib/node_modules \
  /var/db/receipts/org.nodejs.*

exit 0</code></pre>
<blockquote>
<p><a href="https://gist.github.com/nicerobot/2697848">https://gist.github.com/nicerobot/2697848</a></p>
</blockquote>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>UseHttpsRedirection 与 UseHsts 的区别 </title>
		<link>https://blog.yangyuanping.com/usehttpsredirection-%e4%b8%8e-usehsts-%e7%9a%84%e5%8c%ba%e5%88%ab/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Mon, 24 Nov 2025 12:09:12 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[.Net]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=1029</guid>

					<description><![CDATA[两者都与 HTTPS 安全相关，但作用机制不同： app.UseHttpsRedirection() 作用：H [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>两者都与 HTTPS 安全相关，但作用机制不同：</p>
<p>app.UseHttpsRedirection()</p>
<p>作用：HTTP 到 HTTPS 的即时重定向</p>
<ul>
<li>
<p>当用户访问 <a href="http://example.com">http://example.com</a> 时</p>
</li>
<li>
<p>服务器返回 307/308 重定向响应</p>
</li>
<li>
<p>浏览器自动跳转到 <a href="https://example.com">https://example.com</a></p>
</li>
<li>
<p>每次 HTTP 请求都会重定向</p>
<p>特点：</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 立即生效，无需浏览器记忆</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 首次请求仍是 HTTP（可能被拦截）</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 每次都需要一次额外的重定向请求</p>
<p>响应示例：<br />
HTTP/1.1 308 Permanent Redirect<br />
Location: <a href="https://example.com">https://example.com</a></p>
<hr />
<p>app.UseHsts()</p>
<p>作用：HTTP 严格传输安全（HTTP Strict Transport Security）</p>
</li>
<li>
<p>首次访问（HTTPS）后，服务器返回特殊响应头</p>
</li>
<li>
<p>浏览器记住&quot;这个网站只能用 HTTPS&quot;</p>
</li>
<li>
<p>之后浏览器自动将所有 HTTP 请求改为 HTTPS</p>
</li>
<li>
<p>甚至在发送请求前就转换</p>
<p>特点：</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 浏览器端强制，无需服务器重定向</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 防止中间人攻击（用户无法绕过）</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 首次访问必须是 HTTPS 才能设置</p>
</li>
<li>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 设置后很难撤销（有过期时间）</p>
<p>响应头示例：<br />
Strict-Transport-Security: max-age=31536000; includeSubDomains</p>
<p>参数说明：</p>
</li>
<li>
<p>max-age=31536000：浏览器记住 1 年</p>
</li>
<li>
<p>includeSubDomains：所有子域名也强制 HTTPS</p>
<hr />
<p>对比总结</p>
<table>
<thead>
<tr>
<th>特性</th>
<th>UseHttpsRedirection</th>
<th>UseHsts</th>
</tr>
</thead>
<tbody>
<tr>
<td>工作位置</td>
<td>服务器端重定向</td>
<td>浏览器端强制</td>
</tr>
<tr>
<td>首次访问</td>
<td>HTTP 可访问（重定向）</td>
<td>必须 HTTPS</td>
</tr>
<tr>
<td>后续访问</td>
<td>每次都重定向</td>
<td>浏览器自动转 HTTPS</td>
</tr>
<tr>
<td>性能</td>
<td>多一次请求</td>
<td>无额外请求</td>
</tr>
<tr>
<td>安全性</td>
<td>中等（首次可被劫持）</td>
<td>高（浏览器强制）</td>
</tr>
<tr>
<td>撤销难度</td>
<td>随时可撤销</td>
<td>需等待过期（max-age）</td>
</tr>
</tbody>
</table>
</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Claude Error: File has been unexpectedly modified. Read it again before attempting to write it.</title>
		<link>https://blog.yangyuanping.com/claude-error-file-has-been-unexpectedly-modified-read-it-again-before-attempting-to-write-it/</link>
		
		<dc:creator><![CDATA[peny911]]></dc:creator>
		<pubDate>Thu, 20 Nov 2025 13:35:47 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Claude]]></category>
		<guid isPermaLink="false">https://blog.yangyuanping.com/?p=976</guid>

					<description><![CDATA[Error: File has been unexpectedly modified. Read it aga [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Error: File has been unexpectedly modified. Read it again before attempting to write it.</p>
<blockquote>
<p><a href="https://github.com/anthropics/claude-code/issues/7918">https://github.com/anthropics/claude-code/issues/7918</a></p>
</blockquote>
<pre><code class="language-bash">## CRITICAL: File Editing on Windows

### &#x26a0; MANDATORY: Always Use Backslashes on Windows for File Paths

When using Edit or MultiEdit tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).

#### &#x274c; WRONG - Will cause errors:
Edit(file_path: "D:/repos/project/file.tsx", ...)
MultiEdit(file_path: "D:/repos/project/file.tsx", ...)

#### &#x2705; CORRECT - Always works:
Edit(file_path: "D:\repos\project\file.tsx", ...)
MultiEdit(file_path: "D:\repos\project\file.tsx", ...)

- Always reply in Chinese.</code></pre>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
