2023-03-29 10:48:42    25    0    0

        在项目中,我们异步请求可能使用的评率非常高,特别是像遇到需要同时请求几十个接口的情况下,我们应该怎么避免请求一股脑儿的全部发送到服务器端,最终倒是服务压力巨大,这里我们就需要做节流,限制前端发送 请求数量,网上其实也有很多方案,但实际对代码的侵入太大,这里就不做过多描述,这里使用一种更为简单的方法,直接上代码:

定义同时发送请求的数量不超过5个,后进入的
let maxRequestCount = 5
let maxRequestInterval = 500
async throttleGet(url, data) {
    return new Promise((resolve, reject)=> {
        exec();
        function exec(){
            if(maxRequestCount > 0) {
                maxRequestCount--;
                    httpRequest({
                    url: url,
                    method: "GET",
                    data: (data || {}),
                    dataType:"json",
                    takeToken: true,
                    headers:{
                        "Content-Type" : "application/x-www-form-urlencoded"
                    }
                }).then(res => {
                resolve(res)
                }).catch(e => {
                    reject(e);
                }).finally(() => {
                    //执行完以后将占用的请求数量归还
                    maxRequestCoun

2022-12-07 11:22:16    11    0    0

通过PHP渲染form部分,生成表单,直接放到模版里边使用,直接上代码:

<?php
class FormExcetion extends \Exception {

}
/**
 * title fieldType name validateRules  [options value class subtitle tips, placeholder]
 * option 仅在radio checkbox select
 */

class Form {
    /**
     * form 的method属性
     *
     * @var string $name
     */
    private $name = 'ajaxForm';
    /**
     * form 的method属性
     *
     * @var mixed|string $method
     */
    private $method = 'post';
    /**
     * form的action属性
     *
     * @var string $action
     */
    private $action = '';
    /**
     * form 的onsubmit属性
     *
     * @var mixed|string
     */
    private $onsubmit = '';
    /**
     * form需要上传文件就需要设置成 multipart/form-data
     *
     * @var mixed|string
     */
    private $encrypt;
    /**
     * @var $array $fileds
     */
    private $fields = [];
    /**
     * 设置值,避免在添加表单
     * @var array $values
     */
    private $values = [];
    /**
     * 追加 html
     * @var array
     */
    private $appendHtml = [];
    /**
     * 
2022-09-28 22:58:16    23    0    0

    jQuery的应用十分广泛,从最早的PC网站,异步请求、交互效果等,到现在的移动网站,jQuery目前已经迭代到 v3.6.1版本,功能也是越来越强大,本文将介绍通过设置元素的验证规则,遍历表单属性,来实现通用的验证,并实现表单的异步提交。

    首先,第一步,我们将验证绑定到提交按钮,并将表单的sumit设置成return false避免跳过验证直接提交,我们一起来看一下这里的html源代码。

     <form method="POST" onsubmit="return false" data-callback="window.location.href='/';">
    <div class="list-group list-group-sm">
        <div class="list-group-item">
            <input placeholder="昵称" name="nickname" class="form-control no-border" maxlength="30" rules="^([0-9a-zA-Z]){6,20}" required>
        </div>
        <div class="list-group-item">
            <input type="email" name="email" placeholder="邮箱" class="form-control no-border" ng-model="user.email" maxlength="50" rules="^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$" required>
        </div>
        <div class="list-group-item">
            <input type="password" name="password" placeholder="密码" class="form-control no-border" ng-model="user.password" rules="^([a-zA-Z0

2022-03-25 17:23:18    20    0    0

1. 安装 acme.sh

注意:如果需要使用 Standalone Mode请先安装socat
# yum intall socat

It is recommended to install socat first.
We use socat for standalone server if you use standalone mode.
If you don't use standalone mode, just ignore this warning.

[test@ssh ~]$ curl https://get.acme.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 775 0 775 0 0 67 0 --:--:-- 0:00:11 --:--:-- 194
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 193k 100 193k 0 0 234k 0 --:--:-- --:--:-- --:--:-- 234k
Installing from online archive.
Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
Extracting master.tar.gz
It is recommended to install socat first.
We use socat for standalone server if you use standalone mode.
If you don't use standalone mode, just ignore this warning.
Installing to /home/test/.acme.sh
Installed to /home/test/.acme.sh/acme.sh
Installing alias to '/home/test/.bashrc'
OK, Close and re

2022-02-15 14:50:41    18    0    0

Golang 的语法和运行时直接内置了对并发的支持。

Golang 里的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为 goroutine 时,Golang 会将其视为一个独立的工作单元。这个单元会被调度到可用的逻辑处理器上执行。Golang 运行时的调度器是一个复杂的软件,能管理被创建的所有 goroutine 并为其分配执行时间。这个调度器在操作系统之上,将操作系统的线程与语言运行时的逻辑处理器绑定,并在逻辑处理器上运行 goroutine。调度器在任何给定的时间,都会全面控制哪个 goroutine 要在哪个逻辑处理器上运行。

Golang 的并发同步模型来自一个叫作通信顺序进程(Communicating Sequential Processes,CSP)的范型(paradigm)。CSP 是一种消息传递模型,通过在 goroutine 之间传递数据来传递消息,而不是对数据进行加锁来实现同步访问。用于在 goroutine 之间同步和传递数据的关键数据类型叫作通道(channel)。

进程与线程

进程

当运行一个应用程序的时候,操作系统会为这个应用程序启动一个进程。可以将这个进程看作一个包含了应用程序在运行中需要用到和维护的各种资源的容器。这些资源包括但不限于内存地址空间、文件和设备的句柄以及线程。

线程

一个线程是一个执行空间,这个空间会被操作系统调度来运行函数中所写的代码。每个进程至少包含一个线程,每个进程的初始线程被称作主线程。因为执行这个线程的空间是应用程序的本身的空间,所以当主线程终止时,应用程序也会终止。操作系统将线程调度到某个处理器上运行,这个处理器并不一定是进程所在的处理器。下图展示了一个运行中的应用程序的进程和线程视图(下图来自互联网):

c2129531eb51808f9c93493af6701322.png

本质上,无论 windows 还是 linux,操作系统调度的单位都是线程(调度线程在 CPU 上执行)。

逻辑处理器与本地运行队列

逻辑处理器

Golang 的运行时会在逻辑处理器上调度 goroutine 来运行。每个逻辑处理器都与一个操作系统线程绑定。在 Golang 1.5 及以后的版本中,运行时默认会为每个可用的物理处理器分配一个逻辑处理器。

本地运行队列

每个逻辑处理器有一个本地运行队列。如果创建一个 goroutine 并准备运行,这个 goroutine 首先会被放到调度器的全局运行队列中。之后,

2021-09-24 16:12:40    24    0    0

布隆过滤器

是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。但是布隆过滤器可以控制错误率。

具体的布隆过滤器相关的内容可查找相关资料,非常详细,其优势就是占用内存比hash表要小得多,非常适合用于做过滤的场景

Guava中的布隆过滤器

Guava是google开发的java基础库,其中提供了布隆过滤器的实现,即名为BloomFilter的类,其使用方式类似如下:

使用Redis实现布隆过滤器

当布隆过滤器也需要使用大量内存,并要求在多台机器之间共享时,Guava提供的BloomFilter就难以满足需求了。BloomFilter在数据存在上,实际上可以认为是一个非常大了位图,而redis支持bitmap数据结构,正好可以用于实现布隆过滤器。

然而,我们如何实现BloomFilter呢,我们可以先看看guava中的BloomFilter的实现方式:

 

BloomFilter.put()方法中,直接调用了strategy.put(),我们可以继续进入到这个Strategy中:

 

可以看到,Strategy是BloomFilter类中的内部接口,是用于当布隆过滤器存储的对象转换成bits,guava中提供的实现是一个enum:

 

我们继续看看其put方法的实现:

 

其中,除了hash以外,就是对LockFreeBitArray的操作,因此,如果我们能通过redis实现一个新的LockFreeBitArray,那我们就能实现一个基于redis的布隆过滤器了,但是很可惜,LockFreeBitArray是final的类,且是包访问权限,我们无法从LockFreeBitArray类做扩展。

那么我们只有使用两种方式:

  1. 自己从头开始实现BloomFilter
  2. 拿来主义,都是开源的了,抄代码吧,把BloomFilter相关的代码copy出来,替换掉LockFreeBitArray

我这里使得了第二种方式,将guava中的BloomFilter复制一份,并加上JedisPool参数用于访问redis,然后基于redis实现一个LockFreeBitArray,其中基于redis的LockFreeBitArray的实现如下:

  static final class LockFreeBit
2021-08-09 16:26:32    51    0    0

在实习这段时间接触到了Grom框架的使用,很好用,有必要整理下其用法:

 一、CRUD相关

  1. 查询

  

// 获取第一条记录,按主键排序
db.First(&user)
//// SELECT * FROM users ORDER BY id LIMIT 1;
 
// 获取一条记录,不指定排序
db.Take(&user)
//// SELECT * FROM users LIMIT 1;
 
// 获取最后一条记录,按主键排序
db.Last(&user)
//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
 
// 获取所有的记录
db.Find(&users)
//// SELECT * FROM users;
 
// 通过主键进行查询 (仅适用于主键是数字类型)
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;

2. 使用Where添加查询条件
// 获取第一条匹配的记录
db.Where("name = ?""jinzhu").First(&user)
//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;
 
// 获取所有匹配的记录
db.Where("name = ?""jinzhu").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu';
 
// <>
db.Where("name <> ?""jinzhu").Find(&users)
 
// IN
db.Where("name in (?)", []string{"jinzhu""jinzhu 2"}).Find(&users)
 
// LIKE
db.Where("name LIKE ?""%jin%").Find(&users)
 
// AND
db.Where("name = ? AND age >= ?""jinzhu""22").Find(&users)
 
// Time
db.Where("updated_at > ?", lastWeek).Find(&users)
 
// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek
Golang    2021-06-16 18:35:57    65    0    0

4、Golang中make与new有何区别?

一、前言

本文主要给大家介绍了Go语言中函数newmake的使用和区别,关于Go语言中newmake是内建的两个函数,主要用来创建分配类型内存。在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的规则很简单,下面我们就通过一些示例说明他们的区别和使用。

二、变量的声明

var i int
var s string

​ 变量的声明我们可以通过var关键字,然后就可以在程序中使用。当我们不指定变量的默认值时,这些变量的默认值是他们的零值,比如int类型的零值是0,string类型的零值是"",引用类型的零值是nil

对于例子中的两种类型的声明,我们可以直接使用,对其进行赋值输出。但是如果我们换成指针类型呢?

test1.go

package main

import (
 "fmt"
)

func main() {
   var i *int
   *i=10
   fmt.Println(*i)
}
$ go run test1.go 
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4849df]

goroutine 1 [running]:
main.main()
	/home/itheima/go/src/golang_deeper/make_new/t

从这个提示中可以看出,对于引用类型的变量,我们不光要声明它,还要为它分配内容空间,否则我们的值放在哪里去呢?这就是上面错误提示的原因。

对于值类型的声明不需要,是因为已经默认帮我们分配好了。

要分配内存,就引出来今天的newmake

三、new

对于上面的问题我们如何解决呢?既然我们知道了没有为其分配内存,那么我们使用new分配一个吧。

func main() {
  
   var i *int
   i=new(int)
   *i=10
   fmt.Println(*i)
  
}

现在再运行程序,完美PASS,打印10。现在让我们看下new这个内置的函数。

// The new built-in function allocates memory. Th
php    2021-06-16 18:35:50    47    0    0

php5与php7的区别是什么?下面本篇文章就来给大家对比一下php5与php7,介绍php5与php7之间的区别。有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

php5与php7之间的区别:

1、性能提升:PHP7比PHP5.0性能提升了两倍。

2、以前的许多致命错误,现在改成抛出异常。

3、PHP 7.0比PHP5.0移除了一些老的不在支持的SAPI(服务器端应用编程端口)和扩展。

4、PHP 7.0比PHP5.0新增了空接合操作符。

5、PHP 7.0比PHP5.0新增加了结合比较运算符。

6、PHP 7.0比PHP5.0新增加了函数的返回类型声明。

7、PHP 7.0比PHP5.0新增加了标量类型声明。

8、PHP 7.0比PHP5.0新增加匿名类。

9、错误处理和64位支持

如果您了解错误和异常之间的区别,那么您就会知道在PHP 5中处理致命错误非常不容易。PHP7简化了流程,因为它已用可以轻松处理的异常替换了几个主要错误。这是通过引入新的引擎异常对象实现的。

您可能已经知道,PHP 5不支持64位整数或大文件,但PHP 7中的情况已发生变化。PHP7具有64位支持,因此您也可以使用本机64位整数作为大文件,因此,您可以在64位系统体系结构上完美运行应用程序。

10、声明返回类型

在PHP 5中,程序员无法定义函数或方法的返回类型。在现实生活中,这是一个巨大的缺点,因为程序员无法防止意外的返回类型并在其他情况下生成异常。

幸运的是,PHP 7允许程序员根据期望的返回值声明函数的返回类型。这肯定会使代码健壮和准确。有四种不同的返回类型可用-bool,int,string和float。

为什么 PHP7 比 PHP5 性能提升了?

1、变量存储字节减小,减少内存占用,提升变量操作速度

2、改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率

3、改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率

PHP    2021-06-16 15:34:17    36    0    0

在面向对象的设计中,如何通过很少的设计改变就可以应对设计需求变化,这是设计者极为要关注的问题。为此,我们需要掌握面向对象设计的5大设计原则。
面向对象设计的5大设计原则分别是:

  1. 单一职责原则
  2. 接口隔离原则
  3. 开放-封闭原则
  4. 里氏替换原则
  5. 依赖倒置原则
    这5大原则也是23种类设计模式的基础

单一职责原则

单一职责原则(Single Responsibility Principle,SRP)
一个类被改变的原因不能超过一个,也就是说,一个类只有一个职责,如果职责过多,代码就会臃肿,可读性更差,也更难以维护。

为什么要遵守单一职责原则

1、提高类的可维护性和可读写性
一个类的职责少了,复杂度降低了,代码就少了,可读性也就好了,可维护性自然就高了
2、提高系统的可维护性
系统是由类组成的,每个类的可维护性高,相对来讲整个系统的可维护性就高。当然,前提是系统的架构没有问题。
3、降低变更的风险
一个类的职责越多,变更的可能性就更大,变更带来的风险也就越大

如何遵守单一职责原则

合理的职责分解相同的职责放到一起,不同的职责分解到不同的接口和实现中去

单一职责原则最佳实践

在实际工作中,有一个经常会用到的设计模式,DAO模式,又叫数据访问对象,里面定义了数据库中表的增、删、改、查操作.
按照单一职责原则,为什么不把增、删、改、查分别定义成四种接口?这是因为数据库的表操作,基本上就是这四种类型,不可能变化,所以没有必要分开定义。
反而经常变化的是数据库的表结构,表结构一变,这四种操作都要跟着变。所以通常我们会针对一张表实现一个DAO,一张表就代表一种类型的职责。

遵循单一职责原则代码实例

代码源码

接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)

1.客户端不应该依赖它不需要的接口
2.类间的依赖关系应该建立在最小的接口上

通俗来讲:使用多个专门的接口比使用单一的总接口要好。

接口如果能够保持粒度够小,就能保证它足够稳定
换而言之,从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。
过于臃肿的接口是对接口的污染。不应该强迫客户依赖于它们不用的方法。

接口隔离原则与单一职责原则对比

接口隔离原则和单一职责原则非常类似。

单一职责原则要求接口的职责是单一的,而接口隔离原则要求接口尽量细化,它们有异曲同工之妙,都是要让我们的接口功能尽量单一,尽量小。
但是,单一职责原则的着重点是在“职

1/155