文章目录

  • 材料准备
  • 一、统计广告TopN
    • 1.1统计每⼀个省份点击TOP3的⼴告ID
    • 1.2统计每一个省份每一个小时的TOP3广告ID
  • 二、基站停留时间TopN
  • 三、ip地址统计

材料准备

新建一个object文件存放所有案例文件的路径对象

object ExampleConstants {// 广告统计案例的文件路径val PATH_ADS: String = "...\\案例数据\\统计广告ID\\ad.log"// 基站停留案例的父级路径val PATH_LAC: String = "...\\案例数据\\基站停留时间TopN"val PATH_LAC_INFO: String = "...\\案例数据\\基站停留时间TopN\\lac_info"val PATH_LAC_LOG: String = "...\\案例数据\\基站停留时间TopN\\*.log"// ip地址统计案例的文件路径val PATH_IP_LOG: String = "...\\案例数据\\IP地址统计\\http.log"val PATH_IP_IP: String = "...\\案例数据\\IP地址统计\\ip.txt"
}

一、统计广告TopN

数据格式:
timestamp    province    city    userid    adid
时间点            省份          城市    用户        广告1601289641925  6   5   74  4
1601289650719   5   5   90  4
1601289667128   4   1   19  10
1601289655299   1   6   74  2
1601289637363   7   8   59  9
1601289656550   3   1   74  1
1601289657010   4   7   43  1
1601289664045   5   8   53  5用户id范围 0-99
省份,城市,id范围:0-9
adid范围:0-19

1.1统计每⼀个省份点击TOP3的⼴告ID

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}object _01_Ads {// 1、 统计每一个省份点击TOP3的广告ID// timestamp    province    city    userid    adid// 1601289641925    6   5   74  4// 1827361827638    6   5   74  4// 需求1:统计每⼀个省份点击TOP3的⼴告IDval sc: SparkContext = new SparkContext(new SparkConf().setMaster("local").setAppName("Ads"))def main(args: Array[String]): Unit = {// 1. 根据文件,创建RDDval rdd: RDD[String] = sc.textFile(ExampleConstants.PATH_ADS)// 2. 过滤掉每一行中不用的数据,只保留省份和广告ID即可//    使用map进行映射,将每一行的信息字符串,映射成只有省份和广告的数据,用元组表示val rdd1: RDD[((String, String), Int)] = rdd.map(line => {val parts: Array[String] = line.split("[ \t]+")((parts(1), parts(4)), 1)})// 3. 对相同的省份,相同的广告进行累加,得到总的次数val rdd2: RDD[((String, String), Int)] = rdd1.reduceByKey(_ + _)// 4. 对RDD中的数据,进行重新的组合,将省份单独列出来作为键,将广告ID和次数绑定在一起作为值val rdd3: RDD[(String, (String, Int))] = rdd2.map(t => (t._1._1, (t._1._2, t._2)))// 5. 将同一个省份的所有的广告聚合到一起val rdd4: RDD[(String, Iterable[(String, Int)])] = rdd3.groupByKey(1)rdd4.foreach(println)// 6. 将每一个省份的额所有的广告,按照出现次数降序,取Top3val resRDD: RDD[(String, List[(String, Int)])] = rdd4.mapValues(it => it.toList.sortWith(_._2 > _._2).take(3))resRDD.foreach(println)}
}

1.2统计每一个省份每一个小时的TOP3广告ID

import java.util.{Calendar, Date}import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}object _02_Ads {// 2、 统计每一个省份每一个小时的TOP3广告ID// timestamp    province    city    userid    adid// 1601289641925 6   5   74  4// 1827361827638    6   5   74  4def main(args: Array[String]): Unit = {val sc: SparkContext = new SparkContext(new SparkConf().setMaster("local").setAppName("Ads"))// 读取文件的数据val rdd: RDD[String] = sc.textFile(ExampleConstants.PATH_ADS)// 映射元素,带上时间的映射val rdd2: RDD[((String, String, String), Int)] = rdd.map(line => {val parts: Array[String] = line.split("[ \t]+")((parts(1), getHour(parts(0)), parts(4)), 1)})// 将同一个省份、同一个小时的同一个广告数量累加到一起val rdd3: RDD[((String, String, String), Int)] = rdd2.reduceByKey(_ + _)// 统计一个省份,一个小时内的所有的广告val rdd4: RDD[((String, String), Iterable[(String, Int)])] = rdd3.map(t => ((t._1._1, t._1._2), (t._1._3, t._2))).groupByKey()// 求top3val res: RDD[((String, String), List[(String, Int)])] = rdd4.mapValues(it => it.toList.sortWith(_._2 > _._2).take(3))res.foreach(println)}/*** 通过一个字符串时间戳,获取到一个时间(年/月/日/时)* @param timestamp 时间戳字符串,类似于 1601289641925* @return 由年月日时组成的时间格式*/def getHour(timestamp: String): String = {val calendar: Calendar = Calendar.getInstance()calendar.setTimeInMillis(timestamp.toLong)f"${calendar.get(Calendar.YEAR)}/${calendar.get(Calendar.MONTH) + 1}%02d/${calendar.get(Calendar.DAY_OF_MONTH)}%02d/${calendar.get(Calendar.HOUR_OF_DAY)}%02d/${calendar.get(Calendar.MINUTE)}%02d"}//日期函数也可以使用SimpleDateFormatdef timeTransform(time:String): String ={
//        val sdf: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")val sdf: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH")val res: String = sdf.format(new Date(time.toLong))res}

二、基站停留时间TopN

根据用户产生日志的信息(*.log),统计在哪个基站停留时间最长文件组成: 手机号,时间戳,基站ID,连接状态(1连接,0断开)lac_info.txt文件中存储基站信息
文件组成:基站ID,经度,纬度思路:
1.获取⽤户产⽣的⽇志信息并切分
2.⽤户在基站停留的总时⻓
3.获取基站的基础信息
4.把经纬度的信息join到⽤户数据中
5.求出⽤户在某些基站停留的时间top2a.log
18688888888,20160327082400,16030401EAFB68F1E3CDF819735E1C66,1
18611132889,20160327082500,16030401EAFB68F1E3CDF819735E1C66,1
18688888888,20160327170000,16030401EAFB68F1E3CDF819735E1C66,0
18611132889,20160327180000,16030401EAFB68F1E3CDF819735E1C66,0b.log
18611132889,20160327075000,9F36407EAD0629FC166F14DDE7970F68,1
18688888888,20160327075100,9F36407EAD0629FC166F14DDE7970F68,1
18611132889,20160327081000,9F36407EAD0629FC166F14DDE7970F68,0
18688888888,20160327081300,9F36407EAD0629FC166F14DDE7970F68,0
18688888888,20160327175000,9F36407EAD0629FC166F14DDE7970F68,1
18611132889,20160327182000,9F36407EAD0629FC166F14DDE7970F68,1
18688888888,20160327220000,9F36407EAD0629FC166F14DDE7970F68,0
18611132889,20160327230000,9F36407EAD0629FC166F14DDE7970F68,0c.log
18611132889,20160327081100,CC0710CC94ECC657A8561DE549D940E0,1
18688888888,20160327081200,CC0710CC94ECC657A8561DE549D940E0,1
18688888888,20160327081900,CC0710CC94ECC657A8561DE549D940E0,0
18611132889,20160327082000,CC0710CC94ECC657A8561DE549D940E0,0
18688888888,20160327171000,CC0710CC94ECC657A8561DE549D940E0,1
18688888888,20160327171600,CC0710CC94ECC657A8561DE549D940E0,0
18611132889,20160327180500,CC0710CC94ECC657A8561DE549D940E0,1
18611132889,20160327181500,CC0710CC94ECC657A8561DE549D940E0,0loc.info
9F36407EAD0629FC166F14DDE7970F68,116.304864,40.050645,6
CC0710CC94ECC657A8561DE549D940E0,116.303955,40.041935,6
16030401EAFB68F1E3CDF819735E1C66,116.296302,40.032296,6
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}object _03_Lac {def main(args: Array[String]): Unit = {// 1. 实例化SparkContextval sc: SparkContext = new SparkContext(new SparkConf().setMaster("local").setAppName("lac"))// 2. 读取用户信息文件val rdd: RDD[String] = sc.textFile(ExampleConstants.PATH_LAC_LOG)// 3. 将信息切分,得到对我们有用的数据val rdd1: RDD[((String, String), Long)] = rdd.map(line => {val parts: Array[String] = line.split(",")val phone: String = parts(0) // 手机号码val time: Long = parts(1).toLong // 事件产生的时间val lacId: String = parts(2) // 基站IDval eventLog: String = parts(3) // 事件IDval duration: Long = if (eventLog.equals("1")) -time else time((phone, lacId), duration)})// 4. 计算每一个用户在每一个基站停留的总时长val rdd2: RDD[((String, String), Long)] = rdd1.reduceByKey(_ + _)// 5. 转换数据格式,将基站ID作为键,为了和基站信息RDD方便join连接val rdd3: RDD[(String, (String, Long))] = rdd2.map(t => (t._1._2, (t._1._1, t._2)))// 6. 读取基站信息val lacInfoRDD: RDD[String] = sc.textFile(ExampleConstants.PATH_LAC_INFO)// 7. 切割字符串,得到基站的每一个信息val lacInfoRDD1: RDD[(String, (String, String))] = lacInfoRDD.map(line => {val infos: Array[String] = line.split(",")val lacID: String = infos(0) // 基站IDval x: String = infos(1) // 经度val y: String = infos(2) // 纬度(lacID, (x, y))})// 8. 连接用户的信息和基站的信息val rdd4: RDD[(String, ((String, Long), (String, String)))] = rdd3.join(lacInfoRDD1)// 9. 进行数据转换,将手机号码,将基站的信息作为值 (手机号码, 停留时间, (基站ID, (经度, 纬度)))val rdd5: RDD[(String, Long, (String, (String, String)))] = rdd4.map(t => (t._2._1._1, t._2._1._2, (t._1, t._2._2)))// 10.  按照手机号码分组val rdd6: RDD[(String, Iterable[(String, Long, (String, (String, String)))])] = rdd5.groupBy(_._1)// 11. 按照停留时长做排序,取top2val rdd7: RDD[(String, List[(String, Long, (String, (String, String)))])] = rdd6.mapValues(t => t.toList.sortWith(_._2 > _._2).take(2))// 12. 去除value中多余的手机号码和"停留时长"val res: RDD[(String, List[(String, String, String)])] = rdd7.mapValues(list => list.map(t => (t._3._1, t._3._2._1, t._3._2._2)))res.foreach(println)//保存到文件中res.saveAsTextFile("")}
}

三、ip地址统计

给出ip地址统计优化方法

日志信息
20090121000132095572000|125.213.100.123|show.51.com|/shoplist.php?phpfile=shoplist2.php&style=1&sex=137|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0(Compatible Mozilla/4.0(Compatible-EmbeddedWB 14.59 http://bsalsa.com/ EmbeddedWB- 14.59  from: http://bsalsa.com/ )|http://show.51.com/main.php|
20090121000132124542000|117.101.215.133|www.jiayuan.com|/19245971|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TencentTraveler 4.0)|http://photo.jiayuan.com/index.php?uidhash=d1c3b69e9b8355a5204474c749fb76ef|__tkist=0; myloc=50%7C5008; myage=2009; PROFILE=14469674%3A%E8%8B%A6%E6%B6%A9%E5%92%96%E5%95%A1%3Am%3Aphotos2.love21cn.com%2F45%2F1b%2F388111afac8195cc5d91ea286cdd%3A1%3A%3Ahttp%3A%2F%2Fimages.love21cn.com%2Fw4%2Fglobal%2Fi%2Fhykj_m.jpg; last_login_time=1232454068; SESSION_HASH=8176b100a84c9a095315f916d7fcbcf10021e3af; RAW_HASH=008a1bc48ff9ebafa3d5b4815edd04e9e7978050; COMMON_HASH=45388111afac8195cc5d91ea286cdd1b; pop_1232093956=1232468896968; pop_time=1232466715734; pop_1232245908=1232469069390; pop_1219903726=1232477601937; LOVESESSID=98b54794575bf547ea4b55e07efa2e9e; main_search:14469674=%7C%7C%7C00; registeruid=14469674; REG_URL_COOKIE=http%3A%2F%2Fphoto.jiayuan.com%2Fshowphoto.php%3Fuid_hash%3D0319bc5e33ba35755c30a9d88aaf46dc%26total%3D6%26p%3D5; click_count=0%2C3363619
20090121000132406516000|117.101.222.68|gg.xiaonei.com|/view.jsp?p=389|Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; CIBA)|http://home.xiaonei.com/Home.do?id=229670724|_r01_=1; __utma=204579609.31669176.1231940225.1232462740.1232467011.145; __utmz=204579609.1231940225.1.1.utmccn=(direct)
20090121000132581311000|115.120.36.118|tj.tt98.com|/tj.htm|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TheWorld)|http://www.tt98.com/|
20090121000132864647000|123.197.64.247|cul.sohu.com|/20071227/n254338813_22.shtml|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TheWorld)|http://cul.sohu.com/20071227/n254338813_22.shtml|ArticleTab=visit:1; IPLOC=unknown; SUV=0901080709152121; vjuids=832dd37a1.11ebbc5d590.0.b20f858f14e918; club_chat_ircnick=JaabvxC4aaacQ; spanel=%7B%22u%22%3A%22%22%7D; vjlast=1232467312,1232467312,30
20090121000133296729000|222.55.57.176|down.chinaz.com|/|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; iCafeMedia; TencentTraveler 4.0)||cnzz_a33219=0; vw33219=%3A18167791%3A; sin33219=http%3A//www.itxls.com/wz/wyfx/it.html; rtime=0; ltime=1232464387281; cnzz_eid=6264952-1232464379-http%3A//www.itxls.com/wz/wyfx/it.html
20090121000133331104000|123.197.66.93|www.pkwutai.cn|/down/downLoad-id-45383.html|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7)|http://www.baidu.com/s?tn=b1ank_pg&ie=gb2312&bs=%C3%C0%C6%BC%B7%FE%D7%B0%B9%DC%C0%ED%C8%ED%BC%FE&sr=&z=&cl=3&f=8&wd=%C6%C6%BD%E2%C3%C0%C6%BC%B7%FE%D7%B0%B9%DC%C0%ED%C8%ED%BC%FE&ct=0|ip地址信息(ip归属地)
1.0.1.0|1.0.3.255|16777472|16778239|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.0.8.0|1.0.15.255|16779264|16781311|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.0.32.0|1.0.63.255|16785408|16793599|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.1.0.0|1.1.0.255|16842752|16843007|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.1.2.0|1.1.7.255|16843264|16844799|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.1.8.0|1.1.63.255|16844800|16859135|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.2.0.0|1.2.1.255|16908288|16908799|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.2.2.0|1.2.2.255|16908800|16909055|亚洲|中国|北京|北京|海淀|北龙中网|110108|China|CN|116.29812|39.95931
1.2.4.0|1.2.4.255|16909312|16909567|亚洲|中国|北京|北京||中国互联网信息中心|110100|China|CN|116.405285|39.904989
1.2.5.0|1.2.7.255|16909568|16910335|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.2.8.0|1.2.8.255|16910336|16910591|亚洲|中国|北京|北京||中国互联网信息中心|110100|China|CN|116.405285|39.904989
1.2.9.0|1.2.127.255|16910592|16941055|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.3.0.0|1.3.255.255|16973824|17039359|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.4.1.0|1.4.3.255|17039616|17040383|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.4.4.0|1.4.4.255|17040384|17040639|亚洲|中国|北京|北京|海淀|北龙中网|110108|China|CN|116.29812|39.95931
1.4.5.0|1.4.7.255|17040640|17041407|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.4.8.0|1.4.127.255|17041408|17072127|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.8.0.0|1.8.255.255|17301504|17367039|亚洲|中国|北京|北京|海淀|北龙中网|110108|China|CN|116.29812|39.95931统计每一个省份产生的IP访问数量,结果降序排序

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}/*** 需求:  省份, 次数    省份, 市, 次数*/
object _04_IP {def main(args: Array[String]): Unit = {val sc: SparkContext = new SparkContext(new SparkConf().setMaster("local").setAppName("ip"))// 1. 读取ip.txt,解析出每一个城市的地址段implicit val provinces: Array[(Long, Long, String)] = sc.textFile(ExampleConstants.PATH_IP_IP).map(line => {val infos: Array[String] = line.split("\\|")val start: Long = infos(2).toLong // 起始IP十进制表示形式val end: Long = infos(3).toLong // 结束IP十进制表示形式val province: String = infos(6) // 省份信息(start, end, province)}).collect()// 2. 读取http.log文件,截取出IP信息,带入到第一步的集合中,查出省份val rdd: RDD[(String, Int)] = sc.textFile(ExampleConstants.PATH_IP_LOG).map(line => {val infos: Array[String] = line.split("\\|")// 2.1. 提取出IP地址val ipStr: String = infos(1)// 2.2. 将IP地址转成十进制的数字,用来比较范围val ipNumber: Long = ipStr2Num(ipStr)// 2.3. 将ipNumber, 带入到所有的IP地址的集合中,查询属于哪一个省份的val province: String = queryIP(ipNumber)(province, 1)})// 3. 将相同的省份聚合,结果降序排序val res: RDD[(String, Int)] = rdd.reduceByKey(_ + _).sortBy(_._2, ascending = false)res.coalesce(1).saveAsTextFile("C:\\Users\\luds\\Desktop\\output")}/*** 将一个ip地址字符串,转成十进制的数字* @param ipStr ip地址字符串* @return 转成的十进制的结果*/def ipStr2Num(ipStr: String): Long = {// 1. 拆出每一个部分val ips: Array[String] = ipStr.split("[.]")// 2. 定义变量,计算最终的结果var result: Long = 0L// 3. 计算ips.foreach(n => {result = n.toLong | result << 8L})result}def queryIP(ipNumber: Long)(implicit provinces: Array[(Long, Long, String)]): String = {// 使用二分查找法,查询ipNumber属于哪一个城市var min: Int = 0var max: Int = provinces.length - 1while (min <= max) {// 计算中间下标val middle: Int = (min + max) / 2// 进行范围检查val middleElement: (Long, Long, String) = provinces(middle)if (ipNumber >= middleElement._1 && ipNumber <= middleElement._2) {// 说明找到了return middleElement._3} else if (ipNumber < middleElement._1) {max = middle - 1} else {min = middle + 1}}""}
}

【大数据开发】SparkCore——统计广告topN、基站停留时间topN、ip地址统计练习相关推荐

  1. 大数据开发和java开发到底有什么不同?

    2019-04-02 18:30:46 最近发现有些同学并不太了解大数据开发工程师这个职位,所以想简单介绍一下什么是大数据开发工程师,当前互联网公司的数据开发到底是什么样子的?和一般的Java或者PH ...

  2. 大数据开发和java开发有什么不同?

    最近发现有些同学并不太了解大数据开发工程师这个职位,所以想简单介绍一下什么是大数据开发工程师,当前互联网公司的数据开发到底是什么样子的?和一般的Java或者PHP工程师在工作上有什么区别? 什么不是大 ...

  3. Java开发工程师与大数据开发工程师有何区别?

    乐字节教育是集线上教育与线下培训于一体的全栈式教育机构,致力于研发高端IT技术,培养高端IT人才,让更多的人接受更好的教育是乐字节的教学理念. 最近发现有些同学并不太了解大数据开发工程师这个职位,所以 ...

  4. 大数据前景如何?大数据开发工程师是什么?

    最近发现有些同学并不太了解大数据开发工程师这个职位,所以千锋想简单介绍一下什么是大数据开发工程师,当前互联网公司的数据开发到底是什么样子的?和一般的Java或者PHP工程师在工作上有什么区别? 首先入 ...

  5. 【大数据开发】SparkCore——利用广播变量优化ip地址统计、Spark2.x自定义累加器

    文章目录 一.Broadcast广播变量 1.1 广播变量的逻辑过程 1.2 [优化ip地址统计](https://blog.csdn.net/weixin_37090394/article/deta ...

  6. 百万奖金!交通事件、医学病理、广告检测,江苏大数据开发与应用大赛报名...

    大家好,初次见面,这里是SEED2020首届江苏大数据开发与应用大赛! 01 大赛背景 为进一步推动政府治理和公共服务能力现代化,激发大数据技术在智慧城市建设中的创新应用,江苏省工业和信息化厅与无锡市 ...

  7. 如何自学大数据开发?

    大数据技术怎么自学?大数据开发如何自学? 我们在学习大数据开发前需要先找到适合自己的方式方法,首先需要审视一下自身的情况,是否是以兴趣为出发点,对大数据是不是自己是真的感兴趣吗,目前对大数据的了解有多 ...

  8. java和大数据开发该选择哪个好就业?

    java开发和大数据开发无疑都是当前很热门的语言,很多小伙伴在选择方向的时候也是难以取舍~ 其实无论选择哪个语言作为工作的语言,都是要看你个人的兴趣点和未来想发展的方向的~下面给你列举下两个岗位的发展 ...

  9. Java后端开发工程师是否该转大数据开发?

    背景 看到一些java开发工程师,对java后端薪酬太悲观了.认为换去大数据领域就会高工资.觉得java后端没有前途.我从事java后端开发,对大数据领域工作有些了解,但不深入.本文描述一下我对jav ...

最新文章

  1. Makefile中的分析(一)
  2. vscode如何彻底卸载
  3. android activity 渐变,关于Android的径向渐变高级编程的实现
  4. 关于 underscore 中模板引擎的应用示例
  5. 开放计算架构:蚂蚁金服是如何用一套架构容纳所有计算的?
  6. Linux笔记-Linux中的TracerPid
  7. Android mainfests手记
  8. python 进位_Python中常见的数制转换的说明
  9. SPSS图文教程:两个率的比较(卡方检验)及Fisher精确检验
  10. 光盘出租系统mysql_数据库课程设计--碟片出租系统
  11. 学计算机需要什么基础
  12. python实现股票历史数据可视化分析
  13. cad lisp 二次抛物线_cad画二次抛物线
  14. 戒浮戒躁!一个“假程序员”的心里话
  15. 再探矩阵求逆引理 : Woodbury恒等式的证明
  16. vue关于router.replace历史路由问题记录
  17. android 模拟器监听短信,android模拟器用命令和DDMS模拟来电和短信(示例代码)
  18. 推荐视频:浙大郑强教授演讲《中国强大的真正希望》
  19. SpringBoot整合knif4j Api文档
  20. 网络战役刚打响 下波“勒索”更难防

热门文章

  1. 大棚养殖茄子如何“避坑”?资产监控技术提出保障!
  2. 【福大/计院】转专业
  3. mxd2 计算机内存不足,错误:无法将图元文件映射到内存中。 内存不足
  4. Axure教程 axure新手入门基础(1)
  5. CHAPTER 2 目录及文件
  6. 去掉连接图片的虚线框
  7. 【降价提醒】,您关注的商品已降价!
  8. html自动移动滚动条,css如何实现div随滚动条移动?
  9. 香港中文大学9(深圳)医学院李丛磊组招收博后/科研助理/博士生
  10. 【VOLTE】VOLTE的注册和去注册过程