易语言核心自动化场景实战:办公、测试、数据抓取与基础游戏脚本开发

易语言核心自动化场景实战:办公、测试、数据抓取与基础游戏脚本开发

十一、易语言核心自动化场景实战:办公、测试、数据抓取与基础游戏脚本开发

在这里插入图片描述

11.1 引言

💡 自动化是易语言最受欢迎、应用最广泛的核心场景之一!很多人学习易语言的直接动力,就是为了解放双手,提高工作效率——比如批量处理Excel报表、自动登录办公系统、定时发送邮件、自动抓取网页数据,甚至为自己喜欢的单机/绿色窗口游戏写简单的挂机脚本。

前10篇我们已经掌握了易语言的基础语法、组件库、网络通信、数据库操作、多线程优化和高级底层编程,这些都是自动化开发的技术基础。本章将重点讲解四大高频自动化场景的全流程实战开发,帮助大家将所学知识应用到实际工作和生活中。

11.1.1 学习目标

  • 掌握Windows GUI自动化的核心原理(窗口句柄查找、控件操作、消息发送)
  • 学会使用精易模块大漠插件实现自动化操作
  • 完成办公自动化实战(批量生成工资条、自动发送会议通知邮件)
  • 完成网页数据抓取自动化实战(自动抓取天气数据、自动抓取招聘网站职位信息)
  • 完成基础游戏脚本开发实战⚠️仅用于学习,严禁开发/传播违法违规的游戏外挂
  • 掌握自动化项目的通用开发流程,形成自动化开发思维

11.1.2 学习重点

  • 窗口句柄、控件类名、控件ID的获取方法(使用Spy++或精易编程助手)
  • 精易模块和大漠插件的安装与配置
  • Windows API和OLE自动化的使用方法
  • 图像识别和键盘鼠标模拟的实现
  • 自动化项目的测试、优化和打包方法

11.2 自动化开发核心技术基础

11.2.1 Windows GUI自动化原理

Windows GUI自动化的核心是**“识别目标控件,发送操作消息”。每个Windows窗口和控件都有唯一的窗口句柄(HWND),我们可以通过类名(ClassName)、标题(Caption)、控件ID(ControlID)等信息找到目标控件的句柄,然后通过SendMessage或PostMessage**函数发送操作消息(如点击、输入文本)。

获取窗口/控件信息的工具
  1. 精易编程助手:易语言社区开发的免费工具,功能强大,操作简单(推荐)
  2. Spy++:Visual Studio自带的工具,功能专业,但操作复杂
  3. WinSpy:轻量级的免费工具,适合简单场景

使用精易编程助手获取窗口/控件信息的步骤:
① 打开精易编程助手,点击“窗口信息”选项卡
② 点击“句柄探测”按钮,将十字准星拖到目标窗口/控件上
③ 精易编程助手会自动显示目标窗口/控件的句柄、类名、标题、控件ID等信息

11.2.2 精易模块自动化操作函数

精易模块提供了大量的Windows GUI自动化操作函数,如:

  • 窗口_取句柄:根据类名和标题获取窗口句柄
  • 窗口_发送消息:向目标窗口/控件发送消息
  • 窗口_文本输入:向目标编辑框发送文本
  • 窗口_点击:向目标按钮发送点击消息
  • 键盘_模拟输入:模拟键盘输入
  • 鼠标_模拟点击:模拟鼠标点击

11.2.3 大漠插件自动化操作函数

大漠插件(dm.dll)是易语言社区最受欢迎的第三方自动化插件,功能强大,支持图像识别文字识别键盘鼠标模拟窗口操作内存操作等。

大漠插件的安装与配置

① 下载最新版本的大漠插件(https://dm.dmoe.cc/)
② 解压后,将dm.dll文件复制到易语言程序的目录下
③ 打开易语言,点击“工具→支持库配置→全部支持库”,找到“精易模块”并勾选(精易模块封装了大漠插件的常用函数)
④ 在代码中使用dm.创建 ()函数初始化大漠插件

11.3 办公自动化实战

11.3.1 实战一:批量生成工资条

需求分析

每个月财务人员都需要为公司员工批量生成工资条,传统的方法是手动复制粘贴,效率低下且容易出错。我们可以开发一个自动化程序,从Excel工资表中读取员工信息和工资数据,自动生成每个员工的工资条,并保存为PDF文件。

核心技术
  • OLE自动化:通过Word的COM接口操作Word文档
  • Excel支持库:读取Excel工资表中的数据
  • PDF支持库:将Word文档转换为PDF文件
代码实现
.版本 2 .支持库 spec .支持库 eExcel .支持库 eWord .支持库 ePDF .程序集 程序集1 .程序集变量 g_Excel对象, 类_Excel应用程序 .程序集变量 g_Word对象, 类_Word应用程序 .子程序 __启动窗口_创建完毕 ' 初始化组件属性 _启动窗口.标题 = “批量生成工资条” _启动窗口.宽度 = 600 _启动窗口.高度 = 400 _启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2 _启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2 ' 初始化Excel和Word对象 g_Excel对象.创建 () g_Word对象.创建 () 调试输出 (“Excel和Word对象初始化成功!”) .子程序 _btnSelectExcel_被单击 .局部变量 文件名, 文本型 ' 选择Excel工资表 文件名 = 文件_打开 (“请选择Excel工资表”, “Excel文件 (*.xlsx;*.xls)|*.xlsx;*.xls”, , ) .如果真 (文件名 = “”) 返回 () .如果真结束 txtExcelPath.内容 = 文件名 调试输出 (“已选择Excel工资表:”, 文件名) .子程序 _btnSelectSavePath_被单击 .局部变量 文件夹, 文本型 ' 选择保存路径 文件夹 = 文件夹_选择 (“请选择保存路径”, ) .如果真 (文件夹 = “”) 返回 () .如果真结束 txtSavePath.内容 = 文件夹 调试输出 (“已选择保存路径:”, 文件夹) .子程序 _btnGenerate_被单击 .局部变量 工资表, 类_工作簿 .局部变量 工作表, 类_工作表 .局部变量 员工数, 整数型 .局部变量 i, 整数型 .局部变量 员工姓名, 文本型 .局部变量 基本工资, 双精度型 .局部变量 奖金, 双精度型 .局部变量 津贴, 双精度型 .局部变量 扣款, 双精度型 .局部变量 总工资, 双精度型 .局部变量 Word文档, 类_文档 .局部变量 段落, 类_段落 .局部变量 表格, 类_表格 .局部变量 单元格, 类_单元格 .局部变量 PDF文件名, 文本型 ' 检查输入是否为空 .如果真 (txtExcelPath.内容 = “”) 信息框 (“请选择Excel工资表!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txtSavePath.内容 = “”) 信息框 (“请选择保存路径!”, 0, “错误提示”) 返回 () .如果真结束 ' 打开Excel工资表 工资表 = g_Excel对象.工作簿_打开 (txtExcelPath.内容) 工作表 = 工资表.工作表_取当前 () ' 获取员工数 员工数 = 工作表.单元格_取列尾行号 (1, 2) - 1 ' 第1行为表头,第2行开始是员工数据 ' 生成每个员工的工资条 .计次循环首 (员工数, i) ' 读取员工信息和工资数据 员工姓名 = 工作表.单元格_读文本 (1 + i, 1) 基本工资 = 工作表.单元格_读数值 (1 + i, 2) 奖金 = 工作表.单元格_读数值 (1 + i, 3) 津贴 = 工作表.单元格_读数值 (1 + i, 4) 扣款 = 工作表.单元格_读数值 (1 + i, 5) 总工资 = 基本工资 + 奖金 + 津贴 - 扣款 ' 创建Word文档 Word文档 = g_Word对象.文档_新建 () ' 插入标题 段落 = Word文档.段落_添加 () 段落.文本 = “工资条” 段落.对齐方式 = #居中对齐 段落.字体.大小 = 18 段落.字体.加粗 = #真 ' 插入员工姓名 段落 = Word文档.段落_添加 () 段落.文本 = “员工姓名:” + 员工姓名 段落.对齐方式 = #左对齐 段落.字体.大小 = 12 段落.字体.加粗 = #假 ' 插入工资表格 表格 = Word文档.表格_添加 (Word文档.内容_末尾, 5, 2) 表格.边框.设置 (1, #黑色, 1) ' 填充表格数据 表格.单元格_读 (1, 1).文本 = “基本工资” 表格.单元格_读 (1, 2).文本 = 到文本 (基本工资, “0.00”) 表格.单元格_读 (2, 1).文本 = “奖金” 表格.单元格_读 (2, 2).文本 = 到文本 (奖金, “0.00”) 表格.单元格_读 (3, 1).文本 = “津贴” 表格.单元格_读 (3, 2).文本 = 到文本 (津贴, “0.00”) 表格.单元格_读 (4, 1).文本 = “扣款” 表格.单元格_读 (4, 2).文本 = 到文本 (扣款, “0.00”) 表格.单元格_读 (5, 1).文本 = “总工资” 表格.单元格_读 (5, 2).文本 = 到文本 (总工资, “0.00”) ' 保存为PDF文件 PDF文件名 = txtSavePath.内容 + “\” + 员工姓名 + “_工资条.pdf” Word文档.保存为PDF (PDF文件名) ' 关闭Word文档 Word文档.关闭 (False) ' 更新进度条 pbrProgress.位置 = i ÷ 员工数 × 100 .计次循环首 () ' 关闭Excel工资表 工资表.关闭 (False) ' 更新进度条 pbrProgress.位置 = 100 ' 提示生成成功 信息框 (“工资条生成成功!共生成” + 到文本 (员工数) + “个工资条。”, 0, “成功提示”) 调试输出 (“工资条生成成功!共生成” + 到文本 (员工数) + “个工资条。”) .子程序 __启动窗口_将被销毁 ' 关闭Excel和Word对象 g_Excel对象.关闭 () g_Word对象.关闭 () 调试输出 (“Excel和Word对象关闭成功!”) 

11.3.2 实战二:自动发送会议通知邮件

需求分析

公司每周一上午需要召开部门例会,传统的方法是手动发送会议通知邮件,效率低下且容易遗漏。我们可以开发一个自动化程序,从Excel员工表中读取员工的邮箱地址,自动发送会议通知邮件。

核心技术
  • 邮件发送:使用精易模块的邮件发送函数
  • Excel支持库:读取Excel员工表中的邮箱地址
  • 配置文件:保存邮件服务器参数和邮件内容
代码实现
.版本 2 .支持库 spec .支持库 eExcel .支持库 eJYM .程序集 程序集1 .程序集变量 g_Excel对象, 类_Excel应用程序 .子程序 __启动窗口_创建完毕 ' 初始化组件属性 _启动窗口.标题 = “自动发送会议通知邮件” _启动窗口.宽度 = 600 _启动窗口.高度 = 500 _启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2 _启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2 ' 初始化Excel对象 g_Excel对象.创建 () ' 从配置文件中读取邮件服务器参数 txtSMTP服务器.内容 = 配置文件_取文本 (“Email”, “SMTP服务器”, “smtp.qq.com”) txtSMTP端口.内容 = 配置文件_取文本 (“Email”, “SMTP端口”, “587”) txt发件人邮箱.内容 = 配置文件_取文本 (“Email”, “发件人邮箱”, “”) txt发件人密码.内容 = 配置文件_取文本 (“Email”, “发件人密码”, “”) txt邮件主题.内容 = 配置文件_取文本 (“Email”, “邮件主题”, “部门例会通知”) edt邮件内容.内容 = 配置文件_取文本 (“Email”, “邮件内容”, “各位同事:您好!本周一上午9:00将在会议室召开部门例会,请准时参加。谢谢!”) 调试输出 (“Excel对象初始化成功!邮件服务器参数读取成功!”) .子程序 _btnSelectExcel_被单击 .局部变量 文件名, 文本型 ' 选择Excel员工表 文件名 = 文件_打开 (“请选择Excel员工表”, “Excel文件 (*.xlsx;*.xls)|*.xlsx;*.xls”, , ) .如果真 (文件名 = “”) 返回 () .如果真结束 txtExcelPath.内容 = 文件名 调试输出 (“已选择Excel员工表:”, 文件名) .子程序 _btnSendEmail_被单击 .局部变量 员工表, 类_工作簿 .局部变量 工作表, 类_工作表 .局部变量 员工数, 整数型 .局部变量 i, 整数型 .局部变量 员工姓名, 文本型 .局部变量 员工邮箱, 文本型 .局部变量 邮件发送结果, 文本型 ' 检查输入是否为空 .如果真 (txtExcelPath.内容 = “”) 信息框 (“请选择Excel员工表!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txtSMTP服务器.内容 = “”) 信息框 (“请输入SMTP服务器地址!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txtSMTP端口.内容 = “”) 信息框 (“请输入SMTP端口!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txt发件人邮箱.内容 = “”) 信息框 (“请输入发件人邮箱地址!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txt发件人密码.内容 = “”) 信息框 (“请输入发件人密码!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (txt邮件主题.内容 = “”) 信息框 (“请输入邮件主题!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (edt邮件内容.内容 = “”) 信息框 (“请输入邮件内容!”, 0, “错误提示”) 返回 () .如果真结束 ' 打开Excel员工表 员工表 = g_Excel对象.工作簿_打开 (txtExcelPath.内容) 工作表 = 员工表.工作表_取当前 () ' 获取员工数 员工数 = 工作表.单元格_取列尾行号 (1, 2) - 1 ' 第1行为表头,第2行开始是员工数据 ' 发送会议通知邮件 .计次循环首 (员工数, i) ' 读取员工信息 员工姓名 = 工作表.单元格_读文本 (1 + i, 1) 员工邮箱 = 工作表.单元格_读文本 (1 + i, 2) ' 发送邮件 邮件发送结果 = 邮件_发送 (txtSMTP服务器.内容, 到数值 (txtSMTP端口.内容), txt发件人邮箱.内容, txt发件人密码.内容, 员工邮箱, txt邮件主题.内容, edt邮件内容.内容, , , , ) ' 记录发送结果 lstSendResult.插入表项 (, ) lstSendResult.置标题 (lstSendResult.取表项数 () - 1, 0, 员工姓名) lstSendResult.置标题 (lstSendResult.取表项数 () - 1, 1, 员工邮箱) lstSendResult.置标题 (lstSendResult.取表项数 () - 1, 2, 邮件发送结果) ' 更新进度条 pbrProgress.位置 = i ÷ 员工数 × 100 .计次循环首 () ' 关闭Excel员工表 员工表.关闭 (False) ' 更新进度条 pbrProgress.位置 = 100 ' 提示发送成功 信息框 (“会议通知邮件发送成功!共发送” + 到文本 (员工数) + “封邮件。”, 0, “成功提示”) 调试输出 (“会议通知邮件发送成功!共发送” + 到文本 (员工数) + “封邮件。”) .子程序 _btnSaveConfig_被单击 ' 保存邮件服务器参数和邮件内容到配置文件 配置文件_写文本 (“Email”, “SMTP服务器”, txtSMTP服务器.内容) 配置文件_写文本 (“Email”, “SMTP端口”, txtSMTP端口.内容) 配置文件_写文本 (“Email”, “发件人邮箱”, txt发件人邮箱.内容) 配置文件_写文本 (“Email”, “发件人密码”, txt发件人密码.内容) 配置文件_写文本 (“Email”, “邮件主题”, txt邮件主题.内容) 配置文件_写文本 (“Email”, “邮件内容”, edt邮件内容.内容) 信息框 (“配置保存成功!”, 0, “成功提示”) 调试输出 (“配置保存成功!”) .子程序 __启动窗口_将被销毁 ' 关闭Excel对象 g_Excel对象.关闭 () 调试输出 (“Excel对象关闭成功!”) 

11.4 网页数据抓取自动化实战

11.4.1 实战一:自动抓取天气数据并写入Excel

需求分析

每天需要查看多个城市的天气数据,传统的方法是手动打开天气网站查看,效率低下且容易出错。我们可以开发一个自动化程序,自动抓取指定城市的天气数据,并写入Excel表格中。

核心技术
  • WebBrowser组件:加载天气网站
  • HTML解析:使用精易模块的HTML解析函数
  • Excel支持库:将天气数据写入Excel表格
代码实现
.版本 2 .支持库 spec .支持库 eExcel .支持库 eWebBrowser .支持库 eJYM .程序集 程序集1 .程序集变量 g_Excel对象, 类_Excel应用程序 .程序集变量 g_WebBrowser, 类_WebBrowser .子程序 __启动窗口_创建完毕 ' 初始化组件属性 _启动窗口.标题 = “自动抓取天气数据” _启动窗口.宽度 = 800 _启动窗口.高度 = 600 _启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2 _启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2 ' 初始化Excel和WebBrowser对象 g_Excel对象.创建 () g_WebBrowser.创建 () g_WebBrowser.组件_置窗口 (_启动窗口.hwnd) g_WebBrowser.组件_置位置 (0, 0, _启动窗口.宽度, _启动窗口.高度) ' 从配置文件中读取城市列表 读取城市列表 () 调试输出 (“Excel和WebBrowser对象初始化成功!城市列表读取成功!”) .子程序 读取城市列表 .局部变量 城市数组, 文本型, 动态数组 .局部变量 i, 整数型 ' 从配置文件中读取城市列表(格式:北京,上海,广州,深圳) 城市数组 = 分割文本 (配置文件_取文本 (“Weather”, “城市列表”, “北京,上海,广州,深圳”), “,”, ) ' 将城市列表添加到组合框中 .计次循环首 (取数组成员数 (城市数组), i) cboCity.加入项目 (城市数组 [i - 1]) .计次循环首 () ' 默认选中第一个城市 cboCity.现行选中项 = 0 .子程序 _btnCrawlWeather_被单击 .局部变量 城市名, 文本型 .局部变量 天气网站地址, 文本型 .局部变量 HTML内容, 文本型 .局部变量 天气数据, 文本型, 动态数组 .局部变量 温度, 文本型 .局部变量 天气, 文本型 .局部变量 风向, 文本型 .局部变量 风力, 文本型 .局部变量 湿度, 文本型 .局部变量 气压, 文本型 .局部变量 能见度, 文本型 .局部变量 降水量, 文本型 .局部变量 Excel工作簿, 类_工作簿 .局部变量 Excel工作表, 类_工作表 ' 获取选中的城市名 城市名 = cboCity.取项目文本 (cboCity.现行选中项) ' 构建天气网站地址(使用中国天气网的API) 天气网站地址 = “http://www.weather.com.cn/weather/” + 获取城市代码 (城市名) + “.shtml” ' 加载天气网站 g_WebBrowser.导航 (天气网站地址) ' 等待网站加载完成 .循环判断首 () 处理事件 () .循环判断尾 (g_WebBrowser.是否繁忙 () 或 g_WebBrowser.是否正在导航 () ) ' 读取HTML内容 HTML内容 = g_WebBrowser.取文档HTML () ' 解析HTML内容,获取天气数据 温度 = 正则表达式_匹配 (HTML内容, “<span class=““temp”“>(.*?)°C</span>”, 1, ) 天气 = 正则表达式_匹配 (HTML内容, “<span class=““wea”“>(.*?)</span>”, 1, ) 风向 = 正则表达式_匹配 (HTML内容, “<span class=““win”“><span class=““wind_dir”“>(.*?)</span><span class=““wind_level”“>(.*?)</span></span>”, 1, ) 风力 = 正则表达式_匹配 (HTML内容, “<span class=““win”“><span class=““wind_dir”“>(.*?)</span><span class=““wind_level”“>(.*?)</span></span>”, 2, ) 湿度 = 正则表达式_匹配 (HTML内容, “<span class=““hum”“>(.*?)%</span>”, 1, ) 气压 = 正则表达式_匹配 (HTML内容, “<span class=““air”“>(.*?)hPa</span>”, 1, ) 能见度 = 正则表达式_匹配 (HTML内容, “<span class=““vis”“>(.*?)km</span>”, 1, ) 降水量 = 正则表达式_匹配 (HTML内容, “<span class=““pre”“>(.*?)mm</span>”, 1, ) ' 显示天气数据 lbl温度.标题 = “温度:” + 温度 + “°C” lbl天气.标题 = “天气:” + 天气 lbl风向.标题 = “风向:” + 风向 lbl风力.标题 = “风力:” + 风力 lbl湿度.标题 = “湿度:” + 湿度 + “%” lbl气压.标题 = “气压:” + 气压 + “hPa” lbl能见度.标题 = “能见度:” + 能见度 + “km” lbl降水量.标题 = “降水量:” + 降水量 + “mm” ' 将天气数据写入Excel表格 Excel工作簿 = g_Excel对象.工作簿_新建 () Excel工作表 = Excel工作簿.工作表_取当前 () ' 写入表头 Excel工作表.单元格_写文本 (1, 1, “城市名”) Excel工作表.单元格_写文本 (1, 2, “温度”) Excel工作表.单元格_写文本 (1, 3, “天气”) Excel工作表.单元格_写文本 (1, 4, “风向”) Excel工作表.单元格_写文本 (1, 5, “风力”) Excel工作表.单元格_写文本 (1, 6, “湿度”) Excel工作表.单元格_写文本 (1, 7, “气压”) Excel工作表.单元格_写文本 (1, 8, “能见度”) Excel工作表.单元格_写文本 (1, 9, “降水量”) Excel工作表.单元格_写文本 (1, 10, “抓取时间”) ' 写入天气数据 Excel工作表.单元格_写文本 (2, 1, 城市名) Excel工作表.单元格_写文本 (2, 2, 温度 + “°C”) Excel工作表.单元格_写文本 (2, 3, 天气) Excel工作表.单元格_写文本 (2, 4, 风向) Excel工作表.单元格_写文本 (2, 5, 风力) Excel工作表.单元格_写文本 (2, 6, 湿度 + “%”) Excel工作表.单元格_写文本 (2, 7, 气压 + “hPa”) Excel工作表.单元格_写文本 (2, 8, 能见度 + “km”) Excel工作表.单元格_写文本 (2, 9, 降水量 + “mm”) Excel工作表.单元格_写文本 (2, 10, 到文本 (取现行时间 (), , “yyyy-MM-dd HH:mm:ss”)) ' 保存Excel工作簿 Excel工作簿.保存As (取运行目录 () + “\” + 城市名 + “_天气数据_” + 到文本 (取现行时间 (), , “yyyyMMddHHmmss”) + “.xlsx”) Excel工作簿.关闭 (False) ' 提示抓取成功 信息框 (“天气数据抓取成功!已保存到” + 取运行目录 () + “\” + 城市名 + “_天气数据_” + 到文本 (取现行时间 (), , “yyyyMMddHHmmss”) + “.xlsx”, 0, “成功提示”) 调试输出 (“天气数据抓取成功!城市:”, 城市名, “ 温度:”, 温度, “ 天气:”, 天气) .子程序 获取城市代码, 文本型 .参数 城市名, 文本型 .局部变量 城市代码表, 文本型, 动态数组 .局部变量 城市信息, 文本型, 动态数组 .局部变量 i, 整数型 ' 城市代码表(格式:城市名|城市代码) 城市代码表 = {“北京|101010100”, “上海|101020100”, “广州|101280101”, “深圳|101280601”, “杭州|101210101”, “南京|101190101”, “成都|101270101”, “重庆|101040100”, “武汉|101200101”, “西安|101110101”} ' 查找城市代码 .计次循环首 (取数组成员数 (城市代码表), i) 城市信息 = 分割文本 (城市代码表 [i - 1], “|”, ) .如果真 (城市信息 [0] = 城市名) 返回 (城市信息 [1]) .如果真结束 .计次循环首 () ' 如果未找到城市代码,默认返回北京的城市代码 返回 (“101010100”) .子程序 正则表达式_匹配, 文本型 .参数 原文本, 文本型 .参数 正则表达式, 文本型 .参数 匹配组索引, 整数型 .局部变量 正则对象, 正则表达式 .局部变量 匹配集合, 正则表达式匹配 .局部变量 匹配结果, 文本型 ' 初始化正则对象 正则对象.创建 (正则表达式, ) ' 匹配文本 匹配集合 = 正则对象.匹配 (原文本) ' 获取匹配结果 .如果真 (匹配集合.数量 > 0) 匹配结果 = 匹配集合.取子匹配文本 (0, 匹配组索引) .如果真结束 ' 释放资源 正则对象.销毁 () 匹配集合.销毁 () 返回 (匹配结果) .子程序 __启动窗口_将被销毁 ' 关闭Excel和WebBrowser对象 g_Excel对象.关闭 () g_WebBrowser.销毁 () 调试输出 (“Excel和WebBrowser对象关闭成功!”) 

11.4.2 实战二:自动抓取招聘网站的职位信息

需求分析

找工作时需要查看多个招聘网站的职位信息,传统的方法是手动打开招聘网站搜索,效率低下且容易遗漏。我们可以开发一个自动化程序,自动抓取指定招聘网站的职位信息,并写入Excel表格中。

核心技术
  • HTTP访问:使用精易模块的HTTP访问函数
  • HTML解析:使用精易模块的HTML解析函数
  • Excel支持库:将职位信息写入Excel表格
代码实现
.版本 2 .支持库 spec .支持库 eExcel .支持库 eJYM .程序集 程序集1 .程序集变量 g_Excel对象, 类_Excel应用程序 .子程序 __启动窗口_创建完毕 ' 初始化组件属性 _启动窗口.标题 = “自动抓取招聘网站职位信息” _启动窗口.宽度 = 800 _启动窗口.高度 = 600 _启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2 _启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2 ' 初始化Excel对象 g_Excel对象.创建 () ' 从配置文件中读取招聘网站信息 读取招聘网站信息 () 调试输出 (“Excel对象初始化成功!招聘网站信息读取成功!”) .子程序 读取招聘网站信息 .局部变量 招聘网站数组, 文本型, 动态数组 .局部变量 i, 整数型 ' 从配置文件中读取招聘网站信息(格式:网站名称|搜索地址) 招聘网站数组 = 分割文本 (配置文件_取文本 (“Recruitment”, “招聘网站”, “前程无忧|https://search.51job.com/list/000000,000000,0000,00,9,99,易语言,2,1.html;智联招聘|https://sou.zhaopin.com/jobs/searchresult.ashx?jl=000000&kw=易语言&sm=0&p=1”), “;”, ) ' 将招聘网站信息添加到组合框中 .计次循环首 (取数组成员数 (招聘网站数组), i) cboWebsite.加入项目 (分割文本 (招聘网站数组 [i - 1], “|”, ) [0]) .计次循环首 () ' 默认选中第一个招聘网站 cboWebsite.现行选中项 = 0 .子程序 _btnCrawlJobs_被单击 .局部变量 招聘网站信息, 文本型, 动态数组 .局部变量 搜索地址, 文本型 .局部变量 关键词, 文本型 .局部变量 页码数, 整数型 .局部变量 i, 整数型 .局部变量 HTTP响应, 文本型 .局部变量 职位信息数组, 文本型, 动态数组 .局部变量 Excel工作簿, 类_工作簿 .局部变量 Excel工作表, 类_工作表 .局部变量 行号, 整数型 ' 获取选中的招聘网站信息和搜索参数 招聘网站信息 = 分割文本 (配置文件_取文本 (“Recruitment”, “招聘网站”, “前程无忧|https://search.51job.com/list/000000,000000,0000,00,9,99,易语言,2,1.html;智联招聘|https://sou.zhaopin.com/jobs/searchresult.ashx?jl=000000&kw=易语言&sm=0&p=1”), “;”, ) 搜索地址 = 分割文本 (招聘网站信息 [cboWebsite.现行选中项], “|”, ) [1] 关键词 = txtKeyword.内容 页码数 = 到数值 (txtPageCount.内容) ' 检查输入是否为空 .如果真 (关键词 = “”) 信息框 (“请输入搜索关键词!”, 0, “错误提示”) 返回 () .如果真结束 .如果真 (页码数 ≤ 0) 信息框 (“请输入大于0的页码数!”, 0, “错误提示”) 返回 () .如果真结束 ' 创建Excel工作簿 Excel工作簿 = g_Excel对象.工作簿_新建 () Excel工作表 = Excel工作簿.工作表_取当前 () ' 写入表头 Excel工作表.单元格_写文本 (1, 1, “职位名称”) Excel工作表.单元格_写文本 (1, 2, “公司名称”) Excel工作表.单元格_写文本 (1, 3, “工作地点”) Excel工作表.单元格_写文本 (1, 4, “薪资范围”) Excel工作表.单元格_写文本 (1, 5, “工作经验”) Excel工作表.单元格_写文本 (1, 6, “学历要求”) Excel工作表.单元格_写文本 (1, 7, “发布时间”) Excel工作表.单元格_写文本 (1, 8, “职位链接”) 行号 = 2 ' 抓取职位信息 .计次循环首 (页码数, i) ' 构建搜索地址(替换关键词和页码) 搜索地址 = 子文本替换 (搜索地址, “易语言”, 关键词, , , 真) 搜索地址 = 子文本替换 (搜索地址, “p=1”, “p=” + 到文本 (i), , , 真) ' 发送HTTP请求 HTTP响应 = 网页_访问 (搜索地址, , , , , , , , ) ' 解析HTTP响应,获取职位信息数组 .判断开始 (cboWebsite.取项目文本 (cboWebsite.现行选中项) = “前程无忧”) 职位信息数组 = 解析前程无忧职位信息 (HTTP响应) .判断 (cboWebsite.取项目文本 (cboWebsite.现行选中项) = “智联招聘”) 职位信息数组 = 解析智联招聘职位信息 (HTTP响应) .默认 信息框 (“不支持该招聘网站的解析!”, 0, “错误提示”) 返回 () .判断结束 ' 将职位信息写入Excel表格 .计次循环首 (取数组成员数 (职位信息数组), i) Excel工作表.单元格_写文本 (行号, 1, 分割文本 (职位信息数组 [i - 1], “|”, ) [0]) ' 职位名称 Excel工作表.单元格_写文本 (行号, 2, 分割文本 (职位信息数组 [i - 1], “|”, ) [1]) ' 公司名称 Excel工作表.单元格_写文本 (行号, 3, 分割文本 (职位信息数组 [i - 1], “|”, ) [2]) ' 工作地点 Excel工作表.单元格_写文本 (行号, 4, 分割文本 (职位信息数组 [i - 1], “|”, ) [3]) ' 薪资范围 Excel工作表.单元格_写文本 (行号, 5, 分割文本 (职位信息数组 [i - 1], “|”, ) [4]) ' 工作经验 Excel工作表.单元格_写文本 (行号, 6, 分割文本 (职位信息数组 [i - 1], “|”, ) [5]) ' 学历要求 Excel工作表.单元格_写文本 (行号, 7, 分割文本 (职位信息数组 [i - 1], “|”, ) [6]) ' 发布时间 Excel工作表.单元格_写文本 (行号, 8, 分割文本 (职位信息数组 [i - 1], “|”, ) [7]) ' 职位链接 行号 = 行号 + 1 .计次循环首 () ' 更新进度条 pbrProgress.位置 = i ÷ 页码数 × 100 .计次循环首 () ' 保存Excel工作簿 Excel工作簿.保存As (取运行目录 () + “\” + 关键词 + “_职位信息_” + 到文本 (取现行时间 (), , “yyyyMMddHHmmss”) + “.xlsx”) Excel工作簿.关闭 (False) ' 更新进度条 pbrProgress.位置 = 100 ' 提示抓取成功 信息框 (“职位信息抓取成功!共抓取” + 到文本 (行号 - 2) + “个职位信息。已保存到” + 取运行目录 () + “\” + 关键词 + “_职位信息_” + 到文本 (取现行时间 (), , “yyyyMMddHHmmss”) + “.xlsx”, 0, “成功提示”) 调试输出 (“职位信息抓取成功!关键词:”, 关键词, “ 数量:”, 行号 - 2) .子程序 解析前程无忧职位信息, 文本型, 数组 .参数 HTTP响应, 文本型 .局部变量 职位信息数组, 文本型, 动态数组 .局部变量 职位列表HTML, 文本型 .局部变量 职位项HTML数组, 文本型, 动态数组 .局部变量 i, 整数型 .局部变量 职位项HTML, 文本型 .局部变量 职位名称, 文本型 .局部变量 公司名称, 文本型 .局部变量 工作地点, 文本型 .局部变量 薪资范围, 文本型 .局部变量 工作经验, 文本型 .局部变量 学历要求, 文本型 .局部变量 发布时间, 文本型 .局部变量 职位链接, 文本型 ' 提取职位列表HTML 职位列表HTML = 正则表达式_匹配 (HTTP响应, “<div class=““j_joblist”“>(.*?)</div>”, 1, ) ' 提取职位项HTML数组 职位项HTML数组 = 分割文本 (正则表达式_匹配 (职位列表HTML, “<div class=““j_joblist_job”“>(.*?)</div>”, , ), “<div class=““j_joblist_job”“>”, ) ' 解析每个职位项HTML .计次循环首 (取数组成员数 (职位项HTML数组), i) 职位项HTML = 职位项HTML数组 [i - 1] .如果真 (取文本长度 (职位项HTML) < 100) 继续循环 () .如果真结束 ' 提取职位信息 职位名称 = 正则表达式_匹配 (职位项HTML, “<a class=““j_jobname”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 2, ) 职位链接 = 正则表达式_匹配 (职位项HTML, “<a class=““j_jobname”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 1, ) 公司名称 = 正则表达式_匹配 (职位项HTML, “<a class=““j_corname”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 2, ) 工作地点 = 正则表达式_匹配 (职位项HTML, “<span class=““j_position”“>(.*?)</span>”, 1, ) 薪资范围 = 正则表达式_匹配 (职位项HTML, “<span class=““j_salary”“>(.*?)</span>”, 1, ) 工作经验 = 正则表达式_匹配 (职位项HTML, “<span class=““j_experience”“>(.*?)</span>”, 1, ) 学历要求 = 正则表达式_匹配 (职位项HTML, “<span class=““j_education”“>(.*?)</span>”, 1, ) 发布时间 = 正则表达式_匹配 (职位项HTML, “<span class=““j_date”“>(.*?)</span>”, 1, ) ' 将职位信息添加到数组中 加入成员 (职位信息数组, 职位名称 + “|” + 公司名称 + “|” + 工作地点 + “|” + 薪资范围 + “|” + 工作经验 + “|” + 学历要求 + “|” + 发布时间 + “|” + 职位链接) .计次循环首 () 返回 (职位信息数组) .子程序 解析智联招聘职位信息, 文本型, 数组 .参数 HTTP响应, 文本型 .局部变量 职位信息数组, 文本型, 动态数组 .局部变量 职位列表HTML, 文本型 .局部变量 职位项HTML数组, 文本型, 动态数组 .局部变量 i, 整数型 .局部变量 职位项HTML, 文本型 .局部变量 职位名称, 文本型 .局部变量 公司名称, 文本型 .局部变量 工作地点, 文本型 .局部变量 薪资范围, 文本型 .局部变量 工作经验, 文本型 .局部变量 学历要求, 文本型 .局部变量 发布时间, 文本型 .局部变量 职位链接, 文本型 ' 提取职位列表HTML 职位列表HTML = 正则表达式_匹配 (HTTP响应, “<div class=““contentpile__content”“>(.*?)</div>”, 1, ) ' 提取职位项HTML数组 职位项HTML数组 = 分割文本 (正则表达式_匹配 (职位列表HTML, “<div class=““contentpile__content__item”“>(.*?)</div>”, , ), “<div class=““contentpile__content__item”“>”, ) ' 解析每个职位项HTML .计次循环首 (取数组成员数 (职位项HTML数组), i) 职位项HTML = 职位项HTML数组 [i - 1] .如果真 (取文本长度 (职位项HTML) < 100) 继续循环 () .如果真结束 ' 提取职位信息 职位名称 = 正则表达式_匹配 (职位项HTML, “<a class=““contentpile__content__item__info__box__jobname__title”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 2, ) 职位链接 = 正则表达式_匹配 (职位项HTML, “<a class=““contentpile__content__item__info__box__jobname__title”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 1, ) 公司名称 = 正则表达式_匹配 (职位项HTML, “<a class=““contentpile__content__item__info__box__cname__title”“ href=““(.*?)”“ target=““_blank”“>(.*?)</a>”, 2, ) 工作地点 = 正则表达式_匹配 (职位项HTML, “<span class=““contentpile__content__item__info__box__job__demand__item”“>(.*?)</span>”, 1, ) 薪资范围 = 正则表达式_匹配 (职位项HTML, “<span class=““contentpile__content__item__info__box__job__saray”“>(.*?)</span>”, 1, ) 工作经验 = 正则表达式_匹配 (职位项HTML, “<span class=““contentpile__content__item__info__box__job__demand__item”“>(.*?)</span>”, 2, ) 学历要求 = 正则表达式_匹配 (职位项HTML, “<span class=““contentpile__content__item__info__box__job__demand__item”“>(.*?)</span>”, 3, ) 发布时间 = 正则表达式_匹配 (职位项HTML, “<span class=““contentpile__content__item__info__box__job__uptime”“>(.*?)</span>”, 1, ) ' 将职位信息添加到数组中 加入成员 (职位信息数组, 职位名称 + “|” + 公司名称 + “|” + 工作地点 + “|” + 薪资范围 + “|” + 工作经验 + “|” + 学历要求 + “|” + 发布时间 + “|” + 职位链接) .计次循环首 () 返回 (职位信息数组) .子程序 正则表达式_匹配, 文本型, 数组, 公开 .参数 原文本, 文本型 .参数 正则表达式, 文本型 .参数 匹配组索引, 整数型 .参数 是否返回全部匹配, 逻辑型, 可空, 默认值为假 .局部变量 正则对象, 正则表达式 .局部变量 匹配集合, 正则表达式匹配 .局部变量 结果数组, 文本型, 动态数组 .局部变量 i, 整数型 ' 初始化正则对象 正则对象.创建 (正则表达式, ) ' 匹配文本 匹配集合 = 正则对象.匹配 (原文本) ' 提取匹配结果 .如果真 (是否返回全部匹配) .计次循环首 (匹配集合.数量, i) 加入成员 (结果数组, 匹配集合.取子匹配文本 (i - 1, 匹配组索引)) .计次循环首 () .如果真结束 .如果真 (是否返回全部匹配 = 假 且 匹配集合.数量 > 0) 加入成员 (结果数组, 匹配集合.取子匹配文本 (0, 匹配组索引)) .如果真结束 ' 释放资源 正则对象.销毁 () 匹配集合.销毁 () 返回 (结果数组) .子程序 __启动窗口_将被销毁 ' 关闭Excel对象 g_Excel对象.关闭 () 调试输出 (“Excel对象关闭成功!”) 

11.5 基础游戏脚本开发实战(⚠️仅用于学习)

11.5.1 实战:简单的窗口游戏挂机脚本

需求分析

有些单机/绿色窗口游戏需要长时间挂机,传统的方法是手动操作,效率低下且浪费时间。我们可以开发一个简单的自动化脚本,自动点击NPC、自动拾取物品。

⚠️ 重要提示:

  • 仅用于学习Windows GUI自动化和图像识别技术
  • 严禁开发/传播违法违规的游戏外挂
  • 尊重游戏开发商的版权和规则
  • 使用脚本可能会导致账号被封禁
核心技术
  • 图像识别:使用大漠插件的图像识别函数
  • 键盘鼠标模拟:使用精易模块的键盘鼠标模拟函数
  • 窗口操作:使用精易模块的窗口操作函数
代码实现
.版本 2 .支持库 spec .支持库 eJYM .程序集 程序集1 .程序集变量 g_大漠对象, 类_大漠插件 .程序集变量 g_游戏窗口句柄, 整数型 .程序集变量 g_是否继续挂机, 逻辑型 .子程序 __启动窗口_创建完毕 ' 初始化组件属性 _启动窗口.标题 = “简单的窗口游戏挂机脚本” _启动窗口.宽度 = 400 _启动窗口.高度 = 300 _启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2 _启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2 ' 初始化大漠对象 g_大漠对象.创建 () g_大漠对象.设置路径 (取运行目录 ()) ' 设置大漠插件的资源路径 ' 从配置文件中读取游戏窗口标题 txtGameTitle.内容 = 配置文件_取文本 (“Game”, “窗口标题”, “”) ' 初始化全局变量 g_是否继续挂机 = 假 调试输出 (“大漠对象初始化成功!”) .子程序 _btnFindGameWindow_被单击 ' 查找游戏窗口 g_游戏窗口句柄 = 窗口_取句柄 (txtGameTitle.内容, ) .如果真 (g_游戏窗口句柄 = 0) 信息框 (“未找到游戏窗口!”, 0, “错误提示”) 返回 () .如果真结束 ' 激活游戏窗口 窗口_激活 (g_游戏窗口句柄) ' 获取游戏窗口的截图 g_大漠对象.绑定窗口 (g_游戏窗口句柄, “normal”, “normal”, “normal”, 0) g_大漠对象.截图 (取运行目录 () + “\游戏窗口截图.bmp”) g_大漠对象.解绑窗口 () ' 显示截图 图片框1.图片 = 读入文件 (取运行目录 () + “\游戏窗口截图.bmp”) ' 启用开始和停止按钮 btnStart.禁止 = #假 btnStop.禁止 = #真 调试输出 (“已找到游戏窗口!句柄:”, g_游戏窗口句柄) .子程序 _btnStart_被单击 ' 开始挂机 g_是否继续挂机 = 真 btnStart.禁止 = #真 btnStop.禁止 = #假 ' 创建线程执行挂机任务 启动线程 (&挂机任务, , ) 调试输出 (“开始挂机!”) .子程序 挂机任务 .局部变量 怪物坐标, 整数型, 数组 .局部变量 物品坐标, 整数型, 数组 .局部变量 i, 整数型 ' 绑定游戏窗口 g_大漠对象.绑定窗口 (g_游戏窗口句柄, “normal”, “normal”, “normal”, 0) ' 循环执行挂机任务 .判断循环首 (g_是否继续挂机) ' 寻找怪物 怪物坐标 = g_大漠对象.找多图 (取运行目录 () + “\怪物模板.bmp”, 0.8, 0, 0, 800, 600) ' 如果找到怪物,攻击怪物 .如果真 (取数组成员数 (怪物坐标) > 0) ' 移动鼠标到怪物位置 鼠标_移动 (怪物坐标 [0], 怪物坐标 [1]) ' 点击鼠标左键攻击怪物 鼠标_点击 (#左键单击, ) ' 等待攻击动画完成 延迟 (1000) .如果真结束 ' 寻找物品 物品坐标 = g_大漠对象.找多图 (取运行目录 () + “\物品模板.bmp”, 0.8, 0, 0, 800, 600) ' 如果找到物品,拾取物品 .如果真 (取数组成员数 (物品坐标) > 0) ' 移动鼠标到物品位置 鼠标_移动 (物品坐标 [0], 物品坐标 [1]) ' 点击鼠标左键拾取物品 鼠标_点击 (#左键单击, ) ' 等待拾取动画完成 延迟 (500) .如果真结束 ' 等待一段时间后再次执行 延迟 (2000) .判断循环尾 () ' 解绑游戏窗口 g_大漠对象.解绑窗口 () 调试输出 (“停止挂机!”) .子程序 _btnStop_被单击 ' 停止挂机 g_是否继续挂机 = 假 btnStart.禁止 = #假 btnStop.禁止 = #真 .子程序 __启动窗口_将被销毁 ' 停止挂机 g_是否继续挂机 = 假 ' 销毁大漠对象 g_大漠对象.销毁 () 调试输出 (“程序结束!”) 

11.6 自动化项目的通用开发流程

11.6.1 需求分析

明确自动化项目的目标范围功能限制条件

  • 目标:自动化项目要解决什么问题?
  • 范围:自动化项目要覆盖哪些场景?
  • 功能:自动化项目要实现哪些具体功能?
  • 限制条件:自动化项目有哪些时间、成本、技术等方面的限制条件?

11.6.2 目标软件分析

分析目标软件的窗口结构控件属性数据结构操作流程

  • 窗口结构:目标软件的窗口层级是什么?
  • 控件属性:目标控件的句柄、类名、标题、控件ID是什么?
  • 数据结构:目标软件的数据存储格式是什么?(如Excel、Word、CSV、数据库)
  • 操作流程:用户手动操作目标软件的流程是什么?

11.6.3 技术选型

根据需求分析和目标软件分析,选择合适的技术方案工具

  • 技术方案:Windows GUI自动化、OLE自动化、HTTP访问、图像识别、内存读取等
  • 工具:精易模块、大漠插件、WebBrowser组件、Excel支持库、Word支持库等

11.6.4 核心功能开发

按照操作流程,分模块开发自动化项目的核心功能

  • 窗口操作:找到目标窗口、激活目标窗口、最小化/最大化目标窗口
  • 控件操作:向目标控件发送文本、点击目标控件、获取目标控件的文本
  • 数据操作:读取数据、写入数据、导入数据、导出数据
  • 异常处理:处理网络错误、文件错误、控件未找到等异常

11.6.5 测试与优化

对自动化项目进行全面测试,并根据测试结果进行优化

  • 功能测试:测试每个功能是否正常工作
  • 稳定性测试:测试自动化项目在长时间运行时是否稳定
  • 性能测试:测试自动化项目的运行速度和资源占用
  • 优化:优化代码结构、减少内存泄漏、提高运行速度

11.6.6 打包与发布

将自动化项目打包成安装包,并发布给用户使用

  • 设置程序图标和版本信息
  • 打包依赖库
  • 制作安装包
  • 发布安装包

11.7 总结

✅ 本章详细介绍了易语言的四大核心自动化场景的全流程实战开发,包括办公自动化网页数据抓取自动化基础游戏脚本开发(仅用于学习),并总结了自动化项目的通用开发流程

通过学习,我们掌握了:

  • Windows GUI自动化的核心原理(窗口句柄查找、控件操作、消息发送)
  • 精易模块大漠插件的安装与配置
  • OLE自动化HTTP访问HTML解析图像识别的使用方法
  • 自动化项目的测试、优化和打包方法

自动化技术可以帮助我们解放双手,提高工作效率,但我们必须遵守法律法规,不开发/传播违法违规的软件。

希望大家能够将所学的自动化技术应用到合法合规的场景中,不断提升自己的开发水平和工作效率。

Read more

基于Java web的家庭财务管理系统-计算机毕设源码39497

基于Java web的家庭财务管理系统-计算机毕设源码39497

摘  要 本文设计实现了一个基于SpringBoot框架的家庭理财管理系统,该系统采用Java编程语言,MySQL数据库,并结合协同过滤算法实现数据分析功能。系统的主要功能模块包括:数据分析、角色管理(管理员与理财用户)、家庭预算管理、财务收入管理、收入类型管理、财务支出管理、支出类型管理、理财信息管理、家庭信息管理、财务日志管理、分析报告管理、系统管理、网站公告管理和新闻管理等。 通过该系统的开发,用户可以方便地管理家庭的财务数据,进行预算分配、收入支出记录、财务分析等操作。管理员可以对不同角色进行管理,生成各类分析报告,帮助家庭成员更清晰地了解自身的财务状况,实现理财目标。系统的设计与实现能够有效地提升家庭财务管理的效率,提供全方位的财务管理服务,使得家庭理财更加科学和系统化。 关键词: 家庭理财管理、Spring Boot、数据分析 Abstract This article designs and implements a family financial management system based

By Ne0inhk
Java 并发编程终极指南:从原理到实战(避坑+案例)

Java 并发编程终极指南:从原理到实战(避坑+案例)

并发编程是Java开发的核心技能,也是面试高频考点与生产环境故障高发区。多数开发者在使用多线程时,常面临线程安全(如竞态条件、数据不一致)、死锁、性能瓶颈(如线程上下文切换过多)等问题,且对底层原理(JVM内存模型、线程调度)理解模糊。本文将从并发编程核心概念切入,深度解析线程创建方式、同步机制、线程池原理、并发工具类等关键知识点,结合10+实战案例拆解常见坑点(如synchronized锁升级、volatile可见性陷阱),提供一套“原理+实践+优化”的完整方法论,帮助开发者从根源上掌握并发编程,写出高效、安全的多线程代码。 一、并发编程核心概念与底层原理 1. 为什么需要并发编程? 在多核CPU时代,并发编程的核心价值在于充分利用硬件资源,提升程序执行效率: * 提高吞吐量:同时处理多个任务(如Web服务器同时响应上千个请求); * 降低响应时间:将耗时操作(如IO、网络请求)异步化,避免阻塞主线程; * 提升资源利用率:CPU、内存、

By Ne0inhk
【Java 学习】Java的生命之源:走进Object类的神秘花园,解密Object类的背后故事

【Java 学习】Java的生命之源:走进Object类的神秘花园,解密Object类的背后故事

💬 欢迎讨论:如对文章内容有疑问或见解,欢迎在评论区留言,我需要您的帮助! 👍 点赞、收藏与分享:如果这篇文章对您有所帮助,请不吝点赞、收藏或分享,谢谢您的支持! 🚀 传播技术之美:期待您将这篇文章推荐给更多对需要学习Java语言、低代码开发感兴趣的朋友,让我们共同学习、成长! 1. Object 类 1.1 为什么所有类都继承 Object 类? 在Java中,Object 类是所有类的根类。也就是说,所有的类(包括用户自定义的类)都直接或间接继承自 Object 类。这是因为在 Java 中,Object 是所有类层次结构的最顶端类。 为什么所有类都继承 Object 类? 1. 统一的根基:Java 为了实现统一性,决定所有类都直接或间接继承自 Object 类。这意味着每个类都可以拥有 Object 类的一些通用方法,

By Ne0inhk
Java 大视界 -- Java 大数据在智能教育在线考试系统中的考试结果分析与教学反馈优化中的应用(420)

Java 大视界 -- Java 大数据在智能教育在线考试系统中的考试结果分析与教学反馈优化中的应用(420)

Java 大视界 -- Java 大数据在智能教育在线考试系统中的考试结果分析与教学反馈优化中的应用(420) * 引言: * 正文: * 一、智能教育在线考试系统的需求痛点与 Java 大数据的适配逻辑 * 1.1 在线考试系统的四大教学痛点(2024 年教育信息化公开数据) * 1.2 Java 大数据 vs 其他技术栈(教育场景实测对比) * 1.3 教育场景的 Java 大数据技术栈选型(按规模适配) * 二、Java 大数据在在线考试系统中的两大核心场景落地 * 2.1 场景一:考试结果多维分析(高校课程考试核心需求) * 2.1.1 架构设计(某省属高校实战架构) * 2.1.2 核心代码:Spark SQL 多维分析(

By Ne0inhk