【K230 实战项目】气象时钟
【CanMV K230 AI视觉】 气象时钟
- 功能描述:
- 说明
- HMDI资源
- 3.5寸屏幕
- 使用方法
为了方便小伙伴们理解,请查看视频
B站连接

功能描述:
- 天气信息获取:通过连接到互联网,实时获取天气数据,包括温度、湿度、天气状况、风向
- 实时时间显示:气象时钟能够显示当前的时间。
- 可视化天气:包括城市, 温度,相对湿度,实时风向,空气质量
说明
HMDI资源
HDMI屏幕的小伙伴下载链接:K230 气象时钟文件,包含图片,字体,代码

我在此基础上做了一个HDMI的气象时钟。(为了让小伙伴多给上面的大佬点赞,我这边的资源是VIP资源。)小伙伴可以去大佬那里点赞领取代码文件。3.5屏幕的小伙伴直接使用。HDMI的,可以使用我下面的代码。(资源里都带)
3.5寸屏幕
由大佬Dai0707分享,下载链接原作者博客.https://forum.01studio.cc/t/topic/70/2


| 文件 | 说明 |
|---|---|
| ui | 图片 |
| urllib | 代码 |
| main.py | 3.5寸屏代码 |
| main咸鱼浆.py | HDMI代码 |
| Source… | 字体 |
'''
实验名称:天气时钟
实验平台:01Studio CanMV K230
镜像版本:V1.0
日期:2024-8-27验证发布
教程:wiki.01studio.cc
作者:半只半解
版本:v1.0
修改:咸鱼浆
HDMI显示,更改UI坐标等等
'''import os, time, gc, sys, network, json, re
from clock.urllib import urequest ,ntptime
from media.display import *
from media.media import *
from machine import Pin# 初始化 Wi-Fi 指示灯
WIFI_LED_PIN = 52
LED = Pin(WIFI_LED_PIN, Pin.OUT)
bg=image.Image(f"/sdcard/clock/ui/1.jpeg").to_rgb565()
# 选择显示方式
#Display.init(Display.ST7701) # 使用 LCD 屏幕显示
Display.init(Display.LT9611) #通过HDMI显示图像
# 初始化媒体管理器
MediaManager.init()# 创建图像对象用于绘制
canvas = image.Image(1920, 1080, image.RGB565)
canvas.clear() # 清空图像# WiFi账号密码
SSID ='123456'
CODE ='123456'time.sleep(5) #等待WiFi模块初始化def WIFI_Connect(max_retries=5):"""连接到指定的 Wi-Fi 网络,并在屏幕上显示连接状态。"""# 初始化 Wi-Fi 接口wlan = network.WLAN(network.STA_IF)wlan.active(True)start_time = time.time() # 记录时间做超时判断retries = max_retries # 重试次数if not wlan.isconnected():print('连接到网络...')canvas.clear() # 清除屏幕并显示 "正在连接到 WiFi..." 的信息canvas.draw_string_advanced(600, 500, 80, "正在连接到 WiFi...", color=(255, 255, 255))Display.show_image(canvas)wlan.connect(SSID, CODE) # WiFi连接while not wlan.isconnected(): # 添加重试逻辑LED.value(1)time.sleep_ms(300)LED.value(0)time.sleep_ms(300)if time.time() - start_time > 15: # 超时判断,15秒没连接成功判定为超时print('WIFI 连接超时 !')wlan.active(False)return Falseif wlan.isconnected():LED.value(1) # LED点亮canvas.clear()# 清除上次残留# 显示连接成功的信息canvas.draw_string_advanced(600, 200, 80, "WiFi 连接成功", color=(255, 255, 255))canvas.draw_string_advanced(600, 400, 80, "WiFi IP: " + wlan.ifconfig()[0], color=(255, 255, 255))canvas.draw_string_advanced(600, 600, 80, "咸鱼浆", color=(255, 137, 54))Display.show_image(canvas)print('网络信息:', wlan.ifconfig()) # 打印网络信息# 立即获取天气信息和同步时间weather_get()sync_ntp()return Trueelse:canvas.clear() # 清除上次残留canvas.draw_string_advanced(600, 500, 80, "连接失败!", color=(255, 255, 255))Display.show_image(canvas)for _ in range(3): # LED 闪烁三次提示连接失败LED.value(1)time.sleep_ms(300)LED.value(0)time.sleep_ms(300)print('连接失败!!!', wlan.ifconfig()) # 打印错误信信息并把LED重置为熄灭状态# LED 重置为熄灭状态LED.value(0)return False""""同步NTP服务器时间"""
def sync_ntp():ntp_servers = ['202.120.2.101', 'ntp.ntsc.ac.cn'] # 第二个NTP服务器作为备选for server in ntp_servers:ntptime.host = servertry:ntptime.settime()print(f"成功从 {server} 同步时间")breakexcept Exception as e:print(f"从 {server} 同步ntp时间错误: {repr(e)}")continueelse:print("所有NTP服务器均无法同步时间,请检查网络连接或NTP服务器地址。")""""处理日期和时间"""def zero_str(str_num):num = int(str_num)return "0" + str(num) if num > 0 and num < 10 else str(num)"""天气爬取"""# 定义一个长度为5的字符列表
weather = ['']*5
is_first_run = True # 添加一个标志来标记是否为首次运行def weather_get(max_retries=5):print("尝试获取天气数据...")global weatherretries = max_retries# 保存当前的天气信息previous_weather = weather.copy()while retries > 0:try:myURL = urequest.urlopen("http://www.weather.com.cn/weather1d/101070101.shtml")text = myURL.read(40000).decode('utf-8') # 获取前38000个数据以节省内存#text = myURL.read(40000) # 获取前38000个数据以节省内存 V1.1版本用这个# 在网页内容中找出 var observe24h_data 相关内容match = re.search('var observe24h_data = ' + '(.*?)' + ';', text)if match:text2 = json.loads(match.group(1))# 获取城市、温度、湿度、风向、风力级数weather[0] = text2['od']['od1'] # 城市weather[1] = text2['od']['od2'][0]['od22'] # 温度weather[2] = text2['od']['od2'][0]['od27'] # 相对湿度weather[3] = text2['od']['od2'][0]['od24'] # 实时风向weather[4] = text2['od']['od2'][0]['od28'] # 空气质量return # 成功获取数据后退出函数except Exception as e:print(f"Error fetching weather data: {e}")retries -= 1 # 减少重试次数if retries > 0:print(f"尝试重新获取天气数据,剩余{retries}次...")time.sleep(5) # 等待一段时间再重试# 如果获取失败,恢复之前的天气信息weather = previous_weather.copy()print("获取天气数据失败!")""""开始连接wifi"""try:wifi_connected = WIFI_Connect()
except Exception as e:print(f"连接WIFI失败: {e}")wifi_connected = False# 如果连接失败,显示连接失败的信息
if not wifi_connected:print('WiFi连接失败.')canvas.clear() # 清屏,黑色canvas.draw_string_advanced(600, 500, 80, "连接失败,复位重新连接!", color=(255, 255, 255))Display.show_image(canvas) # 显示while True:pass # 阻塞在此,不再继续执行
else:# 创建一个包含所有图片路径的列表#kof_paths = [f"/sdcard/clock/ui/kof/{i}.png" for i in range(1, 18)] # 从1到17#star_paths = [f"/sdcard/clock/ui/star/{i}.png" for i in range(1, 25)] # 从1到24#logo_paths = [f"/sdcard/clock/ui/logo/{i}.png" for i in range(1, 31)] # 从1到31# 预处理所有图像并转换为RGB565格式#star_rgb565 = [image.Image(path).to_rgb565() for path in star_paths]#kof_rgb565 = [image.Image(path).to_rgb565() for path in kof_paths]#logo_rgb565 = [image.Image(path).to_rgb565() for path in logo_paths]# 用于显示图片#star_index = 0#kof_index = 0#logo_index = 0# 获取空气质量字符串aqi_str = weather[4]# 初始绘制,首次绘制.if is_first_run:# 清除上次残留canvas.draw_rectangle(0, 0, 1920, 1080, color = (0, 0, 0), thickness = 2, fill = True)canvas.draw_image(bg, 0, 0, alpha=256, scale=1.0)canvas.draw_string_advanced(140, 20, 120, f" {weather[0]} ", color = (255, 165, 0))# 绘制温度湿度信息canvas.draw_string_advanced(150, 190, 120, f"温度: {weather[1]}℃", color=(255,160,122))canvas.draw_string_advanced(900, 190, 120, f"湿度: {weather[2]}%", color=(32,178,170))# 清楚上次残留,并绘制风向信息canvas.draw_rectangle(140, 900, 840, 140, color = (199, 212, 195), thickness = 2, fill = True)canvas.draw_string_advanced(140, 900, 120, f"实时风向: {weather[3]}", color=(255, 255, 0))# 空气质量try:aqi = int(aqi_str)except ValueError:aqi = 0 # 设置默认值if 0 <= aqi < 50: # 优canvas.draw_rectangle(900, 30, 120, 100, color=(0, 255, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 优!", color=(0, 0, 0))elif 50 <= aqi < 100: # 良canvas.draw_rectangle(900, 30, 120, 100, color=(249, 218, 101), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 良", color=(0, 0, 0))elif 100 <= aqi < 150: # 轻度canvas.draw_rectangle(900, 30, 120, 100, color=(255, 165, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 轻度", color=(0, 0, 0))elif 150 <= aqi < 200: # 中度canvas.draw_rectangle(900, 30, 120, 100, color=(212, 106, 106), thickness=2, fill=True)canvas.draw_string_advanced(900, 20, 80, f" 中度", color=(0, 0, 0))elif 200 <= aqi < 300: # 重度canvas.draw_rectangle(900, 30, 120, 100, color=(220, 20, 60), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 重度", color=(0, 0, 0))elif 300 <= aqi < 500: # 严重canvas.draw_rectangle(900, 30, 120, 100, color=(139, 0, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 严重", color=(0, 0, 0))is_first_run = False # 设置标志为False,下次循环不绘制这些信息# 主循环last_weather_update = time.time() # 记录最后一次更新天气的时间try:while True:os.exitpoint() #检测IDE中断current_time = time.time() # 当前时间localtime_now = time.localtime() # 每次循环开始时定义 localtime_nowif current_time - last_weather_update > 1000: # 每隔1000秒更新一次天气信息last_weather_update = current_timeweather_get() # 获取天气sync_ntp() # 同步时间aqi_str = weather[4] # 更新空气质量字符串# 在同步时间之后获取本地时间并格式化time_str = '%s-%s-%s %s:%s:%s' % (localtime_now[0], # 年zero_str(localtime_now[1]), # 月zero_str(localtime_now[2]), # 日zero_str(localtime_now[3]), # 小时zero_str(localtime_now[4]), # 分钟zero_str(localtime_now[5]) # 秒)print("当前日期和时间:",time_str)# 清除上次残留, # 日期:年月日canvas.draw_rectangle(140, 400, 950, 200, color = (214, 202, 56), thickness = 2, fill = True)canvas.draw_string_advanced(120, 390, 180, f" {localtime_now[0]}-{zero_str(localtime_now[1])}-{zero_str(localtime_now[2])}", color=(144,238,144))# 清除上次残留, # 城市信息canvas.draw_rectangle(150, 20, 140, 140, color = (0, 0, 0), thickness = 2, fill = True)canvas.draw_string_advanced(140, 20, 120, f" {weather[0]} ", color = (255, 165, 0))# 绘制温度湿度信息canvas.draw_string_advanced(150, 190, 120, f"温度: {weather[1]}℃", color=(255,160,122))canvas.draw_string_advanced(900, 190, 120, f"湿度: {weather[2]}%", color=(32,178,170))# 清楚上次残留,并绘制风向信息canvas.draw_rectangle(140, 900, 840, 140, color = (199, 212, 195), thickness = 2, fill = True)canvas.draw_string_advanced(140, 900, 120, f"实时风向: {weather[3]}", color=(255, 255, 0))# 空气质量try:aqi = int(aqi_str)except ValueError:aqi = 0 # 设置默认值if 0 <= aqi < 50: # 优canvas.draw_rectangle(900, 30, 120, 100, color=(0, 255, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 优!", color=(0, 0, 0))elif 50 <= aqi < 100: # 良canvas.draw_rectangle(900, 30, 120, 100, color=(249, 218, 101), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 良", color=(0, 0, 0))elif 100 <= aqi < 150: # 轻度canvas.draw_rectangle(900, 30, 120, 100, color=(255, 165, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 轻度", color=(0, 0, 0))elif 150 <= aqi < 200: # 中度canvas.draw_rectangle(900, 30, 120, 100, color=(212, 106, 106), thickness=2, fill=True)canvas.draw_string_advanced(900, 20, 80, f" 中度", color=(0, 0, 0))elif 200 <= aqi < 300: # 重度canvas.draw_rectangle(900, 30, 120, 100, color=(220, 20, 60), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 重度", color=(0, 0, 0))elif 300 <= aqi < 500: # 严重canvas.draw_rectangle(900, 30, 120, 100, color=(139, 0, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 严重", color=(0, 0, 0))############主循环绘制############# 清除上次残留, # 日期:年月日canvas.draw_rectangle(140, 400, 950, 200, color = (214, 202, 56), thickness = 2, fill = True)canvas.draw_string_advanced(120, 390, 180, f" {localtime_now[0]}-{zero_str(localtime_now[1])}-{zero_str(localtime_now[2])}", color=(144,238,144))# 清除上次残留,# 时间 :小时分钟秒canvas.draw_rectangle(140, 620, 700, 170, color = (102, 218, 119), thickness = 2, fill = True)canvas.draw_string_advanced(120, 610, 150, f" {zero_str(localtime_now[3])}:{zero_str(localtime_now[4])}:{zero_str(localtime_now[5])}", color=(199, 237, 204))# 图片绘制## canvas.draw_image(star_rgb565[star_index], 480, 0, alpha=256, scale=1.0)# canvas.draw_image(kof_rgb565[kof_index], 700,700, alpha=256, scale=1.0)Display.show_image(canvas) # 显示图片time.sleep_ms(20) # 消除图片过快鬼畜# 查询内存,可有可无K230随便造这些小功能DRAM = gc.mem_free()if DRAM < 1000000: # 内存不足gc.collect() # 回收内存# 更新索引,使用模运算实现循环# star_index = (star_index + 1) % len(star_rgb565)# kof_index = (kof_index + 1) % len(kof_rgb565)# logo_index = (logo_index + 1) % len(logo_rgb565)# bg = (bg) % len(bg_rgb565)except KeyboardInterrupt:print("用户停止程序")except Exception as e:print(f"发生异常: {e}")finally:# 释放显示资源Display.deinit()MediaManager.deinit()os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
使用方法
大致使用方法:
1,首先连接WIFI

输入WIFI账号密码
2,默认获取的是深圳市的气象数据

修改城市的方法也很简单,找到这段代码

把HTTP复制 在浏览器上粘贴

改一下自己想看的地方,然后吧链接替换就行

相关文章:
【K230 实战项目】气象时钟
【CanMV K230 AI视觉】 气象时钟 功能描述:说明HMDI资源3.5寸屏幕 使用方法 为了方便小伙伴们理解,请查看视频 B站连接 功能描述: 天气信息获取:通过连接到互联网,实时获取天气数据,包括温度、湿度、天气状…...
什么是 HTTP/3?下一代 Web 协议
毫无疑问,发展互联网底层的庞大协议基础设施是一项艰巨的任务。 HTTP 的下一个主要版本基于 QUIC 协议构建,并有望提供更好的性能和更高的安全性。 以下是 Web 应用程序开发人员需要了解的内容。 HTTP/3 的前景与风险 HTTP/3 致力于让互联网对每个人…...
IDEA Project不显示/缺失文件
问题:侧边栏project 模式下缺少部分文件 先点close project 打开项目所在目录,删除目录下的.idea文件夹 重新open project打开这个项目即可解决...
浅谈vue2.0与vue3.0的区别(整理十六点)
目录 1. 实现数据响应式的原理不同 2. 生命周期不同 3. vue 2.0 采用了 option 选项式 API,vue 3.0 采用了 composition 组合式 API 4. 新特性编译宏 5. 父子组件间双向数据绑定 v-model 不同 6. v-for 和 v-if 优先级不同 7. 使用的 diff 算法不同 8. 兄弟组…...
深入理解 MySQL MVCC:多版本并发控制的核心机制
在数据库领域,并发控制是确保多个事务能够正确地并发执行而不破坏数据完整性的关键技术。MySQL 作为广泛使用的关系型数据库管理系统,采用了多版本并发控制(Multi-Version Concurrency Control,MVCC)机制来实现高效的并…...
Qt6编译达梦8数据库驱动插件
一、编译环境 操作系统:deepin V23 Qt版本: Qt 6.7.2 编译器:gcc/g version 12.3.0,cmake 3.28.3 达梦数据库:开发版V8 二、下载达梦QT接口源码 下载链接: https://eco.dameng.com/downlo…...
什么是机器学习力场
机器学习力场(Machine Learning Force Fields, MLFF)方法是一类将机器学习技术应用于分子动力学(Molecular Dynamics, MD)模拟的技术。它通过使用机器学习算法拟合原子之间的相互作用能量和力场,使得在不牺牲精度的前提…...
USB组合设备——串口+鼠标+键盘
文章目录 USB组合设备——串口+鼠标+键盘描述符结构设备描述符配置描述符集合配置描述符接口关联描述符键盘接口描述符鼠标接口描述符类特殊命令CDC 的类特殊命令HID 的类特殊命令接口 2接口3USB组合设备——串口+鼠标+键盘 描述符结构 设备描述符 配置描述符 接口关联描述符…...
python学习——对无人机影像有RGB转换到HSV
问题描述 最近需要对无人机影像中绿色植被信息进行提取,查看相关论文,发现用的比较多的就是HSV色彩转换方法,动手实践一下。 解决思路 #mermaid-svg-5ejGodIusPv6zFVS {font-family:"trebuchet ms",verdana,arial,sans-serif;fon…...
【南方科技大学】CS315 Computer Security 【Lab2 Buffer Overflow】
目录 引言软件要求启动虚拟机环境设置禁用地址空间布局随机化(ASLR)设置编译器标志以禁用安全功能 概述BOF.ctestShellCode.c解释 createBadfile.c 开始利用漏洞在堆栈上查找返回地址 实验2的作业 之前有写过一个 博客,大家可以先看看栈溢出…...
持续集成与持续交付CI/CD
CI/CD 是指持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery) 持续集成(Continuous Integration) 持续集成是一种软件开发实践&…...
C++学习笔记之变量作用域
C学习笔记之变量作用域 https://www.runoob.com/cplusplus/cpp-variable-scope.html 在C程序中,通常有 3 个地方可以声明变量 在函数或者代码块当中,为局部变量在函数的参数定义中,为形式参数在所有函数的外部,为全局变量 作用域…...
解决跨境电商平台账号无法访问的常见问题
跨境电商的迅猛发展,越来越多的卖家选择在全球各大电商平台如亚马逊、eBay等进行商品销售。然而,在实际运营过程中,卖家经常会遇到账号无法访问、应用打不开等问题,导致业务受阻。本文将针对这些问题进行详细分析,并提…...
P2847 [USACO16DEC] Moocast G
P2847 [USACO16DEC] Moocast G [USACO16DEC] Moocast G 题面翻译 Farmer John 的 N N N 头牛 ( 1 ≤ N ≤ 1000 1 \leq N \leq 1000 1≤N≤1000) 为了在他们之间传播信息,想要组织一个"哞哞广播"系统。奶牛们决定去用步话机装备自己而不是在很远的距离…...
针对国内AIGC市场,国内目前出台了那些法律法规?
针对国内AIGC市场,特别是AI生成与合成内容方面,中国已经出台了一系列法律法规来规范其发展和应用。 图片源自“央视新闻” 以下是一些主要的法律法规: 一、国家层面的法律法规 《中华人民共和国网络安全法》 施行时间:2017年6月…...
Windows+Ubuntu双系统下时钟设置
Ubuntu默认把系统时间(硬件时钟)设置为UTC时间,并根据本地时区和夏令时设置自动调整本地时间,这是一种很合理很优雅的处理硬件时钟和本地时钟的模式。而Windows系统是默认情况下把系统时间设置为本地时间,历来独霸电脑…...
一些写leetcode的笔记
标准库中的string类没有实现像C#和Java中string类的split函数,所以想要分割字符串的时候需要我们自己手动实现。但是有了stringstream类就可以很容易的实现,stringstream默认遇到空格、tab、回车换行会停止字节流输出。 #include <sstream> #incl…...
shopify主题开发之template模板解析
在 Shopify 主题开发中,template 文件是核心部分,它们定义了店铺中不同页面的布局和结构。下面将详细介绍 Shopify 主题中的 template 模板。 一、template 文件结构 在 Shopify 主题中,templates 文件夹包含了所有用于生成店铺页面的模板文…...
Zookeeper学习
文章目录 学习第 1 章 Zookeeper 入门1.1 概述Zookeeper工作机制 1.2 特点1.3 数据结构1.4 应用场景统一命名服务统一配置管理统一集群管理服务器动态上下线软负载均衡 1.5 下载zookeeper 第 2 章 Zookeeper 本地安装2.1 本地模式安装安装前准备配置修改操作 Zookeeper本地安装…...
FAT32文件系统详细分析 (格式化SD nandSD卡)
FAT32 文件系统详细分析 (格式化 SD nand/SD 卡) 目录 FAT32 文件系统详细分析 (格式化 SD nand/SD 卡)1. 前言2.格式化 SD nand/SD 卡3.FAT32 文件系统分析3.1 保留区分析3.1.1 BPB(BIOS Parameter Block) 及 BS 区分析3.1.2 FSInfo 结构扇区分析3.1.3 引导扇区剩余扇区3.1.4 …...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
