首页 文章 精选 留言 我的

精选列表

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

C++使用VARIANT实现二维数组的操作

VARIANT变量是COM组件之间互相通信的重要的参数变量之一,它可以容纳多种不同的类型,如short、long、double等,包括各类指针和数组。组件之间的互相调用是比较耗时的,尤其带当组件位于不同进程中时,因此,减少传递次数是提高效率的一种有效方法。其中,Excel表格的操作就可能涉及到大量数据,一次传递一个二维数组是提高对Excel表的操作效率。下面以两种不同方式来实现VARIANT二维数组的操作。 1、使用SAFEARRAY实现二维数组 SAFEARRAY安全数组可以实现多维数组,SAFEARRAY实现的步骤可以大致分为三步。 (1)创建SAFEARRAY安全数组,包括设置数组元素的类型、数据的维数,大小等。 (2)对SAFEARRAY数组赋值,既可通过SafeArrayPutElement函数逐个元素进行负责,也可通过指针来获得SAFEARRAY的数据地址,然后对指针指向的值进行赋值操作。其中,如果SAFEARRAY中的数组时多维数组,即可以把多维数组转换为一维数组,也可以通过获得指向数组的指针方式来操作数组中的元素。 (3)使用VARIANT变量把SAFEARRAY进行包装。 使用SAFEARRAR实现二维数组的源代码如下: VARTYPE vt = VT_I4; /*数组元素的类型,long*/ SAFEARRAYBOUND sab[2]; /*用于定义数组的维数和下标的起始值*/ sab[0].cElements = 2; sab[0].lLbound = 0; sab[1].cElements = 2; sab[1].lLbound = 0; /*创建一个2*2的类型为long的二维数组*/ SAFEARRAY* psa = SafeArrayCreate(vt, sizeof(sab)/sizeof(SAFEARRAYBOUND), sab); if (NULL == psa) { throw; } /*通过指向数组的指针来对二维数组的元素进行间接赋值*/ long(*pArray)[2]=NULL; HRESULT hRet=SafeArrayAccessData(psa, (void**)&pArray); if(FAILED(hRet)) { throw; } memset(pArray,0,2*2*sizeof(long)); /*释放指向数组的指针*/ SafeArrayUnaccessData(psa); pArray=NULL; /*对二维数组的元素进行逐个赋值*/ longindex[2]={0,0}; longlFirstLBound=0; longlFirstUBound=0; longlSecondLBound=0; longlSecondUBound=0; SafeArrayGetLBound(psa,1,&lFirstLBound); SafeArrayGetUBound(psa,1,&lFirstUBound); SafeArrayGetLBound(psa,2,&lSecondLBound); SafeArrayGetUBound(psa,2,&lSecondUBound); for(longi=lFirstLBound; i<=lFirstUBound; i++) { index[0]=i; for(longj=lSecondLBound; j<=lSecondUBound; j++) { index[1]=j; longlElement=i*sab[1].cElements+j; HRESULT hRet=SafeArrayPutElement(psa, index,&lElement); if(FAILED(hRet)) { throw; } } } /*把SAFEARRAY转换为VARIANT*/ VARIANT var; var.vt=VT_ARRAY|vt;/*vt必须和psa的数据类型保持一致*/ var.parray=psa; SafeArrayDestroy(psa); psa=NULL; 2、使用COleSafeArray实现二维数组 COleSafeArray继承于VARIANT,是MFC的自动化类,因此,只有在使用MFC类库时才能使用该类。COleSafeArray封装操作相关的函数,可通过MSDN查询该类的成员函数来了解与安全数组相关的函数。COleSafeArray还可以直接转换为VARIANT。因此,相对于SAFEARRAY,COleSafeArray的使用更方便。COleSafeArray和SAFEARRAY之间的关系就是MFC类库和Win32 SDK的关系,使用步骤类似。 使用COleSafeArray实现二维数组的源代码如下所示: VARTYPE vt = VT_I4; /*数组元素的类型,long*/ SAFEARRAYBOUND sab[2]; /*用于定义数组的维数和下标的起始值*/ sab[0].cElements = 2; sab[0].lLbound = 0; sab[1].cElements = 2; sab[1].lLbound = 0; COleSafeArray olesa; olesa.Create(vt, sizeof(sab)/sizeof(SAFEARRAYBOUND), sab); /*通过指向数组的指针来对二维数组的元素进行间接赋值*/ long(*pArray)[2]=NULL; olesa.AccessData((void**)&pArray); memset(pArray,0,2*2*sizeof(long)); /*释放指向数组的指针*/ olesa.UnaccessData(); pArray=NULL; /*对二维数组的元素进行逐个赋值*/ longindex[2]={0,0}; longlFirstLBound=0; longlFirstUBound=0; longlSecondLBound=0; longlSecondUBound=0; olesa.GetLBound(1,&lFirstLBound); olesa.GetUBound(1,&lFirstUBound); olesa.GetLBound(2,&lSecondLBound); olesa.GetUBound(2,&lSecondUBound); for(longi=lFirstLBound; i<=lFirstUBound; i++) { index[0]=i; for(longj=lSecondLBound; j<=lSecondUBound; j++) { index[1]=j; longlElement=i*sab[1].cElements+j; olesa.PutElement(index,&lElement); } } /*把COleSafeArray变量转换为VARIANT*/ VARIANT var = (VARIANT)olesa; 参考资料 http://blog.sina.com.cn/s/blog_74f586a50100rv6t.htmlhttp://hfp0601.blog.163.com/blog/static/228483522011031104718762/

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

(转)C# 快速高效率复制对象的方式

1、需求 在项目代码中经常需要把对象复制到新的对象中,或者把属性名相同的值复制一遍。 比如: public class Student { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } public class StudentSecond { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } Student s = new Student() { Age = 20, Id = 1, Name = "Emrys" }; 我们需要给新的Student赋值 Student ss = new Student { Age = s.Age, Id = s.Id, Name = s.Name }; 给另一个类StudentSecond的属性赋值,两个类属性的名称和类型一致。 StudentSecond ss = new StudentSecond { Age = s.Age, Id = s.Id, Name = s.Name }; 2、解决办法 当然最原始的办法就是把需要赋值的属性全部手动手写。这样的效率是最高的。但是这样代码的重复率太高,更重要的是浪费时间,如果一个类有几十个属性,那一个一个属性赋值太浪费了,像这样重复的劳动工作更应该是需要优化的。 2.1、反射 反射应该是很多人用过的方法,就是封装一个类,反射获取属性和设置属性的值。 private static TOut TransReflection<TIn, TOut>(TIn tIn) { TOut tOut = Activator.CreateInstance<TOut>(); var tInType = tIn.GetType(); foreach (var itemOut in tOut.GetType().GetProperties()) { var itemIn = tInType.GetProperty(itemOut.Name); ; if (itemIn != null) { itemOut.SetValue(tOut, itemIn.GetValue(tIn)); } } return tOut; } 调用:StudentSecond ss= TransReflection<Student, StudentSecond>(s); 调用一百万次耗时:2464毫秒 2.2、序列化 序列化的方式有很多种,有二进制、xml、json等等,今天我们就用Newtonsoft的json进行测试。 调用:StudentSecondss= JsonConvert.DeserializeObject<StudentSecond>(JsonConvert.SerializeObject(s)); 调用一百万次耗时:2984毫秒 3、表达式树 3.1、简介 关于表达式树不了解的可以百度。 也就是说复制对象也可以用表达式树的方式 Expression<Func<Student, StudentSecond>> ss = (x) => new StudentSecond { Age = x.Age, Id = x.Id, Name = x.Name }; var f = ss.Compile(); StudentSecond studentSecond = f(s); 这样的方式我们可以达到同样的效果。看似说这样的写法和最原始的复制没有什么区别,代码反而变多了呢,然而这个只是第一步。跟着来!!!!!!!!!!!!!!!!!!!!!!! 3.2、分析代码 用ILSpy反编译下这段表达式代码如下: ParameterExpression parameterExpression; Expression<Func<Student, StudentSecond>> ss = Expression.Lambda<Func<Student, StudentSecond>>(Expression.MemberInit(Expression.New(typeof(StudentSecond)), new MemberBinding[] { Expression.Bind(methodof(StudentSecond.set_Age(int)), Expression.Property(parameterExpression, methodof(Student.get_Age()))), Expression.Bind(methodof(StudentSecond.set_Id(int)), Expression.Property(parameterExpression, methodof(Student.get_Id()))), Expression.Bind(methodof(StudentSecond.set_Name(string)), Expression.Property(parameterExpression, methodof(Student.get_Name()))) }), new ParameterExpression[] { parameterExpression }); Func<Student, StudentSecond> f = ss.Compile(); StudentSecond studentSecond = f(s); 只要用反射循环所有的属性然后Expression.Bind所有的属性。最后调用Compile()(s)就可以获取正确的StudentSecond。 到这有的人又要问了,如果用反射的话那岂不是效率很低,和直接用反射或者用序列化没什么区别吗? 当然这个可以解决的,就是我们的表达式树可以缓存。只是第一次用的时候需要反射,以后再用就不需要反射了 3.3、复制对象通用代码 为了通用性所以其中的Student和StudentSecond分别泛型替换。 private static Dictionary<string, object> _Dic = new Dictionary<string, object>(); private static TOut TransExp<TIn, TOut>(TIn tIn) { string key = string.Format("trans_exp_{0}_{1}", typeof(TIn).FullName, typeof(TOut).FullName); if (!_Dic.ContainsKey(key)) { ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p"); List<MemberBinding> memberBindingList = new List<MemberBinding>(); foreach (var item in typeof(TOut).GetProperties()) { if (!item.CanWrite) continue; MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression }); Func<TIn, TOut> func = lambda.Compile(); _Dic[key] = func; } return ((Func<TIn, TOut>)_Dic[key])(tIn); } 调用:StudentSecond ss= TransExp<Student, StudentSecond>(s); 调用一百万次耗时:564毫秒 3.4、利用泛型的特性再次优化代码 不用字典存储缓存,因为泛型就可以很容易解决这个问题。 public static class TransExpV2<TIn, TOut> { private static readonly Func<TIn, TOut> cache = GetFunc(); private static Func<TIn, TOut> GetFunc() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p"); List<MemberBinding> memberBindingList = new List<MemberBinding>(); foreach (var item in typeof(TOut).GetProperties()) { if (!item.CanWrite) continue; MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression }); return lambda.Compile(); } public static TOut Trans(TIn tIn) { return cache(tIn); } } 调用:StudentSecond ss= TransExpV2<Student, StudentSecond>.Trans(s); 调用一百万次耗时:107毫秒 耗时远远的小于使用automapper的338毫秒。 4、总结 从以上的测试和分析可以很容易得出,用表达式树是可以达到效率与书写方式二者兼备的方法之一,总之比传统的序列化和反射更加优秀。 最后望对各位有所帮助 借鉴之处:http://www.cnblogs.com/emrys5/

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

[译] Introducing Horizon: build realtime apps without writing backend c...

原文: Introducing Horizon: build realtime apps without writing backend code 今天我们非常荣幸地宣布 Horizon 第一次正式发布,一个开源的后端服务,可以帮助开发者构建和扩展实时 web 应用,Horizon 包括: 一个使用 Nodejs 和 RethinkDB 构建的后端服务器,支持数据持久化,实时流,输入校验,用户认证,还有权限体系 一个 JavaScript 客户端库,开发者可以在前端将 json 文档存储到数据库中,执行查询,以及订阅实时更新 一个命令行工具,可以生成项目模板,启动一个本地的 Horizon 开发服务器,还能帮助你将自己的 Horizon 应用部署到云端 Horizon 服务器是一个完整的后端服务,开发者可以用来驱动他们的应用。它非常适合用来实现快速原型:简单地通过命令行运行 Horizon 服务器,利用 Horizon 客户端库来提升你前端的用户体验。有了 Horizon,前端开发者不写一行后端代码就能开发出一个完整的应用。 Horizon 是一个开源软件,就是说你可以按照自己的喜好使用和修改。开发的时在自己的笔记本上运行一个本地实例,之后可以部署到任何你想到部署的地方:低廉的 VPS 主机,公有云,或者你自己的裸机上。Horizon 依靠 RethinkDB 可靠的集群,在你用户增长之后可以很方便地进行扩展。 除了开源的 Horizon 后端,我们还构建了一个可以用来部署,管理和扩展 Horizon 应用的云服务,Horizon Cloud 管理 Horizon 后端服务和底层的 RethinkDB 数据库,还能按照需求自动进行扩展。Horizon Cloud 还对备份和恢复,不停机版本更新,监控和其他实用功能提供了内置支持。开发者可以使用 Horizon 命令行工具将自己的应用部署到 Horizon Cloud。Horizon Cloud 目前还处于内测阶段,但用不了多久就会和大家见面。 为什么是 Horizon 去年在介绍 RethinkDB 1.16 带来的 changefeeds 时,我们分享了推动实时 web 的计划。不再需要通过轮询的方式获取数据更新,开发者可以告诉数据库将应用的实时结果作为持续的流推送过来。当我们与用户分享这一功能时,有个问题翻来覆去地被问起:我可以从浏览器的 web 应用中直接访问 RethinkDB 的实时更新吗? changefeeds 在最开始是为后端开发者设计的 ,由他们决定如何将实时更新传输到前端。在我们推出这个功能后不久,我们开始琢磨如果能将实时数据流直接暴露给浏览器会不会非常牛逼。WebSocket 抽象库, GraphQL 那样的新数据检索技术,以及 RxJS Observables 强大的异步流本源,给前端提供了新的si去检索和处理数据。Web 应用正在不断进化,早已超出 REST 和 XMLHttpRequest 所能承载的能力。Horizon 是为未来而生,它用实时数据流贯通数据库和前端。 Horizon 能减少开发人员在构建和扩展 web 应用时面对的麻烦。它消除了重复的模板和繁琐的步骤,就像手写 CRUD 端点,用户认证,以及 session 管理。我们致力于填补数据持久层和前端之间的鸿沟,将开发者从不断发明轮子的轮回中解脱出来,使其能把更多的时间集中在实现业务逻辑上。 上手 Horizon 开始使用 Horizon 之前,先要从 NPM 上安装 Horizon 库包,其中包含了一个名为 hz 的命令行工具,你可以用它来生成和运行你的首个项目。你可以在Horizon 官网找到详细安装说明和简明教程 Horizon 客户端库提供了简明的 API,你可以通过链式方法表达数据库查询。查询返回 RxJS Observables,便于你对流查询结果进行合并和处理。在这背后,Horizon 的数据集合基于 RethinkDB 的表。在开发模式下运行 Horizon 时,服务器将自动创建所需的表和索引。 下面的例子展示了如何在浏览器或其他前端环境使用 Horizon 客户端库。这段代码展示了如何将 JSON 文档存储在一个 Horizon 集合中,以及从集合记录中获取一个过滤后的子集: var horizon = Horizon(); var messages = horizon("messages"); messages.store({ sender: "Bob", time: new Date(), text: "Hello, World!" }); messages.findAll({sender: "Bob"}).fetch() .subscribe(m => console.log(m)); 如果想不停地执行查询并获得实时更新的流数据,只需要使用 `watch` 方法,接下来的例子便展示了如何通过 Horizon 查询来实现在线游戏中的实时排行榜: var users = horizon("users"); users.order("score", "descending").limit(5).watch() .subscribe(items => console.log(items)) 上边的查询按照用户的分数倒序排列并给出前五名。每当数值发生变化,`subscribe` 回调将获得一个包含更新内容的完整数组,它会自动维护排序顺序,并根据需要添加和删除用户。 Horizon 服务器将客户端的查询翻译成ReQL,即 RethinkDB 的查询语言。查询翻译过程中利用自动生成的索引,最大限度提高效率和性能。Horizon 查询语言设计的要比 ReQL 简单易用,易于开发者学习和进行服务器优化。下面是支持的命令列表: find, findAll above, below, limit, order remove, removeAll store, upsert, replace watch, fetch 你可以查阅Horizon 文档来学习更多关于客户端库 API 的用法。我们正着手一系列的改进,提高查询语言的能力和表现力,比如一个特性就是可以使你将多个查询组合到模型关系中。 整合 Horizon 与 Javascript 生态系统 Horizon 不具有强制性也不会自以为是--它本身就被设计成能与你了解喜爱的 JavaScript 框架配合使用的。Horizon 服务器具有很强可扩展性,就是说,想定制后端服务的开发者可以根据自己的需要将 Horizon 嵌入到 Node.js 应用中,还可以按照需要添加新功能。你甚至可以将 Horizon 整合到现有的 Node.js 后端应用中,可以和常规的框架比如 Express,Koa,Hapi 等愉快的玩耍。 Horizon 客户端库使用一个简单的基于 WebSocket 的协议与服务器进行通信,不过我们提供了一个纯净的抽象层,你不必管理持久性连接,也不用关心 WebSockets 具体怎么工作。Horizon 客户端库可以很好地搭配任何前端框架使用,如 React,Angular,Ember,以及 vanilla JavaScript(全球最流行的 JavaScript 框架 :)。你还可以与 redux 那样的前端状态管理器搭配使用。 你可以在 Horizon 的官方 Github 仓库找到一个示例,展示了如何把 Horizon 与形形色色的前端和后端的框架整合到一起。React 开发者还可以去看一下lovli.js,一个由Patrick Neschkudla编写的实用模板,其中用到了 Horizon,React,以及 Redux。 我们期待某一天能将 Horizon 客户端库搬到移动平台上,我们也在积极的与社区合作,以确保 Horizon JavaScript 客户端能在 Electron 和 React Native 上正常工作。JavaScript 正在渗透到各个地方,从嵌入式物联网系统到桌面和移动应用程序。我们相信 Horizon 能提供一些理由让开发者选择 JavaScript。 此外,我们还为客户端库与 Horizon 后端通信的底层协议编写了文档。开发者可以利用该协议构建其他语言版本的客户端库。该协议包括简单的JSON文件。它基于engine.io,一个支持多个网络传输的实时框架。 规划 今天发布的 Horizon 只是一个起点,远不是最终的目标。你会在项目进度中看到新功能和改进。现有功能包括:查询,实时更新,认证,权限体系,以及对静态资源的支持。 一些主打功能还不够成熟。权限系统和校验支持是近期刚加入的,很晚才列入到开发周期中。在我们着手改进这些功能的时候,你可能会遇到一些不完善的地方。 长期规划仍在不断壮大,不过下面这个列表,是我们希望在未来的版本中包含的功能: 一个内置的管理后台,配备交互式数据浏览器 更好的连接生命周期管理器以及断开连接恢复 支持使用 ReQL 和 JavaScript自定义 Horizon 命令 支持客户端文件上传 除了 OAuth 以外,提供常规的密码认证 内置分页 API,搭配实时查询使用 原生支持执行开放式更新 支持关系性的查询聚合 内置支持GraphQL 数据查询 你可以关注Horizon forum上的日常更新,我们会努力完善这些功能和稳定 Horizon 的代码。 社区参与 Horizon: the realtime, open-source JavaScript backend Horizon forum GitHub - rethinkdb/horizon: Horizon is a realtime, open-source backend for JavaScript apps Join RethinkDB on Slack https://twitter.com/horizonjs 我们期待着与你的合作,我们以推进实时 web 的发展为己任。

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

C# Lambda表达式Contains方法&#160;like

原文: Lambda表达式Contains方法like 1、使用Contains方法的必备条件: Contains等价于SQL中的like语句。不过Contains只针对于字符串(string)类型的数据而言。如果是int等数值类型,则不会有Contains方法的存在,因此数值字段貌似无法通过使用Lambda表达式来完成like操作。因此在使用实体框架的同时,设计数据的时候如果想使用like请确保数据库字段为字符串类型(text、varchar等)。否则在想模糊查询的时候让你痛苦不堪。 2、Contains方法关联方法(均等价于SQL中的like[注意:这里为什么会说是等价呢,因为如下列出的方法均为Stirng里的方法。like的应用是不分字符类型的,数值行亦可]): Contains等价于like '%key%' 指示指定的String对象是否出现在此字符串中。 EndsWith等价于like '%key' 确定此字符串实例的结尾是否与指定的字符串匹配。 StartsWith等价于like 'key%'确定此字符串实例的开头是否与指定的字符串匹配。 3、使用Contains方法时前往不要忘记非NULL的判断: 写这边文章的原因来自,今天在使用Contains来做查询的时候,一直报错(未将对象引用设置到对象的实例。)。 一开始百思不得其解,经过跟踪和调试最后才发现数据库中如果存在值为NULL的值。 为什么会报错,看看如下的代码,想必大家也就知道其中的所以然了。 stringstr = null; str.Contains("报错啦");//这里会报“未将对象引用设置到对象的实例。”错 因此不要忘记将代码 o.SearchKeyword.Contains("查询条件") 改写为: o.SearchKeyword != null && o.SearchKeyword.Contains(("查询条件")

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

数据收集程序一般建筑(C++ ACE达到)

数据收集程序一般功能 经socket数据的接收的另一侧。端方能够访问智能电表采集器,你可曾与计算机之间的通信的通信协议(你良好的一致性是谁client,谁是服务端,即数据流) 为收集程序要求 可扩展:协议到来的时候,你能够不修改其它代码,仅仅创建相应的解码器和通信类就可以。 可配置:能够通过文件或者数据库来载入对方和自己的配置信息。 模块化程度高:採集程序依照模块功能划分为例如以下的几个主要模块(配置载入模块、两级消息队列、消费线程、解码器管理器、两级解码器、通信模块) 採集程序的一般架构 此结构历经JSPTPD多个项目成型,在软件院朱磊总的设计下由多人(zhulei,.zhuyongjin,chenfan,,yuanweiwei,chenlinkong,zhuzhongzhi,lvzhiqianq)实现,各个模块均由DLL封装,出现故障easy定位。满足採集程序的一般要求。 关键接口和系统架构 以下是关键路径上的主要接口明细 上面的接口展示了具体设计中各个模块之间的关系和纽带。能够看出因为功能模块划分的清晰,能够方便的扩展和測试。 眼下难度较大和待完好的部分主要有: (1)ConfigLoader。由于当成千上万的採集器和电表在线的时候,结构化的配置库将是系统不可或缺的信息支撑。当前的ConfigLoader类接口还比較简单,另外ConfigLoader尽管扩展easy,但在扩展的同一时候仍要提供一个清晰易用的接口还是须要细致斟酌的。或许须要多个项目打磨才会比較完好。 (2)使用Acceptor-Connector加Proactor模式实现自己主动异步处理大并发,这个正在进行,期待期待。 平台能力 依照半个小时採集一次的频率算。上面的结构仅仅要部署一到两个拷贝,应足以应付收购一个二线城市城市的智能电表数据。 版权声明:本文博主原创文章。博客,未经同意,不得转载。 本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4759252.html,如需转载请自行联系原作者

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

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

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

用户登录
用户注册