分类 前端 下的文章

前言

记录下常用的Homestead方法,其实说是Homestead,很多时候都是Linux的常规用法

Homestead安装Swoole

流程:

  1. 通过vagrant init创建Vagrantfile文件,通常不用执行

切记,默认git的Homestead是有Vagrantfile文件的,如果删除了再执行这个代码会出现一些异常。

  1. 执行vagrant up 或者执行vagrant provision时,虚拟机进入初始化状态

Vagrant 提供的钩子,触发【Homestead脚本】,具体为 homestead.rb;
Homestead脚本】 读取Homestead.yaml文件,对sites、folders、databases进行重新初始化;
初始化 sites 时,会读取 Homestead 脚本仓库里带着的Nginx站点模板,具体为 scripts/sites-types/laravel.sh或者serve-laravel.sh

Homestead目录

目录.png

Homestead.yaml配置

ip: "192.168.10.10"   #虚拟机的IP,可以通过这个IP访问站点
memory: 2048    #内存大小
cpus: 2     #Cpu核心个数
provider: virtualbox  #虚拟机平台,用virtualbox装的一定要确认这里是virtualbox。(hyper-v、virtualbox、 vmware_fushion、  vmware_workstation、parallels)

authorize: ~/.ssh/id_rsa.pub  #ssh的公钥

keys:
    - ~/.ssh/id_rsa  #ssh的私钥,配置了ssh以后,登录虚拟机可以直接在终端输入homestead ssh进入

folders:
    - map: D:/projects
      to: /home/vagrant/projects

sites:
    - map: lsw.test
     to: /home/vagrant/projects/laravel-swoole-wechat/public

databases:
    - homestead

features:
    - mariadb: false
    - ohmyzsh: false
    - webdriver: false

# ports:
#     - send: 50000
#       to: 5000
#     - send: 7777
#       to: 777
#       protocol: udp
  • sites :配置Nginx站点

    map: homestead.test

    to: /home/vagrant/code/my-project/public #注意laravel一定是指定到public目录

    type : 站点类型,默认Laravel。

    对应的scripts/site-types目录里面的文件。可以用于创建yii、laravel、wordpress等很多框架对应的nginx配置。

    我们还可以自行根据type,在site-types里创建对应的[type].sh文件,生成其对应的nginx配置

Homestead优化

有时候需要把一些常用的命令简写化

这不是vagrant的命令,是登录到Homestead的命令

[8_4SK(E335OPC5A3)HC)F5.png

修改aliases文件,给命令加上别名
如:快速跳转到code目录

alias .code="cd ~/code"

切记修改了Homestead里的文件需要 reload 下

vagrant reload --pervision

开发相关

  • Nginx :/etc/Nginx (sites-available就是所有网站的配置)
  • php -i|grep php.ini :找到PHP.ini文件的位置
  • php -i |less 查看配置文件在哪里,编译参数
  • php -m 查看php扩展(全部显示)
  • php -m |less 查看php加载的模块 (分页查看,输入数字换页,也可以不带)
  • php -m |more 查看php加载的模块 (分页查看,更多的方式,每次多显示一个)
  • sudo service php7.1-fpm restart :重启php7.1-fpm

Linux常用知识:

  • echo $PATH :查看linux的环境变量
  • cat 文件 :查看文件的全部内容

cat log.txt

vi编辑( 通常都要以sudo的方式运行,否则会没有权限)

  • vim 目录文件 :进行编辑

按ESC键 跳出vi的编辑命令,然后:

  • gg :文件开头行
  • G :文件尾(切记一定是大写)
  • :n (n代表指定行数)跳转到指定行数

:50 跳转到50行

  • :w 保存文件但不退出vi
  • :w file 将修改另外保存到file中,不退出vi
  • :w! 强制保存,不推出vi
  • :wq 保存文件并退出vi
  • :wq! 强制保存文件,并退出vi
  • q: 不保存文件,退出vi
  • :q! 不保存文件,强制退出vi
  • :e! 放弃所有修改,从上次保存文件开始再编辑

前言

参考网站:
Homestead安装配置-中文文档
Homestead安装配置-视频讲解
记录下安装Homestead的步骤,以及需要注意的点
以下命令行均使用 git-bash

一、安装所需要的软件

1、安装下列软件,安装方法很简单就不多说了

  • git:
  • vagrant:
  • VirtualBox:一个免费的虚拟机软件

2、由于vagrant默认的工作目录是 C:\Users\用户名\.vagrant.d,如若C盘空间不足,可以将此移至其他目录如:D:\.vagrant.d,然后在环境变量中配置VAGRANT_HOME即可

VAGRANT_HOME=D:\.vagrant.d

1.png

二、下载、添加vagrant Box

1、安装Vagrant Homestead盒子,选择一个支持virtualBox的版本。查看版本

  1. vagrant box add laravel/homestead // 直接安装最新版本,但有可能不支持virtualbox
  2. vagrant box add laravel/homestead --box_version=9.1.0 // 选择对应的版本
  3. vagrant box add laravel/homestead ./virtualbox.box // 安装本地的版本

命令详解 vagrant box add 【本地box名字】 【本地box文件的名字】

  1. vagrant box add metadata.json // 通过配置文件安装

       {
       "name": "laravel/Homestead",  // 本地box名字,就是vagrant box list 是查看的名字
       "versions": [{
           "version": "9.1.0",  // 版本
           "providers": [{
               "name": "virtualbox", // 支持的是hyper-v、virtualbox等
               "url": "./CentOS-7-x86_64-Vagrant-1910_01.VirtualBox.box" // 文件的地址
           }]
       }]
       }
    

2.jpg
如果下载过慢,可以通过上图的Downloading获取到下载链接,通过其他方式下载后安装(要下载其他版本,就修改下版本和后面的virtual)

2、若使用安装最新版本,如若当时最新版本同时支持Hyper-v、virtual等,会要求您选择一个版本,输入对应的数字即可!

5.png

至此Homestead所需环境安装成功

三、安装Homestead

1、克隆Homestead

cd ~
git clone https://github.com/laravel/homestead.git Homestead

2、克隆完成后,需要检查Homestead的版本,因为 master 分支不会总是稳定版本,需要通过Github Release Page检出为release版本

cd ~/Homestead

// Clone the desired release...
git checkout v8.0.1

3、接下来,运行初始化命令来创建Homestead.yaml配置文件

// Mac/Linux...
bash init.sh  // 虽然我用的Windows,但由于是使用git-bash执行的,因此使用这个命令

// Windows...
init.bat

四、配置Homestead.yaml

打开Homestead目录内的Homestead.yaml文件

---
ip: "192.168.10.10"   #虚拟机的IP,可以通过这个IP访问站点
memory: 2048    #内存大小
cpus: 2     #Cpu核心个数
provider: virtualbox  #虚拟机平台,用virtualbox装的一定要确认这里是virtualbox。(hyper-v、virtualbox、vmware_fushion、  vmware_workstation、parallels)

authorize: ~/.ssh/id_rsa.pub  #ssh的公钥

keys:
    - ~/.ssh/id_rsa  #ssh的私钥,配置了ssh以后,登录虚拟机可以直接在终端输入homestead ssh进入

folders:
    - map: D:/projects
      to: /home/vagrant/projects

sites:
    - map: lsw.test
      to: /home/vagrant/projects/laravel-swoole-wechat/public

databases:
    - homestead

features:
    - mariadb: false
    - ohmyzsh: false
    - webdriver: false

# ports:
#     - send: 50000
#       to: 5000
#     - send: 7777
#       to: 777
#       protocol: udp
  • folders映射目录

映射的目录。map:主系统的目录,to:要映射的虚拟机目录!
随着站点数量增加,会遇到性能问题,这时应该映射每个项目到对应的vagrant文件夹

    - map: D:/projects
      to: /home/vagrant/projects

    - map: D:/code
      to: /home/vagrant/code
      type: "nfs"  # 开启nfs

     - map: ~/code
      to: /home/vagrant/code
      type: "rsync"
      options: # 通过options配置同步文件夹
          rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
          rsync__exclude: ["node_modules"]
  • 配置 Nginx 站点

    sites:

    • map: homestead.test
      to: /home/vagrant/code/my-project/public #注意laravel一定是指定到public目录

五、接下来先初始化下vagrant,然后启动vagrant

vagrant init  //切记clone下来的Homestead默认有了,不用再执行一次。初始化,只有第一次时执行,就是创建个VagrantFile,已经有了就不用执行这个命令了
vagrant up 启动

六、登录vagrant,对环境进行配置

vagrant ssh:远程连接

composer config -g repo.packagist composer https://packagist.phpcomposer.com // 修改Composer全局镜像







- 阅读剩余部分 -

原理

希尔排序是插入排序的改进版本。
项目中用的比较少,不稳

  1. 先设置一个间隔(gap),以视为一组。
  2. 当这个间隔的所有组全排序好后,减少间隔,重复1.
  3. 最后以间隔为1,在排序。(其实就是最后执行次插入排序,插入排序就是间隔1的希尔排序)
    注:间隔越大,交换次数越小! 间隔越小,交换次数越多

通常间隔以h或者gap表示

举例说明

如:需要对以下数组进行排序

const arr = [8, 5, 6, 3, 11, 2, 9, 15, 13, 1, 14, 6, 9, 10]

假设间隔(gap)为4,如下图,相同颜色的为一组,执行插入排序。

希尔排序1.png

既然每个数(除去最前面的没有可比较的数以外)都会执行插入排序。那么我们就可以直接使用普通的插入排序方式来实现,只需要将默认的间隔1改为对应的gap

代码实现

我们先来看看普通的插入排序

  for (let i = 1; i < arr.length; i++) { // 以1(第0个数前面没有需要比较的)开始,直到数组跑完
    for (let k = i ; k > 0; k--) {  // 依次与前面的进行比较。如 i=1时,依次与i-1比。i>0是因为i=0时,前面没有数比较了,所以不需要
      if (arr[k] < arr[k - 1]) {
        // 交换 k和 k-1
      } else {
          break;
        }
    }
  }

前面我们也说过,插入排序也可以看做是一个间隔为1的希尔排序

// 一次间隔的排序
function shell_sort_gap(arr, gap) {
  // 普通的插入排序是以,1开始的。而希尔排序,既然以间隔分组,就相当于 0-第一个间隔是一组的,那就是以间隔排序
  for (let i = gap; i < arr.length; i++) { // 以gap开始
    for (let k = i; k > gap - 1; k -= gap) { // 依次与前面的进行比较,每次差距为gap。这里gap-1,是因为gap肯定是最小的可比较数,最前面的那几个数就不要再遍历比较了。
      if (arr[k] < arr[k - gap]) {
        // 交换 k和 k-1
        array_swap(arr, k, k - gap)
      } else {
        break;
      }
    }
  }
}

上面只是间隔为某一个数时的排序,后面需要减少间隔,直到间隔为1。
for (let gap = 4; gap > 0;) { // 这里的4,是我主观意识上取的值

shell_sort_gap(arr, gap)
gap = Math.floor(gap / 2) // 向下取整,如果是其他语言,gap类型为int,就不需要Math.floor了,JS需要不然会有小数

}

上面初次间隔的值,是主观意识上给的,对于算法来说肯定是不合适的。
因此我们改成,默认为数组的一半,然后依次将间隔/2。

  for (let gap = Math.floor(arr.length / 2); gap > 0; gap = Math.floor(gap / 2)) { 
    shell_sort_gap(arr, gap)
  }

但后续很多人发现,这种除以2的方式效率(shell发现的)不是最高的(Knuth(K不发音)发现的)。(还有一些其他的算法)

h = 1
h = 3*h+1
//当h=3h+1时,效率更高!h就是gap,通常算法里默认就是h

因此我们先以1带入h计算出最适合的h,在以公示倒推排序

function shell_sort(arr) {    
  if (arr.length < 2) {
    return
  }
  // 计算最优的gap
  let h = 1
  while (h <= arr.length / 3) { //如果大于1/3了,就超过数组长度了。因此需要小于等于1/3
    h = 3 * h + 1
  }
  for (let gap = Math.floor(h); gap > 0; gap = Math.floor((gap - 1) / 3)) { // 再以倒推的方式排序
    shell_sort_gap(arr, gap)
  }
}

由此可见,不同gap减少方式,会导致效率不同,因此希尔排序的时间复杂度不尽相同,普遍认为是O(n的1.3次方)。

实现原理

以下标1开始,向前比较,小于则交换
原理很像冒泡排序,只不过冒泡排序是两两比较,大的向后移。
而插入排序是无论什么时候,都只操作这一个数

插入排序.png

代码实现:

  for (let i = 1; i < arr.length; i++) { // 以第1(第0个数前面没有需要比较的)个数开始,直到数组跑完

    for (let k = i ; k > 0; k--) { // 依次与前面的进行比较。如 i=1时,依次与i-1比。i>0是因为i=0时,前面没有数比较了,所以不需要
      if (arr[k] < arr[k-1]) {
        array_swap(arr, k, k-1) // 交换位置
      } else {
        break;  // 由于是往前插入的,说明比当前值的都放到前面了,那么如果不比他小的值的地方是已经排好的了,所以可以直接跳出,这样才能满足最好时间复杂度O(n)
      }
      console.log('---第' + k + '次', arr)
    }
    console.log('第' + i + '次', arr)
  }
}

再优化的思路:

  1. 减少交换次数,比较大小后,记录想要插入的位置,后直接插入(不用交换)
  2. 交换使用位移运算的方式,优化数组的insert
  for (let i = 1; i < arr.length; i++) { // 以1 开始,循环
    let minPos = i // 当前数的下标
    let tmp = arr[i] // 当前数
    for (let k = i - 1; k > -1; k--) { // 遍历这个数以前的数
      if (tmp  < arr[k]) { // 用当前值去比较
        minPos = k
      } else {
        break;
      }
    }
    // 插入,前面的都往后移
    for (let j = i; j > minPos; j--) {
      arr[j] = arr[j - 1]
    }
    arr[minPos] = tmp 
  }

实现原理

冒泡排序.png

1、两两比较,把大的往后移

 for (let i = 0; i < arr.length - 1; i++) {
  if (arr[i] > arr[i + 1]) {
    array_swap(arr, i, i + 1) // 交换数组的两个值
  }
}

2、然后循环length次

  for (let k = 0; k < arr.length; k++) {
    for (let i = 0; i < arr.length - 1; i++) {

      if (arr[i] > arr[i + 1]) {
        array_swap(arr, i, i + 1)
      }
     
    }
  }

3、优化代码,但是最好的时间复杂度还是 O(n²),没有达到效果 O(n)

  for (let k = arr.length - 1; k > 0; k--) {
    for (let i = 0; i < k; i++) { // 内部循环时,已经比较过的就不要在比较了
      if (arr[i] > arr[i + 1]) {
        array_swap(arr, i, i + 1)
      }
    }
  }

4、最终优化,加入一个flag标识,用于表示内循环是否有出现交换,如果没有,则代表不需要交换了,已经是最好的方式了
for(let k=

详情

1、能看出它的平均时间复杂度和前面的 选择排序 是一样的 等差数列,O(n²),
2、由于没有用到多余空间,因此空间复杂度为 O(1)
3、由于是两两比较,因此是稳定的,不会导致,明明是后面的8,却排到前面的8去了。