小名开开

在春天的光影里喘息

星际争霸里的数值平衡是挺有意思,值得仔细咀嚼的东西。

预备知识: 虽然星际显示的所有数值都是整数,但在内部绝大部分则使用了更精确的小数计算形式。而只在结果上进行了向上/向下取整处理。在不同场景下,这个计算特性也造成了一些数据结果的特性。比如:

  • 虫族的满血单位在受攻击后会立刻回一点血。
  • 取消建造返回 75% 资源但永远是整数。
  • 人类维修在一矿一气内是先扣款再维修。
  • 一次攻击最低造成 0.5 伤害。

等等……

攻击力,护甲值,血量

对于战斗中的任意一次攻击行为,都是通过以上三项得到最后的伤害计算结果,计算公式为:

伤害 = max { 攻击力 – 护甲值, 0.5 }

直观的公式,攻击力被护甲抵消掉一部分,剩下的对单位造成实际的伤害。

  • 人类枪兵默认 6 点伤害;
  • 人类地堡,默认 1 点护甲;

则人类枪兵每次攻击对地堡造成 5 点伤害。

当护甲值大于等于攻击力时,每次攻击至少造成 0.5 点伤害。

  • SCV 攻击力 5;(战五渣)
  • 行星要塞,升级建筑护甲,护甲值 5。

结果:SCV 每次攻击造成 0.5 伤害,由于显示数值均为向上取整的整数,所以实际上需要两次攻击以后才能看见 HP -1。

虫族被动回血与向上取整

虫族的所有单位均有一个持续的回血速率,为 0.27 血/秒。个别兵种,例如飞龙,或者埋地蟑螂,会有更高的回血速率。这一回血不受任何外界因素影响,也与是否战斗无关,永不停止,直到满血。

星际的血量计算是存在小数数值的,包括伤害下限的 0.5 血,包括虫族回血的 0.27/秒。但这属于内部数据,对外展示出来的最终结果,依然是整数。从真实的小数值到实际呈现的整数值,中间的取数办法是向上取整。也就是说,在任何情况下,只要血量真实值存在小数点,则显示数值均向上取一位。

例如虫族所有单位均有 0.27 血/秒的回血速率(部分特殊兵种更高)。那么任何一个虫族兵种被攻击一次以后,只要不死,则会立刻启动回血过程,在小于半秒的时间内回复了 0.1 的血,在最终数值显示上便回了一点血。这也是那些初级数值研究文章里常说的,虫族在被攻击一次以后会回复一点血的原因。其真实原因如下:

  • 虫族单位的回血是任何时候只要小于满血量便永远存在的;
  • 虫族单位被攻击后进入不满血状态,该回血启动,回复 0.1 甚至更少的值;
  • 系统显示数值是向上取整而非四舍五入;
  • 故显示上是瞬间回 1 血;

某些人认为的“1 点隐藏护甲”,则是完全完全错误的。尝试:

  • 零攻攻城坦克:攻城模式 35 点攻击力,重甲 +15;
  • 零防跳虫:35 血,0 护甲值,轻甲;
  • 一防跳虫:35 血,1 护甲值,轻甲;

零防跳虫就是一炮死。因为来不及回血,也不存在什么隐藏护甲值。但是如果虫族升了一防,则坦克一炮轰上以后跳虫会有两格血,事实上是 35-1 = 34 点伤害,剩余 1 血,同时虫族回血机制启动,极短时间回复 0.1 血(每秒是 0.27,开始回血时还不到 1 秒,几乎瞬间),由于数值向上取整,我们就会见到回复了 2 滴血。再尝试:

  • 一攻女妖:13×2 攻击力;
  • 三攻机枪兵:9 点攻击力
  • 零防跳虫:35 血,0 护甲值;

则零防跳虫在经受了女妖和机枪兵的一轮攻击后,正好还剩下一点血。本来伤害量是正好 35 点的,但由于女妖和枪兵无法做到完全同时产生伤害,使得跳虫有短暂的时间回复零点几的血,从而在第一轮攻击中幸存下来。需要机枪兵额外一次攻击才能杀死。从这些数值可以明显地看出,虫族的 “第一次受攻击秒回一血” 只是一个结果,并不是原因,而 “隐藏护甲” 则简直是瞎扯。另外,虽然从结果上看 “受到攻击后立刻回 1 血” 有时候也正确,但由此衍生出来的什么 “回 1 血隐藏 CD” 也是错误的,单纯只是持续回血过程中是否正好巧合地遇上整数断点罢了。

由于正常情况下伤害值都是整数,故虫族的小数点血量在实际效用上确实等同于整数 1 血。虽然真实血量是个斜线,但效用血量却是阶梯横线。

除了护甲大于等于攻击情况,只有非零攻异龙的弹射攻击是小数点伤害数值,腐化者的腐化技能通过 debuff 加成可能产生大量的小数点伤害数值。奇葩都出在虫族。

攻防升级

每个种族都有针对绝大部分单位的攻防升级科技,可升级三次。攻防升级对已经在战场上的单位同样有效,因此可以利用刚升级完成的时间让大部队发动一次有攻防优势的进攻。

三个种族的攻防升级具体影响的单位并不一样。人类分为生物部队攻防和机械部队攻防;星灵分陆军和空军攻防,另有所有单位的离子盾升级;虫族没有离子盾,但地面部队的近战攻击和远程攻击是分别升级的。

此外,还存在针对个别单位的单独攻防升级项目。人类的建筑护甲升级(+2 甲),雷兽的硬化甲壳升级(+2 甲),人类的恶火对轻甲的伤害加成等。

同一层攻击升级对不同单位的影响也不一。例如虫族地面近战攻击升级,跳虫是每层升 1 点,而雷兽则是每层 3 点。而三族所有防御升级却全是 +1,专项升级除外。因此三攻三防的枪兵内战,和零攻防的枪兵内战效果一模一样,但三攻三防的坦克对打起来却比零攻防的对打死得更快。高级兵种在攻防加成上享受到的比初级兵种更多一些。

多重攻击

在游戏中,“多重攻击”可以理解作“左右开弓”。也就是每次攻击有双份,每份独立进行攻防计算。游戏中除了星灵母舰是 6 重攻击以外,别的拥有多重攻击属性的都是双重攻击。

大部分双重攻击的单位都可以从外观上直观地看出来,收割者是双枪党,显然是双重攻击;女妖导弹有明显的相互缠绕的轨迹,也是双重攻击,导弹塔也类似;狂热者是帅气的幽能双刀;巨像和凤凰的两道激光那么明显,女皇表示她也有两只爪子……

例外的是行星要塞和不朽者。游戏中说明文字上写的行星要塞是加装了双管“伊比克斯”加农炮,外形上也很霸气,却不是双重攻击。不朽者的游戏背景资料写道,他们是仅存的龙骑士们加装了双重相位分裂炮,但实际游戏中也不是双重攻击。

双重攻击意味着 “一轮攻击,两份效果”。通常来说,双重攻击的特性主要是为了数值平衡,“打了一半”的情况极少出现,但如果你刻意制造还是能做出来的,比如狂热者的两刀就是有先后的。

在多重攻击下,伤害计算公式依然简单而符合逻辑:

伤害 = max { 攻击力-护甲值, 0.5 } x 多重攻击数

例如:

  • 零攻收割者,攻击力 4×2;
  • 三防雷兽,护甲 4。

每一轮攻击会造成 0.5×2 的伤害,也就是 1 点。而不是 0.5 点。通常来说,双重攻击在攻防优势时的收益更大,而劣势时的差距也更大。

双重攻击存在完全同步的两次攻击(收割者),以及有先后的双重攻击(狂热者)两种情况,两者在极端情况下的表现会有微小的不同,但大致没有区别。

特定属性加成

很多兵种对特定属性的对象的攻击力会有额外加成。例如劫掠者的普通伤害是 10,而对重甲单位的伤害是 20。被加成的属性通常有轻甲、重甲、生物单位等。目前还没有兵种对两种以上的属性有加成伤害。攻防升级对加成伤害同样有效,升级变化数值有些高于基础伤害的增加值。

但加成伤害的具体数量并没有明确的规律可寻,孢子爬虫对生物单位的伤害高达基础伤害的 3 倍。(15→45),而执政官则只加成约 40%(25→35)。通过特定属性加成并且分别微调,暴雪给自己留了个方便的平衡性改动的口子。

这些加成的计算优先级最高,只和攻击者及被攻击者的属性有关,计算时可以直接视为基础伤害。这造成了非常明显的兵种相克的链条,使用针对性的兵种能有效扩大优势夺取胜利。

攻击间隔

每个可进行直接攻击的单位都有两次攻击间的时间间隔设置,数值也是游戏里的秒。不少资料简单理解为攻击频率,严格地说是不对的。频率定义的是每秒多少次,而不是两次间隔;

  • 攻击间隔是该单位两次攻击行为之间的最短时间间隔,这个时间被形象地称为 “Cooldown”,来源于工业机械的停机散热。并不是到时间就必须进行下一次攻击;
  • 对于分先后的多重攻击,攻击间隔严格描述的是多重攻击每轮攻击中 “第一发” 之间的时间间隔。例如狂热者的两轮攻击,两个第一刀之间的最短时间间隔为 1.2 秒。多重攻击内部间隙一般不考虑了;
  • 除凤凰战机以外,所有兵种在都要站定时才能攻击,也就导致了 “甩枪” 这一操作的出现;
  • 站定输出的实质在于产生一次攻击前有短暂的前置时间,随便理解成瞄准、深呼吸、扣扳机都行,这一时间各兵种有不同但都接近于零,实质上就是程序在判断输出时必须无移动指令;
  • 实战中,站定输出的前置时间长度确实存在,原因是网速。你网速越好,前置站定时间越短;
  • 站定输出的后置停止时间是装饰用的,打完了歇口气的感觉,可以通过手动移动指令覆盖;
  • 兴奋剂、肾上腺素等升级可以减少输出间隔,在相同时间内作出更多次攻击行为,提高伤害;
  • 射程相当时,在移动上有优势的单位可以通过操作把对方兵种的攻击频率拖到跟自己一样;
  • 巢虫领主、航母等附带单位的攻击间隙,主单位与附带单位的攻击间隙都是独立计算的;
  • 尽管攻击力除以攻击间隔就可以得到 DPS(每秒输出伤害)数值,但 DPS 数值并不能有效描述该类单位的实战输出强度;
  • 部分战斗系技能有冷却时间,不耗蓝技能的 CD 较长,而耗蓝技能出于平衡性因素也添加了一些 CD,比如灵能风暴的 2 秒;
  • 修理技能没有 CD,感染者扔异化作战体也没有 CD;

距离与体积

星际中的长度单位以“格”为基础单位,游戏中各种涉及到距离、长度、速度的数据,均以格为基础数据,用精确的小数衡量。“格”的范围在建造建筑时体会非常明显。

尽管建筑占地为 2×2、3×3 之类,但建筑实际挤占的空间却略小于占地面积。在两个对角建造的建筑缝隙间,依然可以穿过体积小于 1 的兵种,比如机枪兵或者小狗。需要错一格才能严格封堵。对于 5×5 的主基地则更为特殊,错两格都依然能通过 1 体积兵种,错一格时甚至能通过一个追猎者。

每个单位都有自己的体积,以指定半径的圆形描述,属于一个内部数据,与玩家选中单位时脚下的圆形没有关系,只能通过解析客户端数据获得。所有的占位、可穿过等与体积相关的特征,都与这个内部数据相关。当两个单位的圆形最近处宽度小于兵种自身直径时,寻路算法便不把两单位之间的缝隙视作一条通道了。部分单位在切换形态时,例如攻城坦克切换到攻城模式时,其体积会发生变化。另一个更实际的例子是星灵机械哨兵的力场,通过从某个特定坐标 “膨胀” 出一个圆形,从而对部队分布产生影响。

而在建筑摆放时,则无视圆形体系这套系统,单纯以建筑网格判断是否可以建造。因此两个相邻建筑的碰撞体积圆周可能是相交的。所以有时候会出现攻城模式的坦克挡住了气矿,气矿无法建造的情况。

空中单位也存在体积,区别在于空中单位并不强制碰撞,而是缓慢地相互分离,直到达到最后互不重合为止。

视野

每个兵种与建筑都有自己的视野范围,呈圆形,在视野内才能看见敌方的动静,视野外则覆盖有战争迷雾,只能看见地形:

  • 地面单位的视野受地形影响更大一些,会受到树、草丛、柱子等影响,而空中单位则不会;
  • 所有友方单位的视野共享,包括多人游戏时的盟友视野,可以借助友方单位的视野进行一些必须有视野才能操作的动作,比如投放矿骡或者挖虫洞;
  • 建筑也拥有自己的视野,大多都是 9,但主基地和防御建筑的视野会更大一些;
  • 感应塔的视野是 12,但额外拥有 30 的感应范围,可感知敌人位置,但不属于视野;
  • 不考虑感应塔的特例,视野最大的建筑是萨尔那加塔,为 22,单位是星灵母舰,14;
  • 雷达可以全图开视野,半径为 13,这个都知道;
  • 所有的工程兵视野均为 8;
  • 建造中的建筑视野为 5,包括自身占据体积,对人类而言,建造中的 SCV 也会实际扩大这一区域的视野。
  • 虫茧,即正在变异中的毒爆、眼虫、巢虫领主和幼虫孵化各兵种时的状态,视野为 5。
  • 埋地单位视野减少为 4,但感染者和毒爆不变,异化作战体减少为 5;
  • 反隐可以认为是一种特殊的视野,反隐单位的反隐距离永远与视野一致;
  • 虽然如此,但视野会被地形遮挡,反隐能力却不会。悬崖下光子炮台,地形受限视野无法覆盖崖上,但借助友军视野,依然能侦测到高地上范围内的隐藏单位;
  • 视野详细数据见:http://wiki.teamliquid.net/starcraft2/Sight

射程

有距离的衡量单位以后,射程也就可以确定了。在游戏中射程的重要性受操作的影响非常大,更经常与地形、视野配合,获取更大的战斗优势。

  • 射程的起止点是从攻击单位的体积边缘一直到受伤害单位的体积边缘,以确保两个不同体积但相同射程的单位在无额外操作的情况下可以相互攻击到对方。最典型例如地堡枪兵(5+1)对抗追猎者(6);
  • 因此在视觉上,重形单位射程比实际数值更大一些。典型例子:光子超载的星灵枢纽、仲裁官;
  • 每个单位都存在体积,其边缘和视觉并不完全一致,有的大有的小。具体数值解析客户端可得,实际往往通过聚团时大小靠感觉判定;
  • 尽管异龙的射程只有 3,但由于弹射另有 2 的射程,再加上建筑较大的自身体积,异龙能打到 7 以上的距离。借助建筑弹射绕路的地面部队也是异龙操作技巧之一;
  • 近战兵种也是有射程的,数值上视为 0.1,但毒爆的触发范围为 0.25,确保毒爆对近战单位的优势。毒爆的伤害范围为 2.2,以爆炸中心点开始计算;
  • 升级冲锋的狂热者在冲锋追上敌人后必定至少造成一次伤害,这次伤害的 “近战距离” 可能大于 0.1,是某个补丁后添加的特殊设计;
  • 大部分兵种的远程攻击距离是整数,但并非必然。收割者(4.5)、巢虫领主(9.5)表示有话说。
  • 蔽目毒云造成的近战距离也为 0.1;
  • 人类攻城模式坦克和星灵风暴战舰是仅有的两个最大射程比视野还大的兵种,需要友军帮助打开视野才能获得最大攻击范围;
  • 人类攻城模式坦克是唯一一个有最小攻击距离的单位,距离为 2;
  • 星灵航母的射程分两段,8 点为派出拦截机的触发距离,14 点为拦截机的强制回收距离。
    • 拦截机派出时间为 8 秒,8 秒后必须回到航母后再重新派出,因此以下内容在讨论距离为 8 – 14 范围时都假定在同一个 8 秒内;
    • 拦截机本身在动画上有射程,但该射程实际并无作用,拦截机有时在动画效果上会飞到接近 14 处,但依然不会攻击 14 以外的目标;
    • 在派出拦截机后,航母可以后撤,只要 14 范围内,拦截机在 8 秒内依然会攻击既定目标;
    • 拦截机也有视野,因此在攻击 8-14 范围目标时不需要额外开视野;
    • 在 8-14 范围内,目标死亡后,玩家可以手动点选一个新目标,拦截机可以不回舱直接转向新目标。此时航母会驶向目标,再次手动拖拽可以使它继续停在 8 以外,达到距离外切换目标的效果;
    • 但 8 为“派出距离”,也就是说如果敌方在 8-14 内时,尽管已经派出的拦截机会继续攻击,但新造的或者未派出的拦截机则不会继续派出;
    • 默认的 “派出间隔” 为 0.5 秒,4 秒全派出。可以通过升级提升到 0.125(前四)到 0.25(后四),1.5 秒全派出;
    • 拦截机的攻击间隔为 3 秒,基础攻击力 5×2 双重攻击,一次派出可以攻击三次;
    • 航母的攻击力完全来自于拦截机,相当于 5 点攻击力的 16 重攻击。因此敌方的护甲升级会产生巨大的影响;
    • 拦截机 25 血,虽然无法选中、无法手动点击,但可以被自动防御机制,例如防空塔、机枪兵、光子炮台等击中摧毁,因此航母需要时刻注意补充拦截机。友军人类开启 SCV 自动修理也可以修理拦截机;
    • 拦截机虽然不占用人口,但由于航母占用 6 人口,因此初始四架每架拦截机等效占用 1.5 人口,满载八架后每架等效占用 0.75 人口;
    • 空的航母在攻击指令下达后也会停在 8 格处,而不会飞到敌人脸上;

移动速度

移动速度是建立在游戏内距离和游戏内时间双重数值下的的一个兵种动态属性。速度的作用在于快速接近敌人、逃跑、追击、巡图、捡漏等,以建立整个对战过程中的战术优势。速度并不影响攻防数值,但却可能影响兵种相克。速度的衡量标准单位为 1 格/秒,可以简写为 1。

  • 移动速度与攻击速度(攻击间隔)是分别的两个属性,例如时空折跃会将区域内敌方兵种移动速度降低到 50%,但并不改变其攻击速度,虽然从感觉上来说应该变;
  • 在较大部队行进时,每个兵种的速度是各自计算的,由于寻路与体积碰撞等因素,整个部队的移动速度会慢于组成兵种的移动速度;
  • 游戏中速度最快的是星灵航母的拦截机,速度为 7.5,但是考虑到拦截机属于特殊情况,而航母本身却只有可怜的 1.875 的速度,所以实战意义上的最快速度并不是它;
  • 可操作的最快速度是菌毯上的代谢加速跳虫,为 6.1088,其次紧随其后的是冲锋状态中的狂热者,速度为 6.05;
  • 那么显然问题来了,冲锋技术哪家强 冲锋狂热者能否追击到菌毯提速狗?
  • 答案当然是不能。事实上冲锋也是一个 BUFF,持续 3.5 秒,在此时间内差不多能冲过 22 格距离,相当于萨尔那加塔的视野,也差不多是一个屏幕的距离,然后就会慢下来;
  • 这与某次补丁的 “冲锋后至少能击中一下” 不矛盾,冲锋在两者距离小于 0.1 时会提前结束,当提前结束时,必然产生一次攻击。但如果是时间到结束,则相当于始终未曾接近,故不产生攻击行为;
  • 所以如果你够骚,可以尝试拿条跳虫把对方的狂热者带到一个屏幕外自己的大部队这里来消灭掉;
  • 速度第三是无菌毯提速狗,4.6991,所以穿狗入矿区必须靠建筑预防;
  • 并列第四的是推进器状态医疗艇、恶火和凤凰,均为 4.25;
  • 速度最慢的是未升级王虫,为 0.586;
  • 其它数据详见:http://wiki.teamliquid.net/starcraft2/Speed;

弹道

很多兵种发射的子弹都有明确的行进轨迹,人类的各种飞弹,星灵的蓝色激光,虫族的绿色喷吐。弹道并不仅仅是一个视觉效果上的设置,在数据方面也会产生一些变化。

  • 弹道类攻击从攻击方发射出来,到防御方受到攻击,中间存在一个时间差。这个时间差随着弹道长度会变化;
  • 随着目标的移动,弹道也会发生变化,最后总是会击中目标,即使目标已经移出自己的射程外;
  • 铁鸦的可以跑远躲开的自动导航炸弹是技能,不是弹道类普通攻击;
  • 子弹飞行时间的长短并不影响攻击兵种的攻击频率,间隔是按发射频率算的;
  • 弹道类攻击有更明显的发射前动作,而不光光是子弹的飞行时间。这使得 “甩枪” 动作需要停留的时间比机枪兵和收割者更慢一些;
  • 尽管常规移动并不影响弹道类飞行的命中,但确实可能通过某些手段回避掉已经发出的弹道类攻击。比如追猎者的闪烁,或者人类兵的快速上下医疗艇。原理是取消弹道类攻击的飞行终点;
  • 整个游戏唯一针对弹道类攻击的技能是铁鸦的定点防御靶机,但出于平衡性修正,个别视觉上属于弹道类的攻击也被排除在外了;
  • 所以上下医疗艇可以防御的弹道类攻击种类最多;
  • 弹道类攻击会出现很多子弹同时射向某个残血目标导致大量输出浪费的现象,原因也是弹道攻击的延时。尽管输出有先后,但在第一发子弹飞到目标前,大家都会认为目标还活着纷纷扔出自己的菜刀;
  • 在非常非常极端的情况下,瞬发技能也可能造成类似的输出浪费。这是因为星际在游戏机制上的最短时间间隔为 0.001 秒,即 1 毫秒,可以通过分析游戏录像包数据得到。这使得在同一个时间间隔内的动作变成 真•同时;

星灵护盾(一)

星灵护盾是星灵特有的属性,覆盖所有的建筑和兵种,甚至包括生产过程中的单位。在任何情况下,星灵单位受到伤害时,都优先扣除护盾值,到护盾为 0 时,再扣除 HP。星际 1 中存在蝎子毒血无视护盾直接伤害 HP,星际 2 不存在。

护盾和护甲的防御是分别计算、单独升级的,所有单位的护盾防御初始值是 0,每级 +1。计算公式和护甲完全相同,即:

伤害 = max { 攻击力-护盾值, 0.5 } x 多重攻击数

在最极端的情况下:

  • 零攻收割者,攻击力 4×2;
  • 机械哨兵,守护者之盾,使光环内友方单位受到的远程伤害减少 2 点;
  • 二盾狂热者,护盾防御 2 点。

收割者每轮攻击为 (4-2)x2,而护盾防御也为 2,实际伤害为 0.5×2,即 1 点。当未开启守护者之盾时,则每轮实际伤害为 4 点。守护者之盾开启与否效果很明显。

当护盾的总量不足以抵挡单次伤害时,则护盾防御与护甲防御同时起作用。比如:

  • 零攻掠夺者,对重甲伤害 20;
  • 一防一盾追猎者,护盾剩余 10 点,护盾防御 1 点,护甲防御 2 点,重甲;

则掠夺的下一发伤害计算为:

  1. 护盾防御减伤: 20-1=19 点伤害;
  2. 全部剩余护盾抵挡掉 10 点伤害,19-10=9,剩余 9 点伤害传递给 HP 承受;
  3. 9 点伤害被护甲抵消 2 点,剩余 7 点伤害实际作用于追猎的血量上。

但当该临界点下的伤害被护甲完全防御时,并不造成额外 0.5 的伤害。比如:

  • 零攻狂热者,伤害 8×2;
  • 一防一盾机械哨兵,40 护盾 40 血,护盾防御 1 点,护甲防御 2 点;
  • 零防一盾机械哨兵,40 护盾 40 血,护盾防御 1 点,护甲防御 1 点;

由于狂热者双重攻击有先后,则攻击过程为:

  1. 前两轮打在护盾上,造成两次 (8-1)x2 =14 伤害,哨兵剩余 12 盾 40 血;
  2. 第三轮前一刀 8-1 点伤害盾完全吸收,后一刀 8-1 点伤害盾吸收 5 点,剩余 2 点打到护甲上;
  3. 零防哨兵 1 护甲会损失 1 点血量,39 HP,一防哨兵 2 护甲则未损失血量,40HP;
  4. 等待哨兵回复满盾后,再重复以上过程,零防哨兵再减 1 点血量,38HP,一防哨兵依然未损失 HP,40HP;
  5. 两次过程积累后可看出,每次破盾后打在护甲上的伤害为 2 点,被护甲 2 点抵消后,不再产生额外 0.5 点伤害。

零防哨兵的掉血曲线间接证明了狂热者双刀有先后,而一防哨兵未掉血,表明在临界点上,一次伤害如果已经对盾造成实际损伤,则即使剩余伤害被护甲完全抵消,也不会额外计算 0.5 伤害。理由大概是已经存在伤害,不需要再考虑伤害下限了。

护盾会在最后一次伤害结算后 10 秒开始回复,回复速度为每秒 2 点。有些说明写的是脱战后 10 秒恢复,从语言表述上来说是不正确的。星际跟 WOW 不一样,并没有明确的“战斗状态”,也就没有进战脱战这种说法。只要 10 秒不受到伤害,在战头中也是可以回复的,下次用闪烁追猎记得多操作。

建造中的建筑或折跃中的单位的护盾行为例外。建筑在放下的一瞬间就有 10% 的血量与护盾,而后按建造总时间与总护盾值匀速增长,没有 10 秒的结算时间,没有护盾防御加成,也没有额外的回复。例如:

  • 星灵枢纽:1000 血 1000 盾,建造时间 100 秒,放下的一瞬间有 100 血 100 盾,之后每秒增加 9 血 9 盾;
  • 零攻追猎者对重甲每次攻击 14 点伤害,1.44 秒攻击一次,100 秒攻击 69 次,造成 966 伤害;

也就是说,只靠一个追猎者,在主基地建造过程中完全无法造成实质伤害……

折跃兵种的过程也是一样,初始状态 10% 血量 10% 盾,因为折跃刷新的时间很短,兵种很快就会结束折跃满血满盾进入战斗。实战中不如集中火力打击水晶或运输船更合算。

所有建筑的护盾和血量都相同,绝大部分的兵种血量都大于等于护盾,但黑暗圣堂和执政官除外。考虑到升级时间与升级费用,在对抗虫族时升级三防有时不如升级一盾更合算,尤其是队伍内有大量执政官时。对抗人类……因为有 EMP……还是算了吧。

星灵护盾(二):刚毅护盾

刚毅护盾是星灵不朽者特有的被动技能,当护盾存在时,所有攻防结算伤害高于 10 点的攻击效果都降低为 10 点。这一上限是先由攻防结算后再作限定的,也就是说是 min{攻击力-护盾防御值, 10}。比如:

零攻追猎者,普通伤害 10 点,对重甲伤害 14 点;
三盾不朽者,重甲,护盾防御 3 点,护盾满,刚毅护盾有效。

则追猎打不朽,以重甲结算,攻击力为 14 点,不朽护盾防御力为 3 点,则攻防结算伤害为 11 点,触发了刚毅护盾,减少为 10 点,所以最终结果是不朽减 10 点盾,并发出刚毅护盾视觉效果。当不朽的护盾不足 10 点时,刚毅护盾效果依然存在,将高于 10 点的攻击伤害降为 10 点,剩下计算和普通的分界线计算一致,再次受到护甲减免。因此即使只有 1 点护盾,也可以抵抗一次高攻伤害。

但刚毅护盾对固定伤害的技能性攻击是无效的。尽管星际2是个科幻背景游戏,不过把以下这些技能理解作是“魔法攻击”,会更方便一些。

“魔法攻击”(技能伤害)

星际2是个科幻背景游戏,但把这些技能理解作是“魔法攻击”,理解上会更方便一些。

  • 聚变打击(幽灵) – 较大范围内 300 点伤害。
  • 大和炮(战列巡航舰)- 单体 300 点伤害。
  • EMP(幽灵) – 范围移除 100 点星灵护盾与 100 点能量(如果有能量)。
  • 哨兵导弹(寡妇雷) – 对攻击主体造成 125 点伤害(有护盾单位额外 +35 点),并造成 40 点溅射伤害(有护盾单位额外 40 点)。
  • 猎杀飞弹(铁鸦) – 攻击主体及范围内造成最多 100 点伤害。
  • 狙杀(幽灵) – 对生物单位造成 25 点伤害,对灵能单位额外造成 25 点伤害。
  • 能量反蚀(光明圣堂武士) – 消耗目标所有能量,每点能量造成 1 点伤害。
  • 灵能风暴(光明圣堂武士) – 范围内 8 次伤害每次 10 点,共计 4 秒。
  • 霉菌滋生(感染者) – 范围内 4 秒造成 30 点(重甲 40 点)伤害,且无法移动。

以上为伤害性技能,其特点是:

  • 伤害值不受攻防升级影响
  • 伤害值无视护甲、护盾防御值
  • 伤害值无视守护者之盾,但是会受到腐化影响
  • 伤害值无视刚毅护盾
  • 除聚变打击外,所有的技能施放都需要能量值

基于这些特性,认为是“魔法攻击”也并无不妥。是的,毒暴的伤害并不属于此类,毒暴的伤害是受攻防加成的。

能量

能量值是大部分兵种和单位施放特殊技能的消耗性资源,在游戏中以紫色条显示。大部分有能量单位的能量上限为 200 点,并且永久地以每秒 0.5625 点回复能量,刚生产出来的单位初始拥有 50 能量,一些单位可以研发升级让初始技能变为 75 点。但有三个单位例外:

  • 星灵枢纽初始能量 0 点,上限 100 点;
  • 皇后初始能量 25 点;
  • 定点防御靶机初始能量 200 点,每秒回复 1 点能量。

和血量相反,能量是向下取整的。

没有任何方式改变能量的增长速度与技能消耗,但依然有两个技能可以影响敌方能量:

  • EMP(人类,幽灵) ,范围内有能量的敌对单位减少 100 点能量;
  • 能量反蚀(星灵,高阶圣堂武士),清除敌对目标所有能量,并对其造成等量伤害。

临时性攻防提升

特定的技能也会影响伤害数据:

守护者之盾:

星灵机械哨兵的主动技能,展开一个范围为 4 的力场,范围内所有友军单位受到的远程伤害降低两点。守护者之盾属于临时的、有限制的防御提升。要注意的几点是:

  • 跟攻击单位的位置无关,只跟受伤害的单位是否在范围内有关;
  • 同样,无法防御“魔法攻击”,比如寡妇雷的哨兵导弹;
  • 自己也同样受益;
  • 对友方误伤也同样起效果;
  • 近战攻击不受减免,溅射伤害不受减免(未证实)
  • 蟑螂、刺蛇、宿主的蝗虫等,在与敌方贴脸攻击时,攻击动作会发生变化,属于近战,也不受减免

腐化:

腐化者主动技能,使目标在 30 秒内受到的伤害提升 20%。注意的点是:

  • 尽管腐化者是对空单位,但腐化技能也可以对地面单位释放;
  • 腐化后的伤害值是可能有小数点的,综合开篇讲的血量向上取整的特性,显示结果就是多次相同情况下的伤害值可能偏差 1 点;
  • 尽管它也属于技能,但并不直接产生伤害,而是依附于普通攻防,因此也受攻防升级影响;
  • 对技能伤害同样有加成,比如寡妇雷炸被腐化不朽伤害为 192 点。(未证实)

定点防御靶机:

铁鸦主动技能,在目标区域投放一个定点防御靶机,击落范围内所有向友方发射的弹道类攻击,每次防御消耗 10 点能量。防御机的工作原理是利用激光破坏飞向友方单位的弹道类攻击,包括人类导弹类攻击、星灵慢速弹道激光等等。注意点包括:

  • 与守护者之盾不同,无关攻击者的位置,甚至也无关友方位置,只要飞弹经过防御范围,定点防御靶机就有作用;
  • 与守护者之盾不同,靶机是直接免除某些类型的攻击,对不免的攻击则无影响,故不存在攻防值计算问题;
  • 与守护者之盾不同,靶机对友方误伤不防御;
  • 基于其工作原理,只对“有弹道、飞弹类”的远程攻击起作用,比如掠夺者、女妖、追猎者、凤凰,飞龙、腐化者,对瞬时远程攻击不起作用,比如机枪兵、不朽等。
  • 对航母的拦截机也有作用;
  • 同样基于其工作原理,雷神和落地维京的对地攻击也无法击落,只能击落雷神和维京的对空飞弹。
  • 所以靶机自身也是可以在不触发防御机制的情况下被击落的;
  • 对于多重攻击,每一重攻击都要消耗一份靶机能量;
  • 靶机能量回复速率比一般单位快,为每秒 1 点,故每存在 10 秒便可额外多击落一次弹道攻击;
  • 靶机属于建筑类型,工程站建筑护甲升级可以为靶机提供额外两点护甲,但它是轻甲,全星际唯一的轻甲建筑;
  • 因为是建筑,所以狙击、腐化、灵能风暴都无效;
  • 但你妈能量反蚀是有效的,一放一个准。50 血 200 能量初始还满能量的家伙……
  • 靶机在原理上属于攻击类,只不过攻击目标是弹道类子弹,所以工程站的研发项目“瞬时自动追踪”,也能让靶机的防御范围 +1,从 8 到 9。
  • 靶机的初始存在时间为 180 秒,最多可以防御 38 次攻击,可升级。升级后存在时间延长到 240 秒,至多防御 44 次攻击;
  • 可以被 SCV 修理,详见另一篇:《星际争霸2建造与修理详解》;
  • 幻像的攻击也会防御,一样消耗能量;
  • 攻防升级与靶机的防御能力无关,三攻子弹和零攻子弹一样防,所以越后期靶机减免的伤害越多,而守护者之盾则固定减伤 2 点,后期效果更弱;
  • 刺蛇、皇后等兵种在与敌方贴脸攻击时,属于近战,此时靶机不起作用
  • 多个靶机不会拦截同一发导弹,他们的防御能力总是累加的;
  • 特别注意:某个版本后,对巢虫领主也不起作用了;

结算顺序

参考以下事实:

  • 掠夺者,对重甲 20 点伤害;
  • 不朽者,重甲,拥有刚毅护盾,任何超过 10 点的伤害降低为 10 点,且站在守护者之盾范围内;
  • 掠夺者射出一枪,进入守护者之盾,对不朽造成 8 点伤害。

关于腐化,也有类似的事实:

  • 掠夺者,对重甲 20 点伤害;
  • 不朽者,重甲,拥有刚毅护盾,任何超过 10 点的伤害降低为 10 点,但处于被腐化状态,受伤害增加 20%;
  • 掠夺者射出一枪,对不朽造成 12 点伤害。

更复杂的:

  • 掠夺者,对重甲 20 点伤害,开兴奋剂增加 50% 攻速;
  • 不朽者,重甲,拥有刚毅护盾,任何超过 10 点的伤害降低为 10 点,但处于被腐化状态,受伤害增加 20%;
  • 附近的机械哨兵展开了守护者力场保护不朽者,所有的远程伤害减少 2 点;
  • 掠夺者射出一枪,对不朽造成 10 点伤害。

根据这一事实,我们得出一个伤害结算顺序的概念:

  • 伤害值都是通过顺序,在一个最基础的值上根据条件进行数值修正或数值替换;
  • 首先计算永久性攻防值(兵种属性决定基础数值),在此基础上进行技能性攻防修正(兵种技能影响最终数值);
  • 如果有多个永久性攻防值(兵种属性),先结算无附加条件的,再结算有附加条件的(护甲类型、兵种类型);
  • 如果有多个临时性攻防修正(兵种技能),先结算无附加条件的,再结算有附加条件的(远程、弹道);
  • 在以上四条确定的同一计算顺序内,先结算输出的伤害值(伤害别人的企图),再结算受到的伤害值(受伤害的企图);

比如上述例三:

  1. 首先计算永久性攻防值(兵种属性):掠夺者 10 点伤害,不朽者 0 盾防,伤害意图为 10 点;
  2. 因为不朽者护盾防御值为 0,因此受伤害意图变为 10-0 = 10 点;
  3. 因为掠夺者有两个永久性攻击值,其中 “对重甲 +10” 属于有条件数值,攻击数值修正为 20,防御为 0,伤害企图为 20 点;
  4. 因为不朽者没有针对远程攻击的有条件防御加成,因此受伤害图依然为 20-0 = 20 点;
  5. 判断掠夺者永久性攻击技能,有振荡弹,但对伤害数值无影响,因此伤害企图为 20+0 = 20 点;
  6. 判断不朽者永久性防御技能,有刚毅护盾,会产生效果,受伤害企图无视源伤害大小,强行修正为 10 点;
  7. 判断掠夺者临时性技能,有兴奋剂,但对伤害数值无影响,伤害企图依然为 10 点;
  8. 判断不朽者临时性技能,有两个,腐化和哨兵盾:
    • 首先结算无附加条件的腐化,受伤害企图修正为 10 x ( 1+20% ) = 12 点;
    • 再结算有附加条件的,哨兵盾只对 “远程攻击” 有效果,使得受到的远程伤害减少 2 点,受伤害企图修正为 10 点;
  9. 无其它条件,最后不朽受到 10 点伤害,进行盾数值、血量和护甲的计算。

如果结算时是先哨兵后腐化,那么不朽的每次伤害只有 (10-2) x 1.2 = 9.6 点,考虑到血/盾的数值向上取整,我们就会见到单次伤害为 9 点,而非 10 点了。

尽管未作测试,但可以大胆断言,在盾血边界的那次伤害上,星灵可以享受盾防御和护甲防御的双重减免,同时腐化也不会影响到转移到血量上的剩余伤害部分。因为在“伤害企图值→受伤害企图值”那次计算中,腐化的技能已经结算完毕。盾血边界的计算,其实是 “受伤害企图值” 与盾、血数值上的计算,而“受伤害企图值”本身已经包含了腐化的结算。否则就变成了一技能两次结算,属于 bug 了。也就是说三防 200 血 1 盾 4 护甲腐化不朽者,被三攻坦克轰了一炮以后,只也掉 7 滴血,而不会出现 (12-1) x 1.2 – 4 = 9.2 血这种复杂的情况。

通常来说 HTML 和 CSS 中引用图片都用的是 <img src=”…”> 和 url(…) 的引用办法。有时为了节约连接数,在诸如图标库等特殊用途 css 中,也会使用一张大图片通过 position 定位到不同位置的办法,来把所有图标放在同一张图片上。

不过还有一种办法是直接把图片通过 base64 编码以后写到文本中。对于非常静态化的需求,比如电子书、自制在线简历、email 投递、网络隐私安全病患者等等,或者各种原因在输入端只支持文本的场合,有时也是一种不错的选择。

这种办法其实很简单,就是把原来写 url 的位置替换成图片 base64 编码以后的文本。

比如我有一张图片,,把它用 base64 编码以后就成了一长串文本:(编译工具用百度一搜就行,在线的,本地的多得去了,在 Github 上还能搜到完全基于 JS 的。)

1
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b+AAAAAAAAAAAABCbCAgZG91YkBv4AAAAAAAAAAAAEJyZFRVbnRGI1JsdAAAAAAAAAAAAAAAAEJsZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRVbnRGI1B4bEBywAAAAAAAAAAACnZlY3RvckRhdGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAAAFBnUEMAAAAATGVmdFVudEYjUmx0AAAAAAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAAU2NsIFVudEYjUHJjQFkAAAAAAAAAAAAQY3JvcFdoZW5QcmludGluZ2Jvb2wAAAAADmNyb3BSZWN0Qm90dG9tbG9uZwAAAAAAAAAMY3JvcFJlY3RMZWZ0bG9uZwAAAAAAAAANY3JvcFJlY3RSaWdodGxvbmcAAAAAAAAAC2Nyb3BSZWN0VG9wbG9uZwAAAAAAOEJJTQPtAAAAAAAQASwAAAABAAIBLAAAAAEAAjhCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAAM9AAAABgAAAAAAAAAAAAAAMAAAADAAAAAEAGIAbwBhAHQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAA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ADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcFJpZ2h0cz0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3JpZ2h0cy8iIHhtcE1NOkRvY3VtZW50SUQ9InV1aWQ6RUNGQzc3Mjg4MDQxREMxMUJDNDVBODNDNjIyRTJGRTkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjU2RTNBMDhERjRERTQxMUI5OTJDQzc3NTY4MTA1MkUiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0idXVpZDpFQ0ZDNzcyODgwNDFEQzExQkM0NUE4M0M2MjJFMkZFOSIgeG1wOkNyZWF0ZURhdGU9IjIwMDctMDgtMDNUMTM6MDk6MjUrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDE0LTEwLTA3VDEzOjAxOjQzKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE0LTEwLTA3VDEzOjAxOjQzKzA4OjAwIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzIgV2luZG93cyIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6TGVnYWN5SVBUQ0RpZ2VzdD0iMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6RjU2RTNBMDhERjRERTQxMUI5OTJDQzc3NTY4MTA1MkUiIHN0RXZ0OndoZW49IjIwMTQtMTAtMDdUMTM6MDE6NDMrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSJ3Ij8+/+4ADkFkb2JlAGRAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQEBAQEBAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAMAAwAwERAAIRAQMRAf/dAAQABv/EAaIA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

这串文本很长,不过相比于图片本身的体积,其实并没有大多少。这种体积的变化详细涉及到信息论和压缩原理,这篇文章先不写了。

然后我们在长串文本前再添加一些说明文字,供浏览器识别:

1
data:image/jpg;base64,

然后就可以直接替换原 url 了,就像这样:

1
2
3
<img src="
data:image/jpg;base64,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b+AAAAAAAAAAAABCbCAgZG91YkBv4AAAAAAAAAAAAEJyZFRVbnRGI1JsdAAAAAAAAAAAAAAAAEJsZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRVbnRGI1B4bEBywAAAAAAAAAAACnZlY3RvckRhdGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAAAFBnUEMAAAAATGVmdFVudEYjUmx0AAAAAAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAAU2NsIFVudEYjUHJjQFkAAAAAAAAAAAAQY3JvcFdoZW5QcmludGluZ2Jvb2wAAAAADmNyb3BSZWN0Qm90dG9tbG9uZwAAAAAAAAAMY3JvcFJlY3RMZWZ0bG9uZwAAAAAAAAANY3JvcFJlY3RSaWdodGxvbmcAAAAAAAAAC2Nyb3BSZWN0VG9wbG9uZwAAAAAAOEJJTQPtAAAAAAAQASwAAAABAAIBLAAAAAEAAjhCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAAM9AAAABgAAAAAAAAAAAAAAMAAAADAAAAAEAGIAbwBhAHQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAA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ADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcFJpZ2h0cz0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3JpZ2h0cy8iIHhtcE1NOkRvY3VtZW50SUQ9InV1aWQ6RUNGQzc3Mjg4MDQxREMxMUJDNDVBODNDNjIyRTJGRTkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjU2RTNBMDhERjRERTQxMUI5OTJDQzc3NTY4MTA1MkUiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0idXVpZDpFQ0ZDNzcyODgwNDFEQzExQkM0NUE4M0M2MjJFMkZFOSIgeG1wOkNyZWF0ZURhdGU9IjIwMDctMDgtMDNUMTM6MDk6MjUrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDE0LTEwLTA3VDEzOjAxOjQzKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE0LTEwLTA3VDEzOjAxOjQzKzA4OjAwIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzIgV2luZG93cyIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6TGVnYWN5SVBUQ0RpZ2VzdD0iMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6RjU2RTNBMDhERjRERTQxMUI5OTJDQzc3NTY4MTA1MkUiIHN0RXZ0OndoZW49IjIwMTQtMTAtMDdUMTM6MDE6NDMrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSJ3Ij8+/+4ADkFkb2JlAGRAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQEBAQEBAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAMAAwAwERAAIRAQMRAf/dAAQABv/EAaIA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
">

编码头的标准格式是

1
data:[<mime type>][;charset=<charset>][;base64],<encoded data>

理论上方括号是可以省略的,同时也可以看到还有其它编码形式,比如base85、base16 等,尽管没有什么实际意义甚至有反效果。(比如有浏览器兼容性、超出合法字符区间等情况)。

好处与坏处:

  • 更新:保证网页上的重要图片不会加载失败。当 HTML 加载完毕或 CSS 加载完毕时,图片一定可以正常显示。不会出现 HTML+CSS 加载成功,但图片没有显示的问题。特别适合于类似评分星级、打标等功能。
  • 节约连接数:http 协议下,每个单独资源在客户端都呈现为一个独立文件(在服务器端部分是),都需要握手协议开销和传输开销,而使用 base64 以后,就变成了 “文件内部” 数据,不需要额外开销。而在呈现上没有变化。这在某网页有大量小文件的静态资源时尤其有用。但随着 cdn 的发展,这种情况又少下去了。
  • 图片过滤无效:有时候用户因为某些原因会屏蔽网页上的图片呈现,这些屏蔽方式通常都是通过匹配 html/css/js 中的资源路径实现的,但在 base64 编码下这种方式会无效。但相应的,基于服务器代理转码的浏览器(UC 之类通常是手机端浏览器),以前也无法转换,现在应该改进了吧。是好是坏看具体场景了。
  • 不方便编辑:这个主要出现在常用的文本编辑器里,在成熟的 IDE 环境中则不存在这种问题,鼠标移到 base64 图片上同样会有预览。有些文件编辑器也通过插件来解决类似问题。
  • 其它:呃…… 少量增加整个网页体积,等。

最后是 php 版的 base64 图片生成:

1
2
3
4
<?php
$img_file = file_get_contents("img/logo.jpg");
echo base64_encode($img_file);
?>

用的也是现成库,别的代码版本就不写了。

昨天下午,某银行信用卡给我打了半小时电话,推销他们的一项保险业务。一如所有的推销电话一样,最后都只能强行挂机,没办法礼貌地互相结束通话,唉,可怜那业务员。(ノへ ̄、)

这个业务很简单,每月交差不多 140来块钱,直接从信用卡上扣,全年 12 期,总长 5 年,可提前结束。价格据说是根据我的年龄、职业等测算出来的,每个人还不一样。小年青们会便宜一点,老头子们更贵一点。然后收益是什么呢,在业务员啰啰嗦嗦不断夸耀优点的情况下,我总结出来以下几项:

  1. 如果是疾病性住院,则只要住院,无视原因无理由赔付每天 ¥200,提供医院帐单复印件、身份证复印件、信用卡复印件即可。有 500 天上限。
  2. 如果是外伤性住院,则只要住院,无视原因无理由赔付每天 ¥400,提供医院帐单复印件、身份证复印件、信用卡复印件即可。有 500 天上限。
  3. 如果一年无赔付,则反还 25%。
  4. 小病小灾,不住院不算保险范围。

其实就是个无理由住院额外险,无论是天上掉流星砸到脚,或者被加班逼到内出血,反正只要躺医院了,就按价赔偿。……不知道自残算不算。( ̄△ ̄;)

然后我拒了。在电话录音说您是否确认现在通过语音确认开通时及时地拒了。

嗯,这个业务本身其实还可以,如果是我玩轮滑狂热的年代我还真就说不定买了,只不过在现在的境况下,核算了一下成本,基于我的逻辑,最后还是回绝掉了。

首先,其实要知道,保险其实永远是越买越亏的。从逻辑上说,保险是以集合众人的付出,给一些人的损失兜底。如果保险运营不需要成本,理论上对于一个人来说,整体的付出大约等于各种损失乘以机率以后的期望值。但实际上,考虑到保险还要支付销售提成、运营成本、赔付审核、股东分红、物业建设等等,对于一个保险客户而言,单纯考虑支出和损失期望,是肯定不合算的。只有考虑到对损失赋以一个额外的权重,也就是考虑到 “损失超出了你的承受能力” 的情况时,购买保险才是一个合算的行为。

换句通俗的话说,就是我明知道不出意外或者出点小意外都是亏的,出大意外,从概率乘以损失来说我还是亏的,但因为我实在承受不起大损失,万一呢?所以还是买点保险用小损失代替吧。比如汽车保险,其实出事的机率,乘以出事要赔的钱,整体而言还是比汽车保费低,但因为真要出点什么事几十万的钱还是会对个人造成极大的甚至是不能承受的打击,那就还是买吧。

我们举另外一个极端的例子。大家在生活中经常会丢失钢磞儿,几毛一块的,积累下来也有不少,比如每年少则十块,多则一百。现在我推出一项保险,“钢磞丢失险”,每月交五块钱,只要丢钢磞就给你等额赔付。假如不考虑实际执行难度,就假设一点不麻烦,说赔就赔,也没有骗保,你会买么?

如果你说,不买,丢了就丢了吧,说不定丢的还没保险费多,只丢钢磞再多也丢不成穷光蛋的。相信大家都完全能理解这种想法。

事实上,大部分人从保险得到的赔付都是不及保费支出的。也就是说,丢的确实不及保费多的。你每月可能丢一个,可能丢五个,可能丢十个,但参保了就相当于稳定丢五个了。全年一统计,你最多的一个月丢了 8 个,有两个月没丢,大多丢三四个,你就发现自己明显赔了。明年就不必参保了。

但假如我们加一个额外限制,『在丢到某一数量以后,这个巨大损失个人承担不了』。比如开开国国王规定如果国民某个月丢硬币损失超过 10 块要杀头。那显然这份保险就变成了买命钱了,五块?太便宜了。

再举一个极端例子。如果你的全部收入全部交了保险,不管你当前交了多少,付给你的保费永远是固定值。过一两年你肯定就会发现亏大了,还不如自己存钱合算。你觉得呢?

也就是说,保险主要针对的是你自己不能承受的重大损失,对于一些承受无压力的小损失,完全可以考虑自行承担,并不一定需要保险,当然也不是不可以考虑,还是看你的承受能力和损失厌恶度。

所以土豪们是不需要常规保险的。是嘛,汽车三方险最多也就到一百万,对于豪车还是杯水车薪,基本都靠土豪自己兜。

其次,这个险号称最长可达 500 天,20 万上限。其实吧……那是住院啊,谁能住院 500 天啊。就算 5 年 500 天,那也是每年住院三个多月啊……这种情况下,医疗保险、扩展医疗保险,甚至是亲朋好友都比这个保险靠谱。当然,两险是不冲突可以同时用的,但归根结底,这个保险反而更像是一种锦上添花而不是真正可以兜底保障的险种。在收益上其实比不上按比例赔付的常规保险类。

那么如何核算支付与收益呢?很简单,每月不是扣 140 来块钱么?全年 1700 块,每年需要住 5-8 天院才能收回保费。这就是一个比较合适的可比较尺度了,就算出了轻伤车祸,在北京这种常规情况下也很难住够五天院,大多都会让你回家休养。而如果重伤到需要超过 8 天,无差别的每天 200-400 也是杯水车薪,我需要更强的保险覆盖。

只有像我学生时代那样,经常没事出个小伤,进医院擦个药打个板,医生也好说话,总能腾出闲天住院的那种状态,才比较合算。而这个保险又是要审核职业、收入等等因素的,想找他们的 “优质客户”,估计在我学生年代就是劣质客户吧。如果我是他们的“优质客户”,那么他们基本就不是我的“优质保险”。

在保险收益预估时,不能以最高保障额度计算,而是应该以个人实际和保险本身赔付方式决定的“常规”意外预期计算。保险公司算得比你精得多,但只要你从“可收回保费所需要的意外程度”进行反向计算,就比较容易得到可感知可衡量的收益标准了。

再次,当然还有心理上的因素,人们对小概率事件的估计总是偏离常规的,我也是。唯一常见例外的也就是车险了,人们还是很认可驾车意外的概率的。

人们对幸运的小概率总是高估,要不然也没有人大把大把地买彩票了。——你可以认为买小额是图个别的心理幸福感之类的,可幸福感不也是心理因素么?

而对厄运的小概率却偏向于低估,就好比真的计算车祸概率,或大或小几十人里也能摊上一个,相当于一个班级、一个小公司、一个小团体中间总能遇上一项,但每个人都不认为是自己。我也是。作为理性青年,在作必要决策时会考虑到这种情况,而在改善性决策时,这种心理就又会占上风了。就好比我如果需要自费购买人生意外、大病医疗院,和需要自费购买这种改善性医疗险,在决策时的“意外概率”是不一样的……

最后,我非常讨厌这种持续性延后性的扣款,利用的又是人们的遗忘心理和小额支付决策时的心理偏差。个人喜恶,冷暖自知。

哦,在这里还有一个奇葩的部分,就是反还 25%。一开始我也被绕进去了。要注意这个反还只有在你不产生保费的情况下会出现,被推销员包装成了“实际保费仅 110几元”。

别傻了,如果不出意外没有保险赔偿,多少钱都是白付给保险公司的,保险成本还是应该按出事的计算。换句话说,这个只有银行在核算净收入时有影响,对你核算出意外时的成本与收益是完全没有任何关系的。因为这项条款只有在“不出意外”的情况下才生效,而“不出意外”你拿不到赔付,多少钱都是白送给银行。

而且反过来想想,如果真出了事要住一两天院,你如果去索保,虽然能拿到 ¥200-400,却失去了返还部分近 ¥400 块。这反而会导致你即使真的入院,在两天以内的也不会去找银行赔付,银行照样是净赚。这还真不如直接把保费降一点好呢。这跟车险动态调整保费还不一样,车险意外发生的概率和个人的驾车行为安全意识有很大相关性,而对于住院而言,个人可控制的因素则少很多。另一方面,车险是下一年费用变化,也不涉及历史费用的返还,并且各公司还通用。两者的差距巨大,从这个策略中我更多地看见的是恶劣的算计,而不是对客户的善意。

其实话说回来,如果真的到了个人不能承受的意外,通常一个家庭也就完了。目前看见的保险制度,绝大部分也都有个吝啬的上限,或者有严苛的赔付标准。做得到锦上添花,却做不到雪中送炭。只有市场化的车险好点,医疗保险也只能说呵呵。农业险,包括农业期货,以我外行的角度看来似乎也不错。只是不知道农民兄弟们,身在此间多有经验,是会说哈哈,还是呵呵。

今天刚看了知乎一篇文章,里面是从业人员吐槽人民没有保险意识。

我呸。

少几个推销,少几份算计,少几段夸张措辞,多来点真货。

Adobe 公司宣布研发部门撤离中国,仅保留销售部门。不过这篇写的不是新闻评论。新闻只是个引子,想写的……可以认为是评论的评论吧。

老有人以 Adobe 各系东西卖得太贵为借口,总说如果能减个零或者减两个零就好了。

……别傻了,好像卖几十块他们就真会买似的。

定价策略这东西,很复杂,但也很简单。简单在于,最后的收益无非是售价乘以销量减掉成本,让收益最大化就行了。而复杂则在于,定价到底在多大程度上会影响销量,进而影响到最大收益,则是要靠商业智慧与决断的。Adobe 的全系列产品不是免费(Flash、Adobe Reader、Creative Suite 2),就是死贵,看起来似乎不合理,但实际上这个定价差不多已经是最优的策略了。

我们通常说的薄利多销,其实并不一定正确 。这句话有一个先验的假设,就是薄利会引发销量的成倍增加。这在传统实物生产中,在某些场景下可能是正确的。在这个成语产生的年代,大部分商品都是小规模作坊式生产的生活必须品。这使得第一对顾客而言,生活必需品是一定需要经常购买的,自然会在过得去的情况下选择更便宜的。第二是对具体的某个商家而言,市场是近乎无穷大的,更便宜意味着有更多顾客会选择他家的商品,只要产量跟得上,他总能卖出去。第三是,更大的产量意味着基于规模效应,单件成本也更低,依然可以腾出足够的利润空间。

也就是在个人作坊向产业规模化集约化发生的过程中,某个商家通过降低售价,一方面扩展自己的市场范围,一方面惠福顾客。这确实是经济学意义上,也是生活意义上的社会改善。……除了那些被竞争挤倒破产的其它商家以外。

但这几点在 Adobe 身上都不存在。

首先,其实对大部分人而言,Adobe 系列软件都称不上是必须品级别的软件,它的市场并没有大家想像的那么大,相反,是个很小的市场。

并不是因为你在家用了盗版 Photoshop,你就也能被计算为市场份额之一。比如假如苹果手机也能盗版,五块一个,那么大街上肯定差不多也是人人都拿着肾6+,可你能就此认为苹果的市场是 99.99% 么?

不是的,因为定价在那里,苹果的市场就是 3 成左右,这是他利润最大化的定价方式。再降,它的市场就算扩大,也比较有限,还不如降价造成已占市场收入减少的损益大。Adobe 软件实际上是“生产力软件”,简单地说,是拿来做生产的工具之一。影楼、设计所、出版业,这些才是 Adobe 家软件瞄准的市场。对于这些市场的用户而言,几乎是固定而没有选择的。反过来就是说,Adobe 的市场真没有大家想像的那么大,那些鼓吹如果便宜就买的,最后只有两种选择,用盗版,或者不用。他们是不会成为 Adobe 家正版用户的。对真正的市场用户来说,Adobe 家的软件真不贵,几千块钱,还没一个相机镜头贵,没一次书籍制版费贵,没一次比稿的路费贵,真心不贵的。

其次,它已经是市场上的王者了,占据了几乎所有的中高端出版软件市场,实际上并不存在可以被挤倒的“其它商家”以让他成倍地扩大市场份额。

有句话是说,所有你觉得 Photoshop 不好用的功能,都是因为你不会用。——这句话依然阐述的是同一个事实:大部分人并不需要 Photoshop 这样级别的软件,没一点臂力,牛刀使起来还不如指甲刀。而另一个事实则是,在针对的市场里 Adobe 则是毫无疑问的王者,他已经把能拿到的市场差不多都拿到了。

最后,软件成本几乎完全是固定成本,少量边际成本也主要出在营销费用、光盘、下载带宽这类上面。也就是说,单纯的销量带不来规模化导致的成本节约。软件的特殊就在于,它的利润完全就等于销量乘以单份售价,那么在市场容量固定,市场份额近乎百分百的情况下,降低售价只能导致更多的损失。你以为¥5000降到¥50,销量就能提升 100 倍?真要降到 ¥50,那帮人依然会抱怨说别的软件都是免费了,为什么 Adobe 要收费,然后依然用着他们的免费盗版。WPS 就是个活生生的例子,坚持到最后也只能靠免费广告流氓手段来推动。

额外一点,如果 Adobe 真在中国降价,你打算让别的国家市场如何推动?Adobe 是序列号授权,并不是云服务,几乎很难以国别定出悬殊的价格差。如果真这样,最后结果只会导致其它国家的用户通过互联网购买最便宜国家的序列号。只会导致 Adobe 的损失更大。现在它退出一个赚不到钱的国家,顶多通过不出对应的语言版本就可以解决(其实也解决不了,因为新加坡用的也是简体中文)。他也想推过云服务,估计也是想做差别定价(比如暴雪就给中国大陆单独架服务器单独定价,其它国家通过信用卡等方式差别定价),但显然正版用户们并不太接受。

无奈。

软件盗版已经是个老生长谈的话题了,而且观点已经趋向一致,即如果没有那么严重的盗版,中国的软件环境和互联网环境也不至于像现在这么恶劣。盗版伤害的不光是大型软件厂家,更是直接导致中国软件梯度被抹杀,没有了中小企业的生存空间。在这种情况下,依然有那么多人把 Adobe 给出的 “收益不及预期” 的原因,归罪到 Adobe 定价太贵上面,有时候真觉得刁民两字,用得不假。

题外话:即使 WPS 目前已经如此,我依然尊敬珠海 WPS 小组,稻壳儿是我在软件相关费用中第三大的一项,仅次于山口山和 App Store。

chocolatey 是 Windows 下的包管理器,类似于 Linux 下的 apt,mac 下的 homebrew。

没错,windows 下的。

官方网站是 http://chocolatey.org/ ,已经写在标题里了。

虽然其实大部分可以 choco install 的包都是像 notepad++、Filezilla、Putty 等本身就可以下载安装包或者本身就是绿色软件,但也许也有一些像 Python、Ruby、Nodejs 之类让从 Linux/Mac 转过来的程序员们倍感亲切的软件包。不过要注意的是保持网络畅通,也就是说你还是需要一个 VPN,而不像 linux 那样可以方便地寻找到镜像源。

说实在的我在用了一段时间以后觉得有点行为艺术……o( ̄ε ̄*),其实最大原因是 CMD 窗口本身并不能提供太多的功能,不像 Linux/Mac 那样通过 ln 可以自定义命令,添加 Path 也比 linux 麻烦。

在图形操作系统下,用命令行去管理一大堆本身就有安装包有图形界面,可以双击图标调用关联程序打开,这些关联程序也大多有图形界面,实在有点违和。

所以最后我的结论是,如果你非要在 Windows 下尝试一下包管理器,Chocolatey 是个不错的选择。

安装方法:用管理员权限打开 CMD,输入以下字符(CMD 窗口的粘贴操作是 Alt+Space→E→P)

1
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

很有可能会开始下载一个 .msu 的安装包,应该是 PowerShell,安装完以后重启系统,用管理员权限打开 CMD,输入以下字符(CMD 窗口的粘贴操作是 Alt+Space→E→P)

1
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

…… 没错我写了两遍,实践证明确实需要两遍……ㄟ( ▔, ▔ )ㄏ

如果已经安装了 PowerShell,可以在 PS 里输入以下命令:

1
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

恭喜你,蛋疼去吧。

这段时间来,我逐渐认识到一个道理。

要做好一件事情,最不能的就是藏着掖着。曝晒在阳光下,让众人评判,让有兴趣的人一起努力,才是最好的办法。靠着私下时有时无的业余时间,没法快速推进。

讲道理都会,真落到自己身上,还是要花费许多时光去接受。即使是现在,也还是有很多担忧。

如果招募连一个回应都没有怎办?如果主意被别人抄走了怎办?付出了辛苦却回报不了大家怎办?如果做不成辜负了大家怎办?如果理解不同争执冲突怎办?如果做得不够完美到不了自己的预期怎办?如果期望太高伤害了大家怎办?如果最后连朋友都做不成怎办?……

有太多不能保证的东西,让人害怕承诺。我总能侃谈构思想法,却每每在盈利模式前语塞。并不是因为没有想过,只是在通往终点的路上有太多太多可能的变数,让我自己都觉得吐出口的,都会变成谎言。

你要知道,有 99% 的项目都会以失败告终,我只能保证我会坚持到最后。

所以请原谅我,然后请帮助我,最后,请再原谅我。我甚至不能保证你们的劳动会有相应的物质金钱回报,我只能说,希望一起来做一件我自觉有趣、有希望、也许还有那么一点点前途的事情。我想靠这个就把你们骗上船,希望能成功。

关于现状:

http://cosjiaoyi.com 现在版本
http://bs.cosjiaoyi.com 未上线版本的 HTML+CSS 原型,还在一点点添加。

使用 Github 管理代码库(私有库),使用 trello 管理任务,使用 SSH 公私钥登录服务器。

目前是淡季,每月大约 5000 PV,高峰也曾到过 600pv/d。新访:回访为 7:3。对一个只有微博转发简单推广,无抽奖无大V互动无漫展现场挂易拉宝的个人小站来说,我觉得已经不错了。这个网站真的是有人在用的,我们也已经真的小小做到了一些事情。这已让我欣喜不已,因此也更加迫不及待。

现在在做的是 Cosplay 服装与周边二手信息的采集与搜索。整体定位是 cos 同好者手边的一个“好用的工具”。作为工具,不需要什么消磨时间的特性,只要需要时被想起就够了。

就像见到雨雪想起的折伞,见到脑残想起的板砖。

我需要后端、前端、设计师、推广:

  1. 你喜欢动漫,现在还喜欢。或者你喜欢我,ヽ(✿゚▽゚)ノ,也行。
  2. python、node.js、php,MySQL,Ubuntu。网站已备案,个人。暂时没注册公司,没有必要,但也不是问题。
  3. 我只会完成基本的 HTML+CSS,速度很慢,也不会 js 和各种框架。我需要前端。
  4. 产品经理也是我。动漫爱好者,理科生,少年时不学无术却想改变世界,现在努力学习只希望能做成一样事情。选择 Cosplay 二手搜索只是切入点,最终梦想不止于此,希望能看它慢慢递进。
  5. 算法常用伪代码,有时也用文档。用 HTML+CSS 写原型,只因无前端。常用 Axure 和 Sketch,但最喜欢还是纸与笔。
  6. 绘画是我曾满心向往而后最终放弃的,所以我明白完成设计稿的辛苦。
  7. 穷是推广的大敌。我们暂时打不过敌人,战略性躲着走。( ̄△ ̄;) 但漫展门票钱传单印刷钱还是有的。
  8. 我花了很多时间学这学那,最终也只是为了去理解别人编码画稿伏案写作的困难与辛苦。而很多人的才能我甚至无法想像,只能仰仗他们的自荐。我相信奇遇,希望你也是。

关于时间安排:

  • 希望你一周有四小时的闲余时间想找事打发,考虑到沟通不畅、理解有误、bug 返工等意外,可能会再占用一周四个小时的生活时间。也就是,预计四小时,能接受极限八小时。
  • 当然,不是每个任务都能拆得那么细,很多还是需要几个周期才能完成。
  • 因为是业余项目,我们一周的周期会从周六开始。
  • 我们都希望进度尽可能快,但也请接受松散业余小团体的各种意外与延误。
  • 进入随意,退出随意,请告诉一声。如果你已经接了一个任务但有急事没时间做也没关系,希望你不介意我把同一个任务再请别人来做。
  • 即使失联几个月,依旧欢迎随时回归。如果不好意思,暗示我一下,我来个喜迎苏武。

交流方式:

主要是 QQ 群交流。之前需要实时语音时,会在 YY 开房间。对的,就是上市公司欢聚时代的里面有好多美女妹子半夜不睡觉卖萌吼歌的著名语音视频聊天工具 YY ——当然,我们不需要视频。不过 YY 用得真的很少,不装也没事,我会打电话给你。

每两周周日晚聚餐一次,聊聊近况,我买单。这个属于每周四小时的部分。也就是说,如果你时间有限,请先安排给聚餐。

每隔一周,我都为找好吃的店头痛不已。这句话的意思是地点每次都会变,不是说一定有多好吃。

如果你不在北京,我会在幸运的日子去找你,无论你在奥兹国,还是在永无岛。

关于回报

“我希望你能为我白干活,还不损害我们的交情,也没法给什么对结果的承诺。”

居然胆敢真的提出这样的要求,实在还是惶恐忐忑,纠结不安。

希望读到这文字的每一个你,都能给我一个机会,让我彻彻底底地忽悠你一次。(* ̄3 ̄)╭ 这样,也许你会想着“反正闲着也是闲着,听着还算靠谱,干吧”。如果你觉得累了,决定彻底退出以前,也麻烦务必再让我忽悠一次,也许就能多坚持两周。

说不定呢,谁知道呢,阿里都搞出史上最大 IPO 了。

但还是希望你能把它当成是像同好社团一样的玩艺儿。我们会有贡献名单,会有定期的聚餐。更重要的是,会有偶而打开看看,咦,现在做得不错了的小小感叹。这样的微小的愉悦,我想我还是能坚持着保证的。当然,万一真的搞大了,自然会尽量让大家更满意。只是在我自己也看不到终点时,还是诚实地说,但尽其事,莫问前程吧。

每个想做一些事情的人都必须有自己的忽悠风格,我把我的风格称之为“诚实的忽悠”,希望你能上当。

我曾发起过一些公益性项目,大多惨淡收场,但也偶有成功。

虽然这次不算公益,但还是希望运气也能不错。

上船吧,水手。

联系方式

开开

企鹅:151493994

微信:kaikaiiiiiii

## 自适应的水平垂直居中

旅行商人罗伦斯在马车货台上的麦束堆里,发现沉睡中的少女——自称是丰收之神赫萝的美丽少女,有着狼的耳朵及尾巴。

「虽然奴家长久以来被尊为神,不过,奴家就是奴家,奴家是赫萝。」

相比于水平居中用 margin:auto; 的简便,CSS 没有直接的垂直居中属性,必须通过各种诡异的技巧去实现,确实让人很头疼。以上算是一种实现方式,核心的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<style type="text/css">
.outer {
text-align: center;
background: #b9f9ff;
height: 300px;
}
.outer:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.inner {
display: inline-block;
width: 300px;
vertical-align: middle;
background: #fffdc6;
}
</style>

<div class="outer">
<div class="inner" >
<p>水平垂直居中</p>
</div>
</div>

这段代码中,最重要的是 .outer:before 这个伪元素。它起到了连接内外元素以及垂直对齐的作用。

需要明白的是,对一个 div 而言,它的伪元素会放在这个 div 包含的任何内容元素的前面,默认为 inline-block 元素(即“行内元素”或者“内联元素”)。示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<style type="text/css">
.outer {
background: #b9f9ff;
height: 120px;
width: 300px;
margin: auto;
}
.outer:before {
content: ':before 伪元素';
border: 1px solid;
}
</style>

<div class="outer">元素内容</div>

执行结果:

元素内容

当元素内容为其它元素,尤其是块级元素时,则有内容的 :before 会在最顶上。

<p>元素块级内容</p>

再强调一遍,:before 其实是一个元素的子元素,永远排在其它实际子元素的前面,比如:

1
2
3
4
5
6
7
8
9
10
11
12
<style type="text/css">
p {
border: 1px solid;
}
p:before {
content: ':before';
background:#fffdc6;
color: #f00;
}
</style>

<p class="special">是特殊的子元素</p>

的实际执行效果如下:

是特殊的子元素

可以看到,对于 p 元素添加的 border,连 :before 这段文字也被包含在内。

现在再回头来看原始代码,如果把 :before 的部分修改一下,给 :before 元素加个边框,修改内容,使得识别更简单:

1
2
3
4
5
6
7
8

.outer:before {
content: 'B';
border: 1px solid;
display: inline-block;
height: 100%;
vertical-align: middle;
}
垂直居中
这样这段代码的原理就非常清楚了。首先,:before 伪元素和内部元素(通过 display:inline-block 设置为行内元素)共同构成了“一行文字”。其次,所有的行内元素都利用 vertical-align:middle 进行了垂直居中对齐。最后,再设置 :before 的高度使得它上下都顶到父元素的边框。这样,同一”行”内的其它元素在视觉就都相对父元素垂直居中了。其实它们在逻辑上真正对齐的对象是 :before。而 :before 自己,则被“卡”到了正中间的位置。

最后,由于 :before 在没有实际内容(通常用 ” ” 空格填充 content 属性)时其实也有宽度,所以在父元素上使用针对文本的 text-align: center; 虽然可以把左右居中也一起做掉。不过还是用常规的 margin:auto 更精确一点。解决办法是对 :after 伪元素也设置 content:” “。

PS:因为 ie6 不支持伪元素,所以……要不还是用 table 吧。

icon ヾ(^▽^o)+

特别喜欢这个微信表情包,然后就从微信安装包里弄出来了。么么的英文名叫 monmon,monster 的 mon。这是官方表情包解压出来时的文件夹名字。还有,难道只有我一个人注意到,流汗那张,么么拿直升机其实是拿反了?风是往反方向吹的。

一开始觉得,这个粉红色小恐龙是个挺女性化的表情包,可是看得多了,忽然觉得这个小哥斯拉很孤单,非常孤独。

没人陪伴,全套表情都是它在孤独地自娱自乐。

想拥抱时,只有摩天大楼,看它紧紧抱着,脸一蹭一蹭,小嘴撅起,很用力的样子,那是得有多孤独;好玩的,是跑大桥上找两辆车玩对撞,一如小时候被关在家里的独子,围着满地的玩具一边哭一边告诉自己这些够玩了;它甚至还有一个专门的表情,叫作“自己玩”,这……无语言说的孤单,直让人心中一揪。

天变冷了,别的表情包里,好冷的图案都是与亲朋的温暖相依,而它只能围着围巾戴上手套,给自己一个用力的环抱;在生病虚弱时,也只能自己裹着棉被含着温度计默默地忍受,有谁会去照看它?

它看起来无忧无虑,那真是不懂有朋友陪伴时心中的温暖。或者其实它懂,只是既不能他解,就只好孤单自解。它把所有想要的温暖,都寄托在周围的环境中,寄付在人类的创造物中,如此,大概能缓解一些它的孤单。

可是人类会不会因为它的破坏行为而攻击它逼迫它离开,大概是一定会的吧。真的是难以想像,最后当它被无数武器攻击而被迫离开时,得有怎样的泪水和委屈。连最后那点自娱自乐的场所,都不被允许拥有。

我叙述这些,是因为这些都是童年的孤单。在一个人成长的过程中,太多东西在不经意间失去,或者是从未拥有过。孩子的心灵并不是感受不到,只是不懂得怎么去叙说痛苦,每每回忆起那些片段,总是泪满盈眶。

只希望么么不要长大,大概能减轻一些它的痛苦,无心无肺地坚强着。

抱紧 好崇拜 不会吧 泪流成河
抱紧 好崇拜 不会吧 泪流成河
流汗 发呆 自己玩 开心
流汗 发呆 自己玩 开心
晕倒 嘤嘤 怒吼 好冷
晕倒 嘤嘤 怒吼 好冷
飞吻 真好玩 呼呼 虚弱
飞吻 真好玩 呼呼 虚弱

我在网上查了不少时间,但一直找不到这个套图的作者是谁。也找不到相关的版权出处,或者更多的衍生作品、产品等。我想,把系列作品免费提供给微信表情,通常也是希望有一定影响力以后,通过其它相关衍生品赚钱吧,如果有谁知道,请告诉我。

http://cosjiaoyi.com 是个针对 cosplay 交易信息的搜索引擎,目前基本完成了对新浪微博特定信息的采集和入库,以及基于拼接 mysql 查询语句的搜索功能。

接下来还有很多要做的事情,包括扩展采集来源、改善垃圾信息过滤、优化前端等工作。不过今天先来讲一下打算做的自制分词算法。

对于动漫这一特定领域,很多常规的分词算法没有多大意义了。因为动漫圈存在大量的仅仅因为“好玩”而产生的各种昵称、诡称、简称。比如 “身陷” 指的是衣服的尺码,包括身高、三围等数据;比如 “穹妹” 指的是动画《缘之空》中的女主角兼主角他妹;比如 “面交” 当然是指当面交易的简称;比如 “炮萝” “秀萝” “叽萝” “咩萝” “丐萝” 都是网游剑网三里的职业人物角色的简称,哦,剑三又别称 “基三”,等等等等……还有一大现象是中英文数字合并成为一个词汇,比如 “PO 主”。另外,又因为拼音输入法的原因,会出现“身限”=“身陷” 等现象。由于本来这些词汇也就是圈子生造词,也难以适用词汇纠错的方法。

wordsegment普通分词算法结果

对于业务场景而言,这里面的很多词汇都是没有多大意义的。而“黑猫”、“弹丸”、“小天使”之类的词能成为高频词,也仅仅是因为它们更接近于“普通词汇”,可以被常规的分词算法认出来。而剑三当中的 “X 萝” 系列,甚至剑三这个词汇本身,都因为被分词算法切分,而没有进入这个图表中。

当然,技术上来说,只要有合理的分词词库,辅以相应的参数调整,还是可以做出一套适用于动漫分词的,但考虑到分词算法往往有几百个核心词汇、几千个附加词汇,每个词汇还都有词性标注,想想就算了……

在之前没考虑过这个问题,一是因为没有实际的业务数据积累,其实也没有考虑到这个问题,经过一段时间的推广和数据积累,现在可以研究了。二是因为对于 mySQL 的 like %…% 语法,尽管效率不高,但在目前的场景下,也没有遭受到多少压力。三是因为,呃,忙,呃,之前没时间做,呃,之后其实也不一定有时间做……

那简易分词打算怎么做呢?

现阶段的核心目的,还是在尽可能减少时间的前提下,能正确理解用户输入的“穹妹旗袍” 是指 “穹妹”+“旗袍”,这两个词汇不一定需要放在一起,只要在同一条微博中出现即可。

  1. 只考虑对 QueryRequest 的 wordstring 进行处理,而不考虑入库数据。内部查询在没有遇到性能问题前,依然使用 like %…%。目的仅仅是为了正确理解用户输入的查询,不至于因为用户输入“剑三的炮萝” 因为无法整串匹配到而搜不到结果,这种情况下应当可以正确处理为“剑三”+“炮萝”
  2. 只分析已经记录在服务器的 SearchQuery 表,不考虑对正文文本的分析。
  3. 和普通分词一样,还是基于词汇表,以及替代词汇表。先考虑分词,再考虑戳憋字。
  4. 基于业务,其实有大量的词汇是不需要的,比如“小天使”、“帮扩”等。对于用户而言,进入到本网站,场景就是搜索需要的东西,因而都是以具像物名词为主。没人会在搜索框里填 “小天使”、“随便” 这类词汇。甚至 “二手” 这个词都基本不会出现。

所以简易规则如下,可以覆盖 99% 的实际需求,计算量很小。

  1. 先对 querystring 根据 devide-word-list 进行切分,devide-word-list 包括 “ ”(半角空格)、“ ”(全角空格)、“的”,可能还会添加。但注意,没有“和”。因为在动漫中,“和”字会经常作为成词字或者人物姓名字出现,不能定义为分隔符。“日和” “和服” 等。由于并不是真的基于语义的分词,所以无法判断是成词字还是分隔字,根据历史搜索统计,只有 4% 的“和”是分隔词,交给用户自己调整没有问题。由于 devide-word-list 的数据量非常少,添加也很谨慎,所以可以直接写进代码里。
  2. 对结果的 querystring[] 根据 known-word-list,切分为 已知词块 和 未知词块 的数组。known-word-list 的生成办法下述。
  3. 对于未知词块,根据词块长度,反复循环,进行简单切分,直到最细:
    • 词块中有英文串的,当英文串字母小于等于两个时,视为一个汉字,不切分。
    • 当英文串大于两个汉字的,视为一个词,对其前后切分,分为三段。
    • 当有数字现出时,视为一个词,对其前后切分,分为三段。
    • 对大于等于四字的词块,直接按两个字一词进行切分。(注意之前把 1/2 个英文字母视作一个汉字,这里和中文等同视之)。
  4. 将结果的 querystring[] 数组,按每词之间 and 关系,对数据库进行查询。

比如:求黑子的篮球的火神大我红毛 私信 po 我。

  1. 变为 [求黑子,篮球,火神大我红毛,私信 po 我] (“的”和“空格”为分隔词)
  2. 变为 [求,黑子,篮球,火神大我红,毛,私信 po 我](“求”和“毛”为定义的已知词。
  3. 变为 [求,黑子,篮球,火神,大我,红,毛,私信,po 我](“po”视为一个汉字)
  4. 实际 Search Request 即 求+黑子+篮球+火神+大我+红+毛+私信+po 我

当然,通常没有这么长的需求,更多的是如下的:

剑三定国炮萝 160 包邮

  1. 还是 [剑三定国炮萝 160 包邮],因为没有分隔。
  2. [剑三,定国炮萝 160,包邮],剑三和包邮应该会加作已知词。
  3. [剑三,定国炮萝,160,包邮],160 是数字单独成词。
  4. [剑三,定国,炮萝,160,包邮],“定国炮萝” 四字切分为两字两字。这就是最后的搜索请求词组了。

当然,在这种规则下,“雪露女武神”,会变成 “雪露”、“女武”、“神”,但又有什么关系呢,如果一个词汇真的必须是三字词,我使用两字“女武”+一字“神”,依然可以搜到库中的正确结果,这就足够了。

接下来说说怎么做已知词汇表。

  1. 人工整理,优先满足历史搜索词汇表。
  2. 暴力分词法:
    1. 直接把采集数据的正文部分全部提取。
    2. 把空格串、数字串、大于两字的英文串、符号串、链接地址、转发标志、“的” 等都视为分隔符替换掉,形成最初的文本块。
    3. 暴力地把所有文本块全部循环切分成两字一组,然后统计相同词汇并排序。注意是循环切分,比如“小天使”块应当切分成“小天”和“天使” 两部分。
    4. 再暴力地把所有文本块全部切分成三字一组,然后统计相同词汇并排序。
    5. 人工筛选排序最前的 1000 组词汇,足够了。

这个当然也有缺点,但在具体的场景下也已经够用了。动漫词汇尽管创意繁多,但基于交流之用,最常用的词汇还是排名比较靠前的。再通过人工筛选过滤掉通用但无用的词汇,就可以获得有效的 know-word-list 了。这种暴力切分法并不是我第一个用,http://www.guokr.com/blog/76814/ 这篇文章就讲到了用暴力切分法去切分古文词汇。其实还是挺实用的,毕竟我这里最后有个人工筛选过程。

====================下面是严肃的分割线=====================

其实中文分语无非两个部分:

  1. 句子匹配已登录词时,多种匹配方式如何选取最优?
  2. 未登录词如何鉴别词性?这中间又细分为如何通过大量文本收录未登录词,转为已登录词;以及在某段文本中确切出现的未登录词,如何进行处理两种情况。

而以上方案,按分词原则来看,其实都有些反其道而行:

  • 故意适当缩小已登录词,相对扩大未登录词范围。——这个是由业务实际情况经取舍后决定的。确实业务中只需要登录掉大部分 “专属通用词” 即可达到需要的效果。
  • 未登录词一律视为双字词。——这个是实际统计结果后决定的。
  • 把输入的正确性,以及由此导致的结果的正确性,责任全部交给用户自己去解决。——也是业务实际,以及以上两项得到的。

这些简化的前提,最重要的一点在于,Cos 交易酱并不需要真的去处理分词以后的结果,只需要确保分词结果能正确地,范围合适地在库中搜索到用户需要的数据即可。

COS 酱的核心功能是促成 cosplay 交易信息的交换流通,所以对信息的采集、整理和优化是最重要的部分。

经过一段时间的数据积累,目前数据库中已有 60000 多余条微博数据,过滤掉的垃圾信息已经有 20000 多条。我们使用最简单的规则过滤掉了三分之一的无用信息,这些信息绝大部分来自于机器控制的僵尸帐号微博。但目前而言,过滤完的信息依然有不少可以定义为重复、垃圾的信息,所以接下来准备对过滤规则进行一些改进。

1. 微博中有“微话题主持人”这样一种角色,我完全不知道有什么存在意义。他们做的唯一的工作就是把同话题下大量的微博重新转发一下,并在转发时再次添加同一个话题,比如 #cos 二手#。由于本站对微博采集就是基于话题、关键词等方式进行的。因而这些无用的微博也会被搜索到。接下来打算通过帐号黑名单方式过滤这一类需求。

2. 热门微博的多次转发。在最初设计这个网站时,考虑过是否采集转发的,最后确定是包括转发也采集。因为存在二手信息发布者通过转发微博的方式提供一些补充信息,比如 “xx 已经出售,还剩 yy、zz” 等。但当初考虑不周的是,某些粉丝众多的红人 cos 的微博存在大量转发,会导致采集到的数据也出现 “刷屏”。另一种是专业转发号在某一时段大量转发,也会出现类似的情况。基于此,接下来需要添加一些入库规则过滤。

2.1 如果一条转发微博的原微博不在库内,则转发微博和原微博都入库。
2.2 如果原微博已有,转发微博用户和原微博用户相同,则视为对原微博的“补充说明”,也入库。
2.3 如果原微博已有,转发用户非原博用户,则入库标记为垃圾微博。
2.4 如果原微博已有,转发微博用户和原微博用户相同,且转发内容为“转发微博”,则入库标记为垃圾微博。

——以上:原则是,对于搜索引擎而言,多条相同信息是无意义的,只需要保留确实有意义的内容即可。

3. 对于搜索请求,由于动漫这个特定领域的分词非常难做。目前网站的搜索是没有分词的,于是导致“火神毛”的搜索请求并没有表达用户本来的意思 “火神+毛”。接下来会研究一下如何变通地实现这个需求。

0%