数据库

  • 数据库范式(Normal Form)

    • 第一范式:确保每列保持原子性。

      • 第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
    • 第二范式:确保表中的每列都和主键相关

      • 第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
    • 第三范式:确保每列都和主键列直接相关,而不是间接相关。或者说非主键之间不应该有依赖关系。

      • 第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
    • BC范式:

      • BC范式(BCNF)是Boyce-Codd范式的缩写,其定义是:在关系模式中每一个决定因素都包含候选键,也就是说,只要属性或属性组A能够决定任何一个属性B,则A的子集中必须有候选键。BCNF范式排除了任何属性(不光是非主属性,2NF和3NF所限制的都是非主属性)对候选键的传递依赖与部分依赖。
    • 第四范式:不存在多值依赖
  • 数据库的索引(B树索引、哈希索引、位图索引)区别。

    • B树索引

      • 不存储含有null的值(复合索引不能全为null)
      • 不适合键值较少的列(重复数据较多的列)
      • 前导模糊查询不能利用索引
    • 位图索引

      • 就是用位图表示的索引,对列的每个键值建立一个位图。
      • 相对于b数索引,占用空间小,创建和使用非常快
      • 不适合键值较多的列。
      • 不适合update、insert、delete频繁的列。
      • 可以存储null值
    • 哈希索引

      • 根据HASH算法来构建的索引,所以检索速度很快,但不能范围查询。
      • 只适合等值查询(包括= <> 和in)
  • 说下聚簇索引和非聚簇索引的区别

    • 聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关。正式因为如此,所以一个表最多只能有一个聚簇索引。我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
  • 数据库索引的作用

    • 加速访问
  • 索引使用什么数据结构实现的

    • B树或者B+树
  • 数据库引擎了解吗,INNODB和MYIASM的区别,效率上的差异,锁的差别

    • MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的。要添加一个新的引擎,就必须重新编译MYSQL。在缺省情况下,MYSQL支持三个引擎:ISAM、MYISAM和HEAP。另外两种类型INNODB和BERKLEY(BDB),也常常可以使用。
    • ISAM:ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。
    • MyISAM:MyISAM是MySQL的ISAM扩展格式和缺省的数据库引擎。除了提供ISAM里所没有的索引和字段管理的大量功能,MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MyISAM还有一些有用的扩展,例如用来修复数据库文件的MyISAMCHK工具和用来恢复浪费空间的 MyISAMPACK工具。MYISAM强调了快速读取操作,这可能就是为什么MySQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。MyISAM格式的一个重要缺陷就是不能在表损坏后恢复数据。
    • HEAP:HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。要记住,在用完表格之后就删除表格。
    • InnoDB数据库引擎都是造就MySQL灵活性的技术的直接产品,这项技术就是MYSQL+API。在使用MYSQL的时候,你所面对的每一个挑战几乎都源于ISAM和MyISAM数据库引擎不支持事务处理(transaction process)也不支持外来键。尽管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了对事务处理和外来键的支持,这两点都是前两个引擎所没有的。如前所述,如果你的设计需要这些特性中的一者或者两者,那你就要被迫使用后两个引擎中的一个了。
    • MyISAM和InnoDB的区别

      • 总的来说,InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。
      • MyISAM的读性能是比Innodb强不少的。
      • MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。
    • MyISAM适合

      • 做很多count的计算
      • 插入不频繁,查询非常频繁
      • 没有事务。
    • InnoDB适合

      • 可靠性要求比较高,或者要求事务
      • 表更新和查询都相当的频繁,并且表锁定的机会比较大的情况指定数据引擎的创建。让所有的灵活性成为可能的开关是提供给ANSI SQL的MySQL扩展——TYPE参数。MySQL能够让你在表格这一层指定数据库引擎,所以它们有时候也指的是table formats。下面的示例代码表明了如何创建分别使用MyISAM、ISAM和HEAP引擎的表格。要注意,创建每个表格的代码是相同的,除了最后的 TYPE参数,这一参数用来指定数据引擎。
  • 数据库事务

    • 事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。
    • 四大特性:

      • 原子性:事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现两种状态之一(要么全部成功要么全部失败)。任何一项操作都会导致整个事务的失败,同时其它已经被执行的操作都将被撤销并回滚,只有所有的操作全部成功,整个事务才算是成功完成。
      • 一致性:事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。
      • 隔离性:事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。

        • 隔离级别有四个:读未提及、读已提交(解决脏读)、可重复读(解决不可重读)、顺序读(严格并发、解决幻读),mysql默认是可重复读
        • 隔离性解决的问题:脏渎、不可重读、幻读(理解这三者的区别)
      • 永久性:事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态。
      • 隔离的实现

        • 隔离的实现也是依赖加锁机制, InnoDB存在两种锁:S锁(共享锁)和X锁(排它锁)
  • 查询优化

    • 合理建立索引、优化SQL语句
    • IN、EXTISTS、JOIN的区别和应用场景

      • in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。in是把外表和内表作hash 连接,而exists 是对外表作loop循环,每次loop循环再对内表进行查询。
      • IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况
    • 防止索引失效
  • 在分库之后,如何设计id

  • 在分库后,一条插入请求,在上层不做处理,如何直接在数据库找到相应的库并插入库中的某个表

  • MySQL怎么进行数据存储

  • 如果让你设计数据库,你会想到那些优化

    • 表空间分离。最起码user和其他应用不应该使用系统表空间。表空间应该分在不同物理存储上,实现表空间分离
    • 开启慢查询日志、善用MySql内部函数explain
    • 善用不同的存储引擎,MySQL有多种不同的存储引擎,InnoDB,Aria,MEMORY根据需要给不同的表选择不同的存储引擎,比如要支持transaction的话用InnoDB等
    • 表很大的时候,做分表查询,有水平分割、垂直分割
    • 读写分离
    • 应该创建索引的字段

      • 经常作为查询条件的字段
      • 经常用在多表连接的列,例如外键
      • 经常需要排序的字段
    • 应该少建或者不建索引的情况

      • 表中数据太少,增加索引基本不会带来查询速度的提升,反而浪费了存储空间。
      • 经常需要插入、修改、删除操作的表
      • 表中数据重复且分布平均的字段(如“性别”)
    • 务必不要使用select * ,尽量使用limit,优化的目的就是尽量不去做全表扫描
    • 频繁查询的where子语句的条件加上索引
    • where子语句的连接不要使用or,这样会使引擎放弃索引,直接全表扫描
    • sql语句不要做太多关联,最好简单分开
  • 一个表有用户id.和用户成绩,怎么找到成绩前10的人。

      1. SELECT * FROM(
      2. SELECT T.*, ROW_NUMBER() OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) RN
      3. FROM T
      4. ) WHERE RN<=10
  • 数据库中char和varchar2的区别,和使用场景。

    • char长度不可变,varchar2长度可变。char效率比varchar2效率稍高,但char浪费更多空间。
  • 怎么防止sql注入(危险字符的转义,对SQL预编译)

  • Redis缓存机制:应用场景和优点、与memcache的区别、如何实现持久性、主从模式

  • 读写分离、主从复制、主从复制的方式

  • sql语句写 一个属性的查询,分组,计数并排序输出。

  • 一段不连续的内存,怎么才可以实现键值对快速更新、查询

  • redis为什么性能高?

    • 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
    • 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的
    • 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
    • 使用多路I/O复用模型,非阻塞IO
    • 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求
  • redis可以做什么,mysql buffer pool 可以做缓存吗?

  • redis有没有用过,常用的数据结构以及在业务中使用的场景,redis的hash怎么实现的。redis cluster有没有了解过,怎么做到高可用的?redis的持久化机制,为啥不能用redis做专门的持久化数据库存储?

  • Redis内存数据库的内存指的是共享内存么

  • 从A表中选出B表没有的数据,就是AB表有一个共同列,这个列中序号的不同的A表的数据全部拿出来

    • select * from A where t2 not in (select t2 from B)
  • nosql

  • SQL语句,查询两个数据库表中ID相同的信息。

    • SELECT information from table_1 left join table_2 where table_1.ID = table_2.ID
  • redis的缺陷

    • 数据存放在私有内存,升级版本和更新困难,且危险性高
    • 内存使用率低,碎片多
    • 备份、全量同步机制采用fork+rdb的方式,且对内存增长没有做控制
    • 死机恢复采用全量+增量方式,如果数据量太大并且写量也足够大,有可能占用大量buffer缓冲且出现反复失败的情况
    • 对于所有命令串行处理,有些慢查询如lrange会阻塞其他命令
    • 存在大包回复时,可能会消耗一大块内存用于存放临时对象
    • 没有防雪崩之类的海量数据运营机制

脑筋急转弯

  • 36匹马6个跑道无秒表选前三,最少跑几轮。

  • 有八只小白鼠,八瓶要其中有一瓶毒药,药发时间是一小时,问最小用几只小白鼠能找出毒药。

    • 二分法,每次把试剂分成两堆,然后用两只小鼠测试,如果一只死掉了,那么就能确定哪一堆有毒。然后继续分。因此,小鼠的数量就是试剂能被二分的次数。8只试剂能被二分3次,所以就需要3值小鼠。
  • 5L 6L空瓶子,弄出3L水

    • 傻逼题
  • 有一只股票,原价为p0,若它涨停10天后又跌停10天后得到p1,若它跌停10天再涨停10天得到p2,求三者关系(p0 > p1 = p2)

  • 有25匹马,五个赛道,用最少比赛次数将25匹马排序

    • 毫无悬念,一匹马只有跑了才能看出其速度,25匹马至少都跑了一次,最少五轮,且每轮能排出名次;由于最终只要最快的三名,顾每组只有1、2、3有意义继续比下去,4、5名直接淘汰。每组的3有意义的前提是该组的2就是总排名的2、1就是总排名的1,每组的2有意义的前提是该组的1至少第二;归根到底还是看每组第一的情况,故5个第一比一次,第一就是总的第一;第四、第五及其所在的组全部被淘汰;故第一的组的二、三名,第二的组第一、二名;第三的组的第一名比最后一次,前两名就是总的二、三名;共七轮。
      1. a1,a2,a3,a4,a5;------>a1,a2,a3;
      2. b1,b2,b3,b4,b5;------>b1,b2,b3;
      3. c1,c2,c3,c4,c5;------>c1,c2,c3;
      4. d1,d2,d3,d4,d5;------>d1,d2,d3;
      5. e1,e2,e3,e4,e5;------>e1,e2,e3;


a1,b1,c1,d1,e1;———> a1 ,b1,c1
a2,a3,b1,b3,c1;———> a2,a3 ;

  • 有100层楼,你有两部手机,请用最少的次数测试出在第几层手机会被摔碎

软件工程

  • 在项目中用到过设计模式吗?讲讲工厂模式,用工厂模式制造不同的单例出来

  • 对于单例模式,有什么使用场景了,讲了全局id生成器,他问我分布式id生成器怎么实现,说了zk,问我zk了解原理不,讲了zab

  • 适配器模式怎么实现么,有什么用

  • 多线程下如何实现单例,加锁?怎么加?synchronized,synchronized在静态方法、实例方法、代码块前使用的区别

  • 7种结构模式以及应用场景:桥接模式、适配器模式、代理模式、享元模式、组合模式、门面模式、装饰模式

  • 重点掌握单例模式和MVC模式(应用场景、优缺点)

  • 了解UML图,能看懂各种不同箭头表示的意思。

  • 写你知道的Git命令
    git init
    git pull
    git fetch git merge
    git add
    git commit
    git push
    git reset —hard
    git stash git stash pop

  • 单例模式、懒汉饿汉

分布式系统

  • 有了解分布式系统吗? 现有开源分布式存储的系统或协议是否了解
  • 数据同步、单点故障、副本容灾、读写一致性等
  • 一致性哈希
  • 知道cap原则吗?
  • 知道dubbo吗

其他

  • 现在要完成一个微博评论的部分,想在用户进入新闻时优先看到自己好友对此新闻的评论,好友可能有多条评论,怎么设计结构。

  • 我现在想要写一个简单的web服务器,响应用户相应的数据,该怎么写(首先创建一个服务器socket,然后bind地址,listen监听,然后把socket加入多路转接监听链表。当有连接到达的时候,我们对socket调用accept,返回一个已连接套接字描述符,然后根据用户传输过来的文件名去查找文件,读取文件内容并回送给用户(被打断)读取文件的时候服务器socket怎么办呢,accept之后创建一个线程,如果使用线程池的话就从池中取一个空闲线程,然后把已连接文件描述符传给这个线程,然后让线程去处理这个用户请求)

  • 假设我想要缓存web服务器的访问记录,该如何实现这个数据结构(用队列吧,根据last visited排序,先进先出,如果你用队列的话,你怎么确定cache是否命中呢,你根据什么判断是否命中,key,那我还是用队列,每一个元素包含键值两部分,值的话呢就是访问的记录。然后我再用一个红黑树保存键值,这个值呢是指向队列元素的指针,其实用hash表更好一点,这样更快,但是我一般都比较喜欢用红黑树…)

  • 在记录有用户上线下线的日志文件中查询某个时间点的在线人数。时间复杂度多少,能不能优化?

  • 然后问有一个图像处理程序,处理一个请求需要50ms的cpu计算,现在打算部署到4核CPU上,问设置几个线程合适。再扩展,假如不仅需要50ms的cpu计算,还需要200ms的IO时间,问设置几个线程合适。

  • 要是设计一个高并发服务器,可以从哪些角度去优化。

  • 假如有一亿QQ用户,每个用户都有500好友,每个人都可能玩很多腾讯出的游戏,问如何存储能使获取一个人的好友玩的游戏列表。
    我想了半天,说不会,最后被提醒用kv存储,面试官让我回去看看bitmap,这一部分是印象最深耗时最长的部分。

  • 直播的架构怎么设计么,要点是什么,说了几个不太对,他说要避免广播风暴,答不会。