<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://lxiange.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://lxiange.com/" rel="alternate" type="text/html" /><updated>2021-05-22T20:01:56+00:00</updated><id>https://lxiange.com/feed.xml</id><title type="html">Lxiange’s Blog</title><subtitle>My blog ^_^</subtitle><author><name>Xiang Li</name></author><entry><title type="html">记人生第一次被拖车</title><link href="https://lxiange.com/posts/car-towed.html" rel="alternate" type="text/html" title="记人生第一次被拖车" /><published>2021-03-18T00:00:00+00:00</published><updated>2021-03-18T00:00:00+00:00</updated><id>https://lxiange.com/posts/car-towed</id><content type="html" xml:base="https://lxiange.com/posts/car-towed.html">&lt;p&gt;周二下午端着一杯开水在窗边眺望风景，发现楼下车位竟然空出来一个，心想真是难得。
毕竟小区停车位非常紧张，能有空位还是非常罕见的。但定睛一看，这不就是我车停的地方吗？我车呢？？&lt;/p&gt;

&lt;p&gt;其实我当时第一反应就是被tow了，因为我记得我当初停车的permit就随意放在副驾驶位置，可能看不见了。
后来事实证明的确如我所想，我的permit卡在副驾驶前挡风玻璃的缝里了，从车外不visible。&lt;/p&gt;

&lt;p&gt;然后紧接着就去网上搜了一下被拖车怎么办。好在网上有非常多的教程（看来在美国没被拖过车人生都不算圆满了）。&lt;/p&gt;

&lt;p&gt;首先是是拨打San Jose的一个电话，可以根据你的车牌查询你的车是否被tow，以及被tow到了哪个停车场。
（当然其实你被tow的地方附近应该有牌子告诉你一旦违停，会被哪个公司拖走）&lt;/p&gt;

&lt;p&gt;接下来就打电话联系这个拖车公司，确认你的车在他们那里，然后你就可以带上你的：&lt;strong&gt;驾照+registration+信用卡&lt;/strong&gt; 去取车了。建议尽快，不然多停一天就多交一百块！&lt;/p&gt;

&lt;p&gt;幸亏我还有自行车，以及那个拖车公司离我家不远，也就几英里。于是赶紧放下手头的事情，风风火火骑上自行车出发了。&lt;/p&gt;

&lt;p&gt;到达拖车行，对方会带你先去做一下“permit inspection”。就是陪你一起去车旁边转一圈，如果在不开车门的情况下，可以看到你的permit，那么你就可以不用交钱直接开走你的车。
虽然我知道我肯定是逃不掉了，但流程还是得走完，绕着车走了两圈，自然是没看到我的permit。&lt;/p&gt;

&lt;p&gt;小插曲是，我给mentor发消息说我车被tow了，他第一句回复的是：“Do you need help?”，说实话有点感动。
然后当时我们组正好在开会，我用手机call进会议跟大家说：“非常抱歉我车被tow了，没法参加今天的会议了。”我老板还听成了被“偷”了，哈哈哈。同事们还都是挺nice的，都让我先忙手头的事。&lt;/p&gt;

&lt;p&gt;之后就是交钱取车，一气呵成，$225+$95=$320，就当是交学费了：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/car-towed/receipt.jpg&quot; alt=&quot;receipt&quot; /&gt;
&lt;em&gt;我的行车码表时间还没有调整为夏令时XD&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;上车后，不到一分钟我就找到了permit：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/car-towed/permit.jpg&quot; alt=&quot;permit&quot; /&gt;
&lt;em&gt;就是这玩意，花了我320刀&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;话说折叠自行车真方便，直接折起来丢车里完事儿！全程不用麻烦别人！&lt;/p&gt;</content><author><name>lxiange</name></author><category term="life" /><summary type="html">周二下午端着一杯开水在窗边眺望风景，发现楼下车位竟然空出来一个，心想真是难得。 毕竟小区停车位非常紧张，能有空位还是非常罕见的。但定睛一看，这不就是我车停的地方吗？我车呢？？</summary></entry><entry><title type="html">Covid 疫苗接种体验</title><link href="https://lxiange.com/posts/vaccination-experience.html" rel="alternate" type="text/html" title="Covid 疫苗接种体验" /><published>2021-03-17T00:00:00+00:00</published><updated>2021-03-17T00:00:00+00:00</updated><id>https://lxiange.com/posts/vaccination-experience</id><content type="html" xml:base="https://lxiange.com/posts/vaccination-experience.html">&lt;h2 id=&quot;预约&quot;&gt;预约&lt;/h2&gt;

&lt;p&gt;说实话今天接种疫苗纯属巧合。&lt;/p&gt;

&lt;p&gt;目前我在的Santa Clara County没有名额，而San Francisco每天都还有不少空位，早上会刷新。
今天早晨9点左右起床正好发现当天11:00和11:45在旧金山有两个空位，可能是有人之前的预约临时取消了，我就赶紧注册了一下。&lt;/p&gt;

&lt;p&gt;因为疫苗拿出来后是当天有效，为了避免资源浪费，我就义不容辞了哈哈。&lt;/p&gt;

&lt;h2 id=&quot;疫苗种类&quot;&gt;疫苗种类&lt;/h2&gt;

&lt;p&gt;大家应该也都知道，目前新冠疫苗主要分两大类，mRNA和灭活。但是美国现在几乎只能接种到mRNA疫苗，主要是Moderna和Pfizer，毕竟mRNA疫苗产量大。不同接种点的疫苗种类不一样，同学在Moscone Center注射的是Pfizer，我在City College of San Francisco注射的是Moderna。他们都属于mRNA疫苗，大体应该都差不多。mRNA疫苗都是要接种两针的，间隔4周。
部分接种点显示有强生疫苗可以选择，但是从来没见有人预约上。&lt;/p&gt;

&lt;p&gt;我无法评价疫苗优劣，因为绝大多数人都是外行，根据网上搜到的只言片语盲目下结论是很可笑的。
&lt;strong&gt;“mRNA疫苗，灭活疫苗，能尽快普及阻止新冠的就是好疫苗！”&lt;/strong&gt;
当然每个人都有自己的判断，不随意judge。&lt;/p&gt;

&lt;p&gt;有意思的是，我问了身边很多朋友要不要一起去打疫苗（本意是想拼车，毕竟三番实在太远了），但得到的答复都是NO，都是说要观望一下。之前和朋友们聊天时，很多人也都说想先观望一阵子，还有些朋友准备一直宅在家等着绝大多数人都接种疫苗后新冠消失了就不用打疫苗了，不过我是受不了这么长时间一直宅在家。感觉华人整体还是比较谨慎，当然我非常理解，只是我一直喜欢尝试新鲜事物（每次iOS出新系统我都第一时间更新哈哈），并且现在健身房都开放了，实在想去。&lt;/p&gt;

&lt;h2 id=&quot;出发&quot;&gt;出发&lt;/h2&gt;

&lt;p&gt;一路上还是挺顺利的，但是三番实在是太远了，单程50miles。好在现在疫情期间，101高速几乎不堵车，开了不到一小时到达了目的地。我选择的是drive through，其实人（车）不是很多，排队也就几分钟。先是在一个停车场check in，核查一下登记信息和ID。之后就开车到接种疫苗的地方（也是一个停车场）。&lt;/p&gt;

&lt;p&gt;拍了几张照片：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/park1.jpg&quot; alt=&quot;park1&quot; /&gt;
&lt;em&gt;第一个checkin的停车场&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/park2.jpg&quot; alt=&quot;park2&quot; /&gt;
&lt;em&gt;正式接种疫苗的停车场&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/lane.jpg&quot; alt=&quot;lane&quot; /&gt;
&lt;em&gt;总共23条队，我正好是最后一条&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;打针的时候，工作人员（一个亚裔的小哥，岁数应该和我差不多）会再次验证一下预约的条形码和ID，然后会问一些问题，譬如是否有同时接种其他疫苗之类的，全部回答NO即可。
接下来会问你打哪个胳膊，之后就是“3，2，1”扎针、推液、拔针、贴创可贴，一气呵成。&lt;/p&gt;

&lt;p&gt;针头比想象中的要细很多，小哥看到我的三角肌说“relax、relax the muscle”。他“3，2，1”读秒时我在做心理建设，但事实是一点都不疼。“啪地一下”就好了，甚至感觉有点不过瘾。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/arm.jpg&quot; alt=&quot;arm&quot; /&gt;
&lt;em&gt;针扎在左手三角肌上&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/card.jpg&quot; alt=&quot;card&quot; /&gt;
&lt;em&gt;“You just got the prove of freedom!” —— 打完疫苗隔壁的护士和我说&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;接种完疫苗后，会让你等待15分钟再走，以确定没有严重的过敏反应，然后就可以直接回家了。&lt;/p&gt;

&lt;h2 id=&quot;副作用&quot;&gt;副作用&lt;/h2&gt;

&lt;p&gt;今天打完疫苗回到家，我跟朋友开玩笑说：&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;打完疫苗回到家，现在非常不舒服&lt;/p&gt;

  &lt;p&gt;——因为连着开了两个多小时车，累死了XD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/vaccination-experience/odometer.jpg&quot; alt=&quot;odometer&quot; /&gt;
&lt;em&gt;整整100miles，强迫症患者表示舒服了，油耗难得跑上30&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;我是相信疫苗是非常安全的，一方面我相信专家们，另一方面毕竟已经有几千万人接种了，好像也没有听到特别恐怖的事情。
不过也听说过一些有副作用的故事。&lt;/p&gt;

&lt;p&gt;感觉部分原因可能是：假设100个人接种疫苗，95个都没有副作用，那这95个或许就成了沉默的大多数。而剩下的5个会speak out loudly。并且“没有副作用”听起来很“无聊”，这100个人的朋友们，可能会更偏向于传播接种疫苗后身体出现不适的故事。&lt;/p&gt;

&lt;p&gt;当然话也不能说得太满，万一被打脸呢？Anyway，希望疫苗的副作用越低越好，这样可以加快普及进度。&lt;/p&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;
&lt;p&gt;总体而言，今天接种疫苗还是非常不错的体验，目前过去了差不多10个小时，还没有任何不适。除了手臂扎针的地方稍微有点痛，但这种疼痛就是普通打针的那种疼痛。接下来如果有不适我会更新此文。&lt;/p&gt;

&lt;p&gt;我个人而言，打疫苗主要动机有：&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;让家人放心。&lt;/strong&gt;可怜天下父母心，尽量让父母不担忧，可能是在外的游子唯一能做的了。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;对他人负责。&lt;/strong&gt;因为我平时经常出门（骑车、hiking、逛超市、etc.)。然后和朋友聚会时，总觉得很不好意思，生怕做了害群之马。接种疫苗后就可以理直气壮一点了哈哈。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;去健身房。&lt;/strong&gt;这点很重要，因为疫情中断了一年多的训练，希望赶紧恢复一下。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;“三番五次”的预算已经消耗掉了一次，一个月后还要再打一针，还要再去一次，实在是有点累。不过下次准备顺便去玩一下，毕竟大多数餐馆都开了。&lt;/p&gt;

&lt;p&gt;不知道国内疫苗接种是怎么样的体验，听说现在也已经开始大规模接种了，希望可以听到更多的分享。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="life" /><summary type="html">预约</summary></entry><entry><title type="html">力量训练教程</title><link href="https://lxiange.com/posts/powerlifting-guide.html" rel="alternate" type="text/html" title="力量训练教程" /><published>2021-03-13T00:00:00+00:00</published><updated>2021-03-13T00:00:00+00:00</updated><id>https://lxiange.com/posts/powerlifting-guide</id><content type="html" xml:base="https://lxiange.com/posts/powerlifting-guide.html">&lt;p&gt;以下部分内容来自于《力量训练基础》和《力量训练计划》两本书。
每一条都是亲身经验之谈，希望可以帮助到热爱锻炼的同学。&lt;/p&gt;

&lt;h2 id=&quot;硬件&quot;&gt;硬件&lt;/h2&gt;
&lt;h3 id=&quot;鞋硬底板鞋&quot;&gt;鞋：硬底板鞋&lt;/h3&gt;
&lt;p&gt;不一定需要专门的举重鞋，平底+硬底鞋即可，板鞋就是最简单的选择，目的就是为了站得稳。
举重鞋多说两句，原理很简单，就是鞋跟垫高两厘米，主要适合欧美的或者个子特别高或者踝关节柔韧性差做不了“亚洲蹲”的人，因为他们蹲下去时候脚后跟会抬起来，而亚洲人一般不需要。正因为举重鞋鞋底不平，硬拉时候反而不能穿举重鞋。
站姿二头弯举或其他一些上身动作时，鞋不是非常重要，但是非常软的鞋会站不稳，导致体验很差。虽然练卧推时穿什么鞋完全无所谓，但我个人习惯不管练什么项目，都以深蹲作为热身项。所以最好简单起见，一律穿硬底板鞋。&lt;/p&gt;

&lt;h3 id=&quot;衣服普通t恤运动裤不要紧身衣&quot;&gt;衣服：普通T恤+运动裤，不要紧身衣&lt;/h3&gt;
&lt;p&gt;应该不会有人穿牛仔裤健身。穿宽松的运动裤就很舒服，夏天的话一般穿短裤。不要穿紧身衣，你是来健身而不是对着镜子拍照的。当然，一般女生比较喜欢穿紧身裤，不了解，不予评价。&lt;/p&gt;

&lt;h3 id=&quot;护具尽量不要护具&quot;&gt;护具：尽量不要护具&lt;/h3&gt;
&lt;p&gt;如果你要冲击最大重量，可以带上护具。而日常训练时，护具只会掩盖你动作的不规范。譬如如果你的深蹲姿势不规范，你会感觉腰或者膝盖疼痛，但是护腰护膝会让你忽视这一点，所以新手尽量不要戴护具。
即使你确定你的动作可以做规范，也没有必要日常训练都戴上护具来冲击最大重量。我们是在训练，而不是在比赛。日常训练时候创造的这些数字有什么意义呢？更不要说卧推背心这种滑稽玩意儿了。&lt;/p&gt;

&lt;p&gt;何况如果每天都冲击最大重量，是在磨损你的身体而不是在锻炼它。所以只在冲击个人记录的那一天戴上护具，其他时候就自然点吧。&lt;/p&gt;

&lt;p&gt;把手套也算在护具里吧，同样，尽量不要带手套（这也是《力量训练基础》所提倡的）。手套并不能防止手被磨伤，同时严重降低手感。做卧推这类动作时，戴手套是非常危险的。
早点磨出茧子，作为天然手套吧 :-)&lt;/p&gt;

&lt;h3 id=&quot;选择健身房&quot;&gt;选择健身房&lt;/h3&gt;
&lt;p&gt;除非你超级有钱，不然肯定还是要去健身房锻炼。买几个简易的健身设备根本达不到训练效果，而一整套力量举设备可能要上万刀，更别说你还要有地方放这些设备。
本文讨论力量训练，所以选择健身房时主要考察自由重量区。泳池大小、跑步机和动感单车数量、固定器械数量相对不是那么重要。
需要考察的有：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;自由深蹲架、卧推凳数量。&lt;/li&gt;
  &lt;li&gt;是否可以做硬拉和抓举（能不能摔杠铃）。专用地板+橡胶杠铃片&lt;/li&gt;
  &lt;li&gt;哑铃、杠铃片数量。&lt;/li&gt;
  &lt;li&gt;是否同时有举重杠和力量举杠（optional）。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;国内有些健身房（譬如威尔士这种年费上万的）自由深蹲架数量为0，这种坚决不能去。国内几乎没看到可以摔杠铃的健身房。而美国这边好一点，普遍都有4个能做深蹲+硬拉+抓举的深蹲架。就像这种对我来说这就是最优选择了:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/powerlifting-guide/rack.jpg&quot; alt=&quot;rack&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;其他&quot;&gt;其他&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;杠铃夹：很多健身房都没有，或者说数量不够。最好还是自己带一下，还好不贵，十几刀。&lt;/li&gt;
  &lt;li&gt;筋膜枪：用来缓解肌肉酸痛还是挺舒服的，不过美国的筋膜枪都卖得太贵了，不太值，用泡沫轴也挺好的。不过如果肌肉非常酸痛，那可能是训练过度了，这不是筋膜枪可以解决的。&lt;/li&gt;
  &lt;li&gt;镁粉：大多情况下不需要，但是硬拉或者抓举或者其他锁握的动作时候一定要用，可以极大增加握力和手感。推荐液体镁粉，可以摸得很均匀，并且不会搞得到处都是。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;健身时间下午最好不要早上&quot;&gt;健身时间：下午最好，不要早上&lt;/h3&gt;
&lt;p&gt;下午往往是身体最活跃的时候。当然不是所有人都能“奢侈地”在下午健身。不过尽量挑自己状态最好的时候去吧，事半功倍。&lt;/p&gt;

&lt;h2 id=&quot;训练项目&quot;&gt;训练项目&lt;/h2&gt;
&lt;p&gt;几乎所有力量训练项目都是围绕杠铃展开，一个深蹲架就可以锻炼绝大多数项目。基础动作为主：深蹲、硬拉、卧推、推举、臂弯举以及对应种种变式。
具体动作规范，请参考《力量训练基础》，讲解得非常详细，不在这里赘述。简单列一下我认为非常重要的几个动作。&lt;/p&gt;

&lt;h3 id=&quot;深蹲如果只能练一个动作那一定是深蹲&quot;&gt;深蹲：如果只能练一个动作，那一定是深蹲&lt;/h3&gt;
&lt;p&gt;深蹲不是单纯练腿，这一点无需多言，深蹲同时也是非常好的热身项目，每次锻炼前来几组深蹲，可以迅速让你的身体进入状态。&lt;/p&gt;

&lt;h3 id=&quot;硬拉谨防训练过度技巧性最强&quot;&gt;硬拉：谨防训练过度，技巧性最强&lt;/h3&gt;
&lt;p&gt;如《力量训练计划》所说，硬拉是最容易过度训练的项目，我自己也深有体会。拉完一组5rm的重量后，很难再重复一组。甚至先做一组80%重量的硬拉，都会影响到正式组的训练。
所以硬拉按“个”来计算就好。&lt;/p&gt;

&lt;h3 id=&quot;卧推随便练练就好&quot;&gt;卧推：随便练练就好&lt;/h3&gt;
&lt;p&gt;其实卧推并不配和前两个动作并列，首先它锻炼的肌肉比较单一，其次标准卧推练出来的胸并不好看。所以可以同时练练上斜卧推和推举。&lt;/p&gt;

&lt;h3 id=&quot;抓举&quot;&gt;抓举&lt;/h3&gt;
&lt;p&gt;最近我特别喜欢的一个动作。练力量举最大问题是柔韧性会比较差，客观说力量举没有什么技术难度。而举重（抓举+挺举）更考察柔韧性、技巧性和爆发力。同时也更有美感。
练举重的可以转行练力量举，但是练力量举的却很难再去练举重了，因为身体已经僵化了。所以有机会还是练练举重吧。
而我因为身体比例+柔韧性差的原因，没有办法练挺举（杠铃没法架在胸前），所以只能练抓举了。不过我个人也更喜欢抓举，因为更优雅，即使挺举重量可以更大一些。&lt;/p&gt;

&lt;p&gt;俗话说，“外行看腹肌，新手看胸，高手看背，大师看腿。”，“健身不练腿，迟早要 **（自行补充）”&lt;/p&gt;

&lt;p&gt;所以一定要提升腿在训练中的比例。只做上半身训练带来的感觉和练腿是完全不一样的。&lt;/p&gt;

&lt;h2 id=&quot;饮食&quot;&gt;饮食&lt;/h2&gt;

&lt;h3 id=&quot;蛋白粉&quot;&gt;蛋白粉&lt;/h3&gt;
&lt;p&gt;这里专门拿出一段讲蛋白粉。首先分清蛋白粉和增肌粉，即使需要增肌也没必要喝增肌粉，省下点热量预算吃点别的不好吗？
其次注意蛋白粉的蛋白质含量，低于70%就是比较差的了。
想省事直接买Optimum Nutrition的就行，质量还是可靠的。
口味的话见仁见智，巧克力味喝起来就像高乐高；香草味也还行，喝多了有点腻；香蕉味非常值得尝试，就是那种香蕉牛奶的味道！
个人推荐用牛奶冲蛋白粉，口感更佳浓郁。&lt;/p&gt;

&lt;p&gt;注意，乳糖不耐的人喝蛋白粉可能会放屁，习惯就好。。或者说喝完蛋白粉就别去约会了。&lt;/p&gt;

&lt;h3 id=&quot;补剂只有蛋白粉是刚需也可以吃点复合维生素片&quot;&gt;补剂：只有蛋白粉是刚需，也可以吃点复合维生素片&lt;/h3&gt;
&lt;p&gt;乱七八糟的补剂我全吃过：CLA、BCAA、左旋肉碱、氮泵、肌酸。
蛋白粉是刚需，因为正常人（尤其是亚洲人的饮食）每天摄入蛋白质都是不够的，好在大多数人应该都知道了（我还见过很多不锻炼的人每天喝蛋白粉，其实也挺好的）。其他乱七八糟的补剂，简单说吧，大多是安慰剂。
氮泵这个东西，确实有点用，作用类比于咖啡因。但你真的需要吗？健身是持之以恒的活动，况且根本没有人在乎你今天做了多大重量。&lt;/p&gt;

&lt;h3 id=&quot;计算热量表&quot;&gt;计算热量表&lt;/h3&gt;
&lt;p&gt;算是一个基本技能了，好在现在强制规定所有食物都要标记热量，计算起来也很方便。
如果熟练了后，基本不用看热量表就能知道大概多少热量，大多数食物都是差不多每盎司150卡左右。薯片可能180卡，而看起来更健康的麦片可能120卡。所以吃啥不重要，少吃才是王道。
水果蔬菜就不用算了，直接按0卡计就行（除了牛油果榴莲这类变态的水果），因为它们给你带来的饱腹感大于它们提供的热量，所以不用太在意。&lt;/p&gt;

&lt;h3 id=&quot;生酮饮食&quot;&gt;生酮饮食&lt;/h3&gt;
&lt;p&gt;没试过，不了解，也不想尝试。个人持否定态度，因为感觉违背正常生理规律。&lt;/p&gt;

&lt;h2 id=&quot;计划&quot;&gt;计划&lt;/h2&gt;
&lt;h3 id=&quot;明确目标&quot;&gt;明确目标&lt;/h3&gt;
&lt;p&gt;去健身房的人五花八门，不是所有人都为了练力量。即使是“练肌肉”，力量举、奥举、健美，都是完全不同的锻炼方向。
当然也可以按照通俗的分法：“增肌”还是“减脂”，这一点在去健身房前就要自己想清楚。&lt;/p&gt;

&lt;p&gt;几个方向没有孰优孰劣，纯粹看个人喜好，本文主要以力量训练为主，即&lt;strong&gt;为了获得最大的静态力量&lt;/strong&gt;。
而不是：锻炼爆发力（奥举），锻炼耐力（跑步），打造肌肉形态（健美）。
但事实上对于大多人而言根本不用分得这么细，大多人获得力量的同时，爆发力、心肺、肌肉都在同步进步。&lt;/p&gt;

&lt;h3 id=&quot;习惯&quot;&gt;习惯&lt;/h3&gt;
&lt;p&gt;很多人说坚持锻炼是一件很需要意志力的东西。确实，其实强迫自己做任何事情都是在消磨意志力。而意志力其实是一种有限的资源，所以如果只是依靠意志力去锻炼的话，那半途而废就是很正常的事情。
最好的办法就是养成习惯，然后制定好计划，这样每天就按部就班完成就行。当你身体习惯了每天锻炼，一旦停下来不练，你反而会觉得不舒服。&lt;/p&gt;

&lt;h3 id=&quot;减脂&quot;&gt;减脂&lt;/h3&gt;
&lt;p&gt;针对减脂，我不是很擅长，虽然我之前初中时候就180斤，后来瘦下来了，但是近年来没怎么专门减脂。我的建议很简单：&lt;strong&gt;少吃&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;对比一下食物的热量表和运动的消耗表就会明白，少吃才是最划算的减脂方式。去操场跑半小时和少喝一杯奶昔，我相信大多人会选择后者。
当然，如果可以同时锻炼肌肉（最好是腿部臀部这些大肌肉），以增加基础代谢，这样速度会更快一些。
所以造成一个奇怪的现象：很多人口口声声说减脂，但不做有氧运动而是做深蹲。你现在应该可以知道是为什么了。
不要指望一步登天，减脂慢慢来，不要一下子节食太狠，尤其是健身前一定要吃饱，然后蛋白质也要供应充足。对大多人人而言，降低日常脂肪摄入即可。&lt;/p&gt;

&lt;h3 id=&quot;训练而不是锻炼&quot;&gt;训练而不是锻炼&lt;/h3&gt;
&lt;p&gt;这里就涉及到一个态度问题，如果你只是在“work out”，那你永远也没办法练出想要的身材。
把健身当作一项严肃的“training”吧。指定训练计划，保质（每次练多重）保量（每次练几组，每周练几次）。最好在你的calendar上book一整段时间。&lt;/p&gt;

&lt;h3 id=&quot;不要过度训练&quot;&gt;不要过度训练&lt;/h3&gt;
&lt;p&gt;切记矫枉过正，每周练7次并不会有太大帮助，因为边际效益递减，过度训练是在浪费你的时间，更糟的是，如果身体一直没有充分休息，你反而没机会冲击更大重量。
如果在健身过程中感觉有任何不舒服（肌肉、关节疼痛），或者仅仅是感觉今天状态不太好，那么立刻回家，不要犹豫，在健身房多待一秒钟都是在浪费时间。&lt;/p&gt;

&lt;h3 id=&quot;力量训练5rm&quot;&gt;力量训练：5RM&lt;/h3&gt;
&lt;p&gt;5RM的奥义不在于做5个，而是用你只能做5个的重量。所以我的建议是每组都试着做6个，能做就再加重。
RM不是做几个的意思，而是训练强度的意思。所以5RM的重量只做了3个是完全正常的。&lt;/p&gt;

&lt;h3 id=&quot;伙伴&quot;&gt;伙伴&lt;/h3&gt;
&lt;p&gt;健身是孤独的，但是最好找个好肌友一起训练。一个人减少很容易走神或者懈怠（譬如组间休息时刷手机停不下来），而有个buddy可以起到督促的作用。
和女生一起训练的人，基本都是图谋不轨。练的项目和重量几乎完全不重合，一起训练就是在浪费彼此时间。所以咱老老实实训练，不要想些乱七八糟的。&lt;/p&gt;

&lt;h3 id=&quot;记录&quot;&gt;记录&lt;/h3&gt;
&lt;p&gt;记录你的体重以及各项（深蹲硬拉握推抓举等等）的成绩，可以让你看到你的进步，这是一件非常让人开心的事情。
一个人坚持健身绝不是因为他看到自己身材变差而产生羞耻感，而是因为看到自己身材变好带来的正向反馈。&lt;/p&gt;

&lt;p&gt;也可以适当记一下每个机械用的重量，这样练的时候就可以直接切换到目标重量，不用每次都花时间去找适合自己的重量。&lt;/p&gt;

&lt;h3 id=&quot;胜负欲&quot;&gt;胜负欲&lt;/h3&gt;
&lt;p&gt;胜负欲是个很有意思的东西，如果完全没有胜负欲，就会失去很大的训练动力。而如果胜负欲太强，就会变成虚荣心。轻则影响自己心态，重则盲目尝试大重量导致受伤。&lt;/p&gt;

&lt;p&gt;后来我发现最好的办法是不要管别人做了多少重量，只和自己比较，不停去战胜自己。听起来是很假大空的道理，但真的很有用，希望每一个训练者都能早点调整自己的心态。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="life" /><summary type="html">以下部分内容来自于《力量训练基础》和《力量训练计划》两本书。 每一条都是亲身经验之谈，希望可以帮助到热爱锻炼的同学。</summary></entry><entry><title type="html">我与微软小冰的那些事</title><link href="https://lxiange.com/posts/xiaoice.html" rel="alternate" type="text/html" title="我与微软小冰的那些事" /><published>2020-12-27T00:00:00+00:00</published><updated>2020-12-27T00:00:00+00:00</updated><id>https://lxiange.com/posts/xiaoice</id><content type="html" xml:base="https://lxiange.com/posts/xiaoice.html">&lt;p&gt;&lt;em&gt;转眼间 2020 年就要过去了，因为懒，已经好久好久没有写博客了。趁年末赶紧水两篇文章，填补一下 2020 的空白。&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;这学期上 Cloud Computing 用到了 Azure 的 Computer Vision API。一看怎么这么熟悉，原来这就是之前那个 Project Oxford。于是一些往事便浮现眼帘。&lt;/p&gt;

&lt;p&gt;我可能是最早的一批用户了。&lt;/p&gt;

&lt;p&gt;最初 MSRA 刚推出微软小冰时，有个“人脸颜值打分”的娱乐功能，我在它没有正式发布时候（并且当时只有网页 demo，网页接口还有反爬措施，不过我还是把这个 API 扒了出来）就第一时间用上了。因为我当时在南大的微软俱乐部，MSRA 的人来跟我们宣传过他们这个试验性产品。&lt;/p&gt;

&lt;p&gt;然后我把本科教务系统库扒了下来，拿到了全校所有学生的证件照（因为图片都是放在静态资源服务器里，文件名是学号，所以很容易枚举）。
便全部拿过去用这个接口打分了一波，选出全校最漂亮的几个女生（好像有股扎克伯格的味道了）。
事实证明，计算机的审美很靠谱，评分高的真的都挺好看的（当然更重要的原因是我自己评分就挺高的，所以我觉得很靠谱，hhhh）。&lt;/p&gt;

&lt;p&gt;当时没有大规模宣传，毕竟是非法的事，但是还是机缘巧合通过朋友介绍认识了其中一个女生（好像是环境学院的），但是人家有男朋友了，然后就没有然后了哈哈哈哈哈。
当时我跟朋友们说这个女生是算法选出来的校花，没有人觉得诧异，因为确实是公认的女神。
并且算法更加理性，专注于五官，更难被化妆术欺骗。&lt;/p&gt;

&lt;p&gt;就不放别人的照片了，侵犯隐私。放一张自己的：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/xiaoice/xiang.png&quot; alt=&quot;xiang.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;（这是5年前的截图，抱歉让校长做绿叶了哈哈哈）&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;后来，微软这套 CV 升级为 Project Oxford。我当时还给官方的 Python SDK 贡献过&lt;a href=&quot;https://github.com/southwood/project-oxford-python/pull/3&quot;&gt;代码&lt;/a&gt;，也是我人生第一次 PR 被 merge，收到的第一个 comment 就是要补 test case XD。再后来云计算兴起后就整合成了 Azure 上的一个产品，价格还真不便宜。&lt;/p&gt;

&lt;p&gt;转眼间，这一切都过去 &lt;strong&gt;5&lt;/strong&gt; 年了。刚搜了下发现那个&lt;a href=&quot;https://ux.msxiaobing.com/beautyv3&quot;&gt;测颜值页面&lt;/a&gt;竟然还在。Judge 别人长相这么政治不正确的事，竟然没被骂。
不过现在的小冰比之前的版本功能更强了，可以根据一组图片训练自己的 preference 并保存下来。所以最后的分数，就不仅仅是小冰的审美，还有你的。&lt;/p&gt;

&lt;p&gt;Btw，顺手测了一下发现自己颜值崩塌了，不胜唏嘘。。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="life" /><summary type="html">转眼间 2020 年就要过去了，因为懒，已经好久好久没有写博客了。趁年末赶紧水两篇文章，填补一下 2020 的空白。</summary></entry><entry><title type="html">C语言NULL的本质</title><link href="https://lxiange.com/posts/null-in-c.html" rel="alternate" type="text/html" title="C语言NULL的本质" /><published>2019-02-17T00:00:00+00:00</published><updated>2019-02-17T00:00:00+00:00</updated><id>https://lxiange.com/posts/null-in-c</id><content type="html" xml:base="https://lxiange.com/posts/null-in-c.html">&lt;p&gt;故事的起因大致是微博上一个网友说C语言里的NULL就是0，然后一个大V挂了他，觉得他连指针和整数类型都分不清。大V评论区里的粉丝也是各种嘲讽该网友是民科，什么都不懂。&lt;/p&gt;

&lt;p&gt;碰巧之前对C语言以及编译器有一定了解，发现很多程序员对这个看起来很基础的问题的认知都是错误的，因此写这篇文章给大家解释一下C语言里的NULL本质是个什么东西。&lt;/p&gt;

&lt;h3 id=&quot;tldr-大v是错的网友部分是对的&quot;&gt;TL;DR 大V是错的，网友部分是对的&lt;/h3&gt;

&lt;p&gt;首先，要承认那位网友说“C语言里的NULL就是0”是有一定道理的。这里我们要纠正一个偏见，一个字面量的类型，是由编译器决定的，而不是我们在生活中觉得它是整数就一定是整数。而我们这里讨论的，也一直是“0”，而不是“整数0”。0字面量在C语言里比较特殊，并不一定代表整数0，也可以被翻译为空指针，这时候它就是指针类型。（但在Java编译器里，就没有这个特权了）&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;并且这不是因为C语言是弱类型语言从而进行隐式类型转换的缘故，即使底层空指针的机器码不为0也可以直接用0表示空指针。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;一些C语言实现里，直接 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#define NULL 0&lt;/code&gt;。所以这位网友说的是有一定道理的。但又并不全对，因为还有一些实现里，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#define NULL ((void *)0)&lt;/code&gt;。这种情况下，说“NULL就是0”就有点问题了。&lt;/p&gt;

&lt;p&gt;不过反过来说“0就是NULL”也是不对的，0虽然可以直接当成空指针来用，但0也可以作为整数0来使用，这时候他的类型是整数，而不是指针类型。&lt;/p&gt;

&lt;p&gt;那么0为什么这么特殊，可以直接当成空指针来用？并且它的类型就是指针，而没有经过隐式类型转换？其他数字行不行？&lt;/p&gt;

&lt;h3 id=&quot;两个例子&quot;&gt;两个例子&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/null-in-c/img1.jpg&quot; alt=&quot;img1&quot; /&gt;
如图，把编译器的Wall选项(关掉了未使用变量的warning)打开，一个需要返回&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void *&lt;/code&gt;的函数，直接返回0，不会报任何warning。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/null-in-c/img2.jpg&quot; alt=&quot;img2&quot; /&gt;
而如果把0改成1，就会报一个隐式类型转换的warning。所以这证明，0很特殊，可以直接当成指针类型来用，和其他整数是不一样的。&lt;/p&gt;

&lt;h3 id=&quot;编译器实现&quot;&gt;编译器实现&lt;/h3&gt;

&lt;p&gt;为什么0会被特殊对待，可以直接当成NULL来用？&lt;/p&gt;

&lt;p&gt;一步步深究下去，我们可以去看编译器的实现。由于GCC的代码极其混乱，我们来看一下Clang的源码：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/null-in-c/clang.png&quot; alt=&quot;clang&quot; /&gt;&lt;/p&gt;

&lt;p&gt;代码地址：&lt;a href=&quot;https://github.com/llvm-mirror/clang/blob/a1e00ed912a8267b04a9021df529c8f46e7db0a3/include/clang/ASTMatchers/ASTMatchers.h#L6214-L6233&quot;&gt;https://github.com/llvm-mirror/clang/blob/a1e00ed912a8267b04a9021df529c8f46e7db0a3/include/clang/ASTMatchers/ASTMatchers.h#L6214-L6233&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;注释里写得很清楚，诸如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NULL, 0, nullptr&lt;/code&gt; 等词，在词法分析阶段，都被直接翻译为空指针常量。因此对编译器而言他们是完全一样的。&lt;/p&gt;

&lt;p&gt;但问题依然没有解开，为什么编译器会这么实现？我们知道，编译器肯定是按照语言的Specification来实现的，追根溯源，还是得去看C语言的Specification。&lt;/p&gt;

&lt;h3 id=&quot;c语言spec&quot;&gt;C语言Spec&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/null-in-c/spec.jpg&quot; alt=&quot;spec&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这里说得很清楚了：&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;“An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我觉得看到这里，已经什么都不用解释了。官方定义非常清楚，它说0字面量可以当空指针来用，那就可以这么用！&lt;/p&gt;

&lt;h3 id=&quot;后记&quot;&gt;后记&lt;/h3&gt;

&lt;p&gt;为什么会出现这种人为规定0可以当做空指针来用的情况呢？
这恐怕得归罪于C语言历史悠久，刚发明时，各种定义都不够规范。不像Java等强类型语言，设计时就用null关键字来表示空引用。&lt;/p&gt;

&lt;p&gt;对C语言而言，很多东西都是后加的，恐怕0要比NULL要早出现好久。但是同时又要保证兼容性，所以出现了这个问题。
类似的例子还有不少，譬如C语言是没有原生bool类型的，用0或者1来表示true或者false完全没有问题。&lt;/p&gt;

&lt;p&gt;以后遇到类似的问题，应该追根溯源，这样会发现很多看起来难以理解的东西，其实真的很简单。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="tech" /><summary type="html">故事的起因大致是微博上一个网友说C语言里的NULL就是0，然后一个大V挂了他，觉得他连指针和整数类型都分不清。大V评论区里的粉丝也是各种嘲讽该网友是民科，什么都不懂。</summary></entry><entry><title type="html">美国之行感想</title><link href="https://lxiange.com/posts/usa-trip.html" rel="alternate" type="text/html" title="美国之行感想" /><published>2018-05-30T00:00:00+00:00</published><updated>2018-05-30T00:00:00+00:00</updated><id>https://lxiange.com/posts/usa-trip</id><content type="html" xml:base="https://lxiange.com/posts/usa-trip.html">&lt;p&gt;今年5月份的时候，去加州找女朋友玩，这也是我第一次去美国，就像刘姥姥进大观园，因此把一些不成熟的感想记录下来。&lt;/p&gt;

&lt;h2 id=&quot;好的方面&quot;&gt;好的方面：&lt;/h2&gt;

&lt;h3 id=&quot;风景环境&quot;&gt;风景、环境&lt;/h3&gt;

&lt;p&gt;很多人说美国是好山好水好无聊，中国是又脏又乱又热闹。别的不谈，美国的自然风景真是首屈一指，单就我去过的美国西部而言，真的是每个地方都是蓝天白云阳光明媚。
由于地广人稀，许多地方都还未被人类侵蚀，经常可以看到野生动物。也经常会有一望无垠的地平线，总体给人的感受就是比较心旷神怡。
或许对于在美国定居已久的人而言，会感觉一丝荒凉的气息，但对我来说，我还是比较喜欢这种地广人稀的环境的。&lt;/p&gt;

&lt;p&gt;放两张图片吧：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/usa-trip/stanford.jpg&quot; alt=&quot;stanford&quot; /&gt;
&lt;em&gt;斯坦福校园&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/usa-trip/gas.jpg&quot; alt=&quot;gas&quot; /&gt;
&lt;em&gt;加油站随拍&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;气候&quot;&gt;气候&lt;/h3&gt;

&lt;p&gt;这条一定要单独列出来讲讲。中学地理时候学过，地中海气候最适合人类居住。
当时没有什么特别的感受，但是切身到实地感受之后，才能真正感受到什么叫气候宜人。&lt;/p&gt;

&lt;p&gt;先来说一下中国的气候，中国大部分人口都生活在东部地区，而东部又根据纬度，分为温带季风气候和亚热带季风气候。
这两种气候区的特点类似，都是夏季炎热潮湿、气压低，冬季寒冷干燥。
包括我在内，绝大多数中国人都生活在这样的气候，因此便思维固化，认为夏季就应该闷热多雨。&lt;/p&gt;

&lt;p&gt;然而事实是，中纬度大陆西岸，存在一种非常奢侈的气候：&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%9C%B0%E4%B8%AD%E6%B5%B7%E5%BC%8F%E6%B0%94%E5%80%99&quot;&gt;地中海气候&lt;/a&gt;。
这种气候的特点是，冬季温和多雨，夏季炎热干燥。并且因为夏季干燥，蚊虫也较少，非常适合人类居住，可惜分布非常稀少。
关于这种“奢侈”的气候，网上也有&lt;a href=&quot;https://zhuanlan.zhihu.com/p/34426176&quot;&gt;相关的讨论&lt;/a&gt;
其中又有一种亚型为“凉夏型副热带夏干气候”，主要分部在大洋旁边，受海风影响，夏季凉爽，少日照而多雾。简单说就是冬暖夏凉，更适合我这种怕热的胖子。美国西海岸的气候，就属于这一种。&lt;/p&gt;

&lt;p&gt;再来看美国西海岸的气候。从全球气候分部图上可以看到，美国狭长的西海岸气候和广大的美国西部不同，自北向南分别是温带海洋性气候和地中海气候。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%B8%A9%E5%B8%A6%E6%B5%B7%E6%B4%8B%E6%80%A7%E6%B0%94%E5%80%99&quot;&gt;温带海洋性气候&lt;/a&gt;也是非常宜居的气候，除了全年降雨都比较充沛外，其他和地中海气候类似，如果不介意雨水的话，也是非常宜居的气候，西欧地区也是这种气候类型。&lt;/p&gt;

&lt;p&gt;从旧金山向南，一直到圣地亚哥，就是奢侈的地中海气候了。地中海气候的舒爽不必再赘述。但硅谷的气候尤其值得一提。&lt;/p&gt;

&lt;p&gt;前面说到，美国西海岸，属于“凉夏型副热带夏干气候”，夏季凉爽多雾，旧金山就是典型代表，感觉天气总是有点阴沉沉的。5月中旬，我在邻近的圣何塞穿着短袖还觉得有点热，而穿着一件并不单薄的外套，在旧金山街头却被冻得瑟瑟发抖。&lt;/p&gt;

&lt;p&gt;而硅谷相对旧金山更靠近内陆，天气同样凉爽，但是却没有水雾。阳光非常明媚——继承了加州灿烂的阳光，同时气温非常凉爽干燥，完全不需要开空调。再往内陆一点的话，就又变得炎热起来，几种气候之间，相隔不过几十公里。这种得天独厚恰到好处的位置，真是不可多得。也难怪汇集了全世界最精英的人才，创造了无数财富神话。&lt;a href=&quot;http://blog.creaders.net/u/3328/201307/154595.html&quot;&gt;这篇博客&lt;/a&gt;也有介绍硅谷的气候。&lt;/p&gt;

&lt;p&gt;本来全球气候中，地中海气候的分布已是凤毛麟角，其中大洋边的“凉夏”亚型更少，而同时能拥有凉爽的天气，又拥有灿烂的阳光的，更是屈指可数。让人不经感慨大自然的吝啬。&lt;/p&gt;

&lt;h3 id=&quot;小费文化&quot;&gt;小费文化&lt;/h3&gt;

&lt;p&gt;许多中国人比较讨厌美国（其实不单单是美国）的小费文化，明明给过钱了，凭什么非要再给小费？并且比例还不低，普遍是15%-20%。&lt;/p&gt;

&lt;p&gt;首先，我认为小费文化确实是种陋习，小费其实是顾客对服务生的赏钱，它从一开始就把顾客和服务生放在了不平等的地位，更何况有时小费还是服务生的主要收入来源。
美国也有很多不需要小费的餐馆，譬如自助餐和快餐等，因为本质上小费是服务费，不需要服务的话，自然也就不需要给小费了。&lt;/p&gt;

&lt;p&gt;其次，小费也没有那么复杂，一般默认都是15%，你在点单时，默认把这部分价格算在内，就跟税一样。甚至有一些中餐馆针对中国人直接强行在账单里加上了小费。
人性就是这样，对于税这种强制的支出没有怨言，而对于有可能不付的钱，给起来就很不情愿。&lt;/p&gt;

&lt;p&gt;小费文化其实也体现了中美的一些思维方式差异：美国人喜欢把每一项分开理清楚，商品的价格里不包含税和服务费等，顾客买单时还需要额外单独支付。
而中国习惯于“总包”，一个商品标价多少就是顾客实际要付的钱，商家已经帮你把各种费用算在其中了。甚至判刑时，也是数罪并罚，给你打包计算出一个总的量刑，不像国外会分开计算刑期。
我觉得这两种方式没有绝对的好坏，单从我个人而言，或许会更喜欢中国这种打包结算的方式，避免了自己额外的换算，也避免了很多金额的零头。&lt;/p&gt;

&lt;p&gt;之所以把小费文化放在美国好的方面的原因是，我觉得小费赋予了消费者更大的权利，它确实可以带来更好的服务。
对比需要支付小费的餐厅和不需要小费的餐厅，甚至国内的餐厅，能够明显感觉到小费的存在对于服务质量是极大的提升，这也很好理解，毕竟这是服务生的直接收入来源。&lt;/p&gt;

&lt;p&gt;而不需要给小费的餐厅，服务生可能就没有足够的热情提供最好的服务。他们的工资由餐厅来发，但羊毛出在羊身上，他们的工资肯定要包含在餐费里，换句话说，你已经支付了服务费，但却没有得到应有的服务（尤其要批评一些美国的中餐馆，即使给小费，服务依然很差）.&lt;/p&gt;

&lt;p&gt;最后再多说一句，小费是在刷完卡结完账之后给，你走了之后，服务员才会发现你有没有给小费。
也就是说，即使你不给小费，服务员也没法来砍你。不过还是自觉点，做个有素质的消费者吧！除非你觉得服务确实不到位，通过不给小费的方式来“敲打”一下服务员。&lt;/p&gt;

&lt;h3 id=&quot;工作压力&quot;&gt;工作压力&lt;/h3&gt;

&lt;p&gt;环境非常重要，在国内，几乎所有企业都会加班到九点后，因为国内整体大环境就是这样。
即使公司没有明文规定，但在大环境的熏陶下所有人也都会“自愿”去加班，最终自己也成为推动这个环境的一部分。&lt;/p&gt;

&lt;p&gt;而硅谷的环境就是不加班，Google这种公司，下午五点半员工就可以走了。即使像Uber、LinkedIn这类小一点的创业公司，也就七点多下班。
对了，早上依然是弹性上班时间，大家通常都是10点后上班。&lt;/p&gt;

&lt;p&gt;工作压力和国内形成鲜明对比。&lt;/p&gt;

&lt;p&gt;同事说，硅谷那边不加班，肯定干不过中国啊。我觉得是有道理的，中国程序员勤奋爱吃苦，使得中国在互联网领域在十几年内迅速赶上美国，去实现一个又一个“中国梦”。&lt;/p&gt;

&lt;p&gt;但是这和个人又有什么关系呢？作为资本家，肯定喜欢中国程序员这种“奉献精神”，不仅劳动力成本低，剥削起来也很方便。
从国家的角度，人民吃苦耐劳多工作也自然是对整体经济发展有利的。所以中国适合创业者，适合冒险家，很多外企也喜欢在中国开office。&lt;/p&gt;

&lt;p&gt;然而作为劳动者的角度，却很残酷，即使这些“中国梦”成真了，又怎样呢？和自己有什么关系么？最好的结果不过是用自己的青春换来北上广一套房罢了。然后继续被剥削，继续忍受一系列的民生问题。&lt;/p&gt;

&lt;h3 id=&quot;房价车价&quot;&gt;房价&amp;amp;车价&lt;/h3&gt;

&lt;p&gt;买房买车可能是每个人一生中最大的消费了。由于并没有在美国长期居住，我自然也没有机会对美国的房地产市场&amp;amp;汽车进行深入的调查。不过公认的是，美国的房子和车子都比中国便宜。在美国买大排量汽车往往可以比国内便宜一半以上，并且油价更低（汽油比瓶装矿泉水便宜这是真的），并且由于美国地广人稀，很多人住的都是别墅，而在中国，现在很少有地方允许盖别墅了。100w美元在美国大部分地区都可以买到很好的带花园的房子，而在北上广，700w人民币只能在北上广买个普通商品房。&lt;/p&gt;

&lt;p&gt;拿美国“大部分地区”和中国北上广相比，或许有点不公平。是的，湾区、纽约这类地方的房价，折合人民币确实会比北京上海高不少。但是再考虑一下当地的平均收入水平，以及买到手的房子的品质。美国的房价依然比中国便宜很多很多。至少不会成为横在年轻人头上的一道坎。&lt;/p&gt;

&lt;p&gt;这一点其实无可厚非，并不是由于“社会主义优越性”导致的。而是中国人口众多，房、车这类商品的价格自然就非常贵（香港、新加坡同样人口密度大，因此买房买车成本比中国更高）。不过中国人口多带来的好处就是劳动力便宜，谁能想象，在上海，请一次保洁阿姨只要￥30/h？&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/usa-trip/house.jpg&quot; alt=&quot;house&quot; /&gt;
&lt;em&gt;随处可见这种房子&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;stop-sign&quot;&gt;STOP sign&lt;/h3&gt;

&lt;p&gt;美国的 Stop Sign 是一个非常有意思的交通标志。规则很简单：遇到有 Stop Sign 的路口，车必须停下三秒。注意，是停下而不是减速，不管有没有人，你都必须停下。&lt;/p&gt;

&lt;p&gt;看起来非常蠢，但仔细想一下，是一个非常巧妙的设计，充分尊重了行人的路权。譬如在有 Stop Sign 的路口，行人可以完全无所顾虑地横穿马路。
因为即使路口有车，车也一定会停下，而驾驶员看到路中央或者路边有行人时，则会继续等行人通过，这样就不会存在人车相撞的情况。&lt;/p&gt;

&lt;p&gt;然而 Stop Sign 并不适合国内，一方面，国内人口密集，人和车都很多。这么搞的话，车就完全没法开了。
另一方面，中国司机素质可能比国外还是差一些，虽然说车一定要停下礼让行人，但作为行人，你敢直接无所顾虑地走吗？&lt;/p&gt;

&lt;h3 id=&quot;原材料便宜&quot;&gt;原材料便宜&lt;/h3&gt;

&lt;p&gt;在美国的餐馆点餐，有个有意思的现象是，荤素几乎一个价格。譬如在中餐馆点餐，一份炒生菜要15刀，而烧一份羊肉也只要19刀。在快餐馆，豆腐盖浇饭和牛肉盖浇饭都是7刀一份。因为一道菜的食材成本只占小头，并且美国肉制品价格也比国内便宜很多。&lt;/p&gt;

&lt;p&gt;不禁要感慨万恶的资本主义，生产力极其强大，农业工业产品非常廉价且富余，人工成本永远比物料贵（另一方面也体现出人民收入高）。一些“低端”的菜（譬如炒生菜）会比国内贵很多，而诸如波士顿龙虾这些东西，价格便和国内差不多，甚至更便宜了。同样，如果考虑当地收入水平，感觉都是白菜价了。&lt;/p&gt;

&lt;p&gt;作为从社会主义来的土鳖，既然荤素都差不多价格，自然只吃肉啦~ :P&lt;/p&gt;

&lt;h2 id=&quot;不好的方面&quot;&gt;不好的方面：&lt;/h2&gt;

&lt;h3 id=&quot;城市脏乱差&quot;&gt;城市脏乱差&lt;/h3&gt;

&lt;p&gt;个人感觉，美国的精髓在乡村，而城市则是污点。
这一点和之前我在网上看到的类似。富人们用脚投票，扎堆搬到了乡下别墅，而流浪汉、低收入者、有色人种留在城市。
并且美国的行政力量远不如中国，建设和管理效率都很低。&lt;/p&gt;

&lt;p&gt;种种因素导致美国的城市给人一种脏乱差的感觉。我在旧金山街头，就亲眼目睹有人随地小便（还是位女性），街上弥漫着尿骚味和大麻味。
到了晚上，街头随处可见流浪汉，如果是女生，真的不敢随便出门。&lt;/p&gt;

&lt;p&gt;各种基础建设也很落后，地铁就是小电车。随眼可见的建筑，可能都有几十年的历史。
美国地广人稀，城市建设像摊大饼，市中心注定永远也没有北京上海繁华。逛街时不要指望有国内那样人流熙熙攘攘、商品琳琅满目的氛围。&lt;/p&gt;

&lt;p&gt;虽然拿中国改革开放刚发展了三四十年的城市和美国发展了上百年的城市作对比非常不公平。
但不得不承认，美国的城市，已经失去了欣欣向荣的气息，正在逐渐丧失对人口的吸引力。
在中国，所有人都向往定居在大城市核心区，而在美国，或许只有部分人会这么想。&lt;/p&gt;

&lt;p&gt;因此在城市发展方面，中国城市的规模、基建水平以及发展速度都超过美国，有后来居上的趋势。&lt;/p&gt;

&lt;h3 id=&quot;美食&quot;&gt;美食&lt;/h3&gt;

&lt;p&gt;美国人民虽然生产力丰富，各种资源也极其充沛，但其对美食的追求如此之低，确实到了令人发指的地步。
在美国，真的很难找到适合中国人的物美价廉的餐馆，稍微不怎么难吃的中餐馆，就已经备受追捧、人满为患了。
然而事实上，很多美国朋友吃遍全城选出了最佳中餐馆，可能还真比不上国内随便一个私房菜馆。
美国的中餐水平较低，可能得归罪于中国的厨师难以获得H1B :P&lt;/p&gt;

&lt;p&gt;当然这么说可能有点偏颇，毕竟不能以中餐水平来评价美国的美食。美国的优点是兼容并包，你可以品尝到全世界各个国家的美食。
譬如在中国就很难吃到正宗的印度菜或者土耳其菜。但事实是，大多数中国人尝遍各国风味后，最后还是会回归于传统中餐。
所以中国人在美国，掌握精湛的厨艺会对生活品质有巨大的提升（失业了也可以去开个餐馆:P）。&lt;/p&gt;

&lt;h3 id=&quot;购物&quot;&gt;购物&lt;/h3&gt;

&lt;p&gt;在美国购物非常不方便，除非你住在大城市的市中心，不然如果想买杯泡面都要开车十几分钟去附近的大超市。由于地广人稀，到了晚上便没有任何生命气息，半夜里饿了的话，只能忍着。&lt;/p&gt;

&lt;p&gt;在中国，晚上加班完回家后，我喜欢坐在便利店窗边，一边吃着关东煮一边看着路上奔走的人群，然后假装思考一下人生，就感觉很惬意。
在美国还是省省吧，大半夜别被打劫就好。&lt;/p&gt;

&lt;p&gt;并且美国法律非常健全，也不可避免会有很多条条框框的限制。譬如快餐店有那种供开车的顾客购买食品的窗口，而一个行人过去直接买，对方是不会卖给你的。这种场景在中国很难想象，中国人情社会的好处就是，套套近乎，客套客套能解决很多问题。所以在中国“会混”很重要（不好意思扯远了）。&lt;/p&gt;

&lt;h3 id=&quot;人工贵&quot;&gt;人工贵&lt;/h3&gt;

&lt;p&gt;人工贵是发达的资本主义国家的共性特点，叫个急救车、请工人修车、请保洁打扫等等事情都非常昂贵，并且活干得还很一般，效率又低，远不如中国的工人们。&lt;/p&gt;

&lt;p&gt;不过从另一方面来说，这倒也从另一方面反映了平民收入高，个体的劳动得到更大的尊重，毕竟普通人只要能搬搬砖就可以获得很不错的收入。&lt;/p&gt;

&lt;p&gt;这么看来，人工贵好像不是缺点了，毕竟我们大多数人都是劳动者，人工贵代表我们在被资本家剥削的时候能多喝点汤。&lt;/p&gt;

&lt;h3 id=&quot;房卡是磁条卡&quot;&gt;房卡是磁条卡&lt;/h3&gt;

&lt;p&gt;可能是发展得比较早，美国的酒店用的几乎都是过时的磁条卡。磁条卡的性能非常差，在我住的每一家酒店，几乎都碰到了磁条卡无法刷开的情况，经常要耐着性子慢慢抽插几次才行。而国内酒店用的基本都是感应IC卡，灵敏度非常高。&lt;/p&gt;

&lt;p&gt;这一点就好像美国的信用卡体系建立得比较早也比较完备，反而阻碍了移动支付的发展。现在无论安全性还是便捷性或是普及率，中国支付宝、微信都秒杀美国的信用卡。因此中国还是有很多弯道超车的机会，譬如前文提到的城市建设。&lt;/p&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;建议大家如果有机会的话多出去走走。多看看别处的生活，或许对过好自己的生活也有帮助。&lt;/p&gt;

&lt;p&gt;最后福利就上一下帅气的博主吧：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/usa-trip/shawn.jpg&quot; alt=&quot;shawn&quot; /&gt;
:P&lt;/p&gt;</content><author><name>lxiange</name></author><category term="life" /><summary type="html">今年5月份的时候，去加州找女朋友玩，这也是我第一次去美国，就像刘姥姥进大观园，因此把一些不成熟的感想记录下来。</summary></entry><entry><title type="html">阿里云ElasticSearch教程</title><link href="https://lxiange.com/posts/aliyun-es.html" rel="alternate" type="text/html" title="阿里云ElasticSearch教程" /><published>2018-03-10T00:00:00+00:00</published><updated>2018-03-10T00:00:00+00:00</updated><id>https://lxiange.com/posts/aliyun-es</id><content type="html" xml:base="https://lxiange.com/posts/aliyun-es.html">&lt;p&gt;Elastic公司的“ELK”是目前最火的日志分析三剑客，其中ElasticSearch负责日志的索引，Logstash负责日志的收集，Kibana负责日志的展示和分析。&lt;/p&gt;

&lt;p&gt;事实上并不局限于日志分析，ELK技术栈同样适用于通用的数据采集、索引、分析业务。不可谓不强大。&lt;/p&gt;

&lt;p&gt;Elastic与阿里云达成了合作伙伴关系，提供“阿里云 Elasticsearch”的新服务，提供了开箱即用的Elasticsearch和Kibana服务，方便我们快速搭建数据分析平台。下面我们将手把手演示一下如何在阿里云上创建并使用ElasticSearch服务。&lt;/p&gt;

&lt;p&gt;首先，我们创建阿里云Elasticsearch服务，阿里云提供了一个月的免费体验服务。&lt;/p&gt;

&lt;p&gt;如图，选择自己服务器所在的区域、VPC以及下面的虚拟交换机。对于大规模集群，可以勾选dedicated master，专用主节点可增强群集的稳定性。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/1.png&quot; alt=&quot;1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;阿里云目前提供了5.5.3_with_X-Pack版本的ElasticSearch，集成了X-Pack扩展，用户不必再手动购买。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;X-pack是Elasticsearch的一个商业版扩展包，将安全，警告，监视，图形和报告功能捆绑在一个易于安装的软件包中。它可以作为插件被快速集成在Kibana中，并提供给用户集群启用认证、角色权限管控、集群实时监控、可视化报表生成、机器学习等能力。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;开通完成后，需要等待3-5分钟进行初始化。初始化完成后，可以点击实例ID，进入管理页面。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/2.png&quot; alt=&quot;2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;管理界面显示了ElasticSearch实例的基本信息，并且提供了重启、扩容、续费等操作。
同时可以从这里进入Kibana控制台以及监控页面。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/3.png&quot; alt=&quot;3.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;监控&quot;&gt;监控&lt;/h2&gt;

&lt;p&gt;监控页面已经和阿里云的云监控整合在一起，使用方式和云监控完全相同。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/4.png&quot; alt=&quot;4.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;譬如在这里我们可以设置一条报警规则，集群的磁盘使用率5分钟的平均值大于80%则报警。还可以配置通知方式，可以选择手机、邮箱、旺、钉钉机器人等。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/5.png&quot; alt=&quot;5.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;elasticsearch&quot;&gt;ElasticSearch&lt;/h2&gt;

&lt;p&gt;购买ElasticSearch后，在同一区域相同VPC下的服务器便可以直接访问ElasticSearch，相关API可以参考&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/5.5/index.html&quot;&gt;官方文档&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;登录到机器上，调用HTTP API来测试一下是否可以连通ElasticSearch&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/6.png&quot; alt=&quot;6.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;查看节点信息：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/7.png&quot; alt=&quot;7.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;查看index信息：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/8.png&quot; alt=&quot;8.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;可见，阿里云ElasticSearch已经帮我们已经默认创建了几个系统index，这其实是集群的监控信息。&lt;/p&gt;

&lt;p&gt;我们来查看一下其中一个index：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/9.png&quot; alt=&quot;9.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;可见，这里记录的是Kibana的监控信息，同理&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.monitoring-es-6-2018.xx.xx&lt;/code&gt;里面记录的是ElasticSearch的监控信息。&lt;/p&gt;

&lt;p&gt;ElasticSearch的使用方式非常简单，我们可以创建一个新的index来体验一下。&lt;/p&gt;

&lt;p&gt;创建一个名为aliyun_es的index：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-XPUT&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; elastic:YOUR_PASSWORD es-cn-xxxxxxxxxxxxx.elasticsearch.aliyuncs.com:9200/aliyun_es
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/10.png&quot; alt=&quot;10.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;index中的每条记录，称为document（下文简称doc），类似于MongoDB中的概念，事实上也很类似，因为每个doc都是一个json对象。
ElasticSearch的灵活之处就在于可以灵活地支持各种结构的数据，同一个index下，doc也可以有不同的structure，但最好不要这么做，这样很影响效率。&lt;/p&gt;

&lt;p&gt;在index下，还可以用Type对doc进一步分组，以区别不同类型（无需单独创建，添加数据时指定路径即可）。&lt;/p&gt;

&lt;p&gt;添加数据的方式非常简单：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; elastic:YOUR_PASSWORD es-cn-xxxxxxxxxxxxx.elasticsearch.aliyuncs.com:9200/index_name/type_name &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{...}'&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;我们创建如下几个doc试试。&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hahaha&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;I am very happy.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;bar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;helloworld&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;然后再查询一下，验证数据已经插入成功。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/11.png&quot; alt=&quot;11.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;但是Type功能正在被逐渐废弃，预计7.x版本将不再支持Type，因此最好不要再使用。&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;虽然只有三条数据，但是道理是相通的，此时我们已经可以开始对数据进行搜索和分析了。&lt;/p&gt;

&lt;h2 id=&quot;kibana&quot;&gt;Kibana&lt;/h2&gt;

&lt;p&gt;不过使用命令行方式操作ElasticSearch很不方便，并且只有非常基础的功能，我们可以使用Kibana来进行搜索以及数据分析。&lt;/p&gt;

&lt;p&gt;点击页面上的按钮进入Kibana控制台，事实上我们只要记录下这个地址便可以由公网访问Kibana控制台，账号为elastic，密码为之前我们创建实例时设定的密码。&lt;/p&gt;

&lt;p&gt;登录后，Kibana会让我们输入index名以进行初始化，输入之前我们创建的aliyun_es：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/12.png&quot; alt=&quot;12.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;创建完成后，可以进一步进行配置。如果不需要的话，那么就已经全部配置完成了！&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/13.png&quot; alt=&quot;13.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;可以在discover一栏看到我们刚才添加的数据，以及数据的大体统计信息：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/14.png&quot; alt=&quot;14.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/17.png&quot; alt=&quot;17.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;也可以进行各种搜索操作：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/15.png&quot; alt=&quot;15.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;以及各种展示信息，譬如我们可以绘制一个饼状图，统计不同author的的doc数量：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/18.png&quot; alt=&quot;18.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;以及可以查看更多更详细的监控信息：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.lxiange.com/posts/aliyun-es/19.png&quot; alt=&quot;19.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;其他&quot;&gt;其他&lt;/h2&gt;

&lt;p&gt;还可以配合Logstash收集日志，组成完整的”ELK日志分析套装”，当然这也并不是必须的，ElasticSearch并不只局限于日志索引，Kibana也不局限于日志分析。
本文变不再赘述，有兴趣的读者可以自己尝试。&lt;/p&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;阿里云ElasticSearch提供了非常完整成熟的ElasticSearch+Kibana解决方案，用户无需手动运维，只要点点鼠标就可以拥有一个独立的ElasticSearch+Kibana集群。&lt;/p&gt;

&lt;p&gt;相比于手动搭建，有如下几点好处：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;搭建、管理方便，只要点点鼠标就可以搭建完成，并可以很容易地实现扩容&lt;/li&gt;
  &lt;li&gt;独立集群，由阿里云集中管理，并支持快照等功能，稳定性高&lt;/li&gt;
  &lt;li&gt;有X-Pack商业授权，可以使用balabala等高级功能，并默认集成多项插件&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不过也有一些缺点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;价格较高，最低配的集群一个月也要三百多元&lt;/li&gt;
  &lt;li&gt;版本有限，现在官方已经更新到6.x版本，而阿里云上目前只有5.5.3这一个版本可供选择，定制性稍差&lt;/li&gt;
  &lt;li&gt;目前只支持 华北2、华东1、华东2、华南1 这几个区域，其他区域的用户还需要再等等&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;总体来看，阿里云ElasticSearch服务更适合最求稳定与便捷性的企业用户。
尤其是业务跑在阿里云上的企业，阿里云ElasticSearch服务将有效降低运维监控的成本，并提升数据分析的便捷性。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="tech" /><summary type="html">Elastic公司的“ELK”是目前最火的日志分析三剑客，其中ElasticSearch负责日志的索引，Logstash负责日志的收集，Kibana负责日志的展示和分析。</summary></entry><entry><title type="html">Java变长参数的限制</title><link href="https://lxiange.com/posts/java-varargs.html" rel="alternate" type="text/html" title="Java变长参数的限制" /><published>2018-01-07T00:00:00+00:00</published><updated>2018-01-07T00:00:00+00:00</updated><id>https://lxiange.com/posts/java-varargs</id><content type="html" xml:base="https://lxiange.com/posts/java-varargs.html">&lt;p&gt;Java从Java 5开始，引入了可变长参数(varargs)机制，这个机制不是所有语言都有，并且各个语言实现可变长参数的方式也都不尽相同。
Java5是Java语言历史上改动最大的一代，引入了泛型机制。
我们知道Java的泛型是“伪泛型”，只是“编译器小说(compiler fiction)”，因为只是Java语言层的改进，而JVM层没有做改变。因此Java的泛型便存在了若干限制（譬如不支持泛型数组）。&lt;/p&gt;

&lt;p&gt;同样，Java的可变长参数也存在若干限制。并且Java支持继承和函数重载，因此在选择调用哪个函数时，变会存在更多规则，以及一些不够优雅的现象。&lt;/p&gt;

&lt;h3 id=&quot;本质是语法糖&quot;&gt;本质是语法糖&lt;/h3&gt;

&lt;p&gt;和泛型一样，可变长参数只是编译器提供的语法糖，是通过数组来实现的。
在JVM层并没有做任何改动，只是编译器前端将可变参数翻译成了数组。&lt;/p&gt;

&lt;p&gt;因此这两行代码，编译生成的字节码是完全一样的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    test.foo(&quot;1&quot;, &quot;2&quot;);
    test.foo(new String[] {&quot;1&quot;, &quot;2&quot;});
    /*
      21: aload_1
      22: iconst_2
      23: anewarray     #21                 // class java/lang/String
      26: dup
      27: iconst_0
      28: ldc           #22                 // String 1
      30: aastore
      31: dup
      32: iconst_1
      33: ldc           #23                 // String 2
      35: aastore
      36: invokevirtual #24                 // Method foo:([Ljava/lang/String;)V
    */
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;类型不安全&quot;&gt;类型不安全&lt;/h3&gt;

&lt;p&gt;正如前面所说，可变长参数本质是转换为数组对象进行传递。而Java不支持泛型数组&lt;a href=&quot;https://www.zhihu.com/question/20928981&quot;&gt;why?&lt;/a&gt;，因此对于引用类型而言，可变长参数是类型不安全的，需要加上&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SafeVarargs&lt;/code&gt;注解，以绕过编译器检查。&lt;/p&gt;

&lt;p&gt;以下代码摘自Java标准库 Collections.java&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    @SafeVarargs
    public static &amp;lt;T&amp;gt; boolean addAll(Collection&amp;lt;? super T&amp;gt; c, T... elements) {
        boolean result = false;
        for (T element : elements)
            result |= c.add(element);
        return result;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这样可变参数数组，实质上就是一个泛型数组。&lt;/p&gt;

&lt;p&gt;譬如这样的代码，是完全合法的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    public void foo(List&amp;lt;Integer&amp;gt;... arg) {
        System.out.println(&quot;hello&quot;);
    }
    List&amp;lt;Integer&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
    List list2 = list;
    list2.add(&quot;boom&quot;);
    test.foo(list2);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;因此泛型数组的类型安全问题，在可变参数上都得到了体现。&lt;/p&gt;

&lt;h3 id=&quot;一个有意思的现象&quot;&gt;一个有意思的现象&lt;/h3&gt;

&lt;p&gt;之前说了，可变长参数本质是语法糖。可以用数组来替代。
可以将数组传给可变参数，但不能将可变参数传给数组参数。
后者比较容易理解，为了保证原有代码的语义。&lt;/p&gt;

&lt;p&gt;但是我觉得“可以将数组传给可变参数”则不是一个很好的想法，尤其是当数组作为参数时，会产生歧义，导致各种稀奇古怪的问题，而这些歧义只能通过编译器的“约定”来解决。
虽然正常人是不会写这种代码的，但是这种不完备性依然会让人觉得很不舒服。&lt;/p&gt;

&lt;p&gt;对于如下代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    public void foo(Object... arg) {
        System.out.println(arg[0].getClass());
    }
    test.foo(1);
    test.foo(1, 2);
    /* output:
     class java.lang.Integer
     class java.lang.Integer
     */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;传入一个参数或者传入两个参数，最后结果是一样的，这点毫无疑问。&lt;/p&gt;

&lt;p&gt;但是另一种情况下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    test.foo(new Object[] {1, 2, 3});
    test.foo(new Object[] {1, 2, 3}, new Object[] {4, 5, 6});
    /* output:
     class java.lang.Integer
     class [Ljava.lang.Object;
    */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果只传一个数组，那么Java会把数组当成可变参数来看，而如果传入两个数组，则会把数组本身当成一个可变参数数组的一个元素。
这种异常的表现，如果不清楚可变参数底层原理的话，就难以理解了。&lt;/p&gt;

&lt;p&gt;当然，不能只怪可变参数，因为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Object&lt;/code&gt;是所有类的公共父类，如果上述例子改成&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Integer&lt;/code&gt;就不会有这个问题了。&lt;/p&gt;

&lt;h3 id=&quot;一些其他问题&quot;&gt;一些其他问题&lt;/h3&gt;

&lt;p&gt;在函数重载时，如果有多个函数可以调用，具体调用哪个函数的优先级是一个问题。一旦加入可变参数后，这个问题就更加烧脑。&lt;/p&gt;

&lt;p&gt;譬如这种情况，到底会调用哪一个呢？&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;    public void foo(String s, String... arg) {
        System.out.println(&quot;String s, String... arg&quot;);
    }

    public void foo(String s, Object arg) {
        System.out.println(&quot;String s, Object arg&quot;);
    }
    test.foo(&quot;1&quot;, &quot;2&quot;);
    /* output:
     String s, Object arg
    */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;好在大部分人并不会写这样的代码，并且现在的IDE都可以很清楚地指出实际调用的函数。&lt;/p&gt;

&lt;h3 id=&quot;总结&quot;&gt;总结&lt;/h3&gt;

&lt;p&gt;Java由于历史原因，后加入了很多特性，譬如泛型、可变参数等等，不可避免地带来了一下不够优雅的地方，而Java为了保证兼容性而做出的一些妥协，我觉得还是值得的。并且那些可以由IDE很容易就检测出来的错误，就没必要像孔乙己那样去钻牛角尖了。&lt;/p&gt;

&lt;p&gt;Java里还有很多稀奇古怪的问题，推荐阅读&lt;a href=&quot;https://book.douban.com/subject/5362860/&quot;&gt;《Java解惑》&lt;/a&gt;&lt;/p&gt;</content><author><name>lxiange</name></author><category term="tech" /><summary type="html">Java从Java 5开始，引入了可变长参数(varargs)机制，这个机制不是所有语言都有，并且各个语言实现可变长参数的方式也都不尽相同。 Java5是Java语言历史上改动最大的一代，引入了泛型机制。 我们知道Java的泛型是“伪泛型”，只是“编译器小说(compiler fiction)”，因为只是Java语言层的改进，而JVM层没有做改变。因此Java的泛型便存在了若干限制（譬如不支持泛型数组）。</summary></entry><entry><title type="html">Mac 下卸载 Chrome 按照企业政策安装的插件</title><link href="https://lxiange.com/posts/mac-remove-chrome-force-installed-extensions.html" rel="alternate" type="text/html" title="Mac 下卸载 Chrome 按照企业政策安装的插件" /><published>2017-11-05T00:00:00+00:00</published><updated>2017-11-05T00:00:00+00:00</updated><id>https://lxiange.com/posts/mac-remove-chrome-force-installed-extensions</id><content type="html" xml:base="https://lxiange.com/posts/mac-remove-chrome-force-installed-extensions.html">&lt;p&gt;公司配发的电脑，往往会按照公司政策安装一些监控软件。这些监控软件同时也会在Chrome浏览器中安装监控插件，并且这些插件是无法卸载的，就像这样：&lt;em&gt;此处有图&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;我是不反对安装监控软件的，毕竟是公司电脑，受到公司监控无可厚非。不过比较麻烦的是强制安装的这些Chrome监控插件有时会让整个浏览器卡死。经常会遇到浏览器左下方提示“正在等待扩展程序：xxxxx”，并且打不开任何页面的情况。这时必须重启浏览器才能生效。&lt;/p&gt;

&lt;p&gt;这类插件严重影响生产力，便想办法干掉。网上搜了一圈，只能找到Windows下的解决方案。macOS下竟然没有找到现成的办法。不过既然我们拥有电脑的root权限，那肯定是肯定做到任何事情的。捣鼓了一圈，终于找到解决方案，分享给大家，希望有所帮助。应该同样适用于卸载其他强制安装的流氓Chrome插件。&lt;/p&gt;

&lt;h2 id=&quot;windows下方法&quot;&gt;Windows下方法&lt;/h2&gt;

&lt;p&gt;很容易找到的方法有：&lt;/p&gt;

&lt;h3 id=&quot;修改组策略&quot;&gt;修改组策略&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://malwaretips.com/blogs/installed-enterprise-policy-removal/&quot;&gt;3 Ways to Remove “Installed by Enterprise Policy” Chrome Extension&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;只看方法一就行了，另外两个方法都要安装额外软件，不推荐&lt;/p&gt;

&lt;h3 id=&quot;修改注册表&quot;&gt;修改注册表&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://lzw.me/a/chrome-extensions-remove-disabled.html&quot;&gt;chrome谷歌浏览器扩展无法关闭、删除：此扩展程序受政策控制,无法删除或停用&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows下我没有亲身做验证，大家可以适当参考。&lt;/p&gt;

&lt;h2 id=&quot;mac下的方法&quot;&gt;Mac下的方法&lt;/h2&gt;

&lt;h3 id=&quot;简单的方法&quot;&gt;简单的方法&lt;/h3&gt;

&lt;p&gt;删除&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/Library/Application\ Support/Google/Chrome/Default/Extensions/&lt;/code&gt;目录下，以该插件ID命名的文件夹。&lt;/p&gt;

&lt;p&gt;缺点：有可能自动更新重生。并且插件列表里依然会存在这个插件（虽然实质上已经不存在了），强迫症患者无法忍受。&lt;/p&gt;

&lt;h3 id=&quot;更简单但不一定有效的方法&quot;&gt;更简单但不一定有效的方法&lt;/h3&gt;

&lt;p&gt;打开&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;系统偏好设置-&amp;gt;描述文件&lt;/code&gt;，找到包含com.google.chrome的一项，删除之。&lt;em&gt;此处有图&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;缺点：有可能顺带删除了该描述文件中其他配置项，不过可以手动再添加回来。
并且有些监控软件会每次重启时自动再添加描述文件，如果是这种情况，就要逐个击破。&lt;/p&gt;

&lt;h3 id=&quot;针对websenseendpoint插件&quot;&gt;针对WebsenseEndpoint插件&lt;/h3&gt;

&lt;p&gt;以&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Websense Endpoint&lt;/code&gt;插件为例。进入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Application\ Support/Websense\ Endpoint/DLP/&lt;/code&gt;目录，打开&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebsenseEndpointExtension.config&lt;/code&gt;文件，你会发现这里配置了往chrome里配置&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExtensionInstallForcelist&lt;/code&gt;这个键，要求chrome强制安装这个插件。&lt;/p&gt;

&lt;p&gt;按道理应该直接删掉这个值即可，但是你会发现即使以root身份也无法编辑。和企业版Windows系统类似，你登录的这个root，是“伪root”，还有一个更高管理员账号。&lt;/p&gt;

&lt;p&gt;如下文。一般的root，只是wheel用户组下的root，还有一个更高权限的admin用户组。
（是不是有种公司手上的电脑不由你做主的感觉？）&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;drwxr-xr-x  3 root        admin    96B  6 27  2017 Websense Endpoint Helper.app
drwxr-xr-x  3 root        wheel    96B  1 27  2017 WebsenseEndpointDLP.kext
-rw-r--r--  1 root        admin   2.3K 11  5 21:40 WebsenseEndpointExtension.config
-rw-r--r--  1 root        admin    11K  1 27  2017 WebsenseEndpointExtension.crx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;其实破解方式也比较简单：Mac进入恢复模式，然后进入终端编辑即可。&lt;/p&gt;

&lt;p&gt;不过需要注意的是，进入恢复模式后，相当于进了一个新的系统。文件系统和原系统不是同一个，因此此时的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library&lt;/code&gt;目录不是彼&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library&lt;/code&gt;，请切换到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Volumes/Macintosh\ HD/&lt;/code&gt;目录，这个才是macOS下的根目录。&lt;/p&gt;

&lt;h2 id=&quot;原理&quot;&gt;原理&lt;/h2&gt;

&lt;p&gt;无论是Windows还是macOS下，其实强制安装不可卸载的插件都不是chrome的锅，而是取决于系统的设置。chrome只是遵循了系统的设定而已，可以在&lt;a href=&quot;chrome://policy/&quot;&gt;chrome://policy/&lt;/a&gt;页面看到按照本机配置的策略安装的插件。&lt;/p&gt;

&lt;p&gt;其实如果去看Chromium的文档的话，会发现讲得很清楚。Chrome强制安装的插件，是由ExtensionInstallForcelist这个配置参数来决定的。如何修改策略以及更多详细说明，大家可以去看文档，不多赘述：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.chromium.org/administrators/policy-list-3#ExtensionInstallForcelist&quot;&gt;ExtensionInstallForcelist&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dev.chromium.org/administrators/mac-quick-start&quot;&gt;Documentation for Administrators&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dev.chromium.org/administrators/policy-templates&quot;&gt;Policy Templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>lxiange</name></author><category term="tech" /><summary type="html">公司配发的电脑，往往会按照公司政策安装一些监控软件。这些监控软件同时也会在Chrome浏览器中安装监控插件，并且这些插件是无法卸载的，就像这样：此处有图</summary></entry><entry><title type="html">Nginx中转Shadowsocks与负载均衡</title><link href="https://lxiange.com/posts/nginx-loadbalance.html" rel="alternate" type="text/html" title="Nginx中转Shadowsocks与负载均衡" /><published>2017-10-20T00:00:00+00:00</published><updated>2017-10-20T00:00:00+00:00</updated><id>https://lxiange.com/posts/nginx-loadbalance</id><content type="html" xml:base="https://lxiange.com/posts/nginx-loadbalance.html">&lt;h2 id=&quot;番羽土啬技术的瓶颈&quot;&gt;番羽土啬技术的瓶颈&lt;/h2&gt;

&lt;p&gt;由于TCP/IP网络模型的瘦腰结构，最终所有流量都会通过IP协议传送。因此防火墙的终极大杀器，就是封禁IP。一旦IP被封杀，此服务器便废了。&lt;/p&gt;

&lt;p&gt;现在能正常上网的同学不要高兴太早。因为现在的防火墙采用的是黑名单方式，等到哪天逼急了采用白名单方式，那所以翻墙方法都会失效。因此闷声发大财，这是最好的。&lt;/p&gt;

&lt;p&gt;另一个瓶颈在于DNS协议。并且现在的DNS污染已经上升到新的高度，即使设置自定义DNS也不能避免。因为除非使用VPN，否则系统的DNS请求全部通过53/UDP端口发送。
DNS请求是未加密的。因此各级网关可以对53/UDP的请求进行针对性的拦截。&lt;/p&gt;

&lt;p&gt;运营商对53/UDP端口的拦截已经是公开的秘密了，只不过大多数时候用户是无法感知的。在ping Google.com时，发现竟然能ping通，并且延时只有几毫秒，不是GFW罢工了，也不是网络信号可以超光速了，只是你的DNS被劫持了而已 :)&lt;/p&gt;

&lt;p&gt;有两种解决方案：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;挂VPN或者使用类似软件，将DNS请求也经由代理发送。&lt;/li&gt;
  &lt;li&gt;手工配置Hosts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;国内转发的重要性&quot;&gt;国内转发的重要性&lt;/h2&gt;

&lt;p&gt;一个常规的数据包流向：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;用户网络环境 ----&amp;gt; 国外VPS ----&amp;gt; 目标国外网站
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;其中，第二段链路往往是比较流畅的（如果你不是又回过头来访问国内网站的话），
而第一段链路波动就比较大，尤其不同运营商会有不同表现。可能联通宽带可以很快访问，换移动宽带就很慢，甚至换了手机4G就完全访问不了。
这种速度、可靠性不稳定的访问体验是非常差的。&lt;/p&gt;

&lt;p&gt;一个比较好的方案是使用一台国内机器作为中转。&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;用户网络环境 ----&amp;gt; 国内VPS ----&amp;gt; 国外VPS ----&amp;gt; 国外目标网站
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;首先，完全不要担心多了一步中转是否会影响速度（延时），因为本来IP数据包就会经过多次路由转发，添加一台机器中转相当于手动优化了路由规则。
绝大多数情况下，经过中转会降低大大降低数据包从用户端到国外目标网站的传输时间。&lt;/p&gt;

&lt;p&gt;像阿里云腾讯云这样的大厂，他们的机房都在主干网上，并且针对国内各个运营商的线路都做了优化。
因此可以保证在新的数据流动路径上，第一段链路在绝大多数情况下都是快速稳定的。&lt;/p&gt;

&lt;p&gt;至于第二段链路，国内VPS到国外VPS。由于阿里云等厂商基本都是BGP机房，出国线路也比较快速和稳定。
此外，由于是两个机房之间的通信，并且都有公网IP，没有NAT问题。&lt;/p&gt;

&lt;p&gt;这三段链路中，第二段和第三段链路的带宽都不是瓶颈，因为阿里云可以选择按流量计费然后带宽选择100Mb，国外流量更加便宜大碗，VPS基本上都是1Gb带宽。
所以整条链路带宽瓶颈就是用户的宽带带宽。&lt;/p&gt;

&lt;p&gt;可以看到，经过国内中转，访问国外网站的瓶颈得到了消除，和访问国内网站无异，看YouTube比看Youku流畅完全是意料之中的事情（或许因为优酷实在是太烂了。。）&lt;/p&gt;

&lt;h2 id=&quot;负载均衡&quot;&gt;负载均衡&lt;/h2&gt;

&lt;p&gt;不过这样也有一个问题，你会发现整条链路是单链的，其中最脆弱的一环依然在国内到国外这一段，因为GFW只建在国境线上。
一旦IP暴露，被GFW封锁，则这台机器就废了，必须换一台。&lt;/p&gt;

&lt;p&gt;对于自建的VPS，闷声发大财，往往没有这个问题。而对于和人共用飞机场的，则很容易被封。&lt;/p&gt;

&lt;p&gt;一个比较好的解决方法是在国内的VPS上挂载负载均衡器，后端挂着多台国外VPS，一个IP被封杀则自动切换到下一个。&lt;/p&gt;

&lt;p&gt;并且多线程下载时也有加速效果。&lt;/p&gt;

&lt;h3 id=&quot;中转工具&quot;&gt;中转工具&lt;/h3&gt;

&lt;p&gt;常用的、也是网上最常搜到的中转方案，是使用iptables和HaProxy
两个工具都有致命缺点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;iptables只是简单转发，没有负载均衡功能，并且配置相对不友好。&lt;/li&gt;
  &lt;li&gt;HaProxy是专门的负载均衡器，可惜只支持TCP。虽说大多数时候够用，但很多时候我们确实需要UDP，譬如查询DNS或者玩游戏。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;所以这篇文章主要介绍用Nginx来进行流量转发和负载均衡，它支持UDP这一点弥补了HaProxy的不足。
并且Nginx支持插件扩展，可以实现更丰富的负载均衡功能。&lt;/p&gt;

&lt;p&gt;建议使用docker来部署Nginx，优点是快捷方便，且适合有洁癖的同学。
不过缺点是不方便自定义Nginx模块。&lt;/p&gt;

&lt;p&gt;配置文件如下：&lt;/p&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;nginx&lt;/span&gt;;
&lt;span class=&quot;n&quot;&gt;worker_processes&lt;/span&gt;  &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;;

&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt; {
    &lt;span class=&quot;n&quot;&gt;worker_connections&lt;/span&gt;  &lt;span class=&quot;m&quot;&gt;1024&lt;/span&gt;;
}

&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; {

    &lt;span class=&quot;n&quot;&gt;upstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group1&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; $&lt;span class=&quot;n&quot;&gt;remote_addr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consistent&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;:&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;;     &lt;span class=&quot;c&quot;&gt;# ip:port
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;:&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;;     &lt;span class=&quot;c&quot;&gt;# ip:port
&lt;/span&gt;    }

    &lt;span class=&quot;n&quot;&gt;upstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group2&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; $&lt;span class=&quot;n&quot;&gt;remote_addr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consistent&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;:&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;;     &lt;span class=&quot;c&quot;&gt;# ip:port
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;:&lt;span class=&quot;n&quot;&gt;xxx&lt;/span&gt;;     &lt;span class=&quot;c&quot;&gt;# ip:port
&lt;/span&gt;    }

    &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;443&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;443&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;udp&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;proxy_pass&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group1&lt;/span&gt;;
    }

    &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;444&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;444&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;udp&lt;/span&gt;;
        &lt;span class=&quot;n&quot;&gt;proxy_pass&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group2&lt;/span&gt;;
    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;没必要做过多解释了，会Nginx的同学自然会配置。“拿来主义者”（非贬义）对Nginx配置参数也没兴趣，能直接用就行。&lt;/p&gt;

&lt;p&gt;把自己的服务器地址填在对应位置，然后运行Nginx即可。&lt;/p&gt;

&lt;p&gt;建议使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose&lt;/code&gt;部署：&lt;/p&gt;

&lt;p&gt;新建&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt;文件：&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;2'&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;nginx_lb&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx:alpine&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;443-444:443-444&quot;&lt;/span&gt;
     &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;443-444:443-444/udp&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./nginx.conf:/etc/nginx/nginx.conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose up -d&lt;/code&gt;即可。&lt;/p&gt;

&lt;p&gt;以及别忘了在ECS控制台配置安全组规则，打开Nginx监听的端口（此处为443-444, udp+tcp端口）。&lt;/p&gt;

&lt;p&gt;Nginx还有很多有趣的负载均衡策略，可以自己去配置。&lt;/p&gt;

&lt;p&gt;不过这里我推荐使用ip_hash的方式，即根据客户端ip来选择转发机器。
这样的好处是同一个用户始终使用同一个代理，不会导致出口地址跳跃继而触发一些网站的风控。&lt;/p&gt;

&lt;p&gt;顺便说一句，因为同时支持tcp+udp，因此也可以用来中转VPN流量。&lt;/p&gt;</content><author><name>lxiange</name></author><category term="tech" /><summary type="html">番羽土啬技术的瓶颈</summary></entry></feed>