首页 文章 精选 留言 我的

精选列表

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

JAVA性能测试初体验

序言:做自动化测试的时候,一直没想过要去做性能,等到现在做性能的时候,才明白这本身就是一个必须都要经历的过程,就像编程一样,编写小型软件的时候,我们不用过多关注架构和性能,但是等成长到一定时候,就会需要关注软件的可复用性(这是由开发成本决定,这点可以在软件架构上去改善,常说的自动化框架也是为了增强脚本的可复用性和可维护性)、性能瓶颈(这是由系统资源成本决定,空间和时间的调配)、可测试行(这能大大提高测试人员的测试效率,很多时候我们要求开发提供一种测试的接口来方便测试人员进行测试)、可部署性(利用make、ant或者maven,能够大大提高软件发布效率,这也是持续集成中的一种手段)等,因此,测试中的发展其实可以有很多的,不仅关注测试手段,还要关注如何在更多的途径上提高测试效率。下面是对本次性能测试项目至今的一些简单总结,欢迎指正。 一、性能测试项目的背景 性能测试缘起于产品存在大量背景数据时,程序响应时间过慢,而且在特定的情况下有可能会造成一些数据上报丢失,所以需要定位。 产品为C/S架构,采用的协议是snmp协议,运行在jvm上。 二、性能测试的策略 1、测试目的的确定 1)系统监控,包括cpu、内存、线程使用情况,在大数据情况下,发现问题,帮助修正代码结构,系统结构,提高系统的运行效率。 2)确定软件运行资源需求指标。 2、性能测试指标确定 1)确定指标来源,主要包括:产品规格、行业标准、客户需求与故障场景等 2)确定测试特性,例如:系统容量、及时性、稳定性、抗压性、资源利用性等,这些特性可以根据行业性能测试特性以及产品的相关特性来决定。 3)确定具体指标,包括数目和单位。 3、性能测试技术储备 其实性能测试可以算得上是自动化测试的一种大数据测试 1)测试场景准备:准备测试场景,可以理解为对背景数据的构造,其实可以将这种构造理解为另类的接口测试,例如:我们的软件服务器是应用SNMP协议进行通信,设备端有一个agent,专门用来与软件服务器端通信,那么可以虚拟出这么一个agent,保存相应的设备信息,虚拟过程可以通过对在网的实际设备进行录制,然后生成。 互联网中,客户端与服务器的交涉是基于http接口协议,其一般的性能测试都是发送大量的http请求,其实这种过程有一个问题就是无法模拟真实的背景数据,因为报文过于单一,而印象很深的是新浪一位朋友开发的tcpcopy工具,在传输层,将线上数据复制到测试场景下,从而成功模拟了真实场景环境,这是一种很好的测试方法。 (还有一种准备工作就是对测试服务器的选型,包括操作系统类型、CPU内核数目、内存数目等) 2)测试数据准备:这其实就是接口数据,在互联网中,这方面的模拟比较简单,用很多工具,例如LR、jmeter、soaupi等都可以成功构造模拟http报文,从而查看服务器的响应。因为我们采用的是snmp协议,所以业内没有这样的snmp接口工具,所以就自己基于snmp协议包开发了其snmp报文模拟工具。 3)性能测试监控:性能测试过程中,对软件系统服务器的监控是关键,例如:web测试中,往往会对web服务器和数据库服务器、操作系统的指标性能进行监控,因为我们的软件是运行在jvm上,所以直接采用jconsole或者jprofiler监控服务器的内存使用、cpu使用、各个线程使用情况,还有对数据库和操作系统的监控等。 4、性能测试方法 1)基于指标,进行测试数据构造测试,查看系统是否工作正常以及监测是否没有问题。 2)基于指标,在基于测试数据测试的同时,由测试人员参与进行操作,测试在特定环境下的系统工作情况。 3)客户场景模拟测试。 4)随机测试,利用算法进行大量随机数据构造。 三、性能测试调优 1、性能测试是一个不断探索和不断完善的一个测试过程。 调优步骤:衡量系统现状、设定调优目标、寻找性能瓶颈、性能调优、衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈)、性能调优结束 2、衡量现状,系统性能主要存在问题 1)内存泄露 2)内存占用过大,响应速率慢 3)线程数不断增加,出现死锁或空闲线程 4)某些类实例化数目过多,占用多余的内存空间 3、内存泄露 1)检验方式:内存泄露需要进行时长测试,既将监控界面及系统界面全部打开,进行长时间运行(如12小时),观察系统类的增长情况。 2)问题定位:若出现JVM的Heap持续增长或者Memory views经过时长测试,出现较大规模的红色部分(增长部分),且无法GC。 4、系统内存占用大 1)检验方式:进行某些特定的操作,系统进行大量内存占用或者数据读写操作。 2)问题定位:若系统内存数突发性的增长,且之后不回落,说明某些模块在持续性的占用系统资源。或者出现JVM的Heap有增长,虽不是持续增长,但一直无法回落。 5、线程数目过多或死锁 1)检验方式:进行某些特定的操作,可以使系统产生大量线程操作。 2)问题定位:若系统线程数突发性的增长或持续增长,且之后不回落,说明某些模块在持续性的占用线程。或者观察是否有许多线程来自同一个模块、长期处于waiting或block状态 6、性能调优原则 调优过程中,充分而不过分使用硬件资源、不要一遇到问题就去改善资源环境,然后,合理调整JVM,需要重点掌握一些JVM的参数,并且要善于分析系统架构和JVM的底层工作机制。 总结:性能测试是一个很漫长的过程,不管是做JVM性能测试、WEB架构方面的性能测试,其实道理是相通的,个人觉得,要做好性能测试,不仅要对测试理解,更要对软件架构和底层的服务器工作机制特别理解,不然,往往,你只能去简单做一些所谓的性能测试操作,但是却无法针对很多场景提供有效的测试策略和调优建议。好的性能测试工程师应该是能够快速搭建场景定位问题、提供指标,并且能够对软件系统架构提出有效建议。共勉之 ====================================分割线================================ 最新内容请见作者的GitHub页:http://qaseven.github.io/

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

用Java代码调用MaxCompute

MaxCompute的客户端的工具odpscmd是好东西,什么都能干。但是它不方便在自己的代码做很好的集成,毕竟它是个Shell脚本。那有什么办法把MaxCompute的作业、设置和自己的代码做无缝集成呢,MaxComput SDK就能干这个。本文就实际的工作中最常见的几个场景,做一些示例。详细的使用可以在Maven上下到SDK的文档说明。其实这里面的很多写法都是文档里有的,或者在帮助文档里有写过类似的例子。这里就做算是做个整理吧。 对象操作 其实官方的SDK文档里,对这方面的介绍是最多的了,可以参考这里。这里我再针对实际场景里的比较多的创建表和分区做个例子,相信看完这些后对这方面就没有疑惑了 String access_id = "your access id"; String access_key =

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

Java面向对象深入篇

1)成员变量和局部变量的区别(本篇学习王伟和传智刘意) 1.1)在类中的位置不同 成员变量:类中方法外 局部变量:方法定义中或者方法声明上 1.2)在内存中的位置不同 成员变量:在堆中 局部变量:在栈中 1.3)生命周期不同 成员变量:随着对象的创建而存在,随着对象的消失而消失 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失 1.4)初始化值不同 成员变量:有默认值 局部变量:没有默认值,必须定义,赋值,然后才能使用 2)构造器(构造方法、构造函数) [<modifier>] <class_name> ( [<type arg_name >, ..]) { [<statements>] } 2.1)格式: 2.1.1)方法名和类名相同 2.1.2)没有返回值类型,连void都不能有 2.1.3)没有返回值 2.2)构造器特点: 2.2.1)一个类可以有多个构建器,但这些构造器的参数列表必须不同 2.2.2)每个类都会至少有一个构造器,如果没有定义构造器,则系统将自动提供一个默认的不带任何参数的构造器,如果类没有定义构造器,可以用这个默认的构造起来生成一个对象.推荐:永远手动自己给出无参构造方法。 2.3)构造器的作用 用于对对象的数据进行初始化。通过构造器来创建对象,使用new 关键字来创建一个对象new后面调用的是类中的一个构造器。 2.4)给成员变量赋值的方式 2.4.1)setXxx() 2.4.2)带参构造方法 2.5)案例 classStudent{ privateStringname; privateintage; publicStudent(){} publicStudent(Stringname,intage){ this.name=name; this.age=age; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } } 2.5.1)测试 classStudentDemo{ publicstaticvoidmain(String[]args){ //方式1 Students1=newStudent(); s1.setName("张三"); s1.setAge(27); System.out.println(s1.getName()+"---"+s1.getAge()); //方式2 Students2=newStudent("李四",30); System.out.println(s2.getName()+"---"+s2.getAge()); } } 2.5.2)Student s = new Student();做了哪些事情? (1)把Student.class文件加载到内存 (2)在栈内存为s开辟空间 (3)在堆内存为学生对象申请空间 (4)给学生的成员变量进行默认初始化。null,0 (5)给学生的成员变量进行显示初始化。林青霞,27 (6)通过构造方法给成员变量进行初始化。刘意,30 (7)对象构造完毕,把地址赋值给s变量 3、this关键字 3.1)代表当前类的引用对象 哪个对象调用方法,该方法内部的this就代表那个对象 3.2)this的应用场景: 3.2.1)解决了局部变量隐藏成员变量的问题 3.2.2)其实this还有其他的应用 4:封装 4.1)隐藏实现细节,提供公共的访问方式 4.2)好处: A:隐藏实现细节,提供公共的访问方式 B:提高代码的复用性 C:提高代码的安全性 4.3)设计原则 把不想让外界知道的实现细节给隐藏起来,提供公共的访问方式 4.4)private是封装的一种体现。 封装:类,方法,private修饰成员变量 4.5)private关键字 私有的意义,可以修饰成员变量和成员方法 4.5.1)特点: 被private修饰的后的成员只能在本类中被访问 4.5.2)private的应用: 以后再写一个类的时候: 把所有的成员变量给private了 提供对应的getXxx()/setXxx()方法 5、static关键字(理解) 5.1)静态的意思。可以修饰成员变量和成员方法。 5.2)静态的特点: A:随着类的加载而加载 B:优先与对象存在 C:被类的所有对象共享 这其实也是我们判断该不该使用静态的依据。 D:可以通过类名调用 既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。 5.3)静态的内存图 静态的内容在方法区的静态区 5.4))静态的注意事项; A:在静态方法中没有this对象 B:静态只能访问静态(代码测试过) 5.5)静态变量和成员变量的区别 A:所属不同 静态变量:属于类,类变量 成员变量:属于对象,对象变量,实例变量 B:内存位置不同 静态变量:方法区的静态区 成员变量:堆内存 C:生命周期不同 静态变量:静态变量是随着类的加载而加载,随着类的消失而消失 成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失 D:调用不同 静态变量:可以通过对象名调用,也可以通过类名调用 成员变量:只能通过对象名调用 5.6)main方法是静态的 public:权限最大 static:不用创建对象调用 void:返回值给jvm没有意义 main:就是一个常见的名称。 String[] args:可以接收数据,提供程序的灵活性 成员变量、局部变量和静态变量的区别 http://blog.csdn.net/haovip123/article/details/43883109

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

java.lang.UnsatisfiedLinkError异常

显然,这是由于读取不到so文件导致的异常。 我尝试了如下方法: 1.检查了jniLibs目录下的文件结构和so文件,都稳稳的躺在那儿; 2.试图使用如下方式重新指定目录,依然无果 sourceSets { main { jniLibs.srcDirs = ['libs'] } } 3.请教提供so文件的开发同学是否与targetSdkVersion等有关系,并且试图配置了和他们一样的version 4.Clean Project 和 Rebuild Project 5.反编译查看apk中的libs目录下确实也存在so文件 然而,并无卵用! 奇怪的是这个异常在真机(OnePlus2,HUAWEI MATE8)上有,而在模拟器上却安然无恙。 于是乎,查看到OnePlus2的CPU架构是CPU_ABI=arm64-v8a。 翻阅到一篇相关文章描述到: 对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹: 如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常 如上图1,本地库不存在arm64-v8a文件夹,反编译apk后发现确实存在此目录,显然是由于其他aar的引入会生成此目录存放相关so文件。 过滤掉此目录 defaultConfig { //省略其余配置 ndk { //这句话的意思是指定ndk需要兼容的架构,其余文件夹so文件全部过滤掉 abiFilters "armeabi", "armeabi-v7a", "x86" } } 这么个问题,两天的光景没了!蓝瘦,香菇。 关于abiFilters的使用

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

[ElasticSearch]Java API之TermQuery

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/52852483 1. 词条查询(Term Query) 词条查询是ElasticSearch的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条。term 查询 会查找我们设定的准确值。term 查询本身很简单,它接受一个字段名和我们希望查找的值。 下面代码查询将匹配 college 字段中含有"California"一词的文档。记住,词条查询是未经分析的,因此需要提供跟索引文档中的词条完全匹配的词条。请注意,我们使用小写开头的california来搜索,而不是California,因为California一词在建立索引时已经变成了california(默认分词器)。 // Query TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("country", "AWxhOn".toLowerCase()); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(termQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-term-query.html 2. 多词条查询(Terms Query) 词条查询(Term Query)允许匹配单个未经分析的词条,多词条查询(Terms Query)可以用来匹配多个这样的词条。只要指定字段包含任一我们给定的词条,就可以查询到该文档。 下面代码得到所有在 country 字段中含有 “德国” 或 "比利时" 的文档。 // Query TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("country", "比利时", "德国"); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(termsQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-terms-query.html 3. 范围查询(Range Query) 范围查询使我们能够找到在某一字段值在某个范围里的文档,字段可以是数值型,也可以是基于字符串的。范围查询只能针对单个字段。 方法: (1) gte() :范围查询将匹配字段值大于或等于此参数值的文档。 (2) gt() :范围查询将匹配字段值大于此参数值的文档。 (3) lte() :范围查询将匹配字段值小于或等于此参数值的文档。 (4) lt() :范围查询将匹配字段值小于此参数值的文档。 (5) from() 开始值 to() 结束值 这两个函数与includeLower()和includeUpper()函数配套使用。 (6) includeLower(true) 表示 from() 查询将匹配字段值大于或等于此参数值的文档。 (7) includeLower(false) 表示 from() 查询将匹配字段值大于此参数值的文档。 (8) includeUpper(true) 表示 to() 查询将匹配字段值小于或等于此参数值的文档。 (9) includeUpper(false) 表示 to() 查询将匹配字段值小于此参数值的文档。 // Query RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age"); rangeQueryBuilder.from(19); rangeQueryBuilder.to(21); rangeQueryBuilder.includeLower(true); rangeQueryBuilder.includeUpper(true); //RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gte(19).lte(21); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(rangeQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); 上面代码中的查询语句与下面的是等价的: QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gte(19).lte(21); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-range-query.html 4. 存在查询(Exists Query) 如果指定字段上至少存在一个no-null的值就会返回该文档。 // Query ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery("name"); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(existsQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 举例说明,下面的几个文档都会得到上面代码的匹配: { "name": "yoona" } { "name": "" } { "name": "-" } { "name": ["yoona"] } { "name": ["yoona", null ] } 第一个是字符串,是一个非null的值。 第二个是空字符串,也是非null。 第三个使用标准分析器的情况下尽管不会返回词条,但是原始字段值是非null的(Even though the standard analyzer would emit zero tokens, the original field is non-null)。 第五个中至少有一个是非null值。 下面几个文档不会得到上面代码的匹配: { "name": null } { "name": [] } { "name": [null] } { "user": "bar" } 第一个是null值。 第二个没有值。 第三个只有null值,至少需要一个非null值。 第四个与指定字段不匹配。 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-exists-query.html 5. 前缀查询(Prefix Query) 前缀查询让我们匹配这样的文档:它们的特定字段已给定的前缀开始。下面代码中我们查询所有country字段以"葡萄"开始的文档。 // Query PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("country", "葡萄"); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(prefixQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 备注: 进行下面前缀查询,没有查找到相应信息,但是数据源中是有的: QueryBuilder queryBuilder = QueryBuilders.prefixQuery("club", "皇家马德里"); 产生以上差别的主要原因是club字段(默认mapping配置)进行了分析器分析了,索引中的数据已经不在是"皇家马德里",而country字段没有进行分析(mapping配置not_analyzed)。 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-prefix-query.html 6. 通配符查询(Wildcard Query) 通配符查询允许我们获取指定字段满足通配符表达式的文档,和前缀查询一样,通配符查询指定字段是未分析的(not analyzed)。 可以使用星号代替0个或多个字符,使用问号代替一个字符。星号表示匹配的数量不受限制,而后者的匹配字符数则受到限制。这个技巧主要用于英文搜索中,如输入““computer*”,就可以找到“computer、computers、computerised、computerized”等单词,而输入“comp?ter”,则只能找到“computer、compater、competer”等单词。注意的是通配符查询不太注重性能,在可能时尽量避免,特别是要避免前缀通配符(以以通配符开始的词条)。 // Query WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("country", "西*牙"); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(wildcardQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-wildcard-query.html 7. 正则表达式查询(Regexp Query) 正则表达式查询允许我们获取指定字段满足正则表达式的文档,和前缀查询一样,正则表达式查询指定字段是未分析的(not analyzed)。正则表达式查询的性能取决于所选的正则表达式。如果我们的正则表达式匹配许多词条,查询将很慢。一般规则是,正则表达式匹配的词条数越高,查询越慢。 // Query RegexpQueryBuilder regexpQueryBuilder = QueryBuilders.regexpQuery("country", "(西班|葡萄)牙"); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(regexpQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-regexp-query.html 8. 模糊查询(Fuzzy Query) 如果指定的字段是string类型,模糊查询是基于编辑距离算法来匹配文档。编辑距离的计算基于我们提供的查询词条和被搜索文档。如果指定的字段是数值类型或者日期类型,模糊查询基于在字段值上进行加减操作来匹配文档(The fuzzy query uses similarity based on Levenshtein edit distance for string fields, and a +/-margin on numeric and date fields)。此查询很占用CPU资源,但当需要模糊匹配时它很有用,例如,当用户拼写错误时。另外我们可以在搜索词的尾部加上字符 “~” 来进行模糊查询。 8.1 string类型字段 模糊查询生成所有可能跟指定词条的匹配结果(在fuzziness指定的最大编辑距离范围之内)。然后检查生成的所有结果是否是在索引中。 下面代码中模糊查询country字段为”西班牙“的所有文档,同时指定最大编辑距离为1(fuzziness),最少公共前缀为0(prefixLength),即不需要公共前缀。 // Query FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("country", "洗班牙"); // 最大编辑距离 fuzzyQueryBuilder.fuzziness(Fuzziness.ONE); // 公共前缀 fuzzyQueryBuilder.prefixLength(0); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(fuzzyQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 8.2 数字和日期类型字段 与范围查询(Range Query)的around比较类似。形成在指定值上上下波动fuzziness大小的一个范围: -fuzziness <= field value <= +fuzziness 下面代码在18岁上下波动2岁,形成[17-19]的一个范围查询: // Query FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("age", "18"); fuzzyQueryBuilder.fuzziness(Fuzziness.TWO); // Search SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); searchRequestBuilder.setTypes(type); searchRequestBuilder.setQuery(fuzzyQueryBuilder); // 执行 SearchResponse searchResponse = searchRequestBuilder.get(); 参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-fuzzy-query.html 备注: 本代码基于ElasticSearch 2.4.1

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

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

Sublime Text

Sublime Text

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

用户登录
用户注册