一、概述 1.1 背景 概念:锁是多线程编程中的机制,用于控制对共享资源的访问。可以防止多个线程同时修改或读取共享资源,从而保证线程安全。
作用:锁用于实现线程间的互斥和协调,确保在多线程环境下对共享资源的访问顺序和正确性。
1.2 锁分类 【按锁性质划分】:
乐观锁:认为一个线程获取共享数据的时候,不会存在其他线程修改该共享数据的情况,所以不会上锁。例如:CAS机制、版本号机制等悲观锁:认为一个线程获取共享数据时,一定会存在其他线程修改该共享数据的情况,因此,获取共享数据时都会进行加锁。例如:Synchronized锁、ReentrantLock锁。 【按锁被持有数量划分】:
独占锁:当前锁只有被一个线程持有。例如:ReentrantLock锁;共享锁:当前锁可以被多个线程持有。例如:Semaphore等。 【按公平性划分】:
公平锁:多个线程竞争锁时,需要进行排队,按照先来后到顺序获取锁。例如:ReentrantLock公平锁。非公平锁:多个线程竞争锁时,先进行插队,插入失败再排队。例如:Synchronized锁、ReentrantLock锁 【按可重入性划分】:
可重入锁:允许一个线程多次加锁。例如:Synchronized锁、ReentrantLock锁
。不可重入锁:允许一个线程仅加锁一次。 【按锁范围划分】:
单体锁:仅能锁住当前JVM进程中的共享资源,对其他JVM进程中的共享资源不起作用。例如: Synchronized锁和ReentrantLock锁;分布式锁:借助中间件,对多个JVM进程中的同一共享资源都能锁住。例如:Redis分布式锁。 二、单JVM进程锁 2.1 独占锁 2.1.1 synchronized锁 详情见:深入解析Synchronized锁底层原理
局限性:
是否释放锁,开发者无法自己控制,导致其他线程只能一直阻塞;若获取锁的线程进入休眠或阻塞,除了线程出现异常,否则其他线程将会一直阻塞等待。
因此,在JDK1.5后,加入了Doug Lea大神贡献的java.util.concurrent包,包内提供了Lock类,提供了更加灵活控制锁的功能,弥补了Synchronized的缺陷。 2.1.2 ReentrantLock锁 Lock完全是由Java编写,提供了锁获取和释放的控制权、可中断的获取锁以及超时获取锁等多种高级特性。Lock只是一个接口,常见的实现类有:
1. 重入锁:ReentrantLock; 2. 读锁:ReadLock 3. 写锁:WriteLock 但底层都是通过聚合了一个java 同步器(AbstractQueueSynchronizer, AQS)来完成线程的访问控制的。因此,需要提前了解AQS的底层原理。详情见:深入解析AQS队列同步器的底层原理
ReentrantLock实现了Lock接口,同时底层通过聚合AQS完成并发的功能【注意:此时state只能为0或1】。主要有以下特点:
1. 支持重进入的锁,表示该锁能够支持一个线程对资源的重复加载,同时还支持获取锁的公平和非公平性。 2. 构造方法会接收一个可选的公平参数(默认是非公平锁)。设置为true时,表示公平锁;否则为非公平锁。 3. 可重入性的体现:任意线程获取锁之后,再次获取该锁时,不会被锁所阻塞。因为是可重入的,有一个计数器记录重入次数n, 当n = 0时表明锁完全被释放。 ReentrantLock实现的公平锁和非公平锁的区别:
1. 获取锁的时候是否按照FIFO的顺序来的。公平锁不仅会对state状态进行判断,还会判断当前同步队列中是否有元素,如果存在元素,则插入到同步队列的尾部,真正的先来后到; 2. 非公平锁性能高于公平锁性能。非公平锁可以减少CPU唤醒线程的开销,整体的吞吐率会高点,CPU也不会唤醒所有的线程,减少唤醒线程的数量。具体原因为: 【公平锁获取锁:】会将线程自己添加到等待队列的队尾并休眠,当某线程用完锁之后,会去唤醒等待队列中队首的线程尝试去获取锁,锁的使用顺序也就是队列中的先后顺序。在整个过程中,线程会从运行状态切换到休眠状态,再从休眠状态恢复成运行状态,但线程每次休眠和恢复都需要从用户态转换成内核态,而这个状态的转换是比较慢的,所以公平锁的执行速度会比较慢。 】非公平锁获取锁:】当线程获取锁时,会先通过 CAS 尝试获取锁,如果获取成功就直接拥有锁,如果获取锁失败才会进入等待队列,等待下次尝试获取锁。这样做的好处是,获取锁不用遵循先到先得的规则,从而避免了线程休眠和恢复的操作,这样就加速了程序的执行效率。 3. 非公平锁会存在线程饥饿的情况。但出现线程饥饿的机率非常低可以忽略不记。这就是默认非公平锁的原因。 2.1.3 局限性 synchronized和ReentrantLock锁,一次仅允许一个线程访问资源,即属于独占性。对于多个线程同时访问共享资源的场景,是无能为力的。不过Java也提供了对应的解决方案:java Semaphore信号量、CountDownLatch以及CyclicBarrier共享锁。
2.2 共享锁 java Semaphore信号量、CountDownLatch以及CyclicBarrier共享锁底层的原理是相通的,都是基于AQS队列同步器来实现的。相比于独占锁,主要区别在于state值设置可由开发者进行控制,这样就可以实现多个线程同时访问共享资源。AQS底层原理见:深入解析AQS队列同步器的底层原理。
上一章:数据结构——单向链表(C语言版)-CSDN博客
目录
什么是双向链表?
双向链表的节点结构
双向链表的基本操作
完整的双向链表示例
总结
什么是双向链表? 双向链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两个指针:一个指向前一个节点,一个指向后一个节点。双向链表可以在任意位置高效地插入和删除节点,相比单向链表,双向链表可以双向遍历,但相应地需要更多的内存空间存储额外的指针。
双向链表的节点结构 typedef struct Node { int data; struct Node* prev; struct Node* next; } Node; 双向链表的基本操作 初始化双向链表
Node* initLinkedList() { Node* head = (Node*)malloc(sizeof(Node)); head->prev = NULL; head->next = NULL; return head; } 插入节点 void insertNode(Node* prevNode, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->prev = prevNode; newNode->next = prevNode->next; prevNode->next->prev = newNode; prevNode->next = newNode;} 3.删除节点 void deleteNode(Node* delNode) { delNode->prev->next = delNode->next; delNode->next->prev = delNode->prev; free(delNode); } 遍历双向链表 void printLinkedList(Node* head) { Node* current = head->next; while (current !
intelliJ 今天遇到使用intelliJ遇到了一个新错误,有问题就解决问题是一个程序员最基本的修养,如下:
在上面的代码中,我使用了this.这个关键字,发现出现了以上问题,找了一些资料,不是很明白,最后发现了在intelliJ右上角有错误和警告标识,鼠标放上去之后出现All problem
点击All Problem,出现None、Syntax 、All Problem
选中None即可,点击之后警告跟错误全部没有了。
总结:“cannot access java.lang.String IntelliJ” 这条错误消息表示 IntelliJ IDEA(一个流行的 Java 集成开发环境)在尝试访java.lang.String 类时遇到了问题。java.lang.String 是 Java 标准库中的一个核心类,它用于表示字符串。
这个错误通常意味着以下几种情况之一:
1.类路径问题:你的项目可能没有正确设置类路径(classpath),导致 IntelliJ IDEA 无法找到 Java 标准库。
2.JDK设置错误:你的项目可能没有正确配置 JDK(Java 开发工具包),或者可能配置了一个损坏的 JDK。
3.依赖冲突:如果你的项目中有一些依赖管理问题,比如多个版本的同一个库,这也可能导致访问问题。
4.IntelliJ IDEA配置问题:IntelliJ IDEA 的内部配置可能出现了问题,需要重置或更新。
5.代码或库损坏:有时,Java 标准库本身或其引用可能由于某种原因而损坏。
目录
Colorlib
生成代码
模块代码
导入测试
测试一
测试二
应用测试
颜色列表 colorList
随机颜色元组 randcolorTuples
随机颜色字串 randcolorStrings
Color类测试
测试一
测试二
题外话
Colorlib 有没有碰到过这样的场景:写代码时想要用上丰富的色彩,但苦思冥想搜肠刮肚只记得这几个常用颜色词: 'BLACK', 'WHITE', 'RED', 'GREEN', 'BLUE', 'YELLOW', 'MAGENTA', 'CYAN',是不是有点尴尬。本篇将介绍怎样从现有库中抽取出有用的颜色自己创建一个库,比如seaborn库的colors包以及pygame库的colordict中都定义了很多种颜色,想到就马上行动起来,动手创建一个自定义颜色库——Colorlib。
生成代码 使用 python IDLE 载入以下代码,按F5就能一键生成自定义颜色库 colorlib.py:
from seaborn.colors import xkcd_rgb, crayons from pygame.colordict import THECOLORS str2tuple = lambda s: tuple(map(lambda x:int(x,16),(s[1:3],s[3:5],s[5:]))) tuple2str = lambda t: '#'+hex(t[0]*256**2+t[1]*256+t[2])[2:].rjust(6,'0').upper() ColorDict = {} for k,v in (*THECOLORS.items(), *xkcd_rgb.items(), *crayons.items()): ColorDict[k] = str2tuple(v) if isinstance(v, str) else v[:3] for c in ('aqua', 'cyan', 'grey', 'pink', 'purple'): ColorDict[c.
1.前言 作为一名从事规划行业的人来讲,计算图斑的椭球面积在工作中是必不可少的,熟悉ArcGIS的人一般会使用下面这些步骤来计算(我的软件版本为ArcGIS 10.2.2 for Desktop):
打开图层属性表;右键要计算椭球面积的字段,进入字段计算器;解析程序选择Python,并在下方输入【!shape.geodesicArea!】,如果需要保留两位小数则输入【round(!shape.geodesicArea!,2)】,点击确定即可计算出椭球面积。 但在实际工作中,难免会遇到面积很小的图斑,而这些面积很小的图斑用上述步骤计算出来可能会出现面积为0的情况。
在最初的时候,这种情况令我百思不得其解,不过我还是找到了一个解决办法,就是去ArcGIS Pro中计算几何(选择测地线面积),这种方法可以保证不管图斑有多小都会有数值计算出来,就在我以为问题解决了的时候,新的问题又出现了。如下:
上面的图片是用ArcGIS 10.2.2计算的,下面的图片是用ArcGIS Pro 3.0.0计算的,可以看到面积相差1.2平方米左右,经过核查,我发现这次是ArcGIS 10.2.2算的准,而ArcGIS Pro却算的不准了,而差的这1.2平方米在数据检查时是会报错的。
这种情况勾起了我的好奇心,想要知道这是为什么,因此我去网上查找有没有相关经验,结果是没有。我又去找有没有计算椭球面积的小工具,但结果是虽然有很多人分享工具和代码出来,但工具大多是要付费的,代码也不是我熟悉的Python语言。
所以这次只能自己写一个计算椭球面积的代码,前后加起来大概花了一天时间完成(在此感谢空间规划工具箱作者@规划酱大大对我的帮助与解惑),经过测试,椭球面积达到了准确无误,源代码免费分享出来,希望能帮到和我一样有困惑的人。
2.源代码分享 椭球面积计算依据:《TD/T 1055-2019 第三次全国国土调查技术规程》中的附录D-图斑椭球面积计算公式及要求。
编写环境:Anaconda3 (64-bit)、Python2.7、ArcGIS10.2.2。
最终做成一个ArcGIS的工具箱,代码如下(由于是我个人使用,函数和变量的命名方式不喜勿喷,我认为有必要加注释的地方都加了注释):
import arcpy import math # 常数 pi = 3.14159265358979 ipi = pi / 180.0 p = 206264.8062471 # 中央经线弧度 L0 = 114.0 * ipi # CGCS2000 椭球常数如下 a = 6378137.0 # 椭球长半轴 f = 1.0 / 298.257222101 #椭球扁率 b = 6356752.31414036 # 椭球短半轴 e1 = 0.
这篇文章主要介绍了怎么在python里面安装库,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。
Python模块安装主要有两种方法(安装方法很多,只列举了常用的两种):
一、通过Pycharm终端安装
1、打开Pycharm,在程序最下面一栏找到终端,单击进入
2、进入终端后,输入:pip install 模块名,按回车(enter键)即可安装
3、等待进度条跑完,提示信息:Successfully installed代表安装成功
二、通过电脑命令行窗口进行安装
1、返回到电脑桌面,按住键盘的win+R(先按win,再按R)
2、弹出运行窗口,在里面输入cmd,打开命令行窗口
3、输入Python,查看Python是否正确安装,也可以查看Python安装的版本
4、 pip uninstall 模块名,卸载已安装的模块
pip install 模块名,重新安装模块
同样提示:Successfully installed代表安装成功
如果小伙伴们发现下载速度很慢,可以使用国内的镜像,下载步骤跟上面一样,只是命令有所变化,命令如下:
pip install 模块名 -i 国内镜像地址 ;
国内常用源镜像地址:
清华:
https://pypi.tuna.tsinghua.edu.cn/simple
中国科技大学 :
https://pypi.mirrors.ustc.edu.cn/simple/
阿里云:
http://mirrors.aliyun.com/pypi/simple/
华中理工大学:
http://pypi.hustunique.com/
---------------------------END--------------------------- 题外话 当下这个大数据时代不掌握一门编程语言怎么跟的上时代呢?当下最火的编程语言Python前景一片光明!如果你也想跟上时代提升自己那么请看一下.
感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面python做个笑脸。
二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典
简历模板
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
若有侵权,请联系删除
llama.cpp 介绍 部署 介绍 大模型的研究分为训练和推理两个部分:
训练的过程,实际上就是在寻找模型参数,使得模型的损失函数最小化;推理结果最优化的过程; 训练完成之后,模型的参数就固定了,这时候就可以使用模型进行推理,对外提供服务。
llama.cpp 主要解决的是推理过程中的性能问题。主要有两点优化:
llama.cpp 使用的是 C 语言写的机器学习张量库 ggmlllama.cpp 提供了模型量化的工具 计算类 Python 库的优化手段之一就是使用 C 重新实现,这部分的性能提升非常明显。另外一个是量化,量化是通过牺牲模型参数的精度,来换取模型的推理速度。llama.cpp 提供了大模型量化的工具,可以将模型参数从 32 位浮点数转换为 16 位浮点数,甚至是 8、4 位整数。
除此之外,llama.cpp 还提供了服务化组件,可以直接对外提供模型的 API 。
使用量化模型 下载编译 llama.cpp
git clone https://github.com/ggerganov/llama.cpp cd llama.cpp make 在目录下会生成一系列可执行文件
main:使用模型进行推理quantize:量化模型server:提供模型 API 服务… 准备 llama.cpp 支持的模型
llama.cpp 支持转换的模型格式有 PyTorch 的 .pth 、huggingface 的 .safetensors 、还有之前 llamma.cpp 采用的 ggmlv3。
在 huggingface 上找到合适格式的模型,下载至 llama.cpp 的 models 目录下。
git clone https://huggingface.co/4bit/Llama-2-7b-chat-hf .
环境:路由器上需要身份认证的Mini NAS + macOS Sonoma 14
这是一个非常简单的问题,但解决方法却藏得比较深,不够直观,GPT也没有给出明确的解决提示,特意记录一下。
macOS很多地方都很自动,有时候让人找不到设置或更改的地方;具体的例子是在路由器上有个需要身份认证的Mini NAS,NAS就是要用samba协议;
开始默认状态一:注意后面的种类为Mac
图一
按192-168-xxx-1 就报错了
图二
知道是“连接身份”出了问题,也知道只要修改了连接身份问题就解决了,但是在界面上直观感觉可能的地方都按了一遍,就是没有找到对的地方,然后咨询了不同的GPT也没有特别明确的答复,最后看苹果官方的说明,因为只有文字说明,不够直观,反复看了很多遍才找到要领,所以记录在此以便以后查询。
在哪里更改"macOS的连接身份"?
根据苹果官网的说明实际上并不难找
在Finder访达里,见下图:
图三
路径:访达->前往->连接服务器 (最下面或用快捷键Command + K),然后输入服务器名称或IP地址,见图四
图四
输入服务器后按右下角的“连接”,如果可以正常连接,同时在需要输入用户名和密码时会跳出图五
图五
在没有需求时不会出现图五,在输入用户名和密码后右下角的“连接”会变活,点击“连接”后如果一起正常可以在图六看到新增加的一条记录。
图六
第二条就是连接成功的NAS,注意后面的“种类”为PC。
在Windows里很简单,在需要输入用户名时会自动跳出界面,无需自己寻找入口。
城市空气质量数据采集系统设计与实现 🏙️ 研究背景 🌬️ 城市化与环境挑战:随着城市化进程的加快,环境污染问题,尤其是空气质量问题,已成为公众关注的焦点。数据监测的重要性:城市空气质量数据的准确获取对于环境管理和政策制定至关重要,但目前存在数据来源不稳定和质量参差不齐的问题。 国外经验借鉴 🌐 发达国家的监测体系:许多发达国家已建立完善的空气质量监测体系,并实施严格的环保政策。研究与技术进展:国外研究机构和大学在空气质量数据采集和分析方面取得了显著成果,为我国提供了宝贵的经验。 国内现状分析 🏠 环保意识的提升:随着环保意识的增强,城市空气质量监测受到政府和公众的高度关注。监测站点的建立:中国各地政府和科研机构已建立空气质量监测站点,但数据获取和整合仍面临挑战。 研究目标和内容 🎯 目标城市:采集中国33个城市的空气质量数据。
数据指标:包括城市名、更新时间、AQI指数、PM2.5、So2、CO、PM0、No2、O3等。
数据采集与保存:使用网络爬虫技术实时抓取数据,并通过pandas保存到本地Excel表格。
数据可视化:利用Echarts技术对数据进行可视化,分析影响空气质量的关键参数。
研究方法 🛠️ 网络抓包分析:通过Chrome浏览器分析XHR动态请求,确定数据源。数据校验:对采集到的数据进行校验,确保数据的准确性。实时数据抓取:运用网络爬虫技术在线抓取空气质量数据。数据整合与保存:使用pandas工具整合数据,并保存到本地。
结语 📜 本研究旨在通过设计并实现一个城市空气质量数据采集系统,提高数据采集的效率和准确性,为城市环境管理和公众健康提供科学依据。通过这一系统,我们期望能够为相关部门提供决策支持,促进环保政策的制定和城市环境质量的改善。
步骤概述 分析网页结构:检查目标网页的HTML结构,确定数据存放的位置。选择爬虫工具:使用如Python的requests和BeautifulSoup库。发送HTTP请求:获取目标网页的内容。解析响应内容:使用BeautifulSoup提取所需数据。数据清洗和存储:对提取的数据进行清洗,并存储到适当的格式中。遵守法律法规:确保爬虫行为符合法律法规和网站政策。 示例代码 以下是一个使用Python编写的简单爬虫示例,用于爬取和打印目标网页上的空气质量数据。
import requests from bs4 import BeautifulSoup # 目标网页URL url = 'https://air.cnemc.cn:18007/' # 发送HTTP请求 response = requests.get(url) # 检查请求是否成功 if response.status_code == 200: # 解析HTML内容 soup = BeautifulSoup(response.text, 'html.parser') # 根据实际的HTML结构找到包含空气质量数据的元素 # 假设数据在一个类名为"city-data"的<div>中 cities_data = soup.find_all('div', class_='city-data') # 遍历每个城市的数据 for city_data in cities_data: # 提取城市名 city_name = city_data.
目录
一、什么是MySQL数据库
二、基于SpringBoot框架连接MySQL数据库
1、首先添加MySQL依赖:
2、配置数据库连接:
3、创建实体类:
4、创建Repository接口:
5、使用Repository:
三、编写业务SQL语句
1、使用Spring Data JPA的方法命名约定:
2、用@Query注解:你可以在Repository接口的方法上使用@Query注解来编写自定义的SQL查询。
3、使用EntityManager:你可以通过注入EntityManager对象来执行原生的SQL查询。
四、常见SQL语句使用(附学习网站)
基本的SQL语句示例,包括查询、插入、更新和删除。
1、查询数据(SELECT):
2、插入数据(INSERT):
4、更新数据(UPDATE):
5、删除数据(DELshi
使用案列(登陆注册):
密码加密:
五、总结 博主介绍:✌专注于前后端领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!
🍅文末三连哦🍅
👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟
一、什么是MySQL数据库 MySQL是一种流行的关系型数据库管理系统(RDBMS),它是开源的,由瑞典公司MySQL AB开发。现在MySQL是Oracle公司的一部分,但MySQL仍然作为开源项目继续开发和维护。
MySQL数据库具有以下特点:
1. 关系型数据库管理系统(RDBMS):MySQL是一种关系型数据库,数据以表格的形式存储,这些表格可以通过关系进行连接。
2. 开源和免费:MySQL是开源的,意味着你可以免费使用它,而且有一个庞大的开源社区支持。
3. 跨平台性:MySQL支持多种操作系统,包括Linux、Windows、macOS等,可以在各种环境中部署和运行。
4. 高性能:MySQL是一种高性能的数据库管理系统,能够处理大量的数据和并发请求。
5. 可扩展性:MySQL支持主从复制、分片等技术,可以实现数据库的水平和垂直扩展。
6. 丰富的功能:MySQL提供了许多功能,包括事务支持、索引、触发器、存储过程、视图等,使得它适用于各种不同的应用场景。
7.MySQL应用:于Web应用程序、企业应用、移动应用等各种场景,是最受欢迎的数据库管理系统之一。
二、基于SpringBoot框架连接MySQL数据库 1、首先添加MySQL依赖: 在pom.xml文件中添加MySQL连接器依赖。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> <!-- 根据需要选择版本 --> </dependency> 2、配置数据库连接: 在application.properties或application.yml文件中配置MySQL数据库连接信息。 spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name spring.datasource.username=your_username spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 或者在application.yml中: spring: datasource: url: jdbc:mysql://localhost:3306/your_database_name username: your_username password: your_password driver-class-name: com.
Hive运行卡死 再次强调
hive:小兄弟,没想到吧,咱可不是随便的人。😄
那么,这次又遇见了hadoop问题,问题描述是这样的。
hive> insert into test values(1, 'nucty', '男'); Query ID = atguigu_20240324175437_2cd7db4a-6216-40f8-88c0-cf828af66f7e Total jobs = 3 Launching Job 1 out of 3 Number of reduce tasks determined at compile time: 1 In order to change the average load for a reducer (in bytes): set hive.exec.reducers.bytes.per.reducer=<number> In order to limit the maximum number of reducers: set hive.exec.reducers.max=<number> In order to set a constant number of reducers: set mapreduce.
一、前言 今天,因为需要做前端项目,然而需要node版本是18以上的,然而我目前是v16.16.0而且,我也需要目前的版本,然后在b站上面看见了nvm版本控制这个好东西感谢老师们的分享! 使用nvm控制node版本【渡一教育】_哔哩哔哩_bilibili使用nvm控制node版本【渡一教育】, 视频播放量 1941、弹幕量 1、点赞数 68、投硬币枚数 8、收藏人数 105、转发人数 4, 视频作者 渡一机构, 作者简介 育人为渡,经久如一 如需课程配套学习资料、源码、工具安装包私信up主~,相关视频:宽度适应内容【渡一教育】,你真的会写注释吗?【渡一教育】,最后一次谈响应式【渡一教育】,来了来了,九分钟的无缝轮播图实现代码【渡一教育】,CSS是你永远学不会的语言【渡一教育】,Proxy比defineProperty到底好在哪【渡一教育】,2024新版Java面试题310问,带你金三银四快速通关,一周天背熟拿下25K!(Java基础、JVM、MySQL、Spring、并发编程、Redis、分布式),解决一个前端开发中的实际问题,后台页面计时器失活【渡一教育】,如何使用 flex 弹性盒保持容器均分布局【渡一教育】,难度拉满的Promise终极面试题【渡一教育】https://www.bilibili.com/video/BV12m411975o/?spm_id_from=333.337.search-card.all.clicknvm(Node Version Manager)是Node.js的版本管理器,可以让我们轻松地在不同的Node.js版本之间进行切换。
二、nvm安装 在安装之前,建议先把电脑上的node卸载了,相信我,如何你用了nvm以后再也不会单独安装node了!(真香定理)我之前的v16.16.0,用了两年,卸载的时候,还有点舍不得~ 1、下载nvm安装包 nvm-setup.zip - 蓝奏云
在github可以选择最新版的【nvm】:(nvm-windows 最新下载地址)
https://github.com/coreybutler/nvm-windows/releases
nvm-noinstall.zip: 这个是绿色免安装版本,但是使用之前需要配置nvm-setup.zip:这是一个安装包,下载之后点击安装,无需配置就可以使用,方便。Source code(zip):zip压缩的源码Sourc code(tar.gz):tar.gz的源码,一般用于*nix系统 2、安装 1、解压缩包
2、点击进行安装
3、自定义安装目录(建议不要使用默认的安装目录)
4、自定义node的安装目录
我的自定义路径
5、安装完成后——测试是否安装成功(可能在vscode里面的终端不生效,重启电脑即可使用)
nvm -v # 如果你下载node版本比较慢,开一个代理,或者换一个镜像源 export NVM_NODEJS_ORG_MIRROR=https://mirrors.aliyun.com/nodejs-release/ 至此!安装完成!!!
三、nvm使用 命令(大致了解一下) 常用命令(这几个差不多就够了) nvm list //查看目前已经安装的版本 nvm list available //显示可下载版本的部分列表 nvm install 10.15.0 //安装指定的版本的nodejs nvm use 10.15.0 //使用指定版本的nodejs //使用淘宝镜像(经常换!如果下载经常失效,就去百度最新的镜像源地址) npm config set registry https://registry.
java: 非法字符: ‘\ufeff’
报错解释:
这个错误通常发生在尝试编译Java源代码文件时,文件开头的字符是一个字节顺序标记(Byte Order Mark,BOM),即\ufeff。在Java中,\ufeff不是一个合法的字符,因此编译器会报“非法字符: ‘\ufeff’”错误。
解决方法:
使用文本编辑器打开源代码文件,比如Notepad++、Sublime Text或者IntelliJ IDEA等,并将文件另存为无BOM的UTF-8编码格式。
如果是从其他地方获取的代码,确保在复制或下载代码之前删除BOM。
使用命令行工具或编译器选项来忽略文件开头的字符。例如,在使用javac编译时,可以使用-encoding参数指定编码方式,如:javac -encoding UTF-8 YourClass.java。
如果是在版本控制系统中,可以设置忽略BOM的配置,例如在Git中,可以添加.gitattributes文件,并添加以下内容:
*.java -text
这样可以保证在检出代码时不会生成BOM
目录
Kafka消息生产
一个Topic对应一个Partition
一个Topic对应多个Partition
Kafka消息的顺序性保证(Producer、Consumer)
全局有序
局部有序 max.in.flight.requests.per.connection参数详解
Kafka的多副本机制
Kafka的follower从leader同步数据的流程
Kafka的follower为什么不能用于消息消费
Kafka的多分区(partition)以及多副本(Replica)机制的作用
Kafka和Zookeeper的关系
Kafka如何保证消息不丢失
Kafka消息发送模式
Kafka保证消息不丢失的措施
Kafka为什么这么快
Kafka如何保证消息不被重复消费
生产者消息重复发送
消费者消息重复消费
Kafka消息消费失败
Kafka消息生产 一个Topic对应一个Partition 生产者生产的所有数据都会发送到此Topic对应的Partition下,从而保证消息的生产顺序。
一个Topic对应多个Partition 此时Kafka根据时机情况采取三种消息分发机制:
partition在写入的时候可以指定需要写入的partition,如果有指定,则写入对应的partition。 没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition数进行取余得到 partition 值;在Producer往Kafka插入数据时,控制同一Key分发到同一Partition。
既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后
面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition值,也就是常说的 round-robin 算法。
Kafka消息的顺序性保证(Producer、Consumer) 全局有序: 一个Topic下的所有消息都需要按照生产顺序消费。局部有序:一个Topic下的消息,只需要满足同一业务字段的要按照生产顺序消费。例如:Topic消息是订单的流水表,包含订单orderId,业务要求同一个orderId的消息需要按照生产顺序进行消费。 全局有序 全局有序需要保证一个Topic下的所有消息都需要按照生产顺序消费。此时设置一个Topic下只对应一个Partition即可。而且对应的consumer也要使用单线程或者保证消费顺序的线程模型。即可保证全局有序。
局部有序 要满足局部有序,只需要在发消息的时候指定Partition Key,Kafka对其进行Hash计算,根据计算结果决定放入哪个Partition。这样Partition Key相同的消息会放在同一个Partition。此时,Partition的数量仍然可以设置多个,提升Topic的整体吞吐量。并且为了达到严格的顺序消费还需要max.in.flight.requests.per.connection = 1。
不直接指定对应的Partition而是指定Partition Key
直接指定Partition,将所有消息指定到一个Partition中,此时相当于全局有序,此Topic下的其他Partition无用,浪费资源。将不同的消息设置不同的Partition,此时生产者需要进行额外的计算,不好控制具体的Partition值。 在不增加partition数量的情况下想提高消费速度,可以考虑再次hash唯一标识(例如订单orderId)到不同的线程上,多个消费者线程并发处理消息(依旧可以保证局部有序)。
5.PhotoView
PhotoView 是 ImageView 的子类, 支持所有 ImageView 的源生行为, 例如: 支持 Pinch 手势自由缩放, 支持双击放大/还原, 支持平滑滚动等等, 并且非常方便的与 ImageLoader/Picasso 之类的网络图片读取库集成使用, 还方便的与 ViewPager 等同样支持滑动手势的控件集成
github https://github.com/chrisbanes/PhotoView
6.CircleImageView
圆角ImageView
github https://github.com/hdodenhof/CircleImageView
7.AndroidImageSlider
AndroidImageSlider 库开发者是代码家, 该库是为 Banner 图片滑动提供多种动画效果, 还可以轻易为 Banner 加载网络图片
github https://github.com/daimajia/AndroidImageSlider
8.RoundedImageView
RoundedImageView 一个快速支持图片圆角显示效果的库, 该库特点是能快速加载, 为了提高加载速度, 该库不用创建原始位图的副本, 不使用 clipPath, 不使用 setXfermode 裁剪的位图等方式来实现 ImageView 圆角, 使用也非常简单
github https://github.com/vinc3m1/RoundedImageView
9.uCrop
uCrop 是Yalantis 组织开源的图片裁剪库, 支持缩放, 旋转图片, 支持各种比例的裁剪框, 非常强大的一个图片裁剪库
github https://github.com/Yalantis/uCrop
权限相关框架 1.soulPermission
一句话搞定权限,亲测确实效果不错
github https://github.com/soulqw/SoulPermission
转载的博客地址:https://blog.csdn.net/shaoyezhangliwei/article/details/90671923
1. 介绍 导航栏在移动应用中扮演着至关重要的角色,它是用户与应用之间进行导航和交互的核心组件之一。无论是简单的页面切换,还是复杂的应用导航,导航栏都能够帮助用户快速找到所需内容,提升用户体验和应用的易用性。
在移动应用开发中,通常有两种常见的导航栏类型:底部导航栏(BottomNavigationBar)和自定义导航栏(CustomNavigationRail)。底部导航栏通常位于屏幕底部,以图标和标签的形式展示应用的不同功能或页面,用户可以通过点击不同的图标来切换页面。而自定义导航栏则是一种更加灵活的导航栏形式,可以根据应用的需求自定义布局、样式和交互方式,适用于一些特定场景或者需要更多定制化的应用。
然而,在某些情况下,我们可能需要在应用中灵活切换底部导航栏和自定义导航栏,以满足不同用户群体或特定场景下的需求。例如,在平板电脑或大屏幕设备上,使用自定义导航栏能够更好地利用屏幕空间,提供更丰富的导航和功能;而在手机端,底部导航栏可能更符合用户的使用习惯和操作方式。因此,全局控制底部导航栏和自定义导航栏的需求就变得十分重要。通过在应用中实现全局控制,我们可以根据不同的设备或用户需求动态切换导航栏类型,从而提升应用的灵活性和适用性。接下来,我们将探讨如何实现这一目标。
2. 底部导航栏与自定义导航栏简介 在移动应用开发中,底部导航栏(BottomNavigationBar)和自定义导航栏(CustomNavigationRail)是两种常见的导航栏形式,它们各具特点并在不同的应用场景下发挥着重要作用。
底部导航栏: 底部导航栏通常位于屏幕底部,以图标和标签的形式展示应用的不同功能或页面。它的特点包括:
简洁直观:底部导航栏的设计简洁直观,用户可以通过点击不同的图标来快速切换页面,易于上手和操作。易于使用:底部导航栏符合用户的使用习惯和操作方式,使用户能够轻松找到所需功能,提升了应用的易用性。适用性广泛:底部导航栏适用于各种类型的应用,特别是那些功能较少或页面切换频繁的应用。 自定义导航栏: 自定义导航栏是一种更加灵活的导航栏形式,开发者可以根据应用的需求自定义布局、样式和交互方式。它的特点包括:
灵活定制:自定义导航栏可以根据应用的特定需求进行灵活定制,包括布局、样式、交互方式等,满足不同应用场景的需求。丰富功能:自定义导航栏可以集成更丰富的功能和交互,如侧边栏、抽屉式导航、手势操作等,提供更多的导航和功能选择。适用特定场景:自定义导航栏通常适用于一些特定场景或需要更多定制化的应用,如平板电脑、桌面应用等,能够更好地利用屏幕空间和提供更丰富的导航体验。 优缺点分析: 底部导航栏和自定义导航栏各有优缺点,适用于不同的应用场景:
底部导航栏适用于功能简单、页面切换频繁的应用,它简洁直观、易于使用,适合手机端的应用。自定义导航栏适用于需要定制化导航和丰富功能的应用,如平板电脑、桌面应用等,它灵活定制、功能丰富,能够提供更好的用户体验。 根据应用的实际需求和用户群体,开发者可以选择合适的导航栏形式,或者在不同设备和场景下动态切换导航栏类型,以提升应用的用户体验和适用性。接下来,我们将探讨如何实现全局控制底部导航栏和自定义导航栏的方法。
3. 枚举类型的使用 在Flutter中,枚举类型(Enum)是一种有限的、离散的数据类型,用于表示一组相关的常量值。枚举类型在表示一组可能的选项时非常有用,可以提高代码的可读性和可维护性。
介绍枚举类型及其在Flutter中的应用: 枚举类型是一种由一组命名的常量值组成的数据类型。在Flutter中,枚举类型通常用于表示一组相关的选项或状态,例如不同的导航栏类型、主题模式、状态等。通过使用枚举类型,我们可以更清晰地表达代码的意图,避免使用散乱的数字或字符串来表示选项,提高了代码的可读性和可维护性。
在Flutter中,枚举类型的声明方式如下所示:
enum NavigationType { bottomNavigationBar, customNavigationRail, } 在上面的示例中,我们定义了一个名为NavigationType的枚举类型,它包含了两个常量值:bottomNavigationBar和customNavigationRail。这些常量值可以被用作代码中的标识符,并且它们的类型都是NavigationType。
定义一个枚举类型来表示导航栏的选择: 在全局控制底部导航栏和自定义导航栏的情景下,我们可以使用枚举类型来表示当前选择使用哪种导航栏。例如,在Flutter应用中,我们可以定义一个枚举类型来表示导航栏的选择,如下所示:
enum NavigationType { bottomNavigationBar, customNavigationRail, } 然后,我们可以在应用中使用这个枚举类型来控制底部导航栏和自定义导航栏的显示和切换。通过这种方式,我们可以清晰地表达当前使用的导航栏类型,并且可以在代码中方便地引用这些选项。接下来,我们将探讨如何利用枚举类型实现全局控制导航栏的方法。
4. 全局控制方法 在移动应用开发中,有时我们需要根据不同的场景或用户需求来动态切换导航栏类型,以提供更好的用户体验。全局控制导航栏的目的是让开发者能够在应用的整个生命周期内灵活地选择和切换导航栏类型,从而满足不同设备、屏幕尺寸或用户需求下的导航需求。
讨论全局控制导航栏的需求和方法: 全局控制导航栏的需求通常包括:
根据设备类型切换导航栏:例如,在手机端使用底部导航栏,在平板电脑或桌面端使用自定义导航栏。根据用户偏好切换导航栏:例如,提供一个设置选项,让用户自由选择喜欢的导航栏类型。 为了实现全局控制导航栏,我们可以借助枚举类型来表示不同的导航栏类型,并在应用的各个部分使用这个枚举类型来决定当前显示的导航栏。通过这种方式,我们可以轻松地切换导航栏类型,而不需要修改大量的代码。
介绍如何使用枚举类型来控制显示不同的导航栏: 首先,我们需要定义一个枚举类型来表示导航栏的选择,如下所示:
enum NavigationType { bottomNavigationBar, customNavigationRail, } 然后,在应用的各个部分,我们可以根据这个枚举类型来决定当前显示的导航栏。例如,在build方法中根据枚举类型选择显示底部导航栏还是自定义导航栏:
Widget build(BuildContext context) { // 根据枚举类型选择显示不同的导航栏 Widget navigationBar; switch (navigationType) { case NavigationType.bottomNavigationBar: navigationBar = BottomNavigationBar(.
标签:PostgreSQL.Druid.Mybatis.Plus;
一、简介 PostgreSQL是一个功能强大的开源数据库系统,具有可靠性、稳定性、数据一致性等特点,且可以运行在所有主流操作系统上,包括Linux、Unix、Windows等。
通过官方文档可以找到大量描述如何安装和使用PostgreSQL的信息。
环境搭建,基于Centos7部署的PostgreSQL-14版本,官方文档中提供yum安装的方式,配置的话可以参考源码仓库中的其他版本「见文尾」,这里不赘述。
# 1、RPM仓库 sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # 2、安装PostgreSQL sudo yum install -y postgresql14-server # 3、初始化选项 sudo /usr/pgsql-14/bin/postgresql-14-setup initdb sudo systemctl enable postgresql-14 sudo systemctl start postgresql-14 # 4、查看版本 psql --version psql (PostgreSQL) 14.11 二、工程搭建 1、工程结构 2、依赖管理 Druid连接池使用的是1.2.18版本;使用mybatis-plus组件的3.5.3.1版本;PostgreSQL本地环境是14.11版本,这里依赖包使用42.6.2版本;
<!-- Postgresql --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> </dependency> <!-- Druid组件 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <version>${druid-spring-boot.version}</version> </dependency> <!-- MybatisPlus组件 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>${mybatis-plus.
🌈个人主页: 鑫宝Code
🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 ECMAScript vs JavaScript:理解两者间的联系与区别1. ECMAScript:定义与角色ECMAScript特性概览: 2. JavaScript:实现与扩展JavaScript的独特之处: 3. 区别与联系结论 ECMAScript vs JavaScript:理解两者间的联系与区别 引言
在前端开发的世界中,ECMAScript(ES)与JavaScript(JS)犹如一对形影不离的伙伴,但它们各自的角色与职责却有着显著的不同。本文将以Markdown格式详细解读这两者之间的关系及其核心差异,帮助开发者深入理解和掌握这一基础而又关键的概念。
1. ECMAScript:定义与角色 ECMAScript是一种由ECMA国际标准化组织制定的脚本语言规范。它定义了一套编程语法、类型、对象及操作的标准规则,并为开发基于客户端和服务器端的脚本提供了一个通用的基础结构。简单来说,ECMAScript就是“JavaScript语言的核心标准”。
ECMAScript特性概览: 语法:规定了变量声明、函数定义、运算符等基本语法结构。数据类型:定义了诸如Number、String、Boolean、Object等基本数据类型及其行为。内置对象:规定了Array、Function、Date、RegExp等内建对象的功能和用法。控制流程:包括条件判断、循环、异常处理等控制结构。 2. JavaScript:实现与扩展 JavaScript,作为浏览器环境下的主要实现之一,严格意义上讲,它是对ECMAScript规范的一种具体实现。换句话说,JavaScript是一种遵循ECMAScript规范的编程语言,由网景公司(Netscape)在1995年首次推出并随着浏览器的发展而逐渐流行开来。
JavaScript的独特之处: 宿主环境:JavaScript通常运行在浏览器环境中,但也支持Node.js等非浏览器环境。API扩展:除了ECMAScript规范之外,JavaScript还提供了大量与浏览器交互的API,如DOM(Document Object Model)和BOM(Browser Object Model),用于操作网页文档和浏览器窗口。库与框架:各大浏览器厂商和开源社区为JavaScript添加了许多非标准特性,并构建了大量的第三方库和框架,如jQuery、React、Vue等,极大地丰富了其功能和应用场景。 3. 区别与联系 区别:ECMAScript专注于定义语言的核心特性和规范,而不涉及任何特定的执行环境或API。而JavaScript则是实现了ECMAScript规范的一种具体的编程语言,同时包含了与具体环境紧密相关的附加功能。
联系:JavaScript的成功在于它不仅采纳了ECMAScript的规范,还在其基础上进行了大量的拓展和优化,使其能够在Web开发领域大放异彩。每一代新的JavaScript版本(如ES6、ES7等)实际上都是对ECMAScript新规范的逐步实现。
结论 总结而言,ECMAScript和JavaScript的关系就如同建筑蓝图与建筑物的关系一样,前者规定了建造的语言规则和基本构造,后者则是在此基础上建设起功能各异、形态万千的应用程序。理解这一区分有助于我们更准确地定位问题,把握技术发展趋势,并根据需求选择合适的编程实践。
MySQL安装 一、下载 MySQL :: MySQL Downloads
要是下载页面卡,可以使用百度网盘分享的mysql
Mysql数据库版本:mysql 8.0.34
百度网盘分享:
链接:百度网盘 请输入提取码
提取码:free
二、对Mysql进行配置 选择自定义模式
选择合适的扩展到右边
点击超链接 Advanced Options,更改路径
执行即可
三、安装结束后进行软件配置 端口默认,加密选择默认推荐
输入密码,弱口令也可以,这里输入的是123456
为root设置密码
接下来默认下一次就好
四、配置环境变量 cmd 进入命令提示符
mysql -- version 查看安装版本
mysql -uroot -p<密码> 登录mysql
SQLyog的安装 下载安装包
百度网盘分享:
链接:百度网盘 请输入提取码
提取码:free
一、SQLyog安装 ---选择中文路径
---选择安装位置
---新建链接
---输入mysql数据库密码,发现错误
二、修改root用户的身份验证规则 ---进入mysql的命令行(搜索栏搜索mysql即可),输入密码
---查看Mysql用户的密码规则,及对应的host
修改root用户的身份验证方式
再次查看mysql用户的密码规则
三、建立链接 ---重新建立新的链接
---输入密码,测试链接
建立链接
Spark Map 和 FlatMap 的比较 本节将介绍Spark中map(func)和flatMap(func)两个函数的区别和基本使用。
函数原型 map(func) 将原数据的每个元素传给函数func进行格式化,返回一个新的分布式数据集。
flatMap(func) 跟map(func)类似,但是每个输入项和成为0个或多个输出项,所以func函数应该返回的是一个序列化的数据而不是单个数据项。
使用说明 在使用时map会将一个长度为N的RDD转换为另一个长度为N的RDD;而flatMap会将一个长度为N的RDD转换成一个N个元素的集合,然后再把这N个元素合成到一个单个RDD的结果集。
比如一个包含三行内容的数据文件“README.md”。
a b c d 经过以下转换过程
val textFile = sc.textFile("README.md") textFile.flatMap(_.split(" ")) 其实就是经历了以下转换
["a b c", "", "d"] => [["a","b","c"],[],["d"]] => ["a","b","c","d"]
在这个示例中,flatMap就把包含多行数据的RDD,即["a b c", "", "d"] ,转换为了一个包含多个单词的集合。实际上,flatMap相对于map多的是[["a","b","c"],[],["d"]] => ["a","b","c","d"]这一步。
区别对比 map(func)函数会对每一条输入进行指定的func操作,然后为每一条输入返回一个对象;而flatMap(func)也会对每一条输入进行执行的func操作,然后每一条输入返回一个相对,但是最后会将所有的对象再合成为一个对象;从返回的结果的数量上来讲,map返回的数据对象的个数和原来的输入数据是相同的,而flatMap返回的个数则是不同的。参考下图进行理解:
通过上图可以看出,flatMap其实比map多的就是flatten操作。
示例验证 接下来,我们用一个例子来进行比较,首先在HDFS里写入了这样内容的一个文件:
C:\WINDOWS\system32>hadoop fs -cat hdfs://localhost:9000/user/input/wordcount.txt word in text hello spark the third line C:\WINDOWS\system32> 然后再spark里进行测试,如下
scala> var textFile =sc.textFile("hdfs://localhost:9000/user/input/wordcount.txt") textFile: org.apache.spark.rdd.RDD[String] = hdfs://localhost:9000/user/input/wordcount.