导航:
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
推荐视频:
黑马程序员全套Java教程_哔哩哔哩
尚硅谷Java入门视频教程_哔哩哔哩
推荐书籍:
《Java编程思想 (第4版)》 《Java核心技术·卷I(原书第12版) : 开发基础》
目录
十一、多线程
11.1 基本介绍
11.1.1 线程和进程的关系
11.1.2 多线程
11.2 创建线程方法
11.2.0 简介
11.2.1 方法1:继承Thread类
11.2.2 方法2:实现 Runnable 接口 11.2.3 方法3:实现Callable接口
11.2.4 方法4:线程池
11.3 知识加油站
11.3.1 线程生命周期
11.3.2 线程的通信方式
11.3.3 线程池
11.3.3.1 作用
11.3.3.2 生命周期 11.3.3.3 创建线程池的方式1:线程池工具类
11.3.3.4 创建线程池的方式2:自定义线程池(推荐)
11.3.3.5 如何为线程池设置合适的线程数
11.3.3.6 线程池的原理
11.3.4 练习:多线程交替打印A/B/C,每个打印3次
11.4 线程安全
11.4.1 基本介绍 11.4.2 原子类
11.4.3 volatile关键字
11.4.4 锁
11.4.5 线程安全的集合
11.5 线程同步
导航:
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
推荐视频:
黑马程序员全套Java教程_哔哩哔哩
尚硅谷Java入门视频教程_哔哩哔哩
推荐书籍:
《Java编程思想 (第4版)》 《Java核心技术·卷I(原书第12版) : 开发基础》
目录
六、异常
6.1 基本介绍
6.2 详细介绍
6.2.1 Throwable类
6.2.2 知识加油站
6.2.2.1 异常的追踪栈
6.2.2.2 日志规范:不建议使用e.printStackTrace() 6.2.3 Error类
6.2.4 Exception类
6.3 异常的两种处理方式
6.3.1 抛出异常
6.3.2 捕获异常(推荐)
6.4 自定义异常:继承异常类
七、集合
7.1 集合体系
7.1.1 集合和映射
7.1.2 思考:Map是不是集合?
7.1.3 常见集合的底层和性能对比
7.1.4 知识加油站:
7.1.4.1 集合的线程安全性
7.1.4.2 思考:什么是线程不安全?
7.1.2 常用API
7.1.2.1 Collection:
7.1.2.2 Map
7.1.3 常用工具类
7.1.3.1 集合工具类Collections
7.1.3.2 数组工具类Arrays
7.2 ArrayList
7.2.1 基本介绍
7.2.2 底层源码和扩容机制
Windows下RabbitMQ的安装和部署 一、引言二、环境搭建三、安装ERLANG四、安装RabbitMQ五、安装RabbitMQ-Plugins六、验证 一、引言 RabbitMQ——Rabbit Message Queue的简写,但不能仅仅理解其为消息队列,消息代理更合适。RabbitMQ 是一个由 Erlang 语言开发的AMQP(高级消息队列协议)的开源实现,其内部结构如下:
RabbitMQ 内部结构
RabbitMQ作为一个消息代理,主要和消息打交道,负责接收并转发消息。RabbitMQ提供了可靠的消息机制、跟踪机制和灵活的消息路由,支持消息集群和分布式部署。适用于排队算法、秒杀活动、消息分发、异步处理、数据同步、处理耗时任务、CQRS等应用场景。
本文介绍RabbitMQ在Window的安装和部署
RabbitMQ详细使用及介绍见文章:https://blog.csdn.net/weixin_45683778/article/details/139839500
RabbitMQ集群搭建及部署见文章:https://blog.csdn.net/weixin_45683778/article/details/139941267
二、环境搭建 安装Erlang运行环境
下载安装Erlang。 安装RabbitMQ
下载安装Windows版本的RabbitMQ。 启动RabbitMQ Server
点击Windows开始按钮,输入RabbitMQ找到RabbitMQ Comman Prompt,以管理员身份运行。 首先要说明的是,rabbitMQ由erlang语言开发,erlang也被中国人称为二郎神
因此,安装RabbitMQ之前,应先安装erlang,需要注意的是,不同的rabbitMQ版本对应的erlang版本不同,我们可以在官网中进行查看:https://www.rabbitmq.com/docs/which-erlang
我选择的是:otp_win64_25.0.1.exe 搭配 rabbitmq-server-3.10.6.exe
下载完成后
三、安装ERLANG 进入安装步骤,先安装二郎神,选择默认安装,安装完成后,配置环境变量
新建系统变量-键入变量名ERLANG_HOME,键入变量值:erlang安装路径,我的路径为:C:\Program Files\Erlang OTP , 如下图:
然后添加系统path路径中,添加 : %ERLANG_HOME%\bin
然后打开cmd,输入erl,看到我们的erlang版本号,就说明安装成功了
四、安装RabbitMQ 下载地址:https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.10.6
直接双击.exe文件执行即可。
安装完成后,配置环境变量 RABBITMQ_SERVER
然后添加系统path路径中,添加 : %RABBITMQ_SERVER%\sbin
五、安装RabbitMQ-Plugins RabbitMQ-Plugins相当于是一个管理界面,方便我们在浏览器界面查看RabbitMQ各个消息队列以及exchange的工作情况。
打开命令行cd进入rabbitmq的sbin目录(或者进入sbin文件下,直接敲cmd,回车)
cd C:\Program Files\RabbitMQ Server\rabbitmq_server-3.10.6\sbin 然后执行安装
rabbitmq-plugins enable rabbitmq_management 安装完成后,
六、验证 上面的命令执行成功之后,我们就可以通过http://localhost:15672来访问web端的管理界面
输入用户名:guest,密码:guest(默认)就可以进入管理界面
RabbitMQ在windows下安装部署完成
Redis集群 之前因为数据量的原因,并没有进行Redis集群的配置需要,现在由于数据量大,需要进行集群部署。
最初在windows系统部署,需要Redis的windows版本,但官方没有windows版本,所以需要去gitHub上找由民间志愿者维护的windows的版本。
历程: 去github找到后,第一次接触windows版本发现没有bin目录,之后想着直接拉去下来,后来发现拉下来的是源码,,,无语了家人,就在浏览器下载zip包,这个是正常的msi包是需要安装,zip解压即可。
部署集群 配置三主三从集群,windows的窗口不能退出(窗口闪退的就是没有运行起来!)
1.解压缩zip文件 下载完成后,里面如下文件
2.为每个node节点文件夹和配置文件 创建文件夹6379-6384文件夹,创建redis-6379.conf(注意后缀名,有的系统会隐藏后缀)
创建config文件,下面只有redis-6379.conf是自己创建的,其他都是运行后生成的。
如上方式,创建其他的节点。
3.创建启动文件 创建start6379.bat启动文件,点击文件一键启动。
内容命令:
redis-server.exe ./6379/redis-6379.conf 如图,其他的方式也如此一共6个bat文件
4.启动集群 启动好之后开始创建集群模式。
cluster-replicas 的意思是 为每个master创建一个副本。是6个实例,那么自动就三主三从的模式。
redis-cli --cluster create 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 --cluster-replicas 1 Redis工具
redis-cli -h 127.0.0.1 -p 6379 -c 注意:加-c(集群启动) 否则,会出现
(error) MOVED 5798 127.0.0.1:6379
从零开始手写STL库–List部分 Github链接:miniSTL
文章目录 从零开始手写STL库–List部分List是什么?List需要包含什么函数1)基础成员函数2)核心功能3)其他功能 基础成员函数的编写核心功能的编写其他功能编写总结 List是什么? std::list是基于双向链表的的数据结构,与std::vector基于数组不同,list在频繁插入和删除的场景中更适合应用。
List需要包含什么函数 应当具有:
1)基础成员函数 构造函数:初始化List头节点
析构函数:释放内存,当运行结束后要摧毁这个List防止内存泄漏
不同于Vector,List这种以链表为基础的容器一般不需要去拷贝新的List,也就不用手动构建拷贝构造函数和拷贝赋值操作符
2)核心功能 push_back/push_front:在List的末尾/头部加入新元素
pop_back/pop_front:移除List末尾/头部元素
size:获取List长度
clear:清空List
get:获取List中某个元素的值
remove:删除某个节点
find:查找某个值对应的节点
empty:检查List是否为空
3)其他功能 迭代器、重载输出符等等
基础成员函数的编写 List的成员:
List本身是链表,那么每个节点应该包括本节点的数据、指向上/下一个节点的指针,而List是描述这一系列节点构成的双向链表,那么只需要记录头节点、尾节点以及List长度即可
template<typename T> class myList { private: struct Node { T data; Node * next; Node * prev; Node(const T & data_, Node * next_ = nullptr, Node * prev_ = nullptr) : data(data_), next(next_), prev(prev_) {} }; Node * head; Node * tail; size_t current_size; public: }; 构造函数和析构函数就是
文心一言是百度基于其强大的“文心”大模型技术推出的生成式AI产品(英文名:ERNIE Bot)。以下是关于文心一言的详细介绍:
一、产品定位与功能
定位:文心一言被定位为人工智能基座型的赋能平台,旨在助力金融、能源、媒体、政务等千行百业的智能化变革,最终“革新生产力工具”。
一、产品定位
人工智能基座型的赋能平台:百度对文心一言的定位是一个能够深刻影响千行百业、实现智能化变革的人工智能基座型赋能平台。这一平台旨在通过新技术帮助企业创建最好的客户体验,让任何公司都有机会离客户更近,从而实现智能化变革、效率提升,获得更强的竞争优势,创造更大的商业价值。
二、功能定位
多领域赋能:文心一言不仅限于搜索或互联网公司,而是旨在影响每一家公司,助力金融、能源、媒体、政务等千行百业的智能化变革。
综合能力展示:在多个使用场景中,文心一言展现了其强大的综合能力,包括文学创作、商业文案创作、数理推算、中文理解以及多模态生成。这些能力使得文心一言能够在不同领域提供多样化的智能服务。
功能:文心一言具备跨模态、跨语言的深度语义理解与生成能力,能够与人对话互动,回答问题,协助创作,高效便捷地帮助人们获取信息、知识和灵感。具体来说,它拥有文学创作、商业文案创作、数理逻辑推算、中文理解、多模态生成等五大能力。文心一言是百度基于其强大的“文心”大模型技术推出的生成式AI产品,其功能丰富且强大,主要包括以下几个方面:
1、自然语言处理:
文本生成:根据用户输入的主题、关键词或情境,自动生成连贯、有逻辑的文本内容,适用于文学创作、商业文案、新闻报道等多种场景。
2、对话交互:实现与用户的自然语言对话,理解用户意图,并给出相应的回答或建议,提供智能化的交互体验。
3、语言理解:准确理解中文语境中的词语、短语、句子等,进行语义分析和推理,确保对话的准确性和流畅性。
4、知识问答:回答用户提出的各种问题,包括百科知识、专业术语、时事热点等,提供准确、详细的信息。支持多轮对话,根据上下文理解用户意图,提供更加精准的回答。
5、内容创作辅助:在文学创作领域,提供灵感、情节构思、角色设定等辅助创作功能,帮助作家快速生成高质量的作品。在商业文案创作方面,根据用户需求生成广告词、产品描述、营销文案等,提高创作效率和质量。
6、数理逻辑推算:具备一定的数理逻辑推算能力,能够解答数学、物理等学科的问题,提供计算过程和结果。
7、多模态生成:除了文本生成外,还支持图片、音频、视频等多种形式的生成,实现多模态内容的创作和编辑。
8、个性化服务:根据用户的偏好、历史行为等信息,提供个性化的推荐和服务,提升用户体验。
9、行业应用:针对不同行业的需求,提供定制化的解决方案和服务,助力金融、能源、媒体、政务等千行百业的智能化变革。
10、持续学习与进化:基于深度学习技术,文心一言能够不断学习和进化,通过用户反馈和数据积累优化模型性能,提升智能化水平。
二、核心能力与特点
1、深度语义理解与生成:文心一言能够深入理解用户输入的语义信息,包括词语、短语、句子以及它们之间的复杂关系。基于深度学习技术,它能够生成自然、流畅且符合语境的文本内容,无论是简单的问答还是复杂的文学创作都能应对自如。
2、跨模态理解与生成:除了文本外,文心一言还具备处理图片、音频、视频等多种模态数据的能力。它可以从这些模态中提取关键信息,并将其转化为文本形式进行输出。同时,它也能将文本内容转化为图片、音频等形式,实现多模态内容的生成与转换。
3、知识问答与推理:文心一言拥有庞大的知识库和先进的推理机制,能够准确回答用户提出的各种问题,包括百科知识、专业知识、时事热点等。它还能根据上下文信息进行推理和判断,提供更加精准和个性化的回答。
4、个性化与定制化服务:文心一言能够根据用户的偏好、历史行为等信息提供个性化的服务。无论是内容推荐、智能客服还是其他应用场景,它都能根据用户的特点进行定制化服务。这种个性化服务能够提升用户体验,增强用户粘性。
5、高效的学习与进化能力:基于深度学习技术的优势,文心一言具备强大的学习能力。它能够通过不断学习和训练来优化自身性能,提升智能化水平。同时,随着用户反馈和数据积累的增加,文心一言还能不断进化和发展,以适应更多样化和复杂化的应用场景。
6、广泛的应用场景适应性:文心一言的核心能力使其能够广泛应用于搜索问答、内容创作生成、智能办公等多个领域。无论是文学创作、商业文案还是新闻报道等场景都能得到很好的支持。同时,它还具备行业定制化的能力,可以根据不同行业的需求提供个性化的解决方案和服务。
7、文学创作:文心一言能够创作故事、小说、诗歌、散文等多种文学形式,根据用户提供的主题或关键词,生成连贯、有逻辑、有深度的文本内容。
8、商业文案创作:它能够根据用户提供的商业需求,生成各种商业文案,如产品介绍、推广文案、营销文案等,极大地提高了写作效率。
9、数理逻辑推算:文心一言具备优秀的数理逻辑推算能力,能够解答各种数学、物理等学科的问题,帮助用户获取准确、清晰、简明的答案。
10、中文理解:它能够准确地理解中文语境中的词语、短语、句子等,进行正确的语义分析和推理,保证对话的流畅和准确。
11、多模态生成:除了能够生成文本外,文心一言还能处理图片、视频等多种形式的输入,实现多模态生成。
三、应用场景
1、文学创作与商业文案
文学创作:文心一言通过其强大的自然语言处理能力,能够为作家提供创作灵感和辅助。作家可以输入主题、情节梗概等要素,文心一言则能生成连贯、有逻辑的文本片段,甚至完整的章节或故事。
这种能力在小说、散文、诗歌等多种文学体裁的创作中都有应用,有助于提升创作效率和质量。
商业文案:
在商业领域,文心一言能够生成广告词、产品描述、营销文案等。企业或个人只需提供相关产品信息、目标受众等要素,文心一言就能快速生成吸引人的文案内容。
这不仅提高了文案创作的效率,还能确保文案的准确性和吸引力,有助于提升品牌形象和销售业绩。
2、智能客服与问答系统
智能客服:
文心一言可以作为智能客服系统的核心引擎,与用户进行自然语言对话。它能够理解用户的问题和需求,并提供相应的解答和帮助。
这种智能客服系统可以应用于电商、银行、保险等多个行业,为用户提供24小时不间断的客户服务,提升用户满意度和忠诚度。
问答系统:
文心一言还可以应用于问答系统中,回答用户提出的各种问题。无论是在企业内部的知识管理系统中,还是在公共领域的搜索引擎中,文心一言都能提供准确、全面的回答。
3、教育培训与学术研究
教育培训:
在教育领域,文心一言可以作为一种智能辅助工具,帮助学生和教师提高教学效率。它可以生成教学材料、练习题、模拟试题等,为学生提供个性化的学习支持。
同时,文心一言还可以用于在线教育和远程教育平台中,提供智能化的学习辅导和答疑服务。
学术研究:
在学术研究领域,文心一言可以辅助学者进行文献综述、论文撰写等工作。它能够快速检索和分析相关文献,提供研究思路和方向建议。
此外,文心一言还可以生成论文摘要、引言、结论等部分的内容,减轻学者的写作负担。
4、新闻媒体与社交媒体
新闻媒体:
文心一言在新闻媒体领域也有广泛应用。它可以快速生成新闻稿件、报道评论等内容,为新闻媒体提供高效的写作支持。
同时,文心一言还可以对新闻事件进行智能分析和预测,为新闻媒体提供有价值的参考信息。
社交媒体:
在社交媒体领域,文心一言可以应用于内容生成和推荐系统中。它能够根据用户的兴趣和行为模式生成个性化的内容推荐列表或动态消息。
此外,文心一言还可以用于社交媒体平台的智能客服系统中,为用户提供快速、准确的解答和帮助。
5、智能制造与物联网
智能制造:
在智能制造领域,文心一言可以应用于设备控制、数据分析和决策支持等方面。通过与设备的对话交互,文心一言能够接收和执行控制指令实现设备的智能化管理和控制。
同时它还可以对生产数据进行实时分析和处理为企业的生产决策提供有力支持。
物联网:
在物联网领域文心一言可以与其他智能设备或系统进行无缝对接实现数据的互联互通。它能够理解用户的语音指令并将其转化为设备可以执行的操作指令从而提升物联网系统的智能化水平和用户体验。
6、搜索问答:文心一言能够回答用户提出的各种问题,提供准确、详细的信息。
内容创作生成:在文学创作、商业文案创作等领域发挥重要作用,帮助用户快速生成高质量的文本内容。
7、智能办公:通过对话互动的方式,辅助用户完成各种办公任务,提高工作效率。
点击可直接使用
深入理解Java源码编译机制:从源代码到字节码的全过程 简介 Java源码编译机制是指将Java源文件(.java文件)编译成字节码文件(.class文件)的过程。编译后的字节码文件可以在任何支持Java虚拟机(JVM)的设备上运行。本文详细介绍Java的编译过程,并通过代码示例和注释帮助理解每个步骤。
编译过程概述 源码编写词法分析语法分析语义分析字节码生成类加载和执行 源码编写 编写Java源码文件,文件扩展名为.java。
/** * HelloWorld 类 * 包含一个 main 方法,输出 "Hello, World!" */ public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); // 打印 "Hello, World!" } } 词法分析(Lexical Analysis) 编译器将源码拆分成单词(tokens),识别关键字、标识符、常量和符号等。
public class HelloWorld { // 词法分析将源码拆分为多个 tokens: // [public, class, HelloWorld, {, public, static, void, main, (, String, [, ], args, ), {, System, ., out, ., println, (, "Hello, World!
基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优 Hive默认使用的计算框架是MapReduce,在我们使用Hive的时候通过写SQL语句,Hive会自动将SQL语句转化成MapReduce作业去执行,但是MapReduce的执行速度远差于Spark。通过搭建一个Hive On Spark可以修改Hive底层的计算引擎,将MapReduce替换成Spark,从而大幅度提升计算速度。接下来就如何搭建Hive On Spark展开描述。 注:集群使用的是CDH6.3.0,使用的Spark版本是2.4.0,使用的集群配置为5个NodeManager节点,每台内存62.8G(64G),cpu 32 Core。
配置Spark 给Yarn分配完资源后,需要配置一些Spark的参数,设置Spark可使用的资源。包括executor和Driver的内存,分配executor和设置并行度。
1) 配置executor内存 在配置executor的内存大小的时候,需要考虑以下因素: 增加executor的内存可以优化map join。但是会增加GC的时间。在某些情况下,HDFS客户端没有并行处理多个写请求,在有多个请求竞争资源的时候会出现一个executor使用过多的core。尽可能的减少空闲的core的个数,cloudera推荐设置spark.executor.cores为4,5,6,这取决于给yarn分配的资源。本集群有155个core可用,将spark.executor.cores设置为5,这样155/5余数为0,设置为6的话会剩余5个空闲,设置为4的话有3个空闲。这样配置之后可以同时运行31个executor,每个executor最多可以运行5个任务(每个core一个)。 spark.executor.memory,hive中设置,代表Hive 在 Spark 上运行时每个 Spark 执行程序的 Java 堆栈内存的最大大小,本集群设为8G,该值不能太大也不能太小,都会导致任务直接失败。executor执行的时候,用的内存可能会超过该值设置的大小,所以会为executor额外预留一部分内存。spark.yarn.executor.memoryOverhead(hive中设置)代表了这部分内存,本集群设置为2G。 yarn.scheduler.maximum-allocation-mb这个参数表示每个container能够申请到的最大内存,一般是集群统一配置。Spark中的executor进程是跑在container中,所以container的最大内存会直接影响到executor的最大可用内存。但是当设置一个比较大的内存时,日志中会报错,同时会打印这个参数的值。还有一点是要spark.yarn.executor.memoryOverhead和spark.executor.memory的和不能超过yarn.scheduler.maximum-allocation-mb(yarn参数)设置的值。本集群scheduler请求最大内存分配的是60G,即某些情况下允许所有可用内存都给某一个executor使用,预留2.8G给系统。
2) 配置Driver内存 SparkDriver 端的配置如下:
spark.driver.memory:当hive运行在spark上时,driver端可用的最大Java堆内存。
spark.yarn.driver.memoryOverhead:每个driver可以额外从yarn请求的堆内存大小。这两个参数和就是yarn为driver端的JVM分配的总内存。
Spark在Driver端的内存不会直接影响性能,但是在没有足够内存的情况下在driver端强制运行Spark任务需要调整。本集群分别设置为3G和1G。
3) 动态分配executor(hive中设置) 设置spark.executor.instances到最大值可以使得Spark集群发挥最大性能。但是这样有个问题是当集群有多个用户运行Hive查询时会有问题,应避免为每个用户的会话分配固定数量的executor,因为executor分配后不能回其他用户的查询使用,如果有空闲的executor,在生产环境中,计划分配好executor可以更充分的利用Spark集群资源。
Spark允许动态的给Spark作业分配集群资源,cloudera推荐开启动态分配,本集群也开启该设置。
4) 设置并行度 为了更加充分的利用executor,必须同时允许足够多的并行任务。在大多数情况下,hive会自动决定并行度,但是有时候我们可能会手动的调整并行度。在输入端,maptask 的个数等于输入端按照一定格式切分的生成的数目,HiveOn Spark 的输入格式是CombineHiveInputFormat,可以根据需要切分底层输入格式。调整hive.exec.reducers.bytes.per.reducer控制每个reducer处理多少数据。但是实际情况下,Spark相比于MapReduce,对于指定的hive.exec.reducers.bytes.per.reducer不敏感。我们需要足够的任务让可用的executor保持工作不空闲,当Hive能够生成足够多的任务,尽可能的利用空闲的executor。
G1 GC 调优 参数配置的位置:spark-defaults.conf,在 spark 配置中查看如下:
具体属性名称为:spark.executor.extraJavaOptions,在“=“后面添加相关属性,本次调优中加入的参数如下:
spark.executor.extraJavaOptions=-XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=35 -XX:ConcGCThreads=20 -XX:+PrintFlagsFinal -XX:+PrintReferenceGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintAdaptiveSizePolicy -XX:+UnlockDiagnosticVMOptions -XX:+G1SummarizeConcMark -XX:NewRatio=1 本次针对调优的sql为:
在executor页面查看显示GC占用运行时间超过10%至30%以上,严重影响程序运行效率,通过分析sql本身和gc信息发现,新生代对象很对,占用空间很大:
【导读】靠 AI 简单加持的集成开发环境(IDE),真的满足你了吗?本文长度 13,000+ 字,作者将从 IDE 设计者和资深程序员的角度出发,深度剖析程序员心中对 IDE 的真正需求,给出 AI 时代下衡量 IDE 优劣的重要标准。
本文整理自字节跳动豆包MarsCode团队技术专家天猪在 2024 全球软件研发技术大会中的演讲,同时收录于《新程序员 008》。《新程序员 008》聚焦于大模型对软件开发的全面支撑,囊括 Daniel Jackson 和 Daniel Povey 等研发专家的真知灼见与“AGI 技术 50 人”栏目的深度访谈内容,欢迎大家点击订阅年卡。
作者 | 天猪
责编 | 王启隆
出品 | 《新程序员》编辑部
我已经从业很多年了,当时可能还没有前端这个岗位。
高二那年,中国刚兴起互联网,网吧每小时要收 12 块钱。我开始学习编写 HTML + JS + CSS 甚至 Flash,从北邮毕业后,先在小公司待了很多年,接着加入了 UC。随着 UC 被阿里收购,我在阿里游戏负责前端团队,搞前端工程化。几年后,为了去看看国内前端的圣地,就应玉伯邀请,转岗去了蚂蚁的体验技术部,主要深耕在 Node.js 基础设施领域。这么多年里也一直在社区参与开源项目,EggJS 和 CNPM 就是我核心参与的 2 个开源项目,欢迎通过 GitHub(@atian25)跟我交流。
加入字节跳动之后,我一直在继续做基础设施建设。入职后,我发现一件很有趣的事:在字节内部有非常大比例的正式员工在使用自研的云端 IDE(集成开发环境),而在其他大厂更多是外包同学在用。这可能是因为字节有很多 monorepo(单一仓库)模式,大库的本地运行极为耗时,又譬如我们的员工遍布全球各地,需要随时随地可以进行编码,种种因素促使云端 IDE 在字节跳动内部的使用需求持续高涨。
2022 年,ChatGPT 横空出世,引爆整个人工智能行业,AI 的能力以超越人类想象的速度进化。如果用第一性原理来看大语言模型,本质上大语言模型的唯一工作就是预测下一个 token,相比起复杂的自然语言,编程语言是更加简洁、严谨、可预测的。我们已经看到了大语言模型在自然语言预测上令人震惊的效果,因此有理由相信,大语言模型在编程语言预测上也具有非常大的潜力。
在过去的这些年,我所在的部门一直从事开发者工具相关工作,我们的产品服务了字节内部成千上万的工程师,在字节内部有 70% 的工程师在使用豆包代码助手的内部版本来提升他们的开发效率,大语言模型的出现,让我们看到了新的生产力提升开发者效率和体验的可能性,也让我们有机会能够在 AI 时代更好地服务所有开发者,我们非常兴奋能够参与到这一旅程之中。
系统时钟是GD32 MCU的时基,可以理解为系统的心跳,片上所有的外设以及CPU最原始的时钟都来自于系统时钟,因而明确当前系统时钟是多少非常重要,只有明确了系统时钟,才能够实现准确的定时、准确的采样间隔以及准确的通信速率等。
以GD32F303为例,其系统时钟配置在system_gd32f30x.c中,如下图所示,可以通过打开或者关闭相关的宏定义进行时钟配置,GD32以及提供了一些时钟配置的函数,可以通过宏定义开关进行选择。
确认当前系统时钟有以下两个方法:
1、软件方式确认
使用void SystemCoreClockUpdate(void)函数进行更新当前系统时钟SystemCoreClock,该函数为根据当前RCU模块寄存器配置以及外部晶振等相关宏定义进行计算,将计算的结果赋值给SystemCoreClock变量,因而调用该函数后,SystemCoreClock的值就是当前系统时钟的数值。
需要注意,如果外部晶振不是8M,则需要调整HXTAL的宏定义,否则可能会造成SystemCoreClock计算出错。
2、时钟输出确认
另外一种最直接最准确的方式,是将系统时钟通过CKOUT引脚输出,然后通过示波器进行查看,如下图所示,CK_SYS为系统时钟,将CKOUT0SEL配置为100,就可以将系统时钟输出到CK_OUT0引脚上,这样外部接示波器就可以查看当前系统时钟了。
另外也可以通过定时器或者通信频率来进行估算,希望大家在系统开发伊始有确认系统时钟的好习惯,避免由于系统时钟配置出错导致的隐藏问题。
更多GD32 MCU相关咨询:https://www.gd32bbs.com/
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBaseRedis (正在更新) 章节内容 上一节我们完成了如下的内容:
bitmap 位操作类型geo 空间类型 空间计算 Z阶曲线 Base32编码Stream类型 消息队列 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个大数据的学习环境,供我学习。
之前已经在 VM 虚拟机上搭建过一次,但是没留下笔记,这次趁着前几天薅羊毛的3台机器,赶紧尝试在公网上搭建体验一下。
2C4G 编号 h1212C4G 编号 h1222C2G 编号 h123 发布订阅 基本简介 Redis提供了订阅发布的功能,可以用于消息的传输
发布者和订阅者都是Redis的客户端,Channel则为Redis的服务端。发布者将消息发送到某个频道,订阅了这个频道的订阅者就能收到这条消息。 Subscribe Redis客户端1:订阅频道1、订阅频道2
执行完之后,程序会阻塞住。
代码实现如下:
root@h121:/usr/redis/bin# ./redis-cli 127.0.0.1:6379> subscribe ch1 ch2 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "ch1" 3) (integer) 1 1) "subscribe" 2) "ch2" 3) (integer) 2 Publish Redis客户端2:将消息发布到频道1、频道2
root@h121:/usr/redis/bin# ./redis-cli 127.0.0.1:6379> publish ch1 hello! (integer) 1 127.
作者:后端小肥肠
创作不易,未经允许严禁转载。
姊妹篇:
【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索_spring security 微信小程序登录-CSDN博客
目录
1. 前言
2. 总体登录流程
3. 数据表设计
3.1. sys_user表
3.2. user_auth表
3.3. 表关系
4. OAuth2 扩展实现小程序登录
4.1 OAuth2登录涉及到的重要组件讲解
4.2 微信小程序自定义登录
5. 结语
1. 前言 随着微信小程序在国内的广泛应用,越来越多的企业希望将微信小程序登录功能集成到他们的系统中,以提供更便捷的用户体验。Spring Security OAuth 2.0 是一个强大的框架,可以帮助我们实现这一需求。本文将详细介绍如何在 Spring Security OAuth 2.0 中扩展支持微信小程序登录,通过自定义授权方式实现无缝登录。
2. 总体登录流程 后端小肥肠 上述流程图描述了小程序集成OAuth2获取Token登录步骤及日常携带token访问接口步骤:
登录步骤:
1. 获取用户基本信息
在小程序端,调用 wx.getUserProfile() 方法来获取用户的基本信息。这一步通常是在用户同意授权后进行的,用于获取用户的头像、昵称等基本资料。
2. 获取登录凭证
通过调用 wx.login() 方法,小程序端可以获取到一个 loginCode,这是一个临时登录凭证,用于后续的认证请求。
3. 获取手机号凭证
调用 getPhoneNumber 方法,小程序端可以获取到一个 phoneCode,这是一个用于获取用户手机号的临时凭证。
4. 发送登录请求
小程序端将 loginCode 和 phoneCode 一起发送给开发者服务器。开发者服务器接收到这些凭证后,开始处理登录请求。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 LLama Factory微调流程一、准备微调的数据集和模型二、读取模型和数据进行训练1.使用web ui2.修改官方脚本(推荐) 第三,加载与推理 LLama Factory微调流程 官方GitHub链接
官方数据集说明
官方微调命令
安装LLama factory
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e ".[torch,metrics]" 总体上你可以把整个流程分为下面几个步骤:
1.准备微调的数据集和模型
2.读取模型和数据进行训练
3.使用命令或者脚本进行微调训练
4.加载微调的训练模型
一、准备微调的数据集和模型 1.下载模型
这里可以使用HuggingFace或者ModelScope提供的方法进行模型下载,这里给出ModelScope的下载方式, 如果要使用Qwen2请看3:
from modelscope import AutoModelForCausalLM, AutoTokenizer, snapshot_download from modelscope import GenerationConfig ##cache_dir表示模型存储的目录 models_dir = "app/models" model_dir = snapshot_download('qwen/Qwen-7B-Chat',cache_dir="app/models") tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True, cache_dir=models_dir) model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="cuda:0",trust_remote_code=True, cache_dir=models_dir).eval() model.generation_config = GenerationConfig.from_pretrained(model_dir, trust_remote_code=True, cache_dir=models_dir) response, history = model.chat(tokenizer, "
MENU 初版前言(重要)代码解析功能概括数据属性mounted生命周期钩子unmounted生命周期钩子方法 总结 完整版前言浏览器刷新或关闭时的顺序简易判断Chrome(谷歌浏览器)关闭或刷新行为的方法发送请求总结 结束语 初版 前言(重要) beforeunload和unload之间的时间关系,也是实现关闭标签自动退出登录的关键。
1、当页面刷新的时候beforeunload和unload之间的时间间隔比较长,亲测时是10毫秒以上。这不是绝对值,要看电脑配置和网络状态是否良好,网上建议5毫秒,但是亲测不行;
2、当页面关闭时,beforeunload和unload之间的时间间隔非常短,具体是多少没有做过测试,反正远远小于10毫秒;
3、所以本案例并不完美,慎用,希望有完美案例的博主可以分享给大家使用。
代码 data() { return { beforeUnload_time: 0, }; }, mounted() { // 页面(浏览器标签页)关闭前 window.addEventListener("beforeunload", (e) => this.runBefor(e)); // 页面(浏览器标签页)关闭后 window.addEventListener("unload", (e) => this.runUnload(e)); // 页面可视时刷新(会加载整个页面,用户体验不是很好,视情况使用) // document.addEventListener("visibilitychange", this.runVisibilitychange); }, unmounted() { window.removeEventListener("beforeunload", (e) => this.runBefor(e)); window.removeEventListener("unload", (e) => this.runUnload(e)); // document.removeEventListener("visibilitychange", this.runVisibilitychange); }, methods: { logout() { // 退出登录 // 跳转到登录页面 }, runVisibilitychange() { if (!document.hidden) location.reload(); }, runBefor() { this.
目录
关于链表的分类
双向链表结构体
初始化
尾插
头插
打印
判断是否为空
尾删
头删
查找
指定位置之后的插入
指定位置的删除
销毁
关于链表的分类 根据链表的三大特性,单向or双向、带头or不带头、循环or不循环,可将链表分为2*2*2,8种链表,前面我们已经实现了单链表,即:不带头单向非循环链表,它的结构简单,不常用于单独存储数据,而是作为其他数据结构的子结构。
实际运用中,只有单链表(不带头单向非循环链表)和双向链表(带头双向循环链表)运用最多,带头双向循环链表,结构最复杂,常常运用于单独存储数据,使用的链表结构也几乎都是双向带头链表。
附上一张bit课件的图:
双向链表结构体 放一张bi课件的图片很形象:
//重定义一下类型,方便统一修改 typedef int LNDataType; typedef struct ListNode { LNDataType data;//数据 struct ListNode* prev;//前一个结点 struct ListNode* next;//后一个结点 }LN; 初始化 双向链表的初始化,应创建一个哨兵结点(也称头结点),它存放的数据是无效数据(假定-1),
所以我们先实现一个创建单节点的函数:
//创建新节点 LN* LNBuyNode(LNDataType x) { LN* node = (LN*)malloc(sizeof(LN));//开辟空间 if (!node) {//判断为空 perror("malloc fail!"); exit(1); } node->data = x;//传入数据 node->next = node->prev = node; //双向循环链表单节点也应满足循环,不能初始化为NULL; return node; } 接着我们就可方便地调用,创建一个哨兵结点:
在此之前,我们通过 《Android 15 上 16K Page Size 为什么是最坑》 介绍了:
什么是16K Page Size为什么它对于 Android 很坑如何测试 如果你还没了解,建议先去了解下前文,然后本篇主要是提供适配的思路,因为这类适配更多工作量在于实际的执行调整和编译跟踪,而非功能上的适配,本质不复杂,但可能量大且繁琐。
是的,想要适配你首选需要有 C/C++ 等 so 库的源码。
适配的开始,我们可以先粗暴的全局搜索 「4096」关键字,看看是否有将 4096 搭配 mmap 、sysconf 等相关的地方,因为 Android 上的 4K 这么多年已经「深入人心」,可以说不少代码都将 Android 默认为「4096」。
对于这些地方,我们可以通过类似 getpagesize() 等方式来进行调整,例如通过 ALOGV("####### %d", getpagesize()); 可以看到在 Android15 上输出的是 16384 。
接着我们可以运行项目到 Android 15 的模拟器上(如果运行不起来看前文),看 so 是否能正常被加载执行,一般情况下你可能会看到类似:
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH ···· (new hash type from the future?) 这类问题基本都是 so 文件没有 16K 编译对齐的原因,此时,根据你的 CMakeList 版本,可以使用 target_link_options 或者 target_link_libraries 进行调整。
个人主页~
string 一、标准库中的string类1、什么是string类2、string类的常用接口讲解(1)string类的常见构造(2)string类的容量操作(3)string类对象的访问及遍历(4)string类对象的修改(5)string类非成员函数(6)其他(7)vs和g++下string结构说明vs下的string结构g++下string结构 一、标准库中的string类 1、什么是string类 (1)字符串是表示字符序列的类,string是表示字符串的字符串类
(2)标准的字符串提供了对此类对象的支持,其接口类似于标准字符容器的接口与常规容器的接口基本相同,但添加了专门用于操作单字节字符字符串的设计特性,也就是专门用来操作string的常规操作
(3)string类是使用char作为它的字符类型
(4)string类是basic_string模版类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数
basic_string<char> s1; string s2; //这两个是一样的,string就是basic_string的char类型特化 typedef basic_string<char, char_traits, allocator> string;//底层 (5)不能操作多字节或者变长字符的序列
(6)在使用时要包头文件以及展开命名空间
2、string类的常用接口讲解 (1)string类的常见构造 函数名称功能说明string()构造空的字符串string(const char* s)用C格式的字符串构造字符串string(const string& s)拷贝构造函数string(size_t n,char c)字符串中包含n个字符c void test() { string s1; string s2("hello world"); string s3(s2); string s4(5, 'a'); } (2)string类的容量操作 函数名称功能说明size返回字符串有效字符长度empty检测字符串是否为空,是返回true,否返回falseclear清空有效字符reserve为字符串预留空间resize将有效字符个数改为n个,多出的空间用字符c填充capacity总空间大小length返回字符串有效字符长度 void test2() { string s1("hello world"); cout << s1 << endl; //测试size和length cout << s1.size() << endl; cout << s1.length() << endl; //size和length底层实现原理完全相同,在刚刚创造出string的时候,对于字符串来说,叫length很合适, //所以起名为length,但不久后STL产生了,为了与其他的模版比如list,vector等统一, //所以加了size,保持接口一致性,一般都用size //测empty cout << s1.
目录 1.Read View1.是什么?2.理解3.整体流程 2.RR与RC的本质区别1.当前读和快照读在RR级别下的区别2.RR与RC的本质区别 1.Read View 1.是什么? Read View就是事务进行 快照读 操作的时候生产的 读视图(Read View),在该事务执行快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID,这个ID是递增的,所以最新的事务,ID值越大)Read View 在 MySQL 源码中,就是一个类,本质是用来进行可见性判断的 即:当某个事务执行快照读的时候,对该记录创建一个 Read View 读视图,把它比作条件,用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的 undo log 里面的某个版本的数据注意:Read View是事务可见性的一个类,不是事务创建出来的,就会有Read View,而是当这个事务(已经存在),首次进行快照读的时候,MYSQL形成Read View 下面是 ReadView 结构,但为了减少同学们负担,我们简化一下class ReadView { // 省略... private: /** 高水位,大于等于这个ID的事务均不可见*/ trx_id_t m_low_limit_id /** 低水位:小于这个ID的事务均可见 */ trx_id_t m_up_limit_id; /** 创建该 Read View 的事务ID*/ trx_id_t m_creator_trx_id; /** 创建视图时的活跃事务id列表*/ ids_t m_ids; /** 配合purge,标识该视图不需要小于m_low_limit_no的UNDO LOG, * 如果其他视图也不需要,则可以删除小于m_low_limit_no的UNDO LOG*/ trx_id_t m_low_limit_no; /** 标记视图是否被关闭*/ bool m_closed; // 省略... }; m_ids; // 一张列表,用来维护Read View生成时刻,系统正活跃的事务ID up_limit_id; // 记录m_ids列表中事务ID最小的ID(没有写错) low_limit_id; // ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1 creator_trx_id // 创建该ReadView的事务ID 2.
欢迎来到@一夜看尽长安花 博客,您的点赞和收藏是我持续发文的动力
对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论的问题可联系我:3329759426@qq.com 。发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。
专栏:
java全栈C&C++PythonAIPCB设计Linux云计算&运维 文章概述:ACM算法 ——前缀和算法
关键词:ACM 一维前缀和 二维前缀和
本文目录:
前缀和
一维前缀和
原理
公式(思想)
运算逻辑(前缀和算法的目的)
示例:
二维前缀和
原理:
公式:
运算逻辑
大家注意:
示例:
前缀和 主要是个思想或者说是个公式
一维前缀和 原理 原数组
前缀和数组
公式(思想) 运算逻辑(前缀和算法的目的) 求得 [ r, l ]之间的原数组元素之和(区间和)
将前r项a数组的和Sr 减去 前l-1项和S l-1 , 得到的是第【r,l】之间的数组元素之和
示例: #include <iostream> using namespace std; const int N=100010; int n,m; //初始化数组 int a[N],s[N]; int main() { scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) scanf("%d",&a[i]); for(int i = 1;i<=n;i++) s[i]=s[i-1]+a[i]; //前缀和的初始化 while(m--) { int l,r; scanf("