项目的总结
第一天:
学习电商行业的背景,电商模式:B2B、B2C、B2B2C、O2O。
分布式,集群的理解,系统的架构,基于SSO的架构。
使用Maven搭建后台工程,及SVN的使用。
第二天:
dubbo的学习和使用,系统和系统之间通信的中间件。
webservice :系统之间通信。应用于外部系统
,并且数据交换不是特别大的情况下(传统行业OA与ERP之间的通信)。
http+json:系统之间通信。属于http的协议
,RestFul风格
传递数据(手机客户端和后台进行通信,SSO系统给手机发布接口调用,传递JSON)。
dubbo:系统之间的通信。属于RPC的协议
(底层二进制协议),使用socket通信
,传输效率高,一般用于内部系统
之间。作为SOA架构的管理工具,能统计各个服务调用的次数。
SSM的整合,逆向工程,商品列表展示,分页插件的使用,Easyui
的使用(datagrid
的使用查询商品列表)。
学习dubbo的架构及4个角色,如何在spring使用。dubbo的使用贯穿于整合项目,有服务层和表现层的交互就需要使用dubbo。
第三天:
商品类目的选择,使用EasyUI
的tree控件
。传统图片上传功能,上传到某一个tomcat,在集群环境下,上传之后,有可能由另一台服务器提供服务,图片不存在,所以需要单独建立图片服务器FastDFS
(tracker、storage)。
在集群环境下使用FastDFS来存储图片(会使用FASTDFS客户端上传下载图片即可)。还有富文本编辑器KindEditor
的使用(纯js实现的)。
富文本编辑器:引入JS、定义好数据源(textarea
)、表单提交之前、同步数据、将富文本编辑器中的内容同步到textarea中。
第四天:
商城首页系统(portal)的搭建 ,使用伪静态URL拦截形式:*.html
。(SEO:搜索引擎优化)
首页的数据应当动态展示
,需要有一个CMS系统
来动态维护(CMS:内容管理系统),就是内容和内容分类管理。轮播图的动态展示。
首页访问压力很大,需要做缓存redis
。
第五天:
在首页中的访问压力特别大,需要解决高并发
的问题,使用缓存技术
,学习了redis技术,并使用redis的java客户端Jedis
在内容获取时的服务层中添加缓存及缓存同步。
redis:就是一种以KEY-VALUE
形式存储数据在内存中
的技术(主要用于缓存)。
set
get
expire
incr
keys *
redis五种存储数据类型:string hash list set sortedset
sortedset 用于做排行榜,有序,并且不重复。
redis的持久化方案:RDB、AOF。
RDB:快照。
AOF:(append only file) redis中的每一个操作都记录起来。一旦重启,就可以将原来数据恢复。
需要手动开启AOF持久化方案,默认是开启RDB。
redis服务器的搭建及集群搭建(奇数结点)因为:redis集群中有投票机制
,半数以上投票。
注意:添加缓存的逻辑不能影响正常的业务逻辑。应用最多的数据类型是string
和hash
。
第六、七天:
lucene是一个全文检索的工具包,提供很多的检索使用的API。
在首页中如果找不到对应的商品,就需要搜索商品,实现搜索的技术是lucene/solr
。
学习了lucene相关的介绍,应用场景,以及实现全文检索的流程。
索引流程及搜索流程。
学习入门程序:索引流程的代码实现。luke的使用。
学习入门程序:搜索流程的代码实现。
索引域及文档的域,以及Field域的说明(是否分词、是否索引、是否存储)
索引的维护:
搜索的两种类型(使用query子类及queryParser)及lucene搜索相关的语法。
最简单的语法:field:value
从field查询包含value的值的数据。
分词的过程:
分词(英文单词,按空格分词) --> 过滤(标点符号去掉) --> 大写转小写 --> 去掉停用词。
中文分词器的IKAnalyzer的使用:
1、jar包添加到工程build path
2、配置文件(xx.cfg.xml、扩展词典、停用词词典)放入classes下
3、定义业务域
特点:可以扩展、可以维护、支持中文分词。
第八天:
solr 是(基于lucene)搜索引擎,可以独立部署,来实现搜索功能,高亮显示,性能优化,可以解决高并发的搜索需求。
lucene和solr的区别:
1、lucene是工具包,solr是服务器(打比方:lucene是汽车引擎,solr是汽车)
2、lucene的业务域不需要先定义后使用,solr必须是先定义后使用。
3、lucene加入应用系统的时候,耦合度很高不易扩展。
4、solr是服务器,只需要通过http请求操作索引。维护、升级方便,并且能做性能优化。
使用solrj
作为java的客户端操作索引和搜索。
京东案例的实现。使用IK分词器,配置在schema.xml中。
第九天:
taotao商城的solr服务在linux的搭建,搜索服务层系统的搭建,表现层搭建,并使用solr实现商品搜索功能(中文分析器的配置、业务域定义、入数据到索引库、索功能的实现)。
solr分页:通过solrj设置start,设置rows,默认查询是10条。
查询的时候需要指定默认的搜索域。
第十天:
在并发量特别大的情况下,一个solr服务器无法满足要求,学习了solr集群在linux下的搭建,参考教案。
测试了solrj的集群版的使用,将搜索功能切换到集群版。
全局异常处理:需要创建一个类实现全局异常处理器的接口(handlerexceptionresolver)
,配置在配置文件springmvc。xml中。
全局异常处理中实现:
1、日志处理
2、发送异常信息邮件给相关人员
3、响应一个友好的错误页面给客户
第十一天:
索引库需要同步时,可以使用异步消息的中间件(activemq)
来实现索引库的同步。
Activemq的使用场景:
不需要同步等待时的系统之间的通信使用。比如:订单系统。
产生订单后,需要发送响应给客户,提示成功。但不需要等待用户点击确定后才继续产生订单。订单系统只需要产生订单后,异步发送一个消息,又继续执行下一个产生订单逻辑而不需要再等待页面响应。
同步索引库。
同步缓存。
生成静态页面。
传递消息的类型:
PTP --> queue --> 默认缓存在mq服务器上,只能被一个消费者接收。
publish/subscribe --> topic默认是不缓存,可以被多个消费者接收。(需要消费者先订阅)
消息的格式(JMS的规范)6种格式。TxtMessage、ObjectMessage、ByteMessage、……
1、一般是和spring进行整合使用。
2、发送端:JMSTemplate 发送消息。
3、接收端:使用设置一个监听容器 --> 指定监听器 (MessageListener)。
第十二天:
商品详情的系统搭建 (参考京东,访问商品详情时,域名已经变化)。
使用jsp和redis实现页面的高性能动态展示。
如果高并发量:需要实现网页静态化
来提升响应速度。
freemarker可实现网页静态化,使用freemarker的常用语法学习。实现网页静态化的方案实现。通过使用activemq实现同步生成静态网页。
实现网页静态化的方案:
部署不同的服务器上的(taoao-item-web)工程,分别订阅了topic(当商品添加/更新的时候发送的topic包含商品id),工程接收到消息,产生静态页面。
工程所在的服务器上再部署一个http服务器,来指定静态页面的目录,提供浏览器访问静态页面,提升效率。
第十三天:
在实现静态化的方案中需要使用nginx,需要学习nginx。nginx能实现的功能:
1、配置虚拟主机,复制server结点
即可。
2、反向代理,设置upstream节点
来指定服务的ip地址和端口,在location结点
设置proxy_pass=http://upstream; 参考教案。
3、负载均衡。
4、作为Http服务器。
学习实现nginx的高可用的原理。
第十四天:
SSO系统:主要解决分布式环境下session共享
的问题。
SSO系统的搭建,注册,登录,通过token
(相当于jsessionid
)获取用户信息。实现SSO服务,提供给其他客户端(如手机接口)
接口。
登录流程:用户填入用户名和密码,如果正确,key是一个uuid生成的唯一值(token)。用户信息存储到redis中,设置此key的有效期模拟session(30分钟),设置到cookie中(跨域:访问的端口不同,域名不同)。
使用JSONP
的技术:登录之后,在首页需要显示用户信息。使用JSONP来实现ajax跨域。
第十五天:
SSO系统的接口的开发完成及购物车实现以及订单确认页面实现。
购物车使用cookie来存放。有缺点:更换设备不能同步数据,存储的容量有限,如果cookie一旦被禁用,无法使用。
解决方案:
在用户未登录的情况下,继续使用cookie来存放购物车,展示列表以cookie为准。
一旦用户登录,将cookie的数据同步到数据库redis中,并删除cookie的内容,展示购物车列表就以redis中的数据为准,后续的添加到购物车也需要添加到redis中。
进入订单确认页面,需要认证身份,通过拦截器
来实现。
第十六天:
订单提交的功能实现。项目的部署,mysql的linux的安装
,系统的网络拓扑图,服务器的域名规划,服务器的数量规划及部署。使用tomcat的热部署,反向代理的配置。
项目中的问题
PS:以下描述若与就业老师所说有冲突,请以就业老师为准,另外参考简历一定要改,切不可拿来主义
1、淘淘商城简历中的描述
参考简历。
注意:在真实的开发项目中,开发工程师不可能开发所有的模块,只会负责某几个模块,大家所要描述的是:你所负责的模块(一般3到4个模块)。
2、淘淘网站的并发量
大概:说5000左右也行。(此处要问怎么来的,可以说经过压力测试
出来的,自己没做过,但是知道。有些情况下,并不是所有的事情都是由你来做,由面试官决定用不用你,你把所知道的说清楚就行)可以满足目前的业务需求。由于我们的系统是分布式架构,支持水平扩展,如果将来并发量提高的话,可以增加服务器来提高并发量。
3、淘淘商城人员的配置
产品经理:3人,确定需求及给出产品原型图。
项目经理:1人,项目管理。
前端团队:5人,根据产品经理给出原型制作出静态页面(当然也包括UI)。
后端团端:20人,实现产品的功能(你们就属于后端团队)。
测试团队:5人,负责测试产品的所有的功能。
4、开发周期
现在开发采用敏捷开发,快速迭代
,开发周期大概6-8个月,后期一般采用迭代的方式
开发,一般迭代的周期为一个月左右。(迭代就是所谓的一个小版本的开发)
5、SKU
表示唯一确定唯一的商品的单位(最小库存单位)SKU==商品ID
例如:对于京东的一款商品:一种颜色,一种配置,一种配送方式,就唯一确定一个商品,这种就叫做一个SKU。
类似于下图:
6、你说你用了redis,你们redis存的是什么格式的数据,都是怎么存的?
redis中存放数据都是key-value的形式。
我们商城使用string类型
来存放的。拿商品来说:商品的id就是key,商品相关的商品信息组成一个JSON存放。
7、你前台系统portal采用4服务器做集群部署,前台系统的并发量提升上去,那对于数据库会不会造成一个瓶颈,这一块你们是怎么处理的?
portal在高并发的情况下,可以通过部署集群
来提高并发量,这种时候,如果每次都访问数据,确实会对数据库造成很大的压力,那么这时候,我们就采用在服务层增加缓存
,使用redis实现
,这样客户端请求到达时,先从缓存中读取,如果存在数据则直接返回,而不会再从数据库查询,如果缓存中没有,则从数据库查询,这样就可减少数据库的访问,达到提升数据的访问瓶颈。
8、购物车存在cookie中,可以实现不登录就可以使用购物车,如果我没有登录,购买了商品,现在更换了设备(电脑),那还能不能看到我买的商品?如果看不到怎么做cookie同步?
不能;现阶段,淘淘商城是采用cookie的方式存放购物车,以减少服务端的存储压力。但是弊端就是当更换设备后将看不到已添加的商品,也就是不能同步商品信息。
打算下一步这么实现:当用户没有登录时,商品的数据放入购物车中,将存放于cookie中,此时如果用户登录,将cookie中的数据存放在redis中,并且是和用户的ID关联,并将cookie中的数据删除。此时如果用户更换设备,只要使用同一帐号登录,就可以看到购物车中的商品信息,就达到了同步cookie的目的。
9、你们商城是通过什么来做搜索的?
因为系统要使用站内搜索功能,数据量很大,需要使用solr。
solr是(基于lucene)搜索引擎,可以独立部署
,来实现搜索功能、高亮显示、性能优化,可以解决高并发
的搜索需求。
例如:我们系统就是用solr做商品搜索。--> 怎么做的呢?
solr是一个服务器,需要搭建,需要先定义好Field
和FieldType
,定义中文分词器
,再使用。
通过solr的Java客户端solrj连接solr服务,它提供丰富的操作索引的方法,可以通过这个客户端来实现搜索功能。
你们索引库一般有多少数据?答:几百万
如果数据量特别大?怎么办?答:做集群。
索引库是如何同步?答:activemq异步消息队列。
10、solr和lucene他们之间有什么区别?lucene
是一个工具包
,类似于一个类库。solr
是一个基于solr的搜索引擎
,可以独立运行和部署,它可以通过http请求来索引和搜索
。
打个比方:solr就相当于一辆汽车,而lucene只是汽车中的引擎,你可以开车,但不开引擎。
另外,使用solr可以独立部署,扩展容易,所以可以最大程度的解耦,而lucene使用需要在业务逻辑中添加代码,逻辑耦合度很高,不易维护。
11、你们使用activemq应用在哪种业务场景中,既然都是系统通信,和其他的系统通信有什么区别?
我们使用activemq应用在生成商品详情,同步索引库。activemq是一个消息中间件
,异步发送消息
,而其他通信技术:比如dubbo
,是同步等待
。
比如:使用activemq在商品服务模块,添加商品并不需要等待索引库同步完成后才能继续添加下一个商品,只需要异步发送一个消息告诉索引服务 ,索引服务通过商品ID查询商品更新索引。
再有:面试中,要淡定,如果有面试官问:数据库设计这样做正确吗?
你不清楚的情况下,你就说我们公司就是这么解决的。其他的我不知道。
有些面试官,可能他也不知道,他也想知道。
12、电商活动倒计时方案
1、确定一个基准时间
。可以使用一个sql语句从数据库中取出一个当前时间。SELECT NOW()
2、活动开始的时间是固定的。
3、使用活动开始时间减去基准时间可以计算出一个秒为单位的数值。
4、在redis中设置一个key(活动开始标识)。设置key的过期时间为第三步计算出来的时间。
5、展示页面的时候取出key的有效时间。ttl命令
。使用js倒计时
。
6、一旦活动开始的key失效,说明活动开始。
7、需要在活动的逻辑中,先判断活动是否开始。
13、你们的商城的秒杀方案是什么?
1、将商品的数量放入redis中。
2、秒杀时,可以使用decr命令
将商品的数量减一。如果不是负数说明抢到。
3、如果返回的是负数,说明商品已经抢完。
14、dubbo服务使用流程,运行流程?zookeeper注册中心的作用?
使用流程:
第一步:要在系统中使用dubbo应该先搭建一个注册中心,一般推荐使用zookeeper。
第二步:有了注册中心然后是发布服务,发布服务需要使用spring容器
和dubbo标签
来发布服务
。并且发布服务时需要指定注册中心的位置。
第三步:服务发布之后就是调用服务。一般调用服务也是使用spring容器
和dubbo标签
来引用服务
,这样就可以在客户端的容器中生成一个服务的代理对象
,在action或者Controller中直接调用service的方法即可。
Zookeeper注册中心的作用:主要就是注册和发现服务
的作用。类似于房产中介
的作用,在系统中并不参与服务的调用及数据的传输
。
15、redis为什么可以做缓存?项目中使用redis的目的是什么?redis什么时候使用?
1、Redis是key-value形式的nosql数据库。可以快速的定位到所查找的key,并把其中的value取出来。并且redis的所有的数据都是放到内存中
,存取的速度非常快,一般都是用来做缓存使用。
2、项目中使用redis一般都是作为缓存来使用的,缓存的目的就是为了减轻数据库的压力提高存取的效率
。
3、在互联网项目中只要是涉及高并发
或者是存在大量读数据的情况下
都可以使用redis作为缓存。当然redis提供丰富的数据类型,除了缓存还可以根据实际的业务场景来决定redis的作用。例如使用redis保存用户的购物车信息、生成订单号、访问量计数器、任务队列、排行榜等。
16、AcitveMQ的作用、原理?(生产者。消费者。 p2p、订阅实现流程)
Activemq的作用就是系统之间进行通信。当然可以使用其他方式进行系统间通信,如果使用Activemq的话可以对系统之间的调用进行解耦
,实现系统间的异步通信
。原理就是生产者生产消息,把消息发送给activemq。Activemq接收到消息,然后查看有多少个消费者,然后把消息转发给消费者,此过程中生产者无需参与。消费者接收到消息后做相应的处理和生产者没有任何关系。
17、ActiveMQ在项目中如何应用的?
Activemq在项目中主要是完成系统之间通信,并且将系统之间的调用进行解耦。例如在添加、修改商品信息后,需要将商品信息同步到索引库、同步缓存中的数据以及生成静态页面一系列操作。在此场景下就可以使用activemq。一旦后台对商品信息进行修改后,就向activemq发送一条消息,然后通过activemq将消息发送给消息的消费端,消费端接收到消息可以进行相应的业务处理。
18、ActiveMQ如果数据提交不成功怎么办?
Activemq有两种通信方式,点到点模式
和发布订阅模式
。
如果是点到点模式
的话,如果消息发送不成功此消息默认会保存到activemq服务端直到有消费者将其消费,所以此时消息是不会丢失的。
如果是发布订阅模式
的通信方式,默认情况下只通知一次,如果接收不到此消息就没有了。这种场景只适用于对消息送达率要求不高
的情况。如果要求消息必须送达不可以丢失的话,需要配置持久订阅
。每个订阅端定义一个id,在订阅时向activemq注册。发布消息和接收消息时需要配置发送模式为持久化
。此时如果客户端接收不到消息,消息会持久化到服务端,直到客户端正常接收后为止。
19、当被问到某个模快存在安全性问题(sso单点登录系统)时,如何回答?
目前商城的sso系统的解决方案中直接把token保存到cookie中
,确实存在安全性问题。但是实现简单方便。如果想提高安全性可以使用CAS框架
实现单点登录。参考链接:https://www.apereo.org/projects/cas
20、当技术面试官问到你某个技术点更深层次研究时,自己没有深入了解怎么回答?
如果没有深入研究就直接回答不知道就可以了。
21、如何把热点商品或者是推广商品的排名提高?
可以设置文档中域的boost值
,boost值越高计算出来的相关度得分
就越高,排名也就越靠前。
22、solr的原理
Solr是基于Lucene开发的全文检索服务器,而Lucene就是一套实现了全文检索的api,其本质就是一个全文检索的过程。全文检索就是把原始文档根据一定的规则拆分成若干个关键词
,然后根据关键词创建索引,当查询时先查询索引找到对应的关键词,并根据关键词找到对应的文档,也就是查询结果,最终把查询结果展示给用户的过程。
23、solr里面IK分词器的原理
IK分析器的分词原理本质上是词典分词
。现在内存中初始化一个词典,然后在分词过程中逐个读取字符,和字典中的字符相匹配,把文档中的所有的词语拆分出来的过程。
21、支付接口是怎么做的?
面试中可以说支付这部分不是我们做的,我们项目中并没有涉及支付部分的处理。如果想了解支付是如何实现可以参考之前学过的易宝支付
相关处理以及支付宝
、微信支付
相关文档。
支付宝:https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.eeTXH8&apiId=850&docType=4#
微信支付:https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/faq_tmpl
24、业务如何说?先说业务、说表、说具体实现?
先说总体的业务流程,然后再说具体业务的实现方法及使用的技术。最后说你在系统中负责的内容。不需要说表结构。
25、单点登录系统,如果cookie禁用,你们怎么解决?
如果禁用cookie可以使用url中带参数,把token传递给服务端。当然此方法涉及安全性问题,其实在cookie中保存token同样存在安全性问题。推荐使用SSO框架CAS
实现单点登录。
26、你们做移动端没有,如果没有移动端,你们为什么做单点登录?
单点登录并不是为移动端准备的,移动端有自己的登录方式。单点登录是解决在同一个公司内部多个互信网站之间进行跳转时不需要多次登录
,多个系统统一登录入口。
27、单点登录的核心是什么?
单点登录的核心是如何在多个系统之间共享身份信息(即共享session)
。
28、除了单点登陆,还做过什么登陆的方式?
除了单点登录那就是普通登录方式
,用户在同一个公司的多个系统之间跳转时需要多次登录
。
29、单点登录,http无状态的,别人模仿如何在后端处理?
http是无状态的,如果别人模仿浏览器发送http请求,一般后台是无法识别的。如果对安全要求高的情况下应该是https协议
。可以保证在通信过程中无法窃取通信内容。
30、安全性问题(别的网站使用爬虫技术爬你的网站怎么办?有没有安全措施)
单位时间内请求次数超过某个阈值就让输入验证码
,可以极大降低抓取的速度
,如果多次超过某个阀值可以加入黑名单
。还有就是页面内容使用json返回
,数据经常变一变格式
,或者js动态生成页面内容
。
31、商品存入数据库怎么保证数据库数据安全?
1、对用户安全管理
用户操作数据库时,必须通过数据库访问的身份认证
。删除数据库中的默认用户,使用自定义的用户及高强度密码。
2、定义视图
为不同的用户定义不同的视图,可以限制用户的访问范围
。通过视图机制把需要保密的数据对无权存取这些数据的用户隐藏起来,可以对数据库提供一定程度的安全保护。实际应用中常将视图机制
与授权机制
结合起来使用,首先用视图机制屏蔽一部分保密数据,然后在视图上进一步进行授权
。
3、数据加密
数据加密是保护数据在存储和传递过程中不被窃取或修改的有效手段。
4、数据库定期备份
5、审计追踪机制
审计追踪机制是指系统设置相应的日志记录
,特别是对数据更新、删除、修改的记录,以便日后查证。日志记录的内容可以包括操作人员的名称、使用的密码、用户的IP地址、登录时间、操作内容等。若发现系统的数据遭到破坏,可以根据日志记录追究责任
,或者从日志记录中判断密码是否被盗,以便修改密码,重新分配权限,确保系统的安全。
32、订单表的数据量太大,我把订单分到许多表中,那么我我想用一条sql查处所有的订单,怎么解决?
分库情况下:可以使用mycat数据库中间件
实现多个表的统一管理。虽然物理上是把一个表中的数据保存到多个数据库中,但是逻辑上还是一个表,使用一条sql语句就可以把数据全部查询出来。
单库情况下:需要动态生成sql语句
。先查询订单相关的表,然后将查询多个表的sql语句使用union连接
即可。
33、咱们单点登录模块中,别人伪造我们cookie中的token怎么办?
服务端是无法阻止客户端伪造cookie的
,如果对安全性要求高的话可以可使用CAS框架
。
34、第一个是当两个客户同时买一件商品时库存只有一个了,怎么控制?
可以使用mysql的行锁机制
,实现乐观锁
,在更新商品之前将商品锁定,其他用户无法读取,当此用户操作完毕后释放锁。当并发量高
的情况下,需要使用缓存工具例如redis来管理库存
。
35、对数据库只是采用了读写分离,并没有完全解决数据库的压力,那么有什么办法解决?
如果数据库压力确实很大的情况下可以考虑数据库分片
,就是将数据库中表拆分到不同的数据库中保存。可以使用mycat中间件
。
36、同一账号以客户端登录怎么挤掉另一端。
用户登录后需要在session中保存用户的id
。当用户登录时,从当前所有的session中判断是否有此用户id的存在,如果存在的话就把保存此用户id的session销毁
。
37、solr的索引查询为什么比数据库要快?
Solr使用的是Lucene API
实现的全文检索。全文检索本质上是查询的索引
。而数据库中并不是所有的字段都建立的索引
,更何况如果使用like查询时很大的可能是不使用索引,所以使用solr查询时要比查数据库快。
38、solr索引库个别数据索引丢失怎么办?
首先Solr是不会丢失个别数据的
。如果索引库中缺少数据,那就向索引库中添加。
39、Lucene索引优化
直接使用Lucene实现全文检索已经是过时的方案,推荐使用solr。Solr已经提供了完整的全文检索解决方案
。