打印输出杨辉三角形--合并2个数组--用支持协程的语言实现并行发起多个http请求,对比java多线程-发起http版实现

26 篇文章 0 订阅

1打印输出杨辉三角形

package main

import (
	"fmt"
 )

func main() {
	yanghuisanjiao(12)
}

func yanghuisanjiao(rows int) {
	for i := 0; i < rows; i++ {
		number := 1
		for k := 0; k < rows-i; k++ {
			fmt.Print("  ")
		}
		for j := 0; j <= i; j++ {
			fmt.Printf("%5d", number)
			number = number * (i - j) / (j + 1)
		}
		fmt.Println()
	}
}

2 合并2个数组

package main

import (
	"fmt"
	"sort"
)

func main() {
	var a = []int{1, 6, 45, 2, 9, 15, 7}
	var b = []int{2, 1, 80, 9, 67, 52, 15, 100, 99}
	c := sumArr(a, b)
	fmt.Println("合并后的数组为")
	fmt.Println(c)
	d := remArr(c)
	fmt.Println("合并、去重后的数组为")
	fmt.Println(d)
	e := sortArr(d)
	fmt.Println("合并、去重、排序后的数组为")
	fmt.Println(e)
}

func sumArr(a, b []int) []int {
	var c []int
	for _, i := range a {
		c = append(c, i)
	}
	for _, j := range b {
		c = append(c, j)
	}
	return c
}

func remArr(c []int) []int {
	d := make([]int, 0)
	tempMap := make(map[int]bool, len(c))
	for _, e := range c {
		if tempMap[e] == false {
			tempMap[e] = true
			d = append(d, e)
		}
	}
	return d
}

func sortArr(e []int) []int {
	sort.Ints(e[:])
	return e
}
合并后的数组为
[1 6 45 2 9 15 7 2 1 80 9 67 52 15 100 99]
合并、去重后的数组为
[1 6 45 2 9 15 7 80 67 52 100 99]
合并、去重、排序后的数组为
[1 2 6 7 9 15 45 52 67 80 99 100]

3 用支持协程的语言实现并行发起多个http请求或读取大文件,对比线程版实现(可选)

Go

请求 http://192.168.1.165:30076/ok.json 4000 次 每次并发20请求。
Go 与java 对比

Go 协程完成时间 spend=2046毫秒
Java 线程完成时间 :spend=11174 毫秒

Go —

// go-sample project main.go
package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sync"
	"time"
)

type Limit struct {
	number  int
	channel chan struct{}
}

// Limit struct 初始化
func New(number int) *Limit {
	return &Limit{
		number:  number,
		channel: make(chan struct{}, number),
	}
}

// Run 方法:创建有限的 go f 函数的 goroutine
func (limit *Limit) Run(f func()) {
	limit.channel <- struct{}{}
	go func() {
		f()
		<-limit.channel
	}()
}

// WaitGroup 对象内部有一个计数器,从0开始
// 有三个方法:Add(), Done(), Wait() 用来控制计数器的数量
var wg = sync.WaitGroup{}

const (
	concurrency = 20 // 控制并发量
)

func main() {

	start := time.Now()
	limit := New(concurrency) // New Limit 控制并发量
	// 接口请求URL
	apiUrl := "http://192.168.1.165:30076/ok.json" // 不要使用接口地址测试
	//max := int(math.Pow10(8))                  // 模拟一千万数据
	max := 4000 // 先测试4000次吧

	// 初始化参数
	param := url.Values{}
	param.Set("key", "您申请的KEY") // 接口请求Key

	for i := 0; i < max; i++ {
		wg.Add(1)
		value := i
		goFunc := func() {
			fmt.Printf("start func: %dn", value)
			// 配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参
			paramX := RandMobile()
			param.Set("paramX", paramX) // 需要查询的手机号码或手机号码前7位
			// 发送请求
			data_, err := Get(apiUrl, param)
			if err != nil {
				fmt.Println(err)
				fmt.Println("paramX: ", paramX, string(data_))
				return
			}
			// 其它逻辑代码...
			//fmt.Println("paramX: ", paramX, string(data_))
			//fmt.Println("for==:", i)

			wg.Done()
		}

		limit.Run(goFunc)
		//	fmt.Println("forXX==:", i)
	}

	// 阻塞代码防止退出
	wg.Wait()

	fmt.Printf("耗时: %f", time.Now().Sub(start).Milliseconds())
}

// Get 方式发起网络请求
func Get(apiURL string, params url.Values) (rs []byte, err error) {
	var Url *url.URL
	Url, err = url.Parse(apiURL)
	if err != nil {
		fmt.Printf("解析url错误:rn%v", err)
		return nil, err
	}
	//如果参数中有中文参数,这个方法会进行URLEncode
	Url.RawQuery = params.Encode()
	resp, err := http.Get(Url.String())
	if err != nil {
		fmt.Println("err:", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

var MobilePrefix = [...]string{"130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "145", "147", "150", "151", "152", "153", "155", "156", "157", "158", "159", "170", "176", "177", "178", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189"}

// GeneratorPhone 生成手机号码
func RandMobile() string {
	return MobilePrefix[RandInt(0, len(MobilePrefix))] + fmt.Sprintf("%0*d", 8, RandInt(0, 100000000))
}

// 指定范围随机 int
func RandInt(min, max int) int {
	rand.Seed(time.Now().UnixNano())
	return min + rand.Intn(max-min)
}



package com.example.demo.config;

import com.example.demo.client.AmapClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@Component
@Order(value = 1)
@Slf4j
public class StartupRunnerOne implements CommandLineRunner {

    @Autowired
    private AmapClient amapClient;
    //请求总数
    public static int clientTotal = 4000;
    //同时并发执行的线程数
    public static int threadTotal = 20;
    public static int count = 0;
    private static final Lock lock = new ReentrantLock();


    @Override
    public void run(String... args) throws Exception {

        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(threadTotal);
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);

        log.info("count:{}", count);
        StopWatch clock = new StopWatch();
        clock.start(); // 计时开始


        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    add();
                    semaphore.release();
                } catch (Exception e) {
                    log.error("exception", e);
                }
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executorService.shutdown();
        //  log.info("count:{}", count);
        clock.stop(); // 计时结束
        log.info("http::@Order(value=1)::spend=" + clock.getTotalTimeMillis());
        System.out.println(">>>>>>>@Order(value=1)>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
    }


    private void add() {
           try {
            Map result = amapClient.getLocation("121.475078", "31.223577");
            count++;
        } finally {     
      }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值