我的自我介绍

欢迎 你好啊,我是本站的站长,我的花名是凌虚。 “凌虚”是动漫《秦时明月》中,张良的佩剑名。凌虚剑身修长秀美,通体晶莹夺目,虽为利器却不见血腥之气,剑身之上有一十八颗碧血丹心,高贵儒雅之风浓重。而其持剑人为张良。取此花名,有暗含自己才智比肩张良之嫌。 本站叫“风萧古道”,英文名是“WindyPath”。 “风萧”来自于“风萧萧兮易水寒”;“古道”来自于“古道西风瘦马”。为了押韵,我把两个词拼在了一起,就是“风萧古道”。为了让外国友人能体会这个词的优雅,我翻遍英语词典,找到了两个单词,“Windy”和“Path”,然后将它们也拼起来,就是“WindyPath”。 我 我目前是一个游戏服务器开发。之前还做过网页Web的全栈开发。现在已经不摆弄html标签了。 我19年毕业,20年底来到中国上海。我和计算机的其他故事可以到这里查阅。 理想主义 有很长一段时间,我不知道要为何而学习软件开发。如果是为了挣钱,那么我现在也已经在挣钱了。那么在我漫长的软件开发生涯中,我要为了什么而继续前行呢? For Chinese Software 为了中国软件。 文章 本站文章更新频率不高,但是我经常查阅互联网上其他独立博客站长的文章。有的站长帖子多,但是大多是发牢骚(当微博发),或者是转载(当笔记本/csdn)。这样的博客对于软件开发技术的水平的提升是没有什么效果的。 所以我的博客里,只有一种文章: 技术文章 哪怕是牢骚,也必须是与软件行业相关的牢骚,确保所有来访者能从中了解或者学习一些东西。 其他的日常生活的吐槽和牢骚就放到Twitter里。 联系方式 Email: windypathblog@gmail.com Telegram: @windypath

四月 29, 2023 · JohnathanLin

Windows XP虚拟机中文版无需激活下载

在这里直接下载我最后完成的虚拟机镜像 虚拟机镜像下载: 链接:https://pan.baidu.com/s/1yfY0SjDrtOeuTiEWf7YizA?pwd=374l 提取码:374l 我本地的VirtualBox 版本:6.1 我可以先聊聊怀旧吗 也许对于老外来说,Win95是他们的青春,所以他们做了React95这样的UI库,或者大家一起努力写了个操作系统serenity。但是对于咱们国内的用户而言,当家用PC走进千家万户时,映入眼帘的是——Windows XP。 一位中国台湾同胞sh1zuku编写开发了一个网页版的Windows XP模拟器:项目链接,在线演示,还有另一位来自越南的老哥khang-nd写了Windows 7的网页模拟器在线演示。 我自然没有能力和时间去编写类似系统的开发,但是有一个想法从我的脑中浮现:那么我就装一个Windows XP虚拟机到电脑上就好了。 你可能会选择的做法 安装VirtualBox; 下载镜像:从MSDN Itellyou中找到Windows XP的镜像,下载; 在VirtualBox中安装镜像; 启动镜像,安装系统 那么你会发现,安装的Windows XP只有30天试用。在二十一世纪初期,盗版泛滥,微软采取了非常强硬的措施限制盗版。即使你安装时输入了正确的序列号,微软也会要求你使用电话等方式进行激活。 但是我们是来怀旧的啊! 正确的做法 不能再使用这种正版的镜像了,需要使用别人处理好的,不需要激活的镜像。 这里我找到了github上的一位老哥提供的链接github WinXPImage,但是他的镜像是位于谷歌云盘上的。我把它下载之后放进百度网盘里了: 链接:https://pan.baidu.com/s/1ypKeaZixJXnbqAo4ZT0YLQ?pwd=30dd 提取码:30dd 在VirtualBox安装此镜像后,你将获得一个无限期使用的,英文版的Windows XP。 但你不一定能启动起来,你需要在导入OVA文件后,在OVA文件的目录下,执行以下命令: vbox-img geometry --filename Windows_XP_Professional-disk1.vdi --format VDI --cylinders 5874 --heads 255 --sectors 56 来自于github issue streeg 老哥给出的解决方案。 如何汉化Windows XP? 如果只是用英文版Windows XP,那么就达不到我们“怀旧”的目的了。 Windows XP英文版默认没有中文语言包。 我翻遍互联网,终于在一个犄角旮旯里找到了语言包mui_win_xp_pro_n_cd1.iso。 我把它下载之后放进百度网盘里了: 链接:https://pan.baidu.com/s/18mW9OCRejMDoEpUcih-zlA?pwd=peu4 提取码:peu4 然后, 设置VirtualBox里Windows XP虚拟机和物理机共享文件夹,具体方法 将mui_win_xp_pro_n_cd1.iso通过共享文件夹从物理机传进虚拟机中 安装,具体方法 最后重启虚拟机即可。 上图!

十月 2, 2022 · JohnathanLin

Java TreeSet的一些用法和特性

先看一个例子(kotlin实现) import java.util.TreeSet /** * 定义一个用于测试TreeSet集合的结构 * 用TreeSet进行排名 * id: 玩家id * score: 玩家得分 */ data class PlayerScore(var id: Int, var score: Int): Comparable<PlayerScore> { override fun compareTo(other: PlayerScore): Int { return if (score > other.score) { 1 } else if (score < other.score) { -1 } else { 0 } } } fun main() { //创建一个TreeSet val treeSet: TreeSet<PlayerScore> = TreeSet() //创建3个PlayerScore,其中对id为101的对象存一个引用 //将3个PlayerScore装入set中 val id101Obj = PlayerScore(101,100) //按不同的顺序加入TreeSet treeSet.add(PlayerScore(102,200)) treeSet....

六月 18, 2022 · JohnathanLin

Linux C++ Socket实战

本文主要介绍Linux C++ 基础Socket网络编程。 大部分知识来自于网站:https://www.geeksforgeeks.org/socket-programming-cc/ Socket编程状态图 从图中可以看到,服务端这边需要处理四步才能进入等待连接的状态,而客户端只要两步。 Socket编程中各函数简单解析 本解析仅为自己理解所用,可能有些纰漏,有则改之。 原文中的知识总结得比我更好,尽量参考原文,我的理解仅做辅助之用。 服务端 先说服务端。服务端需要指定好端口并监听,所以需要bind()绑定好端口,需要listen()进入监听状态,然后通过accept()阻塞等待客户端的消息。 引用表: #include <sys/socket> socket() setsockopt() bind() listen() accept() #include <netinet/in.h> struct sockaddr_in #include <unistd.h> read() #include <arpa/inet.h> inet_pton() socket() 这个函数是用来创建一个socket,3个参数中,需要特别传的就是前两个。返回一个socket编号,是个int值。 int sockfd = socket(domain, type, protocol) domain: IPV4 用 AF_INET, IPV6 用 AF_INET6 type: TCP 用 SOCK_STREAM, UDP 用 SOCK_UGRAM setsockopt() 这个函数用来给上面那个socket()函数返回的socket设置属性,作为服务端,为了方便? 可以设置重用地址和端口号。 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 为了重用地址和端口号,需要这么做: level传SOL_SOCKET,代表你这次设置的属性值是给哪个模块用的 optname传SO_REUSEADDR|SO_REUSEPORT,代表你打算同时设置这两个属性 optval传一个int*指针,指向某一个数字 optlen传sizeof()上面的optval C++ socket很多函数都需要你再传一个length长度,以确定你真正想传给这个函数的数据是多长。...

四月 30, 2022 · JohnathanLin

传统软件服务器与游戏服务器架构区别

项目 智能客服 爬虫 SLG游戏 语言 java python kotlin 模型 异步事件驱动 可能没什么模型可言 actor模型 传输协议 http http tcp + netty 传输结构 json json protobuf 数据库 oracle,redis mongodb mysql,redis 数据库框架 mybatis python库(类似jdbc) hibernate 缓存架构 管理员登录状态用redis 可能只缓存了页码 所有游戏用的数据全部缓存,每隔一段时间写到数据库中 配置信息 只有application.properties config.ini zookeeper,启动前需要将策划表信息刷到zk 并发 无并发(所以根本没用到锁) python多线程同时爬多个网站 无并发actor模型保证一次只做一件事 热更 直接重启 无 继承某个类的某个方法,替换掉线上的类 架构一览 智能客服服务端整体架构 SLG游戏整体架构 典型案例 智能客服聊天 graph LR A[客户端]-->|http聊天消息|B[智能客服系统]-->|将聊天信息放入mq|C[智能问答模型]-->|问答信息记录|D[Oracle数据库] SLG游戏士兵出征 graph LR A[客户端]-->|tcp发送的protobuf|B[Gate的Netty解包]-->|actor内部消息转发|C[WorldActor校验外城沙盘各种状态]-->|actor内部消息转发|D[playerActor内城校验和获取buff] 其中worldActor和playerActor都通过读取内存的方式读取到需要的数据,并不直接读取mysql数据库。 内存里的数据每隔一段时间(30秒左右)将变化的数据通过hibernate的方法更新到mysql中。 配置信息读取 对于智能客服来说,由于并发量业务量很少(因为投放的平台比较少,且晚上凌晨基本没什么人使用,且重启速度很快),有一些需求上的配置数值(比如发送几次“转人工”才进入转人工通道)是直接硬写在业务里的;也有一些配置信息是其他系统的请求地址url,会配在application.properties里。没有使用excel统一存储各个功能模块的配置信息,也确实不需要。 但对于游戏来说,数值这块的配置至关重要,与玩法,奖励,游戏内生态息息相关。因此在游戏服务器里,所有的数值几乎都要从配置表中读取。目前Excel应该是处理数据能力最强的软件了,策划可以通过Excel非常快速的把数值配好。 启动服务器的时候要读取配置表到内存(广义上的)里。但在有了zookeeper这样的工具出现之后,配置表数据可以放在zk中,需要的时候再取出来。 游戏服务器优势 传输结构为protobuf 服务器接收和发送的数据都是ProtoBuf转成的二进制,从而实现客户端服务器端统一的传输结构。protobuf自己有编码解码二进制的功能,从而实现消息数据的大小达到最小,编码解码是由netty执行的,使用上只需要将protobuf生成的对象传给netty即可。这边用的protobuf是v2版本的,有required,optional和repeated三种关键字,分别对传输message里的属性作出了约束。 Akka Actor架构 Actor架构实现单线程的业务逻辑,开发过程中不需要对一些公用的属性上锁;通过内部消息的通讯,让数据处理有序进行。Akka cluster集群有动态负载均衡的功能,可以进行平行扩展,也就是说,如果一台服务器扛不住并发,只要再配置一台或几台新服务器,加入集群就可以完成负载均衡。...

四月 16, 2022 · JohnathanLin