Flutter开发

关键字 late late关键字允许变量将在稍后初始化,但必须在使用之前初始化。 这与 final 关键字不同,final 关键字用于声明必须在声明时或构造函数运行之前初始化的变量。 late 关键字的主要优点是可以提高性能,尤其是在构造函数中包含复杂初始化逻辑的类的情况下。通过使用 late 关键字,您可以推迟初始化,直到实际需要使用该变量时再进行初始化。这可以避免在构造函数中执行不必要的初始化工作,从而提高性能。 以下是一些有关如何使用 late 关键字的示例: class MyWidget extends StatefulWidget { @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { late String _data; @override void initState() { super.initState(); // 此处推迟了 _data 变量的初始化 _loadData(); } void _loadData() async { // 模拟异步数据加载 await Future.delayed(Duration(seconds: 2)); setState(() { _data = 'Data loaded'; }); } @override Widget build(BuildContext context) { if (_data == null) { return CircularProgressIndicator(); } return Text(_data); } } 在这个示例中,_data 变量使用 late 关键字声明。这意味着该变量不必在声明时或构造函数运行之前初始化。相反,它可以在稍后初始化,例如在 initState 方法中。这可以提高性能,因为只有在实际需要使用该变量时才会进行初始化。...

May 24, 2024 · 8 min · 1578 words · sirius1y

【go的源码阅读】channel的实现:chan.go

channel的简单使用 在Go语言中,通道(channel)是一种用于在goroutine之间进行通信和同步的机制。下面是一些简单的通道使用示例,以及它们对应的底层函数调用。 package main import ( "fmt" "time" ) func main() { ch := make(chan int) // 创建通道 go func() { ch <- 42 // 发送数据到通道 }() go func() { value := <-ch // 从通道接收数据 fmt.Println("Received:", value) }() time.Sleep(1 * time.Second) // 等待goroutine完成 close(ch) // 关闭通道 } 底层函数调用 创建通道: ch := make(chan int) 底层调用: makechan(elemtype, size) 发送数据到通道: ch <- 42 底层调用: chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool 从通道接收数据:...

May 10, 2024 · 20 min · 4092 words · sirius1y

计算机基础知识

计算机网络 TCP TCP为什么要进行三次握手? 三次握手是建立网络连接的过程,确保双方能够正确地进行数据传输。 第一次握手SYN:客户端向服务端发送SYN请求同步信号,并初始化客户端序列号; 第二次握手SYN+ACK:服务端收到了客户端发送的SYN信号后回复ACK确认收到,同时也发送SYN,指定自己的初始序列号; 第三次握手ACK:客户端收到服务端的ACK+SYN后,回复一个ACK,表示已经收到服务端的ACK+SYN。这个包的序列会加一,表示客户端已经准备好和服务端进行数据传输了。 为什么是三次握手?不是两次或者四次 原因1:阻止重复的历史连接初始化 如果是两次握手的话,因网络堵塞的问题,客户端发送了两次SYN给服务端,服务端收到了第一个SYN的时候,就回复SYN+ACK给客户端,并进入了ESTABLISHED状态。而客户端这边收到了服务端旧的ACK+SYN,会认为这是历史连接从而发送RST报文,使服务端断开连接。 原因2:同步双方的序列号 TCP协议的双方都必须要维护一个序列号。两次握手只能保证一方的序列号被接收。 原因3:避免资源浪费 如果是两次握手,那么服务端在收到SYN后回复ACK的时候就要主动建立连接,要是网络堵塞,对面发了好多个SYN来,那完蛋了,建立了好多个TCP连接,造成了资源浪费。 TCP的四次挥手 四次挥手是指在TCP断开连接的过程中发生的,一般是由客户端发起,服务端完成最后的断开。 因为TCP是全双工通信,所以需要两边都要通知对方停止数据传输,故需要四次挥手保证断开连接。 具体流程:(刚开始双方都处于ESTABLISHED状态) 1.客户端向服务端发起FIN报文,表示客户端不再发送数据;(客户端进入FIN_WAIT_1中状态) 2.服务端收到FIN报文后,回复一个ACK表示收到;(服务端进入CLOSED_WAIT状态,客户端收到ACK后进入FIN_WAIT_2状态) 3.服务端向客户端发起FIIN报文,表示服务端也不再发送数据;(服务端进入LAST_ACK状态) 4.客户端收到服务端的FIN报文后,也回复一个ACK。(客户端进入TIME_WAIT状态) 发送端在最后会进入到TIME_WAIT的状态, 为什么有TIME_WAIT状态? 原因1:保证历史连接中的数据不会干扰下一次连接。 原因2:保证被动关闭连接。如果服务端没有TIME_WAIT状态直接close的话,要是服务端没有收到客户端最后一次发送的ACK会重发FIN,如果服务器已经处于CLOSE状态,就会返回RST报文,RST报文会被服务端认定为错误。 为什么TIME_WAIT的时间是2MSL? MSL是报文的最大生存时间,超过这个时间的报文都会被丢弃。两个MSL时间可以保证客户端发送的ACK报文可以到达服务端+服务端要是在第一个MSL中没有收到ACK可以重发一次FIN到客户端,并保证能够到达客户端。 HTTP GET方法和POST方法有什么区别? 用途:GET方法一般用于请求服务器上的数据;POST方法用于向服务器提交数据。 请求参数:GET方法的请求参数一般放在URL中,POST的请求参数一般放在请求体中。 幂等:多次执行相同的操作,结果都相同。 幂等行:GET方法是安全幂等的,POST不是幂等的。 缓存机制:GET请求会被浏览器主动cache,如果下一次传输的数据相同,就会返回浏览器中的内容;而POST不会。 GET的请求参数会被保存在浏览器的历史记录中,而POST中的参数不会保留 时间消耗:GET产生一个TCP数据包,浏览器会把header和data一起发送出去,服务器相应200; POST产生两个TCP数据包,浏览器先发送hader,服务器相应100(继续发送),浏览器再发送data,服务器相应200 什么情况下会使用POST读取数据? 当查询的数据量很多,GET方式的URL太长太大,GET方式大概是4KB,POST上限是8MB 当对数据的安全性有更高要求的时候,可以在POST的请求体中对数据进行加密 HTTP版本对比 HTTP/0.9 只支持GET方法 HTTP/1.0 支持多种请求方式 引入了请求头和响应头 引入状态码 不支持长连接 HTTP/1.1 支持长连接 管道网络传输(可以同时发送A、B请求,不必等待A响应) 但是管道网络传输存在队头阻塞的问题 头部冗余 没有请求优先级 请求只能通过客户端推送,服务器不能主动推送 HTTP/2 使用HPACK进行头部压缩 把数据部分压缩成头信息帧和数据帧 并发传输:引入了stream的概念,多个Stream复用一条TCP连接,通过streamID识别,不同stream的帧可以乱序发送 支持服务器推送 HTTPS 和HTTP对比 优点 安全性更高 缺点 HTTPS涉及到了加解密的过程,所以对服务器的负荷会高一些; 握手阶段的延迟比较高,因为还有SSL/TLS握手; 加密过程 HTTPS采用了对称加密+非对称加密的混合加密模式...

May 10, 2024 · 5 min · 987 words · sirius1y

知识复习:正则表达式

正则表达式是一种强大的文本匹配工具,它用于检索、替换那些符合某种模式(规则)的文本。 基本匹配 文字:最简单的正则表达式是普通的字符,如 a、b、1 等,它们会匹配文本中的相应字符。 特殊字符 .:匹配除换行符以外的任意单个字符。例如,a.b 可以匹配 acb、aab、a2b 等。 ^:匹配行的开头。例如,^a 会匹配以 a 开头的行。 $:匹配行的结尾。例如,a$ 会匹配以 a 结尾的行。 [ ]:匹配方括号内的任意字符。例如,[abc] 会匹配 a、b、或 c。 -:在方括号内使用时,表示字符范围。例如,[a-z] 匹配任何小写字母。 [^ ]:匹配不在方括号内的任意字符。例如,[^abc] 会匹配除 a、b、c 之外的任意字符。 重复 *:匹配前面的字符零次或多次。例如,a* 会匹配 ''、a、aa、aaa 等。 +:匹配前面的字符一次或多次。例如,a+ 会匹配 a、aa、aaa 等,但不会匹配 ''。 ?:匹配前面的字符零次或一次。例如,a? 会匹配 '' 和 a。 {n}:匹配前面的字符恰好 n 次。例如,a{3} 会匹配 aaa。 {n,}:匹配前面的字符至少 n 次。例如,a{2,} 会匹配 aa、aaa 等。 {n,m}:匹配前面的字符至少 n 次,但不超过 m 次。例如,a{2,4} 会匹配 aa、aaa、aaaa。 特殊字符类 \d:匹配任何数字,等价于 [0-9]。 \w:匹配任何字母数字字符,等价于 [a-zA-Z0-9_]。 \s:匹配任何空白字符,包括空格、制表符、换行符等。 分组和引用 ( ):将括号内的表达式定义为“组”(group),并按照顺序编号。可以使用 \数字 引用这些组。 或操作 |:匹配前后任意一个表达式。例如,a|b 会匹配 a 或 b。 实例应用 假设我们想匹配一个简单的日期格式 yyyy-mm-dd:...

March 30, 2024 · 1 min · 90 words · sirius1y

全国大学生市场调研大赛-数据分析

数据的预处理 删除答题时间小于1分钟的 对异常数据进行一些修改 检查有没有重复的问卷 保留研究所需要的列 处理公共题目缺失值 把数据分为总数据df,来过游客的数据df_gone,没有来过游客的数据df_not_gone,所有原始信息保留 对于df_gone和df_not_gone分别应用孤立森林清洗异常问卷 得到最后的数据集df, df_gone, df_not_gone import pandas as pd df = pd.read_csv('乌蒙大草原旅游问卷调查_final.csv') print(df.shape) df.head() 这两段代码主要是排除答题时间小于60s的问卷,不过问卷网上可以直接进行筛选 # 先把答题时间转换为时间格式 def convert_to_seconds(time_str): if '分' in time_str: minutes, seconds = time_str[:-1].split('分') return int(minutes) * 60 + int(seconds) else: return int(time_str[:-1]) df['答题时长'] = df['答题时长'].astype(str) df['答题时长'] = pd.to_timedelta(df['答题时长'].apply(convert_to_seconds), unit='s') # 删除答题时间小于1分钟的数据 df = df[df['答题时长'] > '00:01:00'] print(df.shape) df.head() 针对Q2年龄的一些数据问题进行处理 import seaborn as sns import matplotlib.pyplot as plt # 查看Q2有没有非数字的数据 df['Q2'].unique() # 修改数据 df['Q2'] = df['Q2']....

March 21, 2024 · 27 min · 5544 words · sirius1y