本周ARTS
本周ARTS打卡内容:
- Algorithm 来源 LeetCode31
- Review 分享 Never use the word “User” in your code
- Tip 分享 几条iptables的命令
- Share 分享 前端的微服务化
Algorithm
Leetcode的31题 下一排列问题
https://leetcode.com/problems/next-permutation/
首先,什么叫做排列(Arrangement),简单说是从N个不同元素中取出M个,按照一定顺序排成一列,通常用A(M,N)表示。当M=N时,称为全排列(Permutation)。全排列的个数有N!
个。而排列按照某种顺序(升序/降序)获得下一个排列叫做Next Permutation
。
例如:1
2
31,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
解法:
最开始打算用递归的方式来解决,但是题目要求空间复杂度为O(1),所以只能研究下一个排列的规律。发现当前排列,只要其中两个数字是升序的,这个数字之前的数字可以保持不动,这个数字之后的数字找出仅比它大的,调换顺序后排序即可,也可以先对该数字之后的数字排序,拍完序后再调换,实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19func nextPermutation(nums []int) {
ln := len(nums)
if ln == 1 || ln == 0{
return
}
for l := ln-1; l > 0 ; l--{
if nums[l-1] < nums[l] {
sort.Ints(nums[l:])
for k , v := range nums[l:] {
if v > nums[l-1] {
nums[k+l] = nums[l-1]
nums[l-1] = v
return
}
}
}
}
sort.Ints(nums)
}
Review
本周分享 Never use the word “User” in your code
作者强调项目中尽量不要使用User
,使用User
会导致两个问题:
- “User”对你的需求来说并不是一个很好的描述
- “User”会导致安全设计缺陷
“User”的概念太含糊,需要更精准的术语。接下来具体说了这两个问题。
你并没有users
也许你第一眼,user
是一个很好的描述,但是深入一点就会发现你的业务逻辑比那复杂多了。
机票订购系统没有users
- 旅客如果有PNR码,可以通过网站查询他们的订购
- 购买者可以通过信用卡号后四位在网站修改他们的预订
- 旅行社可以通过他们的机构查看修改订购
- 航空公司在旅客提供他们的认证信息的基础上,可以根据他们的角色和机场查看和修改预订信息
我们将人的基本概念映射为旅客,旅行社,购买者,user
是没用的。
Unix没有users
我们将这些全部称为users
:
- 通过终端或者UI登陆的人
- 作为
users
运行的系统服务,比如nginx
作为httpd
用户运行 - 服务端,总有管理账号被多个人共享,这些人通过SSH登陆,使用这个
user
root
,和以上又不一样
在POSIX中他们都是users
,但是它们有四种不同的涵义。后面会看到,将这些概念混淆为一个概念会导致很多安全的问题。
SaaS 供应商没有users
SaaS服务中总有:
- 一个组织的一个人购买了该服务
- 这个组织中的一个或者多个人一起使用了这个服务
如果将这两个概念混为一个user
,会很痛苦。你不能建立团队的模型,不能建立多人支付的模型,然后你需要改造你的系统。
Users
是一个安全问题
users
不止造成业务逻辑的问题,还会导致安全问题,它将两个不同的概念合并了:
- 一个人
- 他们在软件中的代表
假设你在访问一个危险的网址,远程网站想控制你的浏览器,开始上传你所有的文件到他们的服务器上。为什么会造成这样的问题呢?因为你的浏览器作为系统的user
运行,而你,作为一个人,是不同的user
。你,这个user
不想上传这些文件,但是浏览器这个user
能够上传文件,如果浏览器在你的账号下,那他的所有行为被认为是你的意图。
这就是Confused Deputy Problem
,
前期设计的价值
使用类似user
这样含糊的词来建模,在后期会花费大量时间来修复。立刻开始编码看起来高产,但事实却正好相反。
在新项目开始前,请预先花几个小时确定你的术语和概念:虽然不会完全正确,但是会更好。未来的你会感谢你所做的所有预防浪费的工作。
Tip
最近在云主机的日志/var/log/secure
里发现一些恶意尝试登陆的IP,具体表现是不断使用root用户或其他用户尝试登陆失败,尽管设置了强密码,但被这样扫描还是不爽,所以考虑用iptables屏蔽它。
先从/var/log/secure
中筛选出待屏蔽的IP,比如xx.xx.xx.xx。
在linux中,使用iptables维护IP规则表,要封停或者解封IP,其实就是在IP规则表中对入站部分的规则进行添加操作。
要封停一个IP,可以使用以下命令:1
iptables -I INPUT -s ... -j DROP
要解封一个IP,使用以下命令:1
iptables -D INPUT -s ... -j DROP
参数-l表示Insert(添加),-D表示Delete(删除)。后面跟的是规则,INPUT表示入站,…表示要封的IP,DROP表示放弃连接。
例如,想封掉112.85.42.175
这个IP,可以使用:1
iptables -I INPUT -s 112.85.42.175 -j DROP
封IP段的命令:1
iptables -I INPUT -s 124.85.0.0/16 -j DROP
封整个段:1
iptables -I INPUT -s 124.85.0.0/8 -j DROP
只封几个段的80端口:1
iptables -I INPUT -p tcp –dport 80 -s 124.115.0.0/24 -j DROP
禁止指定的端口:1
iptables -A INPUT -p tcp --dport 80 -j DROP
开放指定的端口:1
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
拒绝所有的端口:1
iptables -A INPUT -j DROP
可以通过以下命令查看当前的IP规则:1
iptables -L/--list
如果想清空封掉的IP地址,可以输入:1
iptables -F/--flush
Share
微服务化的前端工程