x1aoguan

x1aoguan 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

x1aoguan 关注了用户 · 2019-05-25

她说她喜欢浪丶 @shopex

关注 76

x1aoguan 赞了文章 · 2019-02-25

PHP冒泡排序(Bubble Sort)算法详解

前言

冒泡排序大概的意思是依次比较相邻的两个数,然后根据大小做出排序,直至最后两位数。由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。但其实在实际过程中也可以根据自己需要反过来用,大树往前放,小数往后放。

实战

直接上代码:

<?php
/**
 * 冒泡排序算法示例
 */

// 这里以一维数组做演示
$demo_array = array(23,15,43,25,54,2,6,82,11,5,21,32,65);

// 第一层for循环可以理解为从数组中键为0开始循环到最后一个
for ($i=0;$i<count($demo_array);$i++) {
    // 第二层将从键为$i的地方循环到数组最后
    for ($j=$i+1;$j<count($demo_array);$j++) {
        // 比较数组中相邻两个值的大小
        if ($demo_array[$i] > $demo_array[$j]) {
            $tmp            = $demo_array[$i]; // 这里的tmp是临时变量
            $demo_array[$i] = $demo_array[$j]; // 第一次更换位置
            $demo_array[$j] = $tmp;            // 完成位置互换
        }
    }
}

// 打印结果集
echo '<pre>';
var_dump($demo_array);
echo '</pre>';

运行结果:

array(13) {
  [0]=>
  int(2)
  [1]=>
  int(5)
  [2]=>
  int(6)
  [3]=>
  int(11)
  [4]=>
  int(15)
  [5]=>
  int(21)
  [6]=>
  int(23)
  [7]=>
  int(25)
  [8]=>
  int(32)
  [9]=>
  int(43)
  [10]=>
  int(54)
  [11]=>
  int(65)
  [12]=>
  int(82)
}

从上面结果中,我们可以看出,数组中键值顺序已经被改变,排序成功。

如果说上面的算法是将数组中的键值按照值得大小从小到大进行排序,那么反之从大到小怎么操作呢?

很简单,只要修改一个比较符号就可以了,如下:

<?php
/**
 * 冒泡排序算法示例
 */

// 这里以一维数组做演示
$demo_array = array(23,15,43,25,54,2,6,82,11,5,21,32,65);

// 第一层for循环可以理解为从数组中键为0开始循环到最后一个
for ($i=0;$i<count($demo_array);$i++) {
    // 第二层将从键为$i的地方循环到数组最后
    for ($j=$i+1;$j<count($demo_array);$j++) {
        // 比较数组中相邻两个值的大小
        if ($demo_array[$i] < $demo_array[$j]) {
            $tmp            = $demo_array[$i]; // 这里的tmp是临时变量
            $demo_array[$i] = $demo_array[$j]; // 第一次更换位置
            $demo_array[$j] = $tmp;            // 完成位置互换
        }
    }
}

// 打印结果集
echo '<pre>';
var_dump($demo_array);
echo '</pre>';

运行结果:

array(13) {
  [0]=>
  int(82)
  [1]=>
  int(65)
  [2]=>
  int(54)
  [3]=>
  int(43)
  [4]=>
  int(32)
  [5]=>
  int(25)
  [6]=>
  int(23)
  [7]=>
  int(21)
  [8]=>
  int(15)
  [9]=>
  int(11)
  [10]=>
  int(6)
  [11]=>
  int(5)
  [12]=>
  int(2)
}

就这样,轻松地改变了顺序。

延伸

如果仔细观察以上代码,就会发现有一个地方值得关注,就是互换变量值得地方。没错,这也是冒泡中的核心要点,这个技巧掌握了,以后同样可以用到其他地方。

这里我们就稍微聊聊这个。

原理:

现在有A、B两个变量,需求是将其值互换。

看到题目,我们首先可能会想到直接赋值,但是如果直接赋值,不论先将谁赋值给谁,其中一个必定会被覆盖,由此我们可以想出再弄出第三个变量C,暂时存储A或B中的值,这样就可以达到需求目标了。

$c = $a; // 暂存
$a = $b; // b给a
$b = $c; // 暂存的a值再给b

注:其实不需要第三个变量,也是可以达到互换A、B变量值的,可以借助substr()、str_replace()等方法,这里因为是介绍冒泡排序的,所以不过多延伸了。

总结

关于冒泡排序的就这么多,归纳起来,主要就是两点:

  1. 循环比较

  2. 交换键值

能够完成这两点,基本就OK了,当然,关于冒泡排序的算法还有很多,这里只是其中一种,有兴趣的同学可以自己研究下。

查看原文

赞 6 收藏 6 评论 2

x1aoguan 收藏了文章 · 2019-02-20

PHP新手开发者的路线建议

前言

在前天(2018-08-02)已经发布了PHP 7.3.0.beta1 Released

如果你还没有使用 PHP7 ,那真的很遗憾。2018 年 PHP 开发者应该熟练使用 PHP7,并且知道版本更新内容。

依赖管理

如果你在想使用一个扩展包时,还在下载源码,并尝试修改命名空间来嵌入你的项目中,你应该改变了,试试使用 Composer 进行依赖管理。
现在的扩展包基本都支持 Composer 安装,你也可以尝试在 Packagist 上发布一个自己的包,可以对包管理的理解加深

使用优秀的包

Guzzle

Guzzle 是一个 PHP 的 HTTP 客户端,用来轻而易举地发送请求,并集成到我们的 WEB 服务上。
它的优点有构建查询语句、POST 请求、分流上传下载大文件、使用 HTTP cookies、上传 JSON 数据等等。
阅读:《Guzzle中文文档》

Carbon

Carbon 是一个继承于 PHP 的 DateTime 类的时间类,让用法更加人性化
可以让你在处理时间时事半功倍,可以看看我以前写的 《Carbon便捷处理时间》

NOSQL

MongoDB

MongoDB 是一个基于分布式文件存储的数据库。它是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
以 MongoDB 作为非关系型数据库的开始非常好,可以看 《PHP7操作MongoDB》

Redis

Redis 是一个可基于内存亦可持久化的日志型、Key-Value 数据库,用于需求不高的队列,经常用来实现缓存

容器

Docker 是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。
对开发和运维人员来说,最希望的就是一次性创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 DockerFile 来进行镜像构建,并结合 持续集成系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署。
而使用 DockerFile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
Docker 入门可以从这里开始 《什么是Docker》

持续集成

持续集成 CI(Continuous integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
集成工具很多,流行的有 JenkinsTravis CI
《使用AppVeyor持续集成本博客》

代码风格

良好的代码规范可以提高代码可读性,降低团队沟通维护成本。
PSR(PHP Standard Recommendations)是 PHP 标准规范 ,是 PHP 开发的实践标准。
其中 PSR-1PSR-2 是编码风格规范。
StyleCI 提供 PHP 代码风格持续集成服务

单元测试

测试对于程序员的重要性不言而喻
PHPUnit 是 PHP 单元测试包,由 Sebastian Bergmann 开发
Laravel 有开箱即用的测试: 《在Laravel中测试》

设计模式

在 Laravel 中你可能会接触到 依赖注入Facade服务容器等概念,可以扩展阅读一波,
包括创建模式(Creational Patterns)、架构模式(Structural Patterns)、行为模式(Behavioral Patterns)

其它

PHP 代码简洁之道 ( PHP Clean Code)

MySQL 是 PHP 开发者接触最多的数据库了,这篇文章讲解了通过分库、分表等方式来《MySQL优化》

需要了解的《什么是 JWT》

数据结构与算法 是一个程序员必需的内功(PHPer 对于这方面要自己判断)

当然,在技术愈加熟练后,掌握一门新的语言,或是往全栈发展(利弊需要自己分析)也是很好的。
对 Web 开发者来说语言推荐 PythonGolang ,全栈的选择非常多,推荐热门的 Laravel+Vue.js+ElementUI
roadmap

查看原文

x1aoguan 关注了用户 · 2019-02-20

大梦成空 @liluoao

关注 52

x1aoguan 赞了文章 · 2017-08-10

两年PHPer聊下架构

前言

2016年很有幸参与了公司内部系统架构3.0的升级,我们把公司的业务进行了四大板块的拆分,分别是应用服务内容服务电商服务支付服务。其他和业务无关的功能拆分到了基础服务,为全公司的业务提供基础服务能力,例如短信、app推送、微信模板消息、图片上传等服务能力。我们还建立我们自己的网关服务,对外提供了统一的服务访问地址。自此之后我对架构的发展和演变也产生了浓厚的兴趣和想法,但是目前接触的有限,与大公司的业务复杂度比还是有很大的差距,一年过去了但是还是想把自己经历的做个总结和自己的想法表达出来,同时也希望大牛们可以指导一番。

备注:“系统架构”是一个很大的范畴,我这里只是把我所经历的小型创业公司的一次架构升级做个分享。

实际架构

直接上最终的架构图,如下:
http://tigerb.cn/imgs/wecook.svg

  • 网关: 企业服务总线,对外暴露统一的资源域,把实际业务中接口中都涉及签名鉴权等一系列鉴权逻辑抽到网关,其次为未来开放第三方服务准备。
  • 协议层: 组装各个服务的结果,把http协议的请求转换成rpc请求(这里我们使用的是phprpc)。
  • 业务服务: 实际的业务方,各种商业逻辑,如图所示。
  • 基础服务: 基础服务能力,和实际商业逻辑无关。

理论架构

上面的架构有什么问题,协议层产生了重度的耦合,协议层耦合各个业务方的逻辑。虽然系统拆分的原则是尽可能的不产生依赖,但是有些还是不可避免的。

三方面:

  • ①透传:明明协议层不需对逻辑做特殊的处理,协议层却要实现一遍代码,增加了工作量
  • ②组装:协议层调用各个服务的组装数据的时候,其实还是下意识涉及了部分业务逻辑
  • ③html5应用直接调用了协议层,没有正真的实现企业总线

其次我认为最恐怖的是负责协议层开发的同学被坑了,写透传的代码没技术含量而且是重复性的工作,涉及数据组装的,还得需要简单的了解各个服务逻辑。从而这个协议层就成了耦合的重灾区,所以我根据自己的想法改进了这个架构设计,架构图如下:
http://tigerb.cn/imgs/wecook-maybe.svg

  • 改进一:html5应用也统一走网关,html5应用的请求执行对应的网关策略
  • 改进二:下移协议层到网关,网关直接进行协议转化
  • 改进三:业务服务直接调用所依赖的服务,这样我们的服务就可以业务直接通过网关暴露出去

更进一步的架构

然而上面的架构有什么问题?业务服务内部互相依赖,一旦未来服务拆分的粒度越来越细,以及业务的新增,这些依赖就成了一个网状结构,慢慢变的不可维护。接着我改进了这个架构图,再进一步,应该是这样的:

http://tigerb.cn/imgs/wecook-my.svg

我把之前服务之间直接的互相依赖转变成了统一对中间件的依赖,这样未来再多的服务整个系统架构都是清晰的。

中间件具备的能力:

  • 同步调用:直接通过对中间件的调用完成对服务的直接调用
  • 异步调用:通过对中间件的调用完成对服务的异步调用

然而,这里有个最大的问题就是所有压力都集中到了中间件,保证中间件的高可用又成为了一个很大的问题。

结语

除了上述的实际架构是真实的生产环境架构,其他的为我个人目前的想法,目前个人未真实在生产环境实现。最后说说实际踩的坑:

  • 服务超时:网关设置了熔断时间,导致服务刚提交事务却被终端请求导致的数据一致性问题。再例如,刚发送短信成功,却被中断请求,客户端返回失败,实际却接收到短信。
  • 分布式事务:跨服务调用使得事务的提交不像以前那么简单
  • 如果开发人少,导致一个人维护多个项目
  • 增加了部署难度
  • 追踪问题难度加深(我们引入了requestId追踪整个链路的调用过程)
Easy PHP:一个极速轻量级的PHP全栈框架

扫面下方二维码关注我的技术公众号,及时为大家推送我的原创技术分享

图片描述

查看原文

赞 39 收藏 155 评论 26

认证与成就

  • 获得 0 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 1 枚银徽章, 获得 0 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-08-10
个人主页被 73 人浏览