精华内容
下载资源
问答
  • 在实际开发中,我们经常遇到与嵌入式进行通信的情况,而由于一些嵌入式设备的处理能力,往往以二进制的数据流的形式传输数据,在此将这些常见的转换做一总结。注意:默认传输时使用小端模式将字节流转换为int...

    在实际开发中,我们经常遇到与嵌入式进行通信的情况,而由于一些嵌入式设备的处理能力较差,往往以二进制的数据流的形式传输数据,在此将这些常见的转换做一总结。

    注意:默认传输时使用小端模式

    将字节流转换为int类型数据

    public static int getInt(byte[] bytes) {

    return (0xff & bytes[0]) | (0xff00 & (bytes[1] << 8)) | (0xff0000 & (bytes[2] << 16))

    | (0xff000000 & (bytes[3] << 24));

    }

    将字节流转换为long类型数据

    public static long getLong(byte[] bytes) {

    return ((0xffL & (long) bytes[0]) | (0xff00L & ((long) bytes[1] << 8)) | (0xff0000L & ((long) bytes[2] << 16))

    | (0xff000000L & ((long) bytes[3] << 24)) | (0xff00000000L & ((long) bytes[4] << 32))

    | (0xff0000000000L & ((long) bytes[5] << 40)) | (0xff000000000000L & ((long) bytes[6] << 48))

    | (0xff00000000000000L & ((long) bytes[7] << 56)));

    }

    将字节流转换为float类型数据

    public static float getFloat(byte[] bytes){

    int temp=getInt(bytes);

    return Float.intBitsToFloat(temp);

    }

    将字节流转换为double类型数据

    public static double getDouble(byte[] bytes){

    long temp=getLong(bytes);

    return Double.longBitsToDouble(temp);

    }

    将int类型数据转换为字节流

    public static byte[] getByteFromInt(int data){

    byte[] temp=new byte[4];

    temp[0]=(byte)(0xFF&(data));

    temp[1]=(byte)(0xFF&(data>>8));

    temp[2]=(byte)(0xFF&(data>>16));

    temp[3]=(byte)(0xFF&(data>>24));

    return temp;

    }

    将long类型数据转换为字节流

    public static byte[] getByteFromLong(long data){

    byte[] temp=new byte[8];

    temp[0]=(byte)(0xFF&(data));

    temp[1]=(byte)(0xFF&(data>>8));

    temp[2]=(byte)(0xFF&(data>>16));

    temp[3]=(byte)(0xFF&(data>>24));

    temp[4]=(byte)(0xFF&(data>>32));

    temp[5]=(byte)(0xFF&(data>>40));

    temp[6]=(byte)(0xFF&(data>>48));

    temp[7]=(byte)(0xFF&(data>>56));

    return temp;

    }

    将float类型数据转换为字节流

    public static byte[] getByteFromFloat(float data){

    byte[] temp=new byte[4];

    int tempInt=Float.floatToIntBits(data);

    temp[0]=(byte)(0xFF&(tempInt));

    temp[1]=(byte)(0xFF&(tempInt>>8));

    temp[2]=(byte)(0xFF&(tempInt>>16));

    temp[3]=(byte)(0xFF&(tempInt>>24));

    return temp;

    }

    将double类型数据转换为字节流

    public static byte[] getByteFromDouble(double data){

    byte[] temp=new byte[8];

    long tempLong=Double.doubleToLongBits(data);

    temp[0]=(byte)(0xFF&(tempLong));

    temp[1]=(byte)(0xFF&(tempLong>>8));

    temp[2]=(byte)(0xFF&(tempLong>>16));

    temp[3]=(byte)(0xFF&(tempLong>>24));

    temp[4]=(byte)(0xFF&(tempLong>>32));

    temp[5]=(byte)(0xFF&(tempLong>>40));

    temp[6]=(byte)(0xFF&(tempLong>>48));

    temp[7]=(byte)(0xFF&(tempLong>>56));

    return temp;

    }

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • Spark作为当前企业覆盖度最广大数据平台,大数据处理能力基本上是每一个算法工程师or数据分析师的必备技能。所以即使不做大数据开发的读者,也很有必要掌握其基本构造以及使用方法。在使用Spark的API接口时,一般...

    Spark作为当前企业覆盖度最广大数据平台,大数据处理能力基本上是每一个算法工程师or数据分析师的必备技能。所以即使不做大数据开发的读者,也很有必要掌握其基本构造以及使用方法。

    在使用Spark的API接口时,一般不会限定使用语言,公司内使用Java/Scala/Python语言调用Spark dataframe,在性能上是没有显著差异的。只有在使用底层RDD形式处理数据时,python的性能较差。当然,目前企业中的数据处理的主要方法是dataframe或者SQL语言,所以可以不用担心使用语言的效率问题。

    基本结构

    Spark可以分为1个driver(笔记本电脑或者集群网关机器上)和若干个executor(在各个节点上),通过SparkContext(简称sc)连接Spark集群、创建RDD、累加器(accumlator)、广播变量(broadcast variables),简单可以认为SparkContext是Spark程序的一个入口,类似于python中的import。

    Driver会把计算任务分成一系列小的task,然后送到executor执行。executor之间可以通信,在每个executor完成自己的task以后,所有的信息会被传回。

    10ca51784848189bc7341a7c5c1a5509.png

    在Spark里,所有的处理和计算任务都会被组织成一系列Resilient Distributed Dataset(弹性分布式数据集,简称RDD)上的transformations(转换) 和 actions(动作)。

    弹性分布式数据集

    RDD是一个包含诸多元素、被划分到不同节点上进行并行处理的数据集合,可以将RDD持久化到内存中,这样就可以有效地在并行操作中复用(在机器学习这种需要反复迭代的任务中非常有效)。在节点发生错误时RDD也可以自动恢复。

    RDD就像一个NumPy array或者一个Pandas Series,可以视作一个有序的item集合。只不过这些item太大了,并不能存在driver端的内存里,而是被分割成很多个partitions,每个partition的数据存在集群的executor的内存中。

    使用python调用非常简单:

    import pyspark
    from pyspark import SparkContext
    from pyspark import SparkConf
    #设定名字和master位置
    conf=SparkConf().setAppName("miniProject").setMaster("local[*]")
    #使用已经存在的SparkContext
    sc=SparkContext.getOrCreate(conf)
    #存放在当前环境中的list初始化为rdd,切分到不同的节点上
    rdd = sc.parallelize([1,2,3,4,5])
    #查看分区状况
    rdd.glom().collect()

    [[1], [2], [3], [4, 5]]

    在这个例子中,是一个4-core的CPU笔记本。Spark创建了4个executor,然后把数据分成4个块。

    第2种方式当然是直接把文本读到RDD了。你的每一行都会被当做一个item,不过需要注意的一点是,Spark一般默认你的路径是指向HDFS的,如果你要从本地读取文件的话,给一个file://开头的全局路径。

    import os
    cwd = os.getcwd()
    rdd = sc.textFile("file://" + cwd + "/names/yob1880.txt")
    #取出一个iterm
    rdd.first()

    u'Mary,F,7065'

    你甚至可以很粗暴地读入整个文件夹的所有文件。但是要特别注意,这种读法,RDD中的每个item实际上是一个形如 (文件名,文件所有内容) 的元组。咱们来试着读一读所有的文件。

    rdd = sc.wholeTextFiles("file://" + cwd + "/names")
    rdd.first()

    (u'file:/home/ds/notebooks/spark/names/yob1880.txt',
    u'Mary,F,7065rnAnna,F,2604rnEmma,F,2003rnElizabeth,F,1939rnMinnie,F,1746rnMargaret,F,1578rnIda,F,1472rnAlice,F,1414rnBertha,F,1320rn)

    RDD还可以通过其他的方式初始化,包括

    1. HDFS上的文件

    2. Hive中的数据库与表

    3. Spark SQL得到的结果

    transformation

    我们先给大家提一下RDD上最最常用到的transformation:

    • map() 对RDD的每一个item都执行同一个操作
    • flatMap() 对RDD中的item执行同一个操作以后得到一个list,然后以平铺的方式把这些list里所有的结果组成新的list
    • filter() 筛选出来满足条件的item
    • distinct() 对RDD中的item去重
    • sample() 从RDD中的item中采样一部分出来,有放回或者无放回
    • sortBy() 对RDD中的item进行排序

    如果你想看操作后的结果,可以用一个叫做collect()的action把所有的item转成一个Python list。

    numbersRDD = sc.parallelize(range(1,10+1))
    print(numbersRDD.collect())
    #map和dataframe中用法相同
    squaresRDD = numbersRDD.map(lambda x: x**2)  # Square every number
    print(squaresRDD.collect())
    
    filteredRDD = numbersRDD.filter(lambda x: x % 2 == 0)  # Only the evens
    print(filteredRDD.collect())

    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    [2, 4, 6, 8, 10]

    输入一个iterm,输出一个iterm.
    然后咱们看看flatMap()的平展功能:

    sentencesRDD = sc.parallelize(['Hello world', 'My name is Patrick'])
    wordsRDD = sentencesRDD.flatMap(lambda sentence: sentence.split(" "))
    print(wordsRDD.collect())
    print(wordsRDD.count())

    ['Hello', 'world', 'My', 'name', 'is', 'Patrick']
    6

    flatmap后的iterm中括号是被打开的,输入一个iterm,输出多个iterm.
    为了做一个小小的对应,咱们看看python里对应的操作大概是什么样的:

    l = ['Hello world', 'My name is Patrick']
    ll = []
    for sentence in l:
        ll = ll + sentence.split(" ")
    ll

    ['Hello', 'world', 'My', 'name', 'is', 'Patrick']
    6

    并且Transformation,可以一个接一个地串联,比如:

    # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    def doubleIfOdd(x):
        if x % 2 == 1:
            return 2 * x
        else:
            return x
    
    resultRDD = (numbersRDD           # In parentheses so we can write each
                 .map(doubleIfOdd)    # transformation in one line
                 .filter(lambda x: x > 6)
                 .distinct())
    
    resultRDD.collect()

    如果你手头上有2个RDD了,下面的这些操作能够帮你对他们以各种方式组合得到1个RDD:

    • rdd1.union(rdd2): 所有rdd1和rdd2中的item组合
    • rdd1.intersection(rdd2): rdd1 和 rdd2的交集
    • rdd1.substract(rdd2): 所有在rdd1中但不在rdd2中的item(差集)
    • rdd1.cartesian(rdd2): rdd1 和 rdd2中所有的元素笛卡尔乘积
    numbersRDD = sc.parallelize([1,2,3])
    moreNumbersRDD = sc.parallelize([2,3,4])
    numbersRDD.union(moreNumbersRDD).collect()

    [1, 2, 3, 2, 3, 4][1, 2, 3, 2, 3, 4]

    numbersRDD.intersection(moreNumbersRDD).collect()

    [2, 3]

    numbersRDD.subtract(moreNumbersRDD).collect()

    [1]

    numbersRDD.cartesian(moreNumbersRDD).collect()

    [(1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4)]

    特别注意:Spark的一个核心概念是惰性计算。当你把一个RDD转换成另一个的时候,这个转换不会立即生效执行。Spark会把它先记在心里,等到真的需要拿到转换结果的时候,才会重新组织你的transformations(因为可能有一连串的变换)。这样可以避免不必要的中间结果存储和通信。

    刚才提到了惰性计算,那么什么东西能让它真的执行转换与运算呢? 是的,就是我们马上提到的Actions,下面是常见的action,当他们出现的时候,表明我们需要执行刚才定义的transform了:

    • collect(): 计算所有的items并返回所有的结果到driver端,接着 collect()会以Python list的形式返回结果
    • first(): 和上面是类似的,不过只返回第1个item
    • take(n): 类似dataframe.head(),但是返回n个item
    • count(): 计算RDD中item的个数
    • top(n): 返回头n个items,按照自然结果排序
    • reduce(): 对RDD中的items做聚合

    我们之前已经看过 collect(), first() 和 count() 的例子了。咱们看看 reduce()如何使用。比如Spark里从1加到10你可以这么做。

    # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    rdd = sc.parallelize(range(1,10+1))
    rdd.reduce(lambda x, y: x + y)

    55

    如果你想了解一下reduce的细节的话,其实可能会先在每个分区(partition)里完成reduce操作,然后再全局地进行reduce。这个过程你可以从如下的代码大致理解。

    def f(x,y):
        return x + y
    l = [1,2,3,4]
    f(f(f(l[0],l[1]), l[2]), l[3])

    10

    咱们刚才已经见识到了Spark中最常见的transform和action,但是有时候我们会遇到更复杂的结构,比如非常非常经典的是以元组形式组织的k-v对(key, value)我们把它叫做pair RDDs,而Sark中针对这种item结构的数据,定义了一些transform和action:

    • reduceByKey(): 对所有有着相同key的items执行reduce操作
    • groupByKey(): 返回类似(key, listOfValues)元组的RDD,后面的value List 是同一个key下面的
    • sortByKey(): 按照key排序
    • countByKey(): 按照key去对item个数进行统计
    • collectAsMap(): 和collect有些类似,但是返回的是k-v的字典

    使用spark中的rdd完成hadoop中的词频统计

    rdd = sc.parallelize(["Hello hello", "Hello New York", "York says hello"])
    resultRDD = (
        rdd
        .flatMap(lambda sentence: sentence.split(" "))  # 分词
        .map(lambda word: word.lower())                 # 小写
        .map(lambda word: (word, 1))                    # 统计词频
        .reduceByKey(lambda x, y: x + y)                # 相同词词频相加(group by 词名)
    )
    resultRDD.collect()

    [('says', 1), ('new', 1), ('hello', 4), ('york', 2)]

    以上的展示结果很丑,所以我们将结果以k-v字典的形式返回(collectAsMap)

    result = resultRDD.collectAsMap()
    result

    {'hello': 4, 'new': 1, 'says': 1, 'york': 2}

    如果你想要出现频次最高的2个词,可以这么做:

    print(resultRDD
          .sortBy(keyfunc=lambda (word, count): count, ascending=False)
          .take(2))

    [('hello', 4), ('york', 2)]

    展开全文
  • 在使用关系型数据库的时候如果发生海量的用户请求对表进行读取,修改等等会导致关系型数据库的崩溃,而且读取速率低下应对高并发的情况处理能力不足,数据关系复杂,扩展性,不便于大规模集群,这时就有了非关系型...

    Redis 简介

    在使用关系型数据库的时候如果发生海量的用户请求对表进行读取,修改等等会导致关系型数据库的崩溃,而且读取速率低下应对高并发的情况处理能力不足,数据关系复杂,扩展性差,不便于大规模集群,这时就有了非关系型数据库
    非关系型数据库Nosql
    降低了磁盘的IO流次数,通过内存存储的方式
    去除了数据间的关系,越是简单越好,通过不存储数据关系只存储数据的形式
    可扩容,可伸缩 灵活的数据模型 大数据量下高性能
    其中最常用的就是Redis

    Redis特征

    1. 数据间没有必然的关联关系
    2. 内部采用单线程机制进行工作
    3. 高性能。官方提供测试数据,50个并发执行100000 个请求,读的速度是110000 次/s,写的速度是81000次/s。
    4. 多数据类型支持
      ◆ 字符串类型 string
      ◆ 列表类型 list
      ◆ 散列类型 hash
      ◆ 集合类型 set
      ◆ 有序集合类型 zset/sorted_set
    5. 支持持久化,可以进行数据灾难恢复

    下载和安装Redis

    直接在liunx中解压
    在这里插入图片描述
    创建conf和data目录用来存放配置文件和日志文件
    在conf中修改配置文件
    在这里插入图片描述
    这里吧端口改成了6380 IP地址更改成0.0.0.0方便后面访问日志文件存放在打他目录下文件名为logs-6380.log
    配置完成以后在src下启动
    通过配置文件启动
    在这里插入图片描述
    遇到报错,说是无法读取logs-6380.log
    权限不够,这里可以去更改配置文件权限,也可以把自己用户变成管理员进行操作
    在这里插入图片描述
    在更改完管理员用户后成功运行
    在这里插入图片描述
    然后可以查看是否存在6380的端口服务

    在这里插入图片描述
    端口正常运行就可以进入redis服务了
    在这里插入图片描述
    这就说明成功启动了。

    Redis的基础数据类型

    redis 数据存储格式

    • redis 自身是一个 Map,其中所有的数据都是采用 key : value 的形式存储
    • 数据类型指的是存储的数据的类型,也就是 value 部分的类型,key 部分永远都是字符串

    Redis 数据类型(5种常用)
    ⚫ string
    ⚫ hash
    ⚫ list
    ⚫ set
    ⚫ sorted_set/zset(应用性较低)

    String类型

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1. 数据操作不成功的反馈与数据正常操作之间的差异
    ◆ 表示运行结果是否成功
    ⚫ (integer) 0 → false 失败
    ⚫ (integer) 1 → true 成功
    ◆ 表示运行结果值
    ⚫ (integer) 3 → 3 3个
    ⚫ (integer) 1 → 1 1个
    2. 数据未获取到时,对应的数据为(nil),等同于null
    3. 数据最大存储量:512MB
    4. string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
    5. 按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错
    9223372036854775807(java中Long型数据最大值,Long.MAX_VALUE)
    6. redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响
    

    主要用于高频访问信息显示控制
    在这里插入图片描述

    - 在redis中为大V用户设定用户信息,以用户主键和属性值作为key,
      后台设定定时刷新策略即可
      eg: user:id:3506728370:fans → 12210947
      eg: user:id:3506728370:blogs → 6164
      eg: user:id:3506728370:focuses → 83
    -  也可以使用json格式保存数据
      eg: user:id:3506728370 → {“fans”:12210947“blogs”:6164“ focuses ”:83
    

    在这里插入图片描述

    hash类型

    如果是对对象进行一个存储用String就显得笨重这时候就可以通过hash结构来存储
    key -> field_01 -> value_01的形式来存储
    在这里插入图片描述
    关系hash的操作
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    hash类型数据的操作注意点

    1. hash类型中value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil)
    2. 每个 hash 可以存储 2^32 - 1 个键值对
    3. hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计
    的,切记不可滥用,更不可以将hash作为对象列表使用
    4. hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈
    

    应用场景
    销售手机充值卡的商家对移动、联通、电信的30元、50元、100元商品推出抢购活动,每种商品抢购上限1000张
    在这里插入图片描述

    • 以商家id作为key
    • 将参与抢购的商品id作为field
    • 将参与抢购的商品数量作为对应的value
    • 抢购时使用降值的方式控制产品数量

    List类型

    存储多个数据,并对数据进入存储空间的顺序进行区分
    一个存储空间保存多个数据,且通过数据可以体现进入顺序
    保存多个数据,底层使用双向链表存储结构实现
    在这里插入图片描述
    在这里插入图片描述
    list的操作
    在这里插入图片描述
    在这里插入图片描述
    list 类型数据操作注意事项

    1. list中保存的数据都是string类型的,数据总容量是有限的,最多2^32- 1元素 (4294967295)2. list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
    3. 获取全部数据操作结束索引设置为-1
    4. list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
    

    应用场景
    企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?
    在这里插入图片描述
    可以用list来解决

    • 依赖list的数据具有顺序的特征对信息进行管理
    • 使用队列模型解决多路信息汇总合并的问题
    • 使用栈模型解决最新消息的问题

    set 类型

    新的存储需求:存储大量的数据,在查询方面提供更高的效率
    需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询
    set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的
    在这里插入图片描述
    在这里插入图片描述
    set 类型数据的基本操作
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    set 类型数据操作的注意事项

    • set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份
    • set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间

    key常用指令

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    数据库的常用指令

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    java中用jedis操作redis

    jar包导入
    下载地址:https://mvnrepository.com/artifact/redis.clients/jedis
    基于maven

    <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
    </dependency>
    

    客户端的连接

    利用Jedis jedis = new Jedis(“IP地址”,端口号;
    来连接redis,通过调用jedis中的get/set方法可以对其进行操作

    package com.jedis;
    
    import redis.clients.jedis.Jedis;
    
    import java.util.Set;
    
    public class JedisTest {
        public static void main(String[] args) {
            //创建jedis对象 传入ip地址和端口号
            Jedis jedis = new Jedis("192.168.23.32",6380);
            //用set方法创建一个键值
            jedis.set("six","哔哩哔哩1");
            jedis.set("name","蔡徐坤1");
            jedis.set("123","苍老师");
            jedis.set("百度","知道");
    //        查询所有键值对
            Set<String> keys = jedis.keys("*");
    //        获取name键对应的值
            String name = jedis.get("name");
            //打印所有key和name的值
            System.out.println(keys+name);
    
        }
    }
    

    运行结果
    在这里插入图片描述
    示例
    在这里插入图片描述
    也可以通过连接池的方式访问
    JedisPool:Jedis提供的连接池技术
    poolConfig:连接池配置对象
    host:redis服务地址
    port:redis服务端口号

    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port) {
    this(poolConfig, host, port, 2000, (String)null, 0, (String)null);
    }
    

    封装连接参数
    jedis.properties

    redis.maxTotal=50
    redis.maxIdel=10
    redis.host=192.168.23.32
    redis.port=6380
    

    利用静态代码块初始化连接资源
    静态代码块初始化资源

    static{
    //读取配置文件 获得参数值
    ResourceBundle rb = ResourceBundle.getBundle("jedis");
    host = rb.getString("jedis.host");
    port = Integer.parseInt(rb.getString("jedis.port"));
    maxTotal = Integer.parseInt(rb.getString("jedis.maxTotal"));
    maxIdle = Integer.parseInt(rb.getString("jedis.maxIdle"));
    poolConfig = new JedisPoolConfig();
    poolConfig.setMaxTotal(maxTotal);
    poolConfig.setMaxIdle(maxIdle);
    jedisPool = new JedisPool(poolConfig,host,port);
    }
    

    获取连接
    对外访问接口,提供jedis连接对象,连接从连接池获取

    public static Jedis getJedis(){
    Jedis jedis = jedisPool.getResource();
    return jedis;
    }
    

    具体代码如下
    redis.properties配置文件中的代码

    redis.maxTotal=50
    redis.maxIdel=10
    redis.host=192.168.23.32
    redis.port=6380
    
    

    jedisUtils连接工具

    package com.Utils;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    import java.util.ResourceBundle;
    
    public class jedisUtils {
        private static String host;
        private static Integer port;
        private static Integer maxTotal;
        private static Integer maxIdle;
        private  static JedisPoolConfig poolConfig;
        private  static JedisPool jedisPool;
    
        static {
            //读取配置文件
            ResourceBundle rb = ResourceBundle.getBundle("redis");
            //读取配置文件中的地址和端口号
            host = rb.getString("redis.host");
            port = Integer.parseInt(rb.getString("redis.port"));
            //设置最大的连接池数量和初始的最大数量
            maxTotal = Integer.parseInt(rb.getString("redis.maxTotal"));
            maxIdle = Integer.parseInt(rb.getString("redis.maxIdel"));
            //对jedis连接池进行配置
            poolConfig = new JedisPoolConfig();
            poolConfig.setMaxTotal(maxTotal);
            poolConfig.setMaxIdle(maxIdle);
            //jedisPool连接池来管理jedis对象
            jedisPool = new JedisPool(poolConfig,host,port);
    
        }
    
    
        public static Jedis getjedis(){
                //调用jedispool中getResource返回给调用者一个连接对象
            Jedis jedis = jedisPool.getResource();
            return jedis;
        }
    }
    

    JedisTest测试类代码

    package com.jedis2;
    
    import com.Utils.jedisUtils;
    import redis.clients.jedis.Jedis;
    
    import java.util.Set;
    
    public class JedisTest {
        public static void main(String[] args) {
            //直接通过类名。方法名获取到连接池对象
            Jedis jedis = jedisUtils.getjedis();
            //直接调用keys查看所有的key
            Set<String> keys = jedis.keys("*");
        //遍历数组
            for (String key : keys) {
                System.out.println(key);
            }
    
        }
    }
    

    运行结果
    在这里插入图片描述
    获取到了刚才存进去的所有key值

    展开全文
  • 自动化测试或者性能测试过程中,经常遇到业务数据被加密等...为了减少代码编写时间和照顾部分代码能力的测试人员,我们可以把代码处理部分封装到JMeter HttpSampler中,减少代码处理时间,甚至无代码编写。一...

    自动化测试或者性能测试过程中,经常遇到业务数据被加密等需求,面对这样需求可以通过BeanShell 和Java Sampler等方式解决 。无论哪种方式均需多次代码编写。同时bean shell脚本语言不适用于性能测试,因为效率低资源占用高。

    为了减少代码编写时间和照顾部分代码能力较差的测试人员,我们可以把代码处理部分封装到JMeter HttpSampler中,减少代码处理时间,甚至无代码编写。

    一、JMeter源码追踪

    Http Sampler 实现方式有httpclient4 和Java(HttpURLConnection)两种方式,此处选择修改Java方式的http sampler,并选择修改POST请求类型。

    JMeter官网下载源码,并导入IDE工具,编译成功后,打开src/protocol/http/sampler目录

    cfde1166b46b

    http sampler

    1、首先阅读HTTPJavaImpl类中sampler()方法,定义了Java方式的HttpSampler。

    cfde1166b46b

    HTTPJavaImpl  sampler 方法

    2、postbody消息获取是通过sendPostData()方法。阅读代码526行定义请求消息内容。if(method.equals(HTTPConstants.POST)) {

    String postBody = sendPostData(conn);

    System.out.println("527====>"+postBody);

    res.setQueryString(postBody);

    cfde1166b46b

    postbody

    3、追踪代码sendPostData()方法

    cfde1166b46b

    sendPostData

    4、进一步追踪代码,postbody内容由PostWriter类的sendPostData()方法完成。

    cfde1166b46b

    PostWriter sendPostData()

    阅读sendPostData()代码,postbody请求内容由files、parmas两种方式完成,由于我们使用params,故定位到如下代码。二进制数据流formDataUrlEncoded为请求内容。

    cfde1166b46b

    formDataUrlEncoded 写入postbody

    4、继续追踪代码,探究formDataUrlEncoded二进制数据如何写入。数据竟然是在sendHeader方法内完成写入。

    cfde1166b46b

    sendHeader()

    由于我们使用params方式完成请求数入,继续追踪代码,找到关键信息。formDataUrlEncoded数据由sendhead方法的postbody传递得到。

    cfde1166b46b

    formDataUrlEncoded传递获得

    请求参数方式为params,继续追踪postbody内容赋值,在sendhead方法292行处找到最终代码。此处我们把请求内容修改,打印日志验证结论是否正确。

    cfde1166b46b

    getQueryString

    二、JMeter源码验证

    1、保存代码后,重新编译打包,然后运行。注意此处在JMeter源码调试模式完成。首先我们创建一个HTTP Java Sampler ,选择Java Client 方式。

    cfde1166b46b

    Java Client

    cfde1166b46b

    post请求并设置参数

    2、运行脚本,察看结果书,发现请求内容已经被二次处理,test2的值已经变成222211111111111111111,原因是因为上面代码中我们已经增加部分内容。postBody = sampler.getQueryString(contentEncoding);

    postBody=postBody+"11111111111111111";

    System.out.println("292====>"+postBody);

    cfde1166b46b

    结果

    三、扩展

    至此我们已经验证结果,也找到了代码修改关键点,我们可以根据自己需要完成扩展。扩展完成后重新编译打包,然后拷贝工程lib/ext中ApacheJMeter_http.jar 文件至JMeter工具的lib/ext目录覆盖即可。

    cfde1166b46b

    ApacheJMeter_http.jar

    展开全文
  • 核心Java程序设计技术

    2021-04-16 12:20:13
    它们包括基础技术、设计模式、并发技术、数据处理、网络通信、性能优化、代码测试以及高级技巧等多个方面。通过对这些书籍的比较,我认为《Core Java》是全面介绍Java技术的经典教材。它篇幅宏大,对Java标准版...
  • java 编程艺术

    2012-09-16 23:38:44
    本书是亚马逊网站上的五星级图书,相信读者能够通过研读本书大大提高自己的Java开发能力。本书代码示例易懂有趣,设计思想独特,定会使您受益匪浅! 目录 第1章 Java精髓 1 1.1 简单数据类型和对象:完美的平衡 2...
  • java

    2010-04-25 18:14:48
    传统的面向过程的思想是一个线性过程,要求现实系统的业务管理规范,处理数据齐全.面向过程思想以过程为中心进行功能组合,软件的扩充和复用能力. 比如:下面用常见的象棋戏作为例子进一步说明面向过程与面向对象...
  • set,map 等 来做数据存储,缺点:并发能力差,没有淘汰策略,缓存过期,加载需要手动处理,并发处理能力差等)。类似的 有 currentHashMap,EhChached2.应用场景对性能有非常高需求,数据变化不大,占用内存不大,有...
  • Java编程艺术 PDF

    2011-04-28 16:39:10
    本书是亚马逊网站上的五星级图书,相信读者能够通过研读本书大大提高自己的Java开发能力。本书代码示例易懂有趣,设计思想独特,定会使您受益匪浅! 目录 第1章 Java精髓 1 1.1 简单数据类型和对象:完美的平衡 2 ...
  • java 面试题 总结

    2009-09-16 08:45:34
    通常性能上较ArrayList,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 8、EJB是基于哪些技术实现的?并说出Session...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    1.Java有那些基本数据类型,String是不是基本数据类型,他们有何区别。 2.字符串的操作: 写一个方法,实现字符串的反转,如:输入abc,输出cba 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出...
  • java j2ee 课程设计报告

    2011-08-31 13:48:00
    但一直以来人们使用传统人工的方式管理文件档案,这种管理方式存在着许多缺点,如:效率低、保密性,另外时间一长,将产生大量的文件和数据,这对于查找、更新和维护都带来了不少的困难。 随着科学技术的不断提高...
  • 项目需求:需要建立socket客户端完成...描述能力,我直接贴使用实例吧!!! 一、获取连接,并启用一个线程: /** * @author spd * 通过ip,port连接到socket * * */ public class ConnectMethod { Soc...
  • 通常性能上较ArrayList,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出...
  • Java 服务器和硬件设备通信的过程中,众多的硬件设备可能数据处理能力,可靠性较,所以在 Netty 模块中使用了帧调度算法。服务器大规模下发数据帧时,可进行有效的拥塞控制、超时重发,可有效提升集群设备的...
  • web容器 WSGI 重要概念

    2020-12-11 20:18:03
    一些重要概念 ... web容器 什么是web容器 ...1.web容器是帮助我们部署java、...第二,帮助处理静态资源请求(html、css、JS),返回给客户端浏览器(django等web服务 器处理静态资源能力差) 常见web容器 1.nginx
  • spark概述

    2018-11-14 20:53:00
    延时高,只适合批处理计算,交互式、实时数据处理支持不够 spark的产生是直击之前的传统的基于分布式的计算框架MapReduce的一些缺点而设计的: Speed Ease of Use 1、提供Scala、Java、Python、R的编程接口 2、提供...
  • 02-21周总结

    2021-02-21 13:42:14
    不能让自己始终松懈下去,收拾好心态,做对的事情,认真规划好学习时间段,让时间充实起来的方法很多,要做出正确的选择,进行下一阶段的学习,将计划实践下去,认认真真的学习,数据库具有强大的数据处理能力,下...
  • 生产问题:生产上一个常用的会话接口,此接口内集成了5个外部接口能力(python的,Java的,其中每个接口基本耗时2~3秒),原有会话接口里是依次去调用的, 这就导致用户体验很,因为2乘5也就是10秒,也就是说...
  • 像的数据库存储、管理技术方案,并使用Java语言实现对遥感影像进行数据库存 储、管理的系统。 通过对有限的几款成熟商用数据库软件的比较,本论文采用的是Oracle Spatial空间数据库进行开发,提供使用者对数据库底层...
  • 在系统设计和开发过程中,要充分考虑系统当前和将来可能承受的工作量,使系统的处理能力和响应时间能够满足信息处理的需求。 2、 系统的开放性和系统的可扩充性:系统在开发过程中,应该充分考虑以后的可扩充性。...
  • 传统的故障诊断方法大多是以领域专家和操作者的启发性经验知识为核心,知识获取困难、推理效率低下、自适应能力差,并且常见的诊断方法常常由于其单一性而存在一定的误差。同时由于故障征兆和故障类型之间常常存在...
  • 因为前端控制的集中处理请求的能力,因此提高了可重用性和可拓展性。 没有前端控制器前: 问题: 如果每次请求需要做相同的处理操作,此时每一个Servlet都要做重复的处理; 2、前端控制器原理 跳转到目录 有了前端控制...
  • 也分享了你的开发经验,“业务变更的修改考验的是你的项目组织能力和面向对象设计能力”,“开发不是做几个数据库表,然后直接CRUD就够了的”;提出建议:“与其累死累活做这种谁都不高兴的软件,不如尝试一下信息化...
  • Heritrix是IA的开放源代码,可扩展的,基于整个Web的,归档网络爬虫工程 Heritrix工程始于2003年初,IA的目的是开发一个特殊的爬虫,对网上的 ...在硬件和系统失败时,恢复能力。 6。很少的时间用来优化性能。
  • Access 微软 Access是一种桌面数据库,只适合数据量少的应用,在处理少量 数据和单机访问的数据库时是很好的,效率也很高 小型企业 三、 Oracle数据库概述 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    8.4 异常处理语句 .95 8.5 小 结 .100 第三部分 面向对象的 C#.101 第九章 面向对象的程序设计 .101 9.1 面向对象的基本概念.101 9.2 对象的模型技术 .103 9.3 面向对象的分析 .105 9.4 面向对象的设计...
  • 4.2.6 JAVA池 144 4.2.7 流池 145 4.2.8 自动SGA内存管理 145 4.2.9 自动内存管理 147 4.3 小结 148 第5章 Oracle进程 149 5.1 服务器进程 149 5.1.1 专用服务器连接 150 5.1.2 共享服务器连接 152 5.1.3 ...

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

java数据处理能力差

java 订阅