iptables详解:常用模块的基本使用

目录

tcp扩展模块

multiport扩展模块

iprange扩展模块

connlimit模块

limit扩展模块

udp扩展模块

icmp扩展模块

state扩展模块

限制每分钟接收10个ICMP数据报文

允许10个数据报文快速通过,然后限制每分钟接收1个个ICMP数据报文

限制网络传输的带宽不可以超过500k/s


tcp扩展模块

-p tcp -m tcp --sport用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围

  • -p protocol,
  • -m:match,指匹配的模块,很多人可能以为是module的缩写,其实是match的缩写,
  • --sport: source port);-p tcp -m tcp
  • --dport用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围(--dport 80:88

这里是我们正常访问80端口的页面

这面的规则是拒绝了来自192.168.159.1无法使用tcp访问本机(192.168.159.200)的80:88端口

iptables -t filter -I INPUT -s 192.168.159.1 -m tcp -p tcp --dport 80:88 -j REJECT

我们可以尝试使用22端口ssh来测试一下:

可以看到我们还是访问成功了,这是为什么呢,就是因为我们设置的规则它是开区间的,80:88,但是并不包括80,所以我们应该设置为79:88。

修改完成后再测试:

查看iptables表我们也可以发现这条拒绝规则收到了数据

此外,tcp扩展模块还有-tcp-flags选项,它可以根据TCP头部的“标识位”来匹配。

注:这里只能封连续的端口,无法封分散的端口,下面的multiport就可以解决这个问题

multiport扩展模块

-p tcp -m multiport --sports用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开;

-p udp -m multiport --dports用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开:

iptables -t filter -I INPUT -s 192.168.159.1 -m multiport -p tcp --dport 80,22 -j REJECT
这里拒绝了来自192.168.159.1 目标80 和 22 端口的流量

我们刚敲完这条命令就会发现由于拒绝了22端口,我们的远程连接直接断开了

那么再测试一下80端口:

 

这里很明显也拒绝成功了!

iprange扩展模块

使用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址。iprange扩展模块中有两个扩展匹配条件可以使用:

--src-range(匹配源地址范围)

– --dst-range(匹配目标地址范围)

iptables -t filter -I INPUT -m iprange --src-range 192.168.159.201-192.168.159.222  -j DROP

上面这条规则的意思就是封堵了192.168.159.201-222ip

那么我们可以尝试使用192,168,159.201尝试ping一下本机

可以看到一直卡在这里,说明规则确实生效了,DROP掉了我们的icmp包 

connlimit模块

使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量

注意:我们不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。(可以限制并发连接,即最多只能有两个进程)

限制22端口(ssh默认端口)连接数量上限不能超过2个;

iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT

表示连接数量只要不超过两个就允许连接,至于超过两个并不一定不允许连接,这得看默认策略是ACCEPT还是DROP或REJECT,又或者有其它规则对它进行限制。

可以配合--connlimit-mask来限制网段:

iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j REJECT

网址由32位二进制组成,最大可写成:255.255.255.255,而mask就是掩码(网络知识,请自行了解),24表示24个1,即255.255.255.0。

我们在192.168.159.200上面配置了限制只能连接两个的规则

连接测试一下:

limit扩展模块

limit模块是限速用的,用于限制“单位时间内流入的数据包的数量”。

每6位秒放行一下ping包(因为1分钟是60秒,所以1分钟10个包,就相当于每6秒1个包):

iptables -t filter -I INPUT -p icmp -m limit --limit 10/minite -j ACCEPT
//默认规则需要修改为DROP

然后需要将默认规则修改为DROP,否则会走默认的ACCEPT规则

iptables -P INPUT DROP

注:修改万模默认规则远程连接可能会断开,不过没有关系,用别的主机测试即可 

--limit后面的单位除了minite,还可以是second、hour、day

--limit-burst: burst是爆发、迸发的意思,在这里是指最多允许一次性有几个包通过,要理解burst,先看以下的“令牌桶算法”。

注:可以防御DDos攻击

令牌桶算法: 有一个木桶,木桶里面放了5块令牌,而且这个木桶最多也只能放下5块令牌,所有报文如果想要出关入关,都必须要持有木桶中的令牌才行,这个木桶有一个神奇的功能,就是每隔6秒钟会生成一块新的令牌,如果此时,木桶中的令牌不足5块,那么新生成的令牌就存放在木桶中,如果木桶中已经存在5块令牌,新生成的令牌就无处安放了,只能溢出木桶(令牌被丢弃),如果此时有5个报文想要入关,那么这5个报文就去木桶里找令牌,正好一人一个,于是他们5个手持令牌,快乐的入关了,此时木桶空了,再有报文想要入关,已经没有对应的令牌可以使用了,但是,过了6秒钟,新的令牌生成了,此刻,正好来了一个报文想要入关,于是,这个报文拿起这个令牌,就入关了,在这个报文之后,如果很长一段时间内没有新的报文想要入关,木桶中的令牌又会慢慢的积攒了起来,直到达到5个令牌,并且一直保持着5个令牌,直到有人需要使用这些令牌,这就是令牌桶算法的大致逻辑。

看完了“令牌桶算法”,其实--limit就相当于指定“多长时间生成一个新令牌”,而--limit-burst则用于指定木桶中最多存放多少块令牌。

我们在192.168.159.200上面配置了上面的那一条规则,然后尝试使用192.168.159.201ping200看看效果:

 可以看到从第六个包开始下面的每一个包都是间隔了6秒发送的

udp扩展模块

udp扩展模块中能用的匹配条件比较少,只有两个,就是--sport--dport,即匹配报文的源端口与目标端口。

例如放行samba服务的137和138端口:

iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp -m udp --dport 138 -j ACCEPT

udp扩展中的--sport--dport与tcp一样,同样支持指定一个连续的端口范围:

iptables -t filter -I INPUT -p udp --dport 137:157 -j ACCEPT

另外与tcp一样,udp也能使用--multiport指定多个不连续的端口。

icmp扩展模块

ping是使用icmp协议的,假设要禁止所有icmp协议的报文进入本机(根据前面所说,我们可以省略用-m icmp来指定使用icmp模块,因为不指定它会默认使用-p指定的协议对应的模块):

iptables -t filter -I INPUT -p icmp -j REJECT

上述命令能产生两个效果:

– 1、别人ping本机时,无法ping通,因为数据报文无法进入

– 2、本机ping别人时,虽然数据包可以出去,但别人的响应包也是icmp协议,无法进来(即“有去无回”)。

所以这样设置会导致,不止别人ping不通本机,本机也ping不通别人。


很明显上边的规则不是我们想要的,我们想要的一般都是允许本机ping别人,不允许别人ping本机:

iptables -t filter -I INPUT -p icmp --icmp-type 8/0(type为8,code为0) -j REJECT

--icmp-type 8/0用于匹配报文type为8,code为0时才会被匹配到,至于会是type和code,这是icmp协议的知识。

其实上边的命令还可以省略code(即把“8/0”写成“8”即可,省略掉“/0”,原因是type=8的报文中只有code=0一种,所以我们不写默认就是code=0,不会有其它值):

iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT

除了能用type/code来匹配icmp报文,还可以使用icmp的描述名称来匹配:

iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT

--icmp-type "echo-request"的效果与icmp --icmp-type 8/0icmp --icmp-type 8的效果完全一样(你可能发现了,icmp协议的描述“echo-request”其实是“echo request”,只不过我们用于作为匹配条件时,要把空格换成横杠)。

例如:

在192.168.159.200上进行配置
iptables -t filter -I INPUT -p icmp --icmp-type 8/0(type为8,code为0) -j REJECT
这里拒绝了给本机里面走的8/0,所以别人无法ping你

配置完成后

本主机ping别人:

别人ping本主机:

注:这里可以使用Wireshark抓包查看

200->201的icmp包:

后面就正常的ping

201->200的icmp包

这里就会拒绝这个包

state扩展模块

在TCP/IP协议簇中,UDP和ICMP是没有所谓的连接的,但是对于state模块来说,tcp报文、udp报文、icmp报文都是有连接状态的,我们可以这样认为,对于state模块而言,只要两台机器在”你来我往”的通信,就算建立起了连接。

而”连接”中的报文可以分为5种状态,报文状态可以为NEW(连接的第一个包)、ESTABLISHED(表示连接已经建立)、RELATED(相关联的连接,当前连接是一个新请求,但是附属于某个已经存在的连接)、INVALID(没有办法识别的包的状态)、UNTRACKED(报文未追踪)。

放行RELATED和ESTABLISHED状态的报文:

iptables -t filter -I INPUT -m state --state RELATED, ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -j REJECT
//这两条命令也可以防止nmap的端口扫描

当我们通过http的url访问某个网站的网页时,客户端向服务端的80端口发起请求,服务端再通过80端口响应我们的请求,于是,作为客户端,我们似乎应该理所应当的放行80端口,以便服务端回应我们的报文可以进入客户端主机,于是,我们在客户端放行了80端口,同理,当我们通过ssh工具远程连接到某台服务器时,客户端向服务端的22号端口发起请求,服务端再通过22号端口响应我们的请求,于是我们理所应当的放行了所有22号端口,以便远程主机的响应请求能够通过防火墙,但是,作为客户端,如果我们并没有主动向80端口发起请求,也没有主动向22号端口发起请求,那么其他主机通过80端口或者22号端口向我们发送数据时,我们可以接收到吗?应该是可以的,因为我们为了收到http与ssh的响应报文,已经放行了80端口与22号端口,所以,不管是”响应”我们的报文,还是”主动发送”给我们的报文,应该都是可以通过这两个端口的,那么仔细想想,这样是不是不太安全呢?如果某些与你敌对的人,利用这些端口”主动”连接到你的主机,你肯定会不爽的吧,一般都是我们主动请求80端口,80端口回应我们,但是一般不会出现80端口主动请求我们的情况吧。

你心里可能会这样想:我知道哪些主机是安全的,我只要针对这些安全的主机放行对应的端口就行了,其他IP一律拒绝,比如,我知道IP为123的主机是安全的,所以,我对123主机开放了22号端口,以便123主机能够通过22号端口响应我们的ssh请求,

那么,如果你需要管理的主机越来越多呢?你是不是每次都要为新的主机配置这些规则呢?如果有30台主机呢?如果有300台主机呢?80端口就更别提了,难道你每次访问一个新的网址,都要对这个网址添加信任吗?这显然不太合理。

你心里可能又会想:针对对应的端口,我用–tcp-flags去匹配tcp报文的标志位,把外来的”第一次握手”的请求拒绝,是不是也可以呢?那么如果对方使用的是UDP协议或者ICMP协议呢?似乎总是有一些不完美的地方。

那么我们仔细的思考一下,造成上述问题的”根源”在哪里,我们为了让”提供服务方”能够正常的”响应”我们的请求,于是在主机上开放了对应的端口,开放这些端口的同时,也出现了问题,别人利用这些开放的端口,”主动”的攻击我们,他们发送过来的报文并不是为了响应我们,而是为了主动攻击我们,好了,我们似乎找到了问题所在?

问题就是:怎样判断这些报文是为了回应我们之前发出的报文,还是主动向我们发送的报文呢?

我们可以通过iptables的state扩展模块解决上述问题,但是我们需要先了解一些state模块的相关概念,然后再回过头来解决上述问题。

从字面上理解,state可以译为状态,但是我们也可以用一个高大上的词去解释它,state模块可以让iptables实现”连接追踪”机制。

那么,既然是”连接追踪”,则必然要有”连接”。

咱们就来聊聊什么是连接吧,一说到连接,你可能会下意识的想到tcp连接,但是,对于state模块而言的”连接”并不能与tcp的”连接”画等号,在TCP/IP协议簇中,UDP和ICMP是没有所谓的连接的,

但是对于state模块来说,tcp报文、udp报文、icmp报文都是有连接状态的,我们可以这样认为,对于state模块而言,只要两台机器在”你来我往”的通信,就算建立起了连接,如下图所示

img

而报文在这个所谓的链接中是什么状态的呢?这是我们后面讨论的话题。

对于state模块的连接而言,”连接”其中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED

那么上述报文的状态都代表什么含义呢?我们先来大概的了解一下概念,然后再结合示例说明。

注意:如下报文状态都是对于state模块来说的。

  • NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。

  • ESTABLISHED:我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立。

或许用图说话更容易被人理解

img

  • RELATED:从字面上理解RELATED译为关系,但是这样仍然不容易理解,我们举个例子。

比如FTP服务,FTP服务端会建立两个进程,一个命令进程(20),一个数据进程(21)。

命令进程负责服务端与客户端之间的命令传输(我们可以把这个传输过程理解成state中所谓的一个”连接”,暂称为”命令连接”)。

数据进程负责服务端与客户端之间的数据传输 ( 我们把这个过程暂称为”数据连接” )。

但是具体传输哪些数据,是由命令去控制的,所以,”数据连接”中的报文与”命令连接”是有”关系”的。

那么,”数据连接”中的报文可能就是RELATED状态,因为这些报文与”命令连接”中的报文有关系。

(注:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块nf_conntrack_ftp,如果想要自动加载,可以配置/etc/sysconfig/iptables-config文件)

INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,我们可以主动屏蔽状态为INVALID的报文。

UNTRACKED:报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接。

好了,我们已经大致了解了state模块中所定义的5种状态,那么现在,我们回过头想想刚才的问题。

刚才问题的根源就是:怎样判断报文是否是为了回应之前发出的报文。

刚才举例中的问题即可使用state扩展模块解决,我们只要放行状态为ESTABLISHED的报文即可,因为如果报文的状态为ESTABLISHED,那么报文肯定是之前发出的报文的回应,如果你还不放心,可以将状态为RELATED或ESTABLISHED的报文都放行,这样,就表示只有回应我们的报文能够通过防火墙,如果是别人主动发送过来的新的报文,则无法通过防火墙,示例如下。

iptables -F
iptables -t filter -I INPUT -m state  --state RELATED,ESTABLISHED -j ACCEPT 
//接受回复的ESTABLISHED的连接
iptables  -t filter -A INPUT -j REJECT 
//直接连接的NEW会被拒绝掉

实验验证:

(1)在192.168.159.200上进行配置

[root@centos111 ~]# iptables -F
[root@centos111 ~]# iptables -t filter -I INPUT -m state  --state RELATED,ESTABLISHED -j ACCEPT
[root@centos111 ~]# iptables -t filter -A INPUT  -j REJECT 

(2)在200上尝试远程登录192.168.159.201

[root@centos111 ~]# ssh root@192.168.159.201
root@192.168.159.201's password: 
Last failed login: Sun Nov 19 09:55:47 CST 2023 from 192.168.159.200 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Sun Nov 19 09:02:50 2023 from 192.168.159.1
[root@centos222 ~]# 

//这里成功的连接了

(3)在201上尝试远程连接200

[root@centos222 ~]# ssh root@192.168.159.200
ssh: connect to host 192.168.159.200 port 22: Connection refused

验证成功!

下面介绍几个实用的案例:

限制每分钟接收10个ICMP数据报文

1.先添加一条规则,限制1分钟内只收10个icmp协议的请求报文。
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
2.然后添加第二条规则,超出10个报文后,其余的报文全部丢弃。
iptables -t filter -A INPUT -p icmp -j DROP
3.查看添加的防火墙规则
[root@centos222 ~]# iptables -t filter -nvxL INPUT --line-numbers 
Chain INPUT (policy ACCEPT 171 packets, 10464 bytes)
num      pkts      bytes target     prot opt in     out     source               destination         
1           0        0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 10/min burst 5
2           0        0 DROP       icmp --  *      *       0.0.0.0/0            0.0.0.0/0 

查看效果,可以看到前5个数据包都可以正常接收,那是因为limit默认初始包就是5个,因此没有任何问题,从第六个数据包开始后,每隔6秒才会正常处理一个数据包,因为1分钟限制10次数据包的接收,那就表示6秒收一个,效果如下图所示。

也可以理解为是一开始可以快速通过5个数据报文,后面的数据报文是每分钟通过10个。

允许10个数据报文快速通过,然后限制每分钟接收1个个ICMP数据报文

实现思路和1)中一模一样,只不过就是调整一下初始包的数量。

1.先添加一条规则,限制1分钟内只收10个icmp协议的请求报文。
iptables -t filter -I INPUT -p icmp -m limit --limit 1/m --limit-burst 10 -j ACCEPT
2.然后添加第二条规则,超出10个报文后,其余的报文全部丢弃。
iptables -t filter  -A INPUT -p icmp -j DROP

效果如下,首先发送了10个数据包正常接收,剩下的数据包每隔1分钟接收1个。

限制网络传输的带宽不可以超过500k/s

限速如何通过limit模块来实现呢?其实也很简单,我们可以计算出1个数据包的大小,然后用500k的大小除以数据包的大小,得出500k能换算出多少个数据包,例如是300个,那么最后设置1秒钟接收的数据包的数量为300个,就可以实现每秒的传输速率带宽在500k左右。

一个数据包的大小大概在1500字节。

公式:(限制的带宽速率*1000)/(单个数据包的大小)

500k的限速,每秒可限制的数据包数量大概为(500*1000/150 = 300个)300个。

[root@centos111 ~]# iptables -t filter -I INPUT -p  tcp -m limit --limit 300/s  -j ACCEPT
[root@centos111 ~]# iptables -t filter -A INPUT -p  tcp -j DROP

速率带宽多多少少是由落差的,如果就想限制在500k以内,可以根据测试的结果来调整每秒数据包的效果,如下图所示,拉取文件的速率为327k/s,此时数据包的数量我是设置的120个。

我们尝试在配置规则完成后的主机上测试传输一个东西:

首先可以使用find命令找一个比较大的文件:

find / -type f -size +100M

然后我使用scp 将这个文件传入到一个目录下,查看它的传输速度:

scp /usr/lib64/firefox/libxul.so root@192.168.159.200:/tmp

但是这里并没有生效,只是传输的很慢而已,大概两分钟传输完了

我们试着清理掉防火墙规则后再测试一下:

这里可以看到1秒中传输完了,这说明我们前面的限速还是有作用的,只是没有达到预期的那么慢

 到这里iptables的基础知识和一些常用的模块的基本使用就介绍完毕了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/166572.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

滚雪球学Java(09-5):Java中的赋值运算符,你真的掌握了吗?

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…

C#入门(13):特性Attribute

C# 特性(Attributes)是用于在运行时为程序元素(如类、方法、属性等)添加声明性信息的一种方式。这些信息可以在程序运行时通过反射(Reflection)访问。特性可以用来控制程序行为、添加元数据或者影响程序的运…

数据结构【DS】图的遍历

BFS 要点 需要一个辅助队列visited数组,防止重复访问 复杂度 时间复杂度:访问结点的时间访问所有的边的时间 广度优先生成树 邻接表存储的图的表示方式不唯一,生成树也不唯一 DFS 复杂度 时间复杂度:访问结点的时间访问所有…

【Flink】核心概念:任务槽(Task Slots)

任务槽 每个 worker(TaskManager)都是一个 JVM 进程,可以在单独的线程中执行一个或多个 subtask。为了控制一个 TaskManager 中接受多少个 task,就有了所谓的 task slots(至少一个)。 每个任务槽&#xf…

CICD 持续集成与持续交付——git

git使用 [rootcicd1 ~]# yum install -y git[rootcicd1 ~]# mkdir demo[rootcicd1 ~]# cd demo/ 初始化版本库 [rootcicd1 demo]# git init 查看状态 [rootcicd1 demo]# git status[rootcicd1 demo]# git status -s #简化输出 [rootcicd1 demo]# echo test > README.md[roo…

树,二叉树,二叉树遍历,哈夫曼树(详解+刷题)

👂 后街男孩经典之精选 - 歌单 - 网易云音乐 👂 年轮(电视剧《花千骨》男声版插曲) - 汪苏泷 - 单曲 - 网易云音乐 目录 🌼5.1 -- 树 🌼5.2 -- 二叉树 1,性质 2,存储 3&#x…

【开源】基于Vue.js的智能教学资源库系统

项目编号: S 050 ,文末获取源码。 \color{red}{项目编号:S050,文末获取源码。} 项目编号:S050,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

CDN是什么,能起到什么作用

随着互联网的快速发展,用户对于快速、稳定、高效的互联网体验的需求日益增长。为了满足这一需求,内容分发网络(CDN)应运而生,并在近年来得到了广泛应用。CDN通过在全球范围内部署大量的服务器和网络节点,实…

【C++】【Opencv】cv::Canny()边缘检测函数详解和示例

Canny边缘检测是一种流行的边缘检测算法,由John F. Canny在1986年开发。它是一种多阶段过程,包括噪声滤波、计算图像强度的梯度、非最大值抑制以及双阈值检测。本文通过函数原型解读和示例对cv::Canny()函数进行详解,以帮助大家理解和使用。 …

[AutoSar]CP autosar 面试题

目录 关键词前言面试官提问答案 关键词 嵌入式、C语言、autosar、面试题 前言 以前面试中的一些常提到的问题,在这里整理一下,希望对要去面试的道友有所帮助。 其中问题的答案后续有时间会再更新整理。 面试官提问 1.Autosar 概述: 解释 …

MyBatis 快速入门

MyBatis 快速入门 前言什么是 MyBatis简介核心特性使用示例配置文件Mapper 接口SQL 映射文件使用 MyBatis 如果大家对以上的导读很懵怎么办!没关系 往下阅读! 1. MyBatis 介绍1.1. 什么是MyBatis1.2. 持久层1.3. 框架1.4. JDBC 弊端1.5.…

【Java】网络编程基础—InetAddress类和URL编程

🌺个人主页:Dawn黎明开始 🎀系列专栏:Java ⭐每日一句:为了那个远方,你要奋不顾身 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️ 文章目录 一.&#x…

【开源】基于Vue.js的独居老人物资配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统,包含了社区档案、…

C++模拟实现——红黑树封装set和map

一、红黑树迭代器的实现 基本的框架和实现链表的迭代器思路是一样的,都是对指针进行封装处理,然后实现一些基本的运算符重载,最重要的是operator,需要不递归的实现走中序的规则,这里只实现那最核心的几个基本功能&…

Day35力扣打卡

打卡记录 相邻字符不同的最长路径(树状DP) 链接 若节点也存在父节点的情况下,传入父节点参数,若是遍历到父节点,直接循环里 continue。 class Solution:def longestPath(self, parent: List[int], s: str) -> in…

如何看待人工智能行业发展

随着人工智能技术的飞速发展,这个领域的就业前景也日益广阔。人工智能在各行各业都有广泛的应用,包括医疗、金融、制造业、教育等。因此,对于想要追求高薪、高技能职业的人来说,学习人工智能是一个非常有前景的选择。 首先&#x…

【Python进阶】近200页md文档14大体系知识点,第4篇:linux命令和vim使用

本文从14大模块展示了python高级用的应用。分别有Linux命令,多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 全套Python进阶笔记地址…

阿里云ECS11月销量王 99元/年

这一波好像真没得说,老用户居然都有份,买来练习、测试冒似已经够了! 阿里云ECS11月销量王 99元/年 2核2G 3M固定带宽不限流量,新老同享,新购、续费同价,开发必备! 活动规则 云服务器ECS 云创季…

读像火箭科学家一样思考笔记03_第一性原理(上)

1. 思维的两种障碍 1.1. 为什么知识会成为一种缺陷而非一种美德 1.1.1. 知识是一种美德 1.1.2. 知识同样的特质也会把它变成一种缺点 1.1.3. 知识确实是个好东西,但知识的作用应该是给人们提供信息,而不是起约束作用 1.1.4. 知识应该启发智慧&#…

程序员告诉你:人工智能是什么?

随着科技的快速发展,人工智能这个词汇已经逐渐融入了我们的日常生活。然而,对于大多数人来说,人工智能仍然是一个相对模糊的概念。 首先,让我们从人工智能的定义开始。人工智能是一种模拟人类智能的技术,它涵盖了多个领…