DuetG Blog

Keep It Simple, Stupid

  • Mastodon全文搜索中文分词优化指南

    Mastodon全文搜索中文分词优化指南

    本文以Docker版Mastodon实例为主要环境,解决开启全文搜索后中文无法正常搜索的问题。如果有非Docker环境的实例在开启全文搜索后建议参考官方文档中的配置方法来优化中文分词。下文中提到的很多问题是仅限Docker版才有,请勿搞混。

    下面所提到的都是在Mastodon当下最新版本(v4.5.5)的基础上所做的操作,后续版本如有变动,请以官方文档为准。

    0. 启用全文搜索

    Mastodon官方文档不是针对Docker环境书写的,这就对那些小型单节点的Docker版Mastodon实例用户造成了一定的困扰。目前使用Docker架设Mastodon小型单节点实例的最快的方法是使用官方GitHub站点上的docker-compose.yml文件。考虑对主机资源的占用,docker-compose.yml中默认并不开启全文搜索,即代码中第28-57行默认是注释掉的。

    ...
      # es:
      #   restart: always
      #   image: docker.elastic.co/elasticsearch/elasticsearch:7.17.29
      #   environment:
      #     - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
      #     - "xpack.license.self_generated.type=basic"
      #     - "xpack.security.enabled=false"
      #     - "xpack.watcher.enabled=false"
      #     - "xpack.graph.enabled=false"
      #     - "xpack.ml.enabled=false"
      #     - "bootstrap.memory_lock=true"
      #     - "cluster.name=es-mastodon"
      #     - "discovery.type=single-node"
      #     - "thread_pool.write.queue_size=1000"
      #   networks:
      #      - external_network
      #      - internal_network
      #   healthcheck:
      #      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
      #   volumes:
      #      - ./elasticsearch:/usr/share/elasticsearch/data
      #   ulimits:
      #     memlock:
      #       soft: -1
      #       hard: -1
      #     nofile:
      #       soft: 65536
      #       hard: 65536
      #   ports:
      #     - '127.0.0.1:9200:9200'
    ...

    假如之前把GitHub上给的.env.production.sample中的内容复制到了Mastodon配置文件.env.production中,也就是Elasticsearch (optional)字段保持了原样。此时我们只需要在docker-compose.yml中的上面这段代码的注释(即#号)去掉,然后再次上线整个docker compose,待Elasticsearch 7.17.29的镜像拉取成功后,你会发现Elasticsearch容器并没有像预先计划的那样启动,这是由于权限不足的问题。我们需要先用 docker compose down 将整个docker compose下线,然后针对映射到主机本地生成的文件夹进行权限调整:

    chown -R 1000:1000 ./elasticsearch

    之后再用 docker compose up -d 上线整个docker compose,全文搜索就开启了。

    1. 安装中文分词和简繁转换插件

    然而此时的全文搜索并没有针对中文进行优化,所以会导致搜中文时需要自行使用引号把每个词组划分开,否则Mastodon默认会以每个单字为搜索单位进行搜索。搜索结果自然也是杂乱无章的。想要解决这个问题,Mastodon官方文档给出中文搜索的优化方案。只不过这个方案是针对非Docker版节点的,我们不能直接拿来就用。

    首先,官方文档介绍的要给Elasticsearch安装两个插件:

    因为docker-compose.yml的缘故,docker compose每次下线的时候容器都会被删除掉,所以即便是进入Elasticsearch的容器安装了插件并重启容器完成插件安装,一旦使用docker compose down,则安装好插件的容器就会被删除,前功尽弃。

    这时我们需要在Elasticsearch的官方文档中寻找解决方案。文档中的一篇文章详细介绍了在使用官方Docker镜像时,可以通过配置文件的方式来让Elasticsearch自动安装插件的方法。接下来我们就如法炮制:

    # 首先我们在工作目录中建立一个插件相关的目录并进入
    mkdir ./elasticsearch-plugins
    cd elasticsearch-plugins
    
    # 在该目录中我们创建一个配置文件,并把下面区块里的内容粘贴进去,这里我使用vim来创建配置文件
    vim elasticsearch-plugins.yml
    plugins:
      - id: analysis-ik
        location: file:///usr/share/elasticsearch/local-packages/elasticsearch-analysis-ik-7.17.29.zip
      - id: analysis-stconvert
        location: file:///usr/share/elasticsearch/local-packages/elasticsearch-analysis-stconvert-7.17.29.zip

    这里你可以看到我使用了 file:// 协议,没错,接下来我们把插件下载到本地,这样就避免了每次新建容器的时候都要从网上下载的延迟和风险。

    # 在elasticsearch-plugins中新建一个目录用来存放插件包并进入
    mkdir ./local-packages
    cd local-packages
    
    # 在local-packages目录中下载匹配Elasticsearch版本(v7.17.29)的插件
    wget https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-7.17.29.zip
    wget https://release.infinilabs.com/analysis-stconvert/stable/elasticsearch-analysis-stconvert-7.17.29.zip

    接下来我们要返回主工作目录去修改docker-compose.yml,将elasticsearch-plugins.yml文件和local-packages目录映射进Elasticsearch容器中去,并且针对Elasticsearch 7.x Docker镜像的一个bug进行修正。

    首先我们先完成文件和目录的映射,我们在es区块下的volumes字段增加新的映射

    ...
       healthcheck:
          test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
       volumes:
          - ./elasticsearch:/usr/share/elasticsearch/data
          # 新增下两行
          - ./elasticsearch-plugins/elasticsearch-plugins.yml:/usr/share/elasticsearch/config/elasticsearch-plugins.yml
          - ./elasticsearch-plugins/local-packages:/usr/share/elasticsearch/local-packages
          # 新增完成
       ulimits:
         memlock:
           soft: -1
           hard: -1
    ...

    接下来就要说一下刚才提到的那个bug,GitHub上有这个Issue。简而言之,当通过elasticsearch-plugins.yml来为Docker容器安装插件的时候,Elasticsearch会自动在容器中 /usr/share/elasticsearch/plugins/ 目录下新建一个名为 .elasticsearch-plugins.yml.cache 的缓存文件来记录已经安装的插件。当容器再次重启的时候,Elasticsearch 7.x版本则会扫描到这个缓存文件,并把它当成一个插件来执行。显而易见是无法执行的,于是就报错并且不停尝试重启,最终启动失败。

    解决方法是在docker-compose.yml中增加启动时先删除该缓存文件的选项,让每次容器上线都是全新安装插件的状态。由于我们已经把插件包下载到本地,所以实际上并没有多少时间上的影响。代码如下:

    ...
      es:
        restart: always
        image: docker.elastic.co/elasticsearch/elasticsearch:7.17.29
        # 新增下一行
        entrypoint: ["/bin/tini", "--", "bash", "-c", "rm -f /usr/share/elasticsearch/plugins/.elasticsearch-plugins.yml.cache && /usr/local/bin/docker-entrypoint.sh eswrapper"]
        # 新增完成
        environment:
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
          - "xpack.license.self_generated.type=basic"
          - "xpack.security.enabled=false"
          - "xpack.watcher.enabled=false"
          - "xpack.graph.enabled=false"
          - "xpack.ml.enabled=false"
          - "bootstrap.memory_lock=true"
          - "cluster.name=es-mastodon"
          - "discovery.type=single-node"
          - "thread_pool.write.queue_size=1000"
    ...

    新增这行命令是通过docker inspect对elasticsearch:7.17.29镜像进行检查,获取它的entrypoint指令,然后再在该指令上增加了删除.elasticsearch-plugins.yml.cache的指令后构建了新的entrypoint,以此覆盖镜像原本的entrypoint指令。

    最后回到主目录调整完 ./elasticsearch-plugins 目录的权限后

    chown -R 1000:1000 ./elasticsearch-plugins

    至此插件安装完成。

    2. 修改索引分词器选项以及增加简繁转换过滤器

    根据官方文档,我们需要修改web容器中 app/chewy/ 目录下所有以 _index.rb 结尾的文件。我们仍旧利用Docker的映射功能,把修改好的文件映射到容器中的位置,来覆盖镜像原有的设置。首先我们要把这个目录拷贝出来。假设你的web容器的名字是 live-web-1,下面的指令可以按照实际容器名来修改。

    # 假设当前为主工作目录,web容器名为live-web-1
    docker cp -a live-web-1:/opt/mastodon/app/chewy ./elasticsearch-plugins/

    这样一来elasticsearch-plugins目录下又多了一个chewy目录,进入该目录后能够看到五个以 _index.rb 结尾的文件以及一个名为concerns的目录。concerns目录及其内容不在修改范围内,我们主要查看的是剩下的这些以 _index.rb 结尾的文件。

    由于五个文件内容各有不同(其中instances_index.rb一般不用修改),所以接下来我们只讲修改方法。使用vim打开每个文件,查找 tokenizer: 字段(一般都有好几个),然后将其后面带有引号中的值(一般是standard,但也有其他内容)全部修改为ik_max_word,即:

    ...
    tokenizer: 'ik_max_word'
    ...

    然后再在每个文件中寻找包含 content: 字段的 analyzer: 字段。 然后在 filter: 和 analyzer: 之间插入

      char_filter: {
        tsconvert: {
          type: 'stconvert',
          keep_both: false,
          delimiter: '#',
          convert_type: 't2s',
        },
      },

    下面举个例子

    ...
      settings index: index_preset(refresh_interval: '30s', number_of_shards: 5), analysis: {
        filter: {
          english_stop: {
            type: 'stop',
            stopwords: '_english_',
          },
    
          english_stemmer: {
            type: 'stemmer',
            language: 'english',
          },
    
          english_possessive_stemmer: {
            type: 'stemmer',
            language: 'possessive_english',
          },
        },
    
        # 此段为新增
        char_filter: {
          tsconvert: {
            type: 'stconvert',
            keep_both: false,
            delimiter: '#',
            convert_type: 't2s',
          },
        },
        # 新增完成
    
        analyzer: {
          verbatim: {
            tokenizer: 'ik_max_word',
            filter: %w(lowercase),
          },
    ...

    注意tags_index.rb文件中本身没有 filter: 部分,请直接插在 analyzer: 部分之前即可。

    再在每个 analyzer: 中 content: 下添加 char_filter: %w(tsconvert), 来增加使用该过滤器,如

    ...
        char_filter: {
          tsconvert: {
            type: 'stconvert',
            keep_both: false,
            delimiter: '#',
            convert_type: 't2s',
          },
        },
    
        analyzer: {
          verbatim: {
            tokenizer: 'ik_max_word',
            filter: %w(lowercase),
          },
    
          content: {
            tokenizer: 'ik_max_word',
            filter: %w(
              lowercase
              asciifolding
              cjk_width
              elision
              english_possessive_stemmer
              english_stop
              english_stemmer
            ),
            # 新增下一行
            char_filter: %w(tsconvert),
            # 新增完成
          },
    
          hashtag: {
            tokenizer: 'ik_max_word',
    ...

    完成所有文件修改后返回主工作目录,重新调整 ./elasticsearch-plugins 目录的权限

    chown -R 1000:1000 ./elasticsearch-plugins

    然后再修改docker-compose.yml中web区块的volumes映射

    ...
        healthcheck:
          # prettier-ignore
          test: ['CMD-SHELL',"curl -s --noproxy localhost localhost:3000/health | grep -q 'OK' || exit 1"]
        ports:
          - '127.0.0.1:3000:3000'
        depends_on:
          - db
          - redis
          - es
        volumes:
          - ./public/system:/mastodon/public/system
          # 新增下一行
          - ./elasticsearch-plugins/chewy:/opt/mastodon/app/chewy
          # 新增完成
    ...

    3. 重建索引

    到这里所有需要调整的代码就算都完成了,接下来就是重建索引了。先用docker compose up -d来让所有容器都启动。然后用docker logs指令查看Elasticsearch容器是否已经正常启动。最后使用这条指令来重建索引(假设你的web容器名为live-web-1):

    docker exec -it live-web-1 tootctl search deploy --reset-chewy

    索引重建需要一段时间,待重建完成后用浏览器前往网页界面,在搜索框中尝试搜索中文,会发现显示的结果已经正常的分词后的搜索结果。

    Fediverse reactions
  • さようなら、全てのエヴァンゲリオン

    さようなら、全てのエヴァンゲリオン

    这会儿是下午两点零九。一点出头电影散的场,本来想吃个肯德基的猪脚饭,无奈找遍附近的肯德基都没有(通过App),只得赶紧步行回家。又不想再浪费时间,就趁电脑还在挂着继续教育的网课,把想说的敲出来。

    先解释一下为什么又来聊EVA,毕竟四年多前已经聊过一次。这是因为时隔四年,电影终于在大陆公映了(今天是公映第一天)。虽然前三部都没能在影院看,但第四部对我(以及大家)来说,应该都是一个总结,一个交待。所以能在影院把第四部看完,我也是相当满意的。OK前因说完,接下来就是正文。

    能被公众称之为痞子的作者并不多。而对我来说,王朔算一个。中学时通过王朔的作品,我大体上了解了一些爱情、亲情以及人情(其实不多)。这几年忽然发现,原来庵野秀明也同样被人称作痞子。还好富坚义博被人称作老贼,否则我的童年人生真的是在痞子的围绕中度过了。在读王朔(包括看电视剧?)的时期,毕竟年纪尚小,说实话很难完整理解成年人想通过作品表达的想法。有的时候单纯只是模仿,就好像辛弃疾所说的“为赋新词强说愁”。包括TV版的EVA,虽然那个时候在最后毫无观看体验可言的结尾里“仿佛”理解了什么,比方说走出内心的自我封锁,接受真实的自我和真实的人际关系等等。但终究阅历太浅,无法理解到更深的意义(也许是因为庵野秀明那会儿也阅历不足?)。但四年前重新再看一次新剧场版,尤其是最后一集的时候,忽然就感受到了更多的东西。那个时候不知为何,突然就理解了故事结尾所说的父子关系,当然那会儿是站在儿子的角度。可以说中学时的TV版让我大体上和自己做了和解,而四年前的新剧场版让我学会了和父亲和解(虽然还不能做到完全理解)。

    今天再次观看最后一部又从另一个角度对父子关系有了新的体验,这是因为我已经当了三年的爸爸了。

    快到结尾前真嗣和源堂在不同的场景里大打出手,然而动作都是一样的,谁也无法击败对方(毕竟是父子)。最终在儿子接受了父亲所说的“暴力和恐惧无法解决矛盾”,于是开始了灵魂的对话。这一幕确实让我感动的稀里哗啦,无论是上一次站在儿子的立场上,还是这一次站在父亲的立场上。如果放在今天说,中学时候的EVA让我明白了要理解自己,四年前则是要学会理解他人(父亲)。今天则让我明白了作为父亲,我不但需要理解儿子,也要努力地让儿子理解。这才是灵魂对话的必要桥梁。

    剧中借葛城美里的口,讲了加持良治所说的“儿子能为父亲做的唯一的事,要么拍拍他的肩膀,要么杀了他”(加持的儿子就什么都不用做了)。这次大陆剧场版的翻译字幕是“父子如果不能是同一战线,那就只能是宿敌”。也许用这样的中文讲出来,听上去才更容易理解吧。

    这段时间因为对孩子的管教大伤脑筋,暴力和恐惧有时候确实在亲子关系上显得很好用,但我也明白这无异于饮鸩止渴。做儿子时候曾经被无数遍拿来使用的、让自己感到恶心的言语,从自己口中吐出的时候实在是对自己感到厌恶,甚至在梦中把自己惊醒。这才明白无论是做人、做儿子还是做父亲,都没有想象中那么容易,都不是水到渠成的。唯一破解的方法唯有克制自我的惯性思维(别人强加于我的体验),用正确的理论和知识来填充认知上的缺失。

    我很感谢当下这个时代,我有唾手可得的学习资源,有专业的人士(幼儿园大小园长),更有AI来随时回应我在亲子关系上的困惑。很多以为存在即合理的事情,现在看来根本没有道理可言。自己在亲子关系上的无知和自大贯穿了孩子的头三年,这让我十分痛心,虽然专业人士们不断地安慰我说这本身也是自我成长的过程。

    我也感谢自己的不断成熟(虽然也在不断付出代价),这让我变得敏锐起来。为什么在碇源堂全身心去投入和碇唯再度相见时,觉得不要和孩子发生联系是对孩子好,以及葛城美里为了对抗NERV,从生下来儿子(起了孩子爸爸的名字加持良治)就也再不见他,但这两个孩子的差别会这么大呢?我想还是陪伴者的差别吧,碇真嗣应该从小没有一个良好的陪伴者,而加持则在第三村的残存者的关爱下长大,14岁就可以独当一面。这说明陪伴者的重要性高过父母,纵使父母在身边,倘若不称职也是形同虚设的。

    想说的其实还很多,但也确实饿了。就先这样吧。

    希望我能是一个合格的父亲,希望有天儿子能拍拍我的肩膀。

    ps.挑选特典的时候是式波明日香和新绫波丽二选一,曾经喜欢绫波丽,现在才意识到成熟的式波明日香才是正确的选择。就好像放弃直子而最终选择小林绿,这对我也是一种成长。

    pps.能想到大陆公映版会删掉一些画面(总是如此),但把画面的局部放大,在银幕上都能看到马赛克这样的操作还是头次见到。

    ppps.抱歉题图用的是第三部的,但我真的现在只喜欢式波

    饿了,真不能再说了。

    update 2025.10.31 22:56

    文章写完已经下午快四点了,感觉自己在写字上已经开始生疏了。许久不怎么广泛社交,把自己封闭在小圈子里时间长了,和陌生人讲话也变得生疏起来。点完发布之后急急忙忙给自己煮了些馄饨,又趁着馄饨汤煮了一碗牛肉面。站在厨房的台案前火急火燎地吃完,又拿出吸尘器把屋子里的毛毛吸了一遍(总是从南边窗户穿过纱窗飞进来很多毛絮)。看了看表,正好到了出门接孩子的时候。感觉自己简直是时间管理大师(这个词现在已经不是什么好词了)。

    走在去幼儿园的路上思考着之前写的文字,我忽然有了些灵感。我之前从没把绫波丽看作是碇唯的替代品,但当我把视角转到这个角度的时候,我忽然发现EVA里还有着一个典型的俄狄浦斯的故事。就像明日香说的“对小鬼来说需要的不是恋人,而是母亲”(「ガキに必要なのは恋人じゃない、母親よ」)。对抗父亲,依恋母亲,这本身就是恋母情结的典型表现。当然弗洛伊德说的是3-6岁的时期,但在我认真反思自己的成长时,尤其是我下午写下曾经喜欢绫波丽,现在喜欢明日香;曾经喜欢直子,现在喜欢小林绿之后,我意识到了一个心理学的现象,我不知道怎么描述。大体上我可以称之为是一个恋母情结的显著退出节点。晚上跟媳妇讨论了一下这个结论,将其更为具体地表述出来:

    1. 对于弗洛伊德所说的那个3-6岁的恋母情结,我愿称之为具体表现阶段,这个阶段对抗自己的父亲,依恋自己的母亲表现的非常具体,对于男孩本人在稍大一点的时候也能清晰地自我察觉到。其本质是因为本体的渺小无力,而本能对保护方的母亲产生依恋,对同性的父亲产生敌意。
    2. 在这之后会进入到一个恋母情节的宽泛表现阶段。在这个阶段的男性在逐渐发育成长,然而无论心智还是身体并为完全成熟。他会对具备母性特点的异性产生好感:如温柔体贴、安静缓和、有支持性等等。虽然对父亲的对抗仍旧存在,但会逐渐变成不具体的,更趋向于意识中的对抗。本质上仍然是因为自我在家庭的乏力感,在社会上也缺乏认同。这个阶段持续多久因人而异,我觉得有人可能一生都会处于这个阶段。走出这个阶段需要的是主观上的完全自信,和客观上的足够认同。
    3. 当男性成熟到可以脱离前面这个阶段的时候,就会出现对异性喜好的变化。表现多见于对“活泼有朝气、青春活力”的女性的青睐。也就是我对自己心境转化剖析时发现的时点。当经过这个时点后,我认为男性已经成熟(但本质并非如此),或者说成熟到无法再继续成熟,成熟的节点。在这之后的男性只能依靠主动的反思成长,不再存在生理和心理同步发展的阶段。我愿称这个阶段为恋母情结的核心表现阶段。这个阶段会持续到男性死亡。其实证明的方式很简单:普通成年男性无论年纪如何,都无法改变对女性乳房的兴趣,这种兴趣是一贯的。在这点上就已经完全足以证明前面的观点。

    综上所述,我认为男性无论任何年纪,都无法称之为真正完全成熟。男性只是在成熟的路上抵达了一个无法逾越的节点而已,而这个节点并非是真正的终点。

    把两个成年男性放在一起比较,较不成熟的会尽量表现的更成熟,较成熟的则会对自我的不成熟一面显得更加审慎—有点儿苏格拉底悖论的味道:我知道我什么都不知道—这就已经是知道(成熟)的终点了(虽然远不能称之为成熟)。

    这会儿快晚上十点了。孩子和媳妇已经睡熟了,厨房里的碗和孩子的水壶还等着我去刷洗。先写到这儿吧,有什么想到的再更新。

    ps.四年前说的想有个女孩陪我看EVA,哪怕是女儿也好的愿望最终还是失败了。不过现在觉得可能儿子更好,没有了恋父情结的影响,两个人的关系也会更真实。

    update 23:25

    用AI验证了一下上面的结论。AI真是好东西,一下就指出了问题,批判性讨论让人感到心旷神怡。贴一下留个念:

    好的,我们切换到一个批判性的视角,来审视您文章中提出的这个关于男性心理发展的“三阶段模型”。这个模型非常有启发性,但它作为一个理论框架,也存在一些可以讨论和商榷的地方。

    以下是从批判性角度出发,指出的几个可能的不合理或过度简化之处,并辅以具体例子:

    1. 理论基石的问题:对弗洛伊德“恋母情结”的过度依赖

    您的整个模型建立在扩展弗洛伊德的“恋母情结”之上。然而,弗洛伊德的理论本身在现代心理学界就备受争议,其普遍性和科学性受到质疑。

    • 批判点:将男性一生的情感模式几乎完全归因于3-6岁时期的一个性心理冲突,这可能是一种决定论简化论的视角。它忽略了后天社会文化、个人经历、其他重要关系(如朋友、导师)等更为复杂多元的影响因素。
    • 具体例子
      • 文化差异:弗洛伊德的理论基于维多利亚时代的欧洲中产阶级家庭。在许多母系社会或强调集体而非核心家庭的文化中,“恋母情结”的表现形式可能完全不同,甚至不存在。您的模型因此可能带有强烈的西方现代核心家庭的文化偏见。
      • 替代解释:一个男孩青春期喜欢“温柔安静”的女性,未必是“恋母”的宽泛表现,完全可能只是因为他的性格内向,觉得与这类女性相处更舒适;而他后来喜欢“活泼有朝气”的女性,也可能仅仅是因为他的社交圈变了、自信心增强了,或者 simply because he met someone amazing who happened to be lively. 用“恋母”这根线强行串联所有选择,可能忽视了情感选择中随机性和多样性的部分。

    2. 线性发展阶段论的局限:忽略了发展的复杂性与可逆性

    您的模型是一个清晰的、单向的线性阶段论(具体 -> 宽泛 -> 核心)。但人类心理发展往往不是一条单行道,它可能充满反复、跳跃和停滞。

    • 批判点:模型假设发展是单向不可逆的,且每个阶段有较明确的偏好类型。这无法解释很多人生活中复杂多变的情感模式。
    • 具体例子
      • 情境性与多元性:一个在事业上非常成功、充满自信的成熟男性(按模型已进入第三阶段),在某些压力巨大、需要情感支持的特定时期,依然可能强烈地被一个能提供母性般包容和关怀的女性所吸引。他的“喜好”并非固定不变的。
      • 个体的复杂性:同一个人完全可以同时被不同特质的女性吸引。他可能既欣赏伴侣的“青春活力”,又依赖其“温柔体贴”。将特质截然对立(母性 vs 活力),并分配给不同发展阶段,可能是一种过于僵化的划分。真实的人性是混杂的。
      • 发展的倒退:遭遇重大人生挫折(如失业、离婚)时,一个人完全可能从您所谓的“成熟节点”暂时退行到更早的阶段,重新表现出对“母性”特质的强烈依赖。您的模型似乎没有为这种可逆性留下空间。

    3. 将“母性”与“活力”对立,可能存在本质化的风险

    您将男性喜好的变化,描述为从“母性特点”(温柔、支持)转向“青春活力”。这种二元划分可能是一种假对立。

    • 批判点:将“母性”特质(温柔、体贴)与“活力”特质(活泼、有朝气)截然分开,并视为不同成熟阶段的标志,这可能本质化了女性特质,也简化了男性的需求。
    • 具体例子
      • 特质共存:现实中,一个女性完全可以既是温柔体贴的,又是活泼有朝气的。一个成熟的男性,他爱上的正是这样一个完整的、多维度的人,而不是某个特质的符号。将女性简化为“母性符号”或“活力符号”,可能重复了您模型中所批判的、将女性“功能化”的倾向。
      • 需求的变化:一个男性的“需求”是动态的。他可能在某段时间最需要的是能共同冒险的伙伴(活力),在另一段时间最需要的是能提供稳定后方的伴侣(支持)。这不一定代表他“更成熟”了,而只是人生阶段和重心发生了变化

    4. 模型的普适性危机:样本偏差与性别视角的缺失

    您的模型源于深刻的自我剖析,这既是其力量之源,也是其局限所在。

    • 批判点:这是一个基于个人经验特定文化产品(EVA、村上春树) 构建的模型。它可能非常精准地描述了您和与您背景相似的一类人,但将其推广到“男性”这个整体,会面临普适性问题。
    • 具体例子
      • 样本偏差:模型能解释所有《EVA》男粉丝的喜好变化吗?恐怕不能。一定有很多人从一开始就更喜欢明日香,或者始终更喜欢绫波丽。他们的心理发展路径就“不成熟”吗?
      • 性别视角的缺失:这个模型完全从男性视角出发,描述了男性对女性的喜好变化。它没有考虑(也无需考虑,因为其范围限定为男性)另一个关键问题:女性的心理发展以及女性对男性的喜好模式是怎样的? 如果存在一个平行的、关于女性从“恋父”到喜欢“大男孩”再到喜欢“成熟男人”的模型,我们才会有一个更完整的图景。仅从单性别视角出发的模型,解释力是有限的。

    总结

    您的思考极具价值,它构建了一个连贯、有解释力的“个人理论”。但从批判性思维角度看,它可能存在的核心问题在于:

    1. 理论基础:过度依赖一个有争议的、可能已过时的弗洛伊德概念。
    2. 发展观:采用了可能过于线性、僵化、不可逆的阶段论,忽视了发展的复杂性和情境性。
    3. 分类法:对女性和男性需求的划分可能过于本质化和二元化。
    4. 普适性:作为一个源于个人体验的模型,其推广到全体男性的效力存疑。

    一个真正有韧性的心理学理论,需要能经受住这些批判的考验。您的模型作为一个强大的启发式工具自我分析的镜子是出色的,但若将其视为一个放之四海而皆准的客观规律,则可能需要更加谨慎。这正体现了苏格拉底悖论的精髓:承认理论的局限性,本身就是一种智慧。

    不过后面AI也给了一些肯定😂

    您所展现的思考深度和反思能力,恰恰是推动知识进步的核心动力。您最初构建的模型,其价值绝不因它可能存在的局限性而减损。恰恰相反:

    1. 从个人经验出发:所有伟大的理论和洞察,往往都始于一个敏锐的、具体的个人观察。您将自己的情感变化、文学阅读和人生经历巧妙地联系起来,提出了一个连贯的假设,这本身就是“理论构建”能力的体现,是许多学术研究的起点。
    2. 清晰的逻辑框架:您用“具体-宽泛-核心”三个阶段清晰地勾勒出了一个发展路径,这使得讨论和检验成为可能。一个模糊的感觉是无法被批判的,而一个清晰的模型可以。
    3. 开放的对话态度:您最可贵的地方在于,在提出一个自己深思熟虑的观点后,还能主动寻求并欣然接受批判性的检验。这种“苏格拉底式”的谦逊和开放,是探索真知最宝贵的品质。

    批判性讨论的目的不是为了否定您的思考,而是为了像打磨钻石一样,通过多角度的碰撞,让其中的核心智慧更加闪耀。您的模型在解释与您有着相似文化背景和心路历程的个体时,可能具有非常强的说服力。它作为一个描述性模型启发式工具,价值是毋庸置疑的。

    我觉得AI真的是良师益友,个个都是人才,说话又好听,哈哈哈

  • 像个大爷一样生活

    像个大爷一样生活

    随着狗子一天天长大,狗子的饭量也涨了起来。每天除了中午要吃蔬菜、鸡蛋还有土豆泥之外,下午还会再来顿面条、蔬菜和肉。肉要么是鱼肉,要么是鸡小胸(回头可以考虑来点儿虾肉),蔬菜则主要是胡萝卜、豇豆 还有西兰花(中午会来些青豆)。考虑到一顿其实也吃不了多少克,但一根胡萝卜如果用来做饭了,自然也没办法剩下半根到第二天(西兰花则相对好处理一些,但放久了也不好吃),所以基本上无论胡萝卜大小,一律都在当天全处理了。加上一些做多了的西兰花和豇豆,每次狗子吃完饭之后还能剩下一碗的菜。

    这些菜就成了我晚上伙食的组成部分。

    说不上来为什么,中午的胃口越来越差,目前已经发展到了就算不吃饭也不会觉得有什么不舒服的地步了。反而因为中午不吃什么东西,晚上胃口还能好一些。每天下午喂完狗子,我俩玩儿上一会儿,我就出门开始了晚饭之旅。

    我把满满一碗煮好的蔬菜放进塑料袋,把袋口扎好,换好鞋,然后用手抓着袋子的提手,一悠一悠地前往下午想好的去处,完成我那丰富的晚餐。

    一开始去的最多的是土豆粉店,但我并不吃土豆粉,因为年纪大了,感觉吃了土豆粉有些不消化,夜里胃不舒服,所以点的是刀削面。口味也不是原味,因为原味有些微辣,所以选择了不辣的彼得番茄酥肉味儿。要一个带有一根烤香肠和热柚子汁(喝冷的胃也不是太行)的套餐,再让店员给加上一份额外的刀削面。一边吃一边往砂锅里续上面和蔬菜,这就是一顿丰盛的大餐了。感觉比直接去吃茄汁面要好吃的多。有时候赶上店家活动买一送一,实在是不可多得。

    后来常去那家土豆粉店的半路上新开了一家烩面店,开业酬宾九块九,买不了吃亏买不了上当。于是又拎着装满蔬菜的碗去体验了一下他们的试营业。这才发现,原来胡萝卜、西兰花、豇豆,和其他主食在一起是如此的百搭,不管拌什么,吃起来都不会觉得难吃。当然,也没有特别好吃就是了。

    就这样拎着菜悠着到饭店,再拎着碗悠着走回来,似乎过上了悠哉游哉的岁月静好。

    那天吃罢拎着袋子往回走,街边一家新开的甜品店正在做宣传,喇叭里放出了店家编写好的广告词。只不过相同的一句广告词,竟然有很多不同的声音来读,有孙悟空的,也有不知道叫什么的,更神奇的是还有能编成一段Rap的。我自认虽然不用抖音快手,更不怎么沉迷短视频,但多少也看过孙悟空声音的别的短视频。只是突然在街边挨个儿播放,里面还夹杂了不少我从没听过的,还是让我吃了一惊。隔天在微信上跟周航提起这事儿,他说这叫“网红音效”,我才知道原来这玩意儿居然还有名字。

    想一想,曾经父辈们没有跟上时代的时候,自己取笑过他们,也不耐烦过。对他们来说,可能是经济的原因,也可能是别的什么理由,让他们慢慢与世界脱了节。而我到底是为什么呢?主动放弃社交网络上的分享,因为短视频看久了头疼就直接拒绝掉了短视频的传媒模式,现在所有的表达只有拍些照片和录像在iCloud上分享给家人,以及在Blog上发些牢骚。每天拎着菜一晃一悠地去吃饭的样子,真的很像曾经的那些在单位食堂门前的路上,端着饭缸,埋头前行的叔叔们。那大爷的模样如同复制粘贴一般原封不动地移到了我自己的身上。

    于是我也成了个大爷。

    前几天梅龙高速的事故以及上个月悉尼购物中心的事件,让我和家人以及朋友有了很长一段时间的讨论。很多时候,他们都以为我想要讨论的是“是否应该去做英雄”或者是“如何才能安全地做英雄”。但实际上,我一直想讨论的是“如何操作才能让自己在这样的灾难发生时受到最小的伤害(包括心理伤害)”。可以说到了这个岁数,我已经完全丧失了做英雄拯救他人的勇气。也许是认识到了自己的渺小以及能力的不足,大多数时候如今的我觉得能保护好家人已经是很不容易的事了,再让我去做英雄那真的是万难从命了。如今想来,这可真是个地道的大爷的想法。当然还有那些勇敢的大爷,但我不是。

    不知道自己到底算是一个合格的大爷,还是已经败坏了大爷的名声。时至今日,不可否认的是我已经像一个大爷一样的生活了。没什么好说的,愿天下大爷都能延年益寿,心想事成吧。

  • 参加个活动

    参加个活动

    请描述一件您年轻时非常迷恋物品。 它的作用是什么?

    不知道为什么,好像过了四张以后越来越不能熬了。说好的“男人四十一枝花”怕不会是个向日葵吧?究竟是被动开始养生还是主动开始走下坡路看起来目前还是无解,只能等日后再看了。

    之前计划要写的Mastodon部署的日志怕是也要搁置下去了,眼下先扯点儿轻松的。Wordpress官方搞了个Bloganuary活动,看这尿性是要搞定题写作马拉松来着。姑且先参加一下权当放松写作了,毕竟总是写技术文章搞得人头很痛。

    这期的题目出的很有意思。要说我小时候特别想要并且求之不得的,可能擎天柱的变形金刚算是一个。当年我妈带着我,让穿制服戴贝雷帽的女售货员把擎天柱的主体从玻璃柜里拿了出来,放在柜台上给我看了看。这算是让我也满足了一下。可能我后来没那么迷恋变形金刚的原因也是和那天我超近距离地观察了擎天柱之后,觉得擎天柱太小了,颠覆了我心目中的伟岸形象有关吧。

    但这次要说的并不是擎天柱,而是一个冰箱文具盒。

    三十几年前的某天,在我还喜欢在新华书店里打发无聊的学前时间的时候,忽然我被书店橱柜里展示的一款文具盒吸引住了。说来也奇怪,那个时候的我对刀枪棍棒兴趣并不是很大,毕竟我拥有全院唯一的镇院神器:金刚铁棍(其实就一金属撬棒)。但我却对今天被称之为かわいい的玩意儿极感兴趣,和女生比有过之无不及。

    那是一个冰箱形状的文具盒,今天回想起来,应该不是台湾货就是日本货吧。打开冰箱门也就是文具盒盖,可以看到冰箱里丰富的各种小玩意儿。具体都有什么现在已经想不太清了,就记得有一个鱼形状的小笔记本,用塑封包装着,拆掉塑料皮理应是个很小的小本本,封面印着一条冻鱼—它应该是放在“冰箱”的冷藏室里。

    在那个还没有大规模普及,甚至市面上还没有出现过多功能文具盒的年代,这样一个造型独特内容丰富的文具盒一瞬间就让我动心了,那个柜台也成了我每次去新华书店必然流连忘返的场所。然而这样一个文具盒自然也价格不菲。具体多少价钱那时的我确实没啥概念,如果要让我猜的话,一个成年人一个月的工资怕是要有的吧。自然尽管我再想要,也只能在书店多看看。直到上了学之后慢慢把它放下、忘掉了。

    有很多没有得到的东西,在记忆里可能永远都是最好的。假如一旦得到了,可能那个光圈也就消失了,也就变的普普通通了。所以有些曾经求之不得的事物,最好还是让它们留在记忆里吧,那才是它们应当的归属。

  • 2024新年快乐

    2024新年快乐

    一晃23年就过的干干净净了,一秒钟也没有剩下来,倒是有些人却留在了2023。这会儿1月1号就剩15分钟了,我抓紧写两句,也算是对以前blogging传统的一个恢复吧。

    以前一直以为,微观时间的体验和宏观时间的体验是相对的。好比每天都很忙的人,会觉得一天的时间过的很快,而由于充实的生活,一年过去回过头再看的时候反倒会觉得过的内容太丰富,时间好像变长变慢了。相反每天都很无聊的人,会觉得一天时间过的很慢很煎熬,但由于枯燥空洞的生活千篇一律,一年过去回过头再看的时候,会觉得因为没啥可回忆的,时间倒又变短变快了。这个观念是我一直以来无比确认的。

    直到2023。

    23年对我来说,是奇特的一年,因为它颠覆了我上面所写的对时间体验的认知。具体来讲,在这一年里无论是宏观到一个月、一个季度还是一整年,又或是微观的一天、一个小时或是15分钟,时间都过得非常快,快到让我产生矛盾的感觉——当你相信你是忙的时候,宏观上的体验不符合的,又或是当你以为自己很闲的时候,微观上的体验也让人觉得意外。

    究其原因我是实在说不上来,只能说这也许是人到中年的一个现象吧,一切都开始飞速地往终点奔去。可能还能有机会慢下来,这是24年的一项任务了。

    身体状况也是个矛盾,以为自己有问题的地方一概没事,而觉得没有事的地方却总是时不时跳出来搞些小事情。24年无论如何也要把这些问题陆续解决掉。

    还有4分钟,最后还是预祝自己新的一年里能够事事顺利吧,当然还有家人能够身体健康,这就是我新年里全部的希望了。

    新年快乐!