论坛首页 Java企业应用论坛

几行代码解决淘宝面试题 之Clojure版

浏览 26223 次
该帖已经被评为精华帖
作者 正文
   发表时间:2010-07-15  
dennis_zane 写道
ray_linn 写道
dennis_zane 写道
有区别吗?没有区别,我当然也可以用一个宏将你口中“天书“的语法包装一下,给你一个很性感的语法糖衣,文中代码也可以精简成一行。不过这不是重点,我其实是想忽悠更多的java程序员去看看clojure。


当然有区别,本来并行的算法就已经很劳神了,在折腾那些有的没的天书似的的语法,就是浪费生命。Microsoft把你看不起的糖衣,能包裹出linq for parellel, linq for grid,并加入对GPU的支持,而程序员专注于自己的处理逻辑本身。


您老很奇怪,又要跟我扯语言之争。我怎么会瞧不起语法糖衣,我对MS也没有任何意见。可能还是我说的不明白:我的本意是希望更多人关注clojure,通过这么个例子可以看出java和clojure之间巨大的生产力差距,看看clojure怎么将一个非并发的函数轻易地修改成并发执行。为了将问题说的清楚些,我不愿意将代码写的更进一步,不过我真不认为文中的代码是天书,从上到下看下来,解释得还算清楚吧。


存在即是道理,也没什么语言之争。一种语言的存在总有它的优势,比如这个语言适合这方便,那个语言更适合那方面,我们所做的就是权衡利弊,选择最合适的而已。不过clojure语法真的有点难懂,这或许是因为我们在大学甚至以前的时候接触的都是类似于C的语法,就连大学可能也把C语言当作一门教学语言,久而久之就习惯了。。有时间可以多了解下clojure。
0 请登录后投票
   发表时间:2010-07-15  
dennis_zane 写道

    我估计我不写这样的标题,吸引不了人气。问题的起因是这个帖子《淘宝面试题:如何充分利用多核CPU,计算很大 的 List中所有整数的和》,看见为了这么个问题写长长的Java代码,让我十分蛋疼。为了表示蛋定,我想介绍下用Clojure解决这个问题 的方法。

这里我想对文章的开头上面这段引用说明一下

 

我不是标题党,也无意吸引什么人气,这个标题是我Ctrl+C过来的。

 

“看见为了这么个问题写长长的Java代码,让我十分蛋疼。”,是想说我的代码太差吗?或者是太长?我想应该是这个意思吧,可能是LZ一激动打错字了。

 

 

javaeye很国内很不错的一个论坛,来到这里的很多人是为了学习,我当时也是这么来的。还记得当时为了一个问题,在问答上提问,一直在线等啊,期待着

有人能看看,能回答,当一刷新页面看到有新提醒的时候是多么激动啊!呵呵,相信这坛子里的很多人和我当时一样,有同样的经历和感受。所以现在我看到有人问

问题的时候,就帮忙想想,能回答的尽量回答下,因为我知道我也是这么走过来的。当然也遇到一些不好的,比如问题很简单,就有人说这么简单的问题也来问,这么白痴的问题也来探讨,哎!别提当时的心情了,呵呵。之所以当时有那么“弱智”的问题,关键在于学艺不精,不知道这条路怎么走。。相信现在坛子里还有很多这样的人。

 

呵呵,回帖发起来感慨了。。希望路过的不要拍我!我想说的是我们都在这里,也就是朋友,称为“坛友”(不知道有这个词吗?)更合适,在这里我们相互学习,熟悉。当然每个人也都希望被尊重,特别是那些刚刚入门的。虽然我们不曾谋面,但是说不定在哪里见了面,聊起来这坛子里的事,然后恍然大悟的说:“哦!,原来你就是javaeye的那个XXX啊”!

 

0 请登录后投票
   发表时间:2010-07-15  
飞雪无情 写道
dennis_zane 写道

    我估计我不写这样的标题,吸引不了人气。问题的起因是这个帖子《淘宝面试题:如何充分利用多核CPU,计算很大 的 List中所有整数的和》,看见为了这么个问题写长长的Java代码,让我十分蛋疼。为了表示蛋定,我想介绍下用Clojure解决这个问题 的方法。

这里我想对文章的开头上面这段引用说明一下

 

我不是标题党,也无意吸引什么人气,这个标题是我Ctrl+C过来的。

 

“看见为了这么个问题写长长的Java代码,让我十分蛋疼。”,是想说我的代码太差吗?或者是太长?我想应该是这个意思吧,可能是LZ一激动打错字了。

 

 

    呵呵,这只是修辞,放松一点,如果让你觉的不适,我很抱歉。我抱怨的不是你的代码,我抱怨的是Java语言本身带来的累赘,为了解决一个问题,我需要写N多跟问题不相关的代码,你不用太在意,不针对任何人。

0 请登录后投票
   发表时间:2010-07-15  

我有个问题,比如增加了一个额外的需求,想统计一下各个子线程分别花了多少时间来完成计算。楼主的 Clojure 版代码容易修改吗?

0 请登录后投票
   发表时间:2010-07-15   最后修改:2010-07-15
chinpom 写道

我有个问 题,比如增加了一个额外的需求,想统计一下各个子线程分别花了多少时间来完成计算。楼主的 Clojure 版代码容易修改吗?


很容易,不过是函数的组合,加个计时函数tme到匿名函数:

(defn mysum3 [coll  n]
    (let [sub-colls   (partition n n [0] coll)
          result-coll (map #(future (time (reduce + 0 %))) sub-colls)] 
         (reduce #(+ %1 @%2) 0 result-coll))) 
 


示范输出:

 

1:1 user=> (mysum3 (range 0 1001) 400)
"Elapsed time: 13.481042 msecs"
"Elapsed time: 3.782884 msecs"
"Elapsed time: 2.498223 msecs"
500500

 

 

javaeye不支持代码的高亮,折腾,注意time函数的位置。

0 请登录后投票
   发表时间:2010-07-15   最后修改:2010-07-15
ray_linn 写道
写了那么长,我们这也是map/reduce

var collection = Enumerable.Range(0, 1000000).ToArray<int>();
long total = 0;
Parallel.For<long>(0, collection.Length, () => 0, (j, loop, subtotal) =>
             {
                 subtotal += collection[j];
                 return subtotal;
             },
             (x) => Interlocked.Add(ref total,x)
             );


最简单的是:当然C#可以把所有魔术变成一行:

   collection.AsParallel<int>().Sum();

比起楼主那些天书一样的语法,PLINQ简明到任何人一看就懂:

    集合.并行处理.累加

上次还有人说,要处理大于10的,好吧,还是一行处理:
  
  collection.AsParallel<int>().Where(i=>i>10).Sum();

  集合.并行处理.取大于10的.累加。

至于什么partition之类的,本来就不需要程序员去介入,线程数应该等于CPU的core数目,手工去分partition,完全是浪费时间。

我有个问题,比如增加了一个额外的需求,想统计一下各个子线程分别花了多少时间来完成计算。你的的 C# 版代码容易修改吗?

0 请登录后投票
   发表时间:2010-07-16  
import scala.actors.Futures._
object Test {
	def split[T](part:Int, list:List[T], acc:List[List[T]]):List[List[T]] = {
		if (list == Nil) return acc
		val (head,tail) = list.splitAt(part)
		split(part, tail, head :: acc)
	}
	
	def parallelSum(n:Int, list:List[Long]):Long = {
		split(n,list,Nil).map({part=>future{part.sum}}).foldLeft(0l){_+_()}
	}
	
	def main(args : Array[String]) : Unit = {
		val list = Range.Long(1, 10000000, 1).toList
		val sum = parallelSum(list.size / 2, list)
	}
}


使用了自带的Future库,split需自己写
0 请登录后投票
   发表时间:2010-07-16  
dennis_zane 写道
飞雪无情 写道
dennis_zane 写道

    我估计我不写这样的标题,吸引不了人气。问题的起因是这个帖子《淘宝面试题:如何充分利用多核CPU,计算很大 的 List中所有整数的和》,看见为了这么个问题写长长的Java代码,让我十分蛋疼。为了表示蛋定,我想介绍下用Clojure解决这个问题 的方法。

这里我想对文章的开头上面这段引用说明一下

 

我不是标题党,也无意吸引什么人气,这个标题是我Ctrl+C过来的。

 

“看见为了这么个问题写长长的Java代码,让我十分蛋疼。”,是想说我的代码太差吗?或者是太长?我想应该是这个意思吧,可能是LZ一激动打错字了。

 

 

    呵呵,这只是修辞,放松一点,如果让你觉的不适,我很抱歉。我抱怨的不是你的代码,我抱怨的是Java语言本身带来的累赘,为了解决一个问题,我需要写N多跟问题不相关的代码,你不用太在意,不针对任何人。

呵呵,java有时候是这样,新的java7也不是让人太满意。这方便Clojure是个优势,有时间要好好看看这个JVM上的语言。。

0 请登录后投票
   发表时间:2010-07-16  
没办法 问题是oracle真叫我蛋疼,JAVA到他手真没什么起色。 悲剧了。
0 请登录后投票
   发表时间:2010-07-16  
虽然clojure不懂,不过能看出楼主的实际意义!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics