• 0.81

  • +0.75

Как я получил работу Джава-программиста



Вот пришла очередь и моей саксесс-стори :)

25 января 2015 года я случайно попал на Джавараш. До этого я себя искал уже около полугода, так как понимал, что работа менеджером — это последнее, на что должен идти уважающий себя человек. Но имея экономическое образование, было не так-то просто свернуть с этой скользкой дорожки.

У меня был четкие приоритеты: я считал (и сейчас считаю), что уважения достойны только созидательные профессии. Поэтому путь мой шел либо в креативный класс, либо в рабочие).

Я пробовал себя в веб-дизайне, немного в программировании. Но это было на столько мимолетно, что достойно максимум одного предложения в моем рассказе.

Итак с этого дня началось мое основательное обучение. Я решил идти до конца, читай до победы. Победой для меня считалось трудоустройство.

Я быстро проскочил первые 6 уровней, потом еще 4. И вот надо платить — денег было немного, пришлось даже занять. Я отдал 12 тыс руб за полные 40 уровней в марте 2015 года. Для меня это были очень большие деньги на тот момент. Знакомые и друзья смотрели тогда немного искоса)

До середины лета я прошел 27 уровней. ИМХО дойдя до 23 уже нужно переходить к изучению веб-стека (servlets, jdbc, tomcat) и активно браться за sql.

По мне так курс слишком затянут, и качество заданий неуклонно снижается после 23 уровня. Параллельно с Джавараш я изучал алгоритмы и дескретную математику. Алгоритмы в дальнейшем очень помогли! По факту, именно они меняют мышление в нужную сторону, и ты начинаешь мыслить уже не в рамках определенной технологии.

Летом я взялся за курсы Тимура Батыршинова, которые дали мне ощутимый прогресс в области EE. Примерно в это же время стал откликаться на вакансии. Но, увы, моих знаний на тот момент было недостаточно.

Пытаясь расширить свой кругозор в области IT, я записался на годовую программу переквалификации от CSC. Я таки расширил свой кругозор и получил большую дозу матана. Диплом вручили 14 июля 2016 года. За эти 9 месяцев я работал больше чем за 5 лет в инсте. Но это отдельная история)

Я понимал, что в моем родном городе, в Волжском, делать в плане джавы нечего. Я предпринял попытку переехать в Воронеж и найти работу джависта там. Но опять не произвел впечатления на работодателя.

Этот сложный период продолжался до января 2016. Меня пинали, то за отсутствие технической вышки, то за плохое знание джавы. Были вакансии, в которых писали что нужен джава дев, я на деле предлагали 1С :) Но я не унывал. Впервые в моей жизни у меня было ощущение, что я занимаю своим делом.

И вот, в ноябре 2015 мне прислали тестовые задания в Джавашколу. Я их с легкостью выполнил и отправил назад. Но на тот поток я не попал, ибо набор закончился. и лишь в январе 2016 мне написали, что все хорошо и ждут меня на собес в спб. Точную дату не назвали.

У меня было мало денег, и я не знал на какой день брать билеты. Взял наугад, чтобы приехать 20 января… И в этот же день, через три часа после прибытия моего поезда, мне назначили собеседование!
Я приехал в офис с вещами, немытый и уставший) Но прошел два этапа отбора и был приглашен в Джавашколу.

В джавашколе я пахал целыми днями, параллельно учась на степике. И вот после показа мне прислали джоб оффер. С 20 апреля я официально работаю Software Developer'ом. Пару дней назад закончился мой испытательный срок. Условием его успешного прохождения была сдача оракловской сертификации. 18 июля я ее сдал.

Сейчас, уже работая разработчиком, я вижу еще больше того, чего не знаю. Но мой энтузиазм изучать новое лишь растет. Я до сих пор часто туплю, но уверенность что любая задача решаема уже не покидает меня :)

P.S.
Если бы я мог отправить себе сообщение в январь 2015 о том, что и как изучать, я бы написал следующее:
1. ДжаваРаш до 23 уровня.
С 17 уровня ДжаваРаш учим:
SQL (Форта «SQL за 10 минут» и www.sql-ex.ru/learn_exercises.php)
Алгоритмы (Лафоре «Алгоритмы на Java»)
2. Батыршинов (Онлайн-библиотека на джава)
*** здесь можно начинать осознанно ходить на собеседования ***
3. Батыршинов (Онлайн-библиотека на джава (спринг))
4. Батыршинов (Веб-сервисы на джава)

Дальше, вы уже сами будете понимать, чего вам не хватает ;)
  • ,

Как пользоваться CopyOnWriteArraySet в Java с примером (перевод)

CopyOnWriteArraySet это младший брат класса CopyOnWriteArrayList. Это специализированный набор классов, добавленных в JDK 1.5 вместе с их более популярным двоюродным братом ConcurrentHashMap. Они являются частью concurrent collection framework и расположены в пакете java.util.concurrent.

CopyOnWriteArraySet лучше всего подходит для read-only коллекций, размер которых достаточно мал, чтобы их скопировать, если произойдут некоторые изменяющие операции. Например, вы можете использовать CopyOnWriteArraySet для хранения объекта при запуске приложения, и дать множеству других потоков доступ к этому объекту на протяжении жизненного цикла приложения. Если новое состояние или объект приходят в течение этого времени, он также может быть добавлен в этот Set, со стоимостью создания нового массива.

Одна из самых важных вещей, которую стоит знать о CopyOnWriteArraySet это то, что он реализован при помощи CopyOnWriteArrayList. Это означает, что CopyOnWriteArraySet также разделяет все основные свойства CopyOnWriteArrayList. Еще одна важная вещь, которую стоит запомнить: итераторы этого класса коллекции не поддерживают операцию remove(). Попытка удалить элемент во время итерирования приведет к выбросу UnsupportedOperationException. Это сделано чтобы гарантировать скорость во время обхода. Обход этой реализации Set, используя итератор, осуществляется достаточно быстро, и во время него исключены вмешательства других потоков. В своей работе итераторы опираются на моментальный снимок массива, который был сделан во время создания итератора.

Короче говоря, используйте CopyOnWriteArraySet если set достаточно мал, чтобы копировать его при добавлении, задании значения или удалении объектов, и основной целью является чтение обновляемых от случая к случаю данных. Кроме того, если вы хотите удалить элементы во время итерации, не используйте эту реализацию, потому что ее итератор не поддерживает remove(), и бросает java.lang.UnsupportedOperationException, как показано ниже:


[RAJ] Event received : FOUR 
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(Unknown Source)
    at Publisher.notifySubs(HelloHP.java:43)
    at HelloHP.main(HelloHP.java:23)


CopyOnWriteArraySet пример на Java

Вот готовая программа на Java показывающая, как использовать CopyOnWriteArraySet. В нашем примере мы использовали шаблон проектирования «Издатель-подписчик» (англ. publisher-subscriber pattern), чтобы продемонстрировать его использование. Большинство подписчиков подписаны во время пуска приложения и главной задачей издателя является их перебор и уведомление о каких-либо обновлениях. Время от времени может случаться добавление и удаление подписчика. Так как нам нужен быстрый обход, CopyOnWriteArraySet является хорошим выбором, особенно в многопоточной среде, где один поток может добавить абонента, а другой поток обрабатывает обновления.


import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Java program to demonstrate how to use CopyOnWriteArraySet in Java. Remember,
 * CopyOnWriteArraySet doesn't support remove() operation.
 *
 * @author Javin Paul
 */
public class CopyOnWriteArraySetDemo{

    public static void main(String args[]) {
        Publisher cricNext = new Publisher();

        SubScriber raj = new SubScriber("RAJ");
        SubScriber adom = new SubScriber("ADOM");

        cricNext.addSubscriber(raj);
        cricNext.addSubscriber(adom);

        cricNext.notifySubs("FOUR");
        cricNext.notifySubs("SIX");

    }

}

class Publisher {

    private CopyOnWriteArraySet setOfSubs = new CopyOnWriteArraySet();

    public void addSubscriber(SubScriber sub) {
        setOfSubs.add(sub);
    }

    public void notifySubs(String score) {
        Iterator itr = setOfSubs.iterator();
        while (itr.hasNext()) {
            SubScriber sub = itr.next();
            sub.receive(score);

            //itr.remove(); // not allowed, throws UnsupportedOperationException
        }
    }
}

class SubScriber {

    private String _name;

    public SubScriber(String name) {
        this._name = name;
    }

    public void receive(String score) {
        System.out.printf("[%s] Event received : %s %n", _name, score);
    }
}


Output:
[RAJ] Event received : FOUR 
[ADOM] Event received : FOUR 
[RAJ] Event received : SIX
[ADOM]Event received : SIX


Что нужно запомнить

CopyOnWriteArraySet реализует интерфейсы Collection и Set, а также, добавленный в JDK 1.5, вместе с другой специальной реализацией Set'а, EnumSet. Это также Set, который использует внутренний CopyOnWriteArrayList для всех своих операций. Таким образом, он разделяет те же основные свойства этого класса. Так как это не SortedSet, порядок элементов не гарантируется в течение итерации.

1. CopyOnWriteArraySet лучше всего подходит для приложений, в которых:
  • Размеры Set'ов, как правило остаются небольшими.
  • Операции read-only значительно превосходят операции, изменяющие объекты.
  • Вы должны предотвратить помехи между потоками во время обхода Set'а.

2. Еще одним преимуществом CopyOnWriteArraySet является потокобезопасность. Эта коллекция поддерживает параллелизм.
3. Мутативные операции (добавление, изменение, удаление и т.д.) являются дорогостоящими, так как они, как правило, требуют копирования всего базового массива.
4. Итераторы не поддерживают мутативную операцию удаления.
5. Обход используя итератор достаточно быстр и во время него исключены вмешательства других потоков. В своей работе итераторы опираются на моментальный снимок массива, который был сделан во время создания итератора.

На этом все об использовании CopyOnWriteArraySet в Java. Как я сказал, он является младшим братом CopyOnWriteArrayList. Так что если вы понимаете хотя бы один из них, то сможете использовать и другой. Единственное отличие в том, что один является List'ом а другой Set'ом, таким образом это влечет за собой унаследование всех отличий между этими структурами данных в Java. Например, в List важен порядок расположения элементов, и он может содержать дубликаты. В то время как Set является неупорядоченным, но не позволяет дублирование объектов.

Всегда помните, что CopyOnWriteArraySet это специализированный Collection класс. Его стоит использовать только когда условия являются благоприятными. В любом другом случае можно пользоваться реализациями общего назначения. Например, HashSet, LinkedHashSet или синхронизированными классами коллекций.

Оригинал статьи
  • ,

level20.lesson02.task01

Встроенная проверка выводит полностью одинаковые результаты. Но все равно пишет, что файлы не равны((
Уже пробовал и не трогать price и через readLine добавлять — все одно и то же :(
Весь день решаю, намекните хоть куда копать(

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/* Читаем и пишем в файл: Human
Реализуйте логику записи в файл и чтения из файла для класса Human
Поле name в классе Human не может быть пустым
В файле your_file_name.tmp может быть несколько объектов Human
Метод main реализован только для вас и не участвует в тестировании
*/
public class Solution {
    public static void main(String[] args) {
        //you can find your_file_name.tmp in your TMP directory or fix outputStream/inputStream according to your real file location
        //вы можете найти your_file_name.tmp в папке TMP или исправьте outputStream/inputStream в соответствии с путем к вашему реальному файлу
        try {

            File your_file_name = File.createTempFile("your_file_name", null, new File("C:/"));
            OutputStream outputStream = new FileOutputStream(your_file_name);
            InputStream inputStream = new FileInputStream(your_file_name);

            Human ivanov = new Human("Ivanov", new Asset("home"), new Asset("car"));
            ivanov.save(outputStream);
            outputStream.flush();

            Human somePerson = new Human();
            somePerson.load(inputStream);
            //ПРОВЕРКА, что ivanov и somePerson равны--------------------------------------------------

            System.out.println(ivanov.name + ": ");

            List<Asset> as = ivanov.assets;

            for (int i = 0; i < as.size(); i++){
                System.out.println(as.get(i).getPrice() + " " + as.get(i).getName());
            }

            System.out.println(somePerson.name + ": ");

            List<Asset> as1 = somePerson.assets;

            for (int i = 0; i < as1.size(); i++){
                System.out.println(as1.get(i).getPrice() + " " + as1.get(i).getName());
            }

            if (ivanov.equals(somePerson)){
                System.out.println("ivanov и somePerson равны");
            }
            else {
                System.out.println("ivanov и somePerson НЕ равны");

            }
            //--------------------------------------------------------------------------------------------

            inputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Oops, something wrong with my file");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Oops, something wrong with save/load method");
        }
    }


    public static class Human {
        public String name;
        public List<Asset> assets = new ArrayList<>();

        public Human() {
        }

        public Human(String name, Asset... assets) {
            this.name = name;
            if (assets != null) {
                this.assets.addAll(Arrays.asList(assets));
            }
        }

        public void save(OutputStream outputStream) throws Exception {
            //implement this method - реализуйте этот метод
            PrintWriter writer = new PrintWriter(outputStream);
            String isNamePresent = name != null ? "yes" : "no";
            writer.println(isNamePresent);

            if (name != null){
                writer.println(name);
            }

            if (assets.size()>0)
            {
                for (int i = 0; i < assets.size(); i++)
                {
                    String isAssetPresent = assets.get(i) != null ? "yes" : "no";
                    writer.println(isAssetPresent);

                    if (isAssetPresent.equals("yes"))
                    {
                        Asset as = assets.get(i);
                        if (assets.get(i) != null) writer.println(as.getName());
                        if (assets.get(i) != null) writer.println(as.getPrice());
                    }
                }
            }
            writer.flush();
            writer.close();
        }

        public void load(InputStream inputStream) throws Exception {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String isNamePresent = reader.readLine();
            if (isNamePresent.equals("yes")){
                name = reader.readLine();


                while(reader.ready()){

                    String isAssetPresent = reader.readLine();

                        if (isAssetPresent.equals("yes")){

                            String s = reader.readLine();
                            
                            Asset a = new Asset(s);
                            double d = Double.parseDouble(reader.readLine());
                            a.setPrice(d);
                            assets.add(a);
                        }
                }
            }
        }
    }
}
  • ,

level19.lesson08.task04

Проблема с принятием задачи (так все работает). Думаю дело в том что у меня вывод не на одной сроке, как в задании. Однако, как я понял, метод менять нельзя. Как вы возвращались на предыдущую строку?

Хотя может быть проблема в другом.

/* Решаем пример
В методе main подмените объект System.out написанной вами ридер-оберткой по аналогии с лекцией
Ваша ридер-обертка должна выводить на консоль решенный пример
Вызовите готовый метод printSomething(), воспользуйтесь testString
Верните переменной System.out первоначальный поток

Возможные операции: + — *
Шаблон входных данных и вывода: a [знак] b = c
Отрицательных и дробных чисел, унарных операторов — нет.

Пример вывода:
3 + 6 = 9
*/

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

public class Solution {
    public static TestString testString = new TestString();

    public static void main(String[] args) {
        PrintStream consoleStream = System.out; // сохраняем ссылку на объект консольного ввода
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // свой объект для ввода
        PrintStream stream = new PrintStream(outputStream);
        System.setOut(stream); // назначаем свой поток, вместо консольного
        testString.printSomething();//Печатаем в консоль, перехватывая результат
        String result = outputStream.toString();//сохраняем его в переменной


        System.setOut(consoleStream);//возвращаем консольный ввод
        StringBuilder sb = new StringBuilder(result); // меняем вывод
        String str = sb.toString();

        char[] charSet = str.toCharArray();

        int a = 0, b = 0, c = 0;
        for (int i = 0; i < charSet.length; i++) {
            a = Character.getNumericValue(charSet[0]);
            b = Character.getNumericValue(charSet[4]);
            if (charSet[2] == '+') {
                c = a + b;
            } else if (charSet[2] == '*') {
                c = a * b;
            } else if (charSet[2] == '-') {
                c = a - b;
            }
        }

        System.out.print(str + "" + c);
    }

    public static class TestString {
        public void printSomething() {
            System.out.println("3 + 6 = ");
        }
    }
}
  • ,

level17.lesson10.bonus03 : Проблема с инкапсуляцией?

/* Ресторан
1.Разберись, что делает программа. Официант почему-то не относит приготовленные блюда назад к столам :(
2.Исправь ошибку.
Подсказка: это одна строчка
*/

Ошибку нашел и задачу решил. Может туплю, но не понимаю: ведь нарушается инкапсуляция коллекции с очередью блюд! (т.к. через геттер из другого класса можно добавить туда блюдо)
  • ,

level17.lesson10.bonus01

Совсем не получается. Темы все прочитал. Не могу разобраться как тестить в командной строке: программа там просто благополучно завершается (как и в идее с кодом 0). В program arguments задавал: -c Миронов м 15/04/1990.

Что я делаю не так?


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/* CRUD
CrUD - Create, Update, Delete
Программа запускается с одним из следующих наборов параметров:
-c name sex bd
-u id name sex bd
-d id
-i id
Значения параметров:
name - имя, String
sex - пол, "м" или "ж", одна буква
bd - дата рождения в следующем формате 15/04/1990
-с  - добавляет человека с заданными параметрами в конец allPeople, выводит id (index) на экран
-u  - обновляет данные человека с данным id
-d  - производит логическое удаление человека с id
-i  - выводит на экран информацию о человеке с id: name sex (м/ж) bd (формат 15-Apr-1990)

id соответствует индексу в списке
Все люди должны храниться в allPeople
Используйте Locale.ENGLISH в качестве второго параметра для SimpleDateFormat

Пример параметров: -c Миронов м 15/04/1990
*/

public class Solution {
    public static List<Person> allPeople = new ArrayList<Person>();
    static {
        allPeople.add(Person.createMale("Иванов Иван", new Date()));  //сегодня родился    id=0
        allPeople.add(Person.createMale("Петров Петр", new Date()));  //сегодня родился    id=1
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Мэйн работает!");

        SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH);


        if (args.length < 2) {
            return;
        }
        //для -c name sex bd (args[3]) код ниже:
        if (args[0].equals("-с")) {
            if (args.length != 3) {
                return;
            }
            Person person; // пустая ссылка на объект персон

            if (args[2].equals('м')) {
                person = Person.createMale(args[1], format.parse(args[3]));
            } else {
                person = Person.createFemale(args[1], format.parse(args[3]));
            }

            allPeople.add(person);
            System.out.println(allPeople.indexOf(person));
        }

        //для -u id name sex bd (args[4]) код ниже. Здесь только редактируем данные:
        else  if (args[0].equals("-u")) {
            if (args.length != 5) {
                return;
            }
            int id = Integer.parseInt(args[1]);
            Person person = allPeople.get(id); //нашли человека по айди

            person.setName(args[2]); //изменили имя

            if (args[3].equals('м')) {  //изменили пол
                person.setSex(Sex.MALE);
            } else {
                person.setSex(Sex.FEMALE);
            }
            person.setBirthDay(format.parse(args[4])); //изменили дату рождения

            allPeople.add(id, person); // почему тут еще и по айди? в конструкторе же нету такого?
        }


        //-d  - производит логическое удаление человека с id. -d id
        else if (args[0].equals("-d")) {
            if (args.length != 2) {
                return;
            }
            Person person = Person.createFemale(null, null);
            person.setSex(null);
            allPeople.set(Integer.parseInt(args[1]), person);
        }

        //-i  - выводит на экран информацию о человеке с id: name sex (м/ж) bd (формат 15-Apr-1990)
        else if (args[0].equals("-i")) {
            if (args.length != 2) {
                return;
            }

            int id = Integer.parseInt(args[1]);
            Person person = allPeople.get(id); //нашли человека по айди

            System.out.println(person.getName() + " " + person.getSex() + " " + format.format(person.getBirthDay()));
        }
    }
}
  • ,

level13.lesson11.bonus01

Все запускается и работает. Проверку не проходит. Почему? :)

package com.javarush.test.level13.lesson11.bonus01;

/* Сортировка четных чисел из файла
1. Ввести имя файла с консоли.
2. Прочитать из него набор чисел.
3. Вывести на консоль только четные, отсортированные по возрастанию.
Пример ввода:
5
8
11
3
2
10
Пример вывода:
2
8
10
*/


import java.io.*;
import java.util.ArrayList;


public class Solution
{
    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String oF = reader.readLine();
        BufferedReader readerFromFile = new BufferedReader(new FileReader(oF));

        ArrayList<Integer> list = new ArrayList<Integer>();


        while (readerFromFile.ready())
        {
            int n = Integer.parseInt(readerFromFile.readLine());
            if (n % 2 == 0) {
                list.add(n);
            }
        }

        reader.close();
        sort(list);

        for (int i : list) {
            System.out.println(i);
        }
    }

    public static void sort(ArrayList<Integer> list) {
        for (int i = list.size() - 1; i > 0; i--) {
            for (int j = 0; j < list.size() - 1 - i; j++) {

                if(list.get(j) > list.get(j+1)){
                    int temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j+1, temp);
                }

            }
        }
    }

}
  • ,

Запуск кода на исполнение в IntelliJ IDEA

Вопрос по IntelliJ IDEA.
У меня на компьютере не так как мне нужно работает кнопка Run (зеленый треугольник)
Он запускает все что угодно, только не мое текущее задание.

Рылся в настройках — не помогло.

Я думаю что дело в имени — у всех заданий название файла Solution. Поэтому он и запускает любой Solution.

Как сделать чтобы запускалось на исполнение именно текущее задание?

Спасибо!