2026年4月
关于记账的思考
现在有公账、私账、平台账。这些都是内部账.
这三种账户都可能直接和外部进行交易. 交易主要就分收入和支出.
这三个账户之间可以进行互转.
三种账户之间互转的类型,以及通常的称呼和方式
首先,三种账户之间互转都存在一种借款和还款的类型。除借还款之外,下面的是单向的,也就是转过之后不需要再还回来。
私账转公账可以称之为投资;
公账转私账可以称之为报销(需要票),或工资(不需要票);
公司账转平台账可以称之为预存;
平台账转公司账称之为提现;
第一个问题是内部账之间的互转可以被视为一种交易吗?
如果内部账之间的互转被视为一种交易的话,那么从A账转B账的话,就需要同时记收入和支出,只记收入或者只记支出都会导致总资金的增加或者减少,那么帐肯定就不平了。
所以不能被视为一种交易,就是有专门的转账类型。
第二个问题是一笔采购交易,如何被看成私账支出还是公账支出?
如果有私账先采购没有开票的情况下,就是私账的支出,如果有开票的情况下,就变成公账支出,需要转给私人的报销款。所以一批私账采购交易是否要报销就看是否开票。
千牛/淘宝/支付宝的保证金明细入口
淘宝和支付宝该怎么说呢,就对商家非常的不厚道。把保证金管理入口藏得非常深。
位置如下:
电脑端登录 b.alipay.com 商家中心-对账中心-左侧资金账户-支付宝账户-保证金
以前保证金的入口跟支付宝账户同级,现在竟然把它隐藏在支付宝账户之下了。
protobuf 3和gRPC, google开发的在二进制和可读代码间快速映射的工具以及远程调用方式.
Protobuf 3 和 gRPC 是 Google 开发并开源的一对“黄金搭档”,它们共同构成了现代高性能微服务通信的基石。简单来说,Protobuf 3 负责高效地“打包”数据,而 gRPC 则负责快速地“运输”这些数据。
📦 什么是 Protobuf 3?
Protobuf 3(Protocol Buffers 3)是 Google 开发的一种轻量级、高效的结构化数据存储格式,可以把它理解成一种数据序列化工具。
它的核心工作流程是:
- 定义数据结构:你使用一种接口定义语言(IDL),在一个
.proto文本文件中定义你的数据结构(称为“消息”)。 - 生成代码:通过
protoc编译器,根据.proto文件自动生成多种编程语言(如 Go, Java, Python, C++ 等)的数据访问类。 - 序列化与反序列化:在你的代码中,使用生成的类来创建、填充数据对象,并将其序列化为紧凑的二进制格式进行传输或存储;接收方则能高效地将其反序列化回对象。
Protobuf 3 的核心优势
- 高性能:与 JSON 或 XML 等基于文本的格式相比,Protobuf 将数据序列化为二进制,因此消息体积更小(通常只有 JSON 的 1/3 到 1/2),解析和序列化速度也更快(可快 50% 以上)。
- 强类型与语言无关:通过
.proto文件定义一份明确的数据契约,可以生成各种语言的代码,确保了不同服务间数据交互的强类型安全和一致性。 - 易于演进:Protobuf 3 的设计哲学强调简单和向后兼容。它移除了
required字段,所有字段默认为optional,并提供了reserved关键字来保护已删除字段的编号,这使得在不破坏现有客户端的情况下对数据结构进行升级变得非常容易。 - 标准化 JSON 支持:Protobuf 3 提供了标准化的 JSON 映射,方便在需要人类可读或与 Web API 交互的场景下进行调试和通信。
🚀 什么是 gRPC?
gRPC 是一个现代、开源、高性能且通用的远程过程调用(RPC)框架。它让一个应用程序能够像调用本地函数一样,去调用另一个远程服务器上的函数,极大地简化了分布式系统间的通信复杂性。
gRPC 的核心特性包括:
- 基于 HTTP/2:gRPC 默认使用 HTTP/2 作为传输协议,这带来了多路复用(在单个连接上并行处理多个请求)、头部压缩、双向流等高级功能,显著提升了网络效率。
- 以 Protobuf 为默认数据格式:gRPC 使用 Protobuf 作为其默认的接口定义语言(IDL)和消息序列化机制,继承了其高性能、强类型的优点。
- 代码生成:通过
.proto文件定义服务接口(包括方法、参数和返回类型),gRPC 可以自动生成客户端和服务端的桩代码,开发者只需关注业务逻辑的实现,无需手动处理底层的网络通信、序列化等细节。
gRPC 的四种通信模式
gRPC 提供了灵活的通信模型,以满足不同场景的需求:
| 通信模式 | 描述 | 方法定义示例 |
|---|---|---|
| 一元 RPC (Unary RPC) | 最普通的调用模式,客户端发送一个请求,服务器返回一个响应。 | rpc SayHello(HelloRequest) returns (HelloReply); |
| 服务器流式 RPC (Server streaming RPC) | 客户端发送一个请求,服务器返回一个数据流(一系列消息)。 | rpc LotsOfReplies(HelloRequest) returns (stream HelloReply); |
| 客户端流式 RPC (Client streaming RPC) | 客户端发送一个数据流(一系列消息),服务器在处理完所有消息后返回一个响应。 | rpc LotsOfGreetings(stream HelloRequest) returns (HelloReply); |
| 双向流式 RPC (Bidirectional streaming RPC) | 客户端和服务器各自通过独立的流互相发送一系列消息,双方可以按任意顺序读写。 | rpc BidiHello(stream HelloRequest) returns (stream HelloReply); |
总而言之,Protobuf 3 和 gRPC 共同提供了一个完整的解决方案,用于构建高效、可靠且易于演进的分布式系统和微服务架构。
腾讯新闻cli
对AI MCP来说这还挺难得的。
https://mp.weixin.qq.com/s/o4cU4OXxMwL3MATpx99StQ
精灵图合并python
将目录中的所有图片按从名称从左到右合并到一张大的精灵图里。
新建: sprite_combine.py
#!/usr/bin/env python3
"""
Sprite Combine Tool
Combine all PNG images in a directory into a single horizontal strip.
"""
import argparse
import os
import sys
from pathlib import Path
from PIL import Image
def main():
parser = argparse.ArgumentParser(
description="Combine PNG images from a directory into a single horizontal image."
)
parser.add_argument(
"directory",
help="Directory containing PNG images to combine"
)
parser.add_argument(
"-o", "--output",
default="combined.png",
help="Output filename (default: combined.png)"
)
parser.add_argument(
"-s", "--spacing",
type=int,
default=0,
help="Spacing between images in pixels (default: 0)"
)
parser.add_argument(
"-b", "--background",
default=None,
help="Background color (hex format like #FFFFFF or transparent for none)"
)
args = parser.parse_args()
dir_path = Path(args.directory)
if not dir_path.exists():
print(f"Error: Directory '{args.directory}' does not exist.", file=sys.stderr)
sys.exit(1)
if not dir_path.is_dir():
print(f"Error: '{args.directory}' is not a directory.", file=sys.stderr)
sys.exit(1)
# Get all PNG files and sort by name
png_files = sorted(dir_path.glob("*.png"), key=lambda x: x.name)
if not png_files:
print(f"Error: No PNG files found in '{args.directory}'.", file=sys.stderr)
sys.exit(1)
print(f"Found {len(png_files)} PNG image(s):")
for f in png_files:
print(f" - {f.name}")
# Load images
images = []
for filepath in png_files:
try:
img = Image.open(filepath)
# Convert to RGBA to handle transparency properly
img = img.convert("RGBA")
images.append(img)
except Exception as e:
print(f"Warning: Could not load '{filepath}': {e}", file=sys.stderr)
continue
if not images:
print("Error: No valid images could be loaded.", file=sys.stderr)
sys.exit(1)
# Calculate dimensions
spacing = args.spacing
max_height = max(img.height for img in images)
total_width = sum(img.width for img in images) + spacing * (len(images) - 1)
print(f"\nOutput dimensions: {total_width} x {max_height} pixels")
# Parse background color
bg_color = None
if args.background:
if args.background.lower() == "transparent":
bg_color = None
else:
# Parse hex color
hex_color = args.background.lstrip("#")
if len(hex_color) == 6:
bg_color = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) + (255,)
else:
print(f"Warning: Invalid hex color '{args.background}', using transparent.", file=sys.stderr)
# Create combined image
if bg_color is not None:
combined = Image.new("RGBA", (total_width, max_height), bg_color)
else:
combined = Image.new("RGBA", (total_width, max_height), (255, 255, 255, 0))
# Paste images
x_offset = 0
for img in images:
# Center vertically if different heights
y_offset = (max_height - img.height) // 2
combined.paste(img, (x_offset, y_offset), img)
x_offset += img.width + spacing
# Save result
output_path = Path(args.output)
combined.save(output_path, "PNG")
print(f"\nSaved combined image to: {output_path.resolve()}")
if __name__ == "__main__":
main()
依赖文件 requirements.txt
Pillow>=10.0.0
安装依赖:
pip install -r requirements.txt
运行方式:
python sprite_combine.py <folder_name>
可以改为bat文件spcomb.bat方便执行:
python sprite_combine.py %1
使用纯净css运行合并后的精灵图动画,可用于微信小程序:
wxml如下:
<view class="shutu-animation"></view>
wxss如下,假设精灵图为150x150px,合并后大小为9150x150px:
.shutu-animation {
width: 150rpx;
height: 150rpx;
background-image: url('https://xxxxx/combine.png'); /* 单行图 */
background-size: 9150rpx 150rpx; /* 总宽 x 高 */
animation: play 6s steps(61) infinite; /* 30帧需要走29步 */
}
@keyframes play {
100% {
background-position: -9150rpx 0;
}
} 如何让AI使用框架?
我发现一个问题,要AI使用框架的话,一定要让AI用最流行的框架,而不要用所谓AI自己觉得最合适你项目的框架。原因是最流行的框架有最丰富的文档,AI在前期训练的时候会对该框架有更多的了解。流行程度不佳的框架文档缺失,AI自己在编程的时候也会遇到更多的阻力,踩更多的坑。
刚刚让AI去编写一个贪吃蛇的游戏,当然我使用了superpowers这个插件来去编写,意图让他长时间的去运行编码任务并且可以编写一个比较复杂的程序。贪吃蛇游戏本身逻辑很简单,然后superpowers在进行问答的过程中,我有意采取了一些更加复杂的游戏设计,看它是否能够实现。
然后我用的是GLM4.7,它就开始提示我用框架的事情,我让他给了几个选择,他说phaser和kaboom都可以用,但是前者的框架太复杂,学习曲线太陡峭了,而后者也就是Kaboom这种轻量级的框架更适合我这种轻量级的小游戏。
phaser我之前是用过的,但是既然他说kaboom可以就让他用吧。没想到后面编码的时候竟然出现将API完全用错的情况。他自己发现错误之后就回过头去重构,然后还要再去理解到底这个API该怎么用。
其中还出现了一个问题,就是它总是要使用8000端口启动游戏的网页服务器。然而,8000端口已经被我的其他内部服务占用了,他对此毫不知情,弃而不舍的去启动这个服务。我只好中断它的运行,让它更换为其他端口。这就不适合用作长期自主运行的agent了。