Flutter热更新技术探索

一,需求背景:

APP发布到市场后,难免会遇到严重的BUG阻碍用户使用,因此有在不发布新版本APP的情况下使用热更新技术立即修复BUG需求。原生APP(例如:Android & IOS)的热更新需求已经比较成熟,但Flutter技术栈目前还缺少类似的技术方案,因此Flutter研发团队,也需要类似的热更新技术。

二,Flutter热更新技术方向分析:

经过分析目前可能有三种可行的方案: 1)类似RN框架; 2)页面动态组件框架; 3)Dart虚拟机定制方案;

方案名称 原理 优点 缺点 开源方案
类似RN的方案 用JS以Flutter语法写dart,然后用JavaScript把XML DSL转为Flutter的原子widget组件,然后再让Flutter来渲染 由于ios系统内置支持js,ios上完全可以实现更新 1)由于跨语言执行,对于性能有影响;学习成本高 2)Android 端需要额外引入JS库 手Q的MXFlutter,58同城的Fair
页面动态组件方案 编译期时插桩/预埋好DynamicWidget到代码中,然后动态下发Json 数据,通过协定好的语义匹配到JSON内的数据,动态替换Widget内容来实现更新 能支持Android/iOS 两端的更新 1)UI更新相对较容易,业务逻辑动态化较麻烦; 2)语义解析器开发成本相对较大,且不易维护 3)需要一整套前后端服务和工具 天猫的Tangram,淘宝的DinamicX等
Dart虚拟机定制方案 通过分析Dart虚拟机的原理,修改Flutter Engine层Java/C++代码实现热更新的目标; 性能影响小,动态性很高,技术上可以替换所有Flutter页面(包括UI,逻辑,资源文件) 由于使用的是定制引擎,需要维护不同版本的Flutter引擎代码; 未开源

因为其他方式都有开源的示例,本案将重点以第三种“Dart虚拟机定制方案”为目标,做方案的研究讲解。

三,预备知识

在开始了解技术方案之前,需要提前了解一些相应的技术概念:

3.1 Flutter编译模式

Flutter开发语言是Dart,它的编译模式来自Dart的编译模式,主要有JIT(Just In Time)和AOT(Ahead Of Time)。

编译模式名称 特点 优点 缺点
JIT 即时编译,典型例子V8,它可以即时编译运行JS,只需要输入源代码字符串,就可以编译运行代码 可以动态下发和执行代码,不用管CPU架构,可以提供动态化内容 1,大量字符串代码让JIT编译器花费时间和内存; 2,性能不好;
AOT 预先编译,典型例子C/C++,通过GCC编译成二进制代码,然后安装取得权限后才可以加载执行 事先编译好的,加载和执行速度快 1,编译时区分CPU架构; 2,生成的二进制代码包比较大; 3,二进制代码需要取得权限才可以执行,无法在ios系统上动态更新

Flutter编译模式有:Debug,Release,Profile;

Flutter编译模式 特点
Debug 对应JIT模式,支持设备和模拟器; 打开了断言,支持快速开发,支持HotReload; 并未对包大小,执行速度做优化;
Release 对应AOT模式,支持真机,不支持模拟器; 禁止了所有断言调试信息; 对包大小,启动和执行速度进行了优化;
Profile 类似Release模式,保留了一些调试功能,帮助性能分析;

3.2 Flutter编译产物分析

Flutter下的iOS/Android工程本质上是一个标准的iOS/Android的工程;IOS平台: Flutter通过在BuildPhase中添加shell(xcode_backend.sh)来生成和嵌入App.framework和Flutter.framework到ios; Android平台: Flutter通过gradle来添加flutter.jar和编译完的二进制文件添加到Android;

3.2.1 引擎层结构分析:

3.2.2 Android编译产物的分析

3.2.3 IOS编译产物的分析

四,热更新技术方案分析

4.1 业务代码分析

根据“3.3.1” ~“3.3.2”的分析可以确定无论是IOS还是Android APP业务代码都是由四个段组成:kDartVmSnapshotData、kDartVmSnapshotInstructions、kDartIsolateSnapshotData、kDartIsolateSnapshotInstructions;理论上只要能动态替换加载的代码段&数据段代码即可实现目标。

名称 注释 作用 注释
kDartIsolateSnapshotData Dart isolate数据段 类信息,全局变量,函数指针等 允许动态下发
kDartIsolateSnapshotInstructions Dart isolate指令段 包含由Dart isolate执行的AOT代码 IOS不允许动态下发
kDartVmSnapshotData vm isolate数据段 isolate 之间共享的 Dart 堆 (heap) 的初始状态 允许动态下发
kDartVmSnapshotInstructions vm isolate指令段 包含 VM 中所有 Dart isolate 之间共享的通用程序的 AOT 指令 IOS不允许动态下发

注释: isolate, snapshot, vm isolate含义解释如下:

名称 含义
isolate Dart是单线程,isolate跟线程差不多,可以理解为 Dart 中的线程。 isolate 与线程的区别:线程与线程之间是共享内存的,而 isolate 和 isolate 之间是内存不共享的。 不存在锁竞争问题,两个Isolate完全是两条独立的执行线,且每个Isolate都有自己的事件循环,它们之间只能通过发送消息通信,所以它的资源开销低于线程。
snapshot 将类信息、全局变量、函数指令直接以序列化的方式存在磁盘中,称为 Snapshot(快照)。
vm isolate 同一个进程里可以有很多isolate,但两个 isolate 的堆区是不能共享的,所以官方设计了 VM isolate,也就是 kDartVmSnapshot,用来多个 isolate 之间的交互。

4.2 业务代码的加载分析(运行时)

按照4.1的分析思路,我们首先需要了解Flutter运行时代码加载的完整流程,经过梳理分析流程如下:

1 )Android- APP业务代码的加载流程:

2)IOS- APP业务代码的加载流程:

4.3 业务代码的编译生成(编译时)

根据以上的分析,我们知道了Flutter业务代码的数据结构,也知道了在运行时如何加载,因此我们只需要在编译时做更改,产生自己需要的代码段,和数据段文件。在运行时加载自己的构建产物即可达到目标。

1)在此以 IOS 构建自己的业务代码流程做详细分析:

**有完成构建流程可以分析,基本流程是“Dart Code(业务代码)” -> (通过Dart编译器gen_snapshot.cc) 生成 snapshot_assemble.S 的汇编文件 -> (通过xcrun工具)生成 snapshot_assemble.o的obj文件 -> (通过xcun clang工具链) 生成了 App.Framework。

2)Android的产物构建流程和IOS类似。由于Android有其他更简单的方案, 因此省略详细的构建流程分析,大致如下:

4.4 实现热更新的方案探索

根据上面的技术分析结果,已经可以独立生成自己的代码段,数据段文件。通过需改虚拟机底层代码的方式,也可以动态的加载运行。但由于IOS系统目前底层的系统还不能动态加载可读写的代码段数据到内存中,所以还有技术难点需要突破。但Android端有更简单的路径可以解决,因此下面以Android端为例重点分析思路,大致如下图所示:

由上图可以得知,Android端 热修复核心步骤如下:

1, 修改Flutter Engine代码,加载指定路径的libapp.so和flutter_aasets,比如私有目录(data/data/files);

2, 编译APK时,利用Gradle Transform插件,根据Flutter SDK的engine version动态替换官方的Flutter engine,最终写入修改后的engine到APK;

3, 生成补丁包:利用BSdiff算法比较新旧APK文件,生成patch补丁包

4, APP启动时访问后端接口,根据参数(app的版本号,补丁包版本号,md5,flutter SDK版本号,Engine版本号)拉取补丁包;

5, 合成补丁包:校验md5,app版本号,补丁版本号,安装时间;

6, 自定义Flutter Engine加载指定路径的libapp.so和flutter_assets资源文件;

作者:京东科技 刘振中、周智

内容来源:京东云开发者社区

本文转载于网络 如有侵权请联系删除

相关文章

  • 《笨开发学习操作系统》2进程

    进程和线程有什么区别?一个常常被问到的面试题 我们在实际的开发过程中,经常打交道的就是线程,而进程呢,通常就是我们整个运行的程序。对于他们两个来说其实并不陌生,你要让我说出个一二三也可以讲,但可能也都是从使用的角度,而今天我们就从操作系统的角度来重新认识一下他们两个(从内核的角度看进程和线程长什么样)。大纲:首先我会让你直观感受我们的进程和基本的分类优先理解他们的数据结构状态的变化是非常重要的一环接着是重点:如何创建他们最后再来看调度你所需要把握的重点是:结构、创建和调度。这些对于以后的开发或是问题的解决都是有着密切联系的。进程的直观感受首先让我们从实际角度来直观感受什么是进程,通过ps-ef命令可以查看当前进程的相关情况UIDPIDPPIDCSTIMETTYTIMECMD root1002021?00:38:48/usr/lib/systemd/systemd--switched-root--system--deserialize22 root2002021?00:00:05[kthreadd] root4202021?00:00:00[kworker/0:0H] root62020

  • 腾讯云ubuntu 16.04 禅道集成环境搭建

    腾讯云ubuntu16.04禅道集成环境搭建服务器系统:ubuntu16.04 禅道版本:版本12.4.3禅道安装地址禅道linux安装地址 https://www.zentao.net/book/zentaopmshelp/90.html禅道邮件发送首先是在虚拟机(Ubuntu16.04)上面部署了禅道:一切正常。 禅道后台发信配置如下: 图片借用网上的一个图片,问题一样;确定,ping,telnet,SELinux都正常; 如过,命令不能执行,根据Ubuntu提示aptinstall先安装包后,再执行;配置hostcdetc/ sudovimhosts复制添加如下 测试,发送邮件,如果,邮件还是提示失败,需要检查腾讯云25端口是否打开;解决25端口的方法1、登录到腾讯云管理控制台; 2、鼠标移动到顶部菜单栏你的用户名上,自动弹出下拉,点击“25端口解封” 如下图所示:3、点击“申请25端口解封”然后,再点击测试,禅道,1s内就会提示发送成功; 禅道后台启动supervisorroot@VM-66-91-ubuntu:/etc/supervisor/conf.d#catzentao

  • RT-Thread Studio 项目实战教程 | 快速打造一个桌面mini网络时钟

    1.RT-ThreadStudioRT-ThreadStudio是一站式的RT-Thread开发工具,通过简单易用的图形化配置系统以及丰富的软件包和组件资源,让物联网开发变得简单和高效。RT-Thread主要包括工程创建和管理,代码编辑,SDK管理,RT-Thread配置,构建配置,调试配置,程序下载和调试等功能,结合图形化配置系统以及软件包和组件资源,减少重复工作,提高开发效率。RT-ThreadStudio可以从RT-Thread官网下载,下载之后一路next安装即可,注意安装路径不要有中文或者空格。2.桌面mini时钟项目迷你桌面时钟项目基于小熊派IoT开发板,使用RT-Thread物联网操作系统,使用RT-ThreadStudio一站式开发工具,在极短的时间内开发完成一个桌面mini时钟。整个项目的架构如下:项目所用的芯片型号如下:主控芯片:STM32L431RCT6温湿度传感器: SHT30通信模组:ESP8266(WIFI)显示模组:0.96'OLED(SSD1306)其中,SHT30传感器挂载到STM32的I2C1引脚上,OLED挂载到STM32的I2C3引脚上

  • 14. css3 media响应式样式示例

    需求在日常的样式编写中,对于浏览器宽度变化的时候,我们为了增加体验,总是需要根据变化进行响应式的样式设置。本篇章编写一个media的浏览器宽度响应示例。media使用说明@media类型and(条件1)and(条件二){*/ css样式*/ }复制上面写的类型有很多种,不过我们一般只需要认识一下屏幕的变化即可,示例如下:/*如果文档宽度小于300像素则修改背景颜色(background-color):*/ @mediascreenand(max-width:300px){ body{ background-color:lightblue; } }复制这是一个最典型根据屏幕的宽度变化,来设置样式的示例。 下面我们来继续丰富这个示例,根据不同的浏览器宽度,变化body的背景色。示例代码<!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="UTF-8"> <title>Title</title> <style> /*@

  • 微软考虑将Python作为官方脚本语言添加到Excel中?

    三年前的报道我们先看一份2017年的一个报道:https://www.bleepingcomputer.com/news/microsoft/microsoft-considers-adding-python-as-an-official-scripting-language-to-excel/具体内容为:根据上个月在Excel反馈中心开放的一个主题,微软正在考虑将Python添加为官方的Excel脚本语言之一。自开放以来,该主题已经成为投票最多的特性请求,是排名第二的主题的两倍。“让我们用Python来编写脚本吧!”耶!这不仅是对VBA的一种替代,也是对字段函数(=SUM(A1:A2))的一种替代。微软正在探索这个想法作为回应,这家操作系统制造商昨日发布了一项调查,以收集更多信息,以及用户希望如何在Excel中使用Python。如果获得批准,Excel用户将能够使用Python脚本与Excel文档、数据和Excel的一些核心功能进行交互,这与Excel目前支持VBA脚本的方式类似。Python是当今最通用的编程语言之一。它在开发人员中也非常流行。用户呼吁在办公应用程序之间实现一个通用

  • Python 【基础常识概念】

    深浅拷贝浅copy与deepcopy浅copy:不管多么复杂的数据结构,浅拷贝都只会copy一层deepcopy:深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,我们对这两个变量中任意一个修改都不会影响其他变量深浅拷贝之间的区别?对象的赋值就是简单的引用,a=[1,2,3],b=a,在上述情况下,a和b是一样的,他们指向同一片内存,b不过是a的别名,是引用,我们可以使用bisa去判断,返回True,表名他们地址相同内容也相同,也可以使用id()函数来查看.看两个列表地址是否相同.深拷贝就是将一个对象拷贝到另一个对象中,这意味着如果你对一个对象的拷贝做出改变时,不会影响原对象。在Python中,我们使用函数deepcopy()执行深拷贝importcopy b=copy.deepcopy(a)复制而浅拷贝则是将一个对象的引用拷贝到另一个对象上,所以如果我们在拷贝中改动,会影响到原对象。我们使用函数function()执行浅拷贝、切片操作是浅拷贝b=copy.copy(a)复制可变与不可变可变类型(mutable):列表,字典不可变类型(unmutable):数字,字

  • Python进阶(三十四)-Python

    Python进阶(三十四)-Python3多线程解读线程讲解  多线程类似于同时执行多个不同程序,多线程运行有如下优点:使用线程可以把占据长时间的程序中的任务放到后台去处理。用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。程序的运行速度可能加快。在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。  线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。   每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。 指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程的上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。   线程可以被抢占(中断)。   在其他线程正在运行时,线程可以暂时搁置(也称为睡眠)–这就是线程的退让。   线程可以分

  • git操作:在CentOS7上面搭建GitLab服务器

    git操作:在CentOS7上面搭建GitLab服务器在这篇文章中将要讲解如何在CentOS7上面搭建本地的GitLab服务器。一、安装并配置必要的依赖关系首先要在CentOS系统上面安装所需的依赖:ssh、防火墙、postfix(用于邮件通知)、wegt,以下这些命令也会打开系统防火墙中的HTTP和SSH端口访问。1、安装SSH协议安装命令:sudoyuminstall-ycurlpolicycoreutils-pythonopenssh-server出现如下图所示的界面表示安装成功:2、设置SSH服务开机自启动安装命令:sudo systemctl enable sshd3、启动SSH服务启动命令:sudosystemctlstartsshd4、安装防火墙安装命令:yuminstallfirewalldsystemd-y出现如下图所示的界面表示安装成功:5、开启防火墙开启命令:service firewalld  start6、添加HTTP服务到firewalld安装命令:sudofirewall-cmd--permanent--add-service=http其中,pemmane

  • Percona XtraDB Cluster高可用与状态快照传输(PXC 5.7 )

    PerconaXtraDBCluster(下称PXC)高可用集群支持任意节点在运行期间的重启,升级或者意外宕机,即它解决了单点故障问题。那在这个意外宕机或者重启期间,该节点丢失的数据如何再次进行同步呢?本文介绍了在节点故障和重启PXC如何实现高可用以及状态快照传输的几种方法优缺点。一、高可用在具有3个节点的基本设置中,如果您关闭任何节点,PerconaXtraDB集群将继续运行。在任何时候,您都可以关闭任何节点来执行维护或进行配置更改。即使在非计划的情况下(如节点崩溃或者通过网络无法使用),PerconaXtraDB集群将继续工作,您将能够在工作节点上运行查询。如果在节点关闭期间数据发生更改,则节点在再次加入群集时可以使用两个选项:  状态快照传输StateSnapshotTransfer(SST),即将所有数据从一个节点复制到另一个时。  通常在新节点加入集群并从现有节点接收所有数据时使用SST。PerconaXtraDB集群中有三种可用的SST方法:    mysqldump     rsync     xtrabackup  mysqldump与rsync的缺点是,当数据正在被复

  • 解决机器学习中不平衡类的问题

    大多数实际的分类问题都显示了一定程度的类不平衡,也就是当每个类不构成你的数据集的相同部分时。适当调整你的度量和方法以适应你的目标是很重要的。如果没有这样做,你可能会在用例的上下文中为一个没有意义的度量进行优化。例如,假设你有两个类-A类和B类。A类在你的数据集中占了90%,B类占了10%,但是你最感兴趣是B类中的识别实例。只需每次预测A类,你可以达到90%的精确度,但是这为你预期的用例提供了一个无用的分类器。相反,一个适当校准的方法可能会降低精确度,但会有一个更高的真阳性率(召回率),这是你本应该优化的指标。这些场景通常发生在检测的环境中,比如在线的滥用内容,或者医疗数据中的疾病标记。现在,我将讨论几种可以用来解决不平衡类问题的技术。一些技术适用于大多数分类问题,而另一些技术可能更适合于特定的不平衡级别。在本文中,我将以二进制分类的方式讨论这些问题,但在大多数情况下,相同的内容将用于多数类分类。我还假设目标用来识别少数类,否则,这些技术并不是必需的。度量 一般来说,这个问题处理的是在召回率(被分类为正向实例的百分比)和精确率的(正向分类的百分比)之间的权衡。在我们想要检测少数类的实例的

  • 腾讯云内容识别简介

    |名称| 描述| |---|---| |APPID |开发者访问内容识别服务时拥有的用户维度唯一资源标识,用以标识资源,可在[API密钥管理](https://console.cloud.tencent.com/capi)页面获取| |SecretId|开发者拥有的项目身份识别ID,用以身份认证,可在[API密钥管理](https://console.cloud.tencent.com/capi)页面获取| |SecretKey |开发者拥有的项目身份密钥,可在[API密钥管理](https://console.cloud.tencent.com/capi)页面获取| |Bucket|存储桶,内容识别服务中用于存储数据的容器。有关存储桶的进一步说明,请参见[存储桶概述](https://cloud.tencent.com/document/product/436/13312)文档| |Object|对象,内容识别服务中存储的具体文件,是存储的基本实体| |ObjectKey|对象键,对象(Object)在存储桶(Bucket)中的唯一标识。有关对象与对象键的进一步说明,请参见[对象

  • 腾讯云区块链可信取证公共参数调用方式

    公共参数是用于标识用户和接口签名的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,但每次请求均需要携带这些参数,才能正常发起请求。 公共参数的具体内容会因您使用的签名方法版本不同而有所差异。 使用签名方法v3的公共参数签名方法v3(有时也称作TC3-HMAC-SHA256)相比签名方法v1(有些文档可能会简称签名方法),更安全,支持更大的请求包,支持POSTJSON格式,性能有一定提升,推荐使用该签名方法计算签名。完整介绍详见签名方法v3。 注意:接口文档中的示例由于目的是展示接口参数用法,简化起见,使用的是签名方法v1GET请求,如果依旧想使用签名方法v1请参考下文章节。 使用签名方法v3时,公共参数需要统一放到HTTPHeader请求头部中,如下表所示: 参数名称 类型 必选 描述 Action String 是 HTTP请求头:X-TC-Action。操作的接口名称。取值参考接口文档中输入参数公共参数Action的说明。例如云服务器的查询实例列表接口,取值为DescribeInstances。 Region String - HTTP请求头:X-

  • 用 Go 快速开发一个 RESTful API 服务

    何时使用单体RESTful服务 对于很多初创公司来说,业务的早期我们更应该关注于业务价值的交付,而单体服务具有架构简单,部署简单,开发成本低等优点,可以帮助我们快速实现产品需求。我们在使用单体服务快速交付业务价值的同时,也需要为业务的发展预留可能性,所以我们一般会在单体服务中清晰的拆分不同的业务模块。 商城单体RESTful服务 我们以商城为例来构建单体服务,商城服务一般来说相对复杂,会由多个模块组成,比较重要的模块包括账号模块、商品模块和订单模块等,每个模块会有自己独立的业务逻辑,同时每个模块间也会相互依赖,比如订单模块和商品模块都会依赖账号模块,在单体应用中这种依赖关系一般是通过模块间方法调用来完成。一般单体服务会共享存储资源,比如MySQL和Redis等。 单体服务的整体架构比较简单,这也是单体服务的优点,客户请求通过DNS解析后通过Nginx转发到商城的后端服务,商城服务部署在ECS云主机上,为了实现更大的吞吐和高可用一般会部署多个副本,这样一个简单的平民架构如果优化好的话也是可以承载较高的吞吐的。 商城服务内部多个模块间存在依赖关系,比如请求订单详情接口/order/det

  • linux中apt-get和yum和wget的区别

    1.RedHat系列:Redhat、Centos、Fedora等 yum2.Debian系列:Debian、Ubuntu等 apt-get   wget类似迅雷 作者:火星十一郎出处:http://www.cnblogs.com/hxsyl/本文版权归作者火星十一郎所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 分享到: 更多

  • [LeetCode] 1250. Check If It Is a Good Array 检查好数组

    Givenanarray nums of positiveintegers.Yourtaskistoselectsomesubsetof nums,multiplyeachelementbyanintegerandaddallthesenumbers. Thearrayissaidtobe good ifyoucanobtainasumof 1 fromthearraybyanypossiblesubsetandmultiplicand. Return True ifthearrayis good otherwise return False. Example1: Input:nums=[12,5,7,23] Output:true Explanation:Picknumbers5and7. 5*3+7*(-2)=1 复制 Example2: Input:nums=[29,6,10] Output:true Explanation:Pi

  • 米尔的国产T507-H开发板怎么玩?macOS如何将Ubuntu系统烧录到eMMC的完全调教指南!

    本篇测评由电子发烧友的优秀测评者“HonestQiao”提供。 此次板卡的测试,是用macOS将Ubuntu系统烧录到eMMC的操作实录。   米尔MYD-YT507H开发板,官方提供了HMI系统和Ubuntu18.04镜像,体验过默认的HMI系统后,我就换上了我喜欢的Ubuntu系统了。 一、系统烧录 参考官方的文档,使用全志的图形界面烧录工具,在Windows下烧录简单又方便:   因为我使用的是macOS系统,所以我是在macOS下进行烧录的,这需要使用命令行来操作。首先,我们看一下板子上的接口:   在上图中,红色的TV接口上面,有两个Type-C的接口,标注了OTG接口,可以用来烧录固件。标注了Debug的,可以用于串口终端,来进行设备调试。所以,要进行系H,连接到电脑,就可以准备烧录了。 从官方资料库中,下载Ubuntu镜像和PhoneixSuit的macOS版本:   然后,进入命令行执行:   此时,会等待按键,具体的按键如下:   当 ----entersem_wait-------出现后

  • Oracle-SQL高级查询

    --一个题目涉及到的50个Sql语句 --(下面表的结构以给出,自己在数据库中建立表.并且添加相应的数据,数据要全面些.其中Student表中,SId为学生的ID) ------------------------------------表结构----------------------------------------学生表tblStudent(编号StuId、姓名StuName、年龄StuAge、性别StuSex)--课程表tblCourse(课程编号CourseId、课程名称CourseName、教师编号TeaId)--成绩表tblScore(学生编号StuId、课程编号CourseId、成绩Score)--教师表tblTeacher(教师编号TeaId、姓名TeaName)--------------------------------------------------------------------------------- --问题: --1、查询“001”课程比“002”课程成绩高的所有学生的学号; SelectStuIdFromtb

  • Python format格式化输出

    http://www.jb51.net/article/63672.htm 推荐参考 1>>>'{0},{1}'.format('hello','python') 2'hello,python' 3>>>'{0}{1}'.format('hello','python') 4'hellopython' 5>>>'yourname:{name}'.format(name='tom') 6'yourname:tom' 7>>>p=['123',45] 8>>>'{0[0]}{0[1]}'.format(p) 9'12345' 10>>>"{:>10}".format('1111') 11'1111'复制 记住几个常用的用法就行,其余的要有个印象!

  • 日程列表

    jQuery事件日历插件e-calendar,支持针对指定日期自定义日程安排(无条数限制),设置过日程的日期会高亮显示,兼容IE7+主流浏览器。 原版使用方法及演示地址:e-calendar原版(鼠标移动到天显示当天的日程安排)   升级版介绍: 1.同一天可存在多个事件交集2.点击天在日历下方出现日程列表3.点击日程列表可添加其事件。4.添加item-grid的显示和隐藏5.Events中数组集合可添加id,type等元素(区分日程类型:任务类型或日程类型) 6.增加年份选择,月份选择7.样式调整8.将ajax加载事件,item点击事件等写在calendar配置中 运行效果图:   主要代码: index.html <!DOCTYPEhtml> <html> <headlang="en">   <metacharset="UTF-8">   <title></title>   <linkrel

  • mysql优化--(三)

    1索引   本质: 获取高效数据的数据结构    理解:排好序的快速查找的数据结构         2explain分析sql    

  • 请教一下16aspx上的源代码要如何在自己的服务器上运行

    很正常呀,,我下载的也有运行不成功的你要去他们16aspx论坛发帖子问这里很少有人回答你这样的问题复制 作者:源码站长资源交易专业网-16aspx.com文章出处:http://www.16aspx.com

相关推荐

推荐阅读