栈 Stack Data Structure

加入 Swift Algorithm Club /‘ælgə’rɪðəm/,回炉重新学习数据结构与算法。 自己创建的项目:GitHub - imzyf/data-structure-and-algorithm。 实现一个 栈 /stæk/,包含 push peek pop 与 Generics 泛型。 stack 栈 非常像一个数组,它包括少量的方法。 push 添加一个新元素到栈顶 pop 从栈顶移除一个元素 peek 查看栈顶的一个元素但是不 pop A stack gives you a LIFO or last-in first-out order. 栈是后进先出,队列是先进先出。 public struct Stack<Element> { fileprivate var array: [Element] = [] } push push 是在数组的尾部添加元素是以 O(1),如果是在数组最前添加是 O(n) 这是昂贵的。 public mutating func push(_ element: Element) { array.append(element) } 因为使用的 struct,修改属性值的方法要加 mutating。 pop 想从一个空栈中弹出最后一个元素将返回 nil。 ...

November 22, 2018 · 1 min · 126 words · Me

解决 Too many symbol files

在上传 App 到 App Store 后收到邮件,有 issues Too many symbol files。在之前看到 Your delivery was successful,此 issues 不影响发布,所以一直搁置了。 今天决定彻底处理下。 背景 先说 *.symbols 这文件是干嘛的,我现在(2018-10)对此的理解: symbols 为符号表文件 符号表是内存地址与函数名、文件名、行号的映射表 <起始地址> <结束地址> <函数> [<文件名:行号>] 为什么要配置符号表? 为了能快速并准确地定位用户 App 发生 Crash 的代码位置,使用符号表对 App 发生 Crash 的程序 堆栈 进行 解析 和 还原。 项目情况 再说下项目情况,因为数字都是用了的是 Int,为防止 32 位设备发生越界情况(理由好像有点扯),所以项目端设置了设备限制 arm64,也就是 5s 之前的设备不可以安装。 因为使用了三方库,但是三方库是支持 32 位设备的,所以生成了冗余的 symbols 文件。 查询 symbols 文件的生成情况:Xcode Window -> Organizer 选择有问题的 archive,右击选择 Show in finder,命令行进入 *.app 中的 dSYMs 文件夹,执行 dwarfdump --uuid * 可以查询到是否生成了多余的文件。 ...

October 30, 2018 · 1 min · 142 words · Me

在 MySQL 中选择合适的日期类型

如何在 MySQL 中选择合适的日期类型困扰了很久,varchar、int、timestamp、datetime 都有尝试过,近来有所感悟,做此总结。 注:此总结考虑了 PHP 和 Laravel 框架的特点。 使用 varchar varchar 存储日期时间的格式完全可以自己控制,月/日/年 还是 年-月-日 需求怎么说就怎么存,读取后展示是也不用在格式化。同时伏笔也就此埋下:日期时间格式没强制约束,总有一天字段里出现了与众不同的格式;要是日期时间会 变化 或作为 查询条件 或要进行 排序 时就又是一坑,还是要格式化标准格式再处理。可以说 varchar 应该是最差的选择了。 使用 int 与 timestamp PHP time() 可以直接获取当前时间戳秒数,数据库字段要也是 int 一存就完事了,不会有格式问题,谁用什么样转什么样。但是在数据库工具中查看此字段时显示不够直观,范围时会不方便,这些在使用 timestamp 是会得到解决。 timestamp 是我一直迷惑的一个类型。我写了几个例子做测试: 将 Laravel 项目设置为 CST 中国标准时间,MySQL 时区设置为 UTC,使用 now() 获取当前日期时间,比如:2018-5-25 11:00:00 存入 timestamp 类型的字段中,使用数据库工具查看字段结果为仍然为 2018-5-25 11:00:00。 继续上面的操作,项目中使用查询语句查询刚才的记录,结果显示为 2018-5-25 11:00:00,将项目时区从 CST 改为 UTC 后再次查询的结果仍然为 2018-5-25 11:00:00 没有变化。 继续上面的操作,将数据库的时区改为 +8:00,数据库工具、项目查询后的结果为 2018-5-25 19:00:00 发生了变化,修改项目为 CST 查询结果是 2018-5-25 19:00:00 和刚才一样也变化了。 这个测试说明了: ...

May 25, 2018 · 2 min · 254 words · Me

NGINX 禁止 IP 访问

禁止 IP 访问,其他域名跳转到 www.xxx.com: server { listen 80; server_name 55.66.77.88; deny all; } server { listen 80; server_name www.xxx.com xxx.com; return 301 https://www.xxx.com$request_uri; } server { listen 443 ssl http2; #... if ($host = 55.66.77.88) { return 403; } if ($host != 'www.xxx.com'){ rewrite ^/(.*)$ https://www.xxx.com/$1 permanent; } #... } – EOF –

May 20, 2018 · 1 min · 53 words · Me

L01 Web 开发实战入门

Laravel 教程 - Web 开发实战入门 基础信息 Laravel 与 PHP Ruby on Rails 有以下原则: 强调与注重敏捷开发; 约定高于配置(Convention over configuration); DRY(Don’t repeat yourself)不要重复自己,提倡代码重用; 重视「编码愉悦性」。 如何正确阅读本书 随后你会有很多机会来学习它们。现在最重要的是保持『训练』的连贯性。 编程是技能,不是知识,技能只有在不断刻意练习下才会有进步。 开发环境布置 第一个应用 composer create-project laravel/laravel Laravel --prefer-dist "5.5.*" Git 与 GitHub 设置 push 的默认模式为 simple git config --global push.default simple 部署上线 注册 Heroku 后: heroku login # 添加 SSH Key 到 Heroku 上 heroku keys:add # 创建配置文件来告诉 Heroku 应当使用什么命令来启动 Web 服务器 echo web: vendor/bin/heroku-php-apache2 public/ > Procfile git add -A git commit -m "Procfile for Heroku" # 创建一个新应用 heroku create # 对应用名称进行更改,保证未被其它人占用 heroku rename imzyf-laravel-essential # 声明应用是用 PHP 写的 heroku buildpacks:set heroku/php # 设置 APP key php artisan key:generate heroku config:set APP_KEY=base64:wuWj8Kicza6I9YxgWczviNVcueVN2RroqiUILreyNmA= # 部署上线 git push heroku master # 快速打开线上应用 heroku open # 输出生产环境上的日志 heroku logs 构建页面 静态页面 生成静态页面控制器: ...

May 9, 2018 · 2 min · 371 words · Me

【Modern PHP】笔记

又回到 PHP Web 开发,使用 Laravel 框架,重读《Modern PHP》。 PHP 正在重生。 特性 命名空间 声明命名空间: <?php namespace Oreilly\ModernPHP; 导入和别名: <?php use Symfony\Component\HttpFoundation\Response as Res; $r = new Res('Oops', 400); $r->send(); PHP 5.6 开始可以导入函数和常量: <?php use func Namespace\functionName; use constant Namespace\CONST_NAME; functionName(); echo CONST_NAME; 使用接口 接口是两个 PHP 对象之间的契约,其目的不是让一个对象依赖另一个对象的身份,而是依赖另一个对象的能力。 使用接口编写更加灵活,能委托别人实现细节。 性状 trait 性状是类的部分实现,可以混入一个或者多个现有的 PHP 类中。性状有两个作用:表明类可以做什么(像是接口);提供模块化实现(像是类)。 如果想让两个无关的 PHP 类具有类似的行为,应该怎么呢?性状就是为了解决这种问题而诞生的。性状能把模块化的实现方式注入多个无关的类中。而且性状还能促进代码的重用。 这与创建一个接口,两个无关的类实现这个接口的优势在于:不用写相同的实现代码,符合 DRY 原则。 PHP 解释器在编译时会把性状复制粘贴到类的定义体中,但是不会处理这个操作引入的不兼容问题。如果性状假定类中有特定的属性和方法(在性状中没有定义),要确保相应的类中有对应的属性和方法。 生成器 Generator 是 PHP 5.5.0 引入的功能。生成器是简单的迭代器,仅此而已。 PHP 生成器不要求类实现 Iterator 接口,从而减轻了类的负担。生成器会根据需求计算并产生要迭代的值。这对应该的性能有重大影响。假如标准的 PHP 迭代器经常在内存中执行迭代操作,这要预先计算出数据集,性能低;此时我们可以使用生成器,即时计算并产出后续值,不占用宝贵的内存资源。 PHP 生成器不能满足所有迭代操作的需求,因为如果不查询,生成器永远不知道下一个要迭代的值是什么,在生成器中无法后退和快进。生成器还是一次性,无法多次迭代同一个生成器。不过,如果需要,可以重建或克隆生成器。 PHP 生成器是 PHP 函数,只不过要在函数中一次或者多次使用 yield 关键字。生成器从不返回值,值产出值。 ...

May 8, 2018 · 3 min · 572 words · Me

PhpStorm 使用经验

Getting Started Two shortcuts to get started Shift+Shift(⇧+⇧) helps you find anything within your project. Alt+Enter(Option+Enter) provides instant access to contextual actions and quick fixes relevant to the selected code. Getting started with PHP in PhpStorm 还有个 One Dark theme 但是 Material Theme UI 已经包含这个主题。 配置: Preferences > Appearance & Behavior > Appearance 下,右侧配置:Theme: Darcula,勾选 User custom font: .AppleSystemUIFont Size: 18。 Preferences > Editor > Font 下,右侧配置:Font: Menlo Size: 18 Line spacing: 1.2。 ...

May 5, 2018 · 3 min · 433 words · Me

使用 Let's Encrypt 通配符证书

一直在使用 Let’s Encrypt 的免费 SSL 证书,但是一直没做笔记。今天看到 Let’s Encrypt 支持了通配符证书(Wildcard Certificates),也就是说二级子域名和主域名可以共用一个证书。 申请证书 # 下载证书申请客户端 cd /opt git clone https://github.com/certbot/certbot cd /opt/certbot # 注意通配符并不包含主域名,所以要配置两个 ./certbot-auto certonly -d *.zyf.im -d zyf.im --manual --preferred-challenges dns --server "https://acme-v02.api.letsencrypt.org/directory" -preferred-challenges dns 使用 DNS 方式校验域名所有权,所以会遇到: ------------------------------------------------------------------------------- Please deploy a DNS TXT record under the name _acme-challenge.zyf.im with the following value: YZ2unEViXH8nYZ2unEViIbW52LhIEViIbW52Lh Before continuing, verify the record is deployed. ------------------------------------------------------------------------------- Press Enter to Continue 要在域名服务商那里将 _acme-challenge.zyf.im 配置 DNS TXT 记录,从而校验域名所有权。 ...

April 26, 2018 · 2 min · 227 words · Me

Docker UFW 失效

今日遇到 Docker 中的项目绕过了宿主机 UFW 的配置,可以被任意 IP 访问,甚是奇怪。查找资料发现: 如果你在 Linux 使用 Docker,很可能你的系统防火墙降级为 Uncomplicated Firewall (UFW)。如果是这样的话,你有一点可能不知道,Docker 和 UFW 的组合带来了一些安全问题。为什么呢?因为 Docker 实际上绕过了 UFW 并直接修改了 iptables,所以一个容器可以绑定一个端口。这就意味着,所有你设置的 UFW 规则都将在 Docker 容器中失效。 如何修复: sudo vi /etc/default/docker # add the following line: DOCKER_OPTS="--iptables=false" Restart the docker daemon: sudo systemctl restart docker # or docker/etc/init.d/docker restart When a problem arises, it only takes a bit of digging to discover the solution was already there, waiting for you to make it so. Don’t let this issue with Docker stop you from using this incredible technology. ...

April 24, 2018 · 1 min · 119 words · Me

Swift 初始化

因为自己是直接从 Swift 进入的 iOS 开发,Swift 与 Objective-C 初始化的对比就不多提了。感觉上 Swift 初始化的方式像 Java,自己也只这样套着 Java 去理解,但也发现了不相同的地方。 初始化顺序 class Blog: NSObject { let param: String override init() { } } 这里有条错误 error: property 'self.param' not initialized at implicitly generated super.init call 说明:param 参数没有在隐式生成 super.init 调用之前完成初始化。 Swift 中并不是不调用 super.init 而是为了方便开发者由编译器完成了这一步,但是要求调用 super.init 之前要完成成员变量的初始化。 class Blog: NSObject { let param: String override init() { param = "swift init" } } 对于需要修改父类中成员变量值,我们需要在调用 super.init 之后再进行修改: class Cat { var name: String init() { name = "cat" } } class Tiger: Cat { let power: Int override init() { power = 10 super.init() name = "tiger" } } Swift 中类的初始化顺序: ...

March 31, 2018 · 5 min · 972 words · Me