1. 个人工具开发【卡片式记忆面试题开发】v.1.0.2

目的:主要是供个人地铁或公交路上,做一些自己整理的面试题。
例如目前比较感兴趣的java、android、算法、系统、正则表达式相关的面试题。方便地铁利用手机记忆用途

2. 思路:卡片记忆法

2.1 交互

  1. 分上下2页,上页显示题目,下页显示答案。
  2. 点击上页切换到下一个题目,同时清空下页内容
  3. 下页默认不显示内容,点击则显示该题目答案。

可能的拓展:
v1.0 暂时做成固定数据库

  1. 做成可以自定义新增或删除的功能
  2. 类似百词斩可以进行斩掉,下次重新背的时候再出现
  3. 数据库变大时的性能优化
    当然这个只是个人的一些想法,基本上是看下自己的需求程度,满足需求就行,不打算做得太复杂,万一哪天自己不想用了,岂不白白浪费时间。
    毕竟工具制作只是个人爱好,要是有报酬的工具单子可以接,也是很快乐的事情。不过这种事情想想就好。

2.2 功能

  1. 经典Java面试题
  2. 经典Android面试题
  3. 经典算法题
  4. 经典Android系统题
  5. 正则表达式

3. 本次开发情况

  • v.1.0.0 先将简单的UI绘制处理(https://blog.csdn.net/su749520/article/details/122143883)
  • v.1.0.1 申请SD卡读写权限,建立数据库,对功能进行简单填充(https://blog.csdn.net/su749520/article/details/122149684?spm=1001.2014.3001.5501)
  • v.1.0.2 建立自定义路径的数据库,对功能进行简单填充(本文)
  • v.1.0.2 读取数据库,调试数据库题库和UI(下文)

4. 数据库的结构设计

  1. 建立数据库名称:ReciteData.db

  2. 根据不同的背诵类别,新建不同的表名
    a. 表名:java
    b. 表名:android
    c. 表名:android_system
    d. 表名:recite_algorithm
    e. 表名:regular_expression

  3. 每张表的数据库字段
    a. 自增的id(可作为题目的序号): _id
    b. 题目内容: question
    c. 题目答案: answer
    d. 题目出现次数(拓展功能): show_count
    e. 题目是否已背(拓展功能,后续不要显示用途): recitedStatus

上述的前提是需要申请访问 SdCard 读写权限

5. 软件编码

5.1 建立自定义路径的数据库

目的主要是为了个人导出数据库,进行手动录入题库到数据库,方便apk随时读取新的题目
思路:重写 ContextWrapper 中的 getDatabasePath 的方法

package com.sufadi.reciteinterviewquestions.dbimport android.content.Context
import android.content.ContextWrapper
import android.database.DatabaseErrorHandler
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteDatabase.CursorFactory
import android.util.Log
import com.sufadi.reciteinterviewquestions.utils.Constans
import java.io.File/*** 自定义数据库路径* 重点重写 getDatabasePath 的方法*/
class DataBaseContext(private val mContext: Context) : ContextWrapper(mContext) {/**重写数据库路径方法, 实现自定义数据库路径 */override fun getDatabasePath(name: String): File {val dirPath: String = Constans.DB_PTAHvar path: String? = nullval parentFile = File(dirPath)if (!parentFile.exists()) {parentFile.mkdirs()}val parentPath = parentFile.absolutePathpath = if (parentPath.lastIndexOf("\\/") != -1) {dirPath + File.separator + name} else {dirPath + name}Log.d(Constans.TAG, "getDatabasePath: $path")return File(path)}override fun openOrCreateDatabase(name: String,mode: Int,factory: CursorFactory): SQLiteDatabase {return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name).absolutePath, factory)}override fun openOrCreateDatabase(name: String,mode: Int,factory: CursorFactory,errorHandler: DatabaseErrorHandler?): SQLiteDatabase {return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name).absolutePath,factory,errorHandler)}}

5.2 建立数据库

  1. 建立数据库名称:ReciteData.db

  2. 根据不同的背诵类别,新建不同的表名
    a. 表名:java
    b. 表名:android
    c. 表名:android_system
    d. 表名:recite_algorithm
    e. 表名:regular_expression

  3. 每张表的数据库字段
    a. 自增的id(可作为题目的序号): _id
    b. 题目内容: question
    c. 题目答案: answer
    d. 题目出现次数(拓展功能): show_count
    e. 题目是否已背(拓展功能,后续不要显示用途): recitedStatus

package com.sufadi.reciteinterviewquestions.dbimport android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteDatabase.CursorFactory
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
import com.sufadi.reciteinterviewquestions.utils.Constans/*** 方便后续填充题目到数据库中,更新数据库,即可以更新后续的背诵内容了* 1. 建立数据库名称:ReciteData.db* 2. 根据不同的背诵类别,新建不同的表名*  a. 表名:java*  b. 表名:android*  c. 表名:android_system*  d. 表名:recite_algorithm*  e. 表名:regular_expression* 3. 每张表的数据库字段*  a. 自增的id(可作为题目的序号): _id*  b. 题目内容: question*  c. 题目答案: answer*  d. 题目出现次数(拓展功能): show_count*  e. 题目是否已背(拓展功能,后续不要显示用途): recitedStatus 0:未背, 1:已背*/
class DBOpenHelper(context: Context?, dbName: String?, factory: CursorFactory?, version: Int) : SQLiteOpenHelper(context, dbName, factory, version) {constructor(context: Context?) : this(context, DB_NAME, null, 1) {Log.d(Constans.TAG, "DBOpenHelper constructor")mDataBaseContext = context as DataBaseContext}companion object {private const val DB_NAME = Constans.DB_NAME //数据库文件名private var INSTANCE: SQLiteDatabase? = null}private var mDataBaseContext: DataBaseContext? = nullval instance: SQLiteDatabase?get() {if (INSTANCE == null) {INSTANCE = DBOpenHelper(mDataBaseContext).writableDatabase}return INSTANCE}/*** 建立数据库的表格*/override fun onCreate(db: SQLiteDatabase) {Log.d(Constans.TAG, "DBOpenHelper onCreate")val createTableJava ="""CREATE TABLE IF NOT EXISTS ${Constans.DB_TABLE_NAME_JAVA}(${Constans.DB_KEY_ID} integer NOT NULL PRIMARY KEY AUTOINCREMENT,${Constans.DB_KEY_QUESTION} text,${Constans.DB_KEY_ANSWER} text,${Constans.DB_KEY_SHOW_COUNT} integer,${Constans.DB_KEY_RECITED_STATUS} integer);"""db.execSQL(createTableJava)val createTableAndroid ="""CREATE TABLE IF NOT EXISTS ${Constans.DB_TABLE_NAME_ANDROID}(${Constans.DB_KEY_ID} integer NOT NULL PRIMARY KEY AUTOINCREMENT,${Constans.DB_KEY_QUESTION} text,${Constans.DB_KEY_ANSWER} text,${Constans.DB_KEY_SHOW_COUNT} integer,${Constans.DB_KEY_RECITED_STATUS} integer);"""db.execSQL(createTableAndroid)val createTableAndroidSystem ="""CREATE TABLE IF NOT EXISTS ${Constans.DB_TABLE_NAME_ANDROID_SYSTEM}(${Constans.DB_KEY_ID} integer NOT NULL PRIMARY KEY AUTOINCREMENT,${Constans.DB_KEY_QUESTION} text,${Constans.DB_KEY_ANSWER} text,${Constans.DB_KEY_SHOW_COUNT} integer,${Constans.DB_KEY_RECITED_STATUS} integer);"""db.execSQL(createTableAndroidSystem)val createTableAlgorithm ="""CREATE TABLE IF NOT EXISTS ${Constans.DB_TABLE_NAME_RECITE_ALGORITHM}(${Constans.DB_KEY_ID} integer NOT NULL PRIMARY KEY AUTOINCREMENT,${Constans.DB_KEY_QUESTION} text,${Constans.DB_KEY_ANSWER} text,${Constans.DB_KEY_SHOW_COUNT} integer,${Constans.DB_KEY_RECITED_STATUS} integer);"""db.execSQL(createTableAlgorithm)val createTableRegularExpression ="""CREATE TABLE IF NOT EXISTS ${Constans.DB_TABLE_NAME_REGULAR_EXPRESSION}(${Constans.DB_KEY_ID} integer NOT NULL PRIMARY KEY AUTOINCREMENT,${Constans.DB_KEY_QUESTION} text,${Constans.DB_KEY_ANSWER} text,${Constans.DB_KEY_SHOW_COUNT} integer,${Constans.DB_KEY_RECITED_STATUS} integer);"""db.execSQL(createTableRegularExpression)}//当数据库的版本发生变化的时候会自动执行,禁止人为调用override fun onUpgrade(db: SQLiteDatabase,oldVersion: Int,newVersion: Int) {}}

5.3 遇到的报错-Failed to open database '/storage/emulated/0/

之前以为只要新增动态运行运行权限即可,没想到还需要在AndroidManifest.xml新增 android:requestLegacyExternalStorage=“true”

5.4 查看运行结果

a. 查看数据库是否生成

HWCLT:/storage/emulated/0 $ ls -al Rec
ReciteData.db          ReciteData.db-journal

b. 查看数据库是否可以插入数据

使用 insertDataToTableAlgorithm和queryFormTableAlgorithm 检测下,例如写入一组数据

package com.sufadi.reciteinterviewquestions.dbimport android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.util.Log
import com.sufadi.reciteinterviewquestions.utils.Constansclass DBHelper(val context: Context) {var mDBOpenHelper: DBOpenHelper? = nullprivate val dBOpenHelper: DBOpenHelperprivate get() {if (mDBOpenHelper == null) {mDBOpenHelper = DBOpenHelper(DataBaseContext(context))}return mDBOpenHelper!!}/**获取数据库对象 */val dateBase: SQLiteDatabase?public get() = dBOpenHelper.instance/**关闭数据库 */fun closeDB() {val db = dateBasedb?.close()}// just testfun insertDataToTableAlgorithm() {val sql="INSERT INTO ${Constans.DB_TABLE_NAME_RECITE_ALGORITHM}(${Constans.DB_KEY_QUESTION},${Constans.DB_KEY_ANSWER}) VALUES('操作符?的含义','前一个字符串0次或1次拓展,例如abc? 表示 ab, abc\n');";dateBase?.execSQL(sql)Log.d(Constans.TAG, "insertDataToTableAlgorithm sql=${sql}")}fun queryFormTableAlgorithm() {val cursor: Cursor? = dateBase?.rawQuery("select * from ${Constans.DB_TABLE_NAME_RECITE_ALGORITHM}", null) ?: nullwhile (cursor!!.moveToNext()) {val id = cursor.getString(cursor.getColumnIndex(Constans.DB_KEY_ID))val question = cursor.getString(cursor.getColumnIndex(Constans.DB_KEY_QUESTION))val answer = cursor.getString(cursor.getColumnIndex(Constans.DB_KEY_ANSWER))Log.d(Constans.TAG, "queryFormTableAlgorithm id=$id, question=$question, answer=$answer")}cursor.close()}
}

c. 数据库存储位置和数据库查询结果

重点:queryFormTableAlgorithm id=1, question=操作符?的含义, answer=前一个字符串0次或1次拓展,例如abc? 表示 ab, abc

2021-12-26 23:22:24.550 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: onClick: 2131165253
2021-12-26 23:22:24.550 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: gotoReciteUI: 0
2021-12-26 23:22:24.663 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: DBOpenHelper constructor
2021-12-26 23:22:24.671 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: getDatabasePath: /storage/emulated/0/ReciteData.db
2021-12-26 23:22:24.694 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: DBOpenHelper onCreate
2021-12-26 23:22:24.698 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: insertDataToTableAlgorithm sql=INSERT INTO recite_algorithm(question,answer) VALUES('操作符?的含义','前一个字符串0次或1次拓展,例如abc? 表示 ab, abc');
2021-12-26 23:22:24.700 25543-25543/com.sufadi.reciteinterviewquestions D/shz_debug: queryFormTableAlgorithm id=1, question=操作符?的含义, answer=前一个字符串0次或1次拓展,例如abc? 表示 ab, abc

个人工具开发【卡片式记忆面试题开发】v.1.0.2相关推荐

  1. 个人工具开发【卡片式记忆-面试题】v.1.0.0

    1. 个人工具开发[卡片式记忆-面试题]v.1.0.0 目的:主要是供个人地铁或公交路上,做一些自己整理的面试题.例如目前比较感兴趣的java\android相关的面试题.方便地铁利用手机记忆用途 2 ...

  2. 个人工具开发【卡片式记忆面试题开发】v.1.0.3

    1. 个人工具开发[卡片式记忆面试题开发]v.1.0.3 目的:主要是供个人地铁或公交路上,做一些自己整理的面试题. 例如目前比较感兴趣的java.android.算法.系统.正则表达式相关的面试题. ...

  3. 卡片式记忆工具:Studies Mac版

    Studies Mac版是学习必备的卡片式记忆工具,你可以使用Studies for mac激活版记录学习笔记,文本.图像.音频.视频都能记录在内,studies for mac版还支持从文本.Exc ...

  4. java GUI开发中关于卡片式布局详细步骤讲解

    java GUI开发中关于卡片式布局详细步骤讲解 JFrame frame = new JFrame("调课");//首先要申明一个JFrame. JPanel p1 = new ...

  5. Android开发:使用CardView实现卡片式设计

    开头引用一段官网的介绍 A FrameLayout with a rounded corner background and shadow. CardView uses elevation prope ...

  6. Android开发学习之卡片式布局的简单实现

    GoogleNow是Android4.1全新推出的一款应用,它可以全面了解你的使用习惯,并为你提供现在或者未来可能用到的各种信息,GoogleNow提供的信息关联度较高,几乎是瞬间返回答案,总而言之, ...

  7. web前端卡片样式_css完成卡片式图片结果_WEB前端开发

    起首我们来看一下结果图: (引荐教程:CSS教程) html代码: 突破企业间壁垒,供应便利的接入体式格局,完成不企业,差别品牌.差别范例间的家电的数据互联互通和数据协同 css代码: .card i ...

  8. iOS开发——BAT网易笔试面试题参考答案

    阿里B2B - 一面 1,load方法执行顺序,分类和主类的load方法顺序,两个分类的load方法顺序,跟main函数的顺序 2,sqllite的跟orcale这些大型的数据库的机制有什么不同的? ...

  9. 白盒测试有哪些方法_QA测试开发常考的面试题+答案汇总(持续更新)

    最近很多朋友都在说今年的互联网行情不好,面试很难,不知道怎么复习,我最近总结了一份在测试开发面试中比较常见的面试题合集,希望对大家有帮助. 本文共 4800 字,预计阅读时间 13 分钟,建议点赞+收 ...

最新文章

  1. Python---爬虫案例
  2. C++---内联函数与宏
  3. 彻底火了!这份Python学习贴,90%程序员用的上!
  4. 程序设计模式的有趣解释-追MM
  5. Java线程学习笔记(两) 线程异常处理
  6. 程序员进入BAT,到底是“好事”还是“坏事”?
  7. ArcGIS利用DEM提取河流水系
  8. 前端特效 —— 八卦图旋转(纯css)
  9. 浏览器的about:config清缓存及其他参数大全及其具体用途介绍
  10. 关于URDF中的惯性矩阵描述问题
  11. “iPad 上不可错过的应用有哪些?”
  12. ceph 运维操作 - POOL
  13. [LetCode-1438] 绝对差不超过限制的最长连续子数组
  14. 双搜----用两只眼睛看世界
  15. bootstrap 让文字显示在响应式图片上
  16. 函数型数据主成分分析(FPCA)
  17. Git提交代码到新仓库(--mirror)
  18. python项目对接钉钉SDK
  19. 数据结构约瑟夫环实验报告
  20. luajit开发文档wiki中文版(二) LuaJIT 扩展

热门文章

  1. 7.18洪资内参(更新中)
  2. 素数筛法(主要是欧拉筛)
  3. 2011年美国十大病毒营销案例
  4. 普及json格式相关问题
  5. 低频R型变压器铁芯好坏如何判断?
  6. Android获取软键盘的高度、键盘的打开与关闭、监听键盘处于打开还是关闭状态
  7. 2021年度高工智能汽车金球奖评选首批入围提名企业公布
  8. 番外篇1-对于分布式服务器的理解
  9. 聚焦2020九大科技热点,本周三ELEXCON电子展大幕将启!(含展商名单+会议推荐)...
  10. h5ai php 函数 禁用,H5ai安装报错Warning : putenv() has been disabled for security的解决办法...