首页 文章 精选 留言 我的

精选列表

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

JUC包中的分而治之策略-为提高性能而生

一、前言 本次分享我们来共同探讨JUC包中一些有意思的类,包含AtomicLong & LongAdder,ThreadLocalRandom原理。 二、AtomicLong & LongAdder 2.1 AtomicLong 类 AtomicLong是JUC包提供的原子性操作类,其内部通过CAS保证了对计数的原子性更新操作。 大家可以翻看源码发现内部是通过UnSafe(rt.jar)这个类的CAs操作来保证对内部的计数器变量 long value进行原子性更新的,比如JDK8中: public final long incrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; } 其中unsafe

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

java多线程中显式锁的轮询检测策略

显式锁简介 java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile,java5.0增加了一种新的机制:ReentrantLock。 锁像synchronized同步块一样,是一种线程同步机制,与synchronized不同的是ReentrantLock提供了一种无条件的、可轮询的、定时的以及可以中断的锁获取操作,并且所有的加锁和解锁的方法都是显式的,所以也叫显式锁。 synchronized的实现中包含了锁机制,但是锁的获取和释放不能人为的进行控制,所以当我们要定时获取锁,检测锁是否被占用时就应当使用显式锁。 显式锁涉及的类和接口 ReentrantLock实现了Lock接口,位于Java的J.U.C包中,包含了一下几个主要方法: 1、void lock(),获取锁; 2、void unlock

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

CentOS6 主机安全加固策略 Clamav 杀毒软件

简单说明: 依据《CentOS6实验机模板搭建部署》克隆两台实验机: Server:192.168.77.10 Client:192.168.77.11 依据《CentOS6u9 简单邮件告警部署》在Server主机上部署命令邮件告警 使用EPEL网络YUM源部署升级clamav是想当方便的,建议使用该方案代替源码编译安装 Server主机部署: 1° 使用YUM源安装: # 可以使用网络EPEL源进行yum安装和升级,比源码安装的方式简单太多了 # 这里选择阿里云镜像网站的源: wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo # 安装 yum -y install clamav clamav-db clamd # 升级 yum update clamav clamav-db clamd # 设置开机启动 chkconfig clamd on # 由软件包clamav-db安装的freshclam的病毒库升级默认使用每日系统任务进行 2° 查看这三个安装包分别安装了哪些组件: rpm -ql clamav # 病毒库升级时用到的配置文件 # /etc/freshclam.conf # 安装出来的可执行命令 # 包括bytecode测试命令、扫描和提交 # 病毒库升级和签名以及库管理工具 # /usr/bin/clambc # /usr/bin/clamscan # /usr/bin/clamsubmit # /usr/bin/freshclam # /usr/bin/sigtool # libclamav 相关的库文件 # /usr/lib64/libclamav.so.7 # /usr/lib64/libclamav.so.7.1.1 # 文档和man文档 # 其中/usr/share/doc/clamav-0.99.4/clamdoc.pdf # 就是 User Manual,该文档系统介绍了clamav # 是下篇拆读博文的主角 # /usr/share/doc/clamav-0.99.4/... # /usr/share/man/man*/... rpm -ql clamav-db # 使用系统cron的每日病毒库升级计划 # /etc/cron.daily/freshclam # Linux的日志文件管理工具logrotate的相关配置 # /etc/logrotate.d/freshclam # 病毒库存储目录和初始的病毒库文件 # /var/lib/clamav/... # 病毒库升级日志目录 # /var/log/clamav/freshclam.log rpm -ql clamd # 配置文件和额外的配置文件目录 # /etc/clamd.conf # /etc/clamd.d # Linux的日志文件管理工具logrotate的相关配置 # /etc/logrotate.d/clamav # 系统守护进程脚本 # /etc/rc.d/init.d/clamd # /usr/sbin/clamd # 配置检测命令、扫描命令和命令行监控工具 # /usr/bin/clamconf # /usr/bin/clamdscan # /usr/bin/clamdtop # 文档和man文档 # /usr/share/clamav/... # /usr/share/doc/clamd-0.99.4/... # /usr/share/man/man*/... # 病毒库目录 # /var/lib/clamav # 日志目录和PID以及Socket目录 # /var/log/clamav/... # /var/run/clamav 3° 配置启动: ALERT_EMAIL=XXXX@qq.com # 守护模式配置文件修改 /etc/clamd.conf sed -i "s/127.0.0.1/$(hostname -i)/g" /etc/clamd.conf sed -i 's/^#ExcludePath/ExcludePath/g' /etc/clamd.conf sed -i 's/^User clam/User root/g' /etc/clamd.conf sed -i "s|^#VirusEvent.*$|\ # VirusEvent /bin/echo \"%v\" \| /bin/mailx -s \"ClamAV 探测告警\" $ALERT_EMAIL|g" \ /etc/clamd.conf # 病毒库升级配置文件修改 /etc/freshclam.conf sed -i 's|^#PidFile.*$|PidFile /var/run/clamav/freshclam.pid|g' /etc/freshclam.conf sed -i 's/^#DatabaseMirror.*$/DatabaseMirror db.cn.clamav.net/g' /etc/freshclam.conf sed -i 's/^#Checks 24$/Checks 24/g' /etc/freshclam.conf sed -i 's|^#NotifyClamd.*$|NotifyClamd /etc/clamd.conf|g' /etc/freshclam.conf sed -i "s|^#OnUpdateExecute.*$|\ # OnUpdateExecute /bin/echo \"升级成功\" \|/bin/mailx -s \"ClamAV升级告警\" $ALERT_EMAIL|g" \ /etc/freshclam.conf # 部署后首次升级病毒库 freshclam # 打开病毒库升级的守护进程模式 freshclam -d echo '/usr/bin/freshclam -d'>>/etc/rc.local # 虽然有每日系统任务,但是还是用守护进程模式每小时更新 # 并且保留/etc/cron.daily/freshclam # 防止守护进程模式异常情况出现 # 开启探测服务 /etc/init.d/clamd start # 测试扫描: clamdscan -h clamdscan --quiet -z -m -l /tmp/clamdscan_$(date +%s).log /boot clamdscan --quiet -z -m -l /tmp/clamdscan_$(date +%s).log /tmp/clamav-0.100.0 # 此时依然可以使用源码安装包进行探测测试 # 注意,需要执行 ./configure && make # 不要执行 make install 进行安装 Client主机配置: # 客户机安装配置clamd客户端clamdscan wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo # 只安装clamd客户端clamdscan yum -y install --downloadonly --downloaddir=/tmp clamd rpm -ivh --nodeps /tmp/clamd-0.99.4-1.el6.x86_64.rpm rm -rf /etc/clamd.d rm -rf /etc/logrotate.d/clamav rm -rf /etc/rc.d/init.d/clamd rm -rf /usr/sbin/clamd rm -rf /usr/share/clamav rm -rf /usr/share/doc/clamd-0.99.4 rm -rf /usr/share/man/man1/clam* rm -rf /usr/share/man/man8/clam* rm -rf /var/lib/clamav rm -rf /var/log/clamav rm -rf /var/run/clamav # 使用yum的downloadonly参数只下载安装包 # 然后使用rpm命令忽略依赖,只安装clamd客户端clamdscan # 然后删掉不需要的安装目录和文件 # 修改配置文件,指向server主机 cd /etc cat>clamd.conf<<EOF TCPAddr 192.168.77.10 TCPSocket 3310 EOF # 测试 clamdscan -z -m /boot cp -av /boot/efi/EFI/redhat/grub.efi /tmp clamdscan -z -m /tmp/grub.efi clamdscan --quiet -z -m -l /tmp/clamdscan_$(date +%s).log /tmp/clamav-0.100.0 # 此时依然可以使用源码安装包进行探测测试 # 注意,需要执行 ./configure && make # 不要执行 make install 进行安装

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

java面试-深入理解JVM(三)——垃圾收集策略详解

Java虚拟机的内存模型分为五个部分,分别是:程序计数器、Java虚拟机栈、本地方法栈、堆、方法区。 这五个区域既然是存储空间,那么为了避免Java虚拟机在运行期间内存存满的情况,就必须得有一个垃圾收集者的角色,不定期地回收一些无效内存,以保障Java虚拟机能够健康地持续运行。 这个垃圾收集者就是平常我们所说的“垃圾收集器”,那么垃圾收集器在何时清扫内存?清扫哪些数据?这就是接下来我们要解决的问题。 程序计数器、Java虚拟机栈、本地方法栈都是线程私有的,也就是每条线程都拥有这三块区域,而且会随着线程的创建而创建,线程的结束而销毁。那么,垃圾收集器在何时清扫这三块区域的问题就解决了。 此外,Java虚拟机栈、本地方法栈中的栈帧会随着方法的开始而入栈,方法的结束而出栈,并且每个栈帧中的本地变量表都是在类被加载的时候就确定的。因此以上三个区域的垃圾收集工作具有确定性,垃圾收集器能够清楚地知道何时清扫这三块区域中的哪些数据。 然而,堆和方法区中的内存清理工作就没那么容易了。堆和方法区所有线程共享,并且都在JVM启动时创建,一直得运行到JVM停止时。因此它们没办法根据线程的创建而创建、线程的结束而释放。 堆中存放JVM运行期间的所有对象,虽然每个对象的内存大小在加载该对象所属类的时候就确定了,但究竟创建多少个对象只有在程序运行期间才能确定。方法区中存放类信息、静态成员变量、常量。类的加载是在程序运行过程中,当需要创建这个类的对象时才会加载这个类。因此,JVM究竟要加载多少个类也需要在程序运行期间确定。因此,堆和方法区的内存回收具有不确定性,因此垃圾收集器在回收堆和方法区内存的时候花了一些心思。 堆内存的回收 1. 如何判定哪些对象需要回收? 在对堆进行对象回收之前,首先要判断哪些是无效对象。我们知道,一个对象不被任何对象或变量引用,那么就是无效对象,需要被回收。一般有两种判别方式: 引用计数法每个对象都有一个计数器,当这个对象被一个变量或另一个对象引用一次,该计数器加一;若该引用失效则计数器减一。当计数器为0时,就认为该对象是无效对象。 可达性分析法所有和GC Roots直接或间接关联的对象都是有效对象,和GC Roots没有关联的对象就是无效对象。GC Roots是指: Java虚拟机栈所引用的对象(栈帧中局部变量表中引用类型的变量所引用的对象) 方法区中静态属性引用的对象 方法区中常量所引用的对象 本地方法栈所引用的对象PS:注意!GC Roots并不包括堆中对象所引用的对象!这样就不会出现循环引用。 两者对比:引用计数法虽然简单,但存在一个严重的问题,它无法解决循环引用的问题。因此,目前主流语言均使用可达性分析方法来判断对象是否有效。 2. 回收无效对象的过程 当JVM筛选出失效的对象之后,并不是立即清除,而是再给对象一次重生的机会,具体过程如下: 判断该对象是否覆盖了finalize()方法 若已覆盖该方法,并该对象的finalize()方法还没有被执行过,那么就会将finalize()扔到F-Queue队列中; 若未覆盖该方法,则直接释放对象内存。 执行F-Queue队列中的finalize()方法虚拟机会以较低的优先级执行这些finalize()方法们,也不会确保所有的finalize()方法都会执行结束。如果finalize()方法中出现耗时操作,虚拟机就直接停止执行,将该对象清除。 对象重生或死亡如果在执行finalize()方法时,将this赋给了某一个引用,那么该对象就重生了。如果没有,那么就会被垃圾收集器清除。 注意:强烈不建议使用finalize()函数进行任何操作!如果需要释放资源,请使用try-finally。因为finalize()不确定性大,开销大,无法保证顺利执行。 方法区的内存回收 我们知道,如果使用复制算法实现堆的内存回收,堆就会被分为新生代和老年代,新生代中的对象“朝生夕死”,每次垃圾回收都会清除掉大量的对象;而老年代中的对象生命较长,每次垃圾回收只有少量的对象被清除掉。 由于方法区中存放生命周期较长的类信息、常量、静态变量,因此方法区就像是堆的老年代,每次垃圾收集的只有少量的垃圾被清除掉。 方法区中主要清除两种垃圾:1. 废弃常量2. 废弃的类 1. 如何判定废弃常量? 清除废弃的常量和清除对象类似,只要常量池中的常量不被任何变量或对象引用,那么这些常量就会被清除掉。 2. 如何废弃废弃的类? 清除废弃类的条件较为苛刻:1. 该类的所有对象都已被清除2. 该类的java.lang.Class对象没有被任何对象或变量引用只要一个类被虚拟机加载进方法区,那么在堆中就会有一个代表该类的对象:java.lang.Class。这个对象在类被加载进方法区的时候创建,在方法区中该类被删除时清除。3. 加载该类的ClassLoader已经被回收 垃圾收集算法 现在我们知道了判定一个对象是无效对象、判定一个类是废弃类、判定一个常量是废弃常量的方法,也就是知道了垃圾收集器会清除哪些数据,那么接下来介绍如何清除这些数据。 1. 标记-清除算法 首先利用刚才介绍的方法判断需要清除哪些数据,并给它们做上标记;然后清除被标记的数据。 分析:这种算法标记和清除过程效率都很低,而且清除完后存在大量碎片空间,导致无法存储大对象,降低了空间利用率。 2. 复制算法 将内存分成两份,只将数据存储在其中一块上。当需要回收垃圾时,也是首先标记出废弃的数据,然后将有用的数据复制到另一块内存上,最后将第一块内存全部清除。 分析:这种算法避免了碎片空间,但内存被缩小了一半。而且每次都需要将有用的数据全部复制到另一片内存上去,效率不高。 解决空间利用率问题:在新生代中,由于大量的对象都是“朝生夕死”,也就是一次垃圾收集后只有少量对象存活,因此我们可以将内存划分成三块:Eden、Survior1、Survior2,内存大小分别是8:1:1。分配内存时,只使用Eden和一块Survior1。当发现Eden+Survior1的内存即将满时,JVM会发起一次MinorGC,清除掉废弃的对象,并将所有存活下来的对象复制到另一块Survior2中。那么,接下来就使用Survior2+Eden进行内存分配。 通过这种方式,只需要浪费10%的内存空间即可实现带有压缩功能的垃圾收集方法,避免了内存碎片的问题。 但是,当一个对象要申请内存空间时,发现Eden+Survior中剩下的空间无法放置该对象,此时需要进行Minor GC,如果MinorGC过后空闲出来的内存空间仍然无法放置该对象,那么此时就需要将对象转移到老年代中,这种方式叫做“分配担保”。 什么是分配担保?当JVM准备为一个对象分配内存空间时,发现此时Eden+Survior中空闲的区域无法装下该对象,那么就会触发MinorGC,对该区域的废弃对象进行回收。但如果MinorGC过后只有少量对象被回收,仍然无法装下新对象,那么此时需要将Eden+Survior中的所有对象都转移到老年代中,然后再将新对象存入Eden区。这个过程就是“分配担保”。 3. 标记-整理算法 在回收垃圾前,首先将所有废弃的对象做上标记,然后将所有未被标记的对象移到一边,最后清空另一边区域即可。 分析:它是一种老年代的垃圾收集算法。老年代中的对象一般寿命比较长,因此每次垃圾回收会有大量对象存活,因此如果选用“复制”算法,每次需要复制大量存活的对象,会导致效率很低。而且,在新生代中使用“复制”算法,当Eden+Survior中都装不下某个对象时,可以使用老年代的内存进行“分配担保”,而如果在老年代使用该算法,那么在老年代中如果出现Eden+Survior装不下某个对象时,没有其他区域给他作分配担保。因此,老年代中一般使用“标记-整理”算法。 4. 分代收集算法 将内存划分为老年代和新生代。老年代中存放寿命较长的对象,新生代中存放“朝生夕死”的对象。然后在不同的区域使用不同的垃圾收集算法。 Java中引用的种类 Java中根据生命周期的长短,将引用分为4类。 1. 强引用 我们平时所使用的引用就是强引用。A a = new A();也就是通过关键字new创建的对象所关联的引用就是强引用。只要强引用存在,该对象永远也不会被回收。 2. 软引用 只有当堆即将发生OOM异常时,JVM才会回收软引用所指向的对象。软引用通过SoftReference类实现。软引用的生命周期比强引用短一些。 3. 弱引用 只要垃圾收集器运行,软引用所指向的对象就会被回收。弱引用通过WeakReference类实现。弱引用的生命周期比软引用短。 4. 虚引用 虚引用也叫幽灵引用,它和没有引用没有区别,无法通过虚引用访问对象的任何属性或函数。一个对象关联虚引用唯一的作用就是在该对象被垃圾收集器回收之前会受到一条系统通知。虚引用通过PhantomReference类来实现。

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

NSProxy实现AOP方便为ios应用实现异常处理策略

前段时间关注过objc实现的AOP。 在GitHub找到了其中的两个库:AOP-in-Objective-C 和 AOP-for-Objective-C 第一个是基于NSProxy来实现的;第二个是基于GCD以及block实现的; 两者都使用了Cocoa的运行时编程技术,将拦截器注入给代理对象,使其干涉真是对象的执行顺序从而达到给代码增加“切面”的目的,这里的模式就是通常的代理模式。 因为时间关系,暂时只看了第一个库的代码,下面简短地分析一下。 NSProxy:如其名,它出现的目的就是为了来“代理”一个真实对象的。这是Foundation库的内置实现。大部门人都知道NSObject是通常Cocoa中的根类,没错,但其实根类并不止一个,NSProxy也是跟NSObject的根类,只是它是个抽象类并且不是用于通常意义上的编程目的,所以不是那么广为人知(事实上我也是今天才知道)。并且NSObject看到它你以为它是个类。但今天看NSProxy定义的时候,我发现它的头文件里是这样定义的: @interface NSProxy <NSObject> 开始我很莫名其妙,如果是继承自NSObject的话,应该是个冒号。这种写法明显就是实现协议的写法啊。于是,查看了一下资料,果然还有个NSObject的协议,并且NSObject类自身也实现了NSObject协议。具体资料请看 这篇文章。 NSProxy与NSObject一虚一实,并且它们都实现了NSObject协议。这让NSProxy的实现类能够很好地“代理”NSObject子类,并且把NSObject协议抽象出来,也让他们能够共享某些行为。 来看看它是如何工作的(测试代码见AOPLibTest.m文件): 在你需要使用AOP的地方,你首先需要实例化一个对象,比如你需要实例化一个NSMutableArray,你需要使用AOPProxy来实例化它: NSMutableArray* testArray = (NSMutableArray*)[[AOPProxy alloc] initWithNewInstanceOfClass:[NSMutableArray class]]; 这里,其实是间接实例化。它提供了一个接口,你把你的类名传给它,由它给你实例化。事实上,这是一种注入方式,而看完这个方法的定义你就会看到其实它返回给你的并不是NSMutableArray的一个实例(其实是AOPProxy,而 它们之所以能互相强制转换是因为他们都实现了NSObject协议): - (id) initWithNewInstanceOfClass:(Class) class { // create a new instance of the specified class id newInstance = [[class alloc] init]; // invoke my designated initializer [self initWithInstance:newInstance]; // release the new instance [newInstance release]; // finally return the configured self return self; } 上面的self指代的就是AOPProxy,其中的initWithInstance方法: - (id) initWithInstance:(id)anObject { parentObject = [anObject retain]; methodStartInterceptors = [[NSMutableArray alloc] init]; methodEndInterceptors = [[NSMutableArray alloc] init]; return self; } 可以看到,它在内部hold住了真实对象,并且实例化了两个数组,用来存储方法执行前后的拦截器集合。 下面,我们可以为NSMutableArray增加拦截器了: [(AOPProxy*)testArray interceptMethodStartForSelector:@selector(addObject:) withInterceptorTarget:self interceptorSelector:@selector( addInterceptor: )]; [(AOPProxy*)testArray interceptMethodEndForSelector:@selector(removeObjectAtIndex:) withInterceptorTarget:self interceptorSelector:@selector( removeInterceptor: )]; 因为这两个方法是AOPProxy的实例方法,所以在编写的时候还是需要在强制转回来(其实你在XCode里跟踪的时候,这里的testArray一直都是APOProxy类型的对象,因为一开始他就是被AOPPorxy allo出来的)。这两个方法的实现很简单,只是将拦截器假如相应的数组中去,待后面取出来执行。 [testArray addObject:[NSNumber numberWithInt:1]]; [testArray removeObjectAtIndex:0]; 好了,看起来这里开始调用某个对象本身的行为了。为什么说看起来呢?难道不是吗。当然不是,我在上面已经说过了,这里只是取名为testArray事实上它并不是NSMutableArray的实例,而是AOPProxy的实例。但为什么它还是可以调用addObject这个方法呢,因为它被强制转换为NSMutableArray类型了,编辑器能够接受这样的类型转换,也就是这是合法的。所以编辑器认为它就是NSMutableArray类型的对象了,所以是可以这么调用的,但后面你会看到。在运行时其实编译器知道了它不是真实的NSMutableArray类型(也就是说它无法响应addObject以及removeObjectAtIndex这两个方法),所以把它交给了另一个专门的方法来处理这些无法响应的消息: - (void)forwardInvocation:(NSInvocation *)anInvocation; 这个方法其实是继承自NSPorxy,NSProxy对它的实现其实就是抛出个异常,子类需要重新实现它,把它消息传递给真实的对象。详细信息参考官方文档! 来看看它的实现: - (void)forwardInvocation:(NSInvocation *)anInvocation; { SEL aSelector = [anInvocation selector]; // check if the parent object responds to the selector ... if ( [parentObject respondsToSelector:aSelector] ) { [anInvocation setTarget:parentObject]; // // Intercept the start of the method. // NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; for ( int i = 0; i < [methodStartInterceptors count]; i++ ) { // first search for this selector ... AOPInterceptorInfo *oneInfo = [methodStartInterceptors objectAtIndex:i]; if ( [oneInfo interceptedSelector] == aSelector ) { // extract the interceptor info id target = [oneInfo interceptorTarget]; SEL selector = [oneInfo interceptorSelector]; // finally invoke the interceptor [(NSObject *) target performSelector:selector withObject:anInvocation]; } } [pool release]; // // Invoke the original method ... // [self invokeOriginalMethod:anInvocation]; // // Intercept the ending of the method. // NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; for ( int i = 0; i < [methodEndInterceptors count]; i++ ) { // first search for this selector ... AOPInterceptorInfo *oneInfo = [methodEndInterceptors objectAtIndex:i]; if ( [oneInfo interceptedSelector] == aSelector ) { // extract the interceptor info id target = [oneInfo interceptorTarget]; SEL selector = [oneInfo interceptorSelector]; // finally invoke the interceptor [(NSObject *) target performSelector:selector withObject:anInvocation]; } } [pool2 release]; } // else { // [super forwardInvocation:invocation]; // } } 可以砍到这里让真实的对象调用了方法,并且干涉了对象的行为,在其前后加入了拦截器的执行操作。从而“优雅”地实现了AOP。 该库中,还提供了两个Aspect: AOPMethodLoger-用于简单记录方法的日志; AOPThreadInvoker-用于在一个单独的线程上执行方法; 之前在Java以及.net中已经很广泛地应用了AOP的实例了,常见的应用有做Log啊,异常捕获啊之类的。最近在做iOS的应用,其中也会牵扯到异常捕获的问题,特别是牵扯到数据库操作以及业务逻辑上的异常,总是写代码捕获块儿,费事还占面积。所以,我在里面又加了一个Aspect:AOPExcettionCatcher。很简单,就是在这里统一实现了异常捕获。 重新实现了invokeOriginalMethod方法: - (void)invokeOriginalMethod:(NSInvocation *)anInvocation{ NSLog(@"%@",@"entry into try block"); @try { [super invokeOriginalMethod:anInvocation]; } @catch (NSException *exception) { NSLog(@"%@",@"entry into catch block"); NSLog(@"%@",[exception reason]); } @finally { NSLog(@"%@",@"entry into finally block"); } } 当然了这只是应用之一,你还可以用它做更多的事情。 原文发布时间为:2012-12-23 本文作者:vinoYang 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

资源下载

更多资源
Nacos

Nacos

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

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

WebStorm

WebStorm

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

用户登录
用户注册