Coder Social home page Coder Social logo

tigerb / easy-tips Goto Github PK

View Code? Open in Web Editor NEW
2.7K 164.0 700.0 38.7 MB

A little Tips in my Code Career with Go&PHP 🥳🥳🥳

Home Page: http://easy-tips.tigerb.cn

PHP 55.46% Shell 0.71% Dockerfile 0.57% HTML 0.14% Go 42.88% C 0.24%
php pattern php-patterns mysql redis sql golang go go-patterns linux-commands

easy-tips's Introduction

《PHPer、Gopher成长之路》V1.10

「全原创系列」

记录我在成为一名PHPer、Gopher路上的学习过程

php go mysql redis patterns algorithm data-structure network docker

English Version

版权申明

  • 未经版权所有者明确授权,禁止发行本手册及其被实质上修改的版本。
  • 未经版权所有者事先授权,禁止将此作品及其衍生作品以标准(纸质)书籍形式发行。

前言

基础不牢,地动山摇,谨以此句提醒自己。

备注

状态 含义
🈳️ 当前未开始总结
🚗 总结中
🧀️ 目前仅供参考未修正和发布
总结完毕
🔧 查漏补缺修改中

目录

测试用例

PHP设计模式

运行脚本: php patterns/[文件夹名称]/test.php

例如,

测试责任链模式: 运行 php patterns/chainOfResponsibility/test.php

运行结果:

请求5850c8354b298: 令牌校验通过~
请求5850c8354b298: 请求频率校验通过~
请求5850c8354b298: 参数校验通过~
请求5850c8354b298: 签名校验通过~
请求5850c8354b298: 权限校验通过~

PHP算法

运行脚本: php algorithm/test.php [算法名称|空获取列表]

例如,

测试冒泡排序: 运行 php algorithm/test.php bubble

运行结果:

==========================冒泡排序=========================
Array
(
    [0] => 11
    [1] => 67
    [2] => 3
    [3] => 121
    [4] => 71
    [5] => 6
    [6] => 100
    [7] => 45
    [8] => 2
)
=========上为初始值==================下为排序后值=============
Array
(
    [0] => 2
    [1] => 3
    [2] => 6
    [3] => 11
    [4] => 45
    [5] => 67
    [6] => 71
    [7] => 100
    [8] => 121
)

常见redis运用实现

运行脚本: php redis/test.php [名称|空获取列表]

例如,

测试悲观锁: 运行 php redis/test.php p-lock

运行结果:

执行count加1操作~

count值为:1

纠错

如果大家发现有什么不对的地方,可以发起一个issue或者pull request,我会及时纠正,THX~

补充:发起pull request的commit message请参考文章Commit message编写指南

英文版

因为国外开发者的要求和个人的时间有限,征集大家有兴趣的可以把本项目进行英文版翻译。希望国外的developer也可以受益于这个项目~

翻译文件认领申请:#36

赞赏

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

easy-tips's People

Contributors

0xaikang avatar akmumu avatar cmderq avatar cugblbs avatar dukeann avatar entimm avatar hidehalo avatar jealone avatar monkeywithacupcake avatar neetdai avatar ocoo avatar rjustice avatar snriud avatar taweisuode avatar tigerb avatar yangqi93 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easy-tips's Issues

常用 mysql 语句有点问题

整理的还挺全面的~
Mysql 常用语句里这个是不对的吧:

列出表:DESC TABLES;

列出表应该是 SHOW TABLES, 而查看表结构是 DESC table_name;

组件并发模式会出现 go协程阻塞积压

// Do 执行子组件
// ctx 业务上下文
// currentConponent 当前组件
// wg 父组件的waitgroup对象
func (bc *BaseConcurrencyComponent) Do(ctx *Context, currentConponent Component, wg *sync.WaitGroup) (err error) {
defer wg.Done()
// 初始化并发子组件channel
if bc.logicResChan == nil {
bc.logicResChan = make(chan interface{}, 1)
}

go currentConponent.BusinessLogicDo(bc.logicResChan)

select {
// 等待业务执行结果
case <-bc.logicResChan:
	// 业务执行结果
	fmt.Println(runFuncName(), "bc.BusinessLogicDo wait.done...")
	break
// 超时等待
case <-ctx.TimeoutCtx.Done():
	// 超时退出
	fmt.Println(runFuncName(), "bc.BusinessLogicDo timeout...")
	bc.Err = ErrConcurrencyComponentTimeout
	break
}
// 执行子组件
err = currentConponent.ChildsDo(ctx)
return

}

这个组件的并发设计中,子任务的执行是同时起生产者和消费者的,在消费者超时退出后,生产者(urrentConponent.BusinessLogicDo(bc.logicResChan))如果此时才获取到结果发送到消费者将会阻塞,这样会造成多go程阻塞,go程积压造成内存爆表。

我模仿写了一个伪代码:
func run(wg *sync.WaitGroup) {
defer wg.Done()
ch := make(chan string)

wg.Add(1)
go func() {
	time.Sleep(9 * time.Second)
            // 阻塞后死锁
	ch <- "work1"
}()

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

select {
case res := <-ch:
	fmt.Println("接收到任务", res)

case <-ctx.Done():
	fmt.Println("ctx err : ", ctx.Err())
	return
}

}

func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go run(&wg)
wg.Wait()

fmt.Println("success")

}

运行结果是go程阻塞死锁 :
ctx err : context deadline exceeded
fatal error: all goroutines are asleep - deadlock!

tcp/ip网络模型想补充下

TCP/IP
应用层(http/https/websocket/ftp...) => 定义:文本传输协议,主要传输数据为报文
|
传输层(tcp/udp) => 定义:端口,主要传输数据为包,再次中会实现分组交换或电路交换
|
网络层(ip) => 定义:IP,主要传输数据为数据帧,典型有arp协议,再此中会添加ip->mac映射关系,crc冗余校验帧完整性等
|
网络接口层(光缆/电缆/交换机/路由/终端...) => 定义:物理 主要传输数据为二进制比特流

冒泡排序

修改内层循环次数

/**
   * 冒泡排序
   *
   * @param  array $value 待排序数组
   * @return array
   */
  function bubble($value = [])
  {
      $length = count($value) - 1;
      // 外循环
      for ($j = 0; $j < $length; ++$j) {
          // 内循环
          for ($i = 0; $i < $length - $j; ++$i) {
              // 如果后一个值小于前一个值,则互换位置
              if ($value[$i + 1] < $value[$i]) {
                  $tmp = $value[$i + 1];
                  $value[$i + 1] = $value[$i];
                  $value[$i] = $tmp;
              }
          }
      }
      return $value;
  }
print_r(bubble([5,3,8,1,2]));

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 5
    [4] => 8
)

数据结构

请问,数据结构是打算这样写一个md文件去描述还是要上代码呢?

悲观锁执行超时处理

悲观锁的代码中如果已获得锁的程序执行时间超过过期时间,就会出现两个程序同时获得了锁,造成数据覆盖,俗称脑裂🙈,你觉得呢?

关于设计模式中单例模式的意见

如题,作者代码单例例子部分代码如下

  /**
   * 魔法方法
   * 禁止clone对象
   * 
   * @return string
   */
  public function __clone()
  {
    echo 'clone is forbidden';
  }

个人觉得可以直接将魔术方法__clone设为私有,当外部利用clone克隆对象直接抛出致命错误,如果如作者设为公有,clone还是可以克隆对象,打印一句话只能警告而已。

悲观锁

image
当超时时间小于当前时间,说明超时,应该解锁。

抽象工厂模式有误

抽象工厂模式中,一个工厂能创建一簇对象不是一类对象,见下面的UML图

image

拿原代码中的例子,plant工厂只能创造plant对象,Animal工厂只能创造Animal对象,不符合抽象工厂模式,只能算是工厂方法模式的嵌套,正确的的抽象工厂模式已提PR #20

php模板模式在php5.

Default value for parameters with a class type hint can only be NULL D:\www\easy-tips\template\SmsCompanyOne.php on line 32

单利模式

clone方法感觉还是修改为pirvate修饰比较好。

TIGERB/easy-tips/php/artisan.md 文件中关于使用匿名函数代码错误

class Two{
    function do(){
        echo 1111;
    }
}

class One
{
    private $closure;

    public function __construct(Closure $closure)
    {  
        $this->closure = $closure();
    }

    public function doSomething()
    {
        if (1) {
            // 用的时候再实例化
            // 实现懒加载
            $instance = $this->closure;
            $instance->do();
        }
         
    }
}
 //或者 
class One
{
    private $closure;

    public function __construct(Closure $closure)
    {  
        $this->closure = $closure;
    }

    public function doSomething()
    {
        if (1) {
            // 用的时候再实例化
            // 实现懒加载
            $instance = $this->closure;
            $instance()->do();
        }
         
    }
}

$instance = new One(function () {
    // 类One外部依赖了类Two
    return new Two();
});
$instance->doSomething();//1111

English version

Hello, I think it's very popular repo is China(?). But I think people around the world also want to get information from it. Can you please translate this thing to English

原型模式的疑问

按我的理解,原型模式中依赖getPrototype()方法得到的2个对象,应该是内存分开的不同对象。
不论是否是深拷贝,Prototype类里用instance来返回对象,而不是每次都返回clone,是有问题的吧?

use prototype\Prototype;

// 创建一个原型对象
$prototype = new Prototype();

// 获取一个原型的clone
$prototypeCloneOne = $prototype->getPrototype();
$prototypeCloneOne->_name = 'one';
$prototypeCloneOne->getName();

// 获取一个原型的clone
$prototypeCloneTwo = $prototype->getPrototype();
$prototypeCloneTwo->_name = 'two';
$prototypeCloneTwo->getName();
$prototypeCloneOne->getName();
//输出 one two two 说明2个对象其实是一个

Magic method access test

Hi, just by brief looking at your code I noticed that you actually measure time with an instantiation of an object. That could possibly distort the results quite a bit since instantiation of an object is usually much more expensive then accessing method.
Meaning that if lets say creating new instance needs 100 units of time, getting property without magic method takes 1 and with magic method takes 10 your results will be 101 units without magic method and 110 with magic method.
This way it looks like it is only about 10% faster. But if you do it without the instantiation you will get 1 to 10 which is actually 10x faster, in percent its 1000%.
Because of that I would like to ask you to either remake your test and do it again.

有歧义的变量命名

麻烦将patterns/decorator/DecoratorBrand.php文件中的phone字符串批量替换成shoes;
另外,不得不说,设计模式章节提供的代码很赞,感谢🙏

设计模式

设计模式总结的不错,说明文档能详细点更好了

Why get & getset twice to get locktime?

How can I do like this?
$timeout = 500; do { $microtime = explode(' ', microtime()); $microtime = (int)round(($microtime[1]+$microtime[0])*1000, 0); $microtimeout = $microtime+$timeout+1; // 上锁 $isLock = $redis->setnx('lock.count', $microtimeout); if (!$isLock) { // 超时判断 $previousTime = $redis->getset('lock.count', $microtimeout); if ($previousTime <= $microtime) { // 超时 break; } } } while (!$isLock);

反馈个错误

builder/PhoneInterface 接口的方法不能是private,不过这个接口最后居然没有用到是什么鬼

[英文版翻译申请]

申请格式如下:

文件名-githubID

希望国外的developer也可以受益于这个项目~

类私有成员属性,建议下划线小写开头驼峰

符合PSR-1/PSR-2的PHP编程规范实例
easy-tips/standard.php里,提到
/**

  • 属性描述.
  • @var string
    */
    private $_privateNameTest = ''; // 类私有成员属性,建议下划线小写开头驼峰

psr-2标准里,是不应该有下划线的。

`
4.2. Properties

Visibility MUST be declared on all properties.

The var keyword MUST NOT be used to declare a property.

There MUST NOT be more than one property declared per statement.

Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.

A property declaration looks like the following.
`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.