1.PHP7源码之array_unique函数分析
2.C#浅析C# List实现原理
3.python-içäºå¤å°(%iå¨python)
4.Python实现十大经典排序算法--python3实现(以及全部的源码排序算法分类)
5.openGauss数据库源码解析系列文章——事务机制源码解析(一)
6.å¦ä½å®è£
resin
PHP7源码之array_unique函数分析
以下源码基于 PHP 7.3.8
array array_unique ( array array[,intarray[,intsort_flags = SORT_STRING ] ) (PHP 4 >= 4.0.1, PHP 5, PHP 7) array_unique — 移除数组中重复的值 参数说明: array:输入的数组。 sort_flag:(可选)排序类型标记,源码用于修改排序行为,源码主要有以下值: SORT_REGULAR - 按照通常方法比较(不修改类型) SORT_NUMERIC - 按照数字形式比较 SORT_STRING - 按照字符串形式比较 SORT_LOCALE_STRING - 根据当前的源码本地化设置,按照字符串比较。源码
array_unique 函数的源码怎么查看网址源码源代码在 /ext/standard/array.c 文件中。由于篇幅过长,源码完整代码不在这里贴出来了,源码可以参见 GitHub 贴出的源码源代码。
定义变量
首先是源码定义变量,array_unique 函数默认使用 PHP_SORT_STRING 排序,源码PHP_SORT_STRING 在 /ext/standard/php_array.h 头文件中定义。源码
可以看到和开头PHP函数的源码sort_flag 参数默认的预定义常量 SORT_STRING 很像。
compare_func_t cmp 这行代码没看懂,源码不清楚是源码做什么的。compare_func_t 在 /Zend/zend_types.h 中定义:应该是定义了一个指向int 型返回值且带有两个指针常量参数的函数指针类型,没有查到相关资料,先搁着,继续往下看。
参数解析
ZEND_PARSE_PARAMETERS_START(1, 2),第一个参数表示必传参数个数,第二个参数表示最多参数个数,即该函数参数范围是 1-2 个。
数组元素个数判断
这段代码很容易看懂,当数组为空或只有 1 个元素时,无需去重操作,直接将array 拷贝到新数组 return_value来返回即可。cancel源码
分配持久化内存
这一步只有当sort_type 为 PHP_SORT_STRING 时才执行。在下面可以看到调用 zend_hash_init 初始化了 array,调用 zend_hash_destroy 释放持久化的内存。
设置比较函数
进行具体比较顺序控制的函数指针是cmp,是通过向 php_get_data_compare_func 传入 sort_type 和 0 得到的,sort_type 也就是 SORT_STRING 这样的标记。
php_get_data_compare_func 在 array.c 文件中定义(即与 array_unique 函数同一文件),代码过长,这里只贴出默认标记为 SORT_STRING 的代码:
在前面的代码中,我们可以看到,cmp = php_get_data_compare_func(sort_type, 0); 的第二个参数,即参数 reverse 的值为 0,也就是当 sort_type 为 PHP_SORT_STRING 时,调用的是 php_array_data_compare_string 函数,即 SORT_STRING 采用 php_array_data_compare_string 进行比较。继续展开 php_array_data_compare_string 函数:
可以得到这样一条调用链:
string_compare_function 是一个 ZEND API,在 /Zend/zend_operators.c 中定义:
可以看到,SORT_STRING 使用 zend_binary_strcmp 函数进行字符串比较。下面的代码是 zend_binary_strcmp 的实现(也在 /Zend/zend_operators.c 中):
上面的代码是比较两个字符串。也就是SORT_STRING 排序方式的底层实现是 C 语言的 memcmp,即它对两个字符串从前往后,按照逐个字节比较,一旦字节有差异,就终止并比较出大小。
数组排序
这段代码初始化一个新的数组,然后将值拷贝到新数组,源码buma然后调用zend_sort 排序函数对数组进行排序。排序算法在 /Zend/zend_sort.c 中实现,注释有这样一句话:
Derived from LLVM's libc++ implementation of std::sort.
这个排序算法是基于LLVM 的 libc++ 中的 std::sort 实现的,算是快排的优化版,当元素数小于等于时有特殊的优化,当元素数小于等于 5 时直接通过 if else 嵌套判断排序。代码就不贴出来了。
数组去重
回到array_unique 上,继续看代码:
遍历排序好的数组,然后删除重复的元素。
众周所知,快排的时间复杂度是O(nlogn),因此,array_unique 函数的时间复杂度是O(nlogn)。array_unique 底层调用了快排算法,加大了函数运行的时间开销,当数据量很大时,会导致整个函数的运行较慢。
C#浅析C# List实现原理
C# List 实现原理详解
在面试中,我被问到List的初始化容量问题,暴露了自己在C#编程中的不足。List作为C#中最常见的可伸缩数组组件,常用于替代数组,其可扩展性避免了手动分配数组大小的麻烦,甚至有时作为链表使用。那么,kotime源码它底层的工作机制如何呢?我们来深入了解其添加、插入、删除、索引操作以及排序等方面的实现。Add操作
在添加元素前,List会调用EnsureCapacity确保有足够的空间,如果容量不够,会按需扩容,初始容量为4,每次扩张都是翻倍:4, 8, , ...。然而,List使用数组作为底层数据结构,虽然索引访问快,扩容时会产生新的数组,造成内存浪费和GC压力。Insert操作
插入操作涉及Array.Copy,将指定索引后的元素后移,时间复杂度为O(n)。这可能导致性能降低和内存冗余。Remove操作
删除元素时,同样通过Array.Copy将指定索引后的元素前移,O(n)复杂度。删除元素后,后续元素需要移动,增加了内存消耗和GC负担。索引访问与Find
直接使用数组下标访问速度快,directsound 源码但Find的线性查找可能导致O(n)效率。在Unity中,foreach可能导致额外的GC,尽管Unity5.5已解决这个问题,但仍需注意foreach可能增加垃圾对象。Clear操作
Clear并不会删除数组,仅清零元素并设_size为0,表示容量为0,避免内存浪费。foreach与Sort
foreach在Unity中可能增加额外GC,但已在新版本中解决。List的Sort使用快速排序,时间复杂度为O(nlogn)。总结与参考
深入理解List的实现原理,对提高C#编程效率至关重要。参考《Unity3D高级编程之进阶主程》第一章和List源码(list.cs),以优化代码和避免不必要的性能损失。python-içäºå¤å°(%iå¨python)
导读ï¼æ¬ç¯æç« é¦å¸CTOç¬è®°æ¥ç»å¤§å®¶ä»ç»æå ³python-içäºå¤å°çç¸å ³å 容ï¼å¸æ对大家ææ帮å©ï¼ä¸èµ·æ¥ççå§ãpythonä¸i!=0æ¯ä»ä¹ææçå¼ä¸çäº0
æ¥å¸¸ç»å¸¸ä¼ç¨å°çæ¡ä»¶â 0,å¨Pythonä¸ä¸çäº0å¯ä»¥ç¨!=0æ¥è¡¨ç¤ºãå¨ä¸é¢çç®å代ç ä¸,æ们ç»XãY两个åéèµå¼1ã2,å使ç¨ifè¯å¥è¿è¡Xä¸çã
python-i
ä¸è½åè¿éé¢è¿è¡çï¼è¦å¨cmdä¸è¿è¡æè¡ã
å½ä»¤ï¼
python-iæä»¶å ¨è·¯å¾
å¨pythonä¸,å¦i=å½å¹¶æåº
å½å¹¶æåºä¹ç§°å并æåºï¼æ¯åæ²»æ³çå ¸ååºç¨ãåæ²»ææ³æ¯å°æ¯ä¸ªé®é¢å解æ个个å°é®é¢ï¼å°æ¯ä¸ªå°é®é¢è§£å³ï¼ç¶åå并ã
å ·ä½çå½å¹¶æåºå°±æ¯ï¼å°ä¸ç»æ åºæ°æn/2éå½å解æåªæä¸ä¸ªå ç´ çå项ï¼ä¸ä¸ªå ç´ å°±æ¯å·²ç»æ好åºçäºãç¶åå°è¿äºæåºçåå ç´ è¿è¡å并ã
å并çè¿ç¨å°±æ¯å¯¹ä¸¤ä¸ªå·²ç»æ好åºçååºåï¼å éå两个ååºåä¸æå°çå ç´ è¿è¡æ¯è¾ï¼éå两个å ç´ ä¸æå°çé£ä¸ªååºå并å°å ¶ä»ååºåä¸
å»ææ·»å å°æç»çç»æéä¸ï¼ç´å°ä¸¤ä¸ªååºåå½å¹¶å®æã
代ç å¦ä¸ï¼
#!/usr/bin/python?importsysdefmerge(nums,first,middle,last):?'''''merge'''?#åçè¾¹ç,å·¦éå³å¼å¹¶ä¸æ¯äº0为å¼å§?lnums=nums[first:middle+1]?rnums=nums[middle+1:last+1]?lnums.append(sys.maxint)?rnums.append(sys.maxint)?l=0?r=0?foriinrange(first,last+1):?iflnums[l]rnums[r]:?nums[i]=lnums[l]?l+=1?else:?nums[i]=rnums[r]?r+=1?defmerge_sort(nums,first,last):?'''''mergesortmerge_sortå½æ°ä¸ä¼ éçæ¯ä¸æ ï¼ä¸æ¯å ç´ ä¸ªæ°'''?iffirstlast:?middle=(first+last)/2?merge_sort(nums,first,middle)?merge_sort(nums,middle+1,last)?merge(nums,first,middle,last)if__name__=='__main__':?nums=[,8,4,-1,2,6,7,3]?print'numsis:',nums?merge_sort(nums,0,7)?print'mergesort:',nums
稳å®ï¼æ¶é´å¤æ度O(nlogn)
æå ¥æåº
代ç å¦ä¸ï¼
#!/usr/bin/python?importsysdefinsert_sort(a):?'''''æå ¥æåºæä¸ä¸ªå·²ç»æåºçæ°æ®åºåï¼è¦æ±å¨è¿ä¸ªå·²ç»æ好çæ°æ®åºåä¸æå ¥ä¸ä¸ªæ°ï¼ä½è¦æ±æå ¥åæ¤æ°æ®åºåä»ç¶æåºãåå¼å§ä¸ä¸ªå ç´ æ¾ç¶æåºï¼ç¶åæå ¥ä¸ä¸ªå ç´ å°éå½ä½ç½®ï¼ç¶ååæå ¥ç¬¬ä¸ä¸ªå ç´ ï¼ä¾æ¬¡ç±»æ¨'''?a_len=len(a)?ifa_len=0anda[j]key:?a[j+1]=a[j]?j-=1?a[j+1]=key?returnaif__name__=='__main__':?nums=[,8,4,-1,2,6,7,3]?print'numsis:',nums?insert_sort(nums)?print'insertsort:',nums
稳å®ï¼æ¶é´å¤æ度O(n^2)
交æ¢ä¸¤ä¸ªå ç´ çå¼pythonä¸ä½ å¯ä»¥è¿ä¹åï¼a,b=b,aï¼å ¶å®è¿æ¯å 为èµå¼ç¬¦å·çå·¦å³ä¸¤è¾¹é½æ¯å ç»
ï¼è¿ééè¦å¼ºè°çæ¯ï¼å¨pythonä¸ï¼å ç»å ¶å®æ¯ç±éå·â,âæ¥çå®çï¼èä¸æ¯æ¬å·ï¼ã
éæ©æåº
éæ©æåº(Selectionsort)æ¯ä¸ç§ç®åç´è§çæåºç®æ³ãå®çå·¥ä½åçå¦ä¸ãé¦å å¨æªæåºåºåä¸æ¾å°æå°ï¼å¤§ï¼å ç´ ï¼åæ¾å°
æåºåºåçèµ·å§ä½ç½®ï¼ç¶åï¼åä»å©ä½æªæåºå ç´ ä¸ç»§ç»å¯»æ¾æå°ï¼å¤§ï¼å ç´ ï¼ç¶åæ¾å°å·²æåºåºåçæ«å°¾ã以æ¤ç±»æ¨ï¼ç´å°æ
æå ç´ åæåºå®æ¯ã
pythonæ³ç¥éè¿ä¸ªç¨åºæ¯ä»ä¹æææåçç»ææ¯å¤å°é¢ç®çå¾ä½ çPythonè¯è¨ç¨åº,æä¸å¤é误ï¼å°±æ¯function1å½æ°ä¸çi-=1è¯å¥,åºè¯¥ç§»åºifè¯å¥åæ¾å°while循ç¯ä¸
ä½ çç¨åºæé½å äºæ³¨é,并ä¸è§£éäºè¿è¡ç»æ,ä½ ççå§ï¼
def?main():?#å½æ°main
i=0?#ièµåå¼0while?i=4:?#å½iå°äºçäº4æ¶,æ§è¡ä¸é¢æä½function1(i)?#è°ç¨function1å½æ°i+=1?#i=i+1print("i?is",i)?#æå°içå¼def?function1(i):?#å½æ°function1?iä¸ºä¼ è¿æ¥çåæ°
line="?"?#lineèµåå¼"?"while?i=1:?#å½i大äºçäº1æ¶,æ§è¡ä¸é¢æä½if?i%3!=0:?#å¦æié¤ä»¥3çä½æ°ä¸çäº0,ä¹å°±æ¯iä¸è½è¢«3æ´é¤,,æ§è¡ä¸é¢æä½line+=str(i)+"?"?#line=line+str(i)+"?",lineå å符串iå ç©ºæ ¼
i-=1?#i=i-1print(line)?#æå°linemain()?#è°ç¨mainå½æ°
æºä»£ç (注ææºä»£ç ç缩è¿)
è¿è¡ç»æåæ
#içäº0æ¶,è°ç¨function1(0),i1,æ以æå°ç©ºæ ¼
iis1#i+=1åiçäº1,æå°çiçå¼1
1?#içäº1æ¶,è°ç¨function1(1),i==1,while循ç¯1,(1)ä¸è½è¢«3æ´é¤,æ以æå°ç©ºæ ¼1ç©ºæ ¼
iis2?#i+=1åiçäº2,æå°çiçå¼2
?#içäº2æ¶,è°ç¨function1(2),i=1,while循ç¯2,1,(2,1)ä¸è½è¢«3æ´é¤,æ以æå°ç©ºæ ¼2ç©ºæ ¼1ç©ºæ ¼
iis3?#i+=1åiçäº3,æå°çiçå¼3
?#içäº3æ¶,è°ç¨function1(3),i=1,while循ç¯3,2,1,(2,1)ä¸è½è¢«3æ´é¤,æ以æå°ç©ºæ ¼2ç©ºæ ¼1ç©ºæ ¼
iis4?#i+=1åiçäº4,æå°çiçå¼4
?#içäº4æ¶,è°ç¨function1(4),i=1,while循ç¯4,3,2,1,(4,2,1)ä¸è½è¢«3æ´é¤,æ以æå°ç©ºæ ¼4ç©ºæ ¼2ç©ºæ ¼1ç©ºæ ¼
iis5?#i+=1åiçäº5,æå°çiçå¼5,i4,ä»ä¸»å½æ°mainä¸éåº
python5-iæ¯ä»ä¹ææ解éå¨çé项ï¼é»è®¤æ¯-iãpython5-iæ¯è§£éå¨çé项ï¼é»è®¤æ¯-iãPythonçåé没æç±»åãPythonæ说çâæ°æ®ç±»åâæ¯åéææçå åä¸å¯¹è±¡çç±»åãPythonæ¯ä¸ç§è§£éåè¯è¨Python使ç¨ç¼©è¿å¯¹é½ç»ç»ä»£ç æ§è¡ï¼æ以没æ缩è¿ç代ç ï¼é½ä¼å¨è½½å ¥æ¶èªå¨æ§è¡æ°æ®ç±»åã
å¨pythonä¸cãi-1ãæ¯ä»ä¹æææ1èµå¼ç»åécã
cçäº1æ¯æåé1èµå¼ç»åécï¼èä¸æ¯å®ä¹ä¸ä¸ªåécï¼å 为pythonä¸åéæ¯æ²¡æå®ä¹çã
çäºå·å¨pythonä¸æ¯èµå¼è¿ç®ç¬¦ï¼è¿æå ³ç³»è¿ç®ç¬¦ãé»è¾è¿ç®ç¬¦çã
ç»è¯ï¼ä»¥ä¸å°±æ¯é¦å¸CTOç¬è®°ä¸ºå¤§å®¶ä»ç»çå ³äºpython-içäºå¤å°çå ¨é¨å 容äºï¼å¸æ对大家ææ帮å©ï¼å¦æä½ è¿æ³äºè§£æ´å¤è¿æ¹é¢çä¿¡æ¯ï¼è®°å¾æ¶èå ³æ³¨æ¬ç«ã
Python实现十大经典排序算法--python3实现(以及全部的排序算法分类)
我简单的绘制了一下排序算法的分类,蓝色字体的排序算法是我们用python3实现的,也是比较常用的排序算法。
一、常用排序算法
1、冒泡排序——交换类排序
1.1 简介
冒泡排序(Bubble Sort)是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。最快:当输入的数据已经是正序时;最慢:当输入的数据是反序时。
1.2 源码
1.3 效果
2、快速排序——交换类排序
2.1 简介
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。特点是选基准、分治、递归。
2.2 源码
2.3 快排简写
2.4 效果
3、选择排序——选择类排序
3.1 简介
选择排序是一种简单直观的排序算法。无论什么数据进去都是 O(n²) 的时间复杂度。
3.2 源码
3.3 效果
4、堆排序——选择类排序
4.1 简介
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。分为两种方法:大顶堆、小顶堆。平均时间复杂度为 Ο(nlogn)。
4.2 源码
4.3 效果
5、插入排序——插入类排序
5.1 简介
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了。工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
5.2 源码
5.3 效果
6、希尔排序——插入类排序
6.1 简介
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。基于插入排序的原理改进方法。
6.2 源码
6.3 效果
7、归并排序——归并类排序
7.1 简介
归并排序(Merge sort)采用分治法(Divide and Conquer)策略,是一种典型的分而治之思想的算法应用。
7.2 源码
7.3 效果
8、计数排序——分布类排序
8.1 简介
计数排序的核心在于将输入的数据值转化为键存储在额外的数组空间中。要求输入的数据必须是有确定范围的整数,运行时间是 Θ(n + k),不是比较排序,性能快于比较排序算法。
8.2 源码
8.3 效果
9、基数排序——分布类排序
9.1 简介
基数排序是一种非比较型整数排序算法,可以用来排序字符串或特定格式的浮点数。
9.2 源码
9.3 效果
、桶排序——分布类排序
.1 简介
桶排序是计数排序的升级版,它利用了函数的映射关系,高效与否的关键在于映射函数的确定。桶排序关键在于均匀分配桶中的元素。
.2 源码
.3 效果
三、Github源码分享
写作不易,分享的代码在 github.com/ShaShiDiZhua...
请点个关注,点个赞吧!!!
openGauss数据库源码解析系列文章——事务机制源码解析(一)
事务是数据库操作的核心单位,必须满足原子性、一致性、隔离性、持久性(ACID)四大属性,确保数据操作的可靠性与一致性。以下是openGauss数据库中事务机制的详细解析:
### 事务整体架构与代码概览
在openGauss中,事务的实现与存储引擎紧密关联,主要集中在源代码的`gausskernel/storage/access/transam`与`gausskernel/storage/lmgr`目录下。事务系统包含关键组件:
1. **事务管理器**:事务系统的中枢,基于有限循环状态机,接收外部命令并根据当前事务状态决定下一步执行。
2. **日志管理器**:记录事务执行状态及数据变化过程,包括事务提交日志(CLOG)、事务提交序列日志(CSNLOG)与事务日志(XLOG)。
3. **线程管理机制**:通过内存区域记录所有线程的事务信息,支持跨线程事务状态查询。
4. **MVCC机制**:采用多版本并发控制(MVCC)实现读写隔离,结合事务提交的CSN序列号,确保数据读取的正确性。
5. **锁管理器**:实现写并发控制,通过锁机制保证事务执行的隔离性。
### 事务并发控制
事务并发控制机制保障并发执行下的数据库ACID属性,主要由以下部分构成:
- **事务状态机**:分上层与底层两个层次,上层状态机通过分层设计,支持灵活处理客户端事务执行语句(BEGIN/START TRANSACTION/COMMIT/ROLLBACK/END),底层状态机记录事务具体状态,包括事务的开启、执行、结束等状态变化。
#### 事务状态机分解
- **事务块状态**:支持多条查询语句的事务块,包含默认、已开始、事务开始、运行中、结束状态。
- **底层事务状态**:状态包括TRANS_DEFAULT、TRANS_START、TRANS_INPROGRESS、TRANS_COMMIT、TRANS_ABORT、TRANS_DEFAULT,分别对应事务的初始、开启、运行、提交、回滚及结束状态。
#### 事务状态转换与实例
通过状态机实例展示事务执行流程,包括BEGIN、SELECT、END语句的执行过程,以及相应的状态转换。
- **BEGIN**:开始一个事务,状态从默认转为已开始,之后根据语句执行逻辑状态转换。
- **SELECT**:查询语句执行,状态保持为已开始或运行中,事务状态不发生变化。
- **END**:结束事务,状态从运行中或已开始转换为默认状态。
#### 事务ID分配与日志
事务ID(xid)以uint单调递增序列分配,用于标识每个事务,CLOG与CSNLOG分别记录事务的提交状态与序列号,采用SLRU机制管理日志,确保资源高效利用。
### 总结
事务机制在openGauss数据库中起着核心作用,通过详细的架构设计与状态管理,确保了数据操作的ACID属性,支持高并发环境下的高效、一致的数据处理。MVCC与事务ID的合理使用,进一步提升了数据库的性能与数据一致性。未来,将深入探讨事务并发控制的MVCC可见性判断机制与进程内的多线程管理机制,敬请期待。
å¦ä½å®è£ resin
1.Resin å¯ä»¥å¨ /download/index.xtp å è´¹ä¸è½½å使ç¨ã使ç¨Resinå¼åæè å¦ä¹ æ¯å è´¹çï¼ä½æ¯å¦ææResinä½ä¸ºæ¶è´¹äº§ååå¸æ¯éè¦ä»è´¹çãç®åççæ¬æ¯2..
ä¸è½½Resin æ¶éæ©Archive Versions ä¸ç windows.zipçæ®éå®è£ å resin-2.1.0.zip.
æ该zipå 解åå°ä»»ä½ç®å½ä¸é¢ï¼å¦dï¼ esin.以ä¸ä»ç»é½å设Resinå®è£ å¨dï¼ esinä¸ãè¿å ¥dï¼ esininï¼
é®å ¥.caucho.sql.*;å»æé¿å å²çª.
DBPoolç±»èä¾:
package com.netease.mm;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public class DBPool
{
private Connection conn = null;
public static DBPool getPool(String poolName)
{
try
{
Context env = (Context) new InitialContext().lookup("java:comp/env");
DataSource source = (DataSource) env.lookup("jdbc/"+poolName);
DBPool pool = new DBPool();
pool.conn = source.getConnection();
return pool;
}
catch(Exception e)
{
return null;
}
}
public Connection getConnection()
{
return conn;
}
}
é ç½®stderr,stdoutçlogé®é¢. Resin3é»è®¤å¹¶ä¸ä¼å°ç¨åºåºéçä¿¡æ¯æå°åºæ¥.éè¦èªå·±è®¾ç½®.
å¨<resin>ç»ç¹ä¹ä¸æ·»å å¦ä¸é ç½®:
<log name='' level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"
format=" ${ log.level} ${ log.loggerName} ${ log.message}"/>
é ç½®ä¸æ æ³è§£å³çé®é¢: å¨resin2.0.xä¸.å¯ä»¥è®¾ç½®error-page,å½resinå¯å¨é误ææªå¯å¨æ¶,访é®ä¸»é¡µå°èªå¨è½¬åå°æ设置çerror-page, å¨resin3ä¸,è½ç¶ä¸»é¡µå¸®å©éé¢æå°è¿ä¸ªè®¾ç½®
ä¾:<error-page exception-type='connection' location='/errpage.html'/>, ä½ç»è¿æµè¯.æ 论å°æ¤è®¾ç½®æ¾å¨åªä¸å±ç»ç¹(resin,server,host,web-app)ä¹ä¸.é½æ æ³èµ·å°è½¬åçä½ç¨. è¿å°±å¼åä¸ä¸ªä¸¥éçé®é¢,å½resin3æªå¯å¨èapacheè¿è¡æ¶.访é®jsp页é¢,å°ç´æ¥æ¾ç¤ºåºæºç .该é®é¢å¨resin3è³ä»åå¸ççæ¬é½åå¨,ç®åæ¾ä¸å°ææ便æ·ç解å³æ¹æ³.
2024-12-28 15:33
2024-12-28 14:48
2024-12-28 14:26
2024-12-28 14:05
2024-12-28 14:02
2024-12-28 13:12