首页 文章 精选 留言 我的

精选列表

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

学习笔记:Docker页面管理平台

Docker Shipyard是什么 ?shipyard是一个开源的docker管理平台,其特性主要包括: 支持节点动态集群,可扩展节点的规模(swarm、etcd方案) 支持镜像管理、容器管理、节点管理等功能 可视化的容器管理和监控管理 在线容器console终端 容器管理 镜像管理 节点管理 容器内部管理 还有很多很好的功能,安装完毕后可以自行探索发现 如何安装? 本文都是A,B节点为模型,A节点是管理节点,B节点只作为node节点 1.在A,B节点上安装docker yum install docker 2.在A,B节点上安装swarm docker pull swarm 3.A节点上安装shipyard curl -s https://shipyard-project.com/deploy | bash -s 注意会用到8080端口,形成页面的管理系统 Username: admin Password: shipyard 4.B节点安装Node curl -sSL https://shipyard-project.com/deploy | ACTION=node DISCOVERY=etcd://A节点IP地址:4001 bash -s 5.测试使用 登陆http://A节点IP地址:8080/ Username: admin Password: shipyard tips: 如果遇到了curl: (35) Peer reports incompatible or unsupported protocol version.的提示请更新下软件就可以解决 命令如下: yum update nss nss-util nspr

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

jquery学习(第三天)

高度和宽度 $(“div”).height();$(“div”).width(); .height()方法和.css(“height”)的区别:返回值不同, .height()方法返回的是 数字类型(20), .css(“height”)返回的是字符串类型(20px), 因此.height()方法常用在参与数学计算的时候 坐标值 $(“div”).offset(); // 获取或设置坐标值 **设置值后变成相对定位**$(“div”).position(); // 获取坐标值 子绝父相 **只能读取不能设置** 固定导航栏(监听scroll) <script type="text/javascript"> $(function () { // 获取顶部 top 的高度值 var topHeight = $(".top").height(); // 监听浏览器的滚动事件 $(window).scroll(function () { var docScrollTop = $(document).scrollTop(); //console.log(docScrollTop); // 判断一下 docScrollTOp 和 topHeight两个大小 // 文档被卷去的高度 大于或等于 top高度的时候 // 让导航栏变成固定定位 if(docScrollTop >= topHeight) { $(".nav").css({ "position": "fixed", "top": 0 }); $(".main").css("margin-top" ,$(".nav").height()); } else { // 让固定导航栏变为默认状态 position: static $(".nav").css({ "position": "static" }); $(".main").css("margin-top" ,0); } }); }); </script> 两侧跟随广告 <script type="text/javascript"> $(function () { $(window).scroll(function () { var docScrollTop = $(document).scrollTop(); //$(".main").css("top", docScrollTop + 80); $(".main").animate({"top" : docScrollTop + 80},30); }); }); </script> 绑定事件 bind 可以绑定一个及以上 中间用空格隔开 可以传两个参数也可以传三个参数 三个参数时中间的值就是函数获取的值$("button").bind("click mouserenter",function(){ alert(111); }); one 单次绑定事件 delegate(委托)绑定方式,可以提高性能 on 事件(就使用它) $("div").on("click","p",function(){ alert(111); }); 第一个参数:触发什么事件 第二个参数:为哪个元素触发事件 第三个参数:处理函数 事件解绑(一一对应) unbind undelegate off 触发事件(提交时校验信息合法性) image.png <script> $(function () { $("form").on("click","#btnSub",function () { var textVal = $("#txtName").val(); if (textVal === "1") { alert("登录成功"); }else { //重新获取焦点 $("#txtName").val("").trigger("focus"); } }); }); </script> click : $(“div”).click(); trigger:触发事件,并且触发浏览器默认行为 triggerHandler:不触发浏览器默认行为 jquery事件对象(重点event=e) event.stopPropagation() //阻止事件冒泡 event.preventDefault(); //阻止默认行为 会做jQuery插件 全局jQuery函数扩展方法 $.log = function() { } //$("li") jQuery扩展方法 $.fn.log = function() { } 引入第三方插件 背景色插件方法 lazyload 插件 jQuery UI 插件 用法很简单: 第一步:引入必要的包 第二步: 实现 安装包管理工具 bower install jquery.lazyloadnmp install jquery-lazyload注意使用nmp的时候需要安装nodejs在pc上 sublime 装插件 sublime 3 第一步: 装上sublime的包管理器package control ctrl+ ~ 上网把 按照package control的那段代码,粘贴一下,然后回车。 第二步:使用Ctrl + shift + p

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

c++ template学习总结3

和往常一样,先来看一段代码: #include <stdexcept> template <typename T, int MAXSIZE> class Stack { private: T elems[MAXSIZE]; // elements int numElems; // current number of elements public: Stack(); // constructor void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return numElems == 0; } bool full() const { // return whether the stack is full return numElems == MAXSIZE; } }; // constructor template <typename T, int MAXSIZE> Stack<T,MAXSIZE>::Stack () : numElems(0) // start with no elements { // nothing else to do } template <typename T, int MAXSIZE> void Stack<T,MAXSIZE>::push (T const& elem) { if (numElems == MAXSIZE) { throw std::out_of_range("Stack<>::push(): stack is full"); } elems[numElems] = elem; // append element ++numElems; // increment number of elements } template<typename T, int MAXSIZE> void Stack<T,MAXSIZE>::pop () { if (numElems <= 0) { throw std::out_of_range("Stack<>::pop(): empty stack"); } --numElems; // decrement number of elements } template <typename T, int MAXSIZE> T Stack<T,MAXSIZE>::top () const { if (numElems <= 0) { throw std::out_of_range("Stack<>::top(): empty stack"); } return elems[numElems-1]; // return last element } 接下来编写我们的测试函数: #include <iostream> #include <string> #include <cstdlib> #include "stack4.hpp" int main() { try { Stack<int,20> int20Stack; // stack of up to 20 ints Stack<int,40> int40Stack; // stack of up to 40 ints Stack<std::string,40> stringStack; // stack of up to 40 strings // manipulate stack of up to 20 ints int20Stack.push(7); std::cout << int20Stack.top() << std::endl; int20Stack.pop(); // manipulate stack of up to 40 strings stringStack.push("hello"); std::cout << stringStack.top() << std::endl; stringStack.pop(); stringStack.pop(); } catch (std::exception const& ex) { std::cerr << "Exception: " << ex.what() << std::endl; return EXIT_FAILURE; // exit program with ERROR status } } 大家要注意int20Stack和int40Stack是两个不同的类型,他们是不能进行硬是或者显示的转换的。也不能够相互赋值。 你还可以为函数模板定义非型别参数: template <typename T, int VAL> T addValue (T const& x) { return x + VAL; } 当我们想把【函数】和某种操作作为参数传递的时候,就非常有用,比如在使用STL时,你可能有下面的代码: std::transform (source.begin(), source.end(), // start and end of source dest.begin(), // start of destination addValue<int,5>); // operation 有时候我们为了使得编译器推导的时候简单一些,可以使用: std::transform (source.begin(), source.end(), // start and end of source dest.begin(), // start of destination (int(*)(int const&)) addValue<int,5>); // operation 但是我们要注意,非类型模板参数也有自己的局限,通常来说他们只能是常整数,包括枚举,或者指向外部链接的指针。如果我们用浮点数或者class-type objects作为非类型模板参数是错误的: template <double VAT> // ERROR: floating-point values are not double process (double v) // allowed as template parameters { return v * VAT; } template <std::string name> // ERROR: class-type objects are not class MyClass { // allowed as template parameters … }; 由于字串字面常熟是一种采用内部链接的物件,也就是说不通模组中的两个同值的字串字面常数其实是两个不同的东西,所以他们也不能用来作为模板参数: template <char const* name> class MyClass { … }; MyClass<"hello"> x; // ERROR: string literal "hello" not allowed 此外全局指针也是不行的: template <char const* name> class MyClass { … }; char const* s = "hello"; MyClass<s> x; // ERROR: s is pointer to object with internal linkage 但是下面的例子是可以的: template <char const* name> class MyClass { … }; extern char const s[] = "hello"; MyClass<s> x; // OK 在这个例子中,s是一个外部连接的部件。 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384762.html,如需转载请自行联系原作者

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

C++ template 学习归纳2

关于c++中的类模板,常见的形式为: template<typename T> class className{ //... }; 比如笔者在这里举一个例子: #include <iostream> #include<vector> #include <stdexcept> template<typename T> class stack{ private: std::vector<T> elems; public: void push(T const&); void pop(); T top() const; bool empty() const{ return elems.empty(); } }; template<typename T> void stack<T>::push(T const& a){ elems.push_back(a); } template<typename T> void stack<T>::pop(){ if(elems.empty()){ throw std::out_of_range("stack<T>::pop empty"); } return elems.pop_back(); } template<typename T> T stack<T>::top()const{ if(elems.empty()){ throw std::out_of_range("stack<T>::top empty"); } return elems.back(); } int main(){ return 0; } 从上面的代码可以看出,为了定义成员函数,我们使用了下面的形式,比如: template<typename T> void stack<T>::push(T const& a){ elems.push_back(a); } 本来在此处有一个问题的,也就是关于类成员函数的实现位置的问题,这个问题我们稍后会提到。 现在我们为了测试上面的例子可以使用下面的函数代码: int main(){ stack<int> intStack; intStack.push(1); intStack.push(2); std::cout<<intStack.top()<<std::endl; stack<std::string> strStack; strStack.push("hello"); std::cout<<strStack.top()<<std::endl; return 0; } 我们有些时候会遇到这样的代码,比如: stack<stack<int> > intStack; 在这种情况下,我们要注意就是两个“>”中间的那个空格,那个是必须的,否则的话,编译器会认为是“>>”。这一点大家写代码的时候要注意。 下面我们来看看类模板的特化: 当我们想特化一个类模板的时候,我们就需要用template<>开头,后面更上我们希望特化的代码。比如: template<> class myStack<std::string>{ //... }; 对于特化类模板而言,就如同编写普通的类成员函数一样,比如: void myStack<int>::pop(int const& a){ //... } 下面我们呢来看看类模板的局部特化。 例如对于下面的代码: template<typename T1,typename T2> class myClass{ /... }; 而言,以下几种像是的局部特化都是正确 的: //局部特化 两个参数一致 template<typename T> class myClass<T,T>{ //... }; //局部特化 第二个为int template<typename T> class myClass<T,int>{ //... }; //两个参数都为指针类型 template<typename T1,typename T2> class myClass<T1*,T2*>{ //... }; 在下面的例子中: myClass<int float>mif; //将使用<T1,T2> myClass<float,float>mif; //将使用<T> myClass<float,int>mif; //将使用<T,int> myClass<int*,double*>mp; //将使用<T1*,T2*> 大家要注意下面的错误代码, myClass<int,int>m; myClass<int*,int*>m; z这两个代码在上面的这个例子中都是错误的。前者因为会和myClass<T,T>产生二义性。后者会和myClass<T,T>产生二义性、使得编译器不知道应该匹配哪一个。 如果想解决上面的第二个二义性的话,我们可以专门特化下面的代码: template<typename T> class myClass<T*,T*>{ //... }; 接下来我们来看看预设模板参数: 我们先来看看代码再说,大家注意和上面的例子进行比较: #include <iostream> #include<vector> #include <deque> #include <cstdlib> #include <stdexcept> template<typename T,typename CONT=std::vector<T> > class stack{ private: CONT elems; public: void push(T const&); void pop(); T top() const; bool empty() const{ return elems.empty(); } }; template<typename T,typename CONT> void stack<T,CONT>::push(T const& a){ elems.push_back(a); } template<typename T,typename CONT> void stack<T,CONT>::pop(){ if(elems.empty()){ throw std::out_of_range("stack<T>::pop empty"); } return elems.pop_back(); } template<typename T,typename CONT> T stack<T,CONT>::top()const{ if(elems.empty()){ throw std::out_of_range("stack<T>::top empty"); } return elems.back(); } int main(){ try{ stack<int> intStack; stack<double,std::vector<double> > douStack; //注意,这里千万不能写下面的这一行代码: // stack<double,std::vector<int> > douStack; intStack.push(1); std::cout<<intStack.top()<<std::endl; douStack.push(1.1); std::cout<<douStack.top()<<std::endl; }catch(std::exception const& ex){ std::cerr<<ex.what()<<std::endl; return EXIT_FAILURE; } return 0; } 我们使用 stack<double,std::vector<double> > douStack; 来声明了一个double stack,他的内部使用的是std:eque<>来管理。 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/07/2383729.html,如需转载请自行联系原作者

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

c++ template归纳学习5

双重模板参数: 我们还是以前几篇中的Stack为例子i:代码如下: template <typename T, template <typename ELEM> class CONT = std::deque > class Stack { private: CONT<T> elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } }; 在这段代码中,我们的第二个模板参数修改为:template <typename ELEM> class CONT 和往常一样,你可以使用class替代typename,但是CONT必须是class。 template <typename T, template <class ELEM> class CONT = std::deque> // OK class Stack { … }; but the following is not: template <typename T, template <typename ELEM> typename CONT = std::deque> class Stack { // ERROR … }; 由于上面例子中的ELEM实际中没有用到,其实是可以省略的。 我们实现一个成员函数看看: template <typename T, template <typename> class CONT> void Stack<T,CONT>::push (T const& elem) { elems.push_back(elem); // append copy of passed elem } 但是如果试图使用上面的stack,编译器会说deque不符合CONT的要求,问题在于,std中的deque要求不只是一个参数,第二个参数是一个配置器,他虽然有预设值,但是当它被用来匹配CONT参数的时候,预设值被编译器忽略了。 对于这个问题,我们可以修改,使得CONT参数要求一个带两个参数的容器。 template <typename T, template <typename ELEM, typename ALLOC = std::allocator<ELEM> > class CONT = std::deque> class Stack { private: CONT<T> elems; // elements … }; 最终版本如下: // basics/stack8.hpp #ifndef STACK_HPP #define STACK_HPP #include <deque> #include <stdexcept> #include <allocator> template <typename T, template <typename ELEM, typename = std::allocator<ELEM> > class CONT = std::deque> class Stack { private: CONT<T> elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } // assign stack of elements of type T2 template<typename T2, template<typename ELEM2, typename = std::allocator<ELEM2> >class CONT2> Stack<T,CONT>& operator= (Stack<T2,CONT2> const&); }; template <typename T, template <typename,typename> class CONT> void Stack<T,CONT>::push (T const& elem) { elems.push_back(elem); // append copy of passed elem } template<typename T, template <typename,typename> class CONT> void Stack<T,CONT>::pop () { if (elems.empty()) { throw std::out_of_range("Stack<>::pop(): empty stack"); } elems.pop_back(); // remove last element } template <typename T, template <typename,typename> class CONT> T Stack<T,CONT>::top () const { if (elems.empty()) { throw std::out_of_range("Stack<>::top(): empty stack"); } return elems.back(); // return copy of last element } template <typename T, template <typename,typename> class CONT> template <typename T2, template <typename,typename> class CONT2> Stack<T,CONT>& Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2) { if ((void*)this == (void*)&op2) { // assignment to itself? return *this; } Stack<T2> tmp(op2); // create a copy of the assigned stack elems.clear(); // remove existing elements while (!tmp.empty()) { // copy all elements elems.push_front(tmp.top()); tmp.pop(); } return *this; } #endif // STACK_HPP 测试如下: // basics/stack8test.cpp #include <iostream> #include <string> #include <cstdlib> #include <vector> #include "stack8.hpp" int main() { try { Stack<int> intStack; // stack of ints Stack<float> floatStack; // stack of floats // manipulate int stack intStack.push(42); intStack.push(7); // manipulate float stack floatStack.push(7.7); // assign stacks of different type floatStack = intStack; // print float stack std::cout << floatStack.top() << std::endl; floatStack.pop(); std::cout << floatStack.top() << std::endl; floatStack.pop(); std::cout << floatStack.top() << std::endl; floatStack.pop(); } catch (std::exception const& ex) { std::cerr << "Exception: " << ex.what() << std::endl; } // stack for ints using a vector as an internal container Stack<int,std::vector> vStack; … vStack.push(42); vStack.push(7); std::cout << vStack.top() << std::endl; vStack.pop(); } 程序的输出为: 7 42 Exception: Stack<>::top(): empty stack 7 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384921.html,如需转载请自行联系原作者

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

C++ template学习总结6

对于基本类型来说,并没有一个default模式来讲他们初始化为有意义的值,没有初始化的变量,其指都是未定义的,但是在模板这一块呢?我们可以采用下面的形式: template <typename T> void foo() { T x = T(); // x is zero (or false)ifT is a built-in type } 对于class template我们可以采用下面例子的方式: template <typename T> class MyClass { private: T x; public: MyClass() : x() { // ensures that x is initialized even for built-in types } … }; 通过引用形式将字串字面常数传递给模板,有时候会遇到错误: #include <string> // note: reference parameters template <typename T> inline T const& max (T const& a, T const& b) { return a < b ? b : a; } int main() { std::string s; ::max("apple","peach"); // OK: same type ::max("apple","tomato"); // ERROR: different types ::max("apple",s); // ERROR: different types } 问题出在于这几个字串字面常数的长度不同,因此其底层的Array也是不同的。换句话说“apple” 是char const[6],”tomato“是char const[7]. 但是如果你使用传值形式的话,那么久是可以的。 #include <string> // note: nonreference parameters template <typename T> inline T max (T a, T b) { return a < b ? b : a; } int main() { std::string s; ::max("apple","peach"); // OK: same type ::max("apple","tomato"); // OK: decays to same type ::max("apple",s); // ERROR: different types } 这种方式之所以可以,是因为在引数的推倒过程中,只有当参数不是一个引用的时候,【array转换为pointer】的动作才会发生,这个规则我们用下面的例子来说明: #include <typeinfo> #include <iostream> template <typename T> void ref (T const& x) { std::cout << "x in ref(T const&): " << typeid(x).name() << '\n'; } template <typename T> void nonref (T x) { std::cout << "x in nonref(T): " << typeid(x).name() << '\n'; } int main() { ref("hello"); nonref("hello"); } 结果为: 其实在这个例子中,最好的方式是对string进行重载,这么做尤其必要的,如果不这么做的弧啊,对于两个字串字面常熟调用max()是合法的,但是max()会以operator<比较两个指针的大小,所比较的其实是两个指针的地址,而不是其字面值,这也就是为什么使用std::string比C-style字串要好的原因之一。 只有当你以by value的方式使用字串字面常熟的时候,字串底部的array才会被转型(退化)为一个字元指针。也就是array to pointer。 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384977.html,如需转载请自行联系原作者

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

JavaScript学习记录day1

JavaScritps 是什么? JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。 在Web世界里,只有JavaScript能跨平台、跨浏览器驱动网页,与用户交互。 编写JS的流程 布局:HTML+CSS 属性:确定要修改哪些属性 事件:确定用户做哪些操作(产品设计) 编写JS:在事件中,用JS来修改页面元素的样式 1. 快速入门 JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>我的第一个JS</title> <script> function myFirstScript() { alert("Hello word!"); } myFirstScript(); </script></head><body></body></html> 由<script>...</script>包含的代码就是JavaScript代码,它将直接被浏览器执行。 第二种方法是把JavaScript代码放到一个单独的.js文件,然后在HTML中通过引入这个文件: <html><head> <script src="/static/js/abc.js"></script></head><body> ...</body></html> 这样,/static/js/abc.js就会被浏览器执行。 把JavaScript代码放入一个单独的.js文件中更利于维护代码,并且多个页面可以各自引用同一份.js文件。 可以在同一个页面中引入多个.js文件,还可以在页面中多次编写<script> js代码... </script>,浏览器按照顺序依次执行。 2. 编程工具 我使用的是webstorm,这款工具非常好用,但是是收费软件,可以使用它的开源license。https://www.jetbrains.com/webstorm/ 3. 语法 JavaScript的语法和Java语言类似,每个语句以;结束,语句块用{...}。但是,JavaScript并不强制要求在每个语句的结尾加;,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;。 注意:让JavaScript引擎自动加分号在某些情况下会改变程序的语义,导致运行结果与期望不一致。为了养成良好习惯,我们不要省略;,所有语句都添加;。 if (2 > 1) { x = 1; y = 2; z = 3; } 注意花括号{...}内的语句具有缩进,通常是4个空格。缩进不是JavaScript语法要求必须的,但缩进有助于我们理解代码的层次,所以编写代码时要遵守缩进规则。很多文本编辑器具有“自动缩进”的功能,可以帮助整理代码。 4. 注释 以//开头直到行末的字符被视为行注释,注释是给开发人员看到,JavaScript引擎会自动忽略: // 这是一行注释 alert('hello'); // 这也是注释//另一种块注释是用/*...*/把多行字符包裹起来,把一大“块”视为一个注释:/* 从这里开始是块注释 仍然是注释 仍然是注释 注释结束 */ 5. 大小写 请注意,JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常。 本文转自 ygqygq2 51CTO博客,原文链接:http://blog.51cto.com/ygqygq2/1917258,如需转载请自行联系原作者

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

SpringCloud学习之eureka集群配置

一。集群方案及部署思路: 如果是单节点的注册中心,是无法保证系统稳定性的,当然现在项目部署架构不可能是单节点的。 集群节点的部署思路:通过运行多个实例并请求他们相互注册,来完成注册中心的高可用性(结伴注册) 注意: 用于本机模拟的前期准备工作:将电脑上hosts 添加如下配置 (linux下位置:/etc/hosts): 127.0.0.1 localhost server1 server2 View Code 二 设计步骤 在这里简单创建一个项目:register-center-node1的项目工程,和我们先前的register-center项目工程一模一样 register-center-node1的application.yml配置: 1 server: 2 port: 8081 3 spring: 4 application: 5 name: register-center 6 eureka: 7 client: 8 service-url: 9 defaultZone: http://server1:8080/eureka 10 fetch-registry: true 11 instance: 12 hostname: server2 View Code register-center的application.yml配置: 1 server: 2 port: 8080 3 spring: 4 application: 5 name: register-center 6 eureka: 7 client: 8 service-url: 9 defaultZone: http://server2:8081/eureka 10 instance: 11 hostname: server1 View Code 注意以下几点: 与先前独立运行register-center不同,大家注意defaultZone属性,两个注册中心地址都指向对方进行结伴注册 去掉fetch-registry 与register-with-eureka配置(其实这样做就会取对应的默认值,两个值均为true) 启动第一个注册中心时会报Cannot execute request on any known server的错误,暂时不管它,实际上eureka注册中心的ui界面是能打开的 所有注册中心的节点的spring.application.name必须保持一致。 当需要往注册中心集群注册服务时的写法:defaultZone:http://server1:8080/eureka,http://server2:8081/eureka 启动完毕后,访问地址:http://localhost:8080 得到如下界面: 我们可以看到注册中心地址已经标记为集群模式了

资源下载

更多资源
优质分享App

优质分享App

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

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

用户登录
用户注册