浏览器技术发展简史

浏览器是互联网应用中最常用的软件之一,它能够解释HTML等标记语言,并将其转化成可视化的网页。现代浏览器可以开发复杂的GUI应用。

WorldWideWeb(1989年)

万维网是由英国物理学家蒂姆·伯纳斯-李发明的,它是第一个基于超链接的信息共享系统。1989年,蒂姆·伯纳斯-李也发明了第一个Web浏览器WorldWideWeb,它能够在图形界面下显示网页,并且支持鼠标操作。

https://worldwideweb.cern.ch/

https://github.com/cynthia/WorldWideWeb

Mosaic(1993年)

Mosaic是由美国伊利诺伊大学厄巴纳-香槟分校的马克·安德森和埃里克·贾维茨等人发明的第一个流行的Web浏览器。Mosaic采用了图形用户界面,支持图片、音频和视频等多媒体内容的显示,是Web浏览器历史上的一次革命性突破。

Netscape Navigator(1994年)

Netscape Navigator是由Mosaic的主要开发者马克·安德森和吉姆·克拉克等人创立的Netscape公司开发的Web浏览器,它成为了互联网初期最流行的浏览器之一。Netscape Navigator的成功推动了Web浏览器技术的快速发展,也促进了互联网的商业化。

Internet Explorer(1995年)

Internet Explorer是由微软公司开发的Web浏览器,它自1995年推出以来,一直是世界上使用最广泛的Web浏览器之一。Internet Explorer采用了与操作系统集成的方式,使得它成为了Windows操作系统的一部分。

Safari(2003年)

Safari浏览器是由苹果公司开发的Web浏览器,它于2003年首次推出,是Mac OS X操作系统的默认浏览器。Safari采用了WebKit渲染引擎,这也是Chrome等现代浏览器所采用的渲染引擎之一。Safari在安全性和隐私保护方面做得相当出色,包括内置的反跟踪功能、自动阻止广告和网站追踪等。Safari浏览器也有适用于Windows操作系统的版本,但该版本已于2012年停止更新和维护。

Mozilla Firefox(2004年)

Mozilla Firefox是由Mozilla基金会开发的Web浏览器,它采用了开源的软件开发模式,推出后受到广泛关注。Firefox采用了高度定制化的方式,允许用户自由地添加插件和主题等功能,同时也是第一个支持标签式浏览的Web浏览器。

Google Chrome(2008年)

Google Chrome是由Google公司开发的Web浏览器,它采用了WebKit渲染引擎和V8 JavaScript引擎,速度快、稳定性高、用户体验优秀。Chrome还推出了独立的应用商店,支持Web应用的下载和安装。

Microsoft Edge (2015年)

Microsoft Edge浏览器是由微软公司开发的Web浏览器,它于2015年首次推出,是Windows 10操作系统的默认浏览器。Edge浏览器采用了与Chrome相同的Chromium渲染引擎和V8 JavaScript引擎。

开源的浏览器引擎

WebKit:苹果公司开发的一款浏览器引擎,它最初是为Safari浏览器所开发,后来被Google Chrome(28)、Opera、Vivaldi等浏览器所采用。

网站 https://webkit.org/

源码库 https://github.com/WebKit/WebKit

Blink:由Google主导开发的一款浏览器引擎,它是WebKit的一个分支,目前被Google Chrome、Microsoft Edge等浏览器所采用。

网站 https://www.chromium.org/blink/

源码库 https://chromium.googlesource.com/chromium/blink/

Gecko:Mozilla基金会开发的一款浏览器引擎,它被Firefox浏览器所采用,具有出色的灵活性和扩展性能力。

KHTML: KDE桌面环境开发的一款HTML渲染引擎,它是WebKit引擎的前身

Servo:Mozilla基金会和Samsung共同开发的一款浏览器引擎,它采用Rust语言开发,目前还在实验阶段。

网站 https://servo.org/

源码库 https://github.com/servo/servo/

浏览器支持的技术和标准

https://developer.mozilla.org/zh-CN/docs/Web

https://www.w3.org/

LBS相关应用总结

根据ip获取位置机构信息

geoip

https://github.com/Loyalsoldier/geoip

本项目每周四自动生成 GeoIP 文件,同时提供命令行界面(CLI)供用户自行定制 GeoIP 文件,包括但不限于 V2Ray dat 格式路由规则文件 geoip.dat 和 MaxMind mmdb 格式文件 Country.mmdb

https://github.com/Hackl0us/GeoIP2-CN

小巧精悍、准确、实用 GeoIP2 数据库

https://github.com/maxmind/GeoIP2-php

geoip2 php sdk

https://github.com/Torann/laravel-geoip/tree/master/src

geoip laravel 扩展包

geoip2数据库官方下载地址

相关文章

深入浅出 Symfony2 – 结合 MongoDB 开发 LBS 应用

电子围栏

DIY台式机

计划配置一台和笔记本相同(相近)型号配置的台式机

目前笔记本型号:Vivobook_ASUSLaptop M7600QE

MB (main board):ASUSTeK COMPUTER

制造商: ASUSTeK COMPUTER INC.
产品名称: Vivobook_ASUSLaptop M7600QE_M7600QE
版本: 1.0
序列号: N1N0CX03A800017
UUID: 9299a24f-4296-0d43-9578-44845ede2179
唤醒类型: 电源开关
SKU编号:
系列: Vivobook

句柄 0x0002, DMI类型 2, 15字节
主板信息
制造商: ASUSTeK COMPUTER INC.
产品名称: M7600QE
版本: 1.0
序列号: N101NBCX000766MB
资产标签: ATN12345678901234567

CPU:AMD® Ryzen 9 5900hx with radeon graphics × 16

架构:x86_64
CPU运行模式:32位,64位
地址大小:48位物理地址,48位虚拟地址
字节顺序:小端模式
CPU数量:16
在线CPU列表:0-15
厂商ID:AuthenticAMD
型号名称:AMD Ryzen 9 5900HX with Radeon Graphics
CPU系列:25
型号:80
每核心线程数:2
每个物理核心的核心数:8
插槽数量:1
步进:0
频率增强:已启用
CPU最大频率:4679.2959 MHz
CPU最小频率:1200.0000 MHz
BogoMIPS:6587.45
标志位:fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm
虚拟化功能:AMD-V
缓存:
L1d缓存:256 KiB(8个实例)
L1i缓存:256 KiB(8个实例)
L2缓存:4 MiB(8个实例)
L3缓存:16 MiB(1个实例)
NUMA(非一致性存储访问):
NUMA节点数:1
NUMA节点0的CPU:0-15
安全漏洞:
Itlb多重命中:不受影响
L1tf漏洞:不受影响
Mds漏洞:不受影响
Meltdown漏洞:不受影响
Mmio陈旧数据:不受影响
Retbleed漏洞:不受影响
Spec store bypass漏洞:通过prctl禁用了推测存储旁路
Spectre v1漏洞:通过用户空间拷贝/swapgs屏障和__user指针的清理来缓解
Spectre v2漏洞:通过Retpolines、IBPB条件、IBRS_FW、STIBP始终开启、RSB填充、PBRSB-eIBRS不受影响
Srbds漏洞:不受影响
Tsx async abort漏洞:不受影响

Disk:三星

Disk model: HFM512GD3JX013N                         
Disk model: SSD 970 EVO 500G

Mem: 美光科技 DDR4 8GB x 2

Set: 无
定位器: DIMM 0
插槽位置: P0 通道 A
类型: DDR4
类型详情: 同步非缓冲 (未注册)
速度: 3200 MT/s
制造商: Micron Technology
序列号: 00000000
资产标签: 未指定
零件编号: 4ATF1G64HZ-3G2E1
等级: 1
配置的内存速度: 3200 MT/s
最低电压: 1.2 V
最高电压: 1.2 V
配置的电压: 1.2 V
内存技术: DRAM
内存操作模式能力: 揮發性存储器
固件版本: 未知
模块制造商ID: 插槽 1,十六进制 0x2C
模块产品ID: 未知
内存子系统控制器制造商ID: 未知
内存子系统控制器产品ID: 未知
非易失性大小: 无
易失性大小: 8 GB

GPU: NVIDIA GeForce RTX 3050 Ti Mobile & Advanced Micro Devices, Inc.

*-独立显卡
描述: 3D 控制器
产品: GA107M [GeForce RTX 3050 Ti Mobile]
制造商: NVIDIA Corporation
物理标识: 0
总线信息: pci@0000:01:00.0
逻辑名称: /dev/fb0
版本: a1
宽度: 64 位
频率: 33MHz
功能: 电源管理、MSI、PCI Express、总线主控、ROM、帧缓冲
配置信息: 深度=32 驱动程序=nvidia 延迟=0 分辨率=2560x1600 可视颜色=truecolor 水平分辨率=2560 垂直分辨率=1600
资源: iomemory:fe0-fdf iomemory:ff0-fef IRQ:91 内存:fb000000-fbffffff 内存:fe00000000-feffffffff 内存:ff00000000-ff01ffffff I/O端口:e000(大小=128) 内存:fc000000-fc07ffff
*-CPU核显
描述: VGA 兼容控制器
产品: Cezanne
制造商: Advanced Micro Devices, Inc. [AMD/ATI]
物理标识: 0
总线信息: pci@0000:04:00.0
逻辑名称: /dev/fb0
版本: c4
宽度: 64 位
频率: 33MHz
功能: 电源管理、PCI Express、MSI-X、VGA 控制器、总线主控、帧缓冲
配置信息: 深度=32 驱动程序=amdgpu 延迟=0 分辨率=3840,2160
资源: iomemory:ff0-fef IRQ:50 内存:ff10000000-ff1fffffff 内存:ff20000000-ff201fffff I/O端口:d000(大小=256) 内存:fc500000-fc57ffff

台式装机注意事项

CPU选择

AMD R7 5800x3d

接口:AMD AM4|不支持核显|105W

京东 2099

主板选择

(ASUS)TUF GAMING B550M-PLUS WIFI II 重炮手

CPU接口 AMD AM4|DDR4 3800,4000 x4|wifi6 最大网络速度2500M|SATA x4|M.2(NVMe)x2|支持PCIE4.0 & 1个PCI Express x1 & 2个 PCI Express x16|电源接口24+8|版型M-ATX 24.4cm x 24.4cm

京东 829

显卡选择

微星(MSI)魔龙Z GeForce RTX 3060 GAMING Z TRIO 12G 超频版 

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 长324mm;宽140mm;高57mm|HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2299

七彩虹(Colorful) iGame GeForce RTX 3060 Advanced OC 12G L 1867MHz GDDR6

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 315.5 131 52 |HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2399

微星(MSI)魔龙 GeForce RTX 4060 Ti GAMING X TRIO 8G 

显存GB| Cuda 4352 2670MHz|电源8pin x 1

三风扇,尺寸338 141 52|双风扇,尺寸247 130 42

京东 3598 3298

内存选择

美商海盗船(USCORSAIR)32GB(16G×2)套装 DDR4 3600 台式机内存条

京东 539

硬盘选择

三星(SAMSUNG)1TB SSD固态硬盘 M.2接口(NVMe协议PCIe 4.0 x4) 980 PRO (MZ-V8P1T0BW)

京东 549

散热器

水冷

利民(Thermalright)Frozen Magic 360冰封幻境一体式水冷散热器C12风扇多平台ARGB冷头 支持LGA1700|散热器尺寸397x120x27 |电源接口4pin|散热器高度52mm

京东 469

电源

硬件配置:首先要考虑你计划使用的硬件配置,包括主板、处理器、显卡、内存、存储设备等。不同的硬件配置对电源功率的需求有所不同。查阅各硬件组件的功耗规格,以了解它们的功率需求。主板(MB)功率+CPU功率+GPU功率+内存(Mem)功率+硬盘(Disk)功率+散热器功率

余量:为了确保电源的稳定性和可靠性,建议选择功率略高于实际需求的电源。保持一定的功率余量可以应对未来可能的升级或添加其他设备的情况。

80 PLUS认证:考虑选择具有80 PLUS认证的电源。80 PLUS认证是一项标准,用于衡量电源的能效水平。认证级别包括80 PLUS、80 PLUS Bronze、80 PLUS Silver、80 PLUS Gold、80 PLUS Platinum和80 PLUS Titanium,其中Titanium级别是效率最高的

品牌和质量:选择知名品牌的电源,这样更有保障质量和可靠性

先马(SAMA)ONCALL 750W 台式电脑主机箱电源 全模组/80PLUS金牌/台系电容/宽幅/节能温控/额定功率750W

支持3060 4060ti|长140mm;宽150mm;高86mm

京东 599

先马(SAMA)白金1200W 台式电脑机箱电源 80PLUS白金认证/全电压/固态电容/12cm风扇/全模组线材/额定1200W

支持4090,RX 6950 XT,更高功率显卡|长187.8mm;宽145.7mm;高86mm

京东 1099

机箱

主板型号要和机箱匹配,ATX,MATX, ITX三种,机箱尺寸

CPU散热器风扇高度

是否支持水冷位,128/240/280/360,水冷风扇厚度限制(冷排体积),水冷头高度(冷头体积)

电源体积限制,有电源仓的机箱,要注意,一般选择标准ATX电源 140 ,150,86

显卡体积限制,一般限制长度

硬盘位数量

理想价位300~700

品牌 乔思伯, 先马

主板+CPU 3000, 先开2000左右,内存+固态 1000左右 电源+机箱 1500左右 ,散热器500左右

Laravel发送邮件操作流程笔记

官方文档描述比较全面,但是不够简洁以及没有操作流程,所以记录一下备忘。

本文是简单实用的快捷配置方式,使用smtp服务,具体需求看官方文档。

申请发件邮箱开启SMTP服务

以qq邮箱为例,授权码即使邮箱发送时验证的密码

网易163邮箱配置

以客户留言接收邮件通知为例 markdown邮件文档

//生成Mailables Markdown 邮件
php artisan make:mail CustomerFeedbackMail --markdown=emails.customer.feedback
如图会生成两个文件,然后编写代码

配置在浏览器中预览邮件 文档

//添加路由
Route::get('mailable', 'Pc\PageController@mailable');//预览mark邮件

//控制器方法
public function mailable(Request $request)
{
   return new CustomerFeedbackMail();
}

//简单编辑邮件模板feedback.blade.php
@component('mail::message')
# 邮件通知

The body of your message.

@component('mail::button', ['url' => ''])
进入官网后台管理
@endcomponent

@endcomponent

引入通知用到模型数据 文档

//预览页面控制器
class PageController extends Controller
{
    public function mailable(Request $request)
    {
        $message = Message::find(1);

        return new CustomerFeedbackMail($message);
    }
}

//邮件mailable
class CustomerFeedbackMail extends Mailable
{
    use Queueable, SerializesModels;

    public $message;

    public function __construct(Message $message)
    {
        $this->message = $message;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {   
        //emails.customer.feedback是视图文件目录和文件
        return $this->markdown('emails.customer.feedback', ['feedback' => $this->message])->subject('邮件标题');
    }
}

//邮件视图文件markdown
@component('mail::message')
# 客户留言通知
## 姓名:{{$feedback->name}},
## 电话:{{$feedback->mobile}},
## 留言:{{$feedback->content}},
## 提交终端:{{$feedback->terminal}},
## 提交页面名称:{{$feedback->page_name}},

@component('mail::button', ['url' => ''])
进入官网后台管理
@endcomponent

@endcomponent
预览效果

发送到指定邮箱 遍历收件人列表

//修改config/mail.php 配置,增加默认收件邮箱
'to' => [
   'address' => explode(',', env('MAIL_DEFAULT_TO_ADDRESS', '')),
   'name' => env('MAIL_TO_NAME', ''),
],

//修改env配置
MAIL_MAILER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=xxxx@qq.com
MAIL_PASSWORD=xxxx
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=xxx@qq.com
MAIL_FROM_NAME=xxx
MAIL_DEFAULT_TO_ADDRESS=xxx@foxmail.com
MAIL_TO_NAME=留言通知

//发送代码,此处使用terminable中间件延时发送
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use App\Mail\CustomerFeedbackMail;
use App\Models\Message;
class SendFeedbackMailTerminable
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        $response_data = json_decode($response->getContent(), true);

        if (!isset($response_data['data']['message_id']) || empty($response_data['data']['message_id'])) {
            return;
        }

        Log::info('留言id=>'.$response_data['data']['message_id']);

        $message = Message::find($response_data['data']['message_id']);

        if (!$message instanceof Message) {
            return;
        }

        $toAddress = config('mail.to.address');

        foreach ($toAddress  as $value) {
            try {
                Mail::to($value)->send(new CustomerFeedbackMail($message));
            } catch (\Throwable $th) {
                Log::channel('sendmail')->info('发送邮件失败'.$th->getMessage());
                continue;
            }

            Log::channel('sendmail')->info('[官网留言邮件通知记录]:', ['email' => $value, 'message_id' => $response_data['data']['message_id']]);
        }
    }
}

iphone11卡死强制重启方法

普通重启方法,按住音量减同时按住电源建。之后会出现滑动关机和医疗卡以及SOS按钮。

IPhone 11如果如果卡死,正常的启动无法启动。需要强制重启,按一下手机侧面的音量加键,之后按一下音量减键,然后按住电源键不放,直到出现滑动关机按钮,(注意此时没有医疗卡和SOS按钮只有滑动关机),之后等待手机重启即可。

有一次出现,卡死灰屏,上述方法没生效。试了一下同事按住音量加,音量减,然后按住电源不放。最后重启了。

消息功能,站内信的设计实现思路汇总

消息功能和站内信的需求概括

B站消息功能界面截图

一般项目的消息功能都会有多种类型,比如订单状态推送,点赞推送,收藏,系统通知,到期提醒,系统公告(后台会有发送消息的需求)。同时可能会伴随多种渠道(短信,邮件,app push)的消息推送。

按推送用户数量分为,发送给全部用户,发送给部分用户,实现发送消息和已读状态更能,在用户数量不多(中小型项目)的情况下,最适合的方法是存中间表。

当用户数量增长之后,比如100万人同时点赞,每天产生的数据量非常大,不存数据库该如何实现?

方案一 使用 redis 的 bitmap

参考 一看就懂系列之 详解redis的bitmap在亿级项目中的应用

redis bitmap介绍

bitmap不是一个实际的数据类型,而是一组定义在String类型上的面向位的操作。由于字符串是二进制安全的blobs,其最大长度为512MB,所以它们适合设置2^32个不同的位。

位操作分为两组:恒定时间的单位操作,如将一个位设置为1或0,或获得其值,以及对位组的操作,如在给定的位范围内计算设置的位的数量(如人口计数)。

位图最大的优点之一是,它们在存储信息时往往能极大地节省空间。例如在一个系统中,不同的用户由递增的用户ID代表,只需使用512MB的内存就可以记住40亿用户的一个比特信息(例如,知道一个用户是否想收到通讯)。

位是用SETBIT和GETBIT命令来设置和检索的。

setbit key 10 1
(整数) 1
getbit key 10
(整数) 1
getbit key 11
(整数) 0
SETBIT命令的第一个参数是位号,第二个参数是要将该位设置为的值,即1或0。

GETBIT只是返回指定索引处的位的值。超出范围的位(寻址的位在存储到目标键的字符串长度之外)总是被认为是零。

有三个命令对位组进行操作。

BITOP在不同的字符串之间进行位的操作。提供的操作有AND、OR、XOR和NOT。
BITCOUNT执行群体计数,报告设置为1的位的数量。
BITPOS找到第一个具有指定值0或1的位。
BITPOS和BITCOUNT都能对字符串的字节范围进行操作,而不是对字符串的整个长度进行操作。下面是一个调用BITCOUNT的微不足道的例子。

setbit key 0 1
(integer) 0
setbit key 100 1
(整数) 0
bitcount key
(整数) 2
位图的常见用户案例有。

各种类型的实时分析。
储存与对象ID相关的节省空间但性能高的布尔信息。
例如,想象一下,你想知道你的网站用户每天访问的最长连贯时间。你从零开始计算天数,也就是你公开网站的那一天,并在每次用户访问网站的时候用SETBIT设置一个位。作为一个比特索引,你只需取当前的unix时间,减去初始偏移量,然后除以3600*24。

这样,对于每个用户,你都有一个包含每天访问信息的小字符串。通过BITCOUNT可以很容易地得到一个给定的用户访问网站的天数,而通过几个BITPOS调用,或者简单地获取和分析客户端的位图,就可以很容易地计算出最长的连绵时间。

将位图分割成多个键是很容易的,例如,为了分片数据集,以及在一般情况下,最好避免使用巨大的键。为了将一个位图分割成不同的键,而不是将所有的位设置成一个键,一个简单的策略就是每个键存储M个位,用位数/M获得键的名称,用位数MOD M获得键内的第N位。

//设置用户已读:
$redis->setBit('message:'.$msg_id, $uid, 1);

//获取是否读取状态:
$redis->getBit('message:'.$msg_id, $uid);

//支持千万级用户,并且不会有数据存储方面的压力

另外:bitmap 还可以做签到,活跃统计,在线状态等等

参考文章

站内信需求设计——人人都是产品经理

技术方案参考文章

消息系统(功能)的设计与实现

消息功能中系统通知这一类信息的已读未读除了用数据表之外有没有比较好的解决方案

站内信设计总结——掘金

站内信设计思路——人手一本PHP工具书

37 | 计数系统设计(一):面对海量数据的计数器要如何做?——极客时间

38 | 计数系统设计(二):50万QPS下如何设计未读数系统?——极客时间

一看就懂系列之 详解redis的bitmap在亿级项目中的应用

如何准确的评估工期

——视频出资微博视频大佬 蛋疼的axb

问题1,过于乐观评估,导致延期,会被leader认为不靠谱

估计三天写完,但是遇到了问题,又花了三天,又遇到问题,又…

问题2,过于保守的评估,也会被认为不靠谱,leader预期一两天就完成的任务

你处于保守估计给出了一周甚至更多的工期,问你哪里有问题,你又说不明白, leader觉得还不如自己做。

以上问题会导致有重要任务就不找你了。

保守评估时给出技术难点困难, leader信服。

解决方案

1.客观正确的评价自己的能力

不要一上来就编码,花2/3的时间设计和测试(测试驱动开发),1/3最多1/2的时间用来编码

2.正确的认清你要做什么事情

如果事情以前不是由你主导到,首先要花时间了解来龙去脉,尤其是注意有没有坑。然后再花时间去预估工期

3. 将开发评估工时当做一种必要的习惯来训练。相似度非常高的项目可以套用,工期评估更准确。

具体的方法

将具体需要的完成的工作列出来,比如划分成多少个模块,需要建多少个表,完成多少个接口,写多少测试。

如何避免成为一个不靠谱的菜鸡程序员

软件开发的绝大部分时间都在和风险打交道,要提升自己预防和对抗风险的能力。

知道自己的能力有限(比如理解慢反应慢思考慢),掌握的知识有限,掌握的信息有限,在做相应事情之前要做充足的提前准备

在对方案之前你需要了解更多的关于方案的背景知识;

在提交测试之前,一定要自己多测试几遍,因为你写的代码一定会有bug;

做设计之前提前想好各种问题的解决方案;

过于追求完美导致的风险

想做代码重构导致上线推迟了;

想修复bug发现不是bug是feature;

越是追求100分的程序员越是需要知道60分的可贵,先做到可用的状态然后再进行优化,避免过早优化,过早优化是万恶之源

举例说明花十天工期完成1个项目

方案一,花9天开发到一个完美的状态,1天内完成测试联调上线这一系列的工作,

方案二6天完成一个基本版本的开发测试联调上线,剩下4天时间逐渐做迭代,应对风险能力强。

风险优先开发原则

按风险评估开发的顺序,风险越高,后果越严重的越需要往前排,这样能让你更早的遇到问题,即使你解决不聊这个问题,你也可以提前去查询资料,求助同事,或者把这个风险告诉主管提前得到预警。

程序员如何优雅的讨论排期

和产品达成共识,目标是提升整体事情的运行效率,推动事情发展。并不是一直加班就能解决问题,提示效率和兼顾质量和可维护性才是重点。

权限系统设计汇总

可能是史上最全的权限系统设计

权限系统设计模型分析(DAC,MAC,RBAC,ABAC)

有赞权限系统(SAM)

用户管理系统 – 用户权限设计从入门到精通

B端产品如何设计权限系统?4个要素,5个模型,2个行业案例

基于RBAC模型的权限系统设计(github开源项目)

权限模型

基于角色的访问控制(RBAC: Role-Based Access Control)

RBAC0模型

最简单常用的模型

RBAC1模型

RBAC2模型

基于核心模型的基础上,进行了角色的约束控制,RBAC2模型中添加了责任分离关系,其规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离和动态责任分离。主要包括以下约束:

  • 互斥角色: 同一用户只能分配到一组互斥角色集合中至多一个角色,支持责任分离的原则。互斥角色是指各自权限互相制约的两个角色。比如财务部有会计和审核员两个角色,他们是互斥角色,那么用户不能同时拥有这两个角色,体现了职责分离原则
  • 基数约束: 一个角色被分配的用户数量受限;一个用户可拥有的角色数目受限;同样一个角色对应的访问权限数目也应受限,以控制高级权限在系统中的分配
  • 先决条件角色: 即用户想获得某上级角色,必须先获得其下一级的角色
rbac2

RBAC3模型

即最全面的权限管理,它是基于RBAC0,将RBAC1和RBAC2进行了整合

rbac3

基于属性的权限验证(ABAC: Attribute-Based Access Control)

自主访问控制(DAC: Discretionary Access Control)

强制访问控制(MAC: Mandatory Access Control)

PHP生态中成熟的权限工具包

laravel-permission

文档 中文翻译

相关文章

[扩展推荐] spatie/Laravel-permission Laravel 应用中的角色和权限控制

php-casbin 分享会-访问控制框架Casbin(社区版)本.pdf

Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型,支持多种语言

laravel-authz  think-authz 

文档

laravel-admin

文档

dcat-admin

文档