首页 文章 精选 留言 我的

精选列表

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

Unity C#编程优化——枚举

考虑下面关于行星枚举的这个例子:public enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, PLUTO // Pluto is a planet!!!}起初,这样的定义还算好,直到需要产生一个行星的质量。所以我们做这样的事情:// Returns the mass of the planet in 10^24 kgpublic float GetMass(Planet planet) { switch(planet) { case Planet.MERCURY: return 0.330; case Planet.VENUS: return 4.87f; case Planet.EARTH: return 5.97f; ... case Planet.PLUTO: return 0.0146f; }} 行星直径又如何? 另一个switch语句? 密度怎么样? 重力? 逃跑速度? 只要想想你将要维护的switch语句的数量。 你可以争辩说,你可以使用一个Dictionary,但仍然笨重。 每个数据的Dictionary都要映射?没门。有一个更好的方法,我会告诉你如何。 这可能已经是非Unity程序员的常识,但我想在我的博客中再次提出这个冗余的主题,对于那些可能不知道这一点的人来说,特别是初学者。 我也想保持简单。基本上,你可以使用类作为枚举。 为什么用类? 这确实表现的更好 您可以存储任意数量的任意数据。 您甚至可以存储例程或功能。 你可以做很多事情。 唯一的要求是它是不可变的,这意味着类一个实例的状态在整个程序期间都不能改变。以下是Planet枚举用类表示的一个版本:public class Planet { // The different values public static readonly Planet MERCURY = new Planet(0, 0.330f, 4879, 5427, 3.7f); public static readonly Planet VENUS = new Planet(1, 4.87f, 12104, 5243, 8.9f); public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f); public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f); public static readonly Planet JUPITER = new Planet(4, 1898.0f, 142984, 1326, 23.1f); public static readonly Planet SATURN = new Planet(5, 568.0f, 120536, 687, 9.0f); public static readonly Planet URANUS = new Planet(6, 86.8f, 51118, 1271, 8.7f); public static readonly Planet NEPTUNE = new Planet(7, 102.0f, 49528, 1638, 11.0f); public static readonly Planet PLUTO = new Planet(8, 0.0146f, 2370, 2095, 0.7f); // Use readonly to maintain immutability private readonly int id; private readonly float mass; // in 10^24 kg private readonly int diameter; // in km private readonly int density; // in kg/m^3 private readonly float gravity; // in m/s^2 // We use a private constructor because this should not be instantiated // anywhere else. private Planet(int id, float mass, int diameter, int density, float gravity) { this.id = id; this.mass = mass; this.diameter = diameter; this.density = density; this.gravity = gravity; } public int Id { get { return id; } } public float Mass { get { return mass; } } public int Diameter { get { return diameter; } } public int Density { get { return density; } } public float Gravity { get { return gravity; } } }为了保持不变性,所有成员变量应该是只读的。 一旦他们被分配,他们将不能再被改变。 这很重要,因为作为枚举,它的内部值不应该改变。 然后将每个枚举值实现为该类的静态只读实例。这是怎么用的? 与正常枚举是一样的,如下使用:// Use it like an enumship.TargetPlanet = Planet.NEPTUNE;// Want to know the target planet's mass?float mass = ship.TargetPlanet.Mass;// Density?int density = ship.TargetPlanet.Density;我们已经消除了切换语句或字典来维护不同行星信息的需要。 想要一个新的行星状态? 只需添加一个新的成员变量并在实例化上指定它们。如何从其他数据类型转换? 喜欢说从int id转换为Planet实例? 这很容易 通常我为这些转换添加了一个公共和静态方法。 例如:public class Planet { // The different values public static readonly Planet MERCURY = new Planet(0, 0.330f, 4879, 5427, 3.7f); public static readonly Planet VENUS = new Planet(1, 4.87f, 12104, 5243, 8.9f); public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f); public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f); public static readonly Planet JUPITER = new Planet(4, 1898.0f, 142984, 1326, 23.1f); public static readonly Planet SATURN = new Planet(5, 568.0f, 120536, 687, 9.0f); public static readonly Planet URANUS = new Planet(6, 86.8f, 51118, 1271, 8.7f); public static readonly Planet NEPTUNE = new Planet(7, 102.0f, 49528, 1638, 11.0f); public static readonly Planet PLUTO = new Planet(8, 0.0146f, 2370, 2095, 0.7f); // This can be used to loop through all planets public static Planet[] ALL = new Planet[] { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, PLUTO }; // Converts the specified id to a Planet instance public static Planet Convert(int id) { for(int i = 0; i < ALL.Length; ++i) { if(ALL.Id == id) { return ALL; } } // return ALL[id] could also work here but what if a non sequential id is used? throw new Exception("Cannot convert {0} to a Planet.".FormatWith(id)); } ...}// UsagePlanet planet = Planet.Convert(someIntPlanet);想从字符串ID转换? 添加将保存此值的字符串成员变量。 而不是使用诸如ALL []的数组,您可以使用如下所示的Dictionary:private static Dictionary<string, planet="" style="color: rgb(34, 34, 34); font-family: 微软雅黑; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">ALL = new Dictionary<string, planet="">() { { MERCURY.TextId, MERCURY }, { VENUS.TextId, VENUS }, { EARTH.TextId, EARTH }, ... { PLUTO.TextId, PLUTO },};// Converts the specified string to a Planet instancepublic static Planet Convert(string id) { return ALL[id];}您可以支持您喜欢的任何类型的转换。还有更多的你可以做。 您现在可以添加功能。 你可以这样做:Planet currentPlanet = Planet.VENUS;currentPlanet.ApplyGravity(ship);The coolest thing for me is you can specify different actions or behavior to the enum values. Something like this (It’s very contrived but you get the idea.):public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f, delegate(Ship ship) { // Actions on land of ship ship.AddFood(1000); ship.RetireCrew(); ship.RecruitNewCrew();});public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f, delegate(Ship ship) { // Actions on land of ship ship.DeductFood(50); ship.Research(); ship.Mine();});通过简单地将你的枚举变成一个类,你已经将它升级到更有组织的东西,而且更加功能强大。 您也可以使用反射和继承等先进功能,但大多数情况下,您不需要。 更多unity2018的功能介绍请到paws3d学习中心查找。

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

leetcode 28 c++ 实现strstr

暴力破解 从前往后找,结果超时了。。。。。。。。。。。。 int strStr(string haystack, string needle) { if (needle.length() == 0) return 0; if (needle.length() > haystack.length()) return -1; int n_index = 0; for (int i = 0; i < haystack.length(); i++) { if (n_index == needle.length()) { return i - needle.length(); } if (haystack[i] == needle[n_index]) { n_index++; } else { if (n_index > 0) { n_index = 0; n_index = 0; //从上一段重合的第二个字符开始找,不然第一段和第二段重合的会让你丢失第一段中后面的元素 i = i - needle.length() + 1; } } } if (n_index < needle.length()) return -1; else if (n_index == needle.length()) return haystack.length() - needle.length(); } 目测输在了每次我比较失败之后都会让 i 回到开始相同的点的后一个位置。来一个复杂度为O(n)的解法。 1、每次比较之前,判断余下的串的长度是否超过子串余下的串的长度 2、两个同步比较,使用continue跳出循环,降低时间复杂度 class Solution { public: int strStr(string haystack, string needle) { if(needle.size()==0) return 0; for(int i=0;i<haystack.size();i++){ if(i+needle.size()-1>=haystack.size()) return -1; int flag=1; for(int j=0;j<needle.size();j++){ if (haystack[i+j]==needle[j]) continue; flag=0; } if (flag==1) return i; } return -1; } };

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

排序算法总结——c++实现

Java实现见链接:https://mp.weixin.qq.com/s/pN4RH4pPKtSkZJgcf2V-Vw 排序算法的稳定性分析 选择排序无法保证稳定性: 归并排序可以保证稳定性:(相等的就先放置左区域内的元素) 快速排序无法保持稳定性(因为partition的时候无法保持稳定性) 以后补充 堆排序无法保证稳定性:(图中数组建堆的过程,稳定性就会被破坏,第二个4会跑到第三个4的后面) 稳定性的意义在哪 数据不会乱 冒泡——稳定排序算法 时间复杂度 O(n*n),空间复杂度O(n)。 下面代码中交换两个数的值的方式虽然节省了一个变量,但是如果溢出就不好玩了,所以不要轻易乱秀。 void bubble(int nums[]) { if (nums == nullptr) return; //获取数组长度 int len= sizeof(nums) / sizeof(int); for (int end = len - 1; end >0; end++) { for (int i=0; i < end; i++) { if (nums[i] > nums[i+1]) { nums[i] = nums[i] + nums[i + 1]; nums[i + 1] = nums[i] - nums[i + 1]; nums[i] = nums[i] - nums[i + 1]; } } } } 冒泡排序改进版——鸡尾酒排序 #include <stdio.h> // 分类 -------------- 内部比较排序 // 数据结构 ---------- 数组 // 最差时间复杂度 ---- O(n^2) // 最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n) // 平均时间复杂度 ---- O(n^2) // 所需辅助空间 ------ O(1) // 稳定性 ------------ 稳定 void Swap(int A[], int i, int j) { int temp = A[i]; A[i] = A[j]; A[j] = temp; } void CocktailSort(int A[], int n) { int left = 0; // 初始化边界 int right = n - 1; while (left < right) { for (int i = left; i < right; i++) // 前半轮,将最大元素放到后面 { if (A[i] > A[i + 1]) { Swap(A, i, i + 1); } } right--; for (int i = right; i > left; i--) // 后半轮,将最小元素放到前面 { if (A[i - 1] > A[i]) { Swap(A, i - 1, i); } } left++; } } int main() { int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; // 从小到大定向冒泡排序 int n = sizeof(A) / sizeof(int); CocktailSort(A, n); printf("鸡尾酒排序结果:"); for (int i = 0; i < n; i++) { printf("%d ", A[i]); } printf("\n"); return 0; } 插入排序——稳定排序 最差时间复杂度:O(n^2) 最优时间复杂度:O(n) 平均时间复杂度:O(n^2) 当存储容器为数组时 //插入排序 void insert(int nums[]) { if (nums == nullptr) return; //获取数组长度 int len = sizeof(nums) / sizeof(int); //当前考察i位置的数字 for (int i = 1; i < len; i++) { //从i往前比较,每次与j和j+1的位置相比较。如果j+1的值小,则把小的放在前面 for (int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; j--) { nums[j] = nums[j] + nums[j + 1]; nums[j + 1] = nums[j] - nums[j + 1]; nums[j] = nums[j] - nums[j + 1]; } } } 当容器为vector时 #include <iostream> #include <vector> using namespace std; //传入一对迭代器,标准的插入排序 void Insertion_sort(vector<int>::iterator begin, vector<int>::iterator end) { for (auto p1 = begin; p1 != end; ++p1) { auto p2 = p1; while ((p2 != begin) && *(p2 - 1) > *p2) { int temp = *(p2); *p2 = *(p2 - 1); *(p2 - 1) = temp; --p2; } } } int main(int argc, char **argv) { int a[10] = { 2,5,6,3,1,4,8,7,9,0 }; vector<int> vec(a, a + 10); Insertion_sort(vec.begin(), vec.end()); for (size_t i = 0; i < vec.size(); ++i) { cout << vec[i] << " "; } return 0; } 当容器为链表时,从前往后遍历,找到对应的位置,进行链表的插入操作即可。 预备知识,链表的创建 #include<iostream> using namespace std; struct ListNode { int val; struct ListNode *next; }; //创建链表 ListNode* create(int arr[], int n) { if (arr == NULL || n <= 0) return NULL; ListNode *head = (ListNode*)malloc(sizeof(struct ListNode)); head->val = arr[0]; head->next = NULL; ListNode *tmp = head; ListNode *next = NULL; for (int i = 1; i < n; i++) { next = (ListNode*)malloc(sizeof(struct ListNode)); if (next) { next->val = arr[i]; next->next = NULL; tmp->next = next; tmp = next; } } return head; } int main() { int arr[6] = { 2,4,5,6,8,9 }; ListNode*first=create(arr, 6); return 0; } 链表实现插入排序代码(硬着头皮,终于写出来了。再坚持一下,再坚持一下,就会成功) #include <iostream> #include <vector> using namespace std; struct linklist { int data; linklist* next; linklist(int num = 0) : data(num), next(nullptr) {} }; //用了两个指针,fast指针用于比较当前节点的值与数组中的值的大小 //slow指向fast所指节点的前一个节点,slow用于插入新节点 linklist* insertion_sort(int arr[], int len){ linklist *before = (linklist*)malloc(sizeof(struct linklist)); linklist *head = (linklist*)malloc(sizeof(struct linklist)); head->data = arr[0]; before->next = head; head->next = NULL; linklist *fast = head; linklist *slow = before; linklist *next = NULL; for (int i = 1; i < len; i++) { //创建链表节点 next = (linklist*)malloc(sizeof(struct linklist)); next->data = arr[i]; //向后查找比arr[i]大的链表节点的位置 while ((arr[i] > fast->data)&&(fast->next!=nullptr)) { fast = fast->next; slow = slow->next; } //此时说明fast并没有指向链表最后一个元素 if (fast->next!=nullptr) { //说明arr[i]的值是最小的,应该插到链表头 if (slow==before) { next->next = slow->next; slow->next = next; } else { next->next = fast; slow->next = next; } } //此时fast指向链表结尾,需要比较fast->data与arr[i]的值 else { if (arr[i] > fast->data) { fast->next = next; next->next = nullptr; } else { next->next = fast; slow->next = next; } } slow = before; fast = slow->next; } return slow->next; } int main(int argc, char **argv){ int a[10] = { 2,5,6,3,1,4,8,7,9,0 }; linklist *answer=insertion_sort(a,10); return 0; } 插入排序改进——二分查找插入排序 #include <stdio.h> // 分类 -------------- 内部比较排序 // 数据结构 ---------- 数组 // 最差时间复杂度 ---- O(n^2) // 最优时间复杂度 ---- O(nlogn) // 平均时间复杂度 ---- O(n^2) // 所需辅助空间 ------ O(1) // 稳定性 ------------ 稳定 void InsertionSortDichotomy(int A[], int n) { for (int i = 1; i < n; i++) { int get = A[i]; // 右手抓到一张扑克牌 int left = 0; // 拿在左手上的牌总是排序好的,所以可以用二分法 int right = i - 1; // 手牌左右边界进行初始化 while (left <= right) // 采用二分法定位新牌的位置 { int mid = (left + right) / 2; if (A[mid] > get) right = mid - 1; else left = mid + 1; } for (int j = i - 1; j >= left; j--) // 将欲插入新牌位置右边的牌整体向右移动一个单位 { A[j + 1] = A[j]; } A[left] = get; // 将抓到的牌插入手牌 } } int main() { int A[] = { 5, 2, 9, 4, 7, 6, 1, 3, 8 };// 从小到大二分插入排序 int n = sizeof(A) / sizeof(int); InsertionSortDichotomy(A, n); printf("二分插入排序结果:"); for (int i = 0; i < n; i++) { printf("%d ", A[i]); } printf("\n"); return 0; } 插入排序再改进——希尔排序 https://www.cnblogs.com/chengxiao/p/6104371.html https://www.iqiyi.com/v_19rrhzyejc.html 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1、插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率; 2、但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位; 希尔排序的基本思想是: 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 #include <iostream> using namespace std; void shell_sort(int a[], int n) { //设定每次的步长 for (int dk = n / 2; dk >= 1; dk = dk / 2) { //对每一组进行插入排序 for (int k = 0; k < dk; k++) { //子组,做简单的插入排序 for (int i = 1; k + i * dk < n; i++) { //确定插入位置 for (int j = 0; j <= i; j++) { if (a[k + j * dk] >= a[k + i * dk]) { int temp = a[k + i * dk]; for (int p = i - 1; p >= j; p--) { a[k + (p + 1)*dk] = a[k + p * dk]; } a[k + j * dk] = temp; break; } } } } } } int main() { int a[10] = { 3,6,4,9,7,1,2,5,8,0 }; shell_sort(a, 10); return 0; } 选择排序 无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间 算法思路: 第1趟,在待排序记录 r[1] ~ r[n] 中选出最小的记录,将它与 r[1] 交换;第2趟,在待排序记录 r[2] ~ r[n] 中选出最小的记录,将它与 r[2] 交换;以此类推,第i趟在待排序记录 r[i] ~ r[n] 中选出最小的记录,将它与 r[i] 交换,使有序序列不断增长直到全部排序完毕。 //选择排序 void select(int nums[]) { if (nums == nullptr) return; //获取数组长度 int len = sizeof(nums) / sizeof(int); for (int i = 0; i < len-1; i++) { int minIndex = i; //循环找到最小的值,将其放在位置i处 for (int j = i + 1; j < len; j++) { minIndex = nums[j] < nums[minIndex] ? j : minIndex; } nums[i] = nums[i] + nums[minIndex]; nums[minIndex] = nums[i] - nums[minIndex]; nums[i] = nums[i] - nums[minIndex]; } } 快速排序 http://www.iqiyi.com/w_19rvedija1.html 算法思路: 1、从数列中挑出一个元素,称为 “基准”(pivot); 2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作; 3、递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序; 递归实现 #include <iostream> void quick_sort(int a[], int l, int r) { if (l >= r) return; int low = l, high=r; int key = a[low]; while (low < high) { //从右往左找,如果该值小于key,则左移到low所指的位置 for (;; high--) { if (high <= low) break; if (a[high] < key) { a[low] = a[high]; break; } } //从左往右找,如果该值大于key,则右移到high所指的位置 for (;; low++) { if (high <= low)break; if (a[low] > key) { a[high] = a[low]; break; } } } //把key放在low和high重合的位置(即key应该在数组中的最终位置) if (low == high) a[low] = key; //分而治之 quick_sort(a, l, low - 1); quick_sort(a, low+1, r); } int main() { int a[10] = {2,6,3,8,9,0,1,4,7,5}; //递归 quick_sort(a, 0,9); return 0; } 非递归 堆排序 堆是一个完全二叉树(满二叉树的每个非叶子节点都有两个孩子节点,完全二叉树是前几层都是满的,左后一层叶子节点从左到右依次连续的,例如:) 堆在实际过程中可以用数组来进行实现。位置 i 的左孩子的下标为 2* i + 1 ,右孩子下标为 2* i + 2 。堆的结构在脑海中,实际的存储形式是数组。 -1/2=0; 堆分为大根堆和小根堆,堆就是完全二叉树。 把数组变成大根堆的过程(找索引位置为 x 的节点的父节点,父节点的索引位置为 (x-1)/2 ) 1、数组: 2、考查范围(0到1时的堆): 由于此时 1 的父节点坐标 x=(1-1)/2 =0 ,计算出 1 的父节点为2,2>1 ,因此 1 不与2 进行交换。 3、考查范围(0-2时的堆): 变换过程如下: 计算 3 的父节点为 (2-1)/2=0,因此3的父节点坐标为0,3 的父节点 2<3 ,此时需要将 3 和 2 的位置进行交换,数组变成 4、考查范围(0-3时的堆): 按照上述比较方式,6先和1进行交换,数组变成,然后6 再和3进行比较,发现自己比3大,因此两个数进行交换 代码实现思路:给你一个数组,依次把 0到 i 的位置的数加进来,将 i 位置元素的值与其父位置元素的值进行比较,只要我大,我们就换,直到不能继续往上换位置,最终形成大根堆。 #include<iostream> using namespace std; void swap(int arr[], int i, int father) { int temp = arr[i]; arr[i] = arr[father]; arr[father] = temp; } void helper(int arr[], int i) { while (arr[i]>arr[(i-1)/2]) { swap(arr, i, (i - 1) / 2); i = (i - 1) / 2; } } void CreatHeap(int input [], int len) { if ((input == nullptr) || (len == 0)) return; for (int i = 0; i < len; i++) { helper(input, i); } } int main() { int heap[] = { 0,1,2,3,4,5,6,7 ,8}; int len = sizeof(heap) / sizeof(int); CreatHeap(heap, len); return 0; } 堆排序就是利用堆结构进行的一个排序 先让数组变成大根堆,然后将堆顶元素与堆中最后一个元素进行交换,再将堆的尺寸减一,此时最大的值就固定在数组的最后一位了。将堆中剩余的元素进行heapify。这样,每次都能确定一个值的位置。 #include "pch.h" #include<iostream> using namespace std; void swap(int arr[], int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } void helper(int arr[], int i) { //不断将其与其父节点进行比较,如果他更大,则交换两个节点的值 while (arr[i]>arr[(i-1)/2]) { swap(arr, i, (i - 1) / 2); i = (i - 1) / 2; } } void heapify(int heap[], int index, int size) { //确定左孩子的节点坐标 int left = index * 2 + 1; //确保不越界 while (left < size) { //选择两个孩子里面的大值 int largest = (left + 1 < size && heap[left + 1] > heap[left]) ? left + 1 : left; //将大值与原index的值进行比较,取两者中最大者 largest = heap[largest] > heap[index] ? largest : index; //说明index已经是最大的值了 if (largest == index) break; //将最大值放在index位 swap(heap, largest, index); index = largest; //重新确定左子树的位置,方便进行下一轮比较 left = index * 2 + 1; } } void CreatHeap(int input [], int len) { if ((input == nullptr) || (len == 0)) return; //一次获取一个元素,考察他应该在堆中的位置 for (int i = 0; i < len; i++) { helper(input, i); } int size = len; swap(input, 0, --size); while (size > 0) { heapify(input, 0, size); swap(input, 0, --size); } } int main() { int heap[] = { 2,1,3,6,0,4}; int len = sizeof(heap) / sizeof(int); CreatHeap(heap, len); return 0; } 归并排序 桶排序、基数排序和基数排序不是基于比较的排序

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

c++ 逗号运算符

逗号运算符含有两个运算对象,按照从左向右的顺序依次求值。 对于逗号运算符,首先对左侧表达式求值,然后将求值结果丢弃。逗号运算符真正的结果是右侧表达式的值。 逗号运算符经常被用在for循环中: #include <iostream> #include<vector> using namespace std; int main() { vector<int>ivec = {1,2,3,4,5}; vector<int>::size_type cnt = ivec.size(); for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt) { cout << "ix=" << ix << endl; cout << "cnt=" << cnt << endl; ivec[ix] = cnt; } return 0; } 运行结果: 补充: 对于 vector<int>::size_type 参考链接:https://blog.csdn.net/jingzhengyi/article/details/44022119

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

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文件系统,支持十年生命周期更新。

WebStorm

WebStorm

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

用户登录
用户注册