首页 文章 精选 留言 我的

精选列表

搜索[内置VPN],共10004篇文章
优秀的个人博客,低调大师

几个提高工作效率的Python内置小工具

在这篇文章里,我们将会介绍4个Python解释器自身提供的小工具。这些小工具在笔者的日常工作中经常用到,减少了各种时间的浪费,然而,却很容易被大家忽略。每当有新来的同事看到我这么使用时,都忍不住感叹,原来Python还隐藏了这么好用的功能。下面就来看一下Python自带的几个小工具 一、1秒钟启动一个下载服务器 在实际工作中,时不时会有这样的一个需求:将文件传给其他同事。将文件传给同事本身并不是一个很繁琐的工作,现在的聊天工具一般都支持文件传输。但是,如果需要传送的文件较多,那么,操作起来就会比较麻烦。此外,如果文件在远程的服务器上,你要将文件传给同事,则需要先将远程服务器的文件下载到本地,然后再通过聊天工具传给同事。再或者,你并不是特别清楚要传哪几个文件给同事,所以,你们需要进行来回的交流。交流的时间成本是比较高的,会降低办事效率。

优秀的个人博客,低调大师

实战案例|利用 MarsCode 内置的 DeepSeek 服务,单元测试耗时缩短70%!

资料来源:火山引擎-开发者社区 单元测试总在奇怪的地方卡 bug?Mock 配置像解谜游戏、边界条件比数学题还烧脑? 没关系! MarsCode 编程助手 X 三款大模型(DeepSeek V3、DeepSeek R1、豆包大模型1.5 )帮你解决所有问题 无需配置,性能Top,代码准确率嗖嗖🚀 用过的朋友都说: “以前写测试像开手动挡,现在像开了自动巡航” ,速看~👇👇👇 准备工作 在正式开始单元测试之前,我们先做好相关准备👇 下载/更新MarsCode 编程助手 1️⃣如果你是新用户,以Visual Studio Code中为例,打开VSCode 扩展窗口,在搜索窗口搜索MarsCode,找到MarsCode 插件单击「install」,完成安装,登录即可使用MarsCode 编程助手。 2️⃣ 如果你是老用户,请更新MarsCode 编程助手到最新版本(若开启了自动更新,则将会自动更新),更新后重启IDE即可 *VSCode:1.1.62 *JetBrains:1.2.1.15 克隆案例项目 本次案例使用的是AI生成的一个最基础的React项目,目的是模拟学习工作中最真实的场景,方便大家迅速掌握快速搭建单元测试环境以及生成单元测试用例的技巧。 Bash git clone https://github.com/ylx911229/unit-test\_back.git 单元测试基础 *因为后续案例选用的是Jest作为单元测试框架,所以介绍的基础内容主要以Jest框架为标准 • 概念介绍 1️⃣ 断言(Assertion) :用于验证测试结果是否符合预期的语句,如 Expect 2️⃣ 测试替身(Test Double) :用于替代真实依赖的模拟对象,确保测试的隔离性,如 Mock、Jest.fn 3️⃣ 测试覆盖率(Test Coverage) :用于衡量测试用例覆盖代码的比例,如 行覆盖率、分支覆盖率 • 单元测试文件命名规范 生成的单元测试文件名必须以 .test.ts/.test.js 作为结尾,否则单元测试框架无法读取并执行单元测试用例 • 运行单元测试用例 Markdown npx jest --coverage 实战跟练 STEP1:搭建测试环境 首先来搭建一下单元测试的环境,向MarsCode输入以下提示词: Markdown Workspace 帮我为整个项目搭建一下单元测试的环境 可以看到MarsCode给我们推荐的单元测试框架是Jest,这是一个流行的JavaScript测试框架,特别适合用于单元测试。 另外,React组件的单元测试,依赖 React Testing Library ,RTL是当前 React 生态中最流行的组件测试解决方案,它提供了一套更贴近真实用户行为的测试工具链。 STEP2:单元测试用例编写 关于单元测试用例,将从函数类和UI类等不同的方式类型来举例实现 • 函数类 1️⃣ 纯函数 & 工具类 对于纯函数的工具类单元测试,特点是输入输出明确,无副作用,整体测试重点是 输出格式验证和唯一性检查,接下来以 生成唯一 ID 为例: JavaScript // 生成唯一 IDfunction generateId(prefix) { return `${prefix}_${Math.random().toString(36).slice(2, 9)}`; } 我们可以打开src\utils\tool-utils.js,选中代码,在对话框直接选择/test功能形成单元测试: 将生成的单测代码另存为tool-utils.test.js,保存后执行得到如下效果: 结果显示覆盖率100%,但是有一个用例并未通过,显示特殊字符作为前缀输出的结果未匹配正则。 我们可以切换到DeepSeek R1模型并选中文件,将出现的问题告诉MarsCode后将生成的代码替换进原来的tool-utils.test.js,再次运行 npx jest --coverage 可以发现问题已解决~ 如果test代码未运行成功出现报错,可以将报错内容复制给MarsCode,利用AI问答继续解决问题。 2️⃣ 数据转换 & 验证 接下来以用户资料表单处理器为例,处理结构化数据或验证规则,这则测试案例重点在于正常数据清洗(trim、类型转换)、异常输入(空值、非法邮箱、年龄不足)、 及错误消息准确性,打开validate-utils.js,选择生成单测: JavaScript // 转换并验证用户输入 export const processUserInput = (formData) => { const result = { name: formData.name.trim(), age: parseInt(formData.age, 10), email: formData.email.toLowerCase() }; if (isNaN(result.age)) { throw new Error('Invalid age: must be a number'); } if (!/^[\w.+]+@\w+\.\w+$/.test(result.email)) throw new Error('Invalid email'); if (result.age < 18) throw new Error('Underage'); return resu< } 同样将MarsCode生成的单测代码保存为validate-utils.test.js后运行,效果如下: 3️⃣ 状态管理 & 业务逻辑 现在我们来探讨更复杂业务逻辑下的单测,以购物车 Redux reducer为例,涉及核心业务规则或全局状态变更,这个案例中我们的测试重点在 • 商品添加逻辑(新增 vs 增量) • 促销码有效性验证 • 不可变数据检查 JavaScript // cartReducer 函数 export const cartReducer = (state = { items: [] }, action) => { switch (action.type) { case 'ADD_ITEM': const existing = state.items.find(item => item.id === action.payload.id); if (existing) { return { ...state, items: state.items.map(item => item.id === action.payload.id ? { ...item, qty: item.qty + 1 } : item ) }; } return { ...state, items: [...state.items, action.payload] }; case 'APPLY_PROMO': if (!action.payload.isValid) return state; return { ...state, promoCode: action.payload.code }; default: return state; } } 现在打开businuss-utils.js,同样选中/test 生成单测: 将MarsCode 生成的新文件保存为businuss-utils.test.js,运行单测命令,得到如下效果: • UI类 我们以用户输入花费金额的REACT组件为例,我们单测的重点在于事件是否能正确触发以及UI是否能正常显示,打开react-test.jsx文件: JavaScript import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { CostInput } from './react-test'; describe('CostInput Component', () => { beforeEach(() => { jest.clearAllMocks(); // 设置全局变量 global.navigator = { // 传入navigator的值 }; global.document = { // 传入document的值 }; global.window = { // 传入window的值 }; global.otherVariables = { // 传入otherVariables的值 }; }); test('renders without crashing', () => { render(<CostInput />); }); test('calls handleChange when the input changes with valid number', () => { const handleChange = jest.fn(); const { getByLabelText } = render(<CostInput handleChange={handleChange} />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '123' } }); expect(handleChange).toHaveBeenCalled(); }); test('does not call handleChange when the input is invalid', () => { const handleChange = jest.fn(); const { getByLabelText } = render(<CostInput handleChange={handleChange} />); fireEvent.change(getByLabelText('cost-input'), { target: { value: 'abc' } }); expect(handleChange).toHaveBeenCalled(); }); test('displays the correct value with dollar sign', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '123' } }); expect(getByLabelText('cost-input')).toHaveValue('$123'); }); test('displays empty value when input is invalid', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: 'abc' } }); expect(getByLabelText('cost-input')).toHaveValue(''); }); test('handles initial dollar sign correctly', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '$123' } }); expect(getByLabelText('cost-input')).toHaveValue('$123'); }); test('handles empty input correctly', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '' } }); expect(getByLabelText('cost-input')).toHaveValue(''); }); test('handles input with leading zeros correctly', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '00123' } }); expect(getByLabelText('cost-input')).toHaveValue('$123'); }); test('handles input with multiple dollar signs correctly', () => { const { getByLabelText } = render(<CostInput />); fireEvent.change(getByLabelText('cost-input'), { target: { value: '$$123' } }); expect(getByLabelText('cost-input')).toHaveValue('$123'); }); }); 向MarsCode 输入单测/test,同样将生成的代码另存为react_tes t.test.js进行运行,运行之后发现单测覆盖率只有62.5%,不太理想。 我们可以继续让MarsCode 生成单测补充用例,提高覆盖率 应 用代码后,可以看到单测覆盖率 提升到83.33%,同时帮我们优化了部分代码,甚至对原来的handleChange函数进行了优化,提升了代码质量。 通过本次实践,我们不仅掌握了单元测试的核心价值与实施方法,更验证了 MarsCode 在提升代码质量方面的工程价值。 相信在更复杂的业务场景下,优秀的工具能帮助开发者释放更多生产力。

优秀的个人博客,低调大师

Flink从入门到真香(16、Flink内置的一些Process Function)

之前的转换算子是无法访问事件的时间戳信息和水位线信息的,而这在一些应用场景下,极为重要。例如MapFunction这样子的map转换算子就无法访问时间戳或者当前事件的事件事件。 基于此,DataStream API提供了一系列LOW-LEVEL的转换算子调用。可以访问时间戳,watermark以及注册定时事件,还可以输出特定的一些事件,例如超时时间等。process function用来构建事件驱动的应用以及实现自定义的业务逻辑(使用之前的window函数和转换算子无法实现)。例如Flink SQL就是使用Process Function实现的。 Flink提供了8个 Process Function ProcessFunction KeyedProcessFunction CoProcessFunction ProcessJoinFunction BroadcastProcessFunction KeyedBroadcastProcessFunction ProcessWindowFunction 下面几个栗子来一一说明: 栗子1- 实现一个连续15秒如果温度持续上升就报警 package com.mafei.apitest import com.mafei.sinktest.SensorReadingTest5 import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor} import org.apache.flink.streaming.api.functions.KeyedProcessFunction import org.apache.flink.streaming.api.scala._ import org.apache.flink.util.Collector object ProcessFunctionTest { def main(args: Array[String]): Unit = { //创建执行环境 val env = StreamExecutionEnvironment.getExecutionEnvironment env.getConfig.setAutoWatermarkInterval(200) //直接全局设置watermark的时间为200毫秒 // val inputStream = env.readTextFile("/opt/java2020_study/maven/flink1/src/main/resources/sensor.txt") //接收一个socket文本流 val inputStream = env.socketTextStream("127.0.0.1",6666) env.setParallelism(1) //先转换成样例类类型 val dataStream = inputStream .map(data => { val arr = data.split(",") //按照,分割数据,获取结果 SensorReadingTest5(arr(0), arr(1).toLong, arr(2).toDouble) //生成一个传感器类的数据,参数中传toLong和toDouble是因为默认分割后是字符串类别 }) .keyBy(_.id) // .process(new TestKeydProcessFunction) //demo .process(new TempIncreWarning(15000L)) dataStream.print() env.execute("定时器KeydProcessFunction") } } /** * 定义3个参数: Key 因为上面是按照id做groupby的,所以是string * 输入数据: SensorReadingTest5 * 输出数据: 这个直接定,可以根据实际情况来改 */ class TempIncreWarning(alertInterval: Long) extends KeyedProcessFunction[String, SensorReadingTest5,String]{ //定义状态: 保存上一个温度进行比较,保存注册定时器的时间用于删除 lazy val lastTempValue: ValueState[Double] = getRuntimeContext.getState(new ValueStateDescriptor[Double]("lastTempValue", classOf[Double])) //定时器时间戳 lazy val timerTimestampState: ValueState[Long] = getRuntimeContext.getState(new ValueStateDescriptor[Long]("timerTimestampState", classOf[Long])) //每条数据都会经过这个方法 override def processElement(value: SensorReadingTest5, ctx: KeyedProcessFunction[String, SensorReadingTest5, String]#Context, out: Collector[String]): Unit = { //先把上一次的值,和定时器的时间给拿出来 var lastTemp = lastTempValue.value() var timerTimestamp = timerTimestampState.value() //把上一次的值,设置成这一次的,用在下次调用 lastTempValue.update(value.temperature) //用这次的温度和上一次的温度值做比较,如果比上次大,那说明在升温 if (value.temperature > lastTemp){ //说明是第一次,没有定时器被设定(定义的没有默认值,长整型所以是0 if (timerTimestamp == 0){ val ts = ctx.timerService().currentProcessingTime() + alertInterval ctx.timerService().registerProcessingTimeTimer(ts) timerTimestampState.update(ts) } }else if( value.temperature <= lastTemp){ //如果温度值没有在上升,那就需要把这个定时器给销毁掉,因为不满足15秒持续上升条件了 ctx.timerService().deleteProcessingTimeTimer(timerTimestamp) // timerTimestampState.update(0L)// 可以直接设置成0 timerTimestampState.clear() //调用这个清空方法也是一样的效果 } } //定义触发的时候实际要做的操作 override def onTimer(timestamp: Long, ctx: KeyedProcessFunction[String, SensorReadingTest5, String]#OnTimerContext, out: Collector[String]): Unit = { // ctx.getCurrentKey就是当前的sensor ID ,是上面.keyBy(_.id)这一步定义的 out.collect("传感器 "+ctx.getCurrentKey+"温度持续了"+alertInterval +"秒在持续上升!!!!") timerTimestampState.clear() //已经触发了,那需要把定时器的时间给清空掉 } } /** * 在KeyedProcessFunction中,点进去就可以看到要传的3个参数 * * @param <K> Type of the key. * * @param <I> Type of the input elements. * * @param <O> Type of the output elements. */ class TestKeydProcessFunction extends KeyedProcessFunction[String, SensorReadingTest5, String]{ // var stateTest1: valueState[Int] = _ override def processElement(value: SensorReadingTest5, ctx: KeyedProcessFunction[String, SensorReadingTest5, String]#Context, out: Collector[String]): Unit = { // ctx.output() //定义一个侧输出流 ctx.getCurrentKey // 获取当前key, 跟从value中一个效果 ctx.timerService().currentWatermark() //获取当前水印 ctx.timerService().currentProcessingTime() //当前处理时间 ctx.timerService().registerEventTimeTimer(ctx.timestamp()+ 30000L) //注册一个定时器到当前时间30秒之后 ctx.timerService().registerProcessingTimeTimer(ctx.timestamp() * 30000L) //跟上面一样,换成processTime ctx.timerService().deleteEventTimeTimer(ctx.timestamp()+ 30000L) //删除一个定时器,这里的时间跟定义的时间要对的上,因为可以注册多个 } override def onTimer(timestamp: Long, ctx: KeyedProcessFunction[String, SensorReadingTest5, String]#OnTimerContext, out: Collector[String]): Unit = super.onTimer(timestamp, ctx, out) } 代码结构和运行效果: 栗子2-实现一个如果温度超过15,则输出到主流上,否则输出到侧流上,实现一个分流操作 package com.mafei.apitest import com.mafei.sinktest.SensorReadingTest5 import jdk.jfr.Threshold import org.apache.flink.streaming.api.functions.ProcessFunction import org.apache.flink.streaming.api.scala._ import org.apache.flink.util.Collector object SideOutputTest { def main(args: Array[String]): Unit = { //使用ProcessFunction,利用侧输出流实现一个分流操作 //创建执行环境 val env = StreamExecutionEnvironment.getExecutionEnvironment env.getConfig.setAutoWatermarkInterval(200) //直接全局设置watermark的时间为200毫秒 // val inputStream = env.readTextFile("/opt/java2020_study/maven/flink1/src/main/resources/sensor.txt") //接收一个socket文本流 val inputStream = env.socketTextStream("127.0.0.1",6666) env.setParallelism(1) //先转换成样例类类型 val dataStream = inputStream .map(data => { val arr = data.split(",") //按照,分割数据,获取结果 SensorReadingTest5(arr(0), arr(1).toLong, arr(2).toDouble) //生成一个传感器类的数据,参数中传toLong和toDouble是因为默认分割后是字符串类别 }) // .process(new TestKeydProcessFunction) //demo val highTempStream = dataStream.process(new SplitTempProcess(10.1)) highTempStream.print("this is high stream: ") /** * new OutputTag[(String,Long, Double)]("low") * 这里[]内的是定义输出的格式,根据实际情况来改,()里面的low是标签的名称 */ val lowTempStream = highTempStream.getSideOutput(new OutputTag[(String,Long, Double)]("low")) lowTempStream.print("this is low stream: ") env.execute("side output test") } } //实现自定义的processFunction,利用侧输出流,进行分流操作 /** * * @param threshold * ProcessFunction传2个参数,第一个是输入的数据类型,第二个是输出的数据类型,都可以自定义 * * */ class SplitTempProcess(threshold: Double) extends ProcessFunction[SensorReadingTest5, SensorReadingTest5]{ override def processElement(value: SensorReadingTest5, ctx: ProcessFunction[SensorReadingTest5, SensorReadingTest5]#Context, out: Collector[SensorReadingTest5]): Unit = { //如果温度值大于设置的阈值,那直接输出 if (value.temperature > threshold){ out.collect(value) }else{ //如果小于等于就输出到侧输出流 /** * 这里侧输出流的定义必须数据类型和id都要跟上面对的上,low后边的参数代表具体要输出的数据, */ ctx.output(new OutputTag[(String,Long, Double)]("low"),(value.id, value.timestamp, value.temperature)) } } } 代码结构及运行效果: 状态后端 Flink提供多种状态后端的存储形式1)MemoryStateBackend内存级的状态后端,会将键控状态作为内存中对象进行管理,将他们存储在TaskManager的JVM堆上,而将checkpoint存储在JobManager的内存中特点: 快速、低延迟、单不稳定(不落盘当然快,但是掉电或者重启进程之类的就没了,通常用在测试)FsStateBackend将checkpoint存储到远程的持久化文件系统(FileSystem)上,而对于本地状态,跟MemoryStateBackend一样,也会存在TaskManager的JVM堆上同时拥有内存级的本地访问速度,和更好的容错保证RocksDBStateBackend将所有状态序列化后,存入本地的RocksDB中存储RocksDB的支持并不直接包含在flink中,需要单独引入依赖: <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-statebackend-rocksdb_2.12</artifactId> <version>1.10.1</version> </dependency> 在代码中配置: // env.setStateBackend(new MemoryStateBackend()) // env.setStateBackend(new FsStateBackend("")) // env.setStateBackend(new RocksDBStateBackend(""))

优秀的个人博客,低调大师

Chrome 内置二维码功能可用,这只小恐龙也在

据Android Police 报道,Chrome 生成二维码分享网页的功能已在Canary 版本可用。目前适用于 Windows 和 Mac。 事实上,去年下半年Chrome 就已添加了这项共享功能,但一直处于不可用状态。现在,带有小恐龙 dino 的二维码终于亮相了。 图片来源:9to5google 在 Chrome Canary 中访问 chrome://flags/#sharing-qr-code-generator,并启用标记 “Enable sharing page via QR Code” 之后,有两种方式可生成二维码,分别是: 点击 URL 栏中的 “QR code” 按钮; 右键菜单中的“为此页面生成 QR code”选项。 接下来,在页面右上角就会出现对应页面的二维码,画面中心便是非常具有标志性的小恐龙。 此外,在二维码下方的输入框中也可自行修改 URL,不必导航到新的页面就可实时生成对应二维码。目前 URL 长度限制为 84 个字符。 经测试,这一功能在多数情况下几乎完全可以正常使用,除了右下角的“下载”按钮还未启用。点击按钮下载时,只会生成一幅全黑图像,而非真实的二维码。 此前我们曾报道过,安卓端 Chrome 也正在测试二维码生成的功能,目前仍在开发中。该功能到达稳定状态,也许要等到今年下半年的 Chrome 84 版本发布。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册