发表于: 2020-08-10 23:02:01

0 2390


今天完成的事情:

实现了任务三查看全部一级导航和二级导航的接口。

任务三深度思考。
明天计划的事情:

1.用c标签和el表达式把任务四静态页面变成动态页面。

2.尝试不用循环查询数据库的方式达到展示全部一级导航和二级导航的效果。
遇到的问题:
收获:

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

反向代理和负载均衡。

反向代理就是nagix充当tomcat,jetty,resin等等要具体运行项目的服务器的中介。

作用:

防止主服务器被恶意攻击

为负载均衡和动静分离提供实现支持

负载均衡:使用反向代理同时代理多个相同内容的应用服务器(比如tomcat),将客户端请求分发到各个应用服务器上并接收响应返回给客户端。

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

代码生成就是利用工具根据数据库表自动生成对应的实体类对象和mapper。

实现方法:在pom.xml里添加mbg插件,配置好资源文件的路径和所依赖的连接mysql的驱动,在资源文件,指定数据库连接用户名密码相关信息,指定要逆向生成哪张数据表,指定生成的pojo路径和对应的pojo名称,指定生成的mapper.xml文件和Mapper接口的路径,然后点击插件运行,即可生成代码,节省了很多的工作量。

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

连接数:

对于mysql服务器最大连接数值的设置范围比较理想的是:服务器响应的最大连接数值占服务器上限连接数值的比例值在10%以上,如果在10%以下,说明mysql服务器最大连接上限值设置过高.

Max_used_connections / max_connections * 100% = 3/512 *100% ≈ 0.0058%

我们可以看到占比远低于10%(因为这是本地监控测试服务器,结果值没有太大的参考意义,大家可以根据实际情况设置连接数的上限值)。

max_used_connections / max_connections * 100% (理想值≈ 85%) 

如果max_used_connections跟max_connections相同 那么就是max_connections设置过低或者超过服务器负载上限了,低于10%则设置过大。

MySQL的max_connections参数用来设置最大连接(用户)数。每个连接MySQL的用户均算作一个连接。


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

http 首次连接通过查看postman的dns解析时间需要400多毫秒,往后连接只需几毫秒,service首次访问Db也是一样,需要几百毫秒,后面只需几毫秒就可以完成一次访问。

根据查找的数据量或者查找的类型来判断sql语句的执行时间,如果是联表查询时间会稍慢一点,在数据量比较小的时候往往也看不出差别,1~2毫秒的差距。

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

  SQL注入就是一些攻击者把SQL命令插入到web表单的输入或者页面的url中,欺骗服务器执行恶意的SQL语句。在某些表单中,用户输入的内容直接用来构造或者影响动态SQL命令,或者作为存储过程的输入参数。这类表单特别容易收到SQL注入式的攻击。

   解决方法:

1)采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。

2)使用正则表达式过滤传入的参数.

3)字符串过滤


SQL注入攻击实例

比如在一个登录界面,要求输入用户名和密码:

可以这样输入实现免帐号登录:

用户名: ‘or 1 = 1 –

密 码:

点登陆,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了.(当然现在的有些语言的数据库API已经处理了这些问题)

这是为什么呢? 下面我们分析一下:

从理论上说,后台认证程序中会有如下的SQL语句:

String sql = "select * from user_table where username=

' "+userName+" ' and password=' "+password+" '";

当输入了上面的用户名和密码,上面的SQL语句变成:

SELECT * FROM user_table WHERE username=

'’or 1 = 1 -- and password='’

分析SQL语句:

条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;

然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。

这还是比较温柔的,如果是执行

SELECT * FROM user_table WHERE

username='' ;DROP DATABASE (DB Name) --' and password=''

….其后果可想而知…

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

不会节省时间,会减轻数据库的性能负担。

单表查询速度很快,对分布式系统的分库分表比较方便

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

连表查询优点:

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

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

缺点:

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

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

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

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

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


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

超过200ms会影响用户体验,通过配置nginx的conf.xml文件,使用aop进行日志记录,记录controller和service的执行时间。

主要耗费在网络延时,数据库连接这几块地方。  

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

自测是因为自己需要对写出来的程序运行情况的一个了解,哪个地方报错,哪个地方需要调优都要了解到。仅仅使用postman测试不够,因为不知道细节方面的耗时,比如连接db的时间,service的运行时间,controller的运行时都不能了解到。

本地测试就是在ide写完代码之后部署到本地tomcate等服务器进行测试。

开发环境(DEV):开发环境是程序猿们专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误报告。

测试环境(UAT):一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发布到生产机上。

生产环境(PROD):是指正式提供对外服务的,一般会关掉错误报告,打开错误日志。

需要,因为要持续集成,改完代码立即提交。 

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

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

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

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


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

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

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

有问题的测试屏蔽。

可以用命令行: mvn -PignoreTest install  跳过。

也可以配置maven-surefire-plugin这个插件, <maven.test.skip>true</maven.test.skip>把这个值设置为true。

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

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

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

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


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

前端动态页面的开发需要依赖于后端提供的数据,项目开发初期商定,前后端一起维护,不提供假数据,前端无法进一步开发,影响开发进度.

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

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

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

方案表数量查询子查询树插入删除引用完整性
邻接表1简单困难简单简单
枚举路径1简单简单简单简单
嵌套集1困难简单困难困难
闭包表2简单简单简单简单

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

为什么不建议通过添加主外键约束 ?

因为在数据库层面通过使用外键的方式进行“硬绑定”,会带来很多额外的资源消耗来进行一致性和完整性校验,即使很多时候我们并不需要这个校验。

所以一般不建议在数据库中使用外键约束来保证数据的一致性和完整性。


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

数据库的三大范式

(1)简单归纳:

  第一范式(1NF):字段不可分;

  第二范式(2NF):有主键,非主键字段依赖主键;

  第三范式(3NF):非主键字段不能相互依赖。

(2)解释:

  1NF:原子性。 字段不可再分,否则就不是关系数据库;;

  2NF:唯一性 。一个表只说明一个事物;

  3NF:每列都与主键有直接关系,不存在传递依赖。

二、例子说明

  (1)不符合第一字段的例子

                                                                             表:字段1, 字段2(字段2.1,字段2.2), 字段3

字段2可以拆分成字段2.1和字段2.2,不符合第一范式。

  (2)不符合第二范式的例子 

                                                                            表:学号, 姓名, 年龄, 课程名称, 成绩, 学分 

这个表明显说明了两个事务:学生信息, 课程信息。

  1)存在以下问题:

                               a、数据冗余:每条记录都含有相同信息; 

                               b、删除异常:删除所有学生成绩,就把课程信息全删除了; 

                               c、插入异常:学生未选课,无法记录进数据库; 

                               d、更新异常:调整课程学分,所有行都调整。

  2)修正:

                               学生表:学号, 姓名, 年龄 

                               课程表:课程名称,学分     

                               选课关系表:学号, 课程名称, 成绩

  (3)不符合第二范式的例子 

                                   表:学号, 姓名, 年龄, 所在学院, 学院联系电话

其中关键字为单一关键字"学号"。存在依赖传递::(学号) → (所在学院) → (学院联系电话) 。

  1)存在问题::

      a、数据冗余:有重复值; 

      b、更新异常:有重复的冗余信息,修改时需要同时修改多条记录,否则会出现数据不一致的情况 

      c、删除异常 

  2)修正: 

                      学生表:学号, 姓名, 年龄, 所在学院;

                      学院表:学院, 电话 

其实范式只是为了可以为你理清数据库的关系的,但是有些情况采用范式的代价要比不采用范式的代价大就可以不适用范式。比如增加了程序逻辑,多联接关系表,不常更新或不更新的基础表信息都可以不必须按照范式的规范来设计。



返回列表 返回列表
评论

    分享到