Leetcode 刷题 第三天 – 167. 两数之和 II – 输入有序数组,283. 移动零

两数之和 II – 输入有序数组

https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/

解题思路:通过hash下标记录待减的数,减少循环

hashMap := map[int]int{}

	for i, num := range numbers {
		if p, ok := hashMap[target-num]; ok {
			return []int{p+1, i+1}
		}
		hashMap[num] = i
	}

移动零

解题思路:通过双指针,i,j,进行比较的下标,如果不等就进行替换,不等移动知道最后一个指针到达终点,通过双指针进行元素的移动,不断进行比较,这样能够减少循环的次数,从而能够在有序的数组中进行不断,不需要双重循环,导致时间复杂度为O(n^2)

left, right, n := 0, 0, len(nums)
	for right < n {
		if nums[right] != 0 {
			nums[left], nums[right] = nums[right], nums[left]
			left++
		}
		right++
	}

https://leetcode-cn.com/problems/move-zeroes/

总结

1、多接力,通过i,j不断移动数组

2、老说话,请拿起纸笔,不要急于编码

leetcode 刷题(第二天)- 双指针,数组排序

977. 有序数组的平方

https://leetcode-cn.com/problems/squares-of-a-sorted-array/

解题要点:通过双指针,来记录素组位置做到排序效果,因为数组已经排序好了,现在需要把负数的跟前一个进行比较替换

n := len(nums)
	ans := make([]int, n)
	i, j := 0, n-1
	for pos := n - 1; pos >= 0; pos-- {
		if v, w := nums[i]*nums[i], nums[j]*nums[j]; v > w {
			ans[pos] = v
			i++
		} else {
			ans[pos] = w
			j--
		}
	}
	return an

189. 旋转数组

https://leetcode-cn.com/problems/squares-of-a-sorted-array/

解题要点:在数组中旋转操作,离不开 mod 的计算,避免移出,通过k mod n,得到最后少于 n 的数,让里面每个数字,都移动k mod n 位,下次循环替换,next位

n := len(nums)
	k %= n

	for start, count := 0, gcd(k, n); start < count; start++ {
		pre, cur := nums[start], start
		fmt.Println("1=1", pre, cur, start)
		for ok := true; ok; ok = cur != start {

			next := (cur + k) % n
                        // 关键点在这里
			nums[next], pre, cur = pre, nums[next], next
			fmt.Println("2=2", nums, next, pre, cur)
		}
	}

leetcode 算法题(第一天)- 总结(二分查找法,空间换时间思想)

这是我做算法题的第一天,为什么要做算法题,思维锻炼,而且能够巩固理论,我认为总会在我们工作上会使用上算法这个东西,用上合适的数据结构,让程序运行更快

这里挑选了两类题

1、数组查找数

https://github.com/haimingfg/data-struct/blob/main/go/twoSum.go

2、二分查找法

https://github.com/haimingfg/data-struct/blob/main/go/searchInsert.go

https://github.com/haimingfg/data-struct/blob/main/go/binary.go

这里可以贴题,但我解析的不够官网精彩,因此我挑选了一些我认为重点的东西

第一,做这些算法题或平时工作首要要做的事情是【读懂题】,这个十分重要,就好像理解需求一样,理解错了,你做的快又如何

第二,要拿起纸笔,做每轮循环里面数组或变量变化的情况

第三,要把一些极端值弄上去看是否有问题

第四,做太久都做不出来先看答案,一般思考10分钟,10分钟编码调式

第五,总结代码套路,便于后续工作做业务的时候能够直接拿来用

如,二分查找法的算法点,空间换时间思想,常用hash表进行一些存储,减少遍历带来的时间损耗

二分查找,三个值,left,mid,right,mid 通过 left + (right - left )/2 计算出来,如果某个值大于target值,则向right向左边走,也就是right = mid - 1 否则 left 右边走

left, right := 0, len(nums)-1
    mid := left


    for left <= right {
        mid = left + (right-left)/2
        fmt.Println(nums[mid], left, mid, right)
        if nums[mid] == target {
            return mid
        } else if nums[mid] > target {
            right = mid - 1
        } else if nums[mid] < target {
            left = mid + 1
        }
    }

空间换时间
if p, ok := hashMap[target-num]; ok {
            return []int{p, i}
        }
        hashMap[num] = i
        fmt.Println(hashMap)

如何搭建一个博客

思考点

目的

我的目的是为了做记录,网上有很多什么,GitHub Pages, go 语言平台下的journey,Hexo,还有一些 medium,wordpress站提供的博客服务等东西

从费用看,GitHub Pages, 免费,就是编辑麻烦,要提交代码,而且不一定让人看到

从功能看,journey,Hexo, wordpress 开源博客里面,功能最全,插件比较多的莫非 wordpress 莫属

因此,我选择了wordpress,并非从技术角度我要拥护某语言,一个工具引用我们需要看三个点

  1. 功能是否齐全,开放,因为大部分功能我们都是想拿起就用,甚至用钱去购买一些功能提高效率,去验证想法
  2. 社区是否成熟,遇到问题,是否有一个地方发出求助,让人家帮助你,或者在里面找到人家遇到过的问题,吸收经验
  3. 背后是否有大公司、有付费服务者支持,避免这个社区突然资金链断裂后,在好的友谊都会被现实打破

搭建一个博客需要做什么?

  1. 按照,找了很多资料。。。实在无办法wordpress,搞很多什么mysql php apache这些,实在不想搞,因此找docker 镜像,进行搭建比较省事
  2. SSL证书,使用letsencrypt免费证书
  3. 常用插件,如SEO,google Analyise 这些站长工具

关于第一点,直接使用,docker-compose 来管理,具体教程可以看这里 docker wordpress

关于第二点,使用letsencrypt免费证书,工具为 certbot ,letsencrypt 证书支持90天,差不多到期可以重新更新,这个为初期创业提供免费好处

关于第三点,使用wordpress 的插件,主题功能解决很多常见场景问题

步骤

首先要搞清楚做事的结构,做事情的次序,按照上面的要点,

我需要准备(因为我有主机,自己是搞开发,因此偏技术些,对于小白想搞,建议都是去一些点点的提供网站服务的地方,不然自己搞好蛋痛)

0、结构图

1、域名

2、主机

3、docker-compose 配置文件,用户起服务

4、SSL生成

我这个blog的结构图,如下我是准备好通个一个入库支持多个站点,便于扩展

关于1,自己可以去Goddday,阿里云哪里进行购买,我之前有域名就不需要在购买了

关于2,我需要一台虚拟主机,我自己有一台机,1C0.5G的机器,但安装目前最新版的wordpress,mysql基本上都运行不了,因此我升级位1C2G的机器,基本上能够用上mysql,与到docker了,为什么要选择这样配置,因为这个组合钱花费比较少

关于3,这里操作比较多,花费时间比较多

先安装 docker-compose centos 7 按照方法(一定要用标准方法,人家定义好规范,不要自己编译,除非你有特别爱折腾)

具体可以查看 https://docs.docker.com/engine/install/centos/

yum -y install docker --skip-broken
// 开机启动
systemctl docker.service enabled
// 查看启动是否开启
systemctl list-unit-files | grep docker

准备 docker-compose.yml

version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: 你的数据库账号
      WORDPRESS_DB_PASSWORD: 你的数据库密码
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - /var/docker/wordpress/html:/var/www/html
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: 你的数据库账号
      MYSQL_PASSWORD: 你的数据库密码
    volumes:
      - /var/docker/wordpress/mysql:/var/lib/mysql

volumes:
  wordpress:
  db:

直接 在该目录上 运行 docker-compose up 输出日志看看是否正常,如果没有问题都ok的话就直接 使用 docker-compose up -d 进行后台运行

这个时候,入库nginx 也是通过这个方式构建

web:
  image: nginx
  restart: always
  volumes:
   - ./vhosts:/etc/nginx/conf.d/
   - ./letsencrypt/.well-known:/var/www/.well-known
   - ./letsencrypt/:/etc/letsencrypt/
  ports:
   - 80:80
   - 443:443

如果要防止直接ip访问网站,需要设置一个默认nginx配置,关键点在

listen  80 default_server;
listen  [::]:80 default_server;
server_name  "";

SSLletsencrypt 证书新建,安装 yum -y install certbot

如果安装过程中,出现报错

RROR: Cannot uninstall 'requests'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
pip install --ignore-installed requests

等任何错误都使用这个方式进行修复

pip uninstall requests
yum reinstall python-requests


pip uninstall six
yum reinstall python-six


pip uninstall urllib3
yum reinstall python-urllib3

参考资料


https://dbillinghamuk.medium.com/certbot-certificate-verification-through-nginx-container-710c299ec549

https://medium.com/@getpagespeed/fix-importerror-pyopenssl-module-missing-required-functionality-e1c514797204


安装好certbot,需要设置好nginx的 well-known 配置

server {
    listen       80;
    listen  [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name  {域名};

    ssl_certificate /etc/letsencrypt/live/{域名}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{域名}/privkey.pem;

    location ^~ /.well-known/ {
      alias  /var/www/.well-known/;
    }

    location / {
	proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Ssl on;
        proxy_set_header Host   {域名};
        proxy_pass http://ip:8080;
    }



    #location / {
    #    root   /usr/share/nginx/html;
    #    index  index.html index.htm;
    #}

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

生成证书之前,需要先把上面的ssl相关的东西先关闭,不然启动不了,启动好nginx,在.well-know 新建一个index.htm文件看看能不能访问,echo “ab” > index.htm

所有东西都准备好了,就进行SSL生成

这里要注意几个步骤

1、新建证书

2、nginx引入证书

3、证书renew,nginx reload

4、定时任务

新建证书


sudo certbot certonly --config-dir=/var/docker/nginx/letsencrypt --work-dir=/var/docker/nginx/letsencrypt/certs --logs-dir=/var/docker/nginx/letsencrypt/logs --webroot -w /var/docker/nginx/letsencrypt/ -d haimingli.me 

具体命令文档可以看
https://certbot.eff.org/docs/using.html#certbot-command-line-options

nginx引入证书

listen       80;
    listen  [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name  {域名};

    ssl_certificate /etc/letsencrypt/live/{域名}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{域名}/privkey.pem;

docker exec nginx_web_1 nginx -s reload 热启动

证书renew

certbot renew --config-dir=/var/docker/nginx/letsencrypt --post-hook="docker exec nginx_web_1 nginx -s reload" 

加 --force-renewal 为强制renew,否则会根据它就近3天的过期的证书

定时任务

crontab -e

输入
SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}'); echo "0 0,12 * * * root sleep $SLEEPTIME && certbot renew --config-dir=/var/docker/nginx/letsencrypt --post-hook=\"docker exec nginx_web_1 nginx -s reload\" -q" | sudo tee -a /etc/crontab > /dev/null

每天12 UTC 时间执行更新,其中需要使用SLEEPTIME睡眠一会,避免执行太多

WordPress 插件

性能类

Autoptimize,js,css合并,图片延迟加载

WP Super Cache,静态页生成

站推广

Google XML Sitemaps,搜索引起sitemap工具

Yoast SEO,SEO工具

Site Kit by Google,谷歌分析工具

总结

从安装博客的这个事情看,在一次深感,在做细节之前,先列清楚地图,要做什么,一步步分解,不然一开始纠结细节后,忘记整体一旦走不动,又要重来,而且地图需要瘦身,适时调整,多做笔记,记录一些重复性指令,步骤,这样一步步积累,做成事情概率会增大

多测试

如注意重启系统后,服务还会不会启动,防止各种异常问题,不要基于发布,因为一个异常错误足以影响你,影响他人