spring boot和spring cloud

1服务器断电致使虚拟机数据丢失的恢复方法

这道题比较偏运维,并非咱们开发的职能范围。对于3年之内的开发算是超纲的面试题了,这种题目的回答最好说本身没有权限操做服务器,或者说是组长负责,技术经理负责。强行回答会陷进面试官的坑里前端

有兴趣能够看这篇文章:https://www.jb51.net/article/133246.htmjava

2 springbootspringcloud实现原理

Springboot: mysql

我的对于springboot的理解是他对spring框架进行了模块化,将spring和目前使用比较多的技术框架集成配置打包,省了使用者在开发时本身去配置集成。大大简化了spring应用开发过程当中的搭建和开发。同时更好的解决了各个框架集成时依赖包的版本冲突以及引用的不稳定性。web

核心原理:面试

1> 基于SpringMVC无配置文件(纯Java)彻底注解化+内置tomcat-embed-core实现SpringBoot框架,Main函数启动。redis

2> SpringBoot核心快速整合第三方框架原理:Maven继承依赖关系。算法

核心思想:开箱即用和约定优于配置spring

 

Springcloud:sql

springcloud虽然带有‘cloud’,可是它并非云计算解决方案,而是在springboot基础上构建的,用于快速构建分布式系统的通用模式的工具集数据库

特色:

1.约定因为配置

2.适用于各类环境。开发、部署在PC Server或各类云环境都可

3.隐藏了组件的复杂性,并提供声明式、无xml的配置方式

4.开箱即用,快速启动。

5.轻量级的组件。Springcloud 整合的组件大多比较轻量。

6.组件丰富,功能齐全。springcloud为微服务架构提供了很是完整的支持。例如配置管理、服务发现、断路器、微服务

7.选型中立、丰富

8.灵活。springcloud的组成部分是解耦的,开发人员可按需灵活挑选技术选型

对比:

SpringBoot专一于快速方便的开发单个个体微服务。

SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、精选决策、分布式会话等集成服务。

SpringBoot能够离开SpringCloud独立开发项目,可是SpringCloud离不开SpringBoot,属于依赖关系。

SpringBoot专一于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

现实中不大的项目使用springcloud只会徒增开发成本,因此在项目前期通常都是使用springboot,更有效率,快捷。

3 项目的构建流程

项目构建流程

  项目立项

  技术选型和项目框架搭建

  需求分析

  开发阶段

    UI界面设计

    编码开发

后端开发(整理完需求便可开始接口开发)

   前端开发(依赖于UI界面设计和后端接口)

测试(完整的测试由测试==>修改==>回归测试组成)

功能测试

性能测试

上线

  

 

 

4 redis项目应用,在哪块,存哪些数据

redis的使用场景不少,回答是不但须要答出在哪里使用,最好要答出为何这么使用

1) 登陆,权限控制:session 数据的缓存

  1. 解决跨域,
  2. 多台服务器应用,实现session数据一致性

具体步骤:   

用户进行登陆时,提交的登陆表单,放入request

    服务器端校验用户名和密码;

    经过后将用户信息存储到Redis中,在数据库中的keysession_id

    服务器返回的response中的set-cookie字段包含该session_id,客户端收到后将其值存入浏览器中;

    客户端以后的操做的request中都包含session_id,服务器收到后提取出并在Redis中拿到该session,完成业务操做;

使用Redis来实现session的共享和存储,必需要保证session_id,不会被轻易获取和破解,并设置合理的失效时间,对敏感操做必须再次校验用户。

2) 首页列表等数据的缓存

这类数据量大,查询条件比较复杂,性能消耗比较大。重复屡次请求会致使数据库压力过大,下降查询效率,甚至宕机

3) 购物车/收藏等我的数据的缓存

这类数据的特色1是操做次数多,且更新快。redis能够快速的写入,移除和修改,很好的匹配这类数据的特性。

特色2是数据结构,其余缓存的数据结构单一,没有很好能符合这类数据的结构,redis的数据结构丰富,关键是它的hash数据类型很好的符合了这类数据结构的需求

 

好比,购物车场景,咱们首先须要两个HASH来存储,第一个HASH是用户与购物车之间的关系,第二个HASH是购物车中的商品列表。

先经过userId获取到shoppingCartId,而后再经过shoppingCartId就能够获取到用户购物车的ProductIds。而后再经过ProductIds就能够异步读取用户购物车的商品信息。

 

整体来讲redis适用于一些实时性要求不高可是请求次数较多的数据。

 

Redis的特色(必须了解):

  • 内存数据库,速度快,也支持数据的持久化,能够将内存中的数据保存在磁盘中,重启的时候能够再次加载进行使用。
  • Redis不只仅支持简单的key-value类型的数据,同时还提供listsetzsethash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • 支持事务

5 如何解决高并发请求

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它一般是指,经过设计保证系统可以同时并行处理不少请求。

高并发相关经常使用的一些指标:

响应时间:系统对请求作出响应的时间。例如系统处理一个HTTP请求须要200ms,这个200ms就是系统的响应时间。

吞吐量:单位时间内处理的请求数量。

QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。

并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通信系统,同时在线量必定程度上表明了系统的并发用户数。

互联网分布式架构设计,提升系统并发能力的方式,方法论上主要有两种:垂直扩展(Scale Up)与水平扩展(Scale Out)。

垂直扩展:提高单机处理能力。垂直扩展的方式又有两种:

1加强单机硬件性能,例如:增长CPU核数如32核,升级更好的网卡如万兆,升级更好的硬盘如SSD,扩充硬盘容量如2T,扩充系统内存如128G

2提高单机架构性能,例如:使用Cache来减小IO次数,使用异步来增长单服务吞吐量,使用无锁数据结构来减小响应时间;

无论是提高单机硬件性能,仍是提高单机架构性能,都有一个致命的不足:单机性能老是有极限的。因此互联网分布式架构设计高并发终极解决方案仍是水平扩展。

水平扩展:只要增长服务器数量,就能线性扩充系统性能。水平扩展对系统架构设计是有要求的,如何在架构各层进行可水平扩展的设计,以及互联网公司架构各层常见的水平扩展实践

咱们公司最先是一台服务器28Gb,当用户交互开始卡顿时升级到了416Gb,后面再次升级成了432GB。当用户量上来后,开始使用集群。

这里就是先作垂直扩展,后作水平扩展

项目初期为了快速迭代开发、推荐业务和成本看了,通常选用垂直扩展。当项目起来,用户量上来盈利了,会选用水平扩展来支撑日益复杂的需求

6 项目中那一块业务用到多线程了?

1 定时短信、站内信的发送,涉及上万用户,若单线程的话耗时会很长,多线程能大大缩短发送时间

2 定时操做列表记录(记录之间操做必须独立)

3 导入大批量数据

7 项目已经上线,出现bug怎么解决,若是宕机了怎么办

线上bug通常分为紧急和非紧急:

对于紧急的bug会当即组织测试和开发进行排查,如果代码问题实时修复,修复后测试没问题通知上线,上线后再测试和跟进

对于非紧急的bug会提交到bug管理工具(如禅道),统一时间进行排查和修复.修复测试没问题在指定时间进行上线

因为开发人员和测试人员有限,对于bug修复必须分状况和优先级进行修复,毕竟开发和测试有其余任务.

8 咱们应该部署多少台服务器,每台服务器承受的压力是多少

部署多少台服务器根据项目实际状况而定,通常用户在10万如下并不会使用到集群,项目功能简单也不会使用到分布式服务.

公司项目初期为了快速迭代开发通常一个应用便可,这时部署一台服务器便可.从成本和效率上来讲是最好的

项目中期的时候,随着功能复杂起来,会对功能模块进行拆分,这时部署会根据模块服务数和用户数来部署

目前咱们公司的服务器状况:

商家数8000+,日活商家数1200+,用户数90w+,日活2w+:

PC web2台服务器,H5 web3台服务器,后台管理1台服务器,核心服务(处理各类定时任务)部署了一台服务器,上传服务器2,短信服务器2,支付服务器2,图片服务器采用的是阿里云的OSS,数据库采用的是阿里云的RDS-mysql,缓存采用的是阿里云的redis

服务器承受的压力有不少因素:服务器的配置,应用的多少和性能都有关系,咱们公司的服务器配置是816G,这种配置服务器能承受并发能过2000以上

9 实际开发中一个项目开发到什么样才能上线

正常上线必须经过产品和测试,产品须要肯定需求中的功能是否已经实现,测试须要肯定现有功能是否已经没有功能性问题,只有经过他们的验收项目或者新需求才能上线.

11 RabbitMQ能承载多少的高并发

RabbitMQ能承载多少高并发于服务器性能有关,测试4核8G的服务器上RabbitMQ的并发能破1000

这种题目只要说听测试同窗说这个样子,毕竟不是全部人都会进行性能测试的.

12 数据库存储过程,项目中有用吗,处理什么业务

MySQL 5.0 版本开始支持存储过程。

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译建立并保存在数据库中,用户可经过指定存储过程的名字并给定参数(须要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

存储过程就是具备名字的一段代码,用来完成一个特定的功能。

建立的存储过程保存在数据库的数据字典中。

优势

存储过程可封装,并隐藏复杂的商业逻辑。

存储过程能够回传值,并能够接受参数。

存储过程没法使用 SELECT 指令来运行,由于它是子程序,与查看表,数据表或用户定义函数不一样。

存储过程能够用在数据检验,强制实行商业逻辑等。

缺点

存储过程,每每定制化于特定的数据库上,由于支持的编程语言不一样。当切换到其余厂商的数据库系统时,须要重写原有的存储过程。

存储过程的性能调校与撰写,受限于各类数据库系统。

存储过程总的来讲比较鸡肋:

1 受限于数据库和编程语言,致使各个公司使用时有顾虑,以后的迁移和转型成本会很大

2 编写要求不像普通sql方便,没有使用熟悉的编程语言开发效率高

目前我待过的几个项目中均没有使用到存储过程

13 MySQL的优化、百万千万级数据处理有什么方法

mysql优化:

目前用到过的

1 实际开发中禁止使用’select *’

2 当知道结果只有一行数据时使用 LIMIT 1,这样一来,MySQL数据库引擎会在找到一条数据后中止搜索,而不是继续日后查少下一条符合记录的数据。

3 为经常使用的搜索字段建索引

4永远为每张表设置一个ID作为其主键,并且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增长的AUTO_INCREMENT标志。

5 like’%‘在前面用不到索引,尽量将’%‘放在后面,进行有模糊查询

6 mysql 不支持函数转换,因此字段前面不能加函数,不然这将用不到索引

7 字段类型转换致使不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引致使全表扫描

8 当数据量大的时候须要分库分表

网上推荐的还有:

1 Join表的时候使用至关类型的例,并将其索引:当两个表中Join的字段是被建过索引时,MySQL内部会启动为你优化JoinSQL语句的机制

2 千万不要 ORDER BY RAND(),这样使用只会让你的数据库的性能呈指数级的降低

3 使用 ENUM 而不是 VARCHAR

4 or 的查询尽可能用 union 代替(Innodb

5 应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描

6 应尽可能避免在 where 子句中使用 != <> 操做符,不然将引擎放弃使用索引而进行全表扫描

7应尽可能避免在 where 子句中使用 or 来链接条件,若是一个字段有索引,一个字段没有索引,将致使引擎放弃使用索引而进行全表扫描

8 in not in 也要慎用,不然会致使全表扫描

 

固然要分析语句是否要优化必定得会使用Explain关键字,从 PROCEDURE ANALYSE() 取得建议

 

千、百万级数据处理方法:

当数据达到千百万级别是,查询的效率是个很大的问题,这时写完sql语句都应该使用explain来查看下语句的查询信息,运行下语句看看使用的时间

当效率很低的时候就必须进行优化了:

1 从语句的性能进行优化 -- 以上的优化手段均可以用

2 从表结构进行优化,常见的有

A)对表字段拆分,好比商品表,商品的名称,主图,规格等不变的字段放到基础信息表中,商品的实时信息放到附属表中;

B) 对大表进行按时间拆分表,好比用户表,对指定时间内(60天)没有登陆过的用户放到一张用户冻结表,其余的放在用户表,当冻结表中的用户从新登陆后再移至用户表中

3 从硬件上进行升级

前面两种是减小语句的扫描量(查询量),后面一种是提升扫描(查询)的性能和效率

14 Oracle出现索引失效怎么办

1. 选用适合的Oracle优化器

2、‍重建索引:‍alter index 索引名 rebuild online

3、强制索引:给该语句加上hint后,强制其使用指定索引

15 jvm参数调优

JVM 中最大堆大小有三方面限制:

a.相关操做系统的数据模型(32-bt仍是64-bit)限制;

b.系统的可用虚拟内存限制;

c.系统的可用物理内存限制。

32位系统下,通常限制在1.5G~2G64为操做系统对内存无限制。

常见配置汇总

堆设置

-Xms:初始堆大小

-Xmx:最大堆大小

-Xmn:年轻代大小

-Xss:每一个线程的虚拟机栈大小

-XX:NewSize=n:设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值。如:3,表示年轻代与年老代比值为13,年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示EdenSurvivor=32,一个Survivor区占整个年轻代的1/5

-XX:MaxPermSize=n:设置持久代大小

-XX:MaxTenuringThreshold=n:设置垃圾最大年龄。若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代

收集器设置

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器

-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一块儿进行垃圾回收。此值最好配置与处理器数目相等

-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集

-XX:+UseParalledlOldGC:设置并行年老代收集器

-XX:+UseConcMarkSweepGC:设置并发收集器

-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,若是没法知足此时间,JVM会自动调全年轻代大小,以知足此值。

-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。

-XX:+DisableExplicitGC,这个参数做用是禁止代码中显示调用GC

垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间

-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。

-XX:PrintHeapAtGC:打印GC先后的详细堆栈信息

-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析。

并发收集器设置

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU状况。

-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,因此无需再设置此值。

-XX:CMSFullGCsBeforeCompaction:因为并发收集器不对内存空间进行压缩、整理,因此运行一段时间之后会产生“碎片”,使得运行效率下降。此值设置运行多少次GC之后对内存空间进行压缩、整理。

-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,可是能够消除碎片

调优总结

年轻代大小选择

响应时间优先的应用:尽量设大,直到接近系统的最低响应时间限制(根据实际状况选择)。在此种状况下,年轻代收集发生的频率也是最小的。同时,减小到达年老代的对象。

吞吐量优先的应用:尽量的设置大,可能到达Gbit的程度。由于对响应时间没有要求,垃圾收集能够并行进行,通常适合8CPU以上的应用。

年老代大小选择

响应时间优先的应用:年老代使用并发收集器,因此其大小须要当心设置,通常要考虑并发会话率和会话持续时间等一些参数。若是堆设置小了,能够会形成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;若是堆大了,则须要较长的收集时间。最优化的方案,通常须要参考如下数据得到:

并发垃圾收集信息

持久代并发收集次数

传统GC信息

花在年轻代和年老代回收上的时间比例

减小年轻代和年老代花费的时间,通常会提升应用的效率

吞吐量优先的应用:通常吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。缘由是,这样能够尽量回收掉大部分短时间对象,减小中期的对象,而年老代尽存放长期存活对象。

较小堆引发的碎片问题

由于年老代的并发收集器使用标记、清除算法,因此不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样能够分配给较大的对象。可是,当堆空间较小时,运行一段时间之后,就会出现“碎片”,若是并发收集器找不到足够的空间,那么并发收集器将会中止,而后使用传统的标记、清除方式进行回收。若是出现“碎片”,可能须要进行以下配置:

-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。

-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的状况下,这里设置多少次Full GC后,对年老代进行压缩

经典案例:

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k

-Xmx3550m:设置JVM最大可用内存为3550M

-Xms3550m:设置JVM促使内存为3550m。此值能够设置与-Xmx相同,以免每次垃圾回收完成后JVM从新分配内存。

-Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代通常固定大小为64m,因此增大年轻代后,将会减少年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8

-Xss128k:设置每一个线程的虚拟机栈大小。JDK5.0之后每一个线程栈大小为1M,之前每一个线程栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减少这个值能生成更多的线程。可是操做系统对一个进程内的线程数仍是有限制的,不能无限生成,经验值在3000~5000左右。

java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为14,年轻代占整个堆栈的1/5

-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6

-XX:MaxPermSize=16m:设置持久代大小为16m

-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代。对于年老代比较多的应用,能够提升效率。若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活时间,增长在年轻代即被回收的概论。

16 自旋锁、分布式锁

何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。

其实,自旋锁与互斥锁比较相似,它们都是为了解决对某项资源的互斥使用。不管是互斥锁,仍是自旋锁,在任什么时候刻,最多只能有一个保持者,也就说,在任什么时候刻最多只能有一个执行单元得到锁。可是二者在调度机制上略有不一样。对于互斥锁,若是资源已经被占用,资源申请者只能进入睡眠状态。可是自旋锁不会引发调用者睡眠,若是自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是所以而得名。

自旋锁是一种比较低级的保护数据结构或代码片断的原始方式,这种锁可能存在两个问题:

死锁。试图递归地得到自旋锁必然会引发死锁:递归程序的持有实例在第二个实例循环,以试图得到相同自旋锁时,不会释放此自旋锁。在递归程序中使用自旋锁应遵照下列策略:递归程序决不能在持有自旋锁时调用它本身,也决不能在递归调用时试图得到相同的自旋锁。此外若是一个进程已经将资源锁定,那么,即便其它申请这个资源的进程不停地疯狂“自旋”,也没法得到资源,从而进入死循环。

过多占用cpu资源。若是不加限制,因为申请者一直在循环等待,所以自旋锁在锁定的时候,若是不成功,不会睡眠,会持续的尝试,cpu的时候自旋锁会让其它process动不了. 所以,通常自旋锁实现会有一个参数限定最多持续尝试次数. 超出后, 自旋锁放弃当前time slice. 等下一次机会。

 

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,经常须要协调他们的动做。若是不一样的系统或是同一个系统的不一样主机之间共享了一个或一组资源,那么访问这些资源的时候,每每须要互斥来防止彼此干扰来保证一致性,在这种状况下,便须要使用到分布式锁。

目前通常会使用redis来实现分布式锁,核心代码:

 

 

 

17 单点登陆原理

单点登陆(Single Sign On),简称为 SSO。是在多个应用系统中,用户只须要登陆一次就能够访问全部相互信任的应用系统。

有一个独立的认证中心,只有认证中心才能接受用户的用户名和密码等信息进行认证,其余系统不提供登陆入口,只接受认证中心的间接受权。间接受权经过令牌实现,当用户提供的用户名和密码经过认证中心认证后,认证中心会建立受权令牌,在接下来的跳转过程当中,受权令牌做为参数发送给各个子系统,子系统拿到令牌即获得了受权,而后建立局部会话

 

特色: 一处登陆,到处穿梭

 18 整个系统从前端到数据库再到前端,代码优化,结构优化,一般考虑哪些问题

1 请求的耗时

2 请求的个数

3 查询的个数

4 查询的耗时

5 代码运行的耗时

6 代码的性能

7 代码的耦合性

8 代码的可读性

总之:优化必定得从如下几个方面考虑

性能:如代码的耗时,请求响应速度,请求的个数,查询的个数,查询的耗时

可维护性:如代码的耦合性,可读性,可维护性

19 怎么防止接口暴露别人用工具恶意刷接口

常见的方式:

1 图形验证码,这经常使用于短信接口的防御

2 限定请求次数,常见于秒杀,抢购等功能中

3 流程条件限制,如知足必定条件,注册用户,获取权限等

4 ip地址限定,java中通常写拦截器对统一ip进行判断,同一ip指定时间内只能访问指定次数

5 服务器接口验证:常见于一些须要付费的接口,这类接口须要内部的token或秘钥才能请求

20 脏数据是怎么回事?

脏读就是指当一个事务正在访问数据,而且对数据进行了修改,而这种修改尚未提交到数据库中,这时,另一个事务也访问这个数据,而后使用了这个数据。由于这个数据是尚未提交的数据,那么另一个事务读到的这个数据是脏数据(Dirty Data),依据脏数据所作的操做多是不正确的。

扩展:不可重复读是指在一个事务内,屡次读同一数据。在这个事务尚未结束时,另一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,因为第二个事务的修改,那么第一个事务两次读到的数据多是不同的。这样就发生了在一个事务内两次读到的数据是不同的,所以称为是不可重复读

21 脏数据有哪些危害?

脏数据在涉及到历史数据,资金等重要数据几乎是致命的。

好比:在秒杀系统中,脏数据的产生可能会致使库存不足,商家就会亏损;在资金系统中,如有脏数据会致使整个系通通帐错误。

22 怎么在线上查看出现的bug

上线的项目查看bug通常是经过日志系统。因此项目中必须有详细日志记录,在更新数据先后,重要操做节点都应该有详细的日志记录。

23 项目中异常是如何处理

项目中异常的处理无非是两种方式:

1 try catch 抓取异常

2 throw 抛出异常

方式简单,可是注意的细节却很多:

1. 能经过预检查方式规避的RuntimeException不该该经过catch方式处理,如IndexOutofBoundsException(角标越位异常),NullPointException(空指针异常)

2. 异常不能用来作流程控制或条件控制:异常的效率远低于比较判断方式

3. try  catch时不能一股脑的吧代码全包含进去,这只会增长问题定位的难度,使得代码没法根据不一样的异常作出处理,同时也是不负责任的表现

4. 捕捉异常的目的是处理他,若不处理就应该将异常抛给他的调用者。在展现给用户以前必须处理掉

5. try catch中如有事务代码,在catch完后必定注意是否须要rollback事务

6. finally代码块中对资源对象、流对象进行关闭时如有异常也要作try catch处理

7. 捕获异常与抛出的异常类型要彻底匹配,或者捕获的异常是抛出异常的父类

8. finally代码块中不能有return:当有return时就不会执行try catch中的return

24 项目日志是如何处理的,怎么跟踪线上问题,日志存在哪里

目前线上的日志使用的是log4j,测试时会记录debug级别的信息,上线时记录info级别的信息。通常更新数据库数据先后须要打日志,敏感操做节点也须要打日志.这些日志都会写到日志文件中保存起来,通常的日志文件保存715.

跟踪线上问题:

1 先肯定问题是在哪一个页面或者哪一个功能中,而后查看功能对应的日志文件,看看是否有Error信息或者Exception信息

2 若没有异常信息说明极可能是代码逻辑的问题,查看功能日志点看看日志状况,通常是能定位问题点

3 若从日志中定位不出来只能是复盘功能代码

日志的存储:

单服务器上日志通常存在指定的目录下,可在日志配置中定义

分布式/集群:能够存在各类服务器上,也可使用日志服务器统一管理日志文件

25 和测试如何交互的

测试的职责是找出项目应用中存在的问题,及时提交给开发修复.在上线前将问题尽量的找出处理掉.如今不少开发以为测试和他们是对立面,常常和测试针锋相对,推脱问题.其实测试和开发都是为了将项目功能尽量的完善,交付给用户使用,这是他们的共同目的.

和测试的交互应该注重客观事实,根据测试提交的问题排查是什么缘由形成的,而后有问题的解决掉,没问题的反馈给测试从新测试.重点是和测试多沟通,了解彼此的想法,不能形成误解,影响工做.

至少我如今公司开发和测试很和谐,天天测试工做时遇到须要紧急需立刻解决的问题会立刻和开发沟通,是否真正有问题由开发排查后反馈解决.非紧急的问题会提交到禅道上,由开发本身去看和解决本身的问题.测试天天定点看禅道的bug解决率,并提醒开发前去解决bug

27 BUG处理的过程是怎么样

问题的反馈: 测试测试出来或者用户反馈过来

问题的肯定开发拿到问题后如今测试服中重现问题,没法重现的经过查看日志,复盘代码来定位问题

问题的解决通常小问题会在主干上修复并测试上线,大问题会开分支专门修复问题测试没问题后合并再测试上线

通知问题解决上线后通知相关的部门和人员修复结果(作到事事有结果)

26 项目如何部署

java项目部署目前通常部署在tomcat上,springboot出现后直接将项目打成jar包进运行。

部署前须要对环境进行确认:确认项目应用所需的环境是否正确,如系统环境,java版本,数据库版本,系统的硬件配置

对项目的配置文件进行确认:有些项目的配置文件在测试时须要修改,这时上线的时候须要改回去,若是没有check,可能会使用测试配置上线,这样就好致使上线出现问题

对数据库表字段进行确认:防止由于新增的表或字段未添加或名称有出入致使上线后报错

对上线时间的确认和通知

上线时对之前线上的代码进行备份:确保上线失败时能够回退

上线后:必须对所上线的功能进行再次测试,防止有问题

28 大家商城开发中都遇到过什bug

1 未作分布式锁时常常会出现并发和重复请求的数据:添加分布式锁

2 秒杀抢购被用户摸到接口,使用工具重复提交抢购:使用拦截器对同一ip同一接口进行请求间隔限制

3 一个用户多地登陆致使数据异常:限制用户只能一地登陆

4 数据库被清空:好在数据库数据每小时都有作备份,吧备份数据导回线上数据库,但仍是损失了备份点以后的数据

5 系统达到瓶颈:升级硬件配置,使用集群

29 订单大家是怎么作的实现思路是什么

目前我碰到的有两种实现方式:

1 用户购买一件商品就生成一条订单记录,商品的库存减一

2 在商品发布时生成库存量个token,每次用户购买商品就获取一个token,同时生成一条订单记录,token使用完后失效

第一种须要注意重复提交和并发问题

第二种适用于商品库存量不大的应用

30 支付大家怎么作的,如何和支付宝和微信对接的,怎么保证安全

微信和支付宝支付接口的对接都有相应的流程,他们都提供了详细的对接demo.这两种支付方式以及快钱支付方式的对接都基本一致.

原理:

用户发起支付请求,应用服务端将支付的金额,支付的缘由以及应用生成的惟一商户订单号使用支付接口方提供的加签方式进行加签后,生产预支付记录,同事调用支付接口进行支付.支付提交后有两种获取回执相应的方式:同步和异步.同步是用户点击支付完成,由服务端像支付接口方服务器发起查询,对查询结果进行校验操做.异步是支付接口方接受到支付打款后向咱们应用指定接口发生支付成功的请求,咱们对请求进行解析校验操做.不管异步仍是同步都会返回咱们生成的惟一商户订单号做为回执.操做成功后,根据商户订单进行更新记录

 

安全性这几种支付方式在提交支付是都会有加签步,当对应支付完成会有他们服务器回调咱们接口.这时咱们对他们的请求参数用指定的密钥和解签方式进行解签,对解签结果进行校验.

31 假设有用户在手机端和PC端同时对购物车里的商品进行下单处理怎么办

 对购物车里的商品加锁,只有拿到锁的一方才能进行下单处理,另外一方没法下单操做.

32 怎么保证用户登陆以后,保证用户的数据一个安全性,保证用户的数据不会被第三方拦截

如今咱们处理的方法:

1加密,通常是对称加密的方法.

2 信息使用特殊字符替换,如手机号:在服务端将手机号中间几位使用*替换掉

相关文章
相关标签/搜索