简介 存储设备分为两大类主存和辅存,另外还有专门提供存储服务的网络存储
主存储器 随机存取存储器(RAM, Random Access Memory) 特点:高速、易失性存储器,断电后数据丢失。用途:临时存储正在使用的数据和程序,提高系统运行速度。类型: DRAM(Dynamic RAM):常见类型,需要定期刷新以保持数据。即内存条SRAM(Static RAM):速度更快,不需要刷新,但更昂贵,主要用于CPU中的缓存。 只读存储器(ROM, Read-Only Memory) 特点:非易失性存储器,断电后数据不会丢失。用途:存储固件(如计算机的BIOS)和不可更改的数据。类型: PROM(Programmable ROM):可编程一次。EPROM(Erasable PROM):可紫外线擦除和重新编程。EEPROM(Electrically Erasable PROM):可电擦除和重新编程。 辅助存储器 这里主要介绍固态硬盘和U盘
机械硬盘(HDD, Hard Disk Drive) 特点:机械结构,磁性存储,容量大,成本低,但速度较慢。用途:主要用于长期存储大量数据。工作原理:通过旋转磁盘和磁头的读写操作存取数据。 固态硬盘(SSD, Solid State Drive) 特点:无机械部件,基于闪存技术,速度快,抗震性好,价格较高。用途:替代传统硬盘,提高系统性能和启动速度。类型 SATA SSD:使用SATA接口,速度相对较慢。NVMe SSD:使用PCIe接口,速度更快。 U盘(USB Flash Drive) 特点:便携式、基于闪存技术、通过USB接口连接。用途:临时存储和传输数据。 光盘存储设备 CD(Compact Disc):用于音乐和数据存储,容量约700 MB。DVD(Digital Versatile Disc):用于视频和数据存储,容量为4.7 GB(单层)或8.5 GB(双层)。Blu-ray Disc:用于高清视频和数据存储,也就是蓝光碟片,容量为25 GB(单层)或50 GB(双层)。 磁带存储设备 特点:容量大,成本低,速度慢,主要用于数据备份和归档。用途:长期数据存储,企业级备份解决方案。 存储卡 SD卡(Secure Digital Card):广泛用于数码相机、智能手机等。microSD卡:体积更小,广泛用于智能手机和平板电脑。 网络存储设备 网络附加存储(NAS, Network Attached Storage) 特点:通过网络提供存储服务,易于共享和管理。用途:家庭和小型企业的数据存储和共享。 存储区域网络(SAN, Storage Area Network) 特点:高性能存储网络,通常用于大型企业。用途:提供集中式存储管理和高性能数据访问。 内存条 内存条,即内存DRAM,主要衡量标准是内存颗粒的好坏,体现为内存频率的高低,但内存频率对使用体验影响没有那么大,受cpu限制,而且不同的内存的频率都没有太大的变化,所以简要了解。
【5minC++基本功】——左值与右值|左值引用与右值引用 1. 为什么要学习左值与右值?2.左值和右值的概念2.1 什么是左值?2.1.1 常见的左值 2.3 什么是右值?2.3.1 常见的纯右值2.2.2 什么是将亡值2.2.3 产生将亡值的情形 1. 为什么要学习左值与右值? C++当中的值语义:
GC(Garbage Collection, 垃圾回收)语言之中, 大部分变量都是引用语义, 内存管理交给GC. 通过值语义, 能够方便直观地控制对象的生命周期,让RAII(Resource Acquisition Is Initialization, 即通过构造和析构函数来获取和释放资源,管理变量的生命周期)用起来更自然.
C++ 11中引入了右值引用的概念, 实现移动语义和完美转发, 提高程序的性能和效率. 这也成为C++相关岗位面试中的一大热点, 因此很有必要掌握左值与右值的概念, 以及左值引用和右值引用的相关知识.
2.左值和右值的概念 2.1 什么是左值? —— 简单地说, 它是指向内存位置的表达式,其值可以被修改, 它的特点是:
可以出在等号左边; 能够取地址 具有别名 2.1.1 常见的左值 变量名 int x = 5; 返回左值引用的函数调 // 返回变量 x 的引用 int& getX() { return x; } 前置自增自减 int y = ++x; // 预增操作,x 先自增再赋值给 y, 这里的++x返回的就是一个左值 ++x = 10; // ++x, 自增操作返回一个左值,可以用10对其赋值 赋值运算或复合赋值运算 ++x = 10; // 自增操作返回左值,可以赋值 std::cout << "
前言 Exif 规范 定义了方向标签,用于指示相机相对于所捕获场景的方向。相机可以使用该标签通过方向传感器自动指示方向,也可以让用户通过菜单开关手动指示方向,而无需实际转换图像数据本身。
在图像处理过程中,若是原图文件包含了方向 Orientation 信息,会导致输出的图片在方向上有些许偏差。一般我们需要在处理图像之前将方向信息去掉,并将图像处理成正确的展示形式。
Orientation说明 拍摄图像时相机相对于场景的方向。“第 0 行”和“第 0 列”与视觉位置的关系如下所示。
值第 0 行第 0 列描述1顶部左边0度:正确方向,无需调整2顶部右边水平翻转3底部右边180度旋转4底部左边水平翻转+180度旋转 (垂直翻转)5左边顶部水平翻转+顺时针270度6右边顶部顺时针270度7右边底部水平翻转+顺时针90度8左边底部顺时针90度 图例说明:
如何查看 系统自带的 preview 的显示检查器可直接查看: 通过命令行工具 Mac可以安装 brew install exiftool 后使用 exiftool 工具进行查看:
处理方式 既然知道了方向定义的含义,就按照相反的方式就行处理即可。
自己通过 Pillow 库实现了一个简单的方法:
from PIL import Image def reset_image_rotate(im: Image) -> Image: # 0x0112 EXIF tags: Orientation ,see PIL.ExifTags.TAGS orientation_code = im.getexif().get_ifd(0x0112) if orientation_code == 2: im = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) elif orientation_code == 3: im = im.
一、实现目标 编写一个爬虫,获取豆瓣网站上“庆余年 第二季”这部电视剧的短评,网站如下:
# https://movie.douban.com/subject/34937650/comments?sort=new_score&status=P #
二、实现步骤 我们在 Google Chrome浏览器中复制粘贴下面的链接,先看看网页内容,打开网页后可以看到,《庆余年 第二季》这部电视剧的相关短评,就在标注的红色方框内。这就是我们今天要获取的内容。
想要获取网页中的短评,首先要获取网页 HTML 代码,再把短评从中提取出来。
2.1 获取网页源码 获取网页中的 HTML 代码,我们可以使用 requests 模块的 get 方法来实现。
# 使用import导入requests模块 import requests # 将豆瓣电影评论URL地址,赋值给变量url url = "https://movie.douban.com/subject/34937650/comments?sort=new_score&status=P" # 使用requests发起GET请求,赋值给response response = requests.get(url) # 使用print输出response.status_code print(response) 这里执行后返回的状态码是418,这意味我们的爬虫被服务端发现了,因为我们用的是 requests 发起的请求,而不是浏览器。
我们需要加上User-Agent参数,伪装成一个浏览器。User-Agent参数值的获取方法也很简单,在chome浏览器中右键检查,在网络功能中可以看到客户端访问服务的请求,在请求头中包括本机的User-Agent参数,直接拿来用即可,如下图。
将User-Agent参数的值以字典的形式的存储在headers参数中,然后在请求时带上headers参数。
# 使用import导入requests模块 import requests # 将豆瓣电影评论URL地址,赋值给变量url url = "https://movie.douban.com/subject/34937650/comments?sort=new_score&status=P" # 将User-Agent以字典键对形式赋值给headers headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.
main.cpp #include "stdafx.h" #include "CNetCrawler.h" #include"afxmt.h" #include"DownloadData.h" #include"MainThread.h" #include"ProjectDlg.h" #include"CNetCrawlerDlg.h" #include<afxinet.h> //向http服务器发送请求及网络相关操作的头文件 #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CCNetCrawlerDlg *pDlg; //主窗口的指针 extern bool ThreadPause; //是否暂停线程 //全局变量 / // MainThread IMPLEMENT_DYNCREATE(MainThread, CWinThread)//在类声明中包含了DECLARE_DYNCREATE 允许CObject派生类对象在运行时自动建立 //用户界面线程构造函数 MainThread::MainThread() { //用户界面线程构造函数 m_bDone=false; //初始化线程未停止 } MainThread::~MainThread(){ } //函数功能:初始化 BOOL MainThread::InitInstance(){ //重写初始化函数 // TODO: perform and per-thread initialization here //生成一个新建工程对话框 //设置共享数据 m_DownData.SetPro(m_FileId,m_ThreadNum,m_LocalDir);//根据用户设定起始文件名称,最大线程数量,保存路径 m_BeginURL.MakeLower();//起始地址的设置 if(m_BeginURL.Find(_T("http://"))==-1) str_BeginURL=_T("http://")+m_BeginURL;//若初始的URL地址并不是以http://开头,则加入 else str_BeginURL=m_BeginURL; //将初始URL地址赋值给工程起始网络地址变量str_BeginURL str_ProjectName=m_ProjectName;//工程名的设置 CWnd *button; //窗口类中的按钮 button=pDlg->GetDlgItem(IDC_BUTTON_NEW);//通过子窗口IDC_BUTTON_NEW得到窗口指针 button->EnableWindow(FALSE);//设置该指定的窗口禁止接受鼠标和键盘的输入 Run(str_BeginURL); //运行守护线程,启动工作者线程,下载网页 return TRUE; } /* int MainThread::ExitInstance(){ CWnd *button; button=pDlg->GetDlgItem(IDC_BUTTON_NEW); button->EnableWindow(TRUE); //线程结束,设置该指定的窗口允许鼠标和键盘的输入 // TODO: perform any per-thread cleanup here return CWinThread::ExitInstance(); } */ int MainThread::ExitInstance(){ CWnd *button; button=pDlg->GetDlgItem(IDC_BUTTON_NEW); button->EnableWindow(TRUE); //线程结束,设置该指定的窗口允许鼠标和键盘的输入 ThreadPause=false; pDlg->m_active=true;//-置回初始值,以便新建下一个工程(7.
日志描述 日志路径:Hive相关日志的默认存储路径为“/var/log/Bigdata/hive/角色名”,Hive1相关日志的默认存储路径为“/var/log/Bigdata/hive1/角色名”,以此类推。
HiveServer:“/var/log/Bigdata/hive/hiveserver”(运行日志),“/var/log/Bigdata/audit/hive/hiveserver”(审计日志)。MetaStore:“/var/log/Bigdata/hive/metastore”(运行日志),“/var/log/Bigdata/audit/hive/metastore”(审计日志)。WebHCat:“/var/log/Bigdata/hive/webhcat”(运行日志),“/var/log/Bigdata/audit/hive/webhcat”(审计日志) 日志归档规则:Hive的日志启动了自动压缩归档功能,缺省情况下,当日志大小超过20MB的时候(此日志文件大小可进行配置),会自动压缩,压缩后的日志文件名规则为:“<原有日志名>-<yyyy-mm-dd_hh-mm-ss>.[编号].log.zip”。最多保留最近的20个压缩文件,压缩文件保留个数和压缩文件阈值可以配置
表 1 Hive日志列表 日志类型
日志文件名
描述
运行日志
/hiveserver/hiveserver.out
HiveServer运行环境信息日志
/hiveserver/hive.log
HiveServer进程的运行日志
/hiveserver/hive-omm-<日期>-<PID>-gc.log.<编号>
HiveServer进程的GC日志
/hiveserver/prestartDetail.log
HiveServer启动前的工作日志
/hiveserver/check-serviceDetail.log
Hive服务启动是否成功的检查日志
/hiveserver/cleanupDetail.log
HiveServer卸载的清理日志
/hiveserver/startDetail.log
HiveServer进程启动日志
/hiveserver/stopDetail.log
HiveServer进程停止日志
/hiveserver/localtasklog/omm_<日期>_<任务ID>.log
Hive本地任务的运行日志
/hiveserver/localtasklog/omm_<日期>_<任务ID>-gc.log.<编号>
Hive本地任务的GC日志
/metastore/metastore.log
MetaStore进程的运行日志
/metastore/hive-omm-<日期>-<PID>-gc.log.<编号>
MetaStore进程的GC日志
/metastore/postinstallDetail.log
MetaStore安装后的工作日志
/metastore/prestartDetail.log
MetaStore启动前的工作日志
/metastore/cleanupDetail.log
MetaStore卸载的清理日志
/metastore/startDetail.log
MetaStore进程启动日志
/metastore/stopDetail.log
MetaStore进程停止日志
/metastore/metastore.out
MetaStore运行环境信息日志
/webhcat/webhcat-console.out
Webhcat进程启停正常日志
/webhcat/webhcat-console-error.out
Webhcat进程启停异常日志
/webhcat/prestartDetail.log
WebHCat启动前的工作日志
/webhcat/cleanupDetail.log
Webhcat卸载时或安装前的清理日志
/webhcat/hive-omm-<日期>-<PID>-gc.log.<编号>
WebHCat进程的GC日志
/webhcat/webhcat.log
WebHCat进程的运行日志
审计日志
hive-audit.log
hive-rangeraudit.log
HiveServer审计日志
metastore-audit.log
MetaStore审计日志
webhcat-audit.log
WebHCat审计日志
jetty-<日期>.request.log
Jetty服务的请求日志
动态IP可以说是做爬虫、采集数据、搜集热门商品信息中必备的代理工具,但在爬虫的使用中,总是会遇到动态IP掉线的情况,从而影响使用效率,本文将探讨动态IP代理掉线的几种常见原因,并提供解决方法,以帮助大家更好地利用动态IP服务。
1. 网络连接不稳定 网络连接不稳定是导致动态IP代理掉线的最常见原因之一。当网络连接出现波动或断开时,动态IP代理将无法正常工作,导致掉线。
解决方法:
确保网络连接稳定:尽量使用稳定的网络连接,避免连接到信号不佳或不稳定的网络。更换网络环境:尝试连接到不同的网络环境,例如切换到另一个Wi-Fi网络或使用移动数据网络。 2. IP地址被封禁 一些网站会采取各种反爬虫策略,例如验证码验证、IP封锁、用户行为分析等,以防止爬虫程序对其数据进行非法获取。在面对这些策略时,使用动态IP的爬虫程序更容易被网站检测到并进行拦截,再加上代理IP不够干净,很容易发生掉线、限制访问的情况。
解决方法:
使用高质量的代理服务:选择信誉良好、稳定可靠的代理服务提供商,避免使用低质量或免费的代理服务,降低IP被封禁的风险。避免频繁更换IP地址:尽量减少频繁更换IP地址的行为,以降低被封禁的可能性。模拟真实用户行为,比如模拟鼠标点击、随机浏览页面、User-Agent等,来减少IP被封禁的可能性。 4. 代理软件或配置问题 有时动态IP代理掉线可能是由于代理软件或配置问题导致的。例如,代理软件可能存在漏洞或兼容性问题,配置错误也可能导致代理无法正常工作。
解决方法:
更新代理软件:确保使用最新版本的代理软件,并及时安装更新补丁以修复可能存在的漏洞。检查代理配置:仔细检查代理配置,确保设置正确,搭建正确的网络环境,并根据需要进行调整或更改。 5. 服务器负载过高 当代理服务器的负载过高时,可能会导致动态IP代理掉线。服务器负载过高可能是由于并发过多导致的,也可能是由于服务器性能不足或配置不当导致的。
解决方法:
使用稳定的代理服务:选择具有良好服务器性能和稳定负载的代理服务提供商,避免使用负载过高的代理服务器。避开高峰时段:尽量避开代理服务器负载高的高峰时段,选择低负载时段使用代理服务,以减少掉线的可能性。合理设置并发数量:尽管服务供应商无限并发数,但使用时并不是并发数越多越好的,IP并发过多也会导致服务器负载过高,从而导致掉线。
一.基本概念 1.Ioc基本概念 Ioc: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器. 什么是控制反转呢?
也就是控制权反转. 什么的控制权发发了反转? 获得依赖对象的过程被反转了也就是说, 当需要某个对象时, 传统开发模式中需要自己通过 new 创建对象, 现在不需要再进行创建, 把创建对象的任务交给容器, 程序中只需要依赖注入(Dependency Injection,DI)就可以了. 这个容器称为:IoC容器. Spring是一个IoC容器,所以有时Spring也称为Spring容器.
控制反转是一种思想, 在生活中也是处处体现.
比如自动驾驶, 传统驾驶方式, 车辆的横向和纵向驾驶控制权由驾驶员来控制, 现在交给了驾驶自动化系统来控制, 这也是控制反转思想在生活中的实现.比如招聘, 企业的员工招聘,入职, 解雇等控制权. 老板转交给HR(人力资源)来处理 2.DI基本概念 DI: Dependency Injection(依赖注入)容器在运行期间, 动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。程序运行时需要某个资源,此时容器就为其提供这个资源.从这点来看, 依赖注入(DI)和控制反转(IoC)是从不同的角度的描述的同⼀件事情,就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间的解耦。IoC 是⼀种思想,也是"目标", 而思想只是一种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现。所以也可以说, DI 是IoC的一种实现. 比如说我今天心情比较好,吃一顿好的犒劳犒劳自己,那么"吃一顿好的"是思想和目标(是IoC),但最后我是吃海底捞还是杨国福?这就是具体的实现,就是 DI。 二.Ioc的使用. IoC交给Spring管理共有两类注解可以实现: 类注解:@Controller、@Service、@Repository、@Component、@Configuration. 方法注解:@Bean. 2.1类注解 2.1.1@Controller注解 使用@Controller存储 bean 的代码如下所示:
@Controller // 将对象存储到 Spring 中 public class UserController { public void sayHi(){ System.
🌈 个人主页:danci_
🔥 系列专栏:《设计模式》《MYSQL应用》
💪🏻 制定明确可量化的目标,坚持默默的做事。
文章目录 一、Explain1.1 explain作用1.2 explain列说明`id``select_type``table``partiitons``type``select_type``possible_keys``key``key_len(key_len值计算)``key_len的计算:(举几个类型)``ref``rows``filtered``Extra` 一、Explain 1.1 explain作用 在sql语句前添加explain,作用是查看mysql对这条sql的执行计划信息。 思考:MYSQL执行SQL语句时一定按这个执行计划执行么? 1.2 explain列说明 在一条简单SQL前面添加explain查看有哪些列,如下:
id 每个select对应一个id值,其值是按 select 出现的顺序增长的。
注:id值越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行
select_type 每个select对应一个select_type,表示select的复杂度,有:
SIMPLE:简单查询。查询不包含子查询和union,如上图
PRIMARY:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARY SUBQUERY:包含在 select 中的子查询(不在 from 子句中) DERIVED:对于包含‘派生表’的查询 UNION:在 union 中的第二个和随后的 select table 这一列表示 explain 的一行正在访问哪个表。 当 from 子句中有子查询时,table列是 <derivenN> 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查 询。 当有 union 时,UNION RESULT 的 table 列的值为<union1,2>,1和2表示参与 union 的 select 行id。 partiitons 匹配的分区信息 type 这一列表示关联类型或访问类型 效率从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL SQL性能优化的目标:至少要达到range级别,要求是ref级别,最好是consts级别。 system:当表中只有一条记录并且该表使用的存储引擎的统计数据都是精确地,表最多有一个匹配行,读取1次,速度比较快。 const:system是 const的特例,表里只有一条元组匹配时为system eq_ref:primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。 ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会 找到多个符合条件的行。 range:用索引获取某些范围区间的记录。 select_type 每个select对应一个select_type,表示select的复杂度 SIMPLE:简单查询。查询不包含子查询和union,如上图 PRIMARY:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARY SUBQUERY:包含在 select 中的子查询(不在 from 子句中) DERIVED:对于包含‘派生表’的查询 UNION:在 union 中的第二个和随后的 select possible_keys 标识某个表查询时可能使用哪些索引来查找。 key 实际使用哪个索引。 当possible_keys有值,而key没有值时,可能是因为表数据很少,mysql认为没有必要走索引,直接全表查询了。 当possible_keys为null时,可根据实际情况在where条件中添加索引来提升查询效率。 key_len(key_len值计算) 实际使用到的索引的字节数,帮我们检查是否充分利用上了索引,对于联合索引有一定的参考意义。 比如有列n和address的联合索引(表my_datas字段有id, n, address 和 time)
一、创建本地仓库 需要将本地仓库放在一个目录下,所以在创建本地仓库之前,应该先创建一个目录,再进入这个目录:
在这个目录中创建一个本地仓库:
git init 创建完成后,我们就会发现当前目录下多了一个.git的隐藏文件:
这样就表示本地仓库已经创建完成了。
二、本地仓库的配置 本地仓库创建以后要为其设置用户名和邮箱:
git config user.name "用户名" git config user.email "邮箱" 如果加上--global选项表示设置的用户名或邮箱会在所有的本地仓库中生效:
git config --global user.name "用户名" git config --global user.email "邮箱" 如果要取消设置的用户名或邮箱,直接加上--unset选项即可:
git config --unset user.name "用户名" git config --unset user.email "邮箱" git config --global --unset user.name "用户名" git config --global --unset user.email "邮箱" git config -l:可以用来查看当前git的配置列表。 三、工作区、暂存区、版本库的认识 我们不能直接修改.git目录下的内容。.git就叫做本地仓库,也叫做版本库,我们要修改只能在创建了本地仓库的这个目录中增删文件,我们把这个目录叫做本地仓库的工作区。
在上图中,stage叫做暂存区或者是索引。我们日常所做的add操作就会将工作区中修改(新增,修改,删除)的内容保存到暂存区中,我们日常所做的commit操作就是将暂存区中的内容添加到master分支中,经过第二步commit操作我们才能说我们已经将工作区中修改的内容放在了版本库中,经过add和commit两步后我们才能让git来管理修改的内容。
在版本库中,其实还有一个叫对象库的东西,修改的工作区的内容会写入对象库的一个新的git对象中,每add一次对象库就会存放一次修改的内容的对象,保存了每一次修改的内容其实就做到了版本的管理。暂存区中其实保存的就不是一个个的对象了而是对象的索引,所以暂存区是比较轻量级的,从而我们也可以知道,master分支中其实存放的也是对象的索引。
从上面的.git的树状图中我们也可以看到,有HEAD指针,对象库(objects)。
华为:
<AR6121E-S>dis acl 3333
Advanced ACL 3333, 4 rules
Acl's step is 5
rule 5 permit icmp source 192.168.188.2 0 destination 192.168.88.88 0 rule 10 permit icmp source 192.168.88.88 0 destination 192.168.188.2 0 rule 15 permit udp source 14.23.154.114 0 source-port eq 1701 destination 14.145.146.57 0 (7 matches)
rule 20 permit udp source 14.145.146.57 0 destination 14.23.154.114 0 destination-port eq 1701 (7 matches)
int g0/0/8
traffic-filter inbound acl 3333
Mac环境如何使用Flutter Version Manager (fvm) Flutter Version Manager (fvm) 是一个 Flutter 版本管理工具,它允许开发者在本地安装并管理多个 Flutter 版本。使用 fvm,您可以轻松切换不同版本的 Flutter SDK,进行多项目开发而无需重复安装。本文将为您提供一个全面的指南,介绍如何在 Mac 环境下安装和使用 fvm。
什么是 fvm? fvm 是一个命令行工具,用于简化 Flutter 版本的管理工作。它允许您:
安装多个 Flutter 版本。轻松切换当前使用的 Flutter 版本。创建特定 Flutter 版本的隔离环境。列出所有已安装的 Flutter 版本。 环境要求 在开始安装之前,请确保您的 Mac 系统满足以下基本要求:
macOS 系统(推荐最新版本)Homebrew 安装在您的 Mac 上(macOS 的包管理器) 安装步骤 1. 安装 Homebrew(如果尚未安装) Homebrew 是 macOS 的包管理器,它将简化 fvm 的安装过程。打开终端(Terminal)并运行以下命令来安装 Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2. 安装 fvm 使用 Homebrew 安装 fvm,只需在终端运行以下命令:
brew install fvm 3.
Mac环境如何安装Flutter:全面指南 Flutter 是 Google 开发的开源移动 UI 框架,允许开发者使用 Dart 语言快速在 iOS 和 Android 上构建高质量的原生界面。本指南将详细指导您如何在 Mac 环境下安装 Flutter,确保您能够顺利开始 Flutter 开发之旅。
环境要求 在开始安装之前,请确保您的 Mac 满足以下基本要求:
macOS 系统(推荐最新版本,至少是 Big Sur 11.3)至少 2 GB 的 RAM(建议 4 GB 以上)至少 200 MB 的硬盘空间用于安装 Flutter SDKXcode 命令行工具(用于编译 iOS 应用) 安装步骤 1. 安装 Homebrew Homebrew 是 macOS 的包管理器,它将简化 Flutter 的安装过程。打开终端(Terminal)并运行以下命令来安装 Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2. 安装 Flutter SDK 安装完 Homebrew 后,可以通过它来安装 Flutter SDK。在终端运行以下命令:
brew tap dart-lang/dart brew install dart brew tap flutter/flutter brew install flutter 这将安装 Dart SDK 和 Flutter SDK。
MySQL 中的逻辑函数允许你根据条件对数据进行判断和选择。以下是一些常用逻辑函数的详细介绍和示例:
IF(expr1, expr2, expr3) 如果 expr1 是真(非零和非 NULL),IF() 函数返回 expr2,否则返回 expr3。
SELECT IF(1 0, 'true', 'false'); -- 结果: 'true' CASE CASE 函数有两种格式:简单 CASE 和搜索 CASE 函数。它们都允许在条件语句中进行选择。
简单 CASE 函数 当有一个表达式需要与一系列值进行比较时使用。
SELECT CASE 2 WHEN 1 THEN 'one' WHEN 2 THEN 'two' WHEN 3 THEN 'three' ELSE 'other'END; -- 结果: 'two' 搜索 CASE 函数 当需要基于多个条件进行判断时使用。
SELECT CASE WHEN 1 0 THEN 'true' WHEN 2 < 1 THEN 'false' ELSE 'unknown'END; -- 结果: 'true' COALESCE(expr1, expr2, .
前言
本篇博客我们正式开启数据结构中的排序,说到排序,我们能联想到我之前在C语言博客中的冒泡排序,它是排序中的一种,但实现效率太慢,这篇博客我们介绍两种新排序,并好好深入理解排序
💓 个人主页:小张同学zkf
⏩ 文章专栏:数据结构
若有问题 评论区见📝 🎉欢迎大家点赞👍收藏⭐文章
目录
1.排序
1.1排序的概念
1.2排序的常见算法
2.插入排序
3.选择排序
1.排序 1.1排序的概念 排序 :所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j] ,且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。 内部排序 :数据元素全部放在内存中的排序。 外部排序 :数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。 1.2排序的常见算法 2.插入排序 即冒泡排序外,我们来认识一下一个新的排序
直接插入排序是一种简单的插入排序法,其基本思想是: 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列 。 实际中我们玩扑克牌时,就用了插入排序的思想 我们来看一下动图
如何用代码实现出来这个插入排序那
我们观察动图其实可以看到假如一趟0~end数是有序的,那么end+1的数得挨个与0~end数比较,比较若比end+1的数大,向右移一位,继续与下一位比较,若比end+1的数小,就插在这个数的前面,进行下一趟重复此过程
代码如下
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> void charupaixu(int* a, int x) { for (int i = 0; i < x - 1; i++) { int end =i; int tmp = a[end + 1]; while (end >= 0) { if (a[end] > tmp) { a[end+1] = a[end]; end--; } else{ break; } } a[end + 1] = tmp; } } int main() { int arr[] = { 2,4,89,23,987,123,5678,13,76,67,6666}; charupaixu(arr, sizeof(arr) / sizeof(arr[0])); for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { printf("
一、PostgreSQL介绍 PostgreSQL是一个功能强大的 开源 的关系型数据库。底层基于C实现。
PostgreSQL的开源协议和Linux内核版本的开源协议是一样的。。BDS协议,这个协议基本和MIT开源协议一样,说人话,就是你可以对PostgreSQL进行一些封装,然后商业化是收费。
PostgreSQL的名字咋来的。之前叫Ingres,后面为了解决一些ingres中的一些问题,作为后面的ingres,就起名叫postgre。
PostgreSQL版本迭代的速度比较快,现在最新的正式的发布版本,已经到了15.RELEASE。
PGSQL的版本选择一般有两种:
如果为了稳定的运行,推荐使用12.x版本。如果想体验新特性,推荐使用14.x版本。 PGSQL允许跨版本升级,而且没有什么大问题。
PGSQL社区特别活跃,基本是三个月一发版。意味着很多常见的BUG都可以得到及时的修复。
PGSQL其实在国外使用的比较多,国内暂时还是以MySQL为主。
但是国内很多国产数据库都是基于PGSQL做的二次封装:比如华为GaussDB还有腾讯的Tbase等等。真实很多公司原来玩的Oracle,直接平转到PGSQL。同时国内的很多云产品都支持PGSQL了。
PGSQL因为开源,有很多做数据迁移的工具,可以让你快速的从MySQL,SQLServer,Oracle直接平转到PGSQL中内部,比如pgloader这样的数据迁移工具。
PGSQL的官方地址:https://www.postgresql.org/
PGSQL的国内社区:http://www.postgres.cn/v2/home
二、PostgreSQL和MySQL的区别 技术没有好坏之分,知识看一下是否符合你的业务,能否解决你的业务需求。其次也要查看社区的活跃度以及更新的频次。
MySQL不支持的几点内容:
MySQL的数据类型不够丰富。MySQL不支持序列概念,Sequence。使用MySQL时,网上比较好用的插件。MySQL的性能优化监控工具不是很多,定位问题的成本是比较高。MySQL的主从复制没有一个官方的同步策略,同步问题难以解决。MySQL虽然开源,but,不够彻底。 PostgreSQL相对MySQL上述问题的特点:
PostgreSQL的数据类型嘎嘎丰富。PostgreSQL是有序列的概念的。PostgreSQL的插件特别丰富。PostgreSQL支持主从复制的同步操作,可以实现数据的0丢失。PostgreSQL的MVCC实现和MySQL不大一样。PostgreSQL一行数据会存储多个版本。最多可以存储40亿个事务版本。 三、PostgreSQL的安装 咱们只在Linux中安装,不推荐大家在Windows下安装。
Linux的版本尽量使用7.x版本,最好是7.6或者是7.8版本。
去官网找按照的方式
选择好PGSQL的版本,已经Linux的发行版本
拿到命令,麻也不管,直接扔到Linux中运行即可
# 下载PGSQL的rpm包 sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # 安装PGSQL12的软件程序,需要下载,需要等一会,一般不会失败,即便失败,他也会重新帮你找镜像 sudo yum install -y postgresql12-server # 数据库初始化 sudo /usr/pgsql-12/bin/postgresql-12-setup initdb # 设置开启启动项,并设置为开启自行启动 sudo systemctl enable postgresql-12 # 启动PGSQL sudo systemctl start postgresql-12 这种属于Windows下的傻瓜式安装,基本不会出错。如果出错,可能是那些问题:
安装Linux的时候,一定要选择最小安装你的Linux不能连接外网Linux中的5432端口,可能被占用了 PostgreSQL不推荐使用root管理,在安装成功postgreSQL后,他默认会给你创建一个用户:postgres
玩PGSQL前,先切换到postgres
su postgres 奇幻到postgres用户后,直接输入psql即可进入到postgreSQL提供的客户端
# 进入命令行 psql # 查看有哪些库,如果是新安装的,有三个库,一个是postgres,template0,template1 \l 其次不推荐下载Windows版本去玩
导言 在C语言中除了结构体外,联合体和枚举也是自定义类型,联合体主要用于节省空间,在同一块内存存储多种类型的数据,而枚举可以提高代码的可读性、可维护性。
联合体(union) 它还有个更容易理解的名字:“共用体”,它有多个成员,成员可以为不同类型,但是编译器只会给最大的成员分配内存空间,所有成员共用一块空间。
联合体的创建 //联合体的创建 union un { int x; int y; }; int main() { union un tmp = { 0 }; return 0; } 联合体的初始化 联合体的初始化只能对整个联合体进行初始化,因为所有联合成员共用一块内存,初始化后所有的成员都是这个值,不管成员类型是否一致。
联合体的访问与结构体一致,这里不再介绍
联合体的大小 联合体大小计算规则:
●联合体大小最少为最大成员的大小
●当最大成员的大小不为最大对齐数的整数倍时,联合体大小要对齐到最大对齐数的整数倍
示例:
值得注意的是:在计算数组的对齐数时,与默认数比较的不是整个数组的大小,而是数组单个元素的大小。
联合体的运用 1.假如一家商店要进一批货,分别为书、卡牌、玩具。这三样物品都有公共属性和私有属性
公共属性:进货量、价格、生产年份
私有属性:
●书:作者、页数、版号
●卡牌:形状(圆或方)
●玩具:颜色、尺寸
使用结构体定义:
struct goods { //公共属性:进货量、价格、生产年份 int count; int price; int year; //私有属性: //书:作者、页数、版号 char name[20]; int pages; int vn; //卡牌:形状(圆或方) int shape; //玩具:颜色、尺寸 char color[10]; int size; };//占用空间60字节 使用联合体定义:
LlaMA 3 系列博客 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (一)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (二)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (三)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (四)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (五)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (六)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (七)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (八)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (九)
基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (十)
Kafka发送消息是异步发送的,所以我们不知道消息是否发送成功,所以会可能造成消息丢失。而且Kafka架构是由生产者-服务器端-消费者三种组成部分构成的。要保证消息不丢失,那么主要有三种解决方法。
生产者(producer)端处理 生产者默认发送消息代码如下:
import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; import java.util.Properties; public class KafkaMessageProducer { public static void main(String[] args) { // 配置Kafka生产者 Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); // Kafka集群地址 props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); // 键的序列化器 props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); // 值的序列化器 // 创建Kafka生产者实例 Producer<String, String> producer = new KafkaProducer<>(props); String topic = "test"; // Kafka主题 try { // 发送消息到Kafka for (int i = 0; i < 10; i++) { String message = "
kafka数据写入流程 1.生产者先从zookeeper的"/brokers/topic/主题名/partitions/分区名/state"节点找到该partition的leader
生产者在ZK中找到对应的broker
broker进程上的leader将消息写入到本地log中。
follower从leader上拉取消息,写入到本地log,并向leader发送ACK
leader接收到所有的ISR中的Replica的ACK中,并向生产者返回ACK
Kafka数据消费流程 两种消息队列消费 kafka采用拉取模型,由消费者自己记录消费状态,每个消费者相互独立的顺序拉取消息。
消费者可以按照任意的顺序消费消息。比如,消费者可以重置到旧的偏移量,重新处理之前已经消费过的消息;或者直接跳到最近的位置,从当前的时刻开始消费。
Kafka消费数据流程 每个consumer都可以根据分配策略(默认RangeAssignor),获得要消费的分区。获取到consumer对应的offset(默认从ZK获取上一次消费的offset)找到分区的leader,拉取数据。消费者提交offset Kafka的数据存储形式 一个topic有多个partition分区组成。
一个分区(partition)有多个segment(段)组成。
一个segment(段)由多个文件组成(log,index,timeindex)
存储日志 Kafka中的数据到底是怎么在磁盘中存储的。
kafka中的数据保存在/export/server/kafka_2.12-2.41/data中
消息是保存在以:【主题名-分区ID】的文件夹中的。
数据文件夹中包含以下内容
这些分别对应:
文件名说明0000000000000000000.index索引文件,根据offset查找数据就是通过该索引文件来操作的。0000000000000000000.log日志数据文件0000000000000000000.timeindex时间索引 leader-epoch-checkpoint
持久化每个partition leader对应的LEO(log end offset,日志文件中下一条待写入消息的offset) 每个日志文件的文件名为起始偏移量,因为每个分区的起始偏移量是0,所以,分区的日志文件都以0000000000000000000.log开始
默认的每个日志文件最大为「log.segment.bytes =1024*1024*1024」1G
为了简化根据offset查找消息,Kafka日志文件名设计为开始的偏移量
观察测试 为了方便测试观察,新创建一个topic:「test_10m」,该topic每个日志数据文件最大为10
bin/kafka-topics.sh --create --zookeeper node1.itcast.cn --topic test_10m --replication-factor 2 --partitions 3 --config segment.bytes=10485760 使用之前的生产者程序往「test_10m」主题中生产数据,可以观察到如下:
新的消息总是写入到最后的一个日志文件中
该文件如果到达指定的大小(默认为:1GB)时,将滚动到一个新的文件中
读取消息 根据【offset】首先需要找到存储数据的segment段(注意:offset指定分区的全局偏移量)
然后根据这个【全局分区offset】找到相对于文件的【segment段offset】
最后再根据 「segment段offset」读取消息
为了提高查询效率,每个文件都会维护对应的范围内存,查找的时候就是使用简单的二分查找
删除消息 在Kafka中,消息是会被定期清理的。一次删除一个segment段的日志文件
Kafka的日志管理器,会根据Kafka的配置,来决定哪些文件可以被删除