百度App Objective-C/Swift 组件化混编之路(一)

2023-10-29

作者丨郭金、陈佳

来源丨百度App技术

一. 背景

1.1 Swift 发展历史

  • 2010 年 7 月,克里斯(Chris Lattner)开始设计 Swift。完成基础架构后,克里斯带领开发小组陆续完成语法设计、编译器、运行时、框架、IDE 和文档等相关工作。

  • WWDC 2014,经历四年的开发,Swift 发布。

  • WWDC 2015,Swift 2.0,苹果宣布 Swift 开源,包含编译器和标准库。这一阶段发展迅速,变动也非常频繁。因此开发者也都处于尝试或观望状态。

  • 2016 Swift 3.0,是语法和接口变化最大的一个版本,大量直接从 OC 移植过来的方法名被简化了,大量常用 Foundation 的类在 Swift 中改成了去掉 "NS" 前缀的结构体和类,原来 OC 方法名的很多描述性语句变成了 label,一些开发框架中的 C 语法 API(如 GCD、CoreGraphics等)也统一了风格, Swift 语法风格基本定型。

  • 2019 Swift 5.0,ABI 稳定,并且向后兼容。2019 年 3 月,Swift 5.0 正式发布。目前,Swift 的当前版本包含跨 Apple 平台的应用程序二进制接口(ABI)的稳定版本。这是朝着帮助开发人员在专用操作系统(如 iOS,macOS,tvOS,watchOS 和 iPadOS)上使用Swift迈出的一大步。苹果正在构建一个坚实的生态系统,因为现在标准的 Swift 库已包含在 OS 版本中。

1.2 ABI 稳定

ABI(Application Binary Interface),即应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间的接口。在 iOS 和 macOS 平台,Swift 编写的二进制程序在运行时通过 ABI 与其他程序库或组件进行交互。程序的编译会产生一个或者多个二进制实体,这些二进制实体必须在一些很底层的细节上达成一致,才能被链接在一起执行。可以说ABI就是一个规范,一种协议。它会规定如何调用函数,如何在内存中表示数据,甚至是如何存储和访问 metadata。Xcode 10.2 集成了 Swift 5.0 编译器,只要使用这个版本以上的编译器,编译出来的二进制就是 ABI 稳定的。

在此示例中,使用 Swift 5.0 构建的应用程序将在安装了 Swift 5 标准库的系统以及 Swift 5.1 或将来的 Swift 6 的系统上运行。

ABI 稳定的好处:

  • 减小包体积:iOS 12.2 以前版本,用 Swift 开发的 App 打包时需要将当前版本的 Swift 内置动态库打包进去;而 iOS 12.2 及以上版本,系统内置了 Swift 动态库,不用每个 App 单独内置,大大减小了包体积(实际减小的包体积大小和 App 用到的 Swift 标准库和系统版本都有关系)。

  • 节省内存:所有 App 使用同一个 Swift 运行时, App 启动不需要额外加载内置 Swift 动态库,在 iOS 12.2 及以上系统会更节省内存。

  • 减小启动耗时:同理,在 iOS 12.2 及以上系统因为启动时无需加载内置 Swift 动态库,也节省了启动耗时。

  • 不强依赖编译器:ABI 稳定之前,两个二进制组件需在同一编译器下编译。ABI 兼容性保障应用程序和各二进制组件可以分开编译,不强依赖编译器,应用和二进制形态组件也不用在同一编译器下编译。

  • Pure Swift:对于 Apple 工程师来说,可以直接在系统框架使用 Swift,而不必用 Objective-C 来 wrap 一遍,运行效率更高,维护成本更低。得益于 ABI 稳定,在 2019 年,Apple 也确实推出了 SwiftUI、RealityKit、Combine、CreateML 4个 Pure Swift 框架。

1.3 Module 稳定

Swift 库和库的 API 以 module 的方式导出,module 文件被编译创建和使用。Swift 5.1 引入了稳定基于文本的 module 接口文件,不同版本的编译器具备兼容性。Module 稳定使我们创建的 Swift framework 能够兼容未来的 Swift 版本。Module 稳定代表着描述模块 API 的信息格式稳定。这个信息会在编译时使用,它表明了这个库所有的类和函数都是什么,如同 C 语言的 header 文件一样。Swift 把这个信息存在一个名为 .swiftmodule 的二进制文件中。由于这个文件在不同编译器间不兼容,这意味着如果应用程序开发人员无法使用其他版本的 Swift 编译器引入该 framework。

Swift 5.1 实现了一个文本的方案来实现 Module 稳定,使用一个名为 .swiftinterface 的文本文件替换二进制的 .swiftmodule 文件,内容类似于 Xcode 中 swift 文件的 generated interface。

例如,你可以使用 Swift 6 构建框架,而该框架的接口将可由 Swift 6 和以后的 Swift 7 编译器读取。

Swift 不同版本的编译器编译出的产物可以互相引用,不会出现以下错误:

“Module compiled with Swift 5.1 cannot be imported by the Swift 5.2 compiler” 

1.4 Library Evolution

Library Evolution 允许二进制组件发生变化时,不用再重新编译其宿主。这样无论是系统框架发生变化时,还是开发者依赖的第三方框架发生变化时,开发者都不需要重新编译自己的应用(或框架)就能直接运行。

在此示例中,应用是基于框架的原始版本(黄色)构建的。由于 Library Evolution,它可以运行在包含黄色版本框架的系统上,也可以直接运行在升级后的红色版本框架的系统上。

1.5 ABI 稳定 、 Module 稳定和 Library Evolution

Swift 具有的特性

支持

状态

ABI 稳定 应用程序能在更高版本的 Swift 标准库环境下运行 Swift 5 之后开始支持
Module 稳定(并且 ABI 稳定) 组件能在更高版本的编译器环境下被引用 Swift 5.1 之后开始支持
Library Evolution 二进制组件在发生改变时,只要 API 向前兼容,引用它的宿主无须重新编译 Swift 5.1 之后开始支持

1.6 开源社区:

从图中可以看到,从 2016 年年中开始,github Swift 代码 push 的量已经超过了 OC,Swift 的新活跃开源项目也远超过 OC。开源推动了外部贡献者参与 Swift 生态建设,长期看 OC 三方开源库面临年久失修和新功能不支持的风险。

1.7 官方推荐

Apple 已经在开发文档中将 Swift 设置为默认示例语言,2019年 WWDC 发布了4个纯 Swift 的 Framework,不排除后面发布的 Framework 只有 Swift 版本的可能;另外 Apple 也积极开展高校合作,目前在美国已经有 18 所大学和学院将 Swift 纳入教学课程,同时也开发了面向高中和高等院校的《使用 Swift 开发》课程,和面向 4 年级至 8 年级学生的《人人能编程》课程;随着 Swift 语言的普及和编程门槛的降低,我们能做的就是为优秀的 Swift 开发者敞开大门。

另外,OC 和 Swift 也有良好的互操作性。至此,所有准备工作已就绪,对 iOS 开发者来说普及已经是大势所趋了。

二. Swift 的优势

2.1 开发效率

Swift 拥有简单而富有表现力的语法,即使你以前没有任何编码经验,也很容易理解。事实上,根据苹果公司的说法,Swift 被设计成第一种供任何人学习的编程语言。Swift 也同时吸收了很多语言的特性, 以至于各种不同语言的开发者写 Swift 的时候都会觉得特别熟悉特别亲切。以下是 Swift 从其他语言借鉴的特性或表示方法:

  • Dictionaries(或Hash Table):简洁的中括号初始化语法从 JavaScript 而来。

  • 数据类型推断:编译器通过变量的初始值很容易推断变量的数据类型。这个功能最早出现在 Haskell、Scala、Opa、微软也在 .Net 3.0 中引入了这个功能。

  • 泛型数据结构声明:Java 5 引入了泛型,通过尖括号中的数据类型,告诉编译器 HashMap,Array,Collection 等集合类中存储了何种数据类型。同一时间微软把这一功能引入到 C# 中。

  • 字符串模板:从 Cold Fusion、JSP 等语言而来。

  • 程序行尾可选分号:从 JavaScript、Python 而来。

  • Protocol(或 Interface):从 Java 和 C# 而来。

  • 元组(Tuples):元组是通过逗号分割,小括号括起来的类型列表,可以让一个函数有多个返回值,这种特性从 Lisp 和 Python 而来。 

  • 闭包:闭包的概念出现于 60 年代,最早实现闭包的程序语言是 Scheme。之后,闭包被广泛使用于函数式编程语言如 ML 语言和 LISP。

  • 协程(async/await):即将引入的协程,作为取代线程的更优雅的异步模型,来源于 Smalltalk、Ruby、Lua、Julia 和 Go 等语言。(Coming soon)

毕加索:(Good artists borrow, Great artists steal)

2.2 安全

Swift 语言的语法鼓励你编写简洁一致的代码,有时甚至会变得严格,同时提供了保护措施以防止错误并提高可读性。
  • 静态类型语言:IDE 在编译前就会检查代码中的错误,类型检查更加严格。

  • 类型推断:编译器可以在编译代码的时候通过表达式的值自动推断出表达式的类型。

  • guard: 我们可以使用 guard 语句来对后面的代码块加以保护,使代码块在未满足条件时能提前正常返回(return)或结束循环(break/continue)或异常退出(throw/fatalError())。

  • optional:默认情况下,Swift 对象不能定为 nil — 这在另一方面保证了 Swift 的安全性。实际上,Swift 编译器会在你尝试创建或使用 nil 对象时显示编译时错误,阻止你继续操作。这使得代码编写变得更简洁、更安全,并且可以防止 app 中出现大量的运行时崩溃。但是,在某些情况下,运用 nil 是适当合理的。针对这类情况,Swift 提供了一项创新功能,称为“可选类型”。可选类型可以包含 nil,但是 Swift 语法会强制要求你使用 ? 语法来安全地处理 nil。使用该语法,等于向编译器表明你理解此行为并将安全地进行处理。

2.2 编译优化

  • SIL(Swift Intermediate Language):SIL 会对 Swift 进行较高级别的语义分析和优化。包括高级别的语义分析,诊断转换,去虚拟化,特化,引用计数优化,TBAA(Type Based Alias Analysis)等。 

  • WMO:全模块编译优化。首先,编译器了解模块中所有函数的实现,所以它能够执行诸如函数内联和函数特殊化等优化。函数特化主要应该是指通过调用上下文传递的类型来生成一个基于特定类型的版本。但是很多情况下,会导致二级制级别的代码膨胀。有了全模块优化,能够把多处基于相同类型生成的函数优化为一个。

2.3 运行性能

  • 静态类型语言:静态类型语言比动态类型语言更快,因为类、方法、数据类型定义更清晰,编译器可以进行内联等优化、减少为支持引用类型而额外分配的内存空间,同时由于采用静态派发的方式也大幅提高了运行时方法的调用效率。

  • 静态派发:是在编译期就能确定的调用方法的派发方式。静态派发相比于动态派发更快,而且静态派发还会进行内联等一些优化,减少函数的寻址及内存地址的偏移计算等一系列操作,使函数的执行速度更快,性能更高。

  • Fast, Whole Module Optimization:开启 -O -whole-module-optimization,Swift 编译器将会同时考虑整个 module 中所有源码的情况,并将那些没有被继承和重载的类型和方法标记为 final,这将尽可能地避免动态派发的调用,或者甚至将方法进行内联处理以加速运行。

  • 结构体:结构体除了属性的存储更安全、效率更高之外,其函数的派发也更高效。由于结构体不能被继承,也就是结构体的类型被 final 修饰,其内部函数应该是属于静态派发,在编译期就确定了函数的执行方式,其函数的调用通过内联(inline)的方式进行优化,其内存连续,减少了函数的寻址及内存地址的偏移计算,其运行相比于动态派发更加高效。

  • Swift 的运行效率甚至能比肩 C++。可以参考 http://www.primatelabs.com/blog/2014/12/swift-performance/ 对 Swift 和 C++ 性能的比较。

2.4 内存管理

  • ARC:OC ARC 支持范围包含 Cocoa Touch framework,但不包含 CoreGraphics、CoreFoundation 等底层框架;Swift 所有 API 都支持 ARC。

  • COW:Copy On Write,写时复制,Swift 针对标准库中的集合类型(Array、Dictionary、Set)进行优化,当变量指向的内存空间并没有发生改变,进行拷贝时,并没有真正发生拷贝,而是指向原来的内存。只有当值发生改变时才会进行深拷贝。

  • 值类型:在 Swift 中定长的值类型都是保存在栈上的,操作时不会涉及堆上的内存。变长的值类型(字符串、集合类型是可变长度的值类型)会分配堆内存。

  • 引用类型:引用类型的存储属性不会直接保存在栈上,系统会在栈上开辟空间用来保存实例的指针,栈上的指针负责去堆上找到相应的对象。

  • 所有权:独占性原则——阻止以互相冲突的方式同时访问某个变量 ;允许被“共享”的值传递下去;允许标记某个类型不能被隐式复制。(Coming soon)

三. Swift 使用现状

3.1 百度App 及矩阵产品

全量工程化和工程改造前,百度App 在 Watch App、各独立 Widget、以及很少一部分 SDK 中使用 Swift。不过百度内部 柠檬爱美、古物潮玩、有噗等创新产品都广泛的使用 Swift 开发。

3.2 国内其他 App

根据现有公开资料,我们了解到手淘已全面支持 Swift,微信部分使用 Swift,今日头条的飞书(Lark)使用了 Swift。

3.3 国外 App

这篇文章(https://blog.csdn.net/Desgard_Duan/article/details/105872728)统计了国内外使用的 Swift 开发的 Top 100 应用列表,但并不明确各 App Swift 的应用范围,也不明确各 App 已经系统化解决 OC 和 Swift 在大型工程或组件化开发模式下的问题。

四. 影响面评估

4.1 应用体积的影响

对于 iOS 12.2 以下的系统,使用 Swift 编写的代码打包成 App 后需要额外内置 Swift 动态库。而 iOS 12.2 及以上版本,使用 Swift 5.0 以上编写的 Swift 代码,不再需要打包 Swift 运行时,相比之前,减小了 7.9 MB。

在"Swift 的优势"部分,我们已经看到 Swift 在开发效率、安全性、运行性能、内存管理方面的优势,也无明显劣势,所以普及也是顺其自然的事情了。

五. 落地步骤

在单工程源码模式下,我们为 Swift 访问 OC 建立 bridge 文件,Swift 编译时也会生成 *-Swift.h 头文件供 OC 调用;这样就可以实现 OC 和 Swift 混合开发。

在以并行开发,或者以 App 工厂为目标的 App ,都会对工程进行组件化拆分,不仅需要依赖管理工具的支撑,也需要对工程进行改造。百度App 目前使用组件化模式开发,同时兼容 源码、二进制 两种组件形态;因此需要保障组件间互操作性,保障对源码、二进制两种形态下的组件编译、链接过程的完整支撑。

百度App 整体落地步骤如下:

  • Swift 优势调研

  • 影响面评估

  • 编码规范制定及约束工具开发

  • EasyBox 工具链混编支持

  • 工程改造与实践

这篇文章介绍了前两部分,Swift 编码规范及约束工具有创新团队同学提供支持。后面两篇文章将重点介绍这里面的两个重点环节,工具链层面系统化支持 OC 和   Swift 混编,以及如何进行工程改造以支撑全面Swift全面应用开发。

六. 参考

  • WWDC 2019 - What's New In Swift:

    https://devstreaming-cdn.apple.com/videos/wwdc/2019/402fd460n3p3w5c/402/402_whats_new_in_swift.pdf?dl=1

  • WWDC 2016 - Understanding Swift Performance:

    https://developer.apple.com/videos/play/wwdc2016/416/

  • What is Module Stability in Swift and why should you care?

    https://www.donnywals.com/what-is-module-stability-in-swift-and-why-should-you-care/

  • ABI Stability and More:

    https://swift.org/blog/abi-stability-and-more/

  • 一次关于 Swift 在 iOS 生态圈里的现状调研:

    https://blog.csdn.net/Desgard_Duan/article/details/105872728

  • 手淘航母级 App 恋上 Swift 之路:
    https://mp.weixin.qq.com/s/_ecHx0-r_od1-AfpYNvchg
  • Swift vs Objective-C: Out with the Old, In with the New:

    https://www.altexsoft.com/blog/engineering/swift-vs-objective-c-out-with-the-old-in-with-the-new/
  • 10 features Apple 'stole' for the Swift programming language:

    https://www.infoworld.com/article/2606431/155797-10-prominent-features-stolen-by-Apple-s-Swift-and-where-they-came-fro.html#slide12
  • Writing High-Performance Swift Code:
    https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst
  • Swift 性能探索和优化分析:

    https://onevcat.com/2016/02/swift-performance/
  • Swift Concurrency Manifesto:

    https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782
  • Ownership Manifesto:

    https://github.com/apple/swift/blob/main/docs/OwnershipManifesto.md
  • Swift性能优化分析:

    https://juejin.cn/post/688786214412648449
  • Swift, C++ Performance:

    http://www.primatelabs.com/blog/2014/12/swift-performance/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

百度App Objective-C/Swift 组件化混编之路(一) 的相关文章

  • iPhone ImageView序列动画

    嘿 尝试将一个简单的 png 序列动画放入我的应用程序中 我在 IB 中放置了第一个框架 并将图形动画出口连接到它 序列中有 54 个 png 名称为 Comp 1 0000 png 到 Comp 1 00053 png 这是我的代码 vo
  • 监控剪贴板活动可可?

    是否可以在可可中 观看 用户剪贴板 例如 如果我的应用程序是系统托盘样式应用程序 例如 dropbox 客户端 我可以订阅用户在另一个应用程序中点击复制 粘贴时引发的事件吗 你可以随时查看Apple的示例代码 剪贴板查看器 http dev
  • Xcode UI 测试 - 通过 id 在 Webview 中查找元素

    我们的应用程序是混合的 包含 webview 我正在尝试使用 Xcode UI 测试自动化我们的应用程序 我能够使用以下方法找到网络按钮 let app XCUIApplication app launch let button app s
  • Swift 中不再有“private init”?

    我看到很多关于使用的参考private init在 Swift 中限制对象构造 例如this http krakendev io blog the right way to write a singleton 但当我尝试时 在 Xcode
  • 后台模式下的 AVSpeechSynthesizer

    我无法获取 iOS 7AVSpeechSynthesizer当我的 iOS 应用程序处于后台模式时工作 我添加了 应用程序播放音频 应用程序支持的后台模式的关键 但我仍然无法让它工作 我还研究了创建一个AVMutableCompositio
  • 在 swift 中使用自定义字体[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个用于 swift sprite kit iOS 的字体 该字体用于商业目的 我正在尝试拥有一
  • 设置属性文本后防止 UILabel 字体自动更改

    我发现如果我将属性文本设置为UILabel 预定义字体将更改为属性文本第一个字符的字体 例如 the font size is set to 20 in Interface Builder println theLabel font poi
  • 有没有办法更改 UITabBar 或 UITabBarItem 中的文本位置?

    这是我打算放在屏幕上的自定义选项卡栏 然而 我的搭档希望文字稍微向上一些 我怎样才能这样做呢 为什么不为视图控制器设置一个空的标题属性 并将标题添加到选项卡的自定义图像中 UPDATE 为了回答的完整性 来自评论和ios标签栏在没有图像时将
  • 在制作自定义 iOS 键盘扩展时,如何创建一个与 Apple 原始退格键具有相同功能的按钮?

    我正在制作一个自定义键盘 其中有用于删除文本的删除按钮 其代码是 func addDelete deleteButton UIButton buttonWithType System as UIButton deleteButton set
  • 将文件上传到 Google 云端硬盘时出错

    我已经在我的应用程序项目中实现了 Google Drive SDK 并尝试在 Google Drive 中上传图像 但出现错误 我的代码来自Here https developers google com drive quickstart
  • 如何将 AFNetworking 2 与摘要式身份验证结合使用

    我一直在搜索 AFNetworking 2 with Digest Authentication 一段时间 但没有找到关于它的有用讨论 除了this one https github com AFNetworking AFNetworkin
  • 为什么类方法中的“self = [[Rectangle alloc] init]”是错误的?

    在 Apple 的文档 Objective C 编程语言 中 第 48 页说道 Rectangle rectangleOfColor NSColor color self Rectangle alloc init BAD self setC
  • Swift 从 Realm 中删除对象

    我有领域对象保存来自 JSON 响应的列表 但现在如果该对象不再从 JSON 中出现在列表中 我需要删除该对象 我怎么做到这一点 这是我的领域初始化 func listItems dic Array lt String AnyObject
  • 块与代表[重复]

    这个问题在这里已经有答案了 可能的重复 代码块能完全取代委托吗 https stackoverflow com questions 4584404 do code blocks completely replace delegates 我刚
  • @interface 中的 Objective-c 特定 iOS 版本

    我正在尝试实现Apple Pay 并且我尝试实现两种方法 一种用于iOS10 一种用于iOS11 所以在我的实现中我有 void paymentAuthorizationViewController PKPaymentAuthorizati
  • 如果在系统设置中关闭隐藏式字幕,则不会显示字幕

    我正在尝试显示字幕 无论设备在辅助功能下设置了什么 目前 如果设备设置为英语并在设置中启用隐藏式字幕 则将播放英语字幕 如果设备设置为西班牙语 则将播放西班牙语字幕 我希望无论隐藏式字幕是否打开 都能播放字幕 我尝试添加这段代码 https
  • 验证 iOS 应用程序时出现 com.apple.developer.linked-domains 问题

    当我在 Xcode 中使用 Organizer 验证我的项目时 出现以下错误 无效的代码签名权利 你的申请包的签名包含代码签名权利iOS 上不支持的 具体来说 值 for key com apple developer associated
  • 优化构建中通用函数的 Core Data Swift 转换失败

    我们有一个具有相当广泛的核心数据模型的应用程序 其中有许多用 Objective C 实现的自定义子类 但越来越多的用 Swift 编写的应用程序也使用这些子类 值得一提的是 我们使用 Xcode 7 3 1 针对 iOS 9 3 进行构建
  • Alamofire 2.0 和 Swift 2 - 标头不起作用。看看如何修复它

    当我将项目升级到swift 2 with Alamofire 2 headers停止工作 代码中没有任何错误 原因是headers不按旧方式工作 login with Alamofire 1 and Swift 1 2 WITH HEADE
  • 用于测试对象类型的通用 Swift 函数

    我正在尝试编写一个函数 该函数接受一个对象和一个类型作为参数 并返回一个布尔值 指示该对象是否属于给定类型 似乎没有 Type 类型 所以我不知道如何做到这一点 我能做的最好的就是 func objectIsType

随机推荐

  • 解决vs中scanf_s问题

    1 scanf s 函数 2 Everything 3 解决问题 1 scanf s 函数 scanf s 函数是Microsoft公司VS开发工具提供的一个功能相同的安全标准输入函数 从vc 2005开始 VS系统提供了scanf s 在
  • 【攻防技术】信息收集之公众号自动收集

    0x00 有个大佬说过 渗透的本质就是信息收集 在边界突破的阶段 信息收集是前置条件 经过多年实战攻防的积累 现在信息收集已经形成了标准化的流程 因此我们在尝试建设自动化信息收集工具 防守方大部分的防守力量都会放到边界的web系统上 对于移
  • Linux查看文件大小的几种方法

    stat命令 stat filepath 第三行的Size字段就是文件的字节数 xanarry ThinkPad stat Downloads jdk 8u60 linux x64 tar gz File home xanarry Down
  • matplotlib画简单的折线图

    用matplotlib画一个简单的折线图 今天要画一个折线图 然后在大佬的推荐下用了matplotlib 用这篇博客来记录一下遇到的题和解决方法 并贴上最后的代码 问题 中文乱码 plt rcParams font sans serif S
  • 网络编程—epoll

    一 原理 epoll使用mmap减少复制开销 并且epoll使用 事件 的就绪通知方式 通过epoll ctl注册fd 一旦该fd就绪 内核就会采用类似callback的回调机制来激活该fd epoll wait便可以收到通知 二 最大连接
  • MobaXterm远程连接centos桌面环境

    记录一下使用MobaXterm连接centos的GNOME桌面环境 MobaXterm 关于MobaXterm可以参考以下文章 链接 https cloud tencent com developer news 244102 连接远程桌面
  • 协方差、协方差矩阵

    在机器学习中 理解协方差矩阵的关键在于牢记它计算的是同一个样本不同特征维度之间的协方差 而不是不同样本之间 拿到样本矩阵之后 我们首先要明确一行是样本还是特征维度 一般来说 样本矩阵中一行是一个样本 一列为一个特征维度 所以要按列计算均值
  • Deep Photometric Stereo Network

    摘要 本文提出了一种基于深度学习的光度立体方法 光度立体的主要困难之一是设计合适的反射模型 该模型既可以表示真实的反射率 又可以在导出表面法线方面在计算上易于处理 与以前的依赖于简化的参数化图像形成模型 例如Lambert模型 的光度学立体
  • 基于Vue的钉钉H5微应用开发(一)

    本系列是基于Vue和Java开发的钉钉H5微应用参考教程 在阅读之前 请关注以下信息 1 开发人员需要拥有钉钉组织的管理员角色 子管理员也行 2 开发人员需要具备基本的前端开发能力 了解或熟悉Vue框架 熟悉Java和SpringBoot框
  • mac操作系统 java 调用tdengine时序数据库

    这里写自定义目录标题 官网下载mac版本的tdengine客户端后 生成软链接 sudo ln s usr local lib libtaos dylib Users admin Library Java Extensions libtao
  • js-http图片地址转base64

    关键 responseType blob 原生js 创建XMLHttpRequest对象 var xhr new XMLHttpRequest 设置请求头 监听请求完成事件 xhr onload function 检查响应状态码 if xh
  • 【Java并发】FutureTask-Callable设置接口超时限制

    目录 代码 运行 代码 原理是新建一个Callable线程 call方法可以返回对象 用FutureTask封装后 通过future对象的get方法来设定超时限制 如果超时 则future cancel true 取消执行 重写Callab
  • Linux 常见问题

    一 如何建立多用户 提醒大家一句 别一直使用root用户 因为root用户在系统中有着至高无上的权力 一不小心就可能破坏系统 比如我们想删除 temp目录 下的文件却将命令不小心输成 rm temp 在 后多了一个空格 那么就极可能删去根目
  • 白盒测试案例设计(我爷爷都能看懂)

    目录 一 白盒测试的概念及特点 1 什么是白盒测试 2 白盒测试的特点 二 白盒测试设计方法 1 静态设计方法 2 动态设计方法 三 逻辑覆盖法 1 语句覆盖 2 判定覆盖 3 条件覆盖 4 判定条件覆盖 5 条件组合覆盖 6 路径覆盖 四
  • 第一次创建maven出现PluginResolutionException的解决办法

    创建javaweb idea不能自动生成webapp 同时报PluginResolutionException 修改了maven项目中的settings xml文件中节点
  • this license xxx has been cancelled

    目录 出现的主要是注册码没有注册成功的问题 修改 end 出现的主要是注册码没有注册成功的问题 修改 需要修改系统配置 windows C Windows System32 drivers etc hosts 使用时需要将 0 0 0 0
  • 双频无线路由器打印服务器,双频无线路由器打印服务器客户端软件_1.14.1127 (Mac)...

    这是双频无线路由器打印服务器客户端软件 1 14 1127 Mac 下载 适用TL WDR3300 V1 0 TL WDR3310 V1 0 TL WDR4310 V1 0 TL WDR4320 V1 0 TL WDR7500 V2 0 T
  • win11注册表打不开解决办法,提示被管理员禁用(亲测)(两种方法)

    本人是入门学习网络安全技术的小白 因一些原因需要用到注册表才发现注册表被管理员禁用 刚买的笔记本 win11系统 之前从来没用过注册表 于是乎我再网上搜索可解决问题的方法 终于找到了两种 大概 解决的办法 现在分享给大家 方法一 这是我在网
  • java中constructor_java中构造器(Constructor)

    构造器是一个创建对象时被自动调用的特殊方法 为的是初始化 构造器的名称应与类的名称一致 当创建一个个对象时 系统会该对象的属性默认初始化 基本类型属性的值为0 数值类型 false 布尔类型 把所有的引用类型设置为null 构造器可以改变这
  • 百度App Objective-C/Swift 组件化混编之路(一)

    作者丨郭金 陈佳 来源丨百度App技术 一 背景 1 1 Swift 发展历史 2010 年 7 月 克里斯 Chris Lattner 开始设计 Swift 完成基础架构后 克里斯带领开发小组陆续完成语法设计 编译器 运行时 框架 IDE