首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

我国5G正在快速发展,5G现阶段发展情况及未来四年发展规划

目前,我国已建成5G基站超过115万个,占全球70%以上,是全球规模最大、技术最先进的5G独立组网网络,全国所有地级市城区、超过97%的县城城区和40%的乡镇镇区实现5G网络覆盖;5G终端用户达到4.5亿户,占全球80%以上。 在5G基站方面,要求到2025年实现每万人拥有5G基站26个,目前我国每万人拥有5G基站数为5个。如此算下来,到2025年,中国5G基站数将达到360多万个。未来4年,中国还将建设至少244.5万个以上的5G基站,预计每年新增60万个5G基站。 目前,全国5G应用创新的案例已超过1万个,覆盖22个国民经济重要行业,工业制造、采矿、港口等垂直行业应用场景加速规模落地,已由最初的生产辅助类业务为主向设备控制、质量管控等核心业务拓展,是当前5G应用方案较为成熟的领域。 教育、医疗、信息消费等领域5G应用加速发展。教育领域,全国多所高校进行积极探索,涌现出一批5G空中课堂、5G虚拟实验室、5G云考场、5G智慧校园等典型应用和标杆项目,为开展5G在智慧教育中的试点应用积累了经验。 医疗领域,全国已有超过600个三甲医院开展5G+急诊急救、远程诊断、健康管理等应用,切实提升了人民群众的幸福感、获得感、安全感。 信息消费领域,AR导游、4K/8K直播、沉浸式教学等5G应用,在游戏娱乐、赛事直播、居住服务等领域大幅提升消费体验。 下一步,工信部将联合相关部委及地方政府重点推进15个行业的5G应用,打造深度融合新生态,实现重点领域5G应用深度和广度双突破,构建技术产业和标准体系双支柱,逐步形成5G应用“扬帆远航”的发展局面。 在总体规模上,要求到2025年,信息通信行业收入达到4.3万亿元,累计增长10%;在信息通信基础设施累计投资达3.7万亿元。 在基础设施方面,要求到2025年,每万人拥有5G基站26个,10G-PON 及以上端口数达1200万个。工业互联网标识解析公共服务节点数达150个,移动网络 IPv6 流量占比达70%,国际互联网出入口带宽达48太比特每秒。 在绿色节能方面,要求到2025年,新建大型和超大型数据中心运行电能利用效率小于1.3。 在应用普及方面,要求到2025年,通信网络终端连接数达45亿个,增幅7%;5G 用户普及率达56%,千兆宽带用户数达6000万户,增加56%;工业互联网标识注册量达500亿个,增加40%;5G 虚拟专网数达5000个,增加44%。 在创新发展方面,要求到2025年,基础电信企业研发投入占收入比例4.5%。 在普惠共享方面,要求到2025年,行政村5G通达率达80%,电信用户综合满意指数大于82,互联网信息服务投诉处理及时率大于90。 针对以上指标,可以总结出多方面规律。运营商收入每年增长10%,支出却每年增长8%,这对运营商未来发展提出了很大挑战,亟需新业务支撑。二是5G基站每年大约需要增长60万。三是运营商将加大固网的投资力度。 虽然目前为止5G普及度和覆盖情况还不错,大多数地方的5G速度和信号还是有待提高,但相信随着技术的不断提高和发展,它将会迎来爆发式的增长!

优秀的个人博客,低调大师

☕【Java技术指南】「序列化系列」深入挖掘FST快速序列化压缩内存的利器的特性和原理

FST的概念和定义 FST序列化全称是Fast Serialization Tool,它是对Java序列化的替换实现。既然前文中提到Java序列化的两点严重不足,在FST中得到了较大的改善,FST的特征如下: JDK提供的序列化提升了10倍,体积也减少3-4倍多 支持堆外Maps,和堆外Maps的持久化 支持序列化为JSON FST序列化的使用 FST的使用有两种方式,一种是快捷方式,另一种需要使用ObjectOutput和ObjectInput。 直接使用FSTConfiguration提供的序列化和反序列化接口 public static void serialSample() { FSTConfiguration conf = FSTConfiguration.createAndroidDefaultConfiguration(); User object = new User(); object.setName("huaijin"); object.setAge(30); System.out.println("serialization, " + object); byte[] bytes = conf.asByteArray(object); User newObject = (User) conf.asObject(bytes); System.out.println("deSerialization, " + newObject); } FSTConfiguration也提供了注册对象的Class接口,如果不注册,默认会将对象的Class Name写入。这个提供了易用高效的API方式,不使用ByteArrayOutputStreams而直接得到byte[]。 使用ObjectOutput和ObjectInput,能更细腻控制序列化的写入写出: static FSTConfiguration conf = FSTConfiguration.createAndroidDefaultConfiguration(); static void writeObject(OutputStream outputStream, User user) throws IOException { FSTObjectOutput out = conf.getObjectOutput(outputStream); out.writeObject(user); out.close(); } static FstObject readObject(InputStream inputStream) throws Exception { FSTObjectInput input = conf.getObjectInput(inputStream); User fstObject = (User) input.readObject(User.class); input.close(); return fstObject; } FST在Dubbo中的应用 Dubbo中对FstObjectInput和FstObjectOutput重新包装解决了序列化和反序列化空指针的问题。 并且构造了FstFactory工厂类,使用工厂模式生成FstObjectInput和FstObjectOutput。其中同时使用单例模式,控制整个应用中FstConfiguration是单例,并且在初始化时将需要序列化的对象全部注册到FstConfiguration。 对外提供了同一的序列化接口FstSerialization,提供serialize和deserialize能力。 FST序列化/反序列化 FST序列化存储格式 基本上所有以Byte形式存储的序列化对象都是类似的存储结构,不管class文件、so文件、dex文件都是类似,这方面没有什么创新的格式,最多是在字段内容上做了一些压缩优化,包括我们最常使用的utf-8编码都是这个做法。 FST的序列化存储和一般的字节格式化存储方案也没有标新立异的地方,比如下面这个FTS的序列化字节文件 00000001: 0001 0f63 6f6d 2e66 7374 2e46 5354 4265 00000010: 616e f701 fc05 7630 7374 7200 格式: Header|类名长度|类名String|字段1类型(1Byte) | [长度] | 内容|字段2类型(1Byte) | [长度] | 内容|… 0000:字节数组类型:00标识OBJECT 0001:类名编码,00标识UTF编码,01表示ASCII编码 0002:Length of class name (1Byte) = 15 0003~0011:Class name string (15Byte) 0012:Integer类型标识 0xf7 0013:Integer的值=1 0014:String类型标识 0xfc 0015:String的长度=5 0016~001a:String的值"v0str" 001b~001c:END 从上面可以看到Integer类型序列化后只占用了一个字节(值等于1),并不像在内存中占用4Byte,所以可以看出是根据一定规则做了压缩,具体代码看FSTObjectInput#instantiateSpecialTag中对不同类型的读取,FSTObjectInput也定义不同类型对应的枚举值: public class FSTObjectOutput implements ObjectOutput { private static final FSTLogger LOGGER = FSTLogger.getLogger(FSTObjectOutput.class); public static Object NULL_PLACEHOLDER = new Object() { public String toString() { return "NULL_PLACEHOLDER"; }}; public static final byte SPECIAL_COMPATIBILITY_OBJECT_TAG = -19; // see issue 52 public static final byte ONE_OF = -18; public static final byte BIG_BOOLEAN_FALSE = -17; public static final byte BIG_BOOLEAN_TRUE = -16; public static final byte BIG_LONG = -10; public static final byte BIG_INT = -9; public static final byte DIRECT_ARRAY_OBJECT = -8; public static final byte HANDLE = -7; public static final byte ENUM = -6; public static final byte ARRAY = -5; public static final byte STRING = -4; public static final byte TYPED = -3; // var class == object written class public static final byte DIRECT_OBJECT = -2; public static final byte NULL = -1; public static final byte OBJECT = 0; protected FSTEncoder codec; ... } FST序列化和反序列化原理 对Object进行Byte序列化,相当于做了持久化的存储,在反序列的时候,如果Bean的定义发生了改变,那么反序列化器就要做兼容的解决方案,我们知道对于JDK的序列化和反序列,serialVersionUID对版本控制起了很重要的作用。FST对这个问题的解决方案是通过@Version注解进行排序。 在进行反序列操作的时候,FST会先反射或者对象Class的所有成员,并对这些成员进行了排序,这个排序对兼容起了关键作用,也就是@Version的原理。在FSTClazzInfo中定义了一个defFieldComparator比较器,用于对Bean的所有Field进行排序: public final class FSTClazzInfo { public static final Comparator<FSTFieldInfo> defFieldComparator = new Comparator<FSTFieldInfo>() { @Override public int compare(FSTFieldInfo o1, FSTFieldInfo o2) { int res = 0; if ( o1.getVersion() != o2.getVersion() ) { return o1.getVersion() < o2.getVersion() ? -1 : 1; } // order: version, boolean, primitives, conditionals, object references if (o1.getType() == boolean.class && o2.getType() != boolean.class) { return -1; } if (o1.getType() != boolean.class && o2.getType() == boolean.class) { return 1; } if (o1.isConditional() && !o2.isConditional()) { res = 1; } else if (!o1.isConditional() && o2.isConditional()) { res = -1; } else if (o1.isPrimitive() && !o2.isPrimitive()) { res = -1; } else if (!o1.isPrimitive() && o2.isPrimitive()) res = 1; // if (res == 0) // 64 bit / 32 bit issues // res = (int) (o1.getMemOffset() - o2.getMemOffset()); if (res == 0) res = o1.getType().getSimpleName().compareTo(o2.getType().getSimpleName()); if (res == 0) res = o1.getName().compareTo(o2.getName()); if (res == 0) { return o1.getField().getDeclaringClass().getName().compareTo(o2.getField().getDeclaringClass().getName()); } return res; } }; ... } 从代码实现上可以看到,比较的优先级是Field的Version大小,然后是Field类型,所以总的来说Version越大排序越靠后,至于为什么要排序,看下FSTObjectInput#instantiateAndReadNoSer方法 public class FSTObjectInput implements ObjectInput { protected Object instantiateAndReadNoSer(Class c, FSTClazzInfo clzSerInfo, FSTClazzInfo.FSTFieldInfo referencee, int readPos) throws Exception { Object newObj; newObj = clzSerInfo.newInstance(getCodec().isMapBased()); ... } else { FSTClazzInfo.FSTFieldInfo[] fieldInfo = clzSerInfo.getFieldInfo(); readObjectFields(referencee, clzSerInfo, fieldInfo, newObj,0,0); } return newObj; } protected void readObjectFields(FSTClazzInfo.FSTFieldInfo referencee, FSTClazzInfo serializationInfo, FSTClazzInfo.FSTFieldInfo[] fieldInfo, Object newObj, int startIndex, int version) throws Exception { if ( getCodec().isMapBased() ) { readFieldsMapBased(referencee, serializationInfo, newObj); if ( version >= 0 && newObj instanceof Unknown == false) getCodec().readObjectEnd(); return; } if ( version < 0 ) version = 0; int booleanMask = 0; int boolcount = 8; final int length = fieldInfo.length; int conditional = 0; for (int i = startIndex; i < length; i++) { // 注意这里的循环 try { FSTClazzInfo.FSTFieldInfo subInfo = fieldInfo[i]; if (subInfo.getVersion() > version ) { // 需要进入下一个版本的迭代 int nextVersion = getCodec().readVersionTag(); // 对象流的下一个版本 if ( nextVersion == 0 ) // old object read { oldVersionRead(newObj); return; } if ( nextVersion != subInfo.getVersion() ) { // 同一个Field的版本不允许变,并且版本变更和流的版本保持同步 throw new RuntimeException("read version tag "+nextVersion+" fieldInfo has "+subInfo.getVersion()); } readObjectFields(referencee,serializationInfo,fieldInfo,newObj,i,nextVersion); // 开始下一个Version的递归 return; } if (subInfo.isPrimitive()) { ... } else { if ( subInfo.isConditional() ) { ... } // object 把读出来的值保存到FSTFieldInfo中 Object subObject = readObjectWithHeader(subInfo); subInfo.setObjectValue(newObj, subObject); } ... 从这段代码的逻辑基本就可以知道FST的序列化和反序列化兼容的原理了,注意里面的循环,正是按照排序后的Filed进行循环,而每个FSTFieldInfo都记录自己在对象流中的位置、类型等详细信息: 序列化: 按照Version对Bean的所有Field进行排序(不包括static和transient修饰的member),没有@Version注解的Field默认version=0;如果version相同,按照version, boolean, primitives, conditionals, object references排序 按照排序的Field把Bean的Field逐个写到输出流 @Version的版本只能加不能减小,如果相等的话,有可能因为默认的排序规则,导致流中的Filed顺序和内存中的FSTFieldInfo[]数组的顺序不一致,而注入错误 反序列化: 反序列化按照对象流的格式进行解析,对象流中保存的Field顺序和内存中的FSTFieldInfo顺序保持一致 相同版本的Field在对象流中存在,在内存Bean中缺失:可能抛异常(会有后向兼容问题) 对象流中包含内存Bean中没有的高版本Field:正常(老版本兼容新) 相同版本的Field在对象流中缺失,在内存Bean中存在:抛出异常 相同的Field在对象流和内存Bean中的版本不一致:抛出异常 内存Bean增加了不高于最大版本的Field:抛出异常 所以从上面的代码逻辑就可以分析出这个使用规则:@Version的使用原则就是,每新增一个Field,就对应的加上@Version注解,并且把version的值设置为当前版本的最大值加一,不允许删除Field 另外再看一下@Version注解的注释:明确说明了用于后向兼容 package org.nustaq.serialization.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) /** * support for adding fields without breaking compatibility to old streams. * For each release of your app increment the version value. No Version annotation means version=0. * Note that each added field needs to be annotated. * * e.g. * * class MyClass implements Serializable { * * // fields on initial release 1.0 * int x; * String y; * * // fields added with release 1.5 * @Version(1) String added; * @Version(1) String alsoAdded; * * // fields added with release 2.0 * @Version(2) String addedv2; * @Version(2) String alsoAddedv2; * * } * * If an old class is read, new fields will be set to default values. You can register a VersionConflictListener * at FSTObjectInput in order to fill in defaults for new fields. * * Notes/Limits: * - Removing fields will break backward compatibility. You can only Add new fields. * - Can slow down serialization over time (if many versions) * - does not work for Externalizable or Classes which make use of JDK-special features such as readObject/writeObject * (AKA does not work if fst has to fall back to 'compatible mode' for an object). * - in case you use custom serializers, your custom serializer has to handle versioning * */ public @interface Version { byte value(); } public class FSTBean implements Serializable { /** serialVersionUID */ private static final long serialVersionUID = -2708653783151699375L; private Integer v0int private String v0str; } 准备序列化和反序列化方法 public class FSTSerial { private static void serialize(FstSerializer fst, String fileName) { try { FSTBean fstBean = new FSTBean(); fstBean.setV0int(1); fstBean.setV0str("v0str"); byte[] v1 = fst.serialize(fstBean); FileOutputStream fos = new FileOutputStream(new File("byte.bin")); fos.write(v1, 0, v1.length); fos.close(); } catch (Exception e) { e.printStackTrace(); } } private static void deserilize(FstSerializer fst, String fileName) { try { FileInputStream fis = new FileInputStream(new File("byte.bin")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[256]; int length = 0; while ((length = fis.read(buf)) > 0) { baos.write(buf, 0, length); } fis.close(); buf = baos.toByteArray(); FSTBean deserial = fst.deserialize(buf, FSTBean.class); System.out.println(deserial); System.out.println(deserial); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { FstSerializer fst = new FstSerializer(); serialize(fst, "byte.bin"); deserilize(fst, "byte.bin"); } } 参考资料 https://github.com/RuedigerMoeller/fast-serialization

优秀的个人博客,低调大师

第90届中国电子展聚焦行业新热点,拉动产业链上下游快速发展

10月25到27日,第90届中国电子展&上海亚洲电子展&IC China 2017也将在上海新国际博览中心拉开帷幕。 10月23日下午,第90届中国电子展&上海亚洲电子展&IC China 2017三展联动的新闻发布会在上海卓美亚喜马拉雅酒店举行。 而在10月25到27日,第90届中国电子展&上海亚洲电子展&IC China 2017也将在上海新国际博览中心拉开帷幕。展会以“信息化带动工业化,电子技术促进产业升级”为主题,聚焦行业前沿技术与创新产品,力争为国内外企业打造一流的交流和合作平台。 核心展区亮点多多,纵览未来行业大势 1.新型电子元器件成为新时代主体 随着下游消费电子产品日益向轻薄化、智能化方向发展,电子元器件也正在进入以新型电子 元器件为主体的新时代。电子元器件由原来只为适应整机的小型化及新工艺要求为主的改进,变成以满足数字技术、微电子技术发展所提出的特性要求为主,而且是成套满足的产业化发展阶段。 新型电子元器件具有高频化、片式化、微型化、薄型化、低功耗、响应速率快、高分辨率、高精度、高功率、模块化等特征,相配套的制作工艺精密化、流程自动化,生产环境也要求越来越高。 我国作为电子元器件的生产和消耗大国,电子元件的产量已占全球的近39%以上。国内厂商始终跟进发展潮流,不断提高自身的技术能力和产品质量,追赶国际先进企业,努力缩短差距,以便更好的满足国内市场对于电子元器件的需求。 在本届展会的综合元器件展区,有来自我国四面八方的厂商参展,诸如中航光电、瑞士雷莫、贵州航天电器、上海洲日、深圳通茂、珩星电子、四川永星、福建火炬、陕西华星、上海克拉、幸亚(苏州)电子、宁波福特、彩智电子、山东迪一、上海佑风电子、广东科信电子、无锡东海、惠州玛尼微、江苏捷捷、启东吉莱等。元器件展区作为中国电子展的传统优势展区,历经多年的努力,已经成为中国电子元器件产品的重要交流平台。 2.摩尔定律濒临极限,但电子信息产业仍将持续进展 英特尔的创始人之一戈登·摩尔曾经做过这样一个预言:每两年微处理器的晶体管数量都将加倍——意味着芯片的处理能力也加倍,这就是半导体行业中最著名的“摩尔定律”,这种指数级的增长,促使上世纪70年代的大型家庭计算机转化成80、90年代更先进的机器,然后又孕育出了高速度的互联网、智能手机和现在的车联网、智能冰箱和智能温控器等。 但是从2000-2005年间,摩尔定律的间隔开始逐渐放缓到两三年,最近更是演变为每隔四年倍增一次,因此,业界正逐渐走向硅芯片的性能极限,但这就意味着电子信息产业走到了尽头吗?不,与以往首先改善芯片、软件随后跟上的发展趋势不同,以后半导体行业的发展将首先看软件,然后反过来看要支持软件和应用的运行需要什么处理能力的芯片来支持,由于新的计算设备变得越来越移动化,新的芯片中,可能会有新的一代的传感器、电源管理电路和其他的硅设备。而量子计算、DNA数据存储、神经形态计算等一系列新技术将继续推行业发展。 本届展会,紫光集团,紫光同芯、北京同方微电子,锐迪科微电子、展讯、长江存储、联发科、天津飞腾、华大半导体、龙芯中科、大唐电信、昂宝电子、高云半导体、中微半导体、analogix、瑞能半导体、迪思科、北方华创、江苏长电、京瓷、宁波江丰、中芯国际、华宏宏力、华润微电子等一大批国内优秀的IC厂商云集,将携带多款创新方案亮相。 3.产业应用热点发生转移,汽车电子成热点 如今,电子信息产业的应用热点已从最初的计算机、通信扩展至物联网硬件产品、汽车电子等领域,尤其是智能网联汽车的迅速发展,为对传感器、MCU(微控制单元)、激光设备、红外设备、雷达设备、GPS等行业带来新的发展机遇。 随着汽车电子所需传感器种类、数量的不断增加,厂商必须不断研制出新型、高精度、高可靠性、低成本和智能化的传感器;随着汽车电子占整车比重不断提高,MCU在汽车领域的应用将超过家电和通讯领域使用的数量,成为世界上最大的MCU应用领域;随着车辆需要精确感知周围状态并对环境形成反馈,激光、红外、雷达等处理装置越发先进;随着车联网需要对大量数据进行传输和交换,数据总线技术应用日益普及。 当前,众多国内外知名半导体厂商均重点推出了旗下智能汽车系列的芯片产品;众多通信厂商则致力于针对联网汽车研发高速率、低延迟的先进通讯技术;传统车企则和科技巨头们强强联手争相抢夺无人驾驶制高点……可以想象,在未来,汽车就是一步跑在轮子上的“超级智能手机”。 在本届展会的智能车联网展区,英特尔、百度、德州仪器、英伟达、科大讯飞、大唐恩智浦、上海先进等国际知名半导体厂商和国内外知名汽车厂商都会有极具吸引力的解决方案呈现。相关专家还会与您共同探讨产业发展模式和方向。或许您能在其中找到解决车联网,特别是国内相关市场需求和难题的钥匙。 4.智能制造成电子信息产业新蓝海 自2008年金融危机之后,世界经济的重心从互联网、金融等虚拟产业重新转移回实体制造业。在全球制造业都在发展时遭遇瓶颈(资产可用度不高、数据透明度差、工业信息安全问题、生产灵活性差以及持续上升的人工成本等等)之时,美国提出了“工业互联网”,日本提出工业复兴计划,德国提出了“工业4.0”,中国提出了“中国制造2025”。这些计划的核心就是利用以物联网为代表的新兴技术来对原有的制造业进行改造升级。 新一代信息技术与制造业的深度融合,将促进制造模式、生产组织方式和产业形态的深刻变革,这也是电子信息产业的一片新蓝海。目前,美、德等着力推进智能制造的发达国家,均有一批电子信息领域的优秀跨国企业提供技术和服务支撑,比如GE的Predix工业互联网操作系统,西门子的MindSphere物联网操作系统…欧美这些企业已经在信息技术与制造业融合上走在世界的前列,抢占了技术和标准的制高。 但我国也不甘落后, 2016年12月,工信部发布了国家《智能制造“十三五”发展规划》, 《规划》提出,到2020年,明显增强智能制造发展基础和支撑能力,传统制造业重点领域基本实现数字化制造。到2025年,智能制造支撑体系基本建立,重点产业初步实现智能转型。 在本届展会的智能制造设备展区,北京北方华创、北京京运通科、北京中科信、四十五所、中微半导体、沈阳拓荆、沈阳芯源微、大连佳峰、浙江晶盛机电、深圳捷佳伟创、青岛赛瑞达、北京京仪、北京七星华创,以及常州同惠、罗德与施瓦茨(RS)、长盛仪器、普源等厂商都将展示工业创新解决方案。 电子信息行业的半壁江山都被搬来,多场买家活动不容错过! 除了综合元器件、仪器仪表、智能制造设备、集成电路、智能网联汽车领域的百余家企业外,创维、华为,中国电信,上海移远通信,海尔,上海欧孚通信技术有限公司将带来物联网和智慧家庭方面的信息;英飞凌、罗姆、华虹宏力和vicor等将在功率半导体方面为您献上多款套餐。更好玩的是,本次展会还设有年轻人的乐园——电子竞技专区,届时,三星,创维,冠捷、云呦等厂商将会给您带来劲爆的游戏体验。 对展商来说,光来参展却没有点儿实质收获怎么能行?若能在洞察行业趋势的同时促成几桩交易,岂不美哉?此次展会不但是电子信息产业发展的风向标,还为国内外企业打造了一流的交流和合作平台。 展会期间将举办由大型企业的技术人员以及有采购决策权的工程师参与的专场采购推介活动,促进参展企业展示推荐自己产品增加销售机会。展会定向邀约包括三星电子采购中心、富士通集团、上海航天电器、苏州松下半导体、天马微电子、南京熊猫、昆山富士康、仁宝电子等近50家采购商手持“30亿”采购意向到现场与参展商沟通采购。 同时,组委会携手采购平台柠檬豆举办《2017家电智能化技术与发展论坛》,将邀请美的、海信、TCL家用电器、惠而浦、美菱、晶弘、康佳、创维、锐驰、方太、四季沐歌等整机采购企业,汇集大量智能方案需求和新技术。论坛现场将集中展示行业领先新品、技术应用,并促成供需企业现场精准对接,可以极大地促进供需企业的高效沟通和家电行业智能化创新的发展。 更新知识储备,多场专题研讨会同期进行 展、会结合,是中国电子展的传统特色。在本届展会上举办的多场高峰论坛和专题研讨会,为与会听众提供了拓宽眼界、更新知识储备的良机。展会期间将举行“第十五届中国国际半导高峰论坛”“2017第十五届中国(上海)汽车电子暨智能网联汽车核心技术峰会”、“2017中国电子元件与材料技术发展高峰论坛”、“2017中国上海嵌入式系统安全论坛”、“NB-IoT技术应用创新融合论坛”、“第二届(上海)电源半导体技术论坛”和“2017年半导体设备与核心部件制造商对话会”。 原文发布时间: 2017-10-23 21:29 本文来自云栖社区合作伙伴镁客网,了解相关信息可以关注镁客网。

优秀的个人博客,低调大师

【读书笔记《Android游戏编程之从零开始》】9.游戏开发基础(如何快速的进入 Android 游戏开发)

1.不可盲目看API文档 很多人在接触学习一门新的平台语言时,总喜欢先去探究一番API文档。先不说成效如何,至少编者认为这种方式不适合大部分人来效仿,主要原因在于 API 领域广泛,牵涉到的知识点太多,而对于刚刚接触平台开发语言的大部分人来说,遗忘速度远远大于记忆!这种做法是大量消耗精力、小量吸取知识的方法,只会事倍功半。2.前人栽树,后人乘凉 对于初学者来说,任何想要学习与掌握的知识点,之前都会有高人总结过;所以建议大家每学习一个知识点,都尽可能的先动手去网上搜索和学习别人总结出来的相关知识点的文章,毕竟前任总结的知识会让你减少学习的弯路。最后再根据每个知识点去详细翻阅相关的 API 文档,有针对性、有目的性的去看 API 文档才会是事半功倍。3.好记性不如烂笔头 这句谚语,几乎无人不知无人不晓,但是总被许多初学者抛在脑后。在学习的时候,总是看代码多,而动手练习代码少!身为一个程序员都应该很清楚,代码如果不多动手敲它,它永远不会自己跑进脑中,所以多动手才是成功的关键。4.养成自学的习惯 学习新的知识如果总是抱着依赖和期望别人手把手教授,那就不太现实了。因为没有任何一个人能时时刻刻的陪在身边给予帮助,但是使用 Baidu 和 Google 可以做到!它们拥有着最全的资源库,使用它们可以查找到最强的技术,不过,它们永远都只在那里等待你去使用它们,如果你不动手去搜索,那么对于你来说它们毫无用处。5.利用小项目实战进步快 在学习游戏开发时,一定要多做小项目,比如今天学会了一个新的知识点,那么首先就要尽可能发散思维,多思考这个知识点会应用到什么类型的游戏中,并在游戏中起到什么样的作用等等。然后拿出时间一定要去写一个小项目联系新知识点。 写小项目有两点好处:一是巩固新知识点;二是通过小项目发现知识点实际应用到游戏中会出现的问题,有些问题不亲自动手编写是根本无法发现的。6.进步来源于问题 好程序不是写出来的,是改出来的!这句话没有人能反驳,因为谁写代码都不可能是一遍成功,不用修改不用完善的。 学习中遇到问题时,不应该烦躁而是应该庆幸,因为解决掉问题就意味着进步。千万不要出到问题不假思索就去请教他人,这样解决掉的问题没有任何意义。 当然不推荐大家遇到问题一定就铁下心的自己去几天几夜的钻研,应该自我把握问题的难易度,如果问题确实超出自己能力的,那么请教他人反而对自己更有帮助,有效率,前提是自己考虑过如何解决此问题。 其实,游戏开发的学习过程应该是一个拼图的过程.首先要分模块来学习,积累了一定的模块知识后,再通过这些模块就可以拼出各种类型\各种风格的游戏。 在游戏开发中,一般很少使用系统提供的组件进行开发,其主要原因在于游戏的多样性.比如一款"连连看"游戏,它就可以有N种玩法、N种场景、N种风格、N种元素.所以,如果还期望从系统中找到对应组件的话,结果会令人失望,不是系统不想提供,而是它永远无法知道将要制作的游戏类型、风格等等。总结一句话: 开发一款游戏,请用自己的双手为这款游戏创建专属它的组件!换言之,就是要自己去实现游戏中的组件,不要再一味的幻想系统能为你带来什么。系统只提供“一支笔”、“一张画布”,仅此而已。至于能创造出多么精彩的游戏世界,那完全取决于游戏开发者。 本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/p/4134758.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

爬虫简介 (爬虫入门小知识点;正式进入爬虫-requests模块的使用;两个实战-使用reques

1.爬虫是什么? 引言:爬虫?什么是爬虫?爬虫的定义:模拟浏览器发送请求,获取响应。书面化爬虫简介!!!点我哦!!! 爬虫的作用: 1.数据采集 抓取微博评论(机器学习舆情监控) 抓取招聘网站的招聘信息(数据分析,挖掘) 新浪滚动新闻 百度新闻网站 2.软件测试 爬虫之自动化测试 虫师 3.12306抢票 4.网站上的投票 5.网络安全 短信轰炸 web漏洞扫描 爬虫的分类: 根据被爬取的数量不同,分类: 通用爬虫:通常指搜索引擎的爬虫 具有很大的局限性:大部分内容没有用,不同搜索目的,返回的内容相同! (通用爬虫是搜索引擎抓取系统 (baidu,goole,yahoo等)的重要组成部分 。 主要目的是将互联网的网页下载到本地 ,形成一个互联网内容的镜像备份。) 聚焦爬虫:针对特定网站的爬虫 (是面向特定主题需求的一种网络爬虫程序 ,它与通用搜索引擎爬虫的区别在于 : 聚焦爬虫在实施页面抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息) 根据是否获取数据为目的,分类: 功能性爬虫,比如,投票,点赞 数据增量爬虫,比如招聘信息 根据url地址和对应的页面内容是否改变,数据增量爬虫分类: 基于url地址变化,内容也随之变化的数据增量爬虫 url地址不变,内容变化的数据增量爬虫 工作流程: 流程:url——>发送请求,获取响应——>提取数据——>保存数据 发送请求,获取响应——>提取url地址,继续请求 robots协议:robots协议:网站通过robots协议,告诉我们搜索引擎哪些页面可以抓取,哪些页面不能抓取,但它仅仅是道德层面上的约束。 http的重点请求头: http的重点请求头: user-agent:告诉对方服务器是什么客户端正在请求资源,爬虫中模拟浏览器非常重要的一个手段 爬虫中通过把user-agent设置为浏览器的ua,能够达到模拟浏览器的效果。 cookie:获取登录之后,才能够访问的资源 常见的请求头,响应头 Content-Type Host(主机和端口号) Upgrade-Insecure-Rwquests(升级为https请求) User-Agent(浏览器名称) Referer(页面跳转处) Cookie Authorization(用于表示http协议中需要认证资源的认证信息,如jwt认证) 浏览器发送http请求的过程: 浏览器发送http请求的过程: 1.域名解析 --> 2.发起TCP的3次握手 --> 3.建立TCP连接后发起http请求 --> 4.服务器响应http请求,浏览器得到html代码 --> 5.浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 6.浏览器对页面进行渲染呈现给用户. 注意: 在网页的检查里的Network->Name->Request Headers view parsed下 的Connection:keep-alive保持常连接,就不用频繁的三次握手和三次分手! 浏览器获取的内容(elements的内容)包含:url地址对应的响应+js+css+jpg 爬虫会获取:url地址对应的响应 爬虫获取的内容和elements内容不一样,进行数据提取的时候,需要根据url地址对应的响应为准 http和HTTPS的概念: 1.http超文本传输协议 协议默认端口80 2.https也是超文本传输协议 协议默认端口443 http因为是明文传输,而https是密文传输,所以HTTPS比http更安全,但是性能低,因为解密需要消耗时间! 2.正式进入爬虫—requests模块的使用! 1.url地址解码的方法: requests.utils.unquote(url) 2.requests中headers如何使用: headers = {"User-Agent":""} requests.get(url,headers=headers) 3.requests中如何发送post请求: data = {"浏览器中的form data"} requests.post(url,data=data) 概念:爬虫就是模拟浏览器发送网络请求,获取请求响应 4.requests如何发送请求和获取响应: response = requests.get(url) response.text ---> str(获取的数据是字符串类型) response.encoding="utf-8"(乱码需要解码,修改编码方式) response.content ---> bytes(获取的数据是字节类型) response.content.decode()(字节需要编码) 5.响应: response.text str类型, response.content 获取内容,字节类型,需要decode编码 response.status_code 获取状态码 response.request.headers 响应对应的请求头 response.headers 响应头 response.request.url 请求url地址 response.url 响应url地址 response.request._cookie 响应对应请求的cookie;返回cookiejar类型 response.cookies 响应cookie(经过了set-cookie动作,返回cookiejar类型) response.json() 自动将json字符串类型的响应内容转换为python对象(dict 或者 list) 6.发送带参数的请求: params = {"":""} url_temp = "不完整的URL地址" requests.get(url_temp,params=params) 例:wd为百度词条搜索url的参数key值 3.实战:利用requests库进行百度贴吧的爬取! import os import requests ''' 为了构造正确的url!!! 进入百度贴吧进行测试,任意搜索一个信息,通过不同页更换,观察url找寻规律: https://tieba.baidu.com/f?kw=美食&ie=utf-8&pn=0 https://tieba.baidu.com/f?kw=美食&ie=utf-8&pn=50 https://tieba.baidu.com/f?kw=美食&ie=utf-8&pn=100 https://tieba.baidu.com/f?kw=美食&ie=utf-8&pn=150 ''' class TiebaSpider: def __init__(self,tieba_name): self.tieba_name = tieba_name self.url_temp = "https://tieba.baidu.com/f?kw="+tieba_name+"&ie=utf-8&pn={}" self.headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"} # 构造url列表 def get_url_list(self): return [self.url_temp.format(i*50) for i in range(5)] # 发送请求,获取响应 def parse_url(self,url): response = requests.get(url,headers=self.headers) return response.content.decode() # 保存 def save_html_str(self, html_str, page_num): file_path = "{}_第{}页.html".format(self.tieba_name, page_num) dir = 'ceshi' if not os.path.exists(dir): os.mkdir(dir) file_path = dir + '/' + file_path with open(file_path, "w", encoding='utf-8') as f: f.write(html_str) print("保存成功!") # 实现主要逻辑 def run(self): # 构造url列表 url_list = self.get_url_list() # 发送请求,获取响应 for url in url_list: html_str = self.parse_url(url) # 保存 page_num = url_list.index(url)+1 self.save_html_str(html_str, page_num) if __name__ == '__main__': name_date = input("请输入你想知道的内容:") tieba_spider = TiebaSpider(name_date) tieba_spider.run() 本代码是爬取指定搜索内容获取到的html源码头5页! 4.requests模块发送post请求 应用场景:登录注册需要传输大文本内容的时候(post请求对长度没有要求) 用法:response = requests.post(“http://www.baidu.com”, data = data, headers = headers)data的形式:字典data的来源:固定值,抓包(form data) 实战:汉译英爬虫实现! import requests import json class King(object): def __init__(self, word): self.url = 'http://fy.iciba.com/ajax.php?a=fy' self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'} self.data = { 'f': 'auto', 't': 'auto', # 'w': '字典' 'w': word } def post_data(self): response = requests.post(self.url, data=self.data, headers=self.headers) return response.content def parse_data(self,data): # 将json字符串转化为字典 dict_data = json.loads(data) try: print(dict_data['content']['out']) except: print(dict_data['content']['word_mean'][0]) def run(self): # 编写爬虫的逻辑 # url # headers # data 字典 # 发送请求获取响应 response = self.post_data() # print(response) # 数据分析 # 获取翻译后的结果 self.parse_data(response) if __name__ == '__main__': word = input('请输入要翻译的单词或者句子:') king = King(word) king.run() 5.使用代理: 什么是代理?什么是代理?代理IP是一个ip ,指的是一个代理服务器。 要晓得正向代理和反向代理是啥?不知道服务器的地址做为判断标准:知道就是正向代理,不知道就是反向代理。 代理ip的分类匿名度:透明代理 :目标服务器可以通过代理找到你的ip匿名代理 :两者之间高匿代理 :在爬虫中经常使用,目标服务器无法获取你的ip协议:根据网站使用的协议不同,需要使用响应的协议代理服务,http代理:目标的url为http协议https代理:目标url为https协议socks代理 :只是简单的传递数据包,不关心是何种协议,比http和HTTPS代理消耗小, 可以转发http和https的请求 为何使用代理?(1)让服务器以为不是同一个客户端在请求(2)防止我们的真实地址被泄露,防止被追究 用法: response = requeses.get("http://www.baidu.com, proxies = proxies") proxies的形式:字典 例如: proxies = { "http": "http://192.168.13.24:8000", "https": "http://192.168.13.24:8000" } 案例:import requestsurl = “http://www.baidu.com” proxies = {‘http’:‘http://111.222.11.123:12222’,}headers = {“User-Agent”:“Mozilla/5.0 (Windows NT 10.0;.36 (KHTML, like Gecko) Chrome/84.0.414.36”} response = requests.get(url,proxies=proxies,headers=headers,timeout=5)print(response.text) 6.cookie与session (1)requests获取cookie requests.utils.dict_from_cookiejar:把cookiejar对象转化为字典。 举例: import requests url = 'http://www.baidu.com' response = requests.get(url) cookie = requests.utils.dict_from_cookiejar(response.cookies) print(cookie) cookie是一个字典: {'ucloud_zz': '1'} (2)requests处理cookie请求 cookie和session的区别: cookie数据存放在客户的浏览器上,session数据放在服务器上 cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗 session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器的性能 单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie 爬虫中为什么要使用cookie: 带上cookie的好处:①能够访问登录页面。②正常的浏览器在请求服务器的时候肯定会带上cookie(第一次请求除外),所以对方服务器有可能会通过是否携带cookie来判断我们是否是一个爬虫,对应的能够起到一定的反爬作用。 带上cookie的坏处:①一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫。②一般使用多账号解决。 requests进行携带cookie登录: 1.cookie字符串放在headers中: headers = { 'User-Agent': 'xxxxx', 'Cookie': 'xxxxx' } 2.把cookie字典交给requests请求方法的cookies: cookies = {‘cookie的name’:‘cookie的value} 使用方法: requests.get(url, headers, cookies=cookie_dict) (3)requests处理cookie请求之session requests提供了session类,用来实现客户端和服务的的会话保持! 会话(状态)保持:保存cookie实现和服务端的长连接 使用方法:session = requests.session()response = session.get(url, headers) session在请求一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次在使用session请求对方的服务器的时候,会带上前一次的cookie! 实战:人人网! import requests # 1.实例化session session = requests.Session() # 2. 使用session发送post请求,对方服务器会把cookie设置在session中 headers = {"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Chrome/4.0.222.3 "} post_url = "http://www.renren.com/PLogin.do" post_data = {"email":"自己的账号","password":"自己的密码"} session.post(post_url,data=post_data,headers=headers) # 3.请求个人主页,会带上之前的cookie,能够请求成功 profile_url = "http://www.renren.com/自己进自己主页会有的/profile" response = session.get(profile_url,headers=headers) with open("renren.html", "w", encoding="utf-8") as f: f.write(response.content.decode()) (4)requests模拟登陆的三种方法 1.session: 实例化对象 session.get(url) #cookie保存在session中 session.get(url) #带上保存在session中cookie 2.cookie方法在headers中 3.cookie传递给cookies参数: cookie = {"cookie 的name的值":"cookie 的value对应的值"} requests处理ssl证书: ssl证书不安全导致爬虫程序报错,返回ssl.CertificateError(证书错误)解决办法:response=requests.get(url, verify = False)verify = False 代表不在验证证书,默认是True验证 requests与超时参数(检测IP代理池): response=requests.get(url, timeout=3)timeout=3,代表保证在3秒钟内返回响应,否则报错 (5)retrying模块(刷新)与超时参数timeout 1.使用retrying模块提供的retry方法 2.通过装饰器的方式,让被装饰的函数反复执行 3.retry中可以传入参数 stop_max_attempt_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行 import requests from retrying import retry headers = {"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Chrome/4.0.222.3 "} @retry(stop_max_attempt_number=3) # stop_max_attempt_number=3最大执行3次,还不成功就报错 def _parse_url(url): # 前面加_代表此函数,其他地方不可调用 print("*"*100) response = requests.get(url, headers=headers, timeout=3) # timeout=3超时参数,3s内 assert response.status_code == 200 # assert断言,此处断言状态码是200,不是则报错 return response.content.decode() def parse_url(url): try: html_str = _parse_url(url) except Exception as e: print(e) html_str = None return html_str if __name__ == '__main__': # url = "www.baidu.com" 这样是会报错的! url = "http://www.baidu.com" print(parse_url(url)) 无法爬取到的情况:url = “www.baidu.com”! 正确爬取到的情况:url = “http://www.baidu.com”! 7.多线程爬虫 (1)多线程爬虫 思路解析: 在python3中,主线程主进程结束,子线程,子进程不会结束 把子线程设置为守护线程,即主线程结束,子线程结束 t1 = threading.Thread(targe=func, args=(,)) t1.setDaemon(True) t1.start() # 线程启动 (2)队列模块的使用(将线程放入队列中实现) from queue import Queue q = Queue(masize=100) item = {} # 不等待,直接放(存),队列满的时候会报错 q.put_nowait(item) # 放入数据,队列满的时候会等待 q.put(item) # 不等待,直接取,队列空的时候会报错 q.get_nowait() # 取出数据,队列空的时候会等待 q.get() # 获取队列中现存数据的个数 q.qsize() # 队列中维持了一个计数,计数不为0时候,让主线程阻塞等待,队列计数为0的时候才会继续往后面执行 q.join() q.task_done() 和get()方法配合,队列计数-1 q.put() 队列计数+1

优秀的个人博客,低调大师

Python爬虫入门教程 45-100 Charles抓取兔儿故事-下载小猪佩奇故事-手机APP爬虫部分

1. Charles抓取兔儿故事背景介绍 之前已经安装了Charles,接下来我将用两篇博客简单写一下关于Charles的使用,今天抓取一下兔儿故事里面关于小猪佩奇的故事。爬虫编写起来核心的重点是分析到链接,只要把链接分析到,剩下的就好办了。 2. 待爬取APP链接分析 夜神模拟器安装APP完毕,之后打开相应的软件,进去到小猪佩奇的分类清单,注意Charles,在里面尽量的去找到下图的链接,说白了就是在APP翻来翻去,看Charles的变化。 在分析中得到如下链接 http://api.tuer123.com/app/android/v1.4/category/detail.html?sort=187&startKey=&x_api_appid=VcDRKTFwD4riHfUQ&x_api_nonce=a502c9a

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册