读藏书阁随手记

可以使用 MongoDB 等数据库来实现地理位置定位以及搜索附近的人。用户使用手机的时候会上传个人的经纬度位置,然后计算出两个人的距离。其中,基于GEO 地理位置的社交是比较有吸引力的。

1、移动 App 搜索附近的人的原理

移动互联网时代下,出现了许多基于地理位置 LBS 的 App。比如高德地图App可以定位当前位置,也可以搜索附近的加油站;美团、饿了么 APP 可以搜索外卖店铺,并且可以按照距离排序;许多交友类 App 也具备“附近的人”搜索功能;以及出行类的滴滴打车、货拉拉、哈罗单车等。

此类平台的后台都有着存储目标任务或店铺坐标数据的功能。以MongoDB 为例,它使用了经典的 GEO 哈希算法来搜索附近的人或车辆,支持地理位置 GEO 搜索,支持平面索引和三维球面体系数据的搜索。且可以直接使用它来存储当前用户的经纬度。

对于同城或 100 公里以内范围的搜索,GEO 哈希搜索算法的性能能够基本满足需求。但是在大范围比如 500 公里以上的、涉及到地球表面弧度问题的搜索,结果就可能出现偏差,因此一般建议使用球体距离计算算法来获取更准确的距离,但不是所有的数据库都支持三维球面距离索引。

理论上,如果涉及到分布式架构,还需要考虑另外一个问题:请求消息的数量QPS和请求数据的大小。比如需要经过网络传输的时候,网络本身也要消耗资源。如果请求来自于不同的客户端,与服务器建立连接的时候会对服务器造成比较大的压力。而同一个节点、同一个客户端,在很短的时间内发送重复的请求,性能则会高很多。 

2、docker 理解 

Docker 于 2013 年初开源,基于 Linux 内核的 cgroup,namespace,以及AUFS 类的UnionFS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。容器就是一个技术类型,而 docker 是当下最主流的一种实现容器的方案。 

docker 或者容器和传统虚拟化最大的区别,就是虚拟化的封装是系统级的封装,docker 或者其他容器是进程级的封装。

#将宿主机/root/docker.txt 复制到容器内/user/local/。

#创建文件

touch docker.txt

#将文件复制到容器

docker cp docker.txt 96f7ec52rt23:/usr/local

#进入容器查看文件是否复制成功

docker exec -it 96f7ec52rt23 /bin/bash

#再从该容器内的/root/docker.txt 文件复制到宿主机/tmp。

#把文件移动到root目录

mv docker.txt /root

#退出容器

exit

#将docker内部文件移动到宿主机/tmp目录下

docker cp 96f7ec52rt23:/root/docker.txt /tmp

3、k8s容器编排管理工具
容器:镜像和容器的关系,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。容器的实质是进程,容器进程运行于属于独立的命名空间。

容器存储层的生存周期和容器一样,当容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。 

4、需求矛盾

客户只是知道自己想要更多新英雄,但并不知道要具体什么样的英雄;开发设计人员知道怎么做英雄,但又不能完全理解用户需求;运维知道部署服务和上线,但又不能完全理解业务逻辑。单体架构中的各个模块隐藏在大系统的页面下,在交付之前对外界是不可见的。导致没有人能看清全貌,各自都把事情做到最好,但组合起来却不是客户想要的东西。

5、PolarDB

PolarDB 实现了计算节点及存储节点的分离,提供即时生效的可扩展能力和运维能力。
简单易用:全面兼容开源数据库MySQL 5.6。
高性能:使用RDMA高速网络和分布式计算节点集群,性能最高能达到MySQL的6倍。
大容量存储:支持单库容量扩展至上百TB级别,计算引擎以及存储都有秒级扩展能力。 
快速备份:同一个实例的所有节点都访问存储节点上的同一份数据,数据备份耗时实现秒级响应。
一键迁移:实现一键快速迁移,并提供云上的完整生态服务。

6、各层命名规约

A) Service/DAO 层方法命名规约

1) 获取单个对象的方法用 get 做前缀。

2) 获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects。

3) 获取统计值的方法用 count 做前缀。

4) 插入的方法用 save/insert 做前缀。

5) 删除的方法用 remove/delete 做前缀。

6) 修改的方法用 update 做前缀。

B) 领域模型命名规约

1) 数据对象:xxxDO,xxx 即为数据表名。

2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。

3) 展示对象:xxxVO,xxx 一般为网页名称。

4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

7、代码规范推荐

【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME

【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。

说明:大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解,也不利于维护。 正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

【强制】采用 4 个空格缩进,禁止使用 tab 字符。 说明:如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时,请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs。

【强制】IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不要 使用 Windows 格式。

【推荐】单个方法的总行数不超过 80 行。 说明:除注释之外的方法签名、左右大括号、方法内代码、空行、回车及任何不可见字符的总行数不超过 80 行。

【强制】外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生 影响。接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么。

【强制】所有整型包装类对象之间值的比较,全部使用 equals 方法比较。 说明:对于 Integer var = ? 在-128 至 127 之间的赋值,Integer 对象是在 IntegerCache.cache 产生, 会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都 会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。

【强制】禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象。 说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。

如:BigDecimal g = new BigDecimal(0.1f); 实际的存储值为:0.10000000149

正例:优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其实执行了 Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。

BigDecimal recommend1 = new BigDecimal("0.1");

BigDecimal recommend2 = BigDecimal.valueOf(0.1);

【强制】获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime()。 说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime 的方式。在 JDK8 中,针对统计时间 等场景,推荐使用 Instant 类。

【强制】不要在程序中写死一年为 365 天,避免在公历闰年时出现日期转换错误或程序逻辑 错误。

正例: // 获取今年的天数 int daysOfThisYear = LocalDate.now().lengthOfYear();

// 获取指定某年的天数 LocalDate.of(2011, 1, 1).lengthOfYear();

反例: // 第一种情况:在闰年 366 天时,出现数组越界异常 int[] dayArray = new int[365];

// 第二种情况:一年有效期的会员制,今年 1 月 26 日注册,硬编码 365 返回的却是 1 月 25 日 Calendar calendar = Calendar.getInstance(); calendar.set(2020, 1, 26); calendar.add(Calendar.DATE, 365);

【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。 说明:keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key 所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,使用 Map.forEach 方法。 正例:values()返回的是 V 值集合,是一个 list 集合对象;keySet()返回的是 K 值集合,是一个 Set 集合对 象;entrySet()返回的是 K-V 值组合集合。

8、什么是云原生

云原生是基于分布部署和统一运管的分布式云 ,以容器、微服务、DevOps等技术为基础建立的一套云技术产品体系。

云原生应用也就是面向“云”而设计的应用,在使用云原生技术后,开发者无需考虑底层的技术实现,可以充分发挥云平台的弹性和分布式优势,实现快速部署、按需伸缩、不停机交付等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值