<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Electronic Punk]]></title><description><![CDATA[Electronic Punk]]></description><link>https://obzer.io/</link><image><url>https://obzer.io/favicon.png</url><title>Electronic Punk</title><link>https://obzer.io/</link></image><generator>Ghost 3.13</generator><lastBuildDate>Thu, 13 Mar 2025 17:36:56 GMT</lastBuildDate><atom:link href="https://obzer.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(4)]]></title><description><![CDATA[<p>在上一节中我们已经得到了每日更新的数据集,在本节中我们将把数据转换为图形</p><p>1.创建一个数据源</p><p>点击左上角的创建,选择数据源-BigQuery-你的项目名-数据集-我们在上一节中设定好的每日更新的表(我的表叫CWL_DAILY)</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/16.png" class="kg-image"></figure><p><a href="https://datastudio.google.com/s/ibEn0BkYs6E">https://datastudio.google.com/s/ibEn0BkYs6E</a></p><p>这是我的模板地址,如果你已经完成了之前的每一个步骤那么复制模板后选择你刚刚创建好的数据源应该就是直接可用的</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/17.png" class="kg-image"></figure><p>当然,在datastudio的社区里很多人反馈即使设置了自己的数据源仍然会返回"无法连接到数据源"的问题,如果你也遇到了这样的问题,那么就重新创建一份新的报告,并按照我模板内的设置重新生成一份报告即可</p><p>(完)</p>]]></description><link>https://obzer.io/ga4-core-web-vitals-bigquery-datestudio-4/</link><guid isPermaLink="false">6094008d2b9ceb05ff47b705</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Thu, 06 May 2021 15:00:58 GMT</pubDate><media:content url="https://obzer.io/content/images/2021/05/google-cloud-logo--1--3.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2021/05/google-cloud-logo--1--3.jpg" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(4)"><p>在上一节中我们已经得到了每日更新的数据集,在本节中我们将把数据转换为图形</p><p>1.创建一个数据源</p><p>点击左上角的创建,选择数据源-BigQuery-你的项目名-数据集-我们在上一节中设定好的每日更新的表(我的表叫CWL_DAILY)</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/16.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(4)"></figure><p><a href="https://datastudio.google.com/s/ibEn0BkYs6E">https://datastudio.google.com/s/ibEn0BkYs6E</a></p><p>这是我的模板地址,如果你已经完成了之前的每一个步骤那么复制模板后选择你刚刚创建好的数据源应该就是直接可用的</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/17.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(4)"></figure><p>当然,在datastudio的社区里很多人反馈即使设置了自己的数据源仍然会返回"无法连接到数据源"的问题,如果你也遇到了这样的问题,那么就重新创建一份新的报告,并按照我模板内的设置重新生成一份报告即可</p><p>(完)</p>]]></content:encoded></item><item><title><![CDATA[使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(3)]]></title><description><![CDATA[<p>在上一节中我们已经完成了GA4向bigquery导入数据的部分,在这一节中我们将处理这些数据并在datastudio中展示这些数据</p><p>1.查看你导出的数据集</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/13-3.png" class="kg-image"></figure><p>等待24小时后,我们可以看到已经有一份数据导入到了我们的数据集中</p><p>2.创建查询SQL</p><!--kg-card-begin: markdown--><pre><code class="language-sql">SELECT
  e.event_name AS name,
  e.device.category AS device,
  CAST(IFNULL(ep.value.double_value,0) * 1000 AS INT64) AS value
FROM
  `YOUR-DATA-SET-NAME.events_*` e
CROSS JOIN
  UNNEST(event_params) ep
WHERE
  _table_suffix = FORMAT_DATE('%Y%m%d',</code></pre>]]></description><link>https://obzer.io/ga4-core-web-vitals-bigquery-datestudio-3/</link><guid isPermaLink="false">6093fa292b9ceb05ff47b678</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Thu, 06 May 2021 15:00:53 GMT</pubDate><media:content url="https://obzer.io/content/images/2021/05/google-cloud-logo--1--2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2021/05/google-cloud-logo--1--2.jpg" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(3)"><p>在上一节中我们已经完成了GA4向bigquery导入数据的部分,在这一节中我们将处理这些数据并在datastudio中展示这些数据</p><p>1.查看你导出的数据集</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/13-3.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(3)"></figure><p>等待24小时后,我们可以看到已经有一份数据导入到了我们的数据集中</p><p>2.创建查询SQL</p><!--kg-card-begin: markdown--><pre><code class="language-sql">SELECT
  e.event_name AS name,
  e.device.category AS device,
  CAST(IFNULL(ep.value.double_value,0) * 1000 AS INT64) AS value
FROM
  `YOUR-DATA-SET-NAME.events_*` e
CROSS JOIN
  UNNEST(event_params) ep
WHERE
  _table_suffix = FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
  AND e.event_name IN (&quot;LCP&quot;,
    &quot;CLS&quot;,
    &quot;FID&quot;)
  AND ep.key = &quot;web_vitals_measurement_value&quot;
</code></pre>
<!--kg-card-end: markdown--><p>我不确定未经处理的数据直接导入到datastudio,event params value的取值过程究竟是怎么产生的,在CLS一栏中我看到了骇人的大于1,2,5,甚至10的数量,理论上CLS的最大值也只是1,所以此处我们先把收集到的数据清洗一遍,导入一个新的表中,再在datastudio中使用这个表</p><p>这个查询sql会查询最新一天的数据记录,注意这个SQL直接复制是无法使用的,需要讲FROM条件中的YOUR-DATA-SET-NAME替换成你自己数据集的名称,一般这个数据集的名称构成是这样的</p><!--kg-card-begin: html--><code>PROJECTNAME-analytics-GA4衡量ID</code><!--kg-card-end: html--><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/14-2.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(3)"></figure><p>这是我的查询结果,可以看到被放大1000倍并转换成整数类型的值已经非常容易处理了</p><p>3.自动更新表数据</p><p>由于我们的单次查询产生的数据是静态的,因此我们应该设定一个定时执行的任务每天刷新一次处理后的数据</p><p>点击界面的上的"计划查询",创建新的计划查询</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/15-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(3)"></figure><p>设定更新数据集的时间和表名称,我们就完成了这一步的操作,注意此处目标表的写入设置应为"覆盖表",否则我们得到的数据就会是随着时间而叠加的而并非最新一天的.</p><p>至此我们已经完成了bigquery的部分,下一节中我们将在datastudio中把数据转换为图表.</p>]]></content:encoded></item><item><title><![CDATA[使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(2)]]></title><description><![CDATA[<p>在上一节中我们已经配置好了GTM,在这一节中我们将前往GA4完成GA4部分的设置</p><p>1(可选) 检查你在GTM中的代码是否生效</p><p>如果你已经把上一节中的GTM代码发布到正式环境,并把相应的GTM代码加入到你网站的HTML中,一段时间之后,你应该在你的GA4面板中看到这样的事件</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/11.png" class="kg-image"></figure><p>这是我的GA4"实时"面板中的事件栏,可以看到我们设置的自定义事件CLS,LCP和FID已经生效了,如果你没有发现这样的事件出现,可能是由以下几个原因造成</p><p>1.1 你在GTM代码中填入的错误的GA4衡量ID</p><p>1.2 你填入的正确的GA4衡量ID,但是没有正确的把GTM代码加入到你web应用最终渲染出的html中去</p><p>1.3 你的GA4衡量id是正确的,GTM代码也加入了,但是没有点击GTM中的"提交"按钮</p><p>1.4 你的web应用,或者NGINX(APACHE)缓存了你的页面,导致GTM代码没有被正确加载</p><p>1.5 你使用了CDN,CDN缓存了你的页面,登录到CDN管理页面并尝试清除缓存</p><p>2.将你的GA4数据导入到Bigquery</p><p>在在GA4页面点击左下角的小齿轮进入设置页面,选中你的媒体资源,在产品点击Big Query关联,如果你的帐号还没有启用Bigquery API,</p>]]></description><link>https://obzer.io/ga4-core-web-vitals-bigquery-datestudio-2/</link><guid isPermaLink="false">6093ee4384a8285a3c9b1a4f</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Thu, 06 May 2021 15:00:48 GMT</pubDate><media:content url="https://obzer.io/content/images/2021/05/google-cloud-logo--1--1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2021/05/google-cloud-logo--1--1.jpg" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(2)"><p>在上一节中我们已经配置好了GTM,在这一节中我们将前往GA4完成GA4部分的设置</p><p>1(可选) 检查你在GTM中的代码是否生效</p><p>如果你已经把上一节中的GTM代码发布到正式环境,并把相应的GTM代码加入到你网站的HTML中,一段时间之后,你应该在你的GA4面板中看到这样的事件</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/11.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(2)"></figure><p>这是我的GA4"实时"面板中的事件栏,可以看到我们设置的自定义事件CLS,LCP和FID已经生效了,如果你没有发现这样的事件出现,可能是由以下几个原因造成</p><p>1.1 你在GTM代码中填入的错误的GA4衡量ID</p><p>1.2 你填入的正确的GA4衡量ID,但是没有正确的把GTM代码加入到你web应用最终渲染出的html中去</p><p>1.3 你的GA4衡量id是正确的,GTM代码也加入了,但是没有点击GTM中的"提交"按钮</p><p>1.4 你的web应用,或者NGINX(APACHE)缓存了你的页面,导致GTM代码没有被正确加载</p><p>1.5 你使用了CDN,CDN缓存了你的页面,登录到CDN管理页面并尝试清除缓存</p><p>2.将你的GA4数据导入到Bigquery</p><p>在在GA4页面点击左下角的小齿轮进入设置页面,选中你的媒体资源,在产品点击Big Query关联,如果你的帐号还没有启用Bigquery API,需要先启用.此处因为我的帐号是已经启用了结算的,所以我并不清楚在Bigquery sandbox环境中我介绍的方法是否可行</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/12.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(2)"></figure><p>这是我已经设置好的界面,我选择的是每天一次导入,由于精力有限我暂时还没有尝试流式导入,但是流式导入能实时反馈你网站的各项指标,在接下来的几天里我将尝试流式导入并把相应的改变加入到这篇指南中</p><p>3.设置完成以后等待24小时,然后在bigquery界面应该已经可以看到你的数据集,在下一部分中我将介绍如何完成bigquery的部分.</p>]]></content:encoded></item><item><title><![CDATA[使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)]]></title><description><![CDATA[<p>使用Tag manager创建GA4和GA4的自定义事件</p><p>1.首先在Tag manager的工作区中创建一个类型为常量的变量,值为你的GA 衡量ID</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/1-1.png" class="kg-image"></figure><p>2.在"代码"中新建一个GA4配置,触发条件选择全部页面,在衡量ID中填入在1中我们设置的GA4_ID变量</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/2-1.png" class="kg-image"></figure><p>3.在左侧模板菜单中选择"搜索模板库",点击放大镜并输入 Core Web Vitals</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/3-1.png" class="kg-image"></figure><p>点击改模板,在编辑器中打开,保存.</p><p>4.在变量中新建类型为数据层变量的如下几个变量</p><p>变量名 — 数据层变量名</p><p>DLV - webVitalsMeasurement.delta — webVitalsMeasurement.delta</p><p>DLV - webVitalsMeasurement.deltaRounded — webVitalsMeasurement.deltaRounded</p><p>DLV - webVitalsMeasurement.id — webVitalsMeasurement.id</p><p>DLV - webVitalsMeasurement.name</p>]]></description><link>https://obzer.io/ga4-core-web-vitals-bigquery-datestudio-1/</link><guid isPermaLink="false">6093e28984a8285a3c9b1945</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Thu, 06 May 2021 15:00:41 GMT</pubDate><media:content url="https://obzer.io/content/images/2021/05/google-cloud-logo--1-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2021/05/google-cloud-logo--1-.jpg" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"><p>使用Tag manager创建GA4和GA4的自定义事件</p><p>1.首先在Tag manager的工作区中创建一个类型为常量的变量,值为你的GA 衡量ID</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/1-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>2.在"代码"中新建一个GA4配置,触发条件选择全部页面,在衡量ID中填入在1中我们设置的GA4_ID变量</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/2-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>3.在左侧模板菜单中选择"搜索模板库",点击放大镜并输入 Core Web Vitals</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/3-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>点击改模板,在编辑器中打开,保存.</p><p>4.在变量中新建类型为数据层变量的如下几个变量</p><p>变量名 — 数据层变量名</p><p>DLV - webVitalsMeasurement.delta — webVitalsMeasurement.delta</p><p>DLV - webVitalsMeasurement.deltaRounded — webVitalsMeasurement.deltaRounded</p><p>DLV - webVitalsMeasurement.id — webVitalsMeasurement.id</p><p>DLV - webVitalsMeasurement.name — webVitalsMeasurement.name</p><p>DLV - webVitalsMeasurement.value — webVitalsMeasurement.value</p><p>DLV - webVitalsMeasurement.valueRounded — webVitalsMeasurement.valueRounded</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/4-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/5-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>5.在触发器中新建一个类型为"自定义事件"的触发器,事件名称为coreWebVitals</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/6-1.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>6.在代码中新建一个类型为GA4事件的代码,配置代码选择我们在2中的配置</p><p>事件名称选择我们刚刚配置好的DLV - webVitalsMeasurement.name变量,</p><p>参数依次填入</p><p>名称 web_vitals_measurement_name 值 DLV - webVitalsMeasurement.name</p><p>名称 web_vitals_measurement_id 值 DLV - webVitalsMeasurement.id</p><p>名称 web_vitals_measurement_value 值 DLV - webVitalsMeasurement.value</p><p>名称 value 值  DLV - webVitalsMeasurement.delta</p><p>触发条件选择我们在上一步中设置的自定义事件</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/7.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>7.在右上角预览按钮旁边找到你的GTM ID,点击这个按钮并按照说明把对应的html代码放到你的html中</p><p>8(可选)调试</p><p>点击右上角的预览按钮</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/8.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>此处的URL可以是任意一个已经安装了你的tag manager的网址(包括示例图片中的localhost,运行在本地开发环境中的应用也可以调试).点击connect并刷新你的网页,此时在应该已经能看到事件已经触发了</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/9.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2021/05/10.png" class="kg-image" alt="使用GA4+Bigquery+Date Studio追踪网站的Core Web Vitals(1)"></figure><p>可以看到GA已经收到了CLS的测量事件,但是令我感到很困惑的是这些自定义事件有些时候并不会触发</p><p>到这里,tag manager部分的配置已经完成了,如果你已经准备好了,就点击提交把当前版本发布,另外不要忘了更新你的web应用</p><p>在下一节中介绍GA4的相关设置</p>]]></content:encoded></item><item><title><![CDATA[最近的一些照片]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/DSC00868.JPG" class="kg-image"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/DSC01029.JPG" class="kg-image"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/20200627-DSC00635.jpg" class="kg-image"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/20200627-DSC00632.jpg" class="kg-image"></figure>]]></description><link>https://obzer.io/zui-jin-de-yi-xie-zhao-pian/</link><guid isPermaLink="false">5f03578635a80705ee3d8c72</guid><category><![CDATA[photos]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Mon, 06 Jul 2020 16:57:53 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/07/DSC00975.JPG" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/DSC00868.JPG" class="kg-image" alt="最近的一些照片"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/DSC01029.JPG" class="kg-image" alt="最近的一些照片"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/20200627-DSC00635.jpg" class="kg-image" alt="最近的一些照片"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/07/20200627-DSC00632.jpg" class="kg-image" alt="最近的一些照片"></figure>]]></content:encoded></item><item><title><![CDATA[林清玄：季节十二帖]]></title><description><![CDATA[这一次我离开你，大概就不容易再见到你了。]]></description><link>https://obzer.io/lin-qing-xuan-ji-jie-shi-er-tie/</link><guid isPermaLink="false">5ed696a935a80705ee3d8c46</guid><category><![CDATA[杂谈]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Tue, 02 Jun 2020 18:23:16 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/06/9e94c8cb18244cfab7029372803ed6b8.jpeg" medium="image"/><content:encoded><![CDATA[<blockquote><strong>一月 大寒</strong></blockquote><img src="https://obzer.io/content/images/2020/06/9e94c8cb18244cfab7029372803ed6b8.jpeg" alt="林清玄：季节十二帖"><p>冷也到了顶点了。 高也高到极限了。 日光下的寒林没有一丝杂质，空气里的冰冷仿佛来自遥远的故乡，带着一些相思，还有细微得难以辨别的骆驼的铃声。</p><p>再给我一点绿色吧，阳光对山说。 再给我一点温暖吧，山对太阳说。 再给我一朵云，再给我一把相思吧，空气对山岗说。 我们互相依偎取暖，毕竟，冷也冷到顶点，高也高到极限了。</p><blockquote><strong>二月 立春</strong></blockquote><p>春气始至，立春是在四日的七时一分。</p><p>日光开始温柔照耀的时候，请告诉我，"地上的青虫对荷叶上的绿蛙说。</p><p>我忙得很呢！我还要告诉茄子、白芋、西瓜、壅菜、肉豆、荇菜，它们发芽的时间到了。"蛙说。“那么谁来告诉我春天到来了呢？"青虫说。</p><p>你可以静听远方的雷声或者仕女们踏青的脚步声呀！"蛙说。</p><p>青虫遂伏耳静听，先听见的竟是抽芽的青草血液流动的声音。</p><blockquote><strong>三月 惊蛰</strong></blockquote><p>“雷鸣动，蛰虫皆震起而出，故名惊蛰。”</p><p>我们可以等待春天的第一声雷，到草原去，那以为是地震的蛰虫都沙沙地奔跑，互相走告：雷在春天，不知道为什么这一次打到地下来了。蚱蜢都笑起来，其实年年雷都震动地底，只是蛰虫生命短暂，不知道去年的事吧！</p><p>在童年的记忆中，我们喜欢春天到草原去钓蛰虫，一株草伸入洞里，蛰虫就紧紧咬住，有如咬住春天。 童年老树下的回忆，在三月里想起来，有春阳一般的温馨。</p><blockquote><strong>四月 清明</strong></blockquote><p>“时万物皆洁齐而清明，盖时当气清景明，万物皆显，因此得名。”</p><p>这一次，让我们去看四月里碧绿的草与洁白的云吧！因为如果错过了四月的草之绿与云之白，今年就再也没有什么景色可以领略了。 但是，别忘了出发前让心沉静下来，用一种清明的心情去观照天空与花树的对话。 我走出去，感觉被和风包围，我对着一朵含苞的小黄花说："亲爱的，四月的时候不要睡着了。"</p><blockquote><strong>五月 小满</strong></blockquote><p>天空突然下起雨来，对于天上的雨我们没有拒绝的权利，只能默默地接受。 站在屋檐下避雨，我想：为什么初夏的雨总没来由地下着，这时，竟有一些愉快的心情，好像心也被雨湿润了。</p><p>痴痴地想起，某一年，也是这样的五月，也是这样突然的初夏之雨，与一个心爱的人奔过落雨的大街。 冲进屋檐下的骑楼，抬头正与一个厢壁的石雕相遇，那石雕今日仍在，一起走过雨路的人，却远了。</p><p>五月的雨，总是突然就停了。 <strong>阳光笑着，从天上跌落下来。</strong></p><blockquote><strong>六月 芒种</strong></blockquote><p>“时可种有芒之谷，过此即失效，故曰芒种。”</p><p>坐火车飞过田野，偶尔会见到农夫正在田中插秧，点点的嫩绿在风中显得特别温柔，甚至让人忘记了那每一株都有一串汗水。</p><p>芒种，是多么美的名字，稻子的背负是芒种，麦穗的承担是芒种，高梁的波浪是芒种，天人菊在野风中盛放是芒种……有时候感觉到那一丝丝落下的阳光，也是芒种。 六月的明亮里，我们能感受到四处流动的光芒。</p><p>芒种，是为光芒植根。在某些特别的时候，我呼唤着你的名字，就仿佛把光芒种植。</p><blockquote><strong>七月 小暑</strong></blockquote><p>院里的玫瑰花，从去年落了以后就没有再开，叶子倒仍然十分青翠，枝干也非常刚强。只是在落雨的黄昏，窗子结满雾气，从雾里看出去，就见到了去年那个孤寂的自己。 这一次从海岸回来，意外看到玫瑰花结成的苞，惊喜地感觉自己又寻回了年轻时那温婉的心情，这小小的花，小小的暑气，使我感觉到真实的自我。</p><p>泡一杯碧螺春，看玫瑰花在暑气里挣扎开放，突然听见从遥远海边传过来的涛声，一波又一波清洗着我心灵的岬角。</p><blockquote><strong>八月 立秋</strong></blockquote><p>秋训：禾谷熟也。”</p><p>梦里醒来的时候，推窗，发现天上还洒着月光。 仿佛刚刚睡去，怎么忽然就从梦里醒来了呢？</p><p>刚刚确实是做了梦的。我努力回想梦境，所有的情节竟然都隐没了，只剩下一个古老、优雅、安静的回廊，回廊里有轻浅的步声，好像一声一声的从我的心头踩过。 让我再继续这个梦吧！躺下时我这样许着愿。</p><p>我果然又走进那个回廓，脚步声是我自己的，千回百转才走到出口，原来出口的地方满天红叶，阳光落了一地。 原来是秋天了，我在回廊里轻轻叹口气。</p><blockquote><strong>九月 白露</strong></blockquote><p>“阴气渐重，凝而为露，故名白露。”</p><p>几棵苍郁的树，被云雾和时间洗过，流露出一种沧桑的神色。我站在这山最高的地方向下望，云一波波地从脚下流过，鸟声从背后传来，我好像也懂了站在这里的树的心情——站在最高的地方可以望远，但也要承担高的冷，还有那第一波来的白露。</p><p>候鸟大概很快就要从这里飞过，到南方的海边去了吧？ 这时站在云雾封弥的山上，我闭上眼睛，就像看见南方那明媚的海岸。</p><blockquote><strong>十月 霜降</strong></blockquote><p>这一次我离开你，大概就不容易再见到你了。 暮色过后，我会真正离开，就让天上温柔的晚霞做最后见证，有一天再看见同样美丽的晚霞，不管在何时何地，我都会想起你来。</p><p>霜已经开始降了，风徐徐的，泪轻轻地，为了走出黑暗的悲剧，我只好悄悄离去。我走的时候，感到夜色好冷，一股凉意自我的心头掠过。</p><blockquote><strong>十一月 立冬</strong></blockquote><p>“冬者，终也。立冬之时，万物终成，故名立冬。”</p><p>如果要认识青春，就要先知道青春有终结的时候。 为花的开放而欢喜，为花的凋落而感伤。这样，我们永远不能认识流过的时间是一种自然的呈现。</p><p>在园子里紫丁香花开的时候，让我们喝春天的乌龙吧！ 在群花散尽，木棉独自开放的冬日，让我们烘着暖炉，听维伐尔第，喝咖啡吧。</p><p>冬天多么美，那枝头最后落下的一朵木棉，是绝美的！</p><blockquote><strong>十二月 冬至</strong></blockquote><p>“吃过这碗汤圆，就长一岁了。”</p><p>冬至的时候，母亲总是这样说。母亲亲手做的汤圆格外好吃，尤其是在寒冷的冬夜，又和着成长的传说。</p><p>吃完汤圆，我们就全家围在一起喝热茶，看腾腾热气在冷空气中久久不散。茶是父亲泡的，他每天都喝茶。但那一天，他环视我们说：“果然又长大一些。” 那是很多年前冬至的记忆。</p><p>父亲逝世后，在冬至这天，我常想起他泡的茶，香味至今仍在齿边。</p>]]></content:encoded></item><item><title><![CDATA[[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲]]></title><description><![CDATA[我个人对这个演讲的逻辑非常赞叹，但也认为他明显偏重了软件系统本身的问题，而对另一个甚至更根本的问题选择了视而不见。那就是当代效率提升过程中的真正瓶颈：人的协作。]]></description><link>https://obzer.io/110509/</link><guid isPermaLink="false">5e9e2bb90c831c04f4748150</guid><category><![CDATA[杂谈]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Mon, 20 Apr 2020 23:25:01 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/04/others-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<img src="https://obzer.io/content/images/2020/04/others-1.jpg" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"><p>编者按：<br>
在2019年5月17号，莫斯科的 DevGAMM上，Jonathan Blow发表了一个题为『阻止文明倒塌』的长达一小时的奇怪演讲。我把这个演讲总结为下面这篇文字记录。<br>
善意提醒：不懂编程不代表你我不能阅读一篇和计算机有关的演讲，并有所思考，只能跟风刷刷梗；另外，对于Blow的观点，作为成年人我们应该可以有自己的反思。<br>
我个人对这个演讲的逻辑非常赞叹，但也认为他明显偏重了软件系统本身的问题，而对另一个甚至更根本的问题选择了视而不见。那就是当代效率提升过程中的真正瓶颈：人的协作。如果仔细观察软件，以及其他可以类比的当代文明复杂系统，大规模的人际协作中无法改进的沟通效率、责任分配、人性的不可管理，都让系统不可避免地显现为笨拙甚至荒谬的面貌。而抽象层级的提高，也绝不仅仅是软件的趋势而已，正如它所带来的问题也绝不仅是机器的问题。<br>
如果你不知道Blow是谁：他是一个独立游戏设计师，《时空幻境》和《见证者》的作者，感兴趣可以听我对他的介绍评述电台关于游戏的信仰 。<br>
以下是正文。</p>
</blockquote>
<!--kg-card-end: markdown--><h2 id="-">阻止文明倒塌</h2><p>乔纳森布洛，2019年5月在莫斯科演讲从1957年苏联发射 Sputnik 上天引发的美苏太空争霸谈起，回顾了首次卫星发射、首次宇航员上天，以及首次登月的过程。在1962年9月肯尼迪总统在一次国会演讲中宣称我们要在这个十年结束之前实现登月。结果1969年阿波罗11号实现了这个目标。Blow 的要点在于：人类（这里指美国）从一无所知，到实现登月只用了12年。然而从那时之后，人类的载人航天事业很大程度上停滞，甚至出现了倒退。这是不是很令人遗憾？</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/1.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>Blow 播放了一段后来解密的阿波罗11号现场纪录片片段，那种震撼的感觉难以名状，只有看的人能了解其中直观的『退步感』。（编者感慨：我们用真实的科幻交换了手中的 iPhone。）</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/4.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/2.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/3.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>然后 Blow 播放了一段 Elon Musk 的 TED 访谈，其中 Elon 指出：我们一定要意识到：不同于可持续能源的未来是必然的，Spacefare civilization（多星球文明）绝对不是必然会发生的（它需要巨大的努力）。1969年人类可以登月，然后人类只能用航天飞机把人送到近地轨道。然后航天飞机退役，近地轨道也没法送上去了——连起来看，趋势是向着0倒退。这和人们对于“科技当然显然必然自动地向前进步”这样的信念相违背。</p><h2 id="elon-">Elon 认为，正好相反，科技在不付出巨大努力的情况下，是逐渐倒退的。</h2><p>从古埃及的后人忘记金字塔，到古罗马人忘记如何建造罗马水道。</p><p>Elon 的火箭创业公司则非常成功，他们的目标是2024年重新实现载人登月。Blow 接下来给出了几个科技倒退的实例：</p><p>第一个是 Lycurgus Cup，公元300年。从正面看它的反光是青色的，透光来看，则呈现为红色。原因是其银和金的颗粒体积非常小，小到50-70纳米，如此之小以至于物理放大镜看不见它们，想观测需要用电子显微镜。然后西罗马帝国覆灭，后人忘记了这个工艺。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/6-1.jpg" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>很多人认为这就是扯淡，当时的人并不知道其任何原理只是误打误撞做出了这些东西。Blow 则认为有如此观点的人显然没有用心亲手打磨过任何东西，否则他们一定会明白，达到这样水平的结果，是不可能通过偶然和运气的，对于工艺的掌握必然在不断迭代过程中达到了非常高的水平，它才有任何可能出现。比如这个图案中人的身体的肉红色，肯定是费劲千辛万苦不断改进实现出来的。这就是一种材料科学。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/6.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>然后 Blow 提到了拜占庭的喷火筒。拜占庭的战船上安装了这种金属喷管，喷出某种成分的“水扑不灭”的有机物燃烧导致的火焰，焚毁敌人船只。这是拜占庭帝国的国家机密，它在帝国灭亡之前就被遗忘，原因不明，具体实现方式已经不可考证。</p><p>第三个例子是机械日历，一种安提凯希拉装置（Antikythera Mechanism），1901年于希腊安提凯特拉岛上的一艘古船残骸中被发现的随船沉没2100余年的钟形装置。这个机械日历的实际模型被复原为一段动画（自己看视频，语言无法描述），它的精密程度是高档机械手表的范畴。它的存在意味着背后多么复杂的一整套制造能力呢？</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/7-1.jpg" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/8.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/9.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>这样的例子还有很多，就不说了，Blow 这时候放了地动仪的图片。要点是：在人类历史上，杰出的科技被完全遗忘，这件事经常发生。当代也一样。</p><p>然后 Blow 给出的例子是 Bob Colwell，早期英特尔的首席芯片架构师，在计算机发展初期的时候接受采访的片段内容，背景是他们发现合作的零部件制造商TI（德州仪器公司）送来的产品不能稳定使用，质量残次。</p><p>Bob 去找 TI 质询，本来以为对方会说“那是你们不知道怎么使用，我们的产品是好的”，实际对方的答复是：“是，我们知道，我看看你的清单。哦，我们还有更多你们不知道的（不好使的产品）。”实际情况是，TI 没有比任何其他竞争对手更差，摩托罗拉、Fairchild 也一样。这些硅制品让英特尔的芯片研发停滞不前，为何会如此？TI的人回答道：“第一代 TTL（逻辑门电路）是那帮胡子花白的老头子做的，他们知道其中的道理；现在的工程师都是毛头小子，学校毕业过来搞生产，他们不知道内部组装的改变，会导致感应峰（inductive spikes）。”这里的spike就是指每一个点的电压变化时，都会产生磁场，而磁场变化的相互干扰，没有被设计者纳入考虑，因为他们不理解。</p><p>这就是科技退步的原因。代际之间的交流和传承需要巨大的努力，这过程中有损失。如果代际的传承失败，文明就灭亡。</p><p>接下来 Blow 给出了历史中文明灭亡的实例，来自于 Eric Clive 的一个演讲，题目是《公元前1700年的文明灭亡》，具体来说是青铜器时代晚期，爱琴海，古埃及，塞浦路斯，迈锡尼，赫梯，古巴比伦等。这一圈围绕在美索不达米亚平原和地中海一带的文明曾经形成了一个非常复杂的贸易网络。在下图中，每个节点是一个文明，不是每一个都能和每一个贸易，但通过中间节点，所有贸易都达到非常优化的效率。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/10.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>这一点非常重要，因为青铜作为国防和生产的重要资料，非常难以制造。你需要用锡和铜一起生产。铜产地比较少，比如塞浦路斯岛。而锡则更难找，而且离铜产地非常远，比如阿富汗。而这些文明需要把它们运到一起以生产青铜。</p><p>而这些文明的灭亡至今没有确切原因，有人说是自然环境恶化导致互相攻击，贸易变成战争。它们灭亡到什么程度呢，不仅是国家不存在了，城市也消失了，语言和文化也消失了。刻在石碑上的文字大多数至今我们不能翻译。</p><p>Blow 的要点是：软件正在倒退，而人类空前依赖软件。尽管，这和我们置身其中的人的观感是相反的。波音飞机掉下来的主要原因就是软件问题（编者不能同意）。文明衰退的速度如果很慢，我们能意识到这个衰退么？</p><p>这里 Blow 给出了他对于“软件明显在蓬勃发展”之直观感受的解释：软件正在享受硬件能力提升的红利，它只是“看上去”蓬勃发展而已。</p><p>机器学习是最明显的例子。一方面，它在二十年前不能存在主要是因为硬件性能无法支持而已。另一方面，它只是人类依赖着的软件世界中极小极小的部分。属于软件的进步已经很长时间停滞。比如，我们使用软件给自己AI换脸成明星的样子，或者配上猪耳朵，这个有趣的部分，只占这个app极小极小的部分，而这个部分非常简单，另外的极大部分却极度复杂，包括把你的脸加载到屏幕上，以及处理你的点击，等等。出问题的是这些部分。人工智能的局部成就，没法和软件世界整体的退化的巨大惯性抗衡。</p><p>最明显的迹象，就是“我们已经不指望软件能长期稳定工作了。”我们的标准一降再降，还能降到多低？降低到哪里会出大问题？</p><p>接下来 Blow 疯狂吐槽了十分钟，关于电脑上一切软件都经常 bug，以至于用户对于一切软件“重启试试”成为不假思索的操作。包括 Emacs 的问题、Visual Studio 不能处理最最简单的指令，只能连续报错，微软 Word 的字符换行 bug 二十年后仍然没有消灭，像幽灵一样此起彼伏；于是他为了缓解自己的愤怒想打游戏，打开 Epic Store 和 Steam 又连续遇到 bug；于是他关掉游戏客户端去看 CS 直播，发现 CS 直播电竞比赛里全程有一个多余的名为“未定义”的 bug 玩家出现在地图里，直到比赛结束；然后他进入俄罗斯签证申请页面，被死活不能通过，且不能刷新的手机号验证脚本逼得只能刷新整个页面重新填写申请；然后他来到莫斯科住进酒店，他的房间的座机有5%的概率会空调开关触发响铃……等等。编者这里就不赘述了。</p><p>这让90年代电脑销售的一个常见推销语“五个9”（指，本设备可以99.999%时间稳定运行）成为今日的讽刺。Blow的电脑连两个9都没有。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/11.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>对于这个问题，软件行业的普遍答案是：市场不会为更好的稳定性买单。Blow则认为：对于一个从未提供出足够稳健的产品的行业，为什么会有人会相信它『能』？</p><p>接下来，Blow 从正面描述了软件的结构：抽象层次的序列。机器语言、汇编语言、Fortran/C/C++、C#/Haskell/Javascript……在这个序列里，绝大多数工程师在最高抽象层次进行工作，因为这是“聪明、省力、高效率的”。在这个抽象从低到高的序列里的某些位置，问题就出在这里。Blow 认为，全行业的高抽象层次工作，多数人的“高效率”的另一面，是失去（或者从未拥有过）能力。考虑 Facebook 作为一个软件的功能增加，和它要多雇佣的成千上万的工程师，二者相除得到的平均每人的价值创造是趋近于零的。这和“抽象层次越高效率越高”明显矛盾。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/12.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>Blow 给出的对比，是 UNIX 发明者 Ken Thompson 的一个演讲片段。他回忆道他趁老婆孩子出去度假，用了三个礼拜写了三个东西（编辑器、编译器、软硬件交互层或者叫操作系统），做出了 UNIX。现场爆发笑声和掌声——当今程序员可没有这种效率。而 Blow 认为这是个悲剧，它并不好笑。今天软件显没有在进步，它的鲁棒性和生产力都在衰退。</p><p>Blow 从图形计算的角度给出了一些“最最基本的，你不能直接做的事情”，其中一个编者能听懂的例子是，把一个程序拷贝到另一个设备（安装是个复杂过程）——而这并不是因为 CPU，CPU 不能背锅因为今天各类设备的 CPU 一致性已经相当好。安装程序不是为了对接 CPU，而是为了解决操作系统层面不可思议之多的兼容问题，其绝大部分是我们不想打交道的。操作系统本来是给 CPU 赋予能力，但同时你也可以说它防止着 CPU 具备很多能力。在编程过程中，你绝大多数时间在处理那些，你很难理解、也不可能预料到的各种和你的设计思路没有关系的问题。</p><p>更可怕的是，你不能直接编写一个独立程序进行编译和 linking。微软为了能让人这么做，专门设计了一个 vswhere 的软件。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/13.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>现在有一种叫做LSP的东西，开源的语言服务器协定。在Blow看来它基本上是一种更复杂、更费劲的编写和调用库的方式，而其满足的需求都是非常基本的操作，比如在你的编辑器里临时起意，查看一个变量的特征或者类型，LSP给你提供一个工具条，或者鼠标点击直接查询的功能。为了实现这个，你需要一个标准化服务跑在服务器上，好让你的编辑器和服务器用socket交互——为了使用方便，你把本地的、单一的编程工作置于分布式的系统之中。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/14.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>这样的做法推而广之，你依赖了越来越多的库，库又依赖了越来越多的库，关键是这些库/服务本身可能是在变化的、并且没有被中心化地存储和管理，这样一来我们就陷入了无穷无尽的debug的、重启服务的、互相同步的……我们自身所不能掌握的问题海洋之中。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/15.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>现在大家竟然在积极主动建设着这样一个东西。程序员们忙着把简单事情复杂化的同时……</p><p>电脑游戏却变得连最基本的事情都很难实现了。比如游戏现在很难保持全屏, 经常跳出为窗口。再比如，辛辛苦苦做的游戏，很难稳定在一个帧数上跑，无论你多努力也不行。Allen（全称听不清楚）在GDC上介绍了他的一篇论文讲述了这个简单的能力我们现在无法具备的原因。</p><p>复杂性的提高，加速了知识的丢失：</p><h2 id="1-"><br>1、知识总量更多，我们就让每个人知道的比例变得更小来应对。</h2><p>每个人对全局的把握一弱再弱，既难以传承知识，也难以做好自己的工作。</p><h2 id="2-"><br>2、『深知识』被『琐碎信息』替代。</h2><p><br>典型的深知识，如理解Cache Coherency（缓存一致性，指保留在高速缓存中的共享资源，保持数据一致性的机制），可以让人优化程序在多个处理器上跑得更快。典型的琐碎信息，如『这个Unity里的小图标不知道为啥不显示了，请教老师傅得知，是某个深藏不露的菜单里看似没有关联的一个开关关闭了导致的，打开就好了，过了一阵子它不知道为何又关闭了，总之，编译之前一定要记得检查那开关打开没有』。后者作为知识，往往几个月后随着Unity版本更新就完全作废，作为程序员要花很多脑力学习这种速朽的所谓知识，这件事情非常缺（offensive）。</p><h2 id="3-">3、好信息被噪音淹没。</h2><p><br>症状是谷歌越来越难用，你的问题越复杂，网上搜来搜去看到的答案就越大概率是错的，或者只是浪费你的时间。</p><p>Blow认为，显而易见的是，复杂性越高，我们承受灾难，或者体制性腐化（参考上文东罗马帝国），的能力就越差。而现在大家似乎相信，我们能承担的复杂性上限，是无限的。想象现在大公司里那种极少数能够透彻理解整个系统的工程师离退休之后后继无人、且很难把整套知识传递给年轻员工的情况，答案已经很明显了。</p><h2 id="--1">这一切和游戏有什么关系呢？</h2><p><br>曾经的游戏，是关于如何榨干性能，将机器的潜力推至极限的。推至极限，要求我们透彻理解机器本身，这就自然导致我们倾向于做出非常棒的程序。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/16.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>今天整个行业转向Unity和Unreal。自己写引擎的人越来越少。一整代程序员从学习到工作，一直在写支离破碎的C#片段，放在Unity的这里那里，从来没写过系统性的，或者底层的程序。这本身倒没什么，它缩短开发时间，提高个人效率，缩短游戏开发时间。但这意味着放弃，对其他能力的放弃，对整体性知识的放弃。</p><p>Blow说，割裂性的分工没问题，但是如果所有人都这样分工，那么没有任何人会做这之外的事情了。Unity和Unreal又是怎么来的呢？它们生长于这样一个环境：所有的游戏公司都在自己写引擎，专门的引擎公司就从这些游戏公司里雇人过来，做出了如今的垄断性引擎。现在没有这样的环境，彻底没有那种人了的话，Unity去哪里雇人？首先的结果，是他们彻底断绝了新引擎作为竞争对手的涌现可能。然后，这几个大引擎怎么继续维护和发展，也成了问题，自身开始衰退，也是很有可能的。</p><p>游戏开发者社群的情况很像阿西莫夫的《基地》：我们有一群人知道怎么用电脑编程、也有一群人精通嵌入式系统/高性能计算这些事。当很多程序败坏、丢失、难以维护的时候，我们这群人的知识可以重建它们——但我（Blow）真的不确定，我们是否有足够多的底层人才，以及对底层充分了解的高层人才，能做好系统底层的工作。也许，我们需要一个新的『基地』（foundation，也有基础的意思）。不好意思，剧透了。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/8-1.jpg" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>说回到青铜时代的文明失落，无数历史显示了一种现象：当只有精英阶层可以读和写的时候，很多能力无法普及，文明变得脆弱——普通人也主观上不想学习那些。今天的我们，几乎没有人能理解自己的程序跑着的时候，CPU里正在发生什么。这就是脆弱。</p><p>如果青铜器时代那个程度的知识都会失落，那面对我们现在如此复杂的系统，我们怎么能相信它的存续和发展？各种各样的生存压力随时可能爆发，考验我们的软件世界。比如气候变迁。比如国际争端，比如一些国家切断国际互联网了，比如中国不给我们加工芯片了。别笑，现在有些国家的程序员连上stackoverflow复制粘贴代码都费劲。这些事情单独来看肯定都不至于伤害我们的文明，系统复杂到今天程度，抗折腾能力会很差。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/17.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>正如Elon Musk所言，技术会自然地退步。我们要警惕，要对抗，就一定要在每一个层级上简化：硬件、操作系统、库、应用层面的代码、网络、编译、debug、内容分发、人机交互。而这一切又完全可以如此简单，因为它们的现状如此荒谬！</p><h2 id="-will-taste-">我们需要的只是『意愿』（will）和『品位』（taste）而已！</h2><p><br>大家都充分认识到复杂之荒谬，简单之美——简化可以让事情变得更好。</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/18.png" class="kg-image" alt="[转载][机核]阻止文明倒塌：Jonathan Blow 在莫斯科 DevGAMM 上的演讲"></figure><p>退一万步讲，也许你认为软件不会让文明倒塌。没关系，咱们就只从自身利益出发——所有程序员都每天气呼呼的工作着，因为他们知道自己大量的时间精力用在没有意义的荒唐事上，而不是真正有趣的，创造性的事上。如果我们不改变做事的方式，未来的程序员工作会更加庸俗不堪，就跟没有SpaceX时候的美国航天事业一样。</p><p>再退一步，假设你只是独立游戏开发者，你可能觉得，自己无力改变任何事情，只要忍几个月，把游戏做完就好了，毕竟重构、重写需要大量的时间——我想告诉你这种想法永远是错误的，因为我们永远低估了自己做游戏需要的时间，你以为的五个月，大概率实际是几年。糟糕的工作方式让你付出的代价，比你以为的，要大得多，长得多。也许那拖延的几年时间，就是拜复杂系统所赐。反过来，如果你积极应战，简化架构和代码，兴许很值得。听起来像是又基础又无聊的建议，但我要大胆断言——我们大多数人甚至都不太知道怎么做这件事了。</p><p>最后Blow给大家提供了三个补充阅读/观看的资料，更新网友搬运的地址：</p><ul><li>Casey Muratori，『三千万行代码难题』。<a href="https://www.bilibili.com/video/av53844104" rel="noopener noreferrer">链接在此</a></li><li>Samo Burja，『文明：体制、知识与未来』。<a href="https://www.bilibili.com/video/av54613661" rel="noopener noreferrer">链接在此</a></li><li>Eric Cline，『公元前1177：文明倒塌时』<a href="https://www.bilibili.com/video/av54613930" rel="noopener noreferrer">链接在此</a></li></ul><p>本演讲的视频：<a href="https://www.bilibili.com/video/av52926158/" rel="noopener noreferrer">链接在此</a></p><p>【演讲完】</p>]]></content:encoded></item><item><title><![CDATA[AWS实战之三,为Web应用部署Cloudfront]]></title><description><![CDATA[系列之三,部署CDN服务]]></description><link>https://obzer.io/aws_3/</link><guid isPermaLink="false">5e9e21df0c831c04f47480a1</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Mon, 20 Apr 2020 23:04:56 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/04/logo-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2020/04/logo-2.png" alt="AWS实战之三,为Web应用部署Cloudfront"><p>在前两节中,我们已经为web应用部署了https服务,在这一节中,我们将为web应用部署AWS的CDN服务</p><p>在控制台中选择cloudfront,并选择创建分配,内容分发方式选择Web</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/15.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>在"源设置"中选择上一节中我们已经创建好的弹性负载均衡器.</p><p>根据你自己web应用的源路径来填写源路径,如果没有就留空</p><p>源id填写一个你自己可以识别的唯一字符串</p><p>源协议策略这里选择匹配查看器</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/16.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>相应超时和保持连接超时根据你自己的web应用酌情填写</p><p>查看器协议策略中我选择了将http重定向至https,如果你不需要就选http和https</p><p>允许的http请求中选第3个,如果你的web应用中不包含动态请求,可以选择第一个或第二个</p><p>"基于选择的请求标头进行缓存"中选择全部</p><p>如果你的web应用存在动态请求,则转发cookies和查询字符串和缓存中一定要选择全部和基于全部标头缓存,否则cdn无法正常工作</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/17-1.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>分配设置中没有什么特别要设置的,除了价格级别选所有边缘站点(反正个人级别的应用也没啥流量,选最贵的一个月也超不过50G,就算超过了也是白菜价)以及SSL证书中选择自定义SSL证书,然后在自动弹出的下拉框中选择第一节中我们申请的证书</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/18.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>最后检查一遍你的设置,一定要注意默认缓存行为中的各个选项,如果你的web应用存在动态请求,确保按照我所说的去填写cdn才能正常工作</p><p>检查完毕后点击右下角的创建分配,等待大约10分钟状态变为已部署后把"域名"一栏的字符串复制到route 53你的a记录中的别名,一般情况下下拉框中会自动出现</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/20.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>恭喜你,现在你获得了一个拥有全球CDN,全站https,且证书无限自动续签的站点</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/21.jpg" class="kg-image" alt="AWS实战之三,为Web应用部署Cloudfront"></figure><p>(完)</p><p>PS:这个颁发者的逼格是不是比letsencrypt高多了(而且不用三个月一次的大姨妈,就算用了acme.sh也老出问题)?</p>]]></content:encoded></item><item><title><![CDATA[AWS实战之二,创建负载均衡器并部署证书]]></title><description><![CDATA[AWS系列之二,部署证书]]></description><link>https://obzer.io/awsshi-zhan-zhi-er-bu-shu-httpszheng-shu/</link><guid isPermaLink="false">5e94515243251e6e84f01b8d</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Mon, 13 Apr 2020 13:10:58 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/04/logo.png" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2020/04/logo.png" alt="AWS实战之二,创建负载均衡器并部署证书"><p>在上一节中,我们已经申请到了https证书,在这一节中,我们将把https部署到负载均衡器中以实现站点的https化</p><p>1.进入EC2 Dashboard,在左侧菜单中选中"负载均衡器",创建负载均衡器</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/6.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>此处我们选择左侧的应用程序负载均衡器</p><p>2.输入名称,在侦听器中添加一项https</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/7.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>选中所有可用区,下一步</p><p>3.选中在上一节中申请的证书</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/8.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>4.安全组配置,如果没有安全组就去创建一个,此处不表</p><p>5.配置目标组,创建一个新的目标组</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/9.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>由于我们并没有在EC2实例上部署证书,此处我们选择http协议.</p><p>6.选中之前准备好的EC2实例,点击添加到已注册</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/10.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>7.提交并审核,注意如果想要实现http自动跳转到https,此处需设置一下侦听器</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/11.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>选中http并点击规则中的"编辑规则"</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/12-1.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>点击上方的铅笔按钮后删除原有动作,添加重定向之443端口的新动作后保存并更新.</p><p>8.等待负载均衡器配置好了之后,复制DNS名称到routes 53中</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/13.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/14.jpg" class="kg-image" alt="AWS实战之二,创建负载均衡器并部署证书"></figure><p>注意此处类型选A类型,启用别名,把刚刚复制的DNS名称粘贴到此处.保存.</p><p>至此我们已经完成了在AWS上部署https站点的步骤,并实现了以下目标</p><p>1.EC2上只需接收来自80端口的http请求,免去了服务器上的https的配置.</p><p>2.证书自动续期(web服务需部署在EC2上才可以,AWS提供的证书免费续签的条件是必须关联到至少1项服务)</p><p>在下一节中我们将继续完善我们的web站点,启用AWS Cloudfront CDN服务</p><p>update #1:</p><p>在本例中我的web应用默认使用的是http协议,在我修改为https协议后遇到了redirect loop的情况,此处我修改了nginx的配置以解决该问题.</p><!--kg-card-begin: markdown--><pre><code class="language-conf.d">proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[AWS实战之一,申请免费https证书]]></title><description><![CDATA[AWS系列之一,申请证书]]></description><link>https://obzer.io/awsshi-zhan-zhi-yi-bu-shu-httpszheng-shu/</link><guid isPermaLink="false">5e9453b343251e6e84f01b93</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Chen Yiguang]]></dc:creator><pubDate>Mon, 13 Apr 2020 12:13:12 GMT</pubDate><media:content url="https://obzer.io/content/images/2020/04/logo-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://obzer.io/content/images/2020/04/logo-1.png" alt="AWS实战之一,申请免费https证书"><p>1.在管理控制台中找到<a href="https://console.aws.amazon.com/acm/home?region=us-east-1">Certificate Manager</a> 服务,进入面板并选择请求一个公有证书</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/1.jpg" class="kg-image" alt="AWS实战之一,申请免费https证书"></figure><p>2.添加域名并验证,这里我们选择DNS验证</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/2.jpg" class="kg-image" alt="AWS实战之一,申请免费https证书"></figure><p>3.添加标签(可选)</p><p>可以添加一些备注信息,此处我们没有备注信息,略过,直接选择审核</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/3.jpg" class="kg-image" alt="AWS实战之一,申请免费https证书"></figure><p>4.按照要求添加相应的txt记录,如果你的域名托管在routes 53上,可以方便的直接点击按钮添加.</p><figure class="kg-card kg-image-card"><img src="https://obzer.io/content/images/2020/04/4.jpg" class="kg-image" alt="AWS实战之一,申请免费https证书"></figure><p>下一节中我将介绍如何把证书部署至web站点</p>]]></content:encoded></item></channel></rss>