i++是原子操作吗?

i++ 是原子操作吗? 不是, i++ 要完成的操作要先读取变量 i 的值, 对这个值加 1, 再把结果保存到 i 中. 所以不是原子操作. 我们来看下面的代码 这段代码是启动 10 个线程, 每个线程对 count 执行 10 万次自增操作, 直观上来看最后 count 的结果是 100 万, 但因为自增操作不是原子性的, 所以最终的结果每次都会不一样, 会有协程做重复操作. 那应该怎么解决这个问题呢? 并发资源的读取问题最直接的解决方法就是加锁. 改良后如下:

January 17, 2021 · 1 min · max

Gerrit概念说明及使用

Gerrit介绍 Gerrit简介 Gerrit, 一种开放源代码的代码审查软件, 使用网页界面. 利用网页浏览器, 同一个团队的软件开发者, 可以相互审阅彼此修改后的代码, 决定是否能够提交, 回退或是继续修改. 它使用版本控制系统Git作为底层. 它分支自Rietveld, 作者为Google公司的Shawn Pearce, 原先是为了管理Android项目而产生. 这个软件的名称, 来自于荷兰家具设计师赫里特·里特费尔德(Gerrit Rietveld). 因为对访问控制表(ACL)相关的修正, 没有被集成进Rietveld, 之后Gerrit就由Rietveld分支出来, 形成独立软件项目. 最早它是由Python写成, 在第二版后, 改成用Java与SQL. 使用Google Web Toolkit来产生前端的JavaScript. 为什么需要Gerrit 首先, 代码审查可以帮助程序员了解系统功能, 从整体掌控代码质量, 其次, 通过代码审核可以及时止损, 构建更加健壮的系统代码. 代码审核的建议(来自程序员客栈) 对事不对人, 大家都是同事, 在一个团队工作和气最重要. 不要在Code Review中说"你写的什么垃圾"这种话, 你可以说"这个变量名不是很好理解, 咱们换成xxx是不是更好" 每个Review至少给一条正面评价. Gerrit中有对代码点赞的功能, 可以时不时的使用一下. 保证发布的代码和评审意见的可读性. 用工具进行基础问题的自动化检查. 用Tab还是空格, 用两个空格还是四个空格, 缩进风格是使用K&R还是Allman. 这些问题可以使用php code sniffer解决, 团队应该把精力放在代码规范, 代码性能优化等地方. 全员参加Code Review, 并设定各部分负责人. 每个代码PR(Pull Request)内容一定要少....

September 23, 2020 · 2 min · max

为什么没有使用索引?

为什么没有用索引? 已知表 a 数据总量是 40w, 根据时间范围过滤出最近 7 天的数据, 语句如下: explain SELECT `question_id`, `student_id`, `teacher_id`, `question_type`, `question_step`, `question_no`, `level`, `class_id`, `lesson_id`, `teacher_get_at`, `teacher_set_at`, `status`, `teacher_from`, `wrong_reason_id`, `created_at`, `submit_time` FROM `answer_records` WHERE `updated_at` BETWEEN '2020-07-14+00:00:00' AND '2020-07-21+00:00:00' ORDER BY `created_at` DESC; 从 explain 返回的数据来看, 这条语句并没有使用到索引, 而且 mysql 进行了全表的扫描, 这个原因就是我们要查询的数据太多了. 因为 innodb 引擎会在检索索引后进行回表的操作, mysql 觉得你查询的数据这么多, 我一个个回表的这点时间都可以把全表扫一次了, 我就没必要用索引再去回表了, 所以就会导致这个索引没有用到. 那我们就想用索引, 应该怎么办呢? FROM `answer_records` FORCE INDEX(rqx) 在业务层面的话, 如果时间范围比较大, 可以分批次查询, 这样就会快一点, 如果是频繁需要此类操作的话, 还是建议将时间戳提早设计进表结构里, 通过 int 类型的时间戳进行范围查找和排序会事半功倍

September 23, 2020 · 1 min · max

在图片上添加文字或图片

intervention/image 这是一个第三方扩展, 用来处理图片的, 功能特别强大, 可以 cover 我们这篇文章提到的需求 安装文档: http://image.intervention.io/getting_started/installation 我们首先在项目中引入这个包: $ composer require intervention/image 其次, laravel 中需要发布配置文件: php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5" lumen 中需要修改 bootstrap.php, 在当中手动注册 $app->register(\Intervention\Image\ImageServiceProviderLumen::class); 该扩展默认使用的是 GD 库, 如果你想用 Imagick 扩展需要修改文件, config/image.php <?php return [ 'driver' => 'imagick' ]; 如果你不想要每次 use 都使用全路径, 可以按照官方所述将 Image 关键字写入 alias 中 Laravel: config/app.php $providers: Intervention\Image\ImageServiceProvider::class $aliases: 'Image' => Intervention\Image\Facades\Image::class Lumen: bootstrap/app.php $app->withAliases(array('Intervention\Image\Facades\Image' => 'Image')); 具体使用 use Image; public function deal() { $image = Image::make(public_path() ....

January 10, 2020 · 1 min · max

比较两个字符串是否相等

有时候, 当用户传入一个字符串时, 你可能会需要拿着这个字符串和最终结果相对比, 如果我们使用 == 号来比较两个字符串, 可能会产生时序攻击. 'abcdef' == $req->code 也就是说, == 号在判断两个字符串相等时, 会一位一位的判断, 如果遇到哪一位不一样, 就返回错误, 这样根据服务器运算速度, 就可以一位一位的猜出最终的结果. php 官方提供了避免时序攻击的字符串比较函数, 就是 hash_equals 无论两个字符串是否相等, 本函数的时间消耗是恒定的. 文档如下: https://www.php.net/manual/zh/function.hash-equals.php

January 10, 2020 · 1 min · max

Homestead完整的切换php版本

相信大多数人搜到的都是这篇文章 https://learnku.com/articles/16881 文章中说, 使用 homestead 自带的工具 update-alternatives 进行切换就可以了, 但是我在使用后 php 的版本是切换了, 但是 pecl 安装扩展的时候安装的还是20170817目录, 这是 php7.2 的扩展包默认目录, 使用 php-config 看的时候也是 php7.2 如何把phpize, pecl, php-config 都切换为 php7.1 呢? 请看下面 sudo update-alternatives --set php /usr/bin/php7.1 sudo update-alternatives --set phar /usr/bin/phar7.1 sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.1 sudo update-alternatives --set phpize /usr/bin/phpize7.1 sudo update-alternatives --set php-config /usr/bin/php-config7.1 如果你在切换之前装了错误的扩展包到其他版本的目录下, 这样切换完之后卸载重新装, 就 ok 了

January 10, 2020 · 1 min · max

mojave下使用pyenv安装python3出错的问题

使用pyenv安装python3时出现如下报错 按照提示来看,好像是在提示我没有安装zlib库,但是我已经装了,没办法,google一下吧. (如果你因为没有安装zlib库而产生这个问题, 那就好办了, 直接brew install zlib) google搜索到的解决方案大都是要安装xcode命令行工具 xcode-select --install 这个我也安装了, 不安装的话啥也干不了啊 最后解决方案 查看一下xcode-select -v的版本 这个版本的xcode-select 在默认情况下不包含Mojave SDK的头文件的,需要手动安装,mojave采用了新的SDK,关于新SDK的解释,官方的文档在这里 https://developer.apple.com/macos/whats-new/ 接下来,我手动安装了新的SDK头文件,解决完毕 sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

February 26, 2019 · 1 min · max

redis中的SDS数据结构

SDS(Simple Dynamic String)简单动态字符串 在Redis中可修改的字符串值都是采用的SDS数据结构, 而不可修改的都采用了C字符串 SDS的结构 有三个基本变量 free 纪录buf数组中未使用字节的数量 len 纪录buf数组中已使用字节的数量, 等于SDS所保存字符串的长度 buf 字节数组, 用于保存字符串(二进制) 为什么采用SDS SDS是基于C字符串结构的缺点优化后的产物, 因为采用C字符串的方式会有以下一些问题: 获取字符串长度需要遍历字符串获取, 将需要O(N)的时间复杂度 C字符串会有缓冲区溢出的问题 一旦修改字符串操作发生就会重新分配内存, 修改N次就分配N次 所以, 基于以上问题SDS结构的优点也显而易见了, 如下: 因为结构体中标记了字符串长度, 所以获取长度的时间复杂度变成了O(1) SDS的API中对内存分配的机制杜绝了缓冲区溢出的问题 同样, API中的操作也减少了修改字符串长度时所需的内存重分配次数 二进制安全 兼容部分C字符串函数 内存分配机制 空间预分配 在字符串增长操作中有两种情况来预分配空间 第一种是修改后的长度(len的值)小于1MB的情况下, free的值会和len的值相同, 来做到减少内存分配次数, 预分配以后可能会使用到的空间 第二种是修改后的长度大于1MB的情况下, free的值会多修改为1MB, 也就是在原来基础上多出1MB的未使用空间 惰性空间释放 在字符串缩短操作的时候, 不会将释放的空间马上回收, 而是会写入到free中, 将缩短的长度标记为未使用空间为将来可能会使用的字符串预留位置。SDS中也有相应的API, 可以在需要时真正释放这部分空间。

February 26, 2019 · 1 min · max

rebase和merge的区别

变基 找了一大圈, 还是官方的解释最好, 贴出来自己看吧, “变基"这个名字起的很好, 文档中的"重新播放"的解释也相当生动 https://git-scm.com/book/zh/v2/Git-分支-变基

February 24, 2019 · 1 min · max

cgi, fastcgi, php-cgi, php-fpm的关系

cgi 通用网关接口, Common Gateway Interface, CGI是Web服务器运行时外部程序的规范, 按CGI编写的程序可以扩展服务器功能. 所以, 广义上的cgi是一种接口标准, 不是字面意义上的接口. 狭义上, cgi就是cgi程序, 运行在服务器上, 提供同客户端HTML页面的接口. 绝大多数的cgi程序被用来解释处理来自表单的输入信息, 并在服务器产生相应的处理, 或将相应的信息反馈给浏览器, cgi程序使网页具有交互功能. cgi程序处理步骤: 通过Internet把用户请求送到web服务器. web服务器接受用户请求并交给CGI程序处理. CGI程序把处理结果传送给web服务器. web服务器把结果送回到用户. fastcgi 快速通用网关接口, Fast Common Gateway Interface, CGI有很多缺点, 每接收一个请求就要fork一个进程处理, 只能接收一个请求作出一个响应, 请求结束后该进程就会结束. 而fastcgi会事先启动起来, 作为一个cgi的管理服务器存在, 使用进程/线程池来处理一连串的请求. fastcgi程序处理步骤: web服务器启动时载入fastcgi进程管理器 fastcgi自身初始化, 启动多个cgi解释器进程并等待来自web server的请求 当请求来到web服务器时, web服务器通过socket请求fastcgi进程管理器, fastcgi进程管理器选择并连接到一个cgi解释器, web服务器将cgi环境变量和标准输入发送到fastcgi子进程 fastcgi子进程处理请求完成后将标准输出和错误从同一连接返回给web服务器, 当fastcgi子进程结束后请求便结束.fastcgi子进程接着等待处理来自fastcgi进程管理器的下一个连接. php-cgi php实现的cgi程序 php-fpm php实现的fastcgi程序

February 21, 2019 · 1 min · max