自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

翻译 一. Go 为什么快?(译: 五件事让Go变得如此之快)

原文地址: five things that make go fast. 本文并非完整翻译,只对原文关键部分进行提取归纳。 正文: 当人们谈论到为什么做出学习Go的决定时,往往会有不同的回答,但总有三个原因是他们都会谈及的: 并发性(Concurrency) 易于部署(Ease to deplo...

2020-04-28 15:42:12 89 0

原创 使用 ETag 以利用浏览器缓存,节省带宽

ETag 可以理解为服务端的一个资源标识,当两次请求相同的 URL,且 URL 对应的资源没有变化时 ETag 的值应该相同。合理使用 ETag 可以有效利用浏览器缓存,降低服务器的带宽压力。 原理分析 用户第一次通过 URL 请求资源时,服务器将为该资源生成 ETag(其值一般为MD5摘要),并...

2020-04-24 15:16:54 71 0

原创 GoMailer - 用 Go 开发的轻量电子邮件推送服务

GoMailer 轻量电子邮件推送服务(A lightly email sending service for Go) 通过form提交用户输入的数据,GoMailer会将这些数据填入预先定义好的邮件内容模板中,并帮你把内容投递到指定的邮箱。 也可以选择把邮件暂存在GoMailer中,另外选择时间...

2020-03-26 00:00:04 81 0

原创 浏览器直接上传文件到 Cloud Storage,绕开 App Engine Request 最大 32M 限制

随着流量的增加,GCP App Engine 会自动为应用分配更多的资源,但自动分配资源仍然受到一些阀值的约束,其中一条便是:发送到应用的请求,请求体不能大于32M。而对于一些上传大文件的需求,这个限制使得那些将文件上传服务的 EndPoint 设置在 App Engine 上的应用无法正常处理请...

2020-01-16 15:18:06 141 0

原创 Go 实现简单的请求路由和中间件框架

go 中区分函数和方法,方法依附于对象,需要先创建对象,才能调用对象的方法;而函数是包级的,只要是公开的,那么通过包就可以访问。go 中定义新的类型有两种方式,类型别名和结构体: // 类型别名 type Integer int type Integer1 = int // 结构体 type U...

2020-01-06 14:55:44 112 0

原创 JetBrains 系列 IDE 快速部署项目到远程服务器

JetBrains 系列 IDE 一直是我开发的主力工具,在开发时往往选择在本机进行运行和调试。这样毫无疑问是很高效的开发方式,但有时我们希望在更接近于线上的环境中进行调试,那么如何使此次的修改快速见效(部署以及运行)是需要解决的关键问题之一。 JetBrains GoLand、JetBrains...

2019-12-12 11:07:14 108 0

原创 grpc java client, go server 错误 io.grpc.StatusRuntimeException: UNAVAILABLE

java client 获取 channel 的代码如下: public ManagedChannel getChannel() { ManagedChannel channel = ManagedChannelBuilder.forAddress(config.getGr...

2019-11-14 15:30:19 1128 0

原创 地图应用如何优化 上: 数据请求和渲染方式

前端在基于 Google Map 的地图应用上渲染数据时一般以 tile 为单位请求数据。简单来说,屏幕上可见的地图区域是由多个 tile 拼接而成的,数据渲染以 tile 为单位,数据请求也以 tile 为单位。 这样,前端只需要绘制可见的几个 tile ,以及预绘制边缘的几个 tile,而不...

2019-10-28 15:23:26 314 0

原创 Spring IOC 容器启动流程分析

Spring IOC 容器启动流程分析 使用 Spring 时,XML 和注解是使用得最多的两种配置方式,虽然是两种完全不同的配置方式,但对于 IOC 容器来说,两种方式的不同主要是在 BeanDefinition 的解析上。而对于核心的容器启动流程,仍然是一致的。 Abstr...

2019-08-29 12:48:28 64 0

原创 for 循环中取地址引发的错误

在for a,b := range c 遍历中, a 和 b 在内存中只会存在一份,即之后每次循环时遍历到的数据都是以值覆盖的方式赋给 a 和 b,a,b 的内存地址始终不变。 以下是错误代码示例: p := []s2.Rect{} var rs []*s2.Rect for _, r...

2019-07-30 17:32:05 111 0

原创 Google Cloud - 使用时值得注意的细节

在 instance 启动和停止时收到通知 appengine 在进行自动扩缩时可能会频繁的停止或启动 instance,应用往往在启动时需要进行一些数据预热处理, appengine 提供了 /_ah/warmup 回调,在应用启动时得到通知,需要注意的是 /_ah/warmup 只有在自动扩缩...

2019-07-19 16:33:27 1057 0

原创 Google Cloud - instance 间通信(pubsub + memcache 实现实例间通信和保证一致性)

GCP - appengine 通过 version 管理应用,你可以在 appengine 上部署多个 version(dev、qa等),而每个 version 可以有多个 instance,一个 instance 可简单理解为一个基于 Spring Boot 实现的微服务,当有请求到达时 ap...

2019-07-11 16:38:28 54 0

原创 词素+词

词素+词 语言结构的层次性:语法层面:词素、词、词组、分句、句子;语篇层面:句子、语段、语篇; 词素 粘附词素-词缀 前缀: postwar coexist后缀:movement careless carelessness前后缀:unlucky coexistence否定前缀:in-(inac...

2019-05-07 07:39:45 361 0

原创 六. 语句与语法:函数 + 列表生成式

函数 在Python中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。 如果没有return语句,函数执行完毕后也会返回结果,只是结果为 None。 return None可以简写为return。 ...

2018-12-14 16:00:39 105 2

原创 五. 语句与语法:语句

输入输出 s = input() 接收输入,接收为str型 input(‘提示’) 先输出提示信息 print(‘=’ * 20) 输出20次 = print(n,b,v,sep=’ - ’) 用-分隔n,b,v并输出 print(1, 2, 3, 4, sep=’\n’, end=’ end’)...

2018-12-14 15:57:12 97 0

原创 四. 数据类型:其它类型 + 文件

空对象 None 布尔 bool:True、False True本质为 1(等且只等于),False本质为0(等且只等于)。 True + 4 -> 5 False – 3 -> -3 注意: bool(3) -> True bool(-3) -&...

2018-12-14 15:52:45 83 0

原创 三. 数据类型:集合类型 + 映射类型

集合类型 set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像。 set存储的元素和dict的key类似,必须是不变对象 借助list创建set,重复元素会被合并。 s = set([1,2,34,1]) ->...

2018-12-14 15:49:23 466 0

原创 二. 数据类型:序列类型

分为可变和不可变序列。 序列通用操作(以列表为例) 生成序列 list(‘abcd’) -> [‘a’,’b’,’c’,’d’] list(range(5)) -> [0,1,2,3,4] 判断元素是否包含 a = [1,2,3,4,’a’,’b’] 1 in a -&...

2018-12-14 15:45:12 319 0

原创 一. 数据类型:基本数据类型

第一个 Python 程序 解释器解释运行,源代码编译为pyc字节码,字节码会被缓存,提供下次运行速度,根据时间戳和版本判断是否需要重新编译。在PVM虚拟机中运行。 Source(py) -> Byte code(pyc) -> Runtime(PVM...

2018-12-14 15:31:11 82 0

原创 排序:六. 堆排序(利用堆结构(二叉完全树)的弹出/下沉操作排序)

平均情况、最好情况和最坏情况的时间复杂度都为O(nlog2n),即线性对数复杂度,不稳定的排序算法。 堆结构在 数据结构:二叉完全树(堆) 一文中进行了分析,接下来用代码来实现其几个关键操作:弹出、插入、取顶、上浮、下沉 堆操作实现 这里的实现以小根堆为例: 堆的基本操作接口定义: 弹出方法 ...

2018-12-14 11:05:14 252 0

转载 数据结构:二叉完全树(堆)

参考文章 堆常用来实现优先队列。 用数组保存数据,而不是链表。 在队列中,操作系统调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。 堆的实现通过构造二叉堆(...

2018-12-14 10:54:56 101 0

原创 排序:四. 归并排序(合并两个已经排好序的数组)

是创建在归并操作上的一种有效的排序算法。 平均、最好和最坏时间复杂度都为O(nlog2n)线性对数。是稳定的。 该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。 归并操作(merge) 也叫归并算法,指的是将两个已经排序的序列合并成一个序...

2018-12-13 09:03:29 2186 0

原创 排序:三. 插入排序(将元素比较插入到前面的位置)

参考文章 时间复杂度O(n2),最好情况O(n),最坏情况O(n2),稳定。(同冒泡) 是一种简单直观的排序算法。适用于量级小于千,或者若已知输入元素大致上按照顺序排列。 插入排序不适合对于数据量比较大的排序应用。 工作原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相...

2018-12-13 08:58:58 152 0

原创 排序:二. 直接选择排序(选择剩下的元素里最大(小)放到最后(前))

时间复杂度O(n2),最好情况O(n2),最坏情况O(n2),不稳定。 选择排序(Selection sort)是一种简单直观的排序算法。元素交换次数少,比较占多数。 工作原理如下 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 然后,再从剩余未排序元素中继续寻找最小(大)元素,然...

2018-12-13 08:54:55 320 0

原创 排序:一. 冒泡排序 (前往后所有未排序的元素相邻比较)

系列文章共实现了六种排序算法: 冒泡排序 直接选择排序 插入排序 归并排序 快速排序 堆排序 定义了 Sortable 接口,每种排序方法实现该接口,在 sort 方法中实现排序。 public interface Sortable<T> { /** ...

2018-12-13 08:51:25 317 0

原创 使用 zebra 对数据库表进行水平拆分

zebra 是美团点评开发的数据库访问层中间件,代码维护在 GitHub:Meituan-Dianping/Zebra Zebra是一个基于JDBC API协议上开发出的高可用、高性能的数据库访问层解决方案,是美团点评内部使用的数据库访问层中间件。具有以下的功能点: 配置集中管理,动态刷新 支...

2018-12-07 11:02:08 1040 0

原创 解析配置文件自动装配 DataSource + AbstractRoutingDataSource + AOP 实现动态数据源 - 补充:兼顾事务回滚以及分布式事务的情况

前两篇文章已经介绍了动态数据源的具体实现过程,在经过一段时间的使用后,发现了两个比较严重的问题,在这里进行补充说明。 事务执行失败时没有切回默认数据源 @Transactional 注解的方法意味着使用数据库事务执行方法中的 sql 操作,默认情况下当方法抛出不受检查异常时,事务会进行回滚,我所实...

2018-11-28 17:55:17 234 0

原创 MyBatis 缓存 - 上:一级缓存

在实际项目中,有些情况下相同的查询语句可能被重复执行,MyBatis 提供了一级缓存来优化这种情况,相同的查询 Sql 会命中一级缓存,直接返回,减少不必要的数据库查询提高性能。 实现原理 Mybatis 提供了 SqlSession 来方便使用者操作数据库,而正真执行数据库操作的是 Execut...

2018-11-19 11:46:28 71 0

原创 单体应用和服务化应用的一些思考

单体应用 单体应用整个项目代码都在同一个应用工程中,这种方式在早期可以有效提高开发效率,测试、部署和运维也比较方便。少量的开发人员就可以完成所有工作。然而随着业务规模、数据量的不断扩大,单体应用就会出现问题, 部署测试效率低下:每次修改了代码需要进行测试验证时必须将整个应用进行编译、打包以及部署...

2018-11-19 10:35:00 201 0

原创 Spring MVC 根据 controller 层方法入参和返回值动态生成日志 - 下 :借助 SpEL 或自定义的方式解析日志表达式

上一篇文章已经就如何获取到 controller 层方法的参数和返回值进行了详细分析,并且封装了 HandlerMethodPostProcessor 接口以便使用,接下来就实现业务需求:根据 controller 层方法的入参和返回值动态生成日志。 实现日志解析 实现思路是这样的:定义一个注解,...

2018-11-16 16:55:13 377 0

原创 Spring MVC 根据 controller 层方法入参和返回值动态生成日志 - 上 :寻找扩展点并进行封装

背景 需求是这样的:对网关层指定接口(url)的调用情况做日志记录,日志需要根据 controller 层方法的入参和返回值动态生成。 如果只是记录 url 的调用情况可以直接使用 HandlerInterceptor 实现,但需求中需要能够访问入参和返回值,虽然通过拦截器提供的接口也可以解析到请...

2018-11-16 16:02:17 918 0

原创 Docker 二:IDEA + Docker 插件创建镜像并运行 spring boot 项目

IDEA 上提供了 Docker integration 插件,可以很方便的管理镜像和容器,当然这些操作通过命令行也能完成,使用 IDEA 插件方式的另一个便利在于 IDEA 提供了 Docker 配套的 Configuration,可以一次性定义好操作序列,修改代码或资源后只需 Run/Debu...

2018-11-16 10:20:26 562 0

原创 Docker 一:入门

Docker 可以用来打包应用、依赖以及环境到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。 docker 两个关键的部分为容器和镜像,这两者的关系可以理解为 OOP 中类和对象的关系,容器作为对象,镜像作为类。Docker 镜像是用于创建 Docker 容器的模板,容器可以独立运...

2018-11-14 16:15:36 101 0

原创 解析配置文件自动装配 DataSource + AbstractRoutingDataSource + AOP 实现动态数据源 上:原理解析,解析数据源

spring boot 自动装配会通过 spring.datasource.*为我们自动装配数据源,所以想要动态的切换数据源,第一件事是配置数据源,其次是怎么切换?最后何时切换? 原理解析(使用 AbstractRoutingDataSource 实现) spring-jdbc 提供了 Abstr...

2018-11-13 17:16:22 363 1

原创 解析配置文件自动装配 DataSource + AbstractRoutingDataSource + AOP 实现动态数据源 下:配置动态数据源,AOP 进行使用

上篇文章中已经借助 DynamicDataSourceBuilder 类从配置文件中解析得到了默认数据源和动态数据源,接下来需要配置动态数据源的“本体”,并借助 AOP 动态的切换数据源。 配置动态数据源 AbstractRoutingDataSource 实现了 InitializingBean...

2018-11-13 17:14:39 289 0

原创 fastjson 始终将 null 对象以 "null " 的形式返回到前端引发的源码解析 - 上:从 DispatcherServlet 出发

背景 项目中使用 fastjson 将 spring MVC 返回结果输出为 json 格式数据,有个需求是 null 对象不输出,即前端不会接收到 "obj": null 形式的 json 数据,然而在进行如下的配置后, null 对象始终输出,因此以阅读源码...

2018-11-07 13:21:54 261 0

原创 fastjson 始终将 null 对象以 "null " 的形式返回到前端引发的源码解析 - 下:来到 fasjson 内部,消除疑惑

接上篇:fastjson 始终将 null 对象以 "null " 的形式返回到前端引发的源码解析 - 上:从 DispatcherServlet 出发 终于来到了 fastjson 内部。 FastJsonHttpMessageConverte...

2018-11-07 13:20:02 207 0

原创 从 HTTPServletRequest 中根据 User-Agent 获取访问设备信息

背景:根据 HttpServletRequest获取访问设备信息。 Http 协议请求头中的 User-Agent属性会将客户端设备的信息传递给服务器,这些信息包括客户端操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。 参考: 用户代理(User-Agent)...

2018-11-01 18:45:35 7168 1

原创 大型网站架构演化发展历程 - 下

1-5见上一篇博文:大型网站架构演化发展历程 - 上 6 使用 CDN 和反向代理加上网站响应 CDN 和反向代理的基本原理都是缓存,区别在于 CDN 不是在网络提供商的机房,使用户在请求网站服务时,可以从距离最近自己最近的网络提供商获取数据 而反向代理则部署在网络的中心机房,当用户请求到达中心...

2018-10-11 08:34:10 200 0

原创 大型网站架构演化发展历程 - 上

大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据。 1 初始阶段的网站架构 大型网站都是从小网站发展而来,也是从小型网站架构逐步演化而来。 此时应用程序、数据库、文件等所有资源都在一台服务器上。 2 应用服务和数据服务分离 随着网站的发展,越来越多的用户访问导致性能越来越差,越来越...

2018-10-08 08:24:31 159 0

提示
确定要删除当前文章?
取消 删除