版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
iOS程序员面试分类模拟21简答题1.
请谈谈数据库中的事务。正确答案:事务是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果(江南博哥)所有操作完成,事务则提交,那么其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。
2.
SDWebImage框架的框架结构是怎么样的?正确答案:SDWebImage框架的3个核心组件。
1)SDWebImageManager:核心管理器。
2)SDImageCache:缓存处理组件,主要对下载的图片进行内存缓存和磁盘缓存处理。
3)SDWebImageDownloader|SDWebImageDownloadOperation:下载处理组件,主要负责在子线程中发送异步网络请求下载图片以及其他相关操作。
3.
什么是内存碎片?什么是内碎片?什么是外碎片?正确答案:内存碎片是由于多次进行内存分配造成的,当进行内存分配时,内存格式一般为:(用户使用段)(空白段)(用户使用段),当空白段很小的时候可能不能提供给用户足够多的空间,比如夹在中间的空白段的大小为5,而用户需要的内存大小为6,这样会产生很多的间隙造成使用效率的下降,这些很小的空隙叫碎片。
内碎片是分配给程序的存储空间没有用完,有一部分是程序不使用,但其他程序也没法用的空间。内碎片是处于区域内部或页面内部的存储块,占有这些区域或页面的进程并不使用这个存储块,而在进程占有这块存储块时,系统无法利用它,直到进程释放它,或进程结束时,系统才有可能利用这个存储块。
外碎片是由于空间太小,小到无法给任何程序分配(不属于任何进程)的存储空间。外碎片是处于任何已分配区域或页面外部的空闲存储块,这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因,使得系统无法满足当前申请。
内碎片和外碎片是一对矛盾体,一种特定的内存分配算法,很难同时解决好内碎片和外碎片的问题,只能根据应用特点进行取舍。
4.
sprintf、strcpy、memcpy的功能分别是什么?正确答案:sprintf是将格式化的数据写入字符串。
strcpy是字符串复制。
memcpy是内存的复制。
5.
GCD如何实现线程同步?正确答案:NSOperation可以通过使用addDependency函数直接设置操作之间的依赖关系来调整操作之间的执行顺序从而实现线程同步,还可以使用setMaxConcurrentOperationcount函数来直接设置并控制最大并发数量,那么在GCD中如何实现呢?
GCD实现线程同步的方法有以下3种:
1)组队列(dispatch_group)。
2)阻塞任务(dispatch_barrier_(a)sync)。
3)信号量机制(dispatch_semaphore)
信号量机制主要是通过设置有限的资源数量来控制线程的最大并发数量及阻塞线程实现线程同步等。
GCD中使用信号量需要用到3个函数:
1)dispatch_semaphore_create用来创建一个semaphore信号量并设置初始信号量的值。
2)dispatch_semaphore_signal发送一个信号让信号量增加1(对应PV操作的V操作)。
3)dispatch_semaphore_wait等待信号使信号量减1(对应PV操作的P操作)。
6.
什么是事务?正确答案:事务是数据库中一个单独的执行单元(unit),它通常由高级数据库操作语言(例如SQL)或编程语言(例如C++、Java等)书写的用户程序的执行所引起。当在数据库中更改数据成功时,在事务中更改的数据便会提交,不再改变。否则,事务就取消或者回滚,更改无效。
例如网上购物,其交易过程至少包括以下几个步骤的操作:
1)更新客户所购商品的库存信息。
2)保存客户付款信息。
3)生成订单并且保存到数据库中。
4)更新用户相关信息,例如购物数量等。
在正常的情况下,这些操作都将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新。但是,如果遇到突然掉电或是其他意外情况,导致这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常、顾客银行账户余额不足等,都将导致整个交易过程失败。而一旦交易失败,数据库中所有信息都必须保持交易前的状态不变,例如最后一步更新用户信息时失败而导致交易失败,那么必须保证这笔失败的交易不影响数据库的状态,即原有的库存信息没有被更新,用户也没有付款,订单也没有生成。否则,数据库的信息将会不一致,或者出现更为严重的不可预测的后果。数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。
事务必须满足4个属性,即原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability),即ACID4种属性。
(1)原子性
事务是一个不可分割的整体,为了保证事务的总体目标,事务必须具有原子性,即当数据修改时,要么全执行,要么全都不执行,即不允许事务部分地完成,避免了只执行这些操作的一部分而带来的错误。原子性要求事务必须被完整执行。
(2)一致性
一个事务执行之前和执行之后数据库数据必须保持一致性状态。数据库的一致性状态应该满足模式锁指定的约束,那么在完整执行该事务后数据库仍然处于一致性状态。为了维护所有数据的完整性,在关系型数据库中,所有的规则必须应用到事务的修改上。数据库的一致性状态由用户来负责,由并发控制机制实现,例如银行转账,转账前后两个账户金额之和应保持不变,由于并发操作带来的数据不一致性包括:丢失数据修改、读“脏”数据、不可重复读和产生幽灵数据。
(3)隔离性
也被称为独立性,当两个或多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与事务的操作隔离起来,不被其他的正在进行的事务看到。例如对任何一对事务T1和T2,对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。数据库有4种类型的事务隔离级别:不提交的读、提交的读、可重复的读和串行化。因为隔离性使得每个事务的更新在它被提交之前,对其他事务都是不可见的,所以实施隔离性是解决临时更新与消除级联回滚问题的一种方式。
(4)持久性
也被称为永久性,事务完成以后,DBMS保证它对数据库中的数据的修改是永久性的,当系统或介质发生故障时,该修改也永久保持。持久性一般通过数据库备份与恢复来保证。
严格来说,数据库事务属性(ACID)都是由数据库管理系统来进行保证的,在整个应用程序运行过程中应用无须去考虑数据库的ACID实现。
一般情况下,通过执行commit或rollback语句来终止事务,当执行commit语句时,自从事务启动以来对数据库所做的一切更改就成为永久性的了,即被写入到磁盘,而当执行rollback语句时,自动事务启动以来对数据库所做的一切更改都会被撤销,并且数据库中内容返回到事务开始之前所处的状态。无论什么情况,在事务完成时,都能保证回到一致状态。
7.
僵尸对象、野指针、空指针分别指什么?它们有什么区别?正确答案:1.僵尸对象
一个引用计数为0的Objective-C对象被释放后就变成僵尸对象。僵尸对象的内存已经被系统回收,虽然该对象可能还存在,数据依然在内存中,但僵尸对象已经是不稳定对象了,不可以再访问或者使用,它的内存是随时可能被别的对象申请而占用的。需要注意的是,僵尸对象所占的内存是正常的,不会造成内存泄漏。
2.野指针
野指针又叫“悬挂指针”,野指针出现的原因是指针没有赋值,或者指针指向的对象已经被释放掉了。野指针指向一块随机的垃圾内存,向它们发送消息会报EXC_BAD_ACCESS错误导致程序崩溃。
3.空指针
空指针不同于野指针,它是一个没有指向任何内容的指针。空指针是有效指针,值为nil、NuLL、Nil或0等,给空指针发送消息不会报错,只是不响应消息而已,应该给野指针及时赋予零值使其变成有效的空指针,避免内存报错。
8.
delete与truncate命令有哪些区别?正确答案:相同点:都可以用来删除一个表中的数据。
不同点:
1)truncate是一个数据定义语言(DataDefinitionLanguage,DDL),它会被隐式地提交,一旦执行后将不能回滚。delete执行的过程是每次从表中删除一行数据,同时将删除的操作以日志的形式进行保存,以便将来进行回滚操作。
2)用delete操作后,被删除的数据占用的存储空间还在,还可以恢复。而用truncate操作删除数据,被删除的数据会立即释放所占有的存储空间,被删除的数据是不能被恢复的。
3)truncate的执行速度比delete快。
9.
如何使用mask属性实现图层蒙版功能?正确答案:在实际开发中,通常使用mask属性来实现图层蒙版的功能。这个属性本身就是CALayer类型,它和其他图层一样拥有绘制和布局的属性。但不同于那些绘制在父图层中的子图层,mask图层定义了父图层的部分可见区域。
mask图层中最重要的是图层的轮廓,在父图层中,与mask图层相重叠的部分将被保留,其他的部分将被遮盖。也就是说,父图层提供内容,而mask图层提供形状。事实上,mask图层不仅仅局限于静态图,还可以使用代码或者动画实时地生成。
示例代码如下:
-(void)viewDidLoad{
[superviewDidLoad];
/*设置寄宿图*/
self.view.layer.contents=(id)[UIImageimageNamed:@"海水"].CGImage;
/*设置寄宿图的显示模式,等价于UIView的contentMode*/
self.view.layer.contentsGravity=@"resizeAspect";
/*设置mask层*/
UIImageView*searchImageView=[[UIImageViewalloe]initWithFrame:CGRectMake(([UIScreenmainScreen].bounds.size.width-150)*0.5,([UIScreenmainScreen].bounds.size.height-150)*0.5,150,150)];
searchImageView.image=[UIImageimageNamed:@"马"];
self.view.layer.mask=searchImageView.layer;
}
代码执行的效果如图所示。
图层蒙版效果
10.
什么是IMP?正确答案:和SEL一样,IMP实际上也是个函数指针,它指向方法实现的首地址,可以把它理解为方法的具体实现。其定义如下:
id(*IMP)(id,SEL,...)
前面讲到可以通过SEL指针查找方法,实际上就是查找方法的IMP。由于每个方法对应唯一的SEL,所以可以通过SEL方便快速准确地获取它所对应的IMP。取得IMP之后,就可以像调用普通的C语言函数一样来使用这个函数指针了。
在objc/runtime.h中还定义了用以表示方法的结构体。
typedefstructobjc_method*Method;
structobjc_method{
SELmethod_name
OBJC2_UNAVAILABLE;
//方法名
char*method_types
OBJC2_UNAVAILABLE;
IMPmethod_imp
OBJC2_UNAVAILABLE;
//方法实现
}
可以看到结构体objc_method包含了一个SEL和IMP,实际上它相当于在SEL和IMP之间作了一个映射。
11.
如何检测内存泄漏?正确答案:检测内存泄漏主要有以下3种方法:
1.静态分析
通过静态分析可以初步地了解到代码的一些不规范的地方或者是存在内存泄漏的地方,这是对内存泄漏的第一步检测。当然有一些警告是不需要关心的,可以略过。
2.通过instruments来检查内存泄漏
这个方法能粗略地定位在哪里发生了内存泄漏。方法是完成一个循环操作,如果内存增长为0,那么就证明程序在该次循环操作中不存在内存泄漏;如果内存增长不为0,那么就证明有可能存在内存泄漏。当然具体问题需要具体分析。
3.代码测试内存泄漏
在做这项工作之前,要注意在dealloc的方法中是否已经释放了该对象所拥有的所有对象。观察对象的生成和销毁是否配对。准确地说,就是init(创建对象的方法)和dealloc是否会被成对触发(简单来说就是有一次创建对象就有一次dealloc该对象)。
12.
Objective-C中的类方法和实例方法有什么本质区别和联系?正确答案:在比较类方法和实例方法的区别之前,先要明确Objective-C中的类对象和实例对象的概念,开发中定义的类自身也是一个对象,称为类对象,保存该类的成员变量、属性列表和方法列表等。类对象经alloc和init实例化后成为实例对象。实例对象、类对象和元类的底层结构如图所示。
实例对象、类对象和元类的关系结构图
1)类方法属于类对象,用“+”号修饰,它类似于C语言中的静态方法,类方法列表定义在类对象的元类中,通过isa指针找到;实例方法属于实例对象,用“-”号修饰,实例方法列表定义在实例对象的类对象中,通过isa指针找到。
2)类方法只能通过类对象调用,也就是类名直接调用;实例方法则需要由通过alloc和init方法实例化后的实例对象调用。
3)类方法中的self指类对象;实例方法中的self指实例对象。
4)类方法可以调用其他的类方法,但不可以直接调用实例方法;而实例方法既可以调用其他实例方法,也可以通过类名直接调用本类或者外部类的类方法。
5)在实例方法中可以访问成员变量,但类方法中不能访问成员变量。
13.
UIView动画原理是什么?以UIView类的animateWithDuration方法为例?正确答案:iOS4.0以后提供了几个基于block块的动画方法(UIView类的+animateWithDuration类方法),替代之前的+beginAnimations:context:和+commitAnimations方法,用于快速实现一些简单常用的UI动画效果。这种方法创建的动画为隐式动画,开发者只需要指定UI元素的一些属性的目标值,即可得到属性从当前值平滑过渡到目标值的动画效果,同时可以指定动画的持续时间。
可以设置UI隐式动画的常用属性主要有frame、bounds、center、transform、alpha、backgroundColor、contentStretch等。
例如,实现一个让视图平滑移动到指定位置的动画代码如下:
[UIViewanimateWithDuration:0.3animations:^{
/*设置center目标属性值*/
view.center=CGPointMake(200,200);
}completion:^(BOOLfinished){
/*动画执行结束回调*/
}];
动画持续时间为0.3s。在animations代码块中定义目标属性值。动画结束后会回调completion代码块,可在动画结束后继续开始新的动画,实现简单的连续动画效果。
14.
Objective-C对象可以被copy的条件是什么?正确答案:Objective-C对象可以被复制的条件是要遵守NSCopying和NSMutableCoping协议,默认是不遵守的。可以向遵守NSCopying协议的类的实例发送copy消息,也可以向遵守NSMutableCopying协议的类的实例发送mutableCopy消息,如果没有遵守协议而发送copy或mutableCopy消息,那么就会出错。两个协议分别对应不可变复制(copy)和可变复制(mutableCopy),而协议内部的实现方式决定是深拷贝还是浅拷贝。
例如,典型的系统类NSAnay是同时遵守了NSCopying和NSMutableCopying协议的,因此既可以发送copy消息,也可以发送mutableCopy消息。此外,iOS中同时遵守NSCopying协议和NSMutableCopying协议的类还有:NSString、NSValue、NSDictionary和NSSet及其子类。
如果想自定义深拷贝或浅拷贝方法,那么就要先遵守对应的协议,并重新实现对应的协议方法。
NSCopying的协议方法为copyWithZone:
-(id)copyWithZone:(nullableNSZone*)zone{
//深拷贝或浅拷贝实现
}
NSMutableCopying的协议方法为mutableCopyWithZone:
-(id)mutableCopyWithZone:(nullableNSZone*)zone{
//深拷贝或浅拷贝实现
}
15.
内存管理有哪几种方式?正确答案:常见的内存管理方式有块式管理、页式管理、段式管理和段页式管理。最常用的是段页式管理。
(1)块式管理把主存分为一大块一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程序片断载入主存,就算所需的程序片段只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但是易于管理。
(2)页式管理用户程序的地址空间被划分成若干个固定大小的区域,这个区域被称为“页”。相应地,内存空间也被划分为若干个物理块,页和块的大小相等。可将用户程序的任意一页放在内存的任意一块中,从而实现了离散分配。这种方式的优点是页的大小是固定的,因此便于管理;缺点是页长与程序的逻辑大小没有任何关系。这就导致在某个时刻一个程序可能只有一部分在主存中,而另一部分在辅存中。这不利于编程时的独立性,并给换入换出处理、存储保护和存储共享等操作造成麻烦。
(3)段式管理段是按照程序的自然分界划分的并且长度可以动态改变的区域。使用这种方式,程序员可以把子程序、操作数和不同类型的数据和函数划分到不同的段中。这种方式将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。在存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。
分页对程序员而言是不可见的,而分段通常对程序员而言是可见的,因而分段为组织程序和数据提供了方便,但是对程序员的要求也比较高。
分段存储主要有如下优点:
1)段的逻辑独立性不仅使其易于编译、管理、修改和保护,还便于多道程序共享。
2)段长可以根据需要动态改变,允许自由调度,以便有效利用主存空间。
3)方便分段共享,分段保护,动态链接,动态增长。
分段存储的缺点为:
1)由于段的大小不固定,所以存储管理比较麻烦。
2)会生成段内碎片,这会造成存储空间利用率降低。而且段式存储管理比页式存储管理方式需要更多的硬件支持。
正是由于页式管理和段式管理都有各种各样的缺点,所以,为了把这两种存储方式的优点结合起来,新引入了段页式管理。
(4)段页式管理段页式存储组织是分段式和分页式结合的存储组织方法,这样可充分利用分段管理和分页管理的优点。
1)用分段方法来分配和管理虚拟存储器。程序的地址空间按逻辑单位分成基本独立的段,而每一段有自己的段名,再把每段分成固定大小的若干页。
2)用分页方法来分配和管理内存。即把整个主存分成与上述页大小相等的存储块,可装入作业的任何一页。程序对内存的调入或调出是按页进行的,但它又可按段实现共享和保护。
16.
iOS应用的生命周期回调方法主要有哪些?正确答案:iOS应用的生命周期主要的回调方法包括程序开始启动和启动完毕、程序进入前台、程序进入后台、程序进入非活动状态和程序将要终止等,在这些状态转换时系统会以事件的方式通知开发者,以便开发者在需要时进行一些自定义操作。具体的回调方法及其含义见表。iOS应用的生命周期具体的回调方法及其含义回调方法含义-(BOOL)application:(UIApplication*)applicationwillFinishLaunchingWithOptions:(NSDictionary*)launchOptions告诉代理进程开始启动,这里是第一个可以开始执行代码的地方-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions告诉代理启动基本完成,程序准备运行,可以进行一些必要的应用初始化操作-(void)applicationWillResignActive:(UIApplication*)application应用程序将要退出前台进入非活动状态,在此期间,应用程序不接收消息或事件,例如来电-(void)applicationDidBecomeActive:(UIApplication*)application当应用程序进入前台活动状态后调用,这个方法的功能正好跟上面那个方法的功能相反-(void)applicationDidEnterBackground:(UIApplication*)application程序开始在后台运行,这里可以设置需要在后台执行的代码,注意当程序在后台运行时随时有可能被系统挂起-(void)applicationWillEnterForeground:(UIApplication*)application当程序从后台将要重新回到前台时候调用,但应用还未处于活跃状态,这个刚好跟上而的那个方法相反-(void)applicationWillTerminate:(UIApplication*)application当程序将要终止时被调用,通常是因为内存不足被系统终止。如果此时应用在挂起状态,则不会调用此方法,一般是用于保存数据和做一些退出前的清理工作
17.
NSNumber与NSInteger有什么区别?正确答案:前面讲到Objective-C中的数据类型大体分为3类:基本数据类型、对象类型和id类型。其中,基本数据类型如int类型、char类型等都不是对象,也就是说,在面向对象的编程环境中不能够向它们发送消息。然而,有时需要将这些值作为对象使用。为了存储基本数据类型的需要,可以使用NSNumber类,它会依据这些数据的类型创建对象。其基本构造方法如下:
+numberWithType:
-initWithType:
示例代码如下:
NSNumber*intNumb,*charNumber;
intNumber=[NSNumbernumberWithInteger:100];
charNumber=[NSNumbernumberWithChar:"M"];
如示例所示,NSInteger和NSNumber最本质的区别是:NSInteger不是一个对象,而是基本数据类型的typedef(也就是基本数据类型另外的一个名称)。它实际上是64位的long或者32位的int。如果需要存储一个数值(如将一个int类型的值存入数组),那么直接使用NSInterger是不行的,必须使用NSNumber类将基本数据类型包装成对象。
18.
如何解决masksToBounds离屏渲染带来的性能损耗?正确答案:在开发中常通过CALayer的cornerRadius属性来设置图层的圆角曲率(如设置圆角图片)。默认情况下,cornerRadius只影响背景颜色而不影响背景图片或子图层。但当将CALayer的masksToBounds设置为YES时,图层的内容就会被截取。代码如下:
imageView.layer.cornerRadius=10
imageView.layer.masksToBounds=YES
由于这样处理的渲染机制是GPU在当前屏幕缓冲区外新开辟的一个渲染缓冲区进行工作,也就是所谓的离屏渲染,所以这会给应用程序带来额外的性能损耗。如果在某一时刻大量地使用这种方式设置圆角,那么就会触发缓冲区频繁合并和上下文之间的频繁切换,这时应用程序就有可能出现掉帧和卡顿。具体可以使用Xcode自带的Instruments(工具)进行检测。
为了防止因离屏渲染而产生性能损耗,可以不使用CALayer的cornerRadius和masksToBounds属性,而将处理图片的权利交于CPU,虽然CPU对图形的处理能力不及GPU,但设置圆角图片的处理难度并不大,且代价远小于上下文切换。以下是实际开发中常用的两种优化方案:
1)使用CALayer提供的shouldRasterize属性。shouldRasterize属性是设置光栅化,可以使离屏渲染的结果缓存到内存中存为位图,当下次使用的时候就可以直接使用内存缓存,这样就节省了一直离屏渲染的性能损耗。为了使用shouldRasterize属性,还需要设置rasterizationScale属性去匹配屏幕,以防止出现Retina屏幕像素化的问题。
imageView.layer.shouldRasterize=YES;
imageView.layer.msterizationScale=[UIScreenmainScreen].scale;
这种方法虽然能在一定程度上优化性能,但是如果layer及sublayers经常改变,那么它就会不停地渲染及设置缓存,在这种情况下还是很耗性能的。
2)通过CoreGraphics绘制出圆角图片。可以使用UIKit中对Core
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026按摩搞笑面试题及答案
- 玻纤非织造制品生产工安全宣传强化考核试卷含答案
- 计算机零部件装配调试员岗前基础验收考核试卷含答案
- 光纤套塑工安全培训效果水平考核试卷含答案
- 聚合物配制工安全实践评优考核试卷含答案
- 电子商务平台入驻合同协议(2026年电商运营)
- 2026安全培训面试题库及答案
- 煤层气排采集输工保密模拟考核试卷含答案
- 茶叶初制工岗前技术传承考核试卷含答案
- 染料生产工创新方法竞赛考核试卷含答案
- 2026年山东名校联盟高三4月核心素养评估语文试题含答案
- 2026中国跨境支付系统合规风险与数字货币融合趋势分析
- 2026年招标采购从业人员《招标采购专业实务(初级)》考试真题(后附答案解析)
- 2026年阜新市医疗系统事业编乡村医生人员招聘考试备考试题及答案详解
- 江苏南通中远海运川崎船舶工程有限公司招聘笔试题库2026
- 苏教版科学四年级下册全册试卷
- 信息无障碍白皮书(2022年)
- 目标探测与识别智慧树知到期末考试答案章节答案2024年北京航空航天大学
- 部编版四年级下册道德与法治教学设计(教案)
- 数字贸易学 课件 第10、11章 开放型全球数字贸易平台、全球公司
- 贵州省2023年九年级中考备考语文专题复习:默写题(含解析)
评论
0/150
提交评论