写点什么

ARTS 打卡第 6 周

作者:苏籍
  • 2023-09-24
    北京
  • 本文字数:5927 字

    阅读完需:约 19 分钟

Algorithm


8. 字符串转换整数

https://leetcode.cn/problems/string-to-integer-atoi/


思路:

  1. 去除首部空格符

  2. 识别出第一个字符是否为符号位+ -,并记录符号位

  3. 判断如果不是 0-9 符号 则返回

  4. 判断边界,不能超过整数范围 可以用 Inter.MAX_VALUE/10 如果当前循环中的数 累加之前 已经超过这个数,则结果一定大于这个数, 如果当前 result=Inter.MAX_VALUE/10 但是中的当前循环中的数已经大于 7 则 也认为超过边界

  5. result=result*10+( i-'0')


class Solution {    public int myAtoi(String s) {      if(s.length()==0) return 0;
// 先去除空格 int j=0; while(j<s.length() && s.charAt(j)==' '){ j++; } s=s.substring(j); if(s.length()==0) return 0; // 2. 判断第一个数是否是符号位 char[] chs=s.toCharArray(); int sign=1; if(chs[0]=='-'){ sign=-1; s=s.substring(1); }else if(chs[0]=='+'){ sign=1; s=s.substring(1); } int res=0; int bound=Integer.MAX_VALUE/10; for(int i=0;i<s.length();i++){ char ch=s.charAt(i); if(ch<'0' || ch>'9')break; if(res>bound || ( res==bound && ch>'7')) return sign==-1? Integer.MIN_VALUE:Integer.MAX_VALUE; res=res*10+ (ch-'0'); } return sign*res; }}
复制代码


Review

今天仍然是 分布式系统的文章 https://aosabook.org/en/v2/distsys.html


文章主要观点 是分布式系统设计终须有关注的核心

  1. 高可用性。服务的可用性,容错

  2. 高性能

  3. 可靠性。指的是数据的一致性

  4. 可扩展,这里指的是流量突增的时候,能够扩容应对。 当然流量增加也意味着业务增加,其实也应该包含业务扩展性

  5. 可维护性。指的是运维和监控能力,对于故障的发现、定位能够快速响应

  6. 成本。系统的维护成本和硬件成本


作者用了一个图片上传的服务器 作为示例,展示如何建设分布式系统


  1. 第一阶段。基本需求就是图片能够上传到远端服务器,同时用户能够通过链接访问或者下载图片 (链接可能嵌入到了其他应用中)

  2. 需要解决的复杂点 是文件数量没有限制,需要考虑存储的扩展能力

  3. 用户希望能够快速访问图片,低延迟

  4. 系统已维护同时 需要考虑成本 (图片服务低利率)

所以综合考虑,只建设了简单的交互,上传和下载作为两个关键点放在了一个服务中,同时有一个存储系统

二. 第二阶段,用户量增长,访问量变大。出现读写性能问题

需要解决的复杂点

  1. 服务扩展能力

  2. 读写性能提升。写耗时一定大于读耗时,且读可以进行异步化优化,同时每个 web 容器有链接数量上限。如果写占据了太多链接,将会影响读

服务根据功能进行拆分,比如读写分离。避免相互影响。这样方便针对慢查询等问题进行优化,并且能够各自根据需要进行服务机器扩容,避免资源浪费。

第三阶段。 用户量持续增加。由于服务和数据只有独立的机器,出现单点故障,和数据丢失等风险

需要解决的复杂度

  1. 数据的高可用性。 数据节点宕机,数据不会丢失或者有地方有副本可以找回

  2. 服务的高可用,服务机器节点宕机,出现故障,能够自动回复 或者切换到其他服务机器提供服务

冗余,对服务和数据进行冗余部署或者创建副本。其中服务最好做成无状态的。不需要有一个中间大脑维护和协调不同节点间的状态。更方便扩容和故障切换。使系统更有可伸缩性。

这里更扩展点,其实由于服务是集群部署,需要有负载均衡。存储其实可以考虑容灾部署,主备、主从等架构


第四个阶段。 数据量过大。目前单个数据服务器已经无法承载。


需要解决的复杂度

  1. 如何将数据进行分区,文件名和不同存储如何映射,需要一个将图像文件名与包含它的服务器关联起来的命名方案。图像的名称可以由分布在服务器上的一致哈希方案生成。或者,每个图像可以被分配一个递增的 ID,这样当客户端请求图像时,图像检索服务只需要维护映射到每个服务器的 ID 范围(

  2. 数据一致性问题,多个客户端对同一个共享资源 读写时候面临的问题,即一些数据应该被更新,但在更新之前进行了读取操作,这种情况下数据是不一致的。

  3. 分区后,数据局部性,数据和操作和计算节点离得越近,性能越好。 因此,将数据分布在多个服务器上可能会导致潜在问题,因为每当需要数据时,它可能不在本地,迫使服务器通过网络执行昂贵的信息获取操作。


一般有两种方案 垂直扩容,将单个服务的容量和配置提升,仍然让单个机器承载全部的数据量。但是不可持续,且成本太高

水平扩容。就是将数据拆分成多个子数据集。分布到不同的存储系统。


Tip


用 postman 生成的 http-java 客户端,直接访问接口进行运维操作,不用再等 java 编译+部署的时间

  1. postman 右侧的</>

  1. 选择 java 客户端生成


  1. 复制到本地自己的工程里面

  2. 引入 okhttp 依赖,版本如果有问题可以自己调整升级,一般是最新的

        <dependency>            <groupId>com.squareup.okhttp3</groupId>            <artifactId>okhttp</artifactId>            <version>4.9.3</version>        </dependency>
复制代码


2 代码调试. 示例:查询+更新

public class Test {

@SneakyThrows public static void main(String[] args) {
String str = "{\"fieldId\":0,\"fieldName\":\"exactCurrencyType\",\"fieldValue\":\"%s\",\"method\":\"UPDATE\",\"id\":\"%s\"}"; String format = String.format(str, "111", "2222"); String oldOppStr="1111,2222"; String newOppStr="3333,4444"; List<Long> oldOppIds=Arrays.stream(oldOppStr.split(",")).map(s->Long.valueOf(s.trim())).collect(Collectors.toList()); List<Long> newOppIds=Arrays.stream(newOppStr.split(",")).map(s->Long.valueOf(s.trim())).collect(Collectors.toList()); if (oldOppIds.size()!=newOppIds.size()){ return; } for (int i = 0; i < oldOppIds.size() ; i++) {
Long oldOppId = oldOppIds.get(i); Long newOppId = newOppIds.get(i); String currency = getOpp(oldOppId); if ((currency.equals("USD"))){ continue; } System.out.println(currency); updateOpp(newOppId,currency); } }
private static void updateOpp(Long oppId,String currency) throws IOException { OkHttpClient client = new OkHttpClient().newBuilder() .build(); String str = "{\"fieldId\":0,\"fieldName\":\"exactCurrencyType\",\"fieldValue\":\"%s\",\"method\":\"UPDATE\",\"id\":\"%s\"}"; String format = String.format(str, currency, oppId); System.out.println(format); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, format); Request request = new Request.Builder() .url("https://www.xxx.net/apps/xxxx/currency-change/") .method("POST", body) .addHeader("accept", "application/json") .addHeader("accept-language", "en") .addHeader("content-type", "application/json") .addHeader("cookie", "xxxx") .addHeader("sec-ch-ua", "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"") .addHeader("sec-ch-ua-mobile", "?0") .addHeader("sec-ch-ua-platform", "\"macOS\"") .addHeader("sec-fetch-dest", "empty") .addHeader("sec-fetch-mode", "cors") .addHeader("sec-fetch-site", "same-origin") .addHeader("start-date", "Mon, 11 Sep 2023 12:18:53 GMT") .addHeader("tenant", "bytedance") .addHeader("tenant-code", "GREP_OVERSEA") .addHeader("time-zone", "GMT+08:00") .addHeader("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36") .addHeader("x-requested-with", "XMLHttpRequest") .build(); Response response = client.newCall(request).execute(); }

@SneakyThrows public static String getOpp(Long oppId){ OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); String url="https://www.xxx.net/xxxx/detail/?id=%s"; Request request = new Request.Builder() .get() .url(String.format(url,oppId))// .method("GET",body) .addHeader("accept", "application/json") .addHeader("accept-language", "en") .addHeader("cookie", "xxx") .addHeader("referer", "https://www.xxxx.net/apps/xxx/list?lang=en&id=222&title=test-%252520KA%2525E7%25259B%2525B4%2525E5%2525AE%2525A2adv2&pipelineId=17277&recordType=record_opportunity_oversea_auction") .addHeader("sec-ch-ua", "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"") .addHeader("sec-ch-ua-mobile", "?0") .addHeader("sec-ch-ua-platform", "\"macOS\"") .addHeader("sec-fetch-dest", "empty") .addHeader("sec-fetch-mode", "cors") .addHeader("sec-fetch-site", "same-origin") .addHeader("start-date", "Mon, 11 Sep 2023 12:25:50 GMT") .addHeader("tenant", "bytedance") .addHeader("tenant-code", "GREP_OVERSEA") .addHeader("time-zone", "GMT+08:00") .addHeader("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36") .addHeader("x-requested-with", "XMLHttpRequest") .build();// client.newCall(request).ar// new Thread(new Runnable() {// @Override// public void run() {// try {// //同步请求,要放到子线程执行// Response response = call.execute();//// Log.i(TAG, "okHttpGet run: response:"+ response.body().string());// } catch (IOException e) {// e.printStackTrace();// }// }// }).start(); Response response = client.newCall(request).execute(); String string = response.body().string(); SingleResponse<OpportunityDetailVO> singleResponse = new Gson().fromJson(string, new TypeToken<SingleResponse<OpportunityDetailVO>>(){}.getType()); OpportunityDetailVO data = singleResponse.getData(); return data.getCurrencyType();// System.out.println(currencyType);

// SingleResponse<OpportunityDetailVO> }
}
复制代码

Share


最近在看《旅行的艺术》这本书,

第一章关于人们旅行的期待和实际结果的差异进行了分析


旅行能够表达出紧张工作和辛苦谋生之外的另一种生活意义。

这种意义在一定程度上呈现了人们认为追求幸福才是生活的要义


我们总被告知要行万里路,但是少有人说为什么要去那个地方,如何到达那个地方

我们去一个地方可能是朋友圈一个美景照片的吸引,或者世界摄影杂志上的作品吸引带来的冲动


我们总是对旅行充满期望,

然而旅行的期望和旅行的现实的关系总会出现问题


我们总是从艺术作品或者别人的口述和朋友圈的照片 对于某个地方充满向往和期待。

但是艺术作品 以及 人们回忆中总会有简单化和选择的过程。就像筛选了砂砾中的黄金。

生活中,我们必须承受那些艺术所忽略的环节,这些是那么琐碎、具体。就像是砂砾一样,它们 可能是旅途中的天气变化、空气中味道,和恋人的磕绊。餐厅服务员的不礼貌 或者酒店的环境不如意,甚至路边的广告牌。都可能给我们造成很多困扰。


在实际旅行中,眼睛是和身体 以及我们的心智情绪 密不可分的。我们必须先满足了自己情感或者心理上的一些更为重要的需求,诸如对理解、爱、宣泄和尊重的需求,就像作者因为和恋人因为一块甜点吵架,导致彼此怨愤。就让他们不再享受整个酒店的迷人之处,一直到和解,和解的快乐又远远大于阳光沙滩带来的喜悦


当我们摒弃掉这些纷乱的干扰,享受期待中的阳光沙滩时候,这种和地方建立起来的幸福感总是那么短暂,可能不超过 10 分钟,因为在我们的意识中,新的焦虑总会生成。比如未来要有台风登录,航班是否延误,中午的饭菜吃什么 会不会太贵,回到工作中要面临解决什么问题等等。对未来近乎永恒的焦虑,是人进化过程中的优势,也在此刻产生干扰


构成幸福的关键因素并非是物质或者是审美的,而是永远是心理的。这也是古代希腊哲人采取的生活方式


想象能让我们平凡的生活变得比其本身更加丰富多彩, 因为在实际经历中,我们所想见到的 总是 在我们所能见到的现实场景中,而他们被稀释、被冲淡,最终可能变得平庸和黯淡。 因为我们焦虑未来而不能专注现在,而且我们对美的欣赏还受制于复杂的物质需要和心理欲求。


所以我想旅行前 要做好心理建设,旅游不必太过期待,也不必过于忧虑。 当然我们没有那么多超越的思考和思想,享受每一个可以享受的过程,培养专注放松愉悦的心态也是不错的


用户头像

苏籍

关注

还未添加个人签名 2019-01-30 加入

还未添加个人简介

评论

发布
暂无评论
ARTS打卡第6周_苏籍_InfoQ写作社区