这样做的目的是彻底避免魔术数字( magic number ),并且希望在逻辑判断中直接通过指针比较。
代码 h 文件
typedef struct __BizType *BizTypeRef; // 对外暴露的常量声明 extern const BizTypeRef kBizTypeA; extern const BizTypeRef kBizTypeB; extern const BizTypeRef kBizTypeC; extern const BizTypeRef kBizTypeD;
实现文件
// 定义结构体 struct __BizType { int value; }; // 定义常量指针 const BizTypeRef kBizTypeA = &(const struct __BizType){ .value = 1 }; const BizTypeRef kBizTypeB = &(const struct __BizType){ .value = 2 }; const BizTypeRef kBizTypeC = &(const struct __BizType){ .value = 3 }; const BizTypeRef kBizTypeD = &(const struct __BizType){ .value = 4 };
使用
// 使用示例 void handleBiz(BizTypeRef type) { if (type == kBizTypeA) { // 处理业务 A } else if (type == kBizTypeB) { // 处理业务 B } }
]]>良心啊,用了三年了
]]>目前的迷茫点和想法:
目前个人目标:
其他:
乱七八糟说了这么多,总之就是想找到适合我的“赚钱途径”和“人生事业”。
毕业一年多来,我总是处在这种焦虑情绪中,现在写出来舒服多了。
]]>import android.content.Context import android.util.Log import com.wlld.common.utils.LogUtils import okhttp3.OkHttpClient import javax.net.ssl.SSLContext import javax.net.ssl.TrustManager import javax.net.ssl.X509TrustManager import java.security.SecureRandom
/**
OkHttp SSL 配置工具类
提供动态证书校验支持 */ object SSLConfigUtil {
private const val TAG = "SSLConfigUtil" private var dynamicTrustManager: DynamicSSLTrustManager? = null
/**
配置 OkHttp 使用动态 SSL 证书校验 */ fun OkHttpClient.Builder.configureDynamicSSL(context: Context): OkHttpClient.Builder { LogUtils.d(TAG, "🔧 开始配置动态 SSL...") return try { // 创建动态信任管理器 dynamicTrustManager = DynamicSSLTrustManager.create(context) LogUtils.d(TAG, "✅ 动态信任管理器创建成功")
// 创建 SSL 上下文 val sslCOntext= SSLContext.getInstance("TLS") sslContext.init(null, arrayOf<TrustManager>(dynamicTrustManager!!), SecureRandom()) LogUtils.d(TAG, "✅ SSL 上下文初始化完成") // 配置 SSL Socket Factory sslSocketFactory(sslContext.socketFactory, dynamicTrustManager!!) LogUtils.d(TAG, "✅ SSL Socket Factory 配置完成") LogUtils.d(TAG, "🎉 动态 SSL 配置应用成功!") this
} catch (e: Exception) { Log.e(TAG, "❌ 动态 SSL 配置失败", e) // 降级到不安全的配置(仅用于紧急情况) configureUnsafeSSL() } }
/**
配置不安全的 SSL (信任所有证书)
仅在紧急情况下使用 */ private fun OkHttpClient.Builder.configureUnsafeSSL(): OkHttpClient.Builder { Log.w(TAG, "Using unsafe SSL configuration - trusts all certificates") return try { val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out java.security.cert.X509Certificate>, authType: String) {} override fun checkServerTrusted(chain: Array<out java.security.cert.X509Certificate>, authType: String) {} override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> = arrayOf() })
val sslCOntext= SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, SecureRandom()) sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager) hostnameVerifier { _, _ -> true } this
} catch (e: Exception) { Log.e(TAG, "Failed to configure unsafe SSL", e) this } }
/**
/**
/**
/**
/**
/**
/**
package com.wlld.common.network
import android.content.Context import android.util.Log import com.wlld.common.R import java.io.ByteArrayInputStream import java.io.InputStream import java.security.KeyStore import java.security.KeyStoreException import java.security.NoSuchAlgorithmException import java.security.PrivateKey import java.security.cert.Certificate import java.security.cert.CertificateException import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import java.util.Date import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager
/**
动态 HTTPS 证书校验工具类
当证书过期时跳过校验,确保应用正常运行 */ class DynamicSSLTrustManager( private val context: Context ) : X509TrustManager {
private val defaultTrustManager: X509TrustManager private val customCertificates: MutableList<X509Certificate> = mutableListOf() private var skipValidation = false
companion object { private const val TAG = "DynamicSSLTrustManager"
// 检查证书是否过期 fun isCertificateExpired(certificate: X509Certificate): Boolean { return try { val expiratiOnDate= certificate.notAfter expirationDate.before(Date()) } catch (e: Exception) { Log.e(TAG, "证书过期检查出错", e) true // 如果无法检查,默认认为过期 } } // 创建动态信任管理器 fun create(context: Context): DynamicSSLTrustManager { return DynamicSSLTrustManager(context) }
}
init { Log.d(TAG, "🚀 DynamicSSLTrustManager 初始化开始")
// 初始化默认信任管理器 defaultTrustManager = createDefaultTrustManager() Log.d(TAG, "✅ 默认信任管理器初始化完成") // 加载自定义证书 loadCustomCertificates() Log.d(TAG, "🎯 DynamicSSLTrustManager 初始化完成 - 跳过校验模式: $skipValidation, 自定义证书数量: ${customCertificates.size}")
}
private fun createDefaultTrustManager(): X509TrustManager { return try { val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(null as KeyStore?) val trustManagers = trustManagerFactory.trustManagers trustManagers.firstOrNull { it is X509TrustManager } as? X509TrustManager ?: throw IllegalStateException("Default X509TrustManager not found") } catch (e: Exception) { Log.e(TAG, "Failed to create default trust manager", e) throw RuntimeException("Failed to initialize SSL trust manager", e) } }
private fun loadCustomCertificates() { try { // 加载 assets 中的证书文件 loadCertificateFromAssets("weilaiqiyuan.cer")
// 可以继续加载其他证书 // loadCertificateFromAssets("other_certificate.cer") Log.d(TAG, "已加载 ${customCertificates.size} 个自定义证书") // 如果没有找到任何证书,启用跳过校验模式 if (customCertificates.isEmpty()) { Log.w(TAG, "未找到任何自定义证书,启用跳过校验模式") skipValidation = true } } catch (e: Exception) { Log.e(TAG, "加载自定义证书失败,启用跳过校验模式", e) skipValidation = true }
}
private fun loadCertificateFromAssets(fileName: String) { try { context.assets.open(fileName).use { inputStream -> val certificate = loadCertificateFromStream(inputStream) if (certificate != null) { customCertificates.add(certificate) Log.d(TAG, "已加载证书: $fileName, 过期时间: ${certificate.notAfter}")
// 检查证书是否过期 if (isCertificateExpired(certificate)) { Log.w(TAG, "证书 $fileName 已过期,启用跳过校验模式") skipValidation = true } } } } catch (e: Exception) { Log.e(TAG, "从 assets 加载证书失败: $fileName", e) }
}
private fun loadCertificateFromStream(inputStream: InputStream): X509Certificate? { return try { val certificateFactory = CertificateFactory.getInstance("X.509") certificateFactory.generateCertificate(inputStream) as X509Certificate } catch (e: Exception) { Log.e(TAG, "解析证书失败", e) null } }
/**
动态添加证书 */ fun addCertificate(certificate: X509Certificate) { customCertificates.add(certificate) Log.d(TAG, "已添加新证书, 过期时间: ${certificate.notAfter}")
// 检查新添加的证书是否过期 if (isCertificateExpired(certificate)) { Log.w(TAG, "新添加的证书已过期,启用跳过校验模式") skipValidation = true } }
/**
/**
/**
/**
override fun checkClientTrusted(chain: Array<out X509Certificate>, authType: String) { // if (skipValidation) { // Log.w(TAG, "⚠️ 跳过客户端证书校验(证书过期或未找到)- 这可能导致抓包风险!") // return // } // // // 先检查自定义证书 // if (validateCustomCertificates(chain)) { // Log.d(TAG, "使用有效的自定义证书") // return // } // // // 使用默认校验 // try { // defaultTrustManager.checkClientTrusted(chain, authType) // } catch (e: CertificateException) { // Log.w(TAG, "默认客户端证书校验失败", e) // // // 检查是否因为过期导致的失败 // if (!checkCertificatesValidity(chain as Array<X509Certificate>)) { // Log.w(TAG, "客户端证书已过期,启用跳过校验模式") // skipValidation = true // return // } // // throw e // } }
override fun checkServerTrusted(chain: Array<out X509Certificate>, authType: String) { Log.d(TAG, "🔍 checkServerTrusted 被调用 - 验证服务器证书,authType: $authType") if (skipValidation) { Log.i(TAG, "跳过服务端证书校验(证书过期或未找到)") return }
// 先检查自定义证书 if (validateCustomCertificates(chain)) { return } // 使用默认校验 try { defaultTrustManager.checkServerTrusted(chain, authType) } catch (e: CertificateException) { Log.w(TAG, "默认服务端证书校验失败", e) // 检查是否因为过期导致的失败 if (!checkCertificatesValidity(chain as Array<X509Certificate>)) { Log.w(TAG, "服务端证书已过期,启用跳过校验模式") skipValidation = true return } throw e }
}
override fun getAcceptedIssuers(): Array<X509Certificate> { return if (skipValidation) { // 跳过校验时返回空数组,接受所有证书 emptyArray() } else { // 返回默认接受的证书颁发机构 defaultTrustManager.acceptedIssuers + customCertificates.toTypedArray() } }
/**
// // 如果自定义证书有效,优先使用 // for (customCert in customCertificates) { // if (!isCertificateExpired(customCert)) { // // 检查自定义证书是否覆盖 weilaiqiyuan.com 域名 // val subjectCN = extractCommonName(customCert.subjectDN.toString()) // if (subjectCN.contains("*.weilaiqiyuan.com") || subjectCN.contains("weilaiqiyuan.com")) { // Log.d(TAG, "使用有效的自定义证书验证 weilaiqiyuan.com 域名: $subjectCN") // return true // } // } // }
// 检查链中的证书是否与自定义证书匹配 for (cert in chain) { for (customCert in customCertificates) { if (cert.subjectDN == customCert.subjectDN) { // 找到匹配的自定义证书 if (!isCertificateExpired(customCert)) { // 🔍 严格验证证书:比较公钥指纹,防止证书伪造 if (verifyCertificateFingerprint(cert, customCert)) { Log.d(TAG, "✅ 证书验证通过(指纹匹配): ${cert.subjectDN}") return true } else { Log.w(TAG, "❌ 证书验证失败(指纹不匹配)- 可能是抓包攻击!") // 指纹不匹配,拒绝连接 throw CertificateException("证书指纹验证失败,可能存在中间人攻击") } } else { Log.w(TAG, "自定义证书已过期: ${cert.subjectDN}") return false } } } } return false } /** * 验证证书指纹,防止证书伪造 */ private fun verifyCertificateFingerprint(cert1: X509Certificate, cert2: X509Certificate): Boolean { return try { // 比较公钥的 SHA-256 指纹 val pubkey1 = cert1.publicKey.encoded val pubkey2 = cert2.publicKey.encoded val digest1 = java.security.MessageDigest.getInstance("SHA-256").digest(pubkey1) val digest2 = java.security.MessageDigest.getInstance("SHA-256").digest(pubkey2) val fingerprint1 = digest1.joinToString("") { "%02X".format(it) } val fingerprint2 = digest2.joinToString("") { "%02X".format(it) } val isValid = fingerprint1 == fingerprint2 Log.d(TAG, "证书指纹对比: $fingerprint1 vs $fingerprint2, 匹配: $isValid") isValid } catch (e: Exception) { Log.e(TAG, "证书指纹验证失败", e) false } } /** * 从 SubjectDN 中提取 Common Name */ private fun extractCommonName(subjectDN: String): String { val cnPattern = "CN=([^,]+)".toRegex() val match = cnPattern.find(subjectDN) return match?.groupValues?.get(1) ?: "" } /** * 获取自定义证书信息 */ fun getCertificateInfo(): List<String> { return customCertificates.map { cert -> "Subject: ${cert.subjectDN}, Issuer: ${cert.issuerDN}, Expires: ${cert.notAfter}, Expired: ${isCertificateExpired(cert)}" } }
}
]]>今年想着临近双十一,就去京东查了一下,现在 2999 。
简直堪比黄金
这是去年的贴 /t/1103553
]]>熟练后可以丝滑体验 Omarchy
项目地址: https://github.com/looplj/axonhub
感兴趣的可以看看,觉得有用的话,欢迎点个✨。
项目的具体能力,上次在 V2 有发过了,有兴趣的可以看看: t/1160378 。
现在的主要能力是作为一个通用的 AI 网关代理,可以代理不同的 API 格式,对外提供统一的 API ;包括 OpenAI 转 Anthropic ,也可以 Anthropic 转 OpenAI 。
不过本项目目标并不仅仅是一个 AI 网关,而是要成为一个 AI/Agent 开发平台,类似于当前的 OpenAI Platform ,可以有 proejct/thead/trace 等功能;然后也会尝试做一些 Agent 开发相关的能力。
当前 AI API 代理能力比较完善了,接下来会开始一些平台能力的开发。
更多信息大家可以看看项目 README ,有什么其他问题的欢迎提问或者创建 issue 。
]]>尝试谷歌搜索、站内搜索、调整 Jetbrains 终端类型/设置/字体均无法解决。
其他的一些尝试:
会占用你的时间 1 - 2 个小时,我们可以语音沟通问题。 费用暂定 200RMB
有意者可以留下你的联系方式。
]]>但是感觉自己更累了,搞不懂最后得到了什么。
]]>有没有已经转其他方案的 v 友,说说体验🤣
目前在留意 codex 和 glm4.6 。
]]>这两年,iOS (包括 iOS ,iPadOS ,macOS 等,以下统一叫 iOS 开发,不准确但顺嘴)开发,web 开发都玩过了。虽然做的东西市场看都懒得看,但是对各个平台的开发感受还是有一些的。
iOS 开发,SwiftUI 的代码,越写越乱,可能水平太差,但是就觉得装饰器放在结构的下面,越加越多,最后把整个结构都淹没了。 开发完审核特别麻烦,一遍一遍的不过,最重要的是不知道哪里有问题,不会改。但是一旦审核完毕,再提交新版本,一般就比较快了,基本一天就能通过上线。后期运维都比较方便。
web 开发,一开始就是因为觉得 iOS 审核太慢了,有个想法想要快速上线 MVP 验证,觉得还是 web 快。这个想法对也不对。如果是国外的开发者,可以使用 Vercel + Superbase 。这东西是真好用,用 Next.js 开发完,放到 GitHub 上就可以上线了。没了,对,没了。然后就可以找地方拉用户了。
但是啊但是,这个东西在国内用不了啊。羡慕国外的开发者。国内得自己去租服务器,买域名,ICP 备案,租 CDN ,自己维护数据库服务器,这些都得花钱。我 TM 就想做个 MVP 试试水,就让人割了。而且数据库要自己手动搭建维护,自己手动打包部署。如果要用单独的数据库服务和对象存储服务,兄弟,得加钱!
国内的开发环境感觉就像原始社会。
啊,对了,国内 iOS 应用上架也得租服务器,租域名,ICP 备案。打脸了。
难啊,麻烦啊,对小开发者太不友好了。
我就吐个槽,不是技术大拿,大家轻喷啊。
]]>已经有人改了代码,为这个版本添加专门的名称:𝜋thon
]]>求大家支支招,解决不了需求,我就只能解决提出需求的人了哈哈😁
]]>HTTP/1.1
、HTTP/2
、HTTP/3
、WebSocket
。安装很简单,只需一行命令:
go install github.com/go-dev-frame/sponge/cmd/sponge@latest
安装之后请看 perftest 的 使用指南。
单机压测执行命令示例:
# 指定总请求数 sponge perftest http --total=100000 --url=http://localhost:8080/user/1 # 指定压测时长 sponge perftest http --duration=30s --url=http://localhost:8080/user/1
当单机压测的能力不足时,使用集群压测,只需运行:
sponge perftest collector
然后在多台机器上执行:
sponge perftest agent --cOnfig=agent.yml
Collector 会自动汇总所有 Agent 的性能数据,并在 Web UI 实时展示,如下图所示:
对于大规模测试,手动管理节点是不现实的,因此提供了完整的 Kubernetes 部署脚本 perftest-deployment.yml
,直接:
kubectl apply -f perftest-deployment.yml
即可启动 Collector + Agent 集群压测。
想测试消息推送、IM 、通知系统性能?示例:
sponge perftest websocket --worker=100 --duration=1m \ --body='{"msg":"hello"}' --url=ws://localhost:8080/ws
QPS 、收发延迟、消息统计全都有。
perftest 是一款“从单机到集群”的压测工具,不花时间配置、不依赖外部组件,非常适合开发阶段接口调优、性能回归、系统瓶颈排查和高并发预演。
]]>非得重启一下才行? rm 之后变成空白目录了,就这还不能删 .....
]]>当时组 nas 的时候纯小白,直接全部选了 basic ,现在每个硬盘复制来复制去也怪麻烦,想着能不能最省事的改一下 raid ,硬盘分别是 2 块 hc320 2 块 hc550 。
]]>看来这种强行附加 DNS 的做法正在扩散,以后说不定还要禁止 DoH 。
]]>我现在用的是 CodeSpace 2c8g 的版本,这个对于我开发来说绰绰有余了,因为也就编译一些 C++,写一些 Python 的东西,而且系统也是 Debian 的,很方便,尤其是这个网络务必丝滑,拉镜像或者依赖相当之快
因为用量有点大,虽然我有 GitHub 的 Pro ,但是感觉还是有可能用超,我愿意付点小钱,想问问还有什么类似的平台
]]>没想到前几天居然出现硬盘显示异常,点了一下 app 上修复功能,也半天没修复,这下所有数据都没了,还好重要资料是同步到另个硬盘的。
现在想要一个稳定点的 nas ,求各位大佬推荐。群晖都说好,但是太贵,购物平台显示评论,都是几个月前的。
]]>为了避免耽误大家的时间,下面简单介绍下这款日志 App ,如果正好是你需要的,欢迎参与测试,再次强调,此为封闭式测试,无法通过公开链接获取 App ,必须要有 Google Play 账号(一般是 Gmail 邮箱)从 Google play 商城获取。
简单来说,它是一个强调文本记录的日志 App ,它的设计完全贴合我的个人使用习惯,算是比较有个性的一个产品。不同于传统的日志 App ,它主要有以下特性:
是的,一天一篇,最初的设定即如此,首页不再是列表,而是当天。基于这个设定,督促我把每天都点亮。即便哪天忘了,我也会努力回忆,补齐当天发生的事情。
除了常见的图文,日志中支持待办记录、事件(重要时刻)记录,未来计划支持每日消费支出、时间开销等记录形式。
对于数据这块,从一开始我便设计为本地储存,至于为什么这么设计,就无需多说了。同时,整个应用也是支持离线运行的。
数据也完全自主可控的,支持明文导出,不加密,不转码,自己的数据,自己做主,自己负责。
日志按每日拆分了,自然也能合并展示,每日待办可以统一页面管理,事件也可以按照日期或按照事件类别,进行展示及统计。
这个日志 App 的常规功能,不过多介绍了。
数据统计,也算是日志 App 的常规功能,不过多介绍。
再次说明:此次测试为封闭式测试,收到邀请的账号才能够下载 App ,所以,务必提供 Google Play 账号给我,我加到测试用户列表中,才会收到 App 的测试通知。
另外,该应用目前只测试了安卓 15 ,15 以下的系统版本,能够使用,但可能会有一些 UI 视觉上的问题,请见谅。
再次感谢参与测试的小伙伴,务必在评论区留下你的 Google 账号。
]]>gorm
中查询可能会返回一个 error ,我希望在出错的时候记录具体的执行的 SQL 语句是什么,但是我看 gorm 返回的 error 中并没有提供相关的获取 SQL 的信息,反而在 Logger 中可以通过 Trace 的方式来记录 Error 信息以及执行的 SQL 。 我疑惑的点在于是否应该通过 error 返回的时候携带具体执行的 SQL 语句更合适呢,这样在记录错误信息的时候也就能记录上相关出错的 SQL ,而通过 gorm 自身 Logger 的方法,就需要通过上下文关联才能定位到具体出错的 SQL 语句。
希望大家帮忙分析一下那个更合适
]]>也考虑过如果部署多端,感觉成本比较高。
]]>