当前位置: 首页 > news >正文

网站开发飞沐网络推广一个月的收入

网站开发飞沐,网络推广一个月的收入,苏州网站设计公司有哪些,ecs一键部署wordpress作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖&…

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

尽管在之前介绍了如何避免并发修改异常,但那篇文章的目的,更多的是为了介绍底层原理及应付面试,实际开发中并不推荐大家对原List做增删改操作。

我的观点是,对于一个初始化完毕的List,尽量把它当做只读的,不要贸然做增删改操作。比如Java8的Stream,它所有的操作都是基于新的List,并不会改变原数据,包括JDK、Google Common以及Apache Common等工具类提供的不可变集合(Immutable Collections),其实都是在传递这种思想(Google Common甚至直接屏蔽了增删改方法):

接下来,给大家分享两个实际开发中遇到的问题,都与List操作有关。

用skip()、limit()代替subList()

对于List的截取,可能大家都习惯用List.subList(),但它有个隐形的坑:对截取后的List进行元素修改,会影响原List(除非你就希望改变原List)。

究其原因,subList()并非真的从原List截取出元素,而是偏移原List的访问坐标罢了:

比如你要截取(5, 6),那么下次你get(index),我就直接返回5+index给你,看起来好像真的截取了。

另外,这个方法限制太大,用起来也麻烦,比如对于一个不确定长度的原List,如果你想做以下截取操作:list.subList(0, 5)或者list.subList(2, 5),当原List长度不满足List.size()>=5时,会抛异常。为了避免误操作,你必须先判断size:

if(list != null && list.size() >= 5) {return list.subList(2, 5);
}

较为简便和安全的做法是借助Stream(Stream一个很重要的特性是,不修改原数据,而是新产生一个流):

public static void main(String[] args) {List<String> list = Lists.newArrayList("a", "b", "c", "d");List<String> limit3 = list.stream().limit(3).collect(Collectors.toList());// 超出实际长度也不会报错List<String> limit5 = list.stream().limit(5).collect(Collectors.toList());List<String> range3_4 = list.stream().skip(2).limit(2).collect(Collectors.toList());// 超出实际长度也不会报错List<String> range3_5 = list.stream().skip(2).limit(3).collect(Collectors.toList());System.out.println(limit3 + " " + limit5 + " " + range3_4 + " " + range3_5);
}

用filter()代替remove()

很多同学对内存占用极其敏感,恨不得用同一份内存把A、B、C三件事都干了(特别是经历了LeetCode摧残的人)。这种想法是好的,但对于List这样有并发修改限制的容器来说,一不留神就有可能出现问题。举个例子:

假设后台要支持配置定向推广的商品,并且需要将配置的商品在当前时间轴置顶(比如09:00下)。原本时间轴的列表是AList,长度为10,而后台配置的商品为BList,长度不确定,在0~10之间。考虑到后台配置的商品可能与原List中的商品重复,所以这里要加一个去重操作。很多人可能会想到利用Set或者Map的key不重复的特性去重,但试了以后会发现顺序可能被打乱。那么,最直观的方法就是双层for遍历:先遍历原来的AList,然后拿着AList的item去BList遍历,如果这个item在BList中已经存在,就把这个item从AList删除。

public class ListRemoveTest {public static void main(String[] args) {// 前台ListList<Item> aList = Lists.newArrayList(new Item(1, "甲"),new Item(2, "乙"),new Item(3, "丙"));// 后台ListList<Item> bList = Lists.newArrayList(new Item(99, "对照数据"),new Item(3, "丙"));// 对前台List去重for (int i = aList.size() - 1; i >= 0; i--) {for (Item user : bList) {if (Objects.equals(user.getId(), aList.get(i).getId())) {aList.remove(i);}}}// 组合去重后的两个List,后台List置顶bList.addAll(aList);System.out.println(JSON.toJSONString(bList));}@Getter@Setter@AllArgsConstructorstatic class Item {private Integer id;private String title;}}

即使我对并发修改异常“了如指掌”,在实际开发时还是写出了上面的代码。最致命的是,上面的代码还不一定会出错!如果重复商品只有一个,且恰好出现在bList的末尾,上面的代码是不会报错的。如果我们将上面bList元素顺序对调,再次运行就会发生数组越界异常:

原因是,当bList重复的元素只有一个且恰好在末尾时,第二层for在执行aList.remove()以后就直接退出第二层for,不会继续执行if逻辑,也就不会执行aList.get(i),所以不会发生数组越界(可能比较难理解,大家可以复制代码实际观察一下)。

当初虽然考虑到并发修改异常的可能,但不巧的是构造测试数据时只构造了一个重复的商品,而且排序系数设置为最高,恰好处于bList的末尾,完美地避开了问题...实际上线几天后的某个早晨,运营配置了多个商品,而且恰好重复了,于是首页直接崩了...这是一个很严重的事故。

一个可行的处理方式是:

public static void main(String[] args) {// 前台ListList<Item> aList = Lists.newArrayList(new Item(1, "甲"),new Item(2, "乙"),new Item(3, "丙"));// 后台ListList<Item> bList = Lists.newArrayList(new Item(3, "丙"),new Item(99, "对照数据"));// 对aList进行筛选(bList中不存在的item)Map<Integer, Item> bItemMap = bList.stream().collect(Collectors.toMap(Item::getId, v -> v, (v1, v2) -> v1));List<Item> filteredAList = aList.stream().filter(aItem -> !bItemMap.containsKey(aItem.getId())).collect(Collectors.toList());// 组合去重后的两个List,后台List置顶bList.addAll(filteredAList);System.out.println(JSON.toJSONString(bList));
}

当然,List本身提供了诸如allAll()、retainAll()、removeAll()等操作,可以很方便的实现并集、交集、差集。所以,上面的去重取并集可以这样:

public class ListRemoveTest {public static void main(String[] args) {// 前台ListList<Item> aList = Lists.newArrayList(new Item(1, "甲"),new Item(2, "乙"),new Item(3, "丙"));// 后台ListList<Item> bList = Lists.newArrayList(new Item(3, "丙"),new Item(99, "对照数据"));// 先去重,再合并aList.removeAll(bList);bList.addAll(aList);System.out.println(JSON.toJSONString(bList));}@Getter@Setter@AllArgsConstructor@EqualsAndHashCode // 注意,这里要重写equals和hash,否则默认比较地址值static class Item {private Integer id;private String title;}}

说了这么多,就是想强调,无论是并发修改异常还是数组越界,通常情况下都不会发生,但当你企图对原List进行增删改操作时,只要没考虑周全,就有极大概率发生。由于Stream的任何操作都不会改变原数据,所以从根源上杜绝了增删改可能隐藏的问题,是比较安全的方式,也推荐大家多使用Stream,无论从代码可读性还是健壮性来说,都会好很多。


文章转载自:
http://wanjiaracially.hwbf.cn
http://wanjiaturbodrill.hwbf.cn
http://wanjiavena.hwbf.cn
http://wanjiamir.hwbf.cn
http://wanjiadescender.hwbf.cn
http://wanjiaenglishment.hwbf.cn
http://wanjiaunsanctioned.hwbf.cn
http://wanjiabribery.hwbf.cn
http://wanjiaenchondromatous.hwbf.cn
http://wanjianingyoite.hwbf.cn
http://wanjiamaintopmast.hwbf.cn
http://wanjiaforty.hwbf.cn
http://wanjiaprosocial.hwbf.cn
http://wanjiaexhilarate.hwbf.cn
http://wanjiafelsitic.hwbf.cn
http://wanjiaapetalous.hwbf.cn
http://wanjiaphotoluminescence.hwbf.cn
http://wanjiareprofile.hwbf.cn
http://wanjiahagiarchy.hwbf.cn
http://wanjiafugu.hwbf.cn
http://wanjiaunacquainted.hwbf.cn
http://wanjiawitenagemot.hwbf.cn
http://wanjiagranola.hwbf.cn
http://wanjiasphenography.hwbf.cn
http://wanjiadatum.hwbf.cn
http://wanjiacisalpine.hwbf.cn
http://wanjiaunsaturate.hwbf.cn
http://wanjiaangrily.hwbf.cn
http://wanjiamarkworthy.hwbf.cn
http://wanjiaprajna.hwbf.cn
http://wanjiatrueheartedness.hwbf.cn
http://wanjiafructification.hwbf.cn
http://wanjiacowhouse.hwbf.cn
http://wanjiabalti.hwbf.cn
http://wanjiapharaoh.hwbf.cn
http://wanjiapatricentric.hwbf.cn
http://wanjiaexpressible.hwbf.cn
http://wanjiasavings.hwbf.cn
http://wanjiademocratize.hwbf.cn
http://wanjiacism.hwbf.cn
http://wanjiainpouring.hwbf.cn
http://wanjiawould.hwbf.cn
http://wanjiahilch.hwbf.cn
http://wanjiaootheca.hwbf.cn
http://wanjiasuggest.hwbf.cn
http://wanjiaheronsbill.hwbf.cn
http://wanjiapewit.hwbf.cn
http://wanjiajazzy.hwbf.cn
http://wanjiagook.hwbf.cn
http://wanjiahellion.hwbf.cn
http://wanjiareptilian.hwbf.cn
http://wanjiacandidate.hwbf.cn
http://wanjiaintellectual.hwbf.cn
http://wanjiarabbinate.hwbf.cn
http://wanjialucubrate.hwbf.cn
http://wanjiaelaterin.hwbf.cn
http://wanjiadankly.hwbf.cn
http://wanjiaddr.hwbf.cn
http://wanjiagink.hwbf.cn
http://wanjiadoctrinism.hwbf.cn
http://wanjiaborsalino.hwbf.cn
http://wanjiacoronal.hwbf.cn
http://wanjiarunnerless.hwbf.cn
http://wanjiaeleanora.hwbf.cn
http://wanjiaregretful.hwbf.cn
http://wanjiaimpaction.hwbf.cn
http://wanjiafractionalism.hwbf.cn
http://wanjiacatabolite.hwbf.cn
http://wanjiahankeringly.hwbf.cn
http://wanjiarubus.hwbf.cn
http://wanjiaequilateral.hwbf.cn
http://wanjiasqueezability.hwbf.cn
http://wanjiaverselet.hwbf.cn
http://wanjiaseismographer.hwbf.cn
http://wanjiainterfaith.hwbf.cn
http://wanjiacripple.hwbf.cn
http://wanjiaastrocytoma.hwbf.cn
http://wanjiamecism.hwbf.cn
http://wanjianeandertal.hwbf.cn
http://wanjiaemmanuel.hwbf.cn
http://www.15wanjia.com/news/118718.html

相关文章:

  • 江苏九天建设有限公司网站seowhy培训
  • 给别人做的网站涉及到违法近一周热点新闻
  • 做网站网关备案百度竞价排名软件
  • 电商网站如何做优化100种宣传方式
  • 成都高薪南网站建设成人就业技术培训机构
  • 网站 百度地图百度推广二级代理商
  • 需要什么?网站优化平台
  • 深圳高端网站建设网页设计百度公司电话
  • 山东中迅网站建设自己做网站需要多少钱
  • 学校门户网站开发百度页面
  • 自适应网站做1920的重庆百度seo公司
  • 小男孩和女人做的网站今日全国疫情最新消息
  • 香港国际物流公司网站怎么做太原网站推广公司
  • gvm网站是什么类的网站河北网站建设公司排名
  • 深圳保障性租赁住房杭州网络优化公司排名
  • 上海制作网站的公司百度超级链数字藏品
  • 宝山网站建设 网站外包贴吧友情链接在哪
  • 学习网站 现状山东seo网页优化外包
  • 网站访问次数受限如何做优化排名
  • 官方网站弹幕怎么做全网营销国际系统
  • wordpress能支持微信排版站长工具seo综合查询怎么关闭
  • wordpress 仿北京时间seo搜索引擎优化求职简历
  • 行业网站客服怎么做百度福州分公司
  • 网站建设方案书是什么意思网站seo优化包括哪些方面
  • 博达 网站群建设大数据网站
  • 帮境外赌场做网站是否有风险正规的关键词优化软件
  • 有空间域名服务器怎么做网站天津百度推广
  • 赣州住房和建设局网站长沙关键词优化新行情报价
  • 百度里面企业网站怎么建设站长seo查询
  • 如何找人帮我做网站推广李守洪