小花花 的回答 (68)
  • 小花花

    很多人当听到别人要开发框架的时候第一想法就是,又重复造轮子。
    其实造轮子的过程是一个快速积累知识的过程,能较快的发现自己的不足,以及学到一些自己未发现的知识点。所以建议在有一定PHP基础的情况下,都去尝试完成一个五脏俱全的基本框架吧。

    那么下面分享一下我之前造轮子的过程吧:

    1. 尝试试用一个以上的框架,看完一遍使用文档,目的在于了解它都有哪些功能,发现他的一些比较好的用法设计;
    2. 在看文档的同时并行的思考这一部分的实现原理,如果想不明白则记下来或者上Github去看源码(当然在不熟悉代码结构的情况下可能很难找,所以我建议还是先记下来);
    3. 看它的项目结构,同时思考这个结构的意义,比如现在大部分框架都把入口文件与静态资源单独放到public目录里与其它目录分开的原因是什么;
    4. 尝试看一遍源码的运行流程,从入口到输出,以及错误处理,模板引擎,配置等多个点了解一下(如果基础允许的话,在这过程中解决上面记下来的疑点吧);
    5. 开始自己实现吧,先写一个大概的功能列表,把你要实现的点写出来;
    6. 然后思考如果组织代码结构,在没有太多实践经验的情况下就按你最熟悉的方式组织吧(先实现再优化);
    7. 先跑通基本的hello world!;
    8. 一点点加功能吧;
    9. 发现不足,改进它;

    这里在加功能的时候,尽量自己实现所有的能实现的组件,比如文件上传,错误处理等等,毕竟目的是实习知识。
    那么这过程其实走下来对于基础稍差的人来说可能会特别不顺利,那么没关系,遇到哪一个点卡住,先解决你对这个点的问题,快速补充知识再回来继续。

  • 小花花
    /**
     * 模板输出重写方法
     * @access protected
     * @param  boolean $isStatic 是否保存为静态文件
     * @param  string $template 模板文件名
     * @param  array  $vars     模板输出变量
     * @param  array  $replace  模板替换
     * @param  array  $config   模板参数
     * @return mixed
     */
    private function staticFetch($isStatic=false,$template = '', $vars = [], $replace = [], $config = [])
    {
        $HTML = $this->fetch($template, $vars, $replace, $config);//获得页面HTML代码
        if ($isStatic){//判断是否需要保存为静态页
            $thisModule=request()->module();//获取模块
            $thisController=request()->controller();//获取控制器
            $thisAction=request()->action();//获取方法
            $new_file = "{$thisModule}/{$thisController}";
            if(!file_exists($new_file)){
                //检查是否有该文件夹,如果没有就创建,并给予最高权限
                mkdir($new_file, 0777,true);
            }
            $new_file.="/{$thisAction}.".config('default_return_type');
            file_put_contents($new_file,$HTML);//生成静态页
        }
        return $HTML;
    }
  • 小花花

    你需要先设置下页面状态,然后进行异步请求,请求未返回时显示正在加载,返回时就显示正确的数据了,这里的异步可以用promise实现

  • 小花花

    主键的话我的建议是自增整形,不要使用与业务相关的名字,仅用 id 即可,而效率问题都可以用索引来解决。

    因为主键的不可变的特性,如果选择不慎,会在未来产生难以预期的问题。

    比如你用 int 型做文章的 id,但是如果在未来某一天文章数超过了无符号整形的最大值,你将没法将主键修改成 bigint。或者为了给用户起一个唯一 id 用了自增主键,但是如果未来有其他的项目用户要合并进来,他也是这么做的。这时候为了区分不同的项目可能要在这个用户 id 前加一个前缀,这时候也没法修改主键的值。主键之所以叫做主键就是到什么时候都不能改,所以最好的方案就是使用自增数字 id 做主键,并且不要给这个主键赋予一个业务相关的意义。

  • 小花花

    Python,特指 CPython 的实现,由于 GIL 的存在,CPython 不能有效的利用多核处理器。表现为任意时间一个进程只有一个线程在跑,而 IO 密集型运算,多数是在 IO 读写将线程堵塞掉了,这个时候线程切换是很合理的,反正线程只是单纯地等待,在这个等待的时候去做其他的事情,资源利用率就上去了。

    简单点解释就是,python 的多线程只能使用一个 cpu 核心。io 密集型应用,本来 cpu 占用率就很低,单个 cpu 核心就够了。用多进程给它多几个核心也不能提升性能。其实从这个特点来看,python多线程这个限制和协程有点像,应用也很像,都是适合io密集型。
    cpu密集型的,显然只用一个 cpu 核心是不行的。

    注意这只是 python,跟其他语言里面的多线程可不是一个概念。

  • 小花花

    很有必要

    举个例子,假设有两个人需要吃饭,但我们只有一个饭碗(共享的资源),这是前提

    由于 CPU 时间片关系,它会在多个不同的线程之间来回切换,无论单核多核与否,都有可能发生以下情况

    其中 A 吃饭吃到一半的时候(即线程工作做到一半时),CPU 将时间片分给其他线程(即在A还没有吃完饭的情况下,就不让他吃了)

    这时候,CPU 将时间片分配给 B,由于只有一个碗,故 B 也只有使用这个碗(共享的资源)

    待 CPU 再次将时间片分给 A 的时候,他就不知道该如何开始了,因为 B 也使用过这个碗(并且他有可能把饭吃完了,碗空了)。如果碗是空的,那么 A 就会以为自己吃完了(线程以为自己做完了工作),其实并没有。

    这时候,就造成了数据的错误

     

    如果加了锁,就不一样了,当 B 想使用碗的时候,发现碗已经被 A 占用了(加了锁),这个时候 B 就只有等待,待 A 用完(完成了工作,不在使用共享的资源)之后,B就可以使用了

    之所以要加锁,在于
    1. 时间片的大小不定。比如单个时间片只能完成给定任务的一半,剩下的那一半就只有等下一个时间片了。而在等待的过程中,如果不加锁,就没法保证其他线程不使用我们的资源,数据就有可能出错
    2. 给线程分配时间片的时机不确定。比如有a,b,c 三个线程,a,c使用了共享的资源。如果前几十个时间片都集中在a,b上,那么很有可能时间片分配给c的时候,a已经完成了工作,因此它也不需要和c争夺资源了。

    分配的时机很大程度由线程的优先级来决定,在前面的例子中,如果a,c优先级比 b 高很多,那么时间片可能大多都分配在a,c上,这个时候a,c就要疯狂的争夺资源了

  • 小花花
    小花花 2个月前 回答了: 多线程是否有意义?

    在老手看来是个蠢问题,但是菜鸟提这个问题却太正常了,我当年也有过类似的疑问。目前这个问题下还没有太好的答案,我试着回答一下。

    计算机程序不论做什么事情,归根到底可以分类为“计算任务”和“读写任务”。两者使用的是计算机上的不同的资源,CPU是计算资源,硬盘、网络是读写资源。多个计算任务之间可能有顺序依赖也可能没有,把彼此之间没有顺序依赖的计算任务同时进行以缩短处理时间的做法叫做“并发(concurrency)”;当计算任务对读写任务有依赖时,不把计算资源浪费在对读写任务的等待上的做法叫做“异步(asynchronous)”。并发和异步都是单一线程无法实现的。

  • 小花花
    小花花 2个月前 回答了: 多线程是否有意义?

    你的问题主要在于编码不多而想得太多。

    多线程是为了解决在单一进程等待 IO 操作时 CPU 空闲的问题,以及使多道任务同时执行,但是如果没有 IO 操作,多线程不比单线程快,因为线程切换时也要占用指令周期,但是如果单线程被阻塞了,整个进程就被阻塞,如果多线程的话还又别的线程可以执行,所以进程不会被阻塞,如果在做服务器程序时应该用尽量少的线程,而不是不用多线程,在做 PC 软件时,应该充分利用多线程,以加快用户响应速度。

     

  • 小花花

    1. 请一直使用 pool,没有何时。
    2. pool 在程序初始化的时候创建,无需销毁,从中抽取实例连接就行,无需关心细节,也无需手动连接和关闭。
    3. 推荐使用一个 ORM 库,例如 sequelize 之类的,很多,包括我们公司自产的 toshihiko,可以简化掉很多细节
    4. 多级连接没什么需要注意的,主要是通过内网 ip 连接,做好环境隔离,保证 mysql 服务的连接数够用,合理设置每个服务的 pool 大小。
    5. 数据库设计是门大学问,数据库优化也是门大学问,祝好

  • 小花花
    foreach (ConfigModel::all(['name', 'value']) as $config) {
        config([$config['name'] => $config['value']]);
    }
最近访客
  • 董俊俊
    董俊俊 2天前
  • shadowhung
    sha 2个月前