文章排序的那些事·一

作者: LostAbaddon | 来源:发表于2014-10-18 01:03 被阅读464次

    事先说明:这是一篇会让人想吐的文章,如果你看到一半感到身体不适,请果断关闭浏览器。


    问题提出

    在一个以页为单位的信息交流平台上,一个不可避免的问题就是如何为这些信息做一个恰当的排序。
      这种行为的出发点有很多,比如要找出最有用的信息,最受欢迎的信息,最让人喜欢或者讨厌的信息,最有趣的新闻,最Hot的热点,等等,这都需要排序。
      排序的指标是什么,指标如何量化,这些都不是本文要说的内容,于是忽略不提。
      那么,我们假定已经为文章列表{A_i}订好了一个属性I(A_i),来表示这个量化的排序指标,剩下的事情就容易了,以I(A_i)为指标做降序(或者升序)处理,事情就做完了。
      似乎一切都很简单。

    下面,让问题复杂一点,假定一个平台上有N个人,文章A_i被其中的n(A_i)个人看过,并被赋予了指标值I(A_i),请问如何排序?
      乍看之下,这个问题似乎没什么营养,还是根据I排序就好了嘛。
      但,如果我们将问题这么描述,会如何呢——
      给出一篇文章在整个平台上的预期受欢迎程度,并以此来排序(假定I表示的就是受欢迎程度)。
      显然,既得值I(A_i)并无法完全表达“预期受欢迎程度”这个需要的量。
      一个最简单的做法,就是I_pre(A_i)=I(A_i)/n(A_i)*N。
      从这里开始,问题就要开始变得复杂了,而且是越来越复杂。

    一个可选的方向,是下面分析文章A_i的兴趣集,并且和人群的兴趣集做分析,以此来给出在离散空间中的耗散动力学,这基本算是网格模拟的问题,我们这里不做进一步考虑。

    另一个这里更有兴趣的问题,就是考虑上“时间”的因素,来看看对“预期”这个谓词来说,会带来什么样的影响。
      比如说,如果我们将文章的“点击数”和“点赞数”的比值作为评判一篇文章质量的标准,那么显然这个值是会随着时间的改变而改变的,那么我们如何获得这个值的“真实正确”值,来建立一个合理的排序呢?

    所以,下面的内容就是建立各种模型,来模拟N个元素中n个已经参与过投票的情况下,如何推算出最终的弛豫值。


    最简模型及其近似解

    现在重新明确一下问题,并做恰当的简化:
    <blockquote>
      现在有两个空间A和B。A中有N个元素,B中有P个元素。
      A中元素可以对B中元素做两个操作x和y,且要执行y必须先执行x,且x和y只能执行一次。
      每一个时间点,A中元素都可以对B中元素进行操作,记为“一次”。
      问题:已知B中元素p第一次操作的结果为n个A中元素对其进行了x操作,m个A元素进行了y操作,求第t次x和y的可能操作数。
    </blockquote>

    问题描述到这里,其实还不够完整,因为A的具体性质对上述问题有着关键的影响,于是下面给出A的性质描述:
    <blockquote>
    A中元素a与b相连的概率为p。
    如果a对B中元素m进行过操作y,则在下一次操作时,若b与a相连且没有对m进行过x操作,则b会对m进行x操作。
    A中元素q如果对B中元素m进行了x操作,则有一定的概率q进行y操作。
    </blockquote>

    到这里,事情就开始有趣起来了,我们可以建立在这样的系统上y操作的传播动力学,其基本运动方程为:
    <pre>
    N_{n+1}=[1-(1-p)^{q N_n}](N-\sum\limit_{i=0}^n N_i)
    </pre>

    当然,就实际来说,需要对上述式子加一个取整函数,所以就是:
    <pre>
    N_{n+1}=Round{[1-(1-p)^{q N_n}](N-\sum\limit_{i=0}^n N_i)}
    </pre>

    到了这一步,用计算机模拟总是没问题的,但如果想要用解析的手法来获得一些结果,则将变得素手无策。
      我们可以用一些近似的手段来处理这个函数,使得不用计算机模拟也能得到一定程度的解析结果。

    第一步,是将上述差分方程做一个近似,其近似前提是A的元素总数N足够大、p足够小:
    <pre>
    N_{n+1}=p q N_n (N-\sum\limit_{i=0}^n N_i)
    </pre>

    第二步,是给出差分方程近似的微分方程:
    <pre>
    y: \sum\limit_{i=0}^n N_i
    y': N_n
    y'': N_{n+1}-N_n
    y''=Cy'[pq(N-y)-1]
    </pre>

    这里的C是由差分和微分的转变而带来的系统参数,我们可以通过第一代数据的简单计算来作拟合,从而是解析的。
      这个方程的解为:
    <pre>
    S_n = \sum \limit_{i = 0}^n N_i) = [p q N - 1 + tanh(C n + A)] / (p q)
    N_n = [tanh(C n + A) - tanh(C n + A - C)] / (p q) n > 0
    </pre>

    其中A为待定参数,由代数方程y(0)=N_0给出,这里的N_0是第0代的“初始”进行x操作的A的元素的数量,因此参数A也是可以通过初始条件解析得到的:<code>A = arctanh[1 - p q (N - N_0)]</code>。
      进而利用第一代数据N_1=y(1)-y(0)给出待定系数C:<code>C = arctanh[1 - p q (N - N_0 - N_1)] - A</code>。
      而N_1可以通过已知条件获得:<code>N_1 = [1 - (1 - p) ^ {q N_0}] (N - N_0)</code>

    而最后,原本用取整函数来获得的“截断”则由y'(t)<B这个代数方程来获得临界t,而B的“自然”值得当然是1,虽然就拟合来说实际值应该大于1。
      具体截断方程为:
    <pre>
    B > [tanh(C m + A) - tanh(C m + A - C)] / (p q)
    </pre>

    从而可以得到截断临界时间m,并利用m获得最想要的数据:S_m。
      到这一步,所有数据都可以解析获得,于是我们可以很好地分析传播相关的各种性质,包括一篇B中元素可以获得的最终x操作数<code>X = S_m</code>(最终y操作数显然为<code>Y = X q = q S_m</code>)。

    到这里,我们先来看一下对最终的排序来说,这样的模型和最一开始的模型到底有什么不同。

    最根本的不同,就在于原来排序的指标是q N,而现在则变为了q S_m。
      而,如果排序是根据当前值(第n代就是q S_n)来做排序的判断,那么可以看到,由于传播的动态性,这样的排序会是很有意思的。
      我们这里主要感兴趣的,是初试y操作数量N_0、相连几率p和x操作转化为y操作的几率q对于最后的稳定值q S_m的影响以及对整个序列q S_n的影响是怎么样的。

    由于这里所做的近似都是在N足够大、p足够小这个前提下的(这也就是说,当S_n接近N时上述近似其实已经失效了,也所以截断方程其实是需要通过实验来拟合出合适的B才能正常使用的而不能通过理论分析获得),所以在这个前提下我们可以得到如下近似结果:
    <pre>
    M = p q N - 1
    S_n = [M + tanh(C n + A)] / (p q)
    N_n = [tanh(C n + A) - tanh(C n + A - C)] / (p q)
    A = N_0 / N / (1 - M) - arctanh(M)
    C = p q N_0 / (1 - M)
    N_1 = p q N N_0

    So:
    m = {arccosh{sqrt[N_0 / B / (1 - M)]} + arctanh(M)} (1 - M) / (p q N_0) - 1 / (p q N)
    C m + A = arccosh{sqrt[N_0 / B / (1 - M)]}
    S_m = N - {1 - sqrt[1 - (2 - p q N) B / N_0]} / (p q)
    </pre>

    从而可以看出,N_0基本上决定了函数的上升速度,p q虽然也能起到类似的作用,但并不是简单的线性关系(<code>p q / (2 - p q N)</code>)。
      而最有趣的部分则在于最终的稳定值S_m上:初试值N_0约小,则最终稳定值S_m也约小;而和传播相关的属性pq则在某个特定值前越小,最终稳定值S_m也约小,特定值之后越大则S_m越小,但这个特定值本身却不小,从而打破了p为小值的前提。
      现在,如果我们要排序的话,其实更好的预测值应该是<code>q S_m = q N - {1 - sqrt[1 - (2 - p q N) B / N_0]} / p</code>。

    不得不说的是,这是利用N足够大和pq足够小这两个前提构造出的近似分析,尤其在截断发生的部分,这种近似本身就值得商榷,所以只是一种定性分析的手段而已。

    上面是通过模型,正向推倒出我们可观测的现象,也就是每一段时间x操作和y操作数的变化情况。
      在实际使用的时候,我们往往需要用到的是反向的问题——如何通过x操作和y操作的数据列,来反推出模型种的那些参数?
      也就是,如果我们知道的是N和N_n(代表了x操作数),以及y操作数Y_n,如何求出最重要的参数p和q?

    q的获得相对来说很容易<code>q = Y_n / N_n</code>。p的获得也还可以:
    <pre>
    p = 1 - [1 - N_{n+1} / (N - S_n)] ^ [1 / q / N_n]
    </pre>

    但,这都是理论上的情况,实际上我们所获得数据都不可能是正好的理论值,都有误差,于是下面就要看误差会导致怎么样的改变。

    先将上述运动方程用更好的方式来重写一下:
    <pre>
    第n代的x操作数为X_n,y操作数为Y_n,x操作总数为R_n,y操作总数为T_n。
    R_n = sum{X_i, i = 0 ~ n}
    T_n = sum{Y_i, i = 0 ~ n}
    Y_n = q X_n
    X_{n + 1} = [1 - (1 - p) ^ Y_n] (N - R_n)
    </pre>

    在这样的情况下,如果在某一代n上,X_n和上述计算获得的值(<code>|X|_n</code>)相比有一个dX_n的偏差,那么我们就要来看一下这个偏差在下一代数据上会导致什么样的偏离:
    <pre>
    X_n = |X|_n + dX_n
    Y_n = q |X|_n + qdX_n + dY_n
    R_n = |R|n + dX_n
    T_n = |T|n + qX_n + dY_n
    X
    {n + 1} = |X|
    {n+1}
    - {1 - (1 - p) ^ Y_n [1 - q ln(1 - p) (N - R_n)]} dX_n
    - (1 - p) ^ Y_n ln(1 - p) (N - R_n) dY_n
    </pre>

    在p和q很小的极限下,上述结果则可以写为:
    <pre>
    X_{n + 1} = |X|_{n+1}
    -p [Y_n - q (1 - p Y_n) (N- R_n)] dX_n
    + p (1 - p Y_n) (N - R_n) dY_n
    </pre>

    这个数据有点意思。
      可以看到,由于n代的Y_n的扰动dY_n引起的n+1代的的扰动的系数,是恒正的,但对于X_n的扰动dX_n来说则不一定。
      更重要的是,这个数据几乎不出意外地是在不断减小的——因为Y_n即便某一次会增大,但其作为一个小于一的数的幂次,产生的影响几乎不能和N - R_n相比,而这个是随着n的增加恒减小的。
      同时,在早期,从上述分析可以看到,dY_n引起的扰动的比例系数近似等于p N,而这个值则近似等于一个节点的“邻点”个数,从而基本是一个大于1的值——因此,这就表示早期扰动对数据的影响是逐渐放大的,会极大地影响到X_n的生成。
      而随着R_n的积累,这种偏差也会被极快地消除——事实上,当Y_n达到一个极大值后开始减小后,Y_n的干扰基本就会自我消除——从前面获得近似解析解可以看到,系数A中由于存在1 - p q (N - N_0),从而在很大程度上A是负值,这就表示sech(C n + A)会是一个先升后降的函数,从而N_n也将在很大程度上是这种函数,而这样的函数在升到最顶端的时候,其实N - R_n便已经积累到接近一半的值了,而Y_n又是最大,从而此时dY_n的影响因子已经变得足够小了。
      所以,总结来说,早期dY_n的影响对整个系统是最大的,此后影响越来越小。而当Y_n开始下降后,dY_n的影响基本可以不做考虑。
      从而,对Y_n来说,早期数据由于扰动过大从而不宜做太多的考虑,后期的Y_n的数据则比较可信。
      而对于X_n的扰动来说,情况则更微妙——
      存在一个临界条件Y_n < q (N - R_n),当条件满足时,dX_n最终对X_{n+1}的影响是正反馈,而当这个条件被破坏时,则变成了负反馈——即使扰动会自己消减。
      可以看到,dY_n的影响始终是累计的,只不过影响因子在不断减小(后期),而dX_n的不单单会累计,还会彼此抵消。
      综合这两项分析可知,当Y_n序列(也即X_n)序列达到最大值的时候开始,是最统计的最佳阶段。在此之前的数据误差起到的作用都会比此后要大。

    具体到实际操作中,也就是如果我们获得了文章的点击数序列X_n和点赞数序列Y_n,那么前一段时间的数据可以不计如统计,而从X_n开始下降的时刻开始统计。

    不过必须要提醒的是,这么做的一个前提,就是假定只有一篇文章,且模型别的方面不出现别的扰动(比如肯定会有的p和q的扰动,以及系统并不能使用平均场假设这一根本性差异)。

    当然,有趣的事情到这里还没有结束。

    我们接下来开始引入“相互作用”的环节。

    相关文章

      网友评论

      • LostAbaddon:@Alamo_Young 另外,我友好地提醒一下:我基本写的文章都会保持段首空格这种优美的样式的,所以你以后基本可以无视我的文章了,这是一个好习惯。
      • LostAbaddon:@Alamo_Young 我倒不会因为排版而直接无视一篇文章,而是自己动手修正格式到我喜欢的样子(所以说Geek改变世界啊)。
      • LostAbaddon:@Alamo_Young 内容聚合我可以说一句话:那是程序这么写的。Spider和RSS生成工具在扒内容的时候会将所有空格都扒掉,这是一个历史传统惯例,因为最初是要考虑节约带宽的,后来就成了惯例,没有什么特殊的理由,和排版基本无关。

        至于说国外门户,这个又回到之前的话题了——那些门户(其实也包括国内的门户)都是用分段而不是用换行不分段,因此从功能性上来说是不需要段首空格。这个如果你看过我之前的分析的话,你就知道原因了,因为这些页面都遵守了段首不需要空格的成立条件。而这也就是回到了我为什么不用的问题的回答了——你没发现我这里大量用的是换行而非分段么?至于我为什么用换行而不用分段,理由是我认为分段留下的空行太多不好看。
        你要说这是惯例的话,这也的确是一种惯例。
      • pfgp2n:我之前遇到排版不太好的网站,会用clear或者readability转换一下。现在呵呵,直接无视
      • pfgp2n:哈。刚好和你相反。我印象中,我看到的空格,除了国内一些门户外,无论是国外媒体还是国内新的内容网站,以及各种内容聚合应用,博客等等,均是定格。
      • LostAbaddon:@Alamo_Young 顺便一说,就我个人经验(而非精确的数字统计),不使用段首空格的网页,基本上是论坛类型的和资源分享类型的,这些地方不使用段首空格的是大多数。
        而真正写文章的地方,就我所看,使用段首空格的略多于不使用段首空格的。简书上的感觉是段首顶格的比段首空格的略多。不过大致上来说对半开。
        所以,你所说的惯例到底是哪里的惯例?我怎么感觉是论坛和资源分享网站的惯例而非内容生成平台的惯例?
        而论坛和UGC是天然不同的,因为论坛讲究的是短频快(这点的用户基本心理诉求就不展开分析了),和写文章本就是两码事——粗略来说就是一个是拍电报一个是写信,两码事。
        所以,你真的觉得你认为的惯例是惯例么?从哪里分析总结来的结论?
      • LostAbaddon:@Alamo_Young 说经过讨论的话,很多规范其实都经不住讨论,而是最后由某个委员会来拍板定下,这是国际惯例。

        至于你要说段首不空格是“惯例”,我本来还想说腾讯大家百度百家的几乎所有文章、新浪博客的很多大V的文章都是段首空格的,但我感觉你会说BAT都是有政治因素的,所以不算。
        这么说来,到底什么算呢?
        所有官方的基本都不算了,而民间的部分,我是段首空格的,我看到很多人的博客也都是段首空格的,但你要说什么惯例,真没什么惯例——所以你所说的惯例到底是怎么来的?不会因为你看到的几个人正好都是段首顶格所以就说段首顶格就是惯例吧?

        引号是有可能有政治因素,但段首空格也有政治因素?那我还能说段首顶格是民愤呢。。。
      • pfgp2n:@LostAbaddon 关于审美就此打住了。你有你的原则。我也有我的原则。我也没想着说服你,也不会被你说服。

        至于规范,倒不是说对我有利与否。门户网站的标准,是根据政治原因制订的,而不是网站根据用户喜好和体验、或者说根据美学、设计的原理设计。我说他不具备参考价值,原因在于这个标准不是经过讨论产生的,而是经过政府强制行程的。

        段前空格是一个例子。还有一个例子就是外文人名。标点使用。例如很多字体下,国标”双引号“显示非常糟糕,因为它只是”简单的“将西文引号拿来用而已(顺便提一下我的引号方向是有意用反的)。打字的时候也很麻烦。相比而言直角引号不论何种字体,至少能做到直观明了。但是其他网站可以用,像简书、知乎可以用,你“也好”,「也好」,『也好』都有人用,顶多别人说这样不好看、那样更好看;但是门户网站却不能随便用,用了就是「原则问题」,而不是简单的「审美问题」,编辑甚至可能要扣钱的。所以我说没有参考价值,并不是因为它于我有利。
      • LostAbaddon:@Alamo_Young 说便一说,你给的网页里不是有四行贴图么?段首没空格的一看就感觉丑爆了,哎…………
      • LostAbaddon:@Alamo_Young 争论很多,这是常识。这年头豆浆甜的咸的都能有海量的争论呢,汉字是存是废都有海量的争论呢,这种美观的纯主观问题没有争论反而不正常了。
        既然有争论,那就是说没有定。既然没有定,我为何要用别人的规范而不用我自己的?
        人首先要做自己,然后才是做别人。

        然后,你一方面说要按照别人的规范做,一方面有说官方的是政治原因不足为信,我只能呵呵。看来对你有利的规则是规则,对你不利的规则就是废话了咯。那我再怎么说也没用了。

        最后,这个问题千言万语其实就一句话:段首不空格的我看起来丑爆了丑得没朋友,所以我不用;但显然在你看来段首不顶格才是丑爆了丑得没朋友。
        所以争论总结下来就是上面这句话,无它。
      • pfgp2n:@LostAbaddon 最后一次回复吧。再一次重述:关于段前空格的争论,已经很多了。你可以随意Google。

        1. 我确实不看门户网站

        2. 门户网站之所以如此做,是有政治原因的,不是像其他网站那样随意就能用。举个例子,门户不能用繁体字;也不能用直角引号;甚至在引用外国人名时候也不能直接使用原名,必须有中文音译为主。很多奇怪的束缚导致。所以门户网站不具备参考性。门户网站从来不考虑体验二字的

        3. 再给你一篇文章。 http://blog.rexsong.com/?p=10041 这个有图对比就比较清楚了
      • LostAbaddon:@Alamo_Young 顺便一说,你有一点我很同意,而且事实上我半年左右以前就反复写文来说明了,那就是我们为何不段首空格?为何说的过去的理由就是你还要按空格啊!我懒我不想按空格啊!除此以外没有任何合理的理由(当然,你看着觉得不漂亮这也是一个合理的理由)。
      • LostAbaddon:@Alamo_Young 首先,很显然,没有什么规则是天然存在的,因为规则都是人造的,既然是人造的就总有没有被造出来的时候。
        我可从来没有说过段首空格是天然就有的哦,所以我不知道你第一段是先要说明什么问题。

        关于第二段,你显然没有看我关于段内换行那段分析。
        你如果去看看那些网页,自然就知道了——大家都没有怎么使用段内换行。
        然后你看看我这篇东西,你就知道了我基本都在使用段内换行。
        这么明显的现象级差异为什么要忽略呢?
        而关于为何我要使用段内换行,我已经回复过了。
        至于你说这是惯例,我看不见得:http://star.news.sohu.com/20141027/n405486124.shtml
        这是搜狐新闻,段首空格,妥妥的。
        我说你从来不看搜狐等门户网站新闻的么?

        至于规范,我还见过有人写规范说中文和英文之间要有半角空格的,这样美观,结果别人一翻历史资料,原来这个“美观”是早年中文排版系统Bug的一个绕过式解决方案留下的遗产,根本和美观无关。
        所以规范这种,大多数都是历史习惯,没有什么为什么。
        而我的习惯很简单:我看着不好看的我不用,仅此而已。
      • pfgp2n:刚才给错了,应该是这个 [sparanoid/chinese-copywriting-guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)
      • pfgp2n:@LostAbaddon 自从创字之初,其实也没有段首顶格的规矩。包括古代的中国书籍。段首空格是后来外文的习惯。中文改成自作向右横向显示后,为了印刷的成本,也采取了这样的方式。并非为了美观,而是为了成本。

        其实关于中文段首空格的争论,已经不少了。你可以随意Google一下。我也就不累述了。而且很显然现在大部分的网站内容都是首行不缩进。这也是成为惯例。

        顺便这里有一个规范。虽然不是权威机构,但是显然在显示方面,要比段首空格舒服很多。[coding-style/chinese.md at master · anjuke/coding-style](https://github.com/anjuke/coding-style/blob/master/text/chinese.md)
      • LostAbaddon:@Alamo_Young 作者写东西首先要给自己看,这是我的一贯观点。
        当然,商业化的写作可能是首要目的是给别人看,但必须要清楚的是:你写的东西的第一个读者是你自己,所以当你说“给别人看的”时候,第一时间做的还是“给自己看”。不存在不是自己作品读者的作者。
        而,往更大了说,当你说“共性”的时候到底再说什么呢?
        就我看来,段首顶格不是人类阅读体验的共性,至少现在不是。段首顶格只是部分读者的偏好,远谈不上“人类的共性”,所以当你举出“人类的共性”的时候你到底在说什么?你是如何将你个人的偏好提升到“人类的共性”上来的?我也可以说段首空格是人类的共性,那这样不就有两个共性了么?
        很显然的一点是,现代的印刷书就不是段首顶格的,所以光就“人类共性”这句话来说,已经是错误的了,你最多可以说是“在阅读电子书方面是人类的共性”,而这句话本身是否正确其实你我都不知道——至少在我看来不是,而在你看来有可能是。
        既然我们连段首顶格是否是“人类的共性”都没能验证,你用这点来反驳我就完全是无理的。
        生造一个“证据”来反驳别人是无效的哦。

        然后,你说“段前空格就是人为的在划分字句”是错误的。
        段首空格的作用不是划分语句,划分语句在段落中是分段的功能,用现代的话说是换行符的功能,不是段首空格的功能。
        段首空格的功能是段落提示,即让阅读者在“略读”过程中可以知道大致的段落结构(精读过程当然不需要考虑这点)。
        所以,你连段首空格的功能都弄错了啊。。。
        现代网页为何不需要考虑这个功能?因为当我们使用分段(而非简单的换行)时,浏览器的默认样式是段间距为行间距的两倍左右,所以我们在略读的时候可以看清楚段落结构,从而自然不需要有段首空格了。
        但,请注意,这就牵扯到这种“不需要”的前提条件了——段间距完成了段落提示的工作,所以不需要额外的段落提示了。
        但这个前提条件是不会被满足的,因为现代浏览器除了允许分段,还允许换行——换行就表示了段落不分而另起一行。
        所以说,我才会在之前的回复中多次声明规范的成立前提——在使用换行而非分段的时候,段落提示的功能没有被浏览器的默认样式发挥出来,所以需要额外的段落提示功能。
        这里你的有效争议点是“为何在有分段的情况下还要使用换行”,而不是别的。
        而对于这个有效争议点,我的回答有两点:
        1,个人习惯;
        2,个人觉得段间距为行间距的两行很难看。
        这都是个人体验,在提供CSS自定义的时候都可以调整,但在大多数情况下大多数网站不提供CSS自定义,呜呼哀哉,所以我继续使用我喜欢的样式。

        剩下的都是废话,没有反驳的价值,所以不说了。

        对于用户的需求,你需要明白一点:你的需求是段首顶格,别的用户的需求是段首空格(不可能只有我一个有这种需求,很显然),所以当你说用户需求的时候请注意一点——要么给不同需求的用户开发不同的应用,从而要开发无穷个应用,要么坚持自己认为大多数人会满意的“需求”,从而只做一个应用,然后不断根据反馈来迭代。
        你是打算开发无穷个应用还是一个应用?呵呵。

        再来关于关于Yanjun的问题,你的回答第一句就不妥哟——这个问题在任何字符排版中都是存在的,不单单是中文排版的通病,而是所有排版系统的通病。这个你只要使用过打字机就能明白了哟。
      • pfgp2n:@Yanjun 这个是中文排版的通病。英文同样无法很好解决段落右边界参差不齐的现象。word 这样的排版工具是通过不断调整字宽、字间距等,来造成视觉上的整齐。但是网页都是经过编码的,字宽和间距都是一致的,需要经过特殊处理,解决中文标点符号的问题。
      • pfgp2n:@LostAbaddon 首先我们有一个非常大的分歧。我认为文章、语言,最重要是给别人看。之所以需要满足作者自己,是因为作者和读者一样也是人,也有人类的共性。满足作者自己的时候,有可能也满足了别人的一些需求。但是由于每个人的观点立场不同,结论不同。很多现在认为的大师成名作,遭到过当时编辑的犀利贬低。

        你觉得段首顶格丑。但是我觉得段首顶格不丑,而且更适合阅读。这样不断一行的长度如何改变,第一行和其他行的落点位置是一样的。我说的空格问题,其实段前空格就是人为的在划分字句。在古代,段落中间是没有空行的,如果段首不空格,刚好上一段结尾也没有空格,就分不出一段来,成为一个大块。文章分块是就是为了更好的阅读,同时也为了更好的写作。

        我说人类体验的时候,是针对你「但段落不是必然出现的,比如在GFM里一个回车是一个换行而不是新建一个段落。在大多数富文本编辑器里shift+enter是换行不是新建段落,等等等等」这句话,对象是工具和体验。我的意思其实很简单,一个产品的功能,是由需求产生的。比如有的人觉得回车换段用起来更熟识;有的人觉得回车换行更好用。但最后落在界面上,总有一套标准可循。

        我没有强迫你接收我的审美。我只是从我的经历来试图阐述我为什么觉得应该是这样。你不用太激动。

        我的第一条评论也说了:段首空格就没有看的欲望了。关掉不看不是一个好的解决方案。你是供方我是需求方,我有义务提醒你我的需求和意见。同样的,你也有义务去阐述自己的观点。因为用户并不理解你这么做背后的意义是什么。

        最后就是,我没看懂你其他说的意思。。。
      • LostAbaddon:@Yanjun 同意。
        这里面的排版差异就要看一下专业书籍了。
        不过,有一点是肯定的,就是实体书、电子书和网页的阅读习惯其实是不一样的。
        实体书和电子书是捧着的,网页一般是在显示器上所以是立着的,人在看着两类东西的时候视线和内容呈现媒介的相对关系(距离、夹角,等等)都有不同,这些都会影响到阅读体验和对感受的影响。
        所以一般来说给实体书的字体字号和给网页的字体字号是要有差异的,这点毋庸置疑。

        不过,段首空格的原本目的是“段落提示”,这点和前面所说的有所不同。这也是为何现代网页上不要求段首空格,因为网页上的段间距一般已经足够视线“段落提示”的效果了。
        可网页奇葩就奇葩在,它在给出“段落”的同时还给出了“段内换行”这个规则破坏者,于是事情就猥琐了。。。
      • Yanjun:@LostAbaddon 翻了本书,感觉实体书行末即使是标点看起来也比较整齐。简书上如果行末是标点就感觉被咬了一口似的。
      • LostAbaddon:@Alamo_Young 第一句话就错了。
        界面规范是有使用范围的,换言之,如果规范的使用前提没有满足,那么这条规范就不应当被使用——无视规范成立的前提而使用规范,这是最常见的“滥用”行为。

        按照人类的体验走,这句话你说对了,但你没有理解。
        首先,什么叫做“人类的体验”?我的体验是不是体验?你的体验是不是体验?大多数人的体验是不是体验?少数人的体验是不是体验?
        我在之前的回复中说过,段首不空格的文章在我看来是丑爆了,请问这是不是“人类的体验”?
        当你再说人类的体验的时候,你是否真的知道你在说什么?
        就这里的问题来说,我的体验就是:段首不空格的东西丑爆了,所以我写的文章会按照我的审美标准来写。因为,文章首先是写给自己看的,其次是给别人看的。如果我都感觉我写的东西丑爆了,那我不会发出来。
        你如果觉得我的东西丑爆了,关掉不看嘛,或者,GEEK一点,运行如下代码:
        var ps = document.querySelectorAll('p'), i, l = ps.length;
        for (i = 0; i < l; i++) ps.innerHTML = ps.innerHTML.replace(/^  /, '').replace(/\n  /, '');
        这段代码的作用就是去掉所有的段首空格。
        你不能强迫别人接受你的审美,就如同我不会去强迫你接受我的审美一样——所以,我写我的,也给了你解决问题的方案,用不用是你的喜好,我强迫不了。

        接着,第三个错误——不是照顾不同工具的差异。
        这句话为什么说错?因为你没有理解我的原文。
        我的原文是说规范成立的条件未必满足,你却理解为我在照顾不同工具差异,呜呼哀哉,让人无语。

        然后在“不过审美。。。”这一段里,再次发生了不顾规范成立的前提的错误,这里不冗述。

        第四个错误——重心不稳。
        从学术的角度来说,段首不空格是必然地导致重心的,这是一个很基本的重心计算的问题。
        所以,你要说重心不稳的话,很不好意思,重心稳才是偶然现象,而且在段首不空格的情况里几乎就是必然现象。

        所谓加大编辑成本,这算是有一点道理,但实际上是将一个规范如何确立的问题换成了工具是否支持规范的问题——换言之,这才是你所说的“照顾不同工具差异”的问题。
        当我们在讨论规范为何如此的时候,随便引入工具是否支持规范是不合理的——再说了,要支持其实是很简单的,编辑器里就是一句话的事情:
        $('p').css({'text-indent:45px'})
        这说白了就是规范确立以后工具想不想做的问题,不是个事……

        至于说“汉字中本来不需要空格来划分字句”,这是将一个无关的问题引入讨论……本来讨论的段首空格,而段首空格的作用根本不是划分字句,所以你无端冒出来这个问题很无厘头啊。。。就好比我说豆浆是咸的好吃还是甜的好吃你突然说吃汤圆的都是异端应该烧死,完全风马牛不相及啊。。。
      • pfgp2n:@LostAbaddon 「并不是必然会得到保证的」这个好像没啥关系吧?界面规范,不是因为工具之间的实现不同。说人话就是:我们应该按照人类的体验走,而不是照顾不同工具的差异。如果一个工具导致人类因此缩手缩脚,比如IE6,那它就应该好好审视自己。用户也没有必要去迁就委屈自己。

        不过审美则是很主观的事情。每个人的审美观都不相同。但还是有一个共性的,就是大部分人都能接受和认可的。自从网页不再受到纸张和印刷的限制,段首空格以及宋体已经没落。即使是实体书籍,也由于脱离了古代生产力的制约,开始放弃段首空格的做法。

        汉字本就是方块字。段首空格是认为的导致制造出不齐整的效果,加上段位不可避免的不齐整,整个段落显得重心不稳。

        还有一点就是,段首空格认为的加大了编辑的成本。一些带有排版功能的编辑器,例如word,可以自行设置段首空格的长度。但是大部分编辑器没有这个功能,尤其是纯文本编辑器。每次分段,敲两次回车操作起来即简单,也毫不费神;但是段首空4格,要么用空格,心中莫属4次;要么设置要Tab键,无端多一门操作。总不及回车来的无脑直接。而且,汉字中本来不需要空格来划分字句,不像字母。所以空格也算是一种冗余操作了。
      • LostAbaddon:@Alamo_Young 来说一点——你再说段首像锯齿的时候是不是从来不看段尾?
        基本所有文章的段落都不会是两端对其,而是左对齐。这就是说——基本上无论如何一篇文章的段尾都是层次不齐如锯齿的。
        你在无法忍受段首像锯齿的时候居然对段尾的锯齿如此放纵,我感觉这就叫双重标准。。。

        所以我的选择就是:干脆统统层次不齐,这也是一种曲线美~~~
      • pfgp2n:尤其是在滚动屏幕的时候,感觉仿佛德州电锯狂人一样
      • LostAbaddon:@Alamo_Young 关键就是“按照美观来走”。
        段首不空格的东西我看着就是毫无美感可言,这和你所说的段首空格的来源一点关系都没有。
        关键就是——我看着感觉好丑,丑爆了。

        另外,你忽略了一点,说到来源的话,现代之所以段首不用空格是因为现代网页排版里段落之间有足够的段间距。但段落不是必然出现的,比如在GFM里一个回车是一个换行而不是新建一个段落。在大多数富文本编辑器里shift+enter是换行不是新建段落,等等等等。
        所以,段首不必空格的前提并不是必然会得到保证的,而无视一个规则的存在前提的普遍性来使用规则,就是传说中的“滥用”。
      • pfgp2n:@LostAbaddon 段首空格应该是专门设计出来为节省纸张和排版方便搞的。就跟宋体是为了刻字方便才广为流传。但是现在这些都不是事儿了,就应该按照美观来走了。段首空格视为缩进,但是其余各行都是顶格,于是每段的第一行和段的其他行之间,搞出了个特殊化。

        尤其是如果一段只有两行,更尤其这种段落连续出现,视线需要不断在空格/没空格/空格/没空格 之间转换。 而且这样的排版看起来就好象是锯齿一样,跟页面左右边界的平整竖线成鲜明对比。感觉都快把内容板块的边界给锯开了。。。
      • LostAbaddon:@Alamo_Young 段首没空格的文章实在是太凶残了,完全无法看啊……
      • LostAbaddon:@叶猛犸 正在考虑。。。哈哈~
      • 叶猛犸:建议@Larry @简叔 考虑一下啊,加个MathJax吧。

      • pfgp2n:段首空格太残忍了,我就打开看了一眼就无奈关闭了。
      • 云何:我擦…
      • 逸之:不明觉厉,你是学数学的么
      • 朱小虎XiaohuZhu:要是弄个PDF的就好了~~我一会再好好看一下
      • 风生水起:确实,也是吐了

      本文标题:文章排序的那些事·一

      本文链接:https://www.haomeiwen.com/subject/efdptttx.html