Eric 发布的文章

提问,是AI时代最硬的计算机技能

IMG_3648.jpg

前阵子和朋友聊起他孩子读大专计算机的事。我们最后的结论很一致:让AI当你的私人导师。现在大模型讲很多知识点,比课堂更细、比教材更贴你的水平。但前提是——你得会提问。

这一点,中国学生普遍吃亏。大家习惯等别人提问,或者自己闷头搜索。太慢了。提问本身就是一种信号:说明你对现状已经花了心思去理解,只是还有卡点。这恰恰是真正理解一个问题的起点。

那提问能力怎么来?本质是一个反复确认的过程:你以为的状态、实际的状态、你不确定的部分,三者不断碰撞。大脑在这个循环里整理、分析,最后生成新的认知。有了AI之后,获取知识变便宜了,但想把一个问题挖透,靠的是不断往下追问。

我最近用大模型学PyPots,深有体会。以前看书、看文档,写的人默认你懂某些前置知识,可那些我恰恰没概念。于是我先让模型给我讲整体框架,包含哪些模块;再逐个拆开,遇到没接触过的就让它展开,多举例子,讲清楚"为什么发明这个概念、前提是什么"。最后它帮我整理成一份适合我自己的文档——每一条从"我不会"开始,直到我把疑问全部划掉,才算真懂。

当然,分支无限,不可能全追到底,有些地方要懂得打住。

这套方法我反复用,总结成一句:从框架讲起,逐层深入到细节,消化完再往下走。这是一个不断提问、不断深挖的迭代过程。过程中还能让它画图、从最基础讲起、举大量例子——以前没有哪个老师能为你一个人讲到这个程度。

所以在我看来,会提问,就是AI时代最重要的自学能力。

记录小米路由器刷 openWRT 并配置代理等操作

自从感觉到 chatGPT 基本能覆盖技术的方方面面, 就不太愿意写博客了. 但是记录一下路由器的设置和操作, 还是很有必要的, 主要方便自己以后重新设置方便.

一开始搬到这边后, 只有一个移动的光猫. 但是在另外一个房间, 总是信号不好. 于是买了一个华为的穿墙路由器, 通过网线连接到移动光猫. 过了半年, 感觉离路由器较远的一个房间还是信号不好, 小孩上网课会卡顿. 于是又买了一个小米的路由器, 改成小米路由器通过网线连移动光猫, 然后华为路由器通过桥接连小米路由器. 这样终于信号不错了. 再后来, 公司的 Proxy 不能用了, 即便在公司电脑上. 于是想在路由器上假设透明代理. 查了下, 发现小米路由器可以ssh, 于是折腾开始了.

给小米路由器装openWRT

有人做了全自动的破解安装ssh, 和安装 openWRT: https://github.com/openwrt-xiaomi/xmir-patcher. 一个 run.sh 或者 run.bat 完全搞定.

openWRT 的基本设置

修改网段

openWRT 的默认网段是 192.168.1.x. 移动路由器也是 192.168.1.x, 虽然一个是在lan, 一个是在wan口, 理论上没影响, 但还是把openWRT上的 192.168.1.x 改成了 192.168.31.x. 这也是小米最初的设置.

修改时区和NTP server

System -> System
时区 -> ntp.aliyun.com, ntp.tencent.com 等.

修改wifi通道

Network -> Wireless -> 选择 SSID -> Edit -> Operating frequency & Country Code

修改 DNS

安装完之后, 刷小红书视频有时候会卡住, 不知道为什么, 猜测可能是openWRT 的默认英文版本里面的 DNS 是国外的, 于是修改 DNS 配置. 在 /tmp/resolv.conf.d/resolv.conf.auto 里面添加国内的 DNS servers

公共 DNS 服务

服务商主要地址特点适合场景
阿里云 DNS223.5.5.5
223.6.6.6
速度快、稳定性好综合最佳
腾讯云 DNS119.29.29.29
182.254.116.116
响应快、干净无劫持日常使用
百度云 DNS180.76.76.76智能解析、抗污染技术用户
114 DNS114.114.114.114
114.114.115.115
老牌稳定、覆盖广基础使用

运营商 DNS

运营商DNS 地址特点
中国电信218.85.152.99
218.85.157.99
本地化最优
中国联通123.123.123.123
210.21.4.130
延迟最低
中国移动211.136.192.6
211.136.192.7
移动网络专用

恢复系统

很多时候, 发现安装某个软件之后, 网络就慢,或者有问题, 可以从头再来. System -> Backup / Flash Firmware -> Flash new firmware image. 这个image 可以从 https://openwrt.org/inbox/toh/xiaomi/ax3000t 安装部分(Installation) -> Firmware OpenWrt Upgrade URL 下载.

诊断 Python 占用一个 CPU 的问题

早上刚打开 MAC 笔记本 5分钟, 就提示我电池快没电了, 于是感觉给它供电. 紧接着, 就听到风扇呼呼作响, 于是查看 Activity Monitor, 发现有个 Python 进程几乎占用一个CPU, 感觉有 bug, 也许是项目的那个代码没写好. hmm, 生产环境不会也是这样吧?

Activity_Monitor.png

先确定进程信息

有了进程号, 进程很容易确定.

% ps aux  | grep 24315
xiatian          24315  99.3  0.0 36938856   9804   ??  R    Mon10PM 1044:13.73 /usr/local/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python /Users/supra/work/projects/agent-ui/main.py

再做 CPU profiling

py-spy 是一个非常流行的采样 profiler,可以在不修改代码的情况下分析任何正在运行的 Python 程序。

pip install py-spy
py-spy record -o profile.svg --pid 24315

火焰图如下:
profile_svg.png

前面三行都是 Python 自带 python3.11/threading.py 里面的代码. 最后一行是 concurrent/futures/thread.py) 的代码, 代码如下:

    try:
        while True:
            work_item = work_queue.get(block=True)
            if work_item is not None:
                work_item.run()
                # Delete references to object. See issue16284
                del work_item

                # attempt to increment idle count
                executor = executor_reference()
                if executor is not None:
                    executor._idle_semaphore.release()
                del executor
                continue

            executor = executor_reference()
            if _shutdown or executor is None or executor._shutdown:
                # Flag the executor as shutting down as early as possible if it
                # is not gc-ed yet.
                if executor is not None:
                    executor._shutdown = True
                # Notice other workers
                work_queue.put(None)
                return
            del executor
    except BaseException:
        _base.LOGGER.critical('Exception in worker', exc_info=True)

看上去从 work_queue.get(block=True) 拿 item , 每次拿到的都是 None. 那么下一个问题就是这个 work_queue 从哪里来的, 为什么会以极快的速度返回一个 None?

交叉验证

要回答上面的问题, 就要深入内存去看这个 work_queue 从哪里来的, 它引用了那些对象, 哪些对象还在引用它. 这样才能确定这个 work_queue 有什么问题. 但是, 在此之前, 我们可以去production 看一下, 看看在prod 的 Linux 上是不是有类似的问题, 结果发现完全没问题, 并且它运行的时间更长.

于是猜测, 这个问题难道只是个 MAC 有关? 或者和 MAC 休眠有关?

github 使用 personal access token 认证

最近又因为这件事情折腾半小时, 索性记录下来.

  1. 因为公司电脑有防火墙或者公司电脑访问策略的问题, 不能使用 git 协议访问 github.com 的 push/pull, 所以只能使用 https 协议, 比如: https://github.com/int0x03/samples.git
  2. github.com 已经禁止使用账户加密码来操作 git push/pull, 看这里: https://docs.github.com/en/get-started/git-basics/about-remote-repositories#cloning-with-https-urls
  3. 如果使用用户名 + 密码会出现下面的错误:

    git push origin master
    Username for 'https://github.com': int0x03
    Password for 'https://[email protected]':
    remote: Support for password authentication was removed on August 13, 2021.
    remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
    fatal: Authentication failed for 'https://github.com/int0x03/samples.git/'
  4. 所以要先添加 personal access token 然后把 token 做密码来访问. 具体路径是: github.com 右上角点头像, 进入 Settints -> Developer setttings -> Personal access tokens -> token classic 添加.
  5. 添加完成, 选择生产 token, 这个token 可以设置终止日期的.
  6. 可选把 token 放到 iTerm 的password 里面.

python Async Sync 函数

这篇是比较好的一篇文章: https://docs.chainlit.io/guides/sync-async

  1. sync -> sync -> ok
  2. sync -> async -> asyncio.run() | asyncio.get_event_loop().run_until_complete(async_func())
  3. async -> sync -> ok | await asyncio.to_thread(sync_task)
  4. async -> async -> await
  5. Python 的 asyncio 库是标准库中用于编写异步 I/O 代码的核心框架,自 Python 3.4 引入后成为构建高性能网络应用和并发程序的重要工具. asyncio 是 Python 异步编程的基石,适合需要高效处理 I/O 并发的场景。通过事件循环和协程机制,开发者能以同步风格编写异步代码,显著提升程序性能.
  6. Asyncer 是一个用于简化 Python 异步编程的第三方库,它通过更优雅的语法和高级功能让异步代码更易编写和维护. 相比标准库 asyncio,Asyncer 通过更高层次的抽象降低了异步编程门槛,适合需要快速开发高并发应用的场景.
  7. Python 的 anyio 库是一个​​跨异步框架的统一接口库​​,旨在简化异步编程的复杂性,同时兼容主流异步模型(如 asyncio 和 trio)。