理解同步、异步、阻塞和非阻塞

关于同步、异步、阻塞和非阻塞这个概念性问题,这可能是非常容易混淆的概念之一,特别是那些刚开始解除网络编程的人来说。本篇文章争取来说清楚这个问题,如果有错误之处,恳请批评指正。

写在前面

首先大家心中需要有以下的清晰认知:

  • 阻塞操作不等于同步(blocking operation does NOT equal to synchronous)
  • 非阻塞操作不等于异步(non-blocking operation does NOT equal to asynchronous)

事实上,同步异步于阻塞和非阻塞没有什么直接的关联关系。

同步和异步

同步和异步关注的是 通信机制 (communication mechanism)

  • 同步是指在发出一个function调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到调用结果了。这个结果可能是一个正确的期望结果,也可能是因为异常原因(比如超时)导致的失败结果。换句话说,就是由调用者主动等待这个调用的结果。

Synchronous is, when we started a function call, the call will not return anything until it gets the result, the function needs to finish everything before it can give anything to us.

  • 异步调用在发出之后,本次调用过程就直接返回了,并没有同时没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态变化、事件通知等机制来通知调用者,或通过回调函数处理这个调用。

Asynchronous does not need to wait for the function completes its operation, once we call it, it returns immediately without any result, the function uses callback function (or other notification method) to “notify” us to get the value after it completes execution.

阻塞和非阻塞

阻塞和非阻塞关注的是 程序在等待调用结果(消息、返回值)时的状态.

Unlike synchronous/asynchronous, blocking/non-blocking focuses on the status of the program while waiting for the result from the function call.

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回

A blocking operation hangs up current thread before it gets the result, in other words, a blocking operation will let the current thread wait for the result returns, even if the target function will use a callback function to notify client side to fetch the result, the thread on the client side will still be blocked until it gets the returned result.

  • 非阻塞是指在不能立刻得到结果之前,该调用不会阻塞当前线程。

the non-blocking operation will not hang up the current thread if no result returned immediately.

对unix操作系统来讲:

  • 阻塞式I/O(默认),非阻塞式I/O(nonblock),I/O复用(select/poll/epoll)都属于同步I/O,因为它们在操作系统将数据由内核缓冲区复制到用户空间缓冲区时都是阻塞的(不能干别的事)。
  • 只有异步I/O模型(AIO)是符合异步I/O操作的含义的,即在数据准备完成以后,由内核空间拷贝回用户缓冲区后再通知通知用户进程,而用户进程在等待通知的这段时间里可以干别的事。

前几天看到了下面的代码片段,我觉的写的挺好的,复制一下:

http://7niucdn.wenchao.ren/20190329000237.png

接下来我会写一篇介绍unix IO模型的文章,在这篇文章中,我会具体谈谈不同的IO模型。

参考资料

brew操作mysql

  • 安装mysql brew install mysql
  • 启动mysql brew services start mysql
  • 停止mysql brew services stop mysql
  • 重启mysql brew services restart mysql

在我的机器上,my.cnf文件的位置在:/usr/local/etc/my.cnf,默认情况下里面的内容为:

1
2
3
4
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1

个人认为的工作多年的开发者的3个最重要技能

不知道你觉的工作多年的开发者最重要的技能是什么?

随着工作经历的增长,我个人越来越觉得对于开发者来说,很多时候个人的专业技能反而并不是最重要的,甚至在很多的时候是最廉价,最容易被替代的。反而是一些非专业技能确显得更加的重要。我觉的按照优先级从高到低依次为:

  • 业务洞察力
  • 技术视野
  • 非常高执行力

业务洞察力

业务洞察力是值:在当下能够做出合理的判断,清楚Team或者公司做什么事情收益最大,很多时候是 战略层面 的问题

我们经常会面临有无穷无尽的事情要做,有无穷无尽的事情可以做,但是

  • 我们应该先做哪个呢?
  • 做哪些事情的收益是最大的呢?
  • 做哪些事情做了和没做对公司区别没那么大呢?
  • 甚至哪些做哪些事情是吃力不讨好的呢?

这里不是说大家要做老油条,而是要有超前的眼光,跳出仅仅作为一个代码编写员的视角,站在更高的层次来思索事情的优先级。

那平时应该怎么做呢?

我觉的首先要有这方面的意识,其次多了解公司各个team正在做的事情,通过新闻、自己的观察、茶前饭后的闲聊、帮其他组同事排查问题时听到的等等的手段,尽可能多的获取一些公司大的层面的一些信息,然后了解公司的一些计划,公司业务的重点发展方向,业务团队经常的痛点是什么等等的。然后基于这些信息,来辅助我们做优先级判断。

技术视野

技术视野即技术选型能力,是 战术层面 的问题,在清楚做什么事情后,需要进一步解决怎么做的问题,也就是能够给出合理的技术选型方案:是完全基于开源的方案,还是基于开源二次开发的方案,还是完全自研的方案,同时要有一定的前瞻性,保持自己对业界技术风向的敏感度。但是一切都要结合公司实际发展情况,要务实不能务虚。不能盲目的追求高新技术,一定要把握好技术风险。

非常高执行力

执行力是技术落地执行层面的问题,一旦技术设计方案确定后,需要能够快速完成。一般工作多年的同事的执行力往往都是比较高的,毕竟手熟。所以要注意培养自己的前两点能力。

这3点层层递进,最重要的是先把技术战略问题思考清楚,然后再进一步解决技术战术问题,最后是快速落地执行的问题。

谈谈程序员成长

本篇文章主要侧重的是程序员的硬技能方面的,不涉及软技能。

关于程序员的成长,网上有很多人都在谈,也有很多的文章,我也看过许多,个人感觉写的最好的是下面2个文章,建议大家阅读。

我此处整理一下:

误区

拜大牛为师

  • 大牛很忙,不太可能单独给你开小灶
  • 大牛不多,不太可能每个团队都有技术大牛,只能说团队里面会有比你水平高的人,即使他每天给你开小灶,最终你也只能提升到他的水平

综合上述的几个原因,我认为对于大部分人来说,要想成为技术大牛,首先还是要明白“主要靠自己”这个道理,适当的时候可以通过请教大牛或者和大牛探讨来提升自己,但大部分时间还是自己系统性、有针对性的提升。

业务代码一样很牛逼

有人认为写业务代码一样可以很牛逼,理由是业务代码一样可以有各种技巧,例如可以使用封装和抽象使得业务代码更具可扩展性,可以通过和产品多交流以便更好的理解和实现业务,日志记录好了问题定位效率可以提升10倍等等。

业务代码一样有技术含量,这点是肯定的,业务代码中的技术是每个程序员的基础,但只是掌握了这些技巧,并不能成为技术大牛,就像游戏中升级打怪一样,开始打小怪,经验值很高,越到后面经验值越少,打小怪已经不能提升经验值了,这个时候就需要打一些更高级的怪,刷一些有挑战的副本了,成为技术大牛的路也是类似的,你要 不断的提升自己的水平,然后面临更大的挑战,通过应对这些挑战从而使自己水平更上一级,然后如此往复。所以我认为:业务代码都写不好的程序员肯定无法成为技术大牛,但只把业务代码写好的程序员也还不能成为技术大牛。

上班太忙没时间自己学习

很多人认为自己没有成为技术大牛并不是自己不聪明,也不是自己不努力,而是中国的这个环境下,技术人员加班都太多了,导致自己没有额外的时间进行学习。

这个理由有一定的客观性,毕竟和欧美相比,我们的加班确实要多一些,但这个因素只是一个需要克服的问题,并不是不可逾越的鸿沟,毕竟我们身边还是有那么多的大牛也是在中国这个环境成长起来的。

我认为有几个误区导致了这种看法的形成:

1)上班做的都是重复工作,要想提升必须自己额外去学习
2)学习需要大段的连续时间

正确的做法

做的更多,做的比你主管安排给你的任务更多。

要想有机会,首先你得从人群中冒出来,要想冒出来,你就必须做到与众不同,要做到与众不同,你就要做得更多!不分哪些是我该做的、哪些不是我该做的

怎么做得更多呢?可以从以下几个方面着手:

  • 熟悉更多业务,不管是不是你负责的;熟悉更多代码,不管是不是你写的
  • 熟悉端到端 比如说你负责web后台开发,但实际上用户发起一个http请求,要经过很多中间步骤才到你的服务器(例如浏览器缓存、DNS、nginx等),服务器一般又会经过很多处理才到你写的那部分代码(路由、权限等)这整个流程中的很多系统或者步骤,绝大部分人是不可能去参与写代码的,但掌握了这些知识对你的综合水平有很大作用,例如方案设计、线上故障处理这些更加有含金量的技术工作都需要综合技术水平。 “系统性”、“全局性”、“综合性”这些字眼看起来比较虚,但其实都是技术大牛的必备的素质,要达到这样的境界,必须去熟悉更多系统、业务、代码。
  • 自学 以垃圾回收为例,我自己平时就抽时间学习了这些知识,学了1年都没用上,但后来用上了几次,每次都解决了卡死的大问题,而有的同学,写了几年的java代码,对于stop-the-world是什么概念都不知道,更不用说去优化了。

这一点和张一鸣说的是完全吻合的:

  • 我工作时,不分哪些是我该做的、哪些不是我该做的
  • 我做事从不设边界

做的更好

要知道这个世界上没有完美的东西,你负责的系统和业务,总有不合理和可以改进的地方,这些“不合理”和“可改进”的地方,都是更高级别的怪物,打完后能够增加更多的经验值。识别出这些地方,并且给出解决方案,然后向主管提出,一次不行两次,多提几次,只要有一次落地了,这就是你的机会。

多练

在做职业等级沟通的时候,发现有很多同学确实也在尝试Do more、Do better,但在执行的过程中,几乎每个人都遇到同一个问题:光看不用效果很差,怎么办?

例如:

  • 学习了jvm的垃圾回收,但是线上比较少出现FGC导致的卡顿问题,就算出现了,恢复业务也是第一位的,不太可能线上出现问题然后让每个同学都去练一下手,那怎么去实践这些jvm的知识和技能呢?
  • Netty我也看了,也了解了Reactor的原理,但是我不可能参与Netty开发,怎么去让自己真正掌握Reactor异步模式呢?
  • 看了《高性能MySQL》,但是线上的数据库都是DBA管理的,测试环境的数据库感觉又是随便配置的,我怎么去验证这些技术呢?
  • 框架封装了DAL层,数据库的访问我们都不需要操心,我们怎么去了解分库分表实现?

诸如此类问题还有很多,我这里分享一下个人的经验,其实就是3个词:learning、trying、teaching!

Learning

这个是第一阶段,看书、google、看视频、看别人的博客都可以,但要注意一点是 “系统化”,特别是一些基础性的东西,例如JVM原理、Java编程、网络编程,HTTP协议等等,这些基础技术不能只通过google或者博客学习,我的做法一般是先完整的看完一本书全面的了解,然后再通过google、视频、博客去有针对性的查找一些有疑问的地方,或者一些技巧。

Trying

这个步骤就是解答前面提到的很多同学的疑惑的关键点,形象来说就是“自己动手丰衣足食”,也就是自己去尝试搭建一些模拟环境,自己写一些测试程序。例如:

  • Jvm垃圾回收:可以自己写一个简单的测试程序,分配内存不释放,然后调整各种jvm启动参数,再运行的过程中使用jstack、jstat等命令查看jvm的堆内存分布和垃圾回收情况。这样的程序写起来很简单,简单一点的就几行,复杂一点的也就几十行。
  • Reactor原理:自己真正去尝试写一个Reactor模式的Demo,不要以为这个很难,最简单的Reactor模式代码量(包括注释)不超过200行(可以参考Doug Lee的PPT)。自己写完后,再去看看netty怎么做,一对比理解就更加深刻了。
  • MySQL:既然有线上的配置可以参考,那可以直接让DBA将线上配置发给我们(注意去掉敏感信息),直接学习;然后自己搭建一个MySQL环境,用线上的配置启动;要知道很多同学用了很多年MySQL,但是连个简单的MySQL环境都搭不起来。
  • 框架封装了DAL层:可以自己用JDBC尝试去写一个分库分表的简单实现,然后与框架的实现进行对比,看看差异在哪里。
  • 用浏览器的工具查看HTTP缓存实现,看看不同种类的网站,不同类型的资源,具体是如何控制缓存的;也可以自己用Python写一个简单的HTTP服务器,模拟返回各种HTTP Headers来观察浏览器的反应。

当然,如果能够在实际工作中使用,效果会更好,毕竟实际的线上环境和业务复杂度不是我们写个模拟程序就能够模拟的,但这样的机会可遇不可求,大部分情况我们还真的只能靠自己模拟,然后等到真正业务要用的时候,能够信手拈来。

Teaching

一般来说,经过Learning和Trying,能掌握70%左右,但要真正掌握,我觉得一定要做到能够跟别人讲清楚。因为在讲的时候,我们既需要将一个知识点系统化,也需要考虑各种细节,这会促使我们进一步思考和学习。同时,讲出来后看或者听的人可以有不同的理解,或者有新的补充,这相当于继续完善了整个知识技能体系。

这样的例子很多,包括我自己写博客的时候经常遇到,本来我觉得自己已经掌握很全面了,但一写就发现很多点没考虑到;组内培训的时候也经常看到,有的同学写了PPT,但是讲的时候,大家一问,或者一讨论,就会发现很多点还没有讲清楚,或者有的点其实是理解错了。写PPT、讲PPT、讨论PPT,这个流程全部走一遍,基本上对一个知识点掌握就比较全面了。

谈谈面试

今晚看到了这篇文章最近面试Java后端开发的感受, 深有感触,感觉写的特别好,有感而发,所以打断写这么一篇文章,来谈谈我的经验吧。

面试是一个综合评分的过程

首先一定要认识到面试是个综合评分的过程,不一定仅仅是考察面试者的技术能力,很多时候都会有一定(甚至很大)的运气成分,这一点其实很像公司内部的
晋级答辩一样,这一点一定要深刻理解。比如碰上一个性格不错,有礼貌的面试官,通过的可能性大多数情况下都会比全程绷着脸,接N个电话的面试官好一些。
所以即便最后最差情况,面试没过,不一定代表你能力不行,可能是技能和工作要求不匹配啊,可能是运气不行啊,说不定换一个面试官就过了等等的,都是可能
的,所以首先要正确看待面试这个环节。

面试前

不可否认的是,跳槽可能(基本)是互联网行业涨薪最快的手段了。而跳槽以后的薪资,虽然会在一定程度上参考上一家公司的薪资水平,但是只要你在面试阶段
的表现能够表现出:【上一家公司在薪资方面亏了我,我其实更值钱】这种情况的话,一般情况下,新公司在初步评级,以及你在和HR的薪资谈判过程,会占有很大
的主动性,所以面试期间的表现很重要。

为了面试期间表现的好,那么一定是需要提前准备的。虽然我不太喜欢突击准备,更喜欢平时多留心留意。但是不可否认面试其实是一个异常情况出现概率很大的事情。指不定面试官会问到哪里,所以面试者首先一定要尽可能的准备充分,并且有意的在简历以及在面试过程中,留下一些【坑】来引导面试官跟随自己提前准备好
的计划来面试,这样可以减少面试过程中异常情况发生。

简历不要瞎编,项目经验不要瞎编,一定要能自圆其说,最起码写在简历上面的要不怕被人问,如果被人三两句问住那就不好了,所以尽可能的多考虑一下面试官
会问什么,同时也百度一下最近的面试题,自己也做做相关的面试题。

面试期间

面试期间要注意的东西其实很多时候是表达能力。不能茶壶里面煮饺子,倒不出来。

尽量提前演练几下,提前想好如果面试官问xxx的时候,怎么回答,这样就不至于太仓促了。另外贴一下这篇文章最近面试Java后端开发的感受中提到的一些注意点,我觉的写的挺好的:

  • 别让人感觉你只会山寨别人的代码
  • 单机版够用?适当了解些分布式
  • 别就知道增删改查,得了解性能优化
  • 围绕数据结构和性能优化准备面试题
  • 至少了解如何看日志排查问题
  • 通读一段底层代码,作为加分项
  • 把上述技能嵌入到你做过的项目里

我总结了一下主要突出下面2个方面:

大家都能做的事情,你做的比别人好

首先普通的事情能做,这是最基本的要求,活都不会干,怎么可能面试通过呢。其次一定要让别人觉的大家都能做的事情,你已经做的比别人好了。就如同上面提到的那篇文章说的:别让人感觉你只会山寨别人的代码。要能发现当前的不足和并给出解决方案。如果和大多数人的水平差不多了,在这点就没法体现出你的优势了。

举几个例子:

  • 都在用Spring + Mybatis + mysql架构,现有的系统的问题在哪,你做了哪些改进和优化
  • 线上出现问题了,你如何更快速的排查出来了呢?有没有自己的一套方法论和问题QA集
  • 现有项目代码存在安全漏洞,你是否主动发现并fix上线了呢?
  • 项目有delay了,是否主动推动了呢?

别人不知道的你知道,别人干不了的你可以

别人不知道的你知道,别人干不了的你可以,这才是你真正和HR谈价钱的资本。所以一定要注重这个表达。当然了很少出现别人完全不知道的和别人完全干不了的情况,所以很多的时候是需要扩展知识的深度和广度

比如:

  • 熟悉Nginx dubbo redis等的原理和底层
  • 比如熟悉业界的cloud native等

最后希望大家都能找到好工作,拿到好工资

Mac privoxy+Shadowsocks+iTerm2走代理

本篇文章讲述如何通过Shadowsocksprivoxy让mac的终端terminal可以翻墙

首先下载安装privoxy

1
brew install privoxy

默认就会启动privoxy,可通过以下终端命令查看privoxy进程是否启动成功:

1
ps aux | grep privoxy

然后配置privoxy,配置文件在/usr/local/etc/privoxy/config, 在文件末尾的listen-address 127.0.0.1:8118的下一行增加:
forward-socks5 / 127.0.0.1:1086 .,其中1086是shadowsocks的本地Sock5监听端口

终端执行以下两条命令即可访问privoxy:

1
2
export http_proxy='http://localhost:8118'
export https_proxy='http://localhost:8118'

一般建议将这2个命令增加到zsh.zshrc文件中去。

至于terminal中ping google失败的问题,请参考请问如何在ss代理下ping通google.com?, 其实此时已经termianl可以访问外网了,不信的话试试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
~ » curl -I -XGET https://www.google.com
HTTP/1.1 200 Connection established

HTTP/2 200
date: Thu, 14 Feb 2019 16:18:17 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=ISO-8859-1
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
server: gws
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
set-cookie: 1P_JAR=2019-02-14-16; expires=Sat, 16-Mar-2019 16:18:17 GMT; path=/; domain=.google.com
set-cookie: NID=160=Mggo_ejHqi_HSj4vULKNmc47pjxGoKK0qcewujmXpdUm9avyK-vw09NrkF_mGZJdRVznZpvww2dlwh8C8LvhyX9KIEQFDQXtN7v0Gt9QrBaBWB1_9HN0XhXaDI0MFP2p_Y519oso-yZggi6HpZ_HynnMyih3EcdQW4nyYQQKXSo; expires=Fri, 16-Aug-2019 16:18:17 GMT; path=/; domain=.google.com; HttpOnly
alt-svc: quic=":443"; ma=2592000; v="44,43,39"
accept-ranges: none
vary: Accept-Encoding

ShadowsocksX-NG 1.8.2设置kcptun

在自己的mac上升级了一下ShadowsocksX-NG1.8.2版本。发现无法使用了,检查发现新版本中没有设置kcptun的地方了,

新版本在【服务器设置】的地方

  • 插件输入框中写kcptun
  • 插件选项写:key=【此处为自己的key】;crypt=aes;mode=fast2;mtu=1350;sndwnd=2048;rcvwnd=2048;datashard=10;parityshard=3;dscp=0

检查发现kcptun会自动打开

1
2
~ » ps -ef | grep kcp
501 31273 31272 0 5:52PM ?? 0:00.37 plugins/kcptun

参考资料

stop using TLS-SNI-01 with Certbot

今天收到一个来自letsencrypt的邮件:Action required: Let's Encrypt certificate renewals,简单的说就是Let’s Encrypt移除了对TLS-SNI-01的支持。
所以我就按照他们的指示,修改了一下我的certbot配置。操作步骤如下:

检查certbot的版本大于0.28

使用命令certbot --version来检查命令。我检查的时候发现我的版本比0.28低,所以我需要升级一下:

1
2
3
4
[root@VM_43_49_centos workspace]# certbot --version
certbot 0.26.1

sudo yum upgrade certbot

我在使用sudo yum upgrade certbot以后,测试版本出现下面的异常:

1
2
3
4
5
6
7
8
9
10
11
[root@VM_43_49_centos workspace]# certbot --version
Traceback (most recent call last):
File "/usr/bin/certbot", line 5, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 3011, in <module>
parse_requirements(__requires__), Environment()
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 626, in resolve
raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: acme>=0.29.0
[root@VM_43_49_centos workspace]# yum list | grep acme
Repository epel is listed more than once in the configuration

所以我还需要升级一下

1
sudo yum upgrade python2-acme.noarch

升级完以后检查版本

1
2
[root@VM_43_49_centos workspace]# certbot --version
certbot 0.29.1

Remove any explicit references to tls-sni-01 in your renewal configuration:

执行下面的命令

1
sudo sh -c "sed -i.bak -e 's/^\(pref_challs.*\)tls-sni-01\(.*\)/\1http-01\2/g' /etc/letsencrypt/renewal/*; rm -f /etc/letsencrypt/renewal/*.bak"

Do a full renewal dry run:

1
sudo certbot renew --dry-run

参考资料

SyntaxHighlighter Evolved带来的字符转义问题

我的WordPress使用的代码高亮插件为SyntaxHighlighter Evolved,主要是喜欢这个配色。

虽然也尝试过crayon syntax highlighter这个插件,此处提一下这个插件代码高亮的主题很多,也解决了
html字符转义的问题,但是配色不是我喜欢的类型。而且主要是以前一直使用SyntaxHighlighter Evolved
代码中使用了太多的[java]xasda[/java]类似这样的代码标签。而crayon syntax highlighter插件对这些
貌似支持的不太好,可能人家是支持的,不过我也没有太研究。所以还是想着解决SyntaxHighlighter Evolved
字符转义的问题。

问题解决

其实解决起来很简单:

  • 先停用SyntaxHighlighter Evolved插件
  • 编辑syntaxhighlighter/syntaxhighlighter.php文件的1046行
    这一行原来的内容为:
1
$code = ( false === strpos( $code, '<' ) && false === strpos( $code, '>' ) && 2 == $this->get_code_format($post) ) ? strip_tags( $code ) : htmlspecialchars( $code );

修改为:

1
$code = ( false === strpos( $code, '<' ) && false === strpos( $code, '>' ) ) ? strip_tags( $code ) : htmlspecialchars( $code );

然后保存,在启用插件就解决了代码中的html转义的问题

参考资料

促销系统设计

写在前面

首先必须得说一下,我并没有实际参与过电商系统相关的业务,我一直工作的项目组做的事情和本篇文章要讲的东西完全不同。因此本篇文章仅仅是我自己平时观察和构想的一些整理,如果有不太合理的地方,希望大家指正,先谢谢大家。

文章简介

在各大电商网站上,基本时时刻刻都可以看到促销活动。相信大家基本都参与过一些促销活动。随着业务的复杂化、运营的精细化,以及品类、平台、渠道的不断丰富,各种新的促销形式也层出不穷,贯穿从商品展示、搜索、购买、支付等整个流程。虽然促销的商品本身千差万别,但是但对于促销这个事情来说,又有很多共同的地方,本篇文章希望可以归纳总结出一套设计促销系统模型的方法论出来。

促销系统介绍

如果需要给促销一个定义的话,那么促销就是:

在某个时间范围内,对满足某些条件的用户,给予满足某些约束的商品进行一定形式的优惠

而促销系统就是为了支撑若干个这样的促销活动而设计出来的系统。
促销规则的生效页面是购物车页面和结算页面。在结算页面比购物车页面多出的是对运费的处理,其它的信息和购物车页面的信息是一致。只有在顾客将某个产品加入购物车后,基于购物车内的产品进行计算分析才会得出折扣后的价格、赠送或其它信息。当然在具体结算的时候,也会根据用户所选择的购物车中的项目重新计算折扣后的价格、赠送等其他信息的

常见的促销活动例子:

  • 购买的图书满100减20,满200减50
  • 购买某商品,赠送另外一个商品
  • 满200元任选一个赠品
  • 某商品特价
  • 买A商品,在买B商品,则给予一定的折扣
  • 满多少免运费
  • ……

促销系统模型的目标

  • 功能强大
  • 可扩展性好
  • 与其他系统耦合度低

促销系统模型的设计

基本的促销模型

基本的促销模型

基本信息模型

促销条件

优惠

限额

规则

参考资料

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×