首页 文章 精选 留言 我的

精选列表

搜索[智能体平台],共10000篇文章
优秀的个人博客,低调大师

通过C++编译视频平台为什么要使用virtual虚析构函数?

大家知道TSINGSEE青犀视频云边端架构系列编译用了几种不同的架构,同时,为了满足不同形式编译的需求,我们也会在编译当中运用到不同的函数来实现。比如在编译中,我们使用了C++语言,为了在对象不被使用之后释放资源,虚函数也可实现多态,我们将虚函数加上了virtual。 C++中基类的析构函数为什么要用virtual虚析构函数?本文我们依据自身的开发经验,和大家分享一下。 我们先来看两段代码的运行结果对比下: 代码1: 代码2: 运行函数: 执行代码1运行结果: 执行代码2运行结果: 从上述结果可以看出执行代码1和代码2有明显差异。 执行代码1可以正常释放资源,而执行代码2则没有正常释放资源。因此,MyClass类的析构函数并没有被调用,但是正常情况下析构函数里都会释放各种资源,而析构函数不被调用的话就会导致内存泄漏。代码1加上virtual关键字,运行次代码会调用析构函数,避免内存泄漏。 所以c++中基类采用virtual虚析构函数主要是为了防止内存泄漏。如果派生类中申请内存空间,而且在析构函数中对内存进行释放。如果没有采用虚构函数,而释放该类对象,派生类对象就不会得到动态绑定。这种情况就会导致内存泄漏。所以为了防止内存泄漏,只要继承关系,被继承的类析构函数是虚函数,都会加上virtual关键字。

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

zlt-mp v4.5.0 发布,基于 Spring Cloud Alibaba 的微服务平台

功能介绍 更新内容 特性/增强 支持OIDC协议授权 应用管理界面增加ID令牌相关的配置 增加oidc协议单点登录样例工程oidc-sso 增加zookeeper工具类zookeeperTemplate 替换默认PasswordEncoder实现类为DelegatingPasswordEncoder 修改文件中心默认依赖为s3 升级spring-boot到2.3.11.RELEASE 问题修复 修复token过期时访问网关返回500状态码 变更语句 Use`oauth-center`; altertableoauth_client_detailsaddsupport_id_tokentinyint(1)DEFAULT1COMMENT'是否支持id_token'; altertableoauth_client_detailsaddid_token_validityint(11)DEFAULT60COMMENT'id_token有效期'; 内容说明 一、支持OIDC协议授权 OIDC是OpenID Connect的简称,它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。 在使用授权码模式或者简化模式时,通过在参数response_type中增加id_token值即可,例子如下: http://localhost:9900/api-uaa/oauth/authorize?client_id=zlt&redirect_uri=http://127.0.0.1&response_type=codeid_token OIDC协议返回示例: { "resp_code":200, "resp_msg":"ok", "datas":{ "access_token":"d1186597-aeb4-4214-b176-08ec09b1f1ed", "token_type":"bearer", "refresh_token":"37fd65d8-f017-4b5a-9975-22b3067fb30b", "expires_in":3599, "id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vemx0MjAwMC5jbiIsImlhdCI6MTYyMTY5NjU4MjYxNSwiZXhwIjoxNjIxNjk2NjQyNjE1LCJzdWIiOiIxIiwibmFtZSI6IueuoeeQhuWRmCIsImxvZ2luX25hbWUiOiJhZG1pbiIsInBpY3R1cmUiOiJodHRwOi8vcGtxdG1uMHAxLmJrdC5jbG91ZGRuLmNvbS_lpLTlg48ucG5nIiwiYXVkIjoiYXBwIiwibm9uY2UiOiJ0NDlicGcifQ.UhsJpHYMWRmny45K0CygXeaASFawqtP2-zgWPDnn0XiBJ6yeiNo5QAwerjf9NFP1YBxuobRUzzhkzRikWGwzramNG9na0NPi4yUQjPNZitX1JzlIA8XSq4LNsuPKO7hS1ALqqiAEHS3oUqKAsjuE-ygt0fN9iVj2LyL3-GFpql0UAFIHhew_J7yIpR14snSh3iLVTmSWNknGu2boDvyO5LWonnUjkNB3XSGD0ukI3UEEFXBJWyOD9rPqfTDOy0sTG_-9wjDEV0WbtJf4FyfO3hPu--bwtM_U0kxRbfLnOujFXyVUStiCKG45wg7iI4Du2lamPJoJCplwjHKWdPc6Zw" } } id_token包含以下内容: { "iss":"http://zlt2000.cn", "iat":1621696582615, "exp":1621696642615, "sub":"1", "name":"管理员", "login_name":"admin", "picture":"http://xxx/头像.png", "aud":"app", "nonce":"t49bpg" } 二、应用管理界面增加ID令牌相关的配置 支持ID令牌:为是则支持返回id_token ID时效:为配置id_token的有效时间 三、增加zookeeper工具类zookeeperTemplate 依赖: <dependency> <groupId>com.zlt</groupId> <artifactId>zlt-zookeeper-spring-boot-starter</artifactId> </dependency> 使用: @Resource privateZookeeperTemplatezkTemplate; zkTemplate.createNode("/","test"); 四、替换默认PasswordEncoder实现类为DelegatingPasswordEncoder 用于同时兼容多种加密方式的密码数据同时存在时的密码校验。 修改旧的密码数据的值,添加前缀标识,支持以下三种格式: 无前缀 //只支持使用bcrypt方式加密的密码 格式:密码 例如:$2a$10$EgTOU7PMe.3jaMwFsumdweJcnY3TsTqyuJEdSaSKxdgwYchAwUJ1C 无盐值 格式:{encodingId}密码 例如:{bcrypt}$2a$10$EgTOU7PMe.3jaMwFsumdweJcnY3TsTqyuJEdSaSKxdgwYchAwUJ1C 有盐值 格式:{encodingId}{salt}密码 例如:{MD5}{5Hstj}0758f7131c6c95c8e3df05e1ac50214c 五、升级zlt-register到2.0.1 zlt-register/nacos替换为官方最新的2.0.1版本 内容与官网一致,只是方便大家直接使用 项目地址 Gitee地址:https://gitee.com/zlt2000/microservices-platform Github地址:https://github.com/zlt2000/microservices-platform 项目文档 https://www.kancloud.cn/zlt2000/microservices-platform/919417 项目更新日志 https://www.kancloud.cn/zlt2000/microservices-platform/93623

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

zlt-mp v4.4.0 发布,基于 Spring Cloud Alibaba 的微服务平台

功能介绍 更新内容 特性/增强 新增工程zlt-oss-spring-boot-starter 新增工程zlt-zookeeper-spring-boot-starter 新增Zookeeper分布式锁 优化日志埋点工具类 升级zlt-register/nacos到2.0.0 内容说明 一、新增工程oss-starter 既支持各种 「S3」 协议的对象存储如 阿里云OSS、七牛云OSS、MinIO 等,同时也支持阿里的 FastDFS。 配置S3: zlt: file-server: type:s3 s3: access-key:${zlt.s3.access-key} accessKeySecret:${zlt.s3.accessKeySecret} endpoint:${zlt.s3.endpoint} bucketName:${zlt.s3.bucketName} 使用S3 @Resource privateS3Templates3Template; s3Template.upload(...); 配置FastDFS: zlt: file-server: type:fastdfs fdfs: web-url:${zlt.fdfs.web-url} fdfs: trackerList:${zlt.fdfs.trackerList} 使用FastDFS @Resource privateFdfsTemplatefdfsTemplate; fdfsTemplate.upload(...); 二、新增工程zookeeper-starter 集成 curator 客户端 配置: zlt: zookeeper: connectString:127.0.0.1:2181 三、新增zookeeper分布式锁 依赖: <dependency> <groupId>com.zlt</groupId> <artifactId>zlt-zookeeper-spring-boot-starter</artifactId> </dependency> 配置: zlt: lock: lockerType:ZK 手动加锁: //lock try( ZLocklock=locker.lock("test"); ){ //......业务逻辑 } //tryLock try( ZLocklock=locker.tryLock("test",10,TimeUnit.SECONDS); ){ if(lock!=null){ //......业务逻辑 } } 注解加锁: /** *等同于locker.lock("test") */ @Lock(key="test") publicvoidtest(){} /** *等同于locker.tryLock("test",10,TimeUnit.SECONDS) */ @Lock(key="test",waitTime=10) publicvoidtest2(){} 四、优化日志埋点工具类 埋点工具类 PointUtil 新增 「builder」 模式,如下代码所示: Mapproperties=newHashMap(2); properties.put("key1","value1"); properties.put("key2","value2"); PointUtil.builder() .id(1) .type("test") .properties(properties) .build(); 输出日志:2021-04-03 23:18:19.112|user-center|1|test|key1=value1&key2=value2 五、升级zlt-register到2.0.0 zlt-register/nacos 替换为官方最新的 2.0.0 版本 内容与官网一致,只是方便大家直接使用 项目地址 Gitee地址:https://gitee.com/zlt2000/microservices-platform Github地址:https://github.com/zlt2000/microservices-platform 项目文档 https://www.kancloud.cn/zlt2000/microservices-platform/919417 项目更新日志 https://www.kancloud.cn/zlt2000/microservices-platform/936235

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

zlt-mp v4.3.0 发布,基于 Spring Cloud Alibaba 的微服务平台

功能介绍 更新内容 特性/增强 登录同应用同账号互踢 增加集成Dubbo的demo 优化日志链路追踪代码 优化oauth2授权错误处理 升级zlt-register/nacos到1.4.1 升级spring-boot到2.3.8.RELEASE 升级spring-cloud到Hoxton.SR9 升级spring-cloud-alibaba到2.2.5.RELEASE 升级spring-boot-admin到2.3.1.RELEASE 升级redisson到3.14.1 升级transmittable到2.12.0 升级elasticsearch到7.10.2 升级spring-data-elasticsearch到4.1.3 内容说明 一、登录同应用同账号互踢 实现了在同一个应用id下,不同的浏览器使用相同的用户名登录,相互互踢。 在zlt-uaa中通过参数isSingleLogin来配置是否开启功能,默认为false为可以同时登录,改为true则会互踢 zlt: uaa: isSingleLogin:true 二、增加集成Dubbo的demo 新增Spring Cloud集成Dubbo的样例工程zlt-demo/dubbo-demo 测试步骤如下: 启动Nacos 修改dubbo-demo里bootstrap.yml文件的server-addr参数 启动dubbo-demo 访问http://127.0.0.1:8091/test/abc PS:集成Spring Cloud Gateway的方式请参考《Dubbo想要个网关怎么办?试试整合Spring Cloud Gateway》 三、优化日志链路追踪代码 同时支持Feign与Dubbo的日志全链路追踪 新增Dubbo过滤器,传递traceId,上游负责传递,下游负责接收并存到MDC中 四、升级zlt-register到1.4.1 zlt-register/nacos替换为官方最新的1.4.1版本 内容与官网一致,只是方便大家直接使用 项目地址 Gitee地址:https://gitee.com/zlt2000/microservices-platform Github地址:https://github.com/zlt2000/microservices-platform 项目文档 https://www.kancloud.cn/zlt2000/microservices-platform/919417 项目更新日志 https://www.kancloud.cn/zlt2000/microservices-platform/936235

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

区块链底层平台PlatONE的共识算法机制(IBFT)及其实现方法简介

一、概述 由万向区块链和生态合作伙伴联合打造的支持隐私计算的区块链联盟链“PlatONE”中的共识为高度优化的BFT类共识算法,其容错率为1/3,在保留即时确认(instant finality)的关键特性的同时,极大地提高了去中心化的程度。共识可以保证上链的区块是确定的,也就是说链不会出现分叉,同时每一个有效的区块都会插入到链上。 PlatONE的共识支持超过100个共识节点。相对于其他一些常见的BFT共识,PlatONE 的共识的性能有显著的提升。在10个共识节点的情况下,TPS接近1000。 PlatONE的共识运行的相关参数可以灵活地进行配置,并且PlatONE的共识中的共识节点集合可以灵活地进行更新。近期计划支持共识的插件化,以及共识的可审计性等。 PlatONE共识是在 round 上进行的。在特定的 round 上,通过预先设置的策略选取一个出块者节点。出块者节点的选取策略目前支持两种:round robin 和 sticky proposer。 出块者节点提议区块后,各共识节点进行共识。共识分三阶段,其中后两个阶段为投票阶段,用以保证 Safety。PlatONE 共识使用 round change 机制结合锁定和解锁机制来保证共识的的 liveness 。通过优化解锁机制,解决了业界多个知名项目内存在的共识死锁问题。 PlatONE 共识会为每一个链上的区块生成共识证明,也就是对于该区块的各共识节点的有效签名,因而区块可以进行自验证,同时也能支持轻节点。 区块中如果不包含交易,则称为空区块。PlatONE 目前支持不出空区块,也就是上链的区块中都含有交易。不出空区块的机制可以有效地节省区块链占用的存储空间。 以下具体介绍 PlatONE 中的共识算法。 二、共识节点选取机制 节点的类型和状态 节点分为共识节点(validator)和观察员节点两种类型。对于共识节点来说,存在两种状态:正常和隔离。只有处于正常状态的共识节点才可以参与共识和打包区块。 共识节点的选取机制 节点管理(NodeManager)系统合约设计用于存储和管理节点信息。可以通过节点申请(NodeRegister)系统合约申请注册共识节点,审核通过后,申请节点的类型会更新为共识节点,更新后的节点信息存储在节点管理合约中,并且可被查询。 管理员可以根据需要更新共识节点的状态,来决定共识节点是否可以参加共识。 共识节点集合的获取 链上每次产生新区块后,节点管理合约中最新的节点信息都会被读取,并且最新的共识节点集合会被保存下来,并被共识引擎读取和使用。 三、共识流程 3.1. 正常流程 3.1.1. 定义 以下是一些重要术语或概念的定义。 +2/3表示"超过 2/3". NEW ROUND: 新的round中会确定一个新的区块提议者(比如采用round robin算法),在新的round开始时,各共识节点等待接收PRE-PREPARE消息。 PRE-PREPARED: validator节点接收到了PRE-PREPARE消息,同时广播PREPARE消息之后进入这种状态。之后,validator节点等待并接收+2/3的PREPARE或COMMIT消息。(注:有的validator节点因锁定在提议区块上,会在收到PRE-PREPARE消息后直接广播COMMIT消息。因此,这里validator节点等待并接收PREPARE或COMMIT消息) PREPARED: validator节点接收到了+2/3的PREPARE消息,同时广播COMMIT消息之后进入这种状态。之后,validator节点等待并接收+2/3的COMMIT消息。 COMMITTED: validator节点接收到了+2/3的COMMIT消息,进入到这种状态。此时,可以将提议的区块插入到区块链上了 FINAL COMMITTED: 新的区块成功上链后,validator节点进入到这种状态。此时,节点准备进入下一个round ROUND CHANGE: validator节点等待接收+2/3的、针对同一个提议round的ROUND CHANGE消息 3.1.2. 选取proposer的规则 Round robin 算法(目前采用的) Sticky proposer 3.1.3. 共识流程(三阶段协议) 共识流程由三个阶段组成:PRE-PREPARE,PREPARE和COMMIT,也称为三阶段协议。 PRE-PREPARE阶段: 每次进入到一个新的round时,就会开始三阶段中的第一个阶段,即PRE-PREPARE阶段。在该阶段中,Proposer(区块提议者)节点生成一个提议区块,并广播给所有的validator节点。接着Proposer节点进入到PRE-PREPARED状态。其他validator 节点接收到有效的PRE-PREPARE消息后进入到PRE-PREPARED状态。 PREPARE阶段: 在这一阶段,validator 节点广播PREPARE消息给其他validator 节点,并等待接收+2/3的有效的PREPARE消息从而进入到PREPARED状态。 COMMIT阶段: 在这一阶段,validator 节点广播COMMIT消息给其他validator 节点,并等待接收+2/3的有效的COMMIT消息从而进入到COMMITTED状态。 以上三阶段完成后,整个共识流程就成功完成了。 3.1.4. 状态迁移: 下图描述了PlatONE的共识流程的状态迁移过程。 NEW ROUND->PRE-PREPARED: (对应于2.1.3节中的PRE-PREPARE阶段) Proposer从txpool中收集交易。 Proposer生成一个提议区块并广播给其他validator节点,接着就进入到PRE-PREPARED状态。 每一个validator节点接收到满足如下条件的PRE-PREPARE消息后,进入到PRE-PREPARED状态: 提议区块来自于有效的proposer节点。 区块头有效 提议区块的sequence(高度)和round和validator节点的当前状态一致。 Validator节点广播PREPARE消息给其他validator节点。 PRE-PREPARED->PREPARED: (对应于2.1.3节中的PREPARE阶段) Validator接收到+2/3的有效的PREPARE消息,从而进入到PREPARED状态。有效的消息需要满足如下条件: sequence 和 round 相一致 区块哈希一致 消息来自于已知的validator节点 Validator节点在进入到PREPARED状态后,广播COMMIT消息。 PREPARED->COMMITTED: (对应于2.1.3节中的COMMIT阶段) Validator接收到+2/3的有效的COMMIT消息,从而进入到COMMITTED状态。有效的消息需要满足如下条件: sequence 和 round 相一致 区块哈希一致 消息来自于已知的validator节点 COMMITTED->FINAL COMMITTED: Validator节点将+2/3的commitment签名(committed seal)添加到区块头的extraData字段中,并尝试将区块插入到区块链中。 区块上链成功后,Validator节点进入到FINAL COMMITTED状态。 FINAL COMMITTED->NEW ROUND: 各Validator节点选取出一个新的proposer节点,并启动一个新的round定时器。 3.2. Round change 机制 以下三种条件都会触发ROUND CHANGE: Round change定时器超时触发 无效的PREPREPARE消息 区块上链失败 3.2.1. round change 的流程 当一个validator节点检测到以上round change触发条件之一满足时,将会广播ROUND CHANGE消息,其中包含要变更到的目标round数值,同时等待接收来自其他validator节点的ROUND CHANGE消息。目标round的数值基于以下条件选取: 如果validator节点已经从其他peer节点接收到了ROUND CHANGE消息,则从所有数量达到F + 1的ROUND CHANGE消息中包含的round数值中选取出最大的那个数值 否则,将目标round的数值设置为:当前的round数值+1 任何时候,如果一个validator节点接收到了F + 1条含有相同的目标round数值的ROUND CHANGE消息,就会将该round数值和其自己的进行比较。如果接收到的数值更大,validator节点就再次广播ROUND CHANGE消息,而消息中的round数值和接收到的相同。 一旦validator节点接收到了2F + 1条带有相同round数值的ROUND CHANGE消息,则结束round change循环,确定出新的proposer节点,之后进入到NEW ROUND状态。 触发validator节点退出round change循环的另外一个条件是其通过p2p同步机制同步到验证后的区块。 3.3. 区块锁定机制 锁定区块的触发条件 节点锁定在区块B、round numberR的含义是指,当前节点只能对区块B的信息投commit票 。当一个节点收到了+2/3个对区块B的PREPARE投票后,进入PREPARED状态。此时,节点被锁定,等待接收其他节点的commit投票信息,锁定的round即当前round; 锁定区块的机制 除了共识起始阶段,当收到更高区块的同步数据时,或当前高度成功产生区块并达成共识时,锁定被状态重置为非锁定状态,并开始新一轮对更高区块共识。如未能在锁定期间收到+2/3个指定round和区块的commit投票,则触发ROUND CHANGE。并且,在特定场景下,原有锁定解锁机制还会出现死锁的情况,我们在代码层面也优化了相关的解锁实现。具体可参考「2. 对Istanbul锁定解锁机制的优化」。 3.4. Consensus proof 目前的存储机制 区块上链前,每个validator节点需要收集2F + 1个committed seal以构成一个consensus proof(共识证明)。一旦validator节点接收到足够的committed seal,就会将其存储于区块头的extraData字段中IstabulExtra结构中CommittedSeal字段中,并重新计算extraData字段,然后将区块插入到区块链中。 Committed seal计算过程如下: Committed seal的计算: 每个validator节点使用其私钥对区块哈希级联上commit消息代码COMMIT_MSG_CODE的结果进行签名,得到签名即为Committed seal: Committed seal:SignECDSA(Keccak256(CONCAT(Hash, COMMIT_MSG_CODE)), PrivateKey) CONCAT(Hash, COMMIT_MSG_CODE): 将区块哈希和commit消息代码COMMIT_MSG_CODE进行级联 PrivateKey: 进行签名的validator节点的私钥 上面提到的extraData是区块头的一个字段,其数据组成为:EXTRA_VANITY | ISTANBUL_EXTRA,其中|用以表示分隔EXTRA_VANITY和ISTANBUL_EXTRA的固定的索引(不是一个实际的分隔字符)。 IstabulExtra结构的类型定义如下: type IstanbulExtra struct { Validators []common.Address //Validator addresses Seal []byte //Proposer seal 65 bytes CommittedSeal [][]byte //Committed seal, 65 * len(Validators) bytes } 其中,各字段的含义如下: + Validators:参与共识的各validator节点的列表 + Seal:Proposer 节点对区块的签名,长度为65字节 + CommittedSeal:用于存储validator节点收集到的committed seal列表。

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

zlt-mp v4.1.0 发布,基于 Spring Cloud Alibaba 的微服务平台

功能介绍 更新内容 特性/增强 优化分布式锁增加自动解锁功能 优化swagger-ui替换为knife4j 更新 seata-demo 的代码适配 seata1.3 完善 web-sso 单点登录demo添加state参数验证,防止CSRF攻击 升级spring-boot到2.2.8.RELEASE 升级spring-cloud到Hoxton.SR7 升级spring-boot-admin到2.2.4.RELEASE 问题修复 [#I1OEEN] 修复改为jwt token类型无效的问题 [#I1P1IL] 优化sc-gateway的异常处理返回状态码 内容说明 一、优化分布式锁增加自动解锁功能 使用编码的方式手动加锁,可以使用 try-with-resource 机制自动解锁 //lock try( ZLocklock=locker.lock("test"); ){ //......业务逻辑 } //tryLock try( ZLocklock=locker.tryLock("test",10,TimeUnit.SECONDS); ){ if(lock!=null){ //......业务逻辑 } } 二、swagger-ui 替换为 knife4j 文档访问页面改为以下地址: http://127.0.0.1:9900/doc.html 三、更新 seata-demo 的代码适配 seata1.3 依赖测试环境 mysql 5.7 seata 1.3 nacos 1.3 详情请看demo里面的README.md 项目地址 Gitee地址:https://gitee.com/zlt2000/microservices-platform Github地址:https://github.com/zlt2000/microservices-platform 项目文档 https://www.kancloud.cn/zlt2000/microservices-platform/919417 项目更新日志 https://www.kancloud.cn/zlt2000/microservices-platform/936235

资源下载

更多资源
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应用均可从中受益。

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等操作系统。

用户登录
用户注册