首页 文章 精选 留言 我的

精选列表

搜索[React Native],共10000篇文章
优秀的个人博客,低调大师

AI改变世界,美团改变AI Native

# **刚发布没两天。** 美团的AI浏览器就翻车了。 3月2日,美团光年之外团队高调宣布Tabbit AI浏览器公测。号称打磨半年,免费使用,聚合DeepSeek、Kimi、通义千问等顶尖大模型。 发布会的文案写得很漂亮,工作交给Tabbit,时间留给自己。 结果3月3日,一个独立开发者发了条帖子,直接把事情搞大了。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/455dba9578f99be8246263c0fc54f54b.png) image ## **一张对比图,炸出来的真相** 网友梦溪睡了吗在社交平台上发帖,称美团的AI浏览器Tabbit抄袭其个人产品陪读蛙的代码,并放出了两款产品界面的对比图。 帖子里写得很直白。 几千亿市值的公司,白嫖嫖到我头上了,shame on you。 左边是美团AI浏览器,右边是他的产品。 界面几乎一模一样。 这还不是最要命的。 有技术爱好者去扒了Tabbit的源代码和资源文件。结果发现了什么? 开发者甚至在源代码和资源中发现Read Frog相关的字符串名称,这可以坐实Tabbit确实使用陪读蛙项目来构建翻译之类的功能。 Read Frog,就是陪读蛙的英文名。 代码里居然还留着原项目的名字。 这波操作,属实有点离谱。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/344544912c839250b424b5c24912850b.png) image ## **GPL协议,你美团法务不知道吗** 问题的核心在于,陪读蛙是一款开源AI浏览器扩展工具,定位为沉浸式语言学习助手。 开源意味着代码公开,任何人都可以看,可以用。 但开源有协议啊。 网友表示,根据GPL协议,使用他的代码的产品都需要开源,而美团并未开源Tabbit。 GPL-3.0协议,在开源界号称最具传染性的协议。 什么叫传染性? 对于在逻辑上与开源代码有关联性且整体发布的衍生作品,只要其中有一部分适用了GPL V3协议发布,那么整个衍生作品都必须适用GPL V3协议而公开。 翻译成人话就是,你用了我的GPL代码,你整个产品都要开源。 不开源?那就是侵权。 Tabbit浏览器按照开源许可证协议也必须整体开源,光年之外没有将Tabbit整体开源就属于违反许可证的做法。 问题来了。 Tabbit开源了吗? 没有。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/b879819fd4db4dc98c1547b5bfec4784.png) image ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/e6eb53d2a852b098925e7e9a91c1e541.png) image ## **这事儿在法律上能赢吗** 很多人可能会问,GPL协议在国内有用吗?大公司随便白嫖,你能拿他怎么样? 还真能。 近日,一起关于GPL版权纠纷案裁判文书公示。一审判决书显示,GPL3.0协议是一种民事法律行为,具有合同性质,可认定为授权人与用户间订立的著作权协议,属于我国合同法调整的范围。 国内法院认的。 而且不只是认,还判过赔钱的案子。 根据开源软件的特性,GPL3.0协议规定的使用条件系授权人许可用户自由使用的前提条件,亦即协议所附的解除条件。一旦用户违反了使用的前提条件,将导致GPL3.0协议在授权人与用户之间自动解除,用户基于协议获得的许可即时终止。用户实施的复制、修改、发布等行为,因失去权利来源而构成侵权。 什么意思? 你违反GPL协议,你的授权自动终止。继续用,就是侵权。 法院据此判决玩友公司停止提供含有侵权沙盒分身功能源代码的四款软件的下载、安装和运营服务并赔偿罗盒公司经济损失及维权合理开支共计50万元。 这是国内首例GPL侵权判赔案。50万。 美团如果真的用了陪读蛙的代码,且没有按照GPL协议开源,法律风险是实实在在的。 ## **更骚的操作来了** 事情还没完。 有网友在扒Tabbit的时候,居然扒出了美团使用的API地址和对应的密钥。 然后呢? 然后大量网友把这些接口接入到自己的项目里,免费白嫖美团的额度。 你白嫖开源社区,我白嫖你的API。 这波属于因果循环,报应不爽。 虽然这个操作也不太合适,但说实话,围观群众的心情可以理解。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/f3237c7ed3448db900764307ad144506.png) image ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/5d09ace1d32627556e23b8d2380cc91f.png) image --- ## **个人开发者的困境** 这件事最让人唏嘘的,其实是独立开发者的处境。 作为Read Frog开发者,其实平时工作日有正式工作。 他是一边上班一边维护这个项目的。 陪读蛙可无缝接入多家大模型服务,你可以根据场景选择更合适的提供商。同时允许自定义Api Key,完全在本地运行,不依托于远程服务。 功能做得不错,用户评价也好,还是开源免费为爱发电的。 结果呢? 几千亿市值的大公司,直接拿去用了。界面抄了,代码用了,连字符串名字都没改。 然后该大公司高调开发布会,说我们打磨了半年。 打磨了半年,打磨了谁的代码? 个人或者小团队的开源作品的话,就算被不遵守许可证的盗版了也没什么办法。 这话说得扎心,但也是现实。 个人没钱没势,公司有资源敢赌。维权成本高得吓人,很多独立开发者只能选择放弃。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/a86f6526fae49dbd269e383d939323c9.png) image ## **美团到底在想什么** 说实话,这件事发生在美团身上,我是有点意外的。 美团旗下光年之外团队宣布,其全新产品Tabbit AI浏览器进入公测。作为服务于上班族、在校学生及内容创作者等人群的AI原生浏览器,Tabbit将网页浏览、全网搜索、AI对话与复杂任务执行融为一体。 定位挺高端的。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/8fdefe8bc83ab947272065576b9eba09.png) image Tabbit是美团光年之外团队推出的AI原生浏览器,从底层重构浏览体验,定位为智能工作伙伴。 从底层重构。 底层用的是独立开发者的开源代码,然后你告诉我从底层重构? 这就很尴尬了。 谁掌握了浏览器,谁就掌握了用户真实网络行为的训练数据,谁就有可能训练出最懂用户的个人AI代理。 浏览器是个好赛道,美团想下场可以理解。 但你堂堂几千亿市值的公司,连开源协议都不尊重,这合适吗? 光年之外当年可是王慧文豪言要打造中国OpenAI的团队。 打造中国OpenAI,从抄袭个人开发者开始? ## **这事儿后续会怎么样,美团道歉了** 就在大家以为这事要闹上法庭的时候,剧情突然反转。 3月3日,陪读蛙作者发布了最新声明。 在问题被指出后,Tabbit团队第一时间与作者取得联系,并对项目使用情况进行了说明与内部自查。从沟通过程来看,对方态度积极、处理及时。 美团主动联系了。 而且动作很快。 作者也确认,本次问题并非出于主观恶意,而是对开源协议理解和合规流程不够严谨所致。 说白了,不是故意的,是不懂规矩。 最关键的来了。 目前相关代码已完成开源处理,双方也在进一步沟通后续事宜。 开源了。 按照GPL协议的要求,开源了。 这波处理,说实话,比我预想的要好。 ![image](https://developer.qcloudimg.com/http-save/yehe-5421023/dd90b29bc306a70fe2bd0abf76b52289.png) image ## **最后说两句** 这件事能这样收场,其实是最好的结果。 开源社区的健康发展,离不开规则意识与相互尊重。 作者在声明里写了一段话,我觉得说得挺好的。 作为一名开发者,也作为中国人,他乐于看到国内AI浏览器与技术产品不断进步、走得更远。在尊重开源规则与作者权益的前提下,技术合作与良性发展才是更值得期待的方向。 格局打开了。 没有揪着不放,没有狮子大开口,而是选择了和解与共建。 美团这边也算是知错就改。被指出问题后没有装死,没有冷处理,第一时间沟通,第一时间整改,第一时间开源。 这才是大公司该有的态度。 当然,这件事也给所有企业提了个醒。 用开源代码之前,先看清楚协议。GPL、MIT、Apache,每个协议的要求都不一样。别等到出了事再补救,那时候口碑已经受损了。 合规这件事,不是成本,是底线。 希望这次的事情能成为一个正面案例。 企业尊重开源协议,开发者愿意沟通合作,社区理性讨论而非一味谩骂。 这样的生态,才能让更多人愿意参与开源,才能让技术真正向前走。 Tabbit浏览器本身的产品理念其实挺好的,工作交给AI,时间留给自己。 希望它能在合规的基础上越做越好。 也希望陪读蛙能获得更多关注和支持。 毕竟,独立开发者为爱发电,值得被看见。 *开源精神的核心是共享与尊重,你怎么看这次的和解?欢迎评论区聊聊。*

优秀的个人博客,低调大师

云原生(cloud native)是什么,怎么理解

很多人都会问“到底什么是云原生”,对此,CNCF 官方大使、阿里云容器平台高级技术专家张磊曾经做过精彩的解释。 实际上,云原生是一条最佳路径或者最佳实践。更详细的说,云原生为用户指定了一条低心智负担的、敏捷的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。 因此,云原生其实是一套指导进行软件架构设计的思想。按照这样的思想而设计出来的软件:首先,天然就“生在云上,长在云上”;其次,能够最大化地发挥云的能力,使得我们开发的软件和“云”能够天然地集成在一起,发挥出“云”的最大价值。 所以,云原生最大的价值和愿景,就是认为未来的软件,会从诞生起就生长在云上,并且遵循一种新的软件开发、发布和运维模式,从而使得软件能够最大化地发挥云的能力。说到了这里,你也可以思考一下为什么容器技术具有革命性? 其实,容器技术和集装箱技术的革命性非常类似,即:容器技术使得应用具有了一种“自包含”的定义方式。所以,这样的应用才能以敏捷的、以可扩展可复制的方式发布在云上,发挥出云的能力。这也就是容器技术对云发挥出的革命性影响所在,所以说,容器技术正是云原生技术的核心底盘。 云原生的技术范畴 云原生的技术范畴包括了以下几个方面: 第一部分是云应用定义与开发流程。这包括应用定义与镜像制作、配置 CI/CD、消息和 Streaming 以及数据库等。 第二部分是云应用的编排与管理流程。这也是 Kubernetes 比较关注的一部分,包括了应用编排与调度、服务发现治理、远程调用、API 网关以及 Service Mesh。 第三部分是监控与可观测性。这部分所强调的是云上应用如何进行监控、日志收集、Tracing 以及在云上如何实现破坏性测试,也就是混沌工程的概念。 第四部分就是云原生的底层技术,比如容器运行时、云原生存储技术、云原生网络技术等。 第五部分是云原生工具集,在前面的这些核心技术点之上,还有很多配套的生态或者周边的工具需要使用,比如流程自动化与配置管理、容器镜像仓库、云原生安全技术以及云端密码管理等。 最后则是 Serverless。Serverless 是一种 PaaS 的特殊形态,它定义了一种更为“极端抽象”的应用编写方式,包含了 FaaS 和 BaaS 这样的概念。而无论是 FaaS 还是 BaaS,其最为典型的特点就是按实际使用计费(Pay as you go),因此 Serverless 计费也是重要的知识和概念。 MBaaS(Mobile Backend as a Service),简称 BaaS FaaS(Function as a Service) 总的来说,云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。除了容器、Kubernetes、Service Mesh等当前比较有代表性的技术,很多企业也在边缘计算方面开展了很多工作 基础设施向云演进的意义 其实,传统的应用所依赖的基础设施正在经历一个向云演进的过程,在此过程中,为我们提供了两个非常重要的优点。 第一个优点是基础设施的一致性和可靠性。同样一个镜像,无论是在美国打开,在中国打开,还是在印度打开都是一样的。并且其中的 OS 环境对于应用而言都是一致的。而对于应用而言,它就不需要关心容器跑在哪里,这就是基础设施一致性非常重要的一个特征。 第二个优点即这样的镜像本身就是自包含的,其包含了应用运行所需要的所有依赖,因此也可以漂移到云上的任何一个位置。 此外,云原生的基础设施还提供了简单、可预测的部署和运维能力。由于现在有了镜像,应用还是自描述的,通过镜像运行起来的整个容器其实可以像 Kubernetes 的 Operator 技术一样将其做成自运维的,所以整个应用本身都是自包含的行为,使得其能够迁移到云上任何一个位置。这也使得整个流程的自动化变得非常容易。 应用本身也可以更好地扩容,从 1 个实例变成 100 个实例,进而变成 1 万个实例。最后,我们可以通过不可变的基础设施来快速部署周围的管控系统和支撑组件。因为,这些组件本身也是容器化的,是符合不可变基础设施理论的组件。这些就是不可变基础设施为用户带来的最大优点。 本文转载自https://mp.weixin.qq.com/s/lbXH0Zk89A9Sf-yy8oveDA

优秀的个人博客,低调大师

Android Native禁止使用系统私有库详解

系统私有库指的是,存放在android系统/system/lib/和/vendor/lib下面,但是Android NDK中没有公开API的lib库。 从Android N开始(SDK >= 24),通过dlopen打开系统私有库,或者lib库中依赖系统私有库,都会产生异常,甚至可能导致app崩溃。具体可以阅读官方文档说明。 这个变更会有怎样的影响呢? 曾经的美好 在以前,在ndk层面,我们是可以使用一些hack的手段得到系统的私有api的。 比如,你想使用虚拟机中的一些内部符号,在N以下版本,你可以这么搞 void *handle = dlopen("libart.so", RTLD_NOW); void *originFunc = dlsym(handle, "_ZNK3art6Thread13DumpJavaStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE"); 这样你就能得到art::Thread::DumpJavaStack的函数指针,然后愉快地调用它了。 晴天霹雳 但是到了N以后, void *handle = dlopen("libart.so", RTLD_NOW); // 没问题,返回了handle指针。 void *originFunc = dlsym(handle, "_ZNK3art6Thread13DumpJavaStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE"); // 失败!得到的originFunc为空! 这就很奇怪了,我们能够得到handle指针,就说明libart.so是找到了。但是为什么libart.so中却没有找到art::Thread::DumpJavaStack的符号呢? 看一下内存映射表,我们发现了一个有趣的东西 7de5d4d000-7de5d4e000 r-xp 00000000 fe:00 774 /system/fake-libs64/libart.so 7de5d4e000-7de5d4f000 r--p 00000000 fe:00 774 /system/fake-libs64/libart.so 7de5d4f000-7de5d50000 rw-p 00001000 fe:00 774 /system/fake-libs64/libart.so ... ... 7de6a04000-7de6feb000 r-xp 00000000 fe:00 1414 /system/lib64/libart.so 7de6feb000-7de6ffa000 r--p 005e6000 fe:00 1414 /system/lib64/libart.so 7de6ffa000-7de6ffd000 rw-p 005f5000 fe:00 1414 /system/lib64/libart.so 难怪,我们知道dlopen参数为libart.so的话,系统会先找到/system/fake-libs64/libart.so,而不是/system/lib64/libart.so。 而/system/fake-libs64/libart.so又是什么鬼?从名字上看,就知道他是个假的libart。在系统源码文件art/libart_fake/README.md中,我们找到了对他的解释, A fake libart made to satisfy some misbehaving apps that will attempt to link against libart.so. 这就是为了以防你们这些图谋不轨(misbehaving)的APP们做一些奇怪的事而专门设的套啊! 只要你自己的lib库依赖了libart.so或者试图打开libart.so,在linker查找libart.so时,因为fake-libs路径被设置在了查找路径表的靠前处,就会先找到/system/fake-libs64/libart.so,而不是真正的/system/lib64/libart.so。 设置fake-libs代码: @ frameworks/base/core/java/android/app/LoadedApk.java public static void makePaths(...) { ... // Add fake libs into the library search path if we target prior to N. if (aInfo.targetSdkVersion <= 23) { outLibPaths.add("/system/fake-libs" + (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : "")); } ... } 而这个/system/fake-libs64/libart.so的内容基本上的空的(art/libart_fake/fake.cc),所以在它里面当然什么符号都找不到啦~ 霸王硬上弓 既然如此,那我们在dlopen中直接指定lib的绝对路径总行了吧?像这样: void *handle = dlopen("/system/lib64/libart.so", RTLD_NOW); 可是很遗憾,它报了一个错: 01-11 13:16:10.413 19869-19869/com.patch.demo E/linker: library "/system/lib64/libart.so" ("/system/lib64/libart.so") needed or dlopened by "/data/app/com.patch.demo-1/lib/arm64/libbcpatch.so" is not accessible for the namespace: [name="classloader-namespace", ld_library_paths="", default_library_paths="/data/app/com.patch.demo-1/lib/arm64:/system/fake-libs64:/data/app/com.patch.demo-1/base.apk!/lib/arm64-v8a", permitted_paths="/data:/mnt/expand:/data/data/com.patch.demo"] 也就是说,你被允许访问的路径(包含ld_library_paths、default_library_paths、permitted_paths)只有 /data/app/com.patch.demo-1/lib/arm64 /system/fake-libs64 /data/app/com.patch.demo-1/base.apk!/lib/arm64-v8a /data /mnt/expand /data/data/com.patch.demo 所以,试图访问/system/lib64/下的libart.so当然是不行的啦。 真是魔高一尺道高一丈啊。 至此,我们算是知道了Google封杀在ndk中访问系统私有库的方法。本质是在linker中加入一系列校验机制来做限制。linker作为最基础的lib库链接器,所有链接行为都会被限制住。 缓兵之计 不过,在Android N,你可以指定APP的sdk为API级别23或更低。那么,对于以下灰名单中的lib,仍然可以正常使用: // TODO(dimitry): The grey-list is a workaround for http://b/26394120 --- // gradually remove libraries from this list until it is gone. static bool is_greylisted(const char* name, const soinfo* needed_by) { static const char* const kLibraryGreyList[] = { "libandroid_runtime.so", "libbinder.so", "libcrypto.so", "libcutils.so", "libexpat.so", "libgui.so", "libmedia.so", "libnativehelper.so", "libskia.so", "libssl.so", "libstagefright.so", "libsqlite.so", "libui.so", "libutils.so", "libvorbisidec.so", nullptr }; 这样的话,每次使用dlopen或者链接以上lib都会打印出一个警告,然后仍然正常执行原有功能。 同时Google也声明了,在将来的版本会将这些lib的支持也一并移除。因此,这只是提供了一个让你尽快在代码中去除相关依赖的过渡期。 可见,不久的将来就无法愉快地使用系统的非公开符号了。 突出重围 那我们真的就没办法了吗? 也不是绝对的,Android限制的只是dlopen这个途径,而我们访问内存是随心所欲的:) 方法就是,通过内存映射表找到libart.so的真实起始位置: 7de6a04000-7de6feb000 r-xp 00000000 fe:00 1414 /system/lib64/libart.so 7de6feb000-7de6ffa000 r--p 005e6000 fe:00 1414 /system/lib64/libart.so 7de6ffa000-7de6ffd000 rw-p 005f5000 fe:00 1414 /system/lib64/libart.so 然后在加载地址起始位置手动解析libart.so的elf格式,提取出所需符号的位置信息。相当于你自己实现linker原本的查找逻辑。 当然,这种遍历内存解析elf的实现是比较复杂的。因此,这一次Google算是封死了一大波底层hack的手段。 不过,网上仍然有很多绕过这个限制的方式,大家有兴趣的可以自己发掘一下。 也可以来这里与我们共同讨论技术

优秀的个人博客,低调大师

native程序异常crash 定位解决方案

Android程序崩溃退出的时候,会将崩溃的堆栈信息保存在/data/tombstones目录下。 该目录需要ROOT权限才能够访问。所以为了访问该路径,手机必须先ROOT破解。jni或者java 代码崩溃的信息都被记录。该目录下会有九个tombstones_0(1-9),生成的崩溃信息会循环写入 该文件中,测试之前可以讲所有的文件删除,就可以得到唯一的一个崩溃日志。生成的文件 记录了详细的堆栈信息。 为了拷贝到电脑上,需要通过adb shell进入手机终端,然后su,获取root权限,接着 拷贝文件到sdcard上,退出adb shell,之后,通过adb pull /sdcard/tombstone_00 E: 拷贝到E盘 该文件详细记录了代码崩溃时候的具体信息,包括了崩溃的堆栈,如果能够获取到该信息,就可以通知堆栈了解崩溃点的信息,但是一般情况下,我们看不到该文件。 当我们发现/data目录为空的情况下,实际上表示我们没有root访问权限,(root是最高级的访问权限,而不是启动的时候的访问文件的权限,这个权限需要对android手机进行权限进行破解) 注意 查看tombstons文件,发现很多情况下,没有提供源码错误的函数名称和源码的错误行号,可以通过ndk-stack.exe 程序对崩溃日志再次定位 $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump tombstons 例子 D:\Development\Android\android-ndk-r10b\ndk-stack.exe–sym armeabi-v7a –dump E:\docs\tombston_01 > E:/detail.txt 附录: 不同的手机遇到空指针的时候,处理的方式是不一样的,小米手机直接闪退,而华为平板依然能够直接运行,跳过崩溃的错误,说明测试多种机型的重要性。 参考 http://cmzx3444.iteye.com/blog/1463035 本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1408644,如需转载请自行联系原作者

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册