发表于: 2020-06-21 23:18:33

1 1740


今天完成的事情:任务三深度思考,安排小课堂内容
明天计划的事情:任务四+小课堂
遇到的问题:项目启动的第一次连接,耗时是最久,之后的的增删改查就耗时很少,我想的是第一次查询后,数据库的数据等相关内容会缓存在session中,不知道自己考虑的对不对。
收获:

1.nginx服务器有什么作用?什么叫反向代理?为什么要使用反向代理?  

Nginx是一个高性能的HTTP和反向代理web服务器,同时也是电子邮件代理服务器,具有速度快,高性能,高可靠性,低内存消耗等特点,

Nginx提供

反向代理:是指用代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络中的上游服务器,并将从上游服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外的表现就是一个Web 服务器。充当反向代理服务器也是Nginx的一种常见用法(反向代理服务器必须能够处理大量并发请求)。

正向代理:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。

  • 正向代理是客户端知道目的服务器在哪里,然后通过代理服务器去访问客户端不能直接访问的目标服务器,而目标服务器并不知道客户端通过什么来访问的, 即 正向代理代理的是客户端
  • 反向代理中,外部网络对于内部网络具体的情况是不可见的,而代理服务器来代理内部网络来返回所要的数据(当然静态文件可以放在Nginx,这个静动分离再说),而服务端知道请求的来源以及数据 反向代理代理的是服务端
  • 反向代理好处:
(1)保护了真实的web服务器,web服务器对外不可见,外网只能看到反向代理服务器,而反向代理服务器上并没有真实数据,因此,保证了web服务器的资源安全。
  • (2)反向代理为基础产生了动静资源分离以及负载均衡的方式,减轻web服务器的负担,加速了对网站访问速度(动静资源分离和负载均衡会以后说)
  • (3)节约了有限的IP地址资源,企业内所有的网站共享一个在internet中注册的IP地址,这些服务器分配私有地址,采用虚拟主机的方式对外提供服务;

2.什么是代码生成,mybatis generator代码生成是怎么实现的,还有什么办法可以生成代码?  

MyBatis代码生成器——MyBatis Generator,MyBatis Generator 是 MyBatis 提供的一个代码生成工具。可以帮我们生成 表对应的持久化对象(po)、操作数据库的接口(dao)、CRUD sql的xml(mapper)。

1.做好你需要的数据库和表

2.添加插件

mybatis.jar

mybatis-generator-core.jar

mysql-connector-java.jar

mybatis-generator-maven-plugin

3.编写配置文件generatorConfig.xml

其他方法:还有能生成service等,单独生成Mapper的。

由于任务三自己想熟悉流程,都是手写的Mapper,实体类这些,后面可以用下这个。

3.Mysql的一般而言应该配置多大的内存, 多大的硬盘 ,多大的连接数?

首先Mysql的连接数不是越大越好,首先计算机一核cpu每次只能执行一个线程,然后操作系统切换上下文,CPU 核心快速调度,执行另一个线程的代码,不停反复,给我们造成了所有进程同时运行假象。太多的连接数,会导致在系统切换上下文上耗时太多。

一般设置连接数的大小为:连接数 = ((核心数 * 2) + 有效磁盘数) 如果说你的服务器 CPU 是 8核 i9 的,连接池大小应该为 ((8*2)+1)=17。

如果系统混合了长事务和短事务,那么就建两个连接池,一个服务于长事务,一个服务于"实时"查询,也就是短事务。

影响数据库性能的,大致可归为三类:CPU   磁盘IO   网络IO

磁盘IO就是寻址耗时和旋转耗时。网络IO就是带宽的影响,10G带宽会比1G带宽的阻塞耗时少一些。

4.在端到端的请求当中,建立Http连接需要多久,Model通过JSP转成Json需要多久,Nginx调用Resin需要多久,Service访问DB需要多久,一个Sql语句执行的时间是多久。

通过昨天的日志发现,在建立连接前会进行DNS解析,我这块的第一次连接花费时间在几百毫秒,但是之后的访问基本都是很快,就几毫秒,Model转成Json也是几毫秒,Nginx到上游服务器连接就27毫秒,第一次Service访问DB花了400多毫秒,第二次之后就是30毫秒多,sql执行就3-5毫秒。

5.什么是Sql注入,应该怎么解决?对于未做SQL注入防范的程序,你可以直接通过调用接口删掉表吗?  

SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。在前面任务的日报自己也有尝试过。

如何防止sql注入

(1) 采用PreparedStatement来避免sql注入,会自动对用户填写的数据进行验证,sql注入只对sql语句的准备(编译)过程有破坏作用 ,而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理, 而不再对sql语句进行解析,准备,因此也就避免了sql注入问题. 

(2) 使用正则表达式过滤传入的参数(典型的SQL 注入攻击的正则表达式 )

(3) 字符串过滤,敏感词过滤

6.在内存里拼装数据会节省时间吗?如果不能,为什么要选择单表查询,而不是直接拼装成Sql语句。 

内存里拼装数据不会节省时间, 拼装数据可以节省数据库性能,降低了高并发时资源消耗和业务之间的耦合。

单表查询速度更快,同时也利于分布式架构中的分库分表

7.为什么一般而言,不允许使用连表查询,不允许使用复杂的Group By等语句,为什么不允许使用存储过程?

连表查询优点:

1)开发效率高,仅仅需要一个 sql 语句就能完成查询工作,把部分的业务逻辑放到了 sql 中

2)查询效率高,只需要一次数据库连接,连接效率高

缺点:

1)缓存效率低,单据查询缓存可用性高,联合查询效率相比较低

2)由于联合查询速度比单个查询耗时多,因此在查询中会增加其他数据库连接(客户端)的锁竞争关系

复杂的 Group by 语句会影响查询速度,接口耗时比较严重的话,影响用户体验,同时还会影响服务器的性能

存储过程:是一组为了完成特定功能的sql语句集

在mysql中,存储过程不是一次编译的,而是对每个会话在执行的时候编译一次,在会话结束的时候抛弃,而且在执行alter procedure的时候是会将所有会话对这个存储过程持有的存储过程的版本抛弃掉。所以mysql的存储过程不推荐

8.为什么响应时间一般不允许超过200MS,怎么查看一个请求从发起到结束,耗费在什么地方了? 

超过200ms会影响用户体验 ,首先一个请求开始到结束的耗时会在前端响应,网络延迟,服务器响应,三个地方,怎么查看,可以用postman参考,加上如果用Nginx的话,可以配置conf中日志,然后在服务器可以看服务器的日志,自己在程序内可以在service和Cotroller用AOP写入日志的方式,查看执行耗时。

9.为什么要自测,仅仅使用Postman来测试足够吗?什么是本地测试,什么是在开发环境测试?在开发过程中,应该每天部署代码到开发环境吗,为什么?

仅仅用PostMan测试肯定不够,因为你不知道细节的地方耗时,比如不能知道当前调用的service方法耗时,DB查询,写入,连接耗时。自测是让自己掌握程序运行的大致情况,该在哪个地方调优的调优,哪个地方出错也能即时捕捉到。

开发环境:开发环境是专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误报告。
测试环境:一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发布到生产机上。
生产环境:是值正式提供对外服务的,一般会关掉错误报告,打开错误日志。

三个环境也可以说是系统开发的三个阶段:开发->测试->上线,其中生产环境也就是通常说的真实环境

https://www.jianshu.com/p/872e3cc26f40

10.保存图片有几种方式?什么样的情景下应该使用哪一种?  

保存在数据库或者保存在硬盘

如果图片比较小,可以选择二进制直接存储在数据库中

如果过大就要保存在硬盘中,数据库对应的字段是链接或者服务器相对路径

11.为什么要先写单元测试?单元测试应该包括哪些?在正式打包的过程中,什么样的单元测试应该被屏蔽?在Maven里用什么方法可以跳过单元测试,单元测试应该被跳过吗。  

单元测试可以先检测数据调出的是否正确。然后开发其他业务。

编写方式:  a.先单元测试,再接口,实现类   b.先接口,实现类,再单元测试

有问题的测试屏蔽。跳过测试,可以让程序启动的要快,用maven的命令可以跳过测试。

12.为什么提供假数据的时候要求,直接Controller接收请求,在JSP中写死数据返回以用做假数据?为什么提供假数据的时候要求数据完整,有分页尽可能给分页,数据尽可能真实?

(1) 先保证访问路径正确,跳转页面也ok,然后在讨论传参数的问题

(2) 在提供假数据的时候,此时数据不和数据库交互,所以在JSP中写死,但是也可以不用jsp的,其他视图也可以,或者直接使用json,

(3)为了前端更好的展示,去模拟真实的场景

13.为什么要写假数据,前后端联调的时候,应该什么时候商定接口文档,接口文档应该谁来维护,如果不提供假数据,会发生什么问题? 

前端动态页面的开发需要依赖于后端提供的数据,项目开发初期商定,前后端一起维护,不提供假数据,前端无法进一步开发,影响开发进度,不过客户端也可以使用 easymock 之类的工具模拟假数据。

14.接口应该怎么定义?一个页面应该只对应一个接口吗?还是一个实体对应一个接口,让前端去组装数据?两者的使用场景是什么?  

接口定义应该根据接口文档要求,进行设计。一个页面可以有多个接口,最好一个实体类一个接口,数据量不大的,业务简单的时候考虑,如果是业务复杂,数据量较大的话,最好定义多个接口,简单数据量较少的话,一个接口,数据丢给前台自己组吧。

15.多层分类应该怎么设计表结构,分别有什么问题?像文章分类这种需求,如果分类不确定,级别不确定,有可能动态调整,数据量和访问量又比较大,该怎么去设计? 

这个就是考虑数据库结构的设计。

常用的邻接表的设计方式不能适应分级不确定的情况,分类就是一种树模型,有几种方案是可以考虑下的:路径枚举、嵌套集以及闭包表。这些解决方案通常看上去比邻接表复杂很多,但它们的确使得某些使用邻接表比较复杂或很低效的操作变得更简单。如果你的项目确实需要提供这些操作,那么这些设计会是邻接表更好的选择。

https://www.cnblogs.com/xiaoxiaoqingyi/p/6954349.html

16.什么是实体表,什么是关系表,一对多和多对多应该怎么设计表?

实体表:就是实际对象对应的表,像学生表,老师表。

关系表:当多对多的情况下,一个老师有很多学生,一个学生有很多学科的老师,就建立学生表,老师表,以及学生老师关系表。

首先这种一对一,一对多,多对多说的是数据库中数据的对应关系,而不是表和表。

一对一:一个学生就一个身份证,一张身份证也只对应唯一的一个人

一对多:一个学生属于一个班级,但是一个班级有很多学生

多对多:学生和学科老师对应关系

2. 利用上面对应关系事例的数据库设计和实体类设计:

一对一:就在学生类中添加身份证字段就行;

一对多:设计学生表和班级表,学生表中添加班级id;

多对多:设计学生表,老师表,老师_学生关系表。老师_关系表中设置学生id,老师id对应关系;

一对一在实体类中多加一个属性,一对多在实体类中多加一个集合属性,多对多就是在两个实体类中各加一个集合属性;

17.什么是外键,用处是什么,为什么不建议使用外键做关联?  

如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字

为什么不建议通过添加主外键约束 ?
因为在数据库层面通过使用外键的方式进行“硬绑定”,会带来很多额外的资源消耗来进行一致性和完整性校验,即使很多时候我们并不需要这个校验。
所以一般不建议在数据库中使用外键约束来保证数据的一致性和完整性。

18.什么是数据库范式,是否应该严格遵守范式,什么情况下应该不遵守范式?  

第一范式(1NF)每一列都是不可分割的原子数据项

第二范式(2NF)在 1NF 的基础上,非码属性必须完全依赖于码(1NF基础上消除非主属性对主码的部分函数依赖)

    1)函数依赖:A->B 如果通过 A 属性(属性组)的值,可以确定唯一 B 属性的值,则称 B 依赖于 A

    例如:学号 -> 姓名 (学号、课程名称)-> 分数

    2)完全函数依赖:A -> B,如果 A 是一个属性组,则 B 属性值的确定需要依赖于 A 属性组中所有的属性值

    例如:(学号、课程名称)-> 姓名

    3)部分依赖:A -> B,如果 A 是一个属性组,则 B 属性值的确定只需要依赖 A 属性组中某一些值即可

    例如:(学号、课程名称)-> 姓名

    4)传递函数依赖 A -> B,B -> C,如果通过 A 属性(属性组)的值,可以确定唯一 B 属性的值,在通过 B 属性(属性组)的值可以确定唯一 C 属性 值,则称 C 传递依赖 A

    5)码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码

    例如:该表中码为:(学号、课程名称)

    主属性:码属性组中的所有属性

    非主属性:除过吗属性组的属性

第三范式(3NF):在 2NF 基础上,任何非主属性不依赖于其他非主属性(2NF 基础上消除传递依赖)


返回列表 返回列表
评论

    分享到