面试题~`

Python基础



### 1、请写出session,cookie和token的区别

```
session存储在服务端,cookie存储在客户端,安全性差。session依赖cookie实现,客户端向服务端发起请求,
在服务端生成一个session_id对应生成一个文件,把session_id返回给客户端,下次请求cookie中携带session_id,
在服务器中查找,如果找到已经登录,没找到返回没权限访问。session不依赖cookie的时候存在表中或者redis中需要,
效率低,不合适单点登录。token是服务端生成客户端存储,减少了服务器的压力,客户端发起请求生成token返回给客户端,
下次客户端请求带着token,服务端解析token用同样的方式加密生成新的签名对比,客户端自认证。主要是优势是解决单点
登录的问题和减少服务器压力,比cookie安全性高。安全性可以采用https加密,定时刷新token实现。
```

### 2、写一个实现鉴权功能装饰器

```
装饰器的作为是在原有功能不变的基础上添加新的功能,主要的应用场景有用户鉴权、日志管理、计算函数执行时间等。以用户鉴权为例,我们所有的接口都需要先获取权限才能访问,如果在每个接口里面判断代码量重复,不便于后期维护。用装饰器的方式实现,在每个需要验证的接口上装饰。django中也可以用中间件实现,flask中要用色钩子函数。
​
def islogin(func):
    def wrapper(*args,**kargs):
        try:
             token = request.headers['Token']
             #验证token,解析再加密对比
             if token != '123':
                 return jsonify({"code":403})
        except print(0):
             return jsonify({"code":403})
       
        return func(*args,**kargs)
    return wrapper
```

### 3、SQL语句优化,索引以及自己的见解?你使用最多的数据库个人体验?

```
主要从以下几方面回答
1.sql语句方面
对于频繁查找的字段加上索引
不要在sql上运算
2.索引优化
3.分表分库
4.缓存及es
```

### 4、请编写一段Python代码处理以下的文字段落,使得其中的日期都变成XXX年xx月xx日的形式,并将全称的医院名字变成"某某A医院"和"某某B医院"(区分不同医院)的形式.需要处理的文字段落

```
2021年10月9日,在浙江省第二十一医院内,CT影像设备出现了重要故障,造成2021年10月9日至11月21日之间无法正常开展放射检查,所有就诊患者只能安排到浙江省第二十二医院接受检查,然后携带检查结果返回二十一医院进行就诊
​
import re
​
html_tag = re.compile("(.*?)年(.*?)月(.*?)日")
​
src = "文字"
​
tgt = re.sub(html_tag, r"xxxx年xx月xx日", src)
```

### 5、JS中var a=1,let a=1有什么区别

```
- var 声明的是全局的
​
- let声明的是局部的
```

### 6、举例说明python中函数设置默认参数的常见问题

```
- 形参顺序问题
- 参数类型问题(尽量使用函数)  例如:def test(a:int) -> string:
- 当有不确定参数个数的时候,需要传递不定长参数
```

### 7、python中的is和=的区别是什么?

```
- is 比较的是内存地址 a is None
- = 是赋值操作
```

### 8、如何使用Python的一个框架(Flask,Django或其他)实现分布式,异步性处理HTTP请求?

```
django3.0、flask2.0都支持异步
最常用的框架是celery,Celery是一个简单,灵活,可靠的分布式系统,用于处理大量消息,它是一个任务队列,专注于实时处理,同时还支持任务调度.一个单进程的celery每分钟可处理上百万个任务
应用场景就是异步通知、邮件、发短信等,批量执行任务,比如批量更新状态,定时任务调度等。
​
Task
就是任务,有异步任务和定时任务
​
Beat
定时任务调度器,根据配置定时将任务发送给Broker。
​
Broker
中间人,接收生产者发来的消息即Task,将任务存入队列。任务的消费者是Worker。
​
Worker
执行任务的单元,它实时监控消息队列,如果有任务就获取任务并执行它。
​
Backend
用于存储任务的执行结果。
​
Celery本身不提供队列服务,推荐用Redis或RabbitMQ实现队列服务。
```

##### 9、设计需求:有一个5000万名学生健康情况的调查问卷form表单(约50个字段)应用,从后端设计的角度考虑,需要既方便展示form的内容`又能快速统计form的字段进行分析?如何设计后端数据库和主要业务逻辑?

<img src="media/微信图片_20220301153041.png" alt="image-20210926145538889" style="zoom:50%;" />

```
首先50个字段同时展示的机率比较小,可以把采用垂直分表,把经常使用的高频展示的放到一个表中,把不经常展示的放到另外一个表中,其次是数据量大的问题,建立500万分一张表,分表会有唯一id生成的问题,如果可以预估用户量用hash取模的方式生成id,也可以采用雪花算法生成,雪花算法64位中其中有10位可以表示机房和机器编号

```

### 10、写出JavaScript中并发请求http接口示例代码

```
this.axios.get('http://localhost:8000/uptoken/').then((result) =>{
​
 console.log(result);
​
 this.uptoken = result.data.uptoken;
​
 });
```

### 11、简述你对Vue.JS前后端开发经验见解或者可分享的案例?

```
1.解偶,提高开发效率,让专业的人做专业的事
2.vue采用MVVM(Model-View-ViewModel)的软件架构设计模式,与视图层进行双向数据绑定,与Model层通过接口请求进行数据交互
3.vue组件化的开发理念,可以按需安装
4.提供了element ui ,vant等框架,方便后台管理系统开发
我在开发中经常用,element ui,vant都非常熟悉,可以自主开发后台管理系统
```

### 12、 Elasticsearch 做全文搜索有什么优势?你咋开发中遇到过什么困难?

```
 ElasticSearch解决了mysql like(模糊查询)性能效率差的问题,底层基于倒排索引实现, 在搜索引擎中每个文件都对应一个文件ID,文件内容被表示为一系列关键词的集合)。例如“文档1”经过分词,提取了20个关键词,每个关键词都会记录它在文档中的出现次数和出现位置。所以es的性能高
 
mysql es如何同步数据?
​
Mysql数据同步到ES中分为两种,分别是全量同步和增量同步。全量同步表示第一次建立好ES索引之后,将Mysql中所有数据一次性导入到ES中。增量同步表示Mysql中产生新的数据,这些新的数据包括三种情况,就是新插入Mysql中的数据,更新老的数据,删除的数据,这些数据的变动与新增都要同步到ES中。
基于Mysql的binlog日志订阅:binlog日志是Mysql用来记录数据实时的变化
ES官方数据收集和同步组件logstash
​
遇到的问题?
我在开发中遇到了mysql和es数据同步问题,就是当mysql中的数据发生改变的时候,es中的数据还没发生改变,导致脏数据的产生
查看elasticsearch日志和logstash日志发现有错误,es在发现磁盘空间大于95%以后,将变成只读状态,此时将不会更新数据,只能查询和删除。修改索引中"read_only_allow_delete"为"false"
​
解决方案
​
清除不使用的索引,释放磁盘空间
如果长期未清除日志文件,清除logs文件夹中的.gz日志文件
检查当前系统中的大文件,释放因其他服务异常导致的磁盘使用异常(如MongoDB)
增加磁盘容量
当磁盘空间大于95%后,es日志不再显示警告,此时还是无法更新索引,需要关闭只读状态操作
```

13、设计限制登录接口(一天5次)

```
import redis
​
r = redis.Redis()
​
key = black
​
num = r.get(key)
​
if int(num):
​
 if num > 5:
​
  return 403
​
 elif 0 < num <=5:
​
  r.incrby(key,1)
 else:
​
  r.setex(key,86400,1)
```

redis

### 1.redis常用的数据类型

```
1. String常用命令: set,get,incr 等。
String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用; 应用场景 常规计数:微博数,粉丝数等。

2.Hash常用命令: hget,hset,hgetall 等。
Hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以Hash数据结构来存储用户信息,商品信息。应用场景购物车key=JavaUser293847value={  “id”: 1,  “name”: “SnailClimb”,  “age”: 22,  “location”: “Wuhan, Hubei”}

3.List常用命令: lpush,rpush,lpop,rpop,lrange等
list就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,消息列表等功能都可以用Redis的 list 结构来实现。Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。另外可以通过 lrange 命令,就是从某个元素开始读取多少个元素,可以基于 list 实现分页查询,这个很棒的一个功能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。

4.Set常用命令: sadd,spop,smembersset 
对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。

5.Sorted Set常用命令: zadd,zrange,zrem,zcard等和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。
```

### 2.redis集群

```
Redis哨兵(Sentinel)模式通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
```

### 3.redis持久化存储

```
快照(snapshotting)持久化(RDB)Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性能),还可以将快照留在原地以便重启服务器的时候使用。AOF持久化与快照持久化相比,AOF持久化 的实时性更好,默认情况下Redis没有开启AOF(append only file)方式的持久化,开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。三种方式appendfsync always     #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度appendfsync everysec  #每秒钟同步一次,显示地将多个写命令同步到硬盘appendfsync no      #让操作系统决定何时进行同步建议采用第二种,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会放慢自己的速度以便适应硬盘的最大写入速度。
```

### 4.redis缓存雪崩

```
缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决办法:
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存
```

### 5.redis击穿

```
一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决办法: 有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。别外一种是,如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
```

### 6.MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?

```
edis 提供 6种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的).
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。不建议使用!
```

### 7.redis过期处理

```
定期删除+惰性删除
定期删除:redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载!惰性删除 :定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,查询的时候删除
```

### 8.redis事务处理

```
Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也具有持久性(Durability)。
```

### 9.如何解决 Redis 的并发竞争 Key 问题

```
所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺序不同,这样也就导致了结果的不同!分布式锁setnx。(如果不存在 Redis 的并发竞争 Key 问题,不要使用分布式锁,这样会影响性能)使用setnx命令方式,同时在redis上创建相同的一个key,为rediskey不能重复,只要创建成功就获取到锁,没创建成功就等待,为了防止死锁现象要加有效期。SET KEY VALUE  EX  PXEX到期时间(以秒为单位)PX到期时间(以毫秒为单位)
```

### 10.如何保证缓存与数据库双写时的数据一致性?

```
读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。更新的时候,先更新数据库,然后再删除缓存。为什么是删除缓存,而不是更新缓存?原因很简单,很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。
```

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值