作者: ianzhi

  • 使用Joplin作为博客后端-使用marked转换joplin笔记中资源文件的地址

    使用Joplin作为博客后端-使用marked转换joplin笔记中资源文件的地址

    joplin笔记中资源文件默认使用的是id,但是如果渲染到网页,需要转换为网络地址,记录一下处理过程。

    export async function transformMarkdown(markdown?: string) {
        if (markdown == null || markdown === '') {
            return ''
        }
    
        const renderer = new marked.Renderer()
    
        marked.use({
            async: true,
            async walkTokens(token) {
                if (token.type === "image") {
                    const id = token.href.replace(':/', '')
                    const resource = await joplinResource(id)
                    token.href = `${process.env.SITE_URL}/resources/${id}.${resource.file_extension}`
                    token.title = resource.title
                }
            },
            renderer: {
                image({ href, text, title }) {
                    return `<img src="${href}" alt="${text}" title="${title}" loading="lazy" />`
                }
            }
        })
    
        return await marked.parse(markdown, {
            renderer,
            gfm: true,
            breaks: false,
            pedantic: false
        })
    }
    
  • 使用Joplin作为博客后端-基于Joplin Terminal部署服务端REST API

    使用Joplin作为博客后端-基于Joplin Terminal部署服务端REST API

    Joplin Server本身虽然有接口,但是并不能直接获取笔记数据,了解后发现Joplin Terminal是支持Data API的,这样的话,可以通过在服务器部署一套Joplin Terminal程序来从服务器提供笔记数据,唯一的问题可能就是会导致服务器存储两份笔记数据,不过也不是很大的问题,这里以通过Docker容器部署为例。

    一、安装Joplin Terminal

    # 创建数据存储文件夹
    mkdir -p joplin/cli
    
    cd joplin/cli
    
    npm i joplin
    
    # 同步配置参考官方文档 https://joplinapp.org/help/apps/terminal/
    
    # 同步数据
    npx joplin sync
    

    二、启动Joplin的Data API Server

    修改项目的package.json,增加一个启动脚本。

    {
      "type": "module",
      "scripts": {
        "joplin": "joplin server start",
        ...
      },
      "dependencies": {
        "joplin": "^3.4.1"
      }
    }
    
    npm run joplin
    

    三、docker compose配置

    services:
        ...
        joplin-api:
            image: node:22.12.0
            restart: unless-stopped
            # 这个应该根据实际的uid和gid设置,与挂载目录的/home/test有关
            user: 1000:1000
            volumes:
                # 挂载这个文件主要是为了保持权限一致,避免本地修改容器不能运行
                - /etc/passwd:/etc/passwd:ro
                # 挂载项目代码
                - ./joplin/cli:/app
                # joplin数据保存位置
                - ./joplin/data:/home/test/.config/joplin
                - ./joplin/.npm:/home/test/.npm/
            # 这个start命令参考下面
            command: ["sh", "-c", "chdir /app && npm start"]
    

    四、转发请求,配置定时任务

    joplin terminal启动的data api默认是写死的绑定127.0.0.1,需要本地启动一个反向代理服务器来做一下请求转发,同时也配置一下定时任务。
    我这里服务器用的h3,用什么其实都可以,感觉JS的Web框架语法都差不太多,这里选h3主要是为了资源占用少。

    import { H3 } from "h3"
    import { createServer } from 'node:http'
    import { toNodeHandler } from "h3/node"
    import cron from 'node-cron'
    import { exec } from "node:child_process"
    
    /**
     * 运行node-cron定时任务
     * /30 * * * /path/to/joplin sync
     */
    cron.schedule('*/15 * * * *', joplinSync)
    
    /**
     * 同步数据
     */
    export async function joplinSync() {
      exec('/app/node_modules/.bin/joplin sync', (_, stdout) => {
        console.log('joplin sync: ', stdout)
      })
    }
    
    export const app = new H3()
    
    /**
     * 反向代理外界请求到本机的41184端口
     * joplin Data API Server默认监听41184,因为Docker环境,也不太可能出现冲突的问题
     */
    app.use(
      async (event) => {
        const { url } = event.req
    
        const proxyUrl = new URL(url)
        proxyUrl.protocol = 'http'
        proxyUrl.host = 'localhost:41184'
        const proxy = await fetch(proxyUrl.toString())
        return proxy.body
      }
    )
    
    createServer(toNodeHandler(app)).listen(3000, '0.0.0.0')
    

    五、完善启动脚本

    {
      "type": "module",
      "scripts": {
        "proxy": "node --experimental-strip-types index.ts",
        "joplin": "joplin server start",
        "start": "npm run proxy & npm run joplin"
      },
      "dependencies": {
        "h3": "^2.0.1-rc.2",
        "joplin": "^3.4.1",
        "node-cron": "^4.2.1"
      },
      "devDependencies": {
        "@types/node": "^24.7.1"
      }
    }
    

    六、后续

    后面其实就简单了,感觉直接开放到公共网络不是很安全,最好还是通过容器间通信使用,真正的权限鉴定放在h3这一层。

  • Shell遍历文件夹下所有文件,并将文件内容写入一个文件中

    Shell遍历文件夹下所有文件,并将文件内容写入一个文件中

    软件著作权要求提供代码文档,这里提供使用Shell遍历文件夹下所有文件,并将文件内容写入一个文件中的方法。

    #!/bin/bash
    dir="."
    target="./target.txt"
    # 过滤指定文件或文件夹
    filter=(node_modules out dist $target)
    
    listfile() {
        filelist=`ls $1`
        for file in $filelist
        do
            if [[ "${filter[@]}" =~ "$file" ]];then
                continue
            fi
    
            if [ -d $1/$file ];then
                listfile $1/$file
            else
                cat $1/$file >> $target
            fi
        done
    }
    
    listfile $dir
    
  • 波特五力模型

    波特五力模型

    mindmap
        id(五力)
            id(供应商的讨价还价能力)
            id(潜在竞争者进入的能力)
            id(行业内竞争者现在的竞争能力)
            id(替代品的替代能力)
            id(购买者的讨价还价能力)
    
  • MySQL常用SQL语句

    MySQL常用SQL语句

    记录一些常用的MySQL语句,方便查找翻阅。

    1. 查看MySQL数据库磁盘占用大小

    select 
    TABLE_SCHEMA as '数据库', 
    concat(truncate(sum(data_length)/1024/1024,2),'MB') as '数据容量(MB)',
    concat(truncate(sum(index_length)/1024/1024,2),'MB') as '索引容量(MB)'
    from information_schema.tables
    group by TABLE_SCHEMA
    ORDER BY data_size desc
    

    2. 查看MySQL数据库中表的磁盘占用

    select  
    table_schema as '数据库',  
    table_name as '表名',  
    table_rows as '记录数',  
    truncate(data_length/1024/1024, 2) as '数据容量(MB)',  
    truncate(index_length/1024/1024, 2) as '索引容量(MB)'  
    from information_schema.tables  
    where table_schema='bwc_plsedu_com'
    order by data_length desc, index_length desc;
    

    3. MySQL创建、删除用户,授权、撤销授权

    create user user@host identified by 'password';
    # 授权
    grant all privileges on db.table to user@host;
    # 取消授权
    revoke all privileges on test.* from 'user'@'host';
    #删除用户
    drop user 'test'@'127.0.0.1';
    # 刷新权限使授权生效
    flush privileges;
    

    4. 性能检查

    -- 查看当前连接
    SHOW PROCESSLIST;
    
  • 网页、APP跳转应用商店

    网页、APP跳转应用商店

    安卓

    1. 跳转到应用页面:market://details?id=
    2. 跳转到搜索:market://search?q=

    IOS

    1. 应用页面:itms-apps://itunes.apple.com/app/id 114211089
  • 财政部发行外国主权债券用途和意义是什么

    财政部发行外国主权债券用途和意义是什么

    财政部发行外币主权债券,核心用途与意义可概括为“四条主线、一个窗口”:

    1. 信用“体检”与定价锚

    通过市场化招标,让全球投资者给中国主权信用“打分”。利率越低,说明国际信任度越高;同时形成一条以中国主权为基准的美元/欧元收益率曲线,为所有中资企业海外发债提供定价参考,直接压降其融资成本。

    2. 人民币国际化的“迂回通道”

    先以美元、欧元计价吸引国际资本流入,让境外投资者先熟悉中国信用、积累持仓,再逐步引导其配置人民币资产,实现从“美元债”到“人民币债”的梯度转换。

    3. 外债结构与汇率风险管理

    主动调节外债的币种、期限结构:用美元债锁定较低利率,对冲未来人民币汇率波动风险;同时把部分短期商业贷款置换为中长期主权债,降低再融资压力。

    4. 高水平对外开放的“宣言书”

    连续在香港、巴黎、伦敦、沙特等地发行,向全球传递“中国持续开放、规则对接国际”的信号,巩固香港离岸中心地位,并带动中欧、中美、中东资本联动。

    5. 为宏观政策腾挪空间

    融入的美元/欧元资金可直接用于支持绿色低碳项目、科技创新补贴或基础设施建设,既补充财政资金来源,又避免过度消耗外汇储备,增强国家在外部冲击下的抗风险能力。

  • Linux有线未托管问题

    Linux有线未托管问题

    今天发现在用的一个Linux开发机一直不能自动连接有线网络,显示“有线未托管”,查找测试了很多文章的解决方案都无法使用,可能更新后有了一些变化或者各自情况不同,这里记录一下个人生效的处理方式。

    sudo vim /etc/netplan/00-installer-config.yaml
    
    #文件中添加
    renderer: NetworkManager
    
    sudo netplan generate
    sudo netplan apply
    sudo reboot
    
  • Linux服务器Swap配置

    Linux服务器Swap配置

    简单记录文件形式的Swap使用与配置方式。

    1. 交换文件大小配置原则

    1. 内存<2G,配置实际内存的两倍
    2. 内存>2G,配置为4G即可
    3. 内存>4G,追求极致性能,不需要配置交换

    2. 创建交换文件

    # 创建一个名称为swap的文件,大小为1GB
    # if 输入文件名称,此处使用/dev/zero即可
    # of 输出文件名称,使用期望的文件名即可
    # bs 同时设置读入/输出的块大小为多少个字节
    # count 拷贝多少个块,块大小等于bs指定的字节数
    dd if=/dev/zero of=/swap bs=1M count=1024
    
    # 配置交换文件权限
    chmod 0600 /swap
    
    # 将文件设置为交换文件
    mkswap /swap
    
    # 启用指定交换文件
    swapon /swap
    
    # 查看交换文件状态
    swapon -s
    
    # 添加交换文件自动挂载
    echo "/swap swap swap defaults 0 0" >> /etc/fstab
    

    3. 删除交换文件

    # 关闭指定交换文件
    swapoff /swap
    
    # 删除文件
    rm /swap
    
    # 删除自动挂载配置
    vi /etc/fstab
    
  • Google Chrome扩展开发

    Google Chrome扩展开发

    Chrome扩展开发者控制台

    1. 需要支付一次性的5美元
    2. 需要使用非国内卡

    参考:

    1. Chrome开发者网站
  • Electron中数据持久化的选择

    Electron中数据持久化的选择

    Electron是一个基于Chromium的桌面应用程序框架,它可以让开发人员在不需要熟练掌握Web开发技术的情况下,快速地开发出高质量的桌面应用程序。在Electron中,开发人员可以使用各种各样的数据存储方式,包括文件系统、数据库等。其中,数据库是一种非常常见的数据存储方式,它可以方便地存储和管理各种数据,包括文本、图片、音频、视频等。

    文件存储

    本地文件适合用来存储一些配置相关的信息,常见的可用格式比如JSON、INI、Yaml、Toml等。

    IndexedDB

    IndexedDB,我觉得更适合用于调用服务端接口的缓存,或者极少在主线程使用的数据,否则来回传递感觉性能可能不太高(未经测试,但是结论应该不会有错)。

    有朋友之前问到怎么在主线程中使用IndexedDB,直接使用是不可能的哈,毕竟那是暴露在浏览器中的,并没有相关的Node实现。不过,其实IndexedDB在Chrome中也是使用SQLite实现的,如果需要保持同构,只需要实现一个简单的数据库中间层来隐藏底层的API或者按照IndexedDB的API来封装一下SQLite的调用即可。

    SQLite

    使用SQLite作为数据库可以让Electron应用程序更加轻量级和易于管理。SQLite是一种基于文件的数据库系统,它可以在不需要安装任何额外软件的情况下,在本地运行和管理数据库。这意味着,开发人员可以在Electron应用程序中使用SQLite数据库,而不必考虑复杂的数据库管理和同步问题。此外,SQLite还支持多种数据模型和查询语言,这可以让开发人员更加方便地存储和管理各种数据。 使用SQLite作为数据库还可以让Electron应用程序更加安全。由于SQLite是一种基于文件的数据库系统,它不会占用过多的系统资源,因此可以在不影响应用程序性能的情况下,存储和管理大量的数据。此外,SQLite还支持数据加密和数据备份,这可以让开发人员更加方便地保护应用程序数据的安全。 总之,使用SQLite作为数据库可以让Electron应用程序更加轻量级和易于管理,同时还可以让应用程序更加安全。如果您正在使用Electron开发桌面应用程序,并且需要存储和管理大量的数据,那么使用SQLite数据库将是一个非常不错的选择。

    其他(LocalStorage/SessionStorage)

    当然渲染进程还是可以使用LocalStorage这些,使用相对IndexedDB就方便很多,只是有大小限制,适合存储用户级别的个性化缓存数据(主题、语言等),其他类型的数据就不是很推荐了。

  • MySQL8 GTID双主配置

    MySQL8 GTID双主配置

    记录一下MySQL8中配置GTID双主的方式。

    需要添加以下配置信息:

    vim /etc/my.cnf
    # 添加
    [mysqld]
    # 两台服务器的server-id不能一致
    server-id=1
    gtid_mode=on
    enforce-gtid-consistency=true
    

    具体使用到的SQL语句:

    # 创建一个账号用于另一台主机复制数据
    # create user 'slave'@'0.0.0.0' identified by 'this is your password';
    
    # 授权
    grant REPLICATION SLAVE on *.* to 'slave'@'0.0.0.0';
    
    # 查看主机状态
    SHOW MASTER STATUS;
    
    # 以下为另一台服务器执行内容
    CHANGE REPLICATION SOURCE to
        SOURCE_HOST = '0.0.0.0',
        SOURCE_PORT = 3306,
        SOURCE_USER = 'slave',
        SOURCE_PASSWORD = 'this is your password';
    
    # 停止并重置复制
    STOP REPLICA;
    reset REPLICA;
    
    # 开始复制并查看复制状态
    START REPLICA;
    SHOW REPLICA STATUS;
    
  • PHP内置服务器与Serverless

    PHP内置服务器与Serverless

    PHP从5.4版本开始就提供了一个内置的WEB服务器,可以通过一个简单的命令php -S启动一个WEB服务器,极大简化了开发环境的搭建。

    到目前为止,官网文档对于内置服务器的使用依然建议用于开发环境,不建议用于生产环境,原因倒是很容易理解,主要有两个方面:

    1. 支持的MIME类型很少,5.4版本放出时只支持.htm和.svg(从5.5版本完善了大部分常见的MIME类型支持)

    2. 仅实现了基本功能,基本没有任何优化,是一个单线程进程(不过从7.4版本开始,内置服务器支持多进程的运行方式)

    从传统开发角度看,这样性能和功能的服务器确实很难应用于生产环境,但是伴随着Serverless的发展,感觉内置服务器的限制突然不是那么重要了。

    使用Serverless服务,不管是AWS Lambda,Google Function,还是国内阿里云的函数计算、腾讯云的云函数,我们关注的点不再聚焦于单机性能释放,而是变成了以下四个方面,我们要做的本质上变成了降低单请求的资源占用和执行时间

    1. 调用次数

    2. CPU时间

    3. 内存占用

    4. 执行时间

    5. 带宽

    我们可以逐个对比以下,

    1. 调用次数显然很难因为WEB服务器的变化有什么变化

    2. CPU时间上,内置服务器作为一个单进程应用,同样的逻辑在函数计算这样的环境下,较少了Nginx与FPM交互的网络开销、Nginx的运行开销,理论上内置服务器应该表现更好

    3. 内存占用方面,内置服务器不再需要运行Nginx,同样逻辑,应该也比传统部署方式占用更少一些

    4. 执行时间,Nginx+FPM需要启动两个进程,需要两个进程间的通信,很难与直接启动PHP进程更快

    5. 带宽基本不用对比,应该不会有什么变化,gzip完全可以在CDN层来实现

    从Serverless的角度看,内置服务器并不算是一个很差的选择,对比传统的运行方式可能更加合适一些,就是不太清楚不建议生产环境使用是否有除性能外的其他原因,回头去翻一翻PHP的issue。

    参考文章

    1. PHP-Built-in web server(https://www.php.net/manual/en/features.commandline.webserver.php

  • Nextcloud安全最佳实践

    Nextcloud安全最佳实践

    1. 复杂密码
    2. Suspicious Login
    3. 两步认证,启用至少一项
      1. *Two-Factor TOTP Provider
      2. *Two-Factor Authentication via Nextcloud Notification
      3. *Two-Factor WebAuthn
      4. Two-Factor Email
  • PostgreSQL常用SQL语句

    PostgreSQL常用SQL语句

    PostgreSQL与MySQL语法有一些细微差异,记录一下PostgreSQL常用的SQL语句。

    1. 创建数据库、用户,并授予用户权限

    # 创建用户并指定owner(不指定owner,对应的用户授权了也看不见)
    CREATE DATABASE xxx owner xxx;
    create user test with password 'test';
    
    # 授权
    GRANT ALL PRIVILEGES ON DATABASE xxx TO xxx;
    GRANT ALL PRIVILEGES ON all tables in schema public TO xxx;
    GRANT ALL ON SCHEMA public TO xxx;
    GRANT USAGE ON SCHEMA public TO xxx;
    
    # 重载配置,让修改生效
    SELECT pg_reload_conf();
    

    2. 删除数据库

    如果有授权信息,删除数据库时会报错,要删除数据库需要先取消授权。

    # 禁止连接
    UPDATE pg_database 
    SET datallowconn = 'false' 
    WHERE datname = 'xxx';
    
    # 关闭已连接进程
    SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE datname = 'xxx';
    
    # 取消授权并删除用户
    revoke all on database postgres from xxx;
    revoke all on all tables in schema public from xxx;
    revoke all on schema public from xxx;
    revoke usage on schema public from xxx;
    
    # 删除用户(不取消授权也无法删除用户)
    drop role xxx;
    
    # 重载配置,让修改生效
    SELECT pg_reload_conf();
    

    3. 重命名用户、数据库

    # 重命名用户
    ALTER USER name RENAME TO new_name;
    
    # 重命名数据库
    ALTER DATABASE name RENAME TO new_name;
    

    4. 修改密码

    ALTER USER xxx WITH PASSWORD 'xxx';
    

    5. 其他常用

    # 统计当前所有连接数
    select count(1) from pg_stat_activity;
    
    # 查询当前连接数详细信息
    select * from pg_stat_activity;
    
    # 查询最大连接数
    show max_connections;
    
  • 摩根·豪泽尔写给普通人的30条财富思考:对金钱认知有多高,人生就有多自由

    摩根·豪泽尔写给普通人的30条财富思考:对金钱认知有多高,人生就有多自由

    在投资大师的演讲对话中,除了巴菲特芒格之外,投资圈里最爱的大约是霍华德·马克斯。

    去年8月听霍华德·马克斯跟摩根·豪泽尔(Morgan Housel)做了一档播客对话,非常精彩。

    得说,摩根·豪泽尔的补充视角和输出语言,是整个对话的亮点,也理解了霍华德为什么会说,他常常从摩根那里获得启发。

    可能真的不是客套。

    摩根是美国合作基金( Collaborative Fund)合伙人、畅销书作家,曾两度获得美国商业编辑和作家协会的最佳商业写作奖。

    2020年,他的代表作《金钱心理学》用生活化的观察揭示金钱、人性与幸福之间的微妙关系,通俗而深刻的文本让这本书在全球畅销800万册,被翻译成50多种语言。

    豆瓣超过1万读者打出8.2高分。

    今年,摩根带来了新作《金钱的艺术》。如果说《金钱心理学》聚焦的是“如何积累财富”,那么这本新书则进一步追问:财富该如何被使用?

    书中通过大量真实案例、心理学研究和历史故事,揭示金钱与人性、幸福、生活方式的深层联系,直指那个更根本的问题——“金钱怎样用,才能让人过好一生?”

    摩根·豪泽尔的财富观深受个人经历的影响。

    童年时期,他的家庭并不宽裕。父亲直到四十岁出头才成为医生,而那时家里已经有了三个孩子。为了养家,父母不得不过着极度节俭的生活。

    后来,在急诊室工作了20年的父亲毅然选择辞职,用积蓄换来更自由的生活方式。

    对年少的摩根而言,这一决定带来的冲击极为深刻:钱最大的意义,不在于拥有更多,而在于关键时刻能赋予人选择的自由。

    这种体悟,也延伸到他的个人生活。家庭对他来说至关重要,他始终坚信,真正的幸福不在于物质堆砌,而在于陪伴与情感。

    他与妻子志趣相投,喜欢徒步、园艺、读书等低成本的活动,保持着简朴的生活方式。

    他们坚持储蓄和投资,把理财视为保障家庭幸福、实现自由生活的工具。

    相比那些出身显赫、履历耀眼的金融精英,摩根的经历平实普通。但正是这种平凡,让他对金钱的理解更接近普通人。

    他的两本书贯穿着一个核心信念:金钱并非简单的数字游戏,而是与家庭、选择和幸福紧密交织的生命体验。

    最宝贵的资产:不用取悦任何人的自由

    在《金钱的艺术》中,摩根把金钱和自由紧密联系在一起。他认为,金钱能带来的最大好处,不是奢侈享受,而是“不用取悦任何人的自由”。

    书中有个经典故事。

    1968年,伦敦《星期日泰晤士报》举办了一场环球帆船赛——谁能第一个完成单人无停靠环球航行,就能成为“史上最伟大的水手”。

    参赛者中有两个人格外特别:唐纳德·克劳赫斯特和伯纳德·穆瓦特西耶。

    克劳赫斯特是个业余水手,几乎没什么经验,却把比赛当成翻身的机会。

    他与商人合作,承诺制造“媒体狂欢”,即便船只状况糟糕,他也硬着头皮出发。航行中,他发现自己根本无法完赛,却因害怕破产和丢脸不敢退出,只能伪造航行坐标。

    直到他“意外领先”,眼看骗局将要暴露,他在日记里写下“游戏结束”,然后消失在大海中。

    穆瓦特西耶则完全不同。他是资深航海家,比赛时正处于夺冠的领先位置,却在中途突然决定退赛。

    他在日记中写道:“一想到要回到欧洲那个‘蛇洞’,我就觉得恶心。我厌倦了那些虚伪的偶像,它们像蜘蛛一样啃噬我们的灵魂。”

    他拦下一艘商船,递上给报社的信:“我要继续驶向太平洋,因为我在海上感到幸福,或许也是为了拯救我的灵魂。”

    他最终在塔希提岛定居,过上了种地、写作、远离喧嚣的生活。

    摩根的评价是:克劳赫斯特活在他人的期待里,最后把自己逼上绝境;穆瓦特西耶只为自己而活,放弃了荣耀,却赢得了自由。

    “金钱最宝贵的用途,就是帮你成为穆瓦特西耶——拥有不用取悦任何人的自由。”

    摩根坦言,年轻时的“富有”对他意味着更多玩具,而如今,“富有”意味着可以不必匆忙,可以自由安排时间,可以与家人共处,可以思想独立。

    简而言之,就是按照自己的方式生活。

    如何用金钱获得这样的自由?

    摩根提出一个简单的方法:把储蓄视为“自由的门票”。

    你存下的1000美元,不只是未来的零花钱,而是拒绝一份讨厌工作的资本;你存下的1万美元,不是用来买奢侈品,而是未来陪伴家人的底气。

    他说:“你未曾花掉的钱,买到的是某种无形却弥足珍贵的东西:自由、独立,以及按照自己意愿支配时间的能力。”

    那么,如何在“活在当下”和“为未来储蓄”之间取得平衡?

    摩根给出的答案是:尽可能减少未来的遗憾。这意味着既不为短期的享乐透支未来,也不因过度节俭而错失当下。

    他提出了两条实践策略。

    第一,用金钱换时间,积累“回忆复利”。与其攒钱买奢侈品,不如花在能沉淀为记忆的体验上,比如旅行、陪伴孩子成长。哪怕少赚一些钱,换来更多自由时间,也能在未来带来更大的满足。

    第二,把储蓄视为购买独立与安心的投资。储蓄不仅是财富积累,更是心理安全感。

    书中提到,前橄榄球运动员约翰·厄舍尔职业生涯仅赚60万美元,却靠坚持储蓄实现了财务自由,退役后攻读博士,最终成为麻省理工学院教授。

    正是储蓄,让他有勇气选择自己真正想要的人生。

    金钱不是用来讨好别人的,而是用来赢得选择权的。你存下的每一元,都是一张写着“自由”的门票。

    财务独立的十五个层级:从“依赖他人”到“掌控人生”

    说到财务自由,人们常把它想象成亿万富翁的特权。

    但摩根·豪泽尔提醒我们:财务独立不是“你有多少钱”,而是“你能多大程度掌控自己的人生”。

    在《金钱的艺术》中,他提出了“财务独立的0到15级”,从完全依赖他人到随心支配时间,每个等级都对应着一种掌控力,每个人都能在这份清单里找到自己的位置。

    第0级:完全依赖陌生人的善意,毫无掌控力。

    第1级:依赖家人、朋友或慈善的救助才能生活。

    第2级:依赖政府或社会保障体系维持生计。

    第3级:靠工作养活自己,但一旦失业就陷入困境。

    第4级:有少量储蓄,能短期应对意外开支。

    第5级:积蓄能支撑几个月,即使暂时失业也不至于崩溃。

    第6级:技能或职业有一定不可替代性,不易被取代。

    第7级:能拒绝糟糕的老板或工作,真正拥有选择权。

    第8级:即使换城市、换行业,也能凭储蓄和能力顺利过渡。

    第9级:拥有稳定的资产或副业收入,减少对单一工作的依赖。

    第10级:储蓄和投资足以覆盖数年的生活成本。

    第11级:即便遭遇金融危机或行业衰退,也能从容应对。

    第12级:被动收入足以覆盖基本生活开支,不再依赖工作生存。

    第13级:储蓄和资产支撑的不仅是温饱,而是理想的生活方式。

    第14级:财富充裕到足以支持你做任何想做的事。

    第15级:完全自由,能随心所欲支配时间,按照自己的方式生活。

    摩根强调,财务独立并非一步到位,而是一个循序渐进的过程。你不需要立刻到达第15级,只要每年向上迈一级,十几年后就能获得真正的自由。

    例如,当下你处在第3级,可以通过攒下几个月的生活费提升到第4级;再提升技能,就能进到第5级。

    每一次储蓄的积累、每一次开支的优化,都是迈向自由的一小步。

    独立并不是非黑即白,而是一条光谱。每个人能走到哪里并没有标准答案,取决于你的价值观和对自由的渴望。

    但重要的是意识到:无论收入多少,你都可以主动购买独立。

    每一元的储蓄都像是一张看不见的“门票”,为你换来不必取悦他人的底气,换来陪伴家人、追求兴趣、自由支配时间的能力。

    “财务独立的核心,不是‘赚更多钱’,而是‘减少对金钱的依赖’——你依赖金钱越少,就能越自由。”

    静默复利:最快的致富方式,是慢慢来

    “如果你现在有1万元,每年能获得8%的收益,30年后会变成10万元;如果坚持50年,就会变成47万元。”

    摩根·豪泽尔在《金钱的艺术》中用这样一个简单的计算,揭示了“静默复利”的力量——那就是“慢慢来”的智慧。

    书中有一类人物被称为“草根富豪”。

    他们没有耀眼的学历,从事的是普通甚至低薪的工作,却在几十年间,通过持续储蓄和投资,积累出数百万乃至数千万的财富。

    他们的共同特征是:从不炫耀,从不攀比,也不在意自己的投资组合是否跑赢指数。他们把注意力放在家庭和生活上,遵循自己的节奏,不被外界裹挟。

    摩根认为,这种“淡定与耐心”就是他们的超能力。

    “静默复利”的关键,在于长期坚持。

    以巴菲特为例:巴菲特的年均投资回报率只有20%,并不比一些对冲基金经理高多少。但他坚持投资了60多年,是复利的奇迹造就了他如今的财富传奇。

    巴菲特的秘诀不是聪明,而是耐心。他愿意花一年时间研究一家公司,再用几十年去持有它。

    摩根认为,复利并不需要复杂的技巧,而是极其简单的三点:

    第一,尽早开始。复利的力量来自时间的积累。开始得越早,哪怕金额很小,也能靠长期增长获得惊人的结果。

    摩根强调:“你不需要一开始就存很多钱,哪怕每月只存100美元,只要坚持,最终都会积少成多。”

    第二,保持稳健。很多人被高收益的诱惑吸引,却忽视了风险。

    摩根提醒,投资不是一场“短跑”,而是一场“马拉松”。选择稳健、长期的资产,耐心等待时间发挥作用,才是复利的真正秘诀。“投资的目标不是一次赚很多钱,而是一直能赚钱。”

    第三,少做决策。频繁操作是复利的大敌。无论是频繁买卖,还是不断更换策略,都会让你在情绪驱动下犯错,甚至抵消复利的效果。

    最好的做法,是在选择好资产之后,安静地持有它,让时间替你完成剩下的工作。

    静默复利是摩根最珍视、最重要的财务信念,因为它如此简单,却非常强大。

    当“静默复利”成为你的目标时,你就不再为他人表演,不再担心短期的得失,而是把目光投向长远的未来。它培养的,正是理财最稀缺的能力——耐力。

    最快的致富之道,其实是慢慢来。

    附:摩根•豪泽尔的30条财富思考

    1. 金钱并非简单的数字游戏,更关乎“故事”——我们对什么重要、什么能带来快乐,以及如何衡量成功的自我叙述。

    2. 理解我们自身的情绪——偏见、期望与恐惧——能够引导我们做出更明智的决策,那些真正契合我们身份、价值观与生活方式的决策。

    3. 没有独立的财富是一种特殊形式的贫困。

    4. 曾经“富有”对我来说意味着拥有许多炫目的玩具。而现在,它意味着不必匆忙,能与家人共度时光,掌控自己的日程,以及思想上的独立。简而言之,就是按照自己的方式生活。独立,才是真正的富有。

    5. 对我而言,独立拥有最高的投资收益率,远超我花钱购买的任何其他东西。

    6. 你未曾花掉的钱,买到的是某种无形却弥足珍贵的东西:自由、独立,以及按照自己的意愿支配时间的能力。你储蓄的每一美元,都为你未来的选择买下了一张“兑换券”。

    8. 最快的致富之道,是慢慢来。

    9. 要意识到,来得快的财富也是易逝的财富。

    10. 我强烈建议你这样做:在预算允许的范围内,尽可能多地尝试各种花钱方式,对那些对你没用、无法带来价值的项目,要毫不犹豫地进行割舍。

    11. 积累长期财富与那些重大、英明的决策关系不大,而更多地与那些微小、持续的决策在长时间内复利累积有关。

    12. 在金钱方面做得好,很大程度上在于理解“杠铃策略”。像悲观主义者一样储蓄,像乐观主义者一样投资。**做最坏的打算,期待最好的结果。**活在当下,为明天做准备。

    13. 如果不控制你最大的开销,几乎不可能积累财富;而如果不关心小额开销,也很难增加财富。

    14. 使用金钱的方式有两种。一是将其视为改善生活的工具,二是将其视为衡量自己与他人地位的标准。许多人向往前者,却用一生去追求后者。

    15. 长久的幸福源自内心的知足与平和。金钱的最佳效用在于,它应该是助力你实现自我、放大人生价值的杠杆,而非用来定义你的身份、衡量自身价值的标尺。

    16. 不要让任何人告诉你,钱该花在哪里或者不该花在哪里。这个世界上根本不存在所谓的正确方式。你必须弄清楚,什么能真正让你感到快乐和满足。

    17. 一种健康的金钱观,是尊重的他人经历,珍视自己的处境,并明白只要掌握足够的信息,所有行为都有其合理性。

    18. 真正的快乐,是在你停止追问“我还缺少什么”的那一刻开始的。一旦意识到这一点,你就会不再执着于“我还缺什么”,而是投入更多时间去享受“我已经拥有的一切”。

    19. 金钱带来的最大陷阱之一,就是不停地追逐那些你尚未拥有的东西。

    20. 美好生活的很大一部分,源于那些未曾发生的事。未曾发生的争吵,未曾染上的疾病,未曾纵容的欲望,未经承受的高消费生活,未曾犯下的错误,以及未曾有的遗憾。

    21. 衡量财富的最佳标准是你所拥有的减去你想要的。

    22. 财富的真正定义,不在于你拥有多少,而在于“拥有”和“渴望”之间的差距。

    23. 社交债务,就是当你的消费方式不经意间影响了他人对你的看法时所产生的一种无形负担。

    24. 金钱有一个容易被忽视的问题:资产易于衡量,而负债却可能深藏不露。

    25. 关键在于,一旦金钱从一种让你获得幸福的工具,转变为他人衡量你的标准,你就已经输掉了这场游戏。

    26. 金钱永远应该是助力你实现自身价值的工具,而不是目标本身。

    27. 让金钱停止作为工具,而成为主宰的最常见方式之一,就是当你的财务目标和信念成为你身份认同的一部分。

    28. 关于理财的好建议,从来不是简单地说“活在当下”或“为未来储蓄”,真正有价值的建议只有一句话:“尽可能减少未来的遗憾。”

    29. 嫉妒他人所拥有的东西,并认为如果你像他们一样生活就会更好,是一种误导,因为你并未看清他们生活的全貌。

    30. 对许多人来说,金钱是财务上的资产,也是心理上的负债。对“更多”的盲目渴望会劫持你真实的身份,控制你的个性,挤占那些能带给你更大快乐的生活空间。

  • ESG概念解释

    ESG概念解释

    ESG 是“环境(Environmental)、社会(Social)、治理(Governance)”的缩写,是一套衡量企业可持续发展能力的非财务指标,也是现代投资与企业管理的核心理念之一。它要求企业在追求经济效益的同时,必须对环境影响、社会责任和内部治理做出系统考量。

    主要构成

    • 环境(E)维度: 评估企业对自然环境的影响,包括碳排放、能源消耗、废物管理、资源利用效率、生物多样性保护以及环保法规的遵守情况。例如,一家公司通过采用可再生能源和节能减排技术,降低温室气体排放,就体现了良好的环境绩效。
    • 社会(S)维度: 衡量企业与各利益相关方的关系,涵盖员工福利、消费者权益保护、供应链管理、社区参与、公益慈善、数据隐私安全等方面。比如,提供安全健康的工作环境、尊重消费者权益、积极参与社区建设等。
    • 治理(G)维度: 关注公司的治理结构与运作规范,包括股权结构、董事会职能、管理层激励机制、信息披露透明度、商业道德、风险管理等。例如,建立独立董事制度、完善内部控制体系、及时准确地披露信息等。

    起源与发展

    ESG 理念的雏形可追溯至1999年,时任联合国秘书长科菲·安南在达沃斯论坛提出倡议,推动全球契约组织(UN Global Compact)的成立。2004 年,该组织在《关怀者胜》报告中首次系统提出 ESG 概念,将其作为衡量企业可持续发展能力的框架。此后,ESG 从最初的投资风险管理工具,逐步演变为全球企业经营与投资决策的核心标准。

    核心价值与意义

    • 对企业:践行 ESG 有助于降低合规风险、优化成本、提升品牌声誉、增强员工归属感,并拓展长期盈利空间。
    • 对投资者:ESG 提供了一套超越财务数据的评估维度,帮助识别更具长期价值的标的,实现可持续投资回报。
    • 对社会:通过引导资本流向环境友好、社会责任强、治理规范的企业,ESG 推动了经济、社会与环境的协调发展,助力实现联合国可持续发展目标(SDGs)。

    应用现状

    目前,ESG 已成为全球资本市场的主流理念。海外资管巨头如贝莱德、全球交易所及评级机构均将 ESG 纳入投资决策。在国内,沪深北交易所已发布可持续发展报告指引,香港联交所也推出气候信息披露新规,标志着 ESG 信息披露和投资实践进入落地阶段。

    简言之,ESG 是一种兼顾经济、环境、社会和治理效益的长期价值理念,旨在推动企业与社会共同实现可持续发展。

  • MySQL给已存在的主键字段添加自增AUTO_INCREMENT

    MySQL给已存在的主键字段添加自增AUTO_INCREMENT

    每次都记不起来,记录一下…

    # 添加自增约束
    alter table table_name modify column COLUMN_NAME COLUMN_TYPE auto_increment;
    # 配置自增起始值
    alter table table_name auto_increment=10000;
    
  • PHP中对象缓存方式的选择

    PHP中对象缓存方式的选择

    类似于Map的键值类型对象缓存对于提高应用的性能有很大的作用,实现此类缓存的方式也比较多,那么该如何选择对象缓存的方式呢?由于PHP常用的运行方式主要是基于FPM的形式,这篇文章暂不考虑常驻内存形式的缓存。

    一、基于文件系统实现缓存

    这应该是比较常见的一种形式,基于文件系统的缓存优点:

    • 不需要安装额外的扩展、中间件
    • 支持几乎所有运行环境
    • 支持文件锁

    缺点:

    • 相对内存形式的缓存方式,性能一般
    • 存在并发读写时,性能极差(并发写,使用文件锁的情况)
    • 占用磁盘容量
    • 不好统计键调用次数等

    适合的场景:单机运行,单键极少写请求,需要持久化的情况,比如动态页面的静态化。

    二、基于数据库实现缓存

    优点:

    • 支持几乎所有运行环境,仅需要安装对应数据库的驱动程序,大部分环境默认提供至少一种数据库驱动程序
    • 支持锁
    • 方便进行复杂的查询统计

    缺点:

    • 作为最常遇到的性能问题点,不太适合用于缓存场景
    • 读写性能一般

    适合的场景:无法控制宿主安装程序或者扩展。

    三、基于Redis/Memcached等中间件实现缓存

    优点:

    • 读写性能好
    • 支持集群运行
    • 支持多数据结构(Redis)
    • 本身支持缓存淘汰策略

    缺点:

    • 需要额外的中间件
    • 需要额外的扩展、包支持
    • 大多数主机环境不支持(可喜的是随着公有云的发展,主机环境正在被新的虚拟化方式替代)

    适合的场景:只要支持安装,适合绝大多数场景。