Java程序员接单分享

作为一名Java程序员,这阵子通过承接些小型项目,我顺利跨过了月薪破万的门槛。这些项目虽小,却如同磨刀石般,让我在实战中发现了自身技术栈的棱角与不足,尤其是意识到了在Java这一浩瀚技术海洋中的诸多未知领域。我深知,仅凭这些成就难以支撑起我在技术深度上的持续飞跃,因此,我将它们视为成长的垫脚石,而非终点。 在项目的洗礼下,我更加明确了自己的技术短板,特别是在Java这一核心领域的探索尚浅。我渴望深入Java的骨髓,从代码优化到性能调优,从理论深挖到实践应用,每一个细节都力求做到极致。我的学习之旅,将不再仅仅依赖于视频教程与快速编码的循环,而是更加注重结合实战与理论,特别是通过研读GitHub上的开源项目,汲取那些顶尖开发者的智慧与灵感,让自己的编程技艺与架构设计能力实现质的飞跃。 我意识到,业余时间的小项目不仅仅是简单的编码实践,更是拓宽视野、结交同好、激发灵感的宝贵机会。在这个过程中,我见证了身边人的不懈努力与坚持,无论是考研路上的默默耕耘,还是小程序创业者的激情奋斗,都让我深受鼓舞。这让我更加坚信,学习永无止境,探索永远在路上。 以下是我接单的项目成果,算法的单子就不展示了 如果您有Java相关的需求项目定制需求,无论是算法实现还是技术难题解决,都欢迎随时联系我。我将凭借丰富的项目经验和专业的技术能力,为您提供最优质的解决方案。我相信,通过我们的共同努力,一定能够创造出更加优秀的技术成果。

人工智能时代,程序员当如何保持核心竞争力?

目录 前言 一.AI辅助编程对程序员工作的影响 二.程序员应重点发展的核心能力 三.人机协作模式下的职业发展规划 结束语 前言 随着AIGC(如chatgpt、midjourney、claude等)大语言模型接二连三的涌现,AI辅助编程工具日益普及,程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工作,也有人认为AI是提高效率的得力助手。面对这一趋势,我们程序员应该如何应对? 一.AI辅助编程对程序员工作的影响 如今AI辅助编程正在逐渐成为程序员日常工作中不可或缺的一部分,下面是小编搜集的观点和自己的理解。 1. 提高开发效率 - 代码补全:AI可以预测程序员接下来可能要输入的代码,从而减少打字时间。 - 代码修复:AI能够识别并建议修复代码中的错误,减少调试时间。 - 代码生成:通过我们自然语言描述,AI可以生成代码片段,甚至完整的程序。 2. 帮助小白学习,降低入门门槛 - 对于编程新手,像小编这种人来说,AI辅助工具可以提供指导,帮助我们更快地理解编程概念和编写代码。 3. 能够优化代码 - AI可以分析代码质量,提出建议,帮助写出更加清晰、高效的代码。 - 自动化测试和代码审查有助于提前发现潜在的问题。 4. 查询计算机知识 - 程序员可以通过AI快速获取相关的知识,例如库和框架的使用方法,以及最佳实践。 5. 顺应AI变化,进行技能转变 - 程序员可能需要掌握与AI辅助工具交互的技能,比如如何更有效地使用AI来辅助编程。 - 程序员可能需要学习如何管理和维护AI模型,确保能够按照预期工作。 6. 调整自身的职业发展 - 随着AI在编程中的应用越来越广泛,程序员可能需要考虑如何将自己的职业发展与AI相结合, - 使用AI辅助编程工具可能引入新的安全风险,例如代码泄露或AI模型被恶意利用。 总的来说,AI辅助编程对程序员的工作带来了深远的影响,既包括正面的效率提升和质量改进,也包括对程序员技能、心态和职业规划的挑战。我们需要适应这些变化,不断学习新技能,以便能够充分利用AI带来的机遇。 二.程序员应重点发展的核心能力 提高技术能力,精通至少一种编程语言,并了解多种语言的特点,掌握基本的算法和数据结构,能够解决复杂问题,了解软件开发生命周期,包括需求分析、设计、测试和维护,能够设计和实现可扩展、高性能的系统。 增强学习与适应能力 ,能够快速掌握新技术和新工具,保持对技术的好奇心,持续更新知识库。 提高问题解决能力,能够准确识别问题的本质,我们不能局限于传统方法,寻求创新的解决方案。 增强沟通与协作能力,能够清晰、准确地表达自己的想法,在团队环境中有效工作,能够与他人协作完成任务。 提高项目管理能力,时间管理:有效管理时间和优先级,确保按时完成任务,资源管理:合理分配和利用资源,包括人力资源和技术资源。 专业发展,了解所在行业的趋势和最佳实践,通过博客、社交媒体、开源项目等方式建立个人品牌。 当然我们也要提高安全意识和责任感,正确合理使用 AI工具,了解网络安全的基本原则,编写安全的代码,在开发过程中注重用户隐私保护。 三.人机协作模式下的职业发展规划 理解AI和机器学习的原理 学习AI和机器学习的基础知识,理解它们的工作原理和应用范围。了解不同类型的AI系统及其在各自领域中的应用。 2.技能提升 提升编程、数据分析、机器学习等硬技能。学习如何有效地与AI系统交互,包括使用AI工具和平台。结合其他领域知识,如心理学、设计思维等,以更好地理解人机协作的复杂性和多样性。 3.终身学习 互联网时代更新迭代很快,作为程序员,我们要不断学习新的知识,掌握新技能,学会创新思 考,要有终身学习的思想,付出实践行动。 结束语 最重要的是要我们要爱惜自己的身体,俗话说,身体才是革命的本钱,加强锻炼,有一个健康的身体,这样的话,敲代码写程序也才更加舒服嘛!!!

【C++高阶】深入理解C++异常处理机制:从try到catch的全面解析

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:Lambda表达式 🌹🌹期待您的关注 🌹🌹 ❀C++异常 📒1. C++异常概念🌸C语言处理错误方式🌺C++异常概念 📜2. 异常的使用⛰️异常的抛出和捕获🌄异常的重新抛出🌞异常安全⭐异常规范 📚3. 自定义异常体系📝4. C++标准库的异常体系📙5. 异常的优缺点📖6. 总结 前言:在编程的浩瀚宇宙中,C++以其卓越的性能、强大的灵活性和对底层硬件的直接控制而著称,是无数开发者心中的瑰宝。然而,在追求高效与极致的路上,错误处理与异常管理往往成为不可忽视的重要环节。C++通过引入异常处理机制,为开发者提供了一套强大而灵活的工具,以优雅地应对程序执行过程中可能遇到的各种异常情况,从而确保程序的健壮性和可靠性 C++的异常处理机制,通过try、catch和throw三个关键字,为开发者构建了一个结构清晰、易于理解的异常处理框架。当程序执行到可能抛出异常的代码段时,可以使用try块将其包围起来;随后,通过一个或多个catch块来捕获并处理可能发生的特定类型的异常;而throw关键字则用于在程序中显式地抛出异常,通知上层调用者当前代码遇到了无法继续执行的情况 这种机制不仅使得异常处理代码与正常业务逻辑代码分离,提高了代码的可读性和可维护性,还通过异常的传播机制,使得开发者能够在更高层次上统一处理异常,从而避免了错误处理的代码在程序中到处蔓延,导致代码结构混乱 我们将一起踏上探索C++异常处理的奇妙旅程,让我们携手前行,在C++的编程世界中,共同书写属于自己的辉煌篇章! 📒1. C++异常概念 🌸C语言处理错误方式 传统的错误处理机制: 终止程序,如assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序。返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通 过把错误码放到errno中,表示错误 实际中C语言基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的 错误 🌺C++异常概念 异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的 直接或间接的调用者处理这个错误 throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。catch: 在您想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异 常,可以有多个catch进行捕获try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块 如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码 代码示例 (C++): double Division(int x, int y) { // 当y == 0时抛出异常 if (y == 0) throw "Division by zero condition!

vscode开发avalonia

安装 安装.net 8 安装avalonia模板 dotnet new install Avalonia.Templates 创建项目 dotnet new avalonia.app -o GetStartedApp 安装c# dev kit插件和Avalonia for VSCode Community dotnet run运行 修改代码 MainWindow.axaml <Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450" x:Class="GetStartedApp.MainWindow" Title="GetStartedApp"> <TextBlock Text="My Text" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Window> 继续修改代码 <Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450" x:Class="GetStartedApp.MainWindow" Title="GetStartedApp"> <Button HorizontalAlignment="Center">Calculate</Button> </Window> 增加布局 <Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450" x:Class="GetStartedApp.MainWindow" Title="GetStartedApp"> <StackPanel> <Border Margin="5" CornerRadius="10" Background="

【C语言】qsort函数的介绍和使用

0. 引言 我们日常生活中经常能碰到需要给一组数据排序的情况,如将班上同学的身高,年龄从大到小排序,平时网上购物时对商品价格从低到高排序等等场景,那么电脑是根据什么程序完成这些排序的?接下来就来给大家介绍一下C语言中,可以实现排序的库函数 --- qsort。 1. qsort 是什么? qsort 是 C语言 标准库 <stdlib.h> 中提供的一个排序函数。 它使用的是快速排序算法(Quick Sort)对数组进行排序。 参考链接:qsort - C++ Reference (cplusplus.com) 2、qsort 函数介绍 2.1 qsort 函数原型 void qsort(void *base, size_t num, size_t size, int (*compar)( const void *, const void * )); 下面是 qsort 函数的参数说明: base:指向待排数组的第一个元素的指针。 num:base指向的待排数组中元素的个数。 size:base指向的待排数组中每个元素的大小,以字节为单位。 compar:函数指针,指向的就是两个元素的比较函数,该函数用于确定排序的顺序。 2.2 compar 比较函数 相信同学们对于qsort函数第四个参数是函数指针不是很了解,在这里给大家详细说说~ qsort 函数使用了一个回调函数。回调函数是什么呢?在计算机编程中,回调函数是一种作为参数传递给另一个函数的函数,以便在某个特定事件发生时由该函数调用。在 qsort 的上下文中,回调函数用于确定数组中元素的比较方式。 在 qsort 的定义中,int (*compar)(const void *, const void *) 是一个函数指针参数,它指向了一个compar 这样一个比较函数。当 qsort 需要比较数组中的两个元素时,它会调用这个比较函数。比较函数的返回值决定了 qsort 如何重新排列数组中的元素。

【数据结构】栈的概念、结构和实现详解

本文来介绍一下数据结构中的栈,以及如何用C语言去实现。 1. 栈的概念及结构 栈:一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。 栈中元素遵循后进先出LIFO(Last In First Out)的原则 压栈:栈的插入操作叫做进栈/入栈/压栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈,出数据也在栈顶。 2. 实现栈的底层方法选择 没有规定栈的哪端是栈顶,只说了数据插入和删除的一端是栈顶,所以我们栈的底层实现可以用链表或者数组 。 虽然数组和单链表都可以实现栈,但是单链表能很好入数据不好删除数据,这里单链表要删除数据就是尾删,尾删需要找到前一个结点,不是很方便。 非要用链表的话有两个解决方法,1.可以用双向链表 2.我们把单链表的头节点当作栈顶,也就是把左边当栈顶,右边当栈底,对单链表进行头插和头删的操作。 现在有3种方法实现栈,数组,单链表,双链表,我们应该如何选? 首先排除双链表,用双链表不如用单链表,双链表因为一个节点存两个指针,比单链表的一个节点多了4个字节或者8个字节。数组实现栈和单链表实现栈有什么区别?基本没区别,都可以,非要说选一个,我们还是更倾向于数组,因为数组的唯一缺点就是内存不足时需要扩容,扩容的影响也不是特别大,最重要的是数组的缓存效率更高。所以我们就用数组实现栈。 3. 栈的实现 提前说明,如果本篇看不太懂可以先看看【数据结构】顺序表-CSDN博客,我们栈的实现和顺序表的实现差不多。 还是一样,新建一个头文件和两个源文件 点开Stack.h文件,在这个文件里面我们要定义栈的结构,以及给类型和栈的结构取别名。 typedef int STDateType; typedef struct Stack { STDateType* a;//动态申请空间 调大小 int top; //用栈顶记录元素个数 int capacity; //数组实现要扩容,记录空间大小 }ST; 栈一共要实现下面这7个接口,我们将一个一个来看. void STInit(ST* pst);//栈初始化 void STDistroy(ST* pst);//栈的销毁 void STPush(ST* pst, STDateType x);//压栈 void STPop(ST* pst);//出栈 STDateType STTopDate(ST* pst);//获取栈顶元素 bool STEmpty(ST* pst);//判断栈是否为空 int STSize(ST* pst);//获取栈元素个数 这里是会用到的头文件,且标注了是什么会用到,被包含的头文件全放在Stack.h中 #include <stdio.h> #include <stdlib.

Redis01——Redis简介

目录 NOSQL与SQL的差异 数据结构:结构化 VS 非结构化 数据关联:关系型 VS 非关系型 数据查询:SQL查询 VS 非SQL查询 事务特性:满足事 VS 没有完全满足 Redis 简介 Redis 安装 Redis 数据结构简介 Redis 常用命令(基本) 通用命令:KEYS、DEL、EXISTS、EXPIRE、TTL keys 查看符合模板的所有key DEL 删除一个指定的key EXISTS 判断key是否存在 Redis中value的常见类型 String 类型 key 的层级结构 Hash 类型 List 类型 Set 类型 SortedSet 类型 NOSQL与SQL的差异 关于图中的扩展性 垂直:关系型数据库在一开始设计数据库时,就没有考虑到数据的分布式存储,通俗来说就是没有考虑到把数据拆分成不同的部分,然后保存到不同的地方。比如一开始把主机A当成数据库服务器,那么主机A的性能就直接决定了数据库服务器的性能,只能通过提高主机A的性能来提高数据库的性能(当然,数据库自身也可以通过一些优化手段来提升性能,但是我觉得这是两码事)。个人的理解:比如主机A的存储空间有1G,那么数据库也最多最多能存储1G的数据,如果想存储更多的数据,那么只能通过给主机A增加存储空间来实现(比如给主机A加内存条啥的),而不能选择说把多的数据存到别的地方,进行分布式存储水平:与垂直相对的,水平是已经考虑到了数据的拆分需求,就是可以把数据拆成多个部分,存储在不同的主机上,实现分布式存储,比如主机A存满了,就存到主机B上。非关系型数据库会通过哈希运算,来判断数据应该存到哪个地方,从而实现数据的拆分,所以对非关系型数据库很容易进行数据扩展 数据结构:结构化 VS 非结构化 数据关联:关系型 VS 非关系型 关系型数据库中数据表之间的联系可以节省数据存储空间 非关系型数据库的数据之间则没有直接的联系,可能会存储重复的数据,如一个商品信息被多个用户购买,那么这个商品信息就会被存储多次 数据查询:SQL查询 VS 非SQL查询 事务特性:满足事 VS 没有完全满足 关系型数据可以全部满足事务的ACID四个 特性,但是非关系型数据库不能同时满足四个特性 Redis 简介 Redis 安装 Redis 是安装在Linux上的,在个人电脑一般都是在虚拟机里安装Linux,安装教程可以在网上找教程,也可以参考我的这个笔记:虚拟机和Linux安装教程 然后Redis的安装和基本使用参见视频:安装Redis和三种启动方式、Redis的命令行客户端、Redis的图形化界面 Redis 数据结构简介 Redis中的数据是以键值对的方式进行存储,即key-value,其中value有多种不同的类型,适用于不同的应用场景

一文读懂 ESLint配置

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎 代码都在github或gitee上,可以去上面自行下载 如果你遇到了问题,自己没法解决,可以去我掘金评论区问。私信看不完,CSDN评论区可能会漏看 掘金账号 https://juejin.cn/user/1942157160101860 掘金账号 本篇介绍了代码校验工具ESlint的配置规则与常用的配置项,无论是新手还是老手都能有所收获 前言 博主看来很多网络上的视频教程,发现对ESLint配置的介绍是比较少的。但ESLint是很有用的,一个项目是否健全,多人开发一个项目时,能否实现代码风格一致,ESLint在这个过程中是不可替代的。今天就来详细介绍ESLint配置规则,与推荐一些基础的配置。 什么是ESLint ESLint 是一种静态代码分析工具,用于在编写 JavaScript 和 TypeScript 代码时识别和报告问题。它的主要目标是帮助开发者在早期阶段发现代码中的潜在错误和不良模式,确保代码的一致性和高质量。 使用ESLint 一:命令行安装ESLint npm init @eslint/config 安装后能在包工具中看到 二:在VSCode安装ESLint插件 三:ESLint通过什么来实现代码风格一致与规范写法? 文件名/类型作用格式.eslintrc定义 ESLint 的规则、环境、解析器、插件等JSON、YAML 或 JavaScripteslint.config.js以 JavaScript 形式编写 ESLint 配置,允许使用更多编程逻辑JavaScript.eslintignore指定 ESLint 应忽略的文件和目录类似于 .gitignore,一行一个路径规则定义文件(plugins)扩展 ESLint 功能,定义一组规则N/A 简单来说,在你项目引入了ESLint后,你只需要在项目目录下放这些文件,就可以达到配置ESLint的效果 一般情况下,我们在项目中添加 .eslintrc 和.eslintignore就能够比较健全的使用ESLint了 四:.eslintignore文件配置与文件配置规则 常用的配置规则 在这里,我给出我项目中一般会使用的.eslintignore配置 docs dist public node_modules .

解决OSError: [WinError 126] 找不到指定的模块。 Error loading “D:\Anaconda3\Lib\site-packages\torch\lib\fbgemm

** 解决 OSError: [WinError 126] 找不到指定的模块。 Error loading “D:\Anaconda3\Lib\site-packages\torch\lib\fbgemm.dll” or one of its dependencies. ** 去这个网站 https://discuss.pytorch.org/t/failed-to-import-pytorch-fbgemm-dll-or-one-of-its-dependencies-is-missing/201969/13 这个大佬解决了我的问题。 这个图片的网址是https://www.dllme.com/dll/files/libomp140_x86_64?sort=upload&arch=0x8664。真真救我狗命!!! 这个方法我没试用,但听下面的回复说有效果!

C语言文件IO

目录 open函数原型参数flagsmode_t read函数原型参数返回值 write函数原型参数返回值 lseek函数原型参数fd的偏移量 access函数原型参数返回值 fcntl函数原型参数文件描述符标签文件状态标签 dup函数原型dup,dup2dup2,fcntl open 基于文件描述符的文件打开方式 函数原型 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char* pathname,int flags); int open(const char* pathname,int flags,mode_t mode); int creat(const char* pathname,mode_t mode); 参数 如果文件打开失败, open 将返回 -1 ,程序需要对异常情况进行处理。导致打开文件的原因又很多,例如:文件不存在;抑或权限不足等等。 flags flags字段使用POSIX的几个宏,此时必须包含头文件<fcntl.h>才行。 可以是下面几个宏的逻辑或组合。这些宏共有三种类型: 访问方式描述O_RDONLY只读O_WRONLY只写O_RDWR可读写 打开时标志描述O_CREAT创建文件,需要指定第3个参数modeO_EXCL与O_CREAT联用,如果文件已存在则返回错误O_TRUNC将清空文件的内容,仅对普通文件有用O_NOCTTY若打开的文件是终端设备,不让它作为该进程的控制终端O_NOBLOCK以非阻塞模式打开 IO操作方式描述O_APPEND把数据写到文件末尾O_NONBLOCK对文件的read()/write(),当无立即可用输入(或输出不能立即写出)时能以EAGAIN错误状态标志立即返回O_ASYNC(异步)此标志被设置,文件描述符有输入数据时会生成SIGIO信号O_SYNCO_DSYNCO_RSYNC mode_t 可以查看man 2 open read 函数原型 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 参数 参数描述fd文件描述符buf读取的数据存放在buf指针指向的缓冲区count读取的字节数 返回值 若果函数执行成功,返回读取的字节数,如果遇到EOF,则返回0。出错返回**-1**,并设置相应errno值。 当我指定要读取100个字节的时候,在读完30个字节后,遇到了EOF,那么这时立即返回30,接下来继续执行read函数的时候返回0。从终端设备读,通常以行为单位,读到换行符就返回。当出错时(即返回-1),如果errno的值是EINTR,表示遇到调用信号而中断了读取,那么我们可以再次尝试read。 write 函数原型 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 参数 参数同read函数

C++第三十一弹---C++继承机制深度剖析(下)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】 1.菱形继承及菱形虚拟继承 1.1 单继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承。 Student的直接父类是Person,PostGraduate的直接父类是Student,且都只有一个直接父类,因此均为单继承。 注意: PostGraduate类只是间接继承了Person,因此依旧为单继承关系。 1.2 多继承 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承。 Assistant子类既继承了Student父类,又继承了Teacher父类,且均为直接继承,因此为多继承关系。 1.3 菱形继承 菱形继承:菱形继承是多继承的一种特殊情况,如下图: 菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。 在Assistant的对象中Person成员会有两份。 从上图我们可以看到,Assistant 类既继承了 Student 类又继承了 Teacher 类 ,而 Student 类和 Teacher 类又都继承了 Person 类, 因此 Assistant 类中有两份 Person 的成员,这也就是菱形继承所带来的数据冗余和二义性问题。 class Person { public: string _name; // 姓名 }; class Student : public Person { protected: int _num; //学号 }; class Teacher : public Person { protected: int _id; // 职工编号 }; // Assistant有两份Person类,存在数据冗余和二义性问题 class Assistant : public Student, public Teacher { protected: string _majorCourse; // 主修课程 }; 主函数

数据采集与预处理【大数据导论】

各位大佬好 ,这里是阿川的博客,祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 数据采集与预处理前 必看 【大数据导论】—大数据序言 【大数据导论】—大数据、人工智能、云计算、物联网、区块链序言 【大数据导论】—大数据基础知识 【大数据导论】—大数据应用 目录 大数据步骤其中数据采集其中数据清洗其中数据转换其中数据脱敏 大数据步骤 数据采集数据清洗数据处理数据分析数据可视化 其中数据采集 通过数据采集,可以获取传感器、互联网、日志文件、企业系统等数据,再通过数据预处理(数据清洗 数据转换 数据脱敏),从而便于后一步的分析 被采集数据类型 结构化数据半结构化数据非结构化数据 大数据特点 数据量大数据类型丰富处理速度快 数据采集比较 数据采集特点 全面性 多维性 高效性 主要数据源 日志文件数据 传感器数据 互联网数据 企业业务系统数据 数据采集工具 Chukwa Flume Scribe 分布式消息订阅分发 Kafka 实时在线处理低延迟批量离线处理高吞吐量 ETL 实现大规模数据加载 网络数据采集 通过网络爬虫、API接口从网站上获取非结构化数据信息且储存为统一的本地结构化数据文件 当中网络爬虫 爬虫节点控制节点资源库 控制节点与爬虫节点关系 网络爬虫的类型 通用网络爬虫(又称全网爬虫) 主要为 门户站点搜索引擎 大型Web服务提供商采集数据 通用网络爬虫结构 页面爬行 页面分析 连接过滤 页面数据库 URL队列 初始URL集合 爬行策略 深度优先策略 广度优先策略 聚焦网络爬虫(又称主题网络爬虫) 选择性爬取与预先定好的主题相关页面的网络爬虫 爬虫步骤 过滤主题无关链接 有用链接放入等待抓取URL队列 根据一定搜索策略 选择下一步抓取的网页URL

有哪些ai写作在线生成器?这篇文章让你了解几种软件的大概情况

与传统的纸笔创作不同,如今ai写作软件的出现正逐步改变着内容创作的生态。 从创意激发到文案优化,这些工具利用先进的人工智能技术,为几乎所有群体提供了前所未有的辅助。而且,大多数人都会有自己所擅长的文体,但ai工具却堪称“六边形战士”,几乎没有什么类型的内容生成任务可以难倒它! 接下来,我就给大家介绍一下ai写作软件都有哪些,感兴趣的话可以看看~ 迅捷AI写作 ↙我为什么介绍这款软件↘ 智能生成:你只需要输入一些关键词或者提纲,迅捷AI写作就能帮你快速生成完整内容,无需从头开始构思。 多种风格:无论是正式的报告、轻松的博客文章,还是专业的学术论文,它都能根据需求调整语言风格。 Scholarcy ↙我为什么介绍这款软件↘ 学术助手:Scholarcy专注于学术领域的写作,能够帮助大家快速整理和格式化参考文献,提高效率。 智能引用:它能够自动检测并生成准确的引用格式,确保学术诚信和论文的规范性。 ShortlyAI ↙我为什么介绍这款软件↘ 快速生成:ShortlyAI擅长于快速生成简短而精炼的内容,适合快速产出的新闻报道或社交媒体帖子。 多样化模板:它提供多种内容模板,能够帮助大家根据不同的写作需求快速搭建文章结构。 Scalenut ↙我为什么介绍这款软件↘ 自动优化:通过智能分析,Scalenut能够帮助大家优化文章结构和语言,提升文章的可读性和吸引力。 SEO友好:它特别适用于SEO写作,能够根据关键词优化内容,提高搜索引擎排名。 ContentBot ↙我为什么介绍这款软件↘ 内容规划:ContentBot能够帮助大家规划内容策略,提供内容创意和结构建议,适合用于内容营销和品牌传播。 自动化发布:该软件支持自动化发布,能够将生成的内容定时发布到不同的平台。 Jasper ↙我为什么介绍这款软件↘ 创意激发:Jasper能够提供创意写作的灵感,帮助大家打破创作瓶颈,拓宽新的写作思路。 个性化定制:它允许大家根据自己的品牌和风格需要定制写作内容,确保内容与品牌形象一致。 看完文章的介绍,我相信大家已经知道ai写作软件都有哪些了。其实,随着内容生成技术的发展,这些工具不仅操作难度越来越低,而且智能化程度也提高了。我相信它们一定能给大家提供很多帮助~

c++STL容器中vector的使用,模拟实现及迭代器使用注意事项和迭代器失效问题

目录 前言: 1.vector的介绍及使用 1.2 vector的使用 1.2 1 vector的定义 1.2 2 vector iterator(迭代器)的使用 1.2.3 vector 空间增长问题 1.2.4 vector 增删查改 1.2.5vector 迭代器失效问题。 2.vector模拟实现 2.1 std::vector的核心框架接口的模拟实现bit::vector 2.2 使用memcpy拷贝问题 前言: 在前面的章节我们已经接触过了关于STL的知识,也就是string类,我们详细介绍了string类的特性及使用,而严格来说string类并没有被归为STL中,因为string类的出现早于STL,string类的接口也比STL中的单个类多,使得string类较其他类显得冗余,这一期我们就要开始讲STL中的内容。 1.vector的介绍及使用 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。 3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。 4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。 5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。 6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。 1.2 vector的使用 vector的使用与string类相似,要实现一些基本的操作,如增,删,查,改这些操作,c++在库中都已经实现好了接口,我们只需要调用这些接口就可以实现对应的操作。c++如今的地位在很大程度上是因为引入了STL这块的内容。 1.2 1 vector的定义 1.2 2 vector iterator(迭代器)的使用 1.2.3 vector 空间增长问题 (1)capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。 (2)reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。 (3)resize在开空间的同时还会进行初始化,影响size。 // 测试vector的默认扩容机制 void TestVectorExpand() { size_t sz; vector<int> v; sz = v.

Flink 实时数仓(七)【DWS 层搭建(一)流量域汇总表创建】

前言 今天开始 DWS 层的搭建,不知不觉又是周一,都忘了昨天是周末,近两年对我来说,周六日晚上八九点能打一小会篮球就算一周的休息了。不得不说自己真的是天生打工体质,每天不管多累,晚上十二点睡,第二天六点多七点准时自然醒,依然精神焕发,中午都不带困的;那既然老天给我这个特质让我像牛一样可以不知疲倦的工作,那我也希望是让我在热爱的领域发光发热;那既然这样,总得先让我找到个满意的工作吧哈哈哈 ... 1、DWS 层搭建 设计要点: DWS层的设计参考指标体系(需求驱动);(前面的 DIM 和 DWD 的设计都是参考建模理论,是业务驱动)DWS层表名的命名规范为dws_数据域_统计粒度_业务过程_统计周期(window) 离线数仓中的 DWS 层的统计周期我们当时做的是 1/7/30 ,那实时数仓的统计周期当然不能这么大;离线数仓中每一天就相当于一个窗口,而在实时数仓当中,窗口都是秒级别的,我们这里开窗的大小选择 10 s,因为我们的可视化平台只能 10s 刷新一次,开得太小没有意义;(生产环境中可以更小比如 1s ,甚至可以不开窗。开窗还是不开窗是性能和时效性的取舍) 1.1、流量域来源关键词粒度页面浏览各窗口汇总表 主要任务: 从 Kafka 页面浏览明细(dwd_traffic_page_log)主题读取数据,过滤搜索行为,使用自定义 UDTF(一进多出)函数对搜索内容分词。统计各窗口各关键词出现频次,写入 ClickHouse。 1.1.1、思路分析 在 DWD 层,我们对日志根据日志类型进行了分流,写入到了 5 个不同的主题当中现在我们需要统计搜索内容中的关键词,所以需要消费页面浏览日志使用分词器将搜索内容分为多个关键词划分窗口,词频统计后存储进 clickhouse 思考:既然用到分词,为啥不直接用 ES 存呢? 答:确实是要分词,但是我们这里是要做词频统计,ES 是对关键词做索引,相当于用 key(关键词)去获得 value(文档),而我们这里是要对 key 进行统计,所以不合适; 1.1.2、代码实现 1)IK 分词器工具类 public class KeywordUtil { public static List<String> analyze(String text){ // 创建集合用于存放切分或的数据 List<String> keywordList = new ArrayList<>(); // 封装待分词内容 StringReader reader = new StringReader(text); // 创建 IK 分词器(ik_smart 智能分词,ik_max_word: 尽可能分最多的词) IKSegmenter ikSegmenter = new IKSegmenter(reader,true); try { // 取出切分好的词 Lexeme lexeme = null; while((lexeme = ikSegmenter.

【无标题】mysql用户+角色+密码安全策略

一.下载安装 mysql-8.0.33-linux-glibc2.12-x86_64.tar 1.清空/etc/目录下的my.cnf [root@000 ~]# rm -rf /etc/my.cnf [root@000 ~]# yum -y remove mariadb 2.解压 [root@000 ~]# tar -xvf mysql-8.0.33-linux-glibc2.12-x86_64.tar [root@000 ~]# tar -xf mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz [root@000 ~]# ls anaconda-ks.cfg mysql-8.0.33-linux-glibc2.12-x86_64 mysql-8.0.33-linux-glibc2.12-x86_64.tar mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz mysql-router-8.0.33-linux-glibc2.12-x86_64.tar.xz mysql-test-8.0.33-linux-glibc2.12-x86_64.tar.xz [root@000 ~]# cd mysql-8.0.33-linux-glibc2.12-x86_64/ [root@000 mysql-8.0.33-linux-glibc2.12-x86_64]# ls bin include LICENSE README support-files docs lib man share 3.将项目文件移动到/usr/local/mysql/ [root@000 ~]# cp -r mysql-8.0.33-linux-glibc2.12-x86_64/ /usr/local/mysql/ 4.查看有没有安装libaio [root@000 ~]# yum list installed |grep libaio libaio.x86_64 0.3.109-13.el7 @anaconda [root@000 ~]# echo $?

排序算法2:直接选择排序与快速排序

目录 1.直接选择排序 1.1直接选择排序的优化 2.快速排序 2.1基准值的置位(Hoare版) 2.2挖坑法 2.3lomuto前后指针 前言 前面我们进入了排序算的讲解。今天我们将继续学习几种重要的排序思想,好,咱们三连上车开始今天的内容。 1.直接选择排序 在元素的集合中选出最大值(最小值),存放在序列的起始位置,直到全部的待排序位置数据排完 在元素集合中arr[i]-----arr[n-1]中选择值最大(小)数据若他不是这组元素中的最后一个数据,则将他与这组的最后一个元素交换。在剩余的arr[i]----arr[n-2](arr[i + 1]-----arr[n-1])的集合中,传重复上面的步骤,直到集合剩余最后一个元素! 思路十分的简单,我们按照这样的思想来实现一下代码: void SelectSort1(int* arr, int sz) { for (int i = 0; i < sz; i++) { int begin = i; int min = begin; for (int j = begin + 1; j < sz; j++) { if (arr[min] > arr[j]) { min = j; } } Swap(&arr[min], &arr[begin]); } } 我们这样就实现了排序的目的,但是大家也不难看出,直接这样的排序跟冒泡排序相差无几,同样的效率低下,想要扩大他的使用场景,就要将他进行进一步的优化。 1.1直接选择排序的优化 原来的直接选择排序在排序时只是将特定范围内的最小值与该范围内的第一个元素进行交换,那如果我们在寻找最小值的同时,也来寻找最大值来与最后面的元素进行交换,这样就可以大幅提高排序的效率了。 按照这个思路我们来实现这个代码:

TypeScript 类

类 在 TypeScript 中,类是一种用于创建对象和组织代码的结构。 创建一个类: class Person { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } sayHi() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); } } let person1 = new Person('Alice', 25); person1.sayHi(); 声明一个 Person 类。这个类有3个成员: name 和 age 是类的属性,用于存储对象的状态信息。constructor 是类的构造函数,用于在创建对象时进行初始化操作,为属性赋值。sayHi 是类的方法,用于定义对象的行为。 在引用任何一个类成员的时候都用了 this。 它表示我们访问的是类的成员。 继承 在 TypeScript 中,类继承是一种面向对象编程的特性,允许一个类(子类)从另一个类(父类)继承属性和方法。 示例: class Animal { name: string; constructor(name: string) { this.

rule_解析`````````````````

"""编写一个Python函数,该函数接受两个参数: 一个文本文件【rule】和一个字符串【input】, 请根据文件中【rule】的替换规则返回一个字符串【output】。 def apply_replacement_rules(rules, input_string): # 你的代码【rule】 解析要求: 1、文本文件【rule】包含按顺序应用的替换规则。 2、每条规则是由空格分隔的两个字符串:s1 s2,其中s1和s2是不包含任何空格字符的字符串。 其含义是:对于输入字符串中的每个子字符串s1, 如果该子字符串没有被之前的任何规则更改过, 则将其替换为s2。 举例: 考虑文件rule.txt的内容如下(包含3条规则): abc cde ab b c a 它在输入字符串babcabdcdc上的工作过程如下: 1.第一条规则:b + cde + abdcdc #abc cde 2.第二条规则:b + cde + b + dcdc #ab b 3.第三条规则:b + cde + b + d + a + d + a #c a (注意,尽管“cde”包含“c”,但它不会被第三条规则出发,因为它是第一条规则产生的新字符串,而不是来自原始字符串) 所以输出是 bcdebdada 请注意:参数规则【rule】不是固定的, 你的程序应该适用于任何顺序与任何替换规则, 如:c ab abc cde ab b 或 abcd ab

OpenCV||超详细的图像分割

图像分割是数字图像分析中的重要环节,在整个研究中起着承前启后的作用,既是对所有图像预处理效果的一个检验,也是后续进行图像分析与解译的基础! 图像分割是由图像处理到图像分析的关键步骤! 壹、图像分割的数学定义 对一幅图像分割所得到的全部子区域的总和应能包括图像中所有的像素,或者说分割应将图像中的每一个像素都分进某个子区域中。在分割的结果中各个子区域是互不重叠的,也就是互相独立的;或者说在分割结果中一个像素不能同时属于两个子区域。在分隔结果中每一个子区域都有独特的特性,或者说属于同一个区域中的像素应该具有某些相同的特性。在分割结果中不同的子区域巨头不同的特性,没有公共的元素,或者说属于不同区域的像素应该具有一些不同的特性。分割结果中同一个子区域内的像素是联通的,即同一个子区域内任何两个像素在该子区域内互相连通,或者说分割得到的区域是一个连通单元。 贰、图像分割的分类方法 1、基于阈值化的分割方法 目标或背景的相邻像素间的灰度值是相似的,而不同的目标或背景的像素在灰度上有差异,反映在直方图上,不同目标和背景对应不同的峰,选区的阈值应位于两个峰之间的谷处。如果图像中具有多类目标,则直方图将呈现多峰特性,相邻两峰之间的谷即为多阈值分割的阈值。 阈值分割准则: P分位数(P-title法)最频值法(Mode法)Ostu法最大熵方法最小误差法矩量保持法 2、基于边缘的分割方法 参考图像边缘检测部分。 步骤: 加载图像:将待处理的图像加载到内存中。预处理:根据需要,对图像进行预处理操作,如去噪、平滑、增强等,以提高边缘检测的效果。边缘检测:应用边缘检测算法(如Canny边缘检测、Sobel算子等)检测图像中的边缘点。边缘连接:根据一定的准则或规则,将边缘点连接成边缘曲线或轮廓。常用的边缘连接方法包括基于阈值、梯度方向等准则。边缘细化:对边缘曲线进行细化处理,消除冗余的像素点,得到更准确的边界线。区域填充:根据边界线将图像分割成不同的区域,可以使用基于种子点的区域生长算法等方法进行区域填充。结果显示:将分割后的图像进行显示或保存。 3、基于区域的分割方法 区域生长法 基本思想:从一组种子点开始,根据某种相似性准则(如灰度级、颜色、纹理等),将邻近的像素点加入到相应的种子点所在的区域中,直到没有更多的像素点可以加入为止。实现步骤: 选择一组种子点。设定相似性准则。遍历图像的每个像素点,将其与种子点所在区域的像素点进行比较。如果满足相似性准则,则将该像素点加入到相应的区域中。重复步骤3和4,直到所有像素点都被分配到相应的区域中。特点:区域生长法对噪声相对不敏感,但计算复杂度较高,且需要预先确定种子点和相似性准则。 区域分裂与合并法 基本思想:首先将图像分成若干个子区域,然后根据区域之间的相似性进行分裂或合并操作,直到满足某种停止准则为止。实现步骤: 将图像分成若干初始子区域。计算相邻子区域之间的相似性。如果相邻子区域之间的相似性小于某个阈值,则进行分裂操作;如果相似性大于某个阈值,则进行合并操作。重复步骤2和3,直到满足停止准则(如区域数量达到预设值、区域间的相似性达到预设阈值等)。特点:区域分裂与合并法能够处理具有复杂结构的图像,但计算复杂度也较高,且需要预先确定分裂和合并的准则。 水平集方法 基本思想:将图像分割问题转化为求解能量函数最小化的问题。通过演化轮廓线(水平集)来逼近图像中的目标边界。实现步骤: 定义能量函数,该函数与轮廓线的位置和形状有关。初始化轮廓线(水平集)。通过迭代优化算法(如梯度下降法)求解能量函数的最小值。在迭代过程中,根据能量函数的变化更新轮廓线的位置和形状。当能量函数达到最小值或满足某种停止准则时,停止迭代。将最终得到的轮廓线作为图像分割的结果。特点:水平集方法能够处理具有复杂边界的图像,且对噪声和初始轮廓线的选择具有一定的鲁棒性。但该方法计算复杂度较高,且需要选择合适的能量函数和迭代优化算法。 图割方法 基本思想:将图像表示为图的形式,其中像素作为图的顶点,像素之间的关系作为图的边。通过最小化图中顶点之间的权重(如基于像素的颜色差异、纹理差异等),将图像分割为不同的区域。实现步骤: 构建图像的图表示。定义顶点和边的权重。使用图割算法(如最小割最大流算法)求解最优的分割方案。将分割结果映射回原图像。特点:图割方法能够处理具有复杂结构和相互重叠的物体图像,且对噪声和光照变化具有一定的鲁棒性。但该方法计算复杂度较高,且需要选择合适的图割算法和权重函数。 4、基于神经网络的分割方法 参考以下几篇文章: 基于神经网络的图像分割_基于图神经网络的医学图像分割-CSDN博客https://blog.csdn.net/weixin_55073640/article/details/123039854基于CNN卷积神经网络的图像分割matlab仿真 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/648715632基于深度学习技术的图像分割 (baidu.com)https://baijiahao.baidu.com/s?id=1783952474192487844&wfr=spider&for=pc 5、基于聚类的分割方法 3个要点: ①选定某种距离度量作为样本间的相似性度量; ②确定某个评价聚类结果质量的准则函数; ③给定某个初始分类,然后通过迭代算法找出使准则函数取得极值的最好聚类结果。 分类: 硬聚类算法模糊聚类算法可能性聚类算法 叄、OpenCV进行图像分割 1、固定阈值分割 API: retval, dst = cv2.threshold(src, thresh, maxval, type[, dst]) 前五个enum的数学实现原理: 示例: import cv2 import numpy as np # 读取图像 image = cv2.imread('image.jpg') # 转换为灰度图 gray = cv2.cvtColor(image, cv2.