zoukankan      html  css  js  c++  java
  • [面试]美团点评面试记录

    自我介绍

    项目介绍

    关于java的知识点,因为我是c++和python技术栈,所以没有直接来问java。

    设计模型

    1. 单例模式
      懒汉模式和饿汉模式。1. 单例类只能有一个实例。2. 单例类必须自己创建自己的唯一实例。3. 单例类必须给所有其他对象提供这一实例。

      1. 懒汉模式:只有在getInstance()方法的时候才会创建单例对象,否则不会创建。
      2. 饿汉模式:在类加载时就已经初始化了一个实例。
    2. 策略模式
      定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

      1. 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为 2. 一个系统需要动态地在几种算法中选择一种。
        其实主要是为了代替代码中冗长的ifelse语句,使每个分支的逻辑都用算法类进行封装,并提供一个统一的使用接口。

    数据库知识点

    1. delete、drop、truncat的区别
      相同点: 1. truncate和不带where子句的delete、以及drop都会删除表内的数据。 2. drop、truncate都是DDL语句(数据定义语言),执行后会自动提交。
      不同点:1. truncate 和 delete 只删除数据不删除表的结构(定义)。drop 语句将删除表的结构被依赖的约束(constrain)、触发器(trigger)、索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。2. delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效;如果有相应的 trigger,执行的时候将被触发。 3. drop 语句将表所占用的空间全部释放。4. 速度上: drop> truncate > delete 5. delete是DML语句,不会自动提交。drop/truncate都是DDL语句,执行后会自动提交。

    2. 索引设计需要注意的规则

      1. 定义主键的数据列一定要建立索引。
      2. 定义有外键的数据列一定要建立索引。
      3. 对于经常查询的数据列最好建立索引。
      4. 对于需要在指定范围内的快速或频繁查询的数据列;
      5. 经常用在WHERE子句中的数据列。
      6. 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。
      7. 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
      8. 对于定义为text、image和bit的数据类型的列不要建立索引。
      9. 对于经常存取的列避免建立索引
      10. 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
      11. 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。
    3. 事务管理

      1. 原子性:是指事务是一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生。
      2. 一致性:是指事务前后数据的完整性要保持一致。
      3. 隔离性:是指是指多个用户并发访问数据库的时候,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数要相互隔离。
      4. 持久性:是指一个事务一旦提交,他对数据库中数据的改变就是就是永久性的。
        不考虑隔离性,会引发下列问题: 1. 脏读:是指一个事务读到另一个事务未提交的数据 2. 不可重复读:在一个事务中,两次查询到的结果不一致(针对update 操作) 3. 虚读(幻读):在一个事务中,两次查询到的结果不一致(针对 insert 操作)。
    4. mysql引擎问题
      三大数据库引擎: 1. MyISAM 2. InnoDB 3. Memory
      InnoDB是一个事务型的存储引擎,有行级锁定和外键约束。
      Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这类型的文章。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
      适用场景: 1. 经常更新的表,适合处理多重并发的更新请求。2. 支持事务。 3. 可以从灾难中恢复(通过bin-log日志等)。 4. 外键约束。只有他支持外键。 5. 支持自动增加列属性auto_increment。

    MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
    MyIsam 存储引擎独立于操作系统,也就是可以在windows上使用,也可以比较简单的将数据转移到linux操作系统上去。
    适用场景: 1. 不支持事务的设计,但是并不代表着有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。2. 不支持外键的表设计。 3. 查询速度很快,如果数据库insert和update的操作比较多的话比较适用。 4. 整天对表进行加锁的场景。 5. MyISAM极度强调快速读取操作。 6. MyIASM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。

    HEAP使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH索引。
    适用场景: 1. 那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地堆中间结果进行分析并得到最终的统计结果。 2. 目标数据比较小,而且非常频繁的进行访问,在内存中存放数据,如果太大的数据会造成内存溢出。可以通过参数max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。 3. 数据是临时的,而且必须立即可用得到,那么就可以放在内存中。 4. 存储在Memory表中的数据如果突然间丢失的话也没有太大的关系。

    1.InnoDB支持事务,而MyISAM不支持事务
    2.InnoDB支持行级锁,而MyISAM支持表级锁
    3.InnoDB支持MVCC, 而MyISAM不支持
    4.InnoDB支持外键,而MyISAM不支持
    5. InnoDB不支持全文索引,而MyISAM支持。
    6.InnoDB不能通过直接拷贝表文件的方法拷贝表到另外一台机器, myisam 支持
    7.InnoDB表支持多种行格式, myisam 不支持
    8.InnoDB是索引组织表, myisam 是堆表

    1. mysql的并发处理?mysql锁的类型。
      从锁的类别上来讲,有共享锁和排他锁.
      共享锁: 又叫做读锁. 当用户要进行数据的读取时,对数据加上共享锁.共享锁可以同时加上多个.
      排他锁: 又叫做写锁. 当用户要进行数据的写入时,对数据加上排他锁.排他锁只可以加一个,他和其他的排他锁,共享锁都相斥.

    2. mysql的分库分表问题
      一般就是垂直切分和水平切分,这是一种结果集描述的切分方式,是物理空间上的切分。

      1. 垂直分表: 也就是“大表拆小表”,基于列字段进行的。一般是表中的字段较多,将不常用的, 数据较大,长度较长(比如text类型字段)的拆分到“扩展表“。 一般是针对那种几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。
      2. 垂直分库: 垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Producet一个库,订单Order一个库。

      水平分表: 针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。
      水平分库分表: 将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。
      水平分库分表切分规则: 1. RANGE 2. HASH取模 3. 地理区域 4. 时间

      分库分表后面临的问题:

      1. 事务支持 2. 多库结果集合并(group by,order by)3. 跨库join
    3. sql优化问题

    id:每个被独立执行的操作的标志,表示对象被操作的顺序。一般来说, id 值大,先被执行;如果 id 值相同,则顺序从上到下。
    select_type:查询中每个 select 子句的类型。
    table:名字,被操作的对象名称,通常的表名(或者别名),但是也有其他格式。
    partitions:匹配的分区信息。
    type:join 类型。
    possible_keys:列出可能会用到的索引。
    key:实际用到的索引。
    key_len:用到的索引键的平均长度,单位为字节。
    ref:表示本行被操作的对象的参照对象,可能是一个常量用 const 表示,也可能是其他表的
    key 指向的对象,比如说驱动表的连接列。
    rows:估计每次需要扫描的行数。
    filtered:rows*filtered/100 表示该步骤最后得到的行数(估计值)。
    extra:重要的补充信息。

    其他

    消息队列是什么?怎么理解消息队列
    把要传输的数据放在队列中。

    1. 解耦: 可以将被动服务模式改变为主动服务模式。
    2. 异步: 将IO阻塞的服务异步执行,减少执行时间。
    3. 削峰/限流: 当系统处理能力不足时,就可以将请求都保存到消息队列里,然后由系统能力来决定能处理的请求数。
      出现的问题:1. 高可用:保证是非单机的。 2. 数据丢失问题: 如何防止消息队列中挂掉,从而出现数据丢失问题。3. 消费者如何拿数据:主动轮询或被动通知。

    Memcache与Redis的区别?

    1. 存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,redis可以持久化其数据
    2. 数据支持类型 memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 ,提供list,set,zset,hash等数据结构的存储
    3. 使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
    4. value 值大小不同:Redis 最大可以达到 512M;memcache 只有 1mb。
    5. redis的速度比memcached快很多
    6. Redis支持数据的备份,即master-slave模式的数据备份。

    redis的过期策略以及内存淘汰机制?
    redis采用的是定期删除+惰性删除策略。
    定时删除: 用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。
    惰性删除: 在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

    volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
    volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
    volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
    allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
    allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
    no-enviction(驱逐):禁止驱逐数据,新写入操作会报错

    如何保证数据一致?
    主从复制,读写分离
    一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

    linux查询100M日志中某个id的日志?less grep命令
    grep命令进行查找,如果文件较多的话应当使用less命令逐行查看。

    git将多个commit合并到一条记录?
    git merge branch会把branch分支的差异内容pull到本地,然后与本地分支的内容一并形成一个committer对象提交到主分支上,合并后的分支与主分支一致;
    git rebase branch会把branch分支优先合并到主分支,然后把本地分支的commit放到主分支后面,合并后的分支就好像从合并后主分支又拉了一个分支一样,本地分支本身不会保留提交历史。

    http请求过程?http请求方式?

    客户端连接到Web服务器->发送Http请求->服务器接受请求并返回HTTP响应->释放连接TCP连接->客户端浏览器解析HTML内容。

    GET方法提交参数长度有限制。表单中所能处理的长度一般为100k。POST请求会把请求的数据放置在HTTP请求包的包体中。

    1. GET方法: 请求指定的页面信息,返回实体主体。
    2. head方法:只获取请求报头,不获取实际内容。
    3. post方法: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
    4. put方法: 向指定资源位置上传其最新内容。
    5. DELETE: 请求服务器删除Request-URL所标识的资源。
    6. TRACE: 回显服务器收到的请求,主要用于测试或诊断。
    7. CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    代码题

    1. 跳台阶(斐波那契数列)
    2. 正则化匹配
  • 相关阅读:
    统计字符串中每个字母出现的次数
    三次握手和四次挥手
    select后面不能包含group by 后面没有的列
    常用adb命令
    replace和replaceAll的区别
    java统计一个字符串中某个字串出现的次数
    大厂如何解决分布式事务
    ADB 用法大全
    PBN飞越转弯Flyover衔接TF、CF航段保护区组图
    PBN旁切转弯保护区组图
  • 原文地址:https://www.cnblogs.com/wildkid1024/p/13498397.html
Copyright © 2011-2022 走看看