10 conselhos de um bom programador

Para se tornar um bom profissional (e isso vale para qualquer área eu acho) é preciso muita dedicação no estudo da teoria e muito mais ainda na aplicação da prática.

Dominar certa tecnologia, técnica ou ferramenta requer muita tentativa, erro e mais tentativa. Até que se chegue ao acerto.

Quando resolvi escrever isso aqui eu pensava em direcionar a lista pra quem ta começando. Mas se me permitem acho que posso ir além. A lista mais abaixo vai trazer 10 ações que considero essenciais para aprender e dominar certa tecnologia. Isso envolve aprender uma linguagem, utilizar um framework, aprender sobre IA, fazer uma faculdade, criar um app e por aí vai.

Embora nunca tenha trabalhado em uma multinacional, startup, ou empresa grande de tecnologia, minha experiência permite que eu possa de forma humilde compilar esta lista. Sem nenhuma arrogância, pois preciso e espero ainda aprender muito. E é muito mesmo.

Então vamos à lista.

1 – Comece. Você vai conseguir;

2 – Comece do início. Não pule etapas. Se você quer aprender um framework, conheça primeiro a linguagem.

3 – Estruture seu conhecimento. Tem um monte de conteúdo, site, canal, blog etc por aí. Mas se você puder comprar um curso e um livro você vai aprender melhor e mais rápido.

4 – Invista em você. Se sentir que está na hora de alcançar outro patamar em sua carreira e pra isso deve fazer um curso que custa um pouco mais, tome a decisão certa na hora certa e faça.

5 – Segure a ansiedade. Não dá pra aprender, fazer, comprar, acompanhar, ler, escrever, gravar, postar, estudar tudo ao mesmo tempo sobre tudo. Calma.

6 – Persista. Se não deu certo hoje, saia, descanse, vá à academia, distraia, beba, esqueça. Amanhã vai funcionar. E outra, se não conseguiu aquela vaga, amanhã aparece outra.

7 – Não acumule dúvidas. Se você leu uma palavra sequer que não entendeu procure seu significado imediatamente. Se aparecer algum assunto relacionado e que você não entenda, pare, pesquise e depois volte. Vai fazer uma diferença e tanto depois.

8 – Pratique. Crie, recrie, copie. Crie um repositório no git e tente recriar site, app, interface etc. Teste seus conhecimentos mas sem cobranças exagaredas.

9 – Compartilhe. É muito clichê e também muito verdade. Uma vez que aprendeu, ensinar ou ajudar alguém vai fazer com que você nunca mais esqueça. E é gratificante demais.

10 – Tenha um hobby. Faça alguma atividade em outra área. Isso ajuda em tudo, inclusive na ansiedade.

Acho que é isso. Espero que possa ajudar e se você quiser acrescentar mais alguma coisa comente aí.

Abçs.

Um extra: se estiver com medo ou inseguro, é assim mesmo. Vai com medo mesmo.

Indicação de livro #01 – Análise de Tráfego em Redes TCP/IP

Inauguro esta nova área no blog indicando este livro que é indispensável para quem gosta e estuda a área.

O livro é dividio em cinco partes:

Conceitos básicos;

Protocolos e sua análise;

Conhecimentos específicos e sua análise;

Tráfegos diversos e sistemas específicos.

Além disso é feita uma ampla abordagem sobre protocolos de rede e assuntos correlatos, como IPv4, IPv6, TCP, UDP, ICMP, Ethernet, ARP e NDP, Modelo OSI, roteamento em redes, bridges e sistemas de firewall.

Pra quem curte pentest e segurança, é indispensável.

E você compra pelo link abaixo com desconto e me ajuda.

Ubuntu Apparmor impedindo MySQL Workbench de guardar senhas

Ao tentar criar uma conexão, me deparei com um erro quando tentava armazenar a senha.

Depois de muito pesquisar identifiquei que se tratava do apparmor, um serviço que garante ou remove privilégios de programas.

O mysql-workbench foi instalado pela Loja do Ubuntu no diretório /snap.

Depois de tentar criar uma entrada pelo apparmor vi uma solução mais simples.

Na apresentação do aplicativo na loja tem as opções de permissões. Depois de acessá-la foi só garantir ao programa a letira/edição de senhas.

Permissões para o apparmor

Instalação MySQL via Docker com acesso pelo workbench

O que parece ser trivial pode acabar demandando configurações extras além do que escrito no Docker hub.

No guia de instalação em https://hub.docker.com/r/mysql/mysql-server o comando docker run permite o acesso via -it com docker exec sem problemas.

O problema surge quando necessário acessar via workbench, o que é mais usual.

O problema: o usuário root com senha padrão gerada na instalação não tem permissão para acessar pelo localhost via TCP/IP. Que no caso do docker é tido como uma conexão remota.

Solução: primeiramente foi necessário expor a porta 3306 da imagem. Também aproveitei para setar uma senha por meio de parâmetro no comando run.

docker run --name mysql-server -e MYSQL_ROOT_PASSWORD=password-p3306:3306 -d mysql/mysql-server:5.6

Após a imagem instalada foi necessário garantir privilégios ao usuário root para acesso de qualquer host por meio dos comandos a seguir:

docker exec -it mysql-server mysql -uroot -p

grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option;

Para entender melhor o esquema de senhas e hash do MySQL segue o tópico da documentação: https://dev.mysql.com/doc/refman/5.6/en/password-hashing.html

Depois de garantido o acesso é só configurar a conexão pelo workbench com o host localhost e senha previamente criada.

E pronto!

Styled Components FlatList ReactNative CSS problem

Something happens when a FlatList decorated with Styled Components update your data: the CSS of the Content disappears.

Bellow the original code and then the fix.

The CSS:
import styled from 'styled-components/native';
import DefaultButton from '~/components/Button';
export const Container = styled.View`
flex: 1;
background: #fff;
border-radius: 4px;
margin-bottom: 10px;
`;
export const Image = styled.Image`
width: auto;
height: 200;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
`;
export const Content = styled.View`
flex: 1;
padding: 15px;
`;
export const Title = styled.Text`
color: #333;
font-size: 16px;
font-weight: bold;
margin: 10px 0;
`;
export const Info = styled.Text`
color: #ccc;
font-size: 12px;
margin: 6px 0 6px 15px;
`;
export const Button = styled(DefaultButton)`
margin-top: 10px;
`;
The FlatList:
return (
<Background>
<Container>
<MeetupList
data={subscriptions}
keyExtractor={item=>String(item.id)}
renderItem={({item}) => (
<Meetup
data={item.meetup}
onHandle={() =>handleCancel(item.id)}
buttonText="Cancelar inscrição"
/>
)}
/>
</Container>
</Background>
);
The fix is set the Content flex-shrink to auto in the Content styled component.
export const Content = styled.View`
flex: 1 auto;
padding: 15px;
`;

SpringBoot @Async methods

Today I needed to implement a method to send a notification email after the registration progress. With the actual logic my application was taking too long during the process. So I decide to make the mail sending asynchronous.

First I tried the JMS, the old school Java Message Service API, but I realized that is not that gold, just old.

So after few googling I found a post of Dan Vega, a SpringBoot guru who has courses on Udemy.

With this post I realized: spring make our lives too easy, indeed.

Tow annotations make the method asynchronous, @Async and @EnableAsync.

Here is the post.

Cross Apply no Sql Server

Precisava criar um relatório que listasse a média das 3 primeiras vendas de clientes novos do ano atual (2018).

A query então deve conter 2 tabelas: cliente e pedidos. O filtro do cliente e dos pedidos é básico. O difícil é fazer com que os pedidos recebam o código do cliente do Select e aplicá-lo na query que traz os pedidos.

A princípio tentei fazer um Join, depois uma subquery mas por conta da operador TOP não conseguia. Logicamente o TOP 3 retornaria apenas três registros da tabela pedido e não três pedidos da tabela pedido para cada cliente da query principal.

Pesquisando um pouco eu cheguei a uma query com dois joins que não deu muito certo, mas a lógica até que é boa:

SELECT
A1_COD,
Z7.Z7_CONSULT,
Z7.Z7_NUM,
Z7.Z7_DTFECHA,
B.*
FROM
SA1010 A1
LEFT JOIN (SELECT TOP 3 Z7_NUM, Z7_CONSULT FROM SZ7010 WHERE D_E_L_E_T_ = '' AND Z7_STATUS = 'F' ORDER BY Z7_DTFECHA) B ON A1.A1_COD = B.Z7_CONSULT
LEFT JOIN SZ7010 Z7 ON Z7.Z7_NUM = B.Z7_NUM
WHERE
A1.D_E_L_E_T_ = '' AND
A1.A1_DTCAD > 20180101 AND
A1.A1_STATUS = 1
ORDER BY
A1.A1_COD

Porém não funcionou. : (

A solução foi a utilizar o operador CROSS APPLY, que utiliza uma query como entrada para outra e as uni. Analisando o problema das novatas em questão fica fácil entender o funcionamento. Veja a query:

SELECT
A1_COD,
A1_NOME,
A1_DTCAD,
CA.*
FROM
SA1010 A1
CROSS APPLY (
SELECT TOP 3
Z7_NUM,
Z7_CONSULT,
Z7_QTDCOMD,
Z7_REGIAO,
Z7_DTFECHA
FROM
SZ7010 B
WHERE
B.D_E_L_E_T_ = '' AND
B.Z7_STATUS = 'F' AND
B.Z7_SERIE <> 'DIR' AND
A1.A1_COD = B.Z7_CONSULT
ORDER BY
Z7_DTFECHA) CA
WHERE
A1.D_E_L_E_T_ = '' AND
A1.A1_DTCAD > 20180101 AND
A1.A1_STATUS = 1
ORDER BY
A1.A1_COD

A query então traz os 3 primeiros pedidos para cada cliente retornado na query inicial e junta os resultados.

109244 <<NOME>> 20180102 842355 109244 23 000122 20180203
109244 <<NOME>> 20180102 844817 109244 45 000122 20180312
109244 <<NOME>> 20180102 862112 109244 54 000122 20180419
109255 <<NOME>> 20180102 839520 109255 17 000072 20180204
109255 <<NOME>> 20180102 854113 109255 28 000072 20180313
109255 <<NOME>> 20180102 861392 109255 42 000072 20180417
109260 <<NOME>> 20180105 838082 109260 25 000093 20180205
109260 <<NOME>> 20180105 851091 109260 41 000093 20180314
109260 <<NOME>> 20180105 863113 109260 41 000093 20180418

Depois disso apenas alterei a query para que ao invés dos três pedidos retornasse a média de peças vendidas e pronto. Relatório concluido com performance e acuracidade.

Seguem dois links que tratam do operador Cross Apply que me ajudaram:

https://www.tutorialti.com/2015/02/o-que-e-cross-apply-sql-server.html

http://blog.dbaacademy.com.br/sql-server-cross-apply-e-cross-join/

Espero ter ajudado e até!

Credit Card Metadata and Validator

Hi!

There’s a service that validates the credit card number and returns the metadata.

The requisition is via http and returns a json. Just like this:

curl -H "Accept-Version: 3" "https://lookup.binlist.net/45717360"
 {
  "number": {
    "length": 16,
    "luhn": true
  },
  "scheme": "visa",
  "type": "debit",
  "brand": "Visa/Dankort",
  "prepaid": false,
  "country": {
    "numeric": "208",
    "alpha2": "DK",
    "name": "Denmark",
    "emoji": "🇩🇰",
    "currency": "DKK",
    "latitude": 56,
    "longitude": 10
  },
  "bank": {
    "name": "Jyske Bank",
    "url": "www.jyskebank.dk",
    "phone": "+4589893300",
    "city": "Hjørring"
  }
}

The link: https://binlist.net/

But if you want regex for the most common credit card brands, check below.

    const elo = /((((636368)|(438935)|(504175)|(451416)|(636297)))[0-9]{4}$)|(((5067)|(4576)|(4011))[0-9]{8}$)$/;
    const visa = /^4[0-9]{12}(?:[0-9]{3})$/;
    const master = /^5[1-5][0-9]{14}$/;
    const amex = /^3[47][0-9]{13}$/;
    const diners = /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/;
    const discover = /^6(?:011|5[0-9]{2})[0-9]{12}$/;
    const jcb = /^(?:2131|1800|35\d{3})\d{11}$/;
That’s it!

Admin-lte height bug (fixed)

Admin-Lte template

Admin-Lte template

Hop!

Desenvolvendo um Web App para a Divisão de Homicídios de Niterói São Gonçalo (DH-NSG) utilizando React e o template do Admin-lte vinha enfrentando um bug na visualização da página. O conteúdo era carregado apenas até a metade da página.

Depois de ter desistido por um tempo de corrigi-lo, descobri hoje um workaround em css que corrige este bug.

Segue:

  .wrapper {
    /*min-height: 100%;
    position: relative;
    overflow: hidden;*/
    width: 100%;
    min-height: 100%;
    height: auto !important;
    position: absolute;
  }
Depois de tentar algumas snippets este funcionou e com isso espero ajudar. Até…

React Native keyboard over InputText

During creating a form in React Native I faced a issue with the android keyboard. It override the text field, so I could not see what is the enter of the field.

So I found the solution, actually, three. I adopted the first one, just changing the View by KeyboardAvoidingView component.

Here is the complete solution.

Very cool and useful.