2024年7月

image

本书是程序员大牛陈皓的文章汇总,内容包括技术、沟通、工程师文化等,通读之后摘录其中精华部分。开卷有益,能读到摘录部分也会收益,当然最好是去读原文,知识转化效率更高。除本书之外,还有一些他的文章也非常值得阅读,包括程序员如何变现,如何学习英语主题等。

05 有竞争力的程序员

好的程序员不一定是技术最强的程序员,但一定是能够在
不完美的工作环境下确保软件质量和工作效率
的程序员
真正的和谐不是只有一种声音,而是百家争鸣
英语对于程序员的价值永远不会被高估,甚至可以被视为超越别人的捷径
在做决定时,
多关注自己能得到的东西
,而不是可能会失去的东西

四步实现竞争力跃迁
一、认知:掌握优质的信息源。关注信息渠道、信息质量、信息密度
二、知识:

  • 知识树:想要系统地学习,就需要将其总结归纳成知识树或知识图。知识由多个知识板块组成,一个知识板块又包含各种知识点,一个知识点会引出相关的知识点,各知识点彼此交叉和依赖。
  • 知识缘由
  • 方法套路

三、技能

  • 精益求精:用相同的方法重复训练无异于搬砖,是无法拥有最专业的技能的。要在每一次训练中寻找更好的方法,并且总结经验,从而使下一次训练更加完美和更有效率。
  • 让自己犯错
  • 找高手切磋

四、领导力

  • 识别自己的特长和天赋
  • 识别自己的兴趣和事业
  • 让自己的习惯和方法变高级

06 成长中的问题

如何保证工程进度?
尽量将长线任务拆分为在一周内完成的多个子任务,因为越容易实现的任务越能调动执行力。可以在一周内完成的任务是最合适的。

08 高效学习

主动学习和被动学习
image.png

人的学习分为
被动学习

主动学习
两个层次。被动学习中听讲、阅读、视觉感受、观看演示这几种形式的学习内容平均留存率为5%,10%,20%,30%。主动学习中通过讨论、实践、教授给他人,分别能将学习的留存率提高到50%、75%、90%。

不要盲目追求阅读的速度和数量,这只会让人产生错觉,误以为这就是勤奋和成长。要思辨,要践行,要总结和归纳,
机械的重复不会带来质的飞跃

学习的终极目的
一、学习是为了找到方法
学习的目的与其说是找到答案,不如说是找到方法。只有掌握思路和方法,才能真正拥有解决问题的能力。

二、学习是为了找到原理
学习不仅仅是为了知道,更是为了思考和理解。学习者不能停留于知识的表象,而是要通过表象去探索知识的本质与原理。一旦理解了某一个关键之处,你就会恍然大悟,因为所有的知识点已经融会贯通。

三、学习是为了了解自己
学习不仅仅是为了开阔眼界,更是为了通过探寻未知世界来了解自己。因此你需要多于不同的人交流,多于比自己聪明的人共事,多走出去了解外面的世界。这样你才会发现自己的短板和盲区,才会有动力审视和分析自己,从而明白如何提升自己。

四、学习是为了改变自己
很多时候,成长是通过改变来实现的。学习是改变我们的思考方式,改变我们的思维惯性,改变我们对与生俱来的直觉的依赖。总之,用于改变自己,才能持续成长。

高效学习的八种方法
一、挑选知识和信息源
二、注重基础和原理
三、使用知识地图 顺藤摸瓜,从知识树的主干开始做广度或深度遍历,就能得到整颗知识树。
四、系统学习
五、举一反三 举一反三包括:联想能力、抽象能力、自身能力。
六、总结和归纳
对看到和学习到的信息进行归纳、排列、关联,实现碎片信息的结构化,从中找到规律和相通之处,然后进行简化和提炼,最终形成一种套路、模式和通用方法。
七、实践出真知
成长的痛苦很大程度上来自实践,但只有痛苦才会让人反思,而反思最终决定了成长的高度
八、坚持不懈
坚持不懈的两个窍门:一是主动建立正向反馈,比如随时把成果晒出来让别人点赞,二是尽快把坚持编程习惯,让生物钟来参与管理

想做到高效学习,个人要有正确的认知、正确的态度、正确的观念和正确的方法,满足这几点要求似乎颇为不易。但程序员的日常工作正好是追求效率,代码如是,学习亦如是。

09 高效沟通

克服六种常见沟通障碍
系统的分析沟通中的主要的障碍:

  1. 信息不准确:信息本身是错误的,无论有多么高超的沟通技巧都无法准确表达。
  2. 信息过量:信息过多等于没有信息
  3. 没有交互:没有交互会影响主动沟通一方的积极性
  4. 表达方式:相同的沟通内容,采用不同的表达方式会产生截然不同的效果
  5. 二手信息:信息在传递过程中会自然损失,很多二手信息的准确度也不够
  6. 信息不对称:信息在网络通信过程中被恶意篡改后,就会造成信息不对称

无往不利的沟通技巧

  1. 引起对方的兴趣:找到对方的关注点,尽可能让沟通向其靠拢
  2. 围绕主题强化观点:表达之前要明白自己表达的目的,组织好要表达的内容,还要多中筛选有用的信息,进一步思考四否有更加简明、易懂的表达方式
  3. 基于数据和事实:沟通时应尽量弱化主观色彩,多用数据、例证、权威引用和客观经验来强调观点的权威性。

12 编程范式

编程范式是一套指导编程方法和风格的规则和约定。以下是一些常见的编程范式:

  1. 面相过程编程
    (Procedural Programming):
    • 以过程或函数为基础,强调可执行语句的改变状态。
  2. 面向对象编程
    (Object-Oriented Programming, OOP):
    • 以类和对象为中心,强调数据和处理数据的方法的封装。
  3. 函数式编程
    (Functional Programming, FP):
    • 以数学函数为基础,强调无副作用的函数和不可变数据。
  4. 逻辑编程
    (Logic Programming):
    • 以逻辑推理为基础,使用事实和规则来解决问题。
  5. 声明式编程
    (Declarative Programming):
    • 强调“做什么”而不是“怎么做”,常见于SQL和HTML。
  6. 命令式编程
    (Imperative Programming):
    • 强调“怎么做”,通过编写一步一步的指令来控制程序状态。
  7. 结构化编程
    (Structured Programming):
    • 强调使用控制结构(如循环和条件语句)来编写清晰、可维护的代码。
  8. 并发编程
    (Concurrent Programming):
    • 强调编写能够同时执行多个任务的程序。
  9. 并行编程
    (Parallel Programming):
    • 强调利用多个处理器或核心来同时执行多个计算任务。
  10. 事件驱动编程
    (Event-Driven Programming):
  • 程序的执行流程由外部事件(如用户输入、消息、信号等)触发。
  1. 元编程
    (Metaprogramming):
  • 程序能够生成或修改其他程序或自身代码。
  1. 响应式编程
    (Reactive Programming):
  • 强调异步数据流和变化的传播,常见于用户界面编程。
  1. 组件化编程
    (Component-Based Programming):
  • 强调将程序分解为独立的、可重用的组件。
  1. 面向切面编程
    (Aspect-Oriented Programming, AOP):
  • 允许将横切关注点(如日志记录、事务管理)与业务逻辑分离。

每种编程范式都有其适用场景和优势,开发者可以根据项目需求和个人偏好选择合适的范式。

函数式编程(Functional Programming,简称FP)是一种编程范式,它将计算视为数学函数的评估,并避免使用程序状态以及易变对象。与面向对象编程相比,函数式编程强调的是无副作用的函数和不可变性。
以下是函数式编程的一些核心概念:

  1. 纯函数
    :函数的输出只依赖于输入的参数,不依赖于任何外部状态或数据。纯函数不会产生副作用。
  2. 不可变性
    :在函数式编程中,数据是不可变的。一旦数据被创建,它就不能被改变。任何修改都会产生新的数据结构。
  3. 高阶函数
    :函数可以作为参数传递给其他函数,或者作为结果返回。这允许创建更抽象和灵活的代码。
  4. 函数组合
    :通过组合简单的函数来构建更复杂的函数。
  5. 递归
    :由于函数式编程语言通常不支持循环结构,递归是实现循环逻辑的主要方式。
  6. 模式匹配
    :许多函数式编程语言支持模式匹配,这使得处理数据结构(如列表、元组等)更加直观和简洁。
  7. 惰性评估
    :表达式不会立即求值,直到它们被需要时才会计算。这可以提高性能,尤其是在处理大型数据结构时。
  8. 类型系统
    :许多函数式编程语言具有强大的类型系统,可以帮助开发者避免错误,并提供更好的代码可读性。

函数式编程语言的例子包括 Haskell、Erlang、Clojure、Scala、F# 等。函数式编程范式在并发和并行计算中特别有用,因为它减少了由于共享状态和副作用引起的复杂性和错误。

13 软件开发与架构设计的原则

原则1:关注收益而不是技术
对于软件架构来说,最重要的是收益。以下几种收益很重要:

  • 降低技术门槛,加快整个团队的开发流程
  • 让整个系统运行得更加稳定
  • 通过简化和自动化来降低成本

原则3:选择主流和成熟的技术

  • 尽可能使用成熟和工业化的技术栈
  • 选择全球流行的技术。只有具备普适性才有更强的生命力
  • 尽可能不要自己造轮子,更不要魔改

原则4:完备性比性能更重要
系统的完备性和可扩展性在比支持多大的流量更重要

  • 优先使用科学、严谨的技术模型
  • 对于性能问题,解决方案和可采取的措施有很多。

原则5:制定并遵循标准规范

原则8:不要迁就技术债务
许多公司都存在大量的技术债务,具体表现如下:

  • 使用老旧的技术
  • 不合理的设计:如在网关中写大量业务逻辑、业务逻辑深度耦合
  • 缺少配套设施:例如自动化测试,良好的软件文档

千万不要指望把一辆拖拉机改装成法拉利跑车

原则9:不要依赖经验
重复过去不可能进步,更新知识才能带来成长。因此不要依赖经验做决策,我建议正确的决策路径如下:

  • 用足够的时间查找相关资料,如技术博客、文章、论文等
  • 收集、对比各家公司和开源世界的做法
  • 比较各种方案的优缺点后形成自己的决策

进步永远来自探索,套索的确要付出代价,但收益也更大。原则是软件开发和架构探索之旅的路线图,尊重与依赖原则让我们有可能在冒险中不犯大错,在抓住机会的同时不止于失去太多。

15 时间管理

时间的价值投资

  1. 把时间投资在打牢基础、熟读文档上是值得的
  2. 把时间花在解放生产力的事情上
  3. 提升自己在整个行业内的影响力

规划自己的时间

  • 对于优先级相同的事情,建议采用最短作业优先的调度算法
  • 代办清单中的任务不断减少才会给人以正向反馈

16 研发效率

关于研发效率的重要结论

  1. 软件工程师分工越细,团队就越没有效率。改善团队间的服务才是重中之重,服务不是我帮你做事,而是我让你做起事来更容易
  2. 如果非要在一个环节上较真,要么在设计和编码时认真,要么在测试上认真。否则,等到运维阶段处理故障,效率会大幅度下滑
  3. 小而精的团队
    +
    条件或资源受限
    是高效率的根本。团队小内耗才会小,条件或资源受限才会用最经济的手段做最有价值的事情,才会追求简单和简化
  4. 技术债是不能欠的,要果断地偿还技术债
  5. 软件架构上要送耦合,团队组织上要紧耦合
  6. 工程师文化是关键,重视过程就是重视结果

17 技术领导力

如何成为一个拥有技术领导力的少数人呢?

  1. 吃透基础技术
  2. 提高学习能力
  3. 坚持做正确的事情
  4. 高标准要求自己

提高学习能力
一、重视信息来源
通过优质的信息来源,可以更快地获取有价值的信息,从而提高学习效率。
二、学会关联思考
技术存在通用性和关联性,例如了解操作系统的网页的缓存后,需要思考他们之间的相同点和不同点。在遇到故障时,尽量把同类问题一次处理完成。
三、与高手交流
与高手交流不仅有助于了解热门技术方向和关键技术点,还可以让他们通过观察,揣摩高手的技术思维和解决问题的方式,提高自己技术的前瞻性和技术决策力。

19 绩效考核

对于劳动密集型公司适合KPI,对于知识密集型公司使用OKR
绩效沟通一定要放在平常的工作中,避免秋后算账

一个有价值的员工需要的能力包括:

  1. 学习新技能
  2. 提高专业水平
  3. 参加培训课程
  4. 与同事建立良好合作关系
  5. 积极参与团队合作
  6. 不断挑战自我

绩效考核不是最终目标,考核结果及其改进方法才是有价值的信息。通过结果不断改善并完善自我,这才是真正正确的绩效打开方式。

21 工程师文化

在软件工程领域提升效率有如下发力方向:

  1. 简化:简单意味着更容易被用户理解,也更易于维护和运维。
  2. 坚决推行自动化:编写程序的根本目的就是用自动化消除重复劳动。而且,很多事情本身更适合由机器来完成,人再多也无法像机器那样既好又快的完成任务。
  3. 以高效决策为原则:具体措施包括采用扁平化管理、用自动化工具取代支撑工作、采用不超过十人的全栈小团队、不按技能而是按负责的产品或功能进行人员分工、用开会表决提案、通过产品的目标和信条来减少沟通和决策的过程。

高质量的分享:

  1. 用问题吸引受众,带着受众一起思考
  2. 用问题模型框柱受众的思考范围,让受众聚焦
  3. 给出几种不同的解决方案,比较它们的优缺点,让受众参与解决问题的过程
  4. 提供最佳实践,方法论或套路。有前面的铺垫,受众更容易接受这些内容
  5. 整个过程能让受众体会到强烈的成长感和收获感

之前文章(“
VMware Cloud Foundation Part 03:准备 Excel 参数表。
”和“
VMware Cloud Foundation Part 04:准备 ESXi 主机。
”),我们已经知道了对于部署一个 VMware Cloud Foundation 来说,需要准备部署参数配置文件以及用于部署管理域的 ESXi 主机,这在前期准备当中确实需要花费大量时间和精力,不过等这一切都准备就绪后,到了真正的实施环节,也许几个小时之内就能完成所有部署上线工作,这就是使用 VMware Cloud Foundation 自动化和标准化 SDDC 解决方案所带来的魅力。

话不多说,下面正式进入主题。

一、Cloud Builder 使用技巧

可能有一些小技巧对于 Cloud Builder 工具的使用能带来帮助。工欲善其事,必先利其器。

1)查看 Log 日志文件

在 Cloud Builder 部署 VCF 管理域过程中,有可能会遇到一些报错或者失败的任务,这时可以查看以下 Cloud Builder 中的 Log 日志文件来检查具体错误的原因。SSH 以 admin 用户登录到 Cloud Builder 并切换到 root 用户,执行以下命令。

tail -f /var/log/vmware/vcf/bringup/vcf-bringup.log
tail -f /var/log/vmware/vcf/bringup/vcf-bringup-debug.log

2)开启 History 历史记录

默认情况下,Cloud Builder 虚拟机的 History 命令历史记录功能是关闭的,如果你想查看之前使用过的命令并向上翻阅历史记录,将会失败。如果想开启 History 功能,可以移除关闭历史记录的配置文件。SSH 以 admin 用户登录到 Cloud Builder 并切换到 root 用户,执行以下命令。

mv /etc/profile.d/disable.history.sh .
history

3)重置 Postgres 数据库

当使用 Cloud Builder 部署完成 VCF 管理域以后,最终会显示如下图所示界面。如果你想继续使用 Cloud Builder 重新部署 VCF 管理域或者部署另外一个 VCF 实例,再去访问 Cloud Builder 时始终会停留在下图所示的界面。

要想再次使用 Cloud Builder,可以重置 Postgres 数据库。SSH 以 admin 用户登录到 Cloud Builder 并切换到 root 用户,执行以下命令。

/usr/pgsql/13/bin/psql -U postgres -d bringup -h localhost

delete from execution;
delete from "Resource";
\q

二、vSAN ESA HCL 自定义文件

当你跟我一样使用了嵌套 ESXi 虚拟机来部署 VMware Cloud Foundation 时,如果你选择使用 vSAN OSA 架构来部署 VCF 管理域,那么在部署的时候不会遇到 HCL 兼容性问题,因为不会去检查 HCL JSON 文件;但是,要是你部署 vSAN ESA 架构,并使用官方的 HCL JSON 文件(https://partnerweb.vmware.com/service/vsan/all.json)的话,那一定会遇到兼容性问题,ESXi host vSAN compatibility validation 检查将会失败(Failed to verify HCL status on ESXi Host vcf-mgmt01-esxi01.mulab.local),如下图所示。

1)生成嵌套 ESXi 主机的自定义 HCL JSON 文件

针对上述这个问题,可以使用 VMware 工程师 William Lam 所制作的 PowerCLI 脚本来生成自定义 HCL JSON 文件进行解决,脚本完整内容如下。很有意思的是,这个方法是不是也可以用于嵌套环境中 vSAN ESA 集群的部署和使用基于映像的 vLCM 生命周期管理所遇到的硬件兼容性问题?!注意,你需要安装
PowerCLI
环境,才能执行以下步骤。

# Author: William Lam
# Description: Dynamically generate custom vSAN ESA HCL JSON file connected to standalone ESXi host

$vmhost = Get-VMHost

$supportedESXiReleases = @("ESXi 8.0 U2")

Write-Host -ForegroundColor Green "`nCollecting SSD information from ESXi host ${vmhost} ... "

$imageManager = Get-View ($Vmhost.ExtensionData.ConfigManager.ImageConfigManager)
$vibs = $imageManager.fetchSoftwarePackages()

$storageDevices = $vmhost.ExtensionData.Config.StorageDevice.scsiTopology.Adapter
$storageAdapters = $vmhost.ExtensionData.Config.StorageDevice.hostBusAdapter
$devices = $vmhost.ExtensionData.Config.StorageDevice.scsiLun
$pciDevices = $vmhost.ExtensionData.Hardware.PciDevice

$ctrResults = @()
$ssdResults = @()
$seen = @{}
foreach ($storageDevice in $storageDevices) {
    $targets = $storageDevice.target
    if($targets -ne $null) {
        foreach ($target in $targets) {
            foreach ($ScsiLun in $target.Lun.ScsiLun) {
                $device = $devices | where {$_.Key -eq $ScsiLun}
                $storageAdapter = $storageAdapters | where {$_.Key -eq $storageDevice.Adapter}
                $pciDevice = $pciDevices | where {$_.Id -eq $storageAdapter.Pci}

                # Convert from Dec to Hex
                $vid = ('{0:x}' -f $pciDevice.VendorId).ToLower()
                $did = ('{0:x}' -f $pciDevice.DeviceId).ToLower()
                $svid = ('{0:x}' -f $pciDevice.SubVendorId).ToLower()
                $ssid = ('{0:x}' -f $pciDevice.SubDeviceId).ToLower()
                $combined = "${vid}:${did}:${svid}:${ssid}"

                if($storageAdapter.Driver -eq "nvme_pcie" -or $storageAdapter.Driver -eq "pvscsi") {
                    switch ($storageAdapter.Driver) {
                        "nvme_pcie" {
                            $controllerType = $storageAdapter.Driver
                            $controllerDriver = ($vibs | where {$_.name -eq "nvme-pcie"}).Version
                        }
                        "pvscsi" {
                            $controllerType = $storageAdapter.Driver
                            $controllerDriver = ($vibs | where {$_.name -eq "pvscsi"}).Version
                        }
                    }

                    $ssdReleases=@{}
                    foreach ($supportedESXiRelease in $supportedESXiReleases) {
                        $tmpObj = [ordered] @{
                            vsanSupport = @( "All Flash:","vSANESA-SingleTier")
                            $controllerType = [ordered] @{
                                $controllerDriver = [ordered] @{
                                    firmwares = @(
                                        [ordered] @{
                                            firmware = $device.Revision
                                            vsanSupport = [ordered] @{
                                                tier = @("AF-Cache", "vSANESA-Singletier")
                                                mode = @("vSAN", "vSAN ESA")
                                            }
                                        }
                                    )
                                    type = "inbox"
                                }
                            }
                        }
                        if(!$ssdReleases[$supportedESXiRelease]) {
                            $ssdReleases.Add($supportedESXiRelease,$tmpObj)
                        }
                    }

                    if($device.DeviceType -eq "disk" -and !$seen[$combined]) {
                        $ssdTmp = [ordered] @{
                            id = [int]$(Get-Random -Minimum 1000 -Maximum 50000).toString()
                            did = $did
                            vid = $vid
                            ssid = $ssid
                            svid = $svid
                            vendor = $device.Vendor
                            model = ($device.Model).trim()
                            devicetype = $device.ApplicationProtocol
                            partnername = $device.Vendor
                            productid = ($device.Model).trim()
                            partnumber = $device.SerialNumber
                            capacity = [Int]((($device.Capacity.BlockSize * $device.Capacity.Block) / 1048576))
                            vcglink = "https://williamlam.com/homelab"
                            releases = $ssdReleases
                            vsanSupport = [ordered] @{
                                mode = @("vSAN", "vSAN ESA")
                                tier = @("vSANESA-Singletier", "AF-Cache")
                            }
                        }

                        $controllerReleases=@{}
                        foreach ($supportedESXiRelease in $supportedESXiReleases) {
                            $tmpObj = [ordered] @{
                                $controllerType = [ordered] @{
                                    $controllerDriver = [ordered] @{
                                        type = "inbox"
                                        queueDepth = $device.QueueDepth
                                        firmwares = @(
                                            [ordered] @{
                                                firmware = $device.Revision
                                                vsanSupport = @( "Hybrid:Pass-Through","All Flash:Pass-Through","vSAN ESA")
                                            }
                                        )
                                    }
                                }
                                vsanSupport = @( "Hybrid:Pass-Through","All Flash:Pass-Through")
                            }
                            if(!$controllerReleases[$supportedESXiRelease]) {
                                $controllerReleases.Add($supportedESXiRelease,$tmpObj)
                            }
                        }

                        $controllerTmp = [ordered] @{
                            id = [int]$(Get-Random -Minimum 1000 -Maximum 50000).toString()
                            releases = $controllerReleases
                        }

                        $ctrResults += $controllerTmp
                        $ssdResults += $ssdTmp
                        $seen[$combined] = "yes"
                    }
                }
            }
        }
    }
}

# Retrieve the latest vSAN HCL jsonUpdatedTime
$results = Invoke-WebRequest -Uri 'https://vsanhealth.vmware.com/products/v1/bundles/lastupdatedtime' -Headers @{'x-vmw-esp-clientid'='vsan-hcl-vcf-2023'}
# Parse out content between '{...}'
$pattern = '\{(.+?)\}'
$matched = ([regex]::Matches($results, $pattern)).Value

if($matched -ne $null) {
    $vsanHclTime = $matched|ConvertFrom-Json
} else {
    Write-Error "Unable to retrieve vSAN HCL jsonUpdatedTime, ensure you have internet connectivity when running this script"
}

$hclObject = [ordered] @{
    timestamp = $vsanHclTime.timestamp
    jsonUpdatedTime = $vsanHclTime.jsonUpdatedTime
    totalCount = $($ssdResults.count + $ctrResults.count)
    supportedReleases = $supportedESXiReleases
    eula = @{}
    data = [ordered] @{
        controller = @($ctrResults)
        ssd = @($ssdResults)
        hdd = @()
    }
}

$dateTimeGenerated = Get-Date -Uformat "%m_%d_%Y_%H_%M_%S"
$outputFileName = "custom_vsan_esa_hcl_${dateTimeGenerated}.json"

Write-Host -ForegroundColor Green "Saving Custom vSAN ESA HCL to ${outputFileName}`n"
$hclObject | ConvertTo-Json -Depth 12 | Out-File -FilePath $outputFileName

运行 Powershell,使用 PowerCLI 命令 Connect-VISserver 连接到嵌套 ESXi 主机,并运行自定义 HCL JSON 文件生成脚本。

生成的自定义 HCL JSON 文件内容如下所示。注意,运行上述脚本需要电脑连接互联网,如果不能连网,则需要手动下载官方的 HCL JSON 文件(https://partnerweb.vmware.com/service/vsan/all.json),然后将 timestamp 和 jsonUpdatedTime 字段的值修改为官方的 HCL JSON 文件中的最新值。

{
    "timestamp":  1721122728,
    "jsonUpdatedTime":  "July 16, 2024, 2:38 AM PDT",
    "totalCount":  2,
    "supportedReleases":  [
                              "ESXi 8.0 U2"
                          ],
    "eula":  {

             },
    "data":  {
                 "controller":  [
                                    {
                                        "id":  33729,
                                        "releases":  {
                                                         "ESXi 8.0 U2":  {
                                                                             "nvme_pcie":  {
                                                                                               "1.2.4.11-1vmw.802.0.0.22380479":  {
                                                                                                                                      "type":  "inbox",
                                                                                                                                      "queueDepth":  510,
                                                                                                                                      "firmwares":  [
                                                                                                                                                        {
                                                                                                                                                            "firmware":  "1.3",
                                                                                                                                                            "vsanSupport":  [
                                                                                                                                                                                "Hybrid:Pass-Through",
                                                                                                                                                                                "All Flash:Pass-Through",
                                                                                                                                                                                "vSAN ESA"
                                                                                                                                                                            ]
                                                                                                                                                        }
                                                                                                                                                    ]
                                                                                                                                  }
                                                                                           },
                                                                             "vsanSupport":  [
                                                                                                 "Hybrid:Pass-Through",
                                                                                                 "All Flash:Pass-Through"
                                                                                             ]
                                                                         }
                                                     }
                                    }
                                ],
                 "ssd":  [
                             {
                                 "id":  25674,
                                 "did":  "7f0",
                                 "vid":  "15ad",
                                 "ssid":  "7f0",
                                 "svid":  "15ad",
                                 "vendor":  "NVMe",
                                 "model":  "VMware Virtual NVMe Disk",
                                 "devicetype":  "NVMe",
                                 "partnername":  "NVMe",
                                 "productid":  "VMware Virtual NVMe Disk",
                                 "partnumber":  "f72c2cf6551ae47e000c2968afc4b0ec",
                                 "capacity":  61440,
                                 "vcglink":  "https://williamlam.com/homelab",
                                 "releases":  {
                                                  "ESXi 8.0 U2":  {
                                                                      "vsanSupport":  [
                                                                                          "All Flash:",
                                                                                          "vSANESA-SingleTier"
                                                                                      ],
                                                                      "nvme_pcie":  {
                                                                                        "1.2.4.11-1vmw.802.0.0.22380479":  {
                                                                                                                               "firmwares":  [
                                                                                                                                                 {
                                                                                                                                                     "firmware":  "1.3",
                                                                                                                                                     "vsanSupport":  {
                                                                                                                                                                         "tier":  [
                                                                                                                                                                                      "AF-Cache",
                                                                                                                                                                                      "vSANESA-Singletier"
                                                                                                                                                                                  ],
                                                                                                                                                                         "mode":  [
                                                                                                                                                                                      "vSAN",
                                                                                                                                                                                      "vSAN ESA"
                                                                                                                                                                                  ]
                                                                                                                                                                     }
                                                                                                                                                 }
                                                                                                                                             ],
                                                                                                                               "type":  "inbox"
                                                                                                                           }
                                                                                    }
                                                                  }
                                              },
                                 "vsanSupport":  {
                                                     "mode":  [
                                                                  "vSAN",
                                                                  "vSAN ESA"
                                                              ],
                                                     "tier":  [
                                                                  "vSANESA-Singletier",
                                                                  "AF-Cache"
                                                              ]
                                                 }
                             }
                         ],
                 "hdd":  [

                         ]
             }
}

2)重新另存为 HCL JSON 文件

很奇怪,不知道为什么上面自动生成的 HCL JSON 文件我这边直接使用有问题,我将生成的 HCL JSON 文件通过记事本打开,然后全部复制到另一个记事本中,再另存为 JSON 文件(如 all.json),最后导入到 Cloud Builder 才验证成功。如果你遇到同样的问题,可以尝试这一操作。

3)上传 HCL JSON 文件到 Cloud Builder

使用上面脚本生成了嵌套 ESXi 主机的自定义 HCL JSON 文件后,需要通过 SFTP 将它上传到 Cloud Builder,同时需要在 Excel 参数表中配置 HCL JSON 文件的路径,后续在部署管理域的时候需要使用。

mv /home/admin/all.json /opt/vmware/bringup/tmp/
chmod 644 /opt/vmware/bringup/tmp/all.json
chown vcf_bringup:vcf /opt/vmware/bringup/tmp/all.json

三、NSX Manager 部署技巧

1)增加 NSX Manager 部署的等待时间

VCF 管理域部署期间,在自动部署和配置 NSX 组件的时候花费的时间最长,如果部署环境的硬件性能不好,可能会持续很长时间,最后甚至会失败。可以调整 Cloud Builder 部署 NSX 组件的等待时间,这样也能在超时之前完成部署过程。SSH 以 admin 用户登录到 Cloud Builder 并切换到 root 用户,执行以下命令。

vim /opt/vmware/bringup/webapps/bringup-app/conf/application.properties

增加下面参数:

nsxt.manager.wait.minutes=100 (或者更长)

重启 Cloud Builder 服务。

systemctl restart vcf-bringup

2)修改 NSX Manager 部署节点的数量

默认情况下,部署 NSX Manager 组件的时候会部署 3 个 NSX Manager 节点并配置完整的 NSX 集群。其实,如果只是测试学习,当部署 VCF 环境的宿主机的资源不是很充足的情况下,可以只部署 1 个 NSX Manager 节点,这样还可以大大降低资源的占用。

通过将 Excel 参数表转换成 JSON 配置文件,然后找到 JSON 文件中关于 NSX 的配置,如下所示。

 "nsxtSpec":
  {
    "nsxtManagerSize": "medium",
    "nsxtManagers": [
      {
          "hostname": "vcf-mgmt01-nsx01a",
          "ip": "192.168.32.67"
      },
      {
          "hostname": "vcf-mgmt01-nsx01b",
          "ip": "192.168.32.68"
      },
      {
          "hostname": "vcf-mgmt01-nsx01c",
          "ip": "192.168.32.69"
      }
    ],
    "rootNsxtManagerPassword": "Vcf5@password",
    "nsxtAdminPassword": "Vcf5@password",
    "nsxtAuditPassword": "Vcf5@password",
    "vip": "192.168.32.66",
    "vipFqdn": "vcf-mgmt01-nsx01",

将另外 2 个 NSX Manager 节点从 JSON 文件中删除,如下所示。这样你就可以只部署 1 个节点了。

  "nsxtSpec":
  {
    "nsxtManagerSize": "medium",
    "nsxtManagers": [
      {
          "hostname": "vcf-mgmt01-nsx01a",
          "ip": "192.168.32.67"
      }
    ],
    "rootNsxtManagerPassword": "Vcf5@password",
    "nsxtAdminPassword": "Vcf5@password",
    "nsxtAuditPassword": "Vcf5@password",
    "vip": "192.168.32.66",
    "vipFqdn": "vcf-mgmt01-nsx01",

3)调整 NSX Manager 默认存储策略

同样的原因,当硬件性能不够时,可以通过调整 vSAN 默认的存储策略,将 FTT 修改为 0,也就是没有任务副本,这样在部署 NSX Manager 组件的时候也可以加快部署,等后续 VCF 管理域部署成功之后,再将 NSX Manager 节点的 vSAN 存储策略调整为 vSAN ESA 默认的存储策略(RAID 5)。注意,这需要在 Cloud Builder 部署 NSX Manager 组件之前登录 vSphere Client 进行调整。

4)修改  NSX Manager 内存预留

同样的原因,当硬件资源不够时,可以将 NSX Manager 节点虚拟机的内存配置中的内存预留修改为“0”,也就是不占用分配的全部内存资源。当然这个可根据需要在 VCF 管理域部署成功之后登录 vSphere Client 进行修改。

四、准备 JSON 配置文件

1)Excel 参数表

下面是针对当前环境准备的 Excel 参数表,大家可以有个直观的了解。License 已经过处理。

  • Credentials 参数表

  • Hosts and Networks 参数表

  • Deploy Parameters 参数表

2)JSON 配置文件

后面将使用 JSON 格式的配置文件导入部署,只保留了 1 个 NSX Manager 节点。License 已经过处理。

{
    "subscriptionLicensing": false,
  "skipEsxThumbprintValidation": false,
  "managementPoolName": "vcf-mgmt01-np01",
  "sddcManagerSpec": {
    "secondUserCredentials": {
      "username": "vcf",
      "password": "Vcf5@password"
    },
    "ipAddress": "192.168.32.70",
    "hostname": "vcf-mgmt01-sddc01",
    "rootUserCredentials": {
      "username": "root",
      "password": "Vcf5@password"
    },
    "localUserPassword": "Vcf5@password"
  },
  "sddcId": "vcf-mgmt01",
  "esxLicense": "00000-00000-00000-00000-00000",
  "taskName": "workflowconfig/workflowspec-ems.json",
  "ceipEnabled": false,
  "fipsEnabled": false,
  "ntpServers": ["192.168.32.3"],
  "dnsSpec": {
    "subdomain": "mulab.local",
    "domain": "mulab.local",
    "nameserver": "192.168.32.3"
  },
  "networkSpecs": [
    {
      "networkType": "MANAGEMENT",
      "subnet": "192.168.32.0/24",
      "gateway": "192.168.32.254",
      "vlanId": "0",
      "mtu": "1500",
      "portGroupKey": "vcf-mgmt01-vds01-pg-mgmt",
      "standbyUplinks":[],
      "activeUplinks":[
        "uplink1",
        "uplink2"
      ]
    },
    {
      "networkType": "VMOTION",
      "subnet": "192.168.40.0/24",
      "gateway": "192.168.40.254",
      "vlanId": "40",
      "mtu": "9000",
      "portGroupKey": "vcf-mgmt01-vds01-pg-vmotion",
      "includeIpAddressRanges": [{"endIpAddress": "192.168.40.4", "startIpAddress": "192.168.40.1"}],
      "standbyUplinks":[],
      "activeUplinks":[
        "uplink1",
        "uplink2"
      ]
    },
    {
      "networkType": "VSAN",
      "subnet": "192.168.41.0/24",
      "gateway": "192.168.41.254",
      "vlanId": "41",
      "mtu": "9000",
      "portGroupKey": "vcf-mgmt01-vds02-pg-vsan",
      "includeIpAddressRanges": [{"endIpAddress": "192.168.41.4", "startIpAddress": "192.168.41.1"}],
      "standbyUplinks":[],
      "activeUplinks":[
        "uplink1",
        "uplink2"
      ]
    },
    {
      "networkType": "VM_MANAGEMENT",
      "subnet": "192.168.32.0/24",
      "gateway": "192.168.32.254",
      "vlanId": "0",
      "mtu": "9000",
      "portGroupKey": "vcf-mgmt01-vds01-pg-vm-mgmt",
      "standbyUplinks":[],
      "activeUplinks":[
        "uplink1",
        "uplink2"
      ]
    }
  ],
  "nsxtSpec":
  {
    "nsxtManagerSize": "medium",
    "nsxtManagers": [
      {
          "hostname": "vcf-mgmt01-nsx01a",
          "ip": "192.168.32.67"
      }
    ],
    "rootNsxtManagerPassword": "Vcf5@password",
    "nsxtAdminPassword": "Vcf5@password",
    "nsxtAuditPassword": "Vcf5@password",
    "vip": "192.168.32.66",
    "vipFqdn": "vcf-mgmt01-nsx01",
    "nsxtLicense": "33333-33333-33333-33333-33333",
    "transportVlanId": 42,
    "ipAddressPoolSpec": {
       "name": "vcf-mgmt01-tep01",
       "description": "ESXi Host Overlay TEP IP Pool",
       "subnets":[
          {
             "ipAddressPoolRanges":[
                {
                   "start": "192.168.42.1",
                   "end": "192.168.42.8"
                }
             ],
             "cidr": "192.168.42.0/24",
             "gateway": "192.168.42.254"
          }
       ]
    }
  },
  "vsanSpec": {
      "licenseFile": "11111-11111-11111-11111-11111",
      "vsanDedup": "false",
      "esaConfig": {
        "enabled": true
      },
      "hclFile": "/opt/vmware/bringup/tmp/all.json",
      "datastoreName": "vcf-mgmt01-vsan-esa-datastore01"
  },
  "dvsSpecs": [
    {
      "dvsName": "vcf-mgmt01-vds01",
      "vmnics": [
        "vmnic0",
        "vmnic1"
      ],
      "mtu": 9000,
      "networks":[
        "MANAGEMENT",
        "VMOTION",
        "VM_MANAGEMENT"
      ],
      "niocSpecs":[
        {
          "trafficType":"VSAN",
          "value":"HIGH"
        },
        {
          "trafficType":"VMOTION",
          "value":"LOW"
        },
        {
          "trafficType":"VDP",
          "value":"LOW"
        },
        {
          "trafficType":"VIRTUALMACHINE",
          "value":"HIGH"
        },
        {
          "trafficType":"MANAGEMENT",
          "value":"NORMAL"
        },
        {
          "trafficType":"NFS",
          "value":"LOW"
        },
        {
          "trafficType":"HBR",
          "value":"LOW"
        },
        {
          "trafficType":"FAULTTOLERANCE",
          "value":"LOW"
        },
        {
          "trafficType":"ISCSI",
          "value":"LOW"
        }
      ],
      "nsxtSwitchConfig": {
        "transportZones": [
        {
          "name": "vcf-mgmt01-tz-vlan01",
          "transportType": "VLAN"
        }
        ]
      }
    },
    {
      "dvsName": "vcf-mgmt01-vds02",
      "vmnics": [
        "vmnic2",
        "vmnic3"
      ],
      "mtu": 9000,
      "networks":[
        "VSAN"
      ],
      "nsxtSwitchConfig": {
        "transportZones": [ {
          "name": "vcf-mgmt01-tz-overlay01",
          "transportType": "OVERLAY"
        },
        {
          "name": "vcf-mgmt01-tz-vlan02",
          "transportType": "VLAN"
        }
        ]
      }
    }
  ],
  "clusterSpec":
  {
    "clusterName": "vcf-mgmt01-cluster01",
    "clusterEvcMode": "intel-broadwell",
    "clusterImageEnabled": true,
    "vmFolders": {
      "MANAGEMENT": "vcf-mgmt01-fd-mgmt",
      "NETWORKING": "vcf-mgmt01-fd-nsx",
      "EDGENODES": "vcf-mgmt01-fd-edge"
    }
  },
  "pscSpecs": [
    {
      "adminUserSsoPassword": "Vcf5@password",
      "pscSsoSpec": {
        "ssoDomain": "vsphere.local"
      }
    }
  ],
  "vcenterSpec": {
      "vcenterIp": "192.168.32.65",
      "vcenterHostname": "vcf-mgmt01-vcsa01",
      "licenseFile": "22222-22222-22222-22222-22222",
      "vmSize": "small",
      "storageSize": "",
      "rootVcenterPassword": "Vcf5@password"
  },
  "hostSpecs": [
    {
      "association": "vcf-mgmt01-datacenter01",
      "ipAddressPrivate": {
        "ipAddress": "192.168.32.61"
      },
      "hostname": "vcf-mgmt01-esxi01",
      "credentials": {
        "username": "root",
        "password": "Vcf5@password"
      },
      "sshThumbprint": "SHA256:PYxgi8oEfK3j263pHx3InwL1xjIY1rAYN6pR607NWjc",
      "sslThumbprint": "FF:A2:88:5B:C3:9A:A0:14:CE:ED:6D:F7:CE:5C:55:B6:2B:6D:35:E8:60:AE:79:79:FD:A3:A7:6C:D7:C1:5C:FA",
      "vSwitch": "vSwitch0"
    },
    {
      "association": "vcf-mgmt01-datacenter01",
      "ipAddressPrivate": {
        "ipAddress": "192.168.32.62"
      },
      "hostname": "vcf-mgmt01-esxi02",
      "credentials": {
        "username": "root",
        "password": "Vcf5@password"
      },
      "sshThumbprint": "SHA256:h6HfTvQi/HJxFq48Q4SQH1TevWqNvgEQ1kWARQwpjKw",
      "sslThumbprint": "70:1A:62:4F:B6:A9:A2:E2:AC:6E:4D:28:DE:E5:A8:FE:B1:F3:B0:A0:3F:26:93:86:F1:66:B3:A6:44:50:1F:AE",
      "vSwitch": "vSwitch0"
    },
    {
      "association": "vcf-mgmt01-datacenter01",
      "ipAddressPrivate": {
        "ipAddress": "192.168.32.63"
      },
      "hostname": "vcf-mgmt01-esxi03",
      "credentials": {
        "username": "root",
        "password": "Vcf5@password"
      },
      "sshThumbprint": "SHA256:rniXpvC4JmiXVq7nd+FkjMrX+oTKCM+CgkvglKATgEE",
      "sslThumbprint": "76:84:9E:03:BB:C5:10:FE:72:FC:D3:24:84:71:F5:85:7B:A7:0B:55:7C:7B:0F:BB:83:EA:D7:4F:66:3E:B1:8D",
      "vSwitch": "vSwitch0"
    },
    {
      "association": "vcf-mgmt01-datacenter01",
      "ipAddressPrivate": {
        "ipAddress": "192.168.32.64"
      },
      "hostname": "vcf-mgmt01-esxi04",
      "credentials": {
        "username": "root",
        "password": "Vcf5@password"
      },
      "sshThumbprint": "SHA256:b5tRZdaKBbMUGmXPAph5s6XdMKQ5Mh0pjzgM0A16J/g",
      "sslThumbprint": "97:83:39:DE:C0:D3:99:06:49:FF:1C:E8:BA:76:60:C6:C1:45:19:BD:C9:10:B0:C2:58:AC:71:12:C8:21:A9:BF",
      "vSwitch": "vSwitch0"
    }
  ]
}

五、部署 SDDC 管理域

在准备以上所有环境后,现在正式进入 SDDC 管理域的部署。通过跳板机访问到 Cloud Builder 并完成登录。

选择 VMware Cloud Foundation 平台。

确定接受,点击 NEXT。

已准备好参数配置文件,点击 NEXT。

上传 JSON 配置文件,点击 NEXT。

完成配置文件检查,点击 NEXT。

点击确定部署 SDDC。

开始 SDDC Bringup 构建过程。

可以去吃个饭喝杯咖啡,然后完成部署。

部署过程的全部任务(之前截图)。

DOWNLOAD 部署报告,用了 2 小时。

点击 FINISH,访问 SDDC Manager。

跳转到 vCenter Server 并输入密码登录。

查看 VMware Cloud Foundation 版本。

六、SDDC 管理域相关信息

1)SDDC Manager

  • SDDC Manager 仪表盘

  • SDDC Manager 清单中所有工作负载域

  • vcf-mgmt01 管理工作负载域摘要

  • vcf-mgmt01 管理工作负载域中的主机

  • vcf-mgmt01 管理工作负载域中的集群

  • vcf-mgmt01 管理工作负载域组件证书

  • SDDC Manager 清单中的所有主机

  • SDDC Manager 中所包含的发行版本

  • SDDC Manager 中所创建的网络池

  • SDDC Manager 配置备份

  • SDDC Manager 中组件密码管理

2)NSX Manager

  • NSX 系统配置概览

  • NSX 节点设备

  • NSX 传输节点

  • NSX 配置文件

  • NSX 传输区域

  • NSX 配置备份

3)vCenter Server

  • VCF 管理域的主机和集群

  • VCF 管理域 vSAN ESA 存储架构

  • VCF 管理域相关组件虚拟机

  • VCF 管理域所使用的 vSAN 存储

  • VCF 管理域的分布式交换机配置

  • VCF 管理域 ESXi 主机的网络配置

效果

本文为实现如下前端效果的学习实践记录:

实践

入门的最佳实践我觉得是先去看官网,官网一般都会有快速入门指引。

根据官网的快速上手文档,构建一个新的Vue3+TypeScript,查看新建的项目结构:

image-20240726084701804

现在先重点关注components、views、App.vue与main.ts。

components
目录通常用于存放可复用的Vue组件。

views
目录用于存放页面级别的组件。这些组件通常对应应用的不同页面或路由视图。

App.vue
是Vue应用的根组件。它通常包含应用的全局样式和结构,是Vue实例挂载的起点,所有的其他组件都是从这个根组件开始渲染的。

main.ts
是Vue应用的入口文件。它负责创建Vue实例并将其挂载到DOM中。

学习Vue不单单学习Vue框架还要学习相关生态,作为刚开始学习Vue的人,自己写css或许不是一个好的选择,但是没关系,现在市面上已经有很多组件库了,一般只需要用这些组件库就满足绝大多数需求了。

刚开始学习可以使用element-plus。

image-20240726090609568

GitHub地址:
https://github.com/element-plus/element-plus

官网地址:
https://element-plus.org

在官网上了解其使用方式,这里简单学习,可以完整引入,在main.ts中添加:

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

app.use(ElementPlus)

如下所示:

image-20240726091526559

现在就可以开始用ElementPlus的组件了。

观察App.vue:

image-20240726091708592

只有views下的HomeView.vue。

再来看下HomeView.vue:

image-20240726091924491

只有来自components的Kuakua.vue。

再来看下Kuakua.vue:

<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'

const prompt1 = ref('')
const fetchData = async () => {
      try {
        const response = await axios.get('https://192.168.1.6:7101/Semantickernel');
        prompt1.value = response.data;
      } catch (error) {
        console.error('There was a problem with the Axios request:', error);
      }
    };
</script>

<template>
    <div>
     <el-row>
    <el-col :span="24">
    <el-space direction="vertical">       
    <el-text type="primary" size="large">夸夸</el-text>        
    <el-input
    v-model="prompt1"
    style="width: 300px"
     :rows="8"
    type="textarea"
    placeholder="Please input"
    clearable
    />  
    <el-button type="primary" round @click="fetchData">夸夸</el-button>
    </el-space>
    </el-col>
    </el-row>
    </div>
</template>

使用了ElementPlus中的UI组件进行布局。

使用v-model将prompt1绑定到el-input。

v-model的文档:
https://cn.vuejs.org/guide/components/v-model.html#component-v-model

image-20240726093140157

刚开始不需要全部看完,知道是为了实现双向绑定即可。

<el-button type="primary" round @click="fetchData">夸夸</el-button>

表示一个点击会触发fetchData函数的按钮。
@click

v-on:
的简写:

image-20240726093528032

在这个事件处理函数中我们需要向后端接口发送一个get请求,可以使用axios来发送http请求。

安装axios,引入axios,使用axios发送请求:

import axios from 'axios'

const fetchData = async () => {
      try {
        const response = await axios.get('https://192.168.1.6:7101/Semantickernel');
        prompt1.value = response.data;
      } catch (error) {
        console.error('There was a problem with the Axios request:', error);
      }
    };

即可实现开头的效果。

总结

Vue框架相关:了解Vue项目结构各个部分的作用,了解组件化开发思想,学习v-model、v-on。

前端生态相关:了解element-plus与axios。

TypeScript相关:类型注解和类型推断、箭头函数、异步函数(async/await)、模块导入。

就在昨晚,Meta发布了可以与OpenAI掰手腕的最新开源大模型:Llama 3.1。

该模型共有三个版本:

  • 8B
  • 70B
  • 405B

对于这次发布,Meta已经在超过150个涵盖广泛语言范围的基准数据集上评估了性能。此外,Meta还进行了广泛的人工评估,在现实场景中将Llama 3.1与竞争模型进行比较。Meta的实验评估表明:

405B版本的评估数据与目前最强的GPT-4、GPT-4o和Claude 3.5 Sonnet相比具有不错的竞争力:

file

此外,8B和70B版本与具有相似参数规模的模型相比也有相同甚至更好的表现:

file

使用 ollama 运行 Llama3.1

下面就来尝个鲜,手把手在本地把Llama3.1的8B版本跑起来。只要跟着下面的步骤做,你不需要有任何技术背景,也能完成。

  1. 安装 ollama

前往官网下载最新的 Ollama:
https://ollama.com/

file

  1. 下载完成之后,打开安装程序,并完成安装步骤。

  2. 打开终端,执行命令:
    ollama run llama3.1

等待模型下载完成

  1. 完成模型下载,如下图所示:

file

已经弹出提示:
Send a message
,可以与AI进行互动了。

  1. 测试一下,尝试让他教我学习Java?

file

彩蛋

最后,常规操作,问一下你是谁:

file

啥情况?是ChatGPT?看到这里的小伙伴也试试看,也是一样的结果吗?有朋友知道为什么吗?知道的评论区求解。

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

兴趣是最好的老师,
HelloGitHub
让你对编程感兴趣!

简介

HelloGitHub
分享 GitHub 上有趣、入门级的开源项目。

github.com/521xueweihan/HelloGitHub

这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、Java、Go、C/C++、Swift...让你在短时间内感受到开源的魅力,对编程产生兴趣!


以下为本期内容|每个月
28
号更新

C 项目

1、
darktable
:开源的摄影后期处理工具。这是一款免费且专业的摄影作品后期处理软件。它像一个虚拟的光桌和暗房,能够帮助摄影师存储数字底片、放大查看和检索照片。该软件可以显示照片的焦距和曝光度等信息,并支持编辑历史、地图模式和打印照片等功能。

2、
gnucash
:完全开源的财务软件。这是一款适用于个人和小型企业的开源财务软件,它采用复式记账法,提供了简洁的操作界面,并支持生成报表、对账、多国货币,以及获取股票实时价格等功能,适用于 Windows、Linux 和 macOS 平台。

C# 项目

3、
git-credential-manager
:通用的 Git 凭据管理器。这是一个基于 .NET 开发的 Git 凭证存储和管理工具。它开箱即用、无需额外操作,使用 git 命令时,工具会自动引导完成登录,后续无需再次登录,轻松解决对远程 Git 仓库进行操作时遇到的需要登录和认证失败等问题,支持 GitHub、Bitbucket 和 GitLab 等平台。

4、
Lean
:基于 C# 的量化交易引擎。这是一款采用 C# 编写的开源、经过实战考验的量化交易引擎。支持使用 Python3 或 C# 编写交易算法,兼容 Windows、Linux 和 macOS 平台,适用于量化交易策略研究、回测和实盘交易等场景。

5、
space-station-14
:开源游戏《14 号空间站》。该项目是经典游戏《Space Station 13》的开源重制版。在这款回合制多人角色扮演的游戏中,玩家可以选择各种角色,如工程师、船长和叛徒,并与其他玩家合作或竞争,在资源有限的环境中生存。

6、
subtitleedit
:开源的视频字幕编辑工具。这是一款适用于 Windows 的免费视频字幕编辑器。它开箱即用且功能强大,支持创建、调整、同步和翻录字幕,还提供了自动翻译、字幕格式转换和语音识别等功能。

C++ 项目

7、
diff-pdf
:直观比较两个 PDF 文件的工具。这是一款用 C++ 编写的 PDF 文件比较工具。它支持两种查看方式,将文件内容的差异输出到一个新的 PDF 文件,或直接在 GUI 中查看。

// 输出差异
diff-pdf --output-diff=diff.pdf a.pdf b.pdf
// 直接查看
diff-pdf --view a.pdf b.pdf

Go 项目

8、
buildg
:交互式的 Dockerfile 调试工具。该项是基于 BuildKit 的交互式调试 Dockerfile 的工具,支持设置断点、单步执行和非 root 模式,并且可以在 VSCode 等编辑器中使用。

9、
devzat
:程序员专属的 SSH 聊天室。这是一个通过 SSH 连接的聊天室,用户无需安装客户端,仅需一条 SSH 命令即可登录。它支持私人消息、多聊天室、图片和代码高亮等功能,还可以集成第三方服务、自托管 SSH 聊天室。

10、
expr
:Go 语言的表达式库。该项目是专为 Go 语言设计的表达式语言和求值引擎,支持丰富的算子和高级函数,具有安全、无副作用和静态类型检测等特点。表达式是一行由变量、运算符和函数组成的代码,它能够简化复杂的计算任务,多用于动态配置和业务规则引擎等场景。来自
@两双筷子sqldc
的分享

func main() {
    // 表达式
	code := `all(Tweets, {.Len <= 240})`

	program, err := expr.Compile(code, expr.Env(Env{}))
	if err != nil {
		panic(err)
	}

	env := Env{
		Tweets: []Tweet{{42}, {98}, {69}},
	}
    // 计算表达式
	output, err := expr.Run(program, env)
	if err != nil {
		panic(err)
	}

	fmt.Println(output)
}

11、
gdu
:快速查看磁盘使用情况的命令行工具。这是一个用 Go 语言编写的磁盘使用分析器,它能够快速扫描并展示文件和目录所占用的磁盘空间,支持 TUI(默认)、非交互和导出三种使用方式。

Java 项目

12、
cryptomator
:为你的云端文件“上锁”的工具。这是一款开源的云存储文件加密工具,支持 Dropbox、OneDrive 等主流云存储服务。它简单易用、跨平台、无需注册,采用 AES-256 加密上传至云存储的文件和目录,适用于需要备份数据至云端,又担心数据泄漏的场景。来自
@孤胆枪手
的分享

13、
JarEditor
:直接编辑 JAR 文件的 IDEA 插件。这是一款 IntelliJ IDEA 插件,让你无需解压即可直接编辑 JAR 文件中的 class 和资源文件。它支持添加、删除、重命名 JAR 包内的文件和目录,并提供了搜索和复制 JAR 包内容等功能,兼容 SpringBoot 和 Kotlin 项目。来自
@鹰影
的分享

14、
PojavLauncher
:Minecraft 游戏的 Android 启动器。该项目可以让你在 Android 上玩 Minecraft(我的世界),提供了离线和多人联机模式。它支持几乎所有版本的 Minercraft,还可以安装 Forge、Fabric 和 OptiFine 等模组和加载器。

JavaScript 项目

15、
grapesjs
:免费的可视化 Web 页面构建平台。该项目通过直观的可视化界面,让用户能够通过拖拽的方式,快速设计和构建网站的 HTML 模板。它所见即所得、移动端适配,适用于官网、新闻和 CMS 等类型的网站。

16、
react-content-loader
:轻松创建骨架屏的 React 组件。该项目是用于创建页面加载时的占位图 React 组件,它体积小、易定制,提供了多种预设样式和示例代码,拿来即用极易上手,支持 React、Vue 和 Angular 等主流框架。

import { Code } from 'react-content-loader'

const MyCodeLoader = () => <Code />

17、
Sink
:基于 Cloudflare 带访问统计的短链平台。该项目是运行在 Cloudflare 上的短链接服务,支持网址缩短、访问分析和链接有效期等功能。来自
@面条
的分享

18、
typebot.io
:自托管的聊天机器人构建器。该项目通过可视化的拖拽界面,让用户能够轻松创建高级聊天机器人,并将其嵌入网站中。它提供了 30 多种聊天构建块,支持自托管、分析工具、自定义域名和品牌定制等功能,适用于在线客服和销售支持等场景。

19、
typed.js
:极易上手的 JavaScript 打字动画库。该项目是专门用于创建打字动画效果的 JavaScript 库,它简单易用且 SEO 友好,支持删除效果、设置打字速度和循环次数等功能。

var typed = new Typed('.element', {
  strings: ["First sentence.", "Second sentence."],
  typeSpeed: 30
});

Kotlin 项目

20、
WiFiAnalyzer
:用于分析 WiFi 信号的 Android 应用。该项目是用 Kotlin 写的 WiFi 分析工具,它提供了直观的图表展示 WiFi 网络情况,支持识别周围的 WiFi、测量信号强度和查看频道拥挤程度等功能。

Python 项目

21、
buzz
:音频转录与翻译工具。该项目是基于 Whisper 的音频转录和翻译工具,它开箱即用且操作简单,支持语音转文字、音频翻译、多种语言和离线使用,适用于 macOS、Windows 和 Linux 平台。

22、
helium
:简化浏览器自动化的 Python 库。该项目是基于 Selenium 的轻量级 Python 库,它通过提供更高级和易用的 API,让用 Python 编写浏览器自动化脚本变得更加简单和方便,支持 Chrome 和 Firefox 浏览器。

23、
jurigged
:Python 的热重载工具。这是一个专为 Python 提供热重载功能的库,它支持在程序运行时修改和更新 Python 代码,无需重启程序。

# Loop over a function
jurigged --loop function_name script.py
jurigged --loop module_name:function_name script.py

# Only stop on exceptions
jurigged --xloop function_name script.py

24、
python-sortedcontainers
:更好用的 Python 排序集合库。该项目提供了 SortedList、SortedDict 和 SortedSet 三种数据结构,完全兼容 List、Dict、Set 内置数据类型的 API。尽管采用纯 Python 编写,其速度却可以媲美使用 C 扩展实现的 Python 库。

from sortedcontainers import SortedList
sl = SortedList(['e', 'a', 'c', 'd', 'b'])
# sl: SortedList(['a', 'b', 'c', 'd', 'e'])
sl *= 10_000_000
sl.count('c')  # 10000000
sl[-3:]  # ['e', 'e', 'e']

from sortedcontainers import SortedDict
sd = SortedDict({'c': -3, 'a': 1, 'b': 2})
# sd: SortedDict({'a': 1, 'b': 2, 'c': -3})
sd.popitem(index=-1)  # ('c', -3)

from sortedcontainers import SortedSet
ss = SortedSet('abracadabra')
# ss: SortedSet(['a', 'b', 'c', 'd', 'r'])
ss.bisect_left('c')  # 2

25、
radon
:Python 代码质量分析工具。这是一款强大的 Python 代码度量工具,它能够计算多种代码指标,包括 McCabe 复杂度、Halstead 指标和可维护性指数,适用于 Python 代码质量评估和持续集成等场景。

$ radon cc sympy/solvers/solvers.py -a -nc
sympy/solvers/solvers.py
    F 346:0 solve - F
    F 1093:0 _solve - F
    F 1434:0 _solve_system - F
    F 2647:0 unrad - F
    F 110:0 checksol - F
    F 2238:0 _tsolve - F
    F 2482:0 _invert - F
    F 1862:0 solve_linear_system - E
    F 1781:0 minsolve_linear_system - D
    F 1636:0 solve_linear - D
    F 2382:0 nsolve - C

11 blocks (classes, functions, methods) analyzed.
Average complexity: F (61.0)

Rust 项目

26、
komorebi
:Windows 的平铺窗口管理器。这是一款专为 Windows 设计的桌面窗口管理工具,支持自动平铺窗口、管理多个虚拟桌面和多显示器等功能,适用于 Windows 10 及更高版本。

27、
min-sized-rust
:优化 Rust 二进制文件大小的方法。Rust 构建时默认不会优化二进制文件的大小,该项目介绍了如何在保证 Rust 程序功能完整的同时,减少二进制文件体积的工具和技巧,适用于嵌入式和物联网等对程序体积敏感的场景。

28、
readyset
:Rust 开发的 SQL 数据库缓存引擎。该项目是采用 Rust 开发的 Postgres 和 MySQL 数据库缓存层,支持自动维护缓存、缓存复杂的 SQL 查询结果和保持数据实时同步等功能。使用时无需改动代码即可集成到现有的应用和数据库之间,显著提升查询性能。来自
@DeShuiYu
的分享

Swift 项目

29、
ATV-Bilibili-demo
:开源的 Apple TV 哔哩哔哩客户端。该项目是专为苹果电视(tvOS)设计的哔哩哔哩客户端,它可以用来观看 B 站上的视频、直播和弹幕,支持登录、投屏、搜索和历史记录等功能,就是安装有点麻烦。

30、
PlayCover
:在 Mac 上运行 iOS 游戏和应用的工具。该项目是专为 Apple Silicon Mac 设备(M 系列芯片)设计,用于运行 iOS 应用和游戏的工具。它通过模拟 iPad 环境和键盘映射功能,让用户可以在 Mac 电脑上玩 iOS 游戏,需自行下载 IPA 文件,适用于 macOS 12.0 或更高版本。

其它

31、
dart_simple_live
:简单易用的看直播工具。该项目可以让你在一个 APP 上看各种主流直播平台,并提供了 Android、iOS、macOS 和 Android TV 等客户端。

32、
github-readme-terminal
:用复古终端 GIF 展示 GitHub 个人资料。该项目可以根据你的 GitHub 个人数据,生成复古风格的电脑启动 GIF 动画,展示你的 GitHub 个人资料。

33、
hugo-book
:书籍风格的 Hugo 主题。这是一个开源的 Hugo 主题,能够帮助用户轻松创建类似书籍的文档网站。它拥有简洁的设计、适配移动端、支持多语言,适用于技术文档、在线教程和书籍等场景。

34、
OMOTE
:开源的通用遥控器。该项目是用 ESP32 制作的通用遥控器,它拥有 2.8 英寸电容触摸屏、2000 毫安电池和实体按键,支持红外、WiFi 和蓝牙连接方式,能够控制各种家电。

35、
pintree
:Chrome 书签变成导航站。该项目可以通过简单的几步,将 Chrome 浏览器的书签,转换成一个美观且易用的导航页面。由于生成的是静态网站,因此无法自动同步新增的书签。来自
@孤胆枪手
的分享

36、
Scoop
:Windows 命令行安装软件的利器。该项目是类似于 Homebrew 的 Windows 命令行安装工具。它可以从命令行安装应用程序,具有消除权限弹窗、隐藏 GUI 向导、自动处理依赖和防止污染 PATH 环境变量等特点。

scoop install sudo
sudo scoop install 7zip git openssh --global
scoop install aria2 curl grep sed less touch
scoop install python ruby go perl

开源书籍

37、
introduction-to-git-and-github-ebook
:《Git 和 GitHub 入门指南》。这是一本介绍 Git 和 GitHub 基础知识的开源书籍,内容包括安装 Git、GitHub CLI、分支管理和工作流程等实用知识。

38、
machine-learning-for-trading
:《Machine Learning for Algorithmic Trading》配套代码。这是一本关于如何将机器学习应用于交易策略的书籍,该项目是书籍的配套代码和资源,包含 150 多个代码示例,涵盖了数据采集、模型训练和策略评估等方面。

机器学习

39、
gpt-computer-assistant
:极简的 GPT-4o 客户端。该项目是适用于 Windows、macOS 和 Ubuntu 的 GPT-4o 客户端,它拥有极简的用户界面,支持执行多种任务,包括读取屏幕、打开应用、系统音频和文本输入等。

40、
mem0
:增强 LLM 上下文连续性的 Python 库。该项目能为多种主流的大型语言模型提供记忆层,它支持保存用户与 LLM 交互时的会话和上下文,并能实时动态更新和调整,从而增强 AI 的个性化,适用于学习助手、医疗助理和虚拟伴侣等需要长期记忆的个性化 LLM 应用。

from mem0 import Memory
m = Memory()
# Add
result = m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
# Search
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
# Update
result = m.update(memory_id="m1", data="Likes to play tennis on weekends")

41、
Retrieval-based-Voice-Conversion-WebUI
:开箱即用的 AI 变声器。该项目是基于 VITS 的变声框架,仅需少量语音数据和普通的显卡,就能快速训练出高质量的语音转换模型。它提供了简单易用的 Web 和 GUI 界面,支持实时变声、人声和伴奏分离等功能。

最后

感谢参与分​享开源项目的小伙伴们,欢迎更多的开源爱好者来 HelloGitHub 自荐/推荐开源项目。如果你发现了 GitHub 上有趣的项目,就
点击这里
分享给大家伙吧!

本期有你感兴趣的开源项目吗?如果有的话就留言告诉我吧~如果还没看过瘾,可以
点击阅读
往期内容。

感谢您的阅读,如果觉得本期内容还不错的话
求赞、求分享
❤️