耗子叔ARTS:第二十周

Algorithm:

/**
 * 7. Reverse Integer
 * Given a 32-bit signed integer, reverse digits of an integer.
 * <p>
 * Example 1:
 * <p>
 * Input: 123
 * Output: 321
 * Example 2:
 * <p>
 * Input: -123
 * Output: -321
 * Example 3:
 * <p>
 * Input: 120
 * Output: 21
 * Note:
 * Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
 */
public static int reverse(int x) {
    long res = 0;
    while (x != 0) {
        res = res * 10 + x % 10;
        x = x / 10;
    }

    if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
        return 0;
    } else {
        return (int) res;
    }
}

Review:

https://onezero.medium.com/three-takeaways-from-the-hack-of-jack-dorseys-twitter-account-e9de7b8614d8

Three Takeaways From the Hack of Jack Dorsey’s Twitter Account

ackers took over the Twitter account of Twitter’s own CEO, Jack Dorsey, for roughly 15 minutes on Friday afternoon. They tweeted a rapid-fire mishmash of boasts, shout-outs, racist slurs, and references to memes, along with a bomb threat and a call for Twitter to reinstate certain suspended accounts. Before Twitter regained control of the account and deleted the tweets, the perpetrators identified themselves as the Chuckling Squad, a group that also recently hacked a series of YouTube stars and actors.

It’s conceivable that the hackers did more than just post some offensive tweets from Dorsey’s account, but there was no immediate evidence of that on Friday. If that’s all they did, the real-world impact of this episode was probably pretty minor in the scheme of things. (This isn’t even the first time it’s happened to Dorsey.) Briefly taking over an individual’s social media account, even a high-profile one, is more like an act of petty vandalism than the sort of sophisticated hack that involves infiltrating a company’s systems or stealing people’s credit card information.

Even so, there are lessons worth paying attention to when the head of a major social media company gets victimized on his own platform. Based on the facts that were available Friday evening, here are three quick takeaways from Friday’s embarrassing hi-@jack-ing.

 

 

1. Check your Twitter app permissions. Like, nowish.

While details of the hack were still emerging Friday, the tweets from Dorsey’s account appeared to have been posted using a service called Cloudhopper. Twitter acquired a startup called Cloudhopper in 2010 that allows people to tweet from their phone via SMS, or text message, without logging into Twitter itself. If Dorsey had activated Cloudhopper at any time, that may have allowed the hackers to post from his account without having to steal his Twitter password. There were also indications that they gained access to his mobile phone number, via a technique called SIM-swapping, rather than the Twitter account itself.

Cloudhopper isn’t some random, shady, third-party app; it was long ago integrated into Twitter itself. It wasn’t immediately clear whether Dorsey could have prevented the attack by disabling it. Nonetheless, it’s a good reminder that your account can be compromised via various apps and services to which you’ve granted access over the years — even if you’ve totally forgotten about them, as Dorsey had apparently forgotten about Cloudhopper. Checking your Twitter app permissions is evergreen advice, but if you haven’t done it, now would be a perfect time. If there are any you don’t recognize, or don’t fully trust, you should revoke its access to your account. You can check your permissions at any time by going to https://twitter.com/settings/applications.

2. Sim-swapping is a serious problem.

Security experts have been warning about SIM-swapping for a while now. There are better explainers out there, but the gist is that someone persuades your phone carrier to transfer your phone number to their own SIM card. They might do it by pretending to be you and asking the carrier really nicely, or they might be bribing or working with someone on the inside.

Once they do that, they’ve essentially stolen your phone: not the hardware, but the phone line itself. That’s a problem, because the default method of protecting your various internet accounts is two-factor authentication, which often relies on access to your phone line as proof that it’s really you trying to log in. So if an app like Facebook or Twitter texts you a confirmation code before allowing you to log in, that code will be sent to the phone of the person who stole your number.

In this case, it seems possible that the phone number was all the hackers needed, thanks to Cloudhopper. Security experts were quick to suspect that the hack of Dorsey’s account involved SIM-swapping, partly because it’s the way the Chuckling Squad carried out previous attacks.

Unfortunately, there’s not a whole lot you can do to fully protect yourself from SIM-swapping. One measure that can help is to use authenticator apps such as Google Authenticator, rather than your phone number, for two-factor authentication, on services that allow it. (Here’s how you can change your two-factor settings on Twitter.) There are various other steps you can take, but realistically, SIM-swapping needs to be addressed on an industry level.

 

3. It could have been worse.

The CEO of Twitter getting hacked looks bad. The president of a country getting hacked could actually be bad, especially if the hackers go to more trouble to disguise themselves than the Chuckling Group did. Remember when a rogue Twitter employee briefly deleted President Trump’s account? A sophisticated actor who gained access to an account like Trump’s could theoretically wreak havoc by posing as him to post tweets that move markets or, God forbid, military forces.

Dorsey has been saying for years now that making Twitter safer and more secure is a top priority. His pinned tweet about committing to make the platform healthier and more civil stayed up Friday, even as the vile tweets from the hackers piled up directly beneath it. Perhaps Dorsey himself getting hacked (again) will prompt the company to redouble its efforts. In the meantime, Twitter will remain a potential point of vulnerability for everyone who uses it — even the tweeter in chief.

Tip:

微服务之间相互调用的时候不能随便抛出异常,因为原来返回的东西与原来约定的不一样。(统一处理异常的情况)

Share:https://mp.weixin.qq.com/s/mzTt0U-lW0RN7d_Y3Dd3-g

巧用Java8中的Stream,让集合操作飞起来!

Java知音 1周前

点击上方“Java知音”,选择“置顶公众号”

技术文章第一时间送达!

 

作者:坚持就是胜利

juejin.im/post/5d5e2616f265da03b638b28a

简介

java8也出来好久了,接口默认方法,lambda表达式,函数式接口,Date API等特性还是有必要去了解一下。比如在项目中经常用到集合,遍历集合可以试下lambda表达式,经常还要对集合进行过滤和排序,Stream就派上用场了。用习惯了,不得不说真的很好用。

Stream作为java8的新特性,基于lambda表达式,是对集合对象功能的增强,它专注于对集合对象进行各种高效、便利的聚合操作或者大批量的数据操作,提高了编程效率和代码可读性。

Stream的原理:将要处理的元素看做一种流,流在管道中传输,并且可以在管道的节点上处理,包括过滤筛选、去重、排序、聚合等。元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结果。

集合有两种方式生成流:

  • stream() − 为集合创建串行流

  • parallelStream() - 为集合创建并行流

 

上图中是Stream类的类结构图,里面包含了大部分的中间和终止操作。

中间操作主要有以下方法(此类型方法返回的都是Stream):map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

终止操作主要有以下方法:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

举例说明

首先为了说明Stream对对象集合的操作,新建一个Student类(学生类),覆写了equals()和hashCode()方法

public class Student {

    private Long id;

    private String name;

    private int age;

    private String address;

    public Student() {}

    public Student(Long id, String name, int age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(id, student.id) &&
                Objects.equals(name, student.name) &&
                Objects.equals(address, student.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, address);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

filter(筛选)

public static void main(String [] args) {

        Student s1 = new Student(1L, "肖战", 15, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        List<Student> streamStudents = testFilter(students);
        streamStudents.forEach(System.out::println);
    }
    /**
     * 集合的筛选
     * @param students
     * @return
     */
    private static List<Student> testFilter(List<Student> students) {
        //筛选年龄大于15岁的学生
//        return students.stream().filter(s -> s.getAge()>15).collect(Collectors.toList());
        //筛选住在浙江省的学生
        return students.stream().filter(s ->"浙江".equals(s.getAddress())).collect(Collectors.toList());
    }

运行结果:

这里我们创建了四个学生,经过filter的筛选,筛选出地址是浙江的学生集合。

map(转换)

    public static void main(String [] args) {

        Student s1 = new Student(1L, "肖战", 15, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        testMap(students);
    }

    /**
     * 集合转换
     * @param students
     * @return
     */
    private static void testMap(List<Student> students) {
        //在地址前面加上部分信息,只获取地址输出
        List<String> addresses = students.stream().map(s ->"住址:"+s.getAddress()).collect(Collectors.toList());
        addresses.forEach(a ->System.out.println(a));
    }

运行结果

map就是将对应的元素按照给定的方法进行转换。

distinct(去重)

    public static void main(String [] args) {

      testDistinct1();
    }

    /**
     * 集合去重(基本类型)
     */
    private static void testDistinct1() {
        //简单字符串的去重
        List<String> list = Arrays.asList("111","222","333","111","222");
        list.stream().distinct().forEach(System.out::println);
    }

运行结果:

public static void main(String [] args) {

      testDistinct2();
    }

    /**
     * 集合去重(引用对象)
     */
    private static void testDistinct2() {
        //引用对象的去重,引用对象要实现hashCode和equal方法,否则去重无效
        Student s1 = new Student(1L, "肖战", 15, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        Student s5 = new Student(1L, "肖战", 15, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s5);
        students.stream().distinct().forEach(System.out::println);
    }

运行结果:

可以看出,两个重复的“肖战”同学进行了去重,这不仅因为使用了distinct()方法,而且因为Student对象重写了equals和hashCode()方法,否则去重是无效的。

sorted(排序)

    public static void main(String [] args) {

        testSort1();
    }

    /**
     * 集合排序(默认排序)
     */
    private static void testSort1() {
        List<String> list = Arrays.asList("333","222","111");
        list.stream().sorted().forEach(System.out::println);
    }

运行结果:

    public static void main(String [] args) {

        testSort2();
    }

    /**
     * 集合排序(指定排序规则)
     */
    private static void testSort2() {
        Student s1 = new Student(1L, "肖战", 15, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.stream()
                .sorted((stu1,stu2) ->Long.compare(stu2.getId(), stu1.getId()))
                .sorted((stu1,stu2) -> Integer.compare(stu2.getAge(),stu1.getAge()))
                .forEach(System.out::println);
    }

运行结果:

上面指定排序规则,先按照学生的id进行降序排序,再按照年龄进行降序排序

limit(限制返回个数)

    public static void main(String [] args) {

        testLimit();
    }

    /**
     * 集合limit,返回前几个元素
     */
    private static void testLimit() {
        List<String> list = Arrays.asList("333","222","111");
        list.stream().limit(2).forEach(System.out::println);
    }

运行结果:

skip(删除元素)

    public static void main(String [] args) {

        testSkip();
    }

    /**
     * 集合skip,删除前n个元素
     */
    private static void testSkip() {
        List<String> list = Arrays.asList("333","222","111");
        list.stream().skip(2).forEach(System.out::println);
    }

运行结果:

reduce(聚合)

    public static void main(String [] args) {
        testReduce();
    }
    /**
     * 集合reduce,将集合中每个元素聚合成一条数据
     */
    private static void testReduce() {
        List<String> list = Arrays.asList("欢","迎","你");
        String appendStr = list.stream().reduce("北京",(a,b) -> a+b);
        System.out.println(appendStr);
    }

运行结果:

min(求最小值)

    public static void main(String [] args) {
        testMin();
    }

    /**
     * 求集合中元素的最小值
     */
    private static void testMin() {
        Student s1 = new Student(1L, "肖战", 14, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        Student minS = students.stream().min((stu1,stu2) ->Integer.compare(stu1.getAge(),stu2.getAge())).get();
        System.out.println(minS.toString());
    }

运行结果:

上面是求所有学生中年龄最小的一个,max同理,求最大值。

anyMatch/allMatch/noneMatch(匹配)

    public static void main(String [] args) {
        testMatch();
    }

    private static void testMatch() {
        Student s1 = new Student(1L, "肖战", 15, "浙江");
        Student s2 = new Student(2L, "王一博", 15, "湖北");
        Student s3 = new Student(3L, "杨紫", 17, "北京");
        Student s4 = new Student(4L, "李现", 17, "浙江");
        List<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        Boolean anyMatch = students.stream().anyMatch(s ->"湖北".equals(s.getAddress()));
        if (anyMatch) {
            System.out.println("有湖北人");
        }
        Boolean allMatch = students.stream().allMatch(s -> s.getAge()>=15);
        if (allMatch) {
            System.out.println("所有学生都满15周岁");
        }
        Boolean noneMatch = students.stream().noneMatch(s -> "杨洋".equals(s.getName()));
        if (noneMatch) {
            System.out.println("没有叫杨洋的同学");
        }
    }

运行结果:

anyMatch:Stream 中任意一个元素符合传入的 predicate,返回 true

allMatch:Stream 中全部元素符合传入的 predicate,返回 true

noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

总结

上面介绍了Stream常用的一些方法,虽然对集合的遍历和操作可以用以前常规的方式,但是当业务逻辑复杂的时候,你会发现代码量很多,可读性很差,明明一行代码解决的事情,你却写了好几行。试试lambda表达式,试试Stream,你会有不一样的体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值