版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
高频iossql面试题及答案SQLite是iOS开发中常用的本地数据存储方案,熟练掌握其相关操作及原理是iOS工程师的必备技能。以下整理了iOS开发中常见的SQL面试问题及详细解答。1.SQLite支持的数据类型有哪些?动态类型系统的特点是什么?SQLite的数据类型分为存储类(StorageClasses)和类型亲和性(TypeAffinity)。存储类包括NULL、INTEGER、REAL、TEXT、BLOB五种,分别对应空值、整数、浮点数、文本、二进制数据。类型亲和性指表列在定义时指定的类型(如INT、VARCHAR)会影响其优先存储的存储类,但SQLite不会严格检查数据类型,允许将任意类型数据存入任意列,这种特性称为动态类型系统。例如,定义为INTEGER类型的列可以存储文本,插入时会尝试转换为整数,无法转换则以原类型存储。动态类型系统提升了灵活性,但也需要开发者在业务层做好类型校验。2.如何在iOS中使用SQLite?FMDB的核心类及作用是什么?iOS原生通过libsqlite3库操作SQLite,需调用C语言接口(如sqlite3_open、sqlite3_prepare_v2),代码冗余且易出错。FMDB是Objective-C封装的轻量级框架,简化了操作。其核心类包括:FMDatabase:代表一个数据库连接,负责执行SQL语句(如executeUpdate用于写操作,executeQuery用于读操作)。FMResultSet:查询结果集,通过next方法遍历数据。FMDatabaseQueue:多线程安全类,通过队列管理数据库操作,避免多线程同时访问导致的崩溃。注意:多线程场景必须使用FMDatabaseQueue,直接使用FMDatabase可能引发数据竞争或死锁。3.SELECT语句中WHERE、HAVING、GROUPBY的执行顺序及区别?执行顺序:FROM→WHERE→GROUPBY→HAVING→SELECT→ORDERBY。WHERE:对原始表数据过滤,在分组前生效,不能使用聚合函数(如SUM、COUNT)。GROUPBY:按指定列分组,分组后提供临时表。HAVING:对分组后的临时表过滤,可使用聚合函数(如HAVINGCOUNT()>5)。示例:查询每个班级(class_id)中分数大于60分的学生,且班级人数超过3人:SELECTclass_id,COUNT()ASnumFROMstudentsWHEREscore>60GROUPBYclass_idHAVINGnum>3;4.事务的ACID特性是什么?iOS中如何实现事务?ACID是事务的四大特性:原子性(Atomicity):事务内操作要么全部成功,要么全部回滚。一致性(Consistency):事务执行前后数据处于合法状态。隔离性(Isolation):多个事务并发执行时,彼此不干扰。持久性(Durability):事务提交后,数据修改永久保存。在iOS中,使用FMDB实现事务有两种方式:(1)通过FMDatabase的inTransaction方法:[dbinTransaction:^(FMDatabasedb,BOOLrollback){BOOLsuccess1=[dbexecuteUpdate:@"INSERTINTOt1VALUES(1)"];BOOLsuccess2=[dbexecuteUpdate:@"INSERTINTOt2VALUES(2)"];if(!success1||!success2){rollback=YES;//任意操作失败则回滚}}];(2)手动执行SQL语句:[dbexecuteUpdate:@"BEGINTRANSACTION"];//开始事务//执行多个操作...if(allSuccess){[dbexecuteUpdate:@"COMMIT"];//提交}else{[dbexecuteUpdate:@"ROLLBACK"];//回滚}注意:事务应尽可能简短,避免长时间持有锁导致界面卡顿。5.索引的作用、类型及使用场景是什么?哪些情况不适合创建索引?索引通过存储列值与行位置的映射,加速查询效率。常见索引类型:普通索引(INDEX):最基本索引,无唯一性约束。唯一索引(UNIQUEINDEX):保证列值唯一(如用户手机号)。主键索引(PRIMARYKEY):特殊的唯一索引,自动创建,加速主键查询。复合索引(多列索引):基于多列创建,遵循“最左前缀匹配”原则(如索引(a,b,c)可用于查询a、a+b、a+b+c)。适合创建索引的场景:频繁作为查询条件的列(如用户表的user_id)。连接操作中频繁使用的列(JOIN的ON条件)。频繁排序的列(ORDERBY)。不适合索引的场景:数据量小的表(索引维护成本可能高于查询优化收益)。频繁更新的列(每次更新需同步更新索引,影响性能)。低基数列(如性别字段只有“男/女”,索引无法有效过滤数据)。6.如何分析SQL查询性能?EXPLAINQUERYPLAN的作用是什么?分析查询性能可通过以下方式:观察执行时间:使用FMDB的executeQueryWithFormat:等方法时,记录耗时(如通过CFAbsoluteTimeGetCurrent()计算)。查看是否全表扫描:全表扫描(SCANTABLE)效率低,应通过索引避免。使用EXPLAINQUERYPLAN:在SQL语句前添加该指令,返回查询计划,显示是否使用索引、扫描方式等。示例:EXPLAINQUERYPLANSELECTFROMusersWHEREage>20;若结果包含“SCANTABLEusers”,说明未使用索引;若包含“SEARCHTABLEusersUSINGINDEXidx_age”,则表示通过索引加速查询。7.分页查询的常见写法及潜在问题?如何优化大数据量分页?常见写法:SELECTFROMtableLIMIToffset,pageSize(如LIMIT1000,20)。潜在问题:当offset很大时(如LIMIT100000,20),数据库需扫描前100000行数据,效率极低。优化方法:(1)记录上一页最后一条数据的主键,通过WHERE条件直接定位:假设主键为id,上一页最后一条id是lastId,则下一页查询:SELECTFROMtableWHEREid>lastIdORDERBYidLIMIT20;此方法仅适用于有序且无删除的场景。(2)使用覆盖索引:若查询仅需部分字段,为这些字段创建索引,避免回表(从索引直接获取数据,无需访问原表)。(3)预计算总页数:通过COUNT()获取总数据量,提前告知用户总页数,避免用户跳转到过大的offset。8.如何避免SQL注入攻击?预处理语句(PreparedStatements)的优势?SQL注入是通过拼接恶意SQL字符串破坏原有逻辑的攻击方式(如输入用户名“'OR'1'='1”导致WHERE条件恒真)。避免方法:使用预处理语句(ParameterizedQueries),通过占位符(?或命名参数)传递参数,而非字符串拼接。FMDB中推荐使用带参数的方法,如executeUpdate:@"INSERTINTOt(name)VALUES(?)",userName;预处理语句的优势:防止SQL注入:参数与SQL语句分离,数据库将参数视为普通数据。提升性能:重复执行相同结构的SQL时,数据库只需编译一次执行计划。减少代码错误:避免字符串拼接的格式错误(如引号未闭合)。9.SQLite的锁机制及多线程访问注意事项?SQLite的锁分为5个级别(从共享到独占):无锁(NONE):未访问数据库。共享锁(SHARED):读操作时获取,允许多个读锁共存。保留锁(RESERVED):写操作开始时获取,阻止其他写锁,允许读锁。独占锁(EXCLUSIVE):写操作提交前获取,阻止所有其他锁。未决锁(PENDING):写操作等待现有读锁释放时获取。多线程访问注意事项:禁止多个线程同时使用同一个FMDatabase实例(可能导致数据错误或崩溃)。使用FMDatabaseQueue管理多线程操作,内部通过GCD队列串行执行数据库任务。长事务(如批量插入)应放在后台线程,避免阻塞主线程导致界面卡顿。10.数据库迁移(Schema升级)的常见策略?如何处理版本控制?应用升级时,数据库结构可能需要变更(如新增字段、修改表结构),需设计迁移策略:(1)版本控制:通过SQLite的user_version字段记录数据库版本(PRAGMAuser_version)。应用启动时检查当前版本与预期版本,差异部分执行迁移。(2)迁移方式:新增字段:ALTERTABLEtableADDCOLUMNnew_colTEXT;(注意:SQLite仅支持ADDCOLUMN,不支持DROPCOLUMN或ALTERCOLUMN)。修改表结构:创建临时表→复制数据→删除原表→重命名临时表(如ALTERTABLE无法满足需求时)。示例代码(FMDB实现版本检查):intcurrentVersion=[dbintForQuery:@"PRAGMAuser_version"];if(currentVersion<2){[dbexecuteUpdate:@"ALTERTABLEusersADDCOLUMNemailTEXT"];[dbexecuteUpdate:@"PRAGMAuser_version=2"];//更新版本号}(3)数据迁移:复杂变更(如拆分表)需先备份数据,迁移后恢复,注意事务保护避免部分失败。11.INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLJOIN的区别?SQLite是否支持?INNERJOIN(内连接):返回两表中满足连接条件的交集数据。LEFTJOIN(左连接):返回左表所有行,右表无匹配时用NULL填充。RIGHTJOIN(右连接):返回右表所有行,左表无匹配时用NULL填充。FULLJOIN(全连接):返回左右表所有行,无匹配时用NULL填充。SQLite不支持RIGHTJOIN和FULLJOIN,可通过LEFTJOIN+UNION+LEFTJOIN(交换表顺序)模拟FULLJOIN:SELECTFROMALEFTJOINBONA.id=B.idUNIONSELECTFROMBLEFTJOINAONB.id=A.id;12.触发器(Trigger)的作用及iOS开发中的使用限制?触发器是绑定到表的事件(INSERT/UPDATE/DELETE)的存储过程,事件发生时自动执行。常见用途:级联更新:删除用户时自动删除其订单(但外键约束更推荐)。数据校验:插入数据前检查合法性(如年龄不能为负数)。iOS开发中使用触发器的限制:性能影响:触发器在每次事件时执行,高频操作可能导致卡顿。维护复杂:触发器逻辑隐含在数据库中,增加代码理解成本。兼容性:不同SQLite版本对触发器的支持可能有差异。建议:优先通过应用层逻辑实现业务规则,仅在必要时使用触发器。13.如何优化批量插入操作的性能?批量插入(如导入1000条数据)时,默认逐条插入效率低(每次插入隐式提交事务),优化方法:(1)使用事务包裹所有插入操作:将1000次单条插入改为1次事务内的批量插入,减少磁盘IO(事务提交时统一写入)。(2)使用INSERTORIGNORE或REPLACEINTO:避免重复插入时的冲突检查开销(根据业务需求选择)。(3)使用预处理语句:复用同一执行计划,减少编译时间。示例(FMDB批量插入):[dbbeginTransaction];for(NSDictionaryitemindataArray){[dbexecuteUpdate:@"INSERTINTOlogs(time,content)VALUES(?,?)",item[@"time"],item[@"content"]];}[dbcommit];测试表明,1000条数据逐条插入需约2秒,事务包裹后仅需约0.1秒。14.外键约束(FOREIGNKEY)的作用?iOS中如何启用?外键约束用于维护表间引用完整性,确保子表的外键值在主表中存在对应主键。例如,订单表(order)的user_id必须是用户表(user)中存在的id。iOS中启用外键需执行PRAGMAforeign_keys=ON;(默认关闭)。注意:外键约束在CREATETABLE时定义(如FOREIGNKEY(user_id)REFERENCESuser(id))。级联操作(CASCADE):删除主表记录时自动删除子表记录(ONDELETECASCADE),需显式声明。性能影响:外键检查会增加写操作开销,高频写场景需权衡是否启用。15.如何判断索引是否生效?索引失效的常见原因?判断索引是否生效:使用EXPLAINQUERYPLAN查看查询计划,若显示“USINGINDEX”则生效。对比使用索引前后的查询时间(显著缩短则生效)。索引失效的常见原因:WHERE子句使用函数或表达式(如WHERESUBSTR(name,1,2)='AB',无法使用name列的索引)。类型不匹配:索引列是INTEGER类型,但查询时使用字符串(如WHEREid='123',可能导致全表扫描)。复合索引未遵循最左前缀(如索引(a,b,c),查询条件为WHEREb=1,无法使用该索引)。使用LIKE通配符开头(如WHEREnameLIKE'%ABC',无法使用name的索引;但LIKE'ABC%'可以)。数据库统计信息过时:SQLite自动维护统计信息,但大量数据变更后可能导致优化器误判,可通过ANALYZE命令更新统计(PRAGMAanalyze;)。16.CoreData与直接使用SQLite的区别?各自适用场景?CoreData是Apple提供的ORM(对象关系映射)框架,底层可基于SQLite存储(也可使用其他存储),与直接使用SQLite的区别:编程模型:CoreData操作对象(NSManagedObject),SQLite操作SQL语句。功能:CoreData提供自动迁移、缓存、撤销/重做等高级功能;SQLite需手动实现。性能:简单查询时CoreData可能有额外开销(对象转换),复杂查询(如多表JOIN)直接SQL更高效。适用场景:CoreData:对象模型复杂、需要自动迁移、注重开发效率的项目(如记录用户行为的App)。直接SQLite/FMDB:需要细粒度控制查询性能、执行复杂SQL(如嵌套子查询)、对存储占用敏感的项目(如工具类App)。17.如何处理数据库的加密需求?iOS中SQLite默认不加密,需使用加密扩展(如SQLCipher)。集成步骤:(1)引入SQLCipher库(通过CocoaPods:pod'FMDB/SQLCipher')。(2)打开数据库时设置密钥:FMDatabasedb=[FMDatabasedatabaseWithPath:dbPath];if([dbopenWithFlags:SQLITE_OPEN_READ_WRITE|SQLITE_OPEN_CREATE]&&[dbsetKey:@"mySecretKey"]){//打开成功}(3)加密原理:SQLCipher基于AES算法对数据库页(Page)加密,密钥正确才能解密读取。注意:加密会增加读写性能开销(约10%-20%),需根据安全需求权衡。18.死锁的原因及解决方法?死锁是两个或多个事务互相等待对方释放锁的状态。例如:事务1:锁定表A,请求锁定表B。事务2:锁定表B,请求锁定表A。双方等待对方释放锁,导致死锁。解决方法:保持加锁顺序:所有事务按相同顺序访问表(如先A后B)。缩短事务时间:减少事务持有锁的时长,降低冲突概率。设置超时:通过sqlite3_busy_timeout设置等待锁的超时时间(FMDB中[dbsetBusyTimeout:5.0];),超时后自动回滚。使用更弱的隔离级别:SQLite默认隔离级别为SERIALIZED,可调整为更宽松的隔离级别(但需
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 47016-2026超高清镜头物理及电气控制接口
- 乳牙牙髓病及根尖周病的临床表现及诊断
- 可降解材料性能评估-第2篇-洞察与解读
- 多组学融合的单细胞蛋白研究-洞察与解读
- 性别平等政策实施效果-第2篇-洞察与解读
- 5G智能风控-洞察与解读
- 产业链绿色协同-洞察与解读
- 纳米技术在护理应用-洞察分析
- 2026年云南省昆明市单招职业适应性测试题库带答案详解(完整版)
- 2026年义乌工商职业技术学院单招综合素质考试题库及答案详解(有一套)
- 智能网联汽车感知技术与应用 课件 任务3.1 视觉感知技术应用
- 9.个体工商户登记(备案)申请书
- 2025RCEM实践指南:急诊室内疑似但不明中毒患者的管理课件
- 2025年孕产期甲状腺疾病防治管理指南(全文)
- 农夫山泉秋招面试题及答案
- 职业紧张综合征干预方案
- 船舶检验与维修流程规范
- 《TCSUS69-2024智慧水务技术标准》
- 浙江森马服饰公司营运资金管理研究
- 地铁车辆段安全培训课件
- DBJT15-80-2021 保障性住房建筑规程
评论
0/150
提交评论