• 申请删帖 at 2017年06月04日

    还没看源码,你的框架我两天前就反编译把所有代码都读完了。还 ThinkPHP,你的这段代码水平是和 ThinkPHP 一较高下了。

    对,你的 Controller 层是要被覆盖,因为连路由匹配都没有 Controller 也不知道是拿来干什么的。拿 PHP 来比较,我听说吹 Laravel 的,ThinkPHP 这种也能拿来吹的,你还是第一个勇士。

  • 申请删帖 at 2017年06月04日

    要是真要目标 get "/" method 目标一致,该用的是 C++ 11 的 std::function 的一些用法,用 std::bind 属于用错刀了。

  • 申请删帖 at 2017年06月04日

    你的纯原生实现连 TCP 的基础概念的实现都是错的,丢人吧你,还给点建议。你当初第一次找我怎么说的?

    我写的,基于 Objective-C 的自制框架,我没用 NIO,而是直接用 TCP + 非阻模型,另外业务比你的强,你这个只有骨架。
    

    TCP 是写错的,非阻模型是阻塞的,Controller 里 return body 直接写死 Hello World,牛逼啊这框架。 接下来又说不想给我看源码,这叫给建议? 还不停追着我喷,我现在是真生气了,然后说我怎么这性格?

  • 申请删帖 at 2017年06月04日

    别说性能优化了,你的服务器根本是不能用的。当 TCP 包不能一次性读回来的时候你的程序会直接奔溃。而且你所谓有业务模型的 Controller 连路由匹配都没有实现,View 层是一个字符串替换。你看了我的实现,你要真看了我的实现还会说我没有 Controller 吗?

  • 申请删帖 at 2017年06月04日

    「讨论 idris,好歹我写过!」 我记下来了。你现在告诉我用 Idris 实现一个 a+b 的函数需要哪几步。

  • 申请删帖 at 2017年06月04日

    你看,你以为你用了 accept_nonblock 就认为不阻塞了。要真这样,Ruby 下的 Web Adapter 几乎全是不阻塞的。把你代码的 accept_nonblock 改成 accept,性能不会发生任何变化,这个 accept_nonblock 用得完全是错的。

  • 申请删帖 at 2017年06月04日

    如果今天还认为 Objective-C 比 Swift 好的,至少在 Type-safe 的问题上是落后于时代十年的。

  • 申请删帖 at 2017年06月04日

    我觉得以楼主现在 Objective-C 的理解,看 Idris 大概是看天书吧。。。

  • challenge #1 - #6 update 06/03 at 2017年06月04日

    Nim Game 的 AI 如果无关输赢的话那就是乱写也可以。因为 Nim Game 从一开始就可以证明是必赢或者必输的。所以一个好的 AI 可以在必输时直接投降,必赢时不会输。

  • 申请删帖 at 2017年06月04日

    这篇文章的错误已经发展到了就算放到上世纪末也会被喷。顺便一说,之前反编译完那个楼主巨牛逼的 Autumn 框架后,我就发现这个所谓的使用了「非阻塞」设计的框架完全就是阻塞的,性能非常差,稍微跑个 benchmark 就能发现。之前只是知道结果,读完这篇文章我不难找到了原因,因为楼主对所有涉及到闭包概念的理解全部都是错误的。把 yield 认为是 goto 的,从算法导论到数据结构到编译原理都需要重新学习一遍。如果不是被点名了我都不想回复这篇文章。

  • mark,最近正好在思考给 midori 添加性能监控的功能,但因为不支持 rack 中间件,没有现成的方案。开源的方案也不好找,没什么可以参考的思路。感觉这个很适合,可以抽空读一下代码。

  • 你的 controller 很轻量,fmdb 实现得很轮子,model 很业务逻辑。我用了才知道好和不好,在下自愧不如。

  • 别的我先不说。

    噢对了,Rails 只是框架,是否 IO 阻塞,你可以换服务器的,就像 Perl - Plack,你可以跑在 HTTP::Server::Simple ,也可以跑在 Starman。
    

    建议你重新读一遍这文章。

    事件模型服务器是 Node 本身设计了一套事件调度,我觉得,你是不是爱屋及乌然后又异想天开把它用 Ruby 重新制造?
    

    EventLoop 从上古世纪的 C 代码里就有了,还变成 Node 设计的了,我看连 Erlang 都不想说话。

    然后,我并不打算重写 Rails 那么多的业务逻辑,所以,我的原文意思是我不打算重复制造齿轮,实际我写的部分几乎也只有 PHP CodeIgniter 业务的一半,我还是喜欢轻量级。
    

    一头声称自己搞了有业务逻辑的 Controller,一头又说自己喜欢轻量级,我没有见过这么分裂的想法。

    我还重复制造了用于这个框架的“FMDB”(做过移动开发的应该知道这个),作为数据模型数据连接的底层。我看你的源码,mysql2.rb 都只不过实现了数据库的 exec。
    

    建议你回头重新认识一下元编程,再看看什么叫不过实现了数据库的 exec

    说到自己没有的东西,一口一个轻量级;说到自己有的东西,一口一个你没有。一边说自己已经实现了业务逻辑,和 Rails 对比又说自己不打算重复造轮子。反而到了数据库的时候,又说自己重新造了 FMDB 的轮子而我只实现了 exec。

    双标也不带这么玩的。

    你要真觉得自己框架好,我觉得无所谓。但不能自己打自己脸地瞎搞啊。

    因为是内部的东西,而且,我没有你们这么爱分享
    

    你跑来说你的框架实现得更好,既不说好在哪里有不说实现细节也不开源最后告诉我是内部的东西。这和「这个世界上有神,但神是不可知的」有什么区别?

    我喜欢低调,多做少说,我预测你这套东西,迟早可能会放弃的
    

    那我来预测几件事吧。

    1. 微软,迟早可能会倒闭的。
    2. 上海房价,迟早可能会跌的。
  • challenge #1 - #6 update 06/03 at 2017年06月02日

    challenge 4 intermediate 对新手来说相当难,我给个大致思路吧。

    方法一:扫描表达式,把所有 * / 都算了,然后重新扫描算 + -,遇到括号递归执行

    方法二:处理成抽象语法树(AST)以支持更多符号的自由添加

    challenge 3 hard 最快速的做法是字符排序然后哈希,复杂度可以做到 O(m+n) m 是 word list 的长度,n 是查询的数量。如果需要输出排序还需要加一个 O(n*p) p 是字符串的长度

  • 量产型炮灰工程师 at 2017年06月02日

    第一篇就是我的 ID。。。第二篇的话已举报了,知乎管理员也及时处理了。

  • 槽点太多,我一时不知从何说起。我随手列举一下吧:

    1. 闭源,没有 Tutorial,Document 几乎不全,却声称可以:Just build your site with Autumn now!
    2. 就文档里提到的这些函数,基本上全部是 midori 当前进度的子集。midori 已经支持 MySQL 和 Postgres 数据库使用 Sequel ORM 的一切操作了。还支持 HTTP/FTP 无需额外声明回调的访问。
    3. 不是所有 MVC 都是 Rails。你就算用 Ruby 重写了你现在的框架,连 Padrino 都算不上,更不要说 Rails 了。
    4. 这个 v0.01 的版本号我无法做出评价
    5. 我不知道这个「另外业务比你的强,你这个只有骨架。」的结论是何处得出的。我暂时没有看到这个框架上对语法的任何优势,没有见到相关的说明,或者比较。
    6. 另外这个「我没用 NIO,而是直接用 TCP + 非阻模型」。。。我觉得你最好理解一下你说的这几个词汇。。。
    7. 另外这个 iOS 上跑 Ruby 的问题,可以学习一下 RubyMotion。
    8. 最关键的问题是,你就给我一个二进制,你让我怎么承认一下你的框架确实写得很好啊。。。总不能让我去搞 LLVM 反编译。。。
  • 比较奇怪的是,Ruby 中 ? 必须出现在方法名的末尾,所以当你写

    3.is_a?Integer #=> true
    

    可以被正确返回,在 Crystal 里当你这么写的时候,我认为 Crystal 也已经把它认为是方法了,因为它报的错误是:

    undefined method 'is_a?' for Int32

    但我觉得 Crystal 应该是在处理 is_a? 方法上有什么魔法,让这里不工作了。

  • 惊了,原来是这样。。。我一开始直接试着写了

    param.is_a?String
    

    给我报了 undefined method 'is_a?' for Int32,我还以为这玩意没有 is_a? 方法。。。我才用的 typeof。没想到在 is_a? 后面加个空格就好了。。。这是什么魔法。。。

  • 量产型炮灰工程师 at 2017年05月31日

    i % 3 ==0 && i % 5 == 0 就是 i % 15 == 0 啊,这个逻辑的关键在于,如果使用了同时是 3 和 5 的倍数这样的「and」逻辑,则必须优先判断它。当然其实可以通过打 flag 的方法绕过,那样则需要做额外的存储。

  • 量产型炮灰工程师 at 2017年05月29日

    一行 JavaScript

    Array.from(Array(100), (_val, index) => console.log((index + 1) % 15 == 0 ? 'FizzBuzz' : (index + 1) % 3 == 0 ? 'Fizz' : (index + 1) % 5 == 0 ? 'Buzz' : index + 1))
    

    一行 Ruby

    (1..100).each { |i| puts (i % 15 == 0) ? 'FizzBuzz' : (i % 3 == 0) ? 'Fizz' : (i % 5 == 0) ? 'Buzz' : i}
    

    其实连一行 Java 都可以

    IntStream.rangeClosed(1, 100).forEach(value -> System.out.println(value % 15 == 0 ? "FizzBuzz" : value % 3 == 0 ? "Fizz" : value % 5 == 0 ? "Buzz": "" + value));
    
  • 量产型炮灰工程师 at 2017年05月28日

    MIT 之前把经典的 6.001 课程给换了,那门课原先就是用的 SICP 作为教材的经典基础课程。然而换课后该上的内容并没有少,只是把语言从 Scheme 换成了 Python。

  • 所有涉及时间的库都要充满各种特殊情况不停的手动追加。比如 Stack Overflow 有个问题说遇到了一个诡异的 bug,两个只差 1 秒的时间 Java 返回了 343 秒:

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        String str3 = "1927-12-31 23:54:07";  
        String str4 = "1927-12-31 23:54:08";  
        Date sDt3 = sf.parse(str3);  
        Date sDt4 = sf.parse(str4);  
        long ld3 = sDt3.getTime() /1000;  
        long ld4 = sDt4.getTime() /1000;
        System.out.println(ld4-ld3);
    }
    

    出现这个问题是因为系统时区是 Asia/Shanghai。而民国17年(1928年),原中央观象台的业务由南京政府中央研究院的天文研究所和气象研究所分别接收。天文研究所编写的历书基本上沿袭中央观象台的做法,仍将全国划分为5个标准时区,只是在有关交气、合朔、太阳出没时刻等处,不再使用北平的地方平时,而改以南京所在的标准时区的区时即东经120°标准时替代。(来源)

    显然这种变化全部都是硬编码进库的,同理的还有 UTC 的各种闰秒。所以一个时间库要做好,维护的成本相当高。同理像 Rails 中提供的类似于 3.hours.ago 都是不考虑闰秒的,如果你的系统对时间要求很高的话,就容易爆炸。

  • 有个比较奇怪的地方是 Crystal 的类型推断,这几乎是这几年最奇怪的类型推断了。举个例子来说,如果这是一段 TypeScript 代码。

    function test(param: String | number) {
      if (param instanceof String) {
        return 'Oops'
      }
      return param * 2 // 此处 param 必是一个 number,所以不会有错误抛出
    }
    test(1) // => 2
    test('wat') // => 'Oops'
    

    而 Crystal 中

    def test(param : String | Int32)
      if typeof(param) == String
        return "Oops"
      end
      return param * 2.0 # no overload matches 'String#*' with type Float64
                         # Overloads are:
                         #  - String#*(times : Int)
    end
    
    puts test(2)
    puts test("wat")
    

    无论是把另一个类型放在 return 后还是 else 中都无非规避掉这个问题。也就是说一个方法内某个参数类型的推断并不是基于行的,而是基于方法定义时指定的。这对于一些复杂的情况来说就变得很麻烦,需要大量地依赖重载的方式才能定义完。

  • 5.5 倍速,Sidekiq 爆揍 Celery at 2017年05月27日

    Python 3 的性能在大多数情况下比 Python 2 更糟糕。。。但一旦用上 Pypy 就形式逆转了😣

  • 量产型炮灰工程师 at 2017年05月25日

    突然就风评被害。。。

  • 量产型炮灰工程师 at 2017年05月24日

    接受标注原作者、非演绎、可商用的转发。

  • 量产型炮灰工程师 at 2017年05月23日

    你这话放 PHP 社区和 Java 6 的社区里才没毛病,在 Ruby 社区办培训班,出来这样的人然后说「市场上需要」,市场上没人需要,这就是为什么要喷。

  • 量产型炮灰工程师 at 2017年05月23日

    这个没有考虑在不满足 fizz 和 buzz 的情况下是要输出数字本身。

  • 量产型炮灰工程师 at 2017年05月23日

    可 100.times 是从 0 开始的。并且原题有说要「输出数字 1-100」,在不满足 fizz 和 buzz 的情况下是要输出数字本身的。

  • 量产型炮灰工程师 at 2017年05月23日

    事实上现在的编程培训班和当年的英语培训班一样,不是说把你培训成适合工作,而是把你培训成骗过面试。就和当年考个托福各种押题一样,公司从培训班里得到的根本不能满足他们的业务。如果说这是一个 PHP 或者 Java 社区,一些人力密集的外包公司确实可以这么做。但是 Ruby 技术栈的公司几乎就不是这么做的,而用同样的模式培训出来的程序员,在这里真的是很难生存。