zoukankan      html  css  js  c++  java
  • qxx 项目总结

    一、账号池功能

    1. 右边注释添加格式

    private $client; // Jyeoo的接口

    2. 将一些配置放到某个配置文件中,然后通过加载配置环境,来获取相关的变量

    app()->configure(xxx);
    $this->config = config(xxx);

    3. app->configure()的加载过程

    function app($make = null)
    {
        if (is_null($make)) {
            return Container::getInstance();
        }
    
        return Container::getInstance()->make($make);
    }
    public function configure($name)
    {
        if (isset($this->loadedConfigurations[$name])) {
            return;
        }
    
        $this->loadedConfigurations[$name] = true;
    
        $path = $this->getConfigurationPath($name);
    
        if ($path) {
            $this->make('config')->set($name, require $path);
        }
    }

    4. 功能要写单元测试,postman测数据测得并不准。

    5. 写代码的时候要考虑到查询数据库的次数,避免懒查询:就是查询的次数特别的多。

    6. 把自己以前写算法的劲头拿出来写代码,考虑代码的效率和可读性。

    7. 使用面向对象的思路来为每个类定义它的属性值。

    Class JyeooAccount extends Model
    {
        const IS_USING_YES = 1;
        const IS_USING_NO = 2;
    }

    8. 避免资源抢占,同时尝试三次抢占。

     // 2.redis中没值,就从资源池中选择,抢占
     $retryTimes = 0;
     while ($retryTimes++ < 3) {
           $jyeooAccount = JyeooAccount::query()
                 ->inRandomOrder()
                 ->where('is_using', JyeooAccount::IS_USING_NO)
                 ->first();
           if (empty($jyeooAccount)) {
                 break;
           }
           $result = JyeooAccount::query()
                 ->where('id', $jyeooAccount->id)
                 ->where('is_using', JyeooAccount::IS_USING_NO)
                 ->update([
                     'is_using' => JyeooAccount::IS_USING_YES,
                     'deadline' => $timeStamp,
                     'usage_time' => $jyeooAccount->usage_time+1
                 ]);
            if ($result) {
                 $accountId = $jyeooAccount->teacher_id;
                 break;
            }
     }

    9. 变量名要统一,别到最后自己看不懂自己的变量名了,这样就很容易出bug,而且测试也不好测出因变量名出错而出现的bug。

    10. if......else.....判断 尽量嵌套的层级要少些,多数情况下就是通过if判断某些特殊的情况,对这些特殊的情况进行特殊的处理,然后其余的情况走大逻辑。

    11. 账号随机获取

    // 如果账号已经存在,那么就重新获取;
    if (!is_null($jyeooAccount)) {
          $min = JyeooAccount::query()
              ->max('teacher_id');
          $teacherId = random_int($min, $min + 1000);
    }

    12. 重要的数据库写操作要用到事务

    try{
          $timeStamp = Carbon::now()->addMinutes($this->config['cacheMinute'])->timestamp;
          DB::beginTransaction();
          $newJyeooAccount = new JyeooAccount();
          $newJyeooAccount->teacher_id = $teacherId;
          $newJyeooAccount->is_using = JyeooAccount::IS_USING_YES;
          $newJyeooAccount->deadline = $timeStamp;
          $newJyeooAccount->usage_time = 1;
          $newJyeooAccount->save();
          DB::commit();
    } catch (Exception $e) {
          Log::error($e);
          DB::rollback();
    }

    13. 账号池通知预警,10分钟通知一次,而且要判断使用了多少剩余多少

    if ($usedNum >= $warningNum) {
      $cacheKey = 'xxxxxxx';
      if (!Cache::has($cacheKey)) {
             $message = sprintf("菁优网账号池预警,已用帐号:%d,帐号池数量:%d", $usedNum, $totalNum);
             $token = $this->config['dingTalkToken'];
             $dingTalk = app(DingTalk::class);
             $dingTalk->setToken($token)->sendTextMessage($message);
             Cache::put($cacheKey, 1, 10); // 10分钟只通知一次
       }
    }

    14. 像发送请求这个东西,可以放到一个类里,然后通过调用这个类中的方法,这样可以做好封装,对用户黑盒。

    $dingTalk = app(DingTalk::class);
    $dingTalk->setToken($token)->sendTextMessage($message);

    15. 给钉钉聊天群发送信息

    class DingTalk
    {
        private $token;
    
        private $url = 'https://oapi.dingtalk.com/robot/send';
    
        public function __construct($token = '')
        {
            if (!empty($token)) {
                $this->token = $token;
            }
        }
    
        public function sendTextMessage($message)
        {
            $data = array('msgtype' => 'text', 'text' => array('content' => $message));
            $data_string = json_encode($data);
            $url = $this->url . '?access_token=' . $this->token;
            return $this->httpRequest($url, $data_string);
        }
    
        public function setToken($token)
        {
            $this->token = $token;
            return $this;
        }
    
        /**
         * 发送curl请求
         *
         * @param $remote_server
         * @param $post_string
         * @return mixed
         */
        private function httpRequest($remote_server, $post_string)
        {
            $env = app()->environment();
            if ($env != 'production') {
                Log::info('SKIP_SEND_DING_TALK_MESSAGE', [$remote_server, $post_string]);
                return false;
            }
    
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $remote_server);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
            // 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
            curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
            $data = curl_exec($ch);
            curl_close($ch);
    
            return $data;
        }
    }

    16. laravel自动创建日志。日志功能很重要,和高手的差距之一就是通过日志排查错误。而且自己在写日志的时候,一定要能知道,谁,在哪,什么时候,事情,事情的结果。就跟记叙文一样

    use AppConsoleCommandsLogTrait;
    use LogTrait;
    $this->log($result, $teachingMaterial->toArray());
    
    public function printProgress()
    {
         $this->info(sprintf(
             "上传进度:%.2f%%(%d/%d), 成功:%d 失败:%d",
             $this->finishNum / $this->totalNum * 100,
             $this->finishNum,
             $this->totalNum,
             $this->successNum,
             $this->failNum
         ));
    }

    17. 把任务放到队列中,当任务失败的时候,队列可以尝试重新执行,6666666。

    18. while循环往往会比递归的效率更高,所以有时候为了提高系统的效率就使用while。

    二、laravel相关知识点

    19. firstOrCreat、updateorCreate

    20. whereIn一次查询替换where数组,能省好多次查询。

    21. 懒加载功能,是指在查询的过程中,一次性把与其相关的数据查询出来。具体如下:

    public function childFiles()
    {
         if ($this->type == 1) {
             return $this->hasMany(TeachingMaterialModel::class, 'father_id');
         }
    
         return $this->hasMany(LectureNoteModel::class, 'father_id');
    }
    
    public function childCatalogues()
    {
         return $this->hasMany(CatalogueModel::class, 'father_id');
    }

    22. 方法

        /**
         *
         * $instance->is_empty
         *
         * @return bool
         */
        public function getIsEmptyAttribute()
        {
            if (count($this->childFiles) > 0) {
                return false;
            }
    
            return true;
        }
    
        public function getCatalogueEmptyAttribute()
        {
            if (count($this->childCatalogues) > 0) {
                return false;
            }
    
            return true;
        }

    23. 读取一条随机数

    User::inRandomOrder()->first();

     24. 获取某个时间点的时间戳

    echo Carbon::now()->addDays(25); //2016-11-09 14:00:01
    echo Carbon::now()->addWeeks(3); //2016-11-05 14:00:01
    echo Carbon::now()->addHours(25); //2016-10-16 15:00:01
    echo Carbon::now()->subHours(2); //2016-10-15 12:00:01
    echo Carbon::now()->addHours(2)->addMinutes(12); //2016-10-15 16:12:01
    echo Carbon::now()->modify('+15 days'); //2016-10-30 14:00:01
    echo Carbon::now()->modify('-2 days'); //2016-10-13 14:00:01

    $time = Carbon::now()->timestamp;

    1. // 直接使用字符串
    2. echo Carbon::now('Europe/London'); //2016-10-14 20:21:20
    3. // 或者
    4. echo Carbon::now(new DateTimeZone('Europe/London'));
    
    
    1. echo Carbon::now(); // 2016-10-14 15:18:34
    2. echo Carbon::today(); // 2016-10-14 00:00:00
    3. echo Carbon::tomorrow('Europe/London'); // 2016-10-14 00:00:00
    4. echo Carbon::yesterday();

      //要想获取字符串类型的日期,可以使用下面的代码:

    1. echo Carbon::today()->toDateTimeString();
    2. echo Carbon::yesterday()->toDateTimeString();
    3. echo Carbon::tomorrow()->toDateTimeString();

      

      //可以使用 parse 方法解析任何顺序和类型的日期(结果为 Carbon 类型的日期时间对象):

    1. echo Carbon::parse('2016-10-15')->toDateTimeString(); //2016-10-15 00:00:00
    2. echo Carbon::parse('2016-10-15')->toDateTimeString(); //2016-10-15 00:00:00
    3. echo Carbon::parse('2016-10-15 00:10:25')->toDateTimeString(); //2016-10-15 00:10:25
    4.  
    5. echo Carbon::parse('today')->toDateTimeString(); //2016-10-15 00:00:00
    6. echo Carbon::parse('yesterday')->toDateTimeString(); //2016-10-14 00:00:00
    7. echo Carbon::parse('tomorrow')->toDateTimeString(); //2016-10-16 00:00:00
    8. echo Carbon::parse('2 days ago')->toDateTimeString(); //2016-10-13 20:49:53
    9. echo Carbon::parse('+3 days')->toDateTimeString(); //2016-10-18 20:49:53
    10. echo Carbon::parse('+2 weeks')->toDateTimeString(); //2016-10-29 20:49:53
    11. echo Carbon::parse('+4 months')->toDateTimeString(); //2017-02-15 20:49:53
    12. echo Carbon::parse('-1 year')->toDateTimeString(); //2015-10-15 20:49:53
    13. echo Carbon::parse('next wednesday')->toDateTimeString(); //2016-10-19 00:00:00
    14. echo Carbon::parse('last friday')->toDateTimeString(); //2016-10-14 00:00:00

      

      //构造日期

    1. $year = '2015';
    2. $month = '04';
    3. $day = '12';
    4.  
    5. echo Carbon::createFromDate($year, $month, $day); //2015-04-12 20:55:59
    6.  
    7. $hour = '02';
    8. $minute = '15':
    9. $second = '30';
    10.  
    11. echo Carbon::create($year, $month, $day, $hour, $minute, $second); //2015-04-12 02:15:30
    12.  
    13. echo Carbon::createFromDate(null, 12, 25); // 年默认为当前年份
    // 日期操作
    日期操作可以通过 add (增加)或 sub (减去)跟上要增加或减去的单位来完成。例如,你想给一个日期增加指定的天数,你可以使用 addDays 方法。此外还提供了一个 modify 方法,参数格式为 + 或 - 跟上值及单位。所以,如果你想给当前日期增加一年,你可以传递 +1 year
    echo Carbon::now()->addDays(25); //2016-11-09 14:00:01
    echo Carbon::now()->addWeeks(3); //2016-11-05 14:00:01
    echo Carbon::now()->addHours(25); //2016-10-16 15:00:01
    echo Carbon::now()->subHours(2); //2016-10-15 12:00:01
    echo Carbon::now()->addHours(2)->addMinutes(12); //2016-10-15 16:12:01
    echo Carbon::now()->modify('+15 days'); //2016-10-30 14:00:01
    echo Carbon::now()->modify('-2 days'); //2016-10-13 14:00:01
    //
    • eq – 判断两个日期是否相等。
    • gt – 判断第一个日期是否比第二个日期大。
    • it – 判断第一个日期是否比第二个日期小。
    • gte – 判断第一个日期是否大于等于第二个日期。
    • ite – 判断第一个日期是否小于等于第二个日期。
    
    
    1. echo Carbon::now()->tzName; // America/Toronto
    2. $first = Carbon::create(2012, 9, 5, 23, 26, 11);
    3. $second = Carbon::create(2012, 9, 5, 20, 26, 11, 'America/Vancouver');
    4.  
    5. echo $first->toDateTimeString(); // 2012-09-05 23:26:11
    6. echo $first->tzName; // America/Toronto
    7. echo $second->toDateTimeString(); // 2012-09-05 20:26:11
    8. echo $second->tzName; // America/Vancouver
    9.  
    10. var_dump($first->eq($second)); // bool(true)
    11. var_dump($first->ne($second)); // bool(false)
    12. var_dump($first->gt($second)); // bool(false)
    13. var_dump($first->gte($second)); // bool(true)
    14. var_dump($first->lt($second)); // bool(false)
    15. var_dump($first->lte($second)); // bool(true)
     
  • 相关阅读:
    如何用VSCode编写Java程序
    使用Xcode + Python进行IOS运动轨迹模拟
    聚类(Clustering)
    异常值(outlier)
    线性回归(regression)
    自适应增强(Adaptive Boosting)
    决策树(Decision Trees)
    支持向量机(SVM)
    朴素贝叶斯(Naive Bayesian)
    ItChat与图灵机器人的结合
  • 原文地址:https://www.cnblogs.com/cjjjj/p/9827308.html
Copyright © 2011-2022 走看看