算法练习:BM2 链表内指定区间反转

问题描述

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度O(n),空间复杂度O(1)。例如:给出的链表为 1→2→3→4→5→NULL, m=2,n=4,返回 1→4→3→2→5→NULL.

数据范围: 链表长度 0<size≤10000,0<mnsize,链表中每个节点的值满足 val∣≤10000

要求:时间复杂度 O(n) ,空间复杂度 O(n)

进阶:时间复杂度O(n),空间复杂度O(1)

示例1

1
2
3
4
5
6
7
输入:

{1,2,3,4,5},2,4

返回值:

{1,4,3,2,5}

示例2

1
2
3
4
5
6
7
输入:

{5},1,1

返回值:

{5}
More...

Window上用包管理应用安装软件 — Chocolatey

前言

在经历了多次重装系统、重新安装各种常用软件后,我突然萌生了一个想法,难道 Window 就没有一个像 Linux 一样可以使用一行命令安装软件的包管理器吗?

答案是:有的。

这里主要是介绍 Chocolatey,对其他包管理器感兴趣的可以自行查看。

安装使用

安装 Chocolatey 前,你需要对检查一下自身系统是否达到所需的要求。

  • Windows 7+ / Windows Server 2003+
  • PowerShell v2+
  • .NET Framework 4+

如果已经满足要求,就可以打开命令行 copy 下面的命令执行。

1
2
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

如果没报红字错误,应该是安装成功了。

1
2
choco -v
# 0.10.11

接下来你可以打开下方的链接,查看一下可以安装的软件列表。

chocolatey.org/docs

比如,安装 Git

1
choco install git

安装 Node

1
2
choco install nodejs.install

也可以加上-y,安装时就不需要等待确认了

1
2

choco install firefox -y

基本用法

  1. 安装 choco install baretail
  2. 升级 choco upgrade baretail
  3. 卸载 choco uninstall baretail
  4. 搜索 choco search something
  5. 列出已安装 choco list -lo

关于更多用法可点击以下链接查看:
chocolatey.org/docs

修改默认安装目录

但是,Chocolatey 安装的软件默认存放在 C 盘,对于我这种不太喜欢把软件装到 C 盘的人来说是不能忍的。

虽然 Chocolatey 自己提供了一个修改默认安装目录的命令,但是需要注册(收费),对于资金充裕的同学我还是建议使用这种方法。

这里我提供另外一个思路,既然他存到默认安装目录,那我们把这个默认安装目录改一下就好了。

比如我要默认存放到E盘,打开注册表,把 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion 下的:

  1. ProgramFilesDir的值改为:E:\Program Files
  2. ProgramFilesDir (x86)的值改为:E:\Program Files (x86)

参考链接:https://juejin.cn/post/6844903782854164487

查看和清理Linux日志文件

1、查看目录大小

du,下面命令显示当前文件夹下各个文件及文件夹大小(汇总)

1
sudo du -sh -- *

2、清理指定大小的日志文件:

1
sudo journalctl --vacuum-size=100M

这将保留最新的 100MB 日志数据。

3、清理指定时间范围之前的日志:

1
sudo journalctl --vacuum-time=10d

docker安装MySQL主从复制

以下是步骤:

1.拉取MySQL的镜像

1
sudo docker pull mysql:8.0.25

2.新建MySQL主服务器的容器实例,端口为3307

1
2
3
4
5
6
7
sudo docker run -p 3501:3306 --name mysql-master \
-v /mnt/n1/data/mysql-master/log:/var/log/mysql \
-v /mnt/n1/data/mysql-master/data:/var/lib/mysql \
-v /mnt/n1/data/mysql-master/conf:/etc/mysql \
-v /mnt/n1/data/mysql-master/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:8.0.25

命令解读:
docker run :创建并运行一个容器
–name : 给容器起一个名字,比如叫做 mysql-master
-p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
-d:后台运行容器
-e:环境变量,如密码什么的
-v:挂载一个数据卷到某个容器内目录,上面分别配置了日志、数据、配置的数据卷

More...

Windows命令-域内信息收集

判断是否存在域

ipconfig

查看网关 IP 地址、DNS 的 IP 地址、域名、本机是否和 DNS 服务器处于同一网段。

1
2
3
4
5
6
7
8
9
10
11
12
ipconfig /all
C:\Users\daniel10> ipconfig /all

Windows IP 配置
主 DNS 后缀 . . . . . . . . . . : teamssix.com
DNS 后缀搜索列表 . . . . . . . . : teamssix.com

以太网适配器 Ethernet0:
IPv4 地址 . . . . . . . . . . .. : 192.168.7.110
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.7.1
DNS 服务器 . . . . . . . . . . . : 192.168.7.7

接着使用 nslookup 解析域名的 IP 地址,查看是否与 DNS 服务器为同一 IP

1
2
3
4
5
6
nslookup teamssix.com
C:\Users\daniel10> nslookup teamssix.com
服务器: UnKnown
Address: 192.168.7.7
名称: teamssix.com
Address: 192.168.7.7

系统详细信息

1
2
3
systeminfo
C:\Users\daniel10> systeminfo | findstr 域
域: teamssix.com

当前登录域与域用户

1
2
3
4
5
net config workstation
C:\Users\daniel10> net config workstation | findstr 域
工作站域 TEAMSSIX
工作站域 DNS 名称 teamssix.com
登录域 TEAMSSIX

判断主域

1
2
3
4
net time /domain
C:\Users\daniel10> net time /domain
\\dc.teamssix.com 的当前时间是 2021/2/13 20:49:56
命令成功完成。

一次Docker应用排查过程

背景

重新发布了一个应用,发现无法访问,把排查过程记录一下。

检查docker程序和开放端口

运行下面语句:

1
sudo docker ps

发现docker都在运行。

运行下面语句:

1
sudo netstat -tunpl

检查开放端口,端口开放正常。

检查frp的状态

运行下面语句:

1
sudo systemctl status frp

由于是通过frp穿透内网的,要看一下是否是frp问题,查看日志,没有报错。

检查内网网页状态

访问内网ip,报错:502 Bad Gateway

运行一下语句,查看docker日志:

1
sudo docker logs ee86b3ee2451

其中 ee86b3ee2451 为容器ID

运行下面语句,查看实时docker日志:

1
sudo docker logs -f ee86b3ee2451

进入Docker查看

如果还是有问题,运行下面语句,查看docker内部情况

1
sudo docker exec -it ee86b3ee2451 bash

总结

经过一番折腾,发现还是docker本身的问题,restart一下就好了,运行以下语句:

1
sudo systemctl restart docker

Django 的日志机制-4

进阶

其实,如果只是为了排错方便,记录一些日志,自定义类基本可以满足要求。但如果要记录访问系统的所有请求日志,那就无能为力了,因为不可能手动在每个接口代码加日志,也没必要。

这个时候,很自然就能想到 Django 中间件了。

Django 中间件

定义中间件类,包括 Filters 代码和 middleware 代码,在本地app文件夹中创建目录:middlewares,目录下创建文件 LogMiddleware.py :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from django.utils.deprecation import MiddlewareMixin
import threading
import logging
import json
import socket

local = threading.local()

class RequestLogFilter(logging.Filter):
"""
日志过滤器
"""

def filter(self, record):
record.sip = getattr(local, 'sip', 'none')
record.dip = getattr(local, 'dip', 'none')
record.body = getattr(local, 'body', 'none')
record.path = getattr(local, 'path', 'none')
record.method = getattr(local, 'method', 'none')
record.username = getattr(local, 'username', 'none')
record.status_code = getattr(local, 'status_code', 'none')
record.reason_phrase = getattr(local, 'reason_phrase', 'none')

return True

class RequestLogMiddleware(MiddlewareMixin):
"""
将request的信息记录在当前的请求线程上。
"""

def __init__(self, get_response=None):
self.get_response = get_response
self.apiLogger = logging.getLogger('web.log')

def __call__(self, request):

try:
body = json.loads(request.body)
except Exception:
body = dict()

if request.method == 'GET':
body.update(dict(request.GET))
else:
body.update(dict(request.POST))

local.body = body
local.path = request.path
local.method = request.method
local.username = request.user
local.sip = request.META.get('REMOTE_ADDR', '')
local.dip = socket.gethostbyname(socket.gethostname())

response = self.get_response(request)
local.status_code = response.status_code
local.reason_phrase = response.reason_phrase
self.apiLogger.info('system-auto')

return response
More...

算法练习:BM1 反转链表

题目内容

给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

数据范围: 0 ≤ n ≤1000

要求:空间复杂度 O(1) ,时间复杂度 O(n) 。

如当输入链表{1,2,3}时,

经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。

我的思路

在遍历链表时,将当前节点的next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。借用网上一个图解:

More...

牛客网 面试必刷TOP101 算法题

介绍

发现一个除了Leecode以外比较好的刷算法的网站:

牛客网在线编程_算法篇_面试必刷TOP101 (nowcoder.com)

据说是收集了很多面试题精选的题目

题目例子

BM83 字符串变形

描述

对于一个长度为 n 字符串,我们需要对它做一些变形。

首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。

比如"Hello World"变形后就变成了"wORLD hELLO"。

数据范围: 1≤n≤1061≤n≤106 , 字符串中包括大写英文字母、小写英文字母、空格。

进阶:空间复杂度 O(n) , 时间复杂度 O(n)

输入描述:

给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^6)

返回值描述:

请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。

示例1

输入:
"This is a sample",16

返回值:
"SAMPLE A IS tHIS"

Python实现

参考了答案,我的代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def trans(self, s: str, n: int) -> str:
word_list = list(s.split(" "))[::-1]
new_str = " ".join(word_list)
res = ""
for i in range(n):
if new_str[i] <= "Z" and new_str[i] >= "A":
res += chr(ord(new_str[i]) - ord("A") + ord("a"))
elif new_str[i] <= "z" and new_str[i] >= "a":
res += chr(ord(new_str[i]) - ord("a") + ord("A"))
else:
res += new_str[i]
print(res)
return res

其中以下写法值得借鉴:

  1. 倒序的实现为 list(s.split(" "))[::-1]
  2. 字母变为小写:chr(ord(new_str[i]) - ord(“A”) + ord(“a”))
  3. 另外 用 swapcase() 函数更简洁

界面和操作

界面如下:

操作还比较方便,有语法提示,有调试界面。

请我喝杯咖啡吧~

支付宝
微信