《Java编程艺术》第12章的问题,

第十六~第二十章:全排列,跳台阶,奇偶排序,第一个只出现一次等问题作者:July、。出处:。引言& & 最近这几天闲职在家,一忙着投简历,二为准备面试而搜集整理各种面试题。故常常关注个人所建的Algorithms1-14群内朋友关于笔试,面试,宣讲会,offer,薪资的讨论以及在群内发布的各种笔/面试题,常感言道:咱们这群人之前已经在学校受够了学校的那种应试教育,如今出来找工作又得东奔西走去参加各种笔试/面试,着实亦不轻松。幻想,如果在企业与求职者之间有个中间面试服务平台就更好了。& & ok,闲话少扯。在上一篇文章中,已经说过,“个人正在针对那100题一题一题的写文章,多种思路,不断优化,即成程序员编程艺术系列。”现本编程艺术系列继续开始创作,你而后自会和我有同样的感慨:各种面试题千变万化,层出不穷,但基本类型,解决问题的思路基本一致。& & 本文为程序员编程艺术第十六章~第二十章,包含以下5个问题:全排列;跳台阶;奇偶排序;第一个只出现一次的字符;一致性哈希算法。& & 同时,本文会在解答去年微软面试100题的部分题目时,尽量结合今年最近各大IT公司最新的面试题来讲解,两相对比,彼此对照,相信你会更加赞同我上面的话。且本文也不奢望读者能从中学到什么高深技术之类的东西,只求读者看此文看着舒服便可,通顺流畅以致一口气读完而无任何压力。ok,有任何问题,欢迎不吝指正。谢谢。第一部分、全排列问题53.字符串的排列。题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c 所能排列出来的所有字符串abc、acb、bac、bca、cab 和cba。& & 分析:此题最初整理于去年的微软面试100题中第53题,第二次整理于&第67题。无独有偶,这个问题今年又出现于今年的百度笔试题中。ok,接下来,咱们先好好分析这个问题。一、递归实现从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列。以对字符串abc进行全排列为例,我们可以这么做:以abc为例固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba固定c,求后面ba的排列:cba,cab。代码可如下编写所示:template&&typename&T&&&void&CalcAllPermutation_R(T&perm[],&int&first,&int&num)&&{&&&&&&if&(num&&=&1)&{&&&&&&&&&&return;&&&&&&}&&&&&&&&&&&&for&(int&i&=&&i&&&first&+&&++i)&{&&&&&&&&&&swap(perm[i],&perm[first]);&&&&&&&&&&CalcAllPermutation_R(perm,&first&+&1,&num&-&1);&&&&&&&&&&swap(perm[i],&perm[first]);&&&&&&}&&} && & 或者如此编写,亦可:void Permutation(char* pStr, char* pBegin);
void Permutation(char* pStr)
Permutation(pStr, pStr);
void Permutation(char* pStr, char* pBegin)
if(!pStr || !pBegin)
if(*pBegin == '\0')
printf(&%s\n&, pStr);
for(char* pCh = pB *pCh != '\0'; ++ pCh)
// swap pCh and pBegin
char temp = *pCh;
*pCh = *pB
Permutation(pStr, pBegin + 1);
// restore pCh and pBegin
temp = *pCh;
*pCh = *pB
}二、字典序排列把升序的排列(当然,也可以实现为降序)作为当前排列开始,然后依次计算当前排列的下一个字典序排列。对当前排列从后向前扫描,找到一对为升序的相邻元素,记为i和j(i & j)。如果不存在这样一对为升序的相邻元素,则所有排列均已找到,算法结束;否则,重新对当前排列从后向前扫描,找到第一个大于i的元素k,交换i和k,然后对从j开始到结束的子序列反转,则此时得到的新排列就为下一个字典序排列。这种方式实现得到的所有排列是按字典序有序的,这也是C++ STL算法next_permutation的思想。算法实现如下:template&&typename&T&&&void&CalcAllPermutation(T&perm[],&int&num)&&{&&&&&&if&(num&&&1)&&&&&&&&&&return;&&&&&&&&&&&&&&&&while&(true)&{&&&&&&&&&&int&i;&&&&&&&&&&for&(i&=&num&-&2;&i&&=&0;&--i)&{&&&&&&&&&&&&&&if&(perm[i]&&&perm[i&+&1])&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&if&(i&&&0)&&&&&&&&&&&&&&break;&&//&已经找到所有排列&&&&&&&&&&&&&&&&int&k;&&&&&&&&&&for&(k&=&num&-&1;&k&&&i;&--k)&{&&&&&&&&&&&&&&if&(perm[k]&&&perm[i])&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&swap(perm[i],&perm[k]);&&&&&&&&&&reverse(perm&+&i&+&1,&perm&+&num);&&& & & & &&&&&}&&} && 扩展:如果不是求字符的所有排列,而是求字符的所有组合,应该怎么办呢?当输入的字符串中含有相同的字符串时,相同的字符交换位置是不同的排列,但是同一个组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。第二部分、跳台阶问题27.跳台阶问题题目:一个台阶总共有n 级,如果一次可以跳1 级,也可以跳2 级。求总共有多少总跳法,并分析算法的时间复杂度。& & 分析:在中第23题又出现了这个问题,题目描述如下:23、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?咱们先撇开这个人人笔试的问题(其实差别就在于人人笔试题中多了一次可以跳三级的情况而已),先来看这个第27题。& & 首先考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。& & 现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。当n&2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶时的不同跳法的总数f(n)=f(n-1)+(f-2)。& & 我们把上面的分析用一个公式总结如下:& & & & / &1 & & & & & & & & & & & & & & n=1f(n)= & & &2 & & & & & & & & & & & & &n=2& & & & \ &f(n-1)+(f-2) & & & & & &n&2& & 原来上述问题就是我们平常所熟知的Fibonacci数列问题。可编写代码,如下:long long Fibonacci_Solution1(unsigned int n)
int result[2] = {0, 1};
return result[n];
return Fibonacci_Solution1(n - 1) + Fibonacci_Solution1(n - 2);
}& & &那么,如果是人人笔试那道题呢?一个人上台阶可以一次上1个,2个,或者3个,岂不是可以轻而易举的写下如下公式:& & & & / & & &1 & & & & & & & & & & & & & & & & & & &n=1f(n)= & & &2 & & & & & & & & & & & & & & & & & & &n=2& & & & & & & 4 & & & & & & & & & & & & & & & & & & &n=3 & & & //111, 12, 21, 3& & & & \ &f(n-1)+(f-2)+f(n-3) & & & & & &n&3& & 行文至此,你可能会认为问题已经解决了,但事实上没有:用递归方法计算的时间复杂度是以n的指数的方式递增的,我们可以尝试用递推方法解决。具体如何操作,读者自行思考。有一种方法,能在O(logn)的时间复杂度内求解Fibonacci数列问题,你能想到么?同时,有朋友指出对于这个台阶问题只需求幂就可以了(求复数幂C++库里有),不用任何循环且复杂度为O(1),如下图所示,是否真如此?:第三部分、奇偶调序54.调整数组顺序使奇数位于偶数前面。题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。分析:你当然可以从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于碰到一个偶数,需要移动O(n)个数字,只是这种方法总的时间复杂度是O(n2),不符合要求,pass。很简单,维护两个指针,一个指针指向数组的第一个数字,向后移动;一个个指针指向最后一个数字,向前移动。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。& & 思路有了,接下来,写代码实现://思路,很简答,俩指针,一首一尾
//如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,
//我们就交换这两个数字
// 2 1 3 4 6 5 7
// 7 1 3 4 6 5 2
// 7 1 3 5 6 4 2
//如果限制空间复杂度为O(1),时间为O(N),且奇偶数之间相对顺序不变,就相当于正负数间顺序调整的那道题了。
//copyright@2010 zhedahht。
void Reorder(int *pData, unsigned int length, bool (*func)(int));
bool isEven(int n);
void ReorderOddEven(int *pData, unsigned int length)
if(pData == NULL || length == 0)
Reorder(pData, length, isEven);
void Reorder(int *pData, unsigned int length, bool (*func)(int))
if(pData == NULL || length == 0)
int *pBegin = pD
int *pEnd = pData + length - 1;
while(pBegin & pEnd)
// if *pBegin does not satisfy func, move forward
if(!func(*pBegin))
pBegin ++;
// if *pEnd does not satisfy func, move backward
if(func(*pEnd))
// if *pBegin satisfy func while *pEnd does not,
// swap these integers
int temp = *pB
*pBegin = *pE
bool isEven(int n)
return (n & 1) == 0;
}& & 细心的读者想必注意到了上述程序注释中所说的“如果限制空间复杂度为O(1),时间为O(N)就相当于正负数间顺序调整的那道题了”,没错,它与个人之前整理的一文中的第5题极其类似:5、一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的正负数之间相对顺序 比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时间复杂度O(N),空间O(1) 。(此题一直没看到令我满意的答案,一般达不到题目所要求的:时间复杂度O(N),空间O(1),且保证原来正负数之间的相对位置不变)。& & 如果你想到了绝妙的解决办法,不妨在本文评论下告知于我,或者来信指导(),谢谢。第四部分、第一个只出现一次的字符第17 题:题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。& & 分析:这道题是2006 年google 的一道笔试题。它在今年又出现了,不过换了一种形式。即最近的搜狐笔试大题:数组非常长,如何找到第一个只出现一次的数字,说明算法复杂度。此问题已经在程序员编程艺术系列第二章中有所阐述,在此不再作过多讲解。代码,可编写如下:#include&&iostream&&&using&namespace&&&&&//查找第一个只出现一次的字符,第1个程序&&//copyright@&Sorehead&&&&July&&//July、updated,.&&char&find_first_unique_char(char&*str)&&{&&&&&&int&data[256];&&&&&&char&*p;&&&&&&&&&&&&if&(str&==&NULL)&&&&&&&&&&return&'\0';&&&&&&&&&&&&memset(data,&0,&sizeof(data));&&&&//数组元素先全部初始化为0&&&&&&p&=&&&&&&&while&(*p&!=&'\0')&&&&&&&&&&data[(unsigned&char)*p++]++;&&//遍历字符串,在相应位置++,(同时,下标强制转换)&&&&&&&&&&&&while&(*str&!=&'\0')&&&&&&{&&&&&&&&&&if&(data[(unsigned&char)*str]&==&1)&&//最后,输出那个第一个只出现次数为1的字符&&&&&&&&&&&&&&return&*&&&&&&&&&&&&&&&&&&&&str++;&&&&&&}&&&&&&&&&&&&return&'\0';&&}&&&&int&main()&&{&&&&&&char&*str&=&&afaccde&;&&&&&&cout&&&&find_first_unique_char(str)&&&&&&&&&&return&0;&&}&&&&当然,代码也可以这么写(测试正确):&//查找第一个只出现一次的字符,第2个程序&&//copyright@&yansha&&//July、updated,.&&char&FirstNotRepeatChar(char*&pString)&&{&&&&&&if(!pString)&&&&&&&&&&return&'\0';&&&&&&&&&&&&const&int&tableSize&=&256;&&&&&&int&hashTable[tableSize]&=&{0};&//存入数组,并初始化为0&&&&&&&&&&&&char*&pHashKey&=&pS&&&&&&while(*(pHashKey)&!=&'\0')&&&&&&&&&&hashTable[*(pHashKey++)]++;&&&&&&&&&&&&while(*pString&!=&'\0')&&&&&&{&&&&&&&&&&if(hashTable[*pString]&==&1)&&&&&&&&&&&&&&return&*pS&&&&&&&&&&&&&&&&&&&&pString++;&&&&&&}&&&&&&return&'\0';&&//没有找到满足条件的字符,退出&&} &第五部分、一致性哈希算法tencent2012笔试题附加题& & 问题描述: 例如手机朋友网有n个服务器,为了方便用户的访问会在服务器上缓存数据,因此用户每次访问的时候最好能保持同一台服务器。已有的做法是根据ServerIPIndex[QQNUM%n]得到请求的服务器,这种方法很方便将用户分到不同的服务器上去。但是如果一台服务器死掉了,那么n就变为了n-1,那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%(n-1)]基本上都不一样了,所以大多数用户的请求都会转到其他服务器,这样会发生大量访问错误。& & 问: 如何改进或者换一种方法,使得:(1)一台服务器死掉后,不会造成大面积的访问错误,(2)原有的访问基本还是停留在同一台服务器上;(3)尽量考虑负载均衡。(思路:往分布式一致哈希算法方面考虑。)最土的办法还是用模余方法:做法很简单,假设有N台服务器,现在完好的是M(M&=N),先用N求模,如果不落在完好的机器上,然后再用N-1求模,直到M.这种方式对于坏的机器不多的情况下,具有更好的稳定性。一致性哈希算法。& & 下面,本文剩下部分重点来讲讲这个一致性哈希算法。应用场景& & 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括:& 轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等。其中哈希算法是最为常用的算法.&&& 典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务。&&& 常用的算法是对hash结果取余数 (hash() mod&N):对机器编号从0到N-1,按照自定义的hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;如果新增一台机器,会有N /(N+1)的服务器的缓存数据需要进行重新计算。对于系统而言,这通常是不可接受的颠簸(因为这意味着大量缓存的失效或者数据需要转移)。那么,如何设计一个负载均衡策略,使得受到影响的请求尽可能的少呢?&&& 在Memcached、Key-Value Store、Bittorrent DHT、LVS中都采用了Consistent Hashing算法,可以说Consistent Hashing 是分布式系统负载均衡的首选算法。Consistent Hashing算法描述&&& 下面以Memcached中的Consisten Hashing算法为例说明。&&& 由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,232-1]间,如果我们把一个圆环用232&个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~232的圆上。&&& 用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。&Consistent Hashing原理示意图&&& 新增一个节点的时候,只有在圆环上新增节点逆时针方向的第一个节点的数据会受到影响。删除一个节点的时候,只有在圆环上原来删除节点顺时针方向的第一个节点的数据会受到影响,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。&&&Consistent Hashing添加服务器示意图&&&&虚拟节点(virtual nodes):之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。&& & & & & & & & &虚拟节点对Consistent Hashing结果的影响&&& 从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。&&& &“但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;”为何是&(N-1)/N&呢?解释如下:& 比如有 3 台机器,hash值&1-6 在这3台上的分布就是:& host 1:&1&4& host 2:&2&5& host 3: 3 6& 如果挂掉一台,只剩两台,模数取 2 ,那么分布情况就变成:& host 1:&1&3 5& host 2:&2&4 6& & 可以看到,还在数据位置不变的只有2个:&1,2,位置发生改变的有4个,占共6个数据的比率是 4/6 = 2/3,这样的话,受影响的数据太多了,势必太多的数据需要重新从 DB&加载到 cache 中,严重影响性能。后记以上部分代码思路有参考自此博客:。特此注明下。& & &行文仓促,若有任何问题或漏洞,欢迎不吝指正或赐教。谢谢。转载,请注明出处。完。
阅读(...) 评论()以前关注过无盘站,现在有瘦客户端,共享器。
硬件版本的:
目前全球多媒体共享器有3个版本:
1:是新加坡技术版本的,因为该软件不能升级所以,以低端用户为主里面有分为几个型号
(1)拖机卡(又叫加密狗)全套包括:加密狗(USB 转 PS/2鼠标键盘接头) PCI显卡 USB线 VGA线 价格是共享器系列产品中目前最低的产品,没有声卡和USB外接口,功能简单,经济实用,早期产品,性能一般.
(2)多媒体共享器(支持USB1.0速度) 全套包括:多媒体盒一个 PCI显卡一张 VGA线一条 USB线一条 驱动盘说明书 该版本为早期多媒体型,集成声卡和USB1.0,因为USB只能支持1.0,所以在共享器设备的速度和稳定性一般,有时会出现鼠标键盘丢失情况,不支持USB和鼠标键盘热插热拔,须重起电脑才可以继续工作.价格便宜,在共享器中排在第2位的便宜价格的.
(3)多媒体型共享器(支持USB2.0)全套包括:多媒体盒一个 PCI显卡一张 VGA线一条 USB线一条 驱动盘说明书 该版本为新版本集成声卡 传输速度快,USB设备稳定性高,支持USB和鼠标键盘热插热拔,是目前新加坡版本的多媒体共享器中最高端的产品,也是替代USB1.0产品的最价版本,价格比支持USB1.0的老版本要贵10块钱左右.市场反映交好,是市场多媒体主流产品之一.
2:美国版多媒体共享器 该产品是有正版软件序列号的多媒体共享器,支持USB2.0传输速度,技术设计和软件设计与新加坡版本有本质的区别,硬件稳定可靠,运行性能比新加坡版本的要好,较稳定,控制台软件比新加坡版本的共享器功能强大,软件每年根据WINDOWS可以升级,集成声卡,2个USB外接口,使用简单,兼容性是目前最好的版本,全套包括:多媒体共享器一台,PCI显卡一张 VGA线一条 USB线一条,说明书光盘 价格比新加坡版本的要贵几十块钱.物有所值.可出口到欧盟,美国等全球市场,进出口最好,主要针对高端客户市场,国内重点招标工程主流产品.
3:PC-STATION网络口电脑共享器 该产品主要是通过网线连接到局网路由器或交换机口上,距离可以传输100米左右,显卡通过虚拟在共享器设备上,一次性可以连接30台以上的,可以登陆局网中任意一台安装了后台软件的电脑主机,安装比较简单,不需要打开电脑主机安装显卡,主要通过网络登陆主机IP地址一些常规的设置就可以使用了,显示分辨率支持1024*768.支持16位真色彩,该款主要是高端市场,价格是目前最高.
清华同方云终端VD1000硬件评测看VD1000的外观,与淘宝上200多元的共享器几乎一模一样,应该就是同一家厂商代工的。与其他共享器的区别是:1、机器内部带了个正版的 WINCE。因此多了 MINIPC 模式和共享模式。其他的共享器只有共享模式。2、带了很多免费的看OFFICE 文档的软件。但是都是第三方的。免费的那种。效果不怎么样。3、同方自己写了一套VDP协议的软件。其实就是微软RDP协议上再开发的,规避了微软的数字授权要付费这一点。4、VD1000有3个USB口,其他的共享器一般是有PS2口,没有USB口。因此VD元。存在的问题1、minipc模式下仍然无法直接通过键盘用普通拼音输入法输入。2、服务器端VDP软件安装后无法再使用RDP的远程桌面。3、鼠标、键盘不稳定,时不时会丢失或者无响应,需要拔下再插上。4、鼠标键盘存在比较严重的延迟问题。有耐心一点一点使用没问题,但是效率高的输入员使用时经常出现因为延迟造成移动鼠标变成选定区域等问题。5、发现只要服务器端安装了QQ2009,会随机的出现很慢很慢的假死情况。而出现假死情况时ping网络,timeout在1以下,CPU占用率在30%一下,而且同一台服务器上的其他用户也能照常使用。
软件版本的
随着教育信息化的推进,很多学校都建立了自己的多媒体机房。机房建设的前期投入比较大,对于富裕地区来说还可以承受,但对于经济欠发达地区来说就比较困难了。在网上找到了一个叫做BeTwin2000/XP的软件,使用该软件,可以在一台PC内建立最多达四个PC虚拟终端,用户只需加入显示器、PCI显卡、USB键盘、USB鼠标和音箱,就可以获得和主机完全相同的Windows环境(图)。也就是说一台电脑主机最多可以5个人使用。使用该软件为学校建立了一个多媒体阅览室,平均下来每台“电脑”的成本不到2000元。所有计算机同时上网、运行多媒体课件、点播视频都很流畅,完全满足了教学要求。
BeTwin2000/XP是微软公司开发的一个瘦客户机软件,由于现在主机的主频很高,而绝大多数情况下我们只用不到其性能的20%,只要给主机增加相应的内存就足可以组建一拖五的单机多用户系统。使用Betwin组建机房比有盘站和无盘站都具有相当大的优势。
2.舜华艾康拖机宝 Hishare
Hishare是一款支持Windows2000/XP的软件,现在比较成熟的版本是2008年6月官方发布的4.03.093版,这一版能完美支持XP SP3。
毕竟成功案例不多。
于是小王老师可以做一张出国申请表的表单来收集学生的数据,并把正在收集数据的表格共享给了小红老师,小红老师立即在表格上进行审核,学生可以随时通过链接查询自己数据的审核情况...
On Error Resume Nexttemp=0set wshshell=wscript.createobject(&wscript.shell&)wshshell.run (&%comspec%...
今天遇到了电脑启动提示“你的电脑遇到问题,需要重新启动,我们只收集某些错误信息,然后为你重新启动。”,我在网上查了许多这方面的问题,主要总结为两点,一、软件,二、硬件。
首先说下这个提示,这是微...
电脑前几天还可以找到局域网中电脑的共享,今天却找不到了。查看防火墙也都关闭了。也能ping通。于是百度了下,提供了如下解决方法:1 删除防火墙(暂时关掉是没用的) 2 网上邻居-〉右键-...
1、信息收集
a. 获取当前组的计算机名
b. 查看所有域
net view /domain
c. 从计算机名获取ipv4地址
ping -n 1 计算机名 -4
  昨晚微软偷偷的更新了,整个机器慢得……恨不得砸了。还好有高人指点解决办法:
  点击“开始”→“设置”→“隐私”→“活动历史记录”,取消“允许Windows从此电脑中收集我的活动”、“允许Win...
说明:我有两台电脑,一台笔记本电脑有两张网卡,一张无线网卡,一张有线的网卡,这样我们就可以通过设置网络共享让其他电脑上网了,另外一台只有一张有线的网卡。工具/原料
笔记本电脑一台
win10装了一些杂七杂八的软件之后
一直出现这样的蓝屏
百度了好多还是没有解决
大概记录一下这个糟心的过程
因为工作需要所以一直不敢重装
过程1:(有人说重启就可以了,但是我的不...
没有更多推荐了,Andrei Alexandrescu 著
译的不好,请大家指正!
06月18日 00:38
06月19日 23:45
让我们看看为什么D语言是值得认真研究的. 当然,我不能哄骗自己说服你很容易. 我们程序员是一群以奇怪的方式来组成和维持语言偏好的. 程序员下意识的反应是在书店看到某某编程语言的书籍后想:好了,我给自己30秒内能找到我不喜欢这个语言的地方.获得编程语言的专业知识是一个长期而艰苦的过程,并且总是充满拖延和不确定性.试图寻找快捷理由来避免努力是一种生存本能:风险高,投资非常危险,因此早在学习过程前就迅速作出消极决定能让我们获得巨大的安慰. 尽管如此,学习和使用一门编程语言是很有乐趣的.由于用一门语言编码是很有趣的:如果这门语言做了令人满意的工作,让人满意的原则就是(让人)带着崇高的敬意使用它.任何一个原因都会让程序员关心语言,例如语言不认真,不安全,自以为是,或者非常乏味.同时,语言不可能满足大家的需求和口味,许多人要求也是矛盾的.因此它必须认真致力于几个基本原则才能适应编程语言的广阔场景. 因此,如何对待D呢?你可能已经听说它了. 在本文中我介绍了大体的概况,这意味着没有严格介绍他们的概念和功能,我必然要使用合理的直觉. 让我们看看一些主要的D语言基本特征.请注意,许多功能或者限制附加条件让他们界限模糊了.所以,如果你读的东西不完全让你满意,请不要担心:下一句可能包含附加的解释.例如,假设你读到"D包含垃圾收集",让你毛骨悚然,心灰意冷,要敬而远之.但如果你有耐心,你会发现,D有构造函数和析构函数,你可以实现一个确定生命周期的对象. 在了解很多的事情之前,有几件事你应该知道.首先,不管你是以什么原因发现的D语言,这一次不是"和其他的一样",如果你早日选择,这实际上大大优于其他的语言.D相对沉默,但是一直在以惊人速度不断变化.许多功能已经完成,正在做的事也成为了已知,就在本文中.在写本文时,我的书&&D编程语言&&已经40%完成,并且可以在Amazon预定,Safari(http://safaribooksonline.com/Corporate/Index/)的订阅服务可以提供一些完成的章节. 这里有两个主要的版本:D1和D2.本文焦点仅在D2.D1是一个稳定版本(将不进行修改除了修正错误).D2是一个重大修改版本,为了做的一贯正确,牺牲了向后兼容,增加了一些关键功能,有关多核和范型编程.在这个过程中,语言的复杂性有所增加.这实际上是一个很好的指标,因为没有实际使用的语言都变的更小.即使语言开始声明的意图就是"小而美"的也不可避免的增长和使用.(是的,甚至是Lisp语言,备用).虽然程序员梦想小巧,简单的语言.当他们醒来,他们似乎只想要更多的建模能力.D语言的转变就是让你在不值得羡慕的立场去处理一个移动的目标.我选择写一篇文章,因为描述的功能可以工作或者不完全执行. 官方D编译器是免费提供的,在digitalmars.com包含桌面平台( Windows ,苹果机和Linux),其他还正在实现中,特别是包括.NET和一个使用LLVM作为后端.此外,还有两个重要的D基本库库,官方-Phobos和社区推动Tango. Tango设计适用于D1,正在移植到D2中, Phobos(这是令人沮丧的古怪的D1迭代实现)正在发生重大修改和补充,以充分利用D2的功能.(因此,毫不奇怪,很多门派讨论哪些基本库更好,但竞争激励让他们一样好.) 最后但绝非不重要的是,两个窗口库实现相当壮观.成熟的DWT库是一个SWT的D实现.新的发展是很受欢迎的Qt库也公布了一个D绑定(在写Alpha版本).Qt是一个伟大的(最好的,如果你听了正确的人)库,开发轻便的GUI界面应用.这两个库让D达到了GUI层面.
2.D基本法则D能被最好的描述是高层次系统编程语言.它包含的功能是在高层次,甚至是脚本语言.象快速的编辑-运行周期,垃圾收集,内建哈希表,或者省略类型定义,但也有低层次的功能例如指针,手工内存管理(象C的malloc/free)或者半自动的(使用构造,析构和独特的scope声明)方法.通常和C/C++程序员知道和喜爱的内存管理直接联系.事实上,D能直接链接和调用C函数,不用任何解释层.整个C标准库都对D程序直接有效.然而,你很少会调用底层,因为D本身的能力,往往更强大,更安全和高效.总的来说,D提供了强类型声明,方法和效率并不一定矛盾.除了更高级别的主题,我们会尽快讨论,没有提及细节的描述,那么D的说明将是不完整的.所有变量都会被初始化,除非你初始化变量为void.数组和关联数组直观好看.迭代清晰,NaN真正在用.重载规则可以理解,内置支持文档和单元测试.D也是多模式的:也就是它包含了面向对象编程,范型编程,函数编程和过程编程功能,多种风格可以无缝封装在小的包中. 下面易于理解的章节介绍D的一些通用部分.
你好,初级例子让我们看看,没有烦人的语法,所以干脆痛快:
import std.
void main()
writeln("Hello, world!");
语法象多数人了解的语法一样-合理.对语言表面(语法)关心多了,我们理解应该是没有多大的差别.但令一方面,我们也不能阻止人们注意语法.(我记得从黑客帝国中的红衣女孩到现在),对于我们大多数人来说,D有很多相类似的语法,因为它是C风格的语法.象C++,Java,C#中的语法风格一样.(我假设你熟悉其中的一个,所以我不需要解释.D有意料中的功能,如整数,浮点数,数组,迭代和递归.
在谈到其他语言,请允许写一个初级例子的C和C++版本: "Hello World".经典的C版本,在K&R的第二版中,看起来像这样:
#include &stdio.h&
printf("hello, world\n");
等价的C++版本例子是(热情的补充)
#include &iostream&
int main()
std::cout && "Hello, world!\n";
许多流行的比较,是用各种语言写的第一个例子的代码长度和需要了解信息的数量.讨论的正确性会让我们采用不同的途径.即会发生什么原因使写入标志输出的贺词失败?当然,C语言回来的错误,因为它没有检查printf的返回值.说实话,其实是有点糟糕,虽然我的系统上无标志编译和运行,C版本的helloworld返回的值在某些操作系统不可以预测,因为在main函数的结尾不可预测.(在我的机器,它会返回13,这让我有些害怕.然后我意识到为什么了:"hello, world\n"有13个字符,printf返回了打印的字符数量,因此吧13存放在EAX寄存器.幸运的是退出代码不理会寄存器;因此操作系统最终是13.).原来结果是C89和C99的标准中给出的程序不正确.在一些搜索中,网络上看来正确的常用C语言打招呼是:
#include & stdio.h&
int main()
printf("hello, world\n");
这是正确的.因为它取代了无法预料的返回值,不论打印是否成功,都会返回成功(给操作系统)
在C++程序中,如果你忘记返回值,C++会保证从main返回0,而且还忽略了错误.在程序开始时
#include &stdio.h&
int main()
return printf("hello, world\n") & 0;
#include &iostream&
int main()
std::cout && "Hello, world!\n";
return std::cout.bad();
进一步调查显示,其他语言典型的"hello,world",如Java (由于空间限制代码省略) ,J# (一种完全语言-我的意思是完全的Java无关),或Perl ,所有例子同样成功.您几乎认为这是一个阴谋,但幸运的是,喜欢的Python和C#的会抛出一个异常.
为D版本会怎么办?当然,它不需要任何改变: writeln会在失败时抛出一个异常.异常的主要原因的信息会打印到标准错误流(如果可能的话),并以失败退出代码,总之,正确的事情是自动完成的.我不会采取这种初级例子.如果没有,原因有两个:第一,想象街头数百万程序员对他们的"Hello, world"程序是冒牌的来哭喊是很有趣的.(图片上口号"hello,world! Exit Code 13"巧合吗?或者,"您好,沉睡的人,醒醒吧!"等等).第二,例子不是孤立的,而是说明了一个普遍模式,D不仅试图让你做正确的事,只要有可能,它会系统地让正确的阻力到最小的方向.和原来的一样,这些常常会超过一个人的想象.(在你修改我的代码前,你应该认为"void main()"是一个合法的D语法.在C++新闻组中,他们需要找到另外一个喜欢的工具而切换到D中,语言学家会让新手用int main()来替换void main().)
够了,我打算讨论的语法和语义结束了.回到语法上来,有一个和C++,C#,Java有明显不同的是D用 T!(X, Y, Z) 代替了 T&X, Y, Z&(T!(X)或者T!X 来代替T&X&)来表示参数化类型.有几个好的理由.使用大于号和小于号,在进行"&"左移,"&"右移或者"&&"的算术操作时会冲突.C++有巨大的代码解析的问题.导致特殊规则的牺牲和任意的歧义.更不用说世界上很少有人知道object.template fun&arg&()的语法.如果你的一个C++学术研究人有了超人级别的自信,问问他们这些语法在做什么,你会看到超人克星工作了.java和C#也采用了大于小于号,但明智的不运行算术表达式作为参数,从而把这个选择留给了将来.D扩展了传统的一元运算符"!"并使用经典双括号搭配,(我相信)你总是会正确的使用它们.
D的编辑单元,是一个保护的模块化文件.文件的包就是一个目录.这不言而喻的精致.没有任何接口,程序源代码真正的感觉好多了,象在一个出色的数据库中.这种方法采用"数据库"发展了很长一段时间了.和版本控制,备份,操作系统级别的安全保护,日志完美的集成在一起.而且也使开发门槛降低:你需要的只是一个编辑器和编译器.目前专门支持的工具还很少,但你可以找到的如Emacs的D模式,Vim的支持,Eclipse的插件Descent,Linux的调试工具ZeroBugs,还有全功能的IDE Poseidon.
生成的代码是一个典型的二步循环编译和链接,但这种情况大大快于大多数类似的环境,有两个原因,不,是三个.
第一,语言的语法允许高度优化的词法分析和分析的步骤分开进行。 二,您可以轻松地指示编译器不产生许多对象,不象其他编译器做的一样,构造的一切存储到内存,并只有一个线性提交到磁盘三,Walter Bright,D的创建者和最初实现者,是一个根深蒂固的优化专家
低延迟的意思就是你可以将D用作一个魔鬼的解释器(全部语法支持).
D有一个真正的模块系统,支持独立的编辑,并自动从源代码生成使用模块的摘要(即"头文件"),因此您不必担心单独维护多余文件,除非你真的想维护的话,在这种情况下,您也可以维护.是的,停止对咬文嚼字纠缠吧.
3.内存模型和多核
我们知道 D 语言能够直接调用 C 函数,看起来好像 D 语言直接构建在 C 语言内存模型上似的。如果我们毫不在乎多核——大规模并行架构所带来的处理能力,或许这还是个好消息,就这样用好了。但如今多核时代已经来临,而 C 语言的那套处理方式则已极端过时和漏洞百出。其他的过程式和面向对象语言仅仅为此做了点点的改善。再就是函数式编程语言的情况,它依赖于不变性优雅的回避了很多并行相关的问题。 作为一个相对新生的语言,D 语言处在一个相当有利的形势。当它进入多线程世界时,可以综合考量、取舍很多东东,而且 D 语言的内存模型在某一方面和很多其他语言完全不同。你可以思考一下,经典的线程是不是如下这样工作:你调用了一个原语来启动一个新线程,然后新线程能够立即看到和访问程序中的任何数据。作为一个可选项,且按照依赖操作系统的晦暗模糊来说,线程也可以获得所谓的线程私有数据来为己所用。总之呢,内存默认是被所有线程所共享的。这种方式昔日已经引起人间腥风血雨无数,直到今天仍然在继续造就新的人间地狱。当初之所以留下这么多人间恨事,主要是因为并发更新的笨拙本质:它很难被正确追踪和同步,以至于不能自始至终的良好保持数据。但是人们仍然趋之若鹜,因为共享内存的观念非常接近于底层硬件的真实模型,而且使用得当的话,效率也非常高。现在是脱离这人间地狱的时候了。今天借助于内存容量的快速增长,需要共享的机会有所减少。关于现代硬件的事实是,处理器之间通讯通过深层分级存储器制度。而这其中每个核心很大一部分保持私有。因此共享内存方式也很难再发挥作用,它快速成为程序变慢的方式之一。因为存储器物理移动的次数和距离也快速增加了。 当传统命令式语言和这些问题缠斗的时候,函数式语言从数学中汲取智慧,另辟其径:命令式傻小子们,我们根本不关心硬件模型,而只关心纯粹的数学模型。因为数学大部分不会变化,而且时间恒定,因此成为并行计算的理想候选人。(想象一下,那些第一批从数学家转程序员的家伙听到并行计算的时候,肯定会直拍自己的前额:“等一下,等一下...”译注:我对 Andrei 老大讲笑话的水平真是不敢恭维)在函数式编程圈子里都知道这样的一个计算模型天生喜爱无序、并行执行,但是它的潜能直到近来才被挖掘出来。今天,越来越清楚地显示函数式的,mutation-free的编程方式至少会成为并行程序设计的一部分。 那么 D 的定位呢。D 对于并行有个基本的必要概念: 内存默认线程私有,按需共享。 在 D 中,所有的内存都是默认线程私有。即使是那些丑陋的全局变量也会被分配给每个线程。如果你想要共享,就需要在对象前面加上 shared 修饰符,这也就是说,该对象可以立即被其他线程可见。更为重要的是,D 语言类型系统了解共享数据,且限制它能够做什么以便确保同步机制能自始至终地被正确使用。这个模型可以很好的避免那些默认线程共享编程语言所带来的诸多同步棘手问题。在那些语言中,类型系统根本无法知道哪一个数据需要共享,哪一个不需要。所以它只能信任程序员,让他们来适当的标明共享数据。但是这样,就会产生很多麻烦,各种各样的场景都需要特别规则说明,比如非共享数据,已标明的共享数据,未标明但实际是共享数据,还有混合情况。Oh,yeah... 多核支持目前是非常活跃的一个研发领域,真正实际的良好模型还没有发现。D 语言把线程私有内存模型作为基础设施,只是为以下这些基础设施做些方便之处:纯函数、lock-free 原语,旧有的基于锁机制的良好编程机制、消息队列(计划中)等等。更高级的特性,比如所有权类型也在讨论中。
4.不可改变性,安全,面向对象功能到目前为止一切良好,但不变性和函数式编程风格的代码所发生的一切都是纯数学演示, D承认关键作用,函数式编程和不可变性构成并行程序(而不是仅仅并行,对于这个问题) ,所以它为永远都不会改变数据定义了一个immutable(关键字).与此同时D还认识到,变化往往是达到目标的最佳手段,更不用说我们许多人熟悉的风格了。 D的答案是相当有趣,因为它将可变数据和不可改变的数据包含在一个整体中了。
为什么不可变数据非常棒?因为在交叉线程中共享不可变数据永远不需要同步。不同步比同步速度快多了。诀窍在于,确保只读要真正意义上只读,否则一切保障都土崩瓦解。为支持并行编程的这一重要方面,D提供了一个无以伦比的混入功能支持非常重要的设计。为用immutable修饰的数据提供了强有力的静态保证,你必须正确输入程序不能改变数据。此外,不变性是深度的-如果你是不可变的,并声明为不可变数据,您将始终是不可变的(为什么呢?如果不那样,你认为你分开了不变的数据可以共享不变量,但最终无意中变成了可变数据共享,在这种情况下,我们又会回到复杂的规则中了,我们希望避免回到从前)。程序中整个相互关联对象的子图可以轻松的用immutable画出。类型系统知道它们,并允许线程自由共享,也可以在单线程代码中优化它们,以便更有优势的访问。
D是第一个提出默认的私有内存模型的语言?别客气。一个系统集成了默认私有线程,还有可变和不可变数据在内存中,这让D必须区别它们。诱惑是内部的更多细节,但让我们离开,为新的一天,继续概况。
极致的安全特性作为一个系统级的编程语言,D允许极端高效,同时也有危险的构造:允许非托管的指针,手工内存管理。非常小心的设计也可能被破坏。
然而,D也有很简单的机制让一个模块“安全”,一致的编辑风格可以强制内存安全。成功编写代码在语言的的一个子集-被亲切的称为“SafeD”,不用担心软件的可移植性,你就用你听到的编程经验就行,或者你不需要单元测试。SafeD仅仅关注消除可能的内存泄漏。安全的模块(或者使用了安全编辑模式)利用了额外的语义检查,禁止在编译时所以的危险语言功能,如忘记释放的指针,或者删除堆栈变量的地址。
在SafeD中你就不会有内存泄漏。安全模块构成了应用的绝大部分,然而“系统”模块却很少(是安全模块),要在代码回审时受到不断的注意。大量的应用程序可以完全用SafeD写成。但是一些事情象内存分配您必须让您的双手油腻(译为费尽心力更好吧)。伟大的是,你不需要用不同的语言完成你的应用的几个部分。在本文写作之时,SafeD还没有完成,还在积极的开发中。
不言自明:没有更多的斧头了
D是多模式的,这是一个需要技巧的说法,它没有心怀叵测。D已经获得备忘。任何事情不一定是一个对象,一个函数,一个列表,一个哈希表,或者牙齿仙女(译注:美国儿童都知道的典故,牙齿仙女可以有无边的法力)。这取决于你怎么做到这一点。用D编程会感觉到解放:因为你在想解决问题的时候不需要花费时间想法适应你选择的锤子(斧子)。现在,真相大白,你的责任就是:花费时间搞清楚什么样的设计最适合给出的问题。
不愿意停留在唯一的方法上,D沿袭了C++开始时的传统和优势,D为多种编程风格的转变提供了支持,更好的集成各种模式,并大大降低了下述任何语言转变的阻力。这对入门者也是很有利的。显然D更多感谢C++,并或多或少的吸收了其他语言:例如Java,Haskell,Eiffel,JavaScript,Python,和Lisp。(其实大多数语言借鉴于Lisp语言,有些只是不会承认这一点)(译注:Lisp的确很伟大,它完全由列表组成,有难以置信的强大功能和灵活性,也算是函数式编程的鼻祖,可惜我不会)
D兼收并蓄其他语言一个很好的例子就是资源管理。有些语言赌定你需要的管理的所有资源都需要垃圾收集。C++程序员知道RAII的优点,有些人说任何事都需要资源管理。每个小组都缺乏详尽的协作使用各种工具的经验,从而导致了滑稽的辩论:各方甚至不理解对方的论点。事实上,两个方法都有不足,因此D打破了一家之言。
面向对象编程
在D中你可以使用结构也可以使用类。它们同享很多优点,但却有不同的章程:结构是值类型,而类是为了动态多态性并通过参考访问。这些让人困惑,切片相关的错误,使用注释的方式“//不,不要继承!”不存在。在你设计一个类型的时候,你可以预先决定它是单态的值还是多态的参考。C++著名的允许顶一个歧义性类型,但是它们很少用,也易于出错,让人反感,足以为了简单设计而避免使用它们。
D提供的面向对象与Java和C#的相似:单一实现继承,多个接口继承。这使得Java和C#的代码非常容易迁移到D的实现中。D决定放弃语言级支持多重继承,但是伴随而来的是酸葡萄理论“多重继承是邪恶的:有什么护身符可以帮助我?”相反,D只是承认困难,使用多重继承工作更有效率,是一种有效的方式。使用多重继承的大部分好处在于控制成本,D允许类型使用多个子类型,如下:
class WidgetBase { ... }
class Gadget { ... }
class Widget : WidgetBase, Interface1, Interface2
Gadget getGadget() { ... }
alias getG // Widget subtypes Gadget!
这个引入的别名和this一样工作。什么时候你在一个Widget中要获得一个Gadget时,编译器就会调用getGadget 得到它。调用完全是透明的,如果不那样,它就不是子类型了,使用它将会让人沮丧。(如果你觉得这是一个讽刺,那么可能就是)。此外,getGadget已酌情完成任务-例如它可能会返回一个子对象,这或一个全新的对象。如果需要,你仍然可以做一些拦截方法,这听起来像很多样板的编码。但在这里就是D预先的反射和代码生成的能力(见下文)。基本思想就是,D子类型可以通过alias this来实现,你甚至可以成为int的子类型,如果你觉得喜欢它。
从面向对象的经验中,D集成了已被证明好的技术,例如一个显示的重载关键字避免意外重载,signal和slots,一种技术因为版权不能提到的,因此我们称为契约编程。
5.函数式和范型编程
函数式编程
如何快速顶一个函数式风格的斐波那契函数?
uint fib(uint int n)
return n & 2 ? n : fib(n - 1) + fib(n - 2);
我承认这是愉快的设想。其中一个设想就是,最后我回去,会以某种方式消除函数的执行,没有计算机科学教授不断教它。(下一个有冒泡排序和快速排序在空间上的函数O(n log n),但是fib有很大余地胜过他们,另外,杀死希特勒或斯大林是冒险的,因为它难以评估后果,而消除fib是好的。)fib需要指数的时间来完成,因此,执行只是无知的复杂性和花计算费用。一个是逗人的马虎借口,一个象越野车的驾驶。你知道什么是坏的指数?fib(10)和fib(20)在我的机器上用的时间可以忽略不计,但是fib(50)却要执行19分半。十有八九,计算fib(1000)会比人类活的还长,这给了我安慰,因为我们是值得的,如果我们继续教授拙劣的程序。
那么什么样的斐波那契函数实现是“Green”函数?
uint fib(uint n)
uint iter(uint i, uint fib_1, uint fib_2)
return i == n
: iter(i + 1, fib_1 + fib_2, fib_1);
return iter(0, 1, 0);
这个修订版可以用很少的时间执行fib(50)。这个实现现在耗费O(n)时间,尾部调用优化(D实现)抵消了空间(时间)复杂度。问题是新的版本看起来不美。修订版本必须维护两个状态变量伪装成函数参数。因此我们不妨删除并写一个直接的循环,避免iter函数带来的费解。
uint fib(uint n)
uint fib_1 = 1, fib_2 = 0;
foreach (i; 0 .. n)
auto t = fib_1;
fib_1 += fib_2;
return fib_2;
Rust与D的并发运算比较,运用3个内核(75%),D的占用内存稍大,但Debug模式下运行效率是Rust的几乎2倍,但Release模式下Rust的威力尽显,,Rust(并发)只是比D(并行)稍少3...
D语言的定义D 语言源自C/C++,借鉴了众多编程语言的特色和现代编译器技术,融会贯通了设计者丰富的实践经验,使之具备了非凡的威力--既有 C/C++ 语言的强大威力,又有 Python 和 Ruby...
C++的缺陷和D的缺陷D语言,从字面上讲应当是在C/C++的基础上进了一位,其特性当然也进了一位。真是这样?也是,也不是。这得看你的出发点和价值观了。D的定位在于继承C/C++的优势,但却更加易学易用...
D 是一种通用的系统和应用编程语言。它是比 C++ 更高级的语言,同时还保持了生成高效代码以及直接访问操作系统API和硬件...
D语言是个具有很多高级特性的编译型的语言,这篇文章教大家配置一个集成编程环境。write by DKink|棼紫进这个站点http://www.digitalmars.com/找到DownLoads下...
1. 首先到D语言官方网站http://www.digitalmars.com/d/2.0/dmd-windows.html下载最新的dmd和dmc2. 两个zip文件直接解压缩的C盘根目录(这里可以...
中文编程语言在国内发展来说,由来已久,普及比较广泛的应当是易语言。易语言的出现,使得很多使用VB开发简单对话框式的Widwos桌面的局面发生变化,很多人开始使用易语言来完成。易语言公司也曾经尝试开发“...
[编者按]D 语言既有 C 语言的强大威力,又有 Python 和 Ruby 的开发效率。它是一种集废料收集、手工内存操作、契约式设计、高级模板技术、内嵌汇编、内置单元测试、Mixin 风格多继承、类...
没有更多推荐了,

我要回帖

更多关于 编程艺术 的文章

 

随机推荐