2021-11-20

17 篇热帖

1. curl 创始人发文“质问”苹果:靠开源年赚数十亿,却把开发者当免费'工具人'


近日,curl 创始人兼首席开发者 Daniel Stenberg 在博客上发文“回怼”苹果引发热议。



据悉,本次事件的原因,是一位名为 @Michael Rieder 的用户在推特上向苹果官方账号 @AppleSupport 寻求帮助,但苹果却只是附上了 curl 的页面地址让该用户自行联系 curl 。



苹果方面如此“敷衍”的答复,不仅引来网友不满纷纷评论质疑,更是引起了 curl 创始人 Daniel Stenberg 的关注,因此专门在博客发文质问苹果。



Daniel Stenberg 原文内容如下:

“Imagine running a trillion dollar company that bundles various open source components into your products, making billions of dollars of profit annually. When one of your users reach out and ask for help, with the product you ship to your customers, you instead refer the user to the open source project. The project which is run by volunteers which you never sponsored with a cent.

Who would do something like that?”

https://daniel.haxx.se/blog/2021/11/18/free-apple-support/

文中他发出了“灵魂拷问”:你能想象一家资产达万亿美元的公司,靠捆绑各种开源组件年赚数十亿美元利润,却从没为这些开源项目赞助过一分钱吗?

他表示,开源项目都是由志愿者来管理的,在未提供支持和帮助的前提下,靠其牟利的公司却在用户向其寻求帮助时,把责任推给让开源项目。

那么,谁会干出这样的事呢?

随后,Daniel Stenberg 在文章底下附上了该事件苹果“推脱责任”敷衍用户的推特截图,对苹果进行“公开处刑”。

现在,我们回头来看那位在推特上向苹果 @AppleSupport 寻求帮助 的用户 @Michael Rieder ,他的问题是请求苹果“在 macOS12 中更新 CURL 的手册页”,因为“curl 是针对安全传输构建的,证书字符串可以是系统或用户密钥链中证书 /私钥的名称或公钥 hash 散列,否则这里的 -E (仅限 iOS 和 macOS )是无效的。”

对于这次事件,苹果直接将寻求帮助的用户推给 curl 项目的做法,Daniel Stenberg 显然是相当不满的。

作为 curl 的核心开发者,Daniel 对 curl 项目的热爱是有目共睹的,此前他也发文称至今已为 curl 提交了 16000 次 commit 。因此,对于来自外界的职业和批评,Daniel 向来都是硬气“回怼”。

早在今年 2 月份,Daniel 就对部分人批评 curl 项目不应该使用 GitHub 的观点进行了“回怼”——“我喜欢 GitHub”。

作为独立开源项目,curl 发展至今,也一直是在没有任何“基础设施部门”支撑的情况下完成的。大约 11 年前,自 curl 项目从 Sourceforge 切换到 Github 之后,就吸引了不少来自全球各地开发者、志愿者的加入,而这些志愿者们为该项目的付出,当然不能让靠其“牟利”的苹果公司来当做免费“工具人”。
2. M1 的兼容性可能没你想的那么好

看网上很多言论盛赞 M1 的兼容性,买之前我搜了下 B 站相关视频https://www.bilibili.com/video/BV1TK4y1L7DU (只是用作举例),觉得兼容性还不错

到手后用了一周发现是过于乐观了。

M1 对 X86 二进制文件的兼容性挺好,现在很多 App 甚至都有原生 ARM 版本。所以很多 app 和 x86 二进制文件都能完美运行。主要的问题出在涉及**C/C++**的编译流程上,老版本库尤其如此。在网上看到的很多人说 M1 兼容性好的操作是使用最新版。不得不说开发者社区很热情,很多开发工具 /库的最新版已经完美适配了 M1 。安装和使用都没有问题

老版本就是另外一种情况了。若干年前应该不会有人想到自己写的针对 X86 构建流程,有人会尝试在 arm 上去构建。所以涉及到**C/C++**编译的老版本软件很有可能会构建失败

我尝试安装 ARM 版的 python, 3.7 以下的版本还没有安装上。对老项目执行了pip install -r requirements.txt numpy,scipy,pandas,cryptography 等接近十个涉及到 C 的库全部不兼容,惊奇的是把这些库升级到最新版都能正常安装,只有一个库不支持, 但是也有人放出了支持的 wheel 包。最后要想使用这些库,我还得对升级后项目做一个大测试

设想一下,以前用 x86 ,很多 github 项目拷贝下来就能正常运行的,用了 M1 后可能就不行了~~

因此个人还是觉得 M1 适合视频工作者 /移动端,前端开发人员。他们的工具不太涉及到老版本工具的 C/C++构建流程

综上,我在办公室放了一台台式机,安装了 Exsi, 虚拟了 ubuntu 和 windows ,ARM 不支持的时候走远程开发流程

用了一下 jetbrains gateway ,可惜,体验并不好

希望各位开发大佬下单的时候考虑一下自己工作流的兼容性,尤其是老项目的兼容性

也希望远程开发工具能给力啊,毕竟谁不想拿个轻薄本连强大的服务器远程开发呢~~~

3. 网络交易诚信是很奢侈的要求吧?
闲鱼交易:

我自己做为买家、卖家的经历都有。

买手机,对方(真实一本院校女大学生)说没有任何问题,无拆修,全原。到手发现静音键坏了,去手机店换电池,结果店里人拆开一看,手机拆换过很多东西,螺丝都少好几个。

卖东西,全新未拆封的,到手砍价。

2 个闲鱼玩家,一个头像是「诚」这个汉字,赖着不确认收货;一个主页简介说诚信比自己命都重要,结果全新未拆封的东西到手,1 万多块钱,反复申请退款。

2 个月来交易 6 单,4 个有诚信问题。
说好的东西,最后都反悔,要么隐瞒实情。

尤其是那个 1 万多东西,反复申请退款的,反反复复扯了好几天皮,真的是把人搞抑郁了……

诚信是很奢侈的要求吧?
有没有好的方法尽量规避掉这些人?
4. 切实的感到经济不行

今天我爹找我借钱,说要帮他一个关系很好的朋友,还不上房贷,房子要被收走了,得救,否则得损失几十万,因此找我要十万块钱,最后给了两万,一方面是我没有理由要去帮一个我完全不认识的陌生人去帮他还房贷,毕竟自己的钱也不是天上掉的,二是自己手头压力也不小,今年已经累计借出了十一万块钱,感觉自己成了真实提款机. 至于借钱理由,有因为扬州封城生活困难的,有自己创业公司完蛋的,有房贷压力的,还有自己小孩要上学的,第一次感觉到身边的人困难到如此真实.

5. 荐输入法-百度输入法 [MacOS Big Sur 11.6.1 (20G224) +MacBook Pro (13-inch, M1, 2020) 验证 OK]
Mac 下的输入法一直是让人比较头疼的事情,前几年自己一直在用手心输入法,但眼看着 MacOS 都更新这么多个版本了他还一直『岿然不动』,上次更新貌似还是 2015 年了……

最近因为系统自带输入法导致 typora 卡顿的问题又开始找了一圈输入法,结果如下:
系统自带输入法:其实自带输入法改版几次了之后的确挺好用的,但是为啥就这种诡异的卡顿呢……不是自己卡就是导致其他 app 卡,是为了减少键盘损耗吗。。。
Google 输入法:停更。
腾讯输入法:停更。
sogou 输入法:广告多。
手心输入法:停更。
Rime:貌似繁体友好,简体不是很友好。
清歌输入法:看起来挺美好,但优先支持五笔。(不是他的问题,是我的问题。。)
最后找到了看起来比较简洁的,而且最近是在 2021 年更新的,百度输入法。
界面比较简洁,输入速度比较快,还能在线联想,目前没发现广告。

非广告。我也是简直了,一个企鹅员工在这推荐竞争对手的产品……
6. 不同意《用户协议》,如何与厂商协商修改

很多 app 和网站的用户协议完全是霸王条款,完全偏向厂商,做不到用户和厂商权责对等,我觉得起码得加上“用户可以在不告知厂商的情况下修改本协议”才算可以接受。 大家如果不同意协议,是怎么联系厂商协商条款的呢?

8. 关于“百度网盘” 我有话要说…
今天在用网盘看网课,突然转菊花卡死了(本机 Macbookpro M1 )。一股“怒火”涌上心头,遂点开“百度用户服务中心”准备写点用户建议。提交之前,转念一想:我为什么蠢到给这种企业写用户反馈?用户是用脚投票的,老子不用了,卸载! (顺路问问各位大神,这东西有什么替代品吗) 剪切--粘贴--来 V 站吐槽…… 原文如下:
1.苹果 M1 芯片上市一年了,作为国内互联网龙头企业,还没有适配 Apple silicon , 让人失望。
2.内存占用过多,尤其是视频播放。不知道是 Rosetta 转译的问题还是程序本身存在可优化空间。
3.看视频时,如果摘下耳机,视频也要重新打开才能有声音;并且在这一过程中有小概率卡死。
4.就算程序优化、适配 Apple silicon 有困难,起码也要将应用界面的外观与 macOS11 适配,如:程序边框 R 角。
5.打开视频有概率在视频中莫名其妙出现当前视频的名称。
6.不想在主界面看见诸如“一刻相册”、“限时低价超级特惠”等内容,其作用无异于喂用户吃屎,尤其是付费用户。
7.针对“第 6 点”,如果不能做到,那是否有给付费用户自行选择的权利的可能?
8.天下苦“百度系”久矣,望君自重!
9. 澳门 iPhone 13 Pro 加美版 AC+
现在澳门买 iPhone 不是每天在官网刷预约就是等澳门电信,不过官网预约需要澳门号码,我从我朋友那边借了一个,这个月十号正好刷到了一台,周五直接去银河拿货。澳门电信只要给 500MOP 定金就等通知拿机就好了,而且内地号码也可以的,不过有些慢。

买的是 iPhone 13 Pro MAX 512G 远峰蓝,价格 12299 葡币合 9801 元,算上浦发超白返现 10%,这一台只有 8821 元,比内地标价 11399 元便宜 2578 元,相当于 77 折拿下西比员工价 EPP 都便宜。


一开始考虑过美版的,转运到澳门,自己过关拿,价格比澳门版本的还便宜一点,不过美版不支持实体双卡,只能实体单卡+双 eSIM ,就没有考虑。

原来准备在澳门买 AppleCare+,不过一看价格很贵,要 1899 葡币,算下来和大陆购买的价格一样。于是跑美国官网购买美版 Apple Care+,按照条款 AppleCare+ 是可以全球保修的,不过有可能硬件有变化。比如美版的机器变成国行的机器,不过问题不大,能用就行。

购买过程有点麻烦,原来可以网页搞定,现在需要打电话给苹果,号码是+1800275 2273 ,用 Skype 可以免费打。直接和客服说你在线买不了 Apple Care+ 就可以了,我是转接了两次客服代表,提供了一下序列号就能
购买,需要注意的是如果问到你地址可以准备一个免税州的地址,我给了 15 刀的税,最后会让你打开 Apple 支持跑一下诊断就好啦,付款链接会发到你的邮箱里面,用信用卡给钱就好啦。两年的计划是 199 刀不含税,合人
民币 1270 元,大陆价格是 1498 元,便宜了 228 元。

大陆的 AC+必须要在购买七天内购买,美版可以在两个月内购买,时间宽容了很多。付款以后不到一个小时
AC+就生效啦的可以在官网查到。

总共算下来一共便宜了 2806 ,四舍五入就是一个亿🌚
接下来考虑从美国转运一台 MBP 回澳门再人肉背回来🌚
10. 好奇大家平躺床上看视频 iPad 是如何放的
是不是瘫着侧躺看电影 都是锁住屏幕旋转
11. 网络通信设备的设置中,为什么使用“使能”这个词语?用启用和开启不是更容易理解吗?
12. Elasticsearch 在未来会全面替代传统的关系型数据库吗?使用上有什么坑吗?

被业务每日新增的数据量所困扰,花了两个小时大概了解了一下 es ,感觉这个东西 [似乎] 可以完全替代关系型数据库的业务。也就是当完全不讨论它的设计初衷,即全文搜索的应用领域,单纯地考虑 es 替代 sql 储存关系型数值数据,似乎看起来也不错?

目前看来的优势: 1 、虽然声称是 nosql ,确实也是不支持 sql ,但是与 redis 等 nosql 不同,es 仍然可以进行一些包含关系型逻辑的搜索。这满足了日常业务的最低档条件。 2 、号称速度很快,全文搜索速度毋庸置疑,如果单纯拿来存数据的话,我没有测试过,不知道速度。 3 、横向扩展的便利性非常香,横向扩展方便不得不说是今天一个太大的优势了。点名批评 oracle ,可能是我笨,真的觉得集群学起来好费劲。 4 、数据库本身,以及工具链的安装非常友好。我本身 java 只能写 helloworld ,但是大概搜了搜直接官网和 github 下了几个工具感觉就完全能用了,初见的低成本令人心旷神怡。与之相对的,传统关系型数据库,比如某甲骨文,安装过程和工具链都给人一种沉重的感觉。

目前了解的缺点: 1 、不支持事务。这个不是大问题,我司事务基本靠业务端解决,不加给数据端。应该很多公司都这么操作,毕竟事务本身有局限性。 2 、权限管理很垃圾,这个是痛点之一,不过感觉大多数业务场合,靠前端中间件的话,也未必不是不能凑合? 3 、性能提升主要吃内存,落盘会让性能下降。这个我没测试过不了解。

总之目前是在考虑要不要尝试迁移,迁移目的是为了追求更高的插入性能和更低的搜索延迟,mysql 进行分库分表+集群各种优化后,数据量太庞大的情况下搜索延迟还是不尽如人意,之前尝试过 oralce 感觉学习成本太高,也没有质变级提升,这次 es 确实让人眼前一亮,不过既然主流工业界没有这么做,也许还存在一些坑也说不定,比如存在数据被污染问题?数据流偶尔缺失问题?更新时效性不足的问题?或者无法处理并发修改的种种问题?有没有踩过坑的大佬讲一讲如何,还有未来发展趋势。

13. mysql 减库存并发问题

减库存数量为 num

update mytable set inventory = inventory-num WHERE id= 1 and inventory >=num

这样减库存不用加乐观锁和悲观锁,也可以是吧

但是有什么弊端吗

14. 关于 asyncio 执行 IO 密集型操作的不解

有一个读文件然后写数据库的操作,想尝试使用协程。
使用协程的:

async def parse_text(file_path: Path, context_qs: [asyncio.Queue]):
    ql = len(context_qs)
    i = 0
    # 每一个 Queue 放 step 个数据就切换下一个
    step = 2
    with open(file_path, encoding="utf8") as f:
        for text in f:
            if i // step == ql:
                i = 0
            context_q = context_qs[i // step]
            context = {}
            text = re.findall(r"\d+", text)
            if text:
                context = {"解析然后组装成 dict"}
                await context_q.put(context)
                # 这里如果不 join ,会一直在这个 for 循环里不出去
                await context_q.join()
                i = i + 1
        else:
            await context_q.put("结束标记")
            return


async def write_db(context_q: asyncio.Queue, model: ModelBase):
    async with AsyncSession() as session:
        while 1:
            context = await context_q.get()
            if context["结束标记"] == "end":
                return
            info, obj = None, None
            try:
                if context["info"]:
                    info = await session.execute(
                        select(InfoModel).filter(
                            InfoModel.attr == context["info"]
                        )
                    )
                    info = info.scalars().one_or_none()
                    if not info:
                        info = InfoModel(attr=context["info"])
                        session.add(info)
                if context["header"]:
                    obj = await session.execute(
                        select(model).filter(
                            model.header == context["header"]
                        ).options(selectinload(getattr(model, "info")))
                    )
                    obj = obj.scalars().one_or_none()
                    if not obj:
                        obj = model(header=context["header"])
                        session.add(obj)
                if obj or info:
                    if info not in obj.info:
                        obj.info.append(info)
                        session.add(obj)
                    await session.commit()
            except Exception as e:
                await session.rollback()
                raise e
            else:
                context_q.task_done()


async def main():
	# 每个读取文件并解析的方法对应 c_q_count 个写数据库的方法
    c_q_count = 3
    a_context_qs = [asyncio.Queue() for i in range(c_q_count)]
    b_context_qs = [asyncio.Queue() for i in range(c_q_count)]
    tasks = [
        asyncio.create_task(
            parse_text(Path("a.txt"), a_context_qs)
        ),
        asyncio.create_task(
            parse_text(Path("b.txt"), b_context_qs)
        ),
    ]
    for i in range(c_q_count):
        tasks.append(asyncio.create_task(write_db(a_context_qs[i], AModel)))
        tasks.append(asyncio.create_task(write_db(b_context_qs[i], BModel)))
    await asyncio.gather(*tasks)



if __name__ == '__main__':
    asyncio.run(main(), debug=settings.DEBUG)

不使用协程的:

def sync_read_file():
    af = Path("a.txt").open(encoding="utf8")
    bf = Path("b.txt").open(encoding="utf8")
    with Session() as session:
        while 1:
            if af:
                try:
                    text = af.readline()
                    context = parse_text(text)
                    sync_write_db(session, context, AModel)
                except IOError:
                    af.close()
                    af = None
            if bf:
                try:
                    text = bf.readline()
                    context = parse_text(text)
                    sync_write_db(session, context, BModel)
                except IOError:
                    bf.close()
                    bf = None
            if not af and not bf:
                return


def sync_write_db(session, context, model):
    info, obj = None, None
    try:
        if context["info"]:
            info = session.execute(
                select(Info).filter(
                    Info.attr == context["info"]
                )
            )
            info = info.scalars().one_or_none()
            if not info:
                info = Info(attr=context["info"])
                session.add(info)
        if context["header"]:
            obj = session.execute(
                select(model).filter(model.info == context["info"]))
            obj = obj.scalars().one_or_none()
            if not obj:
                obj = model(info=context["info"])
                session.add(obj)
        if obj or info:
            if info not in obj.info:
                obj.info.append(info)
                session.add(obj)
            session.commit()
    except Exception as e:
        session.rollback()
        raise e


if __name__ == '__main__':
    sync_read_file()

这个协程的方法,每秒每个表可以写 400 多行,改为同步单线程的还是每秒写 400 多行。
不知道是我协程的用法有问题?还是说有别的什么原因?

15. 北美一年一度的苹果礼卡打折上线了.100 反 15

RT,有需要的可以上,Bestbuy 和 target 都有。 力度没去年大,每 100 只返 15 。但是聊胜于无了,叠加 amex 的 offer 和 paypal 的季度返现,做到 7~8 折应该不难。我在考虑叠上教育优惠买新的 mbp 16 。算下来勉强 8 折。

16. 14 寸 M1 Max 机型键盘中心处积热严重
可能由于过于保守的风扇策略,以及 SoC 在主板上的位置,我手上这台 14 寸 Max 只要是 CPU 不是完全空载,键盘中心处几乎长期处于温热状态,造成手部持续出汗,打字体验不太好。现在在纠结要不要换成 16 寸机型。有没有 16 寸 Max 朋友分享一下 16 寸是否有同样的问题?
17. 有没有什么浏览器扩展,可以整合管理 chrome、edge、firefox 浏览器的收藏夹?由于工作原因,目前我用了三种浏览器,每个浏览器都有各自的收藏夹,不能同步管理,很是崩溃。
如题,希望大佬帮忙推荐一下。我会不定时发送感谢。

谢谢大佬们了。