首页 文章 精选 留言 我的

精选列表

搜索[协作空间],共10000篇文章
优秀的个人博客,低调大师

PyCharm 2026.1:全新调试引擎、原生 uv 支持与自由的 AI 协作

PyCharm 2026.1 现已发布。公告称,这个版本不仅仅是功能上的简单加法,它重新定义了您构建、调试和扩展 Python 项目的方式。 从基于 debugpy 的全新调试引擎,到针对远程目标的一流 uv 支持,再到免费版中大幅增强的 JavaScript 支持,本版本的核心目标在于消除开发阻碍,让用户能够全身心地投入到代码逻辑中。 What’s New(新功能)页面 使用 debugpy标准化调试体验 PyCharm 现在支持将debugpy作为默认调试器后端。通过引入业界标准的调试适配器协议(DAP),IDE 与更广泛的 Python 生态系统实现了高度统一。新引擎采用更稳定的连接模型取代了传统复杂的套接字等待逻辑,让竞态条件(Race Conditions)和时序边缘问题不再干扰您的调试体验。 现代 Python 开发的底层基石 新引擎提供了对PEP 669的完整原生支持,利用 Python 3.12 的低开销监控 API,相比传统的sys.settrace()方法显著降低了调试器的运行开销。这确保了用户的调试会话不仅运行更快,且侵入性更低。此外,此次迁移还带来了全面的asyncio支持。用户现在可以在 FastAPI 和 aiohttp 等现代异步框架中,直接在async上下文中使用调试控制台和表达式求值等全套工具。 跨环境的极高可靠性 除了性能提升,debugpy还简化了“附加到进程(Attach to Process)”的体验,无论是 Docker 容器、云端远程服务器(AWS/Azure/GCP)还是本地进程,操作都更加标准化。针对专业化的工作流,我们引入了全新的“附加到 DAP(Attach to DAP)”运行配置。只需使用debugpy.listen()命令即可连接到目标,彻底告别手动管理连接的繁琐,专注代码本身。 远程解释器原生支持 uv 许多开发者的代码和依赖项都托管在远程服务器上(如通过 SSH、WSL 或 Docker)。通过将 PyCharm 连接到远程机器并将uv作为解释器,你可以保持环境的完全同步,确保包管理符合预期,并像在本地一样流畅地运行项目。 为所有人提供 专业级 Web 开发工具 随着 PyCharm 2026.1 的发布,核心 IDE 体验持续进化。官方决定向所有用户(包括免费版用户)开放更多专业级 Web 开发工具。从初学者到以后端为主的开发者,现在都可以免费使用大量的 JavaScript、TypeScript 和 CSS 功能,以及此前仅限专业版(Pro)订阅用户使用的高级导航和代码智能辅助。 有关新功能的详细细分,可查看这篇博文(英文)。 AI 集成的跨越式进步 PyCharm 正在演变为一个开放平台,赋予您将心仪的 AI 工具直接引入专业开发流的自由。此版本的重点在于构建一个灵活的生态系统,让你可以自由调度当今顶尖的模型和 AI Agent。 ACP 注册表:探索 AI Agent 的大门 新版本推出了ACP 注册表—— 这是一个内置在 IDE 中的 AI 编码 Agent 目录,通过 ACP(Agent Client Protocol)实现无缝集成。 无论你想尝试 OpenCode 等开源 Agent,还是 Gemini CLI 等专业工具,现在只需点击几次即可完成发现与安装。如果有自定义配置或尚未列出的 Agent,可以通过acp.json轻松添加,没有任何束缚地使用你最喜爱的工具。 原生 OpenAI Codex 集成与 BYOK OpenAI Codex 现已原生集成至 JetBrains AI 聊天中。这意味着你可以直接处理复杂的开发任务,无需在浏览器和 IDE 窗口之间频繁切换或复制粘贴。 还引入了自带密钥(BYOK)支持。现在可以在 IDE 设置中直接连接来自 OpenAI、Anthropic 或其他兼容提供商(包括本地模型)的 API 密钥。这让用户可以根据工作流和预算选择最合适的方案,同时将所有 AI 驱动的开发保留在 PyCharm 内部完成。 后续编辑建议:让“心流”不再中断 后续编辑建议(Next Edit Suggestions,简称 NES)提供了一种更智能、更轻量化的方案。当你修改代码时,PyCharm 会主动预测最可能的后续更改并提供内联建议。 轻松保持一致性:通过简单的Tab + Tab体验,快速更新全文件中的所有调用点。 尽在掌控:逐步确认更改,而非一次性审查大篇幅的自动化差异(Diff)。 不计入配额:使用 NES不会消耗 AI 积分。即使没有 JetBrains AI Pro 订阅的配额,也可以尽情使用。 在底层,项目团队还进行了大量的性能优化、稳定性升级以及一些细节打磨。更多详情可查看官方公告。

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

提升协作效率:钉钉流程与低代码平台的无缝对接

摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 钉钉作为目前很多企业都在使用的移动办公平台,提供了很多常用的OA审批功能,同时也支持自定义审批流程,极大的方便了企业的办公审批,那么对于低代码平台而言是否可以实现与钉钉的对接呢?答案当然是肯定的,下面小编就以活字格为例为大家介绍如何在低代码平台中对接钉钉的审批流程。 使用低代码对接钉钉审批流程 活字格对接钉钉可以分为以下5步: 在钉钉中发布流程。 在低代码中设计书表以及页面。 调用钉钉接口实现业务逻辑。 创建钉钉应用。 在活字格中发起钉钉流程。 1.在钉钉中发布流程 在钉钉管理后台中创建流程表单,进行自定义表单设计和流程设计,完成后点击右上角的发布即可。 在基础设置页签的最下面,有该模板的唯一编号,这个也是后面发起流程中需要用到的。 2. 在低代码中设计数据表以及页面 在活字格中设计数据表及界面,不需要和钉钉的表单页面一致,只需最终能组装成符合钉钉要求的数据即可。 3.调用钉钉接口实现业务逻辑 编写活字格提交流程时的方法并调用钉钉接口,可参考钉钉接口文档。 首先要获取accessToken,需要用到Appkey和AppSecret参数,调用发起审批时,需要用到模板的编号,可以将这些参数设置为全局变量,待发布后在管理控制台统一配置,如下图展示,后两个参数会在后面进行介绍。 结合活字格的“发送HTTP请求命令”和“Json反序列化命令”,参照钉钉的接口文档,实现接口调用,可参考附件的工程文件服务端命令->钉钉。 这里要注意formComponentValues参数,需要结合钉钉的表单设计进行构造的,详细信息可以参考下方接口的文档说明。 4.创建钉钉应用 这一步可以参考活字格帮助手册:与钉钉集成。创建完之后就会获得第三步中对应的AppKey与AppSecret。 5.在活字格中发起钉钉流程 在发起流程后,流程就会在钉钉中执行。 除此之外,还可以使用事件订阅的功能查看流程的具体执行情况: 事件订阅的流程以及加解密规则可参考配置事件订阅。 对于请求地址,可创建一个任何人都能访问的,post类型的服务端命令。但因为钉钉的请求数据以及响应数据都是加密的,因此可以使用市场上的钉钉事件订阅加解密插件,可参考附件工程文件的服务端命令->事件订阅->eventsubscription。 开启需要订阅的事件,不同的事件订阅,请求的数据结构有所不同,可以在事件订阅中进行查看。解密之后可以通过EventType做判断,然后结合实际业务逻辑进行处理。 总结 以上就是使用活字格对接钉钉流程的步骤,如果您还想了解更多关于低代码对接钉钉的信息,可以观看这个视频:低代码对接钉钉解决方案2.0,最后附上根据文章内容整理好的活字格文件:对接钉钉流程-9.0.4.0.fgcc。 扩展链接: 从表单驱动到模型驱动,解读低代码开发平台的发展趋势 低代码开发平台是什么? 基于分支的版本管理,帮助低代码从项目交付走向定制化产品开发

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

线程间的协作(2)——生产者与消费者模式

1.何为生产者与消费者 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。 import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @ClassName:Restraurant * @Description:何为生产者与消费者 * @author: * @date:2018年5月3日 */ public class Restraurant { Meal m=null; Chef chef=new Chef(this); WaitPerson wait=new WaitPerson(this); ExecutorService service=Executors.newCachedThreadPool(); public Restraurant() { service.execute(chef); service.execute(wait); } public static void main(String[] args) { new Restraurant(); } } /** * @ClassName:Meal * @Description:生产者生成的数据 * @author: * @date:2018年5月3日 */ class Meal{ private final int orderNum;//食物订单编号 public Meal(int num){ orderNum=num; } public String toString(){ return "Meal"+orderNum; } } /** * @ClassName:Chef * @Description:厨师类,及生产者 * @author: * @date:2018年5月3日 */ class Chef implements Runnable{ Restraurant r; int count=0; public Chef(Restraurant r) { this.r=r; } @Override public void run() { try{ while(!Thread.interrupted()){ synchronized (this) { while(r.m!=null){ System.out.println("厨师等待中"); wait();//等待服务员取餐 } } if(count++==10){ System.out.println("今日已售完"); r.service.shutdownNow(); } System.out.println("订单完成,服务员取餐"); synchronized (r.wait) { r.m=new Meal(count); r.wait.notifyAll(); } TimeUnit.SECONDS.sleep(1); } }catch (InterruptedException e) { System.out.println("生产者线程强制中断"); } } } /** * @ClassName:WaitPerson * @Description:服务员类,即消费者 * @author: * @date:2018年5月3日 */ class WaitPerson implements Runnable{ Restraurant r; public WaitPerson(Restraurant r) { this.r=r; } @Override public void run() { try { while (!Thread.interrupted()) { synchronized (this) { while (r.m == null) { System.out.println("服务员等待中"); wait();// 等待厨师生成食物 } } System.out.println("服务员以取餐" + r.m); synchronized (r.chef) { r.m = null; r.chef.notifyAll(); } } } catch (InterruptedException e) { System.out.println("消费者线程强制中断"); } } } 2.生产者与消费者模式 1)产生原因:在多线程开发 中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理 完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须 等待生产者。wait与notify方法以一种非常低级的方式解决了任务互相通知的问题,即每次交互都要进行一次握手,极大影响的效率以及性能,为了解决这种生产消费能力不均衡的问题,便有了生产者和消费者模式。 2)原理:生产者和消费者模式是通过一个容器(比如同步阻塞队列)来解决生产者和消费者的强耦合问题。生产者和消 费者彼此之间不直接通信,而是通过阻塞队列来进行通信,所以生产者生产完数据之后不用 等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取, 阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。 这个阻塞队列就是用来给生产者和消费者解耦的。java.util.concurrent.BlockingQueue接口提供了这个队列,通常使用其实现子类ArrayBlockingQueue,LinkedBlockingQueue。当消费者任务试图从同步队列中获取对象,如果队列为空时,那么队列则会挂起消费者任务,并且当拥有足够多的元素可用时才会恢复消费者任务。 import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class UseBlockingQueue { public static void main(String[] args) throws InterruptedException { LinkedBlockingQueue<Toast> dry=new LinkedBlockingQueue<Toast>(), butter=new LinkedBlockingQueue<Toast>(), jam=new LinkedBlockingQueue<Toast>(), con=new LinkedBlockingQueue<Toast>(); ExecutorService exec=Executors.newCachedThreadPool(); exec.execute(new MakeToast(dry));//制作初始吐司任务 exec.execute(new Butter(dry,butter));//吐司抹黄油任务 exec.execute(new Jam(butter,jam));//吐司抹果酱任务 exec.execute(new Consumer(jam));//消费者任务,食用吐司 TimeUnit.SECONDS.sleep(5); exec.shutdownNow(); } } class Toast{ private int status;//吐司状态:0代表制作吐司,1代表抹黄油,2代表向抹了黄油的吐司抹果酱 private final int id; public Toast(int id1) { id=id1; } public void butter(){ status=1; }; public void jam(){ status=2; } public int getStatus(){ return status; } public int getId(){ return id; } public String toString(){ return "toast "+id+":"+status; } } /** * @Description:制作初始吐司 */ class MakeToast implements Runnable{ private LinkedBlockingQueue<Toast> queue=new LinkedBlockingQueue<Toast>(); private int count=0; public MakeToast(LinkedBlockingQueue<Toast> q) { queue=q; } @Override public void run() { try{ while(!Thread.interrupted()){ Thread.sleep(1000);//制作时间 Toast t=new Toast(count); System.out.println(t); queue.put(t);//添加到同步队列 count++; } }catch (InterruptedException e) { System.out.println("make process interrupted"); } System.out.println("make process off"); } } /** * @Description:涂抹黄油 */ class Butter implements Runnable{ private LinkedBlockingQueue<Toast> queue1,queue2;//未加料吐司队列,抹黄油后吐司队列 public Butter(LinkedBlockingQueue<Toast> q1,LinkedBlockingQueue<Toast>q2) { queue1=q1; queue2=q2; } @Override public void run() { try{ while(!Thread.interrupted()){ Toast t=queue1.take();//如果队列中没有可用元素将会阻塞,直至有可用元素被添加 t.butter(); System.out.println(t); queue2.put(t); } }catch (InterruptedException e) { System.out.println("butter process interrupted"); } System.out.println("butter process off"); } } /** * @Description:涂抹果酱 */ class Jam implements Runnable{ private LinkedBlockingQueue<Toast> queue1,queue2;//抹黄油后吐司队列,抹果酱吐司队列 public Jam(LinkedBlockingQueue<Toast> q1,LinkedBlockingQueue<Toast>q2) { queue1=q1; queue2=q2; } @Override public void run() { try{ while(!Thread.interrupted()){ Toast t=queue1.take();//如果队列中没有可用元素将会阻塞,直至有可用元素被添加 t.jam(); System.out.println(t); queue2.put(t); } }catch (InterruptedException e) { System.out.println("jam process interrupted"); } System.out.println("jam process off"); } } /** * @Description:被食用 */ class Consumer implements Runnable{ private LinkedBlockingQueue<Toast> finished;//抹黄油后吐司队列,抹果酱吐司队列 int count=0; public Consumer(LinkedBlockingQueue<Toast> q) { finished=q; } @Override public void run() { try{ while(!Thread.interrupted()){ Toast t=finished.take();//如果队列中没有可用元素将会阻塞,直至有可用元素被添加 if(t.getId()!=count++||t.getStatus()!=2){ System.out.println("过程出现错误"); return; }else{ System.out.println("所有过程正确实现"+"toast "+t.getId()+"被食用"); } } }catch (InterruptedException e) { System.out.println("eat process interrupted"); } System.out.println("eat process off"); } }

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册