首页 文章 精选 留言 我的

精选列表

搜索[CEL策略],共10000篇文章
优秀的个人博客,低调大师

Let's Encrypt​​​​​​​ 倡议新证书策略,提高抗网络攻击能力

Let’s Encrypt 是一家得到 Mozilla Firefox 和 Google Chrome 支持的自动化证书颁发机构。该机构近日宣布了一项新措施,从而进一步保护用户免受网络攻击的侵害。这项新功能被称为多角度域认证(multi-perspective domain validation),可帮助证书颁发机构(CA)证明申请人对他们想要获得证书的域具有掌控权。 域验证并不是什么新问题,但在验证过程中还存在很多的漏洞,这意味着网络攻击者可以诱使 CA 机构错误地颁发证书。而通过多角度域认证,网络攻击者需要同时破坏三个不同的网络路径,这不仅大大提高了安全系数,而且在互联网拓扑社区中也能更快发现网络攻击行为。 在新闻稿中,Let’s Encrypt 特别感谢了普林斯顿大学的几位研究人员在多角度域验证方面的帮助,并表示将继续与研究人员合作,以改善设计和实施的有效性。 稿源:cnBeta

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

Canonical 制定了针对 Ubuntu 20.04 LTS 的 32 位支持策略

Canonical 的 Ubuntu 工程师与社区成员共同合作确定了他们对 Ubuntu 20.04 LTS 版本的 32 位支持调整。 在放弃最初的建议(即完全清除32 位软件包)之后,Ubuntu 19.10 附带了一组精简的 32 位软件包(32-bit x86),可供 x86_64 用户使用。Ubuntu 19.10 上的那些 32 位软件包基于流行程度进行选取,它们可能仍在现代 Intel/AMD 系统上普遍使用。而对于 Ubuntu 20.04 LTS,正在进行一些小调整。 Ubuntu 社区的这篇帖子列出了计划在 Ubuntu 20.04 LTS 上进行的一些新增和移除。与 libssl 1.0 一样,wine-stable-i386、gcc-8-base 和其他软件包由于过时或其他因素而被移除。与此同时也增加了其他 32 位软件包,其中包括 Freeglut, libv4l, VDPAU 驱动, VA-API 驱动以及其他的各种库。 Ubuntu 开发者 Steve Langasek概述了大约 1700 个 源程序包将在 Launchpad 的 i386 上触发 Ubuntu Focal (20.04) 的构建。即将进行的是一些其他的构建/基础设施变更,以及对其自动打包测试基础设施的改进。 总的来说,Ubuntu 20.04 LTS 对 32 位软件包的支持将与在 Ubuntu 19.10 中使用 Steam 的方式非常相似,并且仍可访问尚未完全属于x86_64 的其他软件包。

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

Spring Cloud Stream消费失败后的处理策略(一):自动重试

之前写了几篇关于Spring Cloud Stream使用中的常见问题,比如: 如何处理消息重复消费 如何消费自己生产的消息 下面几天就集中来详细聊聊,当消息消费失败之后该如何处理的几种方式。不过不论哪种方式,都需要与具体业务结合,解决不同业务场景可能出现的问题。 今天第一节,介绍一下Spring Cloud Stream中默认就已经配置了的一个异常解决方案:重试! 应用场景 依然要明确一点,任何解决方案都要结合具体的业务实现来确定,不要有了锤子看什么问题都是钉子。那么重试可以解决什么问题呢?由于重试的基础逻辑并不会改变,所以通常重试只能解决因环境不稳定等外在因素导致的失败情况,比如:当我们接收到某个消息之后,需要调用一个外部的Web Service做一些事情,这个时候如果与外部系统的网络出现了抖动,导致调用失败而抛出异常。这个时候,通过重试消息消费的具体逻辑,可能在下一次调用的时候,就能完成整合业务动作,从而解决刚才所述的问题。 动手试试 先通过一个小例子来看看Spring Cloud Stream默认的重试机制是如何运作的。之前在如何消费自己生产的消息一文中的例子,我们可以继续沿用,或者也可以精简一些,都写到一个主类中,比如下面这样: @EnableBinding(TestApplication.TestTopic.class) @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @RestController static class TestController { @Autowired private TestTopic testTopic; /** * 消息生产接口 * @param message * @return */ @GetMapping("/sendMessage") public String messageWithMQ(@RequestParam String message) { testTopic.output().send(MessageBuilder.withPayload(message).build()); return "ok"; } } /** * 消息消费逻辑 */ @Slf4j @Component static class TestListener { @StreamListener(TestTopic.INPUT) public void receive(String payload) { log.info("Received: " + payload); throw new RuntimeException("Message consumer failed!"); } } interface TestTopic { String OUTPUT = "example-topic-output"; String INPUT = "example-topic-input"; @Output(OUTPUT) MessageChannel output(); @Input(INPUT) SubscribableChannel input(); } } 内容很简单,既包含了消息的生产,也包含了消息消费。与之前例子不同的就是在消息消费逻辑中,主动的抛出了一个异常来模拟消息的消费失败。 在启动应用之前,还要记得配置一下输入输出通道对应的物理目标(exchange或topic名),比如: spring.cloud.stream.bindings.example-topic-input.destination=test-topic spring.cloud.stream.bindings.example-topic-output.destination=test-topic 完成了上面配置之后,就可以启动应用,并尝试访问localhost:8080/sendMessage?message=hello接口来发送一个消息到MQ中了。此时可以看到类似下面的日志: 2018-12-10 11:20:21.345 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:22.350 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:24.354 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:54.651 ERROR 30499 --- [w2p2yKethOsqg-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Exception thrown while invoking com.didispace.stream.TestApplication$TestListener#receive[1 args]; nested exception is java.lang.RuntimeException: Message consumer failed!, failedMessage=GenericMessage [payload=byte[5], headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=test-topic, amqp_receivedExchange=test-topic, amqp_deliveryTag=2, deliveryAttempt=3, amqp_consumerQueue=test-topic.anonymous.EuqBJu66Qw2p2yKethOsqg, amqp_redelivered=false, id=a89adf96-7de2-f29d-20b6-2fcb0c64cd8c, amqp_consumerTag=amq.ctag-XFy6vXU2w4RB_NRBzImWTA, contentType=application/json, timestamp=1544412051638}] at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:63) at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158) at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132) at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108) at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:203) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$1100(AmqpInboundChannelAdapter.java:60) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.lambda$onMessage$0(AmqpInboundChannelAdapter.java:214) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:211) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1414) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1337) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:817) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:801) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1042) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.RuntimeException: Message consumer failed! at com.didispace.stream.TestApplication$TestListener.receive(TestApplication.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:181) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:114) at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:55) ... 27 more 从日志中可以看到,一共输出了三次Received: hello,也就是说消息消费逻辑执行了3次,然后抛出了最终执行失败的异常。 设置重复次数 默认情况下Spring Cloud Stream会重试3次,我们也可以通过配置的方式修改这个默认配置,比如下面的配置可以将重试次数调整为1次: spring.cloud.stream.bindings.example-topic-input.consumer.max-attempts=1 对于一些纯内部计算逻辑,不需要依赖外部环境,如果出错通常是代码逻辑错误的情况下,不论我们如何重试都会继续错误的业务逻辑可以将该参数设置为0,避免不必要的重试影响消息处理的速度。 深入思考 完成了上面的基础尝试之后,再思考下面两个问题: 问题一:如果在重试过程中消息处理成功了,还会有异常信息吗? 答案是不会。因为重试过程是消息处理的一个整体,如果某一次重试成功了,会任务对所收到消息的消费成功了。 这个问题可以在上述例子中做一些小改动来验证,比如: @Slf4j @Component static class TestListener { int counter = 1; @StreamListener(TestTopic.INPUT) public void receive(String payload) { log.info("Received: " + payload + ", " + counter); if (counter == 3) { counter = 1; return; } else { counter++; throw new RuntimeException("Message consumer failed!"); } } } 通过加入一个计数器,当重试是第3次的时候,不抛出异常来模拟消费逻辑处理成功了。此时重新运行程序,并调用接口localhost:8080/sendMessage?message=hello,可以获得如下日志结果,并没有异常打印出来。 2018-12-10 16:07:38.390 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 1 2018-12-10 16:07:39.398 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 2 2018-12-10 16:07:41.402 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 3 也就是,虽然前两次消费抛出了异常,但是并不影响最终的结果,也不会打印中间过程的异常,避免了对日志告警产生误报等问题。 问题二:如果重试都失败之后应该怎么办呢? 如果消息在重试了还是失败之后,目前的配置唯一能做的就是将异常信息记录下来,进行告警。由于日志中有消息的消息信息描述,所以应用维护者可以根据这些信息来做一些补救措施。 当然,这样的做法显然不是最好的,因为太过麻烦。那么怎么做才好呢?且听下回分解! 代码示例 本文示例读者可以通过查看下面仓库的中的stream-exception-handler-1项目: Github Gitee 如果您对这些感兴趣,欢迎star、follow、收藏、转发给予支持! 以下专题教程也许您会有兴趣 Spring Boot基础教程 Spring Cloud基础教程

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

LAMP架构下的Web开发概念、流程及优化策略(二)

六、目前流行的PHP框架 应用场景二:M (业务模型,应用者编写) C(业务控制器,应用者编写,由框架控制器自动载入) V(视图,应用者编写,框架自动载入) 现实中复杂应用场景: 1.用户请求:http://domain/blog/list/ 2.分析URL,实例化逻辑控制类blog,执行方法list 3.在控制类news中,又分别实例化业务模型类blog和user,并做相应处理. 4.业务模型类blog,user中,调用数据模型(专用,非M层),对数据进行处理. 5.回到逻辑控制类中,展现视图$this->view->output( ); ※运用中需要注意的地方 •PHP没有持久层,每一次访问请求都是独立运行,建立的模型对象不能持久存在,无法跨访问复用.如果框架/应用的设计过于繁琐,每次装载/初始化都会浪费不少时间. •各层之间的耦合度尽量降到最低,尤其是业务模型和业务逻辑之间要尽量分离.以便日后修改或复用. •PHP本身只有较少功能是抛出异常,大部份是抛出错误(Notice,warning,error),代码编写中应时常对应用环境的正确性做手工检查,不符合条件时手工抛出异常,并设置异常接收器统一处理 •单入口模式 http://domain/index.php?control=blog&action=list http://domain/index.php?control=news&action=read •多入口模式 http://domain/blog.php?action=list http://domain/news.php?action=read •PathInfo模式 http://domain/index.php/blog/list/ http://domain/index.php/news/read/ •Rewrite模式 http://domain/blog/list/ http://domain/news/read/ Rewrite及pathinfo的好处:对搜索引擎友好,对用户更直观 九、数据库抽象层、Active recode •数据库抽象层的作用 减少与具体数据库的底层接触,提供跨数据库平台的访问接口,以实现数据操作与数据库类型的无关性.方便数据库系统的迁移变更. •PHP本身提供的抽象层 Pear::DB(php4),PDO(php5,6) •框架中引入的各种类Active Recode系统 目的:将数据库字段与映射到对象,不用关心具体的SQL语句,只需要操作数据对象及调用相关的方法即可实现数据的CRUD操作。 好处:模型化了数据库,快捷开发,是数据库抽象层的进一步进化。 缺点:对于复杂数据模型的处理较为无力,例如多表连查、子查询。 缺乏灵活性,比如只想要一列数据,却取出了整行。 与数据库字段名的耦合度太高。如通过配置改进,执行效率又打折扣。 难以应付复杂的Web环境。(多种数据库,分布式数据库,缓存系统介入) 十、模板引擎 •为什么引入模板引擎 视图:在web开发中通常就是指前端页面。模板引擎的引入,是为了实现视图层的分离,降低视图与逻辑、模型部份的耦合度。使得前端页面与程序部份可以并行工发、轻松整合的工具 •常见的模板引擎及特点 PHP中常用的模板引擎有Smarty, SmartTemplate 其中smarty提供了强劲的功能,STE则非常轻巧。 两者的核心原理,都是将页面中的变量标签替换成通过assign方法注册的PHP运行变量,并将替换后的页面(“编译”后的页面文件)生成缓存保存在磁盘中。或者提供一定的逻辑控制功能供前端使用。这样即方便将程序和视图分离,使前端设计人员更着重于表现和数据,而不用关心程序上的流程. •缺点 初次加载模板时,因生成缓存,需要额外的处理开销和IO开销 之后加载模板时,会判断模板文件的最后修改时间是否大于生成的缓存文件时间,亦有一定的额外IO开销. ※使用模板引擎的注意事项 八、访问模式 •Qee /FleaPHP (领域设计驱动)•ThinkPHP(大的类库J)•Zend Framework(Pear的OOP版)•Yii•KiwiPHP(工业微内核)•Symfony(配置最简单) 七、WEB中的MVC开发模式 应用场景一: M (数据模型,框架提供) C (控制器,框架实现) V (视图,应用者编写,框架自动载入) 应用者编写的,是供控制器装载的业务处理类 •尽量折分公用组件。 •不要在视图中使用太多的控制语句 就以前的经验来看,简单的if,变量循环输出即已足够。 在视图中加入太多的控制语句会带来的问题,是对设计思想的破坏,因为它打乱了将视图层独立出来的最初目的,让前端的设计人员不得不过多的关注“程序”而非页面本身。要不然就得由程序员最终回头修改前端设计人员已经做好的模板文件。 更重要的一点时:如果在模板中引入太多的控制语句,那还不如直接在页面中写<?php ,因为PHP的本身就是模板引擎。无论哪种都快不过它。 所以,尽量将控制放在PHP程序体内,不要放到视图中去跑. 十一、LAMP架构下的加速系统 十二、各级加速系统说明 •WEB服务层 Nginx :自身支持反向代理,提供简单的负载均衡及从错机制,能很方便的搭建起web服务集群. Lighttpd:超轻量,合适搭建静态访问服务器 Squid:对动态内容亦能做缓存处理. •PHP层 APC:缓存opcode,减少了扫描和编译阶段,但仍无法实现持久对象.纯脚本效率提高在200%--500%,应用场景下实测通常能提高效率一倍. XCACHE •数据层 共享内存 Memcache: Key=>Value对形式的内存数据缓存服务.基于TCP连接.常用于缓存数据库查询结果.支持分布式. 缺点:关机即无,每次连接的时间开销大. 推荐的工具 •Editplus+PHP •XDEBUG+Eclipse PDT •SmartTemplate Xdebug+ WinCacheGrind 【本文首发于: 百度运维空间】 http://hi.baidu.com/ops_bd/blog/item/ae1a7b16c2a6b06acb80c4dd.html 【 关注百度技术沙龙】 本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/748346 ,如需转载请自行联系原作者

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

学习.net 2.0需要讲究一下策略

.NET V2.0编程的技术含量比V1.0提高了,也更成熟了.微软和开源社区都提供了许多的框架和接口. 我们是这些框架的用户.我们也有两种编程模式,一种是基于一个著名的开源框架上,开始阅读和全盘吸收,然后动手大改,变成自己的;一种是在著名的框架上,找到接口或黑客接口,从上面开始继承和定制,从而实现自己的。前者是站在巨人的肩膀上的模式,后者是让巨人背着自己的模式,不过微软的架构师更喜欢背着你,可是不是所有的人都喜欢搭顺风车. 下面列出这些框架,一起来思考一下,我的想法是充分利用这两种模式.吸收各自的精华,时刻走在技术的前沿. MS : Enterprise Library, Composite UI Application Block , WSE/WCF , WWF/WinFx ,Altas etc OpenSource : Castle/Sprint.Net, NHibernate/Ibatisnet, etc 本文转自 张善友 51CTO博客,原文链接:http://blog.51cto.com/shanyou/75066,如需转载请自行联系原作者

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

LAMP架构下的Web开发概念、流程及优化策略(一)

架构设计——前端架构•后端架构•视觉体系对接约定——接口约定•标识约定•通讯代码约定开发——建立开发框架•建立数据库•实施编码测试——功能测试•性能测试 一、架构设计 二、对接约定 1、接口约定 约定请求方式(普通HTTP请求,XMLHTTP请求,SOAP请求,phprpc请求)、请求类型(POST,GET,HEADER)、请求地址、请求参数。(前端请求四要素,文档中体现,程序中实现。) 2、标识约定 为确保前后端并行开发,减少开发的时间周期,需要在开发前就做好标识约定,通过文档描述清楚前端模板变量和后端程序变量之间的约定关系,以及后端返回各种状态值的含义。 建议的最佳应用是:后端不对用户视图负责,只管输出状态代码。呈现给用户的视图由前端负责。 三、各类web服务器优缺点比较 •Nginx 优点:原生支持反向代理,带有简单的负载均衡及容错机制。速度最快。(10%-1000%),占用资源很少。 缺点:文档较少,手工配置,只能以fast-cgi方式运行php. •Apache 优点:文档丰富,稳定(!?),应用环境多。 缺点:占用资源较多,高压力下表现性能不如nginx或lighttpd,手工配置。 •IIS 优点:文档丰富,win平台下安装简单配置方便 缺点:不支持跨平台,性能低下。 四、常见web系统组织图 五、PHP在web应用中的特点 •语言弱类型 •脚本运行,生命周期短。 •面向对象与面向过程并存。 •弱效率、重流程、强扩展。 1、PHP的优点 •适合web开发。将web开发中常用的行为、内容做了良好的封装。程序员可以很轻易的使用它们。 •基于脚本的运行方式,修改代码后不需要重新编译,很多情况下也不需要重启服务器。 •开发快捷,部署方便,支持环境众多。 •非常优秀的扩展能力。非常多的扩展子件。 •开发框架众多。对多种数据库支持很好 •良好的社区支持,本身开源。修改容易 2、PHP的缺点 •容易写出坏的代码。(解决方法:严格遵循规范) •效能不高。(解决方法:复杂业务使用C扩展) •每次执行都要经历扫描-编译-执行的阶段,无执久对象模型。(解决方法:使用APC) •命名混乱,参数混乱,得随时翻着手册 3、PHP框架 •对开发者起编码约束作用。 •提供了ORM,使对数据库变成对数据对象的访问,让程序员对数据的处理更加专注于面向对象上. •通过配置(无需改动代码)即能变更服务环境,使得迁移成本减小 •方便程序员实现完整的MVC开发模式.使程序员更专注于业务领域,不再过多关注建立数据模型的底层代码以及处理视图展示. •内置大量开发中的常用工具。可随时调用。也可自己扩展编写。 •本身即由PHP编写。可随时修改以满足达到自己的需求。 【本文首发于: 百度运维空间】 http://hi.baidu.com/ops_bd/blog/item/c2e2f94986ad95ded0c86ad2.html 【 关注百度技术沙龙】 本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/748354 ,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Spring

Spring

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

Sublime Text

Sublime Text

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

WebStorm

WebStorm

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

用户登录
用户注册